aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/orinoco_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/orinoco_cs.c')
-rw-r--r--drivers/net/wireless/orinoco_cs.c187
1 files changed, 74 insertions, 113 deletions
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index ec6f2a48895b..434f7d7ad841 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -49,7 +49,7 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Allow voltage mismatch between card and socket
49/* PCMCIA specific device information (goes in the card field of 49/* PCMCIA specific device information (goes in the card field of
50 * struct orinoco_private */ 50 * struct orinoco_private */
51struct orinoco_pccard { 51struct orinoco_pccard {
52 dev_link_t link; 52 struct pcmcia_device *p_dev;
53 dev_node_t node; 53 dev_node_t node;
54 54
55 /* Used to handle hard reset */ 55 /* Used to handle hard reset */
@@ -63,8 +63,8 @@ struct orinoco_pccard {
63/* Function prototypes */ 63/* Function prototypes */
64/********************************************************************/ 64/********************************************************************/
65 65
66static void orinoco_cs_config(dev_link_t *link); 66static int orinoco_cs_config(struct pcmcia_device *link);
67static void orinoco_cs_release(dev_link_t *link); 67static void orinoco_cs_release(struct pcmcia_device *link);
68static void orinoco_cs_detach(struct pcmcia_device *p_dev); 68static void orinoco_cs_detach(struct pcmcia_device *p_dev);
69 69
70/********************************************************************/ 70/********************************************************************/
@@ -75,13 +75,13 @@ static int
75orinoco_cs_hard_reset(struct orinoco_private *priv) 75orinoco_cs_hard_reset(struct orinoco_private *priv)
76{ 76{
77 struct orinoco_pccard *card = priv->card; 77 struct orinoco_pccard *card = priv->card;
78 dev_link_t *link = &card->link; 78 struct pcmcia_device *link = card->p_dev;
79 int err; 79 int err;
80 80
81 /* We need atomic ops here, because we're not holding the lock */ 81 /* We need atomic ops here, because we're not holding the lock */
82 set_bit(0, &card->hard_reset_in_progress); 82 set_bit(0, &card->hard_reset_in_progress);
83 83
84 err = pcmcia_reset_card(link->handle, NULL); 84 err = pcmcia_reset_card(link, NULL);
85 if (err) 85 if (err)
86 return err; 86 return err;
87 87
@@ -104,12 +104,11 @@ orinoco_cs_hard_reset(struct orinoco_private *priv)
104 * configure the card at this point -- we wait until we receive a card 104 * configure the card at this point -- we wait until we receive a card
105 * insertion event. */ 105 * insertion event. */
106static int 106static int
107orinoco_cs_attach(struct pcmcia_device *p_dev) 107orinoco_cs_probe(struct pcmcia_device *link)
108{ 108{
109 struct net_device *dev; 109 struct net_device *dev;
110 struct orinoco_private *priv; 110 struct orinoco_private *priv;
111 struct orinoco_pccard *card; 111 struct orinoco_pccard *card;
112 dev_link_t *link;
113 112
114 dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset); 113 dev = alloc_orinocodev(sizeof(*card), orinoco_cs_hard_reset);
115 if (! dev) 114 if (! dev)
@@ -118,7 +117,7 @@ orinoco_cs_attach(struct pcmcia_device *p_dev)
118 card = priv->card; 117 card = priv->card;
119 118
120 /* Link both structures together */ 119 /* Link both structures together */
121 link = &card->link; 120 card->p_dev = link;
122 link->priv = dev; 121 link->priv = dev;
123 122
124 /* Interrupt setup */ 123 /* Interrupt setup */
@@ -135,16 +134,7 @@ orinoco_cs_attach(struct pcmcia_device *p_dev)
135 link->conf.Attributes = 0; 134 link->conf.Attributes = 0;
136 link->conf.IntType = INT_MEMORY_AND_IO; 135 link->conf.IntType = INT_MEMORY_AND_IO;
137 136
138 /* Register with Card Services */ 137 return orinoco_cs_config(link);
139 link->next = NULL;
140
141 link->handle = p_dev;
142 p_dev->instance = link;
143
144 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
145 orinoco_cs_config(link);
146
147 return 0;
148} /* orinoco_cs_attach */ 138} /* orinoco_cs_attach */
149 139
150/* 140/*
@@ -153,16 +143,14 @@ orinoco_cs_attach(struct pcmcia_device *p_dev)
153 * are freed. Otherwise, the structures will be freed when the device 143 * are freed. Otherwise, the structures will be freed when the device
154 * is released. 144 * is released.
155 */ 145 */
156static void orinoco_cs_detach(struct pcmcia_device *p_dev) 146static void orinoco_cs_detach(struct pcmcia_device *link)
157{ 147{
158 dev_link_t *link = dev_to_instance(p_dev);
159 struct net_device *dev = link->priv; 148 struct net_device *dev = link->priv;
160 149
161 if (link->state & DEV_CONFIG) 150 orinoco_cs_release(link);
162 orinoco_cs_release(link);
163 151
164 DEBUG(0, PFX "detach: link=%p link->dev=%p\n", link, link->dev); 152 DEBUG(0, PFX "detach: link=%p link->dev_node=%p\n", link, link->dev_node);
165 if (link->dev) { 153 if (link->dev_node) {
166 DEBUG(0, PFX "About to unregister net device %p\n", 154 DEBUG(0, PFX "About to unregister net device %p\n",
167 dev); 155 dev);
168 unregister_netdev(dev); 156 unregister_netdev(dev);
@@ -180,11 +168,10 @@ static void orinoco_cs_detach(struct pcmcia_device *p_dev)
180 last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \ 168 last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; \
181 } while (0) 169 } while (0)
182 170
183static void 171static int
184orinoco_cs_config(dev_link_t *link) 172orinoco_cs_config(struct pcmcia_device *link)
185{ 173{
186 struct net_device *dev = link->priv; 174 struct net_device *dev = link->priv;
187 client_handle_t handle = link->handle;
188 struct orinoco_private *priv = netdev_priv(dev); 175 struct orinoco_private *priv = netdev_priv(dev);
189 struct orinoco_pccard *card = priv->card; 176 struct orinoco_pccard *card = priv->card;
190 hermes_t *hw = &priv->hw; 177 hermes_t *hw = &priv->hw;
@@ -196,7 +183,7 @@ orinoco_cs_config(dev_link_t *link)
196 cisparse_t parse; 183 cisparse_t parse;
197 void __iomem *mem; 184 void __iomem *mem;
198 185
199 CS_CHECK(ValidateCIS, pcmcia_validate_cis(handle, &info)); 186 CS_CHECK(ValidateCIS, pcmcia_validate_cis(link, &info));
200 187
201 /* 188 /*
202 * This reads the card's CONFIG tuple to find its 189 * This reads the card's CONFIG tuple to find its
@@ -207,19 +194,15 @@ orinoco_cs_config(dev_link_t *link)
207 tuple.TupleData = buf; 194 tuple.TupleData = buf;
208 tuple.TupleDataMax = sizeof(buf); 195 tuple.TupleDataMax = sizeof(buf);
209 tuple.TupleOffset = 0; 196 tuple.TupleOffset = 0;
210 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 197 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
211 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple)); 198 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
212 CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse)); 199 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, &parse));
213 link->conf.ConfigBase = parse.config.base; 200 link->conf.ConfigBase = parse.config.base;
214 link->conf.Present = parse.config.rmask[0]; 201 link->conf.Present = parse.config.rmask[0];
215 202
216 /* Configure card */
217 link->state |= DEV_CONFIG;
218
219 /* Look up the current Vcc */ 203 /* Look up the current Vcc */
220 CS_CHECK(GetConfigurationInfo, 204 CS_CHECK(GetConfigurationInfo,
221 pcmcia_get_configuration_info(handle, &conf)); 205 pcmcia_get_configuration_info(link, &conf));
222 link->conf.Vcc = conf.Vcc;
223 206
224 /* 207 /*
225 * In this loop, we scan the CIS for configuration table 208 * In this loop, we scan the CIS for configuration table
@@ -236,13 +219,13 @@ orinoco_cs_config(dev_link_t *link)
236 * implementation-defined details. 219 * implementation-defined details.
237 */ 220 */
238 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 221 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
239 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple)); 222 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
240 while (1) { 223 while (1) {
241 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry); 224 cistpl_cftable_entry_t *cfg = &(parse.cftable_entry);
242 cistpl_cftable_entry_t dflt = { .index = 0 }; 225 cistpl_cftable_entry_t dflt = { .index = 0 };
243 226
244 if ( (pcmcia_get_tuple_data(handle, &tuple) != 0) 227 if ( (pcmcia_get_tuple_data(link, &tuple) != 0)
245 || (pcmcia_parse_tuple(handle, &tuple, &parse) != 0)) 228 || (pcmcia_parse_tuple(link, &tuple, &parse) != 0))
246 goto next_entry; 229 goto next_entry;
247 230
248 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) 231 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
@@ -274,10 +257,10 @@ orinoco_cs_config(dev_link_t *link)
274 } 257 }
275 258
276 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) 259 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
277 link->conf.Vpp1 = link->conf.Vpp2 = 260 link->conf.Vpp =
278 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; 261 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
279 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) 262 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
280 link->conf.Vpp1 = link->conf.Vpp2 = 263 link->conf.Vpp =
281 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; 264 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
282 265
283 /* Do we need to allocate an interrupt? */ 266 /* Do we need to allocate an interrupt? */
@@ -307,7 +290,7 @@ orinoco_cs_config(dev_link_t *link)
307 } 290 }
308 291
309 /* This reserves IO space but doesn't actually enable it */ 292 /* This reserves IO space but doesn't actually enable it */
310 if (pcmcia_request_io(link->handle, &link->io) != 0) 293 if (pcmcia_request_io(link, &link->io) != 0)
311 goto next_entry; 294 goto next_entry;
312 } 295 }
313 296
@@ -317,9 +300,8 @@ orinoco_cs_config(dev_link_t *link)
317 break; 300 break;
318 301
319 next_entry: 302 next_entry:
320 if (link->io.NumPorts1) 303 pcmcia_disable_device(link);
321 pcmcia_release_io(link->handle, &link->io); 304 last_ret = pcmcia_get_next_tuple(link, &tuple);
322 last_ret = pcmcia_get_next_tuple(handle, &tuple);
323 if (last_ret == CS_NO_MORE_ITEMS) { 305 if (last_ret == CS_NO_MORE_ITEMS) {
324 printk(KERN_ERR PFX "GetNextTuple(): No matching " 306 printk(KERN_ERR PFX "GetNextTuple(): No matching "
325 "CIS configuration. Maybe you need the " 307 "CIS configuration. Maybe you need the "
@@ -333,7 +315,7 @@ orinoco_cs_config(dev_link_t *link)
333 * a handler to the interrupt, unless the 'Handler' member of 315 * a handler to the interrupt, unless the 'Handler' member of
334 * the irq structure is initialized. 316 * the irq structure is initialized.
335 */ 317 */
336 CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq)); 318 CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));
337 319
338 /* We initialize the hermes structure before completing PCMCIA 320 /* We initialize the hermes structure before completing PCMCIA
339 * configuration just in case the interrupt handler gets 321 * configuration just in case the interrupt handler gets
@@ -350,7 +332,7 @@ orinoco_cs_config(dev_link_t *link)
350 * card and host interface into "Memory and IO" mode. 332 * card and host interface into "Memory and IO" mode.
351 */ 333 */
352 CS_CHECK(RequestConfiguration, 334 CS_CHECK(RequestConfiguration,
353 pcmcia_request_configuration(link->handle, &link->conf)); 335 pcmcia_request_configuration(link, &link->conf));
354 336
355 /* Ok, we have the configuration, prepare to register the netdev */ 337 /* Ok, we have the configuration, prepare to register the netdev */
356 dev->base_addr = link->io.BasePort1; 338 dev->base_addr = link->io.BasePort1;
@@ -358,7 +340,7 @@ orinoco_cs_config(dev_link_t *link)
358 SET_MODULE_OWNER(dev); 340 SET_MODULE_OWNER(dev);
359 card->node.major = card->node.minor = 0; 341 card->node.major = card->node.minor = 0;
360 342
361 SET_NETDEV_DEV(dev, &handle_to_dev(handle)); 343 SET_NETDEV_DEV(dev, &handle_to_dev(link));
362 /* Tell the stack we exist */ 344 /* Tell the stack we exist */
363 if (register_netdev(dev) != 0) { 345 if (register_netdev(dev) != 0) {
364 printk(KERN_ERR PFX "register_netdev() failed\n"); 346 printk(KERN_ERR PFX "register_netdev() failed\n");
@@ -366,20 +348,18 @@ orinoco_cs_config(dev_link_t *link)
366 } 348 }
367 349
368 /* At this point, the dev_node_t structure(s) needs to be 350 /* At this point, the dev_node_t structure(s) needs to be
369 * initialized and arranged in a linked list at link->dev. */ 351 * initialized and arranged in a linked list at link->dev_node. */
370 strcpy(card->node.dev_name, dev->name); 352 strcpy(card->node.dev_name, dev->name);
371 link->dev = &card->node; /* link->dev being non-NULL is also 353 link->dev_node = &card->node; /* link->dev_node being non-NULL is also
372 used to indicate that the 354 used to indicate that the
373 net_device has been registered */ 355 net_device has been registered */
374 link->state &= ~DEV_CONFIG_PENDING;
375 356
376 /* Finally, report what we've done */ 357 /* Finally, report what we've done */
377 printk(KERN_DEBUG "%s: index 0x%02x: Vcc %d.%d", 358 printk(KERN_DEBUG "%s: index 0x%02x: ",
378 dev->name, link->conf.ConfigIndex, 359 dev->name, link->conf.ConfigIndex);
379 link->conf.Vcc / 10, link->conf.Vcc % 10); 360 if (link->conf.Vpp)
380 if (link->conf.Vpp1) 361 printk(", Vpp %d.%d", link->conf.Vpp / 10,
381 printk(", Vpp %d.%d", link->conf.Vpp1 / 10, 362 link->conf.Vpp % 10);
382 link->conf.Vpp1 % 10);
383 printk(", irq %d", link->irq.AssignedIRQ); 363 printk(", irq %d", link->irq.AssignedIRQ);
384 if (link->io.NumPorts1) 364 if (link->io.NumPorts1)
385 printk(", io 0x%04x-0x%04x", link->io.BasePort1, 365 printk(", io 0x%04x-0x%04x", link->io.BasePort1,
@@ -389,13 +369,14 @@ orinoco_cs_config(dev_link_t *link)
389 link->io.BasePort2 + link->io.NumPorts2 - 1); 369 link->io.BasePort2 + link->io.NumPorts2 - 1);
390 printk("\n"); 370 printk("\n");
391 371
392 return; 372 return 0;
393 373
394 cs_failed: 374 cs_failed:
395 cs_error(link->handle, last_fn, last_ret); 375 cs_error(link, last_fn, last_ret);
396 376
397 failed: 377 failed:
398 orinoco_cs_release(link); 378 orinoco_cs_release(link);
379 return -ENODEV;
399} /* orinoco_cs_config */ 380} /* orinoco_cs_config */
400 381
401/* 382/*
@@ -404,7 +385,7 @@ orinoco_cs_config(dev_link_t *link)
404 * still open, this will be postponed until it is closed. 385 * still open, this will be postponed until it is closed.
405 */ 386 */
406static void 387static void
407orinoco_cs_release(dev_link_t *link) 388orinoco_cs_release(struct pcmcia_device *link)
408{ 389{
409 struct net_device *dev = link->priv; 390 struct net_device *dev = link->priv;
410 struct orinoco_private *priv = netdev_priv(dev); 391 struct orinoco_private *priv = netdev_priv(dev);
@@ -416,88 +397,68 @@ orinoco_cs_release(dev_link_t *link)
416 priv->hw_unavailable++; 397 priv->hw_unavailable++;
417 spin_unlock_irqrestore(&priv->lock, flags); 398 spin_unlock_irqrestore(&priv->lock, flags);
418 399
419 /* Don't bother checking to see if these succeed or not */ 400 pcmcia_disable_device(link);
420 pcmcia_release_configuration(link->handle);
421 if (link->io.NumPorts1)
422 pcmcia_release_io(link->handle, &link->io);
423 if (link->irq.AssignedIRQ)
424 pcmcia_release_irq(link->handle, &link->irq);
425 link->state &= ~DEV_CONFIG;
426 if (priv->hw.iobase) 401 if (priv->hw.iobase)
427 ioport_unmap(priv->hw.iobase); 402 ioport_unmap(priv->hw.iobase);
428} /* orinoco_cs_release */ 403} /* orinoco_cs_release */
429 404
430static int orinoco_cs_suspend(struct pcmcia_device *p_dev) 405static int orinoco_cs_suspend(struct pcmcia_device *link)
431{ 406{
432 dev_link_t *link = dev_to_instance(p_dev);
433 struct net_device *dev = link->priv; 407 struct net_device *dev = link->priv;
434 struct orinoco_private *priv = netdev_priv(dev); 408 struct orinoco_private *priv = netdev_priv(dev);
435 struct orinoco_pccard *card = priv->card; 409 struct orinoco_pccard *card = priv->card;
436 int err = 0; 410 int err = 0;
437 unsigned long flags; 411 unsigned long flags;
438 412
439 link->state |= DEV_SUSPEND; 413 /* This is probably racy, but I can't think of
440 if (link->state & DEV_CONFIG) { 414 a better way, short of rewriting the PCMCIA
441 /* This is probably racy, but I can't think of 415 layer to not suck :-( */
442 a better way, short of rewriting the PCMCIA 416 if (! test_bit(0, &card->hard_reset_in_progress)) {
443 layer to not suck :-( */ 417 spin_lock_irqsave(&priv->lock, flags);
444 if (! test_bit(0, &card->hard_reset_in_progress)) {
445 spin_lock_irqsave(&priv->lock, flags);
446 418
447 err = __orinoco_down(dev); 419 err = __orinoco_down(dev);
448 if (err) 420 if (err)
449 printk(KERN_WARNING "%s: Error %d downing interface\n", 421 printk(KERN_WARNING "%s: Error %d downing interface\n",
450 dev->name, err); 422 dev->name, err);
451 423
452 netif_device_detach(dev); 424 netif_device_detach(dev);
453 priv->hw_unavailable++; 425 priv->hw_unavailable++;
454 426
455 spin_unlock_irqrestore(&priv->lock, flags); 427 spin_unlock_irqrestore(&priv->lock, flags);
456 }
457
458 pcmcia_release_configuration(link->handle);
459 } 428 }
460 429
461 return 0; 430 return 0;
462} 431}
463 432
464static int orinoco_cs_resume(struct pcmcia_device *p_dev) 433static int orinoco_cs_resume(struct pcmcia_device *link)
465{ 434{
466 dev_link_t *link = dev_to_instance(p_dev);
467 struct net_device *dev = link->priv; 435 struct net_device *dev = link->priv;
468 struct orinoco_private *priv = netdev_priv(dev); 436 struct orinoco_private *priv = netdev_priv(dev);
469 struct orinoco_pccard *card = priv->card; 437 struct orinoco_pccard *card = priv->card;
470 int err = 0; 438 int err = 0;
471 unsigned long flags; 439 unsigned long flags;
472 440
473 link->state &= ~DEV_SUSPEND; 441 if (! test_bit(0, &card->hard_reset_in_progress)) {
474 if (link->state & DEV_CONFIG) { 442 err = orinoco_reinit_firmware(dev);
475 /* FIXME: should we double check that this is 443 if (err) {
476 * the same card as we had before */ 444 printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
477 pcmcia_request_configuration(link->handle, &link->conf); 445 dev->name, err);
478 446 return -EIO;
479 if (! test_bit(0, &card->hard_reset_in_progress)) { 447 }
480 err = orinoco_reinit_firmware(dev);
481 if (err) {
482 printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
483 dev->name, err);
484 return -EIO;
485 }
486
487 spin_lock_irqsave(&priv->lock, flags);
488 448
489 netif_device_attach(dev); 449 spin_lock_irqsave(&priv->lock, flags);
490 priv->hw_unavailable--;
491 450
492 if (priv->open && ! priv->hw_unavailable) { 451 netif_device_attach(dev);
493 err = __orinoco_up(dev); 452 priv->hw_unavailable--;
494 if (err)
495 printk(KERN_ERR "%s: Error %d restarting card\n",
496 dev->name, err);
497 }
498 453
499 spin_unlock_irqrestore(&priv->lock, flags); 454 if (priv->open && ! priv->hw_unavailable) {
455 err = __orinoco_up(dev);
456 if (err)
457 printk(KERN_ERR "%s: Error %d restarting card\n",
458 dev->name, err);
500 } 459 }
460
461 spin_unlock_irqrestore(&priv->lock, flags);
501 } 462 }
502 463
503 return 0; 464 return 0;
@@ -604,7 +565,7 @@ static struct pcmcia_driver orinoco_driver = {
604 .drv = { 565 .drv = {
605 .name = DRIVER_NAME, 566 .name = DRIVER_NAME,
606 }, 567 },
607 .probe = orinoco_cs_attach, 568 .probe = orinoco_cs_probe,
608 .remove = orinoco_cs_detach, 569 .remove = orinoco_cs_detach,
609 .id_table = orinoco_cs_ids, 570 .id_table = orinoco_cs_ids,
610 .suspend = orinoco_cs_suspend, 571 .suspend = orinoco_cs_suspend,