diff options
author | Dominik Brodowski <linux@dominikbrodowski.net> | 2005-11-14 15:21:18 -0500 |
---|---|---|
committer | Dominik Brodowski <linux@dominikbrodowski.net> | 2006-01-05 17:59:02 -0500 |
commit | 98e4c28b7ec390c2dad6a4c69d69629c0f7e8b10 (patch) | |
tree | b3d46f0643352e541d6a39e6da09059687cf713d /drivers/net | |
parent | 63e7ebd06402951bc8863ba5b7bc9b9f42044849 (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.c | 56 | ||||
-rw-r--r-- | drivers/net/pcmcia/3c589_cs.c | 56 | ||||
-rw-r--r-- | drivers/net/pcmcia/axnet_cs.c | 59 | ||||
-rw-r--r-- | drivers/net/pcmcia/com20020_cs.c | 62 | ||||
-rw-r--r-- | drivers/net/pcmcia/fmvj18x_cs.c | 57 | ||||
-rw-r--r-- | drivers/net/pcmcia/ibmtr_cs.c | 59 | ||||
-rw-r--r-- | drivers/net/pcmcia/nmclan_cs.c | 57 | ||||
-rw-r--r-- | drivers/net/pcmcia/pcnet_cs.c | 58 | ||||
-rw-r--r-- | drivers/net/pcmcia/smc91c92_cs.c | 109 | ||||
-rw-r--r-- | drivers/net/pcmcia/xirc2ps_cs.c | 61 | ||||
-rw-r--r-- | drivers/net/wireless/airo_cs.c | 50 | ||||
-rw-r--r-- | drivers/net/wireless/atmel_cs.c | 50 | ||||
-rw-r--r-- | drivers/net/wireless/hostap/hostap_cs.c | 88 | ||||
-rw-r--r-- | drivers/net/wireless/netwave_cs.c | 57 | ||||
-rw-r--r-- | drivers/net/wireless/orinoco_cs.c | 145 | ||||
-rw-r--r-- | drivers/net/wireless/ray_cs.c | 59 | ||||
-rw-r--r-- | drivers/net/wireless/spectrum_cs.c | 96 | ||||
-rw-r--r-- | drivers/net/wireless/wavelan_cs.c | 92 | ||||
-rw-r--r-- | drivers/net/wireless/wl3501_cs.c | 61 |
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 | ||
550 | static 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 | |||
565 | static 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 | ||
1301 | static int __init init_tc574(void) | 1313 | static 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 | ||
424 | static 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 | |||
439 | static 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 | ||
1076 | static int __init init_tc589(void) | 1088 | static 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 | ||
493 | static 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 | |||
508 | static 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 | ||
886 | static int __init init_axnet_cs(void) | 899 | static 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 | ||
424 | static 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 | |||
441 | static 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 | ||
497 | static int __init init_com20020_cs(void) | 511 | static 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 | ||
716 | static 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 | |||
732 | static 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 | ||
718 | static int fmvj18x_event(event_t event, int priority, | 751 | static 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 | ||
798 | static int __init init_fmvj18x_cs(void) | 811 | static 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 | ||
404 | static 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 | |||
420 | static 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 | ||
523 | static int __init init_ibmtr_cs(void) | 538 | static 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 | ||
804 | static 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 | |||
820 | static 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 | /* ---------------------------------------------------------------------------- |
805 | nmclan_event | 838 | nmclan_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 | ||
1690 | static int __init init_nmclan_cs(void) | 1703 | static 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 | ||
783 | static 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 | |||
798 | static 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 | |||
783 | static int pcnet_event(event_t event, int priority, | 816 | static 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 | ||
1854 | static int __init init_pcnet_cs(void) | 1866 | static 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 | ||
898 | static 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 | |||
913 | static 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 | ||
2369 | static int __init init_smc91c92_cs(void) | 2380 | static 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 | |||
1161 | static 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 | |||
1178 | static 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 | ||
2018 | static int __init | 2031 | static 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 | ||
495 | static 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 | |||
509 | static 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 | ||
570 | static int airo_cs_init(void) | 582 | static 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 | ||
480 | static 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 | |||
494 | static 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 | ||
590 | static int atmel_cs_init(void) | 602 | static 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 | ||
849 | static 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 | ||
850 | static 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 | |||
874 | static 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 | |||
901 | static 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 | ||
992 | static int __init init_prism2_pccard(void) | 1002 | static 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 | ||
938 | static 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 | |||
953 | static 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 | ||
1500 | static int __init init_netwave_cs(void) | 1513 | static 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 | ||
468 | static 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 | |||
502 | static 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 | ||
674 | static int __init | 687 | static 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 | ||
894 | static 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 | |||
911 | static 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 | ||
2954 | static int __init init_ray_cs(void) | 2967 | static 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 | |||
952 | static int | ||
953 | spectrum_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 | |||
982 | static int | ||
983 | spectrum_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 | ||
4778 | static 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 | |||
4808 | static 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 | ||
4903 | static int __init | 4915 | static 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 | ||
2176 | static 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 | |||
2193 | static 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 | ||
2254 | static int __init wl3501_init_module(void) | 2267 | static int __init wl3501_init_module(void) |