diff options
author | Michael Buesch <mbuesch@freenet.de> | 2006-02-01 16:09:52 -0500 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2006-03-27 11:18:27 -0500 |
commit | a4a600d3e17f450666a9086465122103e96140d7 (patch) | |
tree | 3b76a9ff5ba2c0dc217b21b330930246ea758614 /drivers/net/wireless | |
parent | 65f3f19120cf32233f537562e69893b88727b634 (diff) |
[PATCH] bcm43xx: Add more initvals sanity checks and error out, if one sanity check fails.
Signed-off-by: Michael Buesch <mbuesch@freenet.de>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless')
-rw-r--r-- | drivers/net/wireless/bcm43xx/bcm43xx_main.c | 62 |
1 files changed, 43 insertions, 19 deletions
diff --git a/drivers/net/wireless/bcm43xx/bcm43xx_main.c b/drivers/net/wireless/bcm43xx/bcm43xx_main.c index cfb0f0a485a7..521777f56a3d 100644 --- a/drivers/net/wireless/bcm43xx/bcm43xx_main.c +++ b/drivers/net/wireless/bcm43xx/bcm43xx_main.c | |||
@@ -2229,9 +2229,9 @@ static irqreturn_t bcm43xx_interrupt_handler(int irq, void *dev_id, struct pt_re | |||
2229 | return IRQ_HANDLED; | 2229 | return IRQ_HANDLED; |
2230 | } | 2230 | } |
2231 | 2231 | ||
2232 | static void bcm43xx_release_firmware(struct bcm43xx_private *bcm) | 2232 | static void bcm43xx_release_firmware(struct bcm43xx_private *bcm, int force) |
2233 | { | 2233 | { |
2234 | if (bcm->firmware_norelease) | 2234 | if (bcm->firmware_norelease && !force) |
2235 | return; /* Suspending or controller reset. */ | 2235 | return; /* Suspending or controller reset. */ |
2236 | release_firmware(bcm->ucode); | 2236 | release_firmware(bcm->ucode); |
2237 | bcm->ucode = NULL; | 2237 | bcm->ucode = NULL; |
@@ -2361,7 +2361,7 @@ static int bcm43xx_request_firmware(struct bcm43xx_private *bcm) | |||
2361 | out: | 2361 | out: |
2362 | return err; | 2362 | return err; |
2363 | error: | 2363 | error: |
2364 | bcm43xx_release_firmware(bcm); | 2364 | bcm43xx_release_firmware(bcm, 1); |
2365 | goto out; | 2365 | goto out; |
2366 | err_noinitval: | 2366 | err_noinitval: |
2367 | printk(KERN_ERR PFX "Error: No InitVals available!\n"); | 2367 | printk(KERN_ERR PFX "Error: No InitVals available!\n"); |
@@ -2409,9 +2409,9 @@ static void bcm43xx_upload_microcode(struct bcm43xx_private *bcm) | |||
2409 | #endif | 2409 | #endif |
2410 | } | 2410 | } |
2411 | 2411 | ||
2412 | static void bcm43xx_write_initvals(struct bcm43xx_private *bcm, | 2412 | static int bcm43xx_write_initvals(struct bcm43xx_private *bcm, |
2413 | const struct bcm43xx_initval *data, | 2413 | const struct bcm43xx_initval *data, |
2414 | const unsigned int len) | 2414 | const unsigned int len) |
2415 | { | 2415 | { |
2416 | u16 offset, size; | 2416 | u16 offset, size; |
2417 | u32 value; | 2417 | u32 value; |
@@ -2422,35 +2422,54 @@ static void bcm43xx_write_initvals(struct bcm43xx_private *bcm, | |||
2422 | size = be16_to_cpu(data[i].size); | 2422 | size = be16_to_cpu(data[i].size); |
2423 | value = be32_to_cpu(data[i].value); | 2423 | value = be32_to_cpu(data[i].value); |
2424 | 2424 | ||
2425 | if (size == 2) | 2425 | if (unlikely(offset >= 0x1000)) |
2426 | bcm43xx_write16(bcm, offset, value); | 2426 | goto err_format; |
2427 | else if (size == 4) | 2427 | if (size == 2) { |
2428 | if (unlikely(value & 0xFFFF0000)) | ||
2429 | goto err_format; | ||
2430 | bcm43xx_write16(bcm, offset, (u16)value); | ||
2431 | } else if (size == 4) { | ||
2428 | bcm43xx_write32(bcm, offset, value); | 2432 | bcm43xx_write32(bcm, offset, value); |
2429 | else | 2433 | } else |
2430 | printk(KERN_ERR PFX "InitVals fileformat error.\n"); | 2434 | goto err_format; |
2431 | } | 2435 | } |
2436 | |||
2437 | return 0; | ||
2438 | |||
2439 | err_format: | ||
2440 | printk(KERN_ERR PFX "InitVals (bcm43xx_initvalXX.fw) file-format error. " | ||
2441 | "Please fix your bcm43xx firmware files.\n"); | ||
2442 | return -EPROTO; | ||
2432 | } | 2443 | } |
2433 | 2444 | ||
2434 | static void bcm43xx_upload_initvals(struct bcm43xx_private *bcm) | 2445 | static int bcm43xx_upload_initvals(struct bcm43xx_private *bcm) |
2435 | { | 2446 | { |
2447 | int err; | ||
2448 | |||
2436 | #ifdef DEBUG_ENABLE_UCODE_MMIO_PRINT | 2449 | #ifdef DEBUG_ENABLE_UCODE_MMIO_PRINT |
2437 | bcm43xx_mmioprint_enable(bcm); | 2450 | bcm43xx_mmioprint_enable(bcm); |
2438 | #else | 2451 | #else |
2439 | bcm43xx_mmioprint_disable(bcm); | 2452 | bcm43xx_mmioprint_disable(bcm); |
2440 | #endif | 2453 | #endif |
2441 | 2454 | ||
2442 | bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals0->data, | 2455 | err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals0->data, |
2443 | bcm->initvals0->size / sizeof(struct bcm43xx_initval)); | 2456 | bcm->initvals0->size / sizeof(struct bcm43xx_initval)); |
2457 | if (err) | ||
2458 | goto out; | ||
2444 | if (bcm->initvals1) { | 2459 | if (bcm->initvals1) { |
2445 | bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals1->data, | 2460 | err = bcm43xx_write_initvals(bcm, (struct bcm43xx_initval *)bcm->initvals1->data, |
2446 | bcm->initvals1->size / sizeof(struct bcm43xx_initval)); | 2461 | bcm->initvals1->size / sizeof(struct bcm43xx_initval)); |
2462 | if (err) | ||
2463 | goto out; | ||
2447 | } | 2464 | } |
2448 | 2465 | ||
2466 | out: | ||
2449 | #ifdef DEBUG_ENABLE_UCODE_MMIO_PRINT | 2467 | #ifdef DEBUG_ENABLE_UCODE_MMIO_PRINT |
2450 | bcm43xx_mmioprint_disable(bcm); | 2468 | bcm43xx_mmioprint_disable(bcm); |
2451 | #else | 2469 | #else |
2452 | bcm43xx_mmioprint_enable(bcm); | 2470 | bcm43xx_mmioprint_enable(bcm); |
2453 | #endif | 2471 | #endif |
2472 | return err; | ||
2454 | } | 2473 | } |
2455 | 2474 | ||
2456 | static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm) | 2475 | static int bcm43xx_initialize_irq(struct bcm43xx_private *bcm) |
@@ -2683,7 +2702,7 @@ static void bcm43xx_chip_cleanup(struct bcm43xx_private *bcm) | |||
2683 | bcm43xx_leds_exit(bcm); | 2702 | bcm43xx_leds_exit(bcm); |
2684 | bcm43xx_gpio_cleanup(bcm); | 2703 | bcm43xx_gpio_cleanup(bcm); |
2685 | free_irq(bcm->irq, bcm); | 2704 | free_irq(bcm->irq, bcm); |
2686 | bcm43xx_release_firmware(bcm); | 2705 | bcm43xx_release_firmware(bcm, 0); |
2687 | } | 2706 | } |
2688 | 2707 | ||
2689 | /* Initialize the chip | 2708 | /* Initialize the chip |
@@ -2708,13 +2727,15 @@ static int bcm43xx_chip_init(struct bcm43xx_private *bcm) | |||
2708 | 2727 | ||
2709 | err = bcm43xx_initialize_irq(bcm); | 2728 | err = bcm43xx_initialize_irq(bcm); |
2710 | if (err) | 2729 | if (err) |
2711 | goto out; | 2730 | goto err_release_fw; |
2712 | 2731 | ||
2713 | err = bcm43xx_gpio_init(bcm); | 2732 | err = bcm43xx_gpio_init(bcm); |
2714 | if (err) | 2733 | if (err) |
2715 | goto err_free_irq; | 2734 | goto err_free_irq; |
2716 | 2735 | ||
2717 | bcm43xx_upload_initvals(bcm); | 2736 | err = bcm43xx_upload_initvals(bcm); |
2737 | if (err) | ||
2738 | goto err_gpio_cleanup; | ||
2718 | bcm43xx_radio_turn_on(bcm); | 2739 | bcm43xx_radio_turn_on(bcm); |
2719 | 2740 | ||
2720 | if (modparam_noleds) | 2741 | if (modparam_noleds) |
@@ -2813,9 +2834,12 @@ out: | |||
2813 | 2834 | ||
2814 | err_radio_off: | 2835 | err_radio_off: |
2815 | bcm43xx_radio_turn_off(bcm); | 2836 | bcm43xx_radio_turn_off(bcm); |
2837 | err_gpio_cleanup: | ||
2816 | bcm43xx_gpio_cleanup(bcm); | 2838 | bcm43xx_gpio_cleanup(bcm); |
2817 | err_free_irq: | 2839 | err_free_irq: |
2818 | free_irq(bcm->irq, bcm); | 2840 | free_irq(bcm->irq, bcm); |
2841 | err_release_fw: | ||
2842 | bcm43xx_release_firmware(bcm, 1); | ||
2819 | goto out; | 2843 | goto out; |
2820 | } | 2844 | } |
2821 | 2845 | ||