diff options
-rw-r--r-- | drivers/net/wireless/orinoco.c | 28 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco.h | 5 |
2 files changed, 26 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); |
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h index 981570bd3b9d..8c2953834923 100644 --- a/drivers/net/wireless/orinoco.h +++ b/drivers/net/wireless/orinoco.h | |||
@@ -66,6 +66,8 @@ struct orinoco_rx_data { | |||
66 | struct list_head list; | 66 | struct list_head list; |
67 | }; | 67 | }; |
68 | 68 | ||
69 | struct firmware; | ||
70 | |||
69 | struct orinoco_private { | 71 | struct orinoco_private { |
70 | void *card; /* Pointer to card dependent structure */ | 72 | void *card; /* Pointer to card dependent structure */ |
71 | struct device *dev; | 73 | struct device *dev; |
@@ -164,6 +166,9 @@ struct orinoco_private { | |||
164 | unsigned int wpa_enabled:1; | 166 | unsigned int wpa_enabled:1; |
165 | unsigned int tkip_cm_active:1; | 167 | unsigned int tkip_cm_active:1; |
166 | unsigned int key_mgmt:3; | 168 | unsigned int key_mgmt:3; |
169 | |||
170 | /* Cached in memory firmware to use in ->resume */ | ||
171 | const struct firmware *cached_fw; | ||
167 | }; | 172 | }; |
168 | 173 | ||
169 | #ifdef ORINOCO_DEBUG | 174 | #ifdef ORINOCO_DEBUG |