Commit 7e8c19ef authored by James Bottomley's avatar James Bottomley

mptfusion: delete watchdogs timers from mptctl and mptscsih

From: 	Moore, Eric Dean <Eric.Moore@lsil.com>

1) mptscsih.c: I have changed task management 
requests so they complete in same thread before returning
to os.  I removed the TMtimer code.  
 
(2) mptctl.c: I have deleted both TMtimer and timer code. Replaced
with wait_event_interruptible_timeout.  So commands are now
completed in same thread.  
 
(3) mptctl_do_fw_download - nasty polling of global parameters
that are set in contents of interrupt handler(mptctl_reply), now using
wait_event_interruptible_timeout. 
 
(4) I have cleaned up mptctl_reply.
Signed-off-by: default avatarEric Moore <Eric.Moore@lsil.com>
Signed-off-by: default avatarJames Bottomley <James.Bottomley@SteelEye.com>
parent 71db3852
...@@ -83,8 +83,8 @@ ...@@ -83,8 +83,8 @@
#define COPYRIGHT "Copyright (c) 1999-2004 " MODULEAUTHOR #define COPYRIGHT "Copyright (c) 1999-2004 " MODULEAUTHOR
#endif #endif
#define MPT_LINUX_VERSION_COMMON "3.01.18" #define MPT_LINUX_VERSION_COMMON "3.01.19"
#define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.18" #define MPT_LINUX_PACKAGE_NAME "@(#)mptlinux-3.01.19"
#define WHAT_MAGIC_STRING "@" "(" "#" ")" #define WHAT_MAGIC_STRING "@" "(" "#" ")"
#define show_mptmod_ver(s,ver) \ #define show_mptmod_ver(s,ver) \
...@@ -420,7 +420,6 @@ do { \ ...@@ -420,7 +420,6 @@ do { \
typedef struct _MPT_IOCTL { typedef struct _MPT_IOCTL {
struct _MPT_ADAPTER *ioc; struct _MPT_ADAPTER *ioc;
struct timer_list timer; /* timer function for this adapter */
u8 ReplyFrame[MPT_DEFAULT_FRAME_SIZE]; /* reply frame data */ u8 ReplyFrame[MPT_DEFAULT_FRAME_SIZE]; /* reply frame data */
u8 sense[MPT_SENSE_BUFFER_ALLOC]; u8 sense[MPT_SENSE_BUFFER_ALLOC];
int wait_done; /* wake-up value for this ioc */ int wait_done; /* wake-up value for this ioc */
...@@ -428,8 +427,6 @@ typedef struct _MPT_IOCTL { ...@@ -428,8 +427,6 @@ typedef struct _MPT_IOCTL {
u8 status; /* current command status */ u8 status; /* current command status */
u8 reset; /* 1 if bus reset allowed */ u8 reset; /* 1 if bus reset allowed */
u8 target; /* target for reset */ u8 target; /* target for reset */
void *tmPtr;
struct timer_list TMtimer; /* timer function for this adapter */
struct semaphore sem_ioc; struct semaphore sem_ioc;
} MPT_IOCTL; } MPT_IOCTL;
...@@ -882,11 +879,9 @@ typedef struct _MPT_SCSI_HOST { ...@@ -882,11 +879,9 @@ typedef struct _MPT_SCSI_HOST {
int port; int port;
u32 pad0; u32 pad0;
struct scsi_cmnd **ScsiLookup; struct scsi_cmnd **ScsiLookup;
u32 qtag_tick;
VirtDevice **Targets; VirtDevice **Targets;
MPT_LOCAL_REPLY *pLocal; /* used for internal commands */ MPT_LOCAL_REPLY *pLocal; /* used for internal commands */
struct timer_list timer; struct timer_list timer;
struct timer_list TMtimer; /* Timer for TM commands ONLY */
/* Pool of memory for holding SCpnts before doing /* Pool of memory for holding SCpnts before doing
* OS callbacks. freeQ is the free pool. * OS callbacks. freeQ is the free pool.
*/ */
...@@ -896,7 +891,6 @@ typedef struct _MPT_SCSI_HOST { ...@@ -896,7 +891,6 @@ typedef struct _MPT_SCSI_HOST {
u8 pad1; u8 pad1;
u8 tmState; u8 tmState;
u8 rsvd[2]; u8 rsvd[2];
MPT_FRAME_HDR *tmPtr; /* Ptr to TM request*/
MPT_FRAME_HDR *cmdPtr; /* Ptr to nonOS request */ MPT_FRAME_HDR *cmdPtr; /* Ptr to nonOS request */
struct scsi_cmnd *abortSCpnt; struct scsi_cmnd *abortSCpnt;
MPT_LOCAL_REPLY localReply; /* internal cmd reply struct */ MPT_LOCAL_REPLY localReply; /* internal cmd reply struct */
......
...@@ -81,6 +81,7 @@ ...@@ -81,6 +81,7 @@
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/types.h> #include <linux/types.h>
#include <linux/pci.h> #include <linux/pci.h>
#include <linux/delay.h> /* for mdelay */
#include <linux/miscdevice.h> #include <linux/miscdevice.h>
#include <linux/smp_lock.h> #include <linux/smp_lock.h>
#include <linux/compat.h> #include <linux/compat.h>
...@@ -145,7 +146,6 @@ static void mptctl_remove(struct pci_dev *); ...@@ -145,7 +146,6 @@ static void mptctl_remove(struct pci_dev *);
#ifdef CONFIG_COMPAT #ifdef CONFIG_COMPAT
static long compat_mpctl_ioctl(struct file *f, unsigned cmd, unsigned long arg); static long compat_mpctl_ioctl(struct file *f, unsigned cmd, unsigned long arg);
#endif #endif
/* /*
* Private function calls. * Private function calls.
*/ */
...@@ -155,7 +155,7 @@ static MptSge_t *kbuf_alloc_2_sgl( int bytes, u32 dir, int sge_offset, int *frag ...@@ -155,7 +155,7 @@ static MptSge_t *kbuf_alloc_2_sgl( int bytes, u32 dir, int sge_offset, int *frag
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 void mptctl_timer_expired (unsigned long data); static void mptctl_timeout_expired (MPT_IOCTL *ioctl);
static int mptctl_bus_reset(MPT_IOCTL *ioctl); static int mptctl_bus_reset(MPT_IOCTL *ioctl);
static int mptctl_set_tm_flags(MPT_SCSI_HOST *hd); static int mptctl_set_tm_flags(MPT_SCSI_HOST *hd);
static void mptctl_free_tm_flags(MPT_ADAPTER *ioc); static void mptctl_free_tm_flags(MPT_ADAPTER *ioc);
...@@ -188,9 +188,6 @@ static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase); ...@@ -188,9 +188,6 @@ static int mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase);
#define MPT_IOCTL_DEFAULT_TIMEOUT 10 /* Default timeout value (seconds) */ #define MPT_IOCTL_DEFAULT_TIMEOUT 10 /* Default timeout value (seconds) */
static u32 fwReplyBuffer[16];
static pMPIDefaultReply_t ReplyMsg = NULL;
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/** /**
* mptctl_syscall_down - Down the MPT adapter syscall semaphore. * mptctl_syscall_down - Down the MPT adapter syscall semaphore.
...@@ -208,11 +205,6 @@ mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock) ...@@ -208,11 +205,6 @@ mptctl_syscall_down(MPT_ADAPTER *ioc, int nonblock)
int rc = 0; int rc = 0;
dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down(%p,%d) called\n", ioc, nonblock)); dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down(%p,%d) called\n", ioc, nonblock));
if (ioc->ioctl->tmPtr != NULL) {
dctlprintk((KERN_INFO MYNAM "::mptctl_syscall_down BUSY\n"));
return -EBUSY;
}
if (nonblock) { if (nonblock) {
if (down_trylock(&ioc->ioctl->sem_ioc)) if (down_trylock(&ioc->ioctl->sem_ioc))
rc = -EAGAIN; rc = -EAGAIN;
...@@ -239,131 +231,101 @@ mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply) ...@@ -239,131 +231,101 @@ mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
u16 iocStatus; u16 iocStatus;
u8 cmd; u8 cmd;
dctlprintk((MYIOC_s_INFO_FMT ": mptctl_reply()!\n", ioc->name)); dctlprintk(("mptctl_reply()!\n"));
if (req) if (req)
cmd = req->u.hdr.Function; cmd = req->u.hdr.Function;
else else
return 1; return 1;
if (ioc->ioctl) { if (ioc->ioctl) {
/* If timer is not running, then an error occurred.
* A timeout will call the reset routine to reload the messaging
* queues.
* Main callback will free message and reply frames.
*/
if (reply && (cmd == MPI_FUNCTION_SCSI_TASK_MGMT) &&
(ioc->ioctl->status & MPT_IOCTL_STATUS_TMTIMER_ACTIVE)) {
/* This is internally generated TM
*/
del_timer (&ioc->ioctl->TMtimer);
ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TMTIMER_ACTIVE;
mptctl_free_tm_flags(ioc); if (reply==NULL) {
/* If TM failed, reset the timer on the existing command, dctlprintk(("mptctl_reply() NULL Reply "
* will trigger an adapter reset. "Function=%x!\n", cmd));
*/
iocStatus = reply->u.reply.IOCStatus & MPI_IOCSTATUS_MASK;
if (iocStatus == MPI_IOCSTATUS_SCSI_TASK_MGMT_FAILED) {
if (ioc->ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE) {
ioc->ioctl->reset &= ~MPTCTL_RESET_OK;
del_timer (&ioc->ioctl->timer);
ioc->ioctl->timer.expires = jiffies + HZ;
add_timer(&ioc->ioctl->timer);
}
}
ioc->ioctl->tmPtr = NULL;
} else if (ioc->ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE) { ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
/* Delete this timer ioc->ioctl->reset &= ~MPTCTL_RESET_OK;
*/
del_timer (&ioc->ioctl->timer);
ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE;
/* Set the overall status byte. Good if:
* IOC status is good OR if no reply and a SCSI IO request
*/
if (reply) {
/* Copy the reply frame (which much exist
* for non-SCSI I/O) to the IOC structure.
*/
dctlprintk((MYIOC_s_INFO_FMT ": Copying Reply Frame @%p to IOC!\n",
ioc->name, reply));
memcpy(ioc->ioctl->ReplyFrame, reply,
min(ioc->reply_sz, 4*reply->u.reply.MsgLength));
ioc->ioctl->status |= MPT_IOCTL_STATUS_RF_VALID;
/* Set the command status to GOOD if IOC Status is GOOD
* OR if SCSI I/O cmd and data underrun or recovered error.
*/
iocStatus = reply->u.reply.IOCStatus & MPI_IOCSTATUS_MASK;
if (iocStatus == MPI_IOCSTATUS_SUCCESS)
ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
if ((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) || /* We are done, issue wake up
(cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { */
ioc->ioctl->reset &= ~MPTCTL_RESET_OK; ioc->ioctl->wait_done = 1;
wake_up (&mptctl_wait);
return 1;
if ((iocStatus == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN) || }
(iocStatus == MPI_IOCSTATUS_SCSI_RECOVERED_ERROR)) {
ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
}
}
/* Copy the sense data - if present dctlprintk(("mptctl_reply() with req=%p "
*/ "reply=%p Function=%x!\n", req, reply, cmd));
if ((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) &&
(reply->u.sreply.SCSIState & MPI_SCSI_STATE_AUTOSENSE_VALID)){
sz = req->u.scsireq.SenseBufferLength;
req_index = le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
sense_data = ((u8 *)ioc->sense_buf_pool + (req_index * MPT_SENSE_BUFFER_ALLOC));
memcpy(ioc->ioctl->sense, sense_data, sz);
ioc->ioctl->status |= MPT_IOCTL_STATUS_SENSE_VALID;
}
if (cmd == MPI_FUNCTION_SCSI_TASK_MGMT) /* Copy the reply frame (which much exist
mptctl_free_tm_flags(ioc); * for non-SCSI I/O) to the IOC structure.
*/
dctlprintk(("Copying Reply Frame @%p to ioc%d!\n",
reply, ioc->id));
memcpy(ioc->ioctl->ReplyFrame, reply,
min(ioc->reply_sz, 4*reply->u.reply.MsgLength));
ioc->ioctl->status |= MPT_IOCTL_STATUS_RF_VALID;
/* Set the command status to GOOD if IOC Status is GOOD
* OR if SCSI I/O cmd and data underrun or recovered error.
*/
iocStatus = reply->u.reply.IOCStatus & MPI_IOCSTATUS_MASK;
if (iocStatus == MPI_IOCSTATUS_SUCCESS)
ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
if ((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) ||
(cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) {
ioc->ioctl->reset &= ~MPTCTL_RESET_OK;
} else if ((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) || if ((iocStatus == MPI_IOCSTATUS_SCSI_DATA_UNDERRUN) ||
(cmd == MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH)) { (iocStatus == MPI_IOCSTATUS_SCSI_RECOVERED_ERROR)) {
ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD; ioc->ioctl->status |= MPT_IOCTL_STATUS_COMMAND_GOOD;
ioc->ioctl->reset &= ~MPTCTL_RESET_OK;
} }
}
/* We are done, issue wake up /* Copy the sense data - if present
*/ */
ioc->ioctl->wait_done = 1; if ((cmd == MPI_FUNCTION_SCSI_IO_REQUEST) &&
wake_up (&mptctl_wait); (reply->u.sreply.SCSIState &
} else if (reply && cmd == MPI_FUNCTION_FW_DOWNLOAD) { MPI_SCSI_STATE_AUTOSENSE_VALID)){
/* Two paths to FW DOWNLOAD! */ sz = req->u.scsireq.SenseBufferLength;
// NOTE: Expects/requires non-Turbo reply! req_index =
dctlprintk((MYIOC_s_INFO_FMT ":Caching MPI_FUNCTION_FW_DOWNLOAD reply!\n", le16_to_cpu(req->u.frame.hwhdr.msgctxu.fld.req_idx);
ioc->name)); sense_data =
memcpy(fwReplyBuffer, reply, min_t(int, sizeof(fwReplyBuffer), 4*reply->u.reply.MsgLength)); ((u8 *)ioc->sense_buf_pool +
ReplyMsg = (pMPIDefaultReply_t) fwReplyBuffer; (req_index * MPT_SENSE_BUFFER_ALLOC));
memcpy(ioc->ioctl->sense, sense_data, sz);
ioc->ioctl->status |= MPT_IOCTL_STATUS_SENSE_VALID;
} }
if (cmd == MPI_FUNCTION_SCSI_TASK_MGMT)
mptctl_free_tm_flags(ioc);
/* We are done, issue wake up
*/
ioc->ioctl->wait_done = 1;
wake_up (&mptctl_wait);
} }
return 1; return 1;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptctl_timer_expired /* mptctl_timeout_expired
* *
* Call back for timer process. Used only for ioctl functionality. * Expecting an interrupt, however timed out.
* *
*/ */
static void mptctl_timer_expired (unsigned long data) static void mptctl_timeout_expired (MPT_IOCTL *ioctl)
{ {
MPT_IOCTL *ioctl = (MPT_IOCTL *) data;
int rc = 1; int rc = 1;
dctlprintk((KERN_NOTICE MYNAM ": Timer Expired! Host %d\n", dctlprintk((KERN_NOTICE MYNAM ": Timeout Expired! Host %d\n",
ioctl->ioc->id)); ioctl->ioc->id));
if (ioctl == NULL) if (ioctl == NULL)
return; return;
ioctl->wait_done = 0;
if (ioctl->reset & MPTCTL_RESET_OK) if (ioctl->reset & MPTCTL_RESET_OK)
rc = mptctl_bus_reset(ioctl); rc = mptctl_bus_reset(ioctl);
...@@ -371,6 +333,8 @@ static void mptctl_timer_expired (unsigned long data) ...@@ -371,6 +333,8 @@ static void mptctl_timer_expired (unsigned long data)
/* Issue a reset for this device. /* Issue a reset for this device.
* The IOC is not responding. * The IOC is not responding.
*/ */
dctlprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
ioctl->ioc->name));
mpt_HardResetHandler(ioctl->ioc, NO_SLEEP); mpt_HardResetHandler(ioctl->ioc, NO_SLEEP);
} }
return; return;
...@@ -395,7 +359,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl) ...@@ -395,7 +359,7 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
if (ioctl->ioc->sh == NULL) if (ioctl->ioc->sh == NULL)
return -EPERM; return -EPERM;
hd = (MPT_SCSI_HOST *) ioctl->ioc->sh->hostdata; hd = (MPT_SCSI_HOST *) ioctl->ioc->sh->hostdata;
if (hd == NULL) if (hd == NULL)
return -EPERM; return -EPERM;
...@@ -435,26 +399,34 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl) ...@@ -435,26 +399,34 @@ static int mptctl_bus_reset(MPT_IOCTL *ioctl)
pScsiTm->Reserved2[ii] = 0; pScsiTm->Reserved2[ii] = 0;
pScsiTm->TaskMsgContext = 0; pScsiTm->TaskMsgContext = 0;
dtmprintk((MYIOC_s_INFO_FMT "mptctl_bus_reset: issued.\n", ioctl->ioc->name)); dtmprintk((MYIOC_s_INFO_FMT
"mptctl_bus_reset: issued.\n", ioctl->ioc->name));
ioctl->tmPtr = mf; DBG_DUMP_TM_REQUEST_FRAME((u32 *)mf);
ioctl->TMtimer.expires = jiffies + HZ * 20; /* 20 seconds */
ioctl->status |= MPT_IOCTL_STATUS_TMTIMER_ACTIVE;
add_timer(&ioctl->TMtimer);
retval = mpt_send_handshake_request(mptctl_id, ioctl->ioc, ioctl->wait_done=0;
sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, NO_SLEEP); if ((retval = mpt_send_handshake_request(mptctl_id, ioctl->ioc,
sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, CAN_SLEEP)) != 0) {
dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
" (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
hd->ioc, mf));
goto mptctl_bus_reset_done;
}
if (retval != 0) { /* Now wait for the command to complete */
dtmprintk((MYIOC_s_WARN_FMT "_send_handshake FAILED!" ii = wait_event_interruptible_timeout(mptctl_wait,
" (hd %p, ioc %p, mf %p) \n", ioctl->ioc->name, hd, hd->ioc, mf)); ioctl->wait_done == 1,
HZ*5 /* 5 second timeout */);
mptctl_free_tm_flags(ioctl->ioc); if(ii <=0 && (ioctl->wait_done != 1 )) {
del_timer(&ioctl->TMtimer); ioctl->wait_done = 0;
mpt_free_msg_frame(ioctl->ioc, mf); retval = -1; /* return failure */
ioctl->tmPtr = NULL;
} }
mptctl_bus_reset_done:
mpt_free_msg_frame(hd->ioc, mf);
mptctl_free_tm_flags(ioctl->ioc);
return retval; return retval;
} }
...@@ -495,7 +467,6 @@ mptctl_free_tm_flags(MPT_ADAPTER *ioc) ...@@ -495,7 +467,6 @@ mptctl_free_tm_flags(MPT_ADAPTER *ioc)
return; return;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptctl_ioc_reset /* mptctl_ioc_reset
* *
...@@ -508,43 +479,22 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) ...@@ -508,43 +479,22 @@ mptctl_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
{ {
MPT_IOCTL *ioctl = ioc->ioctl; MPT_IOCTL *ioctl = ioc->ioctl;
dctlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to IOCTL driver!\n", dctlprintk((KERN_INFO MYNAM ": IOC %s_reset routed to IOCTL driver!\n",
reset_phase==MPT_IOC_SETUP_RESET ? "setup" : ( reset_phase==MPT_IOC_SETUP_RESET ? "setup" : (
reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post"))); reset_phase==MPT_IOC_PRE_RESET ? "pre" : "post")));
if (reset_phase == MPT_IOC_SETUP_RESET){
;
} else if (reset_phase == MPT_IOC_PRE_RESET){
/* Someone has called the reset handler to
* do a hard reset. No more replies from the FW.
* Delete the timer. TM flags cleaned up by SCSI driver.
* Do not need to free msg frame, as re-initialized
*/
if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE)){
del_timer(&ioctl->timer);
}
if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TMTIMER_ACTIVE)){
ioctl->status &= ~MPT_IOCTL_STATUS_TMTIMER_ACTIVE;
del_timer(&ioctl->TMtimer);
mpt_free_msg_frame(ioc, ioctl->tmPtr);
}
} else {
ioctl->tmPtr = NULL;
/* Set the status and continue IOCTL if(ioctl == NULL)
* processing. All memory will be free'd return 1;
* by originating thread after wake_up is
* called.
*/
if (ioctl && (ioctl->status & MPT_IOCTL_STATUS_TIMER_ACTIVE)){
ioctl->status |= MPT_IOCTL_STATUS_DID_IOCRESET;
/* Wake up the calling process switch(reset_phase) {
*/ case MPT_IOC_SETUP_RESET:
ioctl->wait_done = 1; ioctl->status |= MPT_IOCTL_STATUS_DID_IOCRESET;
wake_up(&mptctl_wait); break;
} case MPT_IOC_POST_RESET:
ioctl->status &= ~MPT_IOCTL_STATUS_DID_IOCRESET;
break;
case MPT_IOC_PRE_RESET:
default:
break;
} }
return 1; return 1;
...@@ -749,9 +699,9 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) ...@@ -749,9 +699,9 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
u32 nib; u32 nib;
int fw_bytes_copied = 0; int fw_bytes_copied = 0;
int i; int i;
int cntdn;
int sge_offset = 0; int sge_offset = 0;
u16 iocstat; u16 iocstat;
pFWDownloadReply_t ReplyMsg = NULL;
dctlprintk((KERN_INFO "mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id)); dctlprintk((KERN_INFO "mptctl_do_fwdl called. mptctl_id = %xh.\n", mptctl_id));
...@@ -882,31 +832,25 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen) ...@@ -882,31 +832,25 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
/* /*
* Finally, perform firmware download. * Finally, perform firmware download.
*/ */
ReplyMsg = NULL; iocp->ioctl->wait_done = 0;
mpt_put_msg_frame(mptctl_id, iocp, mf); mpt_put_msg_frame(mptctl_id, iocp, mf);
/* /* Now wait for the command to complete */
* Wait until the reply has been received ret = wait_event_interruptible_timeout(mptctl_wait,
*/ iocp->ioctl->wait_done == 1,
for (cntdn=HZ*60, i=1; ReplyMsg == NULL; cntdn--, i++) { HZ*60);
if (!cntdn) {
ret = -ETIME;
goto fwdl_out;
}
if (!(i%HZ)) { if(ret <=0 && (iocp->ioctl->wait_done != 1 )) {
dctlprintk((KERN_INFO "DbG::_do_fwdl: " /* Now we need to reset the board */
"In ReplyMsg loop - iteration %d\n", mptctl_timeout_expired(iocp->ioctl);
i)); ret = -ENODATA;
} goto fwdl_out;
set_current_state(TASK_INTERRUPTIBLE);
schedule_timeout(1);
} }
if (sgl) if (sgl)
kfree_sgl(sgl, sgl_dma, buflist, iocp); kfree_sgl(sgl, sgl_dma, buflist, iocp);
ReplyMsg = (pFWDownloadReply_t)iocp->ioctl->ReplyFrame;
iocstat = le16_to_cpu(ReplyMsg->IOCStatus) & MPI_IOCSTATUS_MASK; iocstat = le16_to_cpu(ReplyMsg->IOCStatus) & MPI_IOCSTATUS_MASK;
if (iocstat == MPI_IOCSTATUS_SUCCESS) { if (iocstat == MPI_IOCSTATUS_SUCCESS) {
printk(KERN_INFO MYNAM ": F/W update successfully sent to %s!\n", iocp->name); printk(KERN_INFO MYNAM ": F/W update successfully sent to %s!\n", iocp->name);
...@@ -1194,14 +1138,14 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size) ...@@ -1194,14 +1138,14 @@ mptctl_getiocinfo (unsigned long arg, unsigned int data_size)
cim_rev = 0; /* obsolete */ cim_rev = 0; /* obsolete */
else else
return -EFAULT; return -EFAULT;
karg = kmalloc(data_size, GFP_KERNEL); karg = kmalloc(data_size, GFP_KERNEL);
if (karg == NULL) { if (karg == NULL) {
printk(KERN_ERR "%s::mpt_ioctl_iocinfo() @%d - no memory available!\n", printk(KERN_ERR "%s::mpt_ioctl_iocinfo() @%d - no memory available!\n",
__FILE__, __LINE__); __FILE__, __LINE__);
return -ENOMEM; return -ENOMEM;
} }
if (copy_from_user(karg, uarg, data_size)) { if (copy_from_user(karg, uarg, data_size)) {
printk(KERN_ERR "%s@%d::mptctl_getiocinfo - " printk(KERN_ERR "%s@%d::mptctl_getiocinfo - "
"Unable to read in mpt_ioctl_iocinfo struct @ %p\n", "Unable to read in mpt_ioctl_iocinfo struct @ %p\n",
...@@ -1826,8 +1770,8 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) ...@@ -1826,8 +1770,8 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
int iocnum, flagsLength; int iocnum, flagsLength;
int sz, rc = 0; int sz, rc = 0;
int msgContext; int msgContext;
int tm_flags_set = 0;
u16 req_idx; u16 req_idx;
ulong timeout;
dctlprintk(("mptctl_do_mpt_command called.\n")); dctlprintk(("mptctl_do_mpt_command called.\n"));
bufIn.kptr = bufOut.kptr = NULL; bufIn.kptr = bufOut.kptr = NULL;
...@@ -2043,7 +1987,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) ...@@ -2043,7 +1987,6 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
rc = -EPERM; rc = -EPERM;
goto done_free_mem; goto done_free_mem;
} }
tm_flags_set = 1;
} }
break; break;
...@@ -2195,136 +2138,108 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr) ...@@ -2195,136 +2138,108 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
mpt_add_sge(psge, flagsLength, (dma_addr_t) -1); mpt_add_sge(psge, flagsLength, (dma_addr_t) -1);
} }
/* The request is complete. Set the timer parameters
* and issue the request.
*/
if (karg.timeout > 0) {
ioc->ioctl->timer.expires = jiffies + HZ*karg.timeout;
} else {
ioc->ioctl->timer.expires = jiffies + HZ*MPT_IOCTL_DEFAULT_TIMEOUT;
}
ioc->ioctl->wait_done = 0; ioc->ioctl->wait_done = 0;
ioc->ioctl->status |= MPT_IOCTL_STATUS_TIMER_ACTIVE;
add_timer(&ioc->ioctl->timer);
if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) { if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
DBG_DUMP_TM_REQUEST_FRAME((u32 *)mf); DBG_DUMP_TM_REQUEST_FRAME((u32 *)mf);
rc = mpt_send_handshake_request(mptctl_id, ioc,
sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP); if (mpt_send_handshake_request(mptctl_id, ioc,
if (rc == 0) { sizeof(SCSITaskMgmt_t), (u32*)mf,
wait_event(mptctl_wait, ioc->ioctl->wait_done); CAN_SLEEP) != 0) {
} else { dfailprintk((MYIOC_s_ERR_FMT "_send_handshake FAILED!"
" (ioc %p, mf %p) \n", ioc->name,
ioc, mf));
mptctl_free_tm_flags(ioc); mptctl_free_tm_flags(ioc);
tm_flags_set= 0; rc = -ENODATA;
del_timer(&ioc->ioctl->timer); goto done_free_mem;
ioc->ioctl->status &= ~MPT_IOCTL_STATUS_TIMER_ACTIVE;
ioc->ioctl->status |= MPT_IOCTL_STATUS_TM_FAILED;
mpt_free_msg_frame(ioc, mf);
} }
} else {
} else
mpt_put_msg_frame(mptctl_id, ioc, mf); mpt_put_msg_frame(mptctl_id, ioc, mf);
wait_event(mptctl_wait, ioc->ioctl->wait_done);
}
mf = NULL; /* Now wait for the command to complete */
timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;
timeout = wait_event_interruptible_timeout(mptctl_wait,
ioc->ioctl->wait_done == 1,
HZ*timeout);
/* MF Cleanup: if(timeout <=0 && (ioc->ioctl->wait_done != 1 )) {
* If command failed and failure triggered a diagnostic reset /* Now we need to reset the board */
* OR a diagnostic reset happens during command processing,
* no data, messaging queues are reset (mf cannot be accessed), if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT)
* and status is DID_IOCRESET mptctl_free_tm_flags(ioc);
*
* If a user-requested bus reset fails to be handshaked, then mptctl_timeout_expired(ioc->ioctl);
* mf is returned to free queue and status is TM_FAILED.
*
* Otherise, the command completed and the mf was freed
# by ISR (mf cannot be touched).
*/
if (ioc->ioctl->status & MPT_IOCTL_STATUS_DID_IOCRESET) {
/* The timer callback deleted the
* timer and reset the adapter queues.
*/
printk(KERN_WARNING "%s@%d::mptctl_do_mpt_command - "
"Timeout Occurred on IOCTL! Reset IOC.\n", __FILE__, __LINE__);
tm_flags_set= 0;
rc = -ETIME;
} else if (ioc->ioctl->status & MPT_IOCTL_STATUS_TM_FAILED) {
/* User TM request failed! mf has not been freed.
*/
rc = -ENODATA; rc = -ENODATA;
} else { goto done_free_mem;
/* If a valid reply frame, copy to the user. }
* Offset 2: reply length in U32's
*/
if (ioc->ioctl->status & MPT_IOCTL_STATUS_RF_VALID) {
if (karg.maxReplyBytes < ioc->reply_sz) {
sz = min(karg.maxReplyBytes, 4*ioc->ioctl->ReplyFrame[2]);
} else {
sz = min(ioc->reply_sz, 4*ioc->ioctl->ReplyFrame[2]);
}
if (sz > 0) { mf = NULL;
if (copy_to_user(karg.replyFrameBufPtr,
&ioc->ioctl->ReplyFrame, sz)){
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " /* If a valid reply frame, copy to the user.
"Unable to write out reply frame %p\n", * Offset 2: reply length in U32's
__FILE__, __LINE__, karg.replyFrameBufPtr); */
rc = -ENODATA; if (ioc->ioctl->status & MPT_IOCTL_STATUS_RF_VALID) {
goto done_free_mem; if (karg.maxReplyBytes < ioc->reply_sz) {
} sz = min(karg.maxReplyBytes, 4*ioc->ioctl->ReplyFrame[2]);
} } else {
sz = min(ioc->reply_sz, 4*ioc->ioctl->ReplyFrame[2]);
} }
/* If valid sense data, copy to user. if (sz > 0) {
*/ if (copy_to_user(karg.replyFrameBufPtr,
if (ioc->ioctl->status & MPT_IOCTL_STATUS_SENSE_VALID) { &ioc->ioctl->ReplyFrame, sz)){
sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE); printk(KERN_ERR
if (sz > 0) { "%s@%d::mptctl_do_mpt_command - "
if (copy_to_user(karg.senseDataPtr, ioc->ioctl->sense, sz)) { "Unable to write out reply frame %p\n",
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " __FILE__, __LINE__, karg.replyFrameBufPtr);
"Unable to write sense data to user %p\n", rc = -ENODATA;
__FILE__, __LINE__, goto done_free_mem;
karg.senseDataPtr);
rc = -ENODATA;
goto done_free_mem;
}
} }
} }
}
/* If the overall status is _GOOD and data in, copy data /* If valid sense data, copy to user.
* to user. */
*/ if (ioc->ioctl->status & MPT_IOCTL_STATUS_SENSE_VALID) {
if ((ioc->ioctl->status & MPT_IOCTL_STATUS_COMMAND_GOOD) && sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE);
(karg.dataInSize > 0) && (bufIn.kptr)) { if (sz > 0) {
if (copy_to_user(karg.senseDataPtr, ioc->ioctl->sense, sz)) {
if (copy_to_user(karg.dataInBufPtr,
bufIn.kptr, karg.dataInSize)) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - " printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
"Unable to write data to user %p\n", "Unable to write sense data to user %p\n",
__FILE__, __LINE__, __FILE__, __LINE__,
karg.dataInBufPtr); karg.senseDataPtr);
rc = -ENODATA; rc = -ENODATA;
goto done_free_mem;
} }
} }
} }
done_free_mem: /* If the overall status is _GOOD and data in, copy data
/* Clear all status bits except TMTIMER_ACTIVE, this bit is cleared * to user.
* upon completion of the TM command.
* ioc->ioctl->status = 0;
*/ */
ioc->ioctl->status &= ~(MPT_IOCTL_STATUS_TIMER_ACTIVE | MPT_IOCTL_STATUS_TM_FAILED | if ((ioc->ioctl->status & MPT_IOCTL_STATUS_COMMAND_GOOD) &&
MPT_IOCTL_STATUS_COMMAND_GOOD | MPT_IOCTL_STATUS_SENSE_VALID | (karg.dataInSize > 0) && (bufIn.kptr)) {
MPT_IOCTL_STATUS_RF_VALID | MPT_IOCTL_STATUS_DID_IOCRESET);
if (tm_flags_set) if (copy_to_user(karg.dataInBufPtr,
mptctl_free_tm_flags(ioc); bufIn.kptr, karg.dataInSize)) {
printk(KERN_ERR "%s@%d::mptctl_do_mpt_command - "
"Unable to write data to user %p\n",
__FILE__, __LINE__,
karg.dataInBufPtr);
rc = -ENODATA;
}
}
done_free_mem:
ioc->ioctl->status &= ~(MPT_IOCTL_STATUS_COMMAND_GOOD |
MPT_IOCTL_STATUS_SENSE_VALID |
MPT_IOCTL_STATUS_RF_VALID );
/* Free the allocated memory. /* Free the allocated memory.
*/ */
if (bufOut.kptr != NULL) { if (bufOut.kptr != NULL) {
pci_free_consistent(ioc->pcidev, pci_free_consistent(ioc->pcidev,
bufOut.len, (void *) bufOut.kptr, dma_addr_out); bufOut.len, (void *) bufOut.kptr, dma_addr_out);
} }
...@@ -2563,7 +2478,7 @@ mptctl_hp_targetinfo(unsigned long arg) ...@@ -2563,7 +2478,7 @@ mptctl_hp_targetinfo(unsigned long arg)
__FILE__, __LINE__, uarg); __FILE__, __LINE__, uarg);
return -EFAULT; return -EFAULT;
} }
if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) || if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
(ioc == NULL)) { (ioc == NULL)) {
dctlprintk((KERN_ERR "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n", dctlprintk((KERN_ERR "%s::mptctl_hp_targetinfo() @%d - ioc%d not found!\n",
...@@ -2581,7 +2496,7 @@ mptctl_hp_targetinfo(unsigned long arg) ...@@ -2581,7 +2496,7 @@ mptctl_hp_targetinfo(unsigned long arg)
if (ioc->sh->host_no != karg.hdr.host) if (ioc->sh->host_no != karg.hdr.host)
return -ENODEV; return -ENODEV;
/* Get the data transfer speeds /* Get the data transfer speeds
*/ */
data_sz = ioc->spi_data.sdp0length * 4; data_sz = ioc->spi_data.sdp0length * 4;
...@@ -2701,14 +2616,6 @@ static struct miscdevice mptctl_miscdev = { ...@@ -2701,14 +2616,6 @@ static struct miscdevice mptctl_miscdev = {
#include <linux/ioctl32.h> #include <linux/ioctl32.h>
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* compat_XXX functions are used to provide a conversion between
* pointers and u32's. If the arg does not contain any pointers, then
* a specialized function (compat_XXX) is not needed. If the arg
* does contain pointer(s), then the specialized function is used
* to ensure the structure contents is properly processed by mptctl.
*/
static int static int
compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd, compat_mptfwxfer_ioctl(struct file *filp, unsigned int cmd,
unsigned long arg) unsigned long arg)
...@@ -2804,9 +2711,9 @@ compat_mpt_command(struct file *filp, unsigned int cmd, ...@@ -2804,9 +2711,9 @@ compat_mpt_command(struct file *filp, unsigned int cmd,
static long compat_mpctl_ioctl(struct file *f, unsigned int cmd, unsigned long arg) static long compat_mpctl_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
{ {
int ret; long ret;
lock_kernel(); lock_kernel();
switch (cmd) { switch (cmd) {
case MPTIOCINFO: case MPTIOCINFO:
case MPTIOCINFO1: case MPTIOCINFO1:
case MPTIOCINFO2: case MPTIOCINFO2:
...@@ -2867,12 +2774,6 @@ mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -2867,12 +2774,6 @@ mptctl_probe(struct pci_dev *pdev, const struct pci_device_id *id)
memset(mem, 0, sz); memset(mem, 0, sz);
ioc->ioctl = (MPT_IOCTL *) mem; ioc->ioctl = (MPT_IOCTL *) mem;
ioc->ioctl->ioc = ioc; ioc->ioctl->ioc = ioc;
init_timer (&ioc->ioctl->timer);
ioc->ioctl->timer.data = (unsigned long) ioc->ioctl;
ioc->ioctl->timer.function = mptctl_timer_expired;
init_timer (&ioc->ioctl->TMtimer);
ioc->ioctl->TMtimer.data = (unsigned long) ioc->ioctl;
ioc->ioctl->TMtimer.function = mptctl_timer_expired;
sema_init(&ioc->ioctl->sem_ioc, 1); sema_init(&ioc->ioctl->sem_ioc, 1);
return 0; return 0;
...@@ -2916,7 +2817,6 @@ static int __init mptctl_init(void) ...@@ -2916,7 +2817,6 @@ static int __init mptctl_init(void)
": failed to register dd callbacks\n")); ": failed to register dd callbacks\n"));
} }
/* Register this device */ /* Register this device */
err = misc_register(&mptctl_miscdev); err = misc_register(&mptctl_miscdev);
if (err < 0) { if (err < 0) {
...@@ -2948,7 +2848,6 @@ static int __init mptctl_init(void) ...@@ -2948,7 +2848,6 @@ static int __init mptctl_init(void)
out_fail: out_fail:
mpt_device_driver_deregister(MPTCTL_DRIVER); mpt_device_driver_deregister(MPTCTL_DRIVER);
return err; return err;
......
...@@ -179,10 +179,11 @@ static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt, ...@@ -179,10 +179,11 @@ static int mptscsih_AddSGE(MPT_ADAPTER *ioc, struct scsi_cmnd *SCpnt,
static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx); static void mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx);
static void copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply); static void copy_sense_data(struct scsi_cmnd *sc, MPT_SCSI_HOST *hd, MPT_FRAME_HDR *mf, SCSIIOReply_t *pScsiReply);
static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd); static int mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd);
static int mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout );
static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc); static u32 SCPNT_TO_LOOKUP_IDX(struct scsi_cmnd *sc);
static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag); static int mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag); static int mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout);
static int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset); static int mptscsih_ioc_reset(MPT_ADAPTER *ioc, int post_reset);
static int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply); static int mptscsih_event_process(MPT_ADAPTER *ioc, EventNotificationReply_t *pEvReply);
...@@ -196,13 +197,9 @@ static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int fl ...@@ -196,13 +197,9 @@ static int mptscsih_writeSDP1(MPT_SCSI_HOST *hd, int portnum, int target, int fl
static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus); static int mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus);
static int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r); static int mptscsih_scandv_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *r);
static void mptscsih_timer_expired(unsigned long data); static void mptscsih_timer_expired(unsigned long data);
static void mptscsih_taskmgmt_timeout(unsigned long data);
static void mptscsih_schedule_reset(void *hd);
static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd); static int mptscsih_do_cmd(MPT_SCSI_HOST *hd, INTERNAL_CMD *iocmd);
static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum); static int mptscsih_synchronize_cache(MPT_SCSI_HOST *hd, int portnum);
static struct work_struct mptscsih_rstTask;
#ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION #ifdef MPTSCSIH_ENABLE_DOMAIN_VALIDATION
static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io); static int mptscsih_do_raid(MPT_SCSI_HOST *hd, u8 action, INTERNAL_CMD *io);
static void mptscsih_domainValidation(void *hd); static void mptscsih_domainValidation(void *hd);
...@@ -1207,7 +1204,6 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1207,7 +1204,6 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hd->tmState = TM_STATE_NONE; hd->tmState = TM_STATE_NONE;
hd->resetPending = 0; hd->resetPending = 0;
hd->abortSCpnt = NULL; hd->abortSCpnt = NULL;
hd->tmPtr = NULL;
/* Clear the pointer used to store /* Clear the pointer used to store
* single-threaded commands, i.e., those * single-threaded commands, i.e., those
...@@ -1224,14 +1220,6 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id) ...@@ -1224,14 +1220,6 @@ mptscsih_probe(struct pci_dev *pdev, const struct pci_device_id *id)
hd->timer.data = (unsigned long) hd; hd->timer.data = (unsigned long) hd;
hd->timer.function = mptscsih_timer_expired; hd->timer.function = mptscsih_timer_expired;
init_timer(&hd->TMtimer);
hd->TMtimer.data = (unsigned long) hd;
hd->TMtimer.function = mptscsih_taskmgmt_timeout;
hd->qtag_tick = jiffies;
/* Moved Earlier Pam D */
/* ioc->sh = sh; */
if (ioc->bus_type == SCSI) { if (ioc->bus_type == SCSI) {
/* Update with the driver setup /* Update with the driver setup
* values. * values.
...@@ -1925,7 +1913,6 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx) ...@@ -1925,7 +1913,6 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
* @target: Logical Target ID for reset (if appropriate) * @target: Logical Target ID for reset (if appropriate)
* @lun: Logical Unit for reset (if appropriate) * @lun: Logical Unit for reset (if appropriate)
* @ctx2abort: Context for the task to be aborted (if appropriate) * @ctx2abort: Context for the task to be aborted (if appropriate)
* @sleepFlag: If set, use udelay instead of schedule in handshake code.
* *
* Remark: Currently invoked from a non-interrupt thread (_bh). * Remark: Currently invoked from a non-interrupt thread (_bh).
* *
...@@ -1935,7 +1922,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx) ...@@ -1935,7 +1922,7 @@ mptscsih_freeChainBuffers(MPT_ADAPTER *ioc, int req_idx)
* Returns 0 for SUCCESS or -1 if FAILED. * Returns 0 for SUCCESS or -1 if FAILED.
*/ */
static int static int
mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag) mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
{ {
MPT_ADAPTER *ioc; MPT_ADAPTER *ioc;
int rc = -1; int rc = -1;
...@@ -2015,7 +2002,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in ...@@ -2015,7 +2002,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
*/ */
if (hd->hard_resets < -1) if (hd->hard_resets < -1)
hd->hard_resets++; hd->hard_resets++;
rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout, sleepFlag); rc = mptscsih_IssueTaskMgmt(hd, type, channel, target, lun, ctx2abort, timeout);
if (rc) { if (rc) {
printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name); printk(MYIOC_s_INFO_FMT "Issue of TaskMgmt failed!\n", hd->ioc->name);
} else { } else {
...@@ -2029,7 +2016,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in ...@@ -2029,7 +2016,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) { ioc->reload_fw || (ioc->alt_ioc && ioc->alt_ioc->reload_fw))) {
dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n", dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
hd->ioc->name)); hd->ioc->name));
rc = mpt_HardResetHandler(hd->ioc, sleepFlag); rc = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
} }
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));
...@@ -2046,7 +2033,6 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in ...@@ -2046,7 +2033,6 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
* @target: Logical Target ID for reset (if appropriate) * @target: Logical Target ID for reset (if appropriate)
* @lun: Logical Unit for reset (if appropriate) * @lun: Logical Unit for reset (if appropriate)
* @ctx2abort: Context for the task to be aborted (if appropriate) * @ctx2abort: Context for the task to be aborted (if appropriate)
* @sleepFlag: If set, use udelay instead of schedule in handshake code.
* *
* Remark: _HardResetHandler can be invoked from an interrupt thread (timer) * Remark: _HardResetHandler can be invoked from an interrupt thread (timer)
* or a non-interrupt thread. In the former, must not call schedule(). * or a non-interrupt thread. In the former, must not call schedule().
...@@ -2057,7 +2043,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in ...@@ -2057,7 +2043,7 @@ mptscsih_TMHandler(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, in
* else other non-zero value returned. * else other non-zero value returned.
*/ */
static int static int
mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout, int sleepFlag) mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun, int ctx2abort, ulong timeout)
{ {
MPT_FRAME_HDR *mf; MPT_FRAME_HDR *mf;
SCSITaskMgmt_t *pScsiTm; SCSITaskMgmt_t *pScsiTm;
...@@ -2087,7 +2073,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun ...@@ -2087,7 +2073,7 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
pScsiTm->TaskType = type; pScsiTm->TaskType = type;
pScsiTm->Reserved1 = 0; pScsiTm->Reserved1 = 0;
pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS) pScsiTm->MsgFlags = (type == MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS)
? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0; ? MPI_SCSITASKMGMT_MSGFLAGS_LIPRESET_RESET_OPTION : 0;
for (ii= 0; ii < 8; ii++) { for (ii= 0; ii < 8; ii++) {
pScsiTm->LUN[ii] = 0; pScsiTm->LUN[ii] = 0;
...@@ -2099,29 +2085,32 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun ...@@ -2099,29 +2085,32 @@ mptscsih_IssueTaskMgmt(MPT_SCSI_HOST *hd, u8 type, u8 channel, u8 target, u8 lun
pScsiTm->TaskMsgContext = ctx2abort; pScsiTm->TaskMsgContext = ctx2abort;
/* MPI v0.10 requires SCSITaskMgmt requests be sent via Doorbell/handshake dtmprintk((MYIOC_s_INFO_FMT
mpt_put_msg_frame(hd->ioc->id, mf); "IssueTaskMgmt: ctx2abort (0x%08x) type=%d\n",
* Save the MF pointer in case the request times out. hd->ioc->name, ctx2abort, type));
*/
hd->tmPtr = mf;
hd->TMtimer.expires = jiffies + timeout;
add_timer(&hd->TMtimer);
dtmprintk((MYIOC_s_INFO_FMT "IssueTaskMgmt: ctx2abort (0x%08x) 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(ScsiTaskCtx, hd->ioc, if ((retval = mpt_send_handshake_request(ScsiTaskCtx, hd->ioc,
sizeof(SCSITaskMgmt_t), (u32*)pScsiTm, sleepFlag)) sizeof(SCSITaskMgmt_t), (u32*)pScsiTm,
!= 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) \n", hd->ioc->name, hd, hd->ioc, mf)); " (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
hd->tmPtr = NULL; hd->ioc, mf));
del_timer(&hd->TMtimer);
mpt_free_msg_frame(hd->ioc, mf); mpt_free_msg_frame(hd->ioc, mf);
return retval;
} }
if(mptscsih_tm_wait_for_completion(hd, timeout) == FAILED) {
dfailprintk((MYIOC_s_ERR_FMT "_wait_for_completion FAILED!"
" (hd %p, ioc %p, mf %p) \n", hd->ioc->name, hd,
hd->ioc, mf));
mpt_free_msg_frame(hd->ioc, mf);
dtmprintk((MYIOC_s_INFO_FMT "Calling HardReset! \n",
hd->ioc->name));
retval = mpt_HardResetHandler(hd->ioc, CAN_SLEEP);
}
return retval; return retval;
} }
...@@ -2187,13 +2176,13 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) ...@@ -2187,13 +2176,13 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
*/ */
mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx); mf = MPT_INDEX_2_MFPTR(hd->ioc, scpnt_idx);
ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext; ctx2abort = mf->u.frame.hwhdr.msgctxu.MsgContext;
hd->abortSCpnt = SCpnt; hd->abortSCpnt = SCpnt;
spin_unlock_irq(host_lock); spin_unlock_irq(host_lock);
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK, if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_ABORT_TASK,
SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun, SCpnt->device->channel, SCpnt->device->id, SCpnt->device->lun,
ctx2abort, (HZ*2) /* 2 second timeout */,CAN_SLEEP) ctx2abort, 2 /* 2 second timeout */)
< 0) { < 0) {
/* The TM request failed and the subsequent FW-reload failed! /* The TM request failed and the subsequent FW-reload failed!
...@@ -2206,7 +2195,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) ...@@ -2206,7 +2195,7 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
*/ */
hd->tmPending = 0; hd->tmPending = 0;
hd->tmState = TM_STATE_NONE; hd->tmState = TM_STATE_NONE;
spin_lock_irq(host_lock); spin_lock_irq(host_lock);
/* Unmap the DMA buffers, if any. */ /* Unmap the DMA buffers, if any. */
...@@ -2226,7 +2215,6 @@ mptscsih_abort(struct scsi_cmnd * SCpnt) ...@@ -2226,7 +2215,6 @@ mptscsih_abort(struct scsi_cmnd * SCpnt)
} }
spin_lock_irq(host_lock); spin_lock_irq(host_lock);
return SUCCESS; return SUCCESS;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
...@@ -2259,15 +2247,10 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt) ...@@ -2259,15 +2247,10 @@ mptscsih_dev_reset(struct scsi_cmnd * SCpnt)
printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n", printk(KERN_WARNING MYNAM ": %s: >> Attempting target reset! (sc=%p)\n",
hd->ioc->name, SCpnt); hd->ioc->name, SCpnt);
/* Supported for FC only.
*/
if (hd->ioc->bus_type == SCSI)
return FAILED;
spin_unlock_irq(host_lock); spin_unlock_irq(host_lock);
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET, if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_TARGET_RESET,
SCpnt->device->channel, SCpnt->device->id, SCpnt->device->channel, SCpnt->device->id,
0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP) 0, 0, 5 /* 5 second timeout */)
< 0){ < 0){
/* The TM request failed and the subsequent FW-reload failed! /* The TM request failed and the subsequent FW-reload failed!
* Fatal error case. * Fatal error case.
...@@ -2317,7 +2300,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt) ...@@ -2317,7 +2300,7 @@ mptscsih_bus_reset(struct scsi_cmnd * SCpnt)
/* We are now ready to execute the task management request. */ /* We are now ready to execute the task management request. */
spin_unlock_irq(host_lock); spin_unlock_irq(host_lock);
if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS, if (mptscsih_TMHandler(hd, MPI_SCSITASKMGMT_TASKTYPE_RESET_BUS,
SCpnt->device->channel, 0, 0, 0, (HZ*5) /* 5 second timeout */, CAN_SLEEP) SCpnt->device->channel, 0, 0, 0, 5 /* 5 second timeout */)
< 0){ < 0){
/* The TM request failed and the subsequent FW-reload failed! /* The TM request failed and the subsequent FW-reload failed!
...@@ -2398,7 +2381,7 @@ static int ...@@ -2398,7 +2381,7 @@ static int
mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd) mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
{ {
unsigned long flags; unsigned long flags;
int loop_count = 10 * 4; /* Wait 10 seconds */ int loop_count = 4 * 10; /* Wait 10 seconds */
int status = FAILED; int status = FAILED;
do { do {
...@@ -2406,8 +2389,8 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd) ...@@ -2406,8 +2389,8 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
if (hd->tmState == TM_STATE_NONE) { if (hd->tmState == TM_STATE_NONE) {
hd->tmState = TM_STATE_IN_PROGRESS; hd->tmState = TM_STATE_IN_PROGRESS;
hd->tmPending = 1; hd->tmPending = 1;
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
status = SUCCESS; status = SUCCESS;
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
break; break;
} }
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags); spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
...@@ -2417,6 +2400,34 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd) ...@@ -2417,6 +2400,34 @@ mptscsih_tm_pending_wait(MPT_SCSI_HOST * hd)
return status; return status;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/**
* mptscsih_tm_wait_for_completion - wait for completion of TM task
* @hd: Pointer to MPT host structure.
*
* Returns {SUCCESS,FAILED}.
*/
static int
mptscsih_tm_wait_for_completion(MPT_SCSI_HOST * hd, ulong timeout )
{
unsigned long flags;
int loop_count = 4 * timeout;
int status = FAILED;
do {
spin_lock_irqsave(&hd->ioc->FreeQlock, flags);
if(hd->tmPending == 0) {
status = SUCCESS;
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
break;
}
spin_unlock_irqrestore(&hd->ioc->FreeQlock, flags);
msleep_interruptible(250);
} while (--loop_count);
return status;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/** /**
* mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver * mptscsih_taskmgmt_complete - Registered with Fusion MPT base driver
...@@ -2449,9 +2460,6 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m ...@@ -2449,9 +2460,6 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
* Decrement count of outstanding TM requests. * Decrement count of outstanding TM requests.
*/ */
hd = (MPT_SCSI_HOST *)ioc->sh->hostdata; hd = (MPT_SCSI_HOST *)ioc->sh->hostdata;
if (hd->tmPtr) {
del_timer(&hd->TMtimer);
}
} else { } else {
dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n", dtmprintk((MYIOC_s_WARN_FMT "TaskMgmt Complete: NULL Scsi Host Ptr\n",
ioc->name)); ioc->name));
...@@ -2505,7 +2513,6 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m ...@@ -2505,7 +2513,6 @@ mptscsih_taskmgmt_complete(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *m
} }
} }
hd->tmPtr = NULL;
spin_lock_irqsave(&ioc->FreeQlock, flags); spin_lock_irqsave(&ioc->FreeQlock, flags);
hd->tmPending = 0; hd->tmPending = 0;
spin_unlock_irqrestore(&ioc->FreeQlock, flags); spin_unlock_irqrestore(&ioc->FreeQlock, flags);
...@@ -2913,14 +2920,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) ...@@ -2913,14 +2920,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
mpt_free_msg_frame(ioc, hd->cmdPtr); mpt_free_msg_frame(ioc, hd->cmdPtr);
} }
/* 2d. If a task management has not completed,
* free resources associated with this request.
*/
if (hd->tmPtr) {
del_timer(&hd->TMtimer);
mpt_free_msg_frame(ioc, hd->tmPtr);
}
dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name)); dtmprintk((MYIOC_s_WARN_FMT "Pre-Reset complete.\n", ioc->name));
} else { } else {
...@@ -2942,12 +2941,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase) ...@@ -2942,12 +2941,6 @@ mptscsih_ioc_reset(MPT_ADAPTER *ioc, int reset_phase)
/* 2. Chain Buffer initialization /* 2. Chain Buffer initialization
*/ */
/* 3. tmPtr clear
*/
if (hd->tmPtr) {
hd->tmPtr = NULL;
}
/* 4. Renegotiate to all devices, if SCSI /* 4. Renegotiate to all devices, if SCSI
*/ */
if (ioc->bus_type == SCSI) { if (ioc->bus_type == SCSI) {
...@@ -3810,60 +3803,6 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus) ...@@ -3810,60 +3803,6 @@ mptscsih_writeIOCPage4(MPT_SCSI_HOST *hd, int target_id, int bus)
return 0; return 0;
} }
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptscsih_taskmgmt_timeout - Call back for timeout on a
* task management request.
* @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
*
*/
static void mptscsih_taskmgmt_timeout(unsigned long data)
{
MPT_SCSI_HOST *hd = (MPT_SCSI_HOST *) data;
dtmprintk((KERN_WARNING MYNAM ": %s: mptscsih_taskmgmt_timeout: "
"TM request timed out!\n", hd->ioc->name));
/* Delete the timer that triggered this callback.
* Remark: del_timer checks to make sure timer is active
* before deleting.
*/
del_timer(&hd->TMtimer);
/* Call the reset handler. Already had a TM request
* timeout - so issue a diagnostic reset
*/
INIT_WORK(&mptscsih_rstTask, mptscsih_schedule_reset, (void *)hd);
schedule_work(&mptscsih_rstTask);
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* mptscsih_schedule_reset - Call back for timeout on a
* task management request.
* @data: Pointer to MPT_SCSI_HOST recast as an unsigned long
*
*/
static void
mptscsih_schedule_reset(void *arg)
{
MPT_SCSI_HOST *hd;
hd = (MPT_SCSI_HOST *) arg;
if (mpt_HardResetHandler(hd->ioc, CAN_SLEEP) < 0) {
printk((KERN_WARNING " Firmware Reload FAILED!!\n"));
} else {
/* Because we have reset the IOC, no TM requests can be
* pending. So let's make sure the tmPending flag is reset.
*/
dtmprintk((KERN_WARNING MYNAM
": %s: mptscsih_taskmgmt_timeout\n",
hd->ioc->name));
hd->tmPending = 0;
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/ /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
/* /*
* Bus Scan and Domain Validation functionality ... * Bus Scan and Domain Validation functionality ...
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment