Fix rtlwifi async firmware load race condition (rhbz 822120)

This commit is contained in:
Josh Boyer 2012-05-17 10:30:44 -04:00
parent 9011ea4427
commit 5a13292239
2 changed files with 96 additions and 1 deletions

View File

@ -54,7 +54,7 @@ Summary: The Linux kernel
# For non-released -rc kernels, this will be appended after the rcX and
# gitX tags, so a 3 here would become part of release "0.rcX.gitX.3"
#
%global baserelease 3
%global baserelease 4
%global fedora_build %{baserelease}
# base_sublevel is the kernel version we're starting with and patching
@ -801,6 +801,9 @@ Patch22018: atl1c_net_next_update-3.3.patch
#rhbz 795176
Patch22019: rtl818x-fix-sleeping-function-called-from-invalid-context.patch
#rhbz 822120
Patch22020: rtlwifi-fix-for-race-condition-when-firmware-is-cach.patch
# END OF PATCH DEFINITIONS
%endif
@ -1491,6 +1494,9 @@ ApplyPatch atl1c_net_next_update-3.3.patch
#rhbz 795176
ApplyPatch rtl818x-fix-sleeping-function-called-from-invalid-context.patch
#rhbz 822120
ApplyPatch rtlwifi-fix-for-race-condition-when-firmware-is-cach.patch
# END OF PATCH APPLICATIONS
%endif
@ -2229,6 +2235,9 @@ fi
# and build.
%changelog
* Thu May 17 2012 Josh Boyer <jwboyer@redhat.com>
- Fix rtlwifi async firmware load race condition (rhbz 822120)
* Wed May 16 2012 Justin M. Forbes <jforbes@redhat.com> 3.3.6-3
- fix rtl8187: ->brightness_set can not sleep (rhbz 795176)

View File

@ -0,0 +1,86 @@
From 574e02abaf816b582685805f0c1150ca9f1f18ee Mon Sep 17 00:00:00 2001
From: Larry Finger <Larry.Finger@lwfinger.net>
Date: Fri, 4 May 2012 08:27:43 -0500
Subject: [PATCH] rtlwifi: fix for race condition when firmware is cached
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>
Cc: Stable <stable@vger.kernel.org> [3.3]
Signed-off-by: John W. Linville <linville@tuxdriver.com>
---
drivers/net/wireless/rtlwifi/pci.c | 16 ++++++++--------
drivers/net/wireless/rtlwifi/usb.c | 10 +++++-----
2 files changed, 13 insertions(+), 13 deletions(-)
diff --git a/drivers/net/wireless/rtlwifi/pci.c b/drivers/net/wireless/rtlwifi/pci.c
index b588ca8..03c400e 100644
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -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,14 @@ 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"));
+ 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,
diff --git a/drivers/net/wireless/rtlwifi/usb.c b/drivers/net/wireless/rtlwifi/usb.c
index 049e207..20b53ae 100644
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -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: