diff options
author | Prakash, Sathya <sathya.prakash@lsi.com> | 2008-02-08 11:35:35 -0500 |
---|---|---|
committer | James Bottomley <James.Bottomley@HansenPartnership.com> | 2008-02-11 11:20:54 -0500 |
commit | e78d5b8f1e73ab82f3fd041d05824cfee7d83a2c (patch) | |
tree | bd51c151a123789fb24dde00052ab1fd09e1aadb /drivers/message | |
parent | 2f7ecc55b37ef9f0208360e64d8b9d2313df8ce6 (diff) |
[SCSI] mpt fusion: Request I/O resources only when required
This patch modifies the I/O resource allocation behavior of FUSION
driver. The current version of driver allocates the I/O resources
even if they are not required and this creates trouble in low resource
environments. This driver now uses
pci_enable_device_mem/pci_enable_device functions to differentiate the
resource allocations.
Signed-off-by: Sathya Prakash <sathya.prakash@lsi.com>
Signed-off-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/message')
-rw-r--r-- | drivers/message/fusion/mptbase.c | 50 | ||||
-rw-r--r-- | drivers/message/fusion/mptbase.h | 1 |
2 files changed, 44 insertions, 7 deletions
diff --git a/drivers/message/fusion/mptbase.c b/drivers/message/fusion/mptbase.c index d381c38ccbaf..bfda731696f7 100644 --- a/drivers/message/fusion/mptbase.c +++ b/drivers/message/fusion/mptbase.c | |||
@@ -1470,9 +1470,6 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1470 | if (mpt_debug_level) | 1470 | if (mpt_debug_level) |
1471 | printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level); | 1471 | printk(KERN_INFO MYNAM ": mpt_debug_level=%xh\n", mpt_debug_level); |
1472 | 1472 | ||
1473 | if (pci_enable_device(pdev)) | ||
1474 | return r; | ||
1475 | |||
1476 | ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC); | 1473 | ioc = kzalloc(sizeof(MPT_ADAPTER), GFP_ATOMIC); |
1477 | if (ioc == NULL) { | 1474 | if (ioc == NULL) { |
1478 | printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); | 1475 | printk(KERN_ERR MYNAM ": ERROR - Insufficient memory to add adapter!\n"); |
@@ -1482,6 +1479,20 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1482 | ioc->id = mpt_ids++; | 1479 | ioc->id = mpt_ids++; |
1483 | sprintf(ioc->name, "ioc%d", ioc->id); | 1480 | sprintf(ioc->name, "ioc%d", ioc->id); |
1484 | 1481 | ||
1482 | ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM); | ||
1483 | if (pci_enable_device_mem(pdev)) { | ||
1484 | kfree(ioc); | ||
1485 | printk(MYIOC_s_ERR_FMT "pci_enable_device_mem() " | ||
1486 | "failed\n", ioc->name); | ||
1487 | return r; | ||
1488 | } | ||
1489 | if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) { | ||
1490 | kfree(ioc); | ||
1491 | printk(MYIOC_s_ERR_FMT "pci_request_selected_regions() with " | ||
1492 | "MEM failed\n", ioc->name); | ||
1493 | return r; | ||
1494 | } | ||
1495 | |||
1485 | dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name)); | 1496 | dinitprintk(ioc, printk(MYIOC_s_INFO_FMT ": mpt_adapter_install\n", ioc->name)); |
1486 | 1497 | ||
1487 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { | 1498 | if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) { |
@@ -1794,6 +1805,7 @@ mpt_suspend(struct pci_dev *pdev, pm_message_t state) | |||
1794 | CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); | 1805 | CHIPREG_WRITE32(&ioc->chip->IntStatus, 0); |
1795 | 1806 | ||
1796 | pci_disable_device(pdev); | 1807 | pci_disable_device(pdev); |
1808 | pci_release_selected_regions(pdev, ioc->bars); | ||
1797 | pci_set_power_state(pdev, device_state); | 1809 | pci_set_power_state(pdev, device_state); |
1798 | 1810 | ||
1799 | return 0; | 1811 | return 0; |
@@ -1810,7 +1822,6 @@ mpt_resume(struct pci_dev *pdev) | |||
1810 | MPT_ADAPTER *ioc = pci_get_drvdata(pdev); | 1822 | MPT_ADAPTER *ioc = pci_get_drvdata(pdev); |
1811 | u32 device_state = pdev->current_state; | 1823 | u32 device_state = pdev->current_state; |
1812 | int recovery_state; | 1824 | int recovery_state; |
1813 | int err; | ||
1814 | 1825 | ||
1815 | printk(MYIOC_s_INFO_FMT | 1826 | printk(MYIOC_s_INFO_FMT |
1816 | "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n", | 1827 | "pci-resume: pdev=0x%p, slot=%s, Previous operating state [D%d]\n", |
@@ -1818,9 +1829,18 @@ mpt_resume(struct pci_dev *pdev) | |||
1818 | 1829 | ||
1819 | pci_set_power_state(pdev, 0); | 1830 | pci_set_power_state(pdev, 0); |
1820 | pci_restore_state(pdev); | 1831 | pci_restore_state(pdev); |
1821 | err = pci_enable_device(pdev); | 1832 | if (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT) { |
1822 | if (err) | 1833 | ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM | |
1823 | return err; | 1834 | IORESOURCE_IO); |
1835 | if (pci_enable_device(pdev)) | ||
1836 | return 0; | ||
1837 | } else { | ||
1838 | ioc->bars = pci_select_bars(pdev, IORESOURCE_MEM); | ||
1839 | if (pci_enable_device_mem(pdev)) | ||
1840 | return 0; | ||
1841 | } | ||
1842 | if (pci_request_selected_regions(pdev, ioc->bars, "mpt")) | ||
1843 | return 0; | ||
1824 | 1844 | ||
1825 | /* enable interrupts */ | 1845 | /* enable interrupts */ |
1826 | CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM); | 1846 | CHIPREG_WRITE32(&ioc->chip->IntMask, MPI_HIM_DIM); |
@@ -1881,6 +1901,7 @@ mpt_signal_reset(u8 index, MPT_ADAPTER *ioc, int reset_phase) | |||
1881 | * -2 if READY but IOCFacts Failed | 1901 | * -2 if READY but IOCFacts Failed |
1882 | * -3 if READY but PrimeIOCFifos Failed | 1902 | * -3 if READY but PrimeIOCFifos Failed |
1883 | * -4 if READY but IOCInit Failed | 1903 | * -4 if READY but IOCInit Failed |
1904 | * -5 if failed to enable_device and/or request_selected_regions | ||
1884 | */ | 1905 | */ |
1885 | static int | 1906 | static int |
1886 | mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) | 1907 | mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) |
@@ -1979,6 +2000,18 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag) | |||
1979 | } | 2000 | } |
1980 | } | 2001 | } |
1981 | 2002 | ||
2003 | if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP) && | ||
2004 | (ioc->facts.Flags & MPI_IOCFACTS_FLAGS_FW_DOWNLOAD_BOOT)) { | ||
2005 | pci_release_selected_regions(ioc->pcidev, ioc->bars); | ||
2006 | ioc->bars = pci_select_bars(ioc->pcidev, IORESOURCE_MEM | | ||
2007 | IORESOURCE_IO); | ||
2008 | if (pci_enable_device(ioc->pcidev)) | ||
2009 | return -5; | ||
2010 | if (pci_request_selected_regions(ioc->pcidev, ioc->bars, | ||
2011 | "mpt")) | ||
2012 | return -5; | ||
2013 | } | ||
2014 | |||
1982 | /* | 2015 | /* |
1983 | * Device is reset now. It must have de-asserted the interrupt line | 2016 | * Device is reset now. It must have de-asserted the interrupt line |
1984 | * (if it was asserted) and it should be safe to register for the | 2017 | * (if it was asserted) and it should be safe to register for the |
@@ -2383,6 +2416,9 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc) | |||
2383 | ioc->memmap = NULL; | 2416 | ioc->memmap = NULL; |
2384 | } | 2417 | } |
2385 | 2418 | ||
2419 | pci_disable_device(ioc->pcidev); | ||
2420 | pci_release_selected_regions(ioc->pcidev, ioc->bars); | ||
2421 | |||
2386 | #if defined(CONFIG_MTRR) && 0 | 2422 | #if defined(CONFIG_MTRR) && 0 |
2387 | if (ioc->mtrr_reg > 0) { | 2423 | if (ioc->mtrr_reg > 0) { |
2388 | mtrr_del(ioc->mtrr_reg, 0, 0); | 2424 | mtrr_del(ioc->mtrr_reg, 0, 0); |
diff --git a/drivers/message/fusion/mptbase.h b/drivers/message/fusion/mptbase.h index b49b706c0020..d83ea96fe135 100644 --- a/drivers/message/fusion/mptbase.h +++ b/drivers/message/fusion/mptbase.h | |||
@@ -629,6 +629,7 @@ typedef struct _MPT_ADAPTER | |||
629 | dma_addr_t HostPageBuffer_dma; | 629 | dma_addr_t HostPageBuffer_dma; |
630 | int mtrr_reg; | 630 | int mtrr_reg; |
631 | struct pci_dev *pcidev; /* struct pci_dev pointer */ | 631 | struct pci_dev *pcidev; /* struct pci_dev pointer */ |
632 | int bars; /* bitmask of BAR's that must be configured */ | ||
632 | u8 __iomem *memmap; /* mmap address */ | 633 | u8 __iomem *memmap; /* mmap address */ |
633 | struct Scsi_Host *sh; /* Scsi Host pointer */ | 634 | struct Scsi_Host *sh; /* Scsi Host pointer */ |
634 | SpiCfgData spi_data; /* Scsi config. data */ | 635 | SpiCfgData spi_data; /* Scsi config. data */ |