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>
This commit is contained in:
parent
b9637d14dc
commit
82add4e1b3
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user