[SCSI] mpt2sas: Removed redundant global mutex for IOCTLs
authornagalakshmi.nandigama@lsi.com <nagalakshmi.nandigama@lsi.com>
Tue, 20 Mar 2012 06:34:11 +0000 (12:04 +0530)
committerJames Bottomley <JBottomley@Parallels.com>
Mon, 23 Apr 2012 18:26:56 +0000 (19:26 +0100)
When the lock_kernel and unlock_kernel routines were removed in the
2.6.39 kernel, a global mutex was added on top of the existing mutex
which already existed. With this implementation, only one IOCTL
will be active at any time no matter how many ever controllers
are present. This causes poor performance.

Removed the global mutex so that the driver can work with the existing
semaphore that was already part of the existing code.

Signed-off-by: Nagalakshmi Nandigama <nagalakshmi.nandigama@lsi.com>
Signed-off-by: James Bottomley <JBottomley@Parallels.com>
drivers/scsi/mpt2sas/mpt2sas_ctl.c

index 3b9a28efea8281fe85b5c5c1e4757da60f5cf061..8eb85e1a0c374457aeec3118b22b22b94ca18ea8 100644 (file)
@@ -620,11 +620,10 @@ _ctl_set_task_mid(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command *karg,
  * @ioc: per adapter object
  * @karg - (struct mpt2_ioctl_command)
  * @mf - pointer to mf in user space
- * @state - NON_BLOCKING or BLOCKING
  */
 static long
-_ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
-    struct mpt2_ioctl_command karg, void __user *mf, enum block_state state)
+_ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc, struct mpt2_ioctl_command karg,
+       void __user *mf)
 {
        MPI2RequestHeader_t *mpi_request = NULL, *request;
        MPI2DefaultReply_t *mpi_reply;
@@ -647,11 +646,6 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
 
        issue_reset = 0;
 
-       if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
-               return -EAGAIN;
-       else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
-               return -ERESTARTSYS;
-
        if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
                printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
                    ioc->name, __func__);
@@ -1013,27 +1007,24 @@ _ctl_do_mpt_command(struct MPT2SAS_ADAPTER *ioc,
 
        kfree(mpi_request);
        ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
-       mutex_unlock(&ioc->ctl_cmds.mutex);
        return ret;
 }
 
 /**
  * _ctl_getiocinfo - main handler for MPT2IOCINFO opcode
+ * @ioc: per adapter object
  * @arg - user space buffer containing ioctl content
  */
 static long
-_ctl_getiocinfo(void __user *arg)
+_ctl_getiocinfo(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
 {
        struct mpt2_ioctl_iocinfo karg;
-       struct MPT2SAS_ADAPTER *ioc;
 
        if (copy_from_user(&karg, arg, sizeof(karg))) {
                printk(KERN_ERR "failure at %s:%d/%s()!\n",
                    __FILE__, __LINE__, __func__);
                return -EFAULT;
        }
-       if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
-               return -ENODEV;
 
        dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
            __func__));
@@ -1069,21 +1060,19 @@ _ctl_getiocinfo(void __user *arg)
 
 /**
  * _ctl_eventquery - main handler for MPT2EVENTQUERY opcode
+ * @ioc: per adapter object
  * @arg - user space buffer containing ioctl content
  */
 static long
-_ctl_eventquery(void __user *arg)
+_ctl_eventquery(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
 {
        struct mpt2_ioctl_eventquery karg;
-       struct MPT2SAS_ADAPTER *ioc;
 
        if (copy_from_user(&karg, arg, sizeof(karg))) {
                printk(KERN_ERR "failure at %s:%d/%s()!\n",
                    __FILE__, __LINE__, __func__);
                return -EFAULT;
        }
-       if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
-               return -ENODEV;
 
        dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
            __func__));
@@ -1102,21 +1091,19 @@ _ctl_eventquery(void __user *arg)
 
 /**
  * _ctl_eventenable - main handler for MPT2EVENTENABLE opcode
+ * @ioc: per adapter object
  * @arg - user space buffer containing ioctl content
  */
 static long
