diff options
Diffstat (limited to 'drivers/net/wireless/hostap/hostap_cs.c')
-rw-r--r-- | drivers/net/wireless/hostap/hostap_cs.c | 156 |
1 files changed, 52 insertions, 104 deletions
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 2643976a6677..8bc0b528548f 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c | |||
@@ -25,7 +25,6 @@ | |||
25 | 25 | ||
26 | static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)"; | 26 | static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)"; |
27 | static dev_info_t dev_info = "hostap_cs"; | 27 | static dev_info_t dev_info = "hostap_cs"; |
28 | static dev_link_t *dev_list = NULL; | ||
29 | 28 | ||
30 | MODULE_AUTHOR("Jouni Malinen"); | 29 | MODULE_AUTHOR("Jouni Malinen"); |
31 | MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN " | 30 | MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN " |
@@ -203,10 +202,9 @@ static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len) | |||
203 | 202 | ||
204 | 203 | ||
205 | 204 | ||
206 | static void prism2_detach(dev_link_t *link); | 205 | static void prism2_detach(struct pcmcia_device *p_dev); |
207 | static void prism2_release(u_long arg); | 206 | static void prism2_release(u_long arg); |
208 | static int prism2_event(event_t event, int priority, | 207 | static int prism2_config(dev_link_t *link); |
209 | event_callback_args_t *args); | ||
210 | 208 | ||
211 | 209 | ||
212 | static int prism2_pccard_card_present(local_info_t *local) | 210 | static int prism2_pccard_card_present(local_info_t *local) |
@@ -503,15 +501,13 @@ static struct prism2_helper_functions prism2_pccard_funcs = | |||
503 | 501 | ||
504 | /* allocate local data and register with CardServices | 502 | /* allocate local data and register with CardServices |
505 | * initialize dev_link structure, but do not configure the card yet */ | 503 | * initialize dev_link structure, but do not configure the card yet */ |
506 | static dev_link_t *prism2_attach(void) | 504 | static int prism2_attach(struct pcmcia_device *p_dev) |
507 | { | 505 | { |
508 | dev_link_t *link; | 506 | dev_link_t *link; |
509 | client_reg_t client_reg; | ||
510 | int ret; | ||
511 | 507 | ||
512 | link = kmalloc(sizeof(dev_link_t), GFP_KERNEL); | 508 | link = kmalloc(sizeof(dev_link_t), GFP_KERNEL); |
513 | if (link == NULL) | 509 | if (link == NULL) |
514 | return NULL; | 510 | return -ENOMEM; |
515 | 511 | ||
516 | memset(link, 0, sizeof(dev_link_t)); | 512 | memset(link, 0, sizeof(dev_link_t)); |
517 | 513 | ||
@@ -519,50 +515,27 @@ static dev_link_t *prism2_attach(void) | |||
519 | link->conf.Vcc = 33; | 515 | link->conf.Vcc = 33; |
520 | link->conf.IntType = INT_MEMORY_AND_IO; | 516 | link->conf.IntType = INT_MEMORY_AND_IO; |
521 | 517 | ||
522 | /* register with CardServices */ | 518 | link->handle = p_dev; |
523 | link->next = dev_list; | 519 | p_dev->instance = link; |
524 | dev_list = link; | 520 | |
525 | client_reg.dev_info = &dev_info; | 521 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
526 | client_reg.Version = 0x0210; | 522 | if (prism2_config(link)) |
527 | client_reg.event_callback_args.client_data = link; | 523 | PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n"); |
528 | ret = pcmcia_register_client(&link->handle, &client_reg); | 524 | |
529 | if (ret != CS_SUCCESS) { | 525 | return 0; |
530 | cs_error(link->handle, RegisterClient, ret); | ||
531 | prism2_detach(link); | ||
532 | return NULL; | ||
533 | } | ||
534 | return link; | ||
535 | } | 526 | } |
536 | 527 | ||
537 | 528 | ||
538 | static void prism2_detach(dev_link_t *link) | 529 | static void prism2_detach(struct pcmcia_device *p_dev) |
539 | { | 530 | { |
540 | dev_link_t **linkp; | 531 | dev_link_t *link = dev_to_instance(p_dev); |
541 | 532 | ||
542 | PDEBUG(DEBUG_FLOW, "prism2_detach\n"); | 533 | PDEBUG(DEBUG_FLOW, "prism2_detach\n"); |
543 | 534 | ||
544 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
545 | if (*linkp == link) | ||
546 | break; | ||
547 | if (*linkp == NULL) { | ||
548 | printk(KERN_WARNING "%s: Attempt to detach non-existing " | ||
549 | "PCMCIA client\n", dev_info); | ||
550 | return; | ||
551 | } | ||
552 | |||
553 | if (link->state & DEV_CONFIG) { | 535 | if (link->state & DEV_CONFIG) { |
554 | prism2_release((u_long)link); | 536 | prism2_release((u_long)link); |
555 | } | 537 | } |
556 | 538 | ||
557 | if (link->handle) { | ||
558 | int res = pcmcia_deregister_client(link->handle); | ||
559 | if (res) { | ||
560 | printk("CardService(DeregisterClient) => %d\n", res); | ||
561 | cs_error(link->handle, DeregisterClient, res); | ||
562 | } | ||
563 | } | ||
564 | |||
565 | *linkp = link->next; | ||
566 | /* release net devices */ | 539 | /* release net devices */ |
567 | if (link->priv) { | 540 | if (link->priv) { |
568 | struct hostap_cs_priv *hw_priv; | 541 | struct hostap_cs_priv *hw_priv; |
@@ -846,84 +819,58 @@ static void prism2_release(u_long arg) | |||
846 | PDEBUG(DEBUG_FLOW, "release - done\n"); | 819 | PDEBUG(DEBUG_FLOW, "release - done\n"); |
847 | } | 820 | } |
848 | 821 | ||
849 | 822 | static int hostap_cs_suspend(struct pcmcia_device *p_dev) | |
850 | static int prism2_event(event_t event, int priority, | ||
851 | event_callback_args_t *args) | ||
852 | { | 823 | { |
853 | dev_link_t *link = args->client_data; | 824 | dev_link_t *link = dev_to_instance(p_dev); |
854 | struct net_device *dev = (struct net_device *) link->priv; | 825 | struct net_device *dev = (struct net_device *) link->priv; |
855 | int dev_open = 0; | 826 | int dev_open = 0; |
856 | 827 | ||
828 | PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info); | ||
829 | |||
830 | link->state |= DEV_SUSPEND; | ||
831 | |||
857 | if (link->state & DEV_CONFIG) { | 832 | if (link->state & DEV_CONFIG) { |
858 | struct hostap_interface *iface = netdev_priv(dev); | 833 | struct hostap_interface *iface = netdev_priv(dev); |
859 | if (iface && iface->local) | 834 | if (iface && iface->local) |
860 | dev_open = iface->local->num_dev_open > 0; | 835 | dev_open = iface->local->num_dev_open > 0; |
861 | } | 836 | if (dev_open) { |
862 | |||
863 | switch (event) { | ||
864 | case CS_EVENT_CARD_INSERTION: | ||
865 | PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info); | ||
866 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
867 | if (prism2_config(link)) { | ||
868 | PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n"); | ||
869 | } | ||
870 | break; | ||
871 | |||
872 | case CS_EVENT_CARD_REMOVAL: | ||
873 | PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_REMOVAL\n", dev_info); | ||
874 | link->state &= ~DEV_PRESENT; | ||
875 | if (link->state & DEV_CONFIG) { | ||
876 | netif_stop_queue(dev); | 837 | netif_stop_queue(dev); |
877 | netif_device_detach(dev); | 838 | netif_device_detach(dev); |
878 | prism2_release((u_long) link); | ||
879 | } | 839 | } |
880 | break; | 840 | prism2_suspend(dev); |
841 | pcmcia_release_configuration(link->handle); | ||
842 | } | ||
881 | 843 | ||
882 | case CS_EVENT_PM_SUSPEND: | 844 | return 0; |
883 | PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info); | 845 | } |
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 | 846 | ||
899 | case CS_EVENT_PM_RESUME: | 847 | static int hostap_cs_resume(struct pcmcia_device *p_dev) |
900 | PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info); | 848 | { |
901 | link->state &= ~DEV_SUSPEND; | 849 | dev_link_t *link = dev_to_instance(p_dev); |
902 | /* fall through */ | 850 | struct net_device *dev = (struct net_device *) link->priv; |
903 | 851 | int dev_open = 0; | |
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 | 852 | ||
918 | default: | 853 | PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info); |
919 | PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n", | 854 | |
920 | dev_info, event); | 855 | link->state &= ~DEV_SUSPEND; |
921 | break; | 856 | if (link->state & DEV_CONFIG) { |
857 | struct hostap_interface *iface = netdev_priv(dev); | ||
858 | if (iface && iface->local) | ||
859 | dev_open = iface->local->num_dev_open > 0; | ||
860 | |||
861 | pcmcia_request_configuration(link->handle, &link->conf); | ||
862 | |||
863 | prism2_hw_shutdown(dev, 1); | ||
864 | prism2_hw_config(dev, dev_open ? 0 : 1); | ||
865 | if (dev_open) { | ||
866 | netif_device_attach(dev); | ||
867 | netif_start_queue(dev); | ||
868 | } | ||
922 | } | 869 | } |
870 | |||
923 | return 0; | 871 | return 0; |
924 | } | 872 | } |
925 | 873 | ||
926 | |||
927 | static struct pcmcia_device_id hostap_cs_ids[] = { | 874 | static struct pcmcia_device_id hostap_cs_ids[] = { |
928 | PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), | 875 | PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), |
929 | PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), | 876 | PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), |
@@ -982,11 +929,12 @@ static struct pcmcia_driver hostap_driver = { | |||
982 | .drv = { | 929 | .drv = { |
983 | .name = "hostap_cs", | 930 | .name = "hostap_cs", |
984 | }, | 931 | }, |
985 | .attach = prism2_attach, | 932 | .probe = prism2_attach, |
986 | .detach = prism2_detach, | 933 | .remove = prism2_detach, |
987 | .owner = THIS_MODULE, | 934 | .owner = THIS_MODULE, |
988 | .event = prism2_event, | ||
989 | .id_table = hostap_cs_ids, | 935 | .id_table = hostap_cs_ids, |
936 | .suspend = hostap_cs_suspend, | ||
937 | .resume = hostap_cs_resume, | ||
990 | }; | 938 | }; |
991 | 939 | ||
992 | static int __init init_prism2_pccard(void) | 940 | static int __init init_prism2_pccard(void) |