]> git.hungrycats.org Git - linux/commitdiff
rtlwifi: fix for race condition when firmware is cached
authorLarry Finger <Larry.Finger@lwfinger.net>
Fri, 4 May 2012 13:27:43 +0000 (08:27 -0500)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 1 Jun 2012 07:15:54 +0000 (15:15 +0800)
commit 574e02abaf816b582685805f0c1150ca9f1f18ee upstream.

In commit b0302ab, the rtlwifi family of drivers was converted to use
asynchronous firmware loading. Unfortumately, the implementation was
racy, and the ieee80211 routines could be started before rtl_init_core()
was called to setup the data.

This patch fixes the bug noted in https://bugzilla.kernel.org/show_bug.cgi?id=43187.

Reported-by: Joshua Roys <Joshua.Roys@gtri.gatech.edu>
Tested-by: Neptune Ning <frostyplanet@gmail.com>
Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/net/wireless/rtlwifi/pci.c
drivers/net/wireless/rtlwifi/usb.c

index b588ca83571418ec114907b2c05c195be884f00b..3c5e8900294ec196213f1393d3229a7d30ef1f1b 100644 (file)
@@ -1865,14 +1865,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
        /*like read eeprom and so on */
        rtlpriv->cfg->ops->read_eeprom_info(hw);
 
-       if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Can't init_sw_vars.\n"));
-               goto fail3;
-       }
-
-       rtlpriv->cfg->ops->init_sw_leds(hw);
-
        /*aspm */
        rtl_pci_init_aspm(hw);
 
@@ -1892,6 +1884,15 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
                goto fail3;
        }
 
+       if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("Can't init_sw_vars.\n"));
+               err = -ENODEV;
+               goto fail3;
+       }
+
+       rtlpriv->cfg->ops->init_sw_leds(hw);
+
        err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group);
        if (err) {
                RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
index 049e2070ce2452706e495f2a9bd4d0aacd19657c..20b53aea7e406498b2ec7f4ab189f0a8c505ee76 100644 (file)
@@ -970,12 +970,6 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
        rtlpriv->cfg->ops->read_chip_version(hw);
        /*like read eeprom and so on */
        rtlpriv->cfg->ops->read_eeprom_info(hw);
-       if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
-               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-                        ("Can't init_sw_vars.\n"));
-               goto error_out;
-       }
-       rtlpriv->cfg->ops->init_sw_leds(hw);
        err = _rtl_usb_init(hw);
        err = _rtl_usb_init_sw(hw);
        /* Init mac80211 sw */
@@ -985,6 +979,12 @@ int __devinit rtl_usb_probe(struct usb_interface *intf,
                         ("Can't allocate sw for mac80211.\n"));
                goto error_out;
        }
+       if (rtlpriv->cfg->ops->init_sw_vars(hw)) {
+               RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+                        ("Can't init_sw_vars.\n"));
+               goto error_out;
+       }
+       rtlpriv->cfg->ops->init_sw_leds(hw);
 
        return 0;
 error_out: