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>
This commit is contained in:
parent
9e4bffd233
commit
9adca126db
|
@ -51,7 +51,7 @@ struct ath_common {
|
||||||
u8 curbssid[ETH_ALEN];
|
u8 curbssid[ETH_ALEN];
|
||||||
u8 bssidmask[ETH_ALEN];
|
u8 bssidmask[ETH_ALEN];
|
||||||
struct ath_regulatory regulatory;
|
struct ath_regulatory regulatory;
|
||||||
struct ath_ops *ops;
|
const struct ath_ops *ops;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
|
struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
|
||||||
|
|
|
@ -1147,7 +1147,7 @@ struct ath5k_hw {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Attach/Detach Functions */
|
/* Attach/Detach Functions */
|
||||||
extern struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc);
|
extern int ath5k_hw_attach(struct ath5k_softc *sc);
|
||||||
extern void ath5k_hw_detach(struct ath5k_hw *ah);
|
extern void ath5k_hw_detach(struct ath5k_hw *ah);
|
||||||
|
|
||||||
/* LED functions */
|
/* LED functions */
|
||||||
|
|
|
@ -101,28 +101,15 @@ static int ath5k_hw_post(struct ath5k_hw *ah)
|
||||||
* -ENODEV if the device is not supported or prints an error msg if something
|
* -ENODEV if the device is not supported or prints an error msg if something
|
||||||
* else went wrong.
|
* else went wrong.
|
||||||
*/
|
*/
|
||||||
struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc)
|
int ath5k_hw_attach(struct ath5k_softc *sc)
|
||||||
{
|
{
|
||||||
struct ath5k_hw *ah;
|
struct ath5k_hw *ah = sc->ah;
|
||||||
struct ath_common *common;
|
struct ath_common *common;
|
||||||
struct pci_dev *pdev = sc->pdev;
|
struct pci_dev *pdev = sc->pdev;
|
||||||
struct ath5k_eeprom_info *ee;
|
struct ath5k_eeprom_info *ee;
|
||||||
int ret;
|
int ret;
|
||||||
u32 srev;
|
u32 srev;
|
||||||
|
|
||||||
/*If we passed the test malloc a ath5k_hw struct*/
|
|
||||||
ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
|
|
||||||
if (ah == NULL) {
|
|
||||||
ret = -ENOMEM;
|
|
||||||
ATH5K_ERR(sc, "out of memory\n");
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
ah->ah_sc = sc;
|
|
||||||
ah->ah_sc->ah = ah;
|
|
||||||
ah->ah_iobase = sc->iobase;
|
|
||||||
common = ath5k_hw_common(ah);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* HW information
|
* HW information
|
||||||
*/
|
*/
|
||||||
|
@ -347,11 +334,10 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc)
|
||||||
/* turn on HW LEDs */
|
/* turn on HW LEDs */
|
||||||
ath5k_hw_set_ledstate(ah, AR5K_LED_INIT);
|
ath5k_hw_set_ledstate(ah, AR5K_LED_INIT);
|
||||||
|
|
||||||
return ah;
|
return 0;
|
||||||
err_free:
|
err_free:
|
||||||
kfree(ah);
|
kfree(ah);
|
||||||
err:
|
return ret;
|
||||||
return ERR_PTR(ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -371,5 +357,4 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
|
||||||
ath5k_eeprom_detach(ah);
|
ath5k_eeprom_detach(ah);
|
||||||
|
|
||||||
/* assume interrupts are down */
|
/* assume interrupts are down */
|
||||||
kfree(ah);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -565,16 +565,25 @@ ath5k_pci_probe(struct pci_dev *pdev,
|
||||||
goto err_free;
|
goto err_free;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize device */
|
/*If we passed the test malloc a ath5k_hw struct*/
|
||||||
sc->ah = ath5k_hw_attach(sc);
|
sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
|
||||||
if (IS_ERR(sc->ah)) {
|
if (!sc->ah) {
|
||||||
ret = PTR_ERR(sc->ah);
|
ret = -ENOMEM;
|
||||||
|
ATH5K_ERR(sc, "out of memory\n");
|
||||||
goto err_irq;
|
goto err_irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sc->ah->ah_sc = sc;
|
||||||
|
sc->ah->ah_iobase = sc->iobase;
|
||||||
common = ath5k_hw_common(sc->ah);
|
common = ath5k_hw_common(sc->ah);
|
||||||
common->cachelsz = csz << 2; /* convert to bytes */
|
common->cachelsz = csz << 2; /* convert to bytes */
|
||||||
|
|
||||||
|
/* Initialize device */
|
||||||
|
ret = ath5k_hw_attach(sc);
|
||||||
|
if (ret) {
|
||||||
|
goto err_free_ah;
|
||||||
|
}
|
||||||
|
|
||||||
/* set up multi-rate retry capabilities */
|
/* set up multi-rate retry capabilities */
|
||||||
if (sc->ah->ah_version == AR5K_AR5212) {
|
if (sc->ah->ah_version == AR5K_AR5212) {
|
||||||
hw->max_rates = 4;
|
hw->max_rates = 4;
|
||||||
|
@ -643,6 +652,8 @@ err_ah:
|
||||||
ath5k_hw_detach(sc->ah);
|
ath5k_hw_detach(sc->ah);
|
||||||
err_irq:
|
err_irq:
|
||||||
free_irq(pdev->irq, sc);
|
free_irq(pdev->irq, sc);
|
||||||
|
err_free_ah:
|
||||||
|
kfree(sc->ah);
|
||||||
err_free:
|
err_free:
|
||||||
ieee80211_free_hw(hw);
|
ieee80211_free_hw(hw);
|
||||||
err_map:
|
err_map:
|
||||||
|
@ -664,6 +675,7 @@ ath5k_pci_remove(struct pci_dev *pdev)
|
||||||
ath5k_debug_finish_device(sc);
|
ath5k_debug_finish_device(sc);
|
||||||
ath5k_detach(pdev, hw);
|
ath5k_detach(pdev, hw);
|
||||||
ath5k_hw_detach(sc->ah);
|
ath5k_hw_detach(sc->ah);
|
||||||
|
kfree(sc->ah);
|
||||||
free_irq(pdev->irq, sc);
|
free_irq(pdev->irq, sc);
|
||||||
pci_iounmap(pdev, sc->iobase);
|
pci_iounmap(pdev, sc->iobase);
|
||||||
pci_release_region(pdev, 0);
|
pci_release_region(pdev, 0);
|
||||||
|
|
Loading…
Reference in a new issue