[kernel/f16] Fix verbose logging messages in the rtl8192cu driver (rhbz 728740)

Josh Boyer jwboyer at fedoraproject.org
Fri Jan 13 18:28:32 UTC 2012


commit 76da9b0851896424f1a3792cc8fbb04994ad8cd9
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)

 ...s-rtl8192cu-Fix-WARNING-on-suspend-resume.patch |  163 ++++++++++++++++++++
 kernel.spec                                        |   13 ++-
 rtl8192cu-Fix-WARNING-on-suspend-resume.patch      |  163 ++++++++++++++++++++
 3 files changed, 338 insertions(+), 1 deletions(-)
---
diff --git a/compat-wireless-rtl8192cu-Fix-WARNING-on-suspend-resume.patch b/compat-wireless-rtl8192cu-Fix-WARNING-on-suspend-resume.patch
new file mode 100644
index 0000000..bdc8a54
--- /dev/null
+++ b/compat-wireless-rtl8192cu-Fix-WARNING-on-suspend-resume.patch
@@ -0,0 +1,163 @@
+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.
+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>
+
+---
+ 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(-)
+
+--- linux-2.6/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c	2012-01-13 13:07:58.830625006 -0500
++++ linux-2.6/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c	2012-01-13 13:08:06.825439927 -0500
+@@ -227,7 +227,6 @@ int rtl92c_download_fw(struct ieee80211_
+ 	u32 fwsize;
+ 	enum version_8192c version = rtlhal->version;
+ 
+-	pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
+ 	if (!rtlhal->pfirmware)
+ 		return 1;
+
+--- linux-2.6/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c	
++++ linux-2.6/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c	
+@@ -186,6 +186,7 @@ int rtl92c_init_sw_vars(struct ieee80211
+ 	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;
+ }
+--- linux-2.6/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c	
++++ linux-2.6/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c	
+@@ -43,6 +43,8 @@ 
+ #include "hw.h"
+ #include <linux/vmalloc.h>
+ #include <linux/module.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>");
+@@ -51,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);
+@@ -62,12 +68,21 @@ static int rtl92cu_init_sw_vars(struct i
+ 	rtlpriv->dm.disable_framebursting = false;
+ 	rtlpriv->dm.thermalvalue = 0;
+ 	rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
+-	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);
+@@ -82,9 +97,14 @@ static int rtl92cu_init_sw_vars(struct i
+ 		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;
+ }
+@@ -93,12 +113,30 @@ static void rtl92cu_deinit_sw_vars(struc
+ {
+ 	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,
+@@ -374,11 +412,10 @@ static struct usb_driver rtl8192cu_drive
+ 	.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
diff --git a/kernel.spec b/kernel.spec
index 97deee0..d7e10b0 100644
--- a/kernel.spec
+++ b/kernel.spec
@@ -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 1
+%global baserelease 2
 %global fedora_build %{baserelease}
 
 # base_sublevel is the kernel version we're starting with and patching
@@ -870,10 +870,14 @@ Patch21074: KVM-x86-fix-missing-checks-in-syscall-emulation.patch
 Patch50000: compat-wireless-config-fixups.patch
 Patch50001: compat-wireless-change-CONFIG_IWLAGN-CONFIG_IWLWIFI.patch
 Patch50002: compat-wireless-pr_fmt-warning-avoidance.patch
+Patch50003: compat-wireless-rtl8192cu-Fix-WARNING-on-suspend-resume.patch
 
 #rhbz 771058
 Patch22100: msi-irq-sysfs-warning.patch
 
+#rhbz 728740
+Patch21076: rtl8192cu-Fix-WARNING-on-suspend-resume.patch
+
 %endif
 
 BuildRoot: %{_tmppath}/kernel-%{KVERREL}-root
@@ -1612,6 +1616,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
@@ -1677,6 +1684,7 @@ cd compat-wireless-%{cwversion}
 ApplyPatch compat-wireless-config-fixups.patch
 ApplyPatch compat-wireless-change-CONFIG_IWLAGN-CONFIG_IWLWIFI.patch
 ApplyPatch compat-wireless-pr_fmt-warning-avoidance.patch
+ApplyPatch compat-wireless-rtl8192cu-Fix-WARNING-on-suspend-resume.patch
 
 # Remove overlap between bcma/b43 and brcmsmac and reenable bcm4331
 ApplyPatch bcma-brcmsmac-compat.patch
@@ -2381,6 +2389,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> 3.1.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..bdc8a54
--- /dev/null
+++ b/rtl8192cu-Fix-WARNING-on-suspend-resume.patch
@@ -0,0 +1,163 @@
+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.
+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>
+
+---
+ 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(-)
+
+--- linux-2.6/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c	2012-01-13 13:07:58.830625006 -0500
++++ linux-2.6/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c	2012-01-13 13:08:06.825439927 -0500
+@@ -227,7 +227,6 @@ int rtl92c_download_fw(struct ieee80211_
+ 	u32 fwsize;
+ 	enum version_8192c version = rtlhal->version;
+ 
+-	pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
+ 	if (!rtlhal->pfirmware)
+ 		return 1;
+
+--- linux-2.6/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c	
++++ linux-2.6/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c	
+@@ -186,6 +186,7 @@ int rtl92c_init_sw_vars(struct ieee80211
+ 	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;
+ }
+--- linux-2.6/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c	
++++ linux-2.6/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c	
+@@ -43,6 +43,8 @@ 
+ #include "hw.h"
+ #include <linux/vmalloc.h>
+ #include <linux/module.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>");
+@@ -51,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);
+@@ -62,12 +68,21 @@ static int rtl92cu_init_sw_vars(struct i
+ 	rtlpriv->dm.disable_framebursting = false;
+ 	rtlpriv->dm.thermalvalue = 0;
+ 	rtlpriv->dbg.global_debuglevel = rtlpriv->cfg->mod_params->debug;
+-	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);
+@@ -82,9 +97,14 @@ static int rtl92cu_init_sw_vars(struct i
+ 		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;
+ }
+@@ -93,12 +113,30 @@ static void rtl92cu_deinit_sw_vars(struc
+ {
+ 	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,
+@@ -374,11 +412,10 @@ static struct usb_driver rtl8192cu_drive
+ 	.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


More information about the scm-commits mailing list