aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt2sas/mpt2sas_ctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/scsi/mpt2sas/mpt2sas_ctl.c')
-rw-r--r--drivers/scsi/mpt2sas/mpt2sas_ctl.c38
1 files changed, 31 insertions, 7 deletions
diff --git a/drivers/scsi/mpt2sas/mpt2sas_ctl.c b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
index 4e509604b571..3694b63bd993 100644
--- a/drivers/scsi/mpt2sas/mpt2sas_ctl.c
+++ b/drivers/scsi/mpt2sas/mpt2sas_ctl.c
@@ -427,13 +427,16 @@ static int
427_ctl_verify_adapter(int ioc_number, struct MPT2SAS_ADAPTER **iocpp) 427_ctl_verify_adapter(int ioc_number, struct MPT2SAS_ADAPTER **iocpp)
428{ 428{
429 struct MPT2SAS_ADAPTER *ioc; 429 struct MPT2SAS_ADAPTER *ioc;
430 430 /* global ioc lock to protect controller on list operations */
431 spin_lock(&gioc_lock);
431 list_for_each_entry(ioc, &mpt2sas_ioc_list, list) { 432 list_for_each_entry(ioc, &mpt2sas_ioc_list, list) {
432 if (ioc->id != ioc_number) 433 if (ioc->id != ioc_number)
433 continue; 434 continue;
435 spin_unlock(&gioc_lock);
434 *iocpp = ioc; 436 *iocpp = ioc;
435 return ioc_number; 437 return ioc_number;
436 } 438 }
439 spin_unlock(&gioc_lock);
437 *iocpp = NULL; 440 *iocpp = NULL;
438 return -1; 441 return -1;
439} 442}
@@ -522,10 +525,15 @@ _ctl_poll(struct file *filep, poll_table *wait)
522 525
523 poll_wait(filep, &ctl_poll_wait, wait); 526 poll_wait(filep, &ctl_poll_wait, wait);
524 527
528 /* global ioc lock to protect controller on list operations */
529 spin_lock(&gioc_lock);
525 list_for_each_entry(ioc, &mpt2sas_ioc_list, list) { 530 list_for_each_entry(ioc, &mpt2sas_ioc_list, list) {
526 if (ioc->aen_event_read_flag) 531 if (ioc->aen_event_read_flag) {
532 spin_unlock(&gioc_lock);
527 return POLLIN | POLLRDNORM; 533 return POLLIN | POLLRDNORM;
534 }
528 } 535 }
536 spin_unlock(&gioc_lock);
529 return 0; 537 return 0;
530} 538}
531 539
@@ -2168,16 +2176,23 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
2168 2176
2169 if (_ctl_verify_adapter(ioctl_header.ioc_number, &ioc) == -1 || !ioc) 2177 if (_ctl_verify_adapter(ioctl_header.ioc_number, &ioc) == -1 || !ioc)
2170 return -ENODEV; 2178 return -ENODEV;
2179 /* pci_access_mutex lock acquired by ioctl path */
2180 mutex_lock(&ioc->pci_access_mutex);
2171 if (ioc->shost_recovery || ioc->pci_error_recovery || 2181 if (ioc->shost_recovery || ioc->pci_error_recovery ||
2172 ioc->is_driver_loading) 2182 ioc->is_driver_loading || ioc->remove_host) {
2173 return -EAGAIN; 2183 ret = -EAGAIN;
2184 goto out_unlock_pciaccess;
2185 }
2174 2186
2175 state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING; 2187 state = (file->f_flags & O_NONBLOCK) ? NON_BLOCKING : BLOCKING;
2176 if (state == NON_BLOCKING) { 2188 if (state == NON_BLOCKING) {
2177 if (!mutex_trylock(&ioc->ctl_cmds.mutex)) 2189 if (!mutex_trylock(&ioc->ctl_cmds.mutex)) {
2178 return -EAGAIN; 2190 ret = -EAGAIN;
2191 goto out_unlock_pciaccess;
2192 }
2179 } else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) { 2193 } else if (mutex_lock_interruptible(&ioc->ctl_cmds.mutex)) {
2180 return -ERESTARTSYS; 2194 ret = -ERESTARTSYS;
2195 goto out_unlock_pciaccess;
2181 } 2196 }
2182 2197
2183 switch (cmd) { 2198 switch (cmd) {
@@ -2258,6 +2273,8 @@ _ctl_ioctl_main(struct file *file, unsigned int cmd, void __user *arg,
2258 } 2273 }
2259 2274
2260 mutex_unlock(&ioc->ctl_cmds.mutex); 2275 mutex_unlock(&ioc->ctl_cmds.mutex);
2276out_unlock_pciaccess:
2277 mutex_unlock(&ioc->pci_access_mutex);
2261 return ret; 2278 return ret;
2262} 2279}
2263 2280
@@ -2711,6 +2728,12 @@ _ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr,
2711 "warpdrive\n", ioc->name, __func__); 2728 "warpdrive\n", ioc->name, __func__);
2712 goto out; 2729 goto out;
2713 } 2730 }
2731 /* pci_access_mutex lock acquired by sysfs show path */
2732 mutex_lock(&ioc->pci_access_mutex);
2733 if (ioc->pci_error_recovery || ioc->remove_host) {
2734 mutex_unlock(&ioc->pci_access_mutex);
2735 return 0;
2736 }
2714 2737
2715 /* allocate upto GPIOVal 36 entries */ 2738 /* allocate upto GPIOVal 36 entries */
2716 sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36); 2739 sz = offsetof(Mpi2IOUnitPage3_t, GPIOVal) + (sizeof(u16) * 36);
@@ -2749,6 +2772,7 @@ _ctl_BRM_status_show(struct device *cdev, struct device_attribute *attr,
2749 2772
2750 out: 2773 out:
2751 kfree(io_unit_pg3); 2774 kfree(io_unit_pg3);
2775 mutex_unlock(&ioc->pci_access_mutex);
2752 return rc; 2776 return rc;
2753} 2777}
2754static DEVICE_ATTR(BRM_status, S_IRUGO, _ctl_BRM_status_show, NULL); 2778static DEVICE_ATTR(BRM_status, S_IRUGO, _ctl_BRM_status_show, NULL);