diff options
Diffstat (limited to 'drivers/net/wireless/ray_cs.c')
-rw-r--r-- | drivers/net/wireless/ray_cs.c | 154 |
1 files changed, 54 insertions, 100 deletions
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c index 70fd6fd8feb9..319180ca7e71 100644 --- a/drivers/net/wireless/ray_cs.c +++ b/drivers/net/wireless/ray_cs.c | |||
@@ -92,9 +92,7 @@ module_param(pc_debug, int, 0); | |||
92 | /** Prototypes based on PCMCIA skeleton driver *******************************/ | 92 | /** Prototypes based on PCMCIA skeleton driver *******************************/ |
93 | static void ray_config(dev_link_t *link); | 93 | static void ray_config(dev_link_t *link); |
94 | static void ray_release(dev_link_t *link); | 94 | static void ray_release(dev_link_t *link); |
95 | static int ray_event(event_t event, int priority, event_callback_args_t *args); | 95 | static void ray_detach(struct pcmcia_device *p_dev); |
96 | static dev_link_t *ray_attach(void); | ||
97 | static void ray_detach(dev_link_t *); | ||
98 | 96 | ||
99 | /***** Prototypes indicated by device structure ******************************/ | 97 | /***** Prototypes indicated by device structure ******************************/ |
100 | static int ray_dev_close(struct net_device *dev); | 98 | static int ray_dev_close(struct net_device *dev); |
@@ -192,12 +190,6 @@ static int bc; | |||
192 | static char *phy_addr = NULL; | 190 | static char *phy_addr = NULL; |
193 | 191 | ||
194 | 192 | ||
195 | /* The dev_info variable is the "key" that is used to match up this | ||
196 | device driver with appropriate cards, through the card configuration | ||
197 | database. | ||
198 | */ | ||
199 | static dev_info_t dev_info = "ray_cs"; | ||
200 | |||
201 | /* A linked list of "instances" of the ray device. Each actual | 193 | /* A linked list of "instances" of the ray device. Each actual |
202 | PCMCIA card corresponds to one device instance, and is described | 194 | PCMCIA card corresponds to one device instance, and is described |
203 | by one dev_link_t structure (defined in ds.h). | 195 | by one dev_link_t structure (defined in ds.h). |
@@ -314,12 +306,10 @@ static char rcsid[] = "Raylink/WebGear wireless LAN - Corey <Thomas corey@world. | |||
314 | configure the card at this point -- we wait until we receive a | 306 | configure the card at this point -- we wait until we receive a |
315 | card insertion event. | 307 | card insertion event. |
316 | =============================================================================*/ | 308 | =============================================================================*/ |
317 | static dev_link_t *ray_attach(void) | 309 | static int ray_attach(struct pcmcia_device *p_dev) |
318 | { | 310 | { |
319 | client_reg_t client_reg; | ||
320 | dev_link_t *link; | 311 | dev_link_t *link; |
321 | ray_dev_t *local; | 312 | ray_dev_t *local; |
322 | int ret; | ||
323 | struct net_device *dev; | 313 | struct net_device *dev; |
324 | 314 | ||
325 | DEBUG(1, "ray_attach()\n"); | 315 | DEBUG(1, "ray_attach()\n"); |
@@ -328,7 +318,7 @@ static dev_link_t *ray_attach(void) | |||
328 | link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); | 318 | link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); |
329 | 319 | ||
330 | if (!link) | 320 | if (!link) |
331 | return NULL; | 321 | return -ENOMEM; |
332 | 322 | ||
333 | /* Allocate space for private device-specific data */ | 323 | /* Allocate space for private device-specific data */ |
334 | dev = alloc_etherdev(sizeof(ray_dev_t)); | 324 | dev = alloc_etherdev(sizeof(ray_dev_t)); |
@@ -387,30 +377,19 @@ static dev_link_t *ray_attach(void) | |||
387 | dev->stop = &ray_dev_close; | 377 | dev->stop = &ray_dev_close; |
388 | netif_stop_queue(dev); | 378 | netif_stop_queue(dev); |
389 | 379 | ||
390 | /* Register with Card Services */ | 380 | init_timer(&local->timer); |
391 | link->next = dev_list; | ||
392 | dev_list = link; | ||
393 | client_reg.dev_info = &dev_info; | ||
394 | client_reg.Version = 0x0210; | ||
395 | client_reg.event_callback_args.client_data = link; | ||
396 | 381 | ||
397 | DEBUG(2,"ray_cs ray_attach calling pcmcia_register_client(...)\n"); | 382 | link->handle = p_dev; |
383 | p_dev->instance = link; | ||
398 | 384 | ||
399 | init_timer(&local->timer); | 385 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
386 | ray_config(link); | ||
400 | 387 | ||
401 | ret = pcmcia_register_client(&link->handle, &client_reg); | 388 | return 0; |
402 | if (ret != 0) { | ||
403 | printk("ray_cs ray_attach RegisterClient unhappy - detaching\n"); | ||
404 | cs_error(link->handle, RegisterClient, ret); | ||
405 | ray_detach(link); | ||
406 | return NULL; | ||
407 | } | ||
408 | DEBUG(2,"ray_cs ray_attach ending\n"); | ||
409 | return link; | ||
410 | 389 | ||
411 | fail_alloc_dev: | 390 | fail_alloc_dev: |
412 | kfree(link); | 391 | kfree(link); |
413 | return NULL; | 392 | return -ENOMEM; |
414 | } /* ray_attach */ | 393 | } /* ray_attach */ |
415 | /*============================================================================= | 394 | /*============================================================================= |
416 | This deletes a driver "instance". The device is de-registered | 395 | This deletes a driver "instance". The device is de-registered |
@@ -418,9 +397,12 @@ fail_alloc_dev: | |||
418 | structures are freed. Otherwise, the structures will be freed | 397 | structures are freed. Otherwise, the structures will be freed |
419 | when the device is released. | 398 | when the device is released. |
420 | =============================================================================*/ | 399 | =============================================================================*/ |
421 | static void ray_detach(dev_link_t *link) | 400 | static void ray_detach(struct pcmcia_device *p_dev) |
422 | { | 401 | { |
402 | dev_link_t *link = dev_to_instance(p_dev); | ||
423 | dev_link_t **linkp; | 403 | dev_link_t **linkp; |
404 | struct net_device *dev; | ||
405 | ray_dev_t *local; | ||
424 | 406 | ||
425 | DEBUG(1, "ray_detach(0x%p)\n", link); | 407 | DEBUG(1, "ray_detach(0x%p)\n", link); |
426 | 408 | ||
@@ -430,22 +412,18 @@ static void ray_detach(dev_link_t *link) | |||
430 | if (*linkp == NULL) | 412 | if (*linkp == NULL) |
431 | return; | 413 | return; |
432 | 414 | ||
433 | /* If the device is currently configured and active, we won't | 415 | dev = link->priv; |
434 | actually delete it yet. Instead, it is marked so that when | 416 | |
435 | the release() function is called, that will trigger a proper | 417 | if (link->state & DEV_CONFIG) { |
436 | detach(). | 418 | ray_release(link); |
437 | */ | 419 | |
438 | if (link->state & DEV_CONFIG) | 420 | local = (ray_dev_t *)dev->priv; |
439 | ray_release(link); | 421 | del_timer(&local->timer); |
422 | } | ||
440 | 423 | ||
441 | /* Break the link with Card Services */ | ||
442 | if (link->handle) | ||
443 | pcmcia_deregister_client(link->handle); | ||
444 | |||
445 | /* Unlink device structure, free pieces */ | 424 | /* Unlink device structure, free pieces */ |
446 | *linkp = link->next; | 425 | *linkp = link->next; |
447 | if (link->priv) { | 426 | if (link->priv) { |
448 | struct net_device *dev = link->priv; | ||
449 | if (link->dev) unregister_netdev(dev); | 427 | if (link->dev) unregister_netdev(dev); |
450 | free_netdev(dev); | 428 | free_netdev(dev); |
451 | } | 429 | } |
@@ -891,65 +869,40 @@ static void ray_release(dev_link_t *link) | |||
891 | DEBUG(2,"ray_release ending\n"); | 869 | DEBUG(2,"ray_release ending\n"); |
892 | } | 870 | } |
893 | 871 | ||
894 | /*============================================================================= | 872 | static int ray_suspend(struct pcmcia_device *p_dev) |
895 | The card status event handler. Mostly, this schedules other | ||
896 | stuff to run after an event is received. A CARD_REMOVAL event | ||
897 | also sets some flags to discourage the net drivers from trying | ||
898 | to talk to the card any more. | ||
899 | |||
900 | When a CARD_REMOVAL event is received, we immediately set a flag | ||
901 | to block future accesses to this device. All the functions that | ||
902 | actually access the device should check this flag to make sure | ||
903 | the card is still present. | ||
904 | =============================================================================*/ | ||
905 | static int ray_event(event_t event, int priority, | ||
906 | event_callback_args_t *args) | ||
907 | { | 873 | { |
908 | dev_link_t *link = args->client_data; | 874 | dev_link_t *link = dev_to_instance(p_dev); |
909 | struct net_device *dev = link->priv; | 875 | struct net_device *dev = link->priv; |
910 | ray_dev_t *local = (ray_dev_t *)dev->priv; | 876 | |
911 | DEBUG(1, "ray_event(0x%06x)\n", event); | 877 | link->state |= DEV_SUSPEND; |
912 | |||
913 | switch (event) { | ||
914 | case CS_EVENT_CARD_REMOVAL: | ||
915 | link->state &= ~DEV_PRESENT; | ||
916 | netif_device_detach(dev); | ||
917 | if (link->state & DEV_CONFIG) { | ||
918 | ray_release(link); | ||
919 | del_timer(&local->timer); | ||
920 | } | ||
921 | break; | ||
922 | case CS_EVENT_CARD_INSERTION: | ||
923 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
924 | ray_config(link); | ||
925 | 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) { | 878 | if (link->state & DEV_CONFIG) { |
931 | if (link->open) | 879 | if (link->open) |
932 | netif_device_detach(dev); | 880 | netif_device_detach(dev); |
933 | 881 | ||
934 | pcmcia_release_configuration(link->handle); | 882 | pcmcia_release_configuration(link->handle); |
935 | } | 883 | } |
936 | break; | 884 | |
937 | case CS_EVENT_PM_RESUME: | 885 | |
938 | link->state &= ~DEV_SUSPEND; | 886 | return 0; |
939 | /* Fall through... */ | 887 | } |
940 | case CS_EVENT_CARD_RESET: | 888 | |
889 | static int ray_resume(struct pcmcia_device *p_dev) | ||
890 | { | ||
891 | dev_link_t *link = dev_to_instance(p_dev); | ||
892 | struct net_device *dev = link->priv; | ||
893 | |||
894 | link->state &= ~DEV_SUSPEND; | ||
941 | if (link->state & DEV_CONFIG) { | 895 | if (link->state & DEV_CONFIG) { |
942 | pcmcia_request_configuration(link->handle, &link->conf); | 896 | pcmcia_request_configuration(link->handle, &link->conf); |
943 | if (link->open) { | 897 | if (link->open) { |
944 | ray_reset(dev); | 898 | ray_reset(dev); |
945 | netif_device_attach(dev); | 899 | netif_device_attach(dev); |
946 | } | 900 | } |
947 | } | 901 | } |
948 | break; | 902 | |
949 | } | 903 | return 0; |
950 | return 0; | 904 | } |
951 | DEBUG(2,"ray_event ending\n"); | 905 | |
952 | } /* ray_event */ | ||
953 | /*===========================================================================*/ | 906 | /*===========================================================================*/ |
954 | int ray_dev_init(struct net_device *dev) | 907 | int ray_dev_init(struct net_device *dev) |
955 | { | 908 | { |
@@ -2945,10 +2898,11 @@ static struct pcmcia_driver ray_driver = { | |||
2945 | .drv = { | 2898 | .drv = { |
2946 | .name = "ray_cs", | 2899 | .name = "ray_cs", |
2947 | }, | 2900 | }, |
2948 | .attach = ray_attach, | 2901 | .probe = ray_attach, |
2949 | .event = ray_event, | 2902 | .remove = ray_detach, |
2950 | .detach = ray_detach, | ||
2951 | .id_table = ray_ids, | 2903 | .id_table = ray_ids, |
2904 | .suspend = ray_suspend, | ||
2905 | .resume = ray_resume, | ||
2952 | }; | 2906 | }; |
2953 | 2907 | ||
2954 | static int __init init_ray_cs(void) | 2908 | static int __init init_ray_cs(void) |