亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關于我們
? 蟲蟲下載站

?? lance.c

?? LINUX1.0源代碼,代碼條理清晰
?? C
?? 第 1 頁 / 共 2 頁
字號:

    if (lance_debug > 2)
	printk("%s: LANCE open after %d ticks, init block %#x csr0 %4.4x.\n",
	       dev->name, i, (int) &lp->init_block, inw(ioaddr+LANCE_DATA));

    return 0;			/* Always succeed */
}

/* Initialize the LANCE Rx and Tx rings. */
static void
lance_init_ring(struct device *dev)
{
    struct lance_private *lp = (struct lance_private *)dev->priv;
    int i;

    lp->cur_rx = lp->cur_tx = 0;
    lp->dirty_rx = lp->dirty_tx = 0;

    for (i = 0; i < RX_RING_SIZE; i++) {
	lp->rx_ring[i].base = (lp->rx_buffs + i*PKT_BUF_SZ) | 0x80000000;
	lp->rx_ring[i].buf_length = -PKT_BUF_SZ;
    }
    /* The Tx buffer address is filled in as needed, but we do need to clear
       the upper ownership bit. */
    for (i = 0; i < TX_RING_SIZE; i++) {
	lp->tx_ring[i].base = 0;
    }

    lp->init_block.mode = 0x0000;
    for (i = 0; i < 6; i++)
	lp->init_block.phys_addr[i] = dev->dev_addr[i];
    lp->init_block.filter[0] = 0x00000000;
    lp->init_block.filter[1] = 0x00000000;
    lp->init_block.rx_ring = (int)lp->rx_ring | RX_RING_LEN_BITS;
    lp->init_block.tx_ring = (int)lp->tx_ring | TX_RING_LEN_BITS;
}

static int
lance_start_xmit(struct sk_buff *skb, struct device *dev)
{
    struct lance_private *lp = (struct lance_private *)dev->priv;
    int ioaddr = dev->base_addr;
    int entry;

    /* Transmitter timeout, serious problems. */
    if (dev->tbusy) {
	int tickssofar = jiffies - dev->trans_start;
	if (tickssofar < 10)
	    return 1;
	outw(0, ioaddr+LANCE_ADDR);
	printk("%s: transmit timed out, status %4.4x, resetting.\n",
	       dev->name, inw(ioaddr+LANCE_DATA));
	outw(0x0001, ioaddr+LANCE_DATA);
	lp->stats.tx_errors++;
#ifndef final_version
	{
	    int i;
	    printk(" Ring data dump: dirty_tx %d cur_tx %d cur_rx %d.",
		   lp->dirty_tx, lp->cur_tx, lp->cur_rx);
	    for (i = 0 ; i < RX_RING_SIZE; i++)
		printk("%s %08x %04x %04x", i & 0x3 ? "" : "\n ",
		       lp->rx_ring[i].base, -lp->rx_ring[i].buf_length,
		       lp->rx_ring[i].msg_length);
	    for (i = 0 ; i < TX_RING_SIZE; i++)
		printk(" %s%08x %04x %04x", i & 0x3 ? "" : "\n ",
		       lp->tx_ring[i].base, -lp->tx_ring[i].length,
		       lp->tx_ring[i].misc);
	    printk("\n");
	}
#endif
	lance_init_ring(dev);
	outw(0x0043, ioaddr+LANCE_DATA);

	dev->tbusy=0;
	dev->trans_start = jiffies;

	return 0;
    }

    if (skb == NULL) {
	dev_tint(dev);
	return 0;
    }

    /* Fill in the ethernet header. */
    if (!skb->arp  &&  dev->rebuild_header(skb->data, dev)) {
	skb->dev = dev;
	arp_queue (skb);
	return 0;
    }
    skb->arp=1;

    if (skb->len <= 0)
	return 0;

    if (lance_debug > 3) {
	outw(0x0000, ioaddr+LANCE_ADDR);
	printk("%s: lance_start_xmit() called, csr0 %4.4x.\n", dev->name,
	       inw(ioaddr+LANCE_DATA));
	outw(0x0000, ioaddr+LANCE_DATA);
    }

    /* Block a timer-based transmit from overlapping.  This could better be
       done with atomic_swap(1, dev->tbusy), but set_bit() works as well. */
    if (set_bit(0, (void*)&dev->tbusy) != 0)
	printk("%s: Transmitter access conflict.\n", dev->name);

    /* Fill in a Tx ring entry */

    /* Mask to ring buffer boundary. */
    entry = lp->cur_tx & TX_RING_MOD_MASK;

    /* Caution: the write order is important here, set the base address
       with the "ownership" bits last. */

    /* The old LANCE chips doesn't automatically pad buffers to min. size. */
    if (lp->old_lance) {
	lp->tx_ring[entry].length =
	    -(ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN);
    } else
	lp->tx_ring[entry].length = -skb->len;

    lp->tx_ring[entry].misc = 0x0000;

    /* If any part of this buffer is >16M we must copy it to a low-memory
       buffer. */
    if ((int)(skb->data) + skb->len > 0x01000000) {
	if (lance_debug > 5)
	    printk("%s: bouncing a high-memory packet (%#x).\n",
		   dev->name, (int)(skb->data));
	memcpy(&lp->tx_bounce_buffs[entry], skb->data, skb->len);
	lp->tx_ring[entry].base =
	    (int)(lp->tx_bounce_buffs + entry) | 0x83000000;
	if (skb->free)
	    kfree_skb (skb, FREE_WRITE);
    } else {
    	/* We can't free the packet yet, so we inform the memory management
	   code that we are still using it. */
    	if(skb->free==0)
    		skb_kept_by_device(skb);
	lp->tx_ring[entry].base = (int)(skb->data) | 0x83000000;
    }
    lp->cur_tx++;

    /* Trigger an immediate send poll. */
    outw(0x0000, ioaddr+LANCE_ADDR);
    outw(0x0048, ioaddr+LANCE_DATA);

    dev->trans_start = jiffies;

    if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base == 0)
	dev->tbusy=0;

    return 0;
}

