aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/hostap/hostap_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/hostap/hostap_cs.c')
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c198
1 files changed, 79 insertions, 119 deletions
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index d335b250923a..55bed923fbe9 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -42,7 +42,7 @@ MODULE_PARM_DESC(ignore_cis_vcc, "Ignore broken CIS VCC entry");
42/* struct local_info::hw_priv */ 42/* struct local_info::hw_priv */
43struct hostap_cs_priv { 43struct hostap_cs_priv {
44 dev_node_t node; 44 dev_node_t node;
45 dev_link_t *link; 45 struct pcmcia_device *link;
46 int sandisk_connectplus; 46 int sandisk_connectplus;
47}; 47};
48 48
@@ -204,15 +204,13 @@ static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len)
204 204
205static void prism2_detach(struct pcmcia_device *p_dev); 205static void prism2_detach(struct pcmcia_device *p_dev);
206static void prism2_release(u_long arg); 206static void prism2_release(u_long arg);
207static int prism2_config(dev_link_t *link); 207static int prism2_config(struct pcmcia_device *link);
208 208
209 209
210static int prism2_pccard_card_present(local_info_t *local) 210static int prism2_pccard_card_present(local_info_t *local)
211{ 211{
212 struct hostap_cs_priv *hw_priv = local->hw_priv; 212 struct hostap_cs_priv *hw_priv = local->hw_priv;
213 if (hw_priv != NULL && hw_priv->link != NULL && 213 if (hw_priv != NULL && hw_priv->link != NULL && pcmcia_dev_present(hw_priv->link))
214 ((hw_priv->link->state & (DEV_PRESENT | DEV_CONFIG)) ==
215 (DEV_PRESENT | DEV_CONFIG)))
216 return 1; 214 return 1;
217 return 0; 215 return 0;
218} 216}
@@ -237,7 +235,7 @@ static void sandisk_set_iobase(local_info_t *local)
237 reg.Action = CS_WRITE; 235 reg.Action = CS_WRITE;
238 reg.Offset = 0x10; /* 0x3f0 IO base 1 */ 236 reg.Offset = 0x10; /* 0x3f0 IO base 1 */
239 reg.Value = hw_priv->link->io.BasePort1 & 0x00ff; 237 reg.Value = hw_priv->link->io.BasePort1 & 0x00ff;
240 res = pcmcia_access_configuration_register(hw_priv->link->handle, 238 res = pcmcia_access_configuration_register(hw_priv->link,
241 &reg); 239 &reg);
242 if (res != CS_SUCCESS) { 240 if (res != CS_SUCCESS) {
243 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -" 241 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 0 -"
@@ -249,7 +247,7 @@ static void sandisk_set_iobase(local_info_t *local)
249 reg.Action = CS_WRITE; 247 reg.Action = CS_WRITE;
250 reg.Offset = 0x12; /* 0x3f2 IO base 2 */ 248 reg.Offset = 0x12; /* 0x3f2 IO base 2 */
251 reg.Value = (hw_priv->link->io.BasePort1 & 0xff00) >> 8; 249 reg.Value = (hw_priv->link->io.BasePort1 & 0xff00) >> 8;
252 res = pcmcia_access_configuration_register(hw_priv->link->handle, 250 res = pcmcia_access_configuration_register(hw_priv->link,
253 &reg); 251 &reg);
254 if (res != CS_SUCCESS) { 252 if (res != CS_SUCCESS) {
255 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -" 253 printk(KERN_DEBUG "Prism3 SanDisk - failed to set I/O base 1 -"
@@ -301,9 +299,9 @@ static int sandisk_enable_wireless(struct net_device *dev)
301 tuple.TupleData = buf; 299 tuple.TupleData = buf;
302 tuple.TupleDataMax = sizeof(buf); 300 tuple.TupleDataMax = sizeof(buf);
303 tuple.TupleOffset = 0; 301 tuple.TupleOffset = 0;
304 if (pcmcia_get_first_tuple(hw_priv->link->handle, &tuple) || 302 if (pcmcia_get_first_tuple(hw_priv->link, &tuple) ||
305 pcmcia_get_tuple_data(hw_priv->link->handle, &tuple) || 303 pcmcia_get_tuple_data(hw_priv->link, &tuple) ||
306 pcmcia_parse_tuple(hw_priv->link->handle, &tuple, parse) || 304 pcmcia_parse_tuple(hw_priv->link, &tuple, parse) ||
307 parse->manfid.manf != 0xd601 || parse->manfid.card != 0x0101) { 305 parse->manfid.manf != 0xd601 || parse->manfid.card != 0x0101) {
308 /* No SanDisk manfid found */ 306 /* No SanDisk manfid found */
309 ret = -ENODEV; 307 ret = -ENODEV;
@@ -311,9 +309,9 @@ static int sandisk_enable_wireless(struct net_device *dev)
311 } 309 }
312 310
313 tuple.DesiredTuple = CISTPL_LONGLINK_MFC; 311 tuple.DesiredTuple = CISTPL_LONGLINK_MFC;
314 if (pcmcia_get_first_tuple(hw_priv->link->handle, &tuple) || 312 if (pcmcia_get_first_tuple(hw_priv->link, &tuple) ||
315 pcmcia_get_tuple_data(hw_priv->link->handle, &tuple) || 313 pcmcia_get_tuple_data(hw_priv->link, &tuple) ||
316 pcmcia_parse_tuple(hw_priv->link->handle, &tuple, parse) || 314 pcmcia_parse_tuple(hw_priv->link, &tuple, parse) ||
317 parse->longlink_mfc.nfn < 2) { 315 parse->longlink_mfc.nfn < 2) {
318 /* No multi-function links found */ 316 /* No multi-function links found */
319 ret = -ENODEV; 317 ret = -ENODEV;
@@ -328,7 +326,7 @@ static int sandisk_enable_wireless(struct net_device *dev)
328 reg.Action = CS_WRITE; 326 reg.Action = CS_WRITE;
329 reg.Offset = CISREG_COR; 327 reg.Offset = CISREG_COR;
330 reg.Value = COR_SOFT_RESET; 328 reg.Value = COR_SOFT_RESET;
331 res = pcmcia_access_configuration_register(hw_priv->link->handle, 329 res = pcmcia_access_configuration_register(hw_priv->link,
332 &reg); 330 &reg);
333 if (res != CS_SUCCESS) { 331 if (res != CS_SUCCESS) {
334 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n", 332 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
@@ -345,7 +343,7 @@ static int sandisk_enable_wireless(struct net_device *dev)
345 * will be enabled during the first cor_sreset call. 343 * will be enabled during the first cor_sreset call.
346 */ 344 */
347 reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA; 345 reg.Value = COR_LEVEL_REQ | 0x8 | COR_ADDR_DECODE | COR_FUNC_ENA;
348 res = pcmcia_access_configuration_register(hw_priv->link->handle, 346 res = pcmcia_access_configuration_register(hw_priv->link,
349 &reg); 347 &reg);
350 if (res != CS_SUCCESS) { 348 if (res != CS_SUCCESS) {
351 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n", 349 printk(KERN_DEBUG "%s: SanDisk - COR sreset failed (%d)\n",
@@ -380,7 +378,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
380 reg.Action = CS_READ; 378 reg.Action = CS_READ;
381 reg.Offset = CISREG_COR; 379 reg.Offset = CISREG_COR;
382 reg.Value = 0; 380 reg.Value = 0;
383 res = pcmcia_access_configuration_register(hw_priv->link->handle, 381 res = pcmcia_access_configuration_register(hw_priv->link,
384 &reg); 382 &reg);
385 if (res != CS_SUCCESS) { 383 if (res != CS_SUCCESS) {
386 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n", 384 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 1 (%d)\n",
@@ -392,7 +390,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
392 390
393 reg.Action = CS_WRITE; 391 reg.Action = CS_WRITE;
394 reg.Value |= COR_SOFT_RESET; 392 reg.Value |= COR_SOFT_RESET;
395 res = pcmcia_access_configuration_register(hw_priv->link->handle, 393 res = pcmcia_access_configuration_register(hw_priv->link,
396 &reg); 394 &reg);
397 if (res != CS_SUCCESS) { 395 if (res != CS_SUCCESS) {
398 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n", 396 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 2 (%d)\n",
@@ -405,7 +403,7 @@ static void prism2_pccard_cor_sreset(local_info_t *local)
405 reg.Value &= ~COR_SOFT_RESET; 403 reg.Value &= ~COR_SOFT_RESET;
406 if (hw_priv->sandisk_connectplus) 404 if (hw_priv->sandisk_connectplus)
407 reg.Value |= COR_IREQ_ENA; 405 reg.Value |= COR_IREQ_ENA;
408 res = pcmcia_access_configuration_register(hw_priv->link->handle, 406 res = pcmcia_access_configuration_register(hw_priv->link,
409 &reg); 407 &reg);
410 if (res != CS_SUCCESS) { 408 if (res != CS_SUCCESS) {
411 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n", 409 printk(KERN_DEBUG "prism2_pccard_cor_sreset failed 3 (%d)\n",
@@ -439,7 +437,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
439 reg.Action = CS_READ; 437 reg.Action = CS_READ;
440 reg.Offset = CISREG_COR; 438 reg.Offset = CISREG_COR;
441 reg.Value = 0; 439 reg.Value = 0;
442 res = pcmcia_access_configuration_register(hw_priv->link->handle, 440 res = pcmcia_access_configuration_register(hw_priv->link,
443 &reg); 441 &reg);
444 if (res != CS_SUCCESS) { 442 if (res != CS_SUCCESS) {
445 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 " 443 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 1 "
@@ -452,7 +450,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
452 450
453 reg.Action = CS_WRITE; 451 reg.Action = CS_WRITE;
454 reg.Value |= COR_SOFT_RESET; 452 reg.Value |= COR_SOFT_RESET;
455 res = pcmcia_access_configuration_register(hw_priv->link->handle, 453 res = pcmcia_access_configuration_register(hw_priv->link,
456 &reg); 454 &reg);
457 if (res != CS_SUCCESS) { 455 if (res != CS_SUCCESS) {
458 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 " 456 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 2 "
@@ -466,7 +464,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
466 reg.Action = CS_WRITE; 464 reg.Action = CS_WRITE;
467 reg.Value = hcr; 465 reg.Value = hcr;
468 reg.Offset = CISREG_CCSR; 466 reg.Offset = CISREG_CCSR;
469 res = pcmcia_access_configuration_register(hw_priv->link->handle, 467 res = pcmcia_access_configuration_register(hw_priv->link,
470 &reg); 468 &reg);
471 if (res != CS_SUCCESS) { 469 if (res != CS_SUCCESS) {
472 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 " 470 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 3 "
@@ -478,7 +476,7 @@ static void prism2_pccard_genesis_reset(local_info_t *local, int hcr)
478 reg.Action = CS_WRITE; 476 reg.Action = CS_WRITE;
479 reg.Offset = CISREG_COR; 477 reg.Offset = CISREG_COR;
480 reg.Value = old_cor & ~COR_SOFT_RESET; 478 reg.Value = old_cor & ~COR_SOFT_RESET;
481 res = pcmcia_access_configuration_register(hw_priv->link->handle, 479 res = pcmcia_access_configuration_register(hw_priv->link,
482 &reg); 480 &reg);
483 if (res != CS_SUCCESS) { 481 if (res != CS_SUCCESS) {
484 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 " 482 printk(KERN_DEBUG "prism2_pccard_genesis_sreset failed 4 "
@@ -501,40 +499,27 @@ static struct prism2_helper_functions prism2_pccard_funcs =
501 499
502/* allocate local data and register with CardServices 500/* allocate local data and register with CardServices
503 * initialize dev_link structure, but do not configure the card yet */ 501 * initialize dev_link structure, but do not configure the card yet */
504static int prism2_attach(struct pcmcia_device *p_dev) 502static int hostap_cs_probe(struct pcmcia_device *p_dev)
505{ 503{
506 dev_link_t *link; 504 int ret;
507
508 link = kmalloc(sizeof(dev_link_t), GFP_KERNEL);
509 if (link == NULL)
510 return -ENOMEM;
511
512 memset(link, 0, sizeof(dev_link_t));
513 505
514 PDEBUG(DEBUG_HW, "%s: setting Vcc=33 (constant)\n", dev_info); 506 PDEBUG(DEBUG_HW, "%s: setting Vcc=33 (constant)\n", dev_info);
515 link->conf.Vcc = 33; 507 p_dev->conf.IntType = INT_MEMORY_AND_IO;
516 link->conf.IntType = INT_MEMORY_AND_IO;
517
518 link->handle = p_dev;
519 p_dev->instance = link;
520 508
521 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 509 ret = prism2_config(p_dev);
522 if (prism2_config(link)) 510 if (ret) {
523 PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n"); 511 PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n");
512 }
524 513
525 return 0; 514 return ret;
526} 515}
527 516
528 517
529static void prism2_detach(struct pcmcia_device *p_dev) 518static void prism2_detach(struct pcmcia_device *link)
530{ 519{
531 dev_link_t *link = dev_to_instance(p_dev);
532
533 PDEBUG(DEBUG_FLOW, "prism2_detach\n"); 520 PDEBUG(DEBUG_FLOW, "prism2_detach\n");
534 521
535 if (link->state & DEV_CONFIG) { 522 prism2_release((u_long)link);
536 prism2_release((u_long)link);
537 }
538 523
539 /* release net devices */ 524 /* release net devices */
540 if (link->priv) { 525 if (link->priv) {
@@ -547,7 +532,6 @@ static void prism2_detach(struct pcmcia_device *p_dev)
547 prism2_free_local_data(dev); 532 prism2_free_local_data(dev);
548 kfree(hw_priv); 533 kfree(hw_priv);
549 } 534 }
550 kfree(link);
551} 535}
552 536
553 537
@@ -558,7 +542,7 @@ do { last_fn = (fn); if ((last_ret = (ret)) != 0) goto cs_failed; } while (0)
558do { int ret = (retf); \ 542do { int ret = (retf); \
559if (ret != 0) { \ 543if (ret != 0) { \
560 PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", ret); \ 544 PDEBUG(DEBUG_EXTRA, "CardServices(" #fn ") returned %d\n", ret); \
561 cs_error(link->handle, fn, ret); \ 545 cs_error(link, fn, ret); \
562 goto next_entry; \ 546 goto next_entry; \
563} \ 547} \
564} while (0) 548} while (0)
@@ -566,7 +550,7 @@ if (ret != 0) { \
566 550
567/* run after a CARD_INSERTION event is received to configure the PCMCIA 551/* run after a CARD_INSERTION event is received to configure the PCMCIA
568 * socket and make the device available to the system */ 552 * socket and make the device available to the system */
569static int prism2_config(dev_link_t *link) 553static int prism2_config(struct pcmcia_device *link)
570{ 554{
571 struct net_device *dev; 555 struct net_device *dev;
572 struct hostap_interface *iface; 556 struct hostap_interface *iface;
@@ -595,27 +579,24 @@ static int prism2_config(dev_link_t *link)
595 tuple.TupleData = buf; 579 tuple.TupleData = buf;
596 tuple.TupleDataMax = sizeof(buf); 580 tuple.TupleDataMax = sizeof(buf);
597 tuple.TupleOffset = 0; 581 tuple.TupleOffset = 0;
598 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link->handle, &tuple)); 582 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
599 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link->handle, &tuple)); 583 CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));
600 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link->handle, &tuple, parse)); 584 CS_CHECK(ParseTuple, pcmcia_parse_tuple(link, &tuple, parse));
601 link->conf.ConfigBase = parse->config.base; 585 link->conf.ConfigBase = parse->config.base;
602 link->conf.Present = parse->config.rmask[0]; 586 link->conf.Present = parse->config.rmask[0];
603 587
604 CS_CHECK(GetConfigurationInfo, 588 CS_CHECK(GetConfigurationInfo,
605 pcmcia_get_configuration_info(link->handle, &conf)); 589 pcmcia_get_configuration_info(link, &conf));
606 PDEBUG(DEBUG_HW, "%s: %s Vcc=%d (from config)\n", dev_info,
607 ignore_cis_vcc ? "ignoring" : "setting", conf.Vcc);
608 link->conf.Vcc = conf.Vcc;
609 590
610 /* Look for an appropriate configuration table entry in the CIS */ 591 /* Look for an appropriate configuration table entry in the CIS */
611 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; 592 tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;
612 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link->handle, &tuple)); 593 CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));
613 for (;;) { 594 for (;;) {
614 cistpl_cftable_entry_t *cfg = &(parse->cftable_entry); 595 cistpl_cftable_entry_t *cfg = &(parse->cftable_entry);
615 CFG_CHECK2(GetTupleData, 596 CFG_CHECK2(GetTupleData,
616 pcmcia_get_tuple_data(link->handle, &tuple)); 597 pcmcia_get_tuple_data(link, &tuple));
617 CFG_CHECK2(ParseTuple, 598 CFG_CHECK2(ParseTuple,
618 pcmcia_parse_tuple(link->handle, &tuple, parse)); 599 pcmcia_parse_tuple(link, &tuple, parse));
619 600
620 if (cfg->flags & CISTPL_CFTABLE_DEFAULT) 601 if (cfg->flags & CISTPL_CFTABLE_DEFAULT)
621 dflt = *cfg; 602 dflt = *cfg;
@@ -650,10 +631,10 @@ static int prism2_config(dev_link_t *link)
650 } 631 }
651 632
652 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM)) 633 if (cfg->vpp1.present & (1 << CISTPL_POWER_VNOM))
653 link->conf.Vpp1 = link->conf.Vpp2 = 634 link->conf.Vpp =
654 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000; 635 cfg->vpp1.param[CISTPL_POWER_VNOM] / 10000;
655 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM)) 636 else if (dflt.vpp1.present & (1 << CISTPL_POWER_VNOM))
656 link->conf.Vpp1 = link->conf.Vpp2 = 637 link->conf.Vpp =
657 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000; 638 dflt.vpp1.param[CISTPL_POWER_VNOM] / 10000;
658 639
659 /* Do we need to allocate an interrupt? */ 640 /* Do we need to allocate an interrupt? */
@@ -695,19 +676,19 @@ static int prism2_config(dev_link_t *link)
695 676
696 /* This reserves IO space but doesn't actually enable it */ 677 /* This reserves IO space but doesn't actually enable it */
697 CFG_CHECK2(RequestIO, 678 CFG_CHECK2(RequestIO,
698 pcmcia_request_io(link->handle, &link->io)); 679 pcmcia_request_io(link, &link->io));
699 680
700 /* This configuration table entry is OK */ 681 /* This configuration table entry is OK */
701 break; 682 break;
702 683
703 next_entry: 684 next_entry:
704 CS_CHECK(GetNextTuple, 685 CS_CHECK(GetNextTuple,
705 pcmcia_get_next_tuple(link->handle, &tuple)); 686 pcmcia_get_next_tuple(link, &tuple));
706 } 687 }
707 688
708 /* Need to allocate net_device before requesting IRQ handler */ 689 /* Need to allocate net_device before requesting IRQ handler */
709 dev = prism2_init_local_data(&prism2_pccard_funcs, 0, 690 dev = prism2_init_local_data(&prism2_pccard_funcs, 0,
710 &handle_to_dev(link->handle)); 691 &handle_to_dev(link));
711 if (dev == NULL) 692 if (dev == NULL)
712 goto failed; 693 goto failed;
713 link->priv = dev; 694 link->priv = dev;
@@ -717,7 +698,7 @@ static int prism2_config(dev_link_t *link)
717 local->hw_priv = hw_priv; 698 local->hw_priv = hw_priv;
718 hw_priv->link = link; 699 hw_priv->link = link;
719 strcpy(hw_priv->node.dev_name, dev->name); 700 strcpy(hw_priv->node.dev_name, dev->name);
720 link->dev = &hw_priv->node; 701 link->dev_node = &hw_priv->node;
721 702
722 /* 703 /*
723 * Allocate an interrupt line. Note that this does not assign a 704 * Allocate an interrupt line. Note that this does not assign a
@@ -730,7 +711,7 @@ static int prism2_config(dev_link_t *link)
730 link->irq.Handler = prism2_interrupt; 711 link->irq.Handler = prism2_interrupt;
731 link->irq.Instance = dev; 712 link->irq.Instance = dev;
732 CS_CHECK(RequestIRQ, 713 CS_CHECK(RequestIRQ,
733 pcmcia_request_irq(link->handle, &link->irq)); 714 pcmcia_request_irq(link, &link->irq));
734 } 715 }
735 716
736 /* 717 /*
@@ -739,18 +720,17 @@ static int prism2_config(dev_link_t *link)
739 * card and host interface into "Memory and IO" mode. 720 * card and host interface into "Memory and IO" mode.
740 */ 721 */
741 CS_CHECK(RequestConfiguration, 722 CS_CHECK(RequestConfiguration,
742 pcmcia_request_configuration(link->handle, &link->conf)); 723 pcmcia_request_configuration(link, &link->conf));
743 724
744 dev->irq = link->irq.AssignedIRQ; 725 dev->irq = link->irq.AssignedIRQ;
745 dev->base_addr = link->io.BasePort1; 726 dev->base_addr = link->io.BasePort1;
746 727
747 /* Finally, report what we've done */ 728 /* Finally, report what we've done */
748 printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", 729 printk(KERN_INFO "%s: index 0x%02x: ",
749 dev_info, link->conf.ConfigIndex, 730 dev_info, link->conf.ConfigIndex);
750 link->conf.Vcc / 10, link->conf.Vcc % 10); 731 if (link->conf.Vpp)
751 if (link->conf.Vpp1) 732 printk(", Vpp %d.%d", link->conf.Vpp / 10,
752 printk(", Vpp %d.%d", link->conf.Vpp1 / 10, 733 link->conf.Vpp % 10);
753 link->conf.Vpp1 % 10);
754 if (link->conf.Attributes & CONF_ENABLE_IRQ) 734 if (link->conf.Attributes & CONF_ENABLE_IRQ)
755 printk(", irq %d", link->irq.AssignedIRQ); 735 printk(", irq %d", link->irq.AssignedIRQ);
756 if (link->io.NumPorts1) 736 if (link->io.NumPorts1)
@@ -761,9 +741,6 @@ static int prism2_config(dev_link_t *link)
761 link->io.BasePort2+link->io.NumPorts2-1); 741 link->io.BasePort2+link->io.NumPorts2-1);
762 printk("\n"); 742 printk("\n");
763 743
764 link->state |= DEV_CONFIG;
765 link->state &= ~DEV_CONFIG_PENDING;
766
767 local->shutdown = 0; 744 local->shutdown = 0;
768 745
769 sandisk_enable_wireless(dev); 746 sandisk_enable_wireless(dev);
@@ -778,7 +755,7 @@ static int prism2_config(dev_link_t *link)
778 return ret; 755 return ret;
779 756
780 cs_failed: 757 cs_failed:
781 cs_error(link->handle, last_fn, last_ret); 758 cs_error(link, last_fn, last_ret);
782 759
783 failed: 760 failed:
784 kfree(parse); 761 kfree(parse);
@@ -790,7 +767,7 @@ static int prism2_config(dev_link_t *link)
790 767
791static void prism2_release(u_long arg) 768static void prism2_release(u_long arg)
792{ 769{
793 dev_link_t *link = (dev_link_t *)arg; 770 struct pcmcia_device *link = (struct pcmcia_device *)arg;
794 771
795 PDEBUG(DEBUG_FLOW, "prism2_release\n"); 772 PDEBUG(DEBUG_FLOW, "prism2_release\n");
796 773
@@ -799,71 +776,54 @@ static void prism2_release(u_long arg)
799 struct hostap_interface *iface; 776 struct hostap_interface *iface;
800 777
801 iface = netdev_priv(dev); 778 iface = netdev_priv(dev);
802 if (link->state & DEV_CONFIG) 779 prism2_hw_shutdown(dev, 0);
803 prism2_hw_shutdown(dev, 0);
804 iface->local->shutdown = 1; 780 iface->local->shutdown = 1;
805 } 781 }
806 782
807 if (link->win) 783 pcmcia_disable_device(link);
808 pcmcia_release_window(link->win);
809 pcmcia_release_configuration(link->handle);
810 if (link->io.NumPorts1)
811 pcmcia_release_io(link->handle, &link->io);
812 if (link->irq.AssignedIRQ)
813 pcmcia_release_irq(link->handle, &link->irq);
814
815 link->state &= ~DEV_CONFIG;
816
817 PDEBUG(DEBUG_FLOW, "release - done\n"); 784 PDEBUG(DEBUG_FLOW, "release - done\n");
818} 785}
819 786
820static int hostap_cs_suspend(struct pcmcia_device *p_dev) 787static int hostap_cs_suspend(struct pcmcia_device *link)
821{ 788{
822 dev_link_t *link = dev_to_instance(p_dev);
823 struct net_device *dev = (struct net_device *) link->priv; 789 struct net_device *dev = (struct net_device *) link->priv;
824 int dev_open = 0; 790 int dev_open = 0;
791 struct hostap_interface *iface = NULL;
825 792
826 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info); 793 if (dev)
827 794 iface = netdev_priv(dev);
828 link->state |= DEV_SUSPEND;
829 795
830 if (link->state & DEV_CONFIG) { 796 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
831 struct hostap_interface *iface = netdev_priv(dev); 797 if (iface && iface->local)
832 if (iface && iface->local) 798 dev_open = iface->local->num_dev_open > 0;
833 dev_open = iface->local->num_dev_open > 0; 799 if (dev_open) {
834 if (dev_open) { 800 netif_stop_queue(dev);
835 netif_stop_queue(dev); 801 netif_device_detach(dev);
836 netif_device_detach(dev);
837 }
838 prism2_suspend(dev);
839 pcmcia_release_configuration(link->handle);
840 } 802 }
803 prism2_suspend(dev);
841 804
842 return 0; 805 return 0;
843} 806}
844 807
845static int hostap_cs_resume(struct pcmcia_device *p_dev) 808static int hostap_cs_resume(struct pcmcia_device *link)
846{ 809{
847 dev_link_t *link = dev_to_instance(p_dev);
848 struct net_device *dev = (struct net_device *) link->priv; 810 struct net_device *dev = (struct net_device *) link->priv;
849 int dev_open = 0; 811 int dev_open = 0;
812 struct hostap_interface *iface = NULL;
850 813
851 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info); 814 if (dev)
815 iface = netdev_priv(dev);
852 816
853 link->state &= ~DEV_SUSPEND; 817 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
854 if (link->state & DEV_CONFIG) {
855 struct hostap_interface *iface = netdev_priv(dev);
856 if (iface && iface->local)
857 dev_open = iface->local->num_dev_open > 0;
858 818
859 pcmcia_request_configuration(link->handle, &link->conf); 819 if (iface && iface->local)
820 dev_open = iface->local->num_dev_open > 0;
860 821
861 prism2_hw_shutdown(dev, 1); 822 prism2_hw_shutdown(dev, 1);
862 prism2_hw_config(dev, dev_open ? 0 : 1); 823 prism2_hw_config(dev, dev_open ? 0 : 1);
863 if (dev_open) { 824 if (dev_open) {
864 netif_device_attach(dev); 825 netif_device_attach(dev);
865 netif_start_queue(dev); 826 netif_start_queue(dev);
866 }
867 } 827 }
868 828
869 return 0; 829 return 0;
@@ -930,7 +890,7 @@ static struct pcmcia_driver hostap_driver = {
930 .drv = { 890 .drv = {
931 .name = "hostap_cs", 891 .name = "hostap_cs",
932 }, 892 },
933 .probe = prism2_attach, 893 .probe = hostap_cs_probe,
934 .remove = prism2_detach, 894 .remove = prism2_detach,
935 .owner = THIS_MODULE, 895 .owner = THIS_MODULE,
936 .id_table = hostap_cs_ids, 896 .id_table = hostap_cs_ids,