static void elsa_cs_detach(dev_link_t *link) { dev_link_t **linkp; 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); } /* Unlink device structure and free it */ *linkp = link->next; kfree(info); } /* elsa_cs_detach */
static void elsa_cs_detach(struct pcmcia_device *link) { local_info_t *info = link->priv; dev_dbg(&link->dev, "elsa_cs_detach(0x%p)\n", link); info->busy = 1; elsa_cs_release(link); kfree(info); } /* elsa_cs_detach */
static int elsa_cs_config(struct pcmcia_device *link) { int i; IsdnCard_t icard; dev_dbg(&link->dev, "elsa_config(0x%p)\n", link); link->config_flags |= CONF_ENABLE_IRQ | CONF_AUTO_SET_IO; i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL); if (i != 0) goto failed; if (!link->irq) goto failed; i = pcmcia_enable_device(link); if (i != 0) goto failed; icard.para[0] = link->irq; icard.para[1] = link->resource[0]->start; icard.protocol = protocol; icard.typ = ISDN_CTYPE_ELSA_PCMCIA; i = hisax_init_pcmcia(link, &(((local_info_t *)link->priv)->busy), &icard); if (i < 0) { printk(KERN_ERR "elsa_cs: failed to initialize Elsa " "PCMCIA %d with %pR\n", i, link->resource[0]); elsa_cs_release(link); } else ((local_info_t *)link->priv)->cardnr = i; return 0; failed: elsa_cs_release(link); return -ENODEV; } /* elsa_cs_config */
static void elsa_cs_detach(struct pcmcia_device *p_dev) { dev_link_t *link = dev_to_instance(p_dev); local_info_t *info = link->priv; DEBUG(0, "elsa_cs_detach(0x%p)\n", link); if (link->state & DEV_CONFIG) { info->busy = 1; elsa_cs_release(link); } kfree(info); } /* elsa_cs_detach */
static void elsa_cs_detach(dev_link_t *link) { dev_link_t **linkp; 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; del_timer(&link->release); if (link->state & DEV_CONFIG) elsa_cs_release((u_long)link); /* 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) { DEBUG(0, "elsa_cs: detach postponed, '%s' " "still locked\n", link->dev->dev_name); link->state |= DEV_STALE_LINK; return; } /* Break the link with Card Services */ if (link->handle) { ret = CardServices(DeregisterClient, link->handle); if (ret != CS_SUCCESS) cs_error(link->handle, DeregisterClient, ret); } /* Unlink device structure and free it */ *linkp = link->next; kfree(info); } /* elsa_cs_detach */
static int elsa_cs_event(event_t event, int priority, event_callback_args_t *args) { dev_link_t *link = args->client_data; local_info_t *dev = link->priv; DEBUG(1, "elsa_cs_event(%d)\n", event); 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); dev->busy = 0; break; } return 0; } /* elsa_cs_event */
static void elsa_cs_config(dev_link_t *link) { client_handle_t handle; tuple_t tuple; cisparse_t parse; local_info_t *dev; int i, j, last_fn; u_short buf[128]; cistpl_cftable_entry_t *cf = &parse.cftable_entry; DEBUG(0, "elsa_config(0x%p)\n", link); handle = link->handle; dev = link->priv; /* This reads the card's CONFIG tuple to find its configuration registers. */ tuple.DesiredTuple = CISTPL_CONFIG; tuple.TupleData = (cisdata_t *)buf; tuple.TupleDataMax = 255; tuple.TupleOffset = 0; tuple.Attributes = 0; i = first_tuple(handle, &tuple, &parse); if (i != CS_SUCCESS) { last_fn = ParseTuple; goto cs_failed; } link->conf.ConfigBase = parse.config.base; link->conf.Present = parse.config.rmask[0]; /* Configure card */ link->state |= DEV_CONFIG; tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; i = first_tuple(handle, &tuple, &parse); while (i == CS_SUCCESS) { if ( (cf->io.nwin > 0) && cf->io.win[0].base) { printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; i = CardServices(RequestIO, link->handle, &link->io); if (i == CS_SUCCESS) break; } else { printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n"); link->conf.ConfigIndex = cf->index; for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) { link->io.BasePort1 = j; i = CardServices(RequestIO, link->handle, &link->io); if (i == CS_SUCCESS) break; } break; } i = next_tuple(handle, &tuple, &parse); } if (i != CS_SUCCESS) { last_fn = RequestIO; goto cs_failed; } i = CardServices(RequestIRQ, link->handle, &link->irq); if (i != CS_SUCCESS) { link->irq.AssignedIRQ = 0; last_fn = RequestIRQ; goto cs_failed; } i = CardServices(RequestConfiguration, link->handle, &link->conf); if (i != CS_SUCCESS) { last_fn = RequestConfiguration; goto cs_failed; } /* At this point, the dev_node_t structure(s) should be initialized and arranged in a linked list at link->dev. *//* */ sprintf(dev->node.dev_name, "elsa"); dev->node.major = dev->node.minor = 0x0; link->dev = &dev->node; /* Finally, report what we've done */ printk(KERN_INFO "%s: index 0x%02x: Vcc %d.%d", dev->node.dev_name, link->conf.ConfigIndex, link->conf.Vcc/10, link->conf.Vcc%10); if (link->conf.Vpp1) printk(", Vpp %d.%d", link->conf.Vpp1/10, link->conf.Vpp1%10); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); if (link->io.NumPorts2) printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1); printk("\n"); link->state &= ~DEV_CONFIG_PENDING; elsa_init_pcmcia(link->io.BasePort1, link->irq.AssignedIRQ, &(((local_info_t*)link->priv)->busy), protocol); return; cs_failed: cs_error(link->handle, last_fn, i); elsa_cs_release((u_long)link); } /* elsa_cs_config */
static int elsa_cs_config(struct pcmcia_device *link) { local_info_t *dev; int i, last_fn; IsdnCard_t icard; DEBUG(0, "elsa_config(0x%p)\n", link); dev = link->priv; i = pcmcia_loop_config(link, elsa_cs_configcheck, NULL); if (i != 0) { last_fn = RequestIO; goto cs_failed; } i = pcmcia_request_irq(link, &link->irq); if (i != 0) { link->irq.AssignedIRQ = 0; last_fn = RequestIRQ; goto cs_failed; } i = pcmcia_request_configuration(link, &link->conf); if (i != 0) { last_fn = RequestConfiguration; goto cs_failed; } /* At this point, the dev_node_t structure(s) should be initialized and arranged in a linked list at link->dev. *//* */ sprintf(dev->node.dev_name, "elsa"); dev->node.major = dev->node.minor = 0x0; link->dev_node = &dev->node; /* Finally, report what we've done */ printk(KERN_INFO "%s: index 0x%02x: ", dev->node.dev_name, link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); if (link->io.NumPorts2) printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1); printk("\n"); icard.para[0] = link->irq.AssignedIRQ; icard.para[1] = link->io.BasePort1; icard.protocol = protocol; icard.typ = ISDN_CTYPE_ELSA_PCMCIA; i = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->busy), &icard); if (i < 0) { printk(KERN_ERR "elsa_cs: failed to initialize Elsa PCMCIA %d at i/o %#x\n", i, link->io.BasePort1); elsa_cs_release(link); } else ((local_info_t*)link->priv)->cardnr = i; return 0; cs_failed: cs_error(link, last_fn, i); elsa_cs_release(link); return -ENODEV; } /* elsa_cs_config */
static int elsa_cs_config(struct pcmcia_device *link) { tuple_t tuple; cisparse_t parse; local_info_t *dev; int i, j, last_fn; u_short buf[128]; cistpl_cftable_entry_t *cf = &parse.cftable_entry; IsdnCard_t icard; DEBUG(0, "elsa_config(0x%p)\n", link); dev = link->priv; tuple.TupleData = (cisdata_t *)buf; tuple.TupleOffset = 0; tuple.TupleDataMax = 255; tuple.Attributes = 0; tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY; i = first_tuple(link, &tuple, &parse); while (i == CS_SUCCESS) { if ( (cf->io.nwin > 0) && cf->io.win[0].base) { printk(KERN_INFO "(elsa_cs: looks like the 96 model)\n"); link->conf.ConfigIndex = cf->index; link->io.BasePort1 = cf->io.win[0].base; i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } else { printk(KERN_INFO "(elsa_cs: looks like the 97 model)\n"); link->conf.ConfigIndex = cf->index; for (i = 0, j = 0x2f0; j > 0x100; j -= 0x10) { link->io.BasePort1 = j; i = pcmcia_request_io(link, &link->io); if (i == CS_SUCCESS) break; } break; } i = next_tuple(link, &tuple, &parse); } if (i != CS_SUCCESS) { last_fn = RequestIO; goto cs_failed; } i = pcmcia_request_irq(link, &link->irq); if (i != CS_SUCCESS) { link->irq.AssignedIRQ = 0; last_fn = RequestIRQ; goto cs_failed; } i = pcmcia_request_configuration(link, &link->conf); if (i != CS_SUCCESS) { last_fn = RequestConfiguration; goto cs_failed; } /* At this point, the dev_node_t structure(s) should be initialized and arranged in a linked list at link->dev. *//* */ sprintf(dev->node.dev_name, "elsa"); dev->node.major = dev->node.minor = 0x0; link->dev_node = &dev->node; /* Finally, report what we've done */ printk(KERN_INFO "%s: index 0x%02x: ", dev->node.dev_name, link->conf.ConfigIndex); if (link->conf.Attributes & CONF_ENABLE_IRQ) printk(", irq %d", link->irq.AssignedIRQ); if (link->io.NumPorts1) printk(", io 0x%04x-0x%04x", link->io.BasePort1, link->io.BasePort1+link->io.NumPorts1-1); if (link->io.NumPorts2) printk(" & 0x%04x-0x%04x", link->io.BasePort2, link->io.BasePort2+link->io.NumPorts2-1); printk("\n"); icard.para[0] = link->irq.AssignedIRQ; icard.para[1] = link->io.BasePort1; icard.protocol = protocol; icard.typ = ISDN_CTYPE_ELSA_PCMCIA; i = hisax_init_pcmcia(link, &(((local_info_t*)link->priv)->busy), &icard); if (i < 0) { printk(KERN_ERR "elsa_cs: failed to initialize Elsa PCMCIA %d at i/o %#x\n", i, link->io.BasePort1); elsa_cs_release(link); } else ((local_info_t*)link->priv)->cardnr = i; return 0; cs_failed: cs_error(link, last_fn, i); elsa_cs_release(link); return -ENODEV; } /* elsa_cs_config */