-_ctl_eventenable(void __user *arg)
+_ctl_eventenable(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
 {
        struct mpt2_ioctl_eventenable karg;
-       struct MPT2SAS_ADAPTER *ioc;
 
        if (copy_from_user(&karg, arg, sizeof(karg))) {
                printk(KERN_ERR "failure at %s:%d/%s()!\n",
                    __FILE__, __LINE__, __func__);
                return -EFAULT;
        }
-       if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
-               return -ENODEV;
 
        dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
            __func__));
@@ -1142,13 +1129,13 @@ _ctl_eventenable(void __user *arg)
 
 /**
  * _ctl_eventreport - main handler for MPT2EVENTREPORT opcode
+ * @ioc: per adapter object
  * @arg - user space buffer containing ioctl content
  */
 static long
-_ctl_eventreport(void __user *arg)
+_ctl_eventreport(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
 {
        struct mpt2_ioctl_eventreport karg;
-       struct MPT2SAS_ADAPTER *ioc;
        u32 number_bytes, max_events, max;
        struct mpt2_ioctl_eventreport __user *uarg = arg;
 
@@ -1157,8 +1144,6 @@ _ctl_eventreport(void __user *arg)
                    __FILE__, __LINE__, __func__);
                return -EFAULT;
        }
-       if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
-               return -ENODEV;
 
        dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s: enter\n", ioc->name,
            __func__));
@@ -1188,13 +1173,13 @@ _ctl_eventreport(void __user *arg)
 
 /**
  * _ctl_do_reset - main handler for MPT2HARDRESET opcode
+ * @ioc: per adapter object
  * @arg - user space buffer containing ioctl content
  */
 static long
-_ctl_do_reset(void __user *arg)
+_ctl_do_reset(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
 {
        struct mpt2_ioctl_diag_reset karg;
-       struct MPT2SAS_ADAPTER *ioc;
        int retval;
 
        if (copy_from_user(&karg, arg, sizeof(karg))) {
@@ -1202,8 +1187,6 @@ _ctl_do_reset(void __user *arg)
                    __FILE__, __LINE__, __func__);
                return -EFAULT;
        }
-       if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
-               return -ENODEV;
 
        if (ioc->shost_recovery || ioc->pci_error_recovery ||
                ioc->is_driver_loading)
@@ -1292,13 +1275,13 @@ _ctl_btdh_search_raid_device(struct MPT2SAS_ADAPTER *ioc,
 
 /**
  * _ctl_btdh_mapping - main handler for MPT2BTDHMAPPING opcode
+ * @ioc: per adapter object
  * @arg - user space buffer containing ioctl content
  */
 static long
-_ctl_btdh_mapping(void __user *arg)
+_ctl_btdh_mapping(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
 {
        struct mpt2_ioctl_btdh_mapping karg;
-       struct MPT2SAS_ADAPTER *ioc;
        int rc;
 
        if (copy_from_user(&karg, arg, sizeof(karg))) {
@@ -1306,8 +1289,6 @@ _ctl_btdh_mapping(void __user *arg)
                    __FILE__, __LINE__, __func__);
                return -EFAULT;
        }
-       if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
-               return -ENODEV;
 
        dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
            __func__));
@@ -1576,17 +1557,16 @@ mpt2sas_enable_diag_buffer(struct MPT2SAS_ADAPTER *ioc, u8 bits_to_register)
 
 /**
  * _ctl_diag_register - application register with driver
+ * @ioc: per adapter object
  * @arg - user space buffer containing ioctl content
- * @state - NON_BLOCKING or BLOCKING
  *
  * This will allow the driver to setup any required buffers that will be
  * needed by firmware to communicate with the driver.
  */
 static long
-_ctl_diag_register(void __user *arg, enum block_state state)
+_ctl_diag_register(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
 {
        struct mpt2_diag_register karg;
-       struct MPT2SAS_ADAPTER *ioc;
        long rc;
 
        if (copy_from_user(&karg, arg, sizeof(karg))) {
@@ -1594,30 +1574,23 @@ _ctl_diag_register(void __user *arg, enum block_state state)
                    __FILE__, __LINE__, __func__);
                return -EFAULT;
        }
-       if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
-               return -ENODEV;
 
-       if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
-               return -EAGAIN;
-       else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
-               return -ERESTARTSYS;
        rc = _ctl_diag_register_2(ioc, &karg);
-       mutex_unlock(&ioc->ctl_cmds.mutex);
        return rc;
 }
 
 /**
  * _ctl_diag_unregister - application unregister with driver
+ * @ioc: per adapter object
  * @arg - user space buffer containing ioctl content
  *
  * This will allow the driver to cleanup any memory allocated for diag
  * messages and to free up any resources.
  */
 static long
-_ctl_diag_unregister(void __user *arg)
+_ctl_diag_unregister(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
 {
        struct mpt2_diag_unregister karg;
-       struct MPT2SAS_ADAPTER *ioc;
        void *request_data;
        dma_addr_t request_data_dma;
        u32 request_data_sz;
@@ -1628,8 +1601,6 @@ _ctl_diag_unregister(void __user *arg)
                    __FILE__, __LINE__, __func__);
                return -EFAULT;
        }
-       if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
-               return -ENODEV;
 
        dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
            __func__));
