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/wireless/hostap/hostap_cs.c | 88 ++++++++++++++++++--------------- 1 file changed, 49 insertions(+), 39 deletions(-) (limited to 'drivers/net/wireless/hostap/hostap_cs.c') diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 2643976a6677..ba4a7da98ccd 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -846,20 +846,64 @@ static void prism2_release(u_long arg) PDEBUG(DEBUG_FLOW, "release - done\n"); } +static int hostap_cs_suspend(struct pcmcia_device *p_dev) +{ + dev_link_t *link = dev_to_instance(p_dev); + struct net_device *dev = (struct net_device *) link->priv; + int dev_open = 0; -static int prism2_event(event_t event, int priority, - event_callback_args_t *args) + PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info); + + link->state |= DEV_SUSPEND; + + if (link->state & DEV_CONFIG) { + struct hostap_interface *iface = netdev_priv(dev); + if (iface && iface->local) + dev_open = iface->local->num_dev_open > 0; + if (dev_open) { + netif_stop_queue(dev); + netif_device_detach(dev); + } + prism2_suspend(dev); + pcmcia_release_configuration(link->handle); + } + + return 0; +} + +static int hostap_cs_resume(struct pcmcia_device *p_dev) { - dev_link_t *link = args->client_data; + dev_link_t *link = dev_to_instance(p_dev); struct net_device *dev = (struct net_device *) link->priv; int dev_open = 0; + PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info); + + link->state &= ~DEV_SUSPEND; if (link->state & DEV_CONFIG) { struct hostap_interface *iface = netdev_priv(dev); if (iface && iface->local) dev_open = iface->local->num_dev_open > 0; + + pcmcia_request_configuration(link->handle, &link->conf); + + prism2_hw_shutdown(dev, 1); + prism2_hw_config(dev, dev_open ? 0 : 1); + if (dev_open) { + netif_device_attach(dev); + netif_start_queue(dev); + } } + return 0; +} + +static int prism2_event(event_t event, int priority, + event_callback_args_t *args) +{ + dev_link_t *link = args->client_data; + struct net_device *dev = (struct net_device *) link->priv; + switch (event) { case CS_EVENT_CARD_INSERTION: PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info); @@ -879,42 +923,6 @@ static int prism2_event(event_t event, int priority, } break; - case CS_EVENT_PM_SUSPEND: - PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_SUSPEND\n", dev_info); - link->state |= DEV_SUSPEND; - /* fall through */ - - case CS_EVENT_RESET_PHYSICAL: - PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info); - if (link->state & DEV_CONFIG) { - if (dev_open) { - netif_stop_queue(dev); - netif_device_detach(dev); - } - prism2_suspend(dev); - pcmcia_release_configuration(link->handle); - } - break; - - case CS_EVENT_PM_RESUME: - PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_PM_RESUME\n", dev_info); - link->state &= ~DEV_SUSPEND; - /* fall through */ - - case CS_EVENT_CARD_RESET: - PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_RESET\n", dev_info); - if (link->state & DEV_CONFIG) { - pcmcia_request_configuration(link->handle, - &link->conf); - prism2_hw_shutdown(dev, 1); - prism2_hw_config(dev, dev_open ? 0 : 1); - if (dev_open) { - netif_device_attach(dev); - netif_start_queue(dev); - } - } - break; - default: PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n", dev_info, event); @@ -987,6 +995,8 @@ static struct pcmcia_driver hostap_driver = { .owner = THIS_MODULE, .event = prism2_event, .id_table = hostap_cs_ids, + .suspend = hostap_cs_suspend, + .resume = hostap_cs_resume, }; static int __init init_prism2_pccard(void) -- cgit v1.2.3 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/wireless/hostap/hostap_cs.c | 28 +++++----------------------- 1 file changed, 5 insertions(+), 23 deletions(-) (limited to 'drivers/net/wireless/hostap/hostap_cs.c') diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index ba4a7da98ccd..866142af7d92 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -203,7 +203,7 @@ static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len) -static void prism2_detach(dev_link_t *link); +static void prism2_detach(struct pcmcia_device *p_dev); static void prism2_release(u_long arg); static int prism2_event(event_t event, int priority, event_callback_args_t *args); @@ -528,15 +528,16 @@ static dev_link_t *prism2_attach(void) ret = pcmcia_register_client(&link->handle, &client_reg); if (ret != CS_SUCCESS) { cs_error(link->handle, RegisterClient, ret); - prism2_detach(link); + prism2_detach(link->handle); return NULL; } return link; } -static void prism2_detach(dev_link_t *link) +static void prism2_detach(struct pcmcia_device *p_dev) { + dev_link_t *link = dev_to_instance(p_dev); dev_link_t **linkp; PDEBUG(DEBUG_FLOW, "prism2_detach\n"); @@ -554,14 +555,6 @@ static void prism2_detach(dev_link_t *link) prism2_release((u_long)link); } - if (link->handle) { - int res = pcmcia_deregister_client(link->handle); - if (res) { - printk("CardService(DeregisterClient) => %d\n", res); - cs_error(link->handle, DeregisterClient, res); - } - } - *linkp = link->next; /* release net devices */ if (link->priv) { @@ -902,7 +895,6 @@ static int prism2_event(event_t event, int priority, event_callback_args_t *args) { dev_link_t *link = args->client_data; - struct net_device *dev = (struct net_device *) link->priv; switch (event) { case CS_EVENT_CARD_INSERTION: @@ -913,16 +905,6 @@ static int prism2_event(event_t event, int priority, } break; - case CS_EVENT_CARD_REMOVAL: - PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_REMOVAL\n", dev_info); - link->state &= ~DEV_PRESENT; - if (link->state & DEV_CONFIG) { - netif_stop_queue(dev); - netif_device_detach(dev); - prism2_release((u_long) link); - } - break; - default: PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n", dev_info, event); @@ -991,7 +973,7 @@ static struct pcmcia_driver hostap_driver = { .name = "hostap_cs", }, .attach = prism2_attach, - .detach = prism2_detach, + .remove = prism2_detach, .owner = THIS_MODULE, .event = prism2_event, .id_table = hostap_cs_ids, -- cgit v1.2.3 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/wireless/hostap/hostap_cs.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'drivers/net/wireless/hostap/hostap_cs.c') diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 866142af7d92..195a5bf3d725 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -25,7 +25,6 @@ static char *version = PRISM2_VERSION " (Jouni Malinen )"; static dev_info_t dev_info = "hostap_cs"; -static dev_link_t *dev_list = NULL; MODULE_AUTHOR("Jouni Malinen"); MODULE_DESCRIPTION("Support for Intersil Prism2-based 802.11 wireless LAN " @@ -520,8 +519,7 @@ static dev_link_t *prism2_attach(void) link->conf.IntType = INT_MEMORY_AND_IO; /* register with CardServices */ - 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; @@ -538,24 +536,13 @@ static dev_link_t *prism2_attach(void) static void prism2_detach(struct pcmcia_device *p_dev) { dev_link_t *link = dev_to_instance(p_dev); - dev_link_t **linkp; PDEBUG(DEBUG_FLOW, "prism2_detach\n"); - for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) - if (*linkp == link) - break; - if (*linkp == NULL) { - printk(KERN_WARNING "%s: Attempt to detach non-existing " - "PCMCIA client\n", dev_info); - return; - } - if (link->state & DEV_CONFIG) { prism2_release((u_long)link); } - *linkp = link->next; /* release net devices */ if (link->priv) { struct hostap_cs_priv *hw_priv; -- cgit v1.2.3 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/wireless/hostap/hostap_cs.c | 55 +++++++-------------------------- 1 file changed, 12 insertions(+), 43 deletions(-) (limited to 'drivers/net/wireless/hostap/hostap_cs.c') diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c index 195a5bf3d725..8bc0b528548f 100644 --- a/drivers/net/wireless/hostap/hostap_cs.c +++ b/drivers/net/wireless/hostap/hostap_cs.c @@ -204,8 +204,7 @@ static int hfa384x_to_bap(struct net_device *dev, u16 bap, void *buf, int len) static void prism2_detach(struct pcmcia_device *p_dev); static void prism2_release(u_long arg); -static int prism2_event(event_t event, int priority, - event_callback_args_t *args); +static int prism2_config(dev_link_t *link); static int prism2_pccard_card_present(local_info_t *local) @@ -502,15 +501,13 @@ static struct prism2_helper_functions prism2_pccard_funcs = /* allocate local data and register with CardServices * initialize dev_link structure, but do not configure the card yet */ -static dev_link_t *prism2_attach(void) +static int prism2_attach(struct pcmcia_device *p_dev) { dev_link_t *link; - client_reg_t client_reg; - int ret; link = kmalloc(sizeof(dev_link_t), GFP_KERNEL); if (link == NULL) - return NULL; + return -ENOMEM; memset(link, 0, sizeof(dev_link_t)); @@ -518,18 +515,14 @@ static dev_link_t *prism2_attach(void) link->conf.Vcc = 33; link->conf.IntType = INT_MEMORY_AND_IO; - /* register with CardServices */ - 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); - prism2_detach(link->handle); - return NULL; - } - return link; + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + if (prism2_config(link)) + PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n"); + + return 0; } @@ -878,29 +871,6 @@ static int hostap_cs_resume(struct pcmcia_device *p_dev) return 0; } -static int prism2_event(event_t event, int priority, - event_callback_args_t *args) -{ - dev_link_t *link = args->client_data; - - switch (event) { - case CS_EVENT_CARD_INSERTION: - PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_CARD_INSERTION\n", dev_info); - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - if (prism2_config(link)) { - PDEBUG(DEBUG_EXTRA, "prism2_config() failed\n"); - } - break; - - default: - PDEBUG(DEBUG_EXTRA, "%s: prism2_event() - unknown event %d\n", - dev_info, event); - break; - } - return 0; -} - - static struct pcmcia_device_id hostap_cs_ids[] = { PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), @@ -959,10 +929,9 @@ static struct pcmcia_driver hostap_driver = { .drv = { .name = "hostap_cs", }, - .attach = prism2_attach, + .probe = prism2_attach, .remove = prism2_detach, .owner = THIS_MODULE, - .event = prism2_event, .id_table = hostap_cs_ids, .suspend = hostap_cs_suspend, .resume = hostap_cs_resume, -- cgit v1.2.3