aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net
diff options
context:
space:
mode:
authorDominik Brodowski <linux@dominikbrodowski.net>2005-11-14 15:21:18 -0500
committerDominik Brodowski <linux@dominikbrodowski.net>2006-01-05 17:59:02 -0500
commit98e4c28b7ec390c2dad6a4c69d69629c0f7e8b10 (patch)
treeb3d46f0643352e541d6a39e6da09059687cf713d /drivers/net
parent63e7ebd06402951bc8863ba5b7bc9b9f42044849 (diff)
[PATCH] pcmcia: new suspend core
Move the suspend and resume methods out of the event handler, and into special functions. Also use these functions for pre- and post-reset, as almost all drivers already do, and the remaining ones can easily be converted. Bugfix to include/pcmcia/ds.c Signed-off-by: Andrew Morton <akpm@osdl.org> Signed-off-by: Dominik Brodowski <linux@dominikbrodowski.net>
Diffstat (limited to 'drivers/net')
-rw-r--r--drivers/net/pcmcia/3c574_cs.c56
-rw-r--r--drivers/net/pcmcia/3c589_cs.c56
-rw-r--r--drivers/net/pcmcia/axnet_cs.c59
-rw-r--r--drivers/net/pcmcia/com20020_cs.c62
-rw-r--r--drivers/net/pcmcia/fmvj18x_cs.c57
-rw-r--r--drivers/net/pcmcia/ibmtr_cs.c59
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c57
-rw-r--r--drivers/net/pcmcia/pcnet_cs.c58
-rw-r--r--drivers/net/pcmcia/smc91c92_cs.c109
-rw-r--r--drivers/net/pcmcia/xirc2ps_cs.c61
-rw-r--r--drivers/net/wireless/airo_cs.c50
-rw-r--r--drivers/net/wireless/atmel_cs.c50
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c88
-rw-r--r--drivers/net/wireless/netwave_cs.c57
-rw-r--r--drivers/net/wireless/orinoco_cs.c145
-rw-r--r--drivers/net/wireless/ray_cs.c59
-rw-r--r--drivers/net/wireless/spectrum_cs.c96
-rw-r--r--drivers/net/wireless/wavelan_cs.c92
-rw-r--r--drivers/net/wireless/wl3501_cs.c61
19 files changed, 784 insertions, 548 deletions
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c
index 71fd41122c91..80414a77fe75 100644
--- a/drivers/net/pcmcia/3c574_cs.c
+++ b/drivers/net/pcmcia/3c574_cs.c
@@ -547,6 +547,38 @@ static void tc574_release(dev_link_t *link)
547 link->state &= ~DEV_CONFIG; 547 link->state &= ~DEV_CONFIG;
548} 548}
549 549
550static int tc574_suspend(struct pcmcia_device *p_dev)
551{
552 dev_link_t *link = dev_to_instance(p_dev);
553 struct net_device *dev = link->priv;
554
555 link->state |= DEV_SUSPEND;
556 if (link->state & DEV_CONFIG) {
557 if (link->open)
558 netif_device_detach(dev);
559 pcmcia_release_configuration(link->handle);
560 }
561
562 return 0;
563}
564
565static int tc574_resume(struct pcmcia_device *p_dev)
566{
567 dev_link_t *link = dev_to_instance(p_dev);
568 struct net_device *dev = link->priv;
569
570 link->state &= ~DEV_SUSPEND;
571 if (link->state & DEV_CONFIG) {
572 pcmcia_request_configuration(link->handle, &link->conf);
573 if (link->open) {
574 tc574_reset(dev);
575 netif_device_attach(dev);
576 }
577 }
578
579 return 0;
580}
581
550/* 582/*
551 The card status event handler. Mostly, this schedules other 583 The card status event handler. Mostly, this schedules other
552 stuff to run after an event is received. A CARD_REMOVAL event 584 stuff to run after an event is received. A CARD_REMOVAL event
@@ -572,28 +604,6 @@ static int tc574_event(event_t event, int priority,
572 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 604 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
573 tc574_config(link); 605 tc574_config(link);
574 break; 606 break;
575 case CS_EVENT_PM_SUSPEND:
576 link->state |= DEV_SUSPEND;
577 /* Fall through... */
578 case CS_EVENT_RESET_PHYSICAL:
579 if (link->state & DEV_CONFIG) {
580 if (link->open)
581 netif_device_detach(dev);
582 pcmcia_release_configuration(link->handle);
583 }
584 break;
585 case CS_EVENT_PM_RESUME:
586 link->state &= ~DEV_SUSPEND;
587 /* Fall through... */
588 case CS_EVENT_CARD_RESET:
589 if (link->state & DEV_CONFIG) {
590 pcmcia_request_configuration(link->handle, &link->conf);
591 if (link->open) {
592 tc574_reset(dev);
593 netif_device_attach(dev);
594 }
595 }
596 break;
597 } 607 }
598 return 0; 608 return 0;
599} /* tc574_event */ 609} /* tc574_event */
@@ -1296,6 +1306,8 @@ static struct pcmcia_driver tc574_driver = {
1296 .event = tc574_event, 1306 .event = tc574_event,
1297 .detach = tc574_detach, 1307 .detach = tc574_detach,
1298 .id_table = tc574_ids, 1308 .id_table = tc574_ids,
1309 .suspend = tc574_suspend,
1310 .resume = tc574_resume,
1299}; 1311};
1300 1312
1301static int __init init_tc574(void) 1313static int __init init_tc574(void)
diff --git a/drivers/net/pcmcia/3c589_cs.c b/drivers/net/pcmcia/3c589_cs.c
index d83fdd8c1943..bbda681ac102 100644
--- a/drivers/net/pcmcia/3c589_cs.c
+++ b/drivers/net/pcmcia/3c589_cs.c
@@ -421,6 +421,38 @@ static void tc589_release(dev_link_t *link)
421 link->state &= ~DEV_CONFIG; 421 link->state &= ~DEV_CONFIG;
422} 422}
423 423
424static int tc589_suspend(struct pcmcia_device *p_dev)
425{
426 dev_link_t *link = dev_to_instance(p_dev);
427 struct net_device *dev = link->priv;
428
429 link->state |= DEV_SUSPEND;
430 if (link->state & DEV_CONFIG) {
431 if (link->open)
432 netif_device_detach(dev);
433 pcmcia_release_configuration(link->handle);
434 }
435
436 return 0;
437}
438
439static int tc589_resume(struct pcmcia_device *p_dev)
440{
441 dev_link_t *link = dev_to_instance(p_dev);
442 struct net_device *dev = link->priv;
443
444 link->state &= ~DEV_SUSPEND;
445 if (link->state & DEV_CONFIG) {
446 pcmcia_request_configuration(link->handle, &link->conf);
447 if (link->open) {
448 tc589_reset(dev);
449 netif_device_attach(dev);
450 }
451 }
452
453 return 0;
454}
455
424/*====================================================================== 456/*======================================================================
425 457
426 The card status event handler. Mostly, this schedules other 458 The card status event handler. Mostly, this schedules other
@@ -448,28 +480,6 @@ static int tc589_event(event_t event, int priority,
448 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 480 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
449 tc589_config(link); 481 tc589_config(link);
450 break; 482 break;
451 case CS_EVENT_PM_SUSPEND:
452 link->state |= DEV_SUSPEND;
453 /* Fall through... */
454 case CS_EVENT_RESET_PHYSICAL:
455 if (link->state & DEV_CONFIG) {
456 if (link->open)
457 netif_device_detach(dev);
458 pcmcia_release_configuration(link->handle);
459 }
460 break;
461 case CS_EVENT_PM_RESUME:
462 link->state &= ~DEV_SUSPEND;
463 /* Fall through... */
464 case CS_EVENT_CARD_RESET:
465 if (link->state & DEV_CONFIG) {
466 pcmcia_request_configuration(link->handle, &link->conf);
467 if (link->open) {
468 tc589_reset(dev);
469 netif_device_attach(dev);
470 }
471 }
472 break;
473 } 483 }
474 return 0; 484 return 0;
475} /* tc589_event */ 485} /* tc589_event */
@@ -1071,6 +1081,8 @@ static struct pcmcia_driver tc589_driver = {
1071 .event = tc589_event, 1081 .event = tc589_event,
1072 .detach = tc589_detach, 1082 .detach = tc589_detach,
1073 .id_table = tc589_ids, 1083 .id_table = tc589_ids,
1084 .suspend = tc589_suspend,
1085 .resume = tc589_resume,
1074}; 1086};
1075 1087
1076static int __init init_tc589(void) 1088static int __init init_tc589(void)
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c
index 8bb4e85689ea..6c6b25265659 100644
--- a/drivers/net/pcmcia/axnet_cs.c
+++ b/drivers/net/pcmcia/axnet_cs.c
@@ -490,6 +490,40 @@ static void axnet_release(dev_link_t *link)
490 link->state &= ~DEV_CONFIG; 490 link->state &= ~DEV_CONFIG;
491} 491}
492 492
493static int axnet_suspend(struct pcmcia_device *p_dev)
494{
495 dev_link_t *link = dev_to_instance(p_dev);
496 struct net_device *dev = link->priv;
497
498 link->state |= DEV_SUSPEND;
499 if (link->state & DEV_CONFIG) {
500 if (link->open)
501 netif_device_detach(dev);
502 pcmcia_release_configuration(link->handle);
503 }
504
505 return 0;
506}
507
508static int axnet_resume(struct pcmcia_device *p_dev)
509{
510 dev_link_t *link = dev_to_instance(p_dev);
511 struct net_device *dev = link->priv;
512
513 link->state &= ~DEV_SUSPEND;
514 if (link->state & DEV_CONFIG) {
515 pcmcia_request_configuration(link->handle, &link->conf);
516 if (link->open) {
517 axnet_reset_8390(dev);
518 AX88190_init(dev, 1);
519 netif_device_attach(dev);
520 }
521 }
522
523 return 0;
524}
525
526
493/*====================================================================== 527/*======================================================================
494 528
495 The card status event handler. Mostly, this schedules other 529 The card status event handler. Mostly, this schedules other
@@ -517,29 +551,6 @@ static int axnet_event(event_t event, int priority,
517 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 551 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
518 axnet_config(link); 552 axnet_config(link);
519 break; 553 break;
520 case CS_EVENT_PM_SUSPEND:
521 link->state |= DEV_SUSPEND;
522 /* Fall through... */
523 case CS_EVENT_RESET_PHYSICAL:
524 if (link->state & DEV_CONFIG) {
525 if (link->open)
526 netif_device_detach(dev);
527 pcmcia_release_configuration(link->handle);
528 }
529 break;
530 case CS_EVENT_PM_RESUME:
531 link->state &= ~DEV_SUSPEND;
532 /* Fall through... */
533 case CS_EVENT_CARD_RESET:
534 if (link->state & DEV_CONFIG) {
535 pcmcia_request_configuration(link->handle, &link->conf);
536 if (link->open) {
537 axnet_reset_8390(dev);
538 AX88190_init(dev, 1);
539 netif_device_attach(dev);
540 }
541 }
542 break;
543 } 554 }
544 return 0; 555 return 0;
545} /* axnet_event */ 556} /* axnet_event */
@@ -881,6 +892,8 @@ static struct pcmcia_driver axnet_cs_driver = {
881 .event = axnet_event, 892 .event = axnet_event,
882 .detach = axnet_detach, 893 .detach = axnet_detach,
883 .id_table = axnet_ids, 894 .id_table = axnet_ids,
895 .suspend = axnet_suspend,
896 .resume = axnet_resume,
884}; 897};
885 898
886static int __init init_axnet_cs(void) 899static int __init init_axnet_cs(void)
diff --git a/drivers/net/pcmcia/com20020_cs.c b/drivers/net/pcmcia/com20020_cs.c
index b9355d9498a3..68612222de6e 100644
--- a/drivers/net/pcmcia/com20020_cs.c
+++ b/drivers/net/pcmcia/com20020_cs.c
@@ -421,6 +421,42 @@ static void com20020_release(dev_link_t *link)
421 link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING); 421 link->state &= ~(DEV_CONFIG | DEV_RELEASE_PENDING);
422} 422}
423 423
424static int com20020_suspend(struct pcmcia_device *p_dev)
425{
426 dev_link_t *link = dev_to_instance(p_dev);
427 com20020_dev_t *info = link->priv;
428 struct net_device *dev = info->dev;
429
430 link->state |= DEV_SUSPEND;
431 if (link->state & DEV_CONFIG) {
432 if (link->open) {
433 netif_device_detach(dev);
434 }
435 pcmcia_release_configuration(link->handle);
436 }
437
438 return 0;
439}
440
441static int com20020_resume(struct pcmcia_device *p_dev)
442{
443 dev_link_t *link = dev_to_instance(p_dev);
444 com20020_dev_t *info = link->priv;
445 struct net_device *dev = info->dev;
446
447 link->state &= ~DEV_SUSPEND;
448 if (link->state & DEV_CONFIG) {
449 pcmcia_request_configuration(link->handle, &link->conf);
450 if (link->open) {
451 int ioaddr = dev->base_addr;
452 struct arcnet_local *lp = dev->priv;
453 ARCRESET;
454 }
455 }
456
457 return 0;
458}
459
424/*====================================================================== 460/*======================================================================
425 461
426 The card status event handler. Mostly, this schedules other 462 The card status event handler. Mostly, this schedules other
@@ -449,30 +485,6 @@ static int com20020_event(event_t event, int priority,
449 link->state |= DEV_PRESENT; 485 link->state |= DEV_PRESENT;
450 com20020_config(link); 486 com20020_config(link);
451 break; 487 break;
452 case CS_EVENT_PM_SUSPEND:
453 link->state |= DEV_SUSPEND;
454 /* Fall through... */
455 case CS_EVENT_RESET_PHYSICAL:
456 if (link->state & DEV_CONFIG) {
457 if (link->open) {
458 netif_device_detach(dev);
459 }
460 pcmcia_release_configuration(link->handle);
461 }
462 break;
463 case CS_EVENT_PM_RESUME:
464 link->state &= ~DEV_SUSPEND;
465 /* Fall through... */
466 case CS_EVENT_CARD_RESET:
467 if (link->state & DEV_CONFIG) {
468 pcmcia_request_configuration(link->handle, &link->conf);
469 if (link->open) {
470 int ioaddr = dev->base_addr;
471 struct arcnet_local *lp = dev->priv;
472 ARCRESET;
473 }
474 }
475 break;
476 } 488 }
477 return 0; 489 return 0;
478} /* com20020_event */ 490} /* com20020_event */
@@ -492,6 +504,8 @@ static struct pcmcia_driver com20020_cs_driver = {
492 .event = com20020_event, 504 .event = com20020_event,
493 .detach = com20020_detach, 505 .detach = com20020_detach,
494 .id_table = com20020_ids, 506 .id_table = com20020_ids,
507 .suspend = com20020_suspend,
508 .resume = com20020_resume,
495}; 509};
496 510
497static int __init init_com20020_cs(void) 511static int __init init_com20020_cs(void)
diff --git a/drivers/net/pcmcia/fmvj18x_cs.c b/drivers/net/pcmcia/fmvj18x_cs.c
index 356f50909222..388ecade13de 100644
--- a/drivers/net/pcmcia/fmvj18x_cs.c
+++ b/drivers/net/pcmcia/fmvj18x_cs.c
@@ -713,6 +713,39 @@ static void fmvj18x_release(dev_link_t *link)
713 link->state &= ~DEV_CONFIG; 713 link->state &= ~DEV_CONFIG;
714} 714}
715 715
716static int fmvj18x_suspend(struct pcmcia_device *p_dev)
717{
718 dev_link_t *link = dev_to_instance(p_dev);
719 struct net_device *dev = link->priv;
720
721 link->state |= DEV_SUSPEND;
722 if (link->state & DEV_CONFIG) {
723 if (link->open)
724 netif_device_detach(dev);
725 pcmcia_release_configuration(link->handle);
726 }
727
728
729 return 0;
730}
731
732static int fmvj18x_resume(struct pcmcia_device *p_dev)
733{
734 dev_link_t *link = dev_to_instance(p_dev);
735 struct net_device *dev = link->priv;
736
737 link->state &= ~DEV_SUSPEND;
738 if (link->state & DEV_CONFIG) {
739 pcmcia_request_configuration(link->handle, &link->conf);
740 if (link->open) {
741 fjn_reset(dev);
742 netif_device_attach(dev);
743 }
744 }
745
746 return 0;
747}
748
716/*====================================================================*/ 749/*====================================================================*/
717 750
718static int fmvj18x_event(event_t event, int priority, 751static int fmvj18x_event(event_t event, int priority,
@@ -733,28 +766,6 @@ static int fmvj18x_event(event_t event, int priority,
733 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 766 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
734 fmvj18x_config(link); 767 fmvj18x_config(link);
735 break; 768 break;
736 case CS_EVENT_PM_SUSPEND:
737 link->state |= DEV_SUSPEND;
738 /* Fall through... */
739 case CS_EVENT_RESET_PHYSICAL:
740 if (link->state & DEV_CONFIG) {
741 if (link->open)
742 netif_device_detach(dev);
743 pcmcia_release_configuration(link->handle);
744 }
745 break;
746 case CS_EVENT_PM_RESUME:
747 link->state &= ~DEV_SUSPEND;
748 /* Fall through... */
749 case CS_EVENT_CARD_RESET:
750 if (link->state & DEV_CONFIG) {
751 pcmcia_request_configuration(link->handle, &link->conf);
752 if (link->open) {
753 fjn_reset(dev);
754 netif_device_attach(dev);
755 }
756 }
757 break;
758 } 769 }
759 return 0; 770 return 0;
760} /* fmvj18x_event */ 771} /* fmvj18x_event */
@@ -793,6 +804,8 @@ static struct pcmcia_driver fmvj18x_cs_driver = {
793 .event = fmvj18x_event, 804 .event = fmvj18x_event,
794 .detach = fmvj18x_detach, 805 .detach = fmvj18x_detach,
795 .id_table = fmvj18x_ids, 806 .id_table = fmvj18x_ids,
807 .suspend = fmvj18x_suspend,
808 .resume = fmvj18x_resume,
796}; 809};
797 810
798static int __init init_fmvj18x_cs(void) 811static int __init init_fmvj18x_cs(void)
diff --git a/drivers/net/pcmcia/ibmtr_cs.c b/drivers/net/pcmcia/ibmtr_cs.c
index b6c140eb9799..3a7218e51b73 100644
--- a/drivers/net/pcmcia/ibmtr_cs.c
+++ b/drivers/net/pcmcia/ibmtr_cs.c
@@ -401,6 +401,41 @@ static void ibmtr_release(dev_link_t *link)
401 link->state &= ~DEV_CONFIG; 401 link->state &= ~DEV_CONFIG;
402} 402}
403 403
404static int ibmtr_suspend(struct pcmcia_device *p_dev)
405{
406 dev_link_t *link = dev_to_instance(p_dev);
407 ibmtr_dev_t *info = link->priv;
408 struct net_device *dev = info->dev;
409
410 link->state |= DEV_SUSPEND;
411 if (link->state & DEV_CONFIG) {
412 if (link->open)
413 netif_device_detach(dev);
414 pcmcia_release_configuration(link->handle);
415 }
416
417 return 0;
418}
419
420static int ibmtr_resume(struct pcmcia_device *p_dev)
421{
422 dev_link_t *link = dev_to_instance(p_dev);
423 ibmtr_dev_t *info = link->priv;
424 struct net_device *dev = info->dev;
425
426 link->state &= ~DEV_SUSPEND;
427 if (link->state & DEV_CONFIG) {
428 pcmcia_request_configuration(link->handle, &link->conf);
429 if (link->open) {
430 ibmtr_probe(dev); /* really? */
431 netif_device_attach(dev);
432 }
433 }
434
435 return 0;
436}
437
438
404/*====================================================================== 439/*======================================================================
405 440
406 The card status event handler. Mostly, this schedules other 441 The card status event handler. Mostly, this schedules other
@@ -433,28 +468,6 @@ static int ibmtr_event(event_t event, int priority,
433 link->state |= DEV_PRESENT; 468 link->state |= DEV_PRESENT;
434 ibmtr_config(link); 469 ibmtr_config(link);
435 break; 470 break;
436 case CS_EVENT_PM_SUSPEND:
437 link->state |= DEV_SUSPEND;
438 /* Fall through... */
439 case CS_EVENT_RESET_PHYSICAL:
440 if (link->state & DEV_CONFIG) {
441 if (link->open)
442 netif_device_detach(dev);
443 pcmcia_release_configuration(link->handle);
444 }
445 break;
446 case CS_EVENT_PM_RESUME:
447 link->state &= ~DEV_SUSPEND;
448 /* Fall through... */
449 case CS_EVENT_CARD_RESET:
450 if (link->state & DEV_CONFIG) {
451 pcmcia_request_configuration(link->handle, &link->conf);
452 if (link->open) {
453 ibmtr_probe(dev); /* really? */
454 netif_device_attach(dev);
455 }
456 }
457 break;
458 } 471 }
459 return 0; 472 return 0;
460} /* ibmtr_event */ 473} /* ibmtr_event */
@@ -518,6 +531,8 @@ static struct pcmcia_driver ibmtr_cs_driver = {
518 .event = ibmtr_event, 531 .event = ibmtr_event,
519 .detach = ibmtr_detach, 532 .detach = ibmtr_detach,
520 .id_table = ibmtr_ids, 533 .id_table = ibmtr_ids,
534 .suspend = ibmtr_suspend,
535 .resume = ibmtr_resume,
521}; 536};
522 537
523static int __init init_ibmtr_cs(void) 538static int __init init_ibmtr_cs(void)
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c
index 980d7e5d66cb..fa4921f8b9fc 100644
--- a/drivers/net/pcmcia/nmclan_cs.c
+++ b/drivers/net/pcmcia/nmclan_cs.c
@@ -801,6 +801,39 @@ static void nmclan_release(dev_link_t *link)
801 link->state &= ~DEV_CONFIG; 801 link->state &= ~DEV_CONFIG;
802} 802}
803 803
804static int nmclan_suspend(struct pcmcia_device *p_dev)
805{
806 dev_link_t *link = dev_to_instance(p_dev);
807 struct net_device *dev = link->priv;
808
809 link->state |= DEV_SUSPEND;
810 if (link->state & DEV_CONFIG) {
811 if (link->open)
812 netif_device_detach(dev);
813 pcmcia_release_configuration(link->handle);
814 }
815
816
817 return 0;
818}
819
820static int nmclan_resume(struct pcmcia_device *p_dev)
821{
822 dev_link_t *link = dev_to_instance(p_dev);
823 struct net_device *dev = link->priv;
824
825 link->state &= ~DEV_SUSPEND;
826 if (link->state & DEV_CONFIG) {
827 pcmcia_request_configuration(link->handle, &link->conf);
828 if (link->open) {
829 nmclan_reset(dev);
830 netif_device_attach(dev);
831 }
832 }
833
834 return 0;
835}
836
804/* ---------------------------------------------------------------------------- 837/* ----------------------------------------------------------------------------
805nmclan_event 838nmclan_event
806 The card status event handler. Mostly, this schedules other 839 The card status event handler. Mostly, this schedules other
@@ -826,28 +859,6 @@ static int nmclan_event(event_t event, int priority,
826 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 859 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
827 nmclan_config(link); 860 nmclan_config(link);
828 break; 861 break;
829 case CS_EVENT_PM_SUSPEND:
830 link->state |= DEV_SUSPEND;
831 /* Fall through... */
832 case CS_EVENT_RESET_PHYSICAL:
833 if (link->state & DEV_CONFIG) {
834 if (link->open)
835 netif_device_detach(dev);
836 pcmcia_release_configuration(link->handle);
837 }
838 break;
839 case CS_EVENT_PM_RESUME:
840 link->state &= ~DEV_SUSPEND;
841 /* Fall through... */
842 case CS_EVENT_CARD_RESET:
843 if (link->state & DEV_CONFIG) {
844 pcmcia_request_configuration(link->handle, &link->conf);
845 if (link->open) {
846 nmclan_reset(dev);
847 netif_device_attach(dev);
848 }
849 }
850 break;
851 case CS_EVENT_RESET_REQUEST: 862 case CS_EVENT_RESET_REQUEST:
852 return 1; 863 return 1;
853 break; 864 break;
@@ -1685,6 +1696,8 @@ static struct pcmcia_driver nmclan_cs_driver = {
1685 .event = nmclan_event, 1696 .event = nmclan_event,
1686 .detach = nmclan_detach, 1697 .detach = nmclan_detach,
1687 .id_table = nmclan_ids, 1698 .id_table = nmclan_ids,
1699 .suspend = nmclan_suspend,
1700 .resume = nmclan_resume,
1688}; 1701};
1689 1702
1690static int __init init_nmclan_cs(void) 1703static int __init init_nmclan_cs(void)
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 818c185d6438..7db4d6f3db45 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -780,6 +780,39 @@ static void pcnet_release(dev_link_t *link)
780 780
781======================================================================*/ 781======================================================================*/
782 782
783static int pcnet_suspend(struct pcmcia_device *p_dev)
784{
785 dev_link_t *link = dev_to_instance(p_dev);
786 struct net_device *dev = link->priv;
787
788 link->state |= DEV_SUSPEND;
789 if (link->state & DEV_CONFIG) {
790 if (link->open)
791 netif_device_detach(dev);
792 pcmcia_release_configuration(link->handle);
793 }
794
795 return 0;
796}
797
798static int pcnet_resume(struct pcmcia_device *p_dev)
799{
800 dev_link_t *link = dev_to_instance(p_dev);
801 struct net_device *dev = link->priv;
802
803 link->state &= ~DEV_SUSPEND;
804 if (link->state & DEV_CONFIG) {
805 pcmcia_request_configuration(link->handle, &link->conf);
806 if (link->open) {
807 pcnet_reset_8390(dev);
808 NS8390_init(dev, 1);
809 netif_device_attach(dev);
810 }
811 }
812
813 return 0;
814}
815
783static int pcnet_event(event_t event, int priority, 816static int pcnet_event(event_t event, int priority,
784 event_callback_args_t *args) 817 event_callback_args_t *args)
785{ 818{
@@ -798,29 +831,6 @@ static int pcnet_event(event_t event, int priority,
798 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 831 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
799 pcnet_config(link); 832 pcnet_config(link);
800 break; 833 break;
801 case CS_EVENT_PM_SUSPEND:
802 link->state |= DEV_SUSPEND;
803 /* Fall through... */
804 case CS_EVENT_RESET_PHYSICAL:
805 if (link->state & DEV_CONFIG) {
806 if (link->open)
807 netif_device_detach(dev);
808 pcmcia_release_configuration(link->handle);
809 }
810 break;
811 case CS_EVENT_PM_RESUME:
812 link->state &= ~DEV_SUSPEND;
813 /* Fall through... */
814 case CS_EVENT_CARD_RESET:
815 if (link->state & DEV_CONFIG) {
816 pcmcia_request_configuration(link->handle, &link->conf);
817 if (link->open) {
818 pcnet_reset_8390(dev);
819 NS8390_init(dev, 1);
820 netif_device_attach(dev);
821 }
822 }
823 break;
824 } 834 }
825 return 0; 835 return 0;
826} /* pcnet_event */ 836} /* pcnet_event */
@@ -1849,6 +1859,8 @@ static struct pcmcia_driver pcnet_driver = {
1849 .detach = pcnet_detach, 1859 .detach = pcnet_detach,
1850 .owner = THIS_MODULE, 1860 .owner = THIS_MODULE,
1851 .id_table = pcnet_ids, 1861 .id_table = pcnet_ids,
1862 .suspend = pcnet_suspend,
1863 .resume = pcnet_resume,
1852}; 1864};
1853 1865
1854static int __init init_pcnet_cs(void) 1866static int __init init_pcnet_cs(void)
diff --git a/drivers/net/pcmcia/smc91c92_cs.c b/drivers/net/pcmcia/smc91c92_cs.c
index c7cca842e5ee..7c61ec90c2c3 100644
--- a/drivers/net/pcmcia/smc91c92_cs.c
+++ b/drivers/net/pcmcia/smc91c92_cs.c
@@ -895,6 +895,62 @@ free_cfg_mem:
895 return rc; 895 return rc;
896} 896}
897 897
898static int smc91c92_suspend(struct pcmcia_device *p_dev)
899{
900 dev_link_t *link = dev_to_instance(p_dev);
901 struct net_device *dev = link->priv;
902
903 link->state |= DEV_SUSPEND;
904 if (link->state & DEV_CONFIG) {
905 if (link->open)
906 netif_device_detach(dev);
907 pcmcia_release_configuration(link->handle);
908 }
909
910 return 0;
911}
912
913static int smc91c92_resume(struct pcmcia_device *p_dev)
914{
915 dev_link_t *link = dev_to_instance(p_dev);
916 struct net_device *dev = link->priv;
917 struct smc_private *smc = netdev_priv(dev);
918 int i;
919
920 link->state &= ~DEV_SUSPEND;
921 if (link->state & DEV_CONFIG) {
922 if ((smc->manfid == MANFID_MEGAHERTZ) &&
923 (smc->cardid == PRODID_MEGAHERTZ_EM3288))
924 mhz_3288_power(link);
925 pcmcia_request_configuration(link->handle, &link->conf);
926 if (smc->manfid == MANFID_MOTOROLA)
927 mot_config(link);
928 if ((smc->manfid == MANFID_OSITECH) &&
929 (smc->cardid != PRODID_OSITECH_SEVEN)) {
930 /* Power up the card and enable interrupts */
931 set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
932 set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
933 }
934 if (((smc->manfid == MANFID_OSITECH) &&
935 (smc->cardid == PRODID_OSITECH_SEVEN)) ||
936 ((smc->manfid == MANFID_PSION) &&
937 (smc->cardid == PRODID_PSION_NET100))) {
938 /* Download the Seven of Diamonds firmware */
939 for (i = 0; i < sizeof(__Xilinx7OD); i++) {
940 outb(__Xilinx7OD[i], link->io.BasePort1+2);
941 udelay(50);
942 }
943 }
944 if (link->open) {
945 smc_reset(dev);
946 netif_device_attach(dev);
947 }
948 }
949
950 return 0;
951}
952
953
898/*====================================================================== 954/*======================================================================
899 955
900 This verifies that the chip is some SMC91cXX variant, and returns 956 This verifies that the chip is some SMC91cXX variant, and returns
@@ -935,14 +991,12 @@ static int check_sig(dev_link_t *link)
935 } 991 }
936 992
937 if (width) { 993 if (width) {
938 event_callback_args_t args;
939 printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n"); 994 printk(KERN_INFO "smc91c92_cs: using 8-bit IO window.\n");
940 args.client_data = link; 995 smc91c92_suspend(link->handle);
941 smc91c92_event(CS_EVENT_RESET_PHYSICAL, 0, &args);
942 pcmcia_release_io(link->handle, &link->io); 996 pcmcia_release_io(link->handle, &link->io);
943 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8; 997 link->io.Attributes1 = IO_DATA_PATH_WIDTH_8;
944 pcmcia_request_io(link->handle, &link->io); 998 pcmcia_request_io(link->handle, &link->io);
945 smc91c92_event(CS_EVENT_CARD_RESET, 0, &args); 999 smc91c92_resume(link->handle);
946 return check_sig(link); 1000 return check_sig(link);
947 } 1001 }
948 return -ENODEV; 1002 return -ENODEV;
@@ -1184,8 +1238,6 @@ static int smc91c92_event(event_t event, int priority,
1184{ 1238{
1185 dev_link_t *link = args->client_data; 1239 dev_link_t *link = args->client_data;
1186 struct net_device *dev = link->priv; 1240 struct net_device *dev = link->priv;
1187 struct smc_private *smc = netdev_priv(dev);
1188 int i;
1189 1241
1190 DEBUG(1, "smc91c92_event(0x%06x)\n", event); 1242 DEBUG(1, "smc91c92_event(0x%06x)\n", event);
1191 1243
@@ -1199,49 +1251,6 @@ static int smc91c92_event(event_t event, int priority,
1199 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 1251 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
1200 smc91c92_config(link); 1252 smc91c92_config(link);
1201 break; 1253 break;
1202 case CS_EVENT_PM_SUSPEND:
1203 link->state |= DEV_SUSPEND;
1204 /* Fall through... */
1205 case CS_EVENT_RESET_PHYSICAL:
1206 if (link->state & DEV_CONFIG) {
1207 if (link->open)
1208 netif_device_detach(dev);
1209 pcmcia_release_configuration(link->handle);
1210 }
1211 break;
1212 case CS_EVENT_PM_RESUME:
1213 link->state &= ~DEV_SUSPEND;
1214 /* Fall through... */
1215 case CS_EVENT_CARD_RESET:
1216 if (link->state & DEV_CONFIG) {
1217 if ((smc->manfid == MANFID_MEGAHERTZ) &&
1218 (smc->cardid == PRODID_MEGAHERTZ_EM3288))
1219 mhz_3288_power(link);
1220 pcmcia_request_configuration(link->handle, &link->conf);
1221 if (smc->manfid == MANFID_MOTOROLA)
1222 mot_config(link);
1223 if ((smc->manfid == MANFID_OSITECH) &&
1224 (smc->cardid != PRODID_OSITECH_SEVEN)) {
1225 /* Power up the card and enable interrupts */
1226 set_bits(0x0300, dev->base_addr-0x10+OSITECH_AUI_PWR);
1227 set_bits(0x0300, dev->base_addr-0x10+OSITECH_RESET_ISR);
1228 }
1229 if (((smc->manfid == MANFID_OSITECH) &&
1230 (smc->cardid == PRODID_OSITECH_SEVEN)) ||
1231 ((smc->manfid == MANFID_PSION) &&
1232 (smc->cardid == PRODID_PSION_NET100))) {
1233 /* Download the Seven of Diamonds firmware */
1234 for (i = 0; i < sizeof(__Xilinx7OD); i++) {
1235 outb(__Xilinx7OD[i], link->io.BasePort1+2);
1236 udelay(50);
1237 }
1238 }
1239 if (link->open) {
1240 smc_reset(dev);
1241 netif_device_attach(dev);
1242 }
1243 }
1244 break;
1245 } 1254 }
1246 return 0; 1255 return 0;
1247} /* smc91c92_event */ 1256} /* smc91c92_event */
@@ -2364,6 +2373,8 @@ static struct pcmcia_driver smc91c92_cs_driver = {
2364 .event = smc91c92_event, 2373 .event = smc91c92_event,
2365 .detach = smc91c92_detach, 2374 .detach = smc91c92_detach,
2366 .id_table = smc91c92_ids, 2375 .id_table = smc91c92_ids,
2376 .suspend = smc91c92_suspend,
2377 .resume = smc91c92_resume,
2367}; 2378};
2368 2379
2369static int __init init_smc91c92_cs(void) 2380static int __init init_smc91c92_cs(void)
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c
index ce143f08638a..917e50ac37f3 100644
--- a/drivers/net/pcmcia/xirc2ps_cs.c
+++ b/drivers/net/pcmcia/xirc2ps_cs.c
@@ -1157,6 +1157,41 @@ xirc2ps_release(dev_link_t *link)
1157 1157
1158/*====================================================================*/ 1158/*====================================================================*/
1159 1159
1160
1161static int xirc2ps_suspend(struct pcmcia_device *p_dev)
1162{
1163 dev_link_t *link = dev_to_instance(p_dev);
1164 struct net_device *dev = link->priv;
1165
1166 link->state |= DEV_SUSPEND;
1167 if (link->state & DEV_CONFIG) {
1168 if (link->open) {
1169 netif_device_detach(dev);
1170 do_powerdown(dev);
1171 }
1172 pcmcia_release_configuration(link->handle);
1173 }
1174
1175 return 0;
1176}
1177
1178static int xirc2ps_resume(struct pcmcia_device *p_dev)
1179{
1180 dev_link_t *link = dev_to_instance(p_dev);
1181 struct net_device *dev = link->priv;
1182
1183 link->state &= ~DEV_SUSPEND;
1184 if (link->state & DEV_CONFIG) {
1185 pcmcia_request_configuration(link->handle, &link->conf);
1186 if (link->open) {
1187 do_reset(dev,1);
1188 netif_device_attach(dev);
1189 }
1190 }
1191
1192 return 0;
1193}
1194
1160/**************** 1195/****************
1161 * The card status event handler. Mostly, this schedules other 1196 * The card status event handler. Mostly, this schedules other
1162 * stuff to run after an event is received. A CARD_REMOVAL event 1197 * stuff to run after an event is received. A CARD_REMOVAL event
@@ -1191,30 +1226,6 @@ xirc2ps_event(event_t event, int priority,
1191 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 1226 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
1192 xirc2ps_config(link); 1227 xirc2ps_config(link);
1193 break; 1228 break;
1194 case CS_EVENT_PM_SUSPEND:
1195 link->state |= DEV_SUSPEND;
1196 /* Fall through... */
1197 case CS_EVENT_RESET_PHYSICAL:
1198 if (link->state & DEV_CONFIG) {
1199 if (link->open) {
1200 netif_device_detach(dev);
1201 do_powerdown(dev);
1202 }
1203 pcmcia_release_configuration(link->handle);
1204 }
1205 break;
1206 case CS_EVENT_PM_RESUME:
1207 link->state &= ~DEV_SUSPEND;
1208 /* Fall through... */
1209 case CS_EVENT_CARD_RESET:
1210 if (link->state & DEV_CONFIG) {
1211 pcmcia_request_configuration(link->handle, &link->conf);
1212 if (link->open) {
1213 do_reset(dev,1);
1214 netif_device_attach(dev);
1215 }
1216 }
1217 break;
1218 } 1229 }
1219 return 0; 1230 return 0;
1220} /* xirc2ps_event */ 1231} /* xirc2ps_event */
@@ -2013,6 +2024,8 @@ static struct pcmcia_driver xirc2ps_cs_driver = {
2013 .event = xirc2ps_event, 2024 .event = xirc2ps_event,
2014 .detach = xirc2ps_detach, 2025 .detach = xirc2ps_detach,
2015 .id_table = xirc2ps_ids, 2026 .id_table = xirc2ps_ids,
2027 .suspend = xirc2ps_suspend,
2028 .resume = xirc2ps_resume,
2016}; 2029};
2017 2030
2018static int __init 2031static int __init
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index e328547599dc..80c9de749b52 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -492,6 +492,35 @@ static void airo_release(dev_link_t *link)
492 link->state &= ~DEV_CONFIG; 492 link->state &= ~DEV_CONFIG;
493} 493}
494 494
495static int airo_suspend(struct pcmcia_device *p_dev)
496{
497 dev_link_t *link = dev_to_instance(p_dev);
498 local_info_t *local = link->priv;
499
500 link->state |= DEV_SUSPEND;
501 if (link->state & DEV_CONFIG) {
502 netif_device_detach(local->eth_dev);
503 pcmcia_release_configuration(link->handle);
504 }
505
506 return 0;
507}
508
509static int airo_resume(struct pcmcia_device *p_dev)
510{
511 dev_link_t *link = dev_to_instance(p_dev);
512 local_info_t *local = link->priv;
513
514 link->state &= ~DEV_SUSPEND;
515 if (link->state & DEV_CONFIG) {
516 pcmcia_request_configuration(link->handle, &link->conf);
517 reset_airo_card(local->eth_dev);
518 netif_device_attach(local->eth_dev);
519 }
520
521 return 0;
522}
523
495/*====================================================================== 524/*======================================================================
496 525
497 The card status event handler. Mostly, this schedules other 526 The card status event handler. Mostly, this schedules other
@@ -524,25 +553,6 @@ static int airo_event(event_t event, int priority,
524 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 553 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
525 airo_config(link); 554 airo_config(link);
526 break; 555 break;
527 case CS_EVENT_PM_SUSPEND:
528 link->state |= DEV_SUSPEND;
529 /* Fall through... */
530 case CS_EVENT_RESET_PHYSICAL:
531 if (link->state & DEV_CONFIG) {
532 netif_device_detach(local->eth_dev);
533 pcmcia_release_configuration(link->handle);
534 }
535 break;
536 case CS_EVENT_PM_RESUME:
537 link->state &= ~DEV_SUSPEND;
538 /* Fall through... */
539 case CS_EVENT_CARD_RESET:
540 if (link->state & DEV_CONFIG) {
541 pcmcia_request_configuration(link->handle, &link->conf);
542 reset_airo_card(local->eth_dev);
543 netif_device_attach(local->eth_dev);
544 }
545 break;
546 } 556 }
547 return 0; 557 return 0;
548} /* airo_event */ 558} /* airo_event */
@@ -565,6 +575,8 @@ static struct pcmcia_driver airo_driver = {
565 .event = airo_event, 575 .event = airo_event,
566 .detach = airo_detach, 576 .detach = airo_detach,
567 .id_table = airo_ids, 577 .id_table = airo_ids,
578 .suspend = airo_suspend,
579 .resume = airo_resume,
568}; 580};
569 581
570static int airo_cs_init(void) 582static int airo_cs_init(void)
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index 17d1fd90f832..598a9cd0f83e 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -477,6 +477,35 @@ static void atmel_release(dev_link_t *link)
477 link->state &= ~DEV_CONFIG; 477 link->state &= ~DEV_CONFIG;
478} 478}
479 479
480static int atmel_suspend(struct pcmcia_device *dev)
481{
482 dev_link_t *link = dev_to_instance(dev);
483 local_info_t *local = link->priv;
484
485 link->state |= DEV_SUSPEND;
486 if (link->state & DEV_CONFIG) {
487 netif_device_detach(local->eth_dev);
488 pcmcia_release_configuration(link->handle);
489 }
490
491 return 0;
492}
493
494static int atmel_resume(struct pcmcia_device *dev)
495{
496 dev_link_t *link = dev_to_instance(dev);
497 local_info_t *local = link->priv;
498
499 link->state &= ~DEV_SUSPEND;
500 if (link->state & DEV_CONFIG) {
501 pcmcia_request_configuration(link->handle, &link->conf);
502 atmel_open(local->eth_dev);
503 netif_device_attach(local->eth_dev);
504 }
505
506 return 0;
507}
508
480/*====================================================================== 509/*======================================================================
481 510
482 The card status event handler. Mostly, this schedules other 511 The card status event handler. Mostly, this schedules other
@@ -509,25 +538,6 @@ static int atmel_event(event_t event, int priority,
509 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 538 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
510 atmel_config(link); 539 atmel_config(link);
511 break; 540 break;
512 case CS_EVENT_PM_SUSPEND:
513 link->state |= DEV_SUSPEND;
514 /* Fall through... */
515 case CS_EVENT_RESET_PHYSICAL:
516 if (link->state & DEV_CONFIG) {
517 netif_device_detach(local->eth_dev);
518 pcmcia_release_configuration(link->handle);
519 }
520 break;
521 case CS_EVENT_PM_RESUME:
522 link->state &= ~DEV_SUSPEND;
523 /* Fall through... */
524 case CS_EVENT_CARD_RESET:
525 if (link->state & DEV_CONFIG) {
526 pcmcia_request_configuration(link->handle, &link->conf);
527 atmel_open(local->eth_dev);
528 netif_device_attach(local->eth_dev);
529 }
530 break;
531 } 541 }
532 return 0; 542 return 0;
533} /* atmel_event */ 543} /* atmel_event */
@@ -585,6 +595,8 @@ static struct pcmcia_driver atmel_driver = {
585 .event = atmel_event, 595 .event = atmel_event,
586 .detach = atmel_detach, 596 .detach = atmel_detach,
587 .id_table = atmel_ids, 597 .id_table = atmel_ids,
598 .suspend = atmel_suspend,
599 .resume = atmel_resume,
588}; 600};
589 601
590static int atmel_cs_init(void) 602static int atmel_cs_init(void)
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 2643976a6677..ba4a7da98ccd 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -846,20 +846,64 @@ static void prism2_release(u_long arg)
846 PDEBUG(DEBUG_FLOW, "release - done\n"); 846 PDEBUG(DEBUG_FLOW, "release - done\n");
847} 847}
848 848
849static int hostap_cs_suspend(struct pcmcia_device *p_dev)
850{
851 dev_link_t *link = dev_to_instance(p_dev);
852 struct net_device *dev = (struct net_device *) link->priv;
853 int dev_open = 0;
849 854
850static int prism2_event(event_t event, int priority, 855 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
851 event_callback_args_t *args) 856
857 link->state |= DEV_SUSPEND;
858
859 if (link->state & DEV_CONFIG) {
860 struct hostap_interface *iface = netdev_priv(dev);
861 if (iface && iface->local)
862 dev_open = iface->local->num_dev_open > 0;
863 if (dev_open) {
864 netif_stop_queue(dev);
865 netif_device_detach(dev);
866 }
867 prism2_suspend(dev);
868 pcmcia_release_configuration(link->handle);
869 }
870
871 return 0;
872}
873
874static int hostap_cs_resume(struct pcmcia_device *p_dev)
852{ 875{
853 dev_link_t *link = args->client_data; 876 dev_link_t *link = dev_to_instance(p_dev);
854 struct net_device *dev = (struct net_device *) link->priv; 877 struct net_device *dev = (struct net_device *) link->priv;
855 int dev_open = 0; 878 int dev_open = 0;
856 879
880 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
881
882 link->state &= ~DEV_SUSPEND;
857 if (link->state & DEV_CONFIG) { 883 if (link->state & DEV_CONFIG) {
858 struct hostap_interface *iface = netdev_priv(dev); 884 struct hostap_interface *iface = netdev_priv(dev);
859 if (iface && iface->local) 885 if (iface && iface->local)
860 dev_open = iface->local->num_dev_open > 0; 886 dev_open = iface->local->num_dev_open > 0;
887
888 pcmcia_request_configuration(link->handle, &link->conf);
889
890 prism2_hw_shutdown(dev, 1);
891 prism2_hw_config(dev, dev_open ? 0 : 1);
892 if (dev_open) {
893 netif_device_attach(dev);
894 netif_start_queue(dev);
895 }
861 } 896 }
862 897
898 return 0;
899}
900
901static int prism2_event(event_t event, int priority,
902 event_callback_args_t *args)
903{
904 dev_link_t *link = args->client_data;
905 struct net_device *dev = (struct net_device *) link->priv;
906
863 switch (event) { 907 switch (event) {
864 case CS_EVENT_CARD_INSERTION: 908 case CS_EVENT_CARD_INSERTION:
865 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info); 909 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info);
@@ -879,42 +923,6 @@ static int prism2_event(event_t event, int priority,
879 } 923 }
880 break; 924 break;
881 925
882 case CS_EVENT_PM_SUSPEND:
883 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info);
884 link->state |= DEV_SUSPEND;
885 /* fall through */
886
887 case CS_EVENT_RESET_PHYSICAL:
888 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
889 if (link->state & DEV_CONFIG) {
890 if (dev_open) {
891 netif_stop_queue(dev);
892 netif_device_detach(dev);
893 }
894 prism2_suspend(dev);
895 pcmcia_release_configuration(link->handle);
896 }
897 break;
898
899 case CS_EVENT_PM_RESUME:
900 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info);
901 link->state &= ~DEV_SUSPEND;
902 /* fall through */
903
904 case CS_EVENT_CARD_RESET:
905 PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_RESET\n", dev_info);
906 if (link->state & DEV_CONFIG) {
907 pcmcia_request_configuration(link->handle,
908 &link->conf);
909 prism2_hw_shutdown(dev, 1);
910 prism2_hw_config(dev, dev_open ? 0 : 1);
911 if (dev_open) {
912 netif_device_attach(dev);
913 netif_start_queue(dev);
914 }
915 }
916 break;
917
918 default: 926 default:
919 PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n", 927 PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n",
920 dev_info, event); 928 dev_info, event);
@@ -987,6 +995,8 @@ static struct pcmcia_driver hostap_driver = {
987 .owner = THIS_MODULE, 995 .owner = THIS_MODULE,
988 .event = prism2_event, 996 .event = prism2_event,
989 .id_table = hostap_cs_ids, 997 .id_table = hostap_cs_ids,
998 .suspend = hostap_cs_suspend,
999 .resume = hostap_cs_resume,
990}; 1000};
991 1001
992static int __init init_prism2_pccard(void) 1002static int __init init_prism2_pccard(void)
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index 92793b958e32..7ab2d70ffddf 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -935,6 +935,39 @@ static void netwave_release(dev_link_t *link)
935 link->state &= ~DEV_CONFIG; 935 link->state &= ~DEV_CONFIG;
936} 936}
937 937
938static int netwave_suspend(struct pcmcia_device *p_dev)
939{
940 dev_link_t *link = dev_to_instance(p_dev);
941 struct net_device *dev = link->priv;
942
943 link->state |= DEV_SUSPEND;
944 if (link->state & DEV_CONFIG) {
945 if (link->open)
946 netif_device_detach(dev);
947 pcmcia_release_configuration(link->handle);
948 }
949
950 return 0;
951}
952
953static int netwave_resume(struct pcmcia_device *p_dev)
954{
955 dev_link_t *link = dev_to_instance(p_dev);
956 struct net_device *dev = link->priv;
957
958 link->state &= ~DEV_SUSPEND;
959 if (link->state & DEV_CONFIG) {
960 pcmcia_request_configuration(link->handle, &link->conf);
961 if (link->open) {
962 netwave_reset(dev);
963 netif_device_attach(dev);
964 }
965 }
966
967 return 0;
968}
969
970
938/* 971/*
939 * Function netwave_event (event, priority, args) 972 * Function netwave_event (event, priority, args)
940 * 973 *
@@ -973,28 +1006,6 @@ static int netwave_event(event_t event, int priority,
973 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 1006 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
974 netwave_pcmcia_config( link); 1007 netwave_pcmcia_config( link);
975 break; 1008 break;
976 case CS_EVENT_PM_SUSPEND:
977 link->state |= DEV_SUSPEND;
978 /* Fall through... */
979 case CS_EVENT_RESET_PHYSICAL:
980 if (link->state & DEV_CONFIG) {
981 if (link->open)
982 netif_device_detach(dev);
983 pcmcia_release_configuration(link->handle);
984 }
985 break;
986 case CS_EVENT_PM_RESUME:
987 link->state &= ~DEV_SUSPEND;
988 /* Fall through... */
989 case CS_EVENT_CARD_RESET:
990 if (link->state & DEV_CONFIG) {
991 pcmcia_request_configuration(link->handle, &link->conf);
992 if (link->open) {
993 netwave_reset(dev);
994 netif_device_attach(dev);
995 }
996 }
997 break;
998 } 1009 }
999 return 0; 1010 return 0;
1000} /* netwave_event */ 1011} /* netwave_event */
@@ -1495,6 +1506,8 @@ static struct pcmcia_driver netwave_driver = {
1495 .event = netwave_event, 1506 .event = netwave_event,
1496 .detach = netwave_detach, 1507 .detach = netwave_detach,
1497 .id_table = netwave_ids, 1508 .id_table = netwave_ids,
1509 .suspend = netwave_suspend,
1510 .resume = netwave_resume,
1498}; 1511};
1499 1512
1500static int __init init_netwave_cs(void) 1513static int __init init_netwave_cs(void)
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index dc1128a00971..1d66050e3d6a 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -465,6 +465,83 @@ orinoco_cs_release(dev_link_t *link)
465 ioport_unmap(priv->hw.iobase); 465 ioport_unmap(priv->hw.iobase);
466} /* orinoco_cs_release */ 466} /* orinoco_cs_release */
467 467
468static int orinoco_cs_suspend(struct pcmcia_device *p_dev)
469{
470 dev_link_t *link = dev_to_instance(p_dev);
471 struct net_device *dev = link->priv;
472 struct orinoco_private *priv = netdev_priv(dev);
473 struct orinoco_pccard *card = priv->card;
474 int err = 0;
475 unsigned long flags;
476
477 link->state |= DEV_SUSPEND;
478 if (link->state & DEV_CONFIG) {
479 /* This is probably racy, but I can't think of
480 a better way, short of rewriting the PCMCIA
481 layer to not suck :-( */
482 if (! test_bit(0, &card->hard_reset_in_progress)) {
483 spin_lock_irqsave(&priv->lock, flags);
484
485 err = __orinoco_down(dev);
486 if (err)
487 printk(KERN_WARNING "%s: Error %d downing interface\n",
488 dev->name, err);
489
490 netif_device_detach(dev);
491 priv->hw_unavailable++;
492
493 spin_unlock_irqrestore(&priv->lock, flags);
494 }
495
496 pcmcia_release_configuration(link->handle);
497 }
498
499 return 0;
500}
501
502static int orinoco_cs_resume(struct pcmcia_device *p_dev)
503{
504 dev_link_t *link = dev_to_instance(p_dev);
505 struct net_device *dev = link->priv;
506 struct orinoco_private *priv = netdev_priv(dev);
507 struct orinoco_pccard *card = priv->card;
508 int err = 0;
509 unsigned long flags;
510
511 link->state &= ~DEV_SUSPEND;
512 if (link->state & DEV_CONFIG) {
513 /* FIXME: should we double check that this is
514 * the same card as we had before */
515 pcmcia_request_configuration(link->handle, &link->conf);
516
517 if (! test_bit(0, &card->hard_reset_in_progress)) {
518 err = orinoco_reinit_firmware(dev);
519 if (err) {
520 printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
521 dev->name, err);
522 return -EIO;
523 }
524
525 spin_lock_irqsave(&priv->lock, flags);
526
527 netif_device_attach(dev);
528 priv->hw_unavailable--;
529
530 if (priv->open && ! priv->hw_unavailable) {
531 err = __orinoco_up(dev);
532 if (err)
533 printk(KERN_ERR "%s: Error %d restarting card\n",
534 dev->name, err);
535 }
536
537 spin_unlock_irqrestore(&priv->lock, flags);
538 }
539 }
540
541 return 0;
542}
543
544
468/* 545/*
469 * The card status event handler. Mostly, this schedules other stuff 546 * The card status event handler. Mostly, this schedules other stuff
470 * to run after an event is received. 547 * to run after an event is received.
@@ -476,9 +553,7 @@ orinoco_cs_event(event_t event, int priority,
476 dev_link_t *link = args->client_data; 553 dev_link_t *link = args->client_data;
477 struct net_device *dev = link->priv; 554 struct net_device *dev = link->priv;
478 struct orinoco_private *priv = netdev_priv(dev); 555 struct orinoco_private *priv = netdev_priv(dev);
479 struct orinoco_pccard *card = priv->card;
480 int err = 0; 556 int err = 0;
481 unsigned long flags;
482 557
483 switch (event) { 558 switch (event) {
484 case CS_EVENT_CARD_REMOVAL: 559 case CS_EVENT_CARD_REMOVAL:
@@ -497,70 +572,6 @@ orinoco_cs_event(event_t event, int priority,
497 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 572 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
498 orinoco_cs_config(link); 573 orinoco_cs_config(link);
499 break; 574 break;
500
501 case CS_EVENT_PM_SUSPEND:
502 link->state |= DEV_SUSPEND;
503 /* Fall through... */
504 case CS_EVENT_RESET_PHYSICAL:
505 /* Mark the device as stopped, to block IO until later */
506 if (link->state & DEV_CONFIG) {
507 /* This is probably racy, but I can't think of
508 a better way, short of rewriting the PCMCIA
509 layer to not suck :-( */
510 if (! test_bit(0, &card->hard_reset_in_progress)) {
511 spin_lock_irqsave(&priv->lock, flags);
512
513 err = __orinoco_down(dev);
514 if (err)
515 printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
516 dev->name,
517 event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
518 err);
519
520 netif_device_detach(dev);
521 priv->hw_unavailable++;
522
523 spin_unlock_irqrestore(&priv->lock, flags);
524 }
525
526 pcmcia_release_configuration(link->handle);
527 }
528 break;
529
530 case CS_EVENT_PM_RESUME:
531 link->state &= ~DEV_SUSPEND;
532 /* Fall through... */
533 case CS_EVENT_CARD_RESET:
534 if (link->state & DEV_CONFIG) {
535 /* FIXME: should we double check that this is
536 * the same card as we had before */
537 pcmcia_request_configuration(link->handle, &link->conf);
538
539 if (! test_bit(0, &card->hard_reset_in_progress)) {
540 err = orinoco_reinit_firmware(dev);
541 if (err) {
542 printk(KERN_ERR "%s: Error %d re-initializing firmware\n",
543 dev->name, err);
544 break;
545 }
546
547 spin_lock_irqsave(&priv->lock, flags);
548
549 netif_device_attach(dev);
550 priv->hw_unavailable--;
551
552 if (priv->open && ! priv->hw_unavailable) {
553 err = __orinoco_up(dev);
554 if (err)
555 printk(KERN_ERR "%s: Error %d restarting card\n",
556 dev->name, err);
557
558 }
559
560 spin_unlock_irqrestore(&priv->lock, flags);
561 }
562 }
563 break;
564 } 575 }
565 576
566 return err; 577 return err;
@@ -669,6 +680,8 @@ static struct pcmcia_driver orinoco_driver = {
669 .detach = orinoco_cs_detach, 680 .detach = orinoco_cs_detach,
670 .event = orinoco_cs_event, 681 .event = orinoco_cs_event,
671 .id_table = orinoco_cs_ids, 682 .id_table = orinoco_cs_ids,
683 .suspend = orinoco_cs_suspend,
684 .resume = orinoco_cs_resume,
672}; 685};
673 686
674static int __init 687static int __init
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index 70fd6fd8feb9..c2cb6c8e6d7c 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -891,6 +891,40 @@ static void ray_release(dev_link_t *link)
891 DEBUG(2,"ray_release ending\n"); 891 DEBUG(2,"ray_release ending\n");
892} 892}
893 893
894static int ray_suspend(struct pcmcia_device *p_dev)
895{
896 dev_link_t *link = dev_to_instance(p_dev);
897 struct net_device *dev = link->priv;
898
899 link->state |= DEV_SUSPEND;
900 if (link->state & DEV_CONFIG) {
901 if (link->open)
902 netif_device_detach(dev);
903
904 pcmcia_release_configuration(link->handle);
905 }
906
907
908 return 0;
909}
910
911static int ray_resume(struct pcmcia_device *p_dev)
912{
913 dev_link_t *link = dev_to_instance(p_dev);
914 struct net_device *dev = link->priv;
915
916 link->state &= ~DEV_SUSPEND;
917 if (link->state & DEV_CONFIG) {
918 pcmcia_request_configuration(link->handle, &link->conf);
919 if (link->open) {
920 ray_reset(dev);
921 netif_device_attach(dev);
922 }
923 }
924
925 return 0;
926}
927
894/*============================================================================= 928/*=============================================================================
895 The card status event handler. Mostly, this schedules other 929 The card status event handler. Mostly, this schedules other
896 stuff to run after an event is received. A CARD_REMOVAL event 930 stuff to run after an event is received. A CARD_REMOVAL event
@@ -923,29 +957,6 @@ static int ray_event(event_t event, int priority,
923 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 957 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
924 ray_config(link); 958 ray_config(link);
925 break; 959 break;
926 case CS_EVENT_PM_SUSPEND:
927 link->state |= DEV_SUSPEND;
928 /* Fall through... */
929 case CS_EVENT_RESET_PHYSICAL:
930 if (link->state & DEV_CONFIG) {
931 if (link->open)
932 netif_device_detach(dev);
933
934 pcmcia_release_configuration(link->handle);
935 }
936 break;
937 case CS_EVENT_PM_RESUME:
938 link->state &= ~DEV_SUSPEND;
939 /* Fall through... */
940 case CS_EVENT_CARD_RESET:
941 if (link->state & DEV_CONFIG) {
942 pcmcia_request_configuration(link->handle, &link->conf);
943 if (link->open) {
944 ray_reset(dev);
945 netif_device_attach(dev);
946 }
947 }
948 break;
949 } 960 }
950 return 0; 961 return 0;
951 DEBUG(2,"ray_event ending\n"); 962 DEBUG(2,"ray_event ending\n");
@@ -2949,6 +2960,8 @@ static struct pcmcia_driver ray_driver = {
2949 .event = ray_event, 2960 .event = ray_event,
2950 .detach = ray_detach, 2961 .detach = ray_detach,
2951 .id_table = ray_ids, 2962 .id_table = ray_ids,
2963 .suspend = ray_suspend,
2964 .resume = ray_resume,
2952}; 2965};
2953 2966
2954static int __init init_ray_cs(void) 2967static int __init init_ray_cs(void)
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index b1bbc8e8e91f..3938a5735659 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -948,6 +948,56 @@ spectrum_cs_release(dev_link_t *link)
948 ioport_unmap(priv->hw.iobase); 948 ioport_unmap(priv->hw.iobase);
949} /* spectrum_cs_release */ 949} /* spectrum_cs_release */
950 950
951
952static int
953spectrum_cs_suspend(struct pcmcia_device *p_dev)
954{
955 dev_link_t *link = dev_to_instance(p_dev);
956 struct net_device *dev = link->priv;
957 struct orinoco_private *priv = netdev_priv(dev);
958 unsigned long flags;
959 int err = 0;
960
961 link->state |= DEV_SUSPEND;
962 /* Mark the device as stopped, to block IO until later */
963 if (link->state & DEV_CONFIG) {
964 spin_lock_irqsave(&priv->lock, flags);
965
966 err = __orinoco_down(dev);
967 if (err)
968 printk(KERN_WARNING "%s: Error %d downing interface\n",
969 dev->name, err);
970
971 netif_device_detach(dev);
972 priv->hw_unavailable++;
973
974 spin_unlock_irqrestore(&priv->lock, flags);
975
976 pcmcia_release_configuration(link->handle);
977 }
978
979 return 0;
980}
981
982static int
983spectrum_cs_resume(struct pcmcia_device *p_dev)
984{
985 dev_link_t *link = dev_to_instance(p_dev);
986 struct net_device *dev = link->priv;
987 struct orinoco_private *priv = netdev_priv(dev);
988
989 link->state &= ~DEV_SUSPEND;
990 if (link->state & DEV_CONFIG) {
991 /* FIXME: should we double check that this is
992 * the same card as we had before */
993 pcmcia_request_configuration(link->handle, &link->conf);
994 netif_device_attach(dev);
995 priv->hw_unavailable--;
996 schedule_work(&priv->reset_work);
997 }
998 return 0;
999}
1000
951/* 1001/*
952 * The card status event handler. Mostly, this schedules other stuff 1002 * The card status event handler. Mostly, this schedules other stuff
953 * to run after an event is received. 1003 * to run after an event is received.
@@ -959,8 +1009,6 @@ spectrum_cs_event(event_t event, int priority,
959 dev_link_t *link = args->client_data; 1009 dev_link_t *link = args->client_data;
960 struct net_device *dev = link->priv; 1010 struct net_device *dev = link->priv;
961 struct orinoco_private *priv = netdev_priv(dev); 1011 struct orinoco_private *priv = netdev_priv(dev);
962 int err = 0;
963 unsigned long flags;
964 1012
965 switch (event) { 1013 switch (event) {
966 case CS_EVENT_CARD_REMOVAL: 1014 case CS_EVENT_CARD_REMOVAL:
@@ -980,49 +1028,9 @@ spectrum_cs_event(event_t event, int priority,
980 spectrum_cs_config(link); 1028 spectrum_cs_config(link);
981 break; 1029 break;
982 1030
983 case CS_EVENT_PM_SUSPEND:
984 link->state |= DEV_SUSPEND;
985 /* Fall through... */
986 case CS_EVENT_RESET_PHYSICAL:
987 /* Mark the device as stopped, to block IO until later */
988 if (link->state & DEV_CONFIG) {
989 /* This is probably racy, but I can't think of
990 a better way, short of rewriting the PCMCIA
991 layer to not suck :-( */
992 spin_lock_irqsave(&priv->lock, flags);
993
994 err = __orinoco_down(dev);
995 if (err)
996 printk(KERN_WARNING "%s: %s: Error %d downing interface\n",
997 dev->name,
998 event == CS_EVENT_PM_SUSPEND ? "SUSPEND" : "RESET_PHYSICAL",
999 err);
1000
1001 netif_device_detach(dev);
1002 priv->hw_unavailable++;
1003
1004 spin_unlock_irqrestore(&priv->lock, flags);
1005
1006 pcmcia_release_configuration(link->handle);
1007 }
1008 break;
1009
1010 case CS_EVENT_PM_RESUME:
1011 link->state &= ~DEV_SUSPEND;
1012 /* Fall through... */
1013 case CS_EVENT_CARD_RESET:
1014 if (link->state & DEV_CONFIG) {
1015 /* FIXME: should we double check that this is
1016 * the same card as we had before */
1017 pcmcia_request_configuration(link->handle, &link->conf);
1018 netif_device_attach(dev);
1019 priv->hw_unavailable--;
1020 schedule_work(&priv->reset_work);
1021 }
1022 break;
1023 } 1031 }
1024 1032
1025 return err; 1033 return 0;
1026} /* spectrum_cs_event */ 1034} /* spectrum_cs_event */
1027 1035
1028/********************************************************************/ 1036/********************************************************************/
@@ -1050,6 +1058,8 @@ static struct pcmcia_driver orinoco_driver = {
1050 }, 1058 },
1051 .attach = spectrum_cs_attach, 1059 .attach = spectrum_cs_attach,
1052 .detach = spectrum_cs_detach, 1060 .detach = spectrum_cs_detach,
1061 .suspend = spectrum_cs_suspend,
1062 .resume = spectrum_cs_resume,
1053 .event = spectrum_cs_event, 1063 .event = spectrum_cs_event,
1054 .id_table = spectrum_cs_ids, 1064 .id_table = spectrum_cs_ids,
1055}; 1065};
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index c822cad3333f..3e3532830c26 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -4775,6 +4775,56 @@ wavelan_detach(dev_link_t * link)
4775#endif 4775#endif
4776} 4776}
4777 4777
4778static int wavelan_suspend(struct pcmcia_device *p_dev)
4779{
4780 dev_link_t *link = dev_to_instance(p_dev);
4781 struct net_device * dev = (struct net_device *) link->priv;
4782
4783 /* NB: wavelan_close will be called, but too late, so we are
4784 * obliged to close nicely the wavelan here. David, could you
4785 * close the device before suspending them ? And, by the way,
4786 * could you, on resume, add a "route add -net ..." after the
4787 * ifconfig up ? Thanks... */
4788
4789 /* Stop receiving new messages and wait end of transmission */
4790 wv_ru_stop(dev);
4791
4792 /* Power down the module */
4793 hacr_write(dev->base_addr, HACR_DEFAULT & (~HACR_PWR_STAT));
4794
4795 /* The card is now suspended */
4796 link->state |= DEV_SUSPEND;
4797
4798 if(link->state & DEV_CONFIG)
4799 {
4800 if(link->open)
4801 netif_device_detach(dev);
4802 pcmcia_release_configuration(link->handle);
4803 }
4804
4805 return 0;
4806}
4807
4808static int wavelan_resume(struct pcmcia_device *p_dev)
4809{
4810 dev_link_t *link = dev_to_instance(p_dev);
4811 struct net_device * dev = (struct net_device *) link->priv;
4812
4813 link->state &= ~DEV_SUSPEND;
4814 if(link->state & DEV_CONFIG)
4815 {
4816 pcmcia_request_configuration(link->handle, &link->conf);
4817 if(link->open) /* If RESET -> True, If RESUME -> False ? */
4818 {
4819 wv_hw_reset(dev);
4820 netif_device_attach(dev);
4821 }
4822 }
4823
4824 return 0;
4825}
4826
4827
4778/*------------------------------------------------------------------*/ 4828/*------------------------------------------------------------------*/
4779/* 4829/*
4780 * The card status event handler. Mostly, this schedules other stuff 4830 * The card status event handler. Mostly, this schedules other stuff
@@ -4832,46 +4882,6 @@ wavelan_event(event_t event, /* The event received */
4832 else 4882 else
4833 dev->irq = 0; 4883 dev->irq = 0;
4834 break; 4884 break;
4835
4836 case CS_EVENT_PM_SUSPEND:
4837 /* NB: wavelan_close will be called, but too late, so we are
4838 * obliged to close nicely the wavelan here. David, could you
4839 * close the device before suspending them ? And, by the way,
4840 * could you, on resume, add a "route add -net ..." after the
4841 * ifconfig up ? Thanks... */
4842
4843 /* Stop receiving new messages and wait end of transmission */
4844 wv_ru_stop(dev);
4845
4846 /* Power down the module */
4847 hacr_write(dev->base_addr, HACR_DEFAULT & (~HACR_PWR_STAT));
4848
4849 /* The card is now suspended */
4850 link->state |= DEV_SUSPEND;
4851 /* Fall through... */
4852 case CS_EVENT_RESET_PHYSICAL:
4853 if(link->state & DEV_CONFIG)
4854 {
4855 if(link->open)
4856 netif_device_detach(dev);
4857 pcmcia_release_configuration(link->handle);
4858 }
4859 break;
4860
4861 case CS_EVENT_PM_RESUME:
4862 link->state &= ~DEV_SUSPEND;
4863 /* Fall through... */
4864 case CS_EVENT_CARD_RESET:
4865 if(link->state & DEV_CONFIG)
4866 {
4867 pcmcia_request_configuration(link->handle, &link->conf);
4868 if(link->open) /* If RESET -> True, If RESUME -> False ? */
4869 {
4870 wv_hw_reset(dev);
4871 netif_device_attach(dev);
4872 }
4873 }
4874 break;
4875 } 4885 }
4876 4886
4877#ifdef DEBUG_CALLBACK_TRACE 4887#ifdef DEBUG_CALLBACK_TRACE
@@ -4898,6 +4908,8 @@ static struct pcmcia_driver wavelan_driver = {
4898 .event = wavelan_event, 4908 .event = wavelan_event,
4899 .detach = wavelan_detach, 4909 .detach = wavelan_detach,
4900 .id_table = wavelan_ids, 4910 .id_table = wavelan_ids,
4911 .suspend = wavelan_suspend,
4912 .resume = wavelan_resume,
4901}; 4913};
4902 4914
4903static int __init 4915static int __init
diff --git a/drivers/net/wireless/wl3501_cs.c b/drivers/net/wireless/wl3501_cs.c
index 978fdc606781..75114318457e 100644
--- a/drivers/net/wireless/wl3501_cs.c
+++ b/drivers/net/wireless/wl3501_cs.c
@@ -2173,6 +2173,41 @@ static void wl3501_release(dev_link_t *link)
2173 link->state &= ~DEV_CONFIG; 2173 link->state &= ~DEV_CONFIG;
2174} 2174}
2175 2175
2176static int wl3501_suspend(struct pcmcia_device *p_dev)
2177{
2178 dev_link_t *link = dev_to_instance(p_dev);
2179 struct net_device *dev = link->priv;
2180
2181 link->state |= DEV_SUSPEND;
2182
2183 wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
2184 if (link->state & DEV_CONFIG) {
2185 if (link->open)
2186 netif_device_detach(dev);
2187 pcmcia_release_configuration(link->handle);
2188 }
2189
2190 return 0;
2191}
2192
2193static int wl3501_resume(struct pcmcia_device *p_dev)
2194{
2195 dev_link_t *link = dev_to_instance(p_dev);
2196 struct net_device *dev = link->priv;
2197
2198 wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
2199 if (link->state & DEV_CONFIG) {
2200 pcmcia_request_configuration(link->handle, &link->conf);
2201 if (link->open) {
2202 wl3501_reset(dev);
2203 netif_device_attach(dev);
2204 }
2205 }
2206
2207 return 0;
2208}
2209
2210
2176/** 2211/**
2177 * wl3501_event - The card status event handler 2212 * wl3501_event - The card status event handler
2178 * @event - event 2213 * @event - event
@@ -2206,30 +2241,6 @@ static int wl3501_event(event_t event, int pri, event_callback_args_t *args)
2206 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; 2241 link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;
2207 wl3501_config(link); 2242 wl3501_config(link);
2208 break; 2243 break;
2209 case CS_EVENT_PM_SUSPEND:
2210 link->state |= DEV_SUSPEND;
2211 wl3501_pwr_mgmt(dev->priv, WL3501_SUSPEND);
2212 /* Fall through... */
2213 case CS_EVENT_RESET_PHYSICAL:
2214 if (link->state & DEV_CONFIG) {
2215 if (link->open)
2216 netif_device_detach(dev);
2217 pcmcia_release_configuration(link->handle);
2218 }
2219 break;
2220 case CS_EVENT_PM_RESUME:
2221 link->state &= ~DEV_SUSPEND;
2222 wl3501_pwr_mgmt(dev->priv, WL3501_RESUME);
2223 /* Fall through... */
2224 case CS_EVENT_CARD_RESET:
2225 if (link->state & DEV_CONFIG) {
2226 pcmcia_request_configuration(link->handle, &link->conf);
2227 if (link->open) {
2228 wl3501_reset(dev);
2229 netif_device_attach(dev);
2230 }
2231 }
2232 break;
2233 } 2244 }
2234 return 0; 2245 return 0;
2235} 2246}
@@ -2249,6 +2260,8 @@ static struct pcmcia_driver wl3501_driver = {
2249 .event = wl3501_event, 2260 .event = wl3501_event,
2250 .detach = wl3501_detach, 2261 .detach = wl3501_detach,
2251 .id_table = wl3501_ids, 2262 .id_table = wl3501_ids,
2263 .suspend = wl3501_suspend,
2264 .resume = wl3501_resume,
2252}; 2265};
2253 2266
2254static int __init wl3501_init_module(void) 2267static int __init wl3501_init_module(void)