diff options
author | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-05 18:55:49 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2006-01-05 18:55:49 -0500 |
commit | d7906de1d774ca70d696d3047223bb3e5e759d92 (patch) | |
tree | 6065caea25668f9fd33c23a24047cecb2c5b5cd7 /drivers/net/pcmcia/3c574_cs.c | |
parent | fbd91ac22229fdb89f0dd2eaa11dd663f2ba1a92 (diff) | |
parent | 725a6abfe37025975c125ace1c7da35f27ce5384 (diff) |
Merge git://git.kernel.org/pub/scm/linux/kernel/git/brodo/pcmcia-2.6
Diffstat (limited to 'drivers/net/pcmcia/3c574_cs.c')
-rw-r--r-- | drivers/net/pcmcia/3c574_cs.c | 124 |
1 files changed, 39 insertions, 85 deletions
diff --git a/drivers/net/pcmcia/3c574_cs.c b/drivers/net/pcmcia/3c574_cs.c index 71fd41122c91..48774efeec71 100644 --- a/drivers/net/pcmcia/3c574_cs.c +++ b/drivers/net/pcmcia/3c574_cs.c | |||
@@ -227,8 +227,6 @@ static char mii_preamble_required = 0; | |||
227 | 227 | ||
228 | static void tc574_config(dev_link_t *link); | 228 | static void tc574_config(dev_link_t *link); |
229 | static void tc574_release(dev_link_t *link); | 229 | static void tc574_release(dev_link_t *link); |
230 | static int tc574_event(event_t event, int priority, | ||
231 | event_callback_args_t *args); | ||
232 | 230 | ||
233 | static void mdio_sync(kio_addr_t ioaddr, int bits); | 231 | static void mdio_sync(kio_addr_t ioaddr, int bits); |
234 | static int mdio_read(kio_addr_t ioaddr, int phy_id, int location); | 232 | static int mdio_read(kio_addr_t ioaddr, int phy_id, int location); |
@@ -250,12 +248,7 @@ static int el3_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); | |||
250 | static struct ethtool_ops netdev_ethtool_ops; | 248 | static struct ethtool_ops netdev_ethtool_ops; |
251 | static void set_rx_mode(struct net_device *dev); | 249 | static void set_rx_mode(struct net_device *dev); |
252 | 250 | ||
253 | static dev_info_t dev_info = "3c574_cs"; | 251 | static void tc574_detach(struct pcmcia_device *p_dev); |
254 | |||
255 | static dev_link_t *tc574_attach(void); | ||
256 | static void tc574_detach(dev_link_t *); | ||
257 | |||
258 | static dev_link_t *dev_list; | ||
259 | 252 | ||
260 | /* | 253 | /* |
261 | tc574_attach() creates an "instance" of the driver, allocating | 254 | tc574_attach() creates an "instance" of the driver, allocating |
@@ -263,20 +256,18 @@ static dev_link_t *dev_list; | |||
263 | with Card Services. | 256 | with Card Services. |
264 | */ | 257 | */ |
265 | 258 | ||
266 | static dev_link_t *tc574_attach(void) | 259 | static int tc574_attach(struct pcmcia_device *p_dev) |
267 | { | 260 | { |
268 | struct el3_private *lp; | 261 | struct el3_private *lp; |
269 | client_reg_t client_reg; | ||
270 | dev_link_t *link; | 262 | dev_link_t *link; |
271 | struct net_device *dev; | 263 | struct net_device *dev; |
272 | int ret; | ||
273 | 264 | ||
274 | DEBUG(0, "3c574_attach()\n"); | 265 | DEBUG(0, "3c574_attach()\n"); |
275 | 266 | ||
276 | /* Create the PC card device object. */ | 267 | /* Create the PC card device object. */ |
277 | dev = alloc_etherdev(sizeof(struct el3_private)); | 268 | dev = alloc_etherdev(sizeof(struct el3_private)); |
278 | if (!dev) | 269 | if (!dev) |
279 | return NULL; | 270 | return -ENOMEM; |
280 | lp = netdev_priv(dev); | 271 | lp = netdev_priv(dev); |
281 | link = &lp->link; | 272 | link = &lp->link; |
282 | link->priv = dev; | 273 | link->priv = dev; |
@@ -307,20 +298,13 @@ static dev_link_t *tc574_attach(void) | |||
307 | dev->watchdog_timeo = TX_TIMEOUT; | 298 | dev->watchdog_timeo = TX_TIMEOUT; |
308 | #endif | 299 | #endif |
309 | 300 | ||
310 | /* Register with Card Services */ | 301 | link->handle = p_dev; |
311 | link->next = dev_list; | 302 | p_dev->instance = link; |
312 | dev_list = link; | ||
313 | client_reg.dev_info = &dev_info; | ||
314 | client_reg.Version = 0x0210; | ||
315 | client_reg.event_callback_args.client_data = link; | ||
316 | ret = pcmcia_register_client(&link->handle, &client_reg); | ||
317 | if (ret != 0) { | ||
318 | cs_error(link->handle, RegisterClient, ret); | ||
319 | tc574_detach(link); | ||
320 | return NULL; | ||
321 | } | ||
322 | 303 | ||
323 | return link; | 304 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
305 | tc574_config(link); | ||
306 | |||
307 | return 0; | ||
324 | } /* tc574_attach */ | 308 | } /* tc574_attach */ |
325 | 309 | ||
326 | /* | 310 | /* |
@@ -332,30 +316,19 @@ static dev_link_t *tc574_attach(void) | |||
332 | 316 | ||
333 | */ | 317 | */ |
334 | 318 | ||
335 | static void tc574_detach(dev_link_t *link) | 319 | static void tc574_detach(struct pcmcia_device *p_dev) |
336 | { | 320 | { |
321 | dev_link_t *link = dev_to_instance(p_dev); | ||
337 | struct net_device *dev = link->priv; | 322 | struct net_device *dev = link->priv; |
338 | dev_link_t **linkp; | ||
339 | 323 | ||
340 | DEBUG(0, "3c574_detach(0x%p)\n", link); | 324 | DEBUG(0, "3c574_detach(0x%p)\n", link); |
341 | 325 | ||
342 | /* Locate device structure */ | ||
343 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
344 | if (*linkp == link) break; | ||
345 | if (*linkp == NULL) | ||
346 | return; | ||
347 | |||
348 | if (link->dev) | 326 | if (link->dev) |
349 | unregister_netdev(dev); | 327 | unregister_netdev(dev); |
350 | 328 | ||
351 | if (link->state & DEV_CONFIG) | 329 | if (link->state & DEV_CONFIG) |
352 | tc574_release(link); | 330 | tc574_release(link); |
353 | 331 | ||
354 | if (link->handle) | ||
355 | pcmcia_deregister_client(link->handle); | ||
356 | |||
357 | /* Unlink device structure, free bits */ | ||
358 | *linkp = link->next; | ||
359 | free_netdev(dev); | 332 | free_netdev(dev); |
360 | } /* tc574_detach */ | 333 | } /* tc574_detach */ |
361 | 334 | ||
@@ -547,56 +520,37 @@ static void tc574_release(dev_link_t *link) | |||
547 | link->state &= ~DEV_CONFIG; | 520 | link->state &= ~DEV_CONFIG; |
548 | } | 521 | } |
549 | 522 | ||
550 | /* | 523 | static int tc574_suspend(struct pcmcia_device *p_dev) |
551 | The card status event handler. Mostly, this schedules other | ||
552 | stuff to run after an event is received. A CARD_REMOVAL event | ||
553 | also sets some flags to discourage the net drivers from trying | ||
554 | to talk to the card any more. | ||
555 | */ | ||
556 | |||
557 | static int tc574_event(event_t event, int priority, | ||
558 | event_callback_args_t *args) | ||
559 | { | 524 | { |
560 | dev_link_t *link = args->client_data; | 525 | dev_link_t *link = dev_to_instance(p_dev); |
561 | struct net_device *dev = link->priv; | 526 | struct net_device *dev = link->priv; |
562 | 527 | ||
563 | DEBUG(1, "3c574_event(0x%06x)\n", event); | 528 | link->state |= DEV_SUSPEND; |
564 | 529 | if (link->state & DEV_CONFIG) { | |
565 | switch (event) { | 530 | if (link->open) |
566 | case CS_EVENT_CARD_REMOVAL: | ||
567 | link->state &= ~DEV_PRESENT; | ||
568 | if (link->state & DEV_CONFIG) | ||
569 | netif_device_detach(dev); | 531 | netif_device_detach(dev); |
570 | break; | 532 | pcmcia_release_configuration(link->handle); |
571 | case CS_EVENT_CARD_INSERTION: | 533 | } |
572 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 534 | |
573 | tc574_config(link); | 535 | return 0; |
574 | break; | 536 | } |
575 | case CS_EVENT_PM_SUSPEND: | 537 | |
576 | link->state |= DEV_SUSPEND; | 538 | static int tc574_resume(struct pcmcia_device *p_dev) |
577 | /* Fall through... */ | 539 | { |
578 | case CS_EVENT_RESET_PHYSICAL: | 540 | dev_link_t *link = dev_to_instance(p_dev); |
579 | if (link->state & DEV_CONFIG) { | 541 | struct net_device *dev = link->priv; |
580 | if (link->open) | 542 | |
581 | netif_device_detach(dev); | 543 | link->state &= ~DEV_SUSPEND; |
582 | pcmcia_release_configuration(link->handle); | 544 | if (link->state & DEV_CONFIG) { |
583 | } | 545 | pcmcia_request_configuration(link->handle, &link->conf); |
584 | break; | 546 | if (link->open) { |
585 | case CS_EVENT_PM_RESUME: | 547 | tc574_reset(dev); |
586 | link->state &= ~DEV_SUSPEND; | 548 | netif_device_attach(dev); |
587 | /* Fall through... */ | ||
588 | case CS_EVENT_CARD_RESET: | ||
589 | if (link->state & DEV_CONFIG) { | ||
590 | pcmcia_request_configuration(link->handle, &link->conf); | ||
591 | if (link->open) { | ||
592 | tc574_reset(dev); | ||
593 | netif_device_attach(dev); | ||
594 | } | ||
595 | } | 549 | } |
596 | break; | ||
597 | } | 550 | } |
551 | |||
598 | return 0; | 552 | return 0; |
599 | } /* tc574_event */ | 553 | } |
600 | 554 | ||
601 | static void dump_status(struct net_device *dev) | 555 | static void dump_status(struct net_device *dev) |
602 | { | 556 | { |
@@ -1292,10 +1246,11 @@ static struct pcmcia_driver tc574_driver = { | |||
1292 | .drv = { | 1246 | .drv = { |
1293 | .name = "3c574_cs", | 1247 | .name = "3c574_cs", |
1294 | }, | 1248 | }, |
1295 | .attach = tc574_attach, | 1249 | .probe = tc574_attach, |
1296 | .event = tc574_event, | 1250 | .remove = tc574_detach, |
1297 | .detach = tc574_detach, | ||
1298 | .id_table = tc574_ids, | 1251 | .id_table = tc574_ids, |
1252 | .suspend = tc574_suspend, | ||
1253 | .resume = tc574_resume, | ||
1299 | }; | 1254 | }; |
1300 | 1255 | ||
1301 | static int __init init_tc574(void) | 1256 | static int __init init_tc574(void) |
@@ -1306,7 +1261,6 @@ static int __init init_tc574(void) | |||
1306 | static void __exit exit_tc574(void) | 1261 | static void __exit exit_tc574(void) |
1307 | { | 1262 | { |
1308 | pcmcia_unregister_driver(&tc574_driver); | 1263 | pcmcia_unregister_driver(&tc574_driver); |
1309 | BUG_ON(dev_list != NULL); | ||
1310 | } | 1264 | } |
1311 | 1265 | ||
1312 | module_init(init_tc574); | 1266 | module_init(init_tc574); |