/* The LANCE interrupt handler. */
static void
lance_interrupt(int reg_ptr)
{
    int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
    struct device *dev = (struct device *)(irq2dev_map[irq]);
    struct lance_private *lp;
    int csr0, ioaddr;

    if (dev == NULL) {
	printk ("lance_interrupt(): irq %d for unknown device.\n", irq);
	return;
    }

    ioaddr = dev->base_addr;
    lp = (struct lance_private *)dev->priv;
    if (dev->interrupt)
	printk("%s: Re-entering the interrupt handler.\n", dev->name);

    dev->interrupt = 1;

    outw(0x00, dev->base_addr + LANCE_ADDR);
    csr0 = inw(dev->base_addr + LANCE_DATA);

    /* Acknowledge all of the current interrupt sources ASAP. */
    outw(csr0 & ~0x004f, dev->base_addr + LANCE_DATA);

    if (lance_debug > 5)
	printk("%s: interrupt  csr0=%#2.2x new csr=%#2.2x.\n",
	       dev->name, csr0, inw(dev->base_addr + LANCE_DATA));

    if (csr0 & 0x0400)		/* Rx interrupt */
	lance_rx(dev);

    if (csr0 & 0x0200) {	/* Tx-done interrupt */
	int dirty_tx = lp->dirty_tx;

	while (dirty_tx < lp->cur_tx) {
	    int entry = dirty_tx & TX_RING_MOD_MASK;
	    int status = lp->tx_ring[entry].base;
	    void *databuff;
	    
	    if (status < 0)
		break;		/* It still hasn't been Txed */

	    lp->tx_ring[entry].base = 0;
	    databuff = (void*)(status & 0x00ffffff);

	    if (status & 0x40000000) { /* There was an major error, log it. */
		int err_status = lp->tx_ring[entry].misc;
		lp->stats.tx_errors++;
		if (err_status & 0x0400) lp->stats.tx_aborted_errors++;
		if (err_status & 0x0800) lp->stats.tx_carrier_errors++;
		if (err_status & 0x1000) lp->stats.tx_window_errors++;
		if (err_status & 0x4000) lp->stats.tx_fifo_errors++;
		/* Perhaps we should re-init() after the FIFO error. */
	    } else {
		if (status & 0x18000000)
		    lp->stats.collisions++;
		lp->stats.tx_packets++;
	    }

	    /* We don't free the skb if it's a data-only copy in the bounce
	       buffer.  The address checks here are sorted -- the first test
	       should always work.  */
	    if (databuff >= (void*)(&lp->tx_bounce_buffs[TX_RING_SIZE])
		|| databuff < (void*)(lp->tx_bounce_buffs)) {
		struct sk_buff *skb = ((struct sk_buff *)databuff) - 1;
		if (skb->free)
		    kfree_skb(skb, FREE_WRITE);
		else
		    skb_device_release(skb,FREE_WRITE);
		/* Warning: skb may well vanish at the point you call
		   device_release! */
	    }
	    dirty_tx++;
	}

#ifndef final_version
	if (lp->cur_tx - dirty_tx >= TX_RING_SIZE) {
	    printk("out-of-sync dirty pointer, %d vs. %d.\n",
		   dirty_tx, lp->cur_tx);
	    dirty_tx += TX_RING_SIZE;
	}
#endif

	if (dev->tbusy  &&  dirty_tx > lp->cur_tx - TX_RING_SIZE + 2) {
	    /* The ring is no longer full, clear tbusy. */
	    dev->tbusy = 0;
	    mark_bh(INET_BH);
	}

	lp->dirty_tx = dirty_tx;
    }

    if (csr0 & 0x8000) {
	if (csr0 & 0x4000) lp->stats.tx_errors++;
	if (csr0 & 0x1000) lp->stats.rx_errors++;
    }

    /* Clear the interrupts we've handled. */
    outw(0x0000, dev->base_addr + LANCE_ADDR);
    outw(0x7f40, dev->base_addr + LANCE_DATA);

    if (lance_debug > 4)
	printk("%s: exiting interrupt, csr%d=%#4.4x.\n",
	       dev->name, inw(ioaddr + LANCE_ADDR),
	       inw(dev->base_addr + LANCE_DATA));

    dev->interrupt = 0;
    return;
}

