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

📄 avma1_cs.c

📁 这个linux源代码是很全面的~基本完整了~使用c编译的~由于时间问题我没有亲自测试~但就算用来做参考资料也是非常好的
💻 C
📖 第 1 页 / 共 2 页
字号:
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 avma1cs_config(dev_link_t *link){    client_handle_t handle;    tuple_t tuple;    cisparse_t parse;    cistpl_cftable_entry_t *cf = &parse.cftable_entry;    local_info_t *dev;    int i;    u_char buf[64];    char devname[128];    int busy = 0;        handle = link->handle;    dev = link->priv;    DEBUG(0, "avma1cs_config(0x%p)\n", link);    /*       This reads the card's CONFIG tuple to find its configuration       registers.    */    do {	tuple.DesiredTuple = CISTPL_CONFIG;	i = CardServices(GetFirstTuple, handle, &tuple);	if (i != CS_SUCCESS) break;	tuple.TupleData = buf;	tuple.TupleDataMax = 64;	tuple.TupleOffset = 0;	i = CardServices(GetTupleData, handle, &tuple);	if (i != CS_SUCCESS) break;	i = CardServices(ParseTuple, handle, &tuple, &parse);	if (i != CS_SUCCESS) break;	link->conf.ConfigBase = parse.config.base;    } while (0);    if (i != CS_SUCCESS) {	cs_error(link->handle, ParseTuple, i);	link->state &= ~DEV_CONFIG_PENDING;	return;    }        /* Configure card */    link->state |= DEV_CONFIG;    do {	tuple.Attributes = 0;	tuple.TupleData = buf;	tuple.TupleDataMax = 254;	tuple.TupleOffset = 0;	tuple.DesiredTuple = CISTPL_VERS_1;	devname[0] = 0;	if( !first_tuple(handle, &tuple, &parse) && parse.version_1.ns > 1 ) {	    strncpy(devname,parse.version_1.str + parse.version_1.ofs[1], 			sizeof(devname));	}	/*         * find IO port         */	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) {		link->conf.ConfigIndex = cf->index;		link->io.BasePort1 = cf->io.win[0].base;		link->io.NumPorts1 = cf->io.win[0].len;		link->io.NumPorts2 = 0;                printk(KERN_INFO "avma1_cs: testing i/o %#x-%#x\n",			link->io.BasePort1,		        link->io.BasePort1+link->io.NumPorts1 - 1);		i = CardServices(RequestIO, link->handle, &link->io);		if (i == CS_SUCCESS) goto found_port;	    }	    i = next_tuple(handle, &tuple, &parse);	}found_port:	if (i != CS_SUCCESS) {	    cs_error(link->handle, RequestIO, i);	    break;	}		/*	 * allocate an interrupt line	 */	i = CardServices(RequestIRQ, link->handle, &link->irq);	if (i != CS_SUCCESS) {	    cs_error(link->handle, RequestIRQ, i);	    CardServices(ReleaseIO, link->handle, &link->io);	    break;	}		/*         * configure the PCMCIA socket	  */	i = CardServices(RequestConfiguration, link->handle, &link->conf);	if (i != CS_SUCCESS) {	    cs_error(link->handle, RequestConfiguration, i);	    CardServices(ReleaseIO, link->handle, &link->io);	    CardServices(ReleaseIRQ, link->handle, &link->irq);	    break;	}    } while (0);    /* At this point, the dev_node_t structure(s) should be       initialized and arranged in a linked list at link->dev. */    strcpy(dev->node.dev_name, "A1");    dev->node.major = 45;    dev->node.minor = 0;    link->dev = &dev->node;        link->state &= ~DEV_CONFIG_PENDING;    /* If any step failed, release any partially configured state */    if (i != 0) {	avma1cs_release((u_long)link);	return;    }    printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n",				link->io.BasePort1, link->irq.AssignedIRQ);    if (avm_a1_init_pcmcia((void *)(int)link->io.BasePort1,                           link->irq.AssignedIRQ,                           &busy, isdnprot) != 0) {       printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1);       return;    }    i = 0; /* no returncode for cardnr :-( */    dev->node.minor = i;} /* avma1cs_config *//*======================================================================    After a card is removed, avma1cs_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 avma1cs_release(u_long arg){    dev_link_t *link = (dev_link_t *)arg;    local_info_t *local = link->priv;    DEBUG(0, "avma1cs_release(0x%p)\n", link);    /*       If the device is currently in use, we won't release until it       is actually closed.    */    if (link->open) {	DEBUG(1, "avma1_cs: release postponed, '%s' still open\n",	      link->dev->dev_name);	link->state |= DEV_STALE_CONFIG;	return;    }    /* no unregister function with hisax */    HiSax_closecard(local->node.minor);    /* Unlink the device chain */    link->dev = NULL;        /* Don't bother checking to see if these succeed or not */    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)	avma1cs_detach(link);    } /* avma1cs_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 avma1cs_event(event_t event, int priority,			  event_callback_args_t *args){    dev_link_t *link = args->client_data;    DEBUG(1, "avma1cs_event(0x%06x)\n", event);        switch (event) {    case CS_EVENT_CARD_REMOVAL:	link->state &= ~DEV_PRESENT;	if (link->state & DEV_CONFIG) {	    link->release.expires =  jiffies + HZ/20;	    add_timer(&link->release);	}	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)	    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);	break;    }    return 0;} /* avma1cs_event *//*====================================================================*/static int __init init_avma1_cs(void){    servinfo_t serv;    DEBUG(0, "%s\n", version);    CardServices(GetCardServicesInfo, &serv);    if (serv.Revision != CS_RELEASE_CODE) {        printk(KERN_NOTICE "avma1_cs: Card Services release "               "does not match!\n");        return -1;    }    register_pccard_driver(&dev_info, &avma1cs_attach, &avma1cs_detach);    return 0;}static void __exit exit_avma1_cs(void){    DEBUG(0, "avma1_cs: unloading\n");    unregister_pccard_driver(&dev_info);    while (dev_list != NULL)	if (dev_list->state & DEV_CONFIG)	    avma1cs_release((u_long)dev_list);        avma1cs_detach(dev_list);}module_init(init_avma1_cs);module_exit(exit_avma1_cs);

⌨️ 快捷键说明

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