@@ -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;
@@ -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);
}
@@ -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)
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(-)