static int
lance_rx(struct device *dev)
{
    struct lance_private *lp = (struct lance_private *)dev->priv;
    int entry = lp->cur_rx & RX_RING_MOD_MASK;
	
    /* If we own the next entry, it's a new packet. Send it up. */
    while (lp->rx_ring[entry].base >= 0) {
	int status = lp->rx_ring[entry].base >> 24;

	if (status != 0x03) {		/* There was an error. */
	    /* There is an tricky error noted by John Murphy,
	       <murf@perftech.com> to Russ Nelson: Even with full-sized
	       buffers it's possible for a jabber packet to use two
	       buffers, with only the last correctly noting the error. */
	    if (status & 0x01)	/* Only count a general error at the */
		lp->stats.rx_errors++; /* end of a packet.*/
	    if (status & 0x20) lp->stats.rx_frame_errors++;
	    if (status & 0x10) lp->stats.rx_over_errors++;
	    if (status & 0x08) lp->stats.rx_crc_errors++;
	    if (status & 0x04) lp->stats.rx_fifo_errors++;
	} else {
	    /* Malloc up new buffer, compatible with net-2e. */
	    short pkt_len = lp->rx_ring[entry].msg_length;
	    int sksize = sizeof(struct sk_buff) + pkt_len;
	    struct sk_buff *skb;

	    skb = alloc_skb(sksize, GFP_ATOMIC);
	    if (skb == NULL) {
		printk("%s: Memory squeeze, deferring packet.\n", dev->name);
		lp->stats.rx_dropped++;	/* Really, deferred. */
		break;
	    }
	    skb->mem_len = sksize;
	    skb->mem_addr = skb;
	    skb->len = pkt_len;
	    skb->dev = dev;
	    memcpy(skb->data,
		   (unsigned char *)(lp->rx_ring[entry].base & 0x00ffffff),
		   pkt_len);
#ifdef HAVE_NETIF_RX
	    netif_rx(skb);
#else
	    skb->lock = 0;
	    if (dev_rint((unsigned char*)skb, pkt_len, IN_SKBUFF, dev) != 0) {
		kfree_skbmem(skb, sksize);
		lp->stats.rx_dropped++;
		break;
	    }
#endif
	    lp->stats.rx_packets++;
	}

	lp->rx_ring[entry].base |= 0x80000000;
	entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
    }

    /* We should check that at least two ring entries are free.  If not,
       we should free one and mark stats->rx_dropped++. */

    return 0;
}

static int
lance_close(struct device *dev)
{
    int ioaddr = dev->base_addr;
    struct lance_private *lp = (struct lance_private *)dev->priv;

    dev->start = 0;
    dev->tbusy = 1;

    outw(112, ioaddr+LANCE_ADDR);
    lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);

    outw(0, ioaddr+LANCE_ADDR);

    if (lance_debug > 1)
	printk("%s: Shutting down ethercard, status was %2.2x.\n",
	       dev->name, inw(ioaddr+LANCE_DATA));

    /* We stop the LANCE here -- it occasionally polls
       memory if we don't. */
    outw(0x0004, ioaddr+LANCE_DATA);

    disable_dma(dev->dma);

    free_irq(dev->irq);
    free_dma(dev->dma);

    irq2dev_map[dev->irq] = 0;

    return 0;
}

