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) |