@@ -1678,6 +1649,7 @@ _ctl_diag_unregister(void __user *arg)
 
 /**
  * _ctl_diag_query - query relevant info associated with diag buffers
+ * @ioc: per adapter object
  * @arg - user space buffer containing ioctl content
  *
  * The application will send only buffer_type and unique_id.  Driver will
@@ -1685,10 +1657,9 @@ _ctl_diag_unregister(void __user *arg)
  * 0x00, the driver will return info specified by Buffer Type.
  */
 static long
-_ctl_diag_query(void __user *arg)
+_ctl_diag_query(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
 {
        struct mpt2_diag_query karg;
-       struct MPT2SAS_ADAPTER *ioc;
        void *request_data;
        int i;
        u8 buffer_type;
@@ -1698,8 +1669,6 @@ _ctl_diag_query(void __user *arg)
                    __FILE__, __LINE__, __func__);
                return -EFAULT;
        }
-       if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
-               return -ENODEV;
 
        dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
            __func__));
@@ -1866,17 +1835,15 @@ _ctl_send_release(struct MPT2SAS_ADAPTER *ioc, u8 buffer_type, u8 *issue_reset)
 /**
  * _ctl_diag_release - request to send Diag Release Message to firmware
  * @arg - user space buffer containing ioctl content
- * @state - NON_BLOCKING or BLOCKING
  *
  * This allows ownership of the specified buffer to returned to the driver,
  * allowing an application to read the buffer without fear that firmware is
  * overwritting information in the buffer.
  */
 static long
-_ctl_diag_release(void __user *arg, enum block_state state)
+_ctl_diag_release(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
 {
        struct mpt2_diag_release karg;
-       struct MPT2SAS_ADAPTER *ioc;
        void *request_data;
        int rc;
        u8 buffer_type;
@@ -1887,8 +1854,6 @@ _ctl_diag_release(void __user *arg, enum block_state state)
                    __FILE__, __LINE__, __func__);
                return -EFAULT;
        }
-       if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
-               return -ENODEV;
 
        dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
            __func__));
@@ -1942,32 +1907,25 @@ _ctl_diag_release(void __user *arg, enum block_state state)
                return 0;
        }
 
-       if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
-               return -EAGAIN;
-       else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
-               return -ERESTARTSYS;
-
        rc = _ctl_send_release(ioc, buffer_type, &issue_reset);
 
        if (issue_reset)
                mpt2sas_base_hard_reset_handler(ioc, CAN_SLEEP,
                    FORCE_BIG_HAMMER);
 
-       mutex_unlock(&ioc->ctl_cmds.mutex);
        return rc;
 }
 
 /**
  * _ctl_diag_read_buffer - request for copy of the diag buffer
+ * @ioc: per adapter object
  * @arg - user space buffer containing ioctl content
- * @state - NON_BLOCKING or BLOCKING
  */
 static long
-_ctl_diag_read_buffer(void __user *arg, enum block_state state)
+_ctl_diag_read_buffer(struct MPT2SAS_ADAPTER *ioc, void __user *arg)
 {
        struct mpt2_diag_read_buffer karg;
        struct mpt2_diag_read_buffer __user *uarg = arg;
-       struct MPT2SAS_ADAPTER *ioc;
        void *request_data, *diag_data;
        Mpi2DiagBufferPostRequest_t *mpi_request;
        Mpi2DiagBufferPostReply_t *mpi_reply;
@@ -1983,8 +1941,6 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state)
                    __FILE__, __LINE__, __func__);
                return -EFAULT;
        }