static struct enet_statistics *
lance_get_stats(struct device *dev)
{
    struct lance_private *lp = (struct lance_private *)dev->priv;
    short ioaddr = dev->base_addr;
    short saved_addr;

    cli();
    saved_addr = inw(ioaddr+LANCE_ADDR);
    outw(112, ioaddr+LANCE_ADDR);
    lp->stats.rx_missed_errors = inw(ioaddr+LANCE_DATA);
    outw(saved_addr, ioaddr+LANCE_ADDR);
    sti();

    return &lp->stats;
}

#ifdef HAVE_MULTICAST
/* Set or clear the multicast filter for this adaptor.
   num_addrs == -1	Promiscuous mode, receive all packets
   num_addrs == 0	Normal mode, clear multicast list
   num_addrs > 0	Multicast mode, receive normal and MC packets, and do
   			best-effort filtering.
 */
static void
set_multicast_list(struct device *dev, int num_addrs, void *addrs)
{
    short ioaddr = dev->base_addr;

    /* We take the simple way out and always enable promiscuous mode. */
    outw(0, ioaddr+LANCE_ADDR);
    outw(0x0004, ioaddr+LANCE_DATA); /* Temporarily stop the lance.  */

    outw(15, ioaddr+LANCE_ADDR);
    if (num_addrs >= 0) {
	short multicast_table[4];
	int i;
	/* We don't use the multicast table, but rely on upper-layer filtering. */
	memset(multicast_table, (num_addrs == 0) ? 0 : -1, sizeof(multicast_table));
	for (i = 0; i < 4; i++) {
	    outw(8 + i, ioaddr+LANCE_ADDR);
	    outw(multicast_table[i], ioaddr+LANCE_DATA);
	}
	outw(0x0000, ioaddr+LANCE_DATA); /* Unset promiscuous mode */
    } else {
	outw(0x8000, ioaddr+LANCE_DATA); /* Set promiscuous mode */
    }

    outw(0, ioaddr+LANCE_ADDR);
    outw(0x0142, ioaddr+LANCE_DATA); /* Resume normal operation. */
}
#endif

#ifdef HAVE_DEVLIST
static unsigned int lance_portlist[] = {0x300, 0x320, 0x340, 0x360, 0};
struct netdev_entry lance_drv =
{"lance", lance_probe1, LANCE_TOTAL_SIZE, lance_portlist};
#endif

/*
 * Local variables:
 *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c lance.c"
 * End:
 */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
