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

📄 fmvj18x_cs.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
	        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, &link->io));    }    CS_CHECK(RequestIRQ, pcmcia_request_irq(link, &link->irq));    CS_CHECK(RequestConfiguration, pcmcia_request_configuration(link, &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:    case NEC:    case KME:	tuple.DesiredTuple = CISTPL_FUNCE;	tuple.TupleOffset = 0;	CS_CHECK(GetFirstTuple, pcmcia_get_first_tuple(link, &tuple));	tuple.TupleOffset = 0;	CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &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(link, &tuple));		CS_CHECK(GetTupleData, pcmcia_get_tuple_data(link, &tuple));	    }	    node_id = &(tuple.TupleData[2]);	    if( cardtype == TDK ) {		card_name = "TDK LAK-CD021";	    } else if( cardtype == LA501 ) {		card_name = "LA501";	    } else if( cardtype == NEC ) {		card_name = "PK-UG-J001";	    } else if( cardtype == KME ) {		card_name = "Panasonic";	    } 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_node = &lp->node;    SET_NETDEV_DEV(dev, &handle_to_dev(link));    if (register_netdev(dev) != 0) {	printk(KERN_NOTICE "fmvj18x_cs: register_netdev() failed\n");	link->dev_node = 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 %s\n",	   dev->name, card_name, sram_config == 0 ? "4K TX*2" : "8K TX*2", 	   dev->base_addr, dev->irq, print_mac(mac, dev->dev_addr));    return 0;    cs_failed:    /* All Card Services errors end up here */    cs_error(link, last_fn, last_ret);failed:    fmvj18x_release(link);    return -ENODEV;} /* fmvj18x_config *//*====================================================================*/static int fmvj18x_get_hwinfo(struct pcmcia_device *link, u_char *node_id){    win_req_t req;    memreq_t mem;    u_char __iomem *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, &req, &link->win);    if (i != CS_SUCCESS) {	cs_error(link, 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, ReleaseWindow, j);    return (i != 0x200) ? 0 : -1;} /* fmvj18x_get_hwinfo *//*====================================================================*/static int fmvj18x_setup_mfc(struct pcmcia_device *link){    win_req_t req;    memreq_t mem;    u_char __iomem *base;    int i, j;    struct net_device *dev = link->priv;    kio_addr_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, &req, &link->win);    if (i != CS_SUCCESS) {	cs_error(link, 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, ReleaseWindow, j);    return 0;}/*====================================================================*/static void fmvj18x_release(struct pcmcia_device *link){	DEBUG(0, "fmvj18x_release(0x%p)\n", link);	pcmcia_disable_device(link);}static int fmvj18x_suspend(struct pcmcia_device *link){	struct net_device *dev = link->priv;	if (link->open)		netif_device_detach(dev);	return 0;}static int fmvj18x_resume(struct pcmcia_device *link){	struct net_device *dev = link->priv;	if (link->open) {		fjn_reset(dev);		netif_device_attach(dev);	}	return 0;}/*====================================================================*/static struct pcmcia_device_id fmvj18x_ids[] = {	PCMCIA_DEVICE_MANF_CARD(0x0004, 0x0004),	PCMCIA_DEVICE_PROD_ID12("EAGLE Technology", "NE200 ETHERNET LAN MBH10302 04", 0x528c88c4, 0x74f91e59),	PCMCIA_DEVICE_PROD_ID12("Eiger Labs,Inc", "EPX-10BT PC Card Ethernet 10BT", 0x53af556e, 0x877f9922),	PCMCIA_DEVICE_PROD_ID12("Eiger labs,Inc.", "EPX-10BT PC Card Ethernet 10BT", 0xf47e6c66, 0x877f9922),	PCMCIA_DEVICE_PROD_ID12("FUJITSU", "LAN Card(FMV-J182)", 0x6ee5a3d8, 0x5baf31db),	PCMCIA_DEVICE_PROD_ID12("FUJITSU", "MBH10308", 0x6ee5a3d8, 0x3f04875e),	PCMCIA_DEVICE_PROD_ID12("FUJITSU TOWA", "LA501", 0xb8451188, 0x12939ba2),	PCMCIA_DEVICE_PROD_ID12("HITACHI", "HT-4840-11", 0xf4f43949, 0x773910f4),	PCMCIA_DEVICE_PROD_ID12("NextComK.K.", "NC5310B Ver1.0       ", 0x8cef4d3a, 0x075fc7b6),	PCMCIA_DEVICE_PROD_ID12("NextComK.K.", "NC5310 Ver1.0        ", 0x8cef4d3a, 0xbccf43e6),	PCMCIA_DEVICE_PROD_ID12("RATOC System Inc.", "10BASE_T CARD R280", 0x85c10e17, 0xd9413666),	PCMCIA_DEVICE_PROD_ID12("TDK", "LAC-CD02x", 0x1eae9475, 0x8fa0ee70),	PCMCIA_DEVICE_PROD_ID12("TDK", "LAC-CF010", 0x1eae9475, 0x7683bc9a),	PCMCIA_DEVICE_PROD_ID1("CONTEC Co.,Ltd.", 0x58d8fee2),	PCMCIA_DEVICE_PROD_ID1("PCMCIA LAN MBH10304  ES", 0x2599f454),	PCMCIA_DEVICE_PROD_ID1("PCMCIA MBH10302", 0x8f4005da),	PCMCIA_DEVICE_PROD_ID1("UBKK,V2.0", 0x90888080),	PCMCIA_PFC_DEVICE_PROD_ID12(0, "TDK", "GlobalNetworker 3410/3412", 0x1eae9475, 0xd9a93bed),	PCMCIA_PFC_DEVICE_PROD_ID12(0, "NEC", "PK-UG-J001" ,0x18df0ba0 ,0x831b1064),	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0d0a),	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0105, 0x0e0a),	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x0a05),	PCMCIA_PFC_DEVICE_MANF_CARD(0, 0x0032, 0x1101),	PCMCIA_DEVICE_NULL,};MODULE_DEVICE_TABLE(pcmcia, fmvj18x_ids);static struct pcmcia_driver fmvj18x_cs_driver = {	.owner		= THIS_MODULE,	.drv		= {		.name	= "fmvj18x_cs",	},	.probe		= fmvj18x_probe,	.remove		= fmvj18x_detach,	.id_table       = fmvj18x_ids,	.suspend	= fmvj18x_suspend,	.resume		= fmvj18x_resume,};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);}module_init(init_fmvj18x_cs);module_exit(exit_fmvj18x_cs);/*====================================================================*/static irqreturn_t fjn_interrupt(int irq, void *dev_id){    struct net_device *dev = dev_id;    local_info_t *lp = netdev_priv(dev);    kio_addr_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);    kio_addr_t ioaddr = dev->base_addr;    printk(KERN_NOTICE "%s: transmit timed out with status %04x, %s?\n",	   dev->name, htons(inw(ioaddr + TX_STATUS)),	   inb(ioaddr + TX_STATUS) & F_TMT_RDY	   ? "IRQ conflict" : "network cable problem");    printk(KERN_NOTICE "%s: timeout registers: %04x %04x %04x "	   "%04x %04x %04x %04x %04x.\n",	   dev->name, htons(inw(ioaddr + 0)),	   htons(inw(ioaddr + 2)), htons(inw(ioaddr + 4)),	   htons(inw(ioaddr + 6)), htons(inw(ioaddr + 8)),	   htons(inw(ioaddr +10)), htons(inw(ioaddr +12)),	   htons(inw(ioaddr +14)));    lp->stats.tx_errors++;    /* ToDo: We should try to restart the adaptor... */    local_irq_disable();    fjn_reset(dev);    lp->tx_started = 0;    lp->tx_queue = 0;    lp->tx_queue_len = 0;    lp->sent = 0;    lp->open_time = jiffies;    local_irq_enable();

⌨️ 快捷键说明

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