aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/wireless/ray_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/wireless/ray_cs.c')
-rw-r--r--drivers/net/wireless/ray_cs.c154
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 *******************************/
93static void ray_config(dev_link_t *link); 93static void ray_config(dev_link_t *link);
94static void ray_release(dev_link_t *link); 94static void ray_release(dev_link_t *link);
95static int ray_event(event_t event, int priority, event_callback_args_t *args); 95static void ray_detach(struct pcmcia_device *p_dev);
96static dev_link_t *ray_attach(void);
97static void ray_detach(dev_link_t *);
98 96
99/***** Prototypes indicated by device structure ******************************/ 97/***** Prototypes indicated by device structure ******************************/
100static int ray_dev_close(struct net_device *dev); 98static int ray_dev_close(struct net_device *dev);
@@ -192,12 +190,6 @@ static int bc;
192static char *phy_addr = NULL; 190static 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*/
199static 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=============================================================================*/
317static dev_link_t *ray_attach(void) 309static 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
411fail_alloc_dev: 390fail_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=============================================================================*/
421static void ray_detach(dev_link_t *link) 400static 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/*============================================================================= 872static 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=============================================================================*/
905static 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
889static 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/*===========================================================================*/
954int ray_dev_init(struct net_device *dev) 907int 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
2954static int __init init_ray_cs(void) 2908static int __init init_ray_cs(void)