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

📄 xirc2ps_cs.c

📁 内核linux2.4.20,可跟rtlinux3.2打补丁 组成实时linux系统,编译内核
💻 C
📖 第 1 页 / 共 5 页
字号:
    client_handle_t handle = link->handle;    local_info_t *local = link->priv;    struct net_device *dev = &local->dev;    tuple_t tuple;    cisparse_t parse;    ioaddr_t ioaddr;    int err, i;    u_char buf[64];    cistpl_lan_node_id_t *node_id = (cistpl_lan_node_id_t*)parse.funce.data;    cistpl_cftable_entry_t *cf = &parse.cftable_entry;    local->dingo_ccr = 0;    DEBUG(0, "config(0x%p)\n", link);    /*     * This reads the card's CONFIG tuple to find its configuration     * registers.     */    tuple.Attributes = 0;    tuple.TupleData = buf;    tuple.TupleDataMax = 64;    tuple.TupleOffset = 0;    /* Is this a valid	card */    tuple.DesiredTuple = CISTPL_MANFID;    if ((err=first_tuple(handle, &tuple, &parse))) {	printk(KNOT_XIRC "manfid not found in CIS\n");	goto failure;    }    switch(parse.manfid.manf) {      case MANFID_XIRCOM:	local->manf_str = "Xircom";	break;      case MANFID_ACCTON:	local->manf_str = "Accton";	break;      case MANFID_COMPAQ:      case MANFID_COMPAQ2:	local->manf_str = "Compaq";	break;      case MANFID_INTEL:	local->manf_str = "Intel";	break;      case MANFID_TOSHIBA:	local->manf_str = "Toshiba";	break;      default:	printk(KNOT_XIRC "Unknown Card Manufacturer ID: 0x%04x\n",	       (unsigned)parse.manfid.manf);	goto failure;    }    DEBUG(0, "found %s card\n", local->manf_str);    if (!set_card_type(link, buf)) {	printk(KNOT_XIRC "this card is not supported\n");	goto failure;    }    /* get configuration stuff */    tuple.DesiredTuple = CISTPL_CONFIG;    if ((err=first_tuple(handle, &tuple, &parse)))	goto cis_error;    link->conf.ConfigBase = parse.config.base;    link->conf.Present =    parse.config.rmask[0];    /* get the ethernet address from the CIS */    tuple.DesiredTuple = CISTPL_FUNCE;    for (err = first_tuple(handle, &tuple, &parse); !err;			     err = next_tuple(handle, &tuple, &parse)) {	/* Once I saw two CISTPL_FUNCE_LAN_NODE_ID entries:	 * the first one with a length of zero the second correct -	 * so I skip all entries with length 0 */	if (parse.funce.type == CISTPL_FUNCE_LAN_NODE_ID	    && ((cistpl_lan_node_id_t *)parse.funce.data)->nb)	    break;    }    if (err) { /* not found: try to get the node-id from tuple 0x89 */	tuple.DesiredTuple = 0x89;  /* data layout looks like tuple 0x22 */	if (!(err = get_tuple_data(GetFirstTuple, handle, &tuple))) {	    if (tuple.TupleDataLen == 8 && *buf == CISTPL_FUNCE_LAN_NODE_ID)		memcpy(&parse, buf, 8);	    else		err = -1;	}    }    if (err) { /* another try	(James Lehmer's CE2 version 4.1)*/	tuple.DesiredTuple = CISTPL_FUNCE;	for (err = first_tuple(handle, &tuple, &parse); !err;				 err = next_tuple(handle, &tuple, &parse)) {	    if (parse.funce.type == 0x02 && parse.funce.data[0] == 1		&& parse.funce.data[1] == 6 && tuple.TupleDataLen == 13) {		buf[1] = 4;		memcpy(&parse, buf+1, 8);		break;	    }	}    }    if (err) {	printk(KNOT_XIRC "node-id not found in CIS\n");	goto failure;    }    node_id = (cistpl_lan_node_id_t *)parse.funce.data;    if (node_id->nb != 6) {	printk(KNOT_XIRC "malformed node-id in CIS\n");	goto failure;    }    for (i=0; i < 6; i++)	dev->dev_addr[i] = node_id->id[i];    /* Configure card */    link->state |= DEV_CONFIG;    link->io.IOAddrLines =10;    link->io.Attributes1 = IO_DATA_PATH_WIDTH_16;    link->irq.Attributes = IRQ_HANDLE_PRESENT;    link->irq.IRQInfo1 = IRQ_INFO2_VALID | IRQ_LEVEL_ID;    if (irq_list[0] == -1)	link->irq.IRQInfo2 = irq_mask;    else {	for (i = 0; i < 4; i++)	    link->irq.IRQInfo2 |= 1 << irq_list[i];    }    if (local->modem) {	int pass;	if (do_sound) {	    link->conf.Attributes |= CONF_ENABLE_SPKR;	    link->conf.Status |= CCSR_AUDIO_ENA;	}	link->irq.Attributes |= IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED ;	link->io.NumPorts2 = 8;	link->io.Attributes2 = IO_DATA_PATH_WIDTH_8;	if (local->dingo) {	    /* Take the Modem IO port from the CIS and scan for a free	     * Ethernet port */	    link->io.NumPorts1 = 16; /* no Mako stuff anymore */	    tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;	    for (err = first_tuple(handle, &tuple, &parse); !err;				 err = next_tuple(handle, &tuple, &parse)) {		if (cf->io.nwin > 0  &&  (cf->io.win[0].base & 0xf) == 8) {		    for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {			link->conf.ConfigIndex = cf->index ;			link->io.BasePort2 = cf->io.win[0].base;			link->io.BasePort1 = ioaddr;			if (!(err=CardServices(RequestIO, link->handle,								&link->io)))			    goto port_found;		    }		}	    }	} else {	    link->io.NumPorts1 = 18;	    /* We do 2 passes here: The first one uses the regular mapping and	     * the second tries again, thereby considering that the 32 ports are	     * mirrored every 32 bytes. Actually we use a mirrored port for	     * the Mako if (on the first pass) the COR bit 5 is set.	     */	    for (pass=0; pass < 2; pass++) {		tuple.DesiredTuple = CISTPL_CFTABLE_ENTRY;		for (err = first_tuple(handle, &tuple, &parse); !err;				     err = next_tuple(handle, &tuple, &parse)){		    if (cf->io.nwin > 0  &&  (cf->io.win[0].base & 0xf) == 8){			link->conf.ConfigIndex = cf->index ;			link->io.BasePort2 = cf->io.win[0].base;			link->io.BasePort1 = link->io.BasePort2				    + (pass ? (cf->index & 0x20 ? -24:8)					    : (cf->index & 0x20 ?   8:-24));			if (!(err=CardServices(RequestIO, link->handle,								&link->io)))			    goto port_found;		    }		}	    }	    /* if special option:	     * try to configure as Ethernet only.	     * .... */	}	printk(KNOT_XIRC "no ports available\n");    } else {	link->irq.Attributes |= IRQ_TYPE_EXCLUSIVE;	link->io.NumPorts1 = 16;	for (ioaddr = 0x300; ioaddr < 0x400; ioaddr += 0x10) {	    link->io.BasePort1 = ioaddr;	    if (!(err=CardServices(RequestIO, link->handle, &link->io)))		goto port_found;	}	link->io.BasePort1 = 0; /* let CS decide */	if ((err=CardServices(RequestIO, link->handle, &link->io))) {	    cs_error(link->handle, RequestIO, err);	    goto config_error;	}    }  port_found:    if (err)	 goto config_error;    /****************     * Now allocate an interrupt line.	Note that this does not     * actually assign a handler to the interrupt.     */    if ((err=CardServices(RequestIRQ, link->handle, &link->irq))) {	cs_error(link->handle, RequestIRQ, err);	goto config_error;    }    /****************     * This actually configures the PCMCIA socket -- setting up     * the I/O windows and the interrupt mapping.     */    if ((err=CardServices(RequestConfiguration,			  link->handle, &link->conf))) {	cs_error(link->handle, RequestConfiguration, err);	goto config_error;    }    if (local->dingo) {	conf_reg_t reg;	win_req_t req;	memreq_t mem;	/* Reset the modem's BAR to the correct value	 * This is necessary because in the RequestConfiguration call,	 * the base address of the ethernet port (BasePort1) is written	 * to the BAR registers of the modem.	 */	reg.Action = CS_WRITE;	reg.Offset = CISREG_IOBASE_0;	reg.Value = link->io.BasePort2 & 0xff;	if ((err = CardServices(AccessConfigurationRegister, link->handle,				&reg))) {	    cs_error(link->handle, AccessConfigurationRegister, err);	    goto config_error;	}	reg.Action = CS_WRITE;	reg.Offset = CISREG_IOBASE_1;	reg.Value = (link->io.BasePort2 >> 8) & 0xff;	if ((err = CardServices(AccessConfigurationRegister, link->handle,				&reg))) {	    cs_error(link->handle, AccessConfigurationRegister, err);	    goto config_error;	}	/* There is no config entry for the Ethernet part which	 * is at 0x0800. So we allocate a window into the attribute	 * memory and write direct to the CIS registers	 */	req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;	req.Base = req.Size = 0;	req.AccessSpeed = 0;	link->win = (window_handle_t)link->handle;	if ((err = CardServices(RequestWindow, &link->win, &req))) {	    cs_error(link->handle, RequestWindow, err);	    goto config_error;	}	local->dingo_ccr = ioremap(req.Base,0x1000) + 0x0800;	mem.CardOffset = 0x0;	mem.Page = 0;	if ((err = CardServices(MapMemPage, link->win, &mem))) {	    cs_error(link->handle, MapMemPage, err);	    goto config_error;	}	/* Setup the CCRs; there are no infos in the CIS about the Ethernet	 * part.	 */	writeb(0x47, local->dingo_ccr + CISREG_COR);	ioaddr = link->io.BasePort1;	writeb(ioaddr & 0xff	  , local->dingo_ccr + CISREG_IOBASE_0);	writeb((ioaddr >> 8)&0xff , local->dingo_ccr + CISREG_IOBASE_1);      #if 0	{	    u_char tmp;	    printk(KERN_INFO "ECOR:");	    for (i=0; i < 7; i++) {		tmp = readb(local->dingo_ccr + i*2);		printk(" %02x", tmp);	    }	    printk("\n");	    printk(KERN_INFO "DCOR:");	    for (i=0; i < 4; i++) {		tmp = readb(local->dingo_ccr + 0x20 + i*2);		printk(" %02x", tmp);	    }	    printk("\n");	    printk(KERN_INFO "SCOR:");	    for (i=0; i < 10; i++) {		tmp = readb(local->dingo_ccr + 0x40 + i*2);		printk(" %02x", tmp);	    }	    printk("\n");	}      #endif	writeb(0x01, local->dingo_ccr + 0x20);	writeb(0x0c, local->dingo_ccr + 0x22);	writeb(0x00, local->dingo_ccr + 0x24);	writeb(0x00, local->dingo_ccr + 0x26);	writeb(0x00, local->dingo_ccr + 0x28);    }    /* The if_port symbol can be set when the module is loaded */    local->probe_port=0;    if (!if_port) {	local->probe_port = dev->if_port = 1;    } else if ((if_port >= 1 && if_port <= 2) ||	       (local->mohawk && if_port==4))	dev->if_port = if_port;    else	printk(KNOT_XIRC "invalid if_port requested\n");    /* we can now register the device with the net subsystem */    dev->irq = link->irq.AssignedIRQ;    dev->base_addr = link->io.BasePort1;    if ((err=register_netdev(dev))) {	printk(KNOT_XIRC "register_netdev() failed\n");	goto config_error;    }    strcpy(local->node.dev_name, dev->name);    link->dev = &local->node;    link->state &= ~DEV_CONFIG_PENDING;    if (local->dingo)	do_reset(dev, 1); /* a kludge to make the cem56 work */    /* give some infos about the hardware */    printk(KERN_INFO "%s: %s: port %#3lx, irq %d, hwaddr",	 dev->name, local->manf_str,(u_long)dev->base_addr, (int)dev->irq);    for (i = 0; i < 6; i++)	printk("%c%02X", i?':':' ', dev->dev_addr[i]);    printk("\n");    return;  config_error:    link->state &= ~DEV_CONFIG_PENDING;    xirc2ps_release((u_long)link);    return;  cis_error:    printk(KNOT_XIRC "unable to parse CIS\n");  failure:    link->state &= ~DEV_CONFIG_PENDING;} /* xirc2ps_config *//**************** * After a card is removed, xirc2ps_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 voidxirc2ps_release(u_long arg){    dev_link_t *link = (dev_link_t *) arg;    local_info_t *local = link->priv;    struct net_device *dev = &local->dev;    DEBUG(0, "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(0, "release postponed, '%s' "	      "still open\n", link->dev->dev_name);	link->state |= DEV_STALE_CONFIG;	return;    }    if (link->win) {	local_info_t *local = dev->priv;	if (local->dingo)	    iounmap(local->dingo_ccr - 0x0800);	CardServices(ReleaseWindow, link->win);    }    CardServices(ReleaseConfiguration, link->handle);    CardServices(ReleaseIO, link->handle, &link->io);    CardServices(ReleaseIRQ, link->handle, &link->irq);    link->state &= ~DEV_CONFIG;} /* xirc2ps_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 intxirc2ps_event(event_t event, int priority,	      event_callback_args_t * args){    dev_link_t *link = args->client_data;    local_info_t *lp = link->priv;    struct net_device *dev = &lp->dev;    DEBUG(0, "event(%d)\n", (int)event);    switch (event) {    case CS_EVENT_REGISTRATION_COMPLETE:	DEBUG(0, "registration complete\n");	break;    case CS_EVENT_CARD_REMOVAL:	link->state &= ~DEV_PRESENT;	if (link->state & DEV_CONFIG) {	    netif_device_detach(dev);	    mod_timer(&link->release, jiffies + HZ/20);	}	break;    case CS_EVENT_CARD_INSERTION:

⌨️ 快捷键说明

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