public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Greg KH <gregkh@linuxfoundation.org>
To: linux-kernel@vger.kernel.org, stable@vger.kernel.org
Cc: torvalds@linux-foundation.org, akpm@linux-foundation.org,
	alan@lxorguk.ukuu.org.uk,
	Larry Finger <Larry.Finger@lwfinger.net>,
	"John W. Linville" <linville@tuxdriver.com>
Subject: [ 132/175] rtlwifi: Convert to asynchronous firmware load
Date: Fri, 30 Mar 2012 12:50:37 -0700	[thread overview]
Message-ID: <20120330194852.874530733@linuxfoundation.org> (raw)
In-Reply-To: <20120330195801.GA31806@kroah.com>

3.3-stable review patch.  If anyone has any objections, please let me know.

------------------

From: Larry Finger <Larry.Finger@lwfinger.net>

commit b0302aba812bcc39291cdab9ad7e37008f352a91 upstream.

This patch addresses a kernel bugzilla report and two recent mail threads.

The kernel bugzilla report is https://bugzilla.kernel.org/show_bug.cgi?id=42632,
which reports a udev timeout on boot.

The first mail thread, which was on LKML (http://lkml.indiana.edu/hypermail/
linux/kernel/1112.3/00965.html) was for a WARNING that occurs after a
suspend/resume cycle for rtl8192cu.

