Add support to the PCMCIA core to move the supend and resume methods out of the event handler. Also use these functions for pre- and post-reset, as almost all drivers do it this way anyway. Convert pcnet_cs as an example. Signed-off-by: Dominik Brodowski --- Documentation/pcmcia/driver-changes.txt | 6 +++ drivers/net/pcmcia/pcnet_cs.c | 58 +++++++++++++++++++------------- drivers/pcmcia/ds.c | 10 +++++ include/pcmcia/ds.h | 6 +++ 4 files changed, 57 insertions(+), 23 deletions(-) Index: 2.6.13-rc4-git1/drivers/net/pcmcia/pcnet_cs.c =================================================================== --- 2.6.13-rc4-git1.orig/drivers/net/pcmcia/pcnet_cs.c +++ 2.6.13-rc4-git1/drivers/net/pcmcia/pcnet_cs.c @@ -780,6 +780,39 @@ static void pcnet_release(dev_link_t *li ======================================================================*/ +static int pcnet_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 pcnet_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) { + pcnet_reset_8390(dev); + NS8390_init(dev, 1); + netif_device_attach(dev); + } + } + + return 0; +} + static int pcnet_event(event_t event, int priority, event_callback_args_t *args) { @@ -798,29 +831,6 @@ static int pcnet_event(event_t event, in link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; pcnet_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) { - pcnet_reset_8390(dev); - NS8390_init(dev, 1); - netif_device_attach(dev); - } - } - break; } return 0; } /* pcnet_event */ @@ -1843,6 +1853,8 @@ static struct pcmcia_driver pcnet_driver .detach = pcnet_detach, .owner = THIS_MODULE, .id_table = pcnet_ids, + .suspend = pcnet_suspend, + .resume = pcnet_resume, }; static int __init init_pcnet_cs(void) Index: 2.6.13-rc4-git1/include/pcmcia/ds.h =================================================================== --- 2.6.13-rc4-git1.orig/include/pcmcia/ds.h +++ 2.6.13-rc4-git1/include/pcmcia/ds.h @@ -137,6 +137,10 @@ struct pcmcia_driver { int (*event) (event_t event, int priority, event_callback_args_t *); void (*detach)(dev_link_t *); + + int (*suspend) (struct pcmcia_device *dev); + int (*resume) (struct pcmcia_device *dev); + struct module *owner; struct pcmcia_device_id *id_table; struct device_driver drv; @@ -193,6 +197,8 @@ struct pcmcia_device { #define handle_to_pdev(handle) (handle) #define handle_to_dev(handle) (handle->dev) +#define dev_to_instance(dev) (dev->instance); + /* error reporting */ void cs_error(client_handle_t handle, int func, int ret); Index: 2.6.13-rc4-git1/drivers/pcmcia/ds.c =================================================================== --- 2.6.13-rc4-git1.orig/drivers/pcmcia/ds.c +++ 2.6.13-rc4-git1/drivers/pcmcia/ds.c @@ -946,6 +946,16 @@ static int send_event_callback(struct de if (p_dev->state & (CLIENT_UNBOUND|CLIENT_STALE)) return 0; + if ((data->event == CS_EVENT_PM_SUSPEND) || + (data->event == CS_EVENT_RESET_PHYSICAL)) { + if (p_drv->suspend) + return p_drv->suspend(p_dev); + } else if ((data->event == CS_EVENT_PM_RESUME) || + (data->event == CS_EVENT_CARD_RESET)) { + if (p_drv->resume) + return p_drv->resume(p_dev); + } + if (p_drv->event) return p_drv->event(data->event, data->priority, &p_dev->event_callback_args); Index: 2.6.13-rc4-git1/Documentation/pcmcia/driver-changes.txt =================================================================== --- 2.6.13-rc4-git1.orig/Documentation/pcmcia/driver-changes.txt +++ 2.6.13-rc4-git1/Documentation/pcmcia/driver-changes.txt @@ -1,5 +1,11 @@ This file details changes in 2.6 which affect PCMCIA card driver authors: +* Move suspend, resume and reset out of event handler (as of 2.6.14) + int (*suspend) (struct pcmcia_device *dev); + int (*resume) (struct pcmcia_device *dev); + should be initialized in struct pcmcia_driver, and handle + (SUSPEND == RESET_PHYSICAL) and (RESUME == CARD_RESET) events + * event handler initialization in struct pcmcia_driver (as of 2.6.13) The event handler is notified of all events, and must be initialized as the event() callback in the driver's struct pcmcia_driver.