aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorPavel Roskin <proski@gnu.org>2010-01-30 21:37:24 -0500
committerJohn W. Linville <linville@tuxdriver.com>2010-02-01 15:40:09 -0500
commitab5132a26236e308c6d3d832a3e04fca351656d8 (patch)
treedb473e3bd020a5e2f3fe02a381bb24e7b285ab5e /drivers
parente389900ed31975f3ce091764bf394b045058dad1 (diff)
ath9k: fix access to freed data on unload
Calling ath_bus_cleanup() after ieee80211_free_hw() resulted in access to common->bus_ops, which is already freed as part of the device data. Remove the cleanup field in struct ath_bus_ops, as it was never used properly. Remove ath_bus_cleanup(). Merge cleanup functions in place of the ath_bus_cleanup() calls. Take care not to use any device data after ieee80211_free_hw(). Signed-off-by: Pavel Roskin <proski@gnu.org> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/net/wireless/ath/ath.h1
-rw-r--r--drivers/net/wireless/ath/ath9k/ahb.c12
-rw-r--r--drivers/net/wireless/ath/ath9k/ath9k.h5
-rw-r--r--drivers/net/wireless/ath/ath9k/pci.c18
4 files changed, 7 insertions, 29 deletions
diff --git a/drivers/net/wireless/ath/ath.h b/drivers/net/wireless/ath/ath.h
index 9e05648356fe..71fc960814f0 100644
--- a/drivers/net/wireless/ath/ath.h
+++ b/drivers/net/wireless/ath/ath.h
@@ -74,7 +74,6 @@ struct ath_common;
74 74
75struct ath_bus_ops { 75struct ath_bus_ops {
76 void (*read_cachesize)(struct ath_common *common, int *csz); 76 void (*read_cachesize)(struct ath_common *common, int *csz);
77 void (*cleanup)(struct ath_common *common);
78 bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data); 77 bool (*eeprom_read)(struct ath_common *common, u32 off, u16 *data);
79 void (*bt_coex_prep)(struct ath_common *common); 78 void (*bt_coex_prep)(struct ath_common *common);
80}; 79};
diff --git a/drivers/net/wireless/ath/ath9k/ahb.c b/drivers/net/wireless/ath/ath9k/ahb.c
index 9e62a569e816..ca4994f13151 100644
--- a/drivers/net/wireless/ath/ath9k/ahb.c
+++ b/drivers/net/wireless/ath/ath9k/ahb.c
@@ -27,12 +27,6 @@ static void ath_ahb_read_cachesize(struct ath_common *common, int *csz)
27 *csz = L1_CACHE_BYTES >> 2; 27 *csz = L1_CACHE_BYTES >> 2;
28} 28}
29 29
30static void ath_ahb_cleanup(struct ath_common *common)
31{
32 struct ath_softc *sc = (struct ath_softc *)common->priv;
33 iounmap(sc->mem);
34}
35
36static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data) 30static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
37{ 31{
38 struct ath_softc *sc = (struct ath_softc *)common->priv; 32 struct ath_softc *sc = (struct ath_softc *)common->priv;
@@ -54,8 +48,6 @@ static bool ath_ahb_eeprom_read(struct ath_common *common, u32 off, u16 *data)
54 48
55static struct ath_bus_ops ath_ahb_bus_ops = { 49static struct ath_bus_ops ath_ahb_bus_ops = {
56 .read_cachesize = ath_ahb_read_cachesize, 50 .read_cachesize = ath_ahb_read_cachesize,
57 .cleanup = ath_ahb_cleanup,
58
59 .eeprom_read = ath_ahb_eeprom_read, 51 .eeprom_read = ath_ahb_eeprom_read,
60}; 52};
61 53
@@ -164,12 +156,12 @@ static int ath_ahb_remove(struct platform_device *pdev)
164 if (hw) { 156 if (hw) {
165 struct ath_wiphy *aphy = hw->priv; 157 struct ath_wiphy *aphy = hw->priv;
166 struct ath_softc *sc = aphy->sc; 158 struct ath_softc *sc = aphy->sc;
167 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 159 void __iomem *mem = sc->mem;
168 160
169 ath9k_deinit_device(sc); 161 ath9k_deinit_device(sc);
170 free_irq(sc->irq, sc); 162 free_irq(sc->irq, sc);
171 ieee80211_free_hw(sc->hw); 163 ieee80211_free_hw(sc->hw);
172 ath_bus_cleanup(common); 164 iounmap(mem);
173 platform_set_drvdata(pdev, NULL); 165 platform_set_drvdata(pdev, NULL);
174 } 166 }
175 167
diff --git a/drivers/net/wireless/ath/ath9k/ath9k.h b/drivers/net/wireless/ath/ath9k/ath9k.h
index 3f8a7e773d55..0ea340fd071c 100644
--- a/drivers/net/wireless/ath/ath9k/ath9k.h
+++ b/drivers/net/wireless/ath/ath9k/ath9k.h
@@ -538,11 +538,6 @@ static inline void ath_read_cachesize(struct ath_common *common, int *csz)
538 common->bus_ops->read_cachesize(common, csz); 538 common->bus_ops->read_cachesize(common, csz);
539} 539}
540 540
541static inline void ath_bus_cleanup(struct ath_common *common)
542{
543 common->bus_ops->cleanup(common);
544}
545
546extern struct ieee80211_ops ath9k_ops; 541extern struct ieee80211_ops ath9k_ops;
547extern int modparam_nohwcrypt; 542extern int modparam_nohwcrypt;
548 543
diff --git a/drivers/net/wireless/ath/ath9k/pci.c b/drivers/net/wireless/ath/ath9k/pci.c
index 4ae7b5f12029..f2afcbefc076 100644
--- a/drivers/net/wireless/ath/ath9k/pci.c
+++ b/drivers/net/wireless/ath/ath9k/pci.c
@@ -49,16 +49,6 @@ static void ath_pci_read_cachesize(struct ath_common *common, int *csz)
49 *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */ 49 *csz = DEFAULT_CACHELINE >> 2; /* Use the default size */
50} 50}
51 51
52static void ath_pci_cleanup(struct ath_common *common)
53{
54 struct ath_softc *sc = (struct ath_softc *) common->priv;
55 struct pci_dev *pdev = to_pci_dev(sc->dev);
56
57 pci_iounmap(pdev, sc->mem);
58 pci_disable_device(pdev);
59 pci_release_region(pdev, 0);
60}
61
62static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data) 52static bool ath_pci_eeprom_read(struct ath_common *common, u32 off, u16 *data)
63{ 53{
64 struct ath_hw *ah = (struct ath_hw *) common->ah; 54 struct ath_hw *ah = (struct ath_hw *) common->ah;
@@ -98,7 +88,6 @@ static void ath_pci_bt_coex_prep(struct ath_common *common)
98 88
99static const struct ath_bus_ops ath_pci_bus_ops = { 89static const struct ath_bus_ops ath_pci_bus_ops = {
100 .read_cachesize = ath_pci_read_cachesize, 90 .read_cachesize = ath_pci_read_cachesize,
101 .cleanup = ath_pci_cleanup,
102 .eeprom_read = ath_pci_eeprom_read, 91 .eeprom_read = ath_pci_eeprom_read,
103 .bt_coex_prep = ath_pci_bt_coex_prep, 92 .bt_coex_prep = ath_pci_bt_coex_prep,
104}; 93};
@@ -245,12 +234,15 @@ static void ath_pci_remove(struct pci_dev *pdev)
245 struct ieee80211_hw *hw = pci_get_drvdata(pdev); 234 struct ieee80211_hw *hw = pci_get_drvdata(pdev);
246 struct ath_wiphy *aphy = hw->priv; 235 struct ath_wiphy *aphy = hw->priv;
247 struct ath_softc *sc = aphy->sc; 236 struct ath_softc *sc = aphy->sc;
248 struct ath_common *common = ath9k_hw_common(sc->sc_ah); 237 void __iomem *mem = sc->mem;
249 238
250 ath9k_deinit_device(sc); 239 ath9k_deinit_device(sc);
251 free_irq(sc->irq, sc); 240 free_irq(sc->irq, sc);
252 ieee80211_free_hw(sc->hw); 241 ieee80211_free_hw(sc->hw);
253 ath_bus_cleanup(common); 242
243 pci_iounmap(pdev, mem);
244 pci_disable_device(pdev);
245 pci_release_region(pdev, 0);
254} 246}
255 247
256#ifdef CONFIG_PM 248#ifdef CONFIG_PM