aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2012-03-08 23:25:57 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-03-13 14:54:15 -0400
commita3ea2c76b193be5794e0de6aff66e14c21b904f8 (patch)
tree61c28cbc5a3dc3a93bd857155c58c0baa76578d9 /drivers/net
parent843dc6644be05edfcb14f7f7ce5b2ab2bc15b429 (diff)
b43legacy: Load firmware from work queue instead of from probe routine
Recent changes in udev are causing problems for drivers that load firmware from the probe routine. As b43legacy has such a structure, it must be changed. As this driver loads 3 or 4 firmware files, changing to the asynchronous routine request_firmware_nowait() would be complicated. In this implementation, the probe routine starts a work queue that calls the firmware loading routines. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/wireless/b43legacy/b43legacy.h3
-rw-r--r--drivers/net/wireless/b43legacy/main.c33
2 files changed, 23 insertions, 13 deletions
diff --git a/drivers/net/wireless/b43legacy/b43legacy.h b/drivers/net/wireless/b43legacy/b43legacy.h
index 98e3d44400c6..a29da674e69d 100644
--- a/drivers/net/wireless/b43legacy/b43legacy.h
+++ b/drivers/net/wireless/b43legacy/b43legacy.h
@@ -581,6 +581,9 @@ struct b43legacy_wl {
581 struct mutex mutex; /* locks wireless core state */ 581 struct mutex mutex; /* locks wireless core state */
582 spinlock_t leds_lock; /* lock for leds */ 582 spinlock_t leds_lock; /* lock for leds */
583 583
584 /* firmware loading work */
585 struct work_struct firmware_load;
586
584 /* We can only have one operating interface (802.11 core) 587 /* We can only have one operating interface (802.11 core)
585 * at a time. General information about this interface follows. 588 * at a time. General information about this interface follows.
586 */ 589 */
diff --git a/drivers/net/wireless/b43legacy/main.c b/drivers/net/wireless/b43legacy/main.c
index 75e70bce40f6..df7e16dfb36c 100644
--- a/drivers/net/wireless/b43legacy/main.c
+++ b/drivers/net/wireless/b43legacy/main.c
@@ -1557,8 +1557,15 @@ err_format:
1557 return -EPROTO; 1557 return -EPROTO;
1558} 1558}
1559 1559
1560static int b43legacy_request_firmware(struct b43legacy_wldev *dev) 1560static int b43legacy_one_core_attach(struct ssb_device *dev,
1561 struct b43legacy_wl *wl);
1562static void b43legacy_one_core_detach(struct ssb_device *dev);
1563
1564static void b43legacy_request_firmware(struct work_struct *work)
1561{ 1565{
1566 struct b43legacy_wl *wl = container_of(work,
1567 struct b43legacy_wl, firmware_load);
1568 struct b43legacy_wldev *dev = wl->current_dev;
1562 struct b43legacy_firmware *fw = &dev->fw; 1569 struct b43legacy_firmware *fw = &dev->fw;
1563 const u8 rev = dev->dev->id.revision; 1570 const u8 rev = dev->dev->id.revision;
1564 const char *filename; 1571 const char *filename;
@@ -1624,8 +1631,14 @@ static int b43legacy_request_firmware(struct b43legacy_wldev *dev)
1624 if (err) 1631 if (err)
1625 goto err_load; 1632 goto err_load;
1626 } 1633 }
1634 err = ieee80211_register_hw(wl->hw);
1635 if (err)
1636 goto err_one_core_detach;
1637 return;
1627 1638
1628 return 0; 1639err_one_core_detach:
1640 b43legacy_one_core_detach(dev->dev);
1641 goto error;
1629 1642
1630err_load: 1643err_load:
1631 b43legacy_print_fw_helptext(dev->wl); 1644 b43legacy_print_fw_helptext(dev->wl);
@@ -1639,7 +1652,7 @@ err_no_initvals:
1639 1652
1640error: 1653error:
1641 b43legacy_release_firmware(dev); 1654 b43legacy_release_firmware(dev);
1642 return err; 1655 return;
1643} 1656}
1644 1657
1645static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) 1658static int b43legacy_upload_microcode(struct b43legacy_wldev *dev)
@@ -2153,9 +2166,6 @@ static int b43legacy_chip_init(struct b43legacy_wldev *dev)
2153 macctl |= B43legacy_MACCTL_INFRA; 2166 macctl |= B43legacy_MACCTL_INFRA;
2154 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl); 2167 b43legacy_write32(dev, B43legacy_MMIO_MACCTL, macctl);
2155 2168
2156 err = b43legacy_request_firmware(dev);
2157 if (err)
2158 goto out;
2159 err = b43legacy_upload_microcode(dev); 2169 err = b43legacy_upload_microcode(dev);
2160 if (err) 2170 if (err)
2161 goto out; /* firmware is released later */ 2171 goto out; /* firmware is released later */
@@ -3860,17 +3870,13 @@ static int b43legacy_probe(struct ssb_device *dev,
3860 if (err) 3870 if (err)
3861 goto err_wireless_exit; 3871 goto err_wireless_exit;
3862 3872
3863 if (first) { 3873 /* setup and start work to load firmware */
3864 err = ieee80211_register_hw(wl->hw); 3874 INIT_WORK(&wl->firmware_load, b43legacy_request_firmware);
3865 if (err) 3875 schedule_work(&wl->firmware_load);
3866 goto err_one_core_detach;
3867 }
3868 3876
3869out: 3877out:
3870 return err; 3878 return err;
3871 3879
3872err_one_core_detach:
3873 b43legacy_one_core_detach(dev);
3874err_wireless_exit: 3880err_wireless_exit:
3875 if (first) 3881 if (first)
3876 b43legacy_wireless_exit(dev, wl); 3882 b43legacy_wireless_exit(dev, wl);
@@ -3885,6 +3891,7 @@ static void b43legacy_remove(struct ssb_device *dev)
3885 /* We must cancel any work here before unregistering from ieee80211, 3891 /* We must cancel any work here before unregistering from ieee80211,
3886 * as the ieee80211 unreg will destroy the workqueue. */ 3892 * as the ieee80211 unreg will destroy the workqueue. */
3887 cancel_work_sync(&wldev->restart_work); 3893 cancel_work_sync(&wldev->restart_work);
3894 cancel_work_sync(&wl->firmware_load);
3888 3895
3889 B43legacy_WARN_ON(!wl); 3896 B43legacy_WARN_ON(!wl);
3890 if (wl->current_dev == wldev) 3897 if (wl->current_dev == wldev)