[SCSI] fusion - error handling bug fix's
misc error handling bug fix's - properly interpret iocstatus returned after task management request - clear tmState after a failed doorbell - cleanup mptscsih_taskmgmt_complete Signed-off-by: Eric Moore <Eric.Moore@lsi.com> Signed-off-by: James Bottomley <James.Bottomley@SteelEye.com>
This commit is contained in:
committed by
James Bottomley
parent
2ecce49229
commit
cd2c61911d
@@ -916,7 +916,7 @@ mpt_add_sge(char *pAddr, u32 flagslength, dma_addr_t dma_addr)
|
|||||||
int
|
int
|
||||||
mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
|
mpt_send_handshake_request(int handle, MPT_ADAPTER *ioc, int reqBytes, u32 *req, int sleepFlag)
|
||||||
{
|
{
|
||||||
int r = 0;
|
int r = 0;
|
||||||
u8 *req_as_bytes;
|
u8 *req_as_bytes;
|
||||||
int ii;
|
int ii;
|
||||||
|
|
||||||
@@ -3219,6 +3219,9 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
|
|||||||
u32 diag1val = 0;
|
u32 diag1val = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Clear any existing interrupts */
|
||||||
|
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
|
||||||
|
|
||||||
if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
|
if (ioc->pcidev->device == MPI_MANUFACTPAGE_DEVID_SAS1078) {
|
||||||
drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
|
drsprintk((MYIOC_s_WARN_FMT "%s: Doorbell=%p; 1078 reset "
|
||||||
"address=%p\n", ioc->name, __FUNCTION__,
|
"address=%p\n", ioc->name, __FUNCTION__,
|
||||||
@@ -3238,7 +3241,7 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
|
|||||||
" count=%d\n",
|
" count=%d\n",
|
||||||
ioc->name, doorbell, count));
|
ioc->name, doorbell, count));
|
||||||
if (doorbell == MPI_IOC_STATE_READY) {
|
if (doorbell == MPI_IOC_STATE_READY) {
|
||||||
return 0;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* wait 1 sec */
|
/* wait 1 sec */
|
||||||
@@ -3250,9 +3253,6 @@ mpt_diag_reset(MPT_ADAPTER *ioc, int ignore, int sleepFlag)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Clear any existing interrupts */
|
|
||||||
CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
|
|
||||||
|
|
||||||
/* Use "Diagnostic reset" method! (only thing available!) */
|
/* Use "Diagnostic reset" method! (only thing available!) */
|
||||||
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
|
diag0val = CHIPREG_READ32(&ioc->chip->Diagnostic);
|
||||||
|
|
||||||
@@ -3968,7 +3968,7 @@ WaitForDoorbellAck(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while (--cntdn) {
|
while (--cntdn) {
|
||||||
mdelay (1);
|
udelay (1000);
|
||||||
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
|
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
|
||||||
if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
|
if (! (intstat & MPI_HIS_IOP_DOORBELL_STATUS))
|
||||||
break;
|
break;
|
||||||
@@ -4020,7 +4020,7 @@ WaitForDoorbellInt(MPT_ADAPTER *ioc, int howlong, int sleepFlag)
|
|||||||
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
|
intstat = CHIPREG_READ32(&ioc->chip->IntStatus);
|
||||||
if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
|
if (intstat & MPI_HIS_DOORBELL_INTERRUPT)
|
||||||
break;
|
break;
|
||||||
mdelay(1);
|
udelay (1000);
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -313,7 +313,7 @@ static void mptctl_timeout_expired (MPT_IOCTL *ioctl)
|
|||||||
*/
|
*/
|
||||||
dctlprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
|
dctlprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
|
||||||
ioctl->ioc->name));
|
ioctl->ioc->name));
|
||||||
mpt_HardResetHandler(ioctl->ioc, NO_SLEEP);
|
mpt_HardResetHandler(ioctl->ioc, CAN_SLEEP);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@@ -1536,7 +1536,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||||
/*
|
/**
|
||||||
* mptscsih_TMHandler - Generic handler for SCSI Task Management.
|
* mptscsih_TMHandler - Generic handler for SCSI Task Management.
|
||||||
* Fall through to mpt_HardResetHandler if: not operational, too many
|
* Fall through to mpt_HardResetHandler if: not operational, too many
|
||||||
* failed TM requests or handshake failure.
|
* failed TM requests or handshake failure.
|
||||||
@@ -1552,28 +1552,17 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
|
|||||||
* Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
|
* Remark: With old EH code, at most 1 SCSI TaskMgmt function per IOC
|
||||||
* will be active.
|
* will be active.
|
||||||
*
|
*
|
||||||
* Returns 0 for SUCCESS or -1 if FAILED.
|
* Returns 0 for SUCCESS, or FAILED.
|
||||||
*/
|
**/
|
||||||
int
|
int
|
||||||
mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
|
mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
|
||||||
{
|
{
|
||||||
MPT_ADAPTER *ioc;
|
MPT_ADAPTER *ioc;
|
||||||
int rc = -1;
|
int rc = -1;
|
||||||
int doTask = 1;
|
|
||||||
u32 ioc_raw_state;
|
u32 ioc_raw_state;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
|
|
||||||
/* If FW is being reloaded currently, return success to
|
|
||||||
* the calling function.
|
|
||||||
*/
|
|
||||||
if (hd == NULL)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
ioc = hd->ioc;
|
ioc = hd->ioc;
|
||||||
if (ioc == NULL) {
|
|
||||||
printk(KERN_ERR MYNAM " TMHandler" " NULL ioc!\n");
|
|
||||||
return FAILED;
|
|
||||||
}
|
|
||||||
dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
|
dtmprintk((MYIOC_s_INFO_FMT "TMHandler Entered!\n", ioc->name));
|
||||||
|
|
||||||
// SJR - CHECKME - Can we avoid this here?
|
// SJR - CHECKME - Can we avoid this here?
|
||||||
@@ -1586,8 +1575,10 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int c
|
|||||||
spin_unlock_irqrestore(&ioc->diagLock, flags);
|
spin_unlock_irqrestore(&ioc->diagLock, flags);
|
||||||
|
|
||||||
/* Wait a fixed amount of time for the TM pending flag to be cleared.
|
/* Wait a fixed amount of time for the TM pending flag to be cleared.
|
||||||
* If we time out and not bus reset, then we return a FAILED status to the caller.
|
* If we time out and not bus reset, then we return a FAILED status
|
||||||
* The call to mptscsih_tm_pending_wait() will set the pending flag if we are
|
* to the caller.
|
||||||
|
* The call to mptscsih_tm_pending_wait() will set the pending flag
|
||||||
|
* if we are
|
||||||
* successful. Otherwise, reload the FW.
|
* successful. Otherwise, reload the FW.
|
||||||
*/
|
*/
|
||||||
if (mptscsih_tm_pending_wait(hd) == FAILED) {
|
if (mptscsih_tm_pending_wait(hd) == FAILED) {
|
||||||
@@ -1597,18 +1588,16 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int c
|
|||||||
hd->ioc->name, hd->tmPending));
|
hd->ioc->name, hd->tmPending));
|
||||||
return FAILED;
|
return FAILED;
|
||||||
} else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
|
} else if (type == MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET) {
|
||||||
dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target reset: "
|
dtmprintk((KERN_INFO MYNAM ": %s: TMHandler target "
|
||||||
"Timed out waiting for last TM (%d) to complete! \n",
|
"reset: Timed out waiting for last TM (%d) "
|
||||||
hd->ioc->name, hd->tmPending));
|
"to complete! \n", hd->ioc->name,
|
||||||
|
hd->tmPending));
|
||||||
return FAILED;
|
return FAILED;
|
||||||
} else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
|
} else if (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
|
||||||
dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
|
dtmprintk((KERN_INFO MYNAM ": %s: TMHandler bus reset: "
|
||||||
"Timed out waiting for last TM (%d) to complete! \n",
|
"Timed out waiting for last TM (%d) to complete! \n",
|
||||||
hd->ioc->name, hd->tmPending));
|
hd->ioc->name, hd->tmPending));
|
||||||
if (hd->tmPending & (1 << MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS))
|
return FAILED;
|
||||||
return FAILED;
|
|
||||||
|
|
||||||
doTask = 0;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
|
spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
|
||||||
@@ -1616,47 +1605,40 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int c
|
|||||||
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
|
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Is operational?
|
|
||||||
*/
|
|
||||||
ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
|
ioc_raw_state = mpt_GetIocState(hd->ioc, 0);
|
||||||
|
|
||||||
#ifdef MPT_DEBUG_RESET
|
|
||||||
if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
|
if ((ioc_raw_state & MPI_IOC_STATE_MASK) != MPI_IOC_STATE_OPERATIONAL) {
|
||||||
printk(MYIOC_s_WARN_FMT
|
printk(MYIOC_s_WARN_FMT
|
||||||
"TM Handler: IOC Not operational(0x%x)!\n",
|
"TM Handler for type=%x: IOC Not operational (0x%x)!\n",
|
||||||
hd->ioc->name, ioc_raw_state);
|
ioc->name, type, ioc_raw_state);
|
||||||
}
|
printk(KERN_WARNING " Issuing HardReset!!\n");
|
||||||
#endif
|
if (mpt_HardResetHandler(ioc, CAN_SLEEP) < 0)
|
||||||
|
printk((KERN_WARNING "TMHandler: HardReset "
|
||||||
if (doTask && ((ioc_raw_state & MPI_IOC_STATE_MASK) == MPI_IOC_STATE_OPERATIONAL)
|
"FAILED!!\n"));
|
||||||
&& !(ioc_raw_state & MPI_DOORBELL_ACTIVE)) {
|
return FAILED;
|
||||||
|
|
||||||
/* Isse the Task Mgmt request.
|
|
||||||
*/
|
|
||||||
if (hd->hard_resets < -1)
|
|
||||||
hd->hard_resets++;
|
|
||||||
rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun, ctx2abort, timeout);
|
|
||||||
if (rc) {
|
|
||||||
printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
|
|
||||||
} else {
|
|
||||||
dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n", hd->ioc->name));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Only fall through to the HRH if this is a bus reset
|
if (ioc_raw_state & MPI_DOORBELL_ACTIVE) {
|
||||||
|
printk(MYIOC_s_WARN_FMT
|
||||||
|
"TM Handler for type=%x: ioc_state: "
|
||||||
|
"DOORBELL_ACTIVE (0x%x)!\n",
|
||||||
|
ioc->name, type, ioc_raw_state);
|
||||||
|
return FAILED;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Isse the Task Mgmt request.
|
||||||
*/
|
*/
|
||||||
if ((type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) && (rc ||
|
if (hd->hard_resets < -1)
|
||||||
ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
|
hd->hard_resets++;
|
||||||
dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
|
|
||||||
hd->ioc->name));
|
|
||||||
rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
rc = mptscsih_IssueTaskMgmt(hd, type, channel, id, lun,
|
||||||
* Check IOCStatus from TM reply message
|
ctx2abort, timeout);
|
||||||
*/
|
if (rc)
|
||||||
if (hd->tm_iocstatus != MPI_IOCSTATUS_SUCCESS)
|
printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n",
|
||||||
rc = FAILED;
|
hd->ioc->name);
|
||||||
|
else
|
||||||
|
dtmprintk((MYIOC_s_INFO_FMT "Issue of TaskMgmt Successful!\n",
|
||||||
|
hd->ioc->name));
|
||||||
|
|
||||||
dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
|
dtmprintk((MYIOC_s_INFO_FMT "TMHandler rc = %d!\n", hd->ioc->name, rc));
|
||||||
|
|
||||||
@@ -1665,7 +1647,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int c
|
|||||||
|
|
||||||
|
|
||||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||||
/*
|
/**
|
||||||
* mptscsih_IssueTaskMgmt - Generic send Task Management function.
|
* mptscsih_IssueTaskMgmt - Generic send Task Management function.
|
||||||
* @hd: Pointer to MPT_SCSI_HOST structure
|
* @hd: Pointer to MPT_SCSI_HOST structure
|
||||||
* @type: Task Management type
|
* @type: Task Management type
|
||||||
@@ -1678,9 +1660,9 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int c
|
|||||||
*
|
*
|
||||||
* Not all fields are meaningfull for all task types.
|
* Not all fields are meaningfull for all task types.
|
||||||
*
|
*
|
||||||
* Returns 0 for SUCCESS, -999 for "no msg frames",
|
* Returns 0 for SUCCESS, or FAILED.
|
||||||
* else other non-zero value returned.
|
*
|
||||||
*/
|
**/
|
||||||
static int
|
static int
|
||||||
mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
|
mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, int ctx2abort, ulong timeout)
|
||||||
{
|
{
|
||||||
@@ -1720,32 +1702,52 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 id, int lun, i
|
|||||||
|
|
||||||
pScsiTm->TaskMsgContext = ctx2abort;
|
pScsiTm->TaskMsgContext = ctx2abort;
|
||||||
|
|
||||||
dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
|
dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) "
|
||||||
hd->ioc->name, ctx2abort, type));
|
"type=%d\n", hd->ioc->name, ctx2abort, type));
|
||||||
|
|
||||||
DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
|
DBG_DUMP_TM_REQUEST_FRAME((u32 *)pScsiTm);
|
||||||
|
|
||||||
if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
|
if ((retval = mpt_send_handshake_request(hd->ioc->TaskCtx, hd->ioc,
|
||||||
sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
|
sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP)) != 0) {
|
||||||
CAN_SLEEP)) != 0) {
|
dfailprintk((MYIOC_s_ERR_FMT "send_handshake FAILED!"
|
||||||
dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
|
" (hd %p, ioc %p, mf %p, rc=%d) \n", hd->ioc->name, hd,
|
||||||
" (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
|
hd->ioc, mf, retval));
|
||||||
hd->ioc, mf));
|
goto fail_out;
|
||||||
mpt_free_msg_frame(hd->ioc, mf);
|
|
||||||
return retval;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
|
if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
|
||||||
dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
|
dfailprintk((MYIOC_s_ERR_FMT "task management request TIMED OUT!"
|
||||||
" (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
|
" (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
|
||||||
hd->ioc, mf));
|
hd->ioc, mf));
|
||||||
mpt_free_msg_frame(hd->ioc, mf);
|
|
||||||
dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
|
dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
|
||||||
hd->ioc->name));
|
hd->ioc->name));
|
||||||
retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
|
retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
|
||||||
|
dtmprintk((MYIOC_s_INFO_FMT "rc=%d \n",
|
||||||
|
hd->ioc->name, retval));
|
||||||
|
goto fail_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Handle success case, see if theres a non-zero ioc_status.
|
||||||
|
*/
|
||||||
|
if (hd->tm_iocstatus == MPI_IOCSTATUS_SUCCESS ||
|
||||||
|
hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_TASK_TERMINATED ||
|
||||||
|
hd->tm_iocstatus == MPI_IOCSTATUS_SCSI_IOC_TERMINATED)
|
||||||
|
retval = 0;
|
||||||
|
else
|
||||||
|
retval = FAILED;
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
||||||
|
fail_out:
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Free task managment mf, and corresponding tm flags
|
||||||
|
*/
|
||||||
|
mpt_free_msg_frame(hd->ioc, mf);
|
||||||
|
hd->tmPending = 0;
|
||||||
|
hd->tmState = TM_STATE_NONE;
|
||||||
|
return FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@@ -1770,7 +1772,7 @@ mptscsih_get_tm_timeout(MPT_ADAPTER *ioc)
|
|||||||
* (linux scsi_host_template.eh_abort_handler routine)
|
* (linux scsi_host_template.eh_abort_handler routine)
|
||||||
*
|
*
|
||||||
* Returns SUCCESS or FAILED.
|
* Returns SUCCESS or FAILED.
|
||||||
*/
|
**/
|
||||||
int
|
int
|
||||||
mptscsih_abort(struct scsi_cmnd * SCpnt)
|
mptscsih_abort(struct scsi_cmnd * SCpnt)
|
||||||
{
|
{
|
||||||
@@ -1806,9 +1808,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
|
|||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hd->resetPending) {
|
if (hd->resetPending)
|
||||||
return FAILED;
|
return FAILED;
|
||||||
}
|
|
||||||
|
|
||||||
if (hd->timeouts < -1)
|
if (hd->timeouts < -1)
|
||||||
hd->timeouts++;
|
hd->timeouts++;
|
||||||
@@ -1835,9 +1836,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
|
|||||||
ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
|
ctx2abort, mptscsih_get_tm_timeout(hd->ioc));
|
||||||
|
|
||||||
if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
|
if (SCPNT_TO_LOOKUP_IDX(SCpnt) == scpnt_idx &&
|
||||||
SCpnt->serial_number == sn) {
|
SCpnt->serial_number == sn)
|
||||||
retval = FAILED;
|
retval = FAILED;
|
||||||
}
|
|
||||||
|
|
||||||
printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
|
printk (KERN_WARNING MYNAM ": %s: task abort: %s (sc=%p)\n",
|
||||||
hd->ioc->name,
|
hd->ioc->name,
|
||||||
@@ -1845,12 +1845,8 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
|
|||||||
|
|
||||||
if (retval == 0)
|
if (retval == 0)
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
else
|
||||||
if(retval != FAILED ) {
|
return FAILED;
|
||||||
hd->tmPending = 0;
|
|
||||||
hd->tmState = TM_STATE_NONE;
|
|
||||||
}
|
|
||||||
return FAILED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||||
@@ -1861,7 +1857,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
|
|||||||
* (linux scsi_host_template.eh_dev_reset_handler routine)
|
* (linux scsi_host_template.eh_dev_reset_handler routine)
|
||||||
*
|
*
|
||||||
* Returns SUCCESS or FAILED.
|
* Returns SUCCESS or FAILED.
|
||||||
*/
|
**/
|
||||||
int
|
int
|
||||||
mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
|
mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
|
||||||
{
|
{
|
||||||
@@ -1896,14 +1892,11 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
|
|||||||
|
|
||||||
if (retval == 0)
|
if (retval == 0)
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
else
|
||||||
if(retval != FAILED ) {
|
return FAILED;
|
||||||
hd->tmPending = 0;
|
|
||||||
hd->tmState = TM_STATE_NONE;
|
|
||||||
}
|
|
||||||
return FAILED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||||
/**
|
/**
|
||||||
* mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
|
* mptscsih_bus_reset - Perform a SCSI BUS_RESET! new_eh variant
|
||||||
@@ -1912,7 +1905,7 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
|
|||||||
* (linux scsi_host_template.eh_bus_reset_handler routine)
|
* (linux scsi_host_template.eh_bus_reset_handler routine)
|
||||||
*
|
*
|
||||||
* Returns SUCCESS or FAILED.
|
* Returns SUCCESS or FAILED.
|
||||||
*/
|
**/
|
||||||
int
|
int
|
||||||
mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
|
mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
|
||||||
{
|
{
|
||||||
@@ -1946,12 +1939,8 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
|
|||||||
|
|
||||||
if (retval == 0)
|
if (retval == 0)
|
||||||
return SUCCESS;
|
return SUCCESS;
|
||||||
|
else
|
||||||
if(retval != FAILED ) {
|
return FAILED;
|
||||||
hd->tmPending = 0;
|
|
||||||
hd->tmState = TM_STATE_NONE;
|
|
||||||
}
|
|
||||||
return FAILED;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
|
||||||
@@ -2034,7 +2023,6 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
|
|||||||
/**
|
/**
|
||||||
* mptscsih_tm_wait_for_completion - wait for completion of TM task
|
* mptscsih_tm_wait_for_completion - wait for completion of TM task
|
||||||
* @hd: Pointer to MPT host structure.
|
* @hd: Pointer to MPT host structure.
|
||||||
* @timeout: timeout in seconds
|
|
||||||
*
|
*
|
||||||
* Returns {SUCCESS,FAILED}.
|
* Returns {SUCCESS,FAILED}.
|
||||||
*/
|
*/
|
||||||
@@ -2108,7 +2096,7 @@ mptscsih_taskmgmt_response_code(MPT_ADAPTER *ioc, u8 response_code)
|
|||||||
* load/init time via the mpt_register() API call.
|
* load/init time via the mpt_register() API call.
|
||||||
*
|
*
|
||||||
* Returns 1 indicating alloc'd request frame ptr should be freed.
|
* Returns 1 indicating alloc'd request frame ptr should be freed.
|
||||||
*/
|
**/
|
||||||
int
|
int
|
||||||
mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
|
mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
|
||||||
{
|
{
|
||||||
@@ -2118,78 +2106,85 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
|
|||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
u16 iocstatus;
|
u16 iocstatus;
|
||||||
u8 tmType;
|
u8 tmType;
|
||||||
|
u32 termination_count;
|
||||||
|
|
||||||
dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
|
dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt completed (mf=%p,mr=%p)\n",
|
||||||
ioc->name, mf, mr));
|
ioc->name, mf, mr));
|
||||||
if (ioc->sh) {
|
if (!ioc->sh) {
|
||||||
/* Depending on the thread, a timer is activated for
|
dtmprintk((MYIOC_s_WARN_FMT
|
||||||
* the TM request. Delete this timer on completion of TM.
|
"TaskMgmt Complete: NULL Scsi Host Ptr\n", ioc->name));
|
||||||
* Decrement count of outstanding TM requests.
|
|
||||||
*/
|
|
||||||
hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
|
|
||||||
} else {
|
|
||||||
dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
|
|
||||||
ioc->name));
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mr == NULL) {
|
if (mr == NULL) {
|
||||||
dtmprintk((MYIOC_s_WARN_FMT "ERROR! TaskMgmt Reply: NULL Request %p\n",
|
dtmprintk((MYIOC_s_WARN_FMT
|
||||||
ioc->name, mf));
|
"ERROR! TaskMgmt Reply: NULL Request %p\n", ioc->name, mf));
|
||||||
return 1;
|
return 1;
|
||||||
} else {
|
|
||||||
pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
|
|
||||||
pScsiTmReq = (SCSITaskMgmt_t*)mf;
|
|
||||||
|
|
||||||
/* Figure out if this was ABORT_TASK, TARGET_RESET, or BUS_RESET! */
|
|
||||||
tmType = pScsiTmReq->TaskType;
|
|
||||||
|
|
||||||
if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
|
|
||||||
pScsiTmReply->ResponseCode)
|
|
||||||
mptscsih_taskmgmt_response_code(ioc,
|
|
||||||
pScsiTmReply->ResponseCode);
|
|
||||||
|
|
||||||
dtmprintk((MYIOC_s_WARN_FMT " TaskType = %d, TerminationCount=%d\n",
|
|
||||||
ioc->name, tmType, le32_to_cpu(pScsiTmReply->TerminationCount)));
|
|
||||||
DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
|
|
||||||
|
|
||||||
iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
|
|
||||||
hd->tm_iocstatus = iocstatus;
|
|
||||||
dtmprintk((MYIOC_s_WARN_FMT " SCSI TaskMgmt (%d) IOCStatus=%04x IOCLogInfo=%08x\n",
|
|
||||||
ioc->name, tmType, iocstatus, le32_to_cpu(pScsiTmReply->IOCLogInfo)));
|
|
||||||
/* Error? (anything non-zero?) */
|
|
||||||
if (iocstatus) {
|
|
||||||
|
|
||||||
/* clear flags and continue.
|
|
||||||
*/
|
|
||||||
if (tmType == MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK)
|
|
||||||
hd->abortSCpnt = NULL;
|
|
||||||
|
|
||||||
/* If an internal command is present
|
|
||||||
* or the TM failed - reload the FW.
|
|
||||||
* FC FW may respond FAILED to an ABORT
|
|
||||||
*/
|
|
||||||
if (tmType == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) {
|
|
||||||
if ((hd->cmdPtr) ||
|
|
||||||
(iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED)) {
|
|
||||||
if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0) {
|
|
||||||
printk((KERN_WARNING
|
|
||||||
" Firmware Reload FAILED!!\n"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
|
|
||||||
|
|
||||||
hd->abortSCpnt = NULL;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
|
||||||
|
pScsiTmReply = (SCSITaskMgmtReply_t*)mr;
|
||||||
|
pScsiTmReq = (SCSITaskMgmt_t*)mf;
|
||||||
|
tmType = pScsiTmReq->TaskType;
|
||||||
|
iocstatus = le16_to_cpu(pScsiTmReply->IOCStatus) & MPI_IOCSTATUS_MASK;
|
||||||
|
termination_count = le32_to_cpu(pScsiTmReply->TerminationCount);
|
||||||
|
|
||||||
|
if (ioc->facts.MsgVersion >= MPI_VERSION_01_05 &&
|
||||||
|
pScsiTmReply->ResponseCode)
|
||||||
|
mptscsih_taskmgmt_response_code(ioc,
|
||||||
|
pScsiTmReply->ResponseCode);
|
||||||
|
DBG_DUMP_TM_REPLY_FRAME((u32 *)pScsiTmReply);
|
||||||
|
|
||||||
|
#if defined(MPT_DEBUG_REPLY) || defined(MPT_DEBUG_TM)
|
||||||
|
printk("%s: ha=%d [%d:%d:0] task_type=0x%02X "
|
||||||
|
"iocstatus=0x%04X\n\tloginfo=0x%08X response_code=0x%02X "
|
||||||
|
"term_cmnds=%d\n", __FUNCTION__, ioc->id, pScsiTmReply->Bus,
|
||||||
|
pScsiTmReply->TargetID, pScsiTmReq->TaskType,
|
||||||
|
le16_to_cpu(pScsiTmReply->IOCStatus),
|
||||||
|
le32_to_cpu(pScsiTmReply->IOCLogInfo),pScsiTmReply->ResponseCode,
|
||||||
|
le32_to_cpu(pScsiTmReply->TerminationCount));
|
||||||
|
#endif
|
||||||
|
if (!iocstatus) {
|
||||||
|
dtmprintk((MYIOC_s_WARN_FMT " TaskMgmt SUCCESS\n", ioc->name));
|
||||||
|
hd->abortSCpnt = NULL;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Error? (anything non-zero?) */
|
||||||
|
|
||||||
|
/* clear flags and continue.
|
||||||
|
*/
|
||||||
|
switch (tmType) {
|
||||||
|
|
||||||
|
case MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK:
|
||||||
|
if (termination_count == 1)
|
||||||
|
iocstatus = MPI_IOCSTATUS_SCSI_TASK_TERMINATED;
|
||||||
|
hd->abortSCpnt = NULL;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS:
|
||||||
|
|
||||||
|
/* If an internal command is present
|
||||||
|
* or the TM failed - reload the FW.
|
||||||
|
* FC FW may respond FAILED to an ABORT
|
||||||
|
*/
|
||||||
|
if (iocstatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED ||
|
||||||
|
hd->cmdPtr)
|
||||||
|
if (mpt_HardResetHandler(ioc, NO_SLEEP) < 0)
|
||||||
|
printk((KERN_WARNING " Firmware Reload FAILED!!\n"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
spin_lock_irqsave(&ioc->FreeQlock, flags);
|
spin_lock_irqsave(&ioc->FreeQlock, flags);
|
||||||
hd->tmPending = 0;
|
hd->tmPending = 0;
|
||||||
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
|
|
||||||
hd->tmState = TM_STATE_NONE;
|
hd->tmState = TM_STATE_NONE;
|
||||||
|
hd->tm_iocstatus = iocstatus;
|
||||||
|
spin_unlock_irqrestore(&ioc->FreeQlock, flags);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user