* [PATCH] lsilogic mpt fusion: mptctl: Fixed race condition around mptctl_id variable using mutexes
@ 2019-08-14 15:14 Mark Balantzyan
0 siblings, 0 replies; 5+ messages in thread
From: Mark Balantzyan @ 2019-08-14 15:14 UTC (permalink / raw)
To: sathya.prakash
Cc: suganath-prabu.subramani, MPT-FusionLinux.pdl, linux-scsi,
linux-kernel, Mark Balantzyan
Certain functions in the driver, such as mptctl_do_fw_download() and
mptctl_do_mpt_command(), rely on the instance of mptctl_id, which does the
id-ing. There is race condition possible when these functions operate in
concurrency. Via, mutexes, the functions are mutually signalled to cooperate.
Signed-off-by: Mark Balantzyan <mbalant3@gmail.com>
---
drivers/message/fusion/mptctl.c | 36 ++++++++++++++++++++++++++-------
1 file changed, 29 insertions(+), 7 deletions(-)
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 4470630d..58ce0fc0 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -816,12 +816,15 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
/* Valid device. Get a message frame and construct the FW download message.
*/
+ mutex_lock(&mpctl_mutex);
if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
+ mutex_unlock(&mpctl_mutex);
return -EAGAIN;
}
-
+ mutex_lock(&mpctl_mutex);
dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT
"mptctl_do_fwdl called. mptctl_id = %xh.\n", iocp->name, mptctl_id));
+ mutex_unlock(&mpctl_mutex);
dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.bufp = %p\n",
iocp->name, ufwbuf));
dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.fwlen = %d\n",
@@ -943,7 +946,9 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
ReplyMsg = NULL;
SET_MGMT_MSG_CONTEXT(iocp->ioctl_cmds.msg_context, dlmsg->MsgContext);
INITIALIZE_MGMT_STATUS(iocp->ioctl_cmds.status)
+ mutex_lock(&mpctl_mutex);
mpt_put_msg_frame(mptctl_id, iocp, mf);
+ mutex_lock(&mpctl_mutex);
/* Now wait for the command to complete */
retry_wait:
@@ -1889,7 +1894,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
/* Get a free request frame and save the message context.
*/
+ mutex_lock(&mpctl_mutex);
if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
+ mutex_unlock(&mpctl_mutex);
return -EAGAIN;
hdr = (MPIHeader_t *) mf;
@@ -2271,11 +2278,14 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
- (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
+ (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) {
+ mutex_lock(&mpctl_mutex);
mpt_put_msg_frame_hi_pri(mptctl_id, ioc, mf);
- else {
- rc =mpt_send_handshake_request(mptctl_id, ioc,
- sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP);
+ mutex_unlock(&mpctl_mutex);
+ } else {
+ mutex_lock(&mpctl_mutex);
+ rc = mpt_send_handshake_request(mptctl_id, ioc, sizeof(SCSITaskMgmt_t), (u32 *)mf, CAN_SLEEP);
+ mutex_unlock(&mpctl_mutex);
if (rc != 0) {
dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
"send_handshake FAILED! (ioc %p, mf %p)\n",
@@ -2288,7 +2298,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
}
} else
+ mutex_lock(&mpctl_mutex);
mpt_put_msg_frame(mptctl_id, ioc, mf);
+ mutex_unlock(&mpctl_mutex);
/* Now wait for the command to complete */
timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;
@@ -2563,7 +2575,9 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
/*
* Gather ISTWI(Industry Standard Two Wire Interface) Data
*/
+ mutex_lock(&mpctl_mutex);
if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
+ mutex_unlock(&mpctl_mutex);
dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
"%s, no msg frames!!\n", ioc->name, __func__));
goto out;
@@ -2593,7 +2607,9 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context,
IstwiRWRequest->MsgContext);
INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
+ mutex_lock(&mpctl_mutex);
mpt_put_msg_frame(mptctl_id, ioc, mf);
+ mutex_unlock(&mpctl_mutex);
retry_wait:
timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
@@ -3010,9 +3026,11 @@ static int __init mptctl_init(void)
* Install our handler
*/
++where;
+ mutex_lock(&mpctl_mutex);
mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER,
"mptctl_reply");
if (!mptctl_id || mptctl_id >= MPT_MAX_PROTOCOL_DRIVERS) {
+ mutex_unlock(&mpctl_mutex);
printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
misc_deregister(&mptctl_miscdev);
err = -EBUSY;
@@ -3022,13 +3040,14 @@ static int __init mptctl_init(void)
mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER,
"mptctl_taskmgmt_reply");
if (!mptctl_taskmgmt_id || mptctl_taskmgmt_id >= MPT_MAX_PROTOCOL_DRIVERS) {
+ mutex_unlock(&mpctl_mutex);
printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
mpt_deregister(mptctl_id);
misc_deregister(&mptctl_miscdev);
err = -EBUSY;
goto out_fail;
}
-
+ mutex_unlock(&mpctl_mutex);
mpt_reset_register(mptctl_id, mptctl_ioc_reset);
mpt_event_register(mptctl_id, mptctl_event_process);
@@ -3044,13 +3063,14 @@ out_fail:
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static void mptctl_exit(void)
{
+ mutex_lock(&mpctl_mutex);
misc_deregister(&mptctl_miscdev);
printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
/* De-register event handler from base module */
mpt_event_deregister(mptctl_id);
-
+
/* De-register reset handler from base module */
mpt_reset_deregister(mptctl_id);
@@ -3058,6 +3078,8 @@ static void mptctl_exit(void)
mpt_deregister(mptctl_taskmgmt_id);
mpt_deregister(mptctl_id);
+ mutex_unlock(&mpctl_mutex);
+
mpt_device_driver_deregister(MPTCTL_DRIVER);
}
--
2.17.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] lsilogic mpt fusion: mptctl: Fixed race condition around mptctl_id variable using mutexes
2019-08-14 20:48 Mark Balantzyan
@ 2019-08-15 5:51 ` kbuild test robot
0 siblings, 0 replies; 5+ messages in thread
From: kbuild test robot @ 2019-08-15 5:51 UTC (permalink / raw)
To: Mark Balantzyan
Cc: kbuild-all, sathya.prakash, suganath-prabu.subramani,
MPT-FusionLinux.pdl, linux-scsi, linux-kernel, Mark Balantzyan
[-- Attachment #1: Type: text/plain, Size: 21196 bytes --]
Hi Mark,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on linus/master]
[cannot apply to v5.3-rc4 next-20190814]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Mark-Balantzyan/lsilogic-mpt-fusion-mptctl-Fixed-race-condition-around-mptctl_id-variable-using-mutexes/20190815-115822
config: x86_64-lkp (attached as .config)
compiler: gcc-7 (Debian 7.4.0-10) 7.4.0
reproduce:
# save the attached .config to linux build tree
make ARCH=x86_64
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
drivers/message/fusion/mptctl.c: In function 'mptctl_do_fw_download':
>> drivers/message/fusion/mptctl.c:820:3: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
^~
drivers/message/fusion/mptctl.c:822:4: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
return -EAGAIN;
^~~~~~
drivers/message/fusion/mptctl.c: In function 'mptctl_do_mpt_command':
drivers/message/fusion/mptctl.c:1898:9: warning: this 'if' clause does not guard... [-Wmisleading-indentation]
if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
^~
drivers/message/fusion/mptctl.c:1900:17: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'if'
return -EAGAIN;
^~~~~~
vim +/if +820 drivers/message/fusion/mptctl.c
^1da177e4c3f41 Linus Torvalds 2005-04-16 771
^1da177e4c3f41 Linus Torvalds 2005-04-16 772 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^1da177e4c3f41 Linus Torvalds 2005-04-16 773 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 774 * FW Download engine.
^1da177e4c3f41 Linus Torvalds 2005-04-16 775 * Outputs: None.
^1da177e4c3f41 Linus Torvalds 2005-04-16 776 * Return: 0 if successful
^1da177e4c3f41 Linus Torvalds 2005-04-16 777 * -EFAULT if data unavailable
^1da177e4c3f41 Linus Torvalds 2005-04-16 778 * -ENXIO if no such device
^1da177e4c3f41 Linus Torvalds 2005-04-16 779 * -EAGAIN if resource problem
^1da177e4c3f41 Linus Torvalds 2005-04-16 780 * -ENOMEM if no memory for SGE
^1da177e4c3f41 Linus Torvalds 2005-04-16 781 * -EMLINK if too many chain buffers required
^1da177e4c3f41 Linus Torvalds 2005-04-16 782 * -EBADRQC if adapter does not support FW download
^1da177e4c3f41 Linus Torvalds 2005-04-16 783 * -EBUSY if adapter is busy
^1da177e4c3f41 Linus Torvalds 2005-04-16 784 * -ENOMSG if FW upload returned bad status
^1da177e4c3f41 Linus Torvalds 2005-04-16 785 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 786 static int
^1da177e4c3f41 Linus Torvalds 2005-04-16 787 mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
^1da177e4c3f41 Linus Torvalds 2005-04-16 788 {
^1da177e4c3f41 Linus Torvalds 2005-04-16 789 FWDownload_t *dlmsg;
^1da177e4c3f41 Linus Torvalds 2005-04-16 790 MPT_FRAME_HDR *mf;
^1da177e4c3f41 Linus Torvalds 2005-04-16 791 MPT_ADAPTER *iocp;
^1da177e4c3f41 Linus Torvalds 2005-04-16 792 FWDownloadTCSGE_t *ptsge;
^1da177e4c3f41 Linus Torvalds 2005-04-16 793 MptSge_t *sgl, *sgIn;
^1da177e4c3f41 Linus Torvalds 2005-04-16 794 char *sgOut;
^1da177e4c3f41 Linus Torvalds 2005-04-16 795 struct buflist *buflist;
^1da177e4c3f41 Linus Torvalds 2005-04-16 796 struct buflist *bl;
^1da177e4c3f41 Linus Torvalds 2005-04-16 797 dma_addr_t sgl_dma;
^1da177e4c3f41 Linus Torvalds 2005-04-16 798 int ret;
^1da177e4c3f41 Linus Torvalds 2005-04-16 799 int numfrags = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 800 int maxfrags;
^1da177e4c3f41 Linus Torvalds 2005-04-16 801 int n = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 802 u32 sgdir;
^1da177e4c3f41 Linus Torvalds 2005-04-16 803 u32 nib;
^1da177e4c3f41 Linus Torvalds 2005-04-16 804 int fw_bytes_copied = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 805 int i;
^1da177e4c3f41 Linus Torvalds 2005-04-16 806 int sge_offset = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 807 u16 iocstat;
^1da177e4c3f41 Linus Torvalds 2005-04-16 808 pFWDownloadReply_t ReplyMsg = NULL;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 809 unsigned long timeleft;
^1da177e4c3f41 Linus Torvalds 2005-04-16 810
946cbf040adb9d Moore, Eric 2006-02-02 811 if (mpt_verify_adapter(ioc, &iocp) < 0) {
29dd3609f2fc70 Eric Moore 2007-09-14 812 printk(KERN_DEBUG MYNAM "ioctl_fwdl - ioc%d not found!\n",
29dd3609f2fc70 Eric Moore 2007-09-14 813 ioc);
^1da177e4c3f41 Linus Torvalds 2005-04-16 814 return -ENODEV; /* (-6) No such device or address */
946cbf040adb9d Moore, Eric 2006-02-02 815 } else {
^1da177e4c3f41 Linus Torvalds 2005-04-16 816
^1da177e4c3f41 Linus Torvalds 2005-04-16 817 /* Valid device. Get a message frame and construct the FW download message.
^1da177e4c3f41 Linus Torvalds 2005-04-16 818 */
b07cb166c26273 Mark Balantzyan 2019-08-14 819 mutex_lock(&mpctl_mutex);
^1da177e4c3f41 Linus Torvalds 2005-04-16 @820 if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
b07cb166c26273 Mark Balantzyan 2019-08-14 821 mutex_unlock(&mpctl_mutex);
^1da177e4c3f41 Linus Torvalds 2005-04-16 822 return -EAGAIN;
946cbf040adb9d Moore, Eric 2006-02-02 823 }
b07cb166c26273 Mark Balantzyan 2019-08-14 824 mutex_lock(&mpctl_mutex);
09120a8cd38dbd Prakash, Sathya 2007-07-24 825 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT
09120a8cd38dbd Prakash, Sathya 2007-07-24 826 "mptctl_do_fwdl called. mptctl_id = %xh.\n", iocp->name, mptctl_id));
b07cb166c26273 Mark Balantzyan 2019-08-14 827 mutex_unlock(&mpctl_mutex);
09120a8cd38dbd Prakash, Sathya 2007-07-24 828 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.bufp = %p\n",
09120a8cd38dbd Prakash, Sathya 2007-07-24 829 iocp->name, ufwbuf));
09120a8cd38dbd Prakash, Sathya 2007-07-24 830 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.fwlen = %d\n",
09120a8cd38dbd Prakash, Sathya 2007-07-24 831 iocp->name, (int)fwlen));
09120a8cd38dbd Prakash, Sathya 2007-07-24 832 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.ioc = %04xh\n",
09120a8cd38dbd Prakash, Sathya 2007-07-24 833 iocp->name, ioc));
09120a8cd38dbd Prakash, Sathya 2007-07-24 834
^1da177e4c3f41 Linus Torvalds 2005-04-16 835 dlmsg = (FWDownload_t*) mf;
^1da177e4c3f41 Linus Torvalds 2005-04-16 836 ptsge = (FWDownloadTCSGE_t *) &dlmsg->SGL;
^1da177e4c3f41 Linus Torvalds 2005-04-16 837 sgOut = (char *) (ptsge + 1);
^1da177e4c3f41 Linus Torvalds 2005-04-16 838
^1da177e4c3f41 Linus Torvalds 2005-04-16 839 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 840 * Construct f/w download request
^1da177e4c3f41 Linus Torvalds 2005-04-16 841 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 842 dlmsg->ImageType = MPI_FW_DOWNLOAD_ITYPE_FW;
^1da177e4c3f41 Linus Torvalds 2005-04-16 843 dlmsg->Reserved = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 844 dlmsg->ChainOffset = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 845 dlmsg->Function = MPI_FUNCTION_FW_DOWNLOAD;
^1da177e4c3f41 Linus Torvalds 2005-04-16 846 dlmsg->Reserved1[0] = dlmsg->Reserved1[1] = dlmsg->Reserved1[2] = 0;
946cbf040adb9d Moore, Eric 2006-02-02 847 if (iocp->facts.MsgVersion >= MPI_VERSION_01_05)
946cbf040adb9d Moore, Eric 2006-02-02 848 dlmsg->MsgFlags = MPI_FW_DOWNLOAD_MSGFLGS_LAST_SEGMENT;
946cbf040adb9d Moore, Eric 2006-02-02 849 else
^1da177e4c3f41 Linus Torvalds 2005-04-16 850 dlmsg->MsgFlags = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 851
946cbf040adb9d Moore, Eric 2006-02-02 852
^1da177e4c3f41 Linus Torvalds 2005-04-16 853 /* Set up the Transaction SGE.
^1da177e4c3f41 Linus Torvalds 2005-04-16 854 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 855 ptsge->Reserved = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 856 ptsge->ContextSize = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 857 ptsge->DetailsLength = 12;
^1da177e4c3f41 Linus Torvalds 2005-04-16 858 ptsge->Flags = MPI_SGE_FLAGS_TRANSACTION_ELEMENT;
^1da177e4c3f41 Linus Torvalds 2005-04-16 859 ptsge->Reserved_0100_Checksum = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 860 ptsge->ImageOffset = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 861 ptsge->ImageSize = cpu_to_le32(fwlen);
^1da177e4c3f41 Linus Torvalds 2005-04-16 862
^1da177e4c3f41 Linus Torvalds 2005-04-16 863 /* Add the SGL
^1da177e4c3f41 Linus Torvalds 2005-04-16 864 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 865
^1da177e4c3f41 Linus Torvalds 2005-04-16 866 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 867 * Need to kmalloc area(s) for holding firmware image bytes.
^1da177e4c3f41 Linus Torvalds 2005-04-16 868 * But we need to do it piece meal, using a proper
^1da177e4c3f41 Linus Torvalds 2005-04-16 869 * scatter gather list (with 128kB MAX hunks).
^1da177e4c3f41 Linus Torvalds 2005-04-16 870 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 871 * A practical limit here might be # of sg hunks that fit into
^1da177e4c3f41 Linus Torvalds 2005-04-16 872 * a single IOC request frame; 12 or 8 (see below), so:
^1da177e4c3f41 Linus Torvalds 2005-04-16 873 * For FC9xx: 12 x 128kB == 1.5 mB (max)
^1da177e4c3f41 Linus Torvalds 2005-04-16 874 * For C1030: 8 x 128kB == 1 mB (max)
^1da177e4c3f41 Linus Torvalds 2005-04-16 875 * We could support chaining, but things get ugly(ier:)
^1da177e4c3f41 Linus Torvalds 2005-04-16 876 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 877 * Set the sge_offset to the start of the sgl (bytes).
^1da177e4c3f41 Linus Torvalds 2005-04-16 878 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 879 sgdir = 0x04000000; /* IOC will READ from sys mem */
^1da177e4c3f41 Linus Torvalds 2005-04-16 880 sge_offset = sizeof(MPIHeader_t) + sizeof(FWDownloadTCSGE_t);
^1da177e4c3f41 Linus Torvalds 2005-04-16 881 if ((sgl = kbuf_alloc_2_sgl(fwlen, sgdir, sge_offset,
^1da177e4c3f41 Linus Torvalds 2005-04-16 882 &numfrags, &buflist, &sgl_dma, iocp)) == NULL)
^1da177e4c3f41 Linus Torvalds 2005-04-16 883 return -ENOMEM;
^1da177e4c3f41 Linus Torvalds 2005-04-16 884
^1da177e4c3f41 Linus Torvalds 2005-04-16 885 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 886 * We should only need SGL with 2 simple_32bit entries (up to 256 kB)
^1da177e4c3f41 Linus Torvalds 2005-04-16 887 * for FC9xx f/w image, but calculate max number of sge hunks
^1da177e4c3f41 Linus Torvalds 2005-04-16 888 * we can fit into a request frame, and limit ourselves to that.
^1da177e4c3f41 Linus Torvalds 2005-04-16 889 * (currently no chain support)
^1da177e4c3f41 Linus Torvalds 2005-04-16 890 * maxfrags = (Request Size - FWdownload Size ) / Size of 32 bit SGE
^1da177e4c3f41 Linus Torvalds 2005-04-16 891 * Request maxfrags
^1da177e4c3f41 Linus Torvalds 2005-04-16 892 * 128 12
^1da177e4c3f41 Linus Torvalds 2005-04-16 893 * 96 8
^1da177e4c3f41 Linus Torvalds 2005-04-16 894 * 64 4
^1da177e4c3f41 Linus Torvalds 2005-04-16 895 */
14d0f0b063f536 Kashyap, Desai 2009-05-29 896 maxfrags = (iocp->req_sz - sizeof(MPIHeader_t) -
14d0f0b063f536 Kashyap, Desai 2009-05-29 897 sizeof(FWDownloadTCSGE_t))
14d0f0b063f536 Kashyap, Desai 2009-05-29 898 / iocp->SGE_size;
^1da177e4c3f41 Linus Torvalds 2005-04-16 899 if (numfrags > maxfrags) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 900 ret = -EMLINK;
^1da177e4c3f41 Linus Torvalds 2005-04-16 901 goto fwdl_out;
^1da177e4c3f41 Linus Torvalds 2005-04-16 902 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 903
09120a8cd38dbd Prakash, Sathya 2007-07-24 904 dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: sgl buffer = %p, sgfrags = %d\n",
09120a8cd38dbd Prakash, Sathya 2007-07-24 905 iocp->name, sgl, numfrags));
^1da177e4c3f41 Linus Torvalds 2005-04-16 906
^1da177e4c3f41 Linus Torvalds 2005-04-16 907 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 908 * Parse SG list, copying sgl itself,
^1da177e4c3f41 Linus Torvalds 2005-04-16 909 * plus f/w image hunks from user space as we go...
^1da177e4c3f41 Linus Torvalds 2005-04-16 910 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 911 ret = -EFAULT;
^1da177e4c3f41 Linus Torvalds 2005-04-16 912 sgIn = sgl;
^1da177e4c3f41 Linus Torvalds 2005-04-16 913 bl = buflist;
^1da177e4c3f41 Linus Torvalds 2005-04-16 914 for (i=0; i < numfrags; i++) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 915
^1da177e4c3f41 Linus Torvalds 2005-04-16 916 /* Get the SGE type: 0 - TCSGE, 3 - Chain, 1 - Simple SGE
^1da177e4c3f41 Linus Torvalds 2005-04-16 917 * Skip everything but Simple. If simple, copy from
^1da177e4c3f41 Linus Torvalds 2005-04-16 918 * user space into kernel space.
^1da177e4c3f41 Linus Torvalds 2005-04-16 919 * Note: we should not have anything but Simple as
^1da177e4c3f41 Linus Torvalds 2005-04-16 920 * Chain SGE are illegal.
^1da177e4c3f41 Linus Torvalds 2005-04-16 921 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 922 nib = (sgIn->FlagsLength & 0x30000000) >> 28;
^1da177e4c3f41 Linus Torvalds 2005-04-16 923 if (nib == 0 || nib == 3) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 924 ;
^1da177e4c3f41 Linus Torvalds 2005-04-16 925 } else if (sgIn->Address) {
14d0f0b063f536 Kashyap, Desai 2009-05-29 926 iocp->add_sge(sgOut, sgIn->FlagsLength, sgIn->Address);
^1da177e4c3f41 Linus Torvalds 2005-04-16 927 n++;
^1da177e4c3f41 Linus Torvalds 2005-04-16 928 if (copy_from_user(bl->kptr, ufwbuf+fw_bytes_copied, bl->len)) {
29dd3609f2fc70 Eric Moore 2007-09-14 929 printk(MYIOC_s_ERR_FMT "%s@%d::_ioctl_fwdl - "
^1da177e4c3f41 Linus Torvalds 2005-04-16 930 "Unable to copy f/w buffer hunk#%d @ %p\n",
29dd3609f2fc70 Eric Moore 2007-09-14 931 iocp->name, __FILE__, __LINE__, n, ufwbuf);
^1da177e4c3f41 Linus Torvalds 2005-04-16 932 goto fwdl_out;
^1da177e4c3f41 Linus Torvalds 2005-04-16 933 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 934 fw_bytes_copied += bl->len;
^1da177e4c3f41 Linus Torvalds 2005-04-16 935 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 936 sgIn++;
^1da177e4c3f41 Linus Torvalds 2005-04-16 937 bl++;
14d0f0b063f536 Kashyap, Desai 2009-05-29 938 sgOut += iocp->SGE_size;
^1da177e4c3f41 Linus Torvalds 2005-04-16 939 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 940
09120a8cd38dbd Prakash, Sathya 2007-07-24 941 DBG_DUMP_FW_DOWNLOAD(iocp, (u32 *)mf, numfrags);
^1da177e4c3f41 Linus Torvalds 2005-04-16 942
^1da177e4c3f41 Linus Torvalds 2005-04-16 943 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 944 * Finally, perform firmware download.
^1da177e4c3f41 Linus Torvalds 2005-04-16 945 */
946cbf040adb9d Moore, Eric 2006-02-02 946 ReplyMsg = NULL;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 947 SET_MGMT_MSG_CONTEXT(iocp->ioctl_cmds.msg_context, dlmsg->MsgContext);
ea2a788de4ce5e Kashyap, Desai 2009-05-29 948 INITIALIZE_MGMT_STATUS(iocp->ioctl_cmds.status)
b07cb166c26273 Mark Balantzyan 2019-08-14 949 mutex_lock(&mpctl_mutex);
^1da177e4c3f41 Linus Torvalds 2005-04-16 950 mpt_put_msg_frame(mptctl_id, iocp, mf);
b07cb166c26273 Mark Balantzyan 2019-08-14 951 mutex_lock(&mpctl_mutex);
^1da177e4c3f41 Linus Torvalds 2005-04-16 952
^1da177e4c3f41 Linus Torvalds 2005-04-16 953 /* Now wait for the command to complete */
ea2a788de4ce5e Kashyap, Desai 2009-05-29 954 retry_wait:
ea2a788de4ce5e Kashyap, Desai 2009-05-29 955 timeleft = wait_for_completion_timeout(&iocp->ioctl_cmds.done, HZ*60);
ea2a788de4ce5e Kashyap, Desai 2009-05-29 956 if (!(iocp->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
ea2a788de4ce5e Kashyap, Desai 2009-05-29 957 ret = -ETIME;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 958 printk(MYIOC_s_WARN_FMT "%s: failed\n", iocp->name, __func__);
ea2a788de4ce5e Kashyap, Desai 2009-05-29 959 if (iocp->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
ea2a788de4ce5e Kashyap, Desai 2009-05-29 960 mpt_free_msg_frame(iocp, mf);
ea2a788de4ce5e Kashyap, Desai 2009-05-29 961 goto fwdl_out;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 962 }
97009a29e8c999 Kei Tokunaga 2010-06-22 963 if (!timeleft) {
97009a29e8c999 Kei Tokunaga 2010-06-22 964 printk(MYIOC_s_WARN_FMT
97009a29e8c999 Kei Tokunaga 2010-06-22 965 "FW download timeout, doorbell=0x%08x\n",
97009a29e8c999 Kei Tokunaga 2010-06-22 966 iocp->name, mpt_GetIocState(iocp, 0));
ea2a788de4ce5e Kashyap, Desai 2009-05-29 967 mptctl_timeout_expired(iocp, mf);
97009a29e8c999 Kei Tokunaga 2010-06-22 968 } else
ea2a788de4ce5e Kashyap, Desai 2009-05-29 969 goto retry_wait;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 970 goto fwdl_out;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 971 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 972
ea2a788de4ce5e Kashyap, Desai 2009-05-29 973 if (!(iocp->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID)) {
ea2a788de4ce5e Kashyap, Desai 2009-05-29 974 printk(MYIOC_s_WARN_FMT "%s: failed\n", iocp->name, __func__);
ea2a788de4ce5e Kashyap, Desai 2009-05-29 975 mpt_free_msg_frame(iocp, mf);
^1da177e4c3f41 Linus Torvalds 2005-04-16 976 ret = -ENODATA;
^1da177e4c3f41 Linus Torvalds 2005-04-16 977 goto fwdl_out;
^1da177e4c3f41 Linus Torvalds 2005-04-16 978 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 979
^1da177e4c3f41 Linus Torvalds 2005-04-16 980 if (sgl)
^1da177e4c3f41 Linus Torvalds 2005-04-16 981 kfree_sgl(sgl, sgl_dma, buflist, iocp);
^1da177e4c3f41 Linus Torvalds 2005-04-16 982
ea2a788de4ce5e Kashyap, Desai 2009-05-29 983 ReplyMsg = (pFWDownloadReply_t)iocp->ioctl_cmds.reply;
^1da177e4c3f41 Linus Torvalds 2005-04-16 984 iocstat = le16_to_cpu(ReplyMsg->IOCStatus) & MPI_IOCSTATUS_MASK;
^1da177e4c3f41 Linus Torvalds 2005-04-16 985 if (iocstat == MPI_IOCSTATUS_SUCCESS) {
25985edcedea63 Lucas De Marchi 2011-03-30 986 printk(MYIOC_s_INFO_FMT "F/W update successful!\n", iocp->name);
^1da177e4c3f41 Linus Torvalds 2005-04-16 987 return 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 988 } else if (iocstat == MPI_IOCSTATUS_INVALID_FUNCTION) {
29dd3609f2fc70 Eric Moore 2007-09-14 989 printk(MYIOC_s_WARN_FMT "Hmmm... F/W download not supported!?!\n",
29dd3609f2fc70 Eric Moore 2007-09-14 990 iocp->name);
29dd3609f2fc70 Eric Moore 2007-09-14 991 printk(MYIOC_s_WARN_FMT "(time to go bang on somebodies door)\n",
^1da177e4c3f41 Linus Torvalds 2005-04-16 992 iocp->name);
^1da177e4c3f41 Linus Torvalds 2005-04-16 993 return -EBADRQC;
^1da177e4c3f41 Linus Torvalds 2005-04-16 994 } else if (iocstat == MPI_IOCSTATUS_BUSY) {
29dd3609f2fc70 Eric Moore 2007-09-14 995 printk(MYIOC_s_WARN_FMT "IOC_BUSY!\n", iocp->name);
29dd3609f2fc70 Eric Moore 2007-09-14 996 printk(MYIOC_s_WARN_FMT "(try again later?)\n", iocp->name);
^1da177e4c3f41 Linus Torvalds 2005-04-16 997 return -EBUSY;
^1da177e4c3f41 Linus Torvalds 2005-04-16 998 } else {
29dd3609f2fc70 Eric Moore 2007-09-14 999 printk(MYIOC_s_WARN_FMT "ioctl_fwdl() returned [bad] status = %04xh\n",
^1da177e4c3f41 Linus Torvalds 2005-04-16 1000 iocp->name, iocstat);
29dd3609f2fc70 Eric Moore 2007-09-14 1001 printk(MYIOC_s_WARN_FMT "(bad VooDoo)\n", iocp->name);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1002 return -ENOMSG;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1003 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1004 return 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1005
^1da177e4c3f41 Linus Torvalds 2005-04-16 1006 fwdl_out:
ea2a788de4ce5e Kashyap, Desai 2009-05-29 1007
ea2a788de4ce5e Kashyap, Desai 2009-05-29 1008 CLEAR_MGMT_STATUS(iocp->ioctl_cmds.status);
ea2a788de4ce5e Kashyap, Desai 2009-05-29 1009 SET_MGMT_MSG_CONTEXT(iocp->ioctl_cmds.msg_context, 0);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1010 kfree_sgl(sgl, sgl_dma, buflist, iocp);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1011 return ret;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1012 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1013
:::::: The code at line 820 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2
:::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org>
:::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 27706 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] lsilogic mpt fusion: mptctl: Fixed race condition around mptctl_id variable using mutexes
@ 2019-08-14 20:48 Mark Balantzyan
2019-08-15 5:51 ` kbuild test robot
0 siblings, 1 reply; 5+ messages in thread
From: Mark Balantzyan @ 2019-08-14 20:48 UTC (permalink / raw)
To: sathya.prakash
Cc: suganath-prabu.subramani, MPT-FusionLinux.pdl, linux-scsi,
linux-kernel, Mark Balantzyan
Certain functions in the driver, such as mptctl_do_fw_download() and
mptctl_do_mpt_command(), rely on the instance of mptctl_id, which does the
id-ing. There is race condition possible when these functions operate in
concurrency. Via, mutexes, the functions are mutually signalled to cooperate.
Signed-off-by: Mark Balantzyan <mbalant3@gmail.com>
---
drivers/message/fusion/mptctl.c | 39 ++++++++++++++++++++++++++-------
1 file changed, 31 insertions(+), 8 deletions(-)
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 4470630d..f0b49a85 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -816,12 +816,15 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
/* Valid device. Get a message frame and construct the FW download message.
*/
+ mutex_lock(&mpctl_mutex);
if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
+ mutex_unlock(&mpctl_mutex);
return -EAGAIN;
}
-
+ mutex_lock(&mpctl_mutex);
dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT
"mptctl_do_fwdl called. mptctl_id = %xh.\n", iocp->name, mptctl_id));
+ mutex_unlock(&mpctl_mutex);
dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.bufp = %p\n",
iocp->name, ufwbuf));
dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.fwlen = %d\n",
@@ -943,7 +946,9 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
ReplyMsg = NULL;
SET_MGMT_MSG_CONTEXT(iocp->ioctl_cmds.msg_context, dlmsg->MsgContext);
INITIALIZE_MGMT_STATUS(iocp->ioctl_cmds.status)
+ mutex_lock(&mpctl_mutex);
mpt_put_msg_frame(mptctl_id, iocp, mf);
+ mutex_lock(&mpctl_mutex);
/* Now wait for the command to complete */
retry_wait:
@@ -1889,7 +1894,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
/* Get a free request frame and save the message context.
*/
+ mutex_lock(&mpctl_mutex);
if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
+ mutex_unlock(&mpctl_mutex);
return -EAGAIN;
hdr = (MPIHeader_t *) mf;
@@ -2271,11 +2278,14 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
- (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
+ (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) {
+ mutex_lock(&mpctl_mutex);
mpt_put_msg_frame_hi_pri(mptctl_id, ioc, mf);
- else {
- rc =mpt_send_handshake_request(mptctl_id, ioc,
- sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP);
+ mutex_unlock(&mpctl_mutex);
+ } else {
+ mutex_lock(&mpctl_mutex);
+ rc = mpt_send_handshake_request(mptctl_id, ioc, sizeof(SCSITaskMgmt_t), (u32 *)mf, CAN_SLEEP);
+ mutex_unlock(&mpctl_mutex);
if (rc != 0) {
dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
"send_handshake FAILED! (ioc %p, mf %p)\n",
@@ -2287,8 +2297,11 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
}
}
- } else
+ } else {
+ mutex_lock(&mpctl_mutex);
mpt_put_msg_frame(mptctl_id, ioc, mf);
+ mutex_unlock(&mpctl_mutex);
+ }
/* Now wait for the command to complete */
timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;
@@ -2563,7 +2576,9 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
/*
* Gather ISTWI(Industry Standard Two Wire Interface) Data
*/
+ mutex_lock(&mpctl_mutex);
if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
+ mutex_unlock(&mpctl_mutex);
dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
"%s, no msg frames!!\n", ioc->name, __func__));
goto out;
@@ -2593,7 +2608,9 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context,
IstwiRWRequest->MsgContext);
INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
+ mutex_lock(&mpctl_mutex);
mpt_put_msg_frame(mptctl_id, ioc, mf);
+ mutex_unlock(&mpctl_mutex);
retry_wait:
timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
@@ -3010,9 +3027,11 @@ static int __init mptctl_init(void)
* Install our handler
*/
++where;
+ mutex_lock(&mpctl_mutex);
mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER,
"mptctl_reply");
if (!mptctl_id || mptctl_id >= MPT_MAX_PROTOCOL_DRIVERS) {
+ mutex_unlock(&mpctl_mutex);
printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
misc_deregister(&mptctl_miscdev);
err = -EBUSY;
@@ -3022,13 +3041,14 @@ static int __init mptctl_init(void)
mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER,
"mptctl_taskmgmt_reply");
if (!mptctl_taskmgmt_id || mptctl_taskmgmt_id >= MPT_MAX_PROTOCOL_DRIVERS) {
+ mutex_unlock(&mpctl_mutex);
printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
mpt_deregister(mptctl_id);
misc_deregister(&mptctl_miscdev);
err = -EBUSY;
goto out_fail;
}
-
+ mutex_unlock(&mpctl_mutex);
mpt_reset_register(mptctl_id, mptctl_ioc_reset);
mpt_event_register(mptctl_id, mptctl_event_process);
@@ -3044,13 +3064,14 @@ out_fail:
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static void mptctl_exit(void)
{
+ mutex_lock(&mpctl_mutex);
misc_deregister(&mptctl_miscdev);
printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
/* De-register event handler from base module */
mpt_event_deregister(mptctl_id);
-
+
/* De-register reset handler from base module */
mpt_reset_deregister(mptctl_id);
@@ -3058,6 +3079,8 @@ static void mptctl_exit(void)
mpt_deregister(mptctl_taskmgmt_id);
mpt_deregister(mptctl_id);
+ mutex_unlock(&mpctl_mutex);
+
mpt_device_driver_deregister(MPTCTL_DRIVER);
}
--
2.17.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH] lsilogic mpt fusion: mptctl: Fixed race condition around mptctl_id variable using mutexes
2019-08-14 15:12 Mark Balantzyan
@ 2019-08-14 19:53 ` kbuild test robot
0 siblings, 0 replies; 5+ messages in thread
From: kbuild test robot @ 2019-08-14 19:53 UTC (permalink / raw)
To: Mark Balantzyan
Cc: kbuild-all, sathya.prakash, suganath-prabu.subramani,
MPT=FusionLinux.pdl, linux-scsi, linux-kernel, Mark Balantzyan
[-- Attachment #1: Type: text/plain, Size: 48551 bytes --]
Hi Mark,
Thank you for the patch! Perhaps something to improve:
[auto build test WARNING on linus/master]
[cannot apply to v5.3-rc4 next-20190814]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Mark-Balantzyan/lsilogic-mpt-fusion-mptctl-Fixed-race-condition-around-mptctl_id-variable-using-mutexes/20190815-023617
config: parisc-allmodconfig (attached as .config)
compiler: hppa-linux-gcc (GCC) 7.4.0
reproduce:
wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
GCC_VERSION=7.4.0 make.cross ARCH=parisc
If you fix the issue, kindly add following tag
Reported-by: kbuild test robot <lkp@intel.com>
All warnings (new ones prefixed by >>):
drivers/message/fusion/mptctl.c: In function 'mptctl_do_mpt_command':
>> drivers/message/fusion/mptctl.c:2300:4: warning: this 'else' clause does not guard... [-Wmisleading-indentation]
} else
^~~~
drivers/message/fusion/mptctl.c:2302:3: note: ...this statement, but the latter is misleadingly indented as if it were guarded by the 'else'
mpt_put_msg_frame(mptctl_id, ioc, mf);
^~~~~~~~~~~~~~~~~
vim +/else +2300 drivers/message/fusion/mptctl.c
^1da177e4c3f41 Linus Torvalds 2005-04-16 1815
^1da177e4c3f41 Linus Torvalds 2005-04-16 1816 /*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
^1da177e4c3f41 Linus Torvalds 2005-04-16 1817 /* Worker routine for the IOCTL MPTCOMMAND and MPTCOMMAND32 (sparc) commands.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1818 *
^1da177e4c3f41 Linus Torvalds 2005-04-16 1819 * Outputs: None.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1820 * Return: 0 if successful
fc1323bb75ef8a Joe Perches 2008-02-03 1821 * -EBUSY if previous command timeout and IOC reset is not complete.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1822 * -EFAULT if data unavailable
^1da177e4c3f41 Linus Torvalds 2005-04-16 1823 * -ENODEV if no such device/adapter
^1da177e4c3f41 Linus Torvalds 2005-04-16 1824 * -ETIME if timer expires
^1da177e4c3f41 Linus Torvalds 2005-04-16 1825 * -ENOMEM if memory allocation error
^1da177e4c3f41 Linus Torvalds 2005-04-16 1826 * -EPERM if SCSI I/O and target is untagged
^1da177e4c3f41 Linus Torvalds 2005-04-16 1827 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1828 static int
^1da177e4c3f41 Linus Torvalds 2005-04-16 1829 mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1830 {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1831 MPT_ADAPTER *ioc;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1832 MPT_FRAME_HDR *mf = NULL;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1833 MPIHeader_t *hdr;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1834 char *psge;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1835 struct buflist bufIn; /* data In buffer */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1836 struct buflist bufOut; /* data Out buffer */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1837 dma_addr_t dma_addr_in;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1838 dma_addr_t dma_addr_out;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1839 int sgSize = 0; /* Num SG elements */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1840 int iocnum, flagsLength;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1841 int sz, rc = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1842 int msgContext;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1843 u16 req_idx;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1844 ulong timeout;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 1845 unsigned long timeleft;
793955f549c710 Eric Moore 2007-01-29 1846 struct scsi_device *sdev;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 1847 unsigned long flags;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 1848 u8 function;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1849
ab37128797148e Eric Moore 2007-09-29 1850 /* bufIn and bufOut are used for user to kernel space transfers
ab37128797148e Eric Moore 2007-09-29 1851 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1852 bufIn.kptr = bufOut.kptr = NULL;
ab37128797148e Eric Moore 2007-09-29 1853 bufIn.len = bufOut.len = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1854
^1da177e4c3f41 Linus Torvalds 2005-04-16 1855 if (((iocnum = mpt_verify_adapter(karg.hdr.iocnum, &ioc)) < 0) ||
^1da177e4c3f41 Linus Torvalds 2005-04-16 1856 (ioc == NULL)) {
29dd3609f2fc70 Eric Moore 2007-09-14 1857 printk(KERN_DEBUG MYNAM "%s::mptctl_do_mpt_command() @%d - ioc%d not found!\n",
09120a8cd38dbd Prakash, Sathya 2007-07-24 1858 __FILE__, __LINE__, iocnum);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1859 return -ENODEV;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1860 }
ea2a788de4ce5e Kashyap, Desai 2009-05-29 1861
ea2a788de4ce5e Kashyap, Desai 2009-05-29 1862 spin_lock_irqsave(&ioc->taskmgmt_lock, flags);
ea2a788de4ce5e Kashyap, Desai 2009-05-29 1863 if (ioc->ioc_reset_in_progress) {
ea2a788de4ce5e Kashyap, Desai 2009-05-29 1864 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
29dd3609f2fc70 Eric Moore 2007-09-14 1865 printk(KERN_ERR MYNAM "%s@%d::mptctl_do_mpt_command - "
ea2a788de4ce5e Kashyap, Desai 2009-05-29 1866 "Busy with diagnostic reset\n", __FILE__, __LINE__);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1867 return -EBUSY;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1868 }
ea2a788de4ce5e Kashyap, Desai 2009-05-29 1869 spin_unlock_irqrestore(&ioc->taskmgmt_lock, flags);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1870
e819cdb198319c Dan Carpenter 2015-07-03 1871 /* Basic sanity checks to prevent underflows or integer overflows */
e819cdb198319c Dan Carpenter 2015-07-03 1872 if (karg.maxReplyBytes < 0 ||
e819cdb198319c Dan Carpenter 2015-07-03 1873 karg.dataInSize < 0 ||
e819cdb198319c Dan Carpenter 2015-07-03 1874 karg.dataOutSize < 0 ||
e819cdb198319c Dan Carpenter 2015-07-03 1875 karg.dataSgeOffset < 0 ||
e819cdb198319c Dan Carpenter 2015-07-03 1876 karg.maxSenseBytes < 0 ||
e819cdb198319c Dan Carpenter 2015-07-03 1877 karg.dataSgeOffset > ioc->req_sz / 4)
e819cdb198319c Dan Carpenter 2015-07-03 1878 return -EINVAL;
e819cdb198319c Dan Carpenter 2015-07-03 1879
^1da177e4c3f41 Linus Torvalds 2005-04-16 1880 /* Verify that the final request frame will not be too large.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1881 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1882 sz = karg.dataSgeOffset * 4;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1883 if (karg.dataInSize > 0)
14d0f0b063f536 Kashyap, Desai 2009-05-29 1884 sz += ioc->SGE_size;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1885 if (karg.dataOutSize > 0)
14d0f0b063f536 Kashyap, Desai 2009-05-29 1886 sz += ioc->SGE_size;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1887
^1da177e4c3f41 Linus Torvalds 2005-04-16 1888 if (sz > ioc->req_sz) {
29dd3609f2fc70 Eric Moore 2007-09-14 1889 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^1da177e4c3f41 Linus Torvalds 2005-04-16 1890 "Request frame too large (%d) maximum (%d)\n",
29dd3609f2fc70 Eric Moore 2007-09-14 1891 ioc->name, __FILE__, __LINE__, sz, ioc->req_sz);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1892 return -EFAULT;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1893 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1894
^1da177e4c3f41 Linus Torvalds 2005-04-16 1895 /* Get a free request frame and save the message context.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1896 */
beda27821fd319 Mark Balantzyan 2019-08-14 1897 mutex_lock(&mpctl_mutex);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1898 if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
beda27821fd319 Mark Balantzyan 2019-08-14 1899 mutex_unlock(&mpctl_mutex);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1900 return -EAGAIN;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1901
^1da177e4c3f41 Linus Torvalds 2005-04-16 1902 hdr = (MPIHeader_t *) mf;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1903 msgContext = le32_to_cpu(hdr->MsgContext);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1904 req_idx = le16_to_cpu(mf->u.frame.hwhdr.msgctxu.fld.req_idx);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1905
^1da177e4c3f41 Linus Torvalds 2005-04-16 1906 /* Copy the request frame
^1da177e4c3f41 Linus Torvalds 2005-04-16 1907 * Reset the saved message context.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1908 * Request frame in user space
^1da177e4c3f41 Linus Torvalds 2005-04-16 1909 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1910 if (copy_from_user(mf, mfPtr, karg.dataSgeOffset * 4)) {
29dd3609f2fc70 Eric Moore 2007-09-14 1911 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^1da177e4c3f41 Linus Torvalds 2005-04-16 1912 "Unable to read MF from mpt_ioctl_command struct @ %p\n",
29dd3609f2fc70 Eric Moore 2007-09-14 1913 ioc->name, __FILE__, __LINE__, mfPtr);
ea2a788de4ce5e Kashyap, Desai 2009-05-29 1914 function = -1;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1915 rc = -EFAULT;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1916 goto done_free_mem;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1917 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1918 hdr->MsgContext = cpu_to_le32(msgContext);
ea2a788de4ce5e Kashyap, Desai 2009-05-29 1919 function = hdr->Function;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1920
^1da177e4c3f41 Linus Torvalds 2005-04-16 1921
^1da177e4c3f41 Linus Torvalds 2005-04-16 1922 /* Verify that this request is allowed.
^1da177e4c3f41 Linus Torvalds 2005-04-16 1923 */
09120a8cd38dbd Prakash, Sathya 2007-07-24 1924 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "sending mpi function (0x%02X), req=%p\n",
09120a8cd38dbd Prakash, Sathya 2007-07-24 1925 ioc->name, hdr->Function, mf));
09120a8cd38dbd Prakash, Sathya 2007-07-24 1926
ea2a788de4ce5e Kashyap, Desai 2009-05-29 1927 switch (function) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1928 case MPI_FUNCTION_IOC_FACTS:
^1da177e4c3f41 Linus Torvalds 2005-04-16 1929 case MPI_FUNCTION_PORT_FACTS:
^1da177e4c3f41 Linus Torvalds 2005-04-16 1930 karg.dataOutSize = karg.dataInSize = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1931 break;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1932
^1da177e4c3f41 Linus Torvalds 2005-04-16 1933 case MPI_FUNCTION_CONFIG:
09120a8cd38dbd Prakash, Sathya 2007-07-24 1934 {
09120a8cd38dbd Prakash, Sathya 2007-07-24 1935 Config_t *config_frame;
09120a8cd38dbd Prakash, Sathya 2007-07-24 1936 config_frame = (Config_t *)mf;
09120a8cd38dbd Prakash, Sathya 2007-07-24 1937 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT "\ttype=0x%02x ext_type=0x%02x "
09120a8cd38dbd Prakash, Sathya 2007-07-24 1938 "number=0x%02x action=0x%02x\n", ioc->name,
09120a8cd38dbd Prakash, Sathya 2007-07-24 1939 config_frame->Header.PageType,
09120a8cd38dbd Prakash, Sathya 2007-07-24 1940 config_frame->ExtPageType,
09120a8cd38dbd Prakash, Sathya 2007-07-24 1941 config_frame->Header.PageNumber,
09120a8cd38dbd Prakash, Sathya 2007-07-24 1942 config_frame->Action));
09120a8cd38dbd Prakash, Sathya 2007-07-24 1943 break;
09120a8cd38dbd Prakash, Sathya 2007-07-24 1944 }
09120a8cd38dbd Prakash, Sathya 2007-07-24 1945
^1da177e4c3f41 Linus Torvalds 2005-04-16 1946 case MPI_FUNCTION_FC_COMMON_TRANSPORT_SEND:
^1da177e4c3f41 Linus Torvalds 2005-04-16 1947 case MPI_FUNCTION_FC_EX_LINK_SRVC_SEND:
^1da177e4c3f41 Linus Torvalds 2005-04-16 1948 case MPI_FUNCTION_FW_UPLOAD:
^1da177e4c3f41 Linus Torvalds 2005-04-16 1949 case MPI_FUNCTION_SCSI_ENCLOSURE_PROCESSOR:
^1da177e4c3f41 Linus Torvalds 2005-04-16 1950 case MPI_FUNCTION_FW_DOWNLOAD:
^1da177e4c3f41 Linus Torvalds 2005-04-16 1951 case MPI_FUNCTION_FC_PRIMITIVE_SEND:
096f7a2a094af3 Moore, Eric 2006-02-02 1952 case MPI_FUNCTION_TOOLBOX:
096f7a2a094af3 Moore, Eric 2006-02-02 1953 case MPI_FUNCTION_SAS_IO_UNIT_CONTROL:
^1da177e4c3f41 Linus Torvalds 2005-04-16 1954 break;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1955
^1da177e4c3f41 Linus Torvalds 2005-04-16 1956 case MPI_FUNCTION_SCSI_IO_REQUEST:
^1da177e4c3f41 Linus Torvalds 2005-04-16 1957 if (ioc->sh) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 1958 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1959 int qtag = MPI_SCSIIO_CONTROL_UNTAGGED;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1960 int scsidir = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1961 int dataSize;
793955f549c710 Eric Moore 2007-01-29 1962 u32 id;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1963
793955f549c710 Eric Moore 2007-01-29 1964 id = (ioc->devices_per_bus == 0) ? 256 : ioc->devices_per_bus;
793955f549c710 Eric Moore 2007-01-29 1965 if (pScsiReq->TargetID > id) {
29dd3609f2fc70 Eric Moore 2007-09-14 1966 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^1da177e4c3f41 Linus Torvalds 2005-04-16 1967 "Target ID out of bounds. \n",
29dd3609f2fc70 Eric Moore 2007-09-14 1968 ioc->name, __FILE__, __LINE__);
^1da177e4c3f41 Linus Torvalds 2005-04-16 1969 rc = -ENODEV;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1970 goto done_free_mem;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1971 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 1972
793955f549c710 Eric Moore 2007-01-29 1973 if (pScsiReq->Bus >= ioc->number_of_buses) {
29dd3609f2fc70 Eric Moore 2007-09-14 1974 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
793955f549c710 Eric Moore 2007-01-29 1975 "Target Bus out of bounds. \n",
29dd3609f2fc70 Eric Moore 2007-09-14 1976 ioc->name, __FILE__, __LINE__);
793955f549c710 Eric Moore 2007-01-29 1977 rc = -ENODEV;
793955f549c710 Eric Moore 2007-01-29 1978 goto done_free_mem;
793955f549c710 Eric Moore 2007-01-29 1979 }
793955f549c710 Eric Moore 2007-01-29 1980
5f07e2499d6290 Moore, Eric 2006-02-02 1981 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
14d0f0b063f536 Kashyap, Desai 2009-05-29 1982 pScsiReq->MsgFlags |= mpt_msg_flags(ioc);
5f07e2499d6290 Moore, Eric 2006-02-02 1983
^1da177e4c3f41 Linus Torvalds 2005-04-16 1984
^1da177e4c3f41 Linus Torvalds 2005-04-16 1985 /* verify that app has not requested
^1da177e4c3f41 Linus Torvalds 2005-04-16 1986 * more sense data than driver
^1da177e4c3f41 Linus Torvalds 2005-04-16 1987 * can provide, if so, reset this parameter
^1da177e4c3f41 Linus Torvalds 2005-04-16 1988 * set the sense buffer pointer low address
^1da177e4c3f41 Linus Torvalds 2005-04-16 1989 * update the control field to specify Q type
^1da177e4c3f41 Linus Torvalds 2005-04-16 1990 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 1991 if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
^1da177e4c3f41 Linus Torvalds 2005-04-16 1992 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1993 else
^1da177e4c3f41 Linus Torvalds 2005-04-16 1994 pScsiReq->SenseBufferLength = karg.maxSenseBytes;
^1da177e4c3f41 Linus Torvalds 2005-04-16 1995
^1da177e4c3f41 Linus Torvalds 2005-04-16 1996 pScsiReq->SenseBufferLowAddr =
^1da177e4c3f41 Linus Torvalds 2005-04-16 1997 cpu_to_le32(ioc->sense_buf_low_dma
^1da177e4c3f41 Linus Torvalds 2005-04-16 1998 + (req_idx * MPT_SENSE_BUFFER_ALLOC));
^1da177e4c3f41 Linus Torvalds 2005-04-16 1999
793955f549c710 Eric Moore 2007-01-29 2000 shost_for_each_device(sdev, ioc->sh) {
793955f549c710 Eric Moore 2007-01-29 2001 struct scsi_target *starget = scsi_target(sdev);
793955f549c710 Eric Moore 2007-01-29 2002 VirtTarget *vtarget = starget->hostdata;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2003
08f5c5c23d52aa Kashyap, Desai 2010-03-18 2004 if (vtarget == NULL)
08f5c5c23d52aa Kashyap, Desai 2010-03-18 2005 continue;
08f5c5c23d52aa Kashyap, Desai 2010-03-18 2006
793955f549c710 Eric Moore 2007-01-29 2007 if ((pScsiReq->TargetID == vtarget->id) &&
793955f549c710 Eric Moore 2007-01-29 2008 (pScsiReq->Bus == vtarget->channel) &&
793955f549c710 Eric Moore 2007-01-29 2009 (vtarget->tflags & MPT_TARGET_FLAGS_Q_YES))
^1da177e4c3f41 Linus Torvalds 2005-04-16 2010 qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
793955f549c710 Eric Moore 2007-01-29 2011 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2012
^1da177e4c3f41 Linus Torvalds 2005-04-16 2013 /* Have the IOCTL driver set the direction based
^1da177e4c3f41 Linus Torvalds 2005-04-16 2014 * on the dataOutSize (ordering issue with Sparc).
^1da177e4c3f41 Linus Torvalds 2005-04-16 2015 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2016 if (karg.dataOutSize > 0) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2017 scsidir = MPI_SCSIIO_CONTROL_WRITE;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2018 dataSize = karg.dataOutSize;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2019 } else {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2020 scsidir = MPI_SCSIIO_CONTROL_READ;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2021 dataSize = karg.dataInSize;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2022 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2023
^1da177e4c3f41 Linus Torvalds 2005-04-16 2024 pScsiReq->Control = cpu_to_le32(scsidir | qtag);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2025 pScsiReq->DataLength = cpu_to_le32(dataSize);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2026
^1da177e4c3f41 Linus Torvalds 2005-04-16 2027
^1da177e4c3f41 Linus Torvalds 2005-04-16 2028 } else {
29dd3609f2fc70 Eric Moore 2007-09-14 2029 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^1da177e4c3f41 Linus Torvalds 2005-04-16 2030 "SCSI driver is not loaded. \n",
29dd3609f2fc70 Eric Moore 2007-09-14 2031 ioc->name, __FILE__, __LINE__);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2032 rc = -EFAULT;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2033 goto done_free_mem;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2034 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2035 break;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2036
096f7a2a094af3 Moore, Eric 2006-02-02 2037 case MPI_FUNCTION_SMP_PASSTHROUGH:
096f7a2a094af3 Moore, Eric 2006-02-02 2038 /* Check mf->PassthruFlags to determine if
096f7a2a094af3 Moore, Eric 2006-02-02 2039 * transfer is ImmediateMode or not.
096f7a2a094af3 Moore, Eric 2006-02-02 2040 * Immediate mode returns data in the ReplyFrame.
096f7a2a094af3 Moore, Eric 2006-02-02 2041 * Else, we are sending request and response data
096f7a2a094af3 Moore, Eric 2006-02-02 2042 * in two SGLs at the end of the mf.
096f7a2a094af3 Moore, Eric 2006-02-02 2043 */
096f7a2a094af3 Moore, Eric 2006-02-02 2044 break;
096f7a2a094af3 Moore, Eric 2006-02-02 2045
096f7a2a094af3 Moore, Eric 2006-02-02 2046 case MPI_FUNCTION_SATA_PASSTHROUGH:
096f7a2a094af3 Moore, Eric 2006-02-02 2047 if (!ioc->sh) {
29dd3609f2fc70 Eric Moore 2007-09-14 2048 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
096f7a2a094af3 Moore, Eric 2006-02-02 2049 "SCSI driver is not loaded. \n",
29dd3609f2fc70 Eric Moore 2007-09-14 2050 ioc->name, __FILE__, __LINE__);
096f7a2a094af3 Moore, Eric 2006-02-02 2051 rc = -EFAULT;
096f7a2a094af3 Moore, Eric 2006-02-02 2052 goto done_free_mem;
096f7a2a094af3 Moore, Eric 2006-02-02 2053 }
096f7a2a094af3 Moore, Eric 2006-02-02 2054 break;
096f7a2a094af3 Moore, Eric 2006-02-02 2055
^1da177e4c3f41 Linus Torvalds 2005-04-16 2056 case MPI_FUNCTION_RAID_ACTION:
^1da177e4c3f41 Linus Torvalds 2005-04-16 2057 /* Just add a SGE
^1da177e4c3f41 Linus Torvalds 2005-04-16 2058 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2059 break;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2060
^1da177e4c3f41 Linus Torvalds 2005-04-16 2061 case MPI_FUNCTION_RAID_SCSI_IO_PASSTHROUGH:
^1da177e4c3f41 Linus Torvalds 2005-04-16 2062 if (ioc->sh) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2063 SCSIIORequest_t *pScsiReq = (SCSIIORequest_t *) mf;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2064 int qtag = MPI_SCSIIO_CONTROL_SIMPLEQ;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2065 int scsidir = MPI_SCSIIO_CONTROL_READ;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2066 int dataSize;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2067
5f07e2499d6290 Moore, Eric 2006-02-02 2068 pScsiReq->MsgFlags &= ~MPI_SCSIIO_MSGFLGS_SENSE_WIDTH;
14d0f0b063f536 Kashyap, Desai 2009-05-29 2069 pScsiReq->MsgFlags |= mpt_msg_flags(ioc);
5f07e2499d6290 Moore, Eric 2006-02-02 2070
^1da177e4c3f41 Linus Torvalds 2005-04-16 2071
^1da177e4c3f41 Linus Torvalds 2005-04-16 2072 /* verify that app has not requested
^1da177e4c3f41 Linus Torvalds 2005-04-16 2073 * more sense data than driver
^1da177e4c3f41 Linus Torvalds 2005-04-16 2074 * can provide, if so, reset this parameter
^1da177e4c3f41 Linus Torvalds 2005-04-16 2075 * set the sense buffer pointer low address
^1da177e4c3f41 Linus Torvalds 2005-04-16 2076 * update the control field to specify Q type
^1da177e4c3f41 Linus Torvalds 2005-04-16 2077 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2078 if (karg.maxSenseBytes > MPT_SENSE_BUFFER_SIZE)
^1da177e4c3f41 Linus Torvalds 2005-04-16 2079 pScsiReq->SenseBufferLength = MPT_SENSE_BUFFER_SIZE;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2080 else
^1da177e4c3f41 Linus Torvalds 2005-04-16 2081 pScsiReq->SenseBufferLength = karg.maxSenseBytes;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2082
^1da177e4c3f41 Linus Torvalds 2005-04-16 2083 pScsiReq->SenseBufferLowAddr =
^1da177e4c3f41 Linus Torvalds 2005-04-16 2084 cpu_to_le32(ioc->sense_buf_low_dma
^1da177e4c3f41 Linus Torvalds 2005-04-16 2085 + (req_idx * MPT_SENSE_BUFFER_ALLOC));
^1da177e4c3f41 Linus Torvalds 2005-04-16 2086
^1da177e4c3f41 Linus Torvalds 2005-04-16 2087 /* All commands to physical devices are tagged
^1da177e4c3f41 Linus Torvalds 2005-04-16 2088 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2089
^1da177e4c3f41 Linus Torvalds 2005-04-16 2090 /* Have the IOCTL driver set the direction based
^1da177e4c3f41 Linus Torvalds 2005-04-16 2091 * on the dataOutSize (ordering issue with Sparc).
^1da177e4c3f41 Linus Torvalds 2005-04-16 2092 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2093 if (karg.dataOutSize > 0) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2094 scsidir = MPI_SCSIIO_CONTROL_WRITE;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2095 dataSize = karg.dataOutSize;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2096 } else {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2097 scsidir = MPI_SCSIIO_CONTROL_READ;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2098 dataSize = karg.dataInSize;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2099 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2100
^1da177e4c3f41 Linus Torvalds 2005-04-16 2101 pScsiReq->Control = cpu_to_le32(scsidir | qtag);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2102 pScsiReq->DataLength = cpu_to_le32(dataSize);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2103
^1da177e4c3f41 Linus Torvalds 2005-04-16 2104 } else {
29dd3609f2fc70 Eric Moore 2007-09-14 2105 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^1da177e4c3f41 Linus Torvalds 2005-04-16 2106 "SCSI driver is not loaded. \n",
29dd3609f2fc70 Eric Moore 2007-09-14 2107 ioc->name, __FILE__, __LINE__);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2108 rc = -EFAULT;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2109 goto done_free_mem;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2110 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2111 break;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2112
^1da177e4c3f41 Linus Torvalds 2005-04-16 2113 case MPI_FUNCTION_SCSI_TASK_MGMT:
^1da177e4c3f41 Linus Torvalds 2005-04-16 2114 {
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2115 SCSITaskMgmt_t *pScsiTm;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2116 pScsiTm = (SCSITaskMgmt_t *)mf;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2117 dctlprintk(ioc, printk(MYIOC_s_DEBUG_FMT
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2118 "\tTaskType=0x%x MsgFlags=0x%x "
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2119 "TaskMsgContext=0x%x id=%d channel=%d\n",
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2120 ioc->name, pScsiTm->TaskType, le32_to_cpu
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2121 (pScsiTm->TaskMsgContext), pScsiTm->MsgFlags,
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2122 pScsiTm->TargetID, pScsiTm->Bus));
^1da177e4c3f41 Linus Torvalds 2005-04-16 2123 break;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2124 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2125
^1da177e4c3f41 Linus Torvalds 2005-04-16 2126 case MPI_FUNCTION_IOC_INIT:
^1da177e4c3f41 Linus Torvalds 2005-04-16 2127 {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2128 IOCInit_t *pInit = (IOCInit_t *) mf;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2129 u32 high_addr, sense_high;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2130
^1da177e4c3f41 Linus Torvalds 2005-04-16 2131 /* Verify that all entries in the IOC INIT match
^1da177e4c3f41 Linus Torvalds 2005-04-16 2132 * existing setup (and in LE format).
^1da177e4c3f41 Linus Torvalds 2005-04-16 2133 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2134 if (sizeof(dma_addr_t) == sizeof(u64)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2135 high_addr = cpu_to_le32((u32)((u64)ioc->req_frames_dma >> 32));
^1da177e4c3f41 Linus Torvalds 2005-04-16 2136 sense_high= cpu_to_le32((u32)((u64)ioc->sense_buf_pool_dma >> 32));
^1da177e4c3f41 Linus Torvalds 2005-04-16 2137 } else {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2138 high_addr = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2139 sense_high= 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2140 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2141
^1da177e4c3f41 Linus Torvalds 2005-04-16 2142 if ((pInit->Flags != 0) || (pInit->MaxDevices != ioc->facts.MaxDevices) ||
^1da177e4c3f41 Linus Torvalds 2005-04-16 2143 (pInit->MaxBuses != ioc->facts.MaxBuses) ||
^1da177e4c3f41 Linus Torvalds 2005-04-16 2144 (pInit->ReplyFrameSize != cpu_to_le16(ioc->reply_sz)) ||
^1da177e4c3f41 Linus Torvalds 2005-04-16 2145 (pInit->HostMfaHighAddr != high_addr) ||
^1da177e4c3f41 Linus Torvalds 2005-04-16 2146 (pInit->SenseBufferHighAddr != sense_high)) {
29dd3609f2fc70 Eric Moore 2007-09-14 2147 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^1da177e4c3f41 Linus Torvalds 2005-04-16 2148 "IOC_INIT issued with 1 or more incorrect parameters. Rejected.\n",
29dd3609f2fc70 Eric Moore 2007-09-14 2149 ioc->name, __FILE__, __LINE__);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2150 rc = -EFAULT;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2151 goto done_free_mem;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2152 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2153 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2154 break;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2155 default:
^1da177e4c3f41 Linus Torvalds 2005-04-16 2156 /*
^1da177e4c3f41 Linus Torvalds 2005-04-16 2157 * MPI_FUNCTION_PORT_ENABLE
^1da177e4c3f41 Linus Torvalds 2005-04-16 2158 * MPI_FUNCTION_TARGET_CMD_BUFFER_POST
^1da177e4c3f41 Linus Torvalds 2005-04-16 2159 * MPI_FUNCTION_TARGET_ASSIST
^1da177e4c3f41 Linus Torvalds 2005-04-16 2160 * MPI_FUNCTION_TARGET_STATUS_SEND
^1da177e4c3f41 Linus Torvalds 2005-04-16 2161 * MPI_FUNCTION_TARGET_MODE_ABORT
^1da177e4c3f41 Linus Torvalds 2005-04-16 2162 * MPI_FUNCTION_IOC_MESSAGE_UNIT_RESET
^1da177e4c3f41 Linus Torvalds 2005-04-16 2163 * MPI_FUNCTION_IO_UNIT_RESET
^1da177e4c3f41 Linus Torvalds 2005-04-16 2164 * MPI_FUNCTION_HANDSHAKE
^1da177e4c3f41 Linus Torvalds 2005-04-16 2165 * MPI_FUNCTION_REPLY_FRAME_REMOVAL
^1da177e4c3f41 Linus Torvalds 2005-04-16 2166 * MPI_FUNCTION_EVENT_NOTIFICATION
^1da177e4c3f41 Linus Torvalds 2005-04-16 2167 * (driver handles event notification)
^1da177e4c3f41 Linus Torvalds 2005-04-16 2168 * MPI_FUNCTION_EVENT_ACK
^1da177e4c3f41 Linus Torvalds 2005-04-16 2169 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2170
^1da177e4c3f41 Linus Torvalds 2005-04-16 2171 /* What to do with these??? CHECK ME!!!
^1da177e4c3f41 Linus Torvalds 2005-04-16 2172 MPI_FUNCTION_FC_LINK_SRVC_BUF_POST
^1da177e4c3f41 Linus Torvalds 2005-04-16 2173 MPI_FUNCTION_FC_LINK_SRVC_RSP
^1da177e4c3f41 Linus Torvalds 2005-04-16 2174 MPI_FUNCTION_FC_ABORT
^1da177e4c3f41 Linus Torvalds 2005-04-16 2175 MPI_FUNCTION_LAN_SEND
^1da177e4c3f41 Linus Torvalds 2005-04-16 2176 MPI_FUNCTION_LAN_RECEIVE
^1da177e4c3f41 Linus Torvalds 2005-04-16 2177 MPI_FUNCTION_LAN_RESET
^1da177e4c3f41 Linus Torvalds 2005-04-16 2178 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2179
29dd3609f2fc70 Eric Moore 2007-09-14 2180 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^1da177e4c3f41 Linus Torvalds 2005-04-16 2181 "Illegal request (function 0x%x) \n",
29dd3609f2fc70 Eric Moore 2007-09-14 2182 ioc->name, __FILE__, __LINE__, hdr->Function);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2183 rc = -EFAULT;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2184 goto done_free_mem;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2185 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2186
^1da177e4c3f41 Linus Torvalds 2005-04-16 2187 /* Add the SGL ( at most one data in SGE and one data out SGE )
^1da177e4c3f41 Linus Torvalds 2005-04-16 2188 * In the case of two SGE's - the data out (write) will always
^1da177e4c3f41 Linus Torvalds 2005-04-16 2189 * preceede the data in (read) SGE. psgList is used to free the
^1da177e4c3f41 Linus Torvalds 2005-04-16 2190 * allocated memory.
^1da177e4c3f41 Linus Torvalds 2005-04-16 2191 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2192 psge = (char *) (((int *) mf) + karg.dataSgeOffset);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2193 flagsLength = 0;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2194
^1da177e4c3f41 Linus Torvalds 2005-04-16 2195 if (karg.dataOutSize > 0)
^1da177e4c3f41 Linus Torvalds 2005-04-16 2196 sgSize ++;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2197
^1da177e4c3f41 Linus Torvalds 2005-04-16 2198 if (karg.dataInSize > 0)
^1da177e4c3f41 Linus Torvalds 2005-04-16 2199 sgSize ++;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2200
^1da177e4c3f41 Linus Torvalds 2005-04-16 2201 if (sgSize > 0) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2202
^1da177e4c3f41 Linus Torvalds 2005-04-16 2203 /* Set up the dataOut memory allocation */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2204 if (karg.dataOutSize > 0) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2205 if (karg.dataInSize > 0) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2206 flagsLength = ( MPI_SGE_FLAGS_SIMPLE_ELEMENT |
^1da177e4c3f41 Linus Torvalds 2005-04-16 2207 MPI_SGE_FLAGS_END_OF_BUFFER |
14d0f0b063f536 Kashyap, Desai 2009-05-29 2208 MPI_SGE_FLAGS_DIRECTION)
^1da177e4c3f41 Linus Torvalds 2005-04-16 2209 << MPI_SGE_FLAGS_SHIFT;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2210 } else {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2211 flagsLength = MPT_SGE_FLAGS_SSIMPLE_WRITE;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2212 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2213 flagsLength |= karg.dataOutSize;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2214 bufOut.len = karg.dataOutSize;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2215 bufOut.kptr = pci_alloc_consistent(
^1da177e4c3f41 Linus Torvalds 2005-04-16 2216 ioc->pcidev, bufOut.len, &dma_addr_out);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2217
^1da177e4c3f41 Linus Torvalds 2005-04-16 2218 if (bufOut.kptr == NULL) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2219 rc = -ENOMEM;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2220 goto done_free_mem;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2221 } else {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2222 /* Set up this SGE.
^1da177e4c3f41 Linus Torvalds 2005-04-16 2223 * Copy to MF and to sglbuf
^1da177e4c3f41 Linus Torvalds 2005-04-16 2224 */
14d0f0b063f536 Kashyap, Desai 2009-05-29 2225 ioc->add_sge(psge, flagsLength, dma_addr_out);
14d0f0b063f536 Kashyap, Desai 2009-05-29 2226 psge += ioc->SGE_size;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2227
^1da177e4c3f41 Linus Torvalds 2005-04-16 2228 /* Copy user data to kernel space.
^1da177e4c3f41 Linus Torvalds 2005-04-16 2229 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2230 if (copy_from_user(bufOut.kptr,
^1da177e4c3f41 Linus Torvalds 2005-04-16 2231 karg.dataOutBufPtr,
^1da177e4c3f41 Linus Torvalds 2005-04-16 2232 bufOut.len)) {
29dd3609f2fc70 Eric Moore 2007-09-14 2233 printk(MYIOC_s_ERR_FMT
^1da177e4c3f41 Linus Torvalds 2005-04-16 2234 "%s@%d::mptctl_do_mpt_command - Unable "
^1da177e4c3f41 Linus Torvalds 2005-04-16 2235 "to read user data "
^1da177e4c3f41 Linus Torvalds 2005-04-16 2236 "struct @ %p\n",
29dd3609f2fc70 Eric Moore 2007-09-14 2237 ioc->name, __FILE__, __LINE__,karg.dataOutBufPtr);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2238 rc = -EFAULT;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2239 goto done_free_mem;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2240 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2241 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2242 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2243
^1da177e4c3f41 Linus Torvalds 2005-04-16 2244 if (karg.dataInSize > 0) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2245 flagsLength = MPT_SGE_FLAGS_SSIMPLE_READ;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2246 flagsLength |= karg.dataInSize;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2247
^1da177e4c3f41 Linus Torvalds 2005-04-16 2248 bufIn.len = karg.dataInSize;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2249 bufIn.kptr = pci_alloc_consistent(ioc->pcidev,
^1da177e4c3f41 Linus Torvalds 2005-04-16 2250 bufIn.len, &dma_addr_in);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2251
^1da177e4c3f41 Linus Torvalds 2005-04-16 2252 if (bufIn.kptr == NULL) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2253 rc = -ENOMEM;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2254 goto done_free_mem;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2255 } else {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2256 /* Set up this SGE
^1da177e4c3f41 Linus Torvalds 2005-04-16 2257 * Copy to MF and to sglbuf
^1da177e4c3f41 Linus Torvalds 2005-04-16 2258 */
14d0f0b063f536 Kashyap, Desai 2009-05-29 2259 ioc->add_sge(psge, flagsLength, dma_addr_in);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2260 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2261 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2262 } else {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2263 /* Add a NULL SGE
^1da177e4c3f41 Linus Torvalds 2005-04-16 2264 */
14d0f0b063f536 Kashyap, Desai 2009-05-29 2265 ioc->add_sge(psge, flagsLength, (dma_addr_t) -1);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2266 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2267
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2268 SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, hdr->MsgContext);
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2269 INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
^1da177e4c3f41 Linus Torvalds 2005-04-16 2270 if (hdr->Function == MPI_FUNCTION_SCSI_TASK_MGMT) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2271
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2272 mutex_lock(&ioc->taskmgmt_cmds.mutex);
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2273 if (mpt_set_taskmgmt_in_progress_flag(ioc) != 0) {
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2274 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2275 goto done_free_mem;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2276 }
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2277
09120a8cd38dbd Prakash, Sathya 2007-07-24 2278 DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2279
7a195f464e0692 Prakash, Sathya 2007-08-14 2280 if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
beda27821fd319 Mark Balantzyan 2019-08-14 2281 (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) {
beda27821fd319 Mark Balantzyan 2019-08-14 2282 mutex_lock(&mpctl_mutex);
7a195f464e0692 Prakash, Sathya 2007-08-14 2283 mpt_put_msg_frame_hi_pri(mptctl_id, ioc, mf);
beda27821fd319 Mark Balantzyan 2019-08-14 2284 mutex_unlock(&mpctl_mutex);
beda27821fd319 Mark Balantzyan 2019-08-14 2285 } else {
beda27821fd319 Mark Balantzyan 2019-08-14 2286 mutex_lock(&mpctl_mutex);
beda27821fd319 Mark Balantzyan 2019-08-14 2287 rc = mpt_send_handshake_request(mptctl_id, ioc, sizeof(SCSITaskMgmt_t), (u32 *)mf, CAN_SLEEP);
beda27821fd319 Mark Balantzyan 2019-08-14 2288 mutex_unlock(&mpctl_mutex);
7a195f464e0692 Prakash, Sathya 2007-08-14 2289 if (rc != 0) {
7a195f464e0692 Prakash, Sathya 2007-08-14 2290 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2291 "send_handshake FAILED! (ioc %p, mf %p)\n",
7a195f464e0692 Prakash, Sathya 2007-08-14 2292 ioc->name, ioc, mf));
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2293 mpt_clear_taskmgmt_in_progress_flag(ioc);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2294 rc = -ENODATA;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2295 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2296 goto done_free_mem;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2297 }
7a195f464e0692 Prakash, Sathya 2007-08-14 2298 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2299
^1da177e4c3f41 Linus Torvalds 2005-04-16 @2300 } else
beda27821fd319 Mark Balantzyan 2019-08-14 2301 mutex_lock(&mpctl_mutex);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2302 mpt_put_msg_frame(mptctl_id, ioc, mf);
beda27821fd319 Mark Balantzyan 2019-08-14 2303 mutex_unlock(&mpctl_mutex);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2304
^1da177e4c3f41 Linus Torvalds 2005-04-16 2305 /* Now wait for the command to complete */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2306 timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2307 retry_wait:
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2308 timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
^1da177e4c3f41 Linus Torvalds 2005-04-16 2309 HZ*timeout);
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2310 if (!(ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD)) {
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2311 rc = -ETIME;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2312 dfailprintk(ioc, printk(MYIOC_s_ERR_FMT "%s: TIMED OUT!\n",
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2313 ioc->name, __func__));
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2314 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_DID_IOCRESET) {
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2315 if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2316 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2317 goto done_free_mem;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2318 }
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2319 if (!timeleft) {
97009a29e8c999 Kei Tokunaga 2010-06-22 2320 printk(MYIOC_s_WARN_FMT
97009a29e8c999 Kei Tokunaga 2010-06-22 2321 "mpt cmd timeout, doorbell=0x%08x"
97009a29e8c999 Kei Tokunaga 2010-06-22 2322 " function=0x%x\n",
97009a29e8c999 Kei Tokunaga 2010-06-22 2323 ioc->name, mpt_GetIocState(ioc, 0), function);
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2324 if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2325 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2326 mptctl_timeout_expired(ioc, mf);
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2327 mf = NULL;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2328 } else
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2329 goto retry_wait;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2330 goto done_free_mem;
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2331 }
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2332
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2333 if (function == MPI_FUNCTION_SCSI_TASK_MGMT)
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2334 mutex_unlock(&ioc->taskmgmt_cmds.mutex);
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2335
^1da177e4c3f41 Linus Torvalds 2005-04-16 2336
^1da177e4c3f41 Linus Torvalds 2005-04-16 2337 mf = NULL;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2338
^1da177e4c3f41 Linus Torvalds 2005-04-16 2339 /* If a valid reply frame, copy to the user.
^1da177e4c3f41 Linus Torvalds 2005-04-16 2340 * Offset 2: reply length in U32's
^1da177e4c3f41 Linus Torvalds 2005-04-16 2341 */
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2342 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_RF_VALID) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2343 if (karg.maxReplyBytes < ioc->reply_sz) {
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2344 sz = min(karg.maxReplyBytes,
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2345 4*ioc->ioctl_cmds.reply[2]);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2346 } else {
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2347 sz = min(ioc->reply_sz, 4*ioc->ioctl_cmds.reply[2]);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2348 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2349 if (sz > 0) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2350 if (copy_to_user(karg.replyFrameBufPtr,
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2351 ioc->ioctl_cmds.reply, sz)){
29dd3609f2fc70 Eric Moore 2007-09-14 2352 printk(MYIOC_s_ERR_FMT
^1da177e4c3f41 Linus Torvalds 2005-04-16 2353 "%s@%d::mptctl_do_mpt_command - "
^1da177e4c3f41 Linus Torvalds 2005-04-16 2354 "Unable to write out reply frame %p\n",
29dd3609f2fc70 Eric Moore 2007-09-14 2355 ioc->name, __FILE__, __LINE__, karg.replyFrameBufPtr);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2356 rc = -ENODATA;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2357 goto done_free_mem;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2358 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2359 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2360 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2361
^1da177e4c3f41 Linus Torvalds 2005-04-16 2362 /* If valid sense data, copy to user.
^1da177e4c3f41 Linus Torvalds 2005-04-16 2363 */
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2364 if (ioc->ioctl_cmds.status & MPT_MGMT_STATUS_SENSE_VALID) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2365 sz = min(karg.maxSenseBytes, MPT_SENSE_BUFFER_SIZE);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2366 if (sz > 0) {
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2367 if (copy_to_user(karg.senseDataPtr,
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2368 ioc->ioctl_cmds.sense, sz)) {
29dd3609f2fc70 Eric Moore 2007-09-14 2369 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^1da177e4c3f41 Linus Torvalds 2005-04-16 2370 "Unable to write sense data to user %p\n",
29dd3609f2fc70 Eric Moore 2007-09-14 2371 ioc->name, __FILE__, __LINE__,
^1da177e4c3f41 Linus Torvalds 2005-04-16 2372 karg.senseDataPtr);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2373 rc = -ENODATA;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2374 goto done_free_mem;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2375 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2376 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2377 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2378
^1da177e4c3f41 Linus Torvalds 2005-04-16 2379 /* If the overall status is _GOOD and data in, copy data
^1da177e4c3f41 Linus Torvalds 2005-04-16 2380 * to user.
^1da177e4c3f41 Linus Torvalds 2005-04-16 2381 */
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2382 if ((ioc->ioctl_cmds.status & MPT_MGMT_STATUS_COMMAND_GOOD) &&
^1da177e4c3f41 Linus Torvalds 2005-04-16 2383 (karg.dataInSize > 0) && (bufIn.kptr)) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2384
^1da177e4c3f41 Linus Torvalds 2005-04-16 2385 if (copy_to_user(karg.dataInBufPtr,
^1da177e4c3f41 Linus Torvalds 2005-04-16 2386 bufIn.kptr, karg.dataInSize)) {
29dd3609f2fc70 Eric Moore 2007-09-14 2387 printk(MYIOC_s_ERR_FMT "%s@%d::mptctl_do_mpt_command - "
^1da177e4c3f41 Linus Torvalds 2005-04-16 2388 "Unable to write data to user %p\n",
29dd3609f2fc70 Eric Moore 2007-09-14 2389 ioc->name, __FILE__, __LINE__,
^1da177e4c3f41 Linus Torvalds 2005-04-16 2390 karg.dataInBufPtr);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2391 rc = -ENODATA;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2392 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2393 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2394
^1da177e4c3f41 Linus Torvalds 2005-04-16 2395 done_free_mem:
^1da177e4c3f41 Linus Torvalds 2005-04-16 2396
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2397 CLEAR_MGMT_STATUS(ioc->ioctl_cmds.status)
ea2a788de4ce5e Kashyap, Desai 2009-05-29 2398 SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context, 0);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2399
^1da177e4c3f41 Linus Torvalds 2005-04-16 2400 /* Free the allocated memory.
^1da177e4c3f41 Linus Torvalds 2005-04-16 2401 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2402 if (bufOut.kptr != NULL) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2403 pci_free_consistent(ioc->pcidev,
^1da177e4c3f41 Linus Torvalds 2005-04-16 2404 bufOut.len, (void *) bufOut.kptr, dma_addr_out);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2405 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2406
^1da177e4c3f41 Linus Torvalds 2005-04-16 2407 if (bufIn.kptr != NULL) {
^1da177e4c3f41 Linus Torvalds 2005-04-16 2408 pci_free_consistent(ioc->pcidev,
^1da177e4c3f41 Linus Torvalds 2005-04-16 2409 bufIn.len, (void *) bufIn.kptr, dma_addr_in);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2410 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2411
^1da177e4c3f41 Linus Torvalds 2005-04-16 2412 /* mf is null if command issued successfully
25985edcedea63 Lucas De Marchi 2011-03-30 2413 * otherwise, failure occurred after mf acquired.
^1da177e4c3f41 Linus Torvalds 2005-04-16 2414 */
^1da177e4c3f41 Linus Torvalds 2005-04-16 2415 if (mf)
^1da177e4c3f41 Linus Torvalds 2005-04-16 2416 mpt_free_msg_frame(ioc, mf);
^1da177e4c3f41 Linus Torvalds 2005-04-16 2417
^1da177e4c3f41 Linus Torvalds 2005-04-16 2418 return rc;
^1da177e4c3f41 Linus Torvalds 2005-04-16 2419 }
^1da177e4c3f41 Linus Torvalds 2005-04-16 2420
:::::: The code at line 2300 was first introduced by commit
:::::: 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 Linux-2.6.12-rc2
:::::: TO: Linus Torvalds <torvalds@ppc970.osdl.org>
:::::: CC: Linus Torvalds <torvalds@ppc970.osdl.org>
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 57951 bytes --]
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH] lsilogic mpt fusion: mptctl: Fixed race condition around mptctl_id variable using mutexes
@ 2019-08-14 15:12 Mark Balantzyan
2019-08-14 19:53 ` kbuild test robot
0 siblings, 1 reply; 5+ messages in thread
From: Mark Balantzyan @ 2019-08-14 15:12 UTC (permalink / raw)
To: sathya.prakash
Cc: suganath-prabu.subramani, MPT=FusionLinux.pdl, linux-scsi,
linux-kernel, Mark Balantzyan
Certain functions in the driver, such as mptctl_do_fw_download() and
mptctl_do_mpt_command(), rely on the instance of mptctl_id, which does the
id-ing. There is race condition possible when these functions operate in
concurrency. Via, mutexes, the functions are mutually signalled to cooperate.
Signed-off-by: Mark Balantzyan <mbalant3@gmail.com>
---
drivers/message/fusion/mptctl.c | 36 ++++++++++++++++++++++++++-------
1 file changed, 29 insertions(+), 7 deletions(-)
diff --git a/drivers/message/fusion/mptctl.c b/drivers/message/fusion/mptctl.c
index 4470630d..58ce0fc0 100644
--- a/drivers/message/fusion/mptctl.c
+++ b/drivers/message/fusion/mptctl.c
@@ -816,12 +816,15 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
/* Valid device. Get a message frame and construct the FW download message.
*/
+ mutex_lock(&mpctl_mutex);
if ((mf = mpt_get_msg_frame(mptctl_id, iocp)) == NULL)
+ mutex_unlock(&mpctl_mutex);
return -EAGAIN;
}
-
+ mutex_lock(&mpctl_mutex);
dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT
"mptctl_do_fwdl called. mptctl_id = %xh.\n", iocp->name, mptctl_id));
+ mutex_unlock(&mpctl_mutex);
dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.bufp = %p\n",
iocp->name, ufwbuf));
dctlprintk(iocp, printk(MYIOC_s_DEBUG_FMT "DbG: kfwdl.fwlen = %d\n",
@@ -943,7 +946,9 @@ mptctl_do_fw_download(int ioc, char __user *ufwbuf, size_t fwlen)
ReplyMsg = NULL;
SET_MGMT_MSG_CONTEXT(iocp->ioctl_cmds.msg_context, dlmsg->MsgContext);
INITIALIZE_MGMT_STATUS(iocp->ioctl_cmds.status)
+ mutex_lock(&mpctl_mutex);
mpt_put_msg_frame(mptctl_id, iocp, mf);
+ mutex_lock(&mpctl_mutex);
/* Now wait for the command to complete */
retry_wait:
@@ -1889,7 +1894,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
/* Get a free request frame and save the message context.
*/
+ mutex_lock(&mpctl_mutex);
if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL)
+ mutex_unlock(&mpctl_mutex);
return -EAGAIN;
hdr = (MPIHeader_t *) mf;
@@ -2271,11 +2278,14 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
DBG_DUMP_TM_REQUEST_FRAME(ioc, (u32 *)mf);
if ((ioc->facts.IOCCapabilities & MPI_IOCFACTS_CAPABILITY_HIGH_PRI_Q) &&
- (ioc->facts.MsgVersion >= MPI_VERSION_01_05))
+ (ioc->facts.MsgVersion >= MPI_VERSION_01_05)) {
+ mutex_lock(&mpctl_mutex);
mpt_put_msg_frame_hi_pri(mptctl_id, ioc, mf);
- else {
- rc =mpt_send_handshake_request(mptctl_id, ioc,
- sizeof(SCSITaskMgmt_t), (u32*)mf, CAN_SLEEP);
+ mutex_unlock(&mpctl_mutex);
+ } else {
+ mutex_lock(&mpctl_mutex);
+ rc = mpt_send_handshake_request(mptctl_id, ioc, sizeof(SCSITaskMgmt_t), (u32 *)mf, CAN_SLEEP);
+ mutex_unlock(&mpctl_mutex);
if (rc != 0) {
dfailprintk(ioc, printk(MYIOC_s_ERR_FMT
"send_handshake FAILED! (ioc %p, mf %p)\n",
@@ -2288,7 +2298,9 @@ mptctl_do_mpt_command (struct mpt_ioctl_command karg, void __user *mfPtr)
}
} else
+ mutex_lock(&mpctl_mutex);
mpt_put_msg_frame(mptctl_id, ioc, mf);
+ mutex_unlock(&mpctl_mutex);
/* Now wait for the command to complete */
timeout = (karg.timeout > 0) ? karg.timeout : MPT_IOCTL_DEFAULT_TIMEOUT;
@@ -2563,7 +2575,9 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
/*
* Gather ISTWI(Industry Standard Two Wire Interface) Data
*/
+ mutex_lock(&mpctl_mutex);
if ((mf = mpt_get_msg_frame(mptctl_id, ioc)) == NULL) {
+ mutex_unlock(&mpctl_mutex);
dfailprintk(ioc, printk(MYIOC_s_WARN_FMT
"%s, no msg frames!!\n", ioc->name, __func__));
goto out;
@@ -2593,7 +2607,9 @@ mptctl_hp_hostinfo(unsigned long arg, unsigned int data_size)
SET_MGMT_MSG_CONTEXT(ioc->ioctl_cmds.msg_context,
IstwiRWRequest->MsgContext);
INITIALIZE_MGMT_STATUS(ioc->ioctl_cmds.status)
+ mutex_lock(&mpctl_mutex);
mpt_put_msg_frame(mptctl_id, ioc, mf);
+ mutex_unlock(&mpctl_mutex);
retry_wait:
timeleft = wait_for_completion_timeout(&ioc->ioctl_cmds.done,
@@ -3010,9 +3026,11 @@ static int __init mptctl_init(void)
* Install our handler
*/
++where;
+ mutex_lock(&mpctl_mutex);
mptctl_id = mpt_register(mptctl_reply, MPTCTL_DRIVER,
"mptctl_reply");
if (!mptctl_id || mptctl_id >= MPT_MAX_PROTOCOL_DRIVERS) {
+ mutex_unlock(&mpctl_mutex);
printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
misc_deregister(&mptctl_miscdev);
err = -EBUSY;
@@ -3022,13 +3040,14 @@ static int __init mptctl_init(void)
mptctl_taskmgmt_id = mpt_register(mptctl_taskmgmt_reply, MPTCTL_DRIVER,
"mptctl_taskmgmt_reply");
if (!mptctl_taskmgmt_id || mptctl_taskmgmt_id >= MPT_MAX_PROTOCOL_DRIVERS) {
+ mutex_unlock(&mpctl_mutex);
printk(KERN_ERR MYNAM ": ERROR: Failed to register with Fusion MPT base driver\n");
mpt_deregister(mptctl_id);
misc_deregister(&mptctl_miscdev);
err = -EBUSY;
goto out_fail;
}
-
+ mutex_unlock(&mpctl_mutex);
mpt_reset_register(mptctl_id, mptctl_ioc_reset);
mpt_event_register(mptctl_id, mptctl_event_process);
@@ -3044,13 +3063,14 @@ out_fail:
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=*/
static void mptctl_exit(void)
{
+ mutex_lock(&mpctl_mutex);
misc_deregister(&mptctl_miscdev);
printk(KERN_INFO MYNAM ": Deregistered /dev/%s @ (major,minor=%d,%d)\n",
mptctl_miscdev.name, MISC_MAJOR, mptctl_miscdev.minor);
/* De-register event handler from base module */
mpt_event_deregister(mptctl_id);
-
+
/* De-register reset handler from base module */
mpt_reset_deregister(mptctl_id);
@@ -3058,6 +3078,8 @@ static void mptctl_exit(void)
mpt_deregister(mptctl_taskmgmt_id);
mpt_deregister(mptctl_id);
+ mutex_unlock(&mpctl_mutex);
+
mpt_device_driver_deregister(MPTCTL_DRIVER);
}
--
2.17.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
end of thread, other threads:[~2019-08-15 5:52 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-14 15:14 [PATCH] lsilogic mpt fusion: mptctl: Fixed race condition around mptctl_id variable using mutexes Mark Balantzyan
-- strict thread matches above, loose matches on Subject: below --
2019-08-14 20:48 Mark Balantzyan
2019-08-15 5:51 ` kbuild test robot
2019-08-14 15:12 Mark Balantzyan
2019-08-14 19:53 ` kbuild test robot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).