diff options
Diffstat (limited to 'drivers/net/pcmcia/nmclan_cs.c')
-rw-r--r-- | drivers/net/pcmcia/nmclan_cs.c | 134 |
1 files changed, 44 insertions, 90 deletions
diff --git a/drivers/net/pcmcia/nmclan_cs.c b/drivers/net/pcmcia/nmclan_cs.c index 980d7e5d66cb..4a232254a497 100644 --- a/drivers/net/pcmcia/nmclan_cs.c +++ b/drivers/net/pcmcia/nmclan_cs.c | |||
@@ -388,9 +388,6 @@ static char *version = | |||
388 | DRV_NAME " " DRV_VERSION " (Roger C. Pao)"; | 388 | DRV_NAME " " DRV_VERSION " (Roger C. Pao)"; |
389 | #endif | 389 | #endif |
390 | 390 | ||
391 | static dev_info_t dev_info="nmclan_cs"; | ||
392 | static dev_link_t *dev_list; | ||
393 | |||
394 | static char *if_names[]={ | 391 | static char *if_names[]={ |
395 | "Auto", "10baseT", "BNC", | 392 | "Auto", "10baseT", "BNC", |
396 | }; | 393 | }; |
@@ -422,8 +419,6 @@ Function Prototypes | |||
422 | 419 | ||
423 | static void nmclan_config(dev_link_t *link); | 420 | static void nmclan_config(dev_link_t *link); |
424 | static void nmclan_release(dev_link_t *link); | 421 | static void nmclan_release(dev_link_t *link); |
425 | static int nmclan_event(event_t event, int priority, | ||
426 | event_callback_args_t *args); | ||
427 | 422 | ||
428 | static void nmclan_reset(struct net_device *dev); | 423 | static void nmclan_reset(struct net_device *dev); |
429 | static int mace_config(struct net_device *dev, struct ifmap *map); | 424 | static int mace_config(struct net_device *dev, struct ifmap *map); |
@@ -439,8 +434,7 @@ static void set_multicast_list(struct net_device *dev); | |||
439 | static struct ethtool_ops netdev_ethtool_ops; | 434 | static struct ethtool_ops netdev_ethtool_ops; |
440 | 435 | ||
441 | 436 | ||
442 | static dev_link_t *nmclan_attach(void); | 437 | static void nmclan_detach(struct pcmcia_device *p_dev); |
443 | static void nmclan_detach(dev_link_t *); | ||
444 | 438 | ||
445 | /* ---------------------------------------------------------------------------- | 439 | /* ---------------------------------------------------------------------------- |
446 | nmclan_attach | 440 | nmclan_attach |
@@ -449,13 +443,11 @@ nmclan_attach | |||
449 | Services. | 443 | Services. |
450 | ---------------------------------------------------------------------------- */ | 444 | ---------------------------------------------------------------------------- */ |
451 | 445 | ||
452 | static dev_link_t *nmclan_attach(void) | 446 | static int nmclan_attach(struct pcmcia_device *p_dev) |
453 | { | 447 | { |
454 | mace_private *lp; | 448 | mace_private *lp; |
455 | dev_link_t *link; | 449 | dev_link_t *link; |
456 | struct net_device *dev; | 450 | struct net_device *dev; |
457 | client_reg_t client_reg; | ||
458 | int ret; | ||
459 | 451 | ||
460 | DEBUG(0, "nmclan_attach()\n"); | 452 | DEBUG(0, "nmclan_attach()\n"); |
461 | DEBUG(1, "%s\n", rcsid); | 453 | DEBUG(1, "%s\n", rcsid); |
@@ -463,7 +455,7 @@ static dev_link_t *nmclan_attach(void) | |||
463 | /* Create new ethernet device */ | 455 | /* Create new ethernet device */ |
464 | dev = alloc_etherdev(sizeof(mace_private)); | 456 | dev = alloc_etherdev(sizeof(mace_private)); |
465 | if (!dev) | 457 | if (!dev) |
466 | return NULL; | 458 | return -ENOMEM; |
467 | lp = netdev_priv(dev); | 459 | lp = netdev_priv(dev); |
468 | link = &lp->link; | 460 | link = &lp->link; |
469 | link->priv = dev; | 461 | link->priv = dev; |
@@ -497,20 +489,13 @@ static dev_link_t *nmclan_attach(void) | |||
497 | dev->watchdog_timeo = TX_TIMEOUT; | 489 | dev->watchdog_timeo = TX_TIMEOUT; |
498 | #endif | 490 | #endif |
499 | 491 | ||
500 | /* Register with Card Services */ | 492 | link->handle = p_dev; |
501 | link->next = dev_list; | 493 | p_dev->instance = link; |
502 | dev_list = link; | 494 | |
503 | client_reg.dev_info = &dev_info; | 495 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; |
504 | client_reg.Version = 0x0210; | 496 | nmclan_config(link); |
505 | client_reg.event_callback_args.client_data = link; | ||
506 | ret = pcmcia_register_client(&link->handle, &client_reg); | ||
507 | if (ret != 0) { | ||
508 | cs_error(link->handle, RegisterClient, ret); | ||
509 | nmclan_detach(link); | ||
510 | return NULL; | ||
511 | } | ||
512 | 497 | ||
513 | return link; | 498 | return 0; |
514 | } /* nmclan_attach */ | 499 | } /* nmclan_attach */ |
515 | 500 | ||
516 | /* ---------------------------------------------------------------------------- | 501 | /* ---------------------------------------------------------------------------- |
@@ -521,30 +506,19 @@ nmclan_detach | |||
521 | when the device is released. | 506 | when the device is released. |
522 | ---------------------------------------------------------------------------- */ | 507 | ---------------------------------------------------------------------------- */ |
523 | 508 | ||
524 | static void nmclan_detach(dev_link_t *link) | 509 | static void nmclan_detach(struct pcmcia_device *p_dev) |
525 | { | 510 | { |
511 | dev_link_t *link = dev_to_instance(p_dev); | ||
526 | struct net_device *dev = link->priv; | 512 | struct net_device *dev = link->priv; |
527 | dev_link_t **linkp; | ||
528 | 513 | ||
529 | DEBUG(0, "nmclan_detach(0x%p)\n", link); | 514 | DEBUG(0, "nmclan_detach(0x%p)\n", link); |
530 | 515 | ||
531 | /* Locate device structure */ | ||
532 | for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) | ||
533 | if (*linkp == link) break; | ||
534 | if (*linkp == NULL) | ||
535 | return; | ||
536 | |||
537 | if (link->dev) | 516 | if (link->dev) |
538 | unregister_netdev(dev); | 517 | unregister_netdev(dev); |
539 | 518 | ||
540 | if (link->state & DEV_CONFIG) | 519 | if (link->state & DEV_CONFIG) |
541 | nmclan_release(link); | 520 | nmclan_release(link); |
542 | 521 | ||
543 | if (link->handle) | ||
544 | pcmcia_deregister_client(link->handle); | ||
545 | |||
546 | /* Unlink device structure, free bits */ | ||
547 | *linkp = link->next; | ||
548 | free_netdev(dev); | 522 | free_netdev(dev); |
549 | } /* nmclan_detach */ | 523 | } /* nmclan_detach */ |
550 | 524 | ||
@@ -801,59 +775,39 @@ static void nmclan_release(dev_link_t *link) | |||
801 | link->state &= ~DEV_CONFIG; | 775 | link->state &= ~DEV_CONFIG; |
802 | } | 776 | } |
803 | 777 | ||
804 | /* ---------------------------------------------------------------------------- | 778 | static int nmclan_suspend(struct pcmcia_device *p_dev) |
805 | nmclan_event | ||
806 | The card status event handler. Mostly, this schedules other | ||
807 | stuff to run after an event is received. A CARD_REMOVAL event | ||
808 | also sets some flags to discourage the net drivers from trying | ||
809 | to talk to the card any more. | ||
810 | ---------------------------------------------------------------------------- */ | ||
811 | static int nmclan_event(event_t event, int priority, | ||
812 | event_callback_args_t *args) | ||
813 | { | 779 | { |
814 | dev_link_t *link = args->client_data; | 780 | dev_link_t *link = dev_to_instance(p_dev); |
815 | struct net_device *dev = link->priv; | 781 | struct net_device *dev = link->priv; |
782 | |||
783 | link->state |= DEV_SUSPEND; | ||
784 | if (link->state & DEV_CONFIG) { | ||
785 | if (link->open) | ||
786 | netif_device_detach(dev); | ||
787 | pcmcia_release_configuration(link->handle); | ||
788 | } | ||
816 | 789 | ||
817 | DEBUG(1, "nmclan_event(0x%06x)\n", event); | ||
818 | 790 | ||
819 | switch (event) { | 791 | return 0; |
820 | case CS_EVENT_CARD_REMOVAL: | 792 | } |
821 | link->state &= ~DEV_PRESENT; | 793 | |
822 | if (link->state & DEV_CONFIG) | 794 | static int nmclan_resume(struct pcmcia_device *p_dev) |
823 | netif_device_detach(dev); | 795 | { |
824 | break; | 796 | dev_link_t *link = dev_to_instance(p_dev); |
825 | case CS_EVENT_CARD_INSERTION: | 797 | struct net_device *dev = link->priv; |
826 | link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; | 798 | |
827 | nmclan_config(link); | 799 | link->state &= ~DEV_SUSPEND; |
828 | break; | 800 | if (link->state & DEV_CONFIG) { |
829 | case CS_EVENT_PM_SUSPEND: | 801 | pcmcia_request_configuration(link->handle, &link->conf); |
830 | link->state |= DEV_SUSPEND; | 802 | if (link->open) { |
831 | /* Fall through... */ | 803 | nmclan_reset(dev); |
832 | case CS_EVENT_RESET_PHYSICAL: | 804 | netif_device_attach(dev); |
833 | if (link->state & DEV_CONFIG) { | 805 | } |
834 | if (link->open) | ||
835 | netif_device_detach(dev); | ||
836 | pcmcia_release_configuration(link->handle); | ||
837 | } | ||
838 | break; | ||
839 | case CS_EVENT_PM_RESUME: | ||
840 | link->state &= ~DEV_SUSPEND; | ||
841 | /* Fall through... */ | ||
842 | case CS_EVENT_CARD_RESET: | ||
843 | if (link->state & DEV_CONFIG) { | ||
844 | pcmcia_request_configuration(link->handle, &link->conf); | ||
845 | if (link->open) { | ||
846 | nmclan_reset(dev); | ||
847 | netif_device_attach(dev); | ||
848 | } | 806 | } |
849 | } | 807 | |
850 | break; | 808 | return 0; |
851 | case CS_EVENT_RESET_REQUEST: | 809 | } |
852 | return 1; | 810 | |
853 | break; | ||
854 | } | ||
855 | return 0; | ||
856 | } /* nmclan_event */ | ||
857 | 811 | ||
858 | /* ---------------------------------------------------------------------------- | 812 | /* ---------------------------------------------------------------------------- |
859 | nmclan_reset | 813 | nmclan_reset |
@@ -1681,10 +1635,11 @@ static struct pcmcia_driver nmclan_cs_driver = { | |||
1681 | .drv = { | 1635 | .drv = { |
1682 | .name = "nmclan_cs", | 1636 | .name = "nmclan_cs", |
1683 | }, | 1637 | }, |
1684 | .attach = nmclan_attach, | 1638 | .probe = nmclan_attach, |
1685 | .event = nmclan_event, | 1639 | .remove = nmclan_detach, |
1686 | .detach = nmclan_detach, | ||
1687 | .id_table = nmclan_ids, | 1640 | .id_table = nmclan_ids, |
1641 | .suspend = nmclan_suspend, | ||
1642 | .resume = nmclan_resume, | ||
1688 | }; | 1643 | }; |
1689 | 1644 | ||
1690 | static int __init init_nmclan_cs(void) | 1645 | static int __init init_nmclan_cs(void) |
@@ -1695,7 +1650,6 @@ static int __init init_nmclan_cs(void) | |||
1695 | static void __exit exit_nmclan_cs(void) | 1650 | static void __exit exit_nmclan_cs(void) |
1696 | { | 1651 | { |
1697 | pcmcia_unregister_driver(&nmclan_cs_driver); | 1652 | pcmcia_unregister_driver(&nmclan_cs_driver); |
1698 | BUG_ON(dev_list != NULL); | ||
1699 | } | 1653 | } |
1700 | 1654 | ||
1701 | module_init(init_nmclan_cs); | 1655 | module_init(init_nmclan_cs); |