From: Mike Christie <[EMAIL PROTECTED]>

When fc_eh_host_reset returns success, scsi-ml will send a TUR
to check us so we must be ready to go.

This has us wait for some timeout while we try to relogin.
In the future I would like to remove the poll for
the state, and instead have the lport code notify us
but for now this is good enough.

Signed-off-by: Mike Christie <[EMAIL PROTECTED]>
---
 drivers/scsi/libfc/fc_fcp.c |   33 ++++++++++++++++++++++++---------
 1 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/scsi/libfc/fc_fcp.c b/drivers/scsi/libfc/fc_fcp.c
index 99bfadf..6b38b26 100644
--- a/drivers/scsi/libfc/fc_fcp.c
+++ b/drivers/scsi/libfc/fc_fcp.c
@@ -175,6 +175,7 @@ static void fc_fcp_srr_error(struct fc_fcp_pkt *, struct 
fc_frame *);
 #define FC_SCSI_ER_TIMEOUT     (10 * HZ)
 #define FC_SCSI_TM_TOV         (10 * HZ)
 #define FC_SCSI_REC_TOV                (2 * HZ)
+#define FC_HOST_RESET_TIMEOUT  (30 * HZ)
 
 #define FC_MAX_ERROR_CNT  5
 #define FC_MAX_RECOV_RETRY 3
@@ -1653,6 +1654,12 @@ out:
        fc_fcp_pkt_release(fsp);        /* drop hold for outstanding SRR */
 }
 
+static inline int fc_fcp_lport_queue_ready(struct fc_lport *lp)
+{
+       /* lock ? */
+       return (lp->state == LPORT_ST_READY) && (lp->link_status & FC_LINK_UP);
+}
+
 /**
  * fc_queuecommand - The queuecommand function of the scsi template
  * @cmd:       struct scsi_cmnd to be executed
@@ -1692,14 +1699,9 @@ int fc_queuecommand(struct scsi_cmnd *sc_cmd, void 
(*done)(struct scsi_cmnd *))
 
        rp = rport->dd_data;
 
-       if (lp->state != LPORT_ST_READY) {
+       if (!fc_fcp_lport_queue_ready(lp)) {
                rc = SCSI_MLQUEUE_HOST_BUSY;
                goto out;
-       } else {
-               if (!(lp->link_status & FC_LINK_UP)) {
-                       rc = SCSI_MLQUEUE_HOST_BUSY;
-                       goto out;
-               }
        }
 
        sp = fc_fcp_pkt_alloc(lp);
@@ -1987,10 +1989,23 @@ EXPORT_SYMBOL(fc_eh_device_reset);
  */
 int fc_eh_host_reset(struct scsi_cmnd *sc_cmd)
 {
-       struct fc_lport *lp;
+       struct Scsi_Host *shost = sc_cmd->device->host;
+       struct fc_lport *lp = shost_priv(shost);
+       unsigned long wait_tmo;
 
-       lp = shost_priv(sc_cmd->device->host);
-       return lp->tt.lport_reset(lp) ? FAILED : SUCCESS;
+       lp->tt.lport_reset(lp);
+       wait_tmo = jiffies + FC_HOST_RESET_TIMEOUT;
+       while (!fc_fcp_lport_queue_ready(lp) && time_before(jiffies, wait_tmo))
+               msleep(1000);
+
+       if (fc_fcp_lport_queue_ready(lp)) {
+               shost_printk(KERN_INFO, shost, "Host reset succeeded.\n");
+               return SUCCESS;
+       } else {
+               shost_printk(KERN_INFO, shost, "Host reset succeeded failed."
+                           "lport not ready.\n");
+               return FAILED;
+       }
 }
 EXPORT_SYMBOL(fc_eh_host_reset);
 
-- 
1.5.4.1

_______________________________________________
devel mailing list
[email protected]
http://www.open-fcoe.org/mailman/listinfo/devel

Reply via email to