linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [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).