aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/pcmcia/nmclan_cs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/net/pcmcia/nmclan_cs.c')
-rw-r--r--drivers/net/pcmcia/nmclan_cs.c134
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 =
388DRV_NAME " " DRV_VERSION " (Roger C. Pao)"; 388DRV_NAME " " DRV_VERSION " (Roger C. Pao)";
389#endif 389#endif
390 390
391static dev_info_t dev_info="nmclan_cs";
392static dev_link_t *dev_list;
393
394static char *if_names[]={ 391static char *if_names[]={
395 "Auto", "10baseT", "BNC", 392 "Auto", "10baseT", "BNC",
396}; 393};
@@ -422,8 +419,6 @@ Function Prototypes
422 419
423static void nmclan_config(dev_link_t *link); 420static void nmclan_config(dev_link_t *link);
424static void nmclan_release(dev_link_t *link); 421static void nmclan_release(dev_link_t *link);
425static int nmclan_event(event_t event, int priority,
426 event_callback_args_t *args);
427 422
428static void nmclan_reset(struct net_device *dev); 423static void nmclan_reset(struct net_device *dev);
429static int mace_config(struct net_device *dev, struct ifmap *map); 424static int mace_config(struct net_device *dev, struct ifmap *map);
@@ -439,8 +434,7 @@ static void set_multicast_list(struct net_device *dev);
439static struct ethtool_ops netdev_ethtool_ops; 434static struct ethtool_ops netdev_ethtool_ops;
440 435
441 436
442static dev_link_t *nmclan_attach(void); 437static void nmclan_detach(struct pcmcia_device *p_dev);
443static void nmclan_detach(dev_link_t *);
444 438
445/* ---------------------------------------------------------------------------- 439/* ----------------------------------------------------------------------------
446nmclan_attach 440nmclan_attach
@@ -449,13 +443,11 @@ nmclan_attach
449 Services. 443 Services.
450---------------------------------------------------------------------------- */ 444---------------------------------------------------------------------------- */
451 445
452static dev_link_t *nmclan_attach(void) 446static 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
524static void nmclan_detach(dev_link_t *link) 509static 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/* ---------------------------------------------------------------------------- 778static int nmclan_suspend(struct pcmcia_device *p_dev)
805nmclan_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---------------------------------------------------------------------------- */
811static 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) 794static 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/* ----------------------------------------------------------------------------
859nmclan_reset 813nmclan_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
1690static int __init init_nmclan_cs(void) 1645static int __init init_nmclan_cs(void)
@@ -1695,7 +1650,6 @@ static int __init init_nmclan_cs(void)
1695static void __exit exit_nmclan_cs(void) 1650static 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
1701module_init(init_nmclan_cs); 1655module_init(init_nmclan_cs);