diff options
Diffstat (limited to 'drivers/net/pcmcia/axnet_cs.c')
-rw-r--r-- | drivers/net/pcmcia/axnet_cs.c | 128 |
1 files changed, 41 insertions, 87 deletions
diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 8bb4e85689ea..01ddfc8cce3f 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c | |||
@@ -87,8 +87,6 @@ static char *version = | |||
87 | 87 | ||
88 | static void axnet_config(dev_link_t *link); | 88 | static void axnet_config(dev_link_t *link); |
89 | static void axnet_release(dev_link_t *link); | 89 | static void axnet_release(dev_link_t *link); |
90 | static int axnet_event(event_t event, int priority, | ||
91 | event_callback_args_t *args); | ||
92 | static int axnet_open(struct net_device *dev); | 90 | static int axnet_open(struct net_device *dev); |
93 | static int axnet_close(struct net_device *dev); | 91 | static int axnet_close(struct net_device *dev); |
94 | static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | 92 | static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); |
@@ -107,11 +105,7 @@ static void block_input(struct net_device *dev, int count, | |||
107 | static void block_output(struct net_device *dev, int count, | 105 | static void block_output(struct net_device *dev, int count, |
108 | const u_char *buf, const int start_page); | 106 | const u_char *buf, const int start_page); |
109 | 107 | ||
110 | static dev_link_t *axnet_attach(void); | 108 | static void axnet_detach(struct pcmcia_device *p_dev); |
111 | static void axnet_detach(dev_link_t *); | ||
112 | |||
113 | static dev_info_t dev_info = "axnet_cs"; | ||
114 | static dev_link_t *dev_list; | ||
115 | 109 | ||
116 | static void axdev_setup(struct net_device *dev); | 110 | static void axdev_setup(struct net_device *dev); |
117 | static void AX88190_init(struct net_device *dev, int startp); | 111 | static void AX88190_init(struct net_device *dev, int startp); |
@@ -147,13 +141,11 @@ static inline axnet_dev_t *PRIV(struct net_device *dev) | |||
147 | 141 | ||
148 | ======================================================================*/ | 142 | ======================================================================*/ |
149 | 143 | ||
150 | static dev_link_t *axnet_attach(void) | 144 | static int axnet_attach(struct pcmcia_device *p_dev) |
151 | { | 145 | { |
152 | axnet_dev_t *info; | 146 | axnet_dev_t *info; |
153 | dev_link_t *link; | 147 | dev_link_t *link; |
154 | struct net_device *dev; | 148 | struct net_device *dev; |
155 | client_reg_t client_reg; | ||
156 | int ret; | ||
157 | 149 | ||
158 | DEBUG(0, "axnet_attach()\n"); | 150 | DEBUG(0, "axnet_attach()\n"); |
159 | 151 | ||
@@ -161,7 +153,7 @@ static dev_link_t *axnet_attach(void) | |||
161 | "eth%d", axdev_setup); | 153 | "eth%d", axdev_setup); |
162 | 154 | ||
163 | if (!dev) | 155 | if (!dev) |
164 | return NULL; | 156 | return -ENOMEM; |
165 | 157 | ||
166 | info = PRIV(dev); | 158 | info = PRIV(dev); |
167 | link = &info->link; | 159 | link = &info->link; |
@@ -176,20 +168,13 @@ static dev_link_t *axnet_attach(void) | |||
176 | dev->do_ioctl = &axnet_ioctl; | 168 | dev->do_ioctl = &axnet_ioctl; |
177 | SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); | 169 | SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); |
178 | 170 | ||
179 | /* Register with Card Services */ | 171 | link->handle = p_dev; |
180 | link->next = dev_list; | 172 | p_dev->instance = link; |
181 | dev_list = link; | ||
182 | client_reg.dev_info = &dev_info; | ||
183 | client_reg.Version = 0x0210; | ||
184 | client_reg.event_callback_args.client_data = link; | ||
185 | ret = pcmcia_register_client(&link->handle, &client_reg); | ||
186 | if (ret != CS_SUCCESS) { | ||
187 | cs_error(link->handle, RegisterClient, ret); | ||
188 | axnet_detach(link); | ||
189 | return NULL; | ||
190 | } | ||
191 | 173 | ||
192 | return link; | 174 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
175 | axnet_config(link); | ||
176 | |||
177 | return 0; | ||
193 | } /* axnet_attach */ | 178 | } /* axnet_attach */ |
194 | 179 | ||
195 | /*====================================================================== | 180 | /*====================================================================== |
@@ -201,30 +186,19 @@ static dev_link_t *axnet_attach(void) | |||
201 | 186 | ||
202 | ======================================================================*/ | 187 | ======================================================================*/ |
203 | 188 | ||
204 | static void axnet_detach(dev_link_t *link) | 189 | static void axnet_detach(struct pcmcia_device *p_dev) |
205 | { | 190 | { |
191 | dev_link_t *link = dev_to_instance(p_dev); | ||
206 | struct net_device *dev = link->priv; | 192 | struct net_device *dev = link->priv; |
207 | dev_link_t **linkp; | ||
208 | 193 | ||
209 | DEBUG(0, "axnet_detach(0x%p)\n", link); | 194 | DEBUG(0, "axnet_detach(0x%p)\n", link); |
210 | 195 | ||
211 | /* Locate device structure */ | ||
212 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
213 | if (*linkp == link) break; | ||
214 | if (*linkp == NULL) | ||
215 | return; | ||
216 | |||
217 | if (link->dev) | 196 | if (link->dev) |
218 | unregister_netdev(dev); | 197 | unregister_netdev(dev); |
219 | 198 | ||
220 | if (link->state & DEV_CONFIG) | 199 | if (link->state & DEV_CONFIG) |
221 | axnet_release(link); | 200 | axnet_release(link); |
222 | 201 | ||
223 | if (link->handle) | ||
224 | pcmcia_deregister_client(link->handle); | ||
225 | |||
226 | /* Unlink device structure, free bits */ | ||
227 | *linkp = link->next; | ||
228 | free_netdev(dev); | 202 | free_netdev(dev); |
229 | } /* axnet_detach */ | 203 | } /* axnet_detach */ |
230 | 204 | ||
@@ -490,59 +464,39 @@ static void axnet_release(dev_link_t *link) | |||
490 | link->state &= ~DEV_CONFIG; | 464 | link->state &= ~DEV_CONFIG; |
491 | } | 465 | } |
492 | 466 | ||
493 | /*====================================================================== | 467 | static int axnet_suspend(struct pcmcia_device *p_dev) |
494 | |||
495 | The card status event handler. Mostly, this schedules other | ||
496 | stuff to run after an event is received. A CARD_REMOVAL event | ||
497 | also sets some flags to discourage the net drivers from trying | ||
498 | to talk to the card any more. | ||
499 | |||
500 | ======================================================================*/ | ||
501 | |||
502 | static int axnet_event(event_t event, int priority, | ||
503 | event_callback_args_t *args) | ||
504 | { | 468 | { |
505 | dev_link_t *link = args->client_data; | 469 | dev_link_t *link = dev_to_instance(p_dev); |
506 | struct net_device *dev = link->priv; | 470 | struct net_device *dev = link->priv; |
507 | 471 | ||
508 | DEBUG(2, "axnet_event(0x%06x)\n", event); | ||
509 | |||
510 | switch (event) { | ||
511 | case CS_EVENT_CARD_REMOVAL: | ||
512 | link->state &= ~DEV_PRESENT; | ||
513 | if (link->state & DEV_CONFIG) | ||
514 | netif_device_detach(dev); | ||
515 | break; | ||
516 | case CS_EVENT_CARD_INSERTION: | ||
517 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | ||
518 | axnet_config(link); | ||
519 | break; | ||
520 | case CS_EVENT_PM_SUSPEND: | ||
521 | link->state |= DEV_SUSPEND; | 472 | link->state |= DEV_SUSPEND; |
522 | /* Fall through... */ | ||
523 | case CS_EVENT_RESET_PHYSICAL: | ||
524 | if (link->state & DEV_CONFIG) { | 473 | if (link->state & DEV_CONFIG) { |
525 | if (link->open) | 474 | if (link->open) |
526 | netif_device_detach(dev); | 475 | netif_device_detach(dev); |
527 | pcmcia_release_configuration(link->handle); | 476 | pcmcia_release_configuration(link->handle); |
528 | } | 477 | } |
529 | break; | 478 | |
530 | case CS_EVENT_PM_RESUME: | 479 | return 0; |
480 | } | ||
481 | |||
482 | static int axnet_resume(struct pcmcia_device *p_dev) | ||
483 | { | ||
484 | dev_link_t *link = dev_to_instance(p_dev); | ||
485 | struct net_device *dev = link->priv; | ||
486 | |||
531 | link->state &= ~DEV_SUSPEND; | 487 | link->state &= ~DEV_SUSPEND; |
532 | /* Fall through... */ | ||
533 | case CS_EVENT_CARD_RESET: | ||
534 | if (link->state & DEV_CONFIG) { | 488 | if (link->state & DEV_CONFIG) { |
535 | pcmcia_request_configuration(link->handle, &link->conf); | 489 | pcmcia_request_configuration(link->handle, &link->conf); |
536 | if (link->open) { | 490 | if (link->open) { |
537 | axnet_reset_8390(dev); | 491 | axnet_reset_8390(dev); |
538 | AX88190_init(dev, 1); | 492 | AX88190_init(dev, 1); |
539 | netif_device_attach(dev); | 493 | netif_device_attach(dev); |
540 | } | 494 | } |
541 | } | 495 | } |
542 | break; | 496 | |
543 | } | 497 | return 0; |
544 | return 0; | 498 | } |
545 | } /* axnet_event */ | 499 | |
546 | 500 | ||
547 | /*====================================================================== | 501 | /*====================================================================== |
548 | 502 | ||
@@ -616,7 +570,7 @@ static int axnet_open(struct net_device *dev) | |||
616 | 570 | ||
617 | link->open++; | 571 | link->open++; |
618 | 572 | ||
619 | request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, dev_info, dev); | 573 | request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, "axnet_cs", dev); |
620 | 574 | ||
621 | info->link_status = 0x00; | 575 | info->link_status = 0x00; |
622 | init_timer(&info->watchdog); | 576 | init_timer(&info->watchdog); |
@@ -877,10 +831,11 @@ static struct pcmcia_driver axnet_cs_driver = { | |||
877 | .drv = { | 831 | .drv = { |
878 | .name = "axnet_cs", | 832 | .name = "axnet_cs", |
879 | }, | 833 | }, |
880 | .attach = axnet_attach, | 834 | .probe = axnet_attach, |
881 | .event = axnet_event, | 835 | .remove = axnet_detach, |
882 | .detach = axnet_detach, | ||
883 | .id_table = axnet_ids, | 836 | .id_table = axnet_ids, |
837 | .suspend = axnet_suspend, | ||
838 | .resume = axnet_resume, | ||
884 | }; | 839 | }; |
885 | 840 | ||
886 | static int __init init_axnet_cs(void) | 841 | static int __init init_axnet_cs(void) |
@@ -891,7 +846,6 @@ static int __init init_axnet_cs(void) | |||
891 | static void __exit exit_axnet_cs(void) | 846 | static void __exit exit_axnet_cs(void) |
892 | { | 847 | { |
893 | pcmcia_unregister_driver(&axnet_cs_driver); | 848 | pcmcia_unregister_driver(&axnet_cs_driver); |
894 | BUG_ON(dev_list != NULL); | ||
895 | } | 849 | } |
896 | 850 | ||
897 | module_init(init_axnet_cs); | 851 | module_init(init_axnet_cs); |