Commit a36f5dd0 authored by Satish Kharat's avatar Satish Kharat Committed by Martin K. Petersen

fnic: Cleanup the I/O pending with fw and has timed out and is used to issue LUN reset

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: default avatarSatish Kharat <satishkh@cisco.com>
Signed-off-by: default avatarSesidhar Baddela <sebaddel@cisco.com>
Reviewed-by: default avatarEwan Milne <emilne@redhat.com>
Signed-off-by: default avatarMartin K. Petersen <martin.petersen@oracle.com>
parent 691a837c
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
#define DRV_NAME "fnic" #define DRV_NAME "fnic"
#define DRV_DESCRIPTION "Cisco FCoE HBA Driver" #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 PFX DRV_NAME ": "
#define DFX DRV_NAME "%d: " #define DFX DRV_NAME "%d: "
......
...@@ -2039,7 +2039,9 @@ static inline int fnic_queue_dr_io_req(struct fnic *fnic, ...@@ -2039,7 +2039,9 @@ static inline int fnic_queue_dr_io_req(struct fnic *fnic,
* successfully aborted, 1 otherwise * successfully aborted, 1 otherwise
*/ */
static int fnic_clean_pending_aborts(struct fnic *fnic, 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; int tag, abt_tag;
struct fnic_io_req *io_req; struct fnic_io_req *io_req;
...@@ -2057,10 +2059,10 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, ...@@ -2057,10 +2059,10 @@ static int fnic_clean_pending_aborts(struct fnic *fnic,
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
sc = scsi_host_find_tag(fnic->lport->host, tag); sc = scsi_host_find_tag(fnic->lport->host, tag);
/* /*
* ignore this lun reset cmd or cmds that do not belong to * ignore this lun reset cmd if issued using new SC
* this lun * 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); spin_unlock_irqrestore(io_lock, flags);
continue; continue;
} }
...@@ -2166,11 +2168,27 @@ static int fnic_clean_pending_aborts(struct fnic *fnic, ...@@ -2166,11 +2168,27 @@ static int fnic_clean_pending_aborts(struct fnic *fnic,
goto clean_pending_aborts_end; goto clean_pending_aborts_end;
} }
CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE; 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); spin_unlock_irqrestore(io_lock, flags);
fnic_release_ioreq_buf(fnic, io_req, sc); /* original sc used for lr is handled by dev reset code */
mempool_free(io_req, fnic->io_req_pool); 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)); schedule_timeout(msecs_to_jiffies(2 * fnic->config.ed_tov));
...@@ -2264,6 +2282,7 @@ int fnic_device_reset(struct scsi_cmnd *sc) ...@@ -2264,6 +2282,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
int tag = 0; int tag = 0;
DECLARE_COMPLETION_ONSTACK(tm_done); DECLARE_COMPLETION_ONSTACK(tm_done);
int tag_gen_flag = 0; /*to track tags allocated by fnic driver*/ int tag_gen_flag = 0; /*to track tags allocated by fnic driver*/
bool new_sc = 0;
/* Wait for rport to unblock */ /* Wait for rport to unblock */
fc_block_scsi_eh(sc); fc_block_scsi_eh(sc);
...@@ -2309,13 +2328,12 @@ int fnic_device_reset(struct scsi_cmnd *sc) ...@@ -2309,13 +2328,12 @@ int fnic_device_reset(struct scsi_cmnd *sc)
* fix the way the EH ioctls work for real, but until * fix the way the EH ioctls work for real, but until
* that happens we fail these explicit requests here. * 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); tag = fnic_scsi_host_start_tag(fnic, sc);
if (unlikely(tag == SCSI_NO_TAG)) if (unlikely(tag == SCSI_NO_TAG))
goto fnic_device_reset_end; goto fnic_device_reset_end;
tag_gen_flag = 1; tag_gen_flag = 1;
new_sc = 1;
} }
io_lock = fnic_io_lock_hash(fnic, sc); io_lock = fnic_io_lock_hash(fnic, sc);
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
...@@ -2450,7 +2468,7 @@ int fnic_device_reset(struct scsi_cmnd *sc) ...@@ -2450,7 +2468,7 @@ int fnic_device_reset(struct scsi_cmnd *sc)
* the lun reset cmd. If all cmds get cleaned, the lun reset * the lun reset cmd. If all cmds get cleaned, the lun reset
* succeeds * succeeds
*/ */
if (fnic_clean_pending_aborts(fnic, sc)) { if (fnic_clean_pending_aborts(fnic, sc, new_sc)) {
spin_lock_irqsave(io_lock, flags); spin_lock_irqsave(io_lock, flags);
io_req = (struct fnic_io_req *)CMD_SP(sc); io_req = (struct fnic_io_req *)CMD_SP(sc);
FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host, FNIC_SCSI_DBG(KERN_DEBUG, fnic->lport->host,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment