diff options
Diffstat (limited to 'drivers/isdn/hisax/elsa_cs.c')
-rw-r--r-- | drivers/isdn/hisax/elsa_cs.c | 158 |
1 files changed, 37 insertions, 121 deletions
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); |