Merge tag 'xfs-for-linus-4.7-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git...
[cascardo/linux.git] / drivers / scsi / fnic / fnic_scsi.c
index f3032ca..d9fd2f8 100644 (file)
@@ -439,7 +439,6 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
        int sg_count = 0;
        unsigned long flags = 0;
        unsigned long ptr;
-       struct fc_rport_priv *rdata;
        spinlock_t *io_lock = NULL;
        int io_lock_acquired = 0;
 
@@ -455,14 +454,17 @@ static int fnic_queuecommand_lck(struct scsi_cmnd *sc, void (*done)(struct scsi_
                return 0;
        }
 
-       rdata = lp->tt.rport_lookup(lp, rport->port_id);
-       if (!rdata || (rdata->rp_state == RPORT_ST_DELETE)) {
-               FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
-                       "returning IO as rport is removed\n");
-               atomic64_inc(&fnic_stats->misc_stats.rport_not_ready);
-               sc->result = DID_NO_CONNECT;
-               done(sc);
-               return 0;
+       if (rport) {
+               struct fc_rport_libfc_priv *rp = rport->dd_data;
+
+               if (!rp || rp->rp_state != RPORT_ST_READY) {
+                       FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
+                               "returning DID_NO_CONNECT for IO as rport is removed\n");
+                       atomic64_inc(&fnic_stats->misc_stats.rport_not_ready);
+                       sc->result = DID_NO_CONNECT<<16;
+                       done(sc);
+                       return 0;
+               }
        }
 
        if (lp->state != LPORT_ST_READY || !(lp->link_up))
@@ -1091,6 +1093,11 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
                                atomic64_inc(
                                        &term_stats->terminate_fw_timeouts);
                        break;
+               case FCPIO_ITMF_REJECTED:
+                       FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
+                               "abort reject recd. id %d\n",
+                               (int)(id & FNIC_TAG_MASK));
+                       break;
                case FCPIO_IO_NOT_FOUND:
                        if (CMD_FLAGS(sc) & FNIC_IO_ABTS_ISSUED)
                                atomic64_inc(&abts_stats->abort_io_not_found);
@@ -1111,9 +1118,15 @@ static void fnic_fcpio_itmf_cmpl_handler(struct fnic *fnic,
                        spin_unlock_irqrestore(io_lock, flags);
                        return;
                }
-               CMD_ABTS_STATUS(sc) = hdr_status;
+
                CMD_FLAGS(sc) |= FNIC_IO_ABT_TERM_DONE;
 
+               /* If the status is IO not found consider it as success */
+               if (hdr_status == FCPIO_IO_NOT_FOUND)
+                       CMD_ABTS_STATUS(sc) = FCPIO_SUCCESS;
+               else
+                       CMD_ABTS_STATUS(sc) = hdr_status;
+
                atomic64_dec(&fnic_stats->io_stats.active_ios);
                if (atomic64_read(&fnic->io_cmpl_skip))
                        atomic64_dec(&fnic->io_cmpl_skip);
@@ -1926,21 +1939,31 @@ int fnic_abort_cmd(struct scsi_cmnd *sc)
 
        CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE;
 
+       start_time = io_req->start_time;
        /*
         * firmware completed the abort, check the status,
-        * free the io_req irrespective of failure or success
+        * free the io_req if successful. If abort fails,
+        * Device reset will clean the I/O.
         */
-       if (CMD_ABTS_STATUS(sc) != FCPIO_SUCCESS)
+       if (CMD_ABTS_STATUS(sc) == FCPIO_SUCCESS)
+               CMD_SP(sc) = NULL;
+       else {
                ret = FAILED;
-
-       CMD_SP(sc) = NULL;
+               spin_unlock_irqrestore(io_lock, flags);
+               goto fnic_abort_cmd_end;
+       }
 
        spin_unlock_irqrestore(io_lock, flags);
 
-       start_time = io_req->start_time;
        fnic_release_ioreq_buf(fnic, io_req, sc);
        mempool_free(io_req, fnic->io_req_pool);
 
+       if (sc->scsi_done) {
+       /* Call SCSI completion function to complete the IO */
+               sc->result = (DID_ABORT << 16);
+               sc->scsi_done(sc);
+       }
+
 fnic_abort_cmd_end:
        FNIC_TRACE(fnic_abort_cmd, sc->device->host->host_no,
                  sc->request->tag, sc,
@@ -2018,7 +2041,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;
@@ -2036,10 +2061,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;
                }
@@ -2145,11 +2170,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));
@@ -2243,6 +2284,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);
@@ -2288,13 +2330,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);
@@ -2429,7 +2470,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,