OSDN Git Service

fnic: Cleanup the I/O pending with fw and has timed out and is used to issue LUN...
authorSatish Kharat <satishkh@cisco.com>
Fri, 18 Mar 2016 18:22:49 +0000 (11:22 -0700)
committerMartin K. Petersen <martin.petersen@oracle.com>
Mon, 11 Apr 2016 20:57:09 +0000 (16:57 -0400)
In case of LUN reset, the device reset command is issued with one of the
I/Os that has timed out on that LUN. The change is to also return this
I/O with error status set to DID_RESET. In case when the reset is issued
using the sg_reset tool (from sg3_utils) it is a new command and new_sc
is set to 1.  Fnic driver version changed from 1.6.0.19 to 1.6.0.20

[mkp: Fixed checkpatch warning]

Signed-off-by: Satish Kharat <satishkh@cisco.com>
Signed-off-by: Sesidhar Baddela <sebaddel@cisco.com>
Reviewed-by: Ewan Milne <emilne@redhat.com>
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
drivers/scsi/fnic/fnic.h
drivers/scsi/fnic/fnic_scsi.c

index 52a53f8..1023eae 100644 (file)
@@ -39,7 +39,7 @@
 
 #define DRV_NAME               "fnic"
 #define DRV_DESCRIPTION                "Cisco FCoE HBA Driver"
-#define DRV_VERSION            "1.6.0.19"
+#define DRV_VERSION            "1.6.0.20"
 #define PFX                    DRV_NAME ": "
 #define DFX                     DRV_NAME "%d: "
 
index 01b480d..588ffd9 100644 (file)
@@ -2039,7 +2039,9 @@ lr_io_req_end:
  * successfully aborted, 1 otherwise
  */
 static int fnic_clean_pending_aborts(struct fnic *fnic,
-                                    struct scsi_cmnd *lr_sc)
+                                    struct scsi_cmnd *lr_sc,
+                                        bool new_sc)
+
 {
        int tag, abt_tag;
        struct fnic_io_req *io_req;
@@ -2057,10 +2059,10 @@ static int fnic_clean_pending_aborts(struct fnic *fnic,
                spin_lock_irqsave(io_lock, flags);
                sc = scsi_host_find_tag(fnic->lport->host, tag);
                /*
-                * ignore this lun reset cmd or cmds that do not belong to
-                * this lun
+                * ignore this lun reset cmd if issued using new SC
+                * or cmds that do not belong to this lun
                 */
-               if (!sc || sc == lr_sc || sc->device != lun_dev) {
+               if (!sc || ((sc == lr_sc) && new_sc) || sc->device != lun_dev) {
                        spin_unlock_irqrestore(io_lock, flags);
                        continue;
                }
@@ -2166,11 +2168,27 @@ static int fnic_clean_pending_aborts(struct fnic *fnic,
                        goto clean_pending_aborts_end;
                }
                CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE;
-               CMD_SP(sc) = NULL;
+
+               /* original sc used for lr is handled by dev reset code */
+               if (sc != lr_sc)
+                       CMD_SP(sc) = NULL;
                spin_unlock_irqrestore(io_lock, flags);
 
-               fnic_release_ioreq_buf(fnic, io_req, sc);
-               mempool_free(io_req, fnic->io_req_pool);
+               /* original sc used for lr is handled by dev reset code */
+               if (sc != lr_sc) {
+                       fnic_release_ioreq_buf(fnic, io_req, sc);
+                       mempool_free(io_req, fnic->io_req_pool);
+               }
+
+               /*
+                * Any IO is returned during reset, it needs to call scsi_done
+                * to return the scsi_cmnd to upper layer.
+                */
+               if (sc->scsi_done) {
+                       /* Set result to let upper SCSI layer retry */
+                       sc->result = DID_RESET << 16;
+                       sc->scsi_done(sc);
+               }
        }
 
        schedule_timeout(msecs_to_jiffies(2 * fnic->config.ed_tov));
@@ -2264,6 +2282,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
        int tag = 0;
        DECLARE_COMPLETION_ONSTACK(tm_done);
        int tag_gen_flag = 0;   /*to track tags allocated by fnic driver*/
+       bool new_sc = 0;
 
        /* Wait for rport to unblock */
        fc_block_scsi_eh(sc);
@@ -2309,13 +2328,12 @@ int fnic_device_reset(struct scsi_cmnd *sc)
                 * fix the way the EH ioctls work for real, but until
                 * that happens we fail these explicit requests here.
                 */
-               if (shost_use_blk_mq(sc->device->host))
-                       goto fnic_device_reset_end;
 
                tag = fnic_scsi_host_start_tag(fnic, sc);
                if (unlikely(tag == SCSI_NO_TAG))
                        goto fnic_device_reset_end;
                tag_gen_flag = 1;
+               new_sc = 1;
        }
        io_lock = fnic_io_lock_hash(fnic, sc);
        spin_lock_irqsave(io_lock, flags);
@@ -2450,7 +2468,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
         * the lun reset cmd. If all cmds get cleaned, the lun reset
         * succeeds
         */
-       if (fnic_clean_pending_aborts(fnic, sc)) {
+       if (fnic_clean_pending_aborts(fnic, sc, new_sc)) {
                spin_lock_irqsave(io_lock, flags);
                io_req = (struct fnic_io_req *)CMD_SP(sc);
                FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,