summaryrefslogtreecommitdiffstats
path: root/drivers/message/fusion/mptctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/message/fusion/mptctl.c')
-rw-r--r--drivers/message/fusion/mptctl.c53
1 files changed, 37 insertions, 16 deletions
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index f06b29193b4e..a3856ed90aef 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -54,7 +54,7 @@
#include <linux/pci.h>
#include <linux/delay.h> /* for mdelay */
#include <linux/miscdevice.h>
-#include <linux/smp_lock.h>
+#include <linux/mutex.h>
#include <linux/compat.h>
#include <asm/io.h>
@@ -83,6 +83,7 @@ MODULE_VERSION(my_VERSION);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
+static DEFINE_MUTEX(mpctl_mutex);
static u8 mptctl_id = MPT_MAX_PROTOCOL_DRIVERS;
static u8 mptctl_taskmgmt_id = MPT_MAX_PROTOCOL_DRIVERS;
@@ -261,10 +262,16 @@ mptctl_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *req, MPT_FRAME_HDR *reply)
/* We are done, issue wake up
*/
if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_PENDING) {
- if (req->u.hdr.Function == MPI_FUNCTION_SCSI_TASK_MGMT)
+ if (req->u.hdr.Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
mpt_clear_taskmgmt_in_progress_flag(ioc);
- ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
- complete(&ioc->ioctl_cmds.done);
+ ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
+ complete(&ioc->ioctl_cmds.done);
+ if (ioc->bus_type == SAS)
+ ioc->schedule_target_reset(ioc);
+ } else {
+ ioc->ioctl_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
+ complete(&ioc->ioctl_cmds.done);
+ }
}
out_continuation:
@@ -298,6 +305,8 @@ mptctl_taskmgmt_reply(MPT_ADAPTER *ioc, MPT_FRAME_HDR *mf, MPT_FRAME_HDR *mr)
mpt_clear_taskmgmt_in_progress_flag(ioc);
ioc->taskmgmt_cmds.status &= ~MPT_MGMT_STATUS_PENDING;
complete(&ioc->taskmgmt_cmds.done);
+ if (ioc->bus_type == SAS)
+ ioc->schedule_target_reset(ioc);
return 1;
}
return 0;
@@ -593,12 +602,12 @@ mptctl_fasync(int fd, struct file *filep, int mode)
MPT_ADAPTER *ioc;
int ret;
- lock_kernel();
+ mutex_lock(&mpctl_mutex);
list_for_each_entry(ioc, &ioc_list, list)
ioc->aen_event_read_flag=0;
ret = fasync_helper(fd, filep, mode, &async_queue);
- unlock_kernel();
+ mutex_unlock(&mpctl_mutex);
return ret;
}
@@ -690,9 +699,9 @@ static long
mptctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
long ret;
- lock_kernel();
+ mutex_lock(&mpctl_mutex);
ret = __mptctl_ioctl(file, cmd, arg);
- unlock_kernel();
+ mutex_unlock(&mpctl_mutex);
return ret;
}
@@ -946,9 +955,12 @@ retry_wait:
mpt_free_msg_frame(iocp, mf);
goto fwdl_out;
}
- if (!timeleft)
+ if (!timeleft) {
+ printk(MYIOC_s_WARN_FMT
+ "FW download timeout, doorbell=0x%08x\n",
+ iocp->name, mpt_GetIocState(iocp, 0));
mptctl_timeout_expired(iocp, mf);
- else
+ } else
goto retry_wait;
goto fwdl_out;
}
@@ -2293,6 +2305,10 @@ retry_wait:
goto done_free_mem;
}
if (!timeleft) {
+ printk(MYIOC_s_WARN_FMT
+ "mpt cmd timeout, doorbell=0x%08x"
+ " function=0x%x\n",
+ ioc->name, mpt_GetIocState(ioc, 0), function);
if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
mutex_unlock(&ioc->taskmgmt_cmds.mutex);
mptctl_timeout_expired(ioc, mf);
@@ -2600,9 +2616,12 @@ retry_wait:
mpt_free_msg_frame(ioc, mf);
goto out;
}
- if (!timeleft)
+ if (!timeleft) {
+ printk(MYIOC_s_WARN_FMT
+ "HOST INFO command timeout, doorbell=0x%08x\n",
+ ioc->name, mpt_GetIocState(ioc, 0));
mptctl_timeout_expired(ioc, mf);
- else
+ } else
goto retry_wait;
goto out;
}
@@ -2908,7 +2927,7 @@ compat_mpt_command(struct file *filp, unsigned int cmd,
static long compat_mpctl_ioctl(struct file *f, unsigned int cmd, unsigned long arg)
{
long ret;
- lock_kernel();
+ mutex_lock(&mpctl_mutex);
switch (cmd) {
case MPTIOCINFO:
case MPTIOCINFO1:
@@ -2933,7 +2952,7 @@ static long compat_mpctl_ioctl(struct file *f, unsigned int cmd, unsigned long a
ret = -ENOIOCTLCMD;
break;
}
- unlock_kernel();
+ mutex_unlock(&mpctl_mutex);
return ret;
}
@@ -3000,7 +3019,8 @@ static int __init mptctl_init(void)
* Install our handler
*/
++where;
- mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER);
+ mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER,
+ "mptctl_reply");
if (!mptctl_id || mptctl_id >= MPT_MAX_PROTOCOL_DRIVERS) {
printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
misc_deregister(&mptctl_miscdev);
@@ -3008,7 +3028,8 @@ static int __init mptctl_init(void)
goto out_fail;
}
- mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER);
+ mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER,
+ "mptctl_taskmgmt_reply");
if (!mptctl_taskmgmt_id || mptctl_taskmgmt_id >= MPT_MAX_PROTOCOL_DRIVERS) {
printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
mpt_deregister(mptctl_id);