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

📄 avma1_cs.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 2 页
字号:
}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 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];    IsdnCard_t	icard;    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 = pcmcia_get_first_tuple(handle, &tuple);	if (i != CS_SUCCESS) break;	tuple.TupleData = buf;	tuple.TupleDataMax = 64;	tuple.TupleOffset = 0;	i = pcmcia_get_tuple_data(handle, &tuple);	if (i != CS_SUCCESS) break;	i = pcmcia_parse_tuple(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 ) {	    strlcpy(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 = pcmcia_request_io(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 = pcmcia_request_irq(link->handle, &link->irq);	if (i != CS_SUCCESS) {	    cs_error(link->handle, RequestIRQ, i);	    pcmcia_release_io(link->handle, &link->io);	    break;	}		/*	 * configure the PCMCIA socket	 */	i = pcmcia_request_configuration(link->handle, &link->conf);	if (i != CS_SUCCESS) {	    cs_error(link->handle, RequestConfiguration, i);	    pcmcia_release_io(link->handle, &link->io);	    pcmcia_release_irq(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(link);	return;    }    printk(KERN_NOTICE "avma1_cs: checking at i/o %#x, irq %d\n",				link->io.BasePort1, link->irq.AssignedIRQ);    icard.para[0] = link->irq.AssignedIRQ;    icard.para[1] = link->io.BasePort1;    icard.protocol = isdnprot;    icard.typ = ISDN_CTYPE_A1_PCMCIA;        i = hisax_init_pcmcia(link, &busy, &icard);    if (i < 0) {    	printk(KERN_ERR "avma1_cs: failed to initialize AVM A1 PCMCIA %d at i/o %#x\n", i, link->io.BasePort1);	avma1cs_release(link);	return;    }    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(dev_link_t *link){    local_info_t *local = link->priv;    DEBUG(0, "avma1cs_release(0x%p)\n", link);    /* 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 */    pcmcia_release_configuration(link->handle);    pcmcia_release_io(link->handle, &link->io);    pcmcia_release_irq(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:	    if (link->state & DEV_CONFIG)		avma1cs_release(link);	    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)		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);	    break;    }    return 0;} /* avma1cs_event */static struct pcmcia_device_id avma1cs_ids[] = {	PCMCIA_DEVICE_PROD_ID12("AVM", "ISDN A", 0x95d42008, 0xadc9d4bb),	PCMCIA_DEVICE_PROD_ID12("ISDN", "CARD", 0x8d9761c8, 0x01c5aa7b),	PCMCIA_DEVICE_NULL};MODULE_DEVICE_TABLE(pcmcia, avma1cs_ids);static struct pcmcia_driver avma1cs_driver = {	.owner		= THIS_MODULE,	.drv		= {		.name	= "avma1_cs",	},	.attach		= avma1cs_attach,	.event		= avma1cs_event,	.detach		= avma1cs_detach,	.id_table	= avma1cs_ids,}; /*====================================================================*/static int __init init_avma1_cs(void){	return(pcmcia_register_driver(&avma1cs_driver));}static void __exit exit_avma1_cs(void){	pcmcia_unregister_driver(&avma1cs_driver);	BUG_ON(dev_list != NULL);}module_init(init_avma1_cs);module_exit(exit_avma1_cs);

⌨️ 快捷键说明

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