The scond mail thread (http://marc.info/?l=linux-wireless&m=132655490826766&w=2)
concerned changes in udev that break drivers that delay while firmware is loaded
on modprobe.

This patch converts all rtlwifi-based drivers to use the asynchronous firmware
loading mechanism. Drivers rtl8192ce, rtl8192cu and rtl8192de share a common
callback routine. Driver rtl8192se needs different handling of the firmware,
thus it has its own code.

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/base.c               |    1 
 drivers/net/wireless/rtlwifi/core.c               |   42 ++++++++++++++
 drivers/net/wireless/rtlwifi/core.h               |    4 -
 drivers/net/wireless/rtlwifi/pci.c                |   28 +++------
 drivers/net/wireless/rtlwifi/pci.h                |    1 
 drivers/net/wireless/rtlwifi/ps.c                 |    3 -
 drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c |   10 ---
 drivers/net/wireless/rtlwifi/rtl8192ce/hw.c       |    6 --
 drivers/net/wireless/rtlwifi/rtl8192ce/sw.c       |   24 ++------
 drivers/net/wireless/rtlwifi/rtl8192cu/hw.c       |   33 ++++-------
 drivers/net/wireless/rtlwifi/rtl8192cu/sw.c       |   29 +++------
 drivers/net/wireless/rtlwifi/rtl8192de/fw.c       |    8 --
 drivers/net/wireless/rtlwifi/rtl8192de/hw.c       |    3 -
 drivers/net/wireless/rtlwifi/rtl8192de/sw.c       |   38 +++++-------
 drivers/net/wireless/rtlwifi/rtl8192se/fw.c       |    2 
 drivers/net/wireless/rtlwifi/rtl8192se/hw.c       |   16 +++--
 drivers/net/wireless/rtlwifi/rtl8192se/led.c      |    5 +
 drivers/net/wireless/rtlwifi/rtl8192se/sw.c       |   65 ++++++++++++++++------
 drivers/net/wireless/rtlwifi/usb.c                |   36 +++++-------
 drivers/net/wireless/rtlwifi/wifi.h               |    4 +
 20 files changed, 192 insertions(+), 166 deletions(-)

--- a/drivers/net/wireless/rtlwifi/base.c
+++ b/drivers/net/wireless/rtlwifi/base.c
@@ -413,6 +413,7 @@ void rtl_init_rfkill(struct ieee80211_hw
 
 	wiphy_rfkill_start_polling(hw->wiphy);
 }
+EXPORT_SYMBOL(rtl_init_rfkill);
 
 void rtl_deinit_rfkill(struct ieee80211_hw *hw)
 {
--- a/drivers/net/wireless/rtlwifi/core.c
+++ b/drivers/net/wireless/rtlwifi/core.c
@@ -31,8 +31,50 @@
 #include "core.h"
 #include "cam.h"
 #include "base.h"
+#include "pci.h"
 #include "ps.h"
 
+#include <linux/export.h>
+
+void rtl_fw_cb(const struct firmware *firmware, void *context)
+{
+	struct ieee80211_hw *hw = context;
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	int err;
+
+	RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
+			 ("Firmware callback routine entered!\n"));
+	complete(&rtlpriv->firmware_loading_complete);
+	if (!firmware) {
+		pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name);
+		rtlpriv->max_fw_size = 0;
+		return;
+	}
+	if (firmware->size > rtlpriv->max_fw_size) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("Firmware is too big!\n"));
+		release_firmware(firmware);
+		return;
+	}
+	memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
+	rtlpriv->rtlhal.fwsize = firmware->size;
+	release_firmware(firmware);
+
+	err = ieee80211_register_hw(hw);
+	if (err) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("Can't register mac80211 hw\n"));
+		return;
+	} else {
+		rtlpriv->mac80211.mac80211_registered = 1;
+	}
+	set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
+
+	/*init rfkill */
+	rtl_init_rfkill(hw);
+}
+EXPORT_SYMBOL(rtl_fw_cb);
+
 /*mutex for start & stop is must here. */
 static int rtl_op_start(struct ieee80211_hw *hw)
 {
--- a/drivers/net/wireless/rtlwifi/core.h
+++ b/drivers/net/wireless/rtlwifi/core.h
@@ -30,8 +30,6 @@
 #ifndef __RTL_CORE_H__
 #define __RTL_CORE_H__
 
-#include <net/mac80211.h>
-
 #define RTL_SUPPORTED_FILTERS		\
 	(FIF_PROMISC_IN_BSS | \
 	FIF_ALLMULTI | FIF_CONTROL | \
@@ -42,4 +40,6 @@
 #define RTL_SUPPORTED_CTRL_FILTER	0xFF
 
 extern const struct ieee80211_ops rtl_ops;
+void rtl_fw_cb(const struct firmware *firmware, void *context);
+
 #endif
--- a/drivers/net/wireless/rtlwifi/pci.c
+++ b/drivers/net/wireless/rtlwifi/pci.c
@@ -28,8 +28,8 @@
  *****************************************************************************/
 
 #include <linux/export.h>
-#include "core.h"
 #include "wifi.h"
+#include "core.h"
 #include "pci.h"
 #include "base.h"
 #include "ps.h"
@@ -1579,6 +1579,9 @@ static void rtl_pci_stop(struct ieee8021
 
 	rtlpci->driver_is_goingto_unload = true;
 	rtlpriv->cfg->ops->hw_disable(hw);
+	/* some things are not needed if firmware not available */
+	if (!rtlpriv->max_fw_size)
+		return;
 	rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF);
 
 	spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flags);
@@ -1797,6 +1800,7 @@ int __devinit rtl_pci_probe(struct pci_d
 	rtlpriv = hw->priv;
 	pcipriv = (void *)rtlpriv->priv;
 	pcipriv->dev.pdev = pdev;
+	init_completion(&rtlpriv->firmware_loading_complete);
 
 	/* init cfg & intf_ops */
 	rtlpriv->rtlhal.interface = INTF_PCI;
@@ -1817,7 +1821,7 @@ int __devinit rtl_pci_probe(struct pci_d
 	err = pci_request_regions(pdev, KBUILD_MODNAME);
 	if (err) {
 		RT_ASSERT(false, ("Can't obtain PCI resources\n"));
-		return err;
+		goto fail2;
 	}
 
 	pmem_start = pci_resource_start(pdev, rtlpriv->cfg->bar_id);
@@ -1883,15 +1887,6 @@ int __devinit rtl_pci_probe(struct pci_d
 		goto fail3;
 	}
 
-	err = ieee80211_register_hw(hw);
-	if (err) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Can't register mac80211 hw.\n"));
-		goto fail3;
-	} else {
-		rtlpriv->mac80211.mac80211_registered = 1;
-	}
-
 	err = sysfs_create_group(&pdev->dev.kobj, &rtl_attribute_group);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
@@ -1899,9 +1894,6 @@ int __devinit rtl_pci_probe(struct pci_d
 		goto fail3;
 	}
 
-	/*init rfkill */
-	rtl_init_rfkill(hw);
-
 	rtlpci = rtl_pcidev(pcipriv);
 	err = request_irq(rtlpci->pdev->irq, &_rtl_pci_interrupt,
 			  IRQF_SHARED, KBUILD_MODNAME, hw);
@@ -1910,24 +1902,22 @@ int __devinit rtl_pci_probe(struct pci_d
 			 ("%s: failed to register IRQ handler\n",
 			  wiphy_name(hw->wiphy)));
 		goto fail3;
-	} else {
-		rtlpci->irq_alloc = 1;
 	}
+	rtlpci->irq_alloc = 1;
 
-	set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
 	return 0;
 
 fail3:
 	pci_set_drvdata(pdev, NULL);
 	rtl_deinit_core(hw);
 	_rtl_pci_io_handler_release(hw);
-	ieee80211_free_hw(hw);
 
 	if (rtlpriv->io.pci_mem_start != 0)
 		pci_iounmap(pdev, (void __iomem *)rtlpriv->io.pci_mem_start);
 
 fail2:
 	pci_release_regions(pdev);
+	complete(&rtlpriv->firmware_loading_complete);
 
 fail1:
 
@@ -1946,6 +1936,8 @@ void rtl_pci_disconnect(struct pci_dev *
 	struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
 	struct rtl_mac *rtlmac = rtl_mac(rtlpriv);
 
+	/* just in case driver is removed before firmware callback */
+	wait_for_completion(&rtlpriv->firmware_loading_complete);
 	clear_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
 
 	sysfs_remove_group(&pdev->dev.kobj, &rtl_attribute_group);
--- a/drivers/net/wireless/rtlwifi/pci.h
+++ b/drivers/net/wireless/rtlwifi/pci.h
@@ -239,7 +239,6 @@ int __devinit rtl_pci_probe(struct pci_d
 void rtl_pci_disconnect(struct pci_dev *pdev);
 int rtl_pci_suspend(struct device *dev);
 int rtl_pci_resume(struct device *dev);
-
 static inline u8 pci_read8_sync(struct rtl_priv *rtlpriv, u32 addr)
 {
 	return readb((u8 __iomem *) rtlpriv->io.pci_mem_start + addr);
--- a/drivers/net/wireless/rtlwifi/ps.c
+++ b/drivers/net/wireless/rtlwifi/ps.c
@@ -47,7 +47,8 @@ bool rtl_ps_enable_nic(struct ieee80211_
 			 ("Driver is already down!\n"));
 
 	/*<2> Enable Adapter */
-	rtlpriv->cfg->ops->hw_init(hw);
+	if (rtlpriv->cfg->ops->hw_init(hw))
+		return 1;
 	RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
 
 	/*<3> Enable Interrupt */
--- a/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192c/fw_common.c
@@ -262,10 +262,9 @@ int rtl92c_download_fw(struct ieee80211_
 	u32 fwsize;
 	enum version_8192c version = rtlhal->version;
 
-	if (!rtlhal->pfirmware)
+	if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
 		return 1;
 
-	pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
 	pfwheader = (struct rtl92c_firmware_header *)rtlhal->pfirmware;
 	pfwdata = (u8 *) rtlhal->pfirmware;
 	fwsize = rtlhal->fwsize;
@@ -518,15 +517,8 @@ static void _rtl92c_fill_h2c_command(str
 void rtl92c_fill_h2c_cmd(struct ieee80211_hw *hw,
 			 u8 element_id, u32 cmd_len, u8 *p_cmdbuffer)
 {
-	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 	u32 tmp_cmdbuf[2];
 
-	if (rtlhal->fw_ready == false) {
-		RT_ASSERT(false, ("return H2C cmd because of Fw "
-				  "download fail!!!\n"));
-		return;
-	}
-
 	memset(tmp_cmdbuf, 0, 8);
 	memcpy(tmp_cmdbuf, p_cmdbuffer, cmd_len);
 	_rtl92c_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/hw.c
@@ -921,10 +921,7 @@ int rtl92ce_hw_init(struct ieee80211_hw
 			 ("Failed to download FW. Init HW "
 			  "without FW now..\n"));
 		err = 1;
-		rtlhal->fw_ready = false;
 		return err;
-	} else {
-		rtlhal->fw_ready = true;
 	}
 
 	rtlhal->last_hmeboxnum = 0;
@@ -1199,7 +1196,6 @@ static void _rtl92ce_poweroff_adapter(st
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
-	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 	u8 u1b_tmp;
 	u32 u4b_tmp;
 
@@ -1210,7 +1206,7 @@ static void _rtl92ce_poweroff_adapter(st
 	rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0);
-	if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready)
+	if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7))
 		rtl92c_firmware_selfreset(hw);
 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51);
 	rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00);
--- a/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192ce/sw.c
@@ -92,9 +92,7 @@ int rtl92c_init_sw_vars(struct ieee80211
 	int err;
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-	const struct firmware *firmware;
 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
-	char *fw_name = NULL;
 
 	rtl8192ce_bt_reg_init(hw);
 
@@ -166,26 +164,20 @@ int rtl92c_init_sw_vars(struct ieee80211
 	/* request fw */
 	if (IS_VENDOR_UMC_A_CUT(rtlhal->version) &&
 	    !IS_92C_SERIAL(rtlhal->version))
-		fw_name = "rtlwifi/rtl8192cfwU.bin";
+		rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU.bin";
 	else if (IS_81xxC_VENDOR_UMC_B_CUT(rtlhal->version))
-		fw_name = "rtlwifi/rtl8192cfwU_B.bin";
-	else
-		fw_name = rtlpriv->cfg->fw_name;
-	err = request_firmware(&firmware, fw_name, rtlpriv->io.dev);
+		rtlpriv->cfg->fw_name = "rtlwifi/rtl8192cfwU_B.bin";
+
+	rtlpriv->max_fw_size = 0x4000;
+	pr_info("Using firmware %s\n", rtlpriv->cfg->fw_name);
+	err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
+				      rtlpriv->io.dev, GFP_KERNEL, hw,
+				      rtl_fw_cb);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 			 ("Failed to request firmware!\n"));
 		return 1;
 	}
-	if (firmware->size > 0x4000) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Firmware is too big!\n"));
-		release_firmware(firmware);
-		return 1;
-	}
-	memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
-	rtlpriv->rtlhal.fwsize = firmware->size;
-	release_firmware(firmware);
 
 	return 0;
 }
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/hw.c
@@ -1171,10 +1171,7 @@ int rtl92cu_hw_init(struct ieee80211_hw
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 			 ("Failed to download FW. Init HW without FW now..\n"));
 		err = 1;
