ath5k: allocate ath5k_hw prior to initializing hw
authorLuis R. Rodriguez <lrodriguez@atheros.com>
Fri, 11 Sep 2009 01:04:47 +0000 (18:04 -0700)
committerJohn W. Linville <linville@tuxdriver.com>
Wed, 7 Oct 2009 20:39:28 +0000 (16:39 -0400)
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>
drivers/net/wireless/ath/ath.h
drivers/net/wireless/ath/ath5k/ath5k.h
drivers/net/wireless/ath/ath5k/attach.c
drivers/net/wireless/ath/ath5k/base.c

index 38be4279affc0dccb424d1691f949d55efddd3de..be68cb8cf70532fe418e32703226c8b463a8f4a8 100644 (file)
@@ -51,7 +51,7 @@ struct ath_common {
        u8 curbssid[ETH_ALEN];
        u8 bssidmask[ETH_ALEN];
        struct ath_regulatory regulatory;
-       struct ath_ops *ops;
+       const struct ath_ops *ops;
 };
 
 struct sk_buff *ath_rxbuf_alloc(struct ath_common *common,
index fee16fdd9c5a8f023dbd64f1cc3f602761fdda97..29ce868b1f1c72d53a6a9b36cbc7413055f12b47 100644 (file)
@@ -1147,7 +1147,7 @@ struct ath5k_hw {
  */
 
 /* 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);
 
 /* LED functions */
index 123612a8a5c6af864d122f11550ea09c01c165cd..c0840aba271535ca1a8bcb308d72fdbbd8d64412 100644 (file)
@@ -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
  * 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 pci_dev *pdev = sc->pdev;
        struct ath5k_eeprom_info *ee;
        int ret;
        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
         */
@@ -347,11 +334,10 @@ struct ath5k_hw *ath5k_hw_attach(struct ath5k_softc *sc)
        /* turn on HW LEDs */
        ath5k_hw_set_ledstate(ah, AR5K_LED_INIT);
 
-       return ah;
+       return 0;
 err_free:
        kfree(ah);
-err:
-       return ERR_PTR(ret);
+       return ret;
 }
 
 /**
@@ -371,5 +357,4 @@ void ath5k_hw_detach(struct ath5k_hw *ah)
        ath5k_eeprom_detach(ah);
 
        /* assume interrupts are down */
-       kfree(ah);
 }
index 06fc893723fac3df65413567800862704dc39a92..3cb07520d47bd938d134af7c66fbb396c0cb8288 100644 (file)
@@ -565,16 +565,25 @@ ath5k_pci_probe(struct pci_dev *pdev,
                goto err_free;
        }
 
-       /* Initialize device */
-       sc->ah = ath5k_hw_attach(sc);
-       if (IS_ERR(sc->ah)) {
-               ret = PTR_ERR(sc->ah);
+       /*If we passed the test malloc a ath5k_hw struct*/
+       sc->ah = kzalloc(sizeof(struct ath5k_hw), GFP_KERNEL);
+       if (!sc->ah) {
+               ret = -ENOMEM;
+               ATH5K_ERR(sc, "out of memory\n");
                goto err_irq;
        }
 
+       sc->ah->ah_sc = sc;
+       sc->ah->ah_iobase = sc->iobase;
        common = ath5k_hw_common(sc->ah);
        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 */
        if (sc->ah->ah_version == AR5K_AR5212) {
                hw->max_rates = 4;
@@ -643,6 +652,8 @@ err_ah:
        ath5k_hw_detach(sc->ah);
 err_irq:
        free_irq(pdev->irq, sc);
+err_free_ah:
+       kfree(sc->ah);
 err_free:
        ieee80211_free_hw(hw);
 err_map:
@@ -664,6 +675,7 @@ ath5k_pci_remove(struct pci_dev *pdev)
        ath5k_debug_finish_device(sc);
        ath5k_detach(pdev, hw);
        ath5k_hw_detach(sc->ah);
+       kfree(sc->ah);
        free_irq(pdev->irq, sc);
        pci_iounmap(pdev, sc->iobase);
        pci_release_region(pdev, 0);