diff options
author | Luis R. Rodriguez <lrodriguez@atheros.com> | 2009-09-10 21:04:47 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2009-10-07 16:39:28 -0400 |
commit | 9adca126dbf4bf099bc7051deb6b566725a046dc (patch) | |
tree | de3eaed32a5d460b50cf4f0d465a4384eb2ba551 /drivers/net/wireless/ath/ath5k | |
parent | 9e4bffd233f27fe83fc48efb01935aee7d0685bf (diff) |
ath5k: allocate ath5k_hw prior to initializing hw
We can propagate better errors upon failed hw initialization,
and set up the ath_common structure for attach purposes. This
will become important once we start using the ath_common
for read/write ops.
Signed-off-by: Luis R. Rodriguez <lrodriguez@atheros.com>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/ath/ath5k')
-rw-r--r-- | drivers/net/wireless/ath/ath5k/ath5k.h | 2 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/attach.c | 23 | ||||
-rw-r--r-- | drivers/net/wireless/ath/ath5k/base.c | 20 |
3 files changed, 21 insertions, 24 deletions
diff --git a/drivers/net/wireless/ath/ath5k/ath5k.h b/drivers/net/wireless/ath/ath5k/ath5k.h index fee16fdd9c5a..29ce868b1f1c 100644 --- a/drivers/net/wireless/ath/ath5k/ath5k.h +++ b/drivers/net/wireless/ath/ath5k/ath5k.h | |||
@@ -1147,7 +1147,7 @@ struct ath5k_hw { | |||
1147 | */ | 1147 | */ |
1148 | 1148 | ||
1149 | /* Attach/Detach Functions */ | 1149 | /* Attach/Detach Functions */ |
1150 | extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc); | 1150 | extern int ath5k_hw_attach(struct ath5k_softc *sc); |
1151 | extern void ath5k_hw_detach(struct ath5k_hw *ah); | 1151 | extern void ath5k_hw_detach(struct ath5k_hw *ah); |
1152 | 1152 | ||
1153 | /* LED functions */ | 1153 | /* LED functions */ |
diff --git a/drivers/net/wireless/ath/ath5k/attach.c b/drivers/net/wireless/ath/ath5k/attach.c index 123612a8a5c6..c0840aba2715 100644 --- a/drivers/net/wireless/ath/ath5k/attach.c +++ b/drivers/net/wireless/ath/ath5k/attach.c | |||
@@ -101,28 +101,15 @@ static int ath5k_hw_post(struct ath5k_hw *ah) | |||
101 | * -ENODEV if the device is not supported or prints an error msg if something | 101 | * -ENODEV if the device is not supported or prints an error msg if something |
102 | * else went wrong. | 102 | * else went wrong. |
103 | */ | 103 | */ |
104 | struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc) | 104 | int ath5k_hw_attach(struct ath5k_softc *sc) |
105 | { | 105 | { |
106 | struct ath5k_hw *ah; | 106 | struct ath5k_hw *ah = sc->ah; |
107 | struct ath_common *common; | 107 | struct ath_common *common; |
108 | struct pci_dev *pdev = sc->pdev; | 108 | struct pci_dev *pdev = sc->pdev; |
109 | struct ath5k_eeprom_info *ee; | 109 | struct ath5k_eeprom_info *ee; |
110 | int ret; | 110 | int ret; |
111 | u32 srev; | 111 | u32 srev; |
112 | 112 | ||
113 | /*If we passed the test malloc a ath5k_hw struct*/ | ||
114 | ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); | ||
115 | if (ah == NULL) { | ||
116 | ret = -ENOMEM; | ||
117 | ATH5K_ERR(sc, "out of memory\n"); | ||
118 | goto err; | ||
119 | } | ||
120 | |||
121 | ah->ah_sc = sc; | ||
122 | ah->ah_sc->ah = ah; | ||
123 | ah->ah_iobase = sc->iobase; | ||
124 | common = ath5k_hw_common(ah); | ||
125 | |||
126 | /* | 113 | /* |
127 | * HW information | 114 | * HW information |
128 | */ | 115 | */ |
@@ -347,11 +334,10 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc) | |||
347 | /* turn on HW LEDs */ | 334 | /* turn on HW LEDs */ |
348 | ath5k_hw_set_ledstate(ah, AR5K_LED_INIT); | 335 | ath5k_hw_set_ledstate(ah, AR5K_LED_INIT); |
349 | 336 | ||
350 | return ah; | 337 | return 0; |
351 | err_free: | 338 | err_free: |
352 | kfree(ah); | 339 | kfree(ah); |
353 | err: | 340 | return ret; |
354 | return ERR_PTR(ret); | ||
355 | } | 341 | } |
356 | 342 | ||
357 | /** | 343 | /** |
@@ -371,5 +357,4 @@ void ath5k_hw_detach(struct ath5k_hw *ah) | |||
371 | ath5k_eeprom_detach(ah); | 357 | ath5k_eeprom_detach(ah); |
372 | 358 | ||
373 | /* assume interrupts are down */ | 359 | /* assume interrupts are down */ |
374 | kfree(ah); | ||
375 | } | 360 | } |
diff --git a/drivers/net/wireless/ath/ath5k/base.c b/drivers/net/wireless/ath/ath5k/base.c index 06fc893723fa..3cb07520d47b 100644 --- a/drivers/net/wireless/ath/ath5k/base.c +++ b/drivers/net/wireless/ath/ath5k/base.c | |||
@@ -565,16 +565,25 @@ ath5k_pci_probe(struct pci_dev *pdev, | |||
565 | goto err_free; | 565 | goto err_free; |
566 | } | 566 | } |
567 | 567 | ||
568 | /* Initialize device */ | 568 | /*If we passed the test malloc a ath5k_hw struct*/ |
569 | sc->ah = ath5k_hw_attach(sc); | 569 | sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL); |
570 | if (IS_ERR(sc->ah)) { | 570 | if (!sc->ah) { |
571 | ret = PTR_ERR(sc->ah); | 571 | ret = -ENOMEM; |
572 | ATH5K_ERR(sc, "out of memory\n"); | ||
572 | goto err_irq; | 573 | goto err_irq; |
573 | } | 574 | } |
574 | 575 | ||
576 | sc->ah->ah_sc = sc; | ||
577 | sc->ah->ah_iobase = sc->iobase; | ||
575 | common = ath5k_hw_common(sc->ah); | 578 | common = ath5k_hw_common(sc->ah); |
576 | common->cachelsz = csz << 2; /* convert to bytes */ | 579 | common->cachelsz = csz << 2; /* convert to bytes */ |
577 | 580 | ||
581 | /* Initialize device */ | ||
582 | ret = ath5k_hw_attach(sc); | ||
583 | if (ret) { | ||
584 | goto err_free_ah; | ||
585 | } | ||
586 | |||
578 | /* set up multi-rate retry capabilities */ | 587 | /* set up multi-rate retry capabilities */ |
579 | if (sc->ah->ah_version == AR5K_AR5212) { | 588 | if (sc->ah->ah_version == AR5K_AR5212) { |
580 | hw->max_rates = 4; | 589 | hw->max_rates = 4; |
@@ -643,6 +652,8 @@ err_ah: | |||
643 | ath5k_hw_detach(sc->ah); | 652 | ath5k_hw_detach(sc->ah); |
644 | err_irq: | 653 | err_irq: |
645 | free_irq(pdev->irq, sc); | 654 | free_irq(pdev->irq, sc); |
655 | err_free_ah: | ||
656 | kfree(sc->ah); | ||
646 | err_free: | 657 | err_free: |
647 | ieee80211_free_hw(hw); | 658 | ieee80211_free_hw(hw); |
648 | err_map: | 659 | err_map: |
@@ -664,6 +675,7 @@ ath5k_pci_remove(struct pci_dev *pdev) | |||
664 | ath5k_debug_finish_device(sc); | 675 | ath5k_debug_finish_device(sc); |
665 | ath5k_detach(pdev, hw); | 676 | ath5k_detach(pdev, hw); |
666 | ath5k_hw_detach(sc->ah); | 677 | ath5k_hw_detach(sc->ah); |
678 | kfree(sc->ah); | ||
667 | free_irq(pdev->irq, sc); | 679 | free_irq(pdev->irq, sc); |
668 | pci_iounmap(pdev, sc->iobase); | 680 | pci_iounmap(pdev, sc->iobase); |
669 | pci_release_region(pdev, 0); | 681 | pci_release_region(pdev, 0); |