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/wireless | |
| 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/wireless')
| -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 |
9 files changed, 403 insertions, 295 deletions
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c index e328547599..80c9de749b 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 17d1fd90f8..598a9cd0f8 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 2643976a66..ba4a7da98c 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 92793b958e..7ab2d70ffd 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 dc1128a009..1d66050e3d 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 70fd6fd8fe..c2cb6c8e6d 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 b1bbc8e8e9..3938a57356 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 c822cad333..3e3532830c 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 978fdc6067..7511431845 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) |
