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

📄 serial_cs.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 2 页
字号:
		i = CardServices(RequestIO, link->handle, &link->io);		if (i == CS_SUCCESS) goto found_port;	    }	next_entry:	    i = next_tuple(handle, &tuple, &parse);	}    }        /* Second pass: try to find an entry that isn't picky about       its base address, then try to grab any standard serial port       address, and finally try to get any free port. */    i = first_tuple(handle, &tuple, &parse);    while (i != CS_NO_MORE_ITEMS) {	if ((i == CS_SUCCESS) && (cf->io.nwin > 0) &&	    ((cf->io.flags & CISTPL_IO_LINES_MASK) <= 3)) {	    link->conf.ConfigIndex = cf->index;	    for (j = 0; j < 5; j++) {		link->io.BasePort1 = base[j];		link->io.IOAddrLines = base[j] ? 16 : 3;		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);	return -1;    }        i = CardServices(RequestIRQ, link->handle, &link->irq);    if (i != CS_SUCCESS) {	cs_error(link->handle, RequestIRQ, i);	link->irq.AssignedIRQ = 0;    }    if (info->multi && (info->manfid == MANFID_3COM))	link->conf.ConfigIndex &= ~(0x08);    i = CardServices(RequestConfiguration, link->handle, &link->conf);    if (i != CS_SUCCESS) {	cs_error(link->handle, RequestConfiguration, i);	return -1;    }    return setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);}static int multi_config(dev_link_t *link){    client_handle_t handle = link->handle;    serial_info_t *info = link->priv;    tuple_t tuple;    u_char buf[256];    cisparse_t parse;    cistpl_cftable_entry_t *cf = &parse.cftable_entry;    int i, base2 = 0;    tuple.TupleData = (cisdata_t *)buf;    tuple.TupleOffset = 0; tuple.TupleDataMax = 255;    tuple.Attributes = 0;    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;    /* First, look for a generic full-sized window */    link->io.NumPorts1 = info->multi * 8;    i = first_tuple(handle, &tuple, &parse);    while (i != CS_NO_MORE_ITEMS) {	/* The quad port cards have bad CIS's, so just look for a	   window larger than 8 ports and assume it will be right */	if ((i == CS_SUCCESS) && (cf->io.nwin == 1) &&	    (cf->io.win[0].len > 8)) {	    link->conf.ConfigIndex = cf->index;	    link->io.BasePort1 = cf->io.win[0].base;	    link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;	    i = CardServices(RequestIO, link->handle, &link->io);	    base2 = link->io.BasePort1 + 8;	    if (i == CS_SUCCESS) break;	}	i = next_tuple(handle, &tuple, &parse);    }    /* If that didn't work, look for two windows */    if (i != CS_SUCCESS) {	link->io.NumPorts1 = link->io.NumPorts2 = 8;	info->multi = 2;	i = first_tuple(handle, &tuple, &parse);	while (i != CS_NO_MORE_ITEMS) {	    if ((i == CS_SUCCESS) && (cf->io.nwin == 2)) {		link->conf.ConfigIndex = cf->index;		link->io.BasePort1 = cf->io.win[0].base;		link->io.BasePort2 = cf->io.win[1].base;		link->io.IOAddrLines = cf->io.flags & CISTPL_IO_LINES_MASK;		i = CardServices(RequestIO, link->handle, &link->io);		base2 = link->io.BasePort2;		if (i == CS_SUCCESS) break;	    }	    i = next_tuple(handle, &tuple, &parse);	}    }        if (i != CS_SUCCESS) {	cs_error(link->handle, RequestIO, i);	return -1;    }        i = CardServices(RequestIRQ, link->handle, &link->irq);    if (i != CS_SUCCESS) {	cs_error(link->handle, RequestIRQ, i);	link->irq.AssignedIRQ = 0;    }    /* Socket Dual IO: this enables irq's for second port */    if (info->multi && (info->manfid == MANFID_SOCKET)) {	link->conf.Present |= PRESENT_EXT_STATUS;	link->conf.ExtStatus = ESR_REQ_ATTN_ENA;    }    i = CardServices(RequestConfiguration, link->handle, &link->conf);    if (i != CS_SUCCESS) {	cs_error(link->handle, RequestConfiguration, i);	return -1;    }        setup_serial(info, link->io.BasePort1, link->irq.AssignedIRQ);    /* The Nokia cards are not really multiport cards */    if (info->manfid == MANFID_NOKIA)	return 0;    for (i = 0; i < info->multi-1; i++)	setup_serial(info, base2+(8*i), link->irq.AssignedIRQ);        return 0;}/*======================================================================    serial_config() is scheduled to run after a CARD_INSERTION event    is received, to configure the PCMCIA socket, and to make the    serial device available to the system.======================================================================*/#define CS_CHECK(fn, args...) \while ((last_ret=CardServices(last_fn=(fn), args))!=0) goto cs_failedvoid serial_config(dev_link_t *link){    client_handle_t handle = link->handle;    serial_info_t *info = link->priv;    tuple_t tuple;    u_short buf[128];    cisparse_t parse;    cistpl_cftable_entry_t *cf = &parse.cftable_entry;    int i, last_ret, last_fn;    DEBUG(0, "serial_config(0x%p)\n", link);        tuple.TupleData = (cisdata_t *)buf;    tuple.TupleOffset = 0; tuple.TupleDataMax = 255;    tuple.Attributes = 0;    /* Get configuration register information */    tuple.DesiredTuple = CISTPL_CONFIG;    last_ret = first_tuple(handle, &tuple, &parse);    if (last_ret != 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;    /* Is this a compliant multifunction card? */    tuple.DesiredTuple = CISTPL_LONGLINK_MFC;    tuple.Attributes = TUPLE_RETURN_COMMON | TUPLE_RETURN_LINK;    info->multi = (first_tuple(handle, &tuple, &parse) == CS_SUCCESS);        /* Is this a multiport card? */    tuple.DesiredTuple = CISTPL_MANFID;    if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {	info->manfid = le16_to_cpu(buf[0]);	for (i = 0; i < MULTI_COUNT; i++)	    if ((info->manfid == multi_id[i].manfid) &&		(le16_to_cpu(buf[1]) == multi_id[i].prodid))		break;	if (i < MULTI_COUNT)	    info->multi = multi_id[i].multi;    }    /* Another check for dual-serial cards: look for either serial or       multifunction cards that ask for appropriate IO port ranges */    tuple.DesiredTuple = CISTPL_FUNCID;    if ((info->multi == 0) &&	((first_tuple(handle, &tuple, &parse) != CS_SUCCESS) ||	 (parse.funcid.func == CISTPL_FUNCID_MULTI) ||	 (parse.funcid.func == CISTPL_FUNCID_SERIAL))) {	tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;	if (first_tuple(handle, &tuple, &parse) == CS_SUCCESS) {	    if ((cf->io.nwin == 1) && (cf->io.win[0].len % 8 == 0))		info->multi = cf->io.win[0].len >> 3;	    if ((cf->io.nwin == 2) && (cf->io.win[0].len == 8) &&		(cf->io.win[1].len == 8))		info->multi = 2;	}    }        if (info->multi > 1)	multi_config(link);    else	simple_config(link);        if (info->ndev == 0)	goto failed;        if (info->manfid == MANFID_IBM) {	conf_reg_t reg = { 0, CS_READ, 0x800, 0 };	CS_CHECK(AccessConfigurationRegister, link->handle, &reg);	reg.Action = CS_WRITE;	reg.Value = reg.Value | 1;	CS_CHECK(AccessConfigurationRegister, link->handle, &reg);    }    link->dev = &info->node[0];    link->state &= ~DEV_CONFIG_PENDING;    return;cs_failed:    cs_error(link->handle, last_fn, last_ret);failed:    serial_release((u_long)link);} /* serial_config *//*======================================================================    After a card is removed, serial_release() will unregister the net    device, and release the PCMCIA configuration.    ======================================================================*/void serial_release(u_long arg){    dev_link_t *link = (dev_link_t *)arg;    serial_info_t *info = link->priv;    int i;        DEBUG(0, "serial_release(0x%p)\n", link);    for (i = 0; i < info->ndev; i++) {	unregister_serial(info->line[i]);    }    link->dev = NULL;    if (!info->slave) {	CardServices(ReleaseConfiguration, link->handle);	CardServices(ReleaseIO, link->handle, &link->io);	CardServices(ReleaseIRQ, link->handle, &link->irq);    }        link->state &= ~DEV_CONFIG;} /* serial_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 serial drivers from    talking to the ports.    ======================================================================*/static int serial_event(event_t event, int priority,			event_callback_args_t *args){    dev_link_t *link = args->client_data;    serial_info_t *info = link->priv;        DEBUG(1, "serial_event(0x%06x)\n", event);        switch (event) {    case CS_EVENT_CARD_REMOVAL:	link->state &= ~DEV_PRESENT;	if (link->state & DEV_CONFIG)	    mod_timer(&link->release, jiffies + HZ/20);	break;    case CS_EVENT_CARD_INSERTION:	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;	serial_config(link);	break;    case CS_EVENT_PM_SUSPEND:	link->state |= DEV_SUSPEND;	/* Fall through... */    case CS_EVENT_RESET_PHYSICAL:	if ((link->state & DEV_CONFIG) && !info->slave)	    CardServices(ReleaseConfiguration, link->handle);	break;    case CS_EVENT_PM_RESUME:	link->state &= ~DEV_SUSPEND;	/* Fall through... */    case CS_EVENT_CARD_RESET:	if (DEV_OK(link) && !info->slave)	    CardServices(RequestConfiguration, link->handle, &link->conf);	break;    }    return 0;} /* serial_event *//*====================================================================*/static int __init init_serial_cs(void){    servinfo_t serv;    DEBUG(0, "%s\n", version);    CardServices(GetCardServicesInfo, &serv);    if (serv.Revision != CS_RELEASE_CODE) {	printk(KERN_NOTICE "serial_cs: Card Services release "	       "does not match!\n");	return -1;    }    register_pccard_driver(&dev_info, &serial_attach, &serial_detach);    return 0;}static void __exit exit_serial_cs(void){    DEBUG(0, "serial_cs: unloading\n");    unregister_pccard_driver(&dev_info);    while (dev_list != NULL)	serial_detach(dev_list);}module_init(init_serial_cs);module_exit(exit_serial_cs);

⌨️ 快捷键说明

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