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

📄 fmvj18x_cs.c

📁 优龙2410linux2.6.8内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));	CS_CHECK(ParseTuple, pcmcia_parse_tuple(handle, &tuple, &parse));	link->conf.ConfigIndex = parse.cftable_entry.index;	tuple.DesiredTuple = CISTPL_MANFID;	if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS)	    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));	else	    buf[0] = 0xffff;	switch (le16_to_cpu(buf[0])) {	case MANFID_TDK:	    cardtype = TDK;	    if (le16_to_cpu(buf[1]) == PRODID_TDK_CF010) {		cs_status_t status;		pcmcia_get_status(handle, &status);		if (status.CardState & CS_EVENT_3VCARD)		    link->conf.Vcc = 33; /* inserted in 3.3V slot */	    } else if (le16_to_cpu(buf[1]) == PRODID_TDK_GN3410) {		/* MultiFunction Card */		link->conf.ConfigBase = 0x800;		link->conf.ConfigIndex = 0x47;		link->io.NumPorts2 = 8;	    }	    break;	case MANFID_CONTEC:	    cardtype = CONTEC;	    break;	case MANFID_FUJITSU:	    if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10302)                /* RATOC REX-5588/9822/4886's PRODID are 0004(=MBH10302),                   but these are MBH10304 based card. */ 		cardtype = MBH10304;	    else if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10304)		cardtype = MBH10304;	    else		cardtype = LA501;	    break;	default:	    cardtype = MBH10304;	}    } else {	/* old type card */	tuple.DesiredTuple = CISTPL_MANFID;	if (pcmcia_get_first_tuple(handle, &tuple) == CS_SUCCESS)	    CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));	else	    buf[0] = 0xffff;	switch (le16_to_cpu(buf[0])) {	case MANFID_FUJITSU:	    if (le16_to_cpu(buf[1]) == PRODID_FUJITSU_MBH10304) {		cardtype = XXX10304;    /* MBH10304 with buggy CIS */	        link->conf.ConfigIndex = 0x20;	    } else {		cardtype = MBH10302;    /* NextCom NC5310, etc. */		link->conf.ConfigIndex = 1;	    }	    break;	case MANFID_UNGERMANN:	    cardtype = UNGERMANN;	    break;	default:	    cardtype = MBH10302;	    link->conf.ConfigIndex = 1;	}    }    if (link->io.NumPorts2 != 0) {    	link->irq.Attributes =		IRQ_TYPE_DYNAMIC_SHARING|IRQ_FIRST_SHARED|IRQ_HANDLE_PRESENT;	ret = mfc_try_io_port(link);	if (ret != CS_SUCCESS) goto cs_failed;    } else if (cardtype == UNGERMANN) {	ret = ungermann_try_io_port(link);	if (ret != CS_SUCCESS) goto cs_failed;    } else { 	CS_CHECK(RequestIO, pcmcia_request_io(link->handle, &link->io));    }    CS_CHECK(RequestIRQ, pcmcia_request_irq(link->handle, &link->irq));    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link->handle, &link->conf));    dev->irq = link->irq.AssignedIRQ;    dev->base_addr = link->io.BasePort1;    if (link->io.BasePort2 != 0)	fmvj18x_setup_mfc(link);    ioaddr = dev->base_addr;    /* Reset controller */    if (sram_config == 0) 	outb(CONFIG0_RST, ioaddr + CONFIG_0);    else	outb(CONFIG0_RST_1, ioaddr + CONFIG_0);    /* Power On chip and select bank 0 */    if (cardtype == MBH10302)	outb(BANK_0, ioaddr + CONFIG_1);    else	outb(BANK_0U, ioaddr + CONFIG_1);        /* Set hardware address */    switch (cardtype) {    case MBH10304:    case TDK:    case LA501:    case CONTEC:	tuple.DesiredTuple = CISTPL_FUNCE;	tuple.TupleOffset = 0;	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(handle, &tuple));	tuple.TupleOffset = 0;	CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));	if (cardtype == MBH10304) {	    /* MBH10304's CIS_FUNCE is corrupted */	    node_id = &(tuple.TupleData[5]);	    card_name = "FMV-J182";	} else {	    while (tuple.TupleData[0] != CISTPL_FUNCE_LAN_NODE_ID ) {		CS_CHECK(GetNextTuple, pcmcia_get_next_tuple(handle, &tuple));		CS_CHECK(GetTupleData, pcmcia_get_tuple_data(handle, &tuple));	    }	    node_id = &(tuple.TupleData[2]);	    if( cardtype == TDK ) {		card_name = "TDK LAK-CD021";	    } else if( cardtype == LA501 ) {		card_name = "LA501";	    } else {		card_name = "C-NET(PC)C";	    }	}	/* Read MACID from CIS */	for (i = 0; i < 6; i++)	    dev->dev_addr[i] = node_id[i];	break;    case UNGERMANN:	/* Read MACID from register */	for (i = 0; i < 6; i++) 	    dev->dev_addr[i] = inb(ioaddr + UNGERMANN_MAC_ID + i);	card_name = "Access/CARD";	break;    case XXX10304:	/* Read MACID from Buggy CIS */	if (fmvj18x_get_hwinfo(link, tuple.TupleData) == -1) {	    printk(KERN_NOTICE "fmvj18x_cs: unable to read hardware net address.\n");	    goto failed;	}	for (i = 0 ; i < 6; i++) {	    dev->dev_addr[i] = tuple.TupleData[i];	}	card_name = "FMV-J182";	break;    case MBH10302:    default:	/* Read MACID from register */	for (i = 0; i < 6; i++) 	    dev->dev_addr[i] = inb(ioaddr + MAC_ID + i);	card_name = "FMV-J181";	break;    }    lp->cardtype = cardtype;    link->dev = &lp->node;    link->state &= ~DEV_CONFIG_PENDING;    if (register_netdev(dev) != 0) {	printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n");	link->dev = NULL;	goto failed;    }    strcpy(lp->node.dev_name, dev->name);    /* print current configuration */    printk(KERN_INFO "%s: %s, sram %s, port %#3lx, irq %d, hw_addr ", 	   dev->name, card_name, sram_config == 0 ? "4K TX*2" : "8K TX*2", 	   dev->base_addr, dev->irq);    for (i = 0; i < 6; i++)	printk("%02X%s", dev->dev_addr[i], ((i<5) ? ":" : "\n"));    return;    cs_failed:    /* All Card Services errors end up here */    cs_error(link->handle, last_fn, last_ret);failed:    fmvj18x_release(link);    link->state &= ~DEV_CONFIG_PENDING;} /* fmvj18x_config *//*====================================================================*/static int fmvj18x_get_hwinfo(dev_link_t *link, u_char *node_id){    win_req_t req;    memreq_t mem;    u_char *base;    int i, j;    /* Allocate a small memory window */    req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;    req.Base = 0; req.Size = 0;    req.AccessSpeed = 0;    i = pcmcia_request_window(&link->handle, &req, &link->win);    if (i != CS_SUCCESS) {	cs_error(link->handle, RequestWindow, i);	return -1;    }    base = ioremap(req.Base, req.Size);    mem.Page = 0;    mem.CardOffset = 0;    pcmcia_map_mem_page(link->win, &mem);    /*     *  MBH10304 CISTPL_FUNCE_LAN_NODE_ID format     *  22 0d xx xx xx 04 06 yy yy yy yy yy yy ff     *  'xx' is garbage.     *  'yy' is MAC address.    */     for (i = 0; i < 0x200; i++) {	if (readb(base+i*2) == 0x22) {		    if (readb(base+(i-1)*2) == 0xff	     && readb(base+(i+5)*2) == 0x04	     && readb(base+(i+6)*2) == 0x06	     && readb(base+(i+13)*2) == 0xff) 		break;	}    }    if (i != 0x200) {	for (j = 0 ; j < 6; j++,i++) {	    node_id[j] = readb(base+(i+7)*2);	}    }    iounmap(base);    j = pcmcia_release_window(link->win);    if (j != CS_SUCCESS)	cs_error(link->handle, ReleaseWindow, j);    return (i != 0x200) ? 0 : -1;} /* fmvj18x_get_hwinfo *//*====================================================================*/static int fmvj18x_setup_mfc(dev_link_t *link){    win_req_t req;    memreq_t mem;    u_char *base;    int i, j;    struct net_device *dev = link->priv;    ioaddr_t ioaddr;    /* Allocate a small memory window */    req.Attributes = WIN_DATA_WIDTH_8|WIN_MEMORY_TYPE_AM|WIN_ENABLE;    req.Base = 0; req.Size = 0;    req.AccessSpeed = 0;    i = pcmcia_request_window(&link->handle, &req, &link->win);    if (i != CS_SUCCESS) {	cs_error(link->handle, RequestWindow, i);	return -1;    }    base = ioremap(req.Base, req.Size);    mem.Page = 0;    mem.CardOffset = 0;    pcmcia_map_mem_page(link->win, &mem);    ioaddr = dev->base_addr;    writeb(0x47, base+0x800);	/* Config Option Register of LAN */    writeb(0x0, base+0x802);	/* Config and Status Register */    writeb(ioaddr & 0xff, base+0x80a);		/* I/O Base(Low) of LAN */    writeb((ioaddr >> 8) & 0xff, base+0x80c);	/* I/O Base(High) of LAN */       writeb(0x45, base+0x820);	/* Config Option Register of Modem */    writeb(0x8, base+0x822);	/* Config and Status Register */    iounmap(base);    j = pcmcia_release_window(link->win);    if (j != CS_SUCCESS)	cs_error(link->handle, ReleaseWindow, j);    return 0;}/*====================================================================*/static void fmvj18x_release(dev_link_t *link){    DEBUG(0, "fmvj18x_release(0x%p)\n", link);    /* Don't bother checking to see if these succeed or not */    pcmcia_release_window(link->win);    pcmcia_release_configuration(link->handle);    pcmcia_release_io(link->handle, &link->io);    pcmcia_release_irq(link->handle, &link->irq);        link->state &= ~DEV_CONFIG;}/*====================================================================*/static int fmvj18x_event(event_t event, int priority,			  event_callback_args_t *args){    dev_link_t *link = args->client_data;    struct net_device *dev = link->priv;    DEBUG(1, "fmvj18x_event(0x%06x)\n", event);        switch (event) {    case CS_EVENT_CARD_REMOVAL:	link->state &= ~DEV_PRESENT;	if (link->state & DEV_CONFIG)	    netif_device_detach(dev);	break;    case CS_EVENT_CARD_INSERTION:	link->state |= DEV_PRESENT | DEV_CONFIG_PENDING;	fmvj18x_config(link);	break;    case CS_EVENT_PM_SUSPEND:	link->state |= DEV_SUSPEND;	/* Fall through... */    case CS_EVENT_RESET_PHYSICAL:	if (link->state & DEV_CONFIG) {	    if (link->open)		netif_device_detach(dev);	    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);	    if (link->open) {		fjn_reset(dev);		netif_device_attach(dev);	    }	}	break;    }    return 0;} /* fmvj18x_event */static struct pcmcia_driver fmvj18x_cs_driver = {	.owner		= THIS_MODULE,	.drv		= {		.name	= "fmvj18x_cs",	},	.attach		= fmvj18x_attach,	.detach		= fmvj18x_detach,};static int __init init_fmvj18x_cs(void){	return pcmcia_register_driver(&fmvj18x_cs_driver);}static void __exit exit_fmvj18x_cs(void){	pcmcia_unregister_driver(&fmvj18x_cs_driver);	while (dev_list != NULL)		fmvj18x_detach(dev_list);}module_init(init_fmvj18x_cs);module_exit(exit_fmvj18x_cs);/*====================================================================*/static irqreturn_t fjn_interrupt(int irq, void *dev_id, struct pt_regs *regs){    struct net_device *dev = dev_id;    local_info_t *lp = netdev_priv(dev);    ioaddr_t ioaddr;    unsigned short tx_stat, rx_stat;    if (lp == NULL) {        printk(KERN_NOTICE "fjn_interrupt(): irq %d for "	       "unknown device.\n", irq);        return IRQ_NONE;    }    ioaddr = dev->base_addr;    /* avoid multiple interrupts */    outw(0x0000, ioaddr + TX_INTR);    /* wait for a while */    udelay(1);    /* get status */    tx_stat = inb(ioaddr + TX_STATUS);    rx_stat = inb(ioaddr + RX_STATUS);    /* clear status */    outb(tx_stat, ioaddr + TX_STATUS);    outb(rx_stat, ioaddr + RX_STATUS);        DEBUG(4, "%s: interrupt, rx_status %02x.\n", dev->name, rx_stat);    DEBUG(4, "               tx_status %02x.\n", tx_stat);        if (rx_stat || (inb(ioaddr + RX_MODE) & F_BUF_EMP) == 0) {	/* there is packet(s) in rx buffer */	fjn_rx(dev);    }    if (tx_stat & F_TMT_RDY) {	lp->stats.tx_packets += lp->sent ;        lp->sent = 0 ;	if (lp->tx_queue) {	    outb(DO_TX | lp->tx_queue, ioaddr + TX_START);	    lp->sent = lp->tx_queue ;	    lp->tx_queue = 0;	    lp->tx_queue_len = 0;	    dev->trans_start = jiffies;	} else {	    lp->tx_started = 0;	}	netif_wake_queue(dev);    }    DEBUG(4, "%s: exiting interrupt,\n", dev->name);    DEBUG(4, "    tx_status %02x, rx_status %02x.\n", tx_stat, rx_stat);    outb(D_TX_INTR, ioaddr + TX_INTR);    outb(D_RX_INTR, ioaddr + RX_INTR);    return IRQ_HANDLED;} /* fjn_interrupt *//*====================================================================*/static void fjn_tx_timeout(struct net_device *dev){    struct local_info_t *lp = netdev_priv(dev);

⌨️ 快捷键说明

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