spin_unlock_irqrestore(io_lock, flags);
                } else {
                        spin_lock_irqsave(io_lock, flags);
-                       CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED;
+                       if (CMD_FLAGS(sc) & FNIC_DEVICE_RESET)
+                               CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED;
                        spin_unlock_irqrestore(io_lock, flags);
                }
        }
                        spin_unlock_irqrestore(io_lock, flags);
                } else {
                        spin_lock_irqsave(io_lock, flags);
-                       CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED;
+                       if (CMD_FLAGS(sc) & FNIC_DEVICE_RESET)
+                               CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED;
                        spin_unlock_irqrestore(io_lock, flags);
                }
        }
 static int fnic_clean_pending_aborts(struct fnic *fnic,
                                     struct scsi_cmnd *lr_sc)
 {
-       int tag;
+       int tag, abt_tag;
        struct fnic_io_req *io_req;
        spinlock_t *io_lock;
        unsigned long flags;
        struct scsi_lun fc_lun;
        struct scsi_device *lun_dev = lr_sc->device;
        DECLARE_COMPLETION_ONSTACK(tm_done);
+       enum fnic_ioreq_state old_ioreq_state;
 
        for (tag = 0; tag < FNIC_MAX_IO_REQ; tag++) {
                sc = scsi_host_find_tag(fnic->lport->host, tag);
                              "Found IO in %s on lun\n",
                              fnic_ioreq_state_to_str(CMD_STATE(sc)));
 
-               BUG_ON(CMD_STATE(sc) != FNIC_IOREQ_ABTS_PENDING);
+               if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) {
+                       spin_unlock_irqrestore(io_lock, flags);
+                       continue;
+               }
+               if ((CMD_FLAGS(sc) & FNIC_DEVICE_RESET) &&
+                       (!(CMD_FLAGS(sc) & FNIC_DEV_RST_PENDING))) {
+                       FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
+                               "%s dev rst not pending sc 0x%p\n", __func__,
+                               sc);
+                       spin_unlock_irqrestore(io_lock, flags);
+                       continue;
+               }
+               old_ioreq_state = CMD_STATE(sc);
+               /*
+                * Any pending IO issued prior to reset is expected to be
+                * in abts pending state, if not we need to set
+                * FNIC_IOREQ_ABTS_PENDING to indicate the IO is abort pending.
+                * When IO is completed, the IO will be handed over and
+                * handled in this function.
+                */
+               CMD_STATE(sc) = FNIC_IOREQ_ABTS_PENDING;
+
+               if (io_req->abts_done)
+                       shost_printk(KERN_ERR, fnic->lport->host,
+                         "%s: io_req->abts_done is set state is %s\n",
+                         __func__, fnic_ioreq_state_to_str(CMD_STATE(sc)));
+
+               BUG_ON(io_req->abts_done);
+
+               abt_tag = tag;
+               if (CMD_FLAGS(sc) & FNIC_DEVICE_RESET) {
+                       abt_tag |= FNIC_TAG_DEV_RST;
+                       FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
+                                 "%s: dev rst sc 0x%p\n", __func__, sc);
+               }
 
                CMD_ABTS_STATUS(sc) = FCPIO_INVALID_CODE;
                io_req->abts_done = &tm_done;
                /* Now queue the abort command to firmware */
                int_to_scsilun(sc->device->lun, &fc_lun);
 
-               if (fnic_queue_abort_io_req(fnic, tag,
+               if (fnic_queue_abort_io_req(fnic, abt_tag,
                                            FCPIO_ITMF_ABT_TASK_TERM,
                                            fc_lun.scsi_lun, io_req)) {
                        spin_lock_irqsave(io_lock, flags);
                        io_req = (struct fnic_io_req *)CMD_SP(sc);
                        if (io_req)
                                io_req->abts_done = NULL;
+                       if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING)
+                               CMD_STATE(sc) = old_ioreq_state;
                        spin_unlock_irqrestore(io_lock, flags);
                        ret = 1;
                        goto clean_pending_aborts_end;
+               } else {
+                       spin_lock_irqsave(io_lock, flags);
+                       if (CMD_FLAGS(sc) & FNIC_DEVICE_RESET)
+                               CMD_FLAGS(sc) |= FNIC_DEV_RST_TERM_ISSUED;
+                       spin_unlock_irqrestore(io_lock, flags);
                }
 
                wait_for_completion_timeout(&tm_done,
                io_req = (struct fnic_io_req *)CMD_SP(sc);
                if (!io_req) {
                        spin_unlock_irqrestore(io_lock, flags);
-                       ret = 1;
-                       goto clean_pending_aborts_end;
+                       continue;
                }
 
                io_req->abts_done = NULL;
                mempool_free(io_req, fnic->io_req_pool);
        }
 
+       schedule_timeout(msecs_to_jiffies(2 * fnic->config.ed_tov));
+
+       /* walk again to check, if IOs are still pending in fw */
+       if (fnic_is_abts_pending(fnic, lr_sc))
+               ret = FAILED;
+
 clean_pending_aborts_end:
        return ret;
 }
        fc_exch_mgr_reset(lp, sid, did);
 
 }
+
+/*
+ * fnic_is_abts_pending() is a helper function that
+ * walks through tag map to check if there is any IOs pending,if there is one,
+ * then it returns 1 (true), otherwise 0 (false)
+ * if @lr_sc is non NULL, then it checks IOs specific to particular LUN,
+ * otherwise, it checks for all IOs.
+ */
+int fnic_is_abts_pending(struct fnic *fnic, struct scsi_cmnd *lr_sc)
+{
+       int tag;
+       struct fnic_io_req *io_req;
+       spinlock_t *io_lock;
+       unsigned long flags;
+       int ret = 0;
+       struct scsi_cmnd *sc;
+       struct scsi_device *lun_dev = NULL;
+
+       if (lr_sc)
+               lun_dev = lr_sc->device;
+
+       /* walk again to check, if IOs are still pending in fw */
+       for (tag = 0; tag < FNIC_MAX_IO_REQ; tag++) {
+               sc = scsi_host_find_tag(fnic->lport->host, tag);
+               /*
+                * ignore this lun reset cmd or cmds that do not belong to
+                * this lun
+                */
+               if (!sc || (lr_sc && (sc->device != lun_dev || sc == lr_sc)))
+                       continue;
+
+               io_lock = fnic_io_lock_hash(fnic, sc);
+               spin_lock_irqsave(io_lock, flags);
+
+               io_req = (struct fnic_io_req *)CMD_SP(sc);
+
+               if (!io_req || sc->device != lun_dev) {
+                       spin_unlock_irqrestore(io_lock, flags);
+                       continue;
+               }
+
+               /*
+                * Found IO that is still pending with firmware and
+                * belongs to the LUN that we are resetting
+                */
+               FNIC_SCSI_DBG(KERN_INFO, fnic->lport->host,
+                             "Found IO in %s on lun\n",
+                             fnic_ioreq_state_to_str(CMD_STATE(sc)));
+
+               if (CMD_STATE(sc) == FNIC_IOREQ_ABTS_PENDING) {
+                       spin_unlock_irqrestore(io_lock, flags);
+                       ret = 1;
+                       continue;
+               }
+       }
+
+       return ret;
+}