From 8a7e4c24e08fceb94887eb6d8123d6059dc5ddcd Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Wed, 11 Nov 2015 17:30:18 +0530 Subject: mpt3sas: Added mpt2sas driver definitions 1. Added mpt2sas driver related macros in mpt3sas header files 2. Made scsi host's, raid class', pci's, ioctl's callback functions global so that both drivers can use them. Signed-off-by: Sreekanth Reddy Acked-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 40 +++++++++++++++++++------------------- 1 file changed, 20 insertions(+), 20 deletions(-) (limited to 'drivers/scsi/mpt3sas/mpt3sas_ctl.c') diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 080c8a76d23d..e72a16c02eaf 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -490,27 +490,27 @@ mpt3sas_ctl_reset_handler(struct MPT3SAS_ADAPTER *ioc, int reset_phase) } /** - * _ctl_fasync - + * ctl_fasync - * @fd - * @filep - * @mode - * * Called when application request fasyn callback handler. */ -static int -_ctl_fasync(int fd, struct file *filep, int mode) +int +ctl_fasync(int fd, struct file *filep, int mode) { return fasync_helper(fd, filep, mode, &async_queue); } /** - * _ctl_poll - + * ctl_poll - * @file - * @wait - * */ -static unsigned int -_ctl_poll(struct file *filep, poll_table *wait) +unsigned int +ctl_poll(struct file *filep, poll_table *wait) { struct MPT3SAS_ADAPTER *ioc; @@ -2298,13 +2298,13 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg, } /** - * _ctl_ioctl - main ioctl entry point (unlocked) + * ctl_ioctl - main ioctl entry point (unlocked) * @file - (struct file) * @cmd - ioctl opcode * @arg - */ -static long -_ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) +long +ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { long ret; @@ -2314,15 +2314,15 @@ _ctl_ioctl(struct file *file, unsigned int cmd, unsigned long arg) #ifdef CONFIG_COMPAT /** - * _ctl_ioctl_compat - main ioctl entry point (compat) + * ctl_ioctl_compat - main ioctl entry point (compat) * @file - * @cmd - * @arg - * * This routine handles 32 bit applications in 64bit os. */ -static long -_ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg) +long +ctl_ioctl_compat(struct file *file, unsigned cmd, unsigned long arg) { long ret; @@ -3220,11 +3220,11 @@ struct device_attribute *mpt3sas_dev_attrs[] = { static const struct file_operations ctl_fops = { .owner = THIS_MODULE, - .unlocked_ioctl = _ctl_ioctl, - .poll = _ctl_poll, - .fasync = _ctl_fasync, + .unlocked_ioctl = ctl_ioctl, + .poll = ctl_poll, + .fasync = ctl_fasync, #ifdef CONFIG_COMPAT - .compat_ioctl = _ctl_ioctl_compat, + .compat_ioctl = ctl_ioctl_compat, #endif }; @@ -3235,11 +3235,11 @@ static struct miscdevice ctl_dev = { }; /** - * mpt3sas_ctl_init - main entry point for ctl. + * ctl_init - main entry point for ctl. * */ void -mpt3sas_ctl_init(void) +ctl_init(void) { async_queue = NULL; if (misc_register(&ctl_dev) < 0) @@ -3250,11 +3250,11 @@ mpt3sas_ctl_init(void) } /** - * mpt3sas_ctl_exit - exit point for ctl + * ctl_exit - exit point for ctl * */ void -mpt3sas_ctl_exit(void) +ctl_exit(void) { struct MPT3SAS_ADAPTER *ioc; int i; -- cgit v1.2.1 From 7497392a1193ea5b32d8a8a2b8d77888e7fe8221 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Wed, 11 Nov 2015 17:30:19 +0530 Subject: mpt3sas: Move Gen3 HBA's device registration to a separate file Created a mpt3sas_module.c file for mpt3sas driver where it can register SAS3 HBA devices with PCI, SML, IOCTL subsystems. Also removed the corresponding interfaces from mpt3sas_scsih.c file. Signed-off-by: Sreekanth Reddy Acked-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 21 --------------------- 1 file changed, 21 deletions(-) (limited to 'drivers/scsi/mpt3sas/mpt3sas_ctl.c') diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index e72a16c02eaf..ffe79829de30 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -3218,22 +3218,6 @@ struct device_attribute *mpt3sas_dev_attrs[] = { NULL, }; -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 -}; - -static struct miscdevice ctl_dev = { - .minor = MPT3SAS_MINOR, - .name = MPT3SAS_DEV_NAME, - .fops = &ctl_fops, -}; - /** * ctl_init - main entry point for ctl. * @@ -3242,10 +3226,6 @@ void ctl_init(void) { async_queue = NULL; - if (misc_register(&ctl_dev) < 0) - pr_err("%s can't register misc device [minor=%d]\n", - MPT3SAS_DRIVER_NAME, MPT3SAS_MINOR); - init_waitqueue_head(&ctl_poll_wait); } @@ -3279,5 +3259,4 @@ ctl_exit(void) kfree(ioc->event_log); } - misc_deregister(&ctl_dev); } -- cgit v1.2.1 From d357e84d65dfcdb502fdb1aaab2873a82a828db5 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Wed, 11 Nov 2015 17:30:22 +0530 Subject: mpt3sas: Define 'hba_mpi_version_belonged' IOC variable 1. Use 'hba_mpi_version_belonged' IOC varable to uniquely identify each individual generation driver functionality at runtime. 2. Declare global variable 'driver_name' and use this variable while reserving PCI regions and while allocating the IRQs. Signed-off-by: Sreekanth Reddy Acked-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) (limited to 'drivers/scsi/mpt3sas/mpt3sas_ctl.c') diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index ffe79829de30..8b46cbf9463f 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -1023,7 +1023,6 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg) __func__)); memset(&karg, 0 , sizeof(karg)); - karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS3; if (ioc->pfacts) karg.port_number = ioc->pfacts[0].PortNumber; karg.hw_rev = ioc->pdev->revision; @@ -1035,9 +1034,22 @@ _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, MPT3SAS_DRIVER_NAME); + strcpy(karg.driver_version, driver_name); strcat(karg.driver_version, "-"); - strcat(karg.driver_version, MPT3SAS_DRIVER_VERSION); + switch (ioc->hba_mpi_version_belonged) { + case MPI2_VERSION: + karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2; + strcat(karg.driver_version, MPT2SAS_DRIVER_VERSION); + break; + case MPI25_VERSION: + karg.adapter_type = MPT3_IOCTL_INTERFACE_SAS3; + 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))) { -- cgit v1.2.1 From af0094115b080b41eb5a3567c177ce960a07dea4 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Wed, 11 Nov 2015 17:30:23 +0530 Subject: mpt2sas, mpt3sas: Remove SCSI_MPTXSAS_LOGGING entry from Kconfig Currently there is a logging level option provided for each of our drivers in the kernel configuration utility. Users can enable this option to get more verbose information. By default it is enabled. Only when this option is enabled will the functions which display the required information get compiled in. As we are merging the both drivers we can no longer provide this configuration option. Remove the SCSI_MPTXSAS_LOGGING entry from Kconfig and unconditionally enable logging (by removing the #ifdef CONFIG_SCSI_MPT3SAS_LOGGING preprocessor check conditions) so that all functions which are defined to display more verbose information get compiled in. Signed-off-by: Sreekanth Reddy Acked-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers/scsi/mpt3sas/mpt3sas_ctl.c') diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 8b46cbf9463f..5c08d31f781f 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -78,7 +78,6 @@ enum block_state { BLOCKING, }; -#ifdef CONFIG_SCSI_MPT3SAS_LOGGING /** * _ctl_sas_device_find_by_handle - sas device search * @ioc: per adapter object @@ -254,8 +253,6 @@ _ctl_display_some_debug(struct MPT3SAS_ADAPTER *ioc, u16 smid, } } -#endif - /** * mpt3sas_ctl_done - ctl module completion routine * @ioc: per adapter object @@ -302,9 +299,7 @@ mpt3sas_ctl_done(struct MPT3SAS_ADAPTER *ioc, u16 smid, u8 msix_index, } } } -#ifdef CONFIG_SCSI_MPT3SAS_LOGGING _ctl_display_some_debug(ioc, smid, "ctl_done", mpi_reply); -#endif ioc->ctl_cmds.status &= ~MPT3_CMD_PENDING; complete(&ioc->ctl_cmds.done); return 1; @@ -759,9 +754,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, psge = (void *)request + (karg.data_sge_offset*4); /* send command to firmware */ -#ifdef CONFIG_SCSI_MPT3SAS_LOGGING _ctl_display_some_debug(ioc, smid, "ctl_request", NULL); -#endif init_completion(&ioc->ctl_cmds.done); switch (mpi_request->Function) { @@ -916,7 +909,6 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, mpi_reply = ioc->ctl_cmds.reply; ioc_status = le16_to_cpu(mpi_reply->IOCStatus) & MPI2_IOCSTATUS_MASK; -#ifdef CONFIG_SCSI_MPT3SAS_LOGGING if (mpi_reply->Function == MPI2_FUNCTION_SCSI_TASK_MGMT && (ioc->logging_level & MPT_DEBUG_TM)) { Mpi2SCSITaskManagementReply_t *tm_reply = @@ -929,7 +921,7 @@ _ctl_do_mpt_command(struct MPT3SAS_ADAPTER *ioc, struct mpt3_ioctl_command karg, le32_to_cpu(tm_reply->IOCLogInfo), le32_to_cpu(tm_reply->TerminationCount)); } -#endif + /* copy out xdata to user */ if (data_in_sz) { if (copy_to_user(karg.data_in_buf_ptr, data_in, -- cgit v1.2.1 From 7786ab6aff9cea97eb0a8d67705c68e97a664bf3 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Wed, 11 Nov 2015 17:30:28 +0530 Subject: mpt3sas: Ported WarpDrive product SSS6200 support Ported the following list of WarpDrive-specific patches: 1. commit 0bdccdb0a090ad8dc5f851cad5e843244c410ee8 ("mpt2sas: WarpDrive New product SSS6200 support added") 2. commit 82a452581230b3ffc9d6475dffdb2568497b5fec ("mpt2sas: WarpDrive Infinite command retries due to wrong scsi command entry in MPI message") 3. commit ba96bd0b1d4a4e11f23671e1f375a5c8f46b0fe7 ("mpt2sas: Support for greater than 2TB capacity WarpDrive") 4. commit 4da7af9494b2f98a1503a2634059300c3e4615e6 ("mpt2sas: Do not retry a timed out direct IO for Warpdrive") 5. commit daeaa9df92bd742f4e6d4d6039d689277a8e31bd ("mpt2sas: Avoid type casting for direct I/O commands"). Also set the mpt2_ioctl_iocinfo adapter_type to: 1. MPT3_IOCTL_INTERFACE_SAS3 for Gen3 HBAs 2. MPT2_IOCTL_INTERFACE_SAS2_SSS6200 for Warp Drive 3. MPT2_IOCTL_INTERFACE_SAS2 for other Gen2 HBAs Signed-off-by: Sreekanth Reddy Acked-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'drivers/scsi/mpt3sas/mpt3sas_ctl.c') diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 5c08d31f781f..3f22754adb4f 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -1030,7 +1030,10 @@ _ctl_getiocinfo(struct MPT3SAS_ADAPTER *ioc, void __user *arg) strcat(karg.driver_version, "-"); switch (ioc->hba_mpi_version_belonged) { case MPI2_VERSION: - karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2; + if (ioc->is_warpdrive) + karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2_SSS6200; + else + karg.adapter_type = MPT2_IOCTL_INTERFACE_SAS2; strcat(karg.driver_version, MPT2SAS_DRIVER_VERSION); break; case MPI25_VERSION: -- cgit v1.2.1 From 422630955ea34841a2a074cb6734ec5d70758b0d Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Wed, 11 Nov 2015 17:30:29 +0530 Subject: mpt3sas: sysfs attribute to report Backup Rail Monitor Status A new sysfs shost attribute called "BMR_status" is implemented to report Backup Rail Monitor status. This attribute is located in: /sys/class/scsi_host/host#/BMR_status When reading this adapter attribute, the driver will output the state of GPIO[24]. It returns "0" if BMR is healthy and "1" for failure. If it returns an empty string then it means that there was an error while obtaining the BMR status. Check dmesg for what error has occurred. This sysfs shost attribute is mainly for WarpDrive controllers. This commit is a port of 6c265660c262 ("mpt2sas: Provide sysfs attribute to report Backup Rail Monitor Status"). Signed-off-by: Sreekanth Reddy Acked-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 74 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) (limited to 'drivers/scsi/mpt3sas/mpt3sas_ctl.c') diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 3f22754adb4f..1c62db8d80c7 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -2720,6 +2720,77 @@ _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 + * @buf - the buffer returned + * + * This is number of reply queues + * + * A sysfs 'read-only' shost attribute. + */ +static ssize_t +_ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr, + char *buf) +{ + struct Scsi_Host *shost = class_to_shost(cdev); + struct MPT3SAS_ADAPTER *ioc = shost_priv(shost); + Mpi2IOUnitPage3_t *io_unit_pg3 = NULL; + Mpi2ConfigReply_t mpi_reply; + u16 backup_rail_monitor_status = 0; + u16 ioc_status; + int sz; + ssize_t rc = 0; + + if (!ioc->is_warpdrive) { + pr_err(MPT3SAS_FMT "%s: BRM attribute is only for" + " warpdrive\n", ioc->name, __func__); + goto out; + } + + /* allocate upto GPIOVal 36 entries */ + sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36); + io_unit_pg3 = kzalloc(sz, GFP_KERNEL); + if (!io_unit_pg3) { + pr_err(MPT3SAS_FMT "%s: failed allocating memory " + "for iounit_pg3: (%d) bytes\n", ioc->name, __func__, sz); + goto out; + } + + if (mpt3sas_config_get_iounit_pg3(ioc, &mpi_reply, io_unit_pg3, sz) != + 0) { + pr_err(MPT3SAS_FMT + "%s: failed reading iounit_pg3\n", ioc->name, + __func__); + goto out; + } + + ioc_status = le16_to_cpu(mpi_reply.IOCStatus) & MPI2_IOCSTATUS_MASK; + if (ioc_status != MPI2_IOCSTATUS_SUCCESS) { + pr_err(MPT3SAS_FMT "%s: iounit_pg3 failed with " + "ioc_status(0x%04x)\n", ioc->name, __func__, ioc_status); + goto out; + } + + if (io_unit_pg3->GPIOCount < 25) { + pr_err(MPT3SAS_FMT "%s: iounit_pg3->GPIOCount less than " + "25 entries, detected (%d) entries\n", ioc->name, __func__, + io_unit_pg3->GPIOCount); + goto out; + } + + /* BRM status is in bit zero of GPIOVal[24] */ + backup_rail_monitor_status = le16_to_cpu(io_unit_pg3->GPIOVal[24]); + rc = snprintf(buf, PAGE_SIZE, "%d\n", (backup_rail_monitor_status & 1)); + + out: + kfree(io_unit_pg3); + return rc; +} +static DEVICE_ATTR(BRM_status, S_IRUGO, _ctl_BRM_status_show, NULL); +#endif + struct DIAG_BUFFER_START { __le32 Size; __le32 DiagVersion; @@ -3172,6 +3243,9 @@ 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, }; -- cgit v1.2.1 From 08c4d550c5797d842b1f1bb85d474a8b54f02382 Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Wed, 11 Nov 2015 17:30:33 +0530 Subject: mpt3sas: setpci reset kernel oops fix setpci reset on nytro warpdrive card along with sysfs access and cli ioctl access resulted in kernel oops 1. pci_access_mutex lock added to provide synchronization between IOCTL, sysfs, PCI resource handling path 2. gioc_lock spinlock to protect list operations over multiple controllers This patch is ported from commit 6229b414b3ad ("mpt2sas: setpci reset kernel oops fix"). Signed-off-by: Sreekanth Reddy Acked-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 42 ++++++++++++++++++++++++++++++-------- 1 file changed, 34 insertions(+), 8 deletions(-) (limited to 'drivers/scsi/mpt3sas/mpt3sas_ctl.c') diff --git a/drivers/scsi/mpt3sas/mpt3sas_ctl.c b/drivers/scsi/mpt3sas/mpt3sas_ctl.c index 1c62db8d80c7..f257c962c899 100644 --- a/drivers/scsi/mpt3sas/mpt3sas_ctl.c +++ b/drivers/scsi/mpt3sas/mpt3sas_ctl.c @@ -416,13 +416,16 @@ static int _ctl_verify_adapter(int ioc_number, struct MPT3SAS_ADAPTER **iocpp) { struct MPT3SAS_ADAPTER *ioc; - + /* global ioc lock to protect controller on list operations */ + spin_lock(&gioc_lock); list_for_each_entry(ioc, &mpt3sas_ioc_list, list) { if (ioc->id != ioc_number) continue; + spin_unlock(&gioc_lock); *iocpp = ioc; return ioc_number; } + spin_unlock(&gioc_lock); *iocpp = NULL; return -1; } @@ -511,10 +514,15 @@ ctl_poll(struct file *filep, poll_table *wait) poll_wait(filep, &ctl_poll_wait, wait); + /* global ioc lock to protect controller on list operations */ + spin_lock(&gioc_lock); list_for_each_entry(ioc, &mpt3sas_ioc_list, list) { - if (ioc->aen_event_read_flag) + if (ioc->aen_event_read_flag) { + spin_unlock(&gioc_lock); return POLLIN | POLLRDNORM; + } } + spin_unlock(&gioc_lock); return 0; } @@ -2211,16 +2219,25 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg, if (_ctl_verify_adapter(ioctl_header.ioc_number, &ioc) == -1 || !ioc) return -ENODEV; + /* pci_access_mutex lock acquired by ioctl path */ + mutex_lock(&ioc->pci_access_mutex); + if (ioc->shost_recovery || ioc->pci_error_recovery || - ioc->is_driver_loading) - return -EAGAIN; + ioc->is_driver_loading || ioc->remove_host) { + ret = -EAGAIN; + goto out_unlock_pciaccess; + } state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING; if (state == NON_BLOCKING) { - if (!mutex_trylock(&ioc->ctl_cmds.mutex)) - return -EAGAIN; - } else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) - return -ERESTARTSYS; + if (!mutex_trylock(&ioc->ctl_cmds.mutex)) { + ret = -EAGAIN; + goto out_unlock_pciaccess; + } + } else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) { + ret = -ERESTARTSYS; + goto out_unlock_pciaccess; + } switch (cmd) { @@ -2301,6 +2318,8 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg, } mutex_unlock(&ioc->ctl_cmds.mutex); +out_unlock_pciaccess: + mutex_unlock(&ioc->pci_access_mutex); return ret; } @@ -2748,6 +2767,12 @@ _ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr, " warpdrive\n", ioc->name, __func__); goto out; } + /* pci_access_mutex lock acquired by sysfs show path */ + mutex_lock(&ioc->pci_access_mutex); + if (ioc->pci_error_recovery || ioc->remove_host) { + mutex_unlock(&ioc->pci_access_mutex); + return 0; + } /* allocate upto GPIOVal 36 entries */ sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36); @@ -2786,6 +2811,7 @@ _ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr, out: kfree(io_unit_pg3); + mutex_unlock(&ioc->pci_access_mutex); return rc; } static DEVICE_ATTR(BRM_status, S_IRUGO, _ctl_BRM_status_show, NULL); -- cgit v1.2.1 From c84b06a48c4d8ac8270624453132f3fa1a4a0f9d Mon Sep 17 00:00:00 2001 From: Sreekanth Reddy Date: Wed, 11 Nov 2015 17:30:35 +0530 Subject: mpt3sas: Single driver module which supports both SAS 2.0 & SAS 3.0 HBAs Modified the mpt3sas driver to have a single driver module which supports both SAS 2.0 & SAS 3.0 HBA devices. * Added SAS 2.0 HBA device IDs to the mpt3sas_pci_table pci table. * Created two separate SCSI host templates for SAS2 and SAS3 HBAs so that, during the driver load time driver can use corresponding host template(based the pci device ID) while registering a scsi host adapter instance for that pci device. * Registered two IOCTL devices, mpt2ctl is for SAS2 HBAs & mpt3ctl for SAS3 HBAs. Also updated the code to make sure that mpt2ctl device processes only those ioctl cmds issued for the SAS2 HBAs and mpt3ctl device processes only those ioctl cmds issued for the SAS3 HBAs. * Added separate indexing for SAS2 and SAS3 HBAs. * Replaced compile time check 'MPT2SAS_SCSI' to run time check 'hba_mpi_version_belonged' whereever needed. * Aliased this merged driver to mpt2sas using MODULE_ALIAS. * Moved global varaible 'driver_name' to per adapter instance variable. * Created two raid function template and used corresponding raid function templates based on the run time check 'hba_mpi_version_belonged'. * Moved mpt2sas_warpdrive.c file from mpt2sas to mpt3sas folder and renamed it as mpt3sas_warpdrive.c. * Also renamed the functions in mpt3sas_warpdrive.c file to follow current driver function name convention. * Updated the Makefile to build mpt3sas_warpdrive.o file for these WarpDrive-specific functions. * Also in function mpt3sas_setup_direct_io(), used sector_div() API instead of division operator (which gives compilation errors on 32 bit machines). * Removed mpt2sas files, mpt2sas directory & mpt3sas_module.c file. * Added module parameter 'hbas_to_enumerate' which permits using this merged driver as a legacy mpt2sas driver or as a legacy mpt3sas driver. Here are the available options for this module parameter: 0 - Merged driver which enumerates both SAS 2.0 & SAS 3.0 HBAs 1 - Acts as legacy mpt2sas driver, which enumerates only SAS 2.0 HBAs 2 - Acts as legacy mpt3sas driver, which enumerates only SAS 3.0 HBAs * Removed mpt2sas entries from SCSI's Kconfig and Makefile files. Signed-off-by: Sreekanth Reddy Reviewed-by: Christoph Hellwig Reviewed-by: Hannes Reinecke Signed-off-by: Martin K. Petersen --- drivers/scsi/mpt3sas/mpt3sas_ctl.c | 151 ++++++++++++++++++++++++++++++------- 1 file changed, 123 insertions(+), 28 deletions(-) (limited to 'drivers/scsi/mpt3sas/mpt3sas_ctl.c') 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); } -- cgit v1.2.1