diff options
| author | Olof Johansson <olof@lixom.net> | 2013-01-27 22:07:11 -0800 | 
|---|---|---|
| committer | Olof Johansson <olof@lixom.net> | 2013-01-27 22:07:20 -0800 | 
| commit | 6b914c998787d65022e80d6262dfd0edef58cadb (patch) | |
| tree | ec9d9605ae08e6e40664c4302a181979ab4fe1d3 /drivers/net/wireless/b43/main.c | |
| parent | 1f87a404d02a96519284e1928445ca5cfe9667db (diff) | |
| parent | 949db153b6466c6f7cad5a427ecea94985927311 (diff) | |
| download | olio-linux-3.10-6b914c998787d65022e80d6262dfd0edef58cadb.tar.xz olio-linux-3.10-6b914c998787d65022e80d6262dfd0edef58cadb.zip  | |
Merge tag 'v3.8-rc5' into next/cleanup
Linux 3.8-rc5
Signed-off-by: Olof Johansson <olof@lixom.net>
Diffstat (limited to 'drivers/net/wireless/b43/main.c')
| -rw-r--r-- | drivers/net/wireless/b43/main.c | 54 | 
1 files changed, 41 insertions, 13 deletions
diff --git a/drivers/net/wireless/b43/main.c b/drivers/net/wireless/b43/main.c index 16ab280359b..806e34c1928 100644 --- a/drivers/net/wireless/b43/main.c +++ b/drivers/net/wireless/b43/main.c @@ -2088,11 +2088,18 @@ static void b43_print_fw_helptext(struct b43_wl *wl, bool error)  		b43warn(wl, text);  } +static void b43_fw_cb(const struct firmware *firmware, void *context) +{ +	struct b43_request_fw_context *ctx = context; + +	ctx->blob = firmware; +	complete(&ctx->fw_load_complete); +} +  int b43_do_request_fw(struct b43_request_fw_context *ctx,  		      const char *name, -		      struct b43_firmware_file *fw) +		      struct b43_firmware_file *fw, bool async)  { -	const struct firmware *blob;  	struct b43_fw_header *hdr;  	u32 size;  	int err; @@ -2131,11 +2138,31 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx,  		B43_WARN_ON(1);  		return -ENOSYS;  	} -	err = request_firmware(&blob, ctx->fwname, ctx->dev->dev->dev); +	if (async) { +		/* do this part asynchronously */ +		init_completion(&ctx->fw_load_complete); +		err = request_firmware_nowait(THIS_MODULE, 1, ctx->fwname, +					      ctx->dev->dev->dev, GFP_KERNEL, +					      ctx, b43_fw_cb); +		if (err < 0) { +			pr_err("Unable to load firmware\n"); +			return err; +		} +		/* stall here until fw ready */ +		wait_for_completion(&ctx->fw_load_complete); +		if (ctx->blob) +			goto fw_ready; +	/* On some ARM systems, the async request will fail, but the next sync +	 * request works. For this reason, we dall through here +	 */ +	} +	err = request_firmware(&ctx->blob, ctx->fwname, +			       ctx->dev->dev->dev);  	if (err == -ENOENT) {  		snprintf(ctx->errors[ctx->req_type],  			 sizeof(ctx->errors[ctx->req_type]), -			 "Firmware file \"%s\" not found\n", ctx->fwname); +			 "Firmware file \"%s\" not found\n", +			 ctx->fwname);  		return err;  	} else if (err) {  		snprintf(ctx->errors[ctx->req_type], @@ -2144,14 +2171,15 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx,  			 ctx->fwname, err);  		return err;  	} -	if (blob->size < sizeof(struct b43_fw_header)) +fw_ready: +	if (ctx->blob->size < sizeof(struct b43_fw_header))  		goto err_format; -	hdr = (struct b43_fw_header *)(blob->data); +	hdr = (struct b43_fw_header *)(ctx->blob->data);  	switch (hdr->type) {  	case B43_FW_TYPE_UCODE:  	case B43_FW_TYPE_PCM:  		size = be32_to_cpu(hdr->size); -		if (size != blob->size - sizeof(struct b43_fw_header)) +		if (size != ctx->blob->size - sizeof(struct b43_fw_header))  			goto err_format;  		/* fallthrough */  	case B43_FW_TYPE_IV: @@ -2162,7 +2190,7 @@ int b43_do_request_fw(struct b43_request_fw_context *ctx,  		goto err_format;  	} -	fw->data = blob; +	fw->data = ctx->blob;  	fw->filename = name;  	fw->type = ctx->req_type; @@ -2172,7 +2200,7 @@ err_format:  	snprintf(ctx->errors[ctx->req_type],  		 sizeof(ctx->errors[ctx->req_type]),  		 "Firmware file \"%s\" format error.\n", ctx->fwname); -	release_firmware(blob); +	release_firmware(ctx->blob);  	return -EPROTO;  } @@ -2223,7 +2251,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)  			goto err_no_ucode;  		}  	} -	err = b43_do_request_fw(ctx, filename, &fw->ucode); +	err = b43_do_request_fw(ctx, filename, &fw->ucode, true);  	if (err)  		goto err_load; @@ -2235,7 +2263,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)  	else  		goto err_no_pcm;  	fw->pcm_request_failed = false; -	err = b43_do_request_fw(ctx, filename, &fw->pcm); +	err = b43_do_request_fw(ctx, filename, &fw->pcm, false);  	if (err == -ENOENT) {  		/* We did not find a PCM file? Not fatal, but  		 * core rev <= 10 must do without hwcrypto then. */ @@ -2296,7 +2324,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)  	default:  		goto err_no_initvals;  	} -	err = b43_do_request_fw(ctx, filename, &fw->initvals); +	err = b43_do_request_fw(ctx, filename, &fw->initvals, false);  	if (err)  		goto err_load; @@ -2355,7 +2383,7 @@ static int b43_try_request_fw(struct b43_request_fw_context *ctx)  	default:  		goto err_no_initvals;  	} -	err = b43_do_request_fw(ctx, filename, &fw->initvals_band); +	err = b43_do_request_fw(ctx, filename, &fw->initvals_band, false);  	if (err)  		goto err_load;  |