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

📄 elsa_cs.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
    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 *//*======================================================================    elsa_cs_config() is scheduled to run after a CARD_INSERTION event    is received, to configure the PCMCIA socket, and to make the    device available to the system.======================================================================*/static int get_tuple(int fn, client_handle_t handle, tuple_t *tuple,                     cisparse_t *parse){    int i;    i = CardServices(fn, handle, tuple);    if (i != CS_SUCCESS) return i;    i = CardServices(GetTupleData, handle, tuple);    if (i != CS_SUCCESS) return i;    return CardServices(ParseTuple, handle, tuple, parse);}#define first_tuple(a, b, c) get_tuple(GetFirstTuple, a, b, c)#define next_tuple(a, b, c) get_tuple(GetNextTuple, a, b, c)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 *//*======================================================================    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(u_long arg){    dev_link_t *link = (dev_link_t *)arg;    DEBUG(0, "elsa_cs_release(0x%p)\n", link);    /*       If the device is currently in use, we won't release until it       is actually closed, because until then, we can't be sure that       no one will try to access the device or its data structures.    */    if (link->open) {        DEBUG(1, "elsa_cs: release postponed, '%s' "                   "still open\n", link->dev->dev_name);        link->state |= DEV_STALE_CONFIG;        return;    }    /* Unlink the device chain */    link->dev = NULL;    /* Don't bother checking to see if these succeed or not */    if (link->win)        CardServices(ReleaseWindow, link->win);    CardServices(ReleaseConfiguration, link->handle);    CardServices(ReleaseIO, link->handle, &link->io);    CardServices(ReleaseIRQ, link->handle, &link->irq);    link->state &= ~DEV_CONFIG;    if (link->state & DEV_STALE_LINK)        elsa_cs_detach(link);} /* 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;            mod_timer(&link->release, jiffies + HZ/20);        }        break;    case CS_EVENT_CARD_INSERTION:        link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;        dev->bus = args->bus;        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)            CardServices(ReleaseConfiguration, link->handle);        break;    case CS_EVENT_PM_RESUME:        link->state &= ~DEV_SUSPEND;        /* Fall through... */    case CS_EVENT_CARD_RESET:        if (link->state & DEV_CONFIG)            CardServices(RequestConfiguration, link->handle, &link->conf);        dev->busy = 0;        break;    }    return 0;} /* elsa_cs_event *//*====================================================================*/static int __init init_elsa_cs(void){    servinfo_t serv;    DEBUG(0, "%s\n", version);    CardServices(GetCardServicesInfo, &serv);    if (serv.Revision != CS_RELEASE_CODE) {        printk(KERN_NOTICE "elsa_cs: Card Services release "               "does not match!\n");        return -1;    }    register_pccard_driver(&dev_info, &elsa_cs_attach, &elsa_cs_detach);    return 0;}static void __exit exit_elsa_cs(void){    DEBUG(0, "elsa_cs: unloading\n");    unregister_pccard_driver(&dev_info);    while (dev_list != NULL)        elsa_cs_detach(dev_list);}module_init(init_elsa_cs);module_exit(exit_elsa_cs);

⌨️ 快捷键说明

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