diff options
Diffstat (limited to 'drivers/isdn')
-rw-r--r-- | drivers/isdn/hardware/avm/avm_cs.c | 145 | ||||
-rw-r--r-- | drivers/isdn/hisax/avma1_cs.c | 150 | ||||
-rw-r--r-- | drivers/isdn/hisax/elsa_cs.c | 158 | ||||
-rw-r--r-- | drivers/isdn/hisax/sedlbauer_cs.c | 169 | ||||
-rw-r--r-- | drivers/isdn/hisax/teles_cs.c | 149 |
5 files changed, 188 insertions, 583 deletions
diff --git a/drivers/isdn/hardware/avm/avm_cs.c b/drivers/isdn/hardware/avm/avm_cs.c index 27391c32f3e..2a2b03ff096 100644 --- a/drivers/isdn/hardware/avm/avm_cs.c +++ b/drivers/isdn/hardware/avm/avm_cs.c @@ -53,8 +53,6 @@ MODULE_LICENSE("GPL"); static void avmcs_config(dev_link_t *link); static void avmcs_release(dev_link_t *link); -static int avmcs_event(event_t event, int priority, - event_callback_args_t *args); /* The attach() and detach() entry points are used to create and destroy @@ -62,16 +60,7 @@ static int avmcs_event(event_t event, int priority, needed to manage one actual PCMCIA card. */ -static dev_link_t *avmcs_attach(void); -static void avmcs_detach(dev_link_t *); - -/* - The dev_info variable is the "key" that is used to match up this - device driver with appropriate cards, through the card configuration - database. -*/ - -static dev_info_t dev_info = "avm_cs"; +static void avmcs_detach(struct pcmcia_device *p_dev); /* A linked list of "instances" of the skeleton device. Each actual @@ -83,15 +72,7 @@ static dev_info_t dev_info = "avm_cs"; device numbers are used to derive the corresponding array index. */ -static dev_link_t *dev_list = NULL; - /* - A dev_link_t structure has fields for most things that are needed - to keep track of a socket, but there will usually be some device - specific information that also needs to be kept track of. The - 'priv' pointer in a dev_link_t structure can be used to point to - a device-specific private data structure, like this. - A driver needs to provide a dev_node_t structure for each device on a card. In some cases, there is only one device per card (for example, ethernet cards, modems). In other cases, there may be @@ -118,13 +99,11 @@ typedef struct local_info_t { ======================================================================*/ -static dev_link_t *avmcs_attach(void) +static int avmcs_attach(struct pcmcia_device *p_dev) { - client_reg_t client_reg; dev_link_t *link; local_info_t *local; - int ret; - + /* Initialize the dev_link_t structure */ link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); if (!link) @@ -155,25 +134,19 @@ static dev_link_t *avmcs_attach(void) goto err_kfree; memset(local, 0, sizeof(local_info_t)); link->priv = local; - - /* Register with Card Services */ - link->next = dev_list; - dev_list = link; - 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 != 0) { - cs_error(link->handle, RegisterClient, ret); - avmcs_detach(link); - goto err; - } - return link; + + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + avmcs_config(link); + + return 0; err_kfree: kfree(link); err: - return NULL; + return -EINVAL; } /* avmcs_attach */ /*====================================================================== @@ -185,33 +158,13 @@ static dev_link_t *avmcs_attach(void) ======================================================================*/ -static void avmcs_detach(dev_link_t *link) +static void avmcs_detach(struct pcmcia_device *p_dev) { - dev_link_t **linkp; - - /* Locate device structure */ - for (linkp = &dev_list; *linkp; linkp = &(*linkp)->next) - if (*linkp == link) break; - if (*linkp == NULL) - return; + dev_link_t *link = dev_to_instance(p_dev); - /* - If the device is currently configured and active, we won't - actually delete it yet. Instead, it is marked so that when - the release() function is called, that will trigger a proper - detach(). - */ - if (link->state & DEV_CONFIG) { - link->state |= DEV_STALE_LINK; - return; - } + if (link->state & DEV_CONFIG) + avmcs_release(link); - /* Break the link with Card Services */ - if (link->handle) - pcmcia_deregister_client(link->handle); - - /* Unlink device structure, free pieces */ - *linkp = link->next; kfree(link->priv); kfree(link); } /* avmcs_detach */ @@ -424,12 +377,30 @@ static void avmcs_release(dev_link_t *link) pcmcia_release_io(link->handle, &link->io); pcmcia_release_irq(link->handle, &link->irq); link->state &= ~DEV_CONFIG; - - if (link->state & DEV_STALE_LINK) - avmcs_detach(link); - } /* avmcs_release */ +static int avmcs_suspend(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(dev); + + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); + + return 0; +} + +static int avmcs_resume(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(dev); + + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); + + return 0; +} + /*====================================================================== The card status event handler. Mostly, this schedules other @@ -444,38 +415,6 @@ static void avmcs_release(dev_link_t *link) ======================================================================*/ -static int avmcs_event(event_t event, int priority, - event_callback_args_t *args) -{ - dev_link_t *link = args->client_data; - - switch (event) { - case CS_EVENT_CARD_REMOVAL: - link->state &= ~DEV_PRESENT; - if (link->state & DEV_CONFIG) - avmcs_release(link); - break; - case CS_EVENT_CARD_INSERTION: - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - avmcs_config(link); - break; - case CS_EVENT_PM_SUSPEND: - link->state |= DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_RESET_PHYSICAL: - if (link->state & DEV_CONFIG) - 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); - break; - } - return 0; -} /* avmcs_event */ static struct pcmcia_device_id avmcs_ids[] = { PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN-Controller B1", 0x95d42008, 0x845dc335), @@ -490,10 +429,11 @@ static struct pcmcia_driver avmcs_driver = { .drv = { .name = "avm_cs", }, - .attach = avmcs_attach, - .event = avmcs_event, - .detach = avmcs_detach, + .probe = avmcs_attach, + .remove = avmcs_detach, .id_table = avmcs_ids, + .suspend= avmcs_suspend, + .resume = avmcs_resume, }; static int __init avmcs_init(void) @@ -504,7 +444,6 @@ static int __init avmcs_init(void) static void __exit avmcs_exit(void) { pcmcia_unregister_driver(&avmcs_driver); - BUG_ON(dev_list != NULL); } module_init(avmcs_init); diff --git a/drivers/isdn/hisax/avma1_cs.c b/drivers/isdn/hisax/avma1_cs.c index 5f5a5ae740d..969da40c424 100644 --- a/drivers/isdn/hisax/avma1_cs.c +++ b/drivers/isdn/hisax/avma1_cs.c @@ -69,8 +69,6 @@ module_param(isdnprot, int, 0); static void avma1cs_config(dev_link_t *link); static void avma1cs_release(dev_link_t *link); -static int avma1cs_event(event_t event, int priority, - event_callback_args_t *args); /* The attach() and detach() entry points are used to create and destroy @@ -78,16 +76,8 @@ static int avma1cs_event(event_t event, int priority, needed to manage one actual PCMCIA card. */ -static dev_link_t *avma1cs_attach(void); -static void avma1cs_detach(dev_link_t *); +static void avma1cs_detach(struct pcmcia_device *p_dev); -/* - The dev_info variable is the "key" that is used to match up this - device driver with appropriate cards, through the card configuration - database. -*/ - -static dev_info_t dev_info = "avma1_cs"; /* A linked list of "instances" of the skeleton device. Each actual @@ -99,15 +89,7 @@ static dev_info_t dev_info = "avma1_cs"; device numbers are used to derive the corresponding array index. */ -static dev_link_t *dev_list = NULL; - /* - A dev_link_t structure has fields for most things that are needed - to keep track of a socket, but there will usually be some device - specific information that also needs to be kept track of. The - 'priv' pointer in a dev_link_t structure can be used to point to - a device-specific private data structure, like this. - A driver needs to provide a dev_node_t structure for each device on a card. In some cases, there is only one device per card (for example, ethernet cards, modems). In other cases, there may be @@ -134,26 +116,24 @@ typedef struct local_info_t { ======================================================================*/ -static dev_link_t *avma1cs_attach(void) +static int avma1cs_attach(struct pcmcia_device *p_dev) { - client_reg_t client_reg; dev_link_t *link; local_info_t *local; - int ret; - + DEBUG(0, "avma1cs_attach()\n"); /* Initialize the dev_link_t structure */ link = kmalloc(sizeof(struct dev_link_t), GFP_KERNEL); if (!link) - return NULL; + return -ENOMEM; memset(link, 0, sizeof(struct dev_link_t)); /* Allocate space for private device-specific data */ local = kmalloc(sizeof(local_info_t), GFP_KERNEL); if (!local) { kfree(link); - return NULL; + return -ENOMEM; } memset(local, 0, sizeof(local_info_t)); link->priv = local; @@ -178,20 +158,13 @@ static dev_link_t *avma1cs_attach(void) link->conf.ConfigIndex = 1; link->conf.Present = PRESENT_OPTION; - /* Register with Card Services */ - link->next = dev_list; - dev_list = link; - 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 != 0) { - cs_error(link->handle, RegisterClient, ret); - avma1cs_detach(link); - return NULL; - } + link->handle = p_dev; + p_dev->instance = link; - return link; + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + avma1cs_config(link); + + return 0; } /* avma1cs_attach */ /*====================================================================== @@ -203,42 +176,17 @@ static dev_link_t *avma1cs_attach(void) ======================================================================*/ -static void avma1cs_detach(dev_link_t *link) +static void avma1cs_detach(struct pcmcia_device *p_dev) { - dev_link_t **linkp; + dev_link_t *link = dev_to_instance(p_dev); DEBUG(0, "avma1cs_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 the device is currently configured and active, we won't - actually delete it yet. Instead, it is marked so that when - the release() function is called, that will trigger a proper - detach(). - */ - if (link->state & DEV_CONFIG) { -#ifdef PCMCIA_DEBUG - printk(KERN_DEBUG "avma1_cs: detach postponed, '%s' " - "still locked\n", link->dev->dev_name); -#endif - link->state |= DEV_STALE_LINK; - return; - } + if (link->state & DEV_CONFIG) + avma1cs_release(link); - /* Break the link with Card Services */ - if (link->handle) - pcmcia_deregister_client(link->handle); - - /* Unlink device structure, free pieces */ - *linkp = link->next; kfree(link->priv); kfree(link); - } /* avma1cs_detach */ /*====================================================================== @@ -440,58 +388,30 @@ static void avma1cs_release(dev_link_t *link) pcmcia_release_io(link->handle, &link->io); pcmcia_release_irq(link->handle, &link->irq); link->state &= ~DEV_CONFIG; - - if (link->state & DEV_STALE_LINK) - avma1cs_detach(link); } /* avma1cs_release */ -/*====================================================================== +static int avma1cs_suspend(struct pcmcia_device *dev) +{ + dev_link_t *link = dev_to_instance(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. + link->state |= DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); - When a CARD_REMOVAL event is received, we immediately set a flag - to block future accesses to this device. All the functions that - actually access the device should check this flag to make sure - the card is still present. - -======================================================================*/ + return 0; +} -static int avma1cs_event(event_t event, int priority, - event_callback_args_t *args) +static int avma1cs_resume(struct pcmcia_device *dev) { - dev_link_t *link = args->client_data; + dev_link_t *link = dev_to_instance(dev); - DEBUG(1, "avma1cs_event(0x%06x)\n", event); - - switch (event) { - case CS_EVENT_CARD_REMOVAL: - if (link->state & DEV_CONFIG) - avma1cs_release(link); - break; - case CS_EVENT_CARD_INSERTION: - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - avma1cs_config(link); - break; - case CS_EVENT_PM_SUSPEND: - link->state |= DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_RESET_PHYSICAL: - if (link->state & DEV_CONFIG) - 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) + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) pcmcia_request_configuration(link->handle, &link->conf); - break; - } - return 0; -} /* avma1cs_event */ + + return 0; +} + static struct pcmcia_device_id avma1cs_ids[] = { PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb), @@ -505,10 +425,11 @@ static struct pcmcia_driver avma1cs_driver = { .drv = { .name = "avma1_cs", }, - .attach = avma1cs_attach, - .event = avma1cs_event, - .detach = avma1cs_detach, + .probe = avma1cs_attach, + .remove = avma1cs_detach, .id_table = avma1cs_ids, + .suspend = avma1cs_suspend, + .resume = avma1cs_resume, }; /*====================================================================*/ @@ -521,7 +442,6 @@ static int __init init_avma1_cs(void) static void __exit exit_avma1_cs(void) { pcmcia_unregister_driver(&avma1cs_driver); - BUG_ON(dev_list != NULL); } module_init(init_avma1_cs); diff --git a/drivers/isdn/hisax/elsa_cs.c b/drivers/isdn/hisax/elsa_cs.c index 6fc6868de0b..062fb8f0739 100644 --- a/drivers/isdn/hisax/elsa_cs.c +++ b/drivers/isdn/hisax/elsa_cs.c @@ -96,8 +96,6 @@ module_param(protocol, int, 0); static void elsa_cs_config(dev_link_t *link); static void elsa_cs_release(dev_link_t *link); -static int elsa_cs_event(event_t event, int priority, - event_callback_args_t *args); /* The attach() and detach() entry points are used to create and destroy @@ -105,39 +103,9 @@ static int elsa_cs_event(event_t event, int priority, needed to manage one actual PCMCIA card. */ -static dev_link_t *elsa_cs_attach(void); -static void elsa_cs_detach(dev_link_t *); +static void elsa_cs_detach(struct pcmcia_device *p_dev); /* - The dev_info variable is the "key" that is used to match up this - device driver with appropriate cards, through the card configuration - database. -*/ - -static dev_info_t dev_info = "elsa_cs"; - -/* - A linked list of "instances" of the elsa_cs device. Each actual - PCMCIA card corresponds to one device instance, and is described - by one dev_link_t structure (defined in ds.h). - - You may not want to use a linked list for this -- for example, the - memory card driver uses an array of dev_link_t pointers, where minor - device numbers are used to derive the corresponding array index. -*/ - -static dev_link_t *dev_list = NULL; - -/* - A dev_link_t structure has fields for most things that are needed - to keep track of a socket, but there will usually be some device - specific information that also needs to be kept track of. The - 'priv' pointer in a dev_link_t structure can be used to point to - a device-specific private data structure, like this. - - To simplify the data structure handling, we actually include the - dev_link_t structure in the device's private data structure. - A driver needs to provide a dev_node_t structure for each device on a card. In some cases, there is only one device per card (for example, ethernet cards, modems). In other cases, there may be @@ -171,18 +139,16 @@ typedef struct local_info_t { ======================================================================*/ -static dev_link_t *elsa_cs_attach(void) +static int elsa_cs_attach(struct pcmcia_device *p_dev) { - client_reg_t client_reg; dev_link_t *link; local_info_t *local; - int ret; DEBUG(0, "elsa_cs_attach()\n"); /* Allocate space for private device-specific data */ local = kmalloc(sizeof(local_info_t), GFP_KERNEL); - if (!local) return NULL; + if (!local) return -ENOMEM; memset(local, 0, sizeof(local_info_t)); local->cardnr = -1; link = &local->link; link->priv = local; @@ -207,20 +173,13 @@ static dev_link_t *elsa_cs_attach(void) link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - /* Register with Card Services */ - link->next = dev_list; - dev_list = link; - 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); - elsa_cs_detach(link); - return NULL; - } + link->handle = p_dev; + p_dev->instance = link; - return link; + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + elsa_cs_config(link); + + return 0; } /* elsa_cs_attach */ /*====================================================================== @@ -232,32 +191,18 @@ static dev_link_t *elsa_cs_attach(void) ======================================================================*/ -static void elsa_cs_detach(dev_link_t *link) +static void elsa_cs_detach(struct pcmcia_device *p_dev) { - dev_link_t **linkp; + dev_link_t *link = dev_to_instance(p_dev); local_info_t *info = link->priv; - int ret; DEBUG(0, "elsa_cs_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->state & DEV_CONFIG) - elsa_cs_release(link); - - /* Break the link with Card Services */ - if (link->handle) { - ret = pcmcia_deregister_client(link->handle); - if (ret != CS_SUCCESS) - cs_error(link->handle, DeregisterClient, ret); + if (link->state & DEV_CONFIG) { + info->busy = 1; + elsa_cs_release(link); } - /* Unlink device structure and free it */ - *linkp = link->next; kfree(info); } /* elsa_cs_detach */ @@ -447,60 +392,31 @@ static void elsa_cs_release(dev_link_t *link) link->state &= ~DEV_CONFIG; } /* elsa_cs_release */ -/*====================================================================== - - 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 elsa_suspend(struct pcmcia_device *p_dev) +{ + dev_link_t *link = dev_to_instance(p_dev); + local_info_t *dev = link->priv; - When a CARD_REMOVAL event is received, we immediately set a flag - to block future accesses to this device. All the functions that - actually access the device should check this flag to make sure - the card is still present. + link->state |= DEV_SUSPEND; + dev->busy = 1; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); -======================================================================*/ + return 0; +} -static int elsa_cs_event(event_t event, int priority, - event_callback_args_t *args) +static int elsa_resume(struct pcmcia_device *p_dev) { - dev_link_t *link = args->client_data; - local_info_t *dev = link->priv; - - DEBUG(1, "elsa_cs_event(%d)\n", event); + dev_link_t *link = dev_to_instance(p_dev); + local_info_t *dev = link->priv; - switch (event) { - case CS_EVENT_CARD_REMOVAL: - link->state &= ~DEV_PRESENT; - if (link->state & DEV_CONFIG) { - ((local_info_t*)link->priv)->busy = 1; - elsa_cs_release(link); - } - break; - case CS_EVENT_CARD_INSERTION: - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - elsa_cs_config(link); - break; - case CS_EVENT_PM_SUSPEND: - link->state |= DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_RESET_PHYSICAL: - /* Mark the device as stopped, to block IO until later */ - dev->busy = 1; - if (link->state & DEV_CONFIG) - 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); + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); dev->busy = 0; - break; - } - return 0; -} /* elsa_cs_event */ + + return 0; +} static struct pcmcia_device_id elsa_ids[] = { PCMCIA_DEVICE_PROD_ID12("ELSA AG (Aachen, Germany)", "MicroLink ISDN/MC ", 0x983de2c4, 0x333ba257), @@ -514,10 +430,11 @@ static struct pcmcia_driver elsa_cs_driver = { .drv = { .name = "elsa_cs", }, - .attach = elsa_cs_attach, - .event = elsa_cs_event, - .detach = elsa_cs_detach, + .probe = elsa_cs_attach, + .remove = elsa_cs_detach, .id_table = elsa_ids, + .suspend = elsa_suspend, + .resume = elsa_resume, }; static int __init init_elsa_cs(void) @@ -528,7 +445,6 @@ static int __init init_elsa_cs(void) static void __exit exit_elsa_cs(void) { pcmcia_unregister_driver(&elsa_cs_driver); - BUG_ON(dev_list != NULL); } module_init(init_elsa_cs); diff --git a/drivers/isdn/hisax/sedlbauer_cs.c b/drivers/isdn/hisax/sedlbauer_cs.c index dc334aab433..6f5213a18a8 100644 --- a/drivers/isdn/hisax/sedlbauer_cs.c +++ b/drivers/isdn/hisax/sedlbauer_cs.c @@ -97,8 +97,6 @@ module_param(protocol, int, 0); static void sedlbauer_config(dev_link_t *link); static void sedlbauer_release(dev_link_t *link); -static int sedlbauer_event(event_t event, int priority, - event_callback_args_t *args); /* The attach() and detach() entry points are used to create and destroy @@ -106,8 +104,7 @@ static int sedlbauer_event(event_t event, int priority, needed to manage one actual PCMCIA card. */ -static dev_link_t *sedlbauer_attach(void); -static void sedlbauer_detach(dev_link_t *); +static void sedlbauer_detach(struct pcmcia_device *p_dev); /* You'll also need to prototype all the functions that will actually @@ -117,35 +114,6 @@ static void sedlbauer_detach(dev_link_t *); */ /* - The dev_info variable is the "key" that is used to match up this - device driver with appropriate cards, through the card configuration - database. -*/ - -static dev_info_t dev_info = "sedlbauer_cs"; - -/* - A linked list of "instances" of the sedlbauer device. Each actual - PCMCIA card corresponds to one device instance, and is described - by one dev_link_t structure (defined in ds.h). - - You may not want to use a linked list for this -- for example, the - memory card driver uses an array of dev_link_t pointers, where minor - device numbers are used to derive the corresponding array index. -*/ - -static dev_link_t *dev_list = NULL; - -/* - A dev_link_t structure has fields for most things that are needed - to keep track of a socket, but there will usually be some device - specific information that also needs to be kept track of. The - 'priv' pointer in a dev_link_t structure can be used to point to - a device-specific private data structure, like this. - - To simplify the data structure handling, we actually include the - dev_link_t structure in the device's private data structure. - A driver needs to provide a dev_node_t structure for each device on a card. In some cases, there is only one device per card (for example, ethernet cards, modems). In other cases, there may be @@ -180,18 +148,16 @@ typedef struct local_info_t { ======================================================================*/ -static dev_link_t *sedlbauer_attach(void) +static int sedlbauer_attach(struct pcmcia_device *p_dev) { local_info_t *local; dev_link_t *link; - client_reg_t client_reg; - int ret; DEBUG(0, "sedlbauer_attach()\n"); /* Allocate space for private device-specific data */ local = kmalloc(sizeof(local_info_t), GFP_KERNEL); - if (!local) return NULL; + if (!local) return -ENOMEM; memset(local, 0, sizeof(local_info_t)); local->cardnr = -1; link = &local->link; link->priv = local; @@ -221,20 +187,13 @@ static dev_link_t *sedlbauer_attach(void) link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - /* Register with Card Services */ - link->next = dev_list; - dev_list = link; - 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); - sedlbauer_detach(link); - return NULL; - } + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + sedlbauer_config(link); - return link; + return 0; } /* sedlbauer_attach */ /*====================================================================== @@ -246,39 +205,17 @@ static dev_link_t *sedlbauer_attach(void) ======================================================================*/ -static void sedlbauer_detach(dev_link_t *link) +static void sedlbauer_detach(struct pcmcia_device *p_dev) { - dev_link_t **linkp; + dev_link_t *link = dev_to_instance(p_dev); DEBUG(0, "sedlbauer_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 the device is currently configured and active, we won't - actually delete it yet. Instead, it is marked so that when - the release() function is called, that will trigger a proper - detach(). - */ if (link->state & DEV_CONFIG) { -#ifdef PCMCIA_DEBUG - printk(KERN_DEBUG "sedlbauer_cs: detach postponed, '%s' " - "still locked\n", link->dev->dev_name); -#endif - link->state |= DEV_STALE_LINK; - return; + ((local_info_t *)link->priv)->stop = 1; + sedlbauer_release(link); } - /* Break the link with Card Services */ - if (link->handle) - pcmcia_deregister_client(link->handle); - - /* Unlink device structure, and free it */ - *linkp = link->next; /* This points to the parent local_info_t struct */ kfree(link->priv); } /* sedlbauer_detach */ @@ -547,68 +484,34 @@ static void sedlbauer_release(dev_link_t *link) if (link->irq.AssignedIRQ) pcmcia_release_irq(link->handle, &link->irq); link->state &= ~DEV_CONFIG; - - if (link->state & DEV_STALE_LINK) - sedlbauer_detach(link); - } /* sedlbauer_release */ -/*====================================================================== - - The card status event handler. Mostly, this schedules other - stuff to run after an event is received. - - When a CARD_REMOVAL event is received, we immediately set a - private flag to block future accesses to this device. All the - functions that actually access the device should check this flag - to make sure the card is still present. - -======================================================================*/ - -static int sedlbauer_event(event_t event, int priority, - event_callback_args_t *args) +static int sedlbauer_suspend(struct pcmcia_device *p_dev) { - dev_link_t *link = args->client_data; - local_info_t *dev = link->priv; - - DEBUG(1, "sedlbauer_event(0x%06x)\n", event); - - switch (event) { - case CS_EVENT_CARD_REMOVAL: - link->state &= ~DEV_PRESENT; - if (link->state & DEV_CONFIG) { - ((local_info_t *)link->priv)->stop = 1; - sedlbauer_release(link); - } - break; - case CS_EVENT_CARD_INSERTION: - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - sedlbauer_config(link); - break; - case CS_EVENT_PM_SUSPEND: + dev_link_t *link = dev_to_instance(p_dev); + local_info_t *dev = link->priv; + link->state |= DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_RESET_PHYSICAL: - /* Mark the device as stopped, to block IO until later */ dev->stop = 1; if (link->state & DEV_CONFIG) - pcmcia_release_configuration(link->handle); - break; - case CS_EVENT_PM_RESUME: + pcmcia_release_configuration(link->handle); + + return 0; +} + +static int sedlbauer_resume(struct pcmcia_device *p_dev) +{ + dev_link_t *link = dev_to_instance(p_dev); + local_info_t *dev = link->priv; + link->state &= ~DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_CARD_RESET: if (link->state & DEV_CONFIG) - pcmcia_request_configuration(link->handle, &link->conf); + pcmcia_request_configuration(link->handle, &link->conf); dev->stop = 0; - /* - In a normal driver, additional code may go here to restore - the device state and restart IO. - */ - break; - } - return 0; -} /* sedlbauer_event */ + + return 0; +} + static struct pcmcia_device_id sedlbauer_ids[] = { PCMCIA_DEVICE_PROD_ID123("SEDLBAUER", "speed star II", "V 3.1", 0x81fb79f5, 0xf3612e1d, 0x6b95c78a), @@ -627,10 +530,11 @@ static struct pcmcia_driver sedlbauer_driver = { .drv = { .name = "sedlbauer_cs", }, - .attach = sedlbauer_attach, - .event = sedlbauer_event, - .detach = sedlbauer_detach, + .probe = sedlbauer_attach, + .remove = sedlbauer_detach, .id_table = sedlbauer_ids, + .suspend = sedlbauer_suspend, + .resume = sedlbauer_resume, }; static int __init init_sedlbauer_cs(void) @@ -641,7 +545,6 @@ static int __init init_sedlbauer_cs(void) static void __exit exit_sedlbauer_cs(void) { pcmcia_unregister_driver(&sedlbauer_driver); - BUG_ON(dev_list != NULL); } module_init(init_sedlbauer_cs); diff --git a/drivers/isdn/hisax/teles_cs.c b/drivers/isdn/hisax/teles_cs.c index 0ddef1bf778..4e5c14c7240 100644 --- a/drivers/isdn/hisax/teles_cs.c +++ b/drivers/isdn/hisax/teles_cs.c @@ -77,8 +77,6 @@ module_param(protocol, int, 0); static void teles_cs_config(dev_link_t *link); static void teles_cs_release(dev_link_t *link); -static int teles_cs_event(event_t event, int priority, - event_callback_args_t *args); /* The attach() and detach() entry points are used to create and destroy @@ -86,16 +84,7 @@ static int teles_cs_event(event_t event, int priority, needed to manage one actual PCMCIA card. */ -static dev_link_t *teles_attach(void); -static void teles_detach(dev_link_t *); - -/* - The dev_info variable is the "key" that is used to match up this - device driver with appropriate cards, through the card configuration - database. -*/ - -static dev_info_t dev_info = "teles_cs"; +static void teles_detach(struct pcmcia_device *p_dev); /* A linked list of "instances" of the teles_cs device. Each actual @@ -107,18 +96,7 @@ static dev_info_t dev_info = "teles_cs"; device numbers are used to derive the corresponding array index. */ -static dev_link_t *dev_list = NULL; - /* - A dev_link_t structure has fields for most things that are needed - to keep track of a socket, but there will usually be some device - specific information that also needs to be kept track of. The - 'priv' pointer in a dev_link_t structure can be used to point to - a device-specific private data structure, like this. - - To simplify the data structure handling, we actually include the - dev_link_t structure in the device's private data structure. - A driver needs to provide a dev_node_t structure for each device on a card. In some cases, there is only one device per card (for example, ethernet cards, modems). In other cases, there may be @@ -152,18 +130,16 @@ typedef struct local_info_t { ======================================================================*/ -static dev_link_t *teles_attach(void) +static int teles_attach(struct pcmcia_device *p_dev) { - client_reg_t client_reg; dev_link_t *link; local_info_t *local; - int ret; DEBUG(0, "teles_attach()\n"); /* Allocate space for private device-specific data */ local = kmalloc(sizeof(local_info_t), GFP_KERNEL); - if (!local) return NULL; + if (!local) return -ENOMEM; memset(local, 0, sizeof(local_info_t)); local->cardnr = -1; link = &local->link; link->priv = local; @@ -188,20 +164,13 @@ static dev_link_t *teles_attach(void) link->conf.Vcc = 50; link->conf.IntType = INT_MEMORY_AND_IO; - /* Register with Card Services */ - link->next = dev_list; - dev_list = link; - 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); - teles_detach(link); - return NULL; - } + link->handle = p_dev; + p_dev->instance = link; + + link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; + teles_cs_config(link); - return link; + return 0; } /* teles_attach */ /*====================================================================== @@ -213,32 +182,18 @@ static dev_link_t *teles_attach(void) ======================================================================*/ -static void teles_detach(dev_link_t *link) +static void teles_detach(struct pcmcia_device *p_dev) { - dev_link_t **linkp; + dev_link_t *link = dev_to_instance(p_dev); local_info_t *info = link->priv; - int ret; DEBUG(0, "teles_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->state & DEV_CONFIG) - teles_cs_release(link); - - /* Break the link with Card Services */ - if (link->handle) { - ret = pcmcia_deregister_client(link->handle); - if (ret != CS_SUCCESS) - cs_error(link->handle, DeregisterClient, ret); + if (link->state & DEV_CONFIG) { + info->busy = 1; + teles_cs_release(link); } - /* Unlink device structure and free it */ - *linkp = link->next; kfree(info); } /* teles_detach */ @@ -428,60 +383,32 @@ static void teles_cs_release(dev_link_t *link) link->state &= ~DEV_CONFIG; } /* teles_cs_release */ -/*====================================================================== - - 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 teles_suspend(struct pcmcia_device *p_dev) +{ + dev_link_t *link = dev_to_instance(p_dev); + local_info_t *dev = link->priv; - When a CARD_REMOVAL event is received, we immediately set a flag - to block future accesses to this device. All the functions that - actually access the device should check this flag to make sure - the card is still present. + link->state |= DEV_SUSPEND; + dev->busy = 1; + if (link->state & DEV_CONFIG) + pcmcia_release_configuration(link->handle); -======================================================================*/ + return 0; +} -static int teles_cs_event(event_t event, int priority, - event_callback_args_t *args) +static int teles_resume(struct pcmcia_device *p_dev) { - dev_link_t *link = args->client_data; - local_info_t *dev = link->priv; - - DEBUG(1, "teles_cs_event(%d)\n", event); + dev_link_t *link = dev_to_instance(p_dev); + local_info_t *dev = link->priv; - switch (event) { - case CS_EVENT_CARD_REMOVAL: - link->state &= ~DEV_PRESENT; - if (link->state & DEV_CONFIG) { - ((local_info_t*)link->priv)->busy = 1; - teles_cs_release(link); - } - break; - case CS_EVENT_CARD_INSERTION: - link->state |= DEV_PRESENT | DEV_CONFIG_PENDING; - teles_cs_config(link); - break; - case CS_EVENT_PM_SUSPEND: - link->state |= DEV_SUSPEND; - /* Fall through... */ - case CS_EVENT_RESET_PHYSICAL: - /* Mark the device as stopped, to block IO until later */ - dev->busy = 1; - if (link->state & DEV_CONFIG) - 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); + link->state &= ~DEV_SUSPEND; + if (link->state & DEV_CONFIG) + pcmcia_request_configuration(link->handle, &link->conf); dev->busy = 0; - break; - } - return 0; -} /* teles_cs_event */ + + return 0; +} + static struct pcmcia_device_id teles_ids[] = { PCMCIA_DEVICE_PROD_ID12("TELES", "S0/PC", 0x67b50eae, 0xe9e70119), @@ -494,10 +421,11 @@ static struct pcmcia_driver teles_cs_driver = { .drv = { .name = "teles_cs", }, - .attach = teles_attach, - .event = teles_cs_event, - .detach = teles_detach, + .probe = teles_attach, + .remove = teles_detach, .id_table = teles_ids, + .suspend = teles_suspend, + .resume = teles_resume, }; static int __init init_teles_cs(void) @@ -508,7 +436,6 @@ static int __init init_teles_cs(void) static void __exit exit_teles_cs(void) { pcmcia_unregister_driver(&teles_cs_driver); - BUG_ON(dev_list != NULL); } module_init(init_teles_cs); |