aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2012-03-08 23:27:46 -0500
committerJohn W. Linville <linville@tuxdriver.com>2012-03-13 14:54:16 -0400
commit6b6fa5868eec26bdc6a83543cebb8cf832a2645a (patch)
tree71f845d127ec1ff121b8a336ead86c6a6ac1c1bb
parenta3ea2c76b193be5794e0de6aff66e14c21b904f8 (diff)
b43: Load firmware from a work queue and not from the probe routine
Recent changes in udev are causing problems for drivers that load firmware from the probe routine. As b43 has such a structure, it must be changed. As this driver loads more than 1 firmware file, changing to the asynchronous routine request_firmware_nowait() would be complicated. In this implementation, the probe routine starts a 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>
-rw-r--r--drivers/net/wireless/b43/b43.h3
-rw-r--r--drivers/net/wireless/b43/main.c59
2 files changed, 35 insertions, 27 deletions
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 835462dc1206..67c13af6f206 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -932,6 +932,9 @@ struct b43_wl {
932 /* Flag that implement the queues stopping. */ 932 /* Flag that implement the queues stopping. */
933 bool tx_queue_stopped[B43_QOS_QUEUE_NUM]; 933 bool tx_queue_stopped[B43_QOS_QUEUE_NUM];
934 934
935 /* firmware loading work */
936 struct work_struct firmware_load;
937
935 /* The device LEDs. */ 938 /* The device LEDs. */
936 struct b43_leds leds; 939 struct b43_leds leds;
937 940
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 1d633f3b3274..c79e6638c88d 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2390,8 +2390,14 @@ error:
2390 return err; 2390 return err;
2391} 2391}
2392 2392
2393static int b43_request_firmware(struct b43_wldev *dev) 2393static int b43_one_core_attach(struct b43_bus_dev *dev, struct b43_wl *wl);
2394static void b43_one_core_detach(struct b43_bus_dev *dev);
2395
2396static void b43_request_firmware(struct work_struct *work)
2394{ 2397{
2398 struct b43_wl *wl = container_of(work,
2399 struct b43_wl, firmware_load);
2400 struct b43_wldev *dev = wl->current_dev;
2395 struct b43_request_fw_context *ctx; 2401 struct b43_request_fw_context *ctx;
2396 unsigned int i; 2402 unsigned int i;
2397 int err; 2403 int err;
@@ -2399,23 +2405,23 @@ static int b43_request_firmware(struct b43_wldev *dev)
2399 2405
2400 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL); 2406 ctx = kzalloc(sizeof(*ctx), GFP_KERNEL);
2401 if (!ctx) 2407 if (!ctx)
2402 return -ENOMEM; 2408 return;
2403 ctx->dev = dev; 2409 ctx->dev = dev;
2404 2410
2405 ctx->req_type = B43_FWTYPE_PROPRIETARY; 2411 ctx->req_type = B43_FWTYPE_PROPRIETARY;
2406 err = b43_try_request_fw(ctx); 2412 err = b43_try_request_fw(ctx);
2407 if (!err) 2413 if (!err)
2408 goto out; /* Successfully loaded it. */ 2414 goto start_ieee80211; /* Successfully loaded it. */
2409 err = ctx->fatal_failure; 2415 /* Was fw version known? */
2410 if (err) 2416 if (ctx->fatal_failure)
2411 goto out; 2417 goto out;
2412 2418
2419 /* proprietary fw not found, try open source */
2413 ctx->req_type = B43_FWTYPE_OPENSOURCE; 2420 ctx->req_type = B43_FWTYPE_OPENSOURCE;
2414 err = b43_try_request_fw(ctx); 2421 err = b43_try_request_fw(ctx);
2415 if (!err) 2422 if (!err)
2416 goto out; /* Successfully loaded it. */ 2423 goto start_ieee80211; /* Successfully loaded it. */
2417 err = ctx->fatal_failure; 2424 if(ctx->fatal_failure)
2418 if (err)
2419 goto out; 2425 goto out;
2420 2426
2421 /* Could not find a usable firmware. Print the errors. */ 2427 /* Could not find a usable firmware. Print the errors. */
@@ -2425,11 +2431,20 @@ static int b43_request_firmware(struct b43_wldev *dev)
2425 b43err(dev->wl, errmsg); 2431 b43err(dev->wl, errmsg);
2426 } 2432 }
2427 b43_print_fw_helptext(dev->wl, 1); 2433 b43_print_fw_helptext(dev->wl, 1);
2428 err = -ENOENT; 2434 goto out;
2435
2436start_ieee80211:
2437 err = ieee80211_register_hw(wl->hw);
2438 if (err)
2439 goto err_one_core_detach;
2440 b43_leds_register(wl->current_dev);
2441 goto out;
2442
2443err_one_core_detach:
2444 b43_one_core_detach(dev->dev);
2429 2445
2430out: 2446out:
2431 kfree(ctx); 2447 kfree(ctx);
2432 return err;
2433} 2448}
2434 2449
2435static int b43_upload_microcode(struct b43_wldev *dev) 2450static int b43_upload_microcode(struct b43_wldev *dev)
@@ -3023,9 +3038,6 @@ static int b43_chip_init(struct b43_wldev *dev)
3023 macctl |= B43_MACCTL_INFRA; 3038 macctl |= B43_MACCTL_INFRA;
3024 b43_write32(dev, B43_MMIO_MACCTL, macctl); 3039 b43_write32(dev, B43_MMIO_MACCTL, macctl);
3025 3040
3026 err = b43_request_firmware(dev);
3027 if (err)
3028 goto out;
3029 err = b43_upload_microcode(dev); 3041 err = b43_upload_microcode(dev);
3030 if (err) 3042 if (err)
3031 goto out; /* firmware is released later */ 3043 goto out; /* firmware is released later */
@@ -4155,6 +4167,7 @@ redo:
4155 mutex_unlock(&wl->mutex); 4167 mutex_unlock(&wl->mutex);
4156 cancel_delayed_work_sync(&dev->periodic_work); 4168 cancel_delayed_work_sync(&dev->periodic_work);
4157 cancel_work_sync(&wl->tx_work); 4169 cancel_work_sync(&wl->tx_work);
4170 cancel_work_sync(&wl->firmware_load);
4158 mutex_lock(&wl->mutex); 4171 mutex_lock(&wl->mutex);
4159 dev = wl->current_dev; 4172 dev = wl->current_dev;
4160 if (!dev || b43_status(dev) < B43_STAT_STARTED) { 4173 if (!dev || b43_status(dev) < B43_STAT_STARTED) {
@@ -5314,16 +5327,13 @@ static int b43_bcma_probe(struct bcma_device *core)
5314 if (err) 5327 if (err)
5315 goto bcma_err_wireless_exit; 5328 goto bcma_err_wireless_exit;
5316 5329
5317 err = ieee80211_register_hw(wl->hw); 5330 /* setup and start work to load firmware */
5318 if (err) 5331 INIT_WORK(&wl->firmware_load, b43_request_firmware);
5319 goto bcma_err_one_core_detach; 5332 schedule_work(&wl->firmware_load);
5320 b43_leds_register(wl->current_dev);
5321 5333
5322bcma_out: 5334bcma_out:
5323 return err; 5335 return err;
5324 5336
5325bcma_err_one_core_detach:
5326 b43_one_core_detach(dev);
5327bcma_err_wireless_exit: 5337bcma_err_wireless_exit:
5328 ieee80211_free_hw(wl->hw); 5338 ieee80211_free_hw(wl->hw);
5329 return err; 5339 return err;
@@ -5390,18 +5400,13 @@ int b43_ssb_probe(struct ssb_device *sdev, const struct ssb_device_id *id)
5390 if (err) 5400 if (err)
5391 goto err_wireless_exit; 5401 goto err_wireless_exit;
5392 5402
5393 if (first) { 5403 /* setup and start work to load firmware */
5394 err = ieee80211_register_hw(wl->hw); 5404 INIT_WORK(&wl->firmware_load, b43_request_firmware);
5395 if (err) 5405 schedule_work(&wl->firmware_load);
5396 goto err_one_core_detach;
5397 b43_leds_register(wl->current_dev);
5398 }
5399 5406
5400 out: 5407 out:
5401 return err; 5408 return err;
5402 5409
5403 err_one_core_detach:
5404 b43_one_core_detach(dev);
5405 err_wireless_exit: 5410 err_wireless_exit:
5406 if (first) 5411 if (first)
5407 b43_wireless_exit(dev, wl); 5412 b43_wireless_exit(dev, wl);