aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/scsi/mpt3sas/mpt3sas_base.c
diff options
context:
space:
mode:
authorJoe Lawrence <joe.lawrence@stratus.com>2013-08-08 16:45:39 -0400
committerJames Bottomley <JBottomley@Parallels.com>2013-08-26 10:53:45 -0400
commitcf9bd21a41bd999ac6a0b72b549839e218ad5f31 (patch)
treea92825d8db84b4d9bc6f0b02c3855a2f6bf1f6ea /drivers/scsi/mpt3sas/mpt3sas_base.c
parent3b3e6f8df3b03642d6705d1db84842c24415b21f (diff)
[SCSI] mpt3sas: fix cleanup on controller resource mapping failure
If mpt3sas_base_map_resources takes an early error path then its counterpart, mpt3sas_base_free_resources needs to be careful about cleaning up: 1 - _base_mask_interrupts and _base_make_ioc_ready require memory mapped I/O registers, make sure that this is true. 2 - _base_free_irq iterates over the adapter's reply_queue_list, so move this list head initialization out of _base_enable_msix to _scsih_probe so this will always be safe. 3 - check that the controller PCI device and its BARs have been enabled before disabling them. Signed-off-by: Joe Lawrence <joe.lawrence@stratus.com> Acked-by: Sreekanth Reddy <Sreekanth.Reddy@lsi.com> Signed-off-by: James Bottomley <JBottomley@Parallels.com>
Diffstat (limited to 'drivers/scsi/mpt3sas/mpt3sas_base.c')
-rw-r--r--drivers/scsi/mpt3sas/mpt3sas_base.c27
1 files changed, 17 insertions, 10 deletions
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 5dc280c75325..34ff896a140d 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -1709,8 +1709,6 @@ _base_enable_msix(struct MPT3SAS_ADAPTER *ioc)
1709 int i; 1709 int i;
1710 u8 try_msix = 0; 1710 u8 try_msix = 0;
1711 1711
1712 INIT_LIST_HEAD(&ioc->reply_queue_list);
1713
1714 if (msix_disable == -1 || msix_disable == 0) 1712 if (msix_disable == -1 || msix_disable == 0)
1715 try_msix = 1; 1713 try_msix = 1;
1716 1714
@@ -1790,6 +1788,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc)
1790 if (pci_enable_device_mem(pdev)) { 1788 if (pci_enable_device_mem(pdev)) {
1791 pr_warn(MPT3SAS_FMT "pci_enable_device_mem: failed\n", 1789 pr_warn(MPT3SAS_FMT "pci_enable_device_mem: failed\n",
1792 ioc->name); 1790 ioc->name);
1791 ioc->bars = 0;
1793 return -ENODEV; 1792 return -ENODEV;
1794 } 1793 }
1795 1794
@@ -1798,6 +1797,7 @@ mpt3sas_base_map_resources(struct MPT3SAS_ADAPTER *ioc)
1798 MPT3SAS_DRIVER_NAME)) { 1797 MPT3SAS_DRIVER_NAME)) {
1799 pr_warn(MPT3SAS_FMT "pci_request_selected_regions: failed\n", 1798 pr_warn(MPT3SAS_FMT "pci_request_selected_regions: failed\n",
1800 ioc->name); 1799 ioc->name);
1800 ioc->bars = 0;
1801 r = -ENODEV; 1801 r = -ENODEV;
1802 goto out_fail; 1802 goto out_fail;
1803 } 1803 }
@@ -4393,18 +4393,25 @@ mpt3sas_base_free_resources(struct MPT3SAS_ADAPTER *ioc)
4393 dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name, 4393 dexitprintk(ioc, pr_info(MPT3SAS_FMT "%s\n", ioc->name,
4394 __func__)); 4394 __func__));
4395 4395
4396 _base_mask_interrupts(ioc); 4396 if (ioc->chip_phys && ioc->chip) {
4397 ioc->shost_recovery = 1; 4397 _base_mask_interrupts(ioc);
4398 _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET); 4398 ioc->shost_recovery = 1;
4399 ioc->shost_recovery = 0; 4399 _base_make_ioc_ready(ioc, CAN_SLEEP, SOFT_RESET);
4400 ioc->shost_recovery = 0;
4401 }
4402
4400 _base_free_irq(ioc); 4403 _base_free_irq(ioc);
4401 _base_disable_msix(ioc); 4404 _base_disable_msix(ioc);
4402 if (ioc->chip_phys) 4405
4406 if (ioc->chip_phys && ioc->chip)
4403 iounmap(ioc->chip); 4407 iounmap(ioc->chip);
4404 ioc->chip_phys = 0; 4408 ioc->chip_phys = 0;
4405 pci_release_selected_regions(ioc->pdev, ioc->bars); 4409
4406 pci_disable_pcie_error_reporting(pdev); 4410 if (pci_is_enabled(pdev)) {
4407 pci_disable_device(pdev); 4411 pci_release_selected_regions(ioc->pdev, ioc->bars);
4412 pci_disable_pcie_error_reporting(pdev);
4413 pci_disable_device(pdev);
4414 }
4408 return; 4415 return;
4409} 4416}
4410 4417