summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShivasharan S <shivasharan.srikanteshwara@broadcom.com>2017-10-19 02:49:02 -0700
committerMartin K. Petersen <martin.petersen@oracle.com>2017-10-25 04:55:30 -0400
commit82add4e1b354f93ca4b986989a94c957cb8b06c5 (patch)
tree75e33967f803d6b66aa651ae6d713a2decba8da5
parentb9637d14dc00d91cef0068cde1f9a8959b051028 (diff)
downloadop-kernel-dev-82add4e1b354f93ca4b986989a94c957cb8b06c5.zip
op-kernel-dev-82add4e1b354f93ca4b986989a94c957cb8b06c5.tar.gz
scsi: megaraid_sas: Incorrect processing of IOCTL frames for SMP/STP commands
cmd->frame->dcmd.opcode will be valid only for MFI_CMD_DCMD IOCTL frames. Currently driver check for cmd->frame->dcmd.opcode without checking cmd type. Ensure we check dcmd opcode only for MFI_CMD_DCMD commands. Separate handling of MFI_CMD_SMP/STP commands from MFI_CMD_DCMD in completion path. Signed-off-by: Kashyap Desai <kashyap.desai@broadcom.com> Signed-off-by: Shivasharan S <shivasharan.srikanteshwara@broadcom.com> Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.h23
-rw-r--r--drivers/scsi/megaraid/megaraid_sas_base.c22
2 files changed, 31 insertions, 14 deletions
diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
index 83427b5..85ef841 100644
--- a/drivers/scsi/megaraid/megaraid_sas.h
+++ b/drivers/scsi/megaraid/megaraid_sas.h
@@ -187,16 +187,19 @@
/*
* MFI command opcodes
*/
-#define MFI_CMD_INIT 0x00
-#define MFI_CMD_LD_READ 0x01
-#define MFI_CMD_LD_WRITE 0x02
-#define MFI_CMD_LD_SCSI_IO 0x03
-#define MFI_CMD_PD_SCSI_IO 0x04
-#define MFI_CMD_DCMD 0x05
-#define MFI_CMD_ABORT 0x06
-#define MFI_CMD_SMP 0x07
-#define MFI_CMD_STP 0x08
-#define MFI_CMD_INVALID 0xff
+enum MFI_CMD_OP {
+ MFI_CMD_INIT = 0x0,
+ MFI_CMD_LD_READ = 0x1,
+ MFI_CMD_LD_WRITE = 0x2,
+ MFI_CMD_LD_SCSI_IO = 0x3,
+ MFI_CMD_PD_SCSI_IO = 0x4,
+ MFI_CMD_DCMD = 0x5,
+ MFI_CMD_ABORT = 0x6,
+ MFI_CMD_SMP = 0x7,
+ MFI_CMD_STP = 0x8,
+ MFI_CMD_OP_COUNT,
+ MFI_CMD_INVALID = 0xff
+};
#define MR_DCMD_CTRL_GET_INFO 0x01010000
#define MR_DCMD_LD_GET_LIST 0x03010000
diff --git a/drivers/scsi/megaraid/megaraid_sas_base.c b/drivers/scsi/megaraid/megaraid_sas_base.c
index 79e3e23..7e40ff6 100644
--- a/drivers/scsi/megaraid/megaraid_sas_base.c
+++ b/drivers/scsi/megaraid/megaraid_sas_base.c
@@ -3298,6 +3298,9 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
case MFI_CMD_SMP:
case MFI_CMD_STP:
+ megasas_complete_int_cmd(instance, cmd);
+ break;
+
case MFI_CMD_DCMD:
opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
/* Check for LD map update */
@@ -3384,6 +3387,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
default:
dev_info(&instance->pdev->dev, "Unknown command completed! [0x%X]\n",
hdr->cmd);
+ megasas_complete_int_cmd(instance, cmd);
break;
}
}
@@ -7017,7 +7021,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
void *sense = NULL;
dma_addr_t sense_handle;
unsigned long *sense_ptr;
- u32 opcode;
+ u32 opcode = 0;
memset(kbuff_arr, 0, sizeof(kbuff_arr));
@@ -7027,6 +7031,13 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
return -EINVAL;
}
+ if (ioc->frame.hdr.cmd >= MFI_CMD_OP_COUNT) {
+ dev_err(&instance->pdev->dev,
+ "Received invalid ioctl command 0x%x\n",
+ ioc->frame.hdr.cmd);
+ return -ENOTSUPP;
+ }
+
cmd = megasas_get_cmd(instance);
if (!cmd) {
dev_printk(KERN_DEBUG, &instance->pdev->dev, "Failed to get a cmd packet\n");
@@ -7045,7 +7056,9 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
cmd->frame->hdr.flags &= cpu_to_le16(~(MFI_FRAME_IEEE |
MFI_FRAME_SGL64 |
MFI_FRAME_SENSE64));
- opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
+
+ if (cmd->frame->hdr.cmd == MFI_CMD_DCMD)
+ opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
if (opcode == MR_DCMD_CTRL_SHUTDOWN) {
if (megasas_get_ctrl_info(instance) != DCMD_SUCCESS) {
@@ -7127,8 +7140,9 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
if (megasas_issue_blocked_cmd(instance, cmd, 0) == DCMD_NOT_FIRED) {
cmd->sync_cmd = 0;
dev_err(&instance->pdev->dev,
- "return -EBUSY from %s %d opcode 0x%x cmd->cmd_status_drv 0x%x\n",
- __func__, __LINE__, opcode, cmd->cmd_status_drv);
+ "return -EBUSY from %s %d cmd 0x%x opcode 0x%x cmd->cmd_status_drv 0x%x\n",
+ __func__, __LINE__, cmd->frame->hdr.cmd, opcode,
+ cmd->cmd_status_drv);
return -EBUSY;
}
OpenPOWER on IntegriCloud