From 98e4c28b7ec390c2dad6a4c69d69629c0f7e8b10 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 14 Nov 2005 21:21:18 +0100 Subject: [PATCH] pcmcia: new suspend core Move the suspend and resume methods out of the event handler, and into special functions. Also use these functions for pre- and post-reset, as almost all drivers already do, and the remaining ones can easily be converted. Bugfix to include/pcmcia/ds.c Signed-off-by: Andrew Morton Signed-off-by: Dominik Brodowski --- drivers/net/pcmcia/axnet_cs.c | 59 ++++++++++++++++++++++++++----------------- 1 file changed, 36 insertions(+), 23 deletions(-) (limited to 'drivers/net/pcmcia/axnet_cs.c') diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 8bb4e85..6c6b252 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -490,6 +490,40 @@ static void axnet_release(dev_link_t *link) link->state &= ~DEV_CONFIG; } +static int axnet_suspend(struct pcmcia_device *p_dev) +{ + dev_link_t *link = dev_to_instance(p_dev); + struct net_device *dev = link->priv; + + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + if (link->open) + netif_device_detach(dev); + pcmcia_release_configuration(link->handle); + } + + return 0; +} + +static int axnet_resume(struct pcmcia_device *p_dev) +{ + dev_link_t *link = dev_to_instance(p_dev); + struct net_device *dev = link->priv; + + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) { + pcmcia_request_configuration(link->handle, &link->conf); + if (link->open) { + axnet_reset_8390(dev); + AX88190_init(dev, 1); + netif_device_attach(dev); + } + } + + return 0; +} + + /*====================================================================== The card status event handler. Mostly, this schedules other @@ -517,29 +551,6 @@ static int axnet_event(event_t event, int priority, link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; axnet_config(link); break; - case CS_EVENT_PM_SUSPEND: - link->state |= DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_RESET_PHYSICAL: - if (link->state & DEV_CONFIG) { - if (link->open) - netif_device_detach(dev); - pcmcia_release_configuration(link->handle); - } - break; - case CS_EVENT_PM_RESUME: - link->state &= ~DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_CARD_RESET: - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, &link->conf); - if (link->open) { - axnet_reset_8390(dev); - AX88190_init(dev, 1); - netif_device_attach(dev); - } - } - break; } return 0; } /* axnet_event */ @@ -881,6 +892,8 @@ static struct pcmcia_driver axnet_cs_driver = { .event = axnet_event, .detach = axnet_detach, .id_table = axnet_ids, + .suspend = axnet_suspend, + .resume = axnet_resume, }; static int __init init_axnet_cs(void) -- cgit v1.1 From cc3b4866bee996c922e875b8c8efe9f0d8803aae Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 14 Nov 2005 21:23:14 +0100 Subject: [PATCH] pcmcia: unify detach, REMOVAL_EVENT handlers into one remove callback Unify the "detach" and REMOVAL_EVENT handlers to one "remove" function. Old functionality is preserved, for the moment. Signed-off-by: Dominik Brodowski --- drivers/net/pcmcia/axnet_cs.c | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) (limited to 'drivers/net/pcmcia/axnet_cs.c') diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 6c6b252..11f701a 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -108,7 +108,7 @@ static void block_output(struct net_device *dev, int count, const u_char *buf, const int start_page); static dev_link_t *axnet_attach(void); -static void axnet_detach(dev_link_t *); +static void axnet_detach(struct pcmcia_device *p_dev); static dev_info_t dev_info = "axnet_cs"; static dev_link_t *dev_list; @@ -185,7 +185,7 @@ static dev_link_t *axnet_attach(void) ret = pcmcia_register_client(&link->handle, &client_reg); if (ret != CS_SUCCESS) { cs_error(link->handle, RegisterClient, ret); - axnet_detach(link); + axnet_detach(link->handle); return NULL; } @@ -201,8 +201,9 @@ static dev_link_t *axnet_attach(void) ======================================================================*/ -static void axnet_detach(dev_link_t *link) +static void axnet_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; dev_link_t **linkp; @@ -220,9 +221,6 @@ static void axnet_detach(dev_link_t *link) if (link->state & DEV_CONFIG) axnet_release(link); - if (link->handle) - pcmcia_deregister_client(link->handle); - /* Unlink device structure, free bits */ *linkp = link->next; free_netdev(dev); @@ -537,16 +535,10 @@ static int axnet_event(event_t event, int priority, event_callback_args_t *args) { dev_link_t *link = args->client_data; - struct net_device *dev = link->priv; DEBUG(2, "axnet_event(0x%06x)\n", event); switch (event) { - case CS_EVENT_CARD_REMOVAL: - link->state &= ~DEV_PRESENT; - if (link->state & DEV_CONFIG) - netif_device_detach(dev); - break; case CS_EVENT_CARD_INSERTION: link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; axnet_config(link); @@ -890,7 +882,7 @@ static struct pcmcia_driver axnet_cs_driver = { }, .attach = axnet_attach, .event = axnet_event, - .detach = axnet_detach, + .remove = axnet_detach, .id_table = axnet_ids, .suspend = axnet_suspend, .resume = axnet_resume, -- cgit v1.1 From b463581154f3f3eecda27cae60df813fefcd84d3 Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 14 Nov 2005 21:25:35 +0100 Subject: [PATCH] pcmcia: remove dev_list from drivers The linked list of devices managed by each PCMCIA driver is, in very most cases, unused. Therefore, remove it from many drivers. Signed-off-by: Dominik Brodowski --- drivers/net/pcmcia/axnet_cs.c | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) (limited to 'drivers/net/pcmcia/axnet_cs.c') diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 11f701a..3d36207 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -111,7 +111,6 @@ static dev_link_t *axnet_attach(void); static void axnet_detach(struct pcmcia_device *p_dev); static dev_info_t dev_info = "axnet_cs"; -static dev_link_t *dev_list; static void axdev_setup(struct net_device *dev); static void AX88190_init(struct net_device *dev, int startp); @@ -177,8 +176,7 @@ static dev_link_t *axnet_attach(void) SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); /* Register with Card Services */ - link->next = dev_list; - dev_list = link; + link->next = NULL; client_reg.dev_info = &dev_info; client_reg.Version = 0x0210; client_reg.event_callback_args.client_data = link; @@ -205,24 +203,15 @@ static void axnet_detach(struct pcmcia_device *p_dev) { dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = link->priv; - dev_link_t **linkp; DEBUG(0, "axnet_detach(0x%p)\n", link); - /* Locate device structure */ - for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) - if (*linkp == link) break; - if (*linkp == NULL) - return; - if (link->dev) unregister_netdev(dev); if (link->state & DEV_CONFIG) axnet_release(link); - /* Unlink device structure, free bits */ - *linkp = link->next; free_netdev(dev); } /* axnet_detach */ @@ -896,7 +885,6 @@ static int __init init_axnet_cs(void) static void __exit exit_axnet_cs(void) { pcmcia_unregister_driver(&axnet_cs_driver); - BUG_ON(dev_list != NULL); } module_init(init_axnet_cs); -- cgit v1.1 From f8cfa618dccbdc6dab5297f75779566a388a98fd Mon Sep 17 00:00:00 2001 From: Dominik Brodowski Date: Mon, 14 Nov 2005 21:25:51 +0100 Subject: [PATCH] pcmcia: unify attach, EVENT_CARD_INSERTION handlers into one probe callback Unify the EVENT_CARD_INSERTION and "attach" callbacks to one unified probe() callback. As all in-kernel drivers are changed to this new callback, there will be no temporary backwards-compatibility. Inside a probe() function, each driver _must_ set struct pcmcia_device *p_dev->instance and instance->handle correctly. With these patches, the basic driver interface for 16-bit PCMCIA drivers now has the classic four callbacks known also from other buses: int (*probe) (struct pcmcia_device *dev); void (*remove) (struct pcmcia_device *dev); int (*suspend) (struct pcmcia_device *dev); int (*resume) (struct pcmcia_device *dev); Signed-off-by: Dominik Brodowski --- drivers/net/pcmcia/axnet_cs.c | 59 ++++++++----------------------------------- 1 file changed, 10 insertions(+), 49 deletions(-) (limited to 'drivers/net/pcmcia/axnet_cs.c') diff --git a/drivers/net/pcmcia/axnet_cs.c b/drivers/net/pcmcia/axnet_cs.c index 3d36207..01ddfc8 100644 --- a/drivers/net/pcmcia/axnet_cs.c +++ b/drivers/net/pcmcia/axnet_cs.c @@ -87,8 +87,6 @@ static char *version = static void axnet_config(dev_link_t *link); static void axnet_release(dev_link_t *link); -static int axnet_event(event_t event, int priority, - event_callback_args_t *args); static int axnet_open(struct net_device *dev); static int axnet_close(struct net_device *dev); static int axnet_ioctl(struct net_device *dev, struct ifreq *rq, int cmd); @@ -107,11 +105,8 @@ static void block_input(struct net_device *dev, int count, static void block_output(struct net_device *dev, int count, const u_char *buf, const int start_page); -static dev_link_t *axnet_attach(void); static void axnet_detach(struct pcmcia_device *p_dev); -static dev_info_t dev_info = "axnet_cs"; - static void axdev_setup(struct net_device *dev); static void AX88190_init(struct net_device *dev, int startp); static int ax_open(struct net_device *dev); @@ -146,13 +141,11 @@ static inline axnet_dev_t *PRIV(struct net_device *dev) ======================================================================*/ -static dev_link_t *axnet_attach(void) +static int axnet_attach(struct pcmcia_device *p_dev) { axnet_dev_t *info; dev_link_t *link; struct net_device *dev; - client_reg_t client_reg; - int ret; DEBUG(0, "axnet_attach()\n"); @@ -160,7 +153,7 @@ static dev_link_t *axnet_attach(void) "eth%d", axdev_setup); if (!dev) - return NULL; + return -ENOMEM; info = PRIV(dev); link = &info->link; @@ -175,19 +168,13 @@ static dev_link_t *axnet_attach(void) dev->do_ioctl = &axnet_ioctl; SET_ETHTOOL_OPS(dev, &netdev_ethtool_ops); - /* Register with Card Services */ - link->next = NULL; - client_reg.dev_info = &dev_info; - client_reg.Version = 0x0210; - client_reg.event_callback_args.client_data = link; - ret = pcmcia_register_client(&link->handle, &client_reg); - if (ret != CS_SUCCESS) { - cs_error(link->handle, RegisterClient, ret); - axnet_detach(link->handle); - return NULL; - } + link->handle = p_dev; + p_dev->instance = link; - return link; + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + axnet_config(link); + + return 0; } /* axnet_attach */ /*====================================================================== @@ -513,31 +500,6 @@ static int axnet_resume(struct pcmcia_device *p_dev) /*====================================================================== - The card status event handler. Mostly, this schedules other - stuff to run after an event is received. A CARD_REMOVAL event - also sets some flags to discourage the net drivers from trying - to talk to the card any more. - -======================================================================*/ - -static int axnet_event(event_t event, int priority, - event_callback_args_t *args) -{ - dev_link_t *link = args->client_data; - - DEBUG(2, "axnet_event(0x%06x)\n", event); - - switch (event) { - case CS_EVENT_CARD_INSERTION: - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - axnet_config(link); - break; - } - return 0; -} /* axnet_event */ - -/*====================================================================== - MII interface support ======================================================================*/ @@ -608,7 +570,7 @@ static int axnet_open(struct net_device *dev) link->open++; - request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, dev_info, dev); + request_irq(dev->irq, ei_irq_wrapper, SA_SHIRQ, "axnet_cs", dev); info->link_status = 0x00; init_timer(&info->watchdog); @@ -869,8 +831,7 @@ static struct pcmcia_driver axnet_cs_driver = { .drv = { .name = "axnet_cs", }, - .attach = axnet_attach, - .event = axnet_event, + .probe = axnet_attach, .remove = axnet_detach, .id_table = axnet_ids, .suspend = axnet_suspend, -- cgit v1.1