diff options
Diffstat (limited to 'drivers/net/pcmcia/xirc2ps_cs.c')
-rw-r--r-- | drivers/net/pcmcia/xirc2ps_cs.c | 158 |
1 files changed, 42 insertions, 116 deletions
diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index ce143f08638a..049c34b37067 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c | |||
@@ -292,8 +292,6 @@ static void mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg, | |||
292 | static int has_ce2_string(dev_link_t * link); | 292 | static int has_ce2_string(dev_link_t * link); |
293 | static void xirc2ps_config(dev_link_t * link); | 293 | static void xirc2ps_config(dev_link_t * link); |
294 | static void xirc2ps_release(dev_link_t * link); | 294 | static void xirc2ps_release(dev_link_t * link); |
295 | static int xirc2ps_event(event_t event, int priority, | ||
296 | event_callback_args_t * args); | ||
297 | 295 | ||
298 | /**************** | 296 | /**************** |
299 | * The attach() and detach() entry points are used to create and destroy | 297 | * The attach() and detach() entry points are used to create and destroy |
@@ -301,8 +299,7 @@ static int xirc2ps_event(event_t event, int priority, | |||
301 | * needed to manage one actual PCMCIA card. | 299 | * needed to manage one actual PCMCIA card. |
302 | */ | 300 | */ |
303 | 301 | ||
304 | static dev_link_t *xirc2ps_attach(void); | 302 | static void xirc2ps_detach(struct pcmcia_device *p_dev); |
305 | static void xirc2ps_detach(dev_link_t *); | ||
306 | 303 | ||
307 | /**************** | 304 | /**************** |
308 | * You'll also need to prototype all the functions that will actually | 305 | * You'll also need to prototype all the functions that will actually |
@@ -313,14 +310,6 @@ static void xirc2ps_detach(dev_link_t *); | |||
313 | 310 | ||
314 | static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs); | 311 | static irqreturn_t xirc2ps_interrupt(int irq, void *dev_id, struct pt_regs *regs); |
315 | 312 | ||
316 | /* | ||
317 | * The dev_info variable is the "key" that is used to match up this | ||
318 | * device driver with appropriate cards, through the card configuration | ||
319 | * database. | ||
320 | */ | ||
321 | |||
322 | static dev_info_t dev_info = "xirc2ps_cs"; | ||
323 | |||
324 | /**************** | 313 | /**************** |
325 | * A linked list of "instances" of the device. Each actual | 314 | * A linked list of "instances" of the device. Each actual |
326 | * PCMCIA card corresponds to one device instance, and is described | 315 | * PCMCIA card corresponds to one device instance, and is described |
@@ -331,15 +320,7 @@ static dev_info_t dev_info = "xirc2ps_cs"; | |||
331 | * device numbers are used to derive the corresponding array index. | 320 | * device numbers are used to derive the corresponding array index. |
332 | */ | 321 | */ |
333 | 322 | ||
334 | static dev_link_t *dev_list; | ||
335 | |||
336 | /**************** | 323 | /**************** |
337 | * A dev_link_t structure has fields for most things that are needed | ||
338 | * to keep track of a socket, but there will usually be some device | ||
339 | * specific information that also needs to be kept track of. The | ||
340 | * 'priv' pointer in a dev_link_t structure can be used to point to | ||
341 | * a device-specific private data structure, like this. | ||
342 | * | ||
343 | * A driver needs to provide a dev_node_t structure for each device | 324 | * A driver needs to provide a dev_node_t structure for each device |
344 | * on a card. In some cases, there is only one device per card (for | 325 | * on a card. In some cases, there is only one device per card (for |
345 | * example, ethernet cards, modems). In other cases, there may be | 326 | * example, ethernet cards, modems). In other cases, there may be |
@@ -571,21 +552,19 @@ mii_wr(kio_addr_t ioaddr, u_char phyaddr, u_char phyreg, unsigned data, int len) | |||
571 | * card insertion event. | 552 | * card insertion event. |
572 | */ | 553 | */ |
573 | 554 | ||
574 | static dev_link_t * | 555 | static int |
575 | xirc2ps_attach(void) | 556 | xirc2ps_attach(struct pcmcia_device *p_dev) |
576 | { | 557 | { |
577 | client_reg_t client_reg; | ||
578 | dev_link_t *link; | 558 | dev_link_t *link; |
579 | struct net_device *dev; | 559 | struct net_device *dev; |
580 | local_info_t *local; | 560 | local_info_t *local; |
581 | int err; | ||
582 | 561 | ||
583 | DEBUG(0, "attach()\n"); | 562 | DEBUG(0, "attach()\n"); |
584 | 563 | ||
585 | /* Allocate the device structure */ | 564 | /* Allocate the device structure */ |
586 | dev = alloc_etherdev(sizeof(local_info_t)); | 565 | dev = alloc_etherdev(sizeof(local_info_t)); |
587 | if (!dev) | 566 | if (!dev) |
588 | return NULL; | 567 | return -ENOMEM; |
589 | local = netdev_priv(dev); | 568 | local = netdev_priv(dev); |
590 | link = &local->link; | 569 | link = &local->link; |
591 | link->priv = dev; | 570 | link->priv = dev; |
@@ -614,19 +593,13 @@ xirc2ps_attach(void) | |||
614 | dev->watchdog_timeo = TX_TIMEOUT; | 593 | dev->watchdog_timeo = TX_TIMEOUT; |
615 | #endif | 594 | #endif |
616 | 595 | ||
617 | /* Register with Card Services */ | 596 | link->handle = p_dev; |
618 | link->next = dev_list; | 597 | p_dev->instance = link; |
619 | dev_list = link; | 598 | |
620 | client_reg.dev_info = &dev_info; | 599 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
621 | client_reg.Version = 0x0210; | 600 | xirc2ps_config(link); |
622 | client_reg.event_callback_args.client_data = link; | ||
623 | if ((err = pcmcia_register_client(&link->handle, &client_reg))) { | ||
624 | cs_error(link->handle, RegisterClient, err); | ||
625 | xirc2ps_detach(link); | ||
626 | return NULL; | ||
627 | } | ||
628 | 601 | ||
629 | return link; | 602 | return 0; |
630 | } /* xirc2ps_attach */ | 603 | } /* xirc2ps_attach */ |
631 | 604 | ||
632 | /**************** | 605 | /**************** |
@@ -637,40 +610,19 @@ xirc2ps_attach(void) | |||
637 | */ | 610 | */ |
638 | 611 | ||
639 | static void | 612 | static void |
640 | xirc2ps_detach(dev_link_t * link) | 613 | xirc2ps_detach(struct pcmcia_device *p_dev) |
641 | { | 614 | { |
615 | dev_link_t *link = dev_to_instance(p_dev); | ||
642 | struct net_device *dev = link->priv; | 616 | struct net_device *dev = link->priv; |
643 | dev_link_t **linkp; | ||
644 | 617 | ||
645 | DEBUG(0, "detach(0x%p)\n", link); | 618 | DEBUG(0, "detach(0x%p)\n", link); |
646 | 619 | ||
647 | /* Locate device structure */ | ||
648 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
649 | if (*linkp == link) | ||
650 | break; | ||
651 | if (!*linkp) { | ||
652 | DEBUG(0, "detach(0x%p): dev_link lost\n", link); | ||
653 | return; | ||
654 | } | ||
655 | |||
656 | if (link->dev) | 620 | if (link->dev) |
657 | unregister_netdev(dev); | 621 | unregister_netdev(dev); |
658 | 622 | ||
659 | /* | ||
660 | * If the device is currently configured and active, we won't | ||
661 | * actually delete it yet. Instead, it is marked so that when | ||
662 | * the release() function is called, that will trigger a proper | ||
663 | * detach(). | ||
664 | */ | ||
665 | if (link->state & DEV_CONFIG) | 623 | if (link->state & DEV_CONFIG) |
666 | xirc2ps_release(link); | 624 | xirc2ps_release(link); |
667 | 625 | ||
668 | /* Break the link with Card Services */ | ||
669 | if (link->handle) | ||
670 | pcmcia_deregister_client(link->handle); | ||
671 | |||
672 | /* Unlink device structure, free it */ | ||
673 | *linkp = link->next; | ||
674 | free_netdev(dev); | 626 | free_netdev(dev); |
675 | } /* xirc2ps_detach */ | 627 | } /* xirc2ps_detach */ |
676 | 628 | ||
@@ -1157,67 +1109,41 @@ xirc2ps_release(dev_link_t *link) | |||
1157 | 1109 | ||
1158 | /*====================================================================*/ | 1110 | /*====================================================================*/ |
1159 | 1111 | ||
1160 | /**************** | ||
1161 | * The card status event handler. Mostly, this schedules other | ||
1162 | * stuff to run after an event is received. A CARD_REMOVAL event | ||
1163 | * also sets some flags to discourage the net drivers from trying | ||
1164 | * to talk to the card any more. | ||
1165 | * | ||
1166 | * When a CARD_REMOVAL event is received, we immediately set a flag | ||
1167 | * to block future accesses to this device. All the functions that | ||
1168 | * actually access the device should check this flag to make sure | ||
1169 | * the card is still present. | ||
1170 | */ | ||
1171 | 1112 | ||
1172 | static int | 1113 | static int xirc2ps_suspend(struct pcmcia_device *p_dev) |
1173 | xirc2ps_event(event_t event, int priority, | ||
1174 | event_callback_args_t * args) | ||
1175 | { | 1114 | { |
1176 | dev_link_t *link = args->client_data; | 1115 | dev_link_t *link = dev_to_instance(p_dev); |
1177 | struct net_device *dev = link->priv; | 1116 | struct net_device *dev = link->priv; |
1178 | |||
1179 | DEBUG(0, "event(%d)\n", (int)event); | ||
1180 | 1117 | ||
1181 | switch (event) { | ||
1182 | case CS_EVENT_REGISTRATION_COMPLETE: | ||
1183 | DEBUG(0, "registration complete\n"); | ||
1184 | break; | ||
1185 | case CS_EVENT_CARD_REMOVAL: | ||
1186 | link->state &= ~DEV_PRESENT; | ||
1187 | if (link->state & DEV_CONFIG) | ||
1188 | netif_device_detach(dev); | ||
1189 | break; | ||
1190 | case CS_EVENT_CARD_INSERTION: | ||
1191 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
1192 | xirc2ps_config(link); | ||
1193 | break; | ||
1194 | case CS_EVENT_PM_SUSPEND: | ||
1195 | link->state |= DEV_SUSPEND; | 1118 | link->state |= DEV_SUSPEND; |
1196 | /* Fall through... */ | ||
1197 | case CS_EVENT_RESET_PHYSICAL: | ||
1198 | if (link->state & DEV_CONFIG) { | 1119 | if (link->state & DEV_CONFIG) { |
1199 | if (link->open) { | 1120 | if (link->open) { |
1200 | netif_device_detach(dev); | 1121 | netif_device_detach(dev); |
1201 | do_powerdown(dev); | 1122 | do_powerdown(dev); |
1202 | } | 1123 | } |
1203 | pcmcia_release_configuration(link->handle); | 1124 | pcmcia_release_configuration(link->handle); |
1204 | } | 1125 | } |
1205 | break; | 1126 | |
1206 | case CS_EVENT_PM_RESUME: | 1127 | return 0; |
1128 | } | ||
1129 | |||
1130 | static int xirc2ps_resume(struct pcmcia_device *p_dev) | ||
1131 | { | ||
1132 | dev_link_t *link = dev_to_instance(p_dev); | ||
1133 | struct net_device *dev = link->priv; | ||
1134 | |||
1207 | link->state &= ~DEV_SUSPEND; | 1135 | link->state &= ~DEV_SUSPEND; |
1208 | /* Fall through... */ | ||
1209 | case CS_EVENT_CARD_RESET: | ||
1210 | if (link->state & DEV_CONFIG) { | 1136 | if (link->state & DEV_CONFIG) { |
1211 | pcmcia_request_configuration(link->handle, &link->conf); | 1137 | pcmcia_request_configuration(link->handle, &link->conf); |
1212 | if (link->open) { | 1138 | if (link->open) { |
1213 | do_reset(dev,1); | 1139 | do_reset(dev,1); |
1214 | netif_device_attach(dev); | 1140 | netif_device_attach(dev); |
1215 | } | 1141 | } |
1216 | } | 1142 | } |
1217 | break; | 1143 | |
1218 | } | 1144 | return 0; |
1219 | return 0; | 1145 | } |
1220 | } /* xirc2ps_event */ | 1146 | |
1221 | 1147 | ||
1222 | /*====================================================================*/ | 1148 | /*====================================================================*/ |
1223 | 1149 | ||
@@ -2009,10 +1935,11 @@ static struct pcmcia_driver xirc2ps_cs_driver = { | |||
2009 | .drv = { | 1935 | .drv = { |
2010 | .name = "xirc2ps_cs", | 1936 | .name = "xirc2ps_cs", |
2011 | }, | 1937 | }, |
2012 | .attach = xirc2ps_attach, | 1938 | .probe = xirc2ps_attach, |
2013 | .event = xirc2ps_event, | 1939 | .remove = xirc2ps_detach, |
2014 | .detach = xirc2ps_detach, | ||
2015 | .id_table = xirc2ps_ids, | 1940 | .id_table = xirc2ps_ids, |
1941 | .suspend = xirc2ps_suspend, | ||
1942 | .resume = xirc2ps_resume, | ||
2016 | }; | 1943 | }; |
2017 | 1944 | ||
2018 | static int __init | 1945 | static int __init |
@@ -2025,7 +1952,6 @@ static void __exit | |||
2025 | exit_xirc2ps_cs(void) | 1952 | exit_xirc2ps_cs(void) |
2026 | { | 1953 | { |
2027 | pcmcia_unregister_driver(&xirc2ps_cs_driver); | 1954 | pcmcia_unregister_driver(&xirc2ps_cs_driver); |
2028 | BUG_ON(dev_list != NULL); | ||
2029 | } | 1955 | } |
2030 | 1956 | ||
2031 | module_init(init_xirc2ps_cs); | 1957 | module_init(init_xirc2ps_cs); |