aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless
diff options
context:
space:
mode:
authorLarry Finger <Larry.Finger@lwfinger.net>2014-01-12 16:11:38 -0500
committerJohn W. Linville <linville@tuxdriver.com>2014-01-13 14:50:02 -0500
commit0673effd41dba323d6a280ef37b5ef29f3f5a653 (patch)
treea77566c99cb389a3b41584431041312cbfc4104e /drivers/net/wireless
parent09164043f63c947a49797750a09ca1cd7c31108e (diff)
b43: Fix unload oops if firmware is not available
The asyncronous firmware load uses a completion struct to hold firmware processing until the user-space routines are up and running. There is. however, a problem in that the waiter is nevered canceled during teardown. As a result, unloading the driver when firmware is not available causes an oops. To be able to access the completion structure at teardown, it had to be moved into the b43_wldev structure. This patch also fixes a typo in a comment. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Cc: Stable <stable@vger.kernel.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r--drivers/net/wireless/b43/b43.h4
-rw-r--r--drivers/net/wireless/b43/main.c10
2 files changed, 7 insertions, 7 deletions
diff --git a/drivers/net/wireless/b43/b43.h b/drivers/net/wireless/b43/b43.h
index 7f3d461f7e8d..54376fddfaf9 100644
--- a/drivers/net/wireless/b43/b43.h
+++ b/drivers/net/wireless/b43/b43.h
@@ -731,8 +731,6 @@ enum b43_firmware_file_type {
731struct b43_request_fw_context { 731struct b43_request_fw_context {
732 /* The device we are requesting the fw for. */ 732 /* The device we are requesting the fw for. */
733 struct b43_wldev *dev; 733 struct b43_wldev *dev;
734 /* a completion event structure needed if this call is asynchronous */
735 struct completion fw_load_complete;
736 /* a pointer to the firmware object */ 734 /* a pointer to the firmware object */
737 const struct firmware *blob; 735 const struct firmware *blob;
738 /* The type of firmware to request. */ 736 /* The type of firmware to request. */
@@ -809,6 +807,8 @@ enum {
809struct b43_wldev { 807struct b43_wldev {
810 struct b43_bus_dev *dev; 808 struct b43_bus_dev *dev;
811 struct b43_wl *wl; 809 struct b43_wl *wl;
810 /* a completion event structure needed if this call is asynchronous */
811 struct completion fw_load_complete;
812 812
813 /* The device initialization status. 813 /* The device initialization status.
814 * Use b43_status() to query. */ 814 * Use b43_status() to query. */
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c
index 86b2030055d2..c75237eb55a1 100644
--- a/drivers/net/wireless/b43/main.c
+++ b/drivers/net/wireless/b43/main.c
@@ -2070,6 +2070,7 @@ void b43_do_release_fw(struct b43_firmware_file *fw)
2070 2070
2071static void b43_release_firmware(struct b43_wldev *dev) 2071static void b43_release_firmware(struct b43_wldev *dev)
2072{ 2072{
2073 complete(&dev->fw_load_complete);
2073 b43_do_release_fw(&dev->fw.ucode); 2074 b43_do_release_fw(&dev->fw.ucode);
2074 b43_do_release_fw(&dev->fw.pcm); 2075 b43_do_release_fw(&dev->fw.pcm);
2075 b43_do_release_fw(&dev->fw.initvals); 2076 b43_do_release_fw(&dev->fw.initvals);
@@ -2095,7 +2096,7 @@ static void b43_fw_cb(const struct firmware *firmware, void *context)
2095 struct b43_request_fw_context *ctx = context; 2096 struct b43_request_fw_context *ctx = context;
2096 2097
2097 ctx->blob = firmware; 2098 ctx->blob = firmware;
2098 complete(&ctx->fw_load_complete); 2099 complete(&ctx->dev->fw_load_complete);
2099} 2100}
2100 2101
2101int b43_do_request_fw(struct b43_request_fw_context *ctx, 2102int b43_do_request_fw(struct b43_request_fw_context *ctx,
@@ -2142,7 +2143,7 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx,
2142 } 2143 }
2143 if (async) { 2144 if (async) {
2144 /* do this part asynchronously */ 2145 /* do this part asynchronously */
2145 init_completion(&ctx->fw_load_complete); 2146 init_completion(&ctx->dev->fw_load_complete);
2146 err = request_firmware_nowait(THIS_MODULE, 1, ctx->fwname, 2147 err = request_firmware_nowait(THIS_MODULE, 1, ctx->fwname,
2147 ctx->dev->dev->dev, GFP_KERNEL, 2148 ctx->dev->dev->dev, GFP_KERNEL,
2148 ctx, b43_fw_cb); 2149 ctx, b43_fw_cb);
@@ -2150,12 +2151,11 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx,
2150 pr_err("Unable to load firmware\n"); 2151 pr_err("Unable to load firmware\n");
2151 return err; 2152 return err;
2152 } 2153 }
2153 /* stall here until fw ready */ 2154 wait_for_completion(&ctx->dev->fw_load_complete);
2154 wait_for_completion(&ctx->fw_load_complete);
2155 if (ctx->blob) 2155 if (ctx->blob)
2156 goto fw_ready; 2156 goto fw_ready;
2157 /* On some ARM systems, the async request will fail, but the next sync 2157 /* On some ARM systems, the async request will fail, but the next sync
2158 * request works. For this reason, we dall through here 2158 * request works. For this reason, we fall through here
2159 */ 2159 */
2160 } 2160 }
2161 err = request_firmware(&ctx->blob, ctx->fwname, 2161 err = request_firmware(&ctx->blob, ctx->fwname,