diff mbox series

[RFC,v3,28/41] megaraid_sas: use scsi_host_busy_iter to traverse outstanding commands

Message ID 20200430131904.5847-29-hare@suse.de (mailing list archive)
State Changes Requested
Headers show
Series scsi: enable reserved commands for LLDDs | expand

Commit Message

Hannes Reinecke April 30, 2020, 1:18 p.m. UTC
As the block layer now accounts for all outstanding commands we
can use scsi_host_busy_iter() to traverse all commands.

Signed-off-by: Hannes Reinecke <hare@suse.de>
---
 drivers/scsi/megaraid/megaraid_sas.h        |   1 +
 drivers/scsi/megaraid/megaraid_sas_base.c   | 265 +++++++++++++---------
 drivers/scsi/megaraid/megaraid_sas_fusion.c | 329 +++++++++++++++-------------
 3 files changed, 334 insertions(+), 261 deletions(-)
diff mbox series

Patch

diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index bb765e715011..2a089d2ba37b 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -2406,6 +2406,7 @@  struct megasas_instance {
 	struct megasas_cmd *jbod_seq_cmd;
 	unsigned long bar;
 	long reset_flags;
+	unsigned int reset_count;
 	struct mutex reset_mutex;
 	struct timer_list sriov_heartbeat_timer;
 	char skip_heartbeat_timer_del;
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 306c6495f1da..d889119e9c4d 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -1633,76 +1633,126 @@  inline int megasas_cmd_type(struct scsi_cmnd *cmd)
 	return ret;
 }
 