-		rtlhal->fw_ready = false;
 		return err;
-	} else {
-		rtlhal->fw_ready = true;
 	}
 	rtlhal->last_hmeboxnum = 0; /* h2c */
 	_rtl92cu_phy_param_tab_init(hw);
@@ -1270,24 +1267,22 @@ static void  _ResetDigitalProcedure1(str
 		if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(1)) {
 			/* reset MCU ready status */
 			rtl_write_byte(rtlpriv, REG_MCUFWDL, 0);
-			if (rtlhal->fw_ready) {
-				/* 8051 reset by self */
-				rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20);
-				while ((retry_cnts++ < 100) &&
-				       (FEN_CPUEN & rtl_read_word(rtlpriv,
-				       REG_SYS_FUNC_EN))) {
-					udelay(50);
-				}
-				if (retry_cnts >= 100) {
-					RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			/* 8051 reset by self */
+			rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20);
+			while ((retry_cnts++ < 100) &&
+			       (FEN_CPUEN & rtl_read_word(rtlpriv,
+			       REG_SYS_FUNC_EN))) {
+				udelay(50);
+			}
+			if (retry_cnts >= 100) {
+				RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 						("#####=> 8051 reset failed!.."
 						".......................\n"););
-					/* if 8051 reset fail, reset MAC. */
-					rtl_write_byte(rtlpriv,
-						       REG_SYS_FUNC_EN + 1,
-						       0x50);
-					udelay(100);
-				}
+				/* if 8051 reset fail, reset MAC. */
+				rtl_write_byte(rtlpriv,
+					       REG_SYS_FUNC_EN + 1,
+					       0x50);
+				udelay(100);
 			}
 		}
 		/* Reset MAC and Enable 8051 */
--- a/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192cu/sw.c
@@ -54,7 +54,6 @@ MODULE_FIRMWARE("rtlwifi/rtl8192cufw.bin
 static int rtl92cu_init_sw_vars(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	const struct firmware *firmware;
 	int err;
 
 	rtlpriv->dm.dm_initialgain_enable = true;
@@ -62,29 +61,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);
+
+	/* for firmware buf */
+	rtlpriv->rtlhal.pfirmware = vzalloc(0x4000);
 	if (!rtlpriv->rtlhal.pfirmware) {
 		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);
-	if (err) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Failed to request firmware!\n"));
-		return 1;
-	}
-	if (firmware->size > 0x4000) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Firmware is too big!\n"));
-		release_firmware(firmware);
-		return 1;
-	}
-	memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
-	rtlpriv->rtlhal.fwsize = firmware->size;
-	release_firmware(firmware);
+
+	pr_info("Loading firmware %s\n", rtlpriv->cfg->fw_name);
+	rtlpriv->max_fw_size = 0x4000;
+	err = request_firmware_nowait(THIS_MODULE, 1,
+				      rtlpriv->cfg->fw_name, rtlpriv->io.dev,
+				      GFP_KERNEL, hw, rtl_fw_cb);
+
 
 	return 0;
 }
--- a/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/fw.c
@@ -257,7 +257,7 @@ int rtl92d_download_fw(struct ieee80211_
 	bool fw_downloaded = false, fwdl_in_process = false;
 	unsigned long flags;
 
-	if (!rtlhal->pfirmware)
+	if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
 		return 1;
 	fwsize = rtlhal->fwsize;
 	pfwheader = (u8 *) rtlhal->pfirmware;
@@ -539,14 +539,8 @@ static void _rtl92d_fill_h2c_command(str
 void rtl92d_fill_h2c_cmd(struct ieee80211_hw *hw,
 			 u8 element_id, u32 cmd_len, u8 *cmdbuffer)
 {
-	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 	u32 tmp_cmdbuf[2];
 
-	if (rtlhal->fw_ready == false) {
-		RT_ASSERT(false, ("return H2C cmd because of Fw "
-				  "download fail!!!\n"));
-		return;
-	}
 	memset(tmp_cmdbuf, 0, 8);
 	memcpy(tmp_cmdbuf, cmdbuffer, cmd_len);
 	_rtl92d_fill_h2c_command(hw, element_id, cmd_len, (u8 *)&tmp_cmdbuf);
--- a/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/hw.c
@@ -932,10 +932,7 @@ int rtl92de_hw_init(struct ieee80211_hw
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 			 ("Failed to download FW. Init HW "
 			 "without FW..\n"));
-		rtlhal->fw_ready = false;
 		return 1;
-	} else {
-		rtlhal->fw_ready = true;
 	}
 	rtlhal->last_hmeboxnum = 0;
 	rtlpriv->psc.fw_current_inpsmode = false;
--- a/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192de/sw.c
@@ -94,7 +94,6 @@ static int rtl92d_init_sw_vars(struct ie
 	u8 tid;
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-	const struct firmware *firmware;
 	static int header_print;
 
 	rtlpriv->dm.dm_initialgain_enable = true;
@@ -170,6 +169,15 @@ static int rtl92d_init_sw_vars(struct ie
 	else if (rtlpriv->psc.reg_fwctrl_lps == 3)
 		rtlpriv->psc.fwctrl_psmode = FW_PS_DTIM_MODE;
 
+	/* for early mode */
+	rtlpriv->rtlhal.earlymode_enable = true;
+	for (tid = 0; tid < 8; tid++)
+		skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]);
+
+	/* Only load firmware for first MAC */
+	if (header_print)
+		return 0;
+
 	/* for firmware buf */
 	rtlpriv->rtlhal.pfirmware = vzalloc(0x8000);
 	if (!rtlpriv->rtlhal.pfirmware) {
@@ -178,33 +186,21 @@ static int rtl92d_init_sw_vars(struct ie
 		return 1;
 	}
 
-	if (!header_print) {
-		pr_info("Driver for Realtek RTL8192DE WLAN interface\n");
-		pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
-		header_print++;
-	}
+	rtlpriv->max_fw_size = 0x8000;
+	pr_info("Driver for Realtek RTL8192DE WLAN interface\n");
+	pr_info("Loading firmware file %s\n", rtlpriv->cfg->fw_name);
+	header_print++;
+
 	/* request fw */
-	err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
-			       rtlpriv->io.dev);
+	err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
+				      rtlpriv->io.dev, GFP_KERNEL, hw,
+				      rtl_fw_cb);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 			 ("Failed to request firmware!\n"));
 		return 1;
 	}
