|
@@ -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
|