- /**
- * megasas_dump_pending_frames -	Dumps the frame address of all pending cmds
- *					in FW
- * @instance:				Adapter soft state
- */
-static inline void
-megasas_dump_pending_frames(struct megasas_instance *instance)
+static bool megasas_dump_scsi_frame_iter(struct scsi_cmnd *scmd, void *data,
+					 bool reserved)
 {
+	struct megasas_instance *instance = data;
 	struct megasas_cmd *cmd;
-	int i,n;
 	union megasas_sgl *mfi_sgl;
 	struct megasas_io_frame *ldio;
 	struct megasas_pthru_frame *pthru;
 	u32 sgcount;
-	u16 max_cmd = instance->max_fw_cmds;
+	u32 index = scmd->request->tag + 1;
 
-	dev_err(&instance->pdev->dev, "[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",instance->host->host_no);
-	dev_err(&instance->pdev->dev, "[%d]: Total OS Pending cmds : %d\n",instance->host->host_no,atomic_read(&instance->fw_outstanding));
-	if (IS_DMA64)
-		dev_err(&instance->pdev->dev, "[%d]: 64 bit SGLs were sent to FW\n",instance->host->host_no);
-	else
-		dev_err(&instance->pdev->dev, "[%d]: 32 bit SGLs were sent to FW\n",instance->host->host_no);
+	if (reserved)
+		return true;
 
-	dev_err(&instance->pdev->dev, "[%d]: Pending OS cmds in FW : \n",instance->host->host_no);
-	for (i = 0; i < max_cmd; i++) {
-		cmd = instance->cmd_list[i];
-		if (!cmd->scmd)
-			continue;
-		dev_err(&instance->pdev->dev, "[%d]: Frame addr :0x%08lx : ",instance->host->host_no,(unsigned long)cmd->frame_phys_addr);
-		if (megasas_cmd_type(cmd->scmd) == READ_WRITE_LDIO) {
-			ldio = (struct megasas_io_frame *)cmd->frame;
-			mfi_sgl = &ldio->sgl;
-			sgcount = ldio->sge_count;
-			dev_err(&instance->pdev->dev, "[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x,"
-			" lba lo : 0x%x, lba_hi : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",
-			instance->host->host_no, cmd->frame_count, ldio->cmd, ldio->target_id,
-			le32_to_cpu(ldio->start_lba_lo), le32_to_cpu(ldio->start_lba_hi),
+	cmd = instance->cmd_list[index];
+	dev_err(&instance->pdev->dev,
+		"[%d]: Frame addr :0x%08lx : ",
+		instance->host->host_no,
+		(unsigned long)cmd->frame_phys_addr);
+	if (megasas_cmd_type(cmd->scmd) == READ_WRITE_LDIO) {
+		ldio = (struct megasas_io_frame *)cmd->frame;
+
+		mfi_sgl = &ldio->sgl;
+		sgcount = ldio->sge_count;
+		dev_err(&instance->pdev->dev,
+			"[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x,"
+			" lba lo : 0x%x, lba_hi : 0x%x, "
+			"sense_buf addr : 0x%x, sge count : 0x%x\n",
+			instance->host->host_no, cmd->frame_count,
+			ldio->cmd, ldio->target_id,
+			le32_to_cpu(ldio->start_lba_lo),
+			le32_to_cpu(ldio->start_lba_hi),
 			le32_to_cpu(ldio->sense_buf_phys_addr_lo), sgcount);
-		} else {
-			pthru = (struct megasas_pthru_frame *) cmd->frame;
-			mfi_sgl = &pthru->sgl;
-			sgcount = pthru->sge_count;
-			dev_err(&instance->pdev->dev, "[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, "
-			"lun : 0x%x, cdb_len : 0x%x, data xfer len : 0x%x, sense_buf addr : 0x%x,sge count : 0x%x\n",
-			instance->host->host_no, cmd->frame_count, pthru->cmd, pthru->target_id,
-			pthru->lun, pthru->cdb_len, le32_to_cpu(pthru->data_xfer_len),
+	} else {
+		pthru = (struct megasas_pthru_frame *) cmd->frame;
+		mfi_sgl = &pthru->sgl;
+		sgcount = pthru->sge_count;
+		dev_err(&instance->pdev->dev,
+			"[%d]: frame count : 0x%x, Cmd : 0x%x, Tgt id : 0x%x, "
+			"lun : 0x%x, cdb_len : 0x%x, data xfer len : 0x%x, "
+			"sense_buf addr : 0x%x, sge count : 0x%x\n",
+			instance->host->host_no, cmd->frame_count,
+			pthru->cmd, pthru->target_id, pthru->lun,
+			pthru->cdb_len, le32_to_cpu(pthru->data_xfer_len),
 			le32_to_cpu(pthru->sense_buf_phys_addr_lo), sgcount);
+	}
+	if (megasas_dbg_lvl & MEGASAS_DBG_LVL) {
+		int n;
+
+		for (n = 0; n < sgcount; n++) {
+			if (IS_DMA64)
+				dev_err(&instance->pdev->dev,
+					"sgl len : 0x%x, sgl addr : 0x%llx\n",
+					le32_to_cpu(mfi_sgl->sge64[n].length),
+					le64_to_cpu(mfi_sgl->sge64[n].phys_addr));
+			else
+				dev_err(&instance->pdev->dev,
+					"sgl len : 0x%x, sgl addr : 0x%x\n",
+					le32_to_cpu(mfi_sgl->sge32[n].length),
+					le32_to_cpu(mfi_sgl->sge32[n].phys_addr));
 		}
-		if (megasas_dbg_lvl & MEGASAS_DBG_LVL) {
-			for (n = 0; n < sgcount; n++) {
-				if (IS_DMA64)
-					dev_err(&instance->pdev->dev, "sgl len : 0x%x, sgl addr : 0x%llx\n",
-						le32_to_cpu(mfi_sgl->sge64[n].length),
-						le64_to_cpu(mfi_sgl->sge64[n].phys_addr));
-				else
-					dev_err(&instance->pdev->dev, "sgl len : 0x%x, sgl addr : 0x%x\n",
-						le32_to_cpu(mfi_sgl->sge32[n].length),
-						le32_to_cpu(mfi_sgl->sge32[n].phys_addr));
-			}
-		}
-	} /*for max_cmd*/
-	dev_err(&instance->pdev->dev, "[%d]: Pending Internal cmds in FW : \n",instance->host->host_no);
-	for (i = 0; i < max_cmd; i++) {
+	}
+	return true;
+}
 
-		cmd = instance->cmd_list[i];
+static bool megasas_dump_fw_frame_iter(struct scsi_cmnd *scmd, void *data,
+				       bool reserved)
+{
+	struct megasas_instance *instance = data;
+	struct megasas_cmd *cmd;
+	u32 index = scmd->request->tag + 1;
 
-		if (cmd->sync_cmd == 1)
-			dev_err(&instance->pdev->dev, "0x%08lx : ", (unsigned long)cmd->frame_phys_addr);
-	}
-	dev_err(&instance->pdev->dev, "[%d]: Dumping Done\n\n",instance->host->host_no);
+	if (reserved)
+		return true;
+
+	cmd = instance->cmd_list[index];
+	if (cmd->sync_cmd == 1)
+		dev_err(&instance->pdev->dev,
+			"[%d]: Frame addr :0x%08lx : ",
+			instance->host->host_no,
+			(unsigned long)cmd->frame_phys_addr);
+	return true;
+}
+
+/**
+ * megasas_dump_pending_frames -	Dumps the frame address of all pending cmds
+ *					in FW
+ * @instance:				Adapter soft state
+ */
+static inline void
+megasas_dump_pending_frames(struct megasas_instance *instance)
+{
+	dev_err(&instance->pdev->dev,
+		"[%d]: Dumping Frame Phys Address of all pending cmds in FW\n",
+		instance->host->host_no);
+	dev_err(&instance->pdev->dev, "[%d]: Total OS Pending cmds : %d\n",
+		instance->host->host_no,
+		atomic_read(&instance->fw_outstanding));
+	if (IS_DMA64)
+		dev_err(&instance->pdev->dev,
+			"[%d]: 64 bit SGLs were sent to FW\n",
+			instance->host->host_no);
+	else
+		dev_err(&instance->pdev->dev,
+			"[%d]: 32 bit SGLs were sent to FW\n",
+			instance->host->host_no);
+
+	dev_err(&instance->pdev->dev,
+		"[%d]: Pending OS cmds in FW : \n",
+		instance->host->host_no);
+	scsi_host_busy_iter(instance->host, megasas_dump_scsi_frame_iter,
+			    instance);
+
+	dev_err(&instance->pdev->dev,
+		"[%d]: Pending Internal cmds in FW : \n",
+		instance->host->host_no);
+	scsi_host_busy_iter(instance->host, megasas_dump_fw_frame_iter,
+			    instance);
+	dev_err(&instance->pdev->dev,
+		"[%d]: Dumping Done\n\n", instance->host->host_no);
 }
 
 u32
@@ -2106,6 +2156,24 @@  static void megasas_slave_destroy(struct scsi_device *sdev)
 	sdev->hostdata = NULL;
 }
 
+static bool megasas_complete_cmd_iter(struct scsi_cmnd *scmd,
+				      void *data, bool reserved)
+{
+	struct megasas_instance *instance = data;
+	struct megasas_cmd *cmd_mfi;
+	u32 index = scmd->request->tag + 1;
+
+	cmd_mfi = instance->cmd_list[index];
+	if (cmd_mfi->sync_cmd &&
+	    cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT) {
+		if (instance->ctrl_context)
+			cmd_mfi->frame->hdr.cmd_status =
+				MFI_STAT_WRONG_STATE;
+		megasas_complete_cmd(instance, cmd_mfi, DID_OK);
+	}
+	return true;
+}
+
 /*
 * megasas_complete_outstanding_ioctls - Complete outstanding ioctls after a
 *                                       kill adapter
@@ -2114,34 +2182,9 @@  static void megasas_slave_destroy(struct scsi_device *sdev)
 */
 static void megasas_complete_outstanding_ioctls(struct megasas_instance *instance)
 {
-	int i;
-	struct megasas_cmd *cmd_mfi;
-	struct megasas_cmd_fusion *cmd_fusion;
-	struct fusion_context *fusion = instance->ctrl_context;
-
 	/* Find all outstanding ioctls */
-	if (fusion) {
-		for (i = 0; i < instance->max_fw_cmds; i++) {
-			cmd_fusion = fusion->cmd_list[i];
-			if (i < instance->max_mfi_cmds) {
-				cmd_mfi = instance->cmd_list[i];
-				if (cmd_mfi->sync_cmd &&
-				    (cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT)) {
-					cmd_mfi->frame->hdr.cmd_status =
-							MFI_STAT_WRONG_STATE;
-					megasas_complete_cmd(instance,
-							     cmd_mfi, DID_OK);
-				}
-			}
-		}
-	} else {
-		for (i = 0; i < instance->max_fw_cmds; i++) {
-			cmd_mfi = instance->cmd_list[i];
-			if (cmd_mfi->sync_cmd && cmd_mfi->frame->hdr.cmd !=
-				MFI_CMD_ABORT)
-				megasas_complete_cmd(instance, cmd_mfi, DID_OK);
-		}
-	}
+	scsi_host_busy_iter(instance->host, megasas_complete_cmd_iter,
+			    instance);
 }
 
 
@@ -3759,6 +3802,33 @@  megasas_issue_pending_cmds_again(struct megasas_instance *instance)
 	megasas_register_aen(instance, seq_num, class_locale.word);
 }
 
+static bool
+megasas_reset_defer_cmds_iter(struct scsi_cmnd *scmd, void *data, bool rsvd)
+{
+	struct megasas_instance *instance = data;
+	struct megasas_cmd *cmd;
+	u32 index = scmd->request->tag + 1;
+
+	cmd = instance->cmd_list[index];
+	if (cmd->sync_cmd == 1 || cmd->scmd) {
+		dev_notice(&instance->pdev->dev, "moving cmd[%d]:%p:%d:%p"
+			   "on the defer queue as internal\n",
+			   index, cmd, cmd->sync_cmd, cmd->scmd);
+
+		if (!list_empty(&cmd->list)) {
+			dev_notice(&instance->pdev->dev, "ERROR while"
+				   " moving this cmd:%p, %d %p, it was"
+				   "discovered on some list?\n",
+				   cmd, cmd->sync_cmd, cmd->scmd);
+
+			list_del_init(&cmd->list);
+		}
+		list_add_tail(&cmd->list,
+			      &instance->internal_reset_pending_q);
+	}
+	return true;
+}
+
 /**
  * Move the internal reset pending commands to a deferred queue.
  *
@@ -3771,34 +3841,11 @@  megasas_issue_pending_cmds_again(struct megasas_instance *instance)
 static void
 megasas_internal_reset_defer_cmds(struct megasas_instance *instance)
 {
-	struct megasas_cmd *cmd;
-	int i;
-	u16 max_cmd = instance->max_fw_cmds;
-	u32 defer_index;
 	unsigned long flags;
 
-	defer_index = 0;
 	spin_lock_irqsave(&instance->mfi_pool_lock, flags);
-	for (i = 0; i < max_cmd; i++) {
-		cmd = instance->cmd_list[i];
-		if (cmd->sync_cmd == 1 || cmd->scmd) {
-			dev_notice(&instance->pdev->dev, "moving cmd[%d]:%p:%d:%p"
-					"on the defer queue as internal\n",
-				defer_index, cmd, cmd->sync_cmd, cmd->scmd);
-
-			if (!list_empty(&cmd->list)) {
-				dev_notice(&instance->pdev->dev, "ERROR while"
-					" moving this cmd:%p, %d %p, it was"
-					"discovered on some list?\n",
-					cmd, cmd->sync_cmd, cmd->scmd);
-
-				list_del_init(&cmd->list);
-			}
-			defer_index++;
-			list_add_tail(&cmd->list,
-				&instance->internal_reset_pending_q);
-		}
-	}
+	scsi_host_busy_iter(instance->host, megasas_reset_defer_cmds_iter,
+			    instance);
 	spin_unlock_irqrestore(&instance->mfi_pool_lock, flags);
 }
 
diff --git a/drivers/scsi/megaraid/megaraid_sas_fusion.c b/drivers/scsi/megaraid/megaraid_sas_fusion.c
index 6c62c7f647f2..413890ef52ce 100644
--- a/drivers/scsi/megaraid/megaraid_sas_fusion.c
+++ b/drivers/scsi/megaraid/megaraid_sas_fusion.c
@@ -4227,96 +4227,122 @@  void  megasas_reset_reply_desc(struct megasas_instance *instance)
 }
 
 /*
- * megasas_refire_mgmt_cmd :	Re-fire management commands
- * @instance:				Controller's soft instance
-*/
-static void megasas_refire_mgmt_cmd(struct megasas_instance *instance,
-			     bool return_ioctl)
+ * Re-fire management commands.
+ * Do not traverse complet MPT frame pool, only the MFI frame pool.
+ */
+static bool megasas_refire_mgmt_cmd_iter(struct scsi_cmnd *scmd,
+					 void *data, bool reserved)
 {
-	int j;
-	struct megasas_cmd_fusion *cmd_fusion;
-	struct fusion_context *fusion;
 	struct megasas_cmd *cmd_mfi;
+	struct megasas_instance *instance = data;
 	union MEGASAS_REQUEST_DESCRIPTOR_UNION *req_desc;
 	u16 smid;
 	bool refire_cmd = 0;
 	u8 result;
 	u32 opcode = 0;
 
-	fusion = instance->ctrl_context;
-
-	/* Re-fire management commands.
-	 * Do not traverse complete MPT frame pool, only the MFI frame pool.
-	 */
-	for (j = 0; j < instance->max_mfi_cmds; j++) {
-		cmd_fusion = fusion->cmd_list[j];
-		cmd_mfi = instance->cmd_list[j];
-		smid = le16_to_cpu(cmd_mfi->context.smid);
-		result = REFIRE_CMD;
+	if (!reserved)
+		return true;
 
-		if (!smid)
-			continue;
+	cmd_mfi = instance->cmd_list[scmd->request->tag];
+	smid = le16_to_cpu(cmd_mfi->context.smid);
+	result = REFIRE_CMD;
 
-		req_desc = megasas_get_request_descriptor(instance, smid - 1);
-
-		switch (cmd_mfi->frame->hdr.cmd) {
-		case MFI_CMD_DCMD:
-			opcode = le32_to_cpu(cmd_mfi->frame->dcmd.opcode);
-			 /* Do not refire shutdown command */
-			if (opcode == MR_DCMD_CTRL_SHUTDOWN) {
-				cmd_mfi->frame->dcmd.cmd_status = MFI_STAT_OK;
-				result = COMPLETE_CMD;
-				break;
-			}
+	if (!smid)
+		return true;
 
-			refire_cmd = ((opcode != MR_DCMD_LD_MAP_GET_INFO)) &&
-				      (opcode != MR_DCMD_SYSTEM_PD_MAP_GET_INFO) &&
-				      !(cmd_mfi->flags & DRV_DCMD_SKIP_REFIRE);
+	req_desc = megasas_get_request_descriptor(instance, smid - 1);
 
-			if (!refire_cmd)
-				result = RETURN_CMD;
+	switch (cmd_mfi->frame->hdr.cmd) {
+	case MFI_CMD_DCMD:
+		opcode = le32_to_cpu(cmd_mfi->frame->dcmd.opcode);
+		/* Do not refire shutdown command */
+		if (opcode == MR_DCMD_CTRL_SHUTDOWN) {
+			cmd_mfi->frame->dcmd.cmd_status = MFI_STAT_OK;
+			result = COMPLETE_CMD;
+			return true;
+		}
 
-			break;
-		case MFI_CMD_NVME:
-			if (!instance->support_nvme_passthru) {
-				cmd_mfi->frame->hdr.cmd_status = MFI_STAT_INVALID_CMD;
-				result = COMPLETE_CMD;
-			}
+		refire_cmd = ((opcode != MR_DCMD_LD_MAP_GET_INFO)) &&
+			(opcode != MR_DCMD_SYSTEM_PD_MAP_GET_INFO) &&
+			!(cmd_mfi->flags & DRV_DCMD_SKIP_REFIRE);
 
-			break;
-		case MFI_CMD_TOOLBOX:
-			if (!instance->support_pci_lane_margining) {
-				cmd_mfi->frame->hdr.cmd_status = MFI_STAT_INVALID_CMD;
-				result = COMPLETE_CMD;
-			}
+		if (!refire_cmd)
+			result = RETURN_CMD;
 
-			break;
-		default:
-			break;
+		break;
+	case MFI_CMD_NVME:
+		if (!instance->support_nvme_passthru) {
+			cmd_mfi->frame->hdr.cmd_status = MFI_STAT_INVALID_CMD;
+			result = COMPLETE_CMD;
 		}
 
-		if (return_ioctl && cmd_mfi->sync_cmd &&
-		    cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT) {
-			dev_err(&instance->pdev->dev,
-				"return -EBUSY from %s %d cmd 0x%x opcode 0x%x\n",
-				__func__, __LINE__, cmd_mfi->frame->hdr.cmd,
-				le32_to_cpu(cmd_mfi->frame->dcmd.opcode));
-			cmd_mfi->cmd_status_drv = DCMD_BUSY;
+		break;
+	case MFI_CMD_TOOLBOX:
+		if (!instance->support_pci_lane_margining) {
+			cmd_mfi->frame->hdr.cmd_status = MFI_STAT_INVALID_CMD;
 			result = COMPLETE_CMD;
 		}
 
-		switch (result) {
-		case REFIRE_CMD:
-			megasas_fire_cmd_fusion(instance, req_desc);
-			break;
-		case RETURN_CMD:
-			megasas_return_cmd(instance, cmd_mfi);
-			break;
-		case COMPLETE_CMD:
-			megasas_complete_cmd(instance, cmd_mfi, DID_OK);
-			break;
-		}
+		break;
+	default:
+		break;
+	}
+
+	if (!instance->reset_count && cmd_mfi->sync_cmd &&
+	    cmd_mfi->frame->hdr.cmd != MFI_CMD_ABORT) {
+		dev_err(&instance->pdev->dev,
+			"return -EBUSY from %s %d cmd 0x%x opcode 0x%x\n",
+			__func__, __LINE__, cmd_mfi->frame->hdr.cmd,
+			le32_to_cpu(cmd_mfi->frame->dcmd.opcode));
+		cmd_mfi->cmd_status_drv = DCMD_BUSY;
+		result = COMPLETE_CMD;
+	}
+
+	switch (result) {
+	case REFIRE_CMD:
+		megasas_fire_cmd_fusion(instance, req_desc);
+		break;
+	case RETURN_CMD:
+		megasas_return_cmd(instance, cmd_mfi);
+		break;
+	case COMPLETE_CMD:
+		megasas_complete_cmd(instance, cmd_mfi, DID_OK);
+		break;
+	}
+	return true;
+}
+
+/*
+ * megasas_refire_mgmt_cmd :	Re-fire management commands
+ * @instance:				Controller's soft instance
+*/
+static void megasas_refire_mgmt_cmd(struct megasas_instance *instance)
+{
+	scsi_host_busy_iter(instance->host, megasas_refire_mgmt_cmd_iter,
+			    instance);
+}
+
+static bool megasas_polled_cmds_iter(struct scsi_cmnd *scmd, void *data,
+				     bool reserved)
+{
+	struct megasas_instance *instance = data;
+	u32 index = scmd->request->tag;
+	struct megasas_cmd *cmd_mfi;
+
+	if (!reserved)
+		return true;
+	cmd_mfi = instance->cmd_list[index];
+	if (cmd_mfi->flags & DRV_DCMD_POLLED_MODE) {
+		if (megasas_dbg_lvl & OCR_DEBUG)
+			dev_info(&instance->pdev->dev,
+				 "%s %d return cmd 0x%x opcode 0x%x\n",
+				 __func__, __LINE__, cmd_mfi->frame->hdr.cmd,
+				 le32_to_cpu(cmd_mfi->frame->dcmd.opcode));
+		cmd_mfi->flags &= ~DRV_DCMD_POLLED_MODE;
+		megasas_return_cmd(instance, cmd_mfi);
 	}
+	return true;
 }
 
 /*
@@ -4327,27 +4353,36 @@  static void megasas_refire_mgmt_cmd(struct megasas_instance *instance,
 static void
 megasas_return_polled_cmds(struct megasas_instance *instance)
 {
-	int i;
-	struct megasas_cmd_fusion *cmd_fusion;
-	struct fusion_context *fusion;
-	struct megasas_cmd *cmd_mfi;
-
-	fusion = instance->ctrl_context;
+	scsi_host_busy_iter(instance->host, megasas_polled_cmds_iter, instance);
+}
 
-	for (i = 0; i < instance->max_mfi_cmds; i++) {
-		cmd_fusion = fusion->cmd_list[i];
-		cmd_mfi = instance->cmd_list[i];
+struct megasas_track_scsiio_data {
+	struct megasas_instance *instance;
+	unsigned int id;
+	unsigned int channel;
+	bool io_pending;
+};
 
-		if (cmd_mfi->flags & DRV_DCMD_POLLED_MODE) {
-			if (megasas_dbg_lvl & OCR_DEBUG)
-				dev_info(&instance->pdev->dev,
-					 "%s %d return cmd 0x%x opcode 0x%x\n",
-					 __func__, __LINE__, cmd_mfi->frame->hdr.cmd,
-					 le32_to_cpu(cmd_mfi->frame->dcmd.opcode));
-			cmd_mfi->flags &= ~DRV_DCMD_POLLED_MODE;
-			megasas_return_cmd(instance, cmd_mfi);
-		}
+static bool megasas_track_scsiio_iter(struct scsi_cmnd *scmd, void *data,
+				      bool reserved)
+{
+	struct megasas_track_scsiio_data *iter_data = data;
+	u32 index = scmd->request->tag;
+
+	if (reserved)
+		return true;
+
+	if (scmd->device->id == iter_data->id &&
+	    scmd->device->channel == iter_data->channel) {
+		dev_info(&iter_data->instance->pdev->dev,
+			 "SCSI commands pending to target"
+			 "channel %d id %d \tSMID: 0x%x\n",
+			 iter_data->channel, iter_data->id, index);
+		scsi_print_command(scmd);
+		iter_data->io_pending = true;
+		return false;
 	}
+	return true;
 }
 
 /*
@@ -4362,27 +4397,16 @@  megasas_return_polled_cmds(struct megasas_instance *instance)
 static int megasas_track_scsiio(struct megasas_instance *instance,
 		int id, int channel)
 {
-	int i, found = 0;
-	struct megasas_cmd_fusion *cmd_fusion;
-	struct fusion_context *fusion;
-	fusion = instance->ctrl_context;
-
-	for (i = instance->max_mfi_cmds; i < instance->max_fw_cmds; i++) {
-		cmd_fusion = fusion->cmd_list[i];
-		if (cmd_fusion->scmd &&
-			(cmd_fusion->scmd->device->id == id &&
-			cmd_fusion->scmd->device->channel == channel)) {
-			dev_info(&instance->pdev->dev,
-				"SCSI commands pending to target"
-				"channel %d id %d \tSMID: 0x%x\n",
-				channel, id, cmd_fusion->index);
-			scsi_print_command(cmd_fusion->scmd);
-			found = 1;
-			break;
-		}
-	}
-
-	return found ? FAILED : SUCCESS;
+	struct megasas_track_scsiio_data iter_data = {
+		.instance = instance,
+		.id = id,
+		.channel = channel,
+		.io_pending = false,
+	};
+
+	scsi_host_busy_iter(instance->host, megasas_track_scsiio_iter,
+			    &iter_data);
+	return iter_data.io_pending ? FAILED : SUCCESS;
 }
 
 /**
@@ -4804,24 +4828,58 @@  int megasas_check_mpio_paths(struct megasas_instance *instance,
 	return retval;
 }
 
+static bool megasas_return_cmd_iter(struct scsi_cmnd *scmd, void *data,
+				    bool reserved)
+{
+	struct megasas_instance *instance = data;
+	struct fusion_context *fusion = instance->ctrl_context;
+	struct megasas_cmd_fusion *cmd_fusion;
+	u32 index = scmd->request->tag;
+
+	if (reserved)
+		return true;
+
+	cmd_fusion = fusion->cmd_list[index];
+	/* check for extra commands issued by driver*/
+	if (instance->adapter_type >= VENTURA_SERIES) {
+		struct megasas_cmd_fusion *r1_cmd;
+
+		r1_cmd = fusion->cmd_list[index + instance->max_fw_cmds];
+		megasas_return_cmd_fusion(instance, r1_cmd);
+	}
+	if (megasas_dbg_lvl & OCR_DEBUG) {
+		sdev_printk(KERN_INFO,
+			    scmd->device, "SMID: 0x%x\n",
+			    cmd_fusion->index);
+		megasas_dump_fusion_io(scmd);
+	}
+
+	scmd->result = megasas_check_mpio_paths(instance, scmd);
+	if (instance->ldio_threshold &&
+	    megasas_cmd_type(scmd) == READ_WRITE_LDIO)
+		atomic_dec(&instance->ldio_outstanding);
+	megasas_return_cmd_fusion(instance, cmd_fusion);
+	scsi_dma_unmap(scmd);
+	scmd->scsi_done(scmd);
+	return true;
+}
+
 /* Core fusion reset function */
 int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
 {
-	int retval = SUCCESS, i, j, convert = 0;
+	int retval = SUCCESS, j, convert = 0;
 	struct megasas_instance *instance;
-	struct megasas_cmd_fusion *cmd_fusion, *r1_cmd;
 	struct fusion_context *fusion;
-	u32 abs_state, status_reg, reset_adapter, fpio_count = 0;
+	u32 abs_state, status_reg, reset_adapter;
 	u32 io_timeout_in_crash_mode = 0;
-	struct scsi_cmnd *scmd_local = NULL;
 	struct scsi_device *sdev;
 	int ret_target_prop = DCMD_FAILED;
 	bool is_target_prop = false;
 	bool do_adp_reset = true;
-	int max_reset_tries = MEGASAS_FUSION_MAX_RESET_TRIES;
 
 	instance = (struct megasas_instance *)shost->hostdata;
 	fusion = instance->ctrl_context;
+	instance->reset_count = MEGASAS_FUSION_MAX_RESET_TRIES;
 
 	mutex_lock(&instance->reset_mutex);
 
@@ -4890,40 +4948,8 @@  int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
 			dev_info(&instance->pdev->dev, "\nPending SCSI commands:\n");
 
 		/* Now return commands back to the OS */
-		for (i = instance->max_mfi_cmds; i < instance->max_fw_cmds; i++) {
-			cmd_fusion = fusion->cmd_list[i];
-			/*check for extra commands issued by driver*/
-			if (instance->adapter_type >= VENTURA_SERIES) {
-				r1_cmd = fusion->cmd_list[i + instance->max_fw_cmds];
-				megasas_return_cmd_fusion(instance, r1_cmd);
-			}
-			scmd_local = cmd_fusion->scmd;
-			if (cmd_fusion->scmd) {
-				if (megasas_dbg_lvl & OCR_DEBUG) {
-					sdev_printk(KERN_INFO,
-						cmd_fusion->scmd->device, "SMID: 0x%x\n",
-						cmd_fusion->index);
-					megasas_dump_fusion_io(cmd_fusion->scmd);
-				}
-
-				if (cmd_fusion->io_request->Function ==
-					MPI2_FUNCTION_SCSI_IO_REQUEST)
-					fpio_count++;
-
-				scmd_local->result =
-					megasas_check_mpio_paths(instance,
-							scmd_local);
-				if (instance->ldio_threshold &&
-					megasas_cmd_type(scmd_local) == READ_WRITE_LDIO)
-					atomic_dec(&instance->ldio_outstanding);
-				megasas_return_cmd_fusion(instance, cmd_fusion);
-				scsi_dma_unmap(scmd_local);
-				scmd_local->scsi_done(scmd_local);
-			}
-		}
-
-		dev_info(&instance->pdev->dev, "Outstanding fastpath IOs: %d\n",
-			fpio_count);
+		scsi_host_busy_iter(instance->host, megasas_return_cmd_iter,
+				    instance);
 
 		atomic_set(&instance->fw_outstanding, 0);
 
@@ -4943,11 +4969,12 @@  int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
 		if (instance->requestorId && !reason) {
 			msleep(MEGASAS_OCR_SETTLE_TIME_VF);
 			do_adp_reset = false;
-			max_reset_tries = MEGASAS_SRIOV_MAX_RESET_TRIES_VF;
+			instance->reset_count = MEGASAS_SRIOV_MAX_RESET_TRIES_VF;
 		}
 
 		/* Now try to reset the chip */
-		for (i = 0; i < max_reset_tries; i++) {
+		while (instance->reset_count) {
+			instance->reset_count--;
 			/*
 			 * Do adp reset and wait for
 			 * controller to transition to ready
@@ -4977,9 +5004,7 @@  int megasas_reset_fusion(struct Scsi_Host *shost, int reason)
 				goto kill_hba;
 			}
 
-			megasas_refire_mgmt_cmd(instance,
-						(i == (MEGASAS_FUSION_MAX_RESET_TRIES - 1)
-							? 1 : 0));
+			megasas_refire_mgmt_cmd(instance);
 
 			/* Reset load balance info */
 			if (fusion->load_balance_info)