Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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: "

+28 −10
Original line number Diff line number Diff line
@@ -2039,7 +2039,9 @@ static inline int fnic_queue_dr_io_req(struct fnic *fnic,
 * 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,13 +2168,29 @@ static int fnic_clean_pending_aborts(struct fnic *fnic,
			goto clean_pending_aborts_end;
		}
		CMD_STATE(sc) = FNIC_IOREQ_ABTS_COMPLETE;

		/* 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);

		/* 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));

	/* walk again to check, if IOs are still pending in fw */
@@ -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,