aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt3sas/mpt3sas_ctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt3sas/mpt3sas_ctl.c')
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_ctl.c151
1 files changed, 123 insertions, 28 deletions
diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
index f257c962c899..d8366b056b70 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c
@@ -409,11 +409,14 @@ mpt3sas_ctl_event_callback(struct MPT3SAS_ADAPTER *ioc, u8 msix_index,
* _ctl_verify_adapter - validates ioc_number passed from application
* @ioc: per adapter object
* @iocpp: The ioc pointer is returned in this.
+ * @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device &
+ * MPI25_VERSION for mpt3ctl ioctl device.
*
* Return (-1) means error, else ioc_number.
*/
static int
-_ctl_verify_adapter(int ioc_number, struct MPT3SAS_ADAPTER **iocpp)
+_ctl_verify_adapter(int ioc_number, struct MPT3SAS_ADAPTER **iocpp,
+ int mpi_version)
{
struct MPT3SAS_ADAPTER *ioc;
/* global ioc lock to protect controller on list operations */
@@ -421,6 +424,11 @@ _ctl_verify_adapter(int ioc_number, struct MPT3SAS_ADAPTER **iocpp)
list_for_each_entry(ioc, &mpt3sas_ioc_list, list) {
if (ioc->id != ioc_number)
continue;
+ /* Check whether this ioctl command is from right
+ * ioctl device or not, if not continue the search.
+ */
+ if (ioc->hba_mpi_version_belonged != mpi_version)
+ continue;
spin_unlock(&gioc_lock);
*iocpp = ioc;
return ioc_number;
@@ -488,7 +496,7 @@ mpt3sas_ctl_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase)
}
/**
- * ctl_fasync -
+ * _ctl_fasync -
* @fd -
* @filep -
* @mode -
@@ -496,19 +504,19 @@ mpt3sas_ctl_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase)
* Called when application request fasyn callback handler.
*/
int
-ctl_fasync(int fd, struct file *filep, int mode)
+_ctl_fasync(int fd, struct file *filep, int mode)
{
return fasync_helper(fd, filep, mode, &async_queue);
}
/**
- * ctl_poll -
+ * _ctl_poll -
* @file -
* @wait -
*
*/
unsigned int
-ctl_poll(struct file *filep, poll_table *wait)
+_ctl_poll(struct file *filep, poll_table *wait)
{
struct MPT3SAS_ADAPTER *ioc;
@@ -1034,7 +1042,7 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
karg.pci_information.u.bits.function = PCI_FUNC(ioc->pdev->devfn);
karg.pci_information.segment_id = pci_domain_nr(ioc->pdev->bus);
karg.firmware_version = ioc->facts.FWVersion.Word;
- strcpy(karg.driver_version, driver_name);
+ strcpy(karg.driver_version, ioc->driver_name);
strcat(karg.driver_version, "-");
switch (ioc->hba_mpi_version_belonged) {
case MPI2_VERSION:
@@ -1049,10 +1057,6 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg)
strcat(karg.driver_version, MPT3SAS_DRIVER_VERSION);
break;
}
- if (ioc->hba_mpi_version_belonged == MPI2_VERSION)
- strcat(karg.driver_version, MPT2SAS_DRIVER_VERSION);
- else
- strcat(karg.driver_version, MPT3SAS_DRIVER_VERSION);
karg.bios_version = le32_to_cpu(ioc->bios_pg3.BiosVersion);
if (copy_to_user(arg, &karg, sizeof(karg))) {
@@ -2196,12 +2200,14 @@ _ctl_compat_mpt_command(struct MPT3SAS_ADAPTER *ioc, unsigned cmd,
* _ctl_ioctl_main - main ioctl entry point
* @file - (struct file)
* @cmd - ioctl opcode
- * @arg -
- * compat - handles 32 bit applications in 64bit os
+ * @arg - user space data buffer
+ * @compat - handles 32 bit applications in 64bit os
+ * @mpi_version: will be MPI2_VERSION for mpt2ctl ioctl device &
+ * MPI25_VERSION for mpt3ctl ioctl device.
*/
static long
_ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
- u8 compat)
+ u8 compat, u16 mpi_version)
{
struct MPT3SAS_ADAPTER *ioc;
struct mpt3_ioctl_header ioctl_header;
@@ -2216,7 +2222,8 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
return -EFAULT;
}
- if (_ctl_verify_adapter(ioctl_header.ioc_number, &ioc) == -1 || !ioc)
+ if (_ctl_verify_adapter(ioctl_header.ioc_number,
+ &ioc, mpi_version) == -1 || !ioc)
return -ENODEV;
/* pci_access_mutex lock acquired by ioctl path */
@@ -2324,23 +2331,43 @@ out_unlock_pciaccess:
}
/**
- * ctl_ioctl - main ioctl entry point (unlocked)
+ * _ctl_ioctl - mpt3ctl main ioctl entry point (unlocked)
* @file - (struct file)
* @cmd - ioctl opcode
* @arg -
*/
long
-ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
long ret;
- ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0);
+ /* pass MPI25_VERSION value, to indicate that this ioctl cmd
+ * came from mpt3ctl ioctl device.
+ */
+ ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0, MPI25_VERSION);
return ret;
}
+/**
+ * _ctl_mpt2_ioctl - mpt2ctl main ioctl entry point (unlocked)
+ * @file - (struct file)
+ * @cmd - ioctl opcode
+ * @arg -
+ */
+long
+_ctl_mpt2_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
+{
+ long ret;
+
+ /* pass MPI2_VERSION value, to indicate that this ioctl cmd
+ * came from mpt2ctl ioctl device.
+ */
+ ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 0, MPI2_VERSION);
+ return ret;
+}
#ifdef CONFIG_COMPAT
/**
- * ctl_ioctl_compat - main ioctl entry point (compat)
+ *_ ctl_ioctl_compat - main ioctl entry point (compat)
* @file -
* @cmd -
* @arg -
@@ -2348,11 +2375,28 @@ ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
* This routine handles 32 bit applications in 64bit os.
*/
long
-ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
+_ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
{
long ret;
- ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1);
+ ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1, MPI25_VERSION);
+ return ret;
+}
+
+/**
+ *_ ctl_mpt2_ioctl_compat - main ioctl entry point (compat)
+ * @file -
+ * @cmd -
+ * @arg -
+ *
+ * This routine handles 32 bit applications in 64bit os.
+ */
+long
+_ctl_mpt2_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg)
+{
+ long ret;
+
+ ret = _ctl_ioctl_main(file, cmd, (void __user *)arg, 1, MPI2_VERSION);
return ret;
}
#endif
@@ -2739,7 +2783,6 @@ _ctl_ioc_reply_queue_count_show(struct device *cdev,
static DEVICE_ATTR(reply_queue_count, S_IRUGO, _ctl_ioc_reply_queue_count_show,
NULL);
-#ifdef SCSI_MPT2SAS
/**
* _ctl_BRM_status_show - Backup Rail Monitor Status
* @cdev - pointer to embedded class device
@@ -2815,7 +2858,6 @@ _ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr,
return rc;
}
static DEVICE_ATTR(BRM_status, S_IRUGO, _ctl_BRM_status_show, NULL);
-#endif
struct DIAG_BUFFER_START {
__le32 Size;
@@ -3269,9 +3311,7 @@ struct device_attribute *mpt3sas_host_attrs[] = {
&dev_attr_diag_trigger_event,
&dev_attr_diag_trigger_scsi,
&dev_attr_diag_trigger_mpi,
-#ifdef SCSI_MPT2SAS
&dev_attr_BRM_status,
-#endif
NULL,
};
@@ -3325,23 +3365,74 @@ struct device_attribute *mpt3sas_dev_attrs[] = {
NULL,
};
+/* file operations table for mpt3ctl device */
+static const struct file_operations ctl_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = _ctl_ioctl,
+ .poll = _ctl_poll,
+ .fasync = _ctl_fasync,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = _ctl_ioctl_compat,
+#endif
+};
+
+/* file operations table for mpt2ctl device */
+static const struct file_operations ctl_gen2_fops = {
+ .owner = THIS_MODULE,
+ .unlocked_ioctl = _ctl_mpt2_ioctl,
+ .poll = _ctl_poll,
+ .fasync = _ctl_fasync,
+#ifdef CONFIG_COMPAT
+ .compat_ioctl = _ctl_mpt2_ioctl_compat,
+#endif
+};
+
+static struct miscdevice ctl_dev = {
+ .minor = MPT3SAS_MINOR,
+ .name = MPT3SAS_DEV_NAME,
+ .fops = &ctl_fops,
+};
+
+static struct miscdevice gen2_ctl_dev = {
+ .minor = MPT2SAS_MINOR,
+ .name = MPT2SAS_DEV_NAME,
+ .fops = &ctl_gen2_fops,
+};
+
/**
- * ctl_init - main entry point for ctl.
+ * mpt3sas_ctl_init - main entry point for ctl.
*
*/
void
-ctl_init(void)
+mpt3sas_ctl_init(ushort hbas_to_enumerate)
{
async_queue = NULL;
+
+ /* Don't register mpt3ctl ioctl device if
+ * hbas_to_enumarate is one.
+ */
+ if (hbas_to_enumerate != 1)
+ if (misc_register(&ctl_dev) < 0)
+ pr_err("%s can't register misc device [minor=%d]\n",
+ MPT3SAS_DRIVER_NAME, MPT3SAS_MINOR);
+
+ /* Don't register mpt3ctl ioctl device if
+ * hbas_to_enumarate is two.
+ */
+ if (hbas_to_enumerate != 2)
+ if (misc_register(&gen2_ctl_dev) < 0)
+ pr_err("%s can't register misc device [minor=%d]\n",
+ MPT2SAS_DRIVER_NAME, MPT2SAS_MINOR);
+
init_waitqueue_head(&ctl_poll_wait);
}
/**
- * ctl_exit - exit point for ctl
+ * mpt3sas_ctl_exit - exit point for ctl
*
*/
void
-ctl_exit(void)
+mpt3sas_ctl_exit(ushort hbas_to_enumerate)
{
struct MPT3SAS_ADAPTER *ioc;
int i;
@@ -3366,4 +3457,8 @@ ctl_exit(void)
kfree(ioc->event_log);
}
+ if (hbas_to_enumerate != 1)
+ misc_deregister(&ctl_dev);
+ if (hbas_to_enumerate != 2)
+ misc_deregister(&gen2_ctl_dev);
}