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

📄 avm_cs.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 2 页
字号:
    cistpl_cftable_entry_t *cf = &parse.cftable_entry;    local_info_t *dev;    int i;    u_char buf[64];    char devname[128];    int cardtype;    int (*addcard)(unsigned int port, unsigned irq);        handle = link->handle;    dev = link->priv;    /*       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 "avm_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. */    if (devname[0]) {	char *s = strrchr(devname, ' ');	if (!s)	   s = devname;	else s++;	strcpy(dev->node.dev_name, s);        if (strcmp("M1", s) == 0) {           cardtype = AVM_CARDTYPE_M1;        } else if (strcmp("M2", s) == 0) {           cardtype = AVM_CARDTYPE_M2;	} else {           cardtype = AVM_CARDTYPE_B1;	}    } else {        strcpy(dev->node.dev_name, "b1");        cardtype = AVM_CARDTYPE_B1;    }    dev->node.major = 64;    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) {	avmcs_release((u_long)link);	return;    }    switch (cardtype) {        case AVM_CARDTYPE_M1: addcard = b1pcmcia_addcard_m1; break;        case AVM_CARDTYPE_M2: addcard = b1pcmcia_addcard_m2; break;	default:        case AVM_CARDTYPE_B1: addcard = b1pcmcia_addcard_b1; break;    }    if ((i = (*addcard)(link->io.BasePort1, link->irq.AssignedIRQ)) < 0) {        printk(KERN_ERR "avm_cs: failed to add AVM-%s-Controller at i/o %#x, irq %d\n",		dev->node.dev_name, link->io.BasePort1, link->irq.AssignedIRQ);	avmcs_release((u_long)link);	return;    }    dev->node.minor = i;} /* avmcs_config *//*======================================================================    After a card is removed, avmcs_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 avmcs_release(u_long arg){    dev_link_t *link = (dev_link_t *)arg;    /*       If the device is currently in use, we won't release until it       is actually closed.    */    if (link->open) {	link->state |= DEV_STALE_CONFIG;	return;    }    b1pcmcia_delcard(link->io.BasePort1, link->irq.AssignedIRQ);    /* 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)	avmcs_detach(link);    } /* avmcs_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 avmcs_event(event_t event, int priority,			  event_callback_args_t *args){    dev_link_t *link = args->client_data;    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;	avmcs_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;} /* avmcs_event *//*====================================================================*/static int __init avmcs_init(void){    servinfo_t serv;    CardServices(GetCardServicesInfo, &serv);    if (serv.Revision != CS_RELEASE_CODE) {	printk(KERN_NOTICE "avm_cs: Card Services release "	       "does not match!\n");	return -1;    }    register_pccard_driver(&dev_info, &avmcs_attach, &avmcs_detach);    return 0;}static void __exit avmcs_exit(void){    unregister_pccard_driver(&dev_info);    while (dev_list != NULL) {	if (dev_list->state & DEV_CONFIG)	    avmcs_release((u_long)dev_list);	avmcs_detach(dev_list);    }}module_init(avmcs_init);module_exit(avmcs_exit);

⌨️ 快捷键说明

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