rtlwifi: Convert to asynchronous firmware load
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> Cc: Stable <stable@vger.kernel.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
This commit is contained in:

committed by
John W. Linville

parent
feced2012e
commit
b0302aba81
@@ -1565,6 +1565,9 @@ static void rtl_pci_stop(struct ieee80211_hw *hw)
|
||||
|
||||
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);
|
||||
@@ -1779,6 +1782,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
|
||||
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;
|
||||
@@ -1799,7 +1803,7 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
|
||||
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);
|
||||
@@ -1862,15 +1866,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
|
||||
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,
|
||||
@@ -1878,9 +1873,6 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
|
||||
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);
|
||||
@@ -1889,24 +1881,22 @@ int __devinit rtl_pci_probe(struct pci_dev *pdev,
|
||||
"%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:
|
||||
|
||||
@@ -1925,6 +1915,8 @@ void rtl_pci_disconnect(struct pci_dev *pdev)
|
||||
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);
|
||||
|
Reference in New Issue
Block a user