aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/hostap/hostap_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/hostap/hostap_cs.c')
-rw-r--r--drivers/net/wireless/hostap/hostap_cs.c156
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
26static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)"; 26static char *version = PRISM2_VERSION " (Jouni Malinen <jkmaline@cc.hut.fi>)";
27static dev_info_t dev_info = "hostap_cs"; 27static dev_info_t dev_info = "hostap_cs";
28static dev_link_t *dev_list = NULL;
29 28
30MODULE_AUTHOR("Jouni Malinen"); 29MODULE_AUTHOR("Jouni Malinen");
31MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN " 30MODULE_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
206static void prism2_detach(dev_link_t *link); 205static void prism2_detach(struct pcmcia_device *p_dev);
207static void prism2_release(u_long arg); 206static void prism2_release(u_long arg);
208static int prism2_event(event_t event, int priority, 207static int prism2_config(dev_link_t *link);
209 event_callback_args_t *args);
210 208
211 209
212static int prism2_pccard_card_present(local_info_t *local) 210static 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 */
506static dev_link_t *prism2_attach(void) 504static 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
538static void prism2_detach(dev_link_t *link) 529static 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 822static int hostap_cs_suspend(struct pcmcia_device *p_dev)
850static 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: 847static 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
927static struct pcmcia_device_id hostap_cs_ids[] = { 874static 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
992static int __init init_prism2_pccard(void) 940static int __init init_prism2_pccard(void)