⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 elsa_cs.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
    device available to the system.======================================================================*/static int get_tuple(client_handle_t handle, tuple_t *tuple,                     cisparse_t *parse){    int i = pcmcia_get_tuple_data(handle, tuple);    if (i != CS_SUCCESS) return i;    return pcmcia_parse_tuple(handle, tuple, parse);}static int first_tuple(client_handle_t handle, tuple_t *tuple,                     cisparse_t *parse){    int i = pcmcia_get_first_tuple(handle, tuple);    if (i != CS_SUCCESS) return i;    return get_tuple(handle, tuple, parse);}static int next_tuple(client_handle_t handle, tuple_t *tuple,                     cisparse_t *parse){    int i = pcmcia_get_next_tuple(handle, tuple);    if (i != CS_SUCCESS) return i;    return get_tuple(handle, tuple, parse);}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;    IsdnCard_t icard;    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 = pcmcia_request_io(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 = pcmcia_request_io(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 = pcmcia_request_irq(link->handle, &link->irq);    if (i != CS_SUCCESS) {        link->irq.AssignedIRQ = 0;	last_fn = RequestIRQ;        goto cs_failed;    }    i = pcmcia_request_configuration(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;    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;cs_failed:    cs_error(link->handle, last_fn, i);    elsa_cs_release(link);} /* elsa_cs_config *//*======================================================================    After a card is removed, elsa_cs_release() will unregister the net    device, and release the PCMCIA configuration.  If the device is    still open, this will be postponed until it is closed.======================================================================*/static void elsa_cs_release(dev_link_t *link){    local_info_t *local = link->priv;    DEBUG(0, "elsa_cs_release(0x%p)\n", link);    if (local) {    	if (local->cardnr >= 0) {    	    /* no unregister function with hisax */	    HiSax_closecard(local->cardnr);	}    }    /* Unlink the device chain */    link->dev = NULL;    /* Don't bother checking to see if these succeed or not */    if (link->win)        pcmcia_release_window(link->win);    pcmcia_release_configuration(link->handle);    pcmcia_release_io(link->handle, &link->io);    pcmcia_release_irq(link->handle, &link->irq);    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.    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.======================================================================*/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 struct pcmcia_device_id elsa_ids[] = {	PCMCIA_DEVICE_PROD_ID12("ELSA AG (Aachen, Germany)", "MicroLink ISDN/MC ", 0x983de2c4, 0x333ba257),	PCMCIA_DEVICE_PROD_ID12("ELSA GmbH, Aachen", "MicroLink ISDN/MC ", 0x639e5718, 0x333ba257),	PCMCIA_DEVICE_NULL};MODULE_DEVICE_TABLE(pcmcia, elsa_ids);static struct pcmcia_driver elsa_cs_driver = {	.owner		= THIS_MODULE,	.drv		= {		.name	= "elsa_cs",	},	.attach		= elsa_cs_attach,	.event		= elsa_cs_event,	.detach		= elsa_cs_detach,	.id_table	= elsa_ids,};static int __init init_elsa_cs(void){	return pcmcia_register_driver(&elsa_cs_driver);}static void __exit exit_elsa_cs(void){	pcmcia_unregister_driver(&elsa_cs_driver);	BUG_ON(dev_list != NULL);}module_init(init_elsa_cs);module_exit(exit_elsa_cs);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -