public inbox for linux-scsi@vger.kernel.org
 help / color / mirror / Atom feed
From: Mike Christie <michaelc@cs.wisc.edu>
To: jeykholt@cisco.com
Cc: linux-scsi@vger.kernel.org, jre@nuovasystems.com,
	ajoglekar@nuovasystems.com
Subject: Re: [RFC][PATCH 2/6] fnic: add fnic_scsi.c and fnic_io.h.
Date: Mon, 25 Aug 2008 13:22:56 -0500	[thread overview]
Message-ID: <48B2F880.7080108@cs.wisc.edu> (raw)
In-Reply-To: <20080823025222.13569.37765.stgit@feynman.nuovasystems.com>

jeykholt@cisco.com wrote:
> fnic: add fnic_scsi.c and fnic_io.h.
> 
> fnic_scsi.c contains the FCP SCSI handling as well as firmware reset
> and FLOGI registration handling.
> 

I just looked at this one function, because I was fixing the same code 
in fcoe.ko/libfc:fc_fcp.c


> +int fnic_reset(struct Scsi_Host *shost)
> +{
> +	struct fc_lport *lp;
> +	struct fnic *fnic;
> +	unsigned long flags;
> +	int ret = SUCCESS;
> +	enum fnic_state old_state;
> +	DECLARE_COMPLETION_ONSTACK(reset_wait);
> +
> +	lp = shost_priv(shost);
> +	fnic = lp->drv_priv;
> +
> +	printk(KERN_DEBUG DFX "fnic_reset called\n", fnic->fnic_no);
> +
> +	/* Issue firmware reset */
> +	spin_lock_irqsave(&fnic->fnic_lock, flags);
> +	fnic->reset_wait = &reset_wait;
> +	old_state = fnic->state;
> +	fnic->state = FNIC_IN_FC_TRANS_ETH_MODE;
> +	vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr);
> +	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> +
> +	if (fnic_fw_reset_handler(fnic)) {
> +		spin_lock_irqsave(&fnic->fnic_lock, flags);
> +		ret = FAILED;
> +		if (fnic->state == FNIC_IN_FC_TRANS_ETH_MODE)
> +			fnic->state = old_state;
> +		fnic->reset_wait = NULL;
> +		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> +		goto fnic_reset_end;
> +	}
> +
> +	/* fw reset is issued, now wait for it to complete */
> +	wait_for_completion_timeout(&reset_wait,
> +				    msecs_to_jiffies(FNIC_HOST_RESET_TIMEOUT));
> +
> +	/* Check for status */
> +	spin_lock_irqsave(&fnic->fnic_lock, flags);
> +	fnic->reset_wait = NULL;
> +	ret = (fnic->state == FNIC_IN_ETH_MODE) ? SUCCESS : FAILED;
> +	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> +
> +	/* Now reset local port, this will clean up libFC exchanges,
> +	 * reset remote port sessions, and if link is up, begin flogi
> +	 */
> +	fc_lport_lock(lp);
> +	if (lp->tt.lport_reset(lp))
> +		ret = FAILED;


The problem here is that this only starts the login. When fnic_reset 
returns for the scsi eh path, scsi-ml is going to send a TUR to make 
sure that we are ready to go. If we are not the devices will be 
offlined. So unless it is a really quick relogin we are going to offline 
the devices by accident.

For fc_fcp.c I added a hokey loop and wait like some other drivers. We 
could instead have libfc notify any waiters of a state change here. We 
could also do a rport blocked timedout helper, convert the fc drivers 
and use it here so we only wait for the login to complete or for the 
port block to fail.




> +	fc_lport_unlock(lp);
> +
> +fnic_reset_end:
> +	printk(KERN_DEBUG DFX "Returning from fnic reset %s\n",
> +	       fnic->fnic_no, (ret == SUCCESS) ? "SUCCESS" : "FAILED");
> +
> +	return ret;
> +}
> +
> +/* SCSI Error handling calls driver's eh_host_reset if all prior
> + * error handling levels return FAILED. If host reset completes
> + * successfully, and if link is up, then Fabric login begins.
> + *
> + * Host Reset is the highest level of error recovery. If this fails, then
> + * host is offlined by SCSI.
> + *
> + */
> +int fnic_host_reset(struct scsi_cmnd *sc)
> +{
> +	return fnic_reset(sc->device->host);
> +}
> +
> +/*
> + * This fxn is called from libFC when host is removed
> + */
> +void fnic_scsi_abort_io(struct fc_lport *lp)
> +{
> +	int err = 0;
> +	unsigned long flags;
> +	enum fnic_state old_state;
> +	struct fnic *fnic = lp->drv_priv;
> +	DECLARE_COMPLETION_ONSTACK(remove_wait);
> +
> +	/* Issue firmware reset for fnic, wait for reset to complete */
> +	spin_lock_irqsave(&fnic->fnic_lock, flags);
> +	fnic->remove_wait = &remove_wait;
> +	old_state = fnic->state;
> +	fnic->state = FNIC_IN_FC_TRANS_ETH_MODE;
> +	vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr);
> +	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> +
> +	err = fnic_fw_reset_handler(fnic);
> +	if (err) {
> +		spin_lock_irqsave(&fnic->fnic_lock, flags);
> +		if (fnic->state == FNIC_IN_FC_TRANS_ETH_MODE)
> +			fnic->state = old_state;
> +		fnic->remove_wait = NULL;
> +		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> +		goto abort_io_end;
> +	}
> +
> +	/* Wait for firmware reset to complete */
> +	wait_for_completion_timeout(&remove_wait,
> +				    msecs_to_jiffies(FNIC_RMDEVICE_TIMEOUT));
> +
> +	spin_lock_irqsave(&fnic->fnic_lock, flags);
> +	fnic->remove_wait = NULL;
> +	printk(KERN_DEBUG DFX "fnic_scsi_abort_io %s\n", fnic->fnic_no,
> +	       (fnic->state == FNIC_IN_ETH_MODE) ? "SUCCESS" : "FAILED");
> +	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> +
> +abort_io_end:
> +	return;
> +}
> +
> +/*
> + * This fxn called from libFC to clean up driver IO state on link down
> + */
> +void fnic_scsi_cleanup(struct fc_lport *lp)
> +{
> +	unsigned long flags;
> +	enum fnic_state old_state;
> +	struct fnic *fnic = lp->drv_priv;
> +
> +	/* issue fw reset */
> +	spin_lock_irqsave(&fnic->fnic_lock, flags);
> +	old_state = fnic->state;
> +	fnic->state = FNIC_IN_FC_TRANS_ETH_MODE;
> +	vnic_dev_del_addr(fnic->vdev, fnic->data_src_addr);
> +	spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> +
> +	if (fnic_fw_reset_handler(fnic)) {
> +		spin_lock_irqsave(&fnic->fnic_lock, flags);
> +		if (fnic->state == FNIC_IN_FC_TRANS_ETH_MODE)
> +			fnic->state = old_state;
> +		spin_unlock_irqrestore(&fnic->fnic_lock, flags);
> +	}
> +
> +}
> 
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


  reply	other threads:[~2008-08-25 18:23 UTC|newest]

Thread overview: 18+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-08-23  2:51 [RFC][PATCH 0/6] fnic: initial submission of driver for FCoE HBA jeykholt
2008-08-23  2:52 ` [RFC][PATCH 1/6] fnic: add main file with module infrastructure, etc jeykholt
2008-08-23  2:52 ` [RFC][PATCH 2/6] fnic: add fnic_scsi.c and fnic_io.h jeykholt
2008-08-25 18:22   ` Mike Christie [this message]
2008-08-25 19:15     ` James Smart
2008-08-25 19:31       ` Mike Christie
2008-08-25 19:39         ` James Smart
2008-08-25 21:01           ` Joe Eykholt
2008-08-25 21:51             ` Mike Christie
2008-08-25 21:55               ` Mike Christie
2008-08-28  1:31                 ` Abhijeet Joglekar
2008-08-25 18:41   ` Mike Christie
2008-08-25 19:17     ` James Smart
2008-08-25 19:38       ` Mike Christie
2008-08-23  2:52 ` [RFC][PATCH 3/6] fnic: Add fnic_fcs.c and fnic_attr.c jeykholt
2008-08-23  2:52 ` [RFC][PATCH 4/6] fnic: add resource, interrupt, and firmware interfaces jeykholt
2008-08-23  2:52 ` [RFC][PATCH 5/6] fnic: add queue interfaces jeykholt
2008-08-23  2:53 ` [RFC][PATCH 6/6] fnic: add Makefile, patch Kconfig, MAINTAINERS, pci_ids.h jeykholt

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=48B2F880.7080108@cs.wisc.edu \
    --to=michaelc@cs.wisc.edu \
    --cc=ajoglekar@nuovasystems.com \
    --cc=jeykholt@cisco.com \
    --cc=jre@nuovasystems.com \
    --cc=linux-scsi@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox