[kernel/f15] Fix verbose logging messages in the rtl8192cu driver (rhbz 728740)
Josh Boyer
jwboyer at fedoraproject.org
Fri Jan 13 18:28:27 UTC 2012
commit 63af6b006b334fe0494489460874df2c6aada19a
Author: Josh Boyer <jwboyer at redhat.com>
Date: Fri Jan 13 11:53:59 2012 -0500
Fix verbose logging messages in the rtl8192cu driver (rhbz 728740)
kernel.spec | 11 ++-
rtl8192cu-Fix-WARNING-on-suspend-resume.patch | 177 +++++++++++++++++++++++++
2 files changed, 187 insertions(+), 1 deletions(-)
---
diff --git a/kernel.spec b/kernel.spec
index ce78f42..cfd4cc8 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -42,7 +42,7 @@ Summary: The Linux kernel
# When changing real_sublevel below, reset this by hand to 1
# (or to 0 and then use rpmdev-bumpspec).
#
-%global baserelease 1
+%global baserelease 2
%global fedora_build %{baserelease}
# real_sublevel is the 3.x kernel version we're starting with
@@ -741,6 +741,9 @@ Patch21073: mac80211-fix-rx-key-NULL-ptr-deref-in-promiscuous-mode.patch
Patch21074: KVM-x86-extend-struct-x86_emulate_ops-with-get_cpuid.patch
Patch21075: KVM-x86-fix-missing-checks-in-syscall-emulation.patch
+#rhbz 728740
+Patch21076: rtl8192cu-Fix-WARNING-on-suspend-resume.patch
+
%endif
BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
@@ -1375,6 +1378,9 @@ ApplyPatch mac80211-fix-rx-key-NULL-ptr-deref-in-promiscuous-mode.patch
ApplyPatch KVM-x86-extend-struct-x86_emulate_ops-with-get_cpuid.patch
ApplyPatch KVM-x86-fix-missing-checks-in-syscall-emulation.patch
+#rhbz 728740
+ApplyPatch rtl8192cu-Fix-WARNING-on-suspend-resume.patch
+
# END OF PATCH APPLICATIONS
%endif
@@ -2022,6 +2028,9 @@ fi
# and build.
%changelog
+* Fri Jan 13 2012 Josh Boyer <jwboyer at redhat.com>
+- Fix verbose logging messages in the rtl8192cu driver (rhbz 728740)
+
* Fri Jan 13 2012 Josh Boyer <jwboyer at redhat.com> 2.6.41.9-1
- Linux 3.1.9
- CVE-2012-0045 kvm: syscall instruction induced guest panic (rhbz 773392)
diff --git a/rtl8192cu-Fix-WARNING-on-suspend-resume.patch b/rtl8192cu-Fix-WARNING-on-suspend-resume.patch
new file mode 100644
index 0000000..e784b16
--- /dev/null
+++ b/rtl8192cu-Fix-WARNING-on-suspend-resume.patch
@@ -0,0 +1,177 @@
+From e234ca17f2d5ce23606fceef2df6c02f8555547e Mon Sep 17 00:00:00 2001
+From: Josh Boyer <jwboyer at redhat.com>
+Date: Wed, 11 Jan 2012 13:35:33 -0500
+Subject: [PATCH] rtl8192cu: Fix WARNING on suspend/resume
+
+A recent LKML thread (http://lkml.indiana.edu/hypermail/linux/kernel/1112.3/00965.html)
+discusses warnings that occur during a suspend/resume cycle. The driver
+attempts to read the firmware file before userspace is ready, leading to the
+following warning:
+
+WARNING: at drivers/base/firmware_class.c:537 _request_firmware+0x3f6/0x420()
+
+For rtl8192cu, the problem is fixed by storing the firmware in a global buffer
+rather than one allocated per device. The usage count is increased when
+suspending and decreased when resuming. This way, the firmware is retained
+through a suspend/resume cycle, and does not have to be reread.
+
+This patch should fix the bug reported in
+https://bugzilla.redhat.com/show_bug.cgi?id=771002.
+
+Note: This patch also touches rtl8192ce as the "firmware" loaded message
+is now printed in the wrong place.
+
+Reported-by: Mohammed Arafa <bugzilla at xxxxxxxxxxxx>
+Reported-by: Dave Jones <davej at xxxxxxxxxx>
+Signed-off-by: Larry Finger <Larry.Finger at xxxxxxxxxxxx>
+Cc: Linus Torvalds <torvalds at xxxxxxxxxxxxxxxxxxxx>
+Cc: Stable <stable at xxxxxxxxxxxxxxx>
+
+Backported to Fedora 3.1.x.
+---
+ drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c | 1 -
+ drivers/net/wireless/rtlwifi/rtl8192ce/sw.c | 1 +
+ drivers/net/wireless/rtlwifi/rtl8192cu/sw.c | 58 +++++++++++++++++----
+ 3 files changed, 49 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
+index 49a064b..e3c4ac7 100644
+--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
++++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
+@@ -226,7 +226,6 @@ int rtl92c_download_fw(struct ieee80211_hw *hw)
+ u32 fwsize;
+ enum version_8192c version = rtlhal->version;
+
+- pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
+ if (!rtlhal->pfirmware)
+ return 1;
+
+diff --git a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+index 373dc78..9c3a8f1 100644
+--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
++++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+@@ -171,6 +171,7 @@ int rtl92c_init_sw_vars(struct ieee80211_hw *hw)
+ memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
+ rtlpriv->rtlhal.fwsize = firmware->size;
+ release_firmware(firmware);
++ pr_info("rtl8192ce: Loaded firmware file %s\n", rtlpriv->cfg->fw_name);
+
+ return 0;
+ }
+diff --git a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+index ef63c0d..f4230dd 100644
+--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
++++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+@@ -42,6 +42,9 @@
+ #include "led.h"
+ #include "hw.h"
+ #include <linux/vmalloc.h>
++#include <linux/atomic.h>
++#include <linux/types.h>
++
+
+ MODULE_AUTHOR("Georgia <georgia at realtek.com>");
+ MODULE_AUTHOR("Ziv Huang <ziv_huang at realtek.com>");
+@@ -50,6 +53,10 @@ MODULE_LICENSE("GPL");
+ MODULE_DESCRIPTION("Realtek 8192C/8188C 802.11n USB wireless");
+ MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin");
+
++static char *rtl8192cu_firmware; /* pointer to firmware */
++static int firmware_size;
++static atomic_t usage_count;
++
+ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
+ {
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+@@ -60,12 +67,21 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
+ rtlpriv->dm.dm_flag = 0;
+ rtlpriv->dm.disable_framebursting = 0;
+ rtlpriv->dm.thermalvalue = 0;
+- rtlpriv->rtlhal.pfirmware = vmalloc(0x4000);
+- if (!rtlpriv->rtlhal.pfirmware) {
++
++ if (rtl8192cu_firmware) {
++ /* firmware already loaded - true for suspend/resume
++ * and multiple instances of the device */
++ rtlpriv->rtlhal.pfirmware = rtl8192cu_firmware;
++ rtlpriv->rtlhal.fwsize = firmware_size;
++ return 0;
++ }
++ rtl8192cu_firmware = vzalloc(0x4000);
++ if (!rtl8192cu_firmware) {
+ RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+ ("Can't alloc buffer for fw.\n"));
+ return 1;
+ }
++
+ /* request fw */
+ err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
+ rtlpriv->io.dev);
+@@ -80,9 +96,14 @@ static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
+ release_firmware(firmware);
+ return 1;
+ }
+- memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
++ pr_info("rtl8192cu: Loaded firmware from file %s\n",
++ rtlpriv->cfg->fw_name);
++ memcpy(rtl8192cu_firmware, firmware->data, firmware->size);
++ firmware_size = firmware->size;
+ rtlpriv->rtlhal.fwsize = firmware->size;
++ rtlpriv->rtlhal.pfirmware = rtl8192cu_firmware;
+ release_firmware(firmware);
++ atomic_inc(&usage_count);
+
+ return 0;
+ }
+@@ -91,12 +112,30 @@ static void rtl92cu_deinit_sw_vars(struct ieee80211_hw *hw)
+ {
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+- if (rtlpriv->rtlhal.pfirmware) {
+- vfree(rtlpriv->rtlhal.pfirmware);
++ atomic_dec(&usage_count);
++ if (!atomic_read(&usage_count) && rtlpriv->rtlhal.pfirmware) {
++ vfree(rtl8192cu_firmware);
++ rtl8192cu_firmware = NULL;
+ rtlpriv->rtlhal.pfirmware = NULL;
+ }
+ }
+
++#ifdef CONFIG_PM_SLEEP
++static int rtl8192cu_usb_suspend(struct usb_interface *pusb_intf,
++ pm_message_t message)
++{
++ /* Increase usage_count to Save loaded fw across suspend/resume */
++ atomic_inc(&usage_count);
++ return 0;
++}
++
++static int rtl8192cu_usb_resume(struct usb_interface *pusb_intf)
++{
++ atomic_dec(&usage_count); /* after resume, decrease usage count */
++ return 0;
++}
++#endif
++
+ static struct rtl_hal_ops rtl8192cu_hal_ops = {
+ .init_sw_vars = rtl92cu_init_sw_vars,
+ .deinit_sw_vars = rtl92cu_deinit_sw_vars,
+@@ -338,11 +377,10 @@ static struct usb_driver rtl8192cu_driver = {
+ .disconnect = rtl_usb_disconnect,
+ .id_table = rtl8192c_usb_ids,
+
+-#ifdef CONFIG_PM
+- /* .suspend = rtl_usb_suspend, */
+- /* .resume = rtl_usb_resume, */
+- /* .reset_resume = rtl8192c_resume, */
+-#endif /* CONFIG_PM */
++#ifdef CONFIG_PM_SLEEP
++ .suspend = rtl8192cu_usb_suspend,
++ .resume = rtl8192cu_usb_resume,
++#endif /* CONFIG_PM_SLEEP */
+ #ifdef CONFIG_AUTOSUSPEND
+ .supports_autosuspend = 1,
+ #endif
+--
+1.7.7.5
+
More information about the scm-commits
mailing list