-	if (firmware->size > 0x8000) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Firmware is too big!\n"));
-		release_firmware(firmware);
-		return 1;
-	}
-	memcpy(rtlpriv->rtlhal.pfirmware, firmware->data, firmware->size);
-	rtlpriv->rtlhal.fwsize = firmware->size;
-	release_firmware(firmware);
 
-	/* for early mode */
-	rtlpriv->rtlhal.earlymode_enable = true;
-	for (tid = 0; tid < 8; tid++)
-		skb_queue_head_init(&rtlpriv->mac80211.skb_waitq[tid]);
 	return 0;
 }
 
--- a/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/fw.c
@@ -364,7 +364,7 @@ int rtl92s_download_fw(struct ieee80211_
 	u8 fwstatus = FW_STATUS_INIT;
 	bool rtstatus = true;
 
-	if (!rtlhal->pfirmware)
+	if (rtlpriv->max_fw_size == 0 || !rtlhal->pfirmware)
 		return 1;
 
 	firmware = (struct rt_firmware *)rtlhal->pfirmware;
--- a/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/hw.c
@@ -952,11 +952,10 @@ int rtl92se_hw_init(struct ieee80211_hw
 	if (!rtstatus) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
 			 ("Failed to download FW. "
-			 "Init HW without FW now.., Please copy FW into"
+			 "Init HW without FW now.., "
+			 "Please copy FW into"
 			 "/lib/firmware/rtlwifi\n"));
-		rtlhal->fw_ready = false;
-	} else {
-		rtlhal->fw_ready = true;
+		return 1;
 	}
 
 	/* After FW download, we have to reset MAC register */
@@ -1219,9 +1218,14 @@ void rtl92se_enable_interrupt(struct iee
 
 void rtl92se_disable_interrupt(struct ieee80211_hw *hw)
 {
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
-	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
+	struct rtl_priv *rtlpriv;
+	struct rtl_pci *rtlpci;
 
+	rtlpriv = rtl_priv(hw);
+	/* if firmware not available, no interrupts */
+	if (!rtlpriv || !rtlpriv->max_fw_size)
+		return;
+	rtlpci = rtl_pcidev(rtl_pcipriv(hw));
 	rtl_write_dword(rtlpriv, INTA_MASK, 0);
 	rtl_write_dword(rtlpriv, INTA_MASK + 4, 0);
 
--- a/drivers/net/wireless/rtlwifi/rtl8192se/led.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/led.c
@@ -76,10 +76,13 @@ void rtl92se_sw_led_on(struct ieee80211_
 
 void rtl92se_sw_led_off(struct ieee80211_hw *hw, struct rtl_led *pled)
 {
-	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_priv *rtlpriv;
 	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
 	u8 ledcfg;
 
+	rtlpriv = rtl_priv(hw);
+	if (!rtlpriv || rtlpriv->max_fw_size)
+		return;
 	RT_TRACE(rtlpriv, COMP_LED, DBG_LOUD,
 		 ("LedAddr:%X ledpin=%d\n", LEDCFG, pled->ledpin));
 
--- a/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
+++ b/drivers/net/wireless/rtlwifi/rtl8192se/sw.c
@@ -35,6 +35,8 @@
 #include "../wifi.h"
 #include "../core.h"
 #include "../pci.h"
+#include "../base.h"
+#include "../pci.h"
 #include "reg.h"
 #include "def.h"
 #include "phy.h"
@@ -89,12 +91,53 @@ static void rtl92s_init_aspm_vars(struct
 	rtlpci->const_support_pciaspm = 2;
 }
 
+static void rtl92se_fw_cb(const struct firmware *firmware, void *context)
+{
+	struct ieee80211_hw *hw = context;
+	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
+	struct rtl_priv *rtlpriv = rtl_priv(hw);
+	struct rtl_pci *rtlpci = rtl_pcidev(pcipriv);
+	struct rt_firmware *pfirmware = NULL;
+	int err;
+
+	RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
+			 ("Firmware callback routine entered!\n"));
+	complete(&rtlpriv->firmware_loading_complete);
+	if (!firmware) {
+		pr_err("Firmware %s not available\n", rtlpriv->cfg->fw_name);
+		rtlpriv->max_fw_size = 0;
+		return;
+	}
+	if (firmware->size > rtlpriv->max_fw_size) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("Firmware is too big!\n"));
+		release_firmware(firmware);
+		return;
+	}
+	pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware;
+	memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
+	pfirmware->sz_fw_tmpbufferlen = firmware->size;
+	release_firmware(firmware);
+
+	err = ieee80211_register_hw(hw);
+	if (err) {
+		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
+			 ("Can't register mac80211 hw\n"));
+		return;
+	} else {
+		rtlpriv->mac80211.mac80211_registered = 1;
+	}
+	rtlpci->irq_alloc = 1;
+	set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
+
+	/*init rfkill */
+	rtl_init_rfkill(hw);
+}
+
 static int rtl92s_init_sw_vars(struct ieee80211_hw *hw)
 {
 	struct rtl_priv *rtlpriv = rtl_priv(hw);
 	struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw));
-	const struct firmware *firmware;
-	struct rt_firmware *pfirmware = NULL;
 	int err = 0;
 	u16 earlyrxthreshold = 7;
 
@@ -192,27 +235,19 @@ static int rtl92s_init_sw_vars(struct ie
 		return 1;
 	}
 
+	rtlpriv->max_fw_size = sizeof(struct rt_firmware);
+
 	pr_info("Driver for Realtek RTL8192SE/RTL8191SE\n"
 		"Loading firmware %s\n", rtlpriv->cfg->fw_name);
 	/* request fw */
-	err = request_firmware(&firmware, rtlpriv->cfg->fw_name,
-			rtlpriv->io.dev);
+	err = request_firmware_nowait(THIS_MODULE, 1, rtlpriv->cfg->fw_name,
+				      rtlpriv->io.dev, GFP_KERNEL, hw,
+				      rtl92se_fw_cb);
 	if (err) {
 		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
 			 ("Failed to request firmware!\n"));
 		return 1;
 	}
-	if (firmware->size > sizeof(struct rt_firmware)) {
-		RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG,
-			 ("Firmware is too big!\n"));
-		release_firmware(firmware);
-		return 1;
-	}
-
-	pfirmware = (struct rt_firmware *)rtlpriv->rtlhal.pfirmware;
-	memcpy(pfirmware->sz_fw_tmpbuffer, firmware->data, firmware->size);
-	pfirmware->sz_fw_tmpbufferlen = firmware->size;
-	release_firmware(firmware);
 
 	return err;
 }
--- a/drivers/net/wireless/rtlwifi/usb.c
+++ b/drivers/net/wireless/rtlwifi/usb.c
@@ -29,8 +29,8 @@
 
 #include <linux/usb.h>
 #include <linux/export.h>
-#include "core.h"
 #include "wifi.h"
+#include "core.h"
 #include "usb.h"
 #include "base.h"
 #include "ps.h"
@@ -667,15 +667,17 @@ static int rtl_usb_start(struct ieee8021
 	struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw));
 
 	err = rtlpriv->cfg->ops->hw_init(hw);
-	rtl_init_rx_config(hw);
+	if (!err) {
+		rtl_init_rx_config(hw);
 
-	/* Enable software */
-	SET_USB_START(rtlusb);
-	/* should after adapter start and interrupt enable. */
-	set_hal_start(rtlhal);
+		/* Enable software */
+		SET_USB_START(rtlusb);
+		/* should after adapter start and interrupt enable. */
+		set_hal_start(rtlhal);
 
-	/* Start bulk IN */
-	_rtl_usb_receive(hw);
+		/* Start bulk IN */
+		_rtl_usb_receive(hw);
+	}
 
 	return err;
 }
@@ -952,6 +954,7 @@ int __devinit rtl_usb_probe(struct usb_i
 		return -ENOMEM;
 	}
 	rtlpriv = hw->priv;
+	init_completion(&rtlpriv->firmware_loading_complete);
 	SET_IEEE80211_DEV(hw, &intf->dev);
 	udev = interface_to_usbdev(intf);
 	usb_get_dev(udev);
@@ -986,24 +989,12 @@ int __devinit rtl_usb_probe(struct usb_i
 		goto error_out;
 	}
 
-	/*init rfkill */
-	/* rtl_init_rfkill(hw); */
-
-	err = ieee80211_register_hw(hw);
-	if (err) {
-		RT_TRACE(rtlpriv, COMP_INIT, DBG_EMERG,
-			 ("Can't register mac80211 hw.\n"));
-		goto error_out;
-	} else {
-		rtlpriv->mac80211.mac80211_registered = 1;
-	}
-	set_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status);
 	return 0;
 error_out:
 	rtl_deinit_core(hw);
 	_rtl_usb_io_handler_release(hw);
-	ieee80211_free_hw(hw);
 	usb_put_dev(udev);
+	complete(&rtlpriv->firmware_loading_complete);
 	return -ENODEV;
 }
 EXPORT_SYMBOL(rtl_usb_probe);