成人av在线网站| 99久久伊人久久99| 中文字幕制服丝袜成人av| 色婷婷精品久久二区二区蜜臂av| 日韩在线观看一区二区| 国产午夜亚洲精品羞羞网站| 欧美视频中文字幕| 国产精品一区久久久久| 午夜视频久久久久久| 国产精品成人网| 337p粉嫩大胆色噜噜噜噜亚洲 | 3d动漫精品啪啪一区二区竹菊| 久草这里只有精品视频| 亚洲一区二区欧美日韩| 国产精品久久777777| 精品嫩草影院久久| 欧美日韩高清影院| 一本色道久久综合亚洲aⅴ蜜桃 | 亚洲成人免费看| 中文字幕一区二区三区不卡| 欧美mv日韩mv| 91精品久久久久久久99蜜桃 | 久久久久久久久久久电影| 欧美日韩国产一级| 色哟哟欧美精品| 成人精品视频.| 国产一区二区三区日韩| 日本va欧美va瓶| 亚洲午夜av在线| 亚洲欧美另类小说视频| 国产精品三级在线观看| 久久午夜羞羞影院免费观看| 欧美成人三级电影在线| 91精品国产入口| 69堂成人精品免费视频| 欧美色精品在线视频| 在线观看成人免费视频| 99久久99精品久久久久久| 国产盗摄一区二区三区| 国产一区二区三区精品欧美日韩一区二区三区 | 日韩免费观看高清完整版| 欧美色手机在线观看| 在线精品亚洲一区二区不卡| 色一情一伦一子一伦一区| 色综合视频一区二区三区高清| 91免费版在线看| 91色|porny| 色综合色综合色综合| 日本精品视频一区二区| 精品视频1区2区| 欧美一区二区网站| 日韩你懂的在线观看| 2020国产精品自拍| 国产夜色精品一区二区av| 中文字幕巨乱亚洲| 亚洲精选视频免费看| 一区二区三区欧美亚洲| 亚洲高清免费一级二级三级| 日本不卡视频在线| 国产美女在线观看一区| 国产精品99久久久久久久女警| 丁香六月久久综合狠狠色| 99久久国产综合色|国产精品| 91精品福利视频| 91精品国产综合久久久久| 欧美tickling网站挠脚心| 国产婷婷色一区二区三区| 国产精品久久精品日日| 亚洲成精国产精品女| 久久精品久久综合| 大胆亚洲人体视频| 欧美综合天天夜夜久久| 欧美成人精品福利| 国产午夜亚洲精品理论片色戒| 亚洲人精品午夜| 美日韩一区二区| 成人免费视频一区| 精品视频在线视频| 欧美精品一区在线观看| 亚洲日本青草视频在线怡红院| 五月天视频一区| 国产精品一区二区在线看| 色哟哟一区二区在线观看| 日韩欧美电影在线| 亚洲欧美日韩国产综合| 日本成人在线视频网站| 成人午夜电影小说| 欧美欧美欧美欧美首页| ww亚洲ww在线观看国产| 亚洲香肠在线观看| 国产999精品久久久久久绿帽| 在线精品观看国产| 国产亚洲污的网站| 亚洲国产精品久久久久秋霞影院 | 91亚洲大成网污www| 日韩一区二区免费视频| 国产精品久久久久影院色老大| 亚洲va欧美va人人爽| 成人性色生活片| 日韩视频免费观看高清完整版| 最新成人av在线| 精品一区二区三区免费毛片爱| 91欧美一区二区| 精品对白一区国产伦| 亚洲高清免费观看| 丁香天五香天堂综合| 欧美一级日韩不卡播放免费| 亚洲人成网站影音先锋播放| 国产成人一区在线| 欧美一区二区三区的| 亚洲精品日产精品乱码不卡| 国产精品18久久久久久久久久久久| 欧美系列亚洲系列| 国产精品夫妻自拍| 精品一区二区久久久| 91精品国产麻豆国产自产在线| 国产精品第一页第二页第三页| 狠狠色伊人亚洲综合成人| 91麻豆精品国产91久久久更新时间 | 99re这里都是精品| 欧美国产精品一区二区三区| 国产一区二区免费在线| 欧美一区在线视频| 五月天婷婷综合| 欧美日韩在线播放| 日韩久久一区二区| 成人免费毛片app| 久久亚洲影视婷婷| 麻豆成人免费电影| 91精品在线麻豆| 无码av中文一区二区三区桃花岛| 色噜噜偷拍精品综合在线| 综合激情成人伊人| www.成人网.com| 国产精品久久久久久户外露出| 国产·精品毛片| 中文字幕乱码日本亚洲一区二区 | 国产夫妻精品视频| 国产视频亚洲色图| 国产成人精品一区二| 久久五月婷婷丁香社区| 精品国产第一区二区三区观看体验| 成人性生交大片免费看视频在线 | 91国内精品野花午夜精品| 亚洲不卡在线观看| 国产一区二区三区四区五区入口| 久久亚洲精品小早川怜子| 欧美日韩高清影院| 一区二区三区在线高清| 豆国产96在线|亚洲| 国产精品久久99| 色哟哟日韩精品| 亚洲无线码一区二区三区| 欧美夫妻性生活| 免费av成人在线| 久久综合狠狠综合久久综合88| 国产乱码一区二区三区| 中文字幕精品一区二区精品绿巨人 | 色综合色狠狠综合色| 一区二区三区在线高清| 69堂成人精品免费视频| 捆绑变态av一区二区三区| 久久久久国产精品人| 成人午夜视频在线观看| 亚洲男人的天堂在线aⅴ视频| 日本韩国一区二区三区| 日本欧美大码aⅴ在线播放| 久久久久久免费网| 99re在线视频这里只有精品| 午夜精品久久久久久久久久| 欧美一级久久久久久久大片| 国产一区二区三区美女| 日韩伦理电影网| 91精品国产综合久久蜜臀| 中文字幕欧美一| 久久精品夜夜夜夜久久| 精品毛片乱码1区2区3区| 欧美日韩色一区| 欧美性极品少妇| 欧美日韩成人综合天天影院 | 欧美精品一卡两卡| 精品综合免费视频观看| 欧美一区二区三区在线视频| 亚洲国产视频一区二区| 成人夜色视频网站在线观看| 欧美日韩欧美一区二区| 日韩精品一区二区三区视频在线观看| 中文字幕二三区不卡| 国产.欧美.日韩| 午夜精品视频在线观看| 5566中文字幕一区二区电影 | 99免费精品视频| 国产成人久久精品77777最新版本 国产成人鲁色资源国产91色综 | 日韩一二在线观看| 久久久精品tv| 天堂av在线一区| 在线免费亚洲电影| 亚洲另类中文字| 国产老肥熟一区二区三区| 欧美日韩三级一区二区|