aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTim Gardner <tim.gardner@canonical.com>2012-02-02 15:48:06 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-02-06 14:55:52 -0500
commit3d86b93064c7f18378a2008bab9608ca7d11bdbb (patch)
treedad5a3e5e53a7b87397472599d00d0fc0dae6137
parent885bd8eca6ac172e299750d99bd5c9fddbed89b9 (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>
-rw-r--r--drivers/net/wireless/rtlwifi/pci.c19
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
1887fail3: 1891fail3:
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
1899fail1: 1902fail1:
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}
1906EXPORT_SYMBOL(rtl_pci_probe); 1911EXPORT_SYMBOL(rtl_pci_probe);