diff options
author | Tim Gardner <tim.gardner@canonical.com> | 2012-02-02 15:48:06 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-02-06 14:55:52 -0500 |
commit | 3d86b93064c7f18378a2008bab9608ca7d11bdbb (patch) | |
tree | dad5a3e5e53a7b87397472599d00d0fc0dae6137 /drivers/net/wireless/rtlwifi | |
parent | 885bd8eca6ac172e299750d99bd5c9fddbed89b9 (diff) |
rtlwifi: Fix PCI probe error path orphaned memory
Memory allocated by ieee80211_alloc_hw() will get orphaned
if any subsequent initializations fail.
Also don't pci_set_drvdata(pdev, NULL) until just before disabling
the PCI device. Functions called by rtl_deinit_core(hw) may eventually need
the context (when its actually implemented).
Cc: Larry Finger <Larry.Finger@lwfinger.net>
Cc: Chaoming Li <chaoming_li@realsil.com.cn>
Cc: John W. Linville <linville@tuxdriver.com>
Cc: linux-wireless@vger.kernel.org
Cc: netdev@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Tim Gardner <tim.gardner@canonical.com>
Acked-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/rtlwifi')
-rw-r--r-- | drivers/net/wireless/rtlwifi/pci.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c index 9a0190944de5..c5f6a322feb2 100644 --- a/drivers/net/wireless/rtlwifi/pci.c +++ b/drivers/net/wireless/rtlwifi/pci.c | |||
@@ -1758,8 +1758,8 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, | |||
1758 | if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { | 1758 | if (pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32))) { |
1759 | RT_ASSERT(false, | 1759 | RT_ASSERT(false, |
1760 | "Unable to obtain 32bit DMA for consistent allocations\n"); | 1760 | "Unable to obtain 32bit DMA for consistent allocations\n"); |
1761 | pci_disable_device(pdev); | 1761 | err = -ENOMEM; |
1762 | return -ENOMEM; | 1762 | goto fail1; |
1763 | } | 1763 | } |
1764 | } | 1764 | } |
1765 | 1765 | ||
@@ -1801,7 +1801,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, | |||
1801 | err = pci_request_regions(pdev, KBUILD_MODNAME); | 1801 | err = pci_request_regions(pdev, KBUILD_MODNAME); |
1802 | if (err) { | 1802 | if (err) { |
1803 | RT_ASSERT(false, "Can't obtain PCI resources\n"); | 1803 | RT_ASSERT(false, "Can't obtain PCI resources\n"); |
1804 | goto fail2; | 1804 | goto fail1; |
1805 | } | 1805 | } |
1806 | 1806 | ||
1807 | pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id); | 1807 | pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id); |
@@ -1814,6 +1814,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, | |||
1814 | rtlpriv->cfg->bar_id, pmem_len); | 1814 | rtlpriv->cfg->bar_id, pmem_len); |
1815 | if (rtlpriv->io.pci_mem_start == 0) { | 1815 | if (rtlpriv->io.pci_mem_start == 0) { |
1816 | RT_ASSERT(false, "Can't map PCI mem\n"); | 1816 | RT_ASSERT(false, "Can't map PCI mem\n"); |
1817 | err = -ENOMEM; | ||
1817 | goto fail2; | 1818 | goto fail2; |
1818 | } | 1819 | } |
1819 | 1820 | ||
@@ -1830,8 +1831,10 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, | |||
1830 | pci_write_config_byte(pdev, 0x04, 0x07); | 1831 | pci_write_config_byte(pdev, 0x04, 0x07); |
1831 | 1832 | ||
1832 | /* find adapter */ | 1833 | /* find adapter */ |
1833 | if (!_rtl_pci_find_adapter(pdev, hw)) | 1834 | if (!_rtl_pci_find_adapter(pdev, hw)) { |
1835 | err = -ENODEV; | ||
1834 | goto fail3; | 1836 | goto fail3; |
1837 | } | ||
1835 | 1838 | ||
1836 | /* Init IO handler */ | 1839 | /* Init IO handler */ |
1837 | _rtl_pci_io_handler_init(&pdev->dev, hw); | 1840 | _rtl_pci_io_handler_init(&pdev->dev, hw); |
@@ -1841,6 +1844,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, | |||
1841 | 1844 | ||
1842 | if (rtlpriv->cfg->ops->init_sw_vars(hw)) { | 1845 | if (rtlpriv->cfg->ops->init_sw_vars(hw)) { |
1843 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n"); | 1846 | RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Can't init_sw_vars\n"); |
1847 | err = -ENODEV; | ||
1844 | goto fail3; | 1848 | goto fail3; |
1845 | } | 1849 | } |
1846 | 1850 | ||
@@ -1885,7 +1889,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev, | |||
1885 | return 0; | 1889 | return 0; |
1886 | 1890 | ||
1887 | fail3: | 1891 | fail3: |
1888 | pci_set_drvdata(pdev, NULL); | ||
1889 | rtl_deinit_core(hw); | 1892 | rtl_deinit_core(hw); |
1890 | _rtl_pci_io_handler_release(hw); | 1893 | _rtl_pci_io_handler_release(hw); |
1891 | 1894 | ||
@@ -1897,10 +1900,12 @@ fail2: | |||
1897 | complete(&rtlpriv->firmware_loading_complete); | 1900 | complete(&rtlpriv->firmware_loading_complete); |
1898 | 1901 | ||
1899 | fail1: | 1902 | fail1: |
1900 | 1903 | if (hw) | |
1904 | ieee80211_free_hw(hw); | ||
1905 | pci_set_drvdata(pdev, NULL); | ||
1901 | pci_disable_device(pdev); | 1906 | pci_disable_device(pdev); |
1902 | 1907 | ||
1903 | return -ENODEV; | 1908 | return err; |
1904 | 1909 | ||
1905 | } | 1910 | } |
1906 | EXPORT_SYMBOL(rtl_pci_probe); | 1911 | EXPORT_SYMBOL(rtl_pci_probe); |