@@ -1017,6 +1008,9 @@ void rtl_usb_disconnect(struct usb_inter
 
 	if (unlikely(!rtlpriv))
 		return;
+
+	/* just in case driver is removed before firmware callback */
+	wait_for_completion(&rtlpriv->firmware_loading_complete);
 	/*ieee80211_unregister_hw will call ops_stop */
 	if (rtlmac->mac80211_registered == 1) {
 		ieee80211_unregister_hw(hw);
--- a/drivers/net/wireless/rtlwifi/wifi.h
+++ b/drivers/net/wireless/rtlwifi/wifi.h
@@ -36,6 +36,7 @@
 #include <linux/vmalloc.h>
 #include <linux/usb.h>
 #include <net/mac80211.h>
+#include <linux/completion.h>
 #include "debug.h"
 
 #define RF_CHANGE_BY_INIT			0
@@ -1045,7 +1046,6 @@ struct rtl_hal {
 	u16 fw_subversion;
 	bool h2c_setinprogress;
 	u8 last_hmeboxnum;
-	bool fw_ready;
 	/*Reserve page start offset except beacon in TxQ. */
 	u8 fw_rsvdpage_startoffset;
 	u8 h2c_txcmd_seq;
@@ -1591,6 +1591,7 @@ struct rtl_debug {
 };
 
 struct rtl_priv {
+	struct completion firmware_loading_complete;
 	struct rtl_locks locks;
 	struct rtl_works works;
 	struct rtl_mac mac80211;
@@ -1612,6 +1613,7 @@ struct rtl_priv {
 	struct rtl_rate_priv *rate_priv;
 
 	struct rtl_debug dbg;
+	int max_fw_size;
 
 	/*
 	 *hal_cfg : for diff cards



  parent reply	other threads:[~2012-03-30 21:42 UTC|newest]

Thread overview: 194+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2012-03-30 19:58 [ 000/175] 3.3.1-stable review Greg KH
2012-03-30 19:48 ` [ 001/175] USB: option: Add MediaTek MT6276M modem&app interfaces Greg KH
2012-03-30 19:48 ` [ 002/175] USB: option driver: adding support for Telit CC864-SINGLE, CC864-DUAL and DE910-DUAL modems Greg KH
2012-03-30 19:48 ` [ 003/175] USB: option: make interface blacklist work again Greg KH
2012-03-30 19:48 ` [ 004/175] USB: option: add ZTE MF820D Greg KH
2012-03-30 19:48 ` [ 005/175] staging: android/lowmemorykiller: Dont unregister notifier from atomic context Greg KH
2012-03-30 19:48 ` [ 006/175] staging: zcache: avoid AB-BA deadlock condition Greg KH
2012-03-30 19:48 ` [ 007/175] staging/octeon: Fix PHY binding in octeon-ethernet driver Greg KH
2012-03-30 19:48 ` [ 008/175] USB: ftdi_sio: fix problem when the manufacture is a NULL string Greg KH
2012-03-30 19:48 ` [ 009/175] USB: ftdi_sio: add support for BeagleBone rev A5+ Greg KH
2012-03-30 19:48 ` [ 010/175] USB: Microchip VID mislabeled as Hornby VID in ftdi_sio Greg KH
2012-03-30 19:48 ` [ 011/175] USB: ftdi_sio: new PID: Distortec JTAG-lock-pick Greg KH
2012-03-30 19:48 ` [ 012/175] USB: ftdi_sio: add support for FT-X series devices Greg KH
2012-03-30 19:48 ` [ 013/175] USB: ftdi_sio: new PID: LUMEL PD12 Greg KH
2012-03-30 19:48 ` [ 014/175] powerpc/usb: fix bug of kernel hang when initializing usb Greg KH
2012-03-30 19:48 ` [ 015/175] staging: r8712u: Fix regression introduced by commit a5ee652 Greg KH
2012-03-30 19:48 ` [ 016/175] staging: r8712u: Fix regression in signal level after commit c6dc001 Greg KH
2012-03-30 19:48 ` [ 017/175] usb: dwc3: make dwc3_get_device_id() return the id Greg KH
2012-03-30 19:48 ` [ 018/175] usb: dwc3: gadget: dont wrap around the TRB poll on non-ISOC Greg KH
2012-03-30 19:48 ` [ 019/175] usb: dwc3: fix bogus test in dwc3_gadget_start_isoc Greg KH
2012-03-30 19:48 ` [ 020/175] usb: dwc3: use proper function for setting endpoint name Greg KH
2012-03-30 19:48 ` [ 021/175] staging: vme: fix section mismatches in linux-next 20120314 Greg KH
2012-03-30 19:48 ` [ 022/175] usb: musb: Reselect index reg in interrupt context Greg KH
2012-03-30 19:48 ` [ 023/175] usb: gadget: Clear usb_endpoint_descriptor inside the struct usb_ep on disable Greg KH
2012-03-30 19:48 ` [ 024/175] usb: renesas_usbhs: bugfix: add .release function to gpriv->gadget.dev Greg KH
2012-03-30 19:48 ` [ 025/175] usb: gadgetfs: return number of bytes on ep0 read request Greg KH
2012-03-30 19:48 ` [ 026/175] USB: gadget: Make g_hid device class conform to spec Greg KH
2012-03-30 19:48 ` [ 027/175] futex: Cover all PI opcodes with cmpxchg enabled check Greg KH
2012-03-30 19:48 ` [ 028/175] sysfs: Fix memory leak in sysfs_sd_setsecdata() Greg KH
2012-03-30 19:48 ` [ 029/175] tty: serial: OMAP: Fix oops due to NULL pdata in DT boot Greg KH
2012-03-30 19:48 ` [ 030/175] tty: moxa: fix bit test in moxa_start() Greg KH
2012-03-30 19:48 ` [ 031/175] TTY: Wrong unicode value copied in con_set_unimap() Greg KH
2012-03-30 19:48 ` [ 032/175] USB: serial: fix console error reporting Greg KH
2012-03-30 19:48 ` [ 033/175] cdc-wdm: Fix more races on the read path Greg KH
2012-03-30 19:48 ` [ 034/175] cdc-wdm: Dont clear WDM_READ unless entire read buffer is emptied Greg KH
2012-03-30 19:49 ` [ 035/175] usb: fsl_udc_core: Fix scheduling while atomic dump message Greg KH
2012-03-30 19:49 ` [ 036/175] usb: Fix build error due to dma_mask is not at pdev_archdata at ARM Greg KH
2012-03-30 19:49 ` [ 037/175] USB: ums_realtek: do not use stack memory for DMA in __do_config_autodelink Greg KH
2012-03-30 19:49 ` [ 038/175] USB: qcserial: dont grab QMI port on Gobi 1000 devices Greg KH
2012-03-30 19:49 ` [ 039/175] usb-serial: Add support for the Sealevel SeaLINK+8 2038-ROHS device Greg KH
2012-03-30 19:49 ` [ 040/175] usb: cp210x: Update to support CP2105 and multiple interface devices Greg KH
2012-03-30 19:49 ` [ 041/175] USB: serial: mos7840: Fixed MCS7820 device attach problem Greg KH
2012-03-30 19:49 ` [ 042/175] rt2x00: Add support for D-Link DWA-127 to rt2800usb Greg KH
2012-03-30 19:49 ` [ 043/175] rtlwifi: rtl8192c_common: rtl8192de: Check for allocation failures Greg KH
2012-03-30 19:49 ` [ 044/175] rtlwifi: Handle previous allocation failures when freeing device memory Greg KH
2012-03-30 19:49 ` [ 045/175] rtlwifi: rtl8192c: Prevent sleeping from invalid context in rtl8192cu Greg KH
2012-03-30 19:49 ` [ 046/175] rtlwifi: rtl8192ce: Fix loss of receive performance Greg KH
2012-03-30 19:49 ` [ 047/175] serial: PL011: clear pending interrupts Greg KH
2012-03-30 19:49 ` [ 048/175] iwlwifi: always monitor for stuck queues Greg KH
2012-03-30 19:49 ` [ 049/175] ath9k: fix going to full-sleep on PS idle Greg KH
2012-03-30 19:49 ` [ 050/175] math: Introduce div64_long Greg KH
2012-03-30 19:49 ` [ 051/175] ntp: Fix integer overflow when setting time Greg KH
2012-03-30 19:49 ` [ 052/175] uevent: send events in correct order according to seqnum (v3) Greg KH
2012-03-30 19:49 ` [ 053/175] genirq: Fix long-term regression in genirq irq_set_irq_type() handling Greg KH
2012-03-30 19:49 ` [ 054/175] genirq: Fix incorrect check for forced IRQ thread handler Greg KH
2012-03-30 19:49 ` [ 055/175] rtc: Disable the alarm in the hardware (v2) Greg KH
2012-03-30 19:49 ` [ 056/175] p54spi: Release GPIO lines and IRQ on error in p54spi_probe Greg KH
2012-03-30 19:49 ` [ 057/175] rtnetlink: Fix VF IFLA policy Greg KH
2012-03-30 19:49 ` [ 058/175] IB/iser: Post initial receive buffers before sending the final login request Greg KH
2012-03-30 19:49 ` [ 059/175] mlx4_core: Fix one more static exported function Greg KH
2012-03-30 19:49 ` [ 060/175] ima: fix Kconfig dependencies Greg KH
2012-03-30 19:49 ` [ 061/175] x86/ioapic: Add register level checks to detect bogus io-apic entries Greg KH
2012-03-30 19:49 ` [ 062/175] mm: thp: fix pmd_bad() triggering in code paths holding mmap_sem read mode Greg KH
2012-03-30 19:49 ` [ 063/175] TPM: Zero buffer whole after copying to userspace Greg KH
2012-03-30 19:49 ` [ 064/175] PM / Domains: Fix handling of wakeup devices during system resume Greg KH
2012-03-30 19:49 ` [ 065/175] bootmem/sparsemem: remove limit constraint in alloc_bootmem_section Greg KH
2012-03-30 19:49 ` [ 066/175] hugetlbfs: avoid taking i_mutex from hugetlbfs_read() Greg KH
2012-03-30 19:49 ` [ 067/175] ASoC: fsl: p1022ds: tell the WM8776 codec driver that its the master Greg KH
2012-03-30 19:49 ` [ 068/175] ASoC: pxa-ssp: atomically set stream active masks Greg KH
2012-03-30 19:49 ` [ 069/175] tcm_loop: Set residual field for SCSI commands Greg KH
2012-03-30 19:49 ` [ 070/175] SCSI: iscsi: fix setting of pid from netlink skb Greg KH
2012-03-30 19:49 ` [ 071/175] iscsi-target: Fix iscsit_alloc_buffs() failure cases Greg KH
2012-03-30 19:49 ` [ 072/175] iscsi-target: Fix dynamic -> explict NodeACL pointer reference Greg KH
2012-03-30 19:49 ` [ 073/175] ALSA: hda - fix printing of high HDMI sample rates Greg KH
2012-03-30 19:49 ` [ 074/175] usb gadget: fix a section mismatch when compiling g_ffs with CONFIG_USB_FUNCTIONFS_ETH Greg KH
2012-03-30 19:49 ` [ 075/175] gma500: Fix mmap frambuffer Greg KH
2012-03-30 19:49 ` [ 076/175] udlfb: remove sysfs framebuffer device with USB .disconnect() Greg KH
2012-03-30 19:49 ` [ 077/175] tcm_fc: Fix fc_exch memory leak in ft_send_resp_status Greg KH
2012-03-30 19:49 ` [ 078/175] ib_srpt: Fix srpt_handle_cmd send_ioctx->ioctx_kref leak on exception Greg KH
2012-03-30 19:49 ` [ 079/175] md/bitmap: ensure to load bitmap when creating via sysfs Greg KH
2012-03-30 19:49 ` [ 080/175] md: dont set md arrays to readonly on shutdown Greg KH
2012-03-30 19:49 ` [ 081/175] md/raid1,raid10: avoid deadlock during resync/recovery Greg KH
2012-03-30 19:49 ` [ 082/175] md: fix clearing of the changed flags for the bad blocks list Greg KH
2012-03-30 19:49 ` [ 083/175] drm/i915: Only clear the GPU domains upon a successful finish Greg KH
2012-03-30 19:49 ` [ 084/175] drm/radeon: Restrict offset for legacy hardware cursor Greg KH
2012-03-30 19:49 ` [ 085/175] drm/radeon/kms: fix analog load detection on DVI-I connectors Greg KH
2012-03-30 19:49 ` [ 086/175] drm/radeon/kms: add connector quirk for Fujitsu D3003-S2 board Greg KH
2012-03-30 19:49 ` [ 087/175] target: Fix up handling of short INQUIRY buffers Greg KH
2012-03-30 19:49 ` [ 088/175] target: Set peripheral device type consistently in INQUIRY response Greg KH
2012-03-30 19:49 ` [ 089/175] target: Dont set WBUS16 or SYNC bits " Greg KH
2012-03-30 19:49 ` [ 090/175] target: fix use after free in target_report_luns Greg KH
2012-03-30 19:49 ` [ 091/175] target: prevent NULL pointer dereference " Greg KH
2012-03-30 19:49 ` [ 092/175] target: Fix 16-bit target ports for SET TARGET PORT GROUPS emulation Greg KH
2012-03-30 19:49 ` [ 093/175] Bluetooth: Add AR30XX device ID on Asus laptops Greg KH
2012-03-30 19:49 ` [ 094/175] HID: add extra hotkeys in Asus AIO keyboards Greg KH
2012-03-30 19:50 ` [ 095/175] HID: add more " Greg KH
2012-03-30 19:50 ` [ 096/175] ahci: add AHCI_HFLAG_DELAY_ENGINE host flag Greg KH
2012-03-30 19:50 ` [ 097/175] ahci: move AHCI_HFLAGS() macro to ahci.h Greg KH
2012-03-30 19:50 ` [ 098/175] ahci_platform: add STRICT_AHCI platform type Greg KH
2012-03-30 19:50 ` [ 099/175] pata_legacy: correctly mask recovery field for HT6560B Greg KH
2012-03-30 19:50 ` [ 100/175] firewire: ohci: fix too-early completion of IR multichannel buffers Greg KH
2012-03-30 19:50 ` [ 101/175] mm: vmscan: forcibly scan highmem if there are too many buffer_heads pinning highmem Greg KH
2012-04-03  3:01   ` Ben Hutchings
2012-04-05 20:31     ` Mel Gorman
2012-04-06  1:10       ` Ben Hutchings
2012-04-06  6:13       ` Nikola Ciprich
2012-04-07  2:00         ` Hugh Dickins
2012-03-30 19:50 ` [ 102/175] NFS: Properly handle the case where the delegation is revoked Greg KH
2012-03-30 19:50 ` [ 103/175] NFSv4: Return the delegation if the server returns NFS4ERR_OPENMODE Greg KH
2012-03-30 19:50 ` [ 104/175] xfs: fix inode lookup race Greg KH
2012-03-30 19:50 ` [ 105/175] CIFS: Respect negotiated MaxMpxCount Greg KH
2012-04-01  0:18   ` Jeff Layton
2012-04-01  7:26     ` Steve French
2012-04-01 13:55       ` Jeff Layton
2012-03-30 19:50 ` [ 106/175] cifs: fix issue mounting of DFS ROOT when redirecting from one domain controller to the next Greg KH
2012-03-30 19:50 ` [ 107/175] CIFS: Fix a spurious error in cifs_push_posix_locks Greg KH
2012-03-30 19:50 ` [ 108/175] UBI: fix error handling in ubi_scan() Greg KH
2012-03-30 19:50 ` [ 109/175] UBI: fix eraseblock picking criteria Greg KH
2012-03-30 19:50 ` [ 110/175] SUNRPC: We must not use list_for_each_entry_safe() in rpc_wake_up() Greg KH
2012-03-30 19:50 ` [ 111/175] usbnet: increase URB reference count before usb_unlink_urb Greg KH
2012-03-30 19:50 ` [ 112/175] usbnet: dont clear urb->dev in tx_complete Greg KH
2012-03-30 19:50 ` [ 113/175] x86-32: Fix typo for mq_getsetattr in syscall table Greg KH
2012-03-30 19:50 ` [ 114/175] x86-32: Fix endless loop when processing signals for kernel tasks Greg KH
2012-03-30 19:50 ` [ 115/175] proc-ns: use d_set_d_op() API to set dentry ops in proc_ns_instantiate() Greg KH
2012-03-30 19:50 ` [ 116/175] iommu/amd: Fix section warning for prealloc_protection_domains Greg KH
2012-03-30 19:50 ` [ 117/175] iommu/amd: Make sure IOMMU interrupts are re-enabled on resume Greg KH
2012-04-03  3:28   ` Ben Hutchings
2012-04-11 15:45     ` Joerg Roedel
2012-04-11 16:00       ` Greg KH
2012-04-11 16:21         ` Joerg Roedel
2012-03-30 19:50 ` [ 118/175] sysctl: protect poll() in entries that may go away Greg KH
2012-03-30 19:50 ` [ 119/175] hwmon: (fam15h_power) Correct sign extension of running_avg_capture Greg KH
2012-03-30 19:50 ` [ 120/175] [media] lgdt330x: fix signedness error in i2c_read_demod_bytes() Greg KH
2012-03-30 19:50 ` [ 121/175] [media] as102: add __packed attribute to structs defined inside packed structs Greg KH
2012-03-30 19:50 ` [ 122/175] [media] tda10071: fix the delivery system Greg KH
2012-03-30 19:50 ` [ 123/175] [media] au8522: bug-fix: enable modulation AFTER tune (instead of before tuning) Greg KH
2012-03-30 19:50 ` [ 124/175] [media] pvrusb2: fix 7MHz & 8MHz DVB-T tuner support for HVR1900 rev D1F5 Greg KH
2012-03-30 19:50 ` [ 125/175] [media] mxl111sf: fix error on stream stop in mxl111sf_ep6_streaming_ctrl() Greg KH
2012-03-30 19:50 ` [ 126/175] PM / Domains: Fix hibernation restore of devices, v2 Greg KH
2012-03-30 19:50 ` [ 127/175] PM / Domains: Check domain status during hibernation restore of devices Greg KH
2012-03-30 19:50 ` [ 128/175] PM / Domains: Introduce "always on" device flag Greg KH
2012-03-30 19:50 ` [ 129/175] PM / shmobile: Make TMU driver use pm_genpd_dev_always_on() Greg KH
2012-03-30 19:50 ` [ 130/175] PM / shmobile: Make CMT " Greg KH
2012-03-30 19:50 ` [ 131/175] PM / shmobile: Make MTU2 " Greg KH
2012-03-30 19:50 ` Greg KH [this message]
2012-03-30 19:50 ` [ 133/175] staging: r8712u: Add missing initialization and remove configuration parameter CONFIG_R8712_AP Greg KH
2012-03-30 19:50 ` [ 134/175] NFSv4: Rate limit the state manager warning messages Greg KH
2012-03-30 19:50 ` [ 135/175] PM / Hibernate: Enable usermodehelpers in hibernate() error path Greg KH
2012-03-30 19:50 ` [ 136/175] jbd2: clear BH_Delay & BH_Unwritten in journal_unmap_buffer Greg KH
2012-03-30 19:50 ` [ 137/175] ext4: ignore EXT4_INODE_JOURNAL_DATA flag with delalloc Greg KH
2012-03-30 19:50 ` [ 138/175] ext4: fix race between unwritten extent conversion and truncate Greg KH
2012-03-30 19:50 ` [ 139/175] ext4: fix race between sync and completed io work Greg KH
2012-03-30 19:50 ` [ 140/175] ext4: check for zero length extent Greg KH
2012-03-30 19:50 ` [ 141/175] vfs: fix d_ancestor() case in d_materialize_unique Greg KH
2012-03-30 19:50 ` [ 142/175] ARM: tegra: select required CPU and L2 errata options Greg KH
2012-03-30 19:50 ` [ 143/175] gpio/omap: fix _set_gpio_irqenable implementation Greg KH
2012-03-30 19:50 ` [ 144/175] gpio/davinci: fix oops on unbanked gpio irq request Greg KH
2012-03-30 19:50 ` [ 145/175] gpio/davinci: fix enabling unbanked GPIO IRQs Greg KH
2012-03-30 19:50 ` [ 146/175] mfd: Test for jack detection when deciding if wm8994 should suspend Greg KH
2012-03-30 19:50 ` [ 147/175] drm/radeon/kms/atom: force bpc to 8 for now Greg KH
2012-03-30 19:50 ` [ 148/175] dm crypt: fix mempool deadlock Greg KH
2012-03-30 19:50 ` [ 149/175] dm crypt: add missing error handling Greg KH
2012-03-30 19:50 ` [ 150/175] dm exception store: fix init error path Greg KH
2012-03-30 19:50 ` [ 151/175] dm persistent data: fix btree rebalancing after remove Greg KH
2012-03-30 19:50 ` [ 152/175] dm thin: fix stacked bi_next usage Greg KH
2012-06-22 14:59   ` [PATCH] dm thin: reinstate missing mempool_free in cell_release_singleton Mike Snitzer
2012-06-22 15:16     ` Greg KH
2012-06-22 15:27       ` Mike Snitzer
2012-06-22 16:21       ` [PATCH] " Touko Korpela
2012-06-22 16:48         ` Greg KH
2012-06-27  1:51         ` Ben Hutchings
2012-03-30 19:50 ` [ 153/175] backlight: fix typo in tosa_lcd.c Greg KH
2012-03-30 19:50 ` [ 154/175] xfs: Fix oops on IO error during xlog_recover_process_iunlinks() Greg KH
2012-03-30 19:51 ` [ 155/175] slub: Do not hold slub_lock when calling sysfs_slab_add() Greg KH
2012-03-30 19:51 ` [ 156/175] NFSv4: Fix two infinite loops in the mount code Greg KH
2012-03-30 19:51 ` [ 157/175] NFSv4.1: Fix layoutcommit error handling Greg KH
2012-03-30 19:51 ` [ 158/175] module: Remove module size limit Greg KH
2012-03-30 19:51 ` [ 159/175] drm/i915: suspend fbdev device around suspend/hibernate Greg KH
2012-03-30 19:51 ` [ 160/175] net: bpf_jit: fix BPF_S_LDX_B_MSH compilation Greg KH
2012-03-30 19:51 ` [ 161/175] ipv6: fix incorrent ipv6 ipsec packet fragment Greg KH
2012-03-30 19:51 ` [ 162/175] Remove printk from rds_sendmsg Greg KH
2012-03-30 19:51 ` [ 163/175] Fix pppol2tp getsockname() Greg KH
2012-03-30 19:51 ` [ 164/175] net: fix napi_reuse_skb() skb reserve Greg KH
2012-03-30 19:51 ` [ 165/175] sky2: override for PCI legacy power management Greg KH
2012-03-30 19:51 ` [ 166/175] xfrm: Access the replay notify functions via the registered callbacks Greg KH
2012-03-30 19:51 ` [ 167/175] net: fix a potential rcu_read_lock() imbalance in rt6_fill_node() Greg KH
2012-03-30 19:51 ` [ 168/175] lockd: fix arg parsing for grace_period and timeout Greg KH
2012-03-30 19:51 ` [ 169/175] x86, tsc: Skip refined tsc calibration on systems with reliable TSC Greg KH
2012-03-30 19:51 ` [ 170/175] x86, tls: Off by one limit check Greg KH
2012-03-30 19:51 ` [ 171/175] compat: use sys_sendfile64() implementation for sendfile syscall Greg KH
2012-03-30 19:51 ` [ 172/175] rtc: Provide flag for rtc devices that dont support UIE Greg KH
2012-03-30 19:51 ` [ 173/175] nfsd: dont allow zero length strings in cache_parse() Greg KH
2012-03-30 19:51 ` [ 174/175] ARM: tegra: Fix device tree AUXDATA for USB/EHCI Greg KH
2012-03-30 19:51 ` [ 175/175] serial: sh-sci: fix a race of DMA submit_tx on transfer Greg KH

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20120330194852.874530733@linuxfoundation.org \
    --to=gregkh@linuxfoundation.org \
    --cc=Larry.Finger@lwfinger.net \
    --cc=akpm@linux-foundation.org \
    --cc=alan@lxorguk.ukuu.org.uk \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linville@tuxdriver.com \
    --cc=stable@vger.kernel.org \
    --cc=torvalds@linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox