提交 7d757f18 编写于 作者: K Kashyap, Desai 提交者: James Bottomley

[SCSI] mptfusion: Updated SCSI IO IOCTL error handling.

Behavior changes only for IOCTLs that time out.  Current behavior of
Bus Reset remains the same for RAID Passthru Timeouts Current behavior
of Diagnostic reset for any other type of IOCTL remains the same

CHANGE: For IOCTL SCSI IOs that timeout, a Target Reset TM is sent,
instead of Bus Reset. All error handing from that point is the same as
what the driver currently does, which is to say that if the Device
Reset TM fails it escalates do diagnostic reset.
Signed-off-by: NKashyap Desai <kashyap.desai@lsi.com>
Signed-off-by: NJames Bottomley <James.Bottomley@suse.de>
上级 d0f698c4
...@@ -128,7 +128,6 @@ static MptSge_t *kbuf_alloc_2_sgl(int bytes, u32 dir, int sge_offset, int *frags ...@@ -128,7 +128,6 @@ static MptSge_t *kbuf_alloc_2_sgl(int bytes, u32 dir, int sge_offset, int *frags
struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc); struct buflist **blp, dma_addr_t *sglbuf_dma, MPT_ADAPTER *ioc);
static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma, static void kfree_sgl(MptSge_t *sgl, dma_addr_t sgl_dma,
struct buflist *buflist, MPT_ADAPTER *ioc); struct buflist *buflist, MPT_ADAPTER *ioc);
static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function);
/* /*
* Reset Handler cleanup function * Reset Handler cleanup function
...@@ -275,45 +274,6 @@ mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply) ...@@ -275,45 +274,6 @@ mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
return 1; return 1;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptctl_timeout_expired
*
* Expecting an interrupt, however timed out.
*
*/
static void
mptctl_timeout_expired(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
{
unsigned long flags;
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": %s\n",
ioc->name, __func__));
if (mpt_fwfault_debug)
mpt_halt_firmware(ioc);
spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
if (ioc->ioc_reset_in_progress) {
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status)
mpt_free_msg_frame(ioc, mf);
return;
}
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
if (!mptctl_bus_reset(ioc, mf->u.hdr.Function))
return;
/* Issue a reset for this device.
* The IOC is not responding.
*/
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling HardReset! \n",
ioc->name));
CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status)
mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
mpt_free_msg_frame(ioc, mf);
}
static int static int
mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
...@@ -343,12 +303,8 @@ mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr) ...@@ -343,12 +303,8 @@ mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
return 0; return 0;
} }
/* mptctl_bus_reset static int
* mptctl_do_taskmgmt(MPT_ADAPTER *ioc, u8 tm_type, u8 bus_id, u8 target_id)
* Bus reset code.
*
*/
static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
{ {
MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mf;
SCSITaskMgmt_t *pScsiTm; SCSITaskMgmt_t *pScsiTm;
...@@ -359,13 +315,6 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function) ...@@ -359,13 +315,6 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
unsigned long time_count; unsigned long time_count;
u16 iocstatus; u16 iocstatus;
/* bus reset is only good for SCSI IO, RAID PASSTHRU */
if (!(function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH ||
function == MPI_FUNCTION_SCSI_IO_REQUEST)) {
dtmprintk(ioc, printk(MYIOC_s_WARN_FMT
"TaskMgmt, not SCSI_IO!!\n", ioc->name));
return -EPERM;
}
mutex_lock(&ioc->taskmgmt_cmds.mutex); mutex_lock(&ioc->taskmgmt_cmds.mutex);
if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) { if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
...@@ -375,15 +324,14 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function) ...@@ -375,15 +324,14 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
retval = 0; retval = 0;
/* Send request
*/
mf = mpt_get_msg_frame(mptctl_taskmgmt_id, ioc); mf = mpt_get_msg_frame(mptctl_taskmgmt_id, ioc);
if (mf == NULL) { if (mf == NULL) {
dtmprintk(ioc, printk(MYIOC_s_WARN_FMT dtmprintk(ioc,
"TaskMgmt, no msg frames!!\n", ioc->name)); printk(MYIOC_s_WARN_FMT "TaskMgmt, no msg frames!!\n",
ioc->name));
mpt_clear_taskmgmt_in_progress_flag(ioc); mpt_clear_taskmgmt_in_progress_flag(ioc);
retval = -ENOMEM; retval = -ENOMEM;
goto mptctl_bus_reset_done; goto tm_done;
} }
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n", dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "TaskMgmt request (mf=%p)\n",
...@@ -392,10 +340,13 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function) ...@@ -392,10 +340,13 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
pScsiTm = (SCSITaskMgmt_t *) mf; pScsiTm = (SCSITaskMgmt_t *) mf;
memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t)); memset(pScsiTm, 0, sizeof(SCSITaskMgmt_t));
pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT; pScsiTm->Function = MPI_FUNCTION_SCSI_TASK_MGMT;
pScsiTm->TaskType = MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS; pScsiTm->TaskType = tm_type;
pScsiTm->MsgFlags = MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION; if ((tm_type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) &&
pScsiTm->TargetID = 0; (ioc->bus_type == FC))
pScsiTm->Bus = 0; pScsiTm->MsgFlags =
MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION;
pScsiTm->TargetID = target_id;
pScsiTm->Bus = bus_id;
pScsiTm->ChainOffset = 0; pScsiTm->ChainOffset = 0;
pScsiTm->Reserved = 0; pScsiTm->Reserved = 0;
pScsiTm->Reserved1 = 0; pScsiTm->Reserved1 = 0;
...@@ -413,17 +364,16 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function) ...@@ -413,17 +364,16 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
timeout = 30; timeout = 30;
break; break;
case SPI: case SPI:
default: default:
timeout = 2; timeout = 10;
break; break;
} }
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT dtmprintk(ioc,
"TaskMgmt type=%d timeout=%ld\n", printk(MYIOC_s_DEBUG_FMT "TaskMgmt type=%d timeout=%ld\n",
ioc->name, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, timeout)); ioc->name, tm_type, timeout));
INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status) INITIALIZE_MGMT_STATUS(ioc->taskmgmt_cmds.status)
CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
time_count = jiffies; time_count = jiffies;
if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) && if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
(ioc->facts.MsgVersion >= MPI_VERSION_01_05)) (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
...@@ -432,17 +382,20 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function) ...@@ -432,17 +382,20 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
retval = mpt_send_handshake_request(mptctl_taskmgmt_id, ioc, retval = mpt_send_handshake_request(mptctl_taskmgmt_id, ioc,
sizeof(SCSITaskMgmt_t), (u32 *)pScsiTm, CAN_SLEEP); sizeof(SCSITaskMgmt_t), (u32 *)pScsiTm, CAN_SLEEP);
if (retval != 0) { if (retval != 0) {
dfailprintk(ioc, printk(MYIOC_s_ERR_FMT dfailprintk(ioc,
printk(MYIOC_s_ERR_FMT
"TaskMgmt send_handshake FAILED!" "TaskMgmt send_handshake FAILED!"
" (ioc %p, mf %p, rc=%d) \n", ioc->name, " (ioc %p, mf %p, rc=%d) \n", ioc->name,
ioc, mf, retval)); ioc, mf, retval));
mpt_free_msg_frame(ioc, mf);
mpt_clear_taskmgmt_in_progress_flag(ioc); mpt_clear_taskmgmt_in_progress_flag(ioc);
goto mptctl_bus_reset_done; goto tm_done;
} }
} }
/* Now wait for the command to complete */ /* Now wait for the command to complete */
ii = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done, timeout*HZ); ii = wait_for_completion_timeout(&ioc->taskmgmt_cmds.done, timeout*HZ);
if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) { if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"TaskMgmt failed\n", ioc->name)); "TaskMgmt failed\n", ioc->name));
...@@ -452,14 +405,14 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function) ...@@ -452,14 +405,14 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
retval = 0; retval = 0;
else else
retval = -1; /* return failure */ retval = -1; /* return failure */
goto mptctl_bus_reset_done; goto tm_done;
} }
if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) { if (!(ioc->taskmgmt_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT
"TaskMgmt failed\n", ioc->name)); "TaskMgmt failed\n", ioc->name));
retval = -1; /* return failure */ retval = -1; /* return failure */
goto mptctl_bus_reset_done; goto tm_done;
} }
pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply; pScsiTmReply = (SCSITaskMgmtReply_t *) ioc->taskmgmt_cmds.reply;
...@@ -467,7 +420,7 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function) ...@@ -467,7 +420,7 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
"TaskMgmt fw_channel = %d, fw_id = %d, task_type=0x%02X, " "TaskMgmt fw_channel = %d, fw_id = %d, task_type=0x%02X, "
"iocstatus=0x%04X\n\tloginfo=0x%08X, response_code=0x%02X, " "iocstatus=0x%04X\n\tloginfo=0x%08X, response_code=0x%02X, "
"term_cmnds=%d\n", ioc->name, pScsiTmReply->Bus, "term_cmnds=%d\n", ioc->name, pScsiTmReply->Bus,
pScsiTmReply->TargetID, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, pScsiTmReply->TargetID, tm_type,
le16_to_cpu(pScsiTmReply->IOCStatus), le16_to_cpu(pScsiTmReply->IOCStatus),
le32_to_cpu(pScsiTmReply->IOCLogInfo), le32_to_cpu(pScsiTmReply->IOCLogInfo),
pScsiTmReply->ResponseCode, pScsiTmReply->ResponseCode,
...@@ -485,13 +438,71 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function) ...@@ -485,13 +438,71 @@ static int mptctl_bus_reset(MPT_ADAPTER *ioc, u8 function)
retval = -1; /* return failure */ retval = -1; /* return failure */
} }
tm_done:
mptctl_bus_reset_done:
mutex_unlock(&ioc->taskmgmt_cmds.mutex); mutex_unlock(&ioc->taskmgmt_cmds.mutex);
CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status) CLEAR_MGMT_STATUS(ioc->taskmgmt_cmds.status)
return retval; return retval;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptctl_timeout_expired
*
* Expecting an interrupt, however timed out.
*
*/
static void
mptctl_timeout_expired(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf)
{
unsigned long flags;
int ret_val = -1;
SCSIIORequest_t *scsi_req = (SCSIIORequest_t *) mf;
u8 function = mf->u.hdr.Function;
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT ": %s\n",
ioc->name, __func__));
if (mpt_fwfault_debug)
mpt_halt_firmware(ioc);
spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
if (ioc->ioc_reset_in_progress) {
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status)
mpt_free_msg_frame(ioc, mf);
return;
}
spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
CLEAR_MGMT_PENDING_STATUS(ioc->ioctl_cmds.status)
if (ioc->bus_type == SAS) {
if (function == MPI_FUNCTION_SCSI_IO_REQUEST)
ret_val = mptctl_do_taskmgmt(ioc,
MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
scsi_req->Bus, scsi_req->TargetID);
else if (function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)
ret_val = mptctl_do_taskmgmt(ioc,
MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
scsi_req->Bus, 0);
if (!ret_val)
return;
} else {
if ((function == MPI_FUNCTION_SCSI_IO_REQUEST) ||
(function == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH))
ret_val = mptctl_do_taskmgmt(ioc,
MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
scsi_req->Bus, 0);
if (!ret_val)
return;
}
dtmprintk(ioc, printk(MYIOC_s_DEBUG_FMT "Calling Reset! \n",
ioc->name));
mpt_Soft_Hard_ResetHandler(ioc, CAN_SLEEP);
mpt_free_msg_frame(ioc, mf);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptctl_ioc_reset /* mptctl_ioc_reset
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册