diff options
author | Larry Finger <Larry.Finger@lwfinger.net> | 2012-03-08 23:25:57 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2012-03-13 14:54:15 -0400 |
commit | a3ea2c76b193be5794e0de6aff66e14c21b904f8 (patch) | |
tree | 61c28cbc5a3dc3a93bd857155c58c0baa76578d9 /drivers/net/wireless/b43legacy | |
parent | 843dc6644be05edfcb14f7f7ce5b2ab2bc15b429 (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/wireless/b43legacy')
-rw-r--r-- | drivers/net/wireless/b43legacy/b43legacy.h | 3 | ||||
-rw-r--r-- | drivers/net/wireless/b43legacy/main.c | 33 |
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 | ||
1560 | static int b43legacy_request_firmware(struct b43legacy_wldev *dev) | 1560 | static int b43legacy_one_core_attach(struct ssb_device *dev, |
1561 | struct b43legacy_wl *wl); | ||
1562 | static void b43legacy_one_core_detach(struct ssb_device *dev); | ||
1563 | |||
1564 | static 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; | 1639 | err_one_core_detach: |
1640 | b43legacy_one_core_detach(dev->dev); | ||
1641 | goto error; | ||
1629 | 1642 | ||
1630 | err_load: | 1643 | err_load: |
1631 | b43legacy_print_fw_helptext(dev->wl); | 1644 | b43legacy_print_fw_helptext(dev->wl); |
@@ -1639,7 +1652,7 @@ err_no_initvals: | |||
1639 | 1652 | ||
1640 | error: | 1653 | error: |
1641 | b43legacy_release_firmware(dev); | 1654 | b43legacy_release_firmware(dev); |
1642 | return err; | 1655 | return; |
1643 | } | 1656 | } |
1644 | 1657 | ||
1645 | static int b43legacy_upload_microcode(struct b43legacy_wldev *dev) | 1658 | static 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 | ||
3869 | out: | 3877 | out: |
3870 | return err; | 3878 | return err; |
3871 | 3879 | ||
3872 | err_one_core_detach: | ||
3873 | b43legacy_one_core_detach(dev); | ||
3874 | err_wireless_exit: | 3880 | err_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) |