diff options
Diffstat (limited to 'drivers/net/wireless/orinoco.c')
-rw-r--r-- | drivers/net/wireless/orinoco.c | 28 |
1 files changed, 21 insertions, 7 deletions
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c index 7bd1559e8711..5a39166e2a0f 100644 --- a/drivers/net/wireless/orinoco.c +++ b/drivers/net/wireless/orinoco.c | |||
@@ -487,12 +487,17 @@ orinoco_dl_firmware(struct orinoco_private *priv, | |||
487 | if (err) | 487 | if (err) |
488 | goto free; | 488 | goto free; |
489 | 489 | ||
490 | err = request_firmware(&fw_entry, firmware, priv->dev); | 490 | if (priv->cached_fw) |
491 | if (err) { | 491 | fw_entry = priv->cached_fw; |
492 | printk(KERN_ERR "%s: Cannot find firmware %s\n", | 492 | else { |
493 | dev->name, firmware); | 493 | err = request_firmware(&fw_entry, firmware, priv->dev); |
494 | err = -ENOENT; | 494 | if (err) { |
495 | goto free; | 495 | printk(KERN_ERR "%s: Cannot find firmware %s\n", |
496 | dev->name, firmware); | ||
497 | err = -ENOENT; | ||
498 | goto free; | ||
499 | } | ||
500 | priv->cached_fw = fw_entry; | ||
496 | } | 501 | } |
497 | 502 | ||
498 | hdr = (const struct orinoco_fw_header *) fw_entry->data; | 503 | hdr = (const struct orinoco_fw_header *) fw_entry->data; |
@@ -535,7 +540,11 @@ orinoco_dl_firmware(struct orinoco_private *priv, | |||
535 | dev->name, hermes_present(hw)); | 540 | dev->name, hermes_present(hw)); |
536 | 541 | ||
537 | abort: | 542 | abort: |
538 | release_firmware(fw_entry); | 543 | /* In case of error, assume firmware was bogus and release it */ |
544 | if (err) { | ||
545 | priv->cached_fw = NULL; | ||
546 | release_firmware(fw_entry); | ||
547 | } | ||
539 | 548 | ||
540 | free: | 549 | free: |
541 | kfree(pda); | 550 | kfree(pda); |
@@ -3532,6 +3541,8 @@ struct net_device | |||
3532 | netif_carrier_off(dev); | 3541 | netif_carrier_off(dev); |
3533 | priv->last_linkstatus = 0xffff; | 3542 | priv->last_linkstatus = 0xffff; |
3534 | 3543 | ||
3544 | priv->cached_fw = NULL; | ||
3545 | |||
3535 | return dev; | 3546 | return dev; |
3536 | } | 3547 | } |
3537 | 3548 | ||
@@ -3543,6 +3554,9 @@ void free_orinocodev(struct net_device *dev) | |||
3543 | * when we call tasklet_kill it will run one final time, | 3554 | * when we call tasklet_kill it will run one final time, |
3544 | * emptying the list */ | 3555 | * emptying the list */ |
3545 | tasklet_kill(&priv->rx_tasklet); | 3556 | tasklet_kill(&priv->rx_tasklet); |
3557 | if (priv->cached_fw) | ||
3558 | release_firmware(priv->cached_fw); | ||
3559 | priv->cached_fw = NULL; | ||
3546 | priv->wpa_ie_len = 0; | 3560 | priv->wpa_ie_len = 0; |
3547 | kfree(priv->wpa_ie); | 3561 | kfree(priv->wpa_ie); |
3548 | orinoco_mic_free(priv); | 3562 | orinoco_mic_free(priv); |