diff options
Diffstat (limited to 'drivers/net/wireless/netwave_cs.c')
-rw-r--r-- | drivers/net/wireless/netwave_cs.c | 184 |
1 files changed, 53 insertions, 131 deletions
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c index 92793b958e32..bf6271ee387a 100644 --- a/drivers/net/wireless/netwave_cs.c +++ b/drivers/net/wireless/netwave_cs.c | |||
@@ -166,8 +166,6 @@ static char *version = | |||
166 | #define DEBUG(n, args...) | 166 | #define DEBUG(n, args...) |
167 | #endif | 167 | #endif |
168 | 168 | ||
169 | static dev_info_t dev_info = "netwave_cs"; | ||
170 | |||
171 | /*====================================================================*/ | 169 | /*====================================================================*/ |
172 | 170 | ||
173 | /* Parameters that can be set with 'insmod' */ | 171 | /* Parameters that can be set with 'insmod' */ |
@@ -195,12 +193,9 @@ module_param(mem_speed, int, 0); | |||
195 | 193 | ||
196 | /* PCMCIA (Card Services) related functions */ | 194 | /* PCMCIA (Card Services) related functions */ |
197 | static void netwave_release(dev_link_t *link); /* Card removal */ | 195 | static void netwave_release(dev_link_t *link); /* Card removal */ |
198 | static int netwave_event(event_t event, int priority, | ||
199 | event_callback_args_t *args); | ||
200 | static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card | 196 | static void netwave_pcmcia_config(dev_link_t *arg); /* Runs after card |
201 | insertion */ | 197 | insertion */ |
202 | static dev_link_t *netwave_attach(void); /* Create instance */ | 198 | static void netwave_detach(struct pcmcia_device *p_dev); /* Destroy instance */ |
203 | static void netwave_detach(dev_link_t *); /* Destroy instance */ | ||
204 | 199 | ||
205 | /* Hardware configuration */ | 200 | /* Hardware configuration */ |
206 | static void netwave_doreset(kio_addr_t iobase, u_char __iomem *ramBase); | 201 | static void netwave_doreset(kio_addr_t iobase, u_char __iomem *ramBase); |
@@ -228,17 +223,6 @@ static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev); | |||
228 | static void set_multicast_list(struct net_device *dev); | 223 | static void set_multicast_list(struct net_device *dev); |
229 | 224 | ||
230 | /* | 225 | /* |
231 | A linked list of "instances" of the skeleton device. Each actual | ||
232 | PCMCIA card corresponds to one device instance, and is described | ||
233 | by one dev_link_t structure (defined in ds.h). | ||
234 | |||
235 | You may not want to use a linked list for this -- for example, the | ||
236 | memory card driver uses an array of dev_link_t pointers, where minor | ||
237 | device numbers are used to derive the corresponding array index. | ||
238 | */ | ||
239 | static dev_link_t *dev_list; | ||
240 | |||
241 | /* | ||
242 | A dev_link_t structure has fields for most things that are needed | 226 | A dev_link_t structure has fields for most things that are needed |
243 | to keep track of a socket, but there will usually be some device | 227 | to keep track of a socket, but there will usually be some device |
244 | specific information that also needs to be kept track of. The | 228 | specific information that also needs to be kept track of. The |
@@ -394,20 +378,18 @@ static struct iw_statistics *netwave_get_wireless_stats(struct net_device *dev) | |||
394 | * configure the card at this point -- we wait until we receive a | 378 | * configure the card at this point -- we wait until we receive a |
395 | * card insertion event. | 379 | * card insertion event. |
396 | */ | 380 | */ |
397 | static dev_link_t *netwave_attach(void) | 381 | static int netwave_attach(struct pcmcia_device *p_dev) |
398 | { | 382 | { |
399 | client_reg_t client_reg; | ||
400 | dev_link_t *link; | 383 | dev_link_t *link; |
401 | struct net_device *dev; | 384 | struct net_device *dev; |
402 | netwave_private *priv; | 385 | netwave_private *priv; |
403 | int ret; | 386 | |
404 | |||
405 | DEBUG(0, "netwave_attach()\n"); | 387 | DEBUG(0, "netwave_attach()\n"); |
406 | 388 | ||
407 | /* Initialize the dev_link_t structure */ | 389 | /* Initialize the dev_link_t structure */ |
408 | dev = alloc_etherdev(sizeof(netwave_private)); | 390 | dev = alloc_etherdev(sizeof(netwave_private)); |
409 | if (!dev) | 391 | if (!dev) |
410 | return NULL; | 392 | return -ENOMEM; |
411 | priv = netdev_priv(dev); | 393 | priv = netdev_priv(dev); |
412 | link = &priv->link; | 394 | link = &priv->link; |
413 | link->priv = dev; | 395 | link->priv = dev; |
@@ -449,21 +431,14 @@ static dev_link_t *netwave_attach(void) | |||
449 | dev->open = &netwave_open; | 431 | dev->open = &netwave_open; |
450 | dev->stop = &netwave_close; | 432 | dev->stop = &netwave_close; |
451 | link->irq.Instance = dev; | 433 | link->irq.Instance = dev; |
452 | |||
453 | /* Register with Card Services */ | ||
454 | link->next = dev_list; | ||
455 | dev_list = link; | ||
456 | client_reg.dev_info = &dev_info; | ||
457 | client_reg.Version = 0x0210; | ||
458 | client_reg.event_callback_args.client_data = link; | ||
459 | ret = pcmcia_register_client(&link->handle, &client_reg); | ||
460 | if (ret != 0) { | ||
461 | cs_error(link->handle, RegisterClient, ret); | ||
462 | netwave_detach(link); | ||
463 | return NULL; | ||
464 | } | ||
465 | 434 | ||
466 | return link; | 435 | link->handle = p_dev; |
436 | p_dev->instance = link; | ||
437 | |||
438 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
439 | netwave_pcmcia_config( link); | ||
440 | |||
441 | return 0; | ||
467 | } /* netwave_attach */ | 442 | } /* netwave_attach */ |
468 | 443 | ||
469 | /* | 444 | /* |
@@ -474,42 +449,20 @@ static dev_link_t *netwave_attach(void) | |||
474 | * structures are freed. Otherwise, the structures will be freed | 449 | * structures are freed. Otherwise, the structures will be freed |
475 | * when the device is released. | 450 | * when the device is released. |
476 | */ | 451 | */ |
477 | static void netwave_detach(dev_link_t *link) | 452 | static void netwave_detach(struct pcmcia_device *p_dev) |
478 | { | 453 | { |
479 | struct net_device *dev = link->priv; | 454 | dev_link_t *link = dev_to_instance(p_dev); |
480 | dev_link_t **linkp; | 455 | struct net_device *dev = link->priv; |
481 | 456 | ||
482 | DEBUG(0, "netwave_detach(0x%p)\n", link); | 457 | DEBUG(0, "netwave_detach(0x%p)\n", link); |
483 | 458 | ||
484 | /* | 459 | if (link->state & DEV_CONFIG) |
485 | If the device is currently configured and active, we won't | 460 | netwave_release(link); |
486 | actually delete it yet. Instead, it is marked so that when | 461 | |
487 | the release() function is called, that will trigger a proper | 462 | if (link->dev) |
488 | detach(). | 463 | unregister_netdev(dev); |
489 | */ | 464 | |
490 | if (link->state & DEV_CONFIG) | 465 | free_netdev(dev); |
491 | netwave_release(link); | ||
492 | |||
493 | /* Break the link with Card Services */ | ||
494 | if (link->handle) | ||
495 | pcmcia_deregister_client(link->handle); | ||
496 | |||
497 | /* Locate device structure */ | ||
498 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
499 | if (*linkp == link) break; | ||
500 | if (*linkp == NULL) | ||
501 | { | ||
502 | DEBUG(1, "netwave_cs: detach fail, '%s' not in list\n", | ||
503 | link->dev->dev_name); | ||
504 | return; | ||
505 | } | ||
506 | |||
507 | /* Unlink device structure, free pieces */ | ||
508 | *linkp = link->next; | ||
509 | if (link->dev) | ||
510 | unregister_netdev(dev); | ||
511 | free_netdev(dev); | ||
512 | |||
513 | } /* netwave_detach */ | 466 | } /* netwave_detach */ |
514 | 467 | ||
515 | /* | 468 | /* |
@@ -935,69 +888,38 @@ static void netwave_release(dev_link_t *link) | |||
935 | link->state &= ~DEV_CONFIG; | 888 | link->state &= ~DEV_CONFIG; |
936 | } | 889 | } |
937 | 890 | ||
938 | /* | 891 | static int netwave_suspend(struct pcmcia_device *p_dev) |
939 | * Function netwave_event (event, priority, args) | ||
940 | * | ||
941 | * The card status event handler. Mostly, this schedules other | ||
942 | * stuff to run after an event is received. A CARD_REMOVAL event | ||
943 | * also sets some flags to discourage the net drivers from trying | ||
944 | * to talk to the card any more. | ||
945 | * | ||
946 | * When a CARD_REMOVAL event is received, we immediately set a flag | ||
947 | * to block future accesses to this device. All the functions that | ||
948 | * actually access the device should check this flag to make sure | ||
949 | * the card is still present. | ||
950 | * | ||
951 | */ | ||
952 | static int netwave_event(event_t event, int priority, | ||
953 | event_callback_args_t *args) | ||
954 | { | 892 | { |
955 | dev_link_t *link = args->client_data; | 893 | dev_link_t *link = dev_to_instance(p_dev); |
956 | struct net_device *dev = link->priv; | 894 | struct net_device *dev = link->priv; |
957 | 895 | ||
958 | DEBUG(1, "netwave_event(0x%06x)\n", event); | ||
959 | |||
960 | switch (event) { | ||
961 | case CS_EVENT_REGISTRATION_COMPLETE: | ||
962 | DEBUG(0, "netwave_cs: registration complete\n"); | ||
963 | break; | ||
964 | |||
965 | case CS_EVENT_CARD_REMOVAL: | ||
966 | link->state &= ~DEV_PRESENT; | ||
967 | if (link->state & DEV_CONFIG) { | ||
968 | netif_device_detach(dev); | ||
969 | netwave_release(link); | ||
970 | } | ||
971 | break; | ||
972 | case CS_EVENT_CARD_INSERTION: | ||
973 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
974 | netwave_pcmcia_config( link); | ||
975 | break; | ||
976 | case CS_EVENT_PM_SUSPEND: | ||
977 | link->state |= DEV_SUSPEND; | 896 | link->state |= DEV_SUSPEND; |
978 | /* Fall through... */ | ||
979 | case CS_EVENT_RESET_PHYSICAL: | ||
980 | if (link->state & DEV_CONFIG) { | 897 | if (link->state & DEV_CONFIG) { |
981 | if (link->open) | 898 | if (link->open) |
982 | netif_device_detach(dev); | 899 | netif_device_detach(dev); |
983 | pcmcia_release_configuration(link->handle); | 900 | pcmcia_release_configuration(link->handle); |
984 | } | 901 | } |
985 | break; | 902 | |
986 | case CS_EVENT_PM_RESUME: | 903 | return 0; |
904 | } | ||
905 | |||
906 | static int netwave_resume(struct pcmcia_device *p_dev) | ||
907 | { | ||
908 | dev_link_t *link = dev_to_instance(p_dev); | ||
909 | struct net_device *dev = link->priv; | ||
910 | |||
987 | link->state &= ~DEV_SUSPEND; | 911 | link->state &= ~DEV_SUSPEND; |
988 | /* Fall through... */ | ||
989 | case CS_EVENT_CARD_RESET: | ||
990 | if (link->state & DEV_CONFIG) { | 912 | if (link->state & DEV_CONFIG) { |
991 | pcmcia_request_configuration(link->handle, &link->conf); | 913 | pcmcia_request_configuration(link->handle, &link->conf); |
992 | if (link->open) { | 914 | if (link->open) { |
993 | netwave_reset(dev); | 915 | netwave_reset(dev); |
994 | netif_device_attach(dev); | 916 | netif_device_attach(dev); |
995 | } | 917 | } |
996 | } | 918 | } |
997 | break; | 919 | |
998 | } | 920 | return 0; |
999 | return 0; | 921 | } |
1000 | } /* netwave_event */ | 922 | |
1001 | 923 | ||
1002 | /* | 924 | /* |
1003 | * Function netwave_doreset (ioBase, ramBase) | 925 | * Function netwave_doreset (ioBase, ramBase) |
@@ -1491,10 +1413,11 @@ static struct pcmcia_driver netwave_driver = { | |||
1491 | .drv = { | 1413 | .drv = { |
1492 | .name = "netwave_cs", | 1414 | .name = "netwave_cs", |
1493 | }, | 1415 | }, |
1494 | .attach = netwave_attach, | 1416 | .probe = netwave_attach, |
1495 | .event = netwave_event, | 1417 | .remove = netwave_detach, |
1496 | .detach = netwave_detach, | ||
1497 | .id_table = netwave_ids, | 1418 | .id_table = netwave_ids, |
1419 | .suspend = netwave_suspend, | ||
1420 | .resume = netwave_resume, | ||
1498 | }; | 1421 | }; |
1499 | 1422 | ||
1500 | static int __init init_netwave_cs(void) | 1423 | static int __init init_netwave_cs(void) |
@@ -1505,7 +1428,6 @@ static int __init init_netwave_cs(void) | |||
1505 | static void __exit exit_netwave_cs(void) | 1428 | static void __exit exit_netwave_cs(void) |
1506 | { | 1429 | { |
1507 | pcmcia_unregister_driver(&netwave_driver); | 1430 | pcmcia_unregister_driver(&netwave_driver); |
1508 | BUG_ON(dev_list != NULL); | ||
1509 | } | 1431 | } |
1510 | 1432 | ||
1511 | module_init(init_netwave_cs); | 1433 | module_init(init_netwave_cs); |