-       if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 || !ioc)
-               return -ENODEV;
 
        dctlprintk(ioc, printk(MPT2SAS_INFO_FMT "%s\n", ioc->name,
            __func__));
@@ -2055,10 +2011,6 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state)
        }
        /* Get a free request frame and save the message context.
        */
-       if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
-               return -EAGAIN;
-       else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
-               return -ERESTARTSYS;
 
        if (ioc->ctl_cmds.status != MPT2_CMD_NOT_USED) {
                printk(MPT2SAS_ERR_FMT "%s: ctl_cmd in use\n",
@@ -2139,115 +2091,170 @@ _ctl_diag_read_buffer(void __user *arg, enum block_state state)
  out:
 
        ioc->ctl_cmds.status = MPT2_CMD_NOT_USED;
-       mutex_unlock(&ioc->ctl_cmds.mutex);
        return rc;
 }
 
+
+#ifdef CONFIG_COMPAT
+/**
+ * _ctl_compat_mpt_command - convert 32bit pointers to 64bit.
+ * @ioc: per adapter object
+ * @cmd - ioctl opcode
+ * @arg - (struct mpt2_ioctl_command32)
+ *
+ * MPT2COMMAND32 - Handle 32bit applications running on 64bit os.
+ */
+static long
+_ctl_compat_mpt_command(struct MPT2SAS_ADAPTER *ioc, unsigned cmd,
+       void __user *arg)
+{
+       struct mpt2_ioctl_command32 karg32;
+       struct mpt2_ioctl_command32 __user *uarg;
+       struct mpt2_ioctl_command karg;
+
+       if (_IOC_SIZE(cmd) != sizeof(struct mpt2_ioctl_command32))
+               return -EINVAL;
+
+       uarg = (struct mpt2_ioctl_command32 __user *) arg;
+
+       if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32))) {
+               printk(KERN_ERR "failure at %s:%d/%s()!\n",
+                   __FILE__, __LINE__, __func__);
+               return -EFAULT;
+       }
+
+       memset(&karg, 0, sizeof(struct mpt2_ioctl_command));
+       karg.hdr.ioc_number = karg32.hdr.ioc_number;
+       karg.hdr.port_number = karg32.hdr.port_number;
+       karg.hdr.max_data_size = karg32.hdr.max_data_size;
+       karg.timeout = karg32.timeout;
+       karg.max_reply_bytes = karg32.max_reply_bytes;
+       karg.data_in_size = karg32.data_in_size;
+       karg.data_out_size = karg32.data_out_size;
+       karg.max_sense_bytes = karg32.max_sense_bytes;
+       karg.data_sge_offset = karg32.data_sge_offset;
+       karg.reply_frame_buf_ptr = compat_ptr(karg32.reply_frame_buf_ptr);
+       karg.data_in_buf_ptr = compat_ptr(karg32.data_in_buf_ptr);
+       karg.data_out_buf_ptr = compat_ptr(karg32.data_out_buf_ptr);
+       karg.sense_data_ptr = compat_ptr(karg32.sense_data_ptr);
+       return _ctl_do_mpt_command(ioc, karg, &uarg->mf);
+}
+#endif
+
 /**
  * _ctl_ioctl_main - main ioctl entry point
  * @file - (struct file)
  * @cmd - ioctl opcode
  * @arg -
+ * compat - handles 32 bit applications in 64bit os
  */
 static long
