diff options
Diffstat (limited to 'drivers/net/wireless/prism54/islpci_hotplug.c')
-rw-r--r-- | drivers/net/wireless/prism54/islpci_hotplug.c | 43 |
1 files changed, 27 insertions, 16 deletions
diff --git a/drivers/net/wireless/prism54/islpci_hotplug.c b/drivers/net/wireless/prism54/islpci_hotplug.c index f692dccf0d0..58257b40c04 100644 --- a/drivers/net/wireless/prism54/islpci_hotplug.c +++ b/drivers/net/wireless/prism54/islpci_hotplug.c | |||
@@ -1,5 +1,4 @@ | |||
1 | /* | 1 | /* |
2 | * | ||
3 | * Copyright (C) 2002 Intersil Americas Inc. | 2 | * Copyright (C) 2002 Intersil Americas Inc. |
4 | * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org> | 3 | * Copyright (C) 2003 Herbert Valerio Riedel <hvr@gnu.org> |
5 | * | 4 | * |
@@ -40,8 +39,8 @@ static int init_pcitm = 0; | |||
40 | module_param(init_pcitm, int, 0); | 39 | module_param(init_pcitm, int, 0); |
41 | 40 | ||
42 | /* In this order: vendor, device, subvendor, subdevice, class, class_mask, | 41 | /* In this order: vendor, device, subvendor, subdevice, class, class_mask, |
43 | * driver_data | 42 | * driver_data |
44 | * If you have an update for this please contact prism54-devel@prism54.org | 43 | * If you have an update for this please contact prism54-devel@prism54.org |
45 | * The latest list can be found at http://prism54.org/supported_cards.php */ | 44 | * The latest list can be found at http://prism54.org/supported_cards.php */ |
46 | static const struct pci_device_id prism54_id_tbl[] = { | 45 | static const struct pci_device_id prism54_id_tbl[] = { |
47 | /* Intersil PRISM Duette/Prism GT Wireless LAN adapter */ | 46 | /* Intersil PRISM Duette/Prism GT Wireless LAN adapter */ |
@@ -132,15 +131,15 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
132 | 131 | ||
133 | /* 0x40 is the programmable timer to configure the response timeout (TRDY_TIMEOUT) | 132 | /* 0x40 is the programmable timer to configure the response timeout (TRDY_TIMEOUT) |
134 | * 0x41 is the programmable timer to configure the retry timeout (RETRY_TIMEOUT) | 133 | * 0x41 is the programmable timer to configure the retry timeout (RETRY_TIMEOUT) |
135 | * The RETRY_TIMEOUT is used to set the number of retries that the core, as a | 134 | * The RETRY_TIMEOUT is used to set the number of retries that the core, as a |
136 | * Master, will perform before abandoning a cycle. The default value for | 135 | * Master, will perform before abandoning a cycle. The default value for |
137 | * RETRY_TIMEOUT is 0x80, which far exceeds the PCI 2.1 requirement for new | 136 | * RETRY_TIMEOUT is 0x80, which far exceeds the PCI 2.1 requirement for new |
138 | * devices. A write of zero to the RETRY_TIMEOUT register disables this | 137 | * devices. A write of zero to the RETRY_TIMEOUT register disables this |
139 | * function to allow use with any non-compliant legacy devices that may | 138 | * function to allow use with any non-compliant legacy devices that may |
140 | * execute more retries. | 139 | * execute more retries. |
141 | * | 140 | * |
142 | * Writing zero to both these two registers will disable both timeouts and | 141 | * Writing zero to both these two registers will disable both timeouts and |
143 | * *can* solve problems caused by devices that are slow to respond. | 142 | * *can* solve problems caused by devices that are slow to respond. |
144 | * Make this configurable - MSW | 143 | * Make this configurable - MSW |
145 | */ | 144 | */ |
146 | if ( init_pcitm >= 0 ) { | 145 | if ( init_pcitm >= 0 ) { |
@@ -171,14 +170,15 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
171 | pci_set_master(pdev); | 170 | pci_set_master(pdev); |
172 | 171 | ||
173 | /* enable MWI */ | 172 | /* enable MWI */ |
174 | pci_set_mwi(pdev); | 173 | if (!pci_set_mwi(pdev)) |
174 | printk(KERN_INFO "%s: pci_set_mwi(pdev) succeeded\n", DRV_NAME); | ||
175 | 175 | ||
176 | /* setup the network device interface and its structure */ | 176 | /* setup the network device interface and its structure */ |
177 | if (!(ndev = islpci_setup(pdev))) { | 177 | if (!(ndev = islpci_setup(pdev))) { |
178 | /* error configuring the driver as a network device */ | 178 | /* error configuring the driver as a network device */ |
179 | printk(KERN_ERR "%s: could not configure network device\n", | 179 | printk(KERN_ERR "%s: could not configure network device\n", |
180 | DRV_NAME); | 180 | DRV_NAME); |
181 | goto do_pci_release_regions; | 181 | goto do_pci_clear_mwi; |
182 | } | 182 | } |
183 | 183 | ||
184 | priv = netdev_priv(ndev); | 184 | priv = netdev_priv(ndev); |
@@ -208,6 +208,8 @@ prism54_probe(struct pci_dev *pdev, const struct pci_device_id *id) | |||
208 | pci_set_drvdata(pdev, NULL); | 208 | pci_set_drvdata(pdev, NULL); |
209 | free_netdev(ndev); | 209 | free_netdev(ndev); |
210 | priv = NULL; | 210 | priv = NULL; |
211 | do_pci_clear_mwi: | ||
212 | pci_clear_mwi(pdev); | ||
211 | do_pci_release_regions: | 213 | do_pci_release_regions: |
212 | pci_release_regions(pdev); | 214 | pci_release_regions(pdev); |
213 | do_pci_disable_device: | 215 | do_pci_disable_device: |
@@ -241,7 +243,7 @@ prism54_remove(struct pci_dev *pdev) | |||
241 | isl38xx_disable_interrupts(priv->device_base); | 243 | isl38xx_disable_interrupts(priv->device_base); |
242 | islpci_set_state(priv, PRV_STATE_OFF); | 244 | islpci_set_state(priv, PRV_STATE_OFF); |
243 | /* This bellow causes a lockup at rmmod time. It might be | 245 | /* This bellow causes a lockup at rmmod time. It might be |
244 | * because some interrupts still linger after rmmod time, | 246 | * because some interrupts still linger after rmmod time, |
245 | * see bug #17 */ | 247 | * see bug #17 */ |
246 | /* pci_set_power_state(pdev, 3);*/ /* try to power-off */ | 248 | /* pci_set_power_state(pdev, 3);*/ /* try to power-off */ |
247 | } | 249 | } |
@@ -255,6 +257,8 @@ prism54_remove(struct pci_dev *pdev) | |||
255 | free_netdev(ndev); | 257 | free_netdev(ndev); |
256 | priv = NULL; | 258 | priv = NULL; |
257 | 259 | ||
260 | pci_clear_mwi(pdev); | ||
261 | |||
258 | pci_release_regions(pdev); | 262 | pci_release_regions(pdev); |
259 | 263 | ||
260 | pci_disable_device(pdev); | 264 | pci_disable_device(pdev); |
@@ -288,12 +292,19 @@ prism54_resume(struct pci_dev *pdev) | |||
288 | { | 292 | { |
289 | struct net_device *ndev = pci_get_drvdata(pdev); | 293 | struct net_device *ndev = pci_get_drvdata(pdev); |
290 | islpci_private *priv = ndev ? netdev_priv(ndev) : NULL; | 294 | islpci_private *priv = ndev ? netdev_priv(ndev) : NULL; |
291 | BUG_ON(!priv); | 295 | int err; |
292 | 296 | ||
293 | pci_enable_device(pdev); | 297 | BUG_ON(!priv); |
294 | 298 | ||
295 | printk(KERN_NOTICE "%s: got resume request\n", ndev->name); | 299 | printk(KERN_NOTICE "%s: got resume request\n", ndev->name); |
296 | 300 | ||
301 | err = pci_enable_device(pdev); | ||
302 | if (err) { | ||
303 | printk(KERN_ERR "%s: pci_enable_device failed on resume\n", | ||
304 | ndev->name); | ||
305 | return err; | ||
306 | } | ||
307 | |||
297 | pci_restore_state(pdev); | 308 | pci_restore_state(pdev); |
298 | 309 | ||
299 | /* alright let's go into the PREBOOT state */ | 310 | /* alright let's go into the PREBOOT state */ |