diff options
author | Pavel Roskin <proski@gnu.org> | 2006-04-07 04:10:57 -0400 |
---|---|---|
committer | John W. Linville <linville@tuxdriver.com> | 2006-04-24 16:15:52 -0400 |
commit | b884c872fa1917614b42a39020ffcca7fa9302b1 (patch) | |
tree | 82f5ba67f6b38c96804fb449e018d83fbdce65a1 /drivers/net/wireless/orinoco_pci.c | |
parent | c6fb2e9abef894efc4870e4c1e3aa4365b830a11 (diff) |
[PATCH] orinoco: reduce differences between PCI drivers, create orinoco_pci.h
Make all Orinoco PCI drivers (orinoco_pci, orinoco_plx, orinoco_tmd and
orinoco_nortel) as similar as possible. Use the best implementation of
error handling, the best error messages, the best comments.
Put common code to orinoco_pci.h. For now, it's suspend and resume
functions and function for registering the network device.
Signed-off-by: Pavel Roskin <proski@gnu.org>
Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'drivers/net/wireless/orinoco_pci.c')
-rw-r--r-- | drivers/net/wireless/orinoco_pci.c | 144 |
1 files changed, 24 insertions, 120 deletions
diff --git a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c index 75df90ff1dc9..41efac22ba6a 100644 --- a/drivers/net/wireless/orinoco_pci.c +++ b/drivers/net/wireless/orinoco_pci.c | |||
@@ -100,6 +100,7 @@ | |||
100 | #include <linux/pci.h> | 100 | #include <linux/pci.h> |
101 | 101 | ||
102 | #include "orinoco.h" | 102 | #include "orinoco.h" |
103 | #include "orinoco_pci.h" | ||
103 | 104 | ||
104 | /* All the magic there is from wlan-ng */ | 105 | /* All the magic there is from wlan-ng */ |
105 | /* Magic offset of the reset register of the PCI card */ | 106 | /* Magic offset of the reset register of the PCI card */ |
@@ -113,11 +114,6 @@ | |||
113 | #define HERMES_PCI_COR_OFFT (500) /* ms */ | 114 | #define HERMES_PCI_COR_OFFT (500) /* ms */ |
114 | #define HERMES_PCI_COR_BUSYT (500) /* ms */ | 115 | #define HERMES_PCI_COR_BUSYT (500) /* ms */ |
115 | 116 | ||
116 | /* Orinoco PCI specific data */ | ||
117 | struct orinoco_pci_card { | ||
118 | void __iomem *pci_ioaddr; | ||
119 | }; | ||
120 | |||
121 | /* | 117 | /* |
122 | * Do a soft reset of the PCI card using the Configuration Option Register | 118 | * Do a soft reset of the PCI card using the Configuration Option Register |
123 | * We need this to get going... | 119 | * We need this to get going... |
@@ -131,12 +127,11 @@ struct orinoco_pci_card { | |||
131 | * Note bis : Don't try to access HERMES_CMD during the reset phase. | 127 | * Note bis : Don't try to access HERMES_CMD during the reset phase. |
132 | * It just won't work ! | 128 | * It just won't work ! |
133 | */ | 129 | */ |
134 | static int | 130 | static int orinoco_pci_cor_reset(struct orinoco_private *priv) |
135 | orinoco_pci_cor_reset(struct orinoco_private *priv) | ||
136 | { | 131 | { |
137 | hermes_t *hw = &priv->hw; | 132 | hermes_t *hw = &priv->hw; |
138 | unsigned long timeout; | 133 | unsigned long timeout; |
139 | u16 reg; | 134 | u16 reg; |
140 | 135 | ||
141 | /* Assert the reset until the card notice */ | 136 | /* Assert the reset until the card notice */ |
142 | hermes_write_regn(hw, PCI_COR, HERMES_PCI_COR_MASK); | 137 | hermes_write_regn(hw, PCI_COR, HERMES_PCI_COR_MASK); |
@@ -163,17 +158,14 @@ orinoco_pci_cor_reset(struct orinoco_private *priv) | |||
163 | return 0; | 158 | return 0; |
164 | } | 159 | } |
165 | 160 | ||
166 | /* | ||
167 | * Initialise a card. Mostly similar to PLX code. | ||
168 | */ | ||
169 | static int orinoco_pci_init_one(struct pci_dev *pdev, | 161 | static int orinoco_pci_init_one(struct pci_dev *pdev, |
170 | const struct pci_device_id *ent) | 162 | const struct pci_device_id *ent) |
171 | { | 163 | { |
172 | int err = 0; | 164 | int err; |
173 | void __iomem *pci_ioaddr = NULL; | 165 | struct orinoco_private *priv; |
174 | struct orinoco_private *priv = NULL; | ||
175 | struct orinoco_pci_card *card; | 166 | struct orinoco_pci_card *card; |
176 | struct net_device *dev = NULL; | 167 | struct net_device *dev; |
168 | void __iomem *hermes_io; | ||
177 | 169 | ||
178 | err = pci_enable_device(pdev); | 170 | err = pci_enable_device(pdev); |
179 | if (err) { | 171 | if (err) { |
@@ -182,38 +174,32 @@ static int orinoco_pci_init_one(struct pci_dev *pdev, | |||
182 | } | 174 | } |
183 | 175 | ||
184 | err = pci_request_regions(pdev, DRIVER_NAME); | 176 | err = pci_request_regions(pdev, DRIVER_NAME); |
185 | if (err != 0) { | 177 | if (err) { |
186 | printk(KERN_ERR PFX "Cannot obtain PCI resources\n"); | 178 | printk(KERN_ERR PFX "Cannot obtain PCI resources\n"); |
187 | goto fail_resources; | 179 | goto fail_resources; |
188 | } | 180 | } |
189 | 181 | ||
190 | /* Resource 0 is mapped to the hermes registers */ | 182 | hermes_io = pci_iomap(pdev, 0, 0); |
191 | pci_ioaddr = pci_iomap(pdev, 0, 0); | 183 | if (!hermes_io) { |
192 | if (!pci_ioaddr) { | 184 | printk(KERN_ERR PFX "Cannot remap chipset registers\n"); |
193 | err = -EIO; | 185 | err = -EIO; |
194 | printk(KERN_ERR PFX "Cannot remap hardware registers\n"); | 186 | goto fail_map_hermes; |
195 | goto fail_map; | ||
196 | } | 187 | } |
197 | 188 | ||
198 | /* Allocate network device */ | 189 | /* Allocate network device */ |
199 | dev = alloc_orinocodev(sizeof(*card), orinoco_pci_cor_reset); | 190 | dev = alloc_orinocodev(sizeof(*card), orinoco_pci_cor_reset); |
200 | if (! dev) { | 191 | if (!dev) { |
192 | printk(KERN_ERR PFX "Cannot allocate network device\n"); | ||
201 | err = -ENOMEM; | 193 | err = -ENOMEM; |
202 | goto fail_alloc; | 194 | goto fail_alloc; |
203 | } | 195 | } |
204 | 196 | ||
205 | priv = netdev_priv(dev); | 197 | priv = netdev_priv(dev); |
206 | card = priv->card; | 198 | card = priv->card; |
207 | card->pci_ioaddr = pci_ioaddr; | ||
208 | dev->mem_start = pci_resource_start(pdev, 0); | ||
209 | dev->mem_end = dev->mem_start + pci_resource_len(pdev, 0) - 1; | ||
210 | SET_MODULE_OWNER(dev); | 199 | SET_MODULE_OWNER(dev); |
211 | SET_NETDEV_DEV(dev, &pdev->dev); | 200 | SET_NETDEV_DEV(dev, &pdev->dev); |
212 | 201 | ||
213 | hermes_struct_init(&priv->hw, pci_ioaddr, HERMES_32BIT_REGSPACING); | 202 | hermes_struct_init(&priv->hw, hermes_io, HERMES_32BIT_REGSPACING); |
214 | |||
215 | printk(KERN_DEBUG PFX "Detected device %s, mem:0x%lx-0x%lx, irq %d\n", | ||
216 | pci_name(pdev), dev->mem_start, dev->mem_end, pdev->irq); | ||
217 | 203 | ||
218 | err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, | 204 | err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, |
219 | dev->name, dev); | 205 | dev->name, dev); |
@@ -222,9 +208,8 @@ static int orinoco_pci_init_one(struct pci_dev *pdev, | |||
222 | err = -EBUSY; | 208 | err = -EBUSY; |
223 | goto fail_irq; | 209 | goto fail_irq; |
224 | } | 210 | } |
225 | dev->irq = pdev->irq; | 211 | orinoco_pci_setup_netdev(dev, pdev, 0); |
226 | 212 | ||
227 | /* Perform a COR reset to start the card */ | ||
228 | err = orinoco_pci_cor_reset(priv); | 213 | err = orinoco_pci_cor_reset(priv); |
229 | if (err) { | 214 | if (err) { |
230 | printk(KERN_ERR PFX "Initial reset failed\n"); | 215 | printk(KERN_ERR PFX "Initial reset failed\n"); |
@@ -233,7 +218,7 @@ static int orinoco_pci_init_one(struct pci_dev *pdev, | |||
233 | 218 | ||
234 | err = register_netdev(dev); | 219 | err = register_netdev(dev); |
235 | if (err) { | 220 | if (err) { |
236 | printk(KERN_ERR PFX "Failed to register net device\n"); | 221 | printk(KERN_ERR PFX "Cannot register network device\n"); |
237 | goto fail; | 222 | goto fail; |
238 | } | 223 | } |
239 | 224 | ||
@@ -249,9 +234,9 @@ static int orinoco_pci_init_one(struct pci_dev *pdev, | |||
249 | free_orinocodev(dev); | 234 | free_orinocodev(dev); |
250 | 235 | ||
251 | fail_alloc: | 236 | fail_alloc: |
252 | iounmap(pci_ioaddr); | 237 | pci_iounmap(pdev, hermes_io); |
253 | 238 | ||
254 | fail_map: | 239 | fail_map_hermes: |
255 | pci_release_regions(pdev); | 240 | pci_release_regions(pdev); |
256 | 241 | ||
257 | fail_resources: | 242 | fail_resources: |
@@ -264,98 +249,17 @@ static void __devexit orinoco_pci_remove_one(struct pci_dev *pdev) | |||
264 | { | 249 | { |
265 | struct net_device *dev = pci_get_drvdata(pdev); | 250 | struct net_device *dev = pci_get_drvdata(pdev); |
266 | struct orinoco_private *priv = netdev_priv(dev); | 251 | struct orinoco_private *priv = netdev_priv(dev); |
267 | struct orinoco_pci_card *card = priv->card; | ||
268 | 252 | ||
269 | unregister_netdev(dev); | 253 | unregister_netdev(dev); |
270 | free_irq(dev->irq, dev); | 254 | free_irq(dev->irq, dev); |
271 | pci_set_drvdata(pdev, NULL); | 255 | pci_set_drvdata(pdev, NULL); |
272 | free_orinocodev(dev); | 256 | free_orinocodev(dev); |
273 | iounmap(card->pci_ioaddr); | 257 | pci_iounmap(pdev, priv->hw.iobase); |
274 | pci_release_regions(pdev); | 258 | pci_release_regions(pdev); |
275 | pci_disable_device(pdev); | 259 | pci_disable_device(pdev); |
276 | } | 260 | } |
277 | 261 | ||
278 | static int orinoco_pci_suspend(struct pci_dev *pdev, pm_message_t state) | 262 | static struct pci_device_id orinoco_pci_id_table[] = { |
279 | { | ||
280 | struct net_device *dev = pci_get_drvdata(pdev); | ||
281 | struct orinoco_private *priv = netdev_priv(dev); | ||
282 | unsigned long flags; | ||
283 | int err; | ||
284 | |||
285 | |||
286 | err = orinoco_lock(priv, &flags); | ||
287 | if (err) { | ||
288 | printk(KERN_ERR "%s: hw_unavailable on orinoco_pci_suspend\n", | ||
289 | dev->name); | ||
290 | return err; | ||
291 | } | ||
292 | |||
293 | err = __orinoco_down(dev); | ||
294 | if (err) | ||
295 | printk(KERN_WARNING "%s: orinoco_pci_suspend(): Error %d downing interface\n", | ||
296 | dev->name, err); | ||
297 | |||
298 | netif_device_detach(dev); | ||
299 | |||
300 | priv->hw_unavailable++; | ||
301 | |||
302 | orinoco_unlock(priv, &flags); | ||
303 | |||
304 | free_irq(pdev->irq, dev); | ||
305 | pci_save_state(pdev); | ||
306 | pci_disable_device(pdev); | ||
307 | pci_set_power_state(pdev, PCI_D3hot); | ||
308 | |||
309 | return 0; | ||
310 | } | ||
311 | |||
312 | static int orinoco_pci_resume(struct pci_dev *pdev) | ||
313 | { | ||
314 | struct net_device *dev = pci_get_drvdata(pdev); | ||
315 | struct orinoco_private *priv = netdev_priv(dev); | ||
316 | unsigned long flags; | ||
317 | int err; | ||
318 | |||
319 | printk(KERN_DEBUG "%s: Orinoco-PCI waking up\n", dev->name); | ||
320 | |||
321 | pci_set_power_state(pdev, 0); | ||
322 | pci_enable_device(pdev); | ||
323 | pci_restore_state(pdev); | ||
324 | |||
325 | err = request_irq(pdev->irq, orinoco_interrupt, SA_SHIRQ, | ||
326 | dev->name, dev); | ||
327 | if (err) { | ||
328 | printk(KERN_ERR "%s: Cannot re-allocate IRQ\n", dev->name); | ||
329 | pci_disable_device(pdev); | ||
330 | return -EBUSY; | ||
331 | } | ||
332 | |||
333 | err = orinoco_reinit_firmware(dev); | ||
334 | if (err) { | ||
335 | printk(KERN_ERR "%s: Error %d re-initializing firmware on orinoco_pci_resume()\n", | ||
336 | dev->name, err); | ||
337 | return err; | ||
338 | } | ||
339 | |||
340 | spin_lock_irqsave(&priv->lock, flags); | ||
341 | |||
342 | netif_device_attach(dev); | ||
343 | |||
344 | priv->hw_unavailable--; | ||
345 | |||
346 | if (priv->open && (! priv->hw_unavailable)) { | ||
347 | err = __orinoco_up(dev); | ||
348 | if (err) | ||
349 | printk(KERN_ERR "%s: Error %d restarting card on orinoco_pci_resume()\n", | ||
350 | dev->name, err); | ||
351 | } | ||
352 | |||
353 | spin_unlock_irqrestore(&priv->lock, flags); | ||
354 | |||
355 | return 0; | ||
356 | } | ||
357 | |||
358 | static struct pci_device_id orinoco_pci_pci_id_table[] = { | ||
359 | /* Intersil Prism 3 */ | 263 | /* Intersil Prism 3 */ |
360 | {0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID,}, | 264 | {0x1260, 0x3872, PCI_ANY_ID, PCI_ANY_ID,}, |
361 | /* Intersil Prism 2.5 */ | 265 | /* Intersil Prism 2.5 */ |
@@ -365,11 +269,11 @@ static struct pci_device_id orinoco_pci_pci_id_table[] = { | |||
365 | {0,}, | 269 | {0,}, |
366 | }; | 270 | }; |
367 | 271 | ||
368 | MODULE_DEVICE_TABLE(pci, orinoco_pci_pci_id_table); | 272 | MODULE_DEVICE_TABLE(pci, orinoco_pci_id_table); |
369 | 273 | ||
370 | static struct pci_driver orinoco_pci_driver = { | 274 | static struct pci_driver orinoco_pci_driver = { |
371 | .name = DRIVER_NAME, | 275 | .name = DRIVER_NAME, |
372 | .id_table = orinoco_pci_pci_id_table, | 276 | .id_table = orinoco_pci_id_table, |
373 | .probe = orinoco_pci_init_one, | 277 | .probe = orinoco_pci_init_one, |
374 | .remove = __devexit_p(orinoco_pci_remove_one), | 278 | .remove = __devexit_p(orinoco_pci_remove_one), |
375 | .suspend = orinoco_pci_suspend, | 279 | .suspend = orinoco_pci_suspend, |