-_ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg)
+_ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
+       u8 compat)
 {
+       struct MPT2SAS_ADAPTER *ioc;
+       struct mpt2_ioctl_header ioctl_header;
        enum block_state state;
        long ret = -EINVAL;
 
-       state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING :
-           BLOCKING;
+       /* get IOCTL header */
+       if (copy_from_user(&ioctl_header, (char __user *)arg,
+           sizeof(struct mpt2_ioctl_header))) {
+               printk(KERN_ERR "failure at %s:%d/%s()!\n",
+                   __FILE__, __LINE__, __func__);
+               return -EFAULT;
+       }
+
+       if (_ctl_verify_adapter(ioctl_header.ioc_number, &ioc) == -1 || !ioc)
+               return -ENODEV;
+       if (ioc->shost_recovery || ioc->pci_error_recovery ||
+           ioc->is_driver_loading)
+               return -EAGAIN;
+
+       state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING;
+       if (state == NON_BLOCKING && !mutex_trylock(&ioc->ctl_cmds.mutex))
+               return -EAGAIN;
+       else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex))
+               return -ERESTARTSYS;
 
        switch (cmd) {
        case MPT2IOCINFO:
                if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_iocinfo))
-                       ret = _ctl_getiocinfo(arg);
+                       ret = _ctl_getiocinfo(ioc, arg);
                break;
+#ifdef CONFIG_COMPAT
+       case MPT2COMMAND32:
+#endif
        case MPT2COMMAND:
        {
-               struct mpt2_ioctl_command karg;
                struct mpt2_ioctl_command __user *uarg;
-               struct MPT2SAS_ADAPTER *ioc;
-
+               struct mpt2_ioctl_command karg;
+#ifdef CONFIG_COMPAT
+               if (compat) {
+                       ret = _ctl_compat_mpt_command(ioc, cmd, arg);
+                       break;
+               }
+#endif
                if (copy_from_user(&karg, arg, sizeof(karg))) {
                        printk(KERN_ERR "failure at %s:%d/%s()!\n",
                            __FILE__, __LINE__, __func__);
-                       return -EFAULT;
+                       ret = -EFAULT;
+                       break;
                }
 
-               if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 ||
-                   !ioc)
-                       return -ENODEV;
-
-               if (ioc->shost_recovery || ioc->pci_error_recovery ||
-                               ioc->is_driver_loading)
-                       return -EAGAIN;
-
                if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_command)) {
                        uarg = arg;
-                       ret = _ctl_do_mpt_command(ioc, karg, &uarg->mf, state);
+                       ret = _ctl_do_mpt_command(ioc, karg, &uarg->mf);
                }
                break;
        }
        case MPT2EVENTQUERY:
                if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_eventquery))
-                       ret = _ctl_eventquery(arg);
+                       ret = _ctl_eventquery(ioc, arg);
                break;
        case MPT2EVENTENABLE:
                if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_eventenable))
-                       ret = _ctl_eventenable(arg);
+                       ret = _ctl_eventenable(ioc, arg);
                break;
        case MPT2EVENTREPORT:
-               ret = _ctl_eventreport(arg);
+               ret = _ctl_eventreport(ioc, arg);
                break;
        case MPT2HARDRESET:
                if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_diag_reset))
-                       ret = _ctl_do_reset(arg);
+                       ret = _ctl_do_reset(ioc, arg);
                break;
        case MPT2BTDHMAPPING:
                if (_IOC_SIZE(cmd) == sizeof(struct mpt2_ioctl_btdh_mapping))
-                       ret = _ctl_btdh_mapping(arg);
+                       ret = _ctl_btdh_mapping(ioc, arg);
                break;
        case MPT2DIAGREGISTER:
                if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_register))
-                       ret = _ctl_diag_register(arg, state);
+                       ret = _ctl_diag_register(ioc, arg);
                break;
        case MPT2DIAGUNREGISTER:
                if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_unregister))
-                       ret = _ctl_diag_unregister(arg);
+                       ret = _ctl_diag_unregister(ioc, arg);
                break;
        case MPT2DIAGQUERY:
                if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_query))
-                       ret = _ctl_diag_query(arg);
+                       ret = _ctl_diag_query(ioc, arg);
                break;
        case MPT2DIAGRELEASE:
                if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_release))
-                       ret = _ctl_diag_release(arg, state);
+                       ret = _ctl_diag_release(ioc, arg);
                break;
        case MPT2DIAGREADBUFFER:
                if (_IOC_SIZE(cmd) == sizeof(struct mpt2_diag_read_buffer))
-                       ret = _ctl_diag_read_buffer(arg, state);
+                       ret = _ctl_diag_read_buffer(ioc, arg);
                break;
        default:
-       {
-               struct mpt2_ioctl_command karg;
-               struct MPT2SAS_ADAPTER *ioc;
-
-               if (copy_from_user(&karg, arg, sizeof(karg))) {
-                       printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                           __FILE__, __LINE__, __func__);
-                       return -EFAULT;
-               }
-
-               if (_ctl_verify_adapter(karg.hdr.ioc_number, &ioc) == -1 ||
-                   !ioc)
-                       return -ENODEV;
 
                dctlprintk(ioc, printk(MPT2SAS_INFO_FMT
                    "unsupported ioctl opcode(0x%08x)\n", ioc->name, cmd));
                break;
        }
-       }
+
+       mutex_unlock(&ioc->ctl_cmds.mutex);
        return ret;
 }
 
@@ -2262,65 +2269,10 @@ _ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
 {
        long ret;
 
-       mutex_lock(&_ctl_mutex);
-       ret = _ctl_ioctl_main(file, cmd, (void __user *)arg);
-       mutex_unlock(&_ctl_mutex);
+       ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0);
        return ret;
 }
-
 #ifdef CONFIG_COMPAT
-/**
- * _ctl_compat_mpt_command - convert 32bit pointers to 64bit.
- * @file - (struct file)
- * @cmd - ioctl opcode
- * @arg - (struct mpt2_ioctl_command32)
- *
- * MPT2COMMAND32 - Handle 32bit applications running on 64bit os.
- */
-static long
-_ctl_compat_mpt_command(struct file *file, unsigned cmd, unsigned long arg)
-{
-       struct mpt2_ioctl_command32 karg32;
-       struct mpt2_ioctl_command32 __user *uarg;
-       struct mpt2_ioctl_command karg;
-       struct MPT2SAS_ADAPTER *ioc;
-       enum block_state state;
-
-       if (_IOC_SIZE(cmd) != sizeof(struct mpt2_ioctl_command32))
-               return -EINVAL;
-
-       uarg = (struct mpt2_ioctl_command32 __user *) arg;
-
-       if (copy_from_user(&karg32, (char __user *)arg, sizeof(karg32))) {
-               printk(KERN_ERR "failure at %s:%d/%s()!\n",
-                   __FILE__, __LINE__, __func__);
-               return -EFAULT;
-       }
-       if (_ctl_verify_adapter(karg32.hdr.ioc_number, &ioc) == -1 || !ioc)
-               return -ENODEV;
-
-       if (ioc->shost_recovery || ioc->pci_error_recovery ||
-                       ioc->is_driver_loading)
-               return -EAGAIN;
-
-       memset(&karg, 0, sizeof(struct mpt2_ioctl_command));
-       karg.hdr.ioc_number = karg32.hdr.ioc_number;
-       karg.hdr.port_number = karg32.hdr.port_number;
-       karg.hdr.max_data_size = karg32.hdr.max_data_size;
-       karg.timeout = karg32.timeout;
-       karg.max_reply_bytes = karg32.max_reply_bytes;
-       karg.data_in_size = karg32.data_in_size;
-       karg.data_out_size = karg32.data_out_size;
-       karg.max_sense_bytes = karg32.max_sense_bytes;
-       karg.data_sge_offset = karg32.data_sge_offset;
-       karg.reply_frame_buf_ptr = compat_ptr(karg32.reply_frame_buf_ptr);
-       karg.data_in_buf_ptr = compat_ptr(karg32.data_in_buf_ptr);
-       karg.data_out_buf_ptr = compat_ptr(karg32.data_out_buf_ptr);
-       karg.sense_data_ptr = compat_ptr(karg32.sense_data_ptr);
-       state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING;
-       return _ctl_do_mpt_command(ioc, karg, &uarg->mf, state);
-}
-
 /**
  * _ctl_ioctl_compat - main ioctl entry point (compat)
  * @file -
@@ -2334,12 +2286,7 @@ _ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
 {
        long ret;
 
-       mutex_lock(&_ctl_mutex);
-       if (cmd == MPT2COMMAND32)
-               ret = _ctl_compat_mpt_command(file, cmd, arg);
-       else
-               ret = _ctl_ioctl_main(file, cmd, (void __user *)arg);
-       mutex_unlock(&_ctl_mutex);
+       ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1);
        return ret;
 }
 #endif