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

? 歡迎來到蟲蟲下載站! | ?? 資源下載 ?? 資源專輯 ?? 關(guān)于我們
? 蟲蟲下載站

?? ne.c

?? 內(nèi)核是系統(tǒng)的心臟
?? C
字號:
/* ne.c: A general non-shared-memory NS8390 ethernet driver for linux. */
/*
    Written 1992,1993 by Donald Becker.

    Copyright 1993 United States Government as represented by the
    Director, National Security Agency.  This software may be used and
    distributed according to the terms of the GNU Public License,
    incorporated herein by reference.

    This driver should work with many 8390-based ethernet boards.  Currently
    it support the NE1000, NE2000, clones, and some Cabletron products.

    The Author may be reached as becker@super.org or
    C/O Supercomputing Research Ctr., 17100 Science Dr., Bowie MD 20715
*/

/* Routines for the NatSemi-based designs (NE[12]000). */

static char *version =
    "ne.c:v0.99-15k 3/3/94 Donald Becker (becker@super.org)\n";

#include <linux/config.h>
#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/errno.h>
#include <asm/system.h>
#include <asm/io.h>

#include "dev.h"
#include "8390.h"

#define NE_BASE	 (dev->base_addr)
#define NE_CMD	 	0x00
#define NE_DATAPORT	0x10	/* NatSemi-defined port window offset. */
#define NE_RESET	0x1f	/* Issue a read to reset, a write to clear. */

#define NE1SM_START_PG	0x20	/* First page of TX buffer */
#define NE1SM_STOP_PG 	0x40	/* Last page +1 of RX ring */
#define NESM_START_PG	0x40	/* First page of TX buffer */
#define NESM_STOP_PG	0x80	/* Last page +1 of RX ring */

int ne_probe(struct device *dev);
static int neprobe1(int ioaddr, struct device *dev, int verbose);

static void ne_reset_8390(struct device *dev);
static int ne_block_input(struct device *dev, int count,
			  char *buf, int ring_offset);
static void ne_block_output(struct device *dev, const int count,
		const unsigned char *buf, const int start_page);


/*  Probe for various non-shared-memory ethercards.

   NEx000-clone boards have a Station Address PROM (SAPROM) in the packet
   buffer memory space.  NE2000 clones have 0x57,0x57 in bytes 0x0e,0x0f of
   the SAPROM, while other supposed NE2000 clones must be detected by their
   SA prefix.

   Reading the SAPROM from a word-wide card with the 8390 set in byte-wide
   mode results in doubled values, which can be detected and compansated for.

   The probe is also responsible for initializing the card and filling
   in the 'dev' and 'ei_status' structures.

   We use the minimum memory size for some ethercard product lines, iff we can't
   distinguish models.  You can increase the packet buffer size by setting
   PACKETBUF_MEMSIZE.  Reported Cabletron packet buffer locations are:
	E1010   starts at 0x100 and ends at 0x2000.
	E1010-x starts at 0x100 and ends at 0x8000. ("-x" means "more memory")
	E2010	 starts at 0x100 and ends at 0x4000.
	E2010-x starts at 0x100 and ends at 0xffff.  */

int ne_probe(struct device *dev)
{
    int *port, ports[] = {0x300, 0x280, 0x320, 0x340, 0x360, 0};
    short ioaddr = dev->base_addr;

    if (ioaddr < 0)
	return ENXIO;		/* Don't probe at all. */
    if (ioaddr > 0x100)
	return ! neprobe1(ioaddr, dev, 1);

    for (port = &ports[0]; *port; port++) {
#ifdef HAVE_PORTRESERVE
	if (check_region(*port, 32))
	    continue;
#endif
	if (inb_p(*port) != 0xff && neprobe1(*port, dev, 0)) {
	    dev->base_addr = *port;
	    return 0;
	}
    }
    dev->base_addr = ioaddr;
    return ENODEV;
}

static int neprobe1(int ioaddr, struct device *dev, int verbose)
{
    int i;
    unsigned char SA_prom[32];
    int wordlength = 2;
    char *name;
    int start_page, stop_page;
    int neX000, ctron, dlink, dfi;
    int reg0 = inb(ioaddr);

    if ( reg0 == 0xFF)
	return 0;

    /* Do a quick preliminary check that we have a 8390. */
    {	int regd;
	outb_p(E8390_NODMA+E8390_PAGE1+E8390_STOP, ioaddr + E8390_CMD);
	regd = inb_p(ioaddr + 0x0d);
	outb_p(0xff, ioaddr + 0x0d);
	outb_p(E8390_NODMA+E8390_PAGE0, ioaddr + E8390_CMD);
	inb_p(ioaddr + EN0_COUNTER0); /* Clear the counter by reading. */
	if (inb_p(ioaddr + EN0_COUNTER0) != 0) {
	    outb_p(reg0, ioaddr);
	    outb(regd, ioaddr + 0x0d);	/* Restore the old values. */
	    return 0;
	}
    }

    printk("NE*000 ethercard probe at %#3x:", ioaddr);

    /* Read the 16 bytes of station address prom, returning 1 for
       an eight-bit interface and 2 for a 16-bit interface.
       We must first initialize registers, similar to NS8390_init(eifdev, 0).
       We can't reliably read the SAPROM address without this.
       (I learned the hard way!). */
    {
	struct {unsigned char value, offset; } program_seq[] = {
	    {E8390_NODMA+E8390_PAGE0+E8390_STOP, E8390_CMD}, /* Select page 0*/
	    {0x48,	EN0_DCFG},	/* Set byte-wide (0x48) access. */
	    {0x00,	EN0_RCNTLO},	/* Clear the count regs. */
	    {0x00,	EN0_RCNTHI},
	    {0x00,	EN0_IMR},	/* Mask completion irq. */
	    {0xFF,	EN0_ISR},
	    {E8390_RXOFF, EN0_RXCR},	/* 0x20  Set to monitor */
	    {E8390_TXOFF, EN0_TXCR},	/* 0x02  and loopback mode. */
	    {32,	EN0_RCNTLO},
	    {0x00,	EN0_RCNTHI},
	    {0x00,	EN0_RSARLO},	/* DMA starting at 0x0000. */
	    {0x00,	EN0_RSARHI},
	    {E8390_RREAD+E8390_START, E8390_CMD},
	};
	for (i = 0; i < sizeof(program_seq)/sizeof(program_seq[0]); i++)
	    outb_p(program_seq[i].value, ioaddr + program_seq[i].offset);
    }
    for(i = 0; i < 32 /*sizeof(SA_prom)*/; i+=2) {
	SA_prom[i] = inb(ioaddr + NE_DATAPORT);
	SA_prom[i+1] = inb(ioaddr + NE_DATAPORT);
	if (SA_prom[i] != SA_prom[i+1])
	    wordlength = 1;
    }

    if (wordlength == 2) {
	/* We must set the 8390 for word mode. */
	outb_p(0x49, ioaddr + EN0_DCFG);
	/* We used to reset the ethercard here, but it doesn't seem
	   to be necessary. */
	/* Un-double the SA_prom values. */
	for (i = 0; i < 16; i++)
	    SA_prom[i] = SA_prom[i+i];
    }

#if defined(show_all_SAPROM)
    /* If your ethercard isn't detected define this to see the SA_PROM. */
    for(i = 0; i < sizeof(SA_prom); i++)
	printk(" %2.2x", SA_prom[i]);
#else
    for(i = 0; i < ETHER_ADDR_LEN; i++) {
	dev->dev_addr[i] = SA_prom[i];
	printk(" %2.2x", SA_prom[i]);
    }
#endif

    neX000 = (SA_prom[14] == 0x57  &&  SA_prom[15] == 0x57);
    ctron =  (SA_prom[0] == 0x00 && SA_prom[1] == 0x00 && SA_prom[2] == 0x1d);
    dlink =  (SA_prom[0] == 0x00 && SA_prom[1] == 0xDE && SA_prom[2] == 0x01);
    dfi   =  (SA_prom[0] == 'D' && SA_prom[1] == 'F' && SA_prom[2] == 'I');

    /* Set up the rest of the parameters. */
    if (neX000 || dlink || dfi) {
	if (wordlength == 2) {
	    name = dlink ? "DE200" : "NE2000";
	    start_page = NESM_START_PG;
	    stop_page = NESM_STOP_PG;
	} else {
	    name = dlink ? "DE100" : "NE1000";
	    start_page = NE1SM_START_PG;
	    stop_page = NE1SM_STOP_PG;
	}
    } else if (ctron) {
	name = "Cabletron";
	start_page = 0x01;
	stop_page = (wordlength == 2) ? 0x40 : 0x20;
    } else {
	printk(" not found.\n");
	return 0;
    }

    if (dev->irq < 2) {
	autoirq_setup(0);
	outb_p(0x50, ioaddr + EN0_IMR);	/* Enable one interrupt. */
	outb_p(0x00, ioaddr + EN0_RCNTLO);
	outb_p(0x00, ioaddr + EN0_RCNTHI);
	outb_p(E8390_RREAD+E8390_START, ioaddr); /* Trigger it... */
	outb_p(0x00, ioaddr + EN0_IMR); 		/* Mask it again. */
	dev->irq = autoirq_report(0);
	if (ei_debug > 2)
	    printk(" autoirq is %d", dev->irq);
    } else if (dev->irq == 2)
	/* Fixup for users that don't know that IRQ 2 is really IRQ 9,
	   or don't know which one to set. */
	dev->irq = 9;
    
    /* Snarf the interrupt now.  There's no point in waiting since we cannot
       share and the board will usually be enabled. */
    {
	int irqval = irqaction (dev->irq, &ei_sigaction);
	if (irqval) {
	    printk (" unable to get IRQ %d (irqval=%d).\n", dev->irq, irqval);
	    return 0;
	}
    }

    dev->base_addr = ioaddr;

#ifdef HAVE_PORTRESERVE
    snarf_region(ioaddr, 32);
#endif

    ethdev_init(dev);
    printk("\n%s: %s found at %#x, using IRQ %d.\n",
	   dev->name, name, ioaddr, dev->irq);

    if (ei_debug > 0)
	printk(version);

    ei_status.name = name;
    ei_status.tx_start_page = start_page;
    ei_status.stop_page = stop_page;
    ei_status.word16 = (wordlength == 2);

    ei_status.rx_start_page = start_page + TX_PAGES;
#ifdef PACKETBUF_MEMSIZE
    /* Allow the packet buffer size to be overridden by know-it-alls. */
    ei_status.stop_page = ei_status.tx_start_page + PACKETBUF_MEMSIZE;
#endif

    ei_status.reset_8390 = &ne_reset_8390;
    ei_status.block_input = &ne_block_input;
    ei_status.block_output = &ne_block_output;
    NS8390_init(dev, 0);
    return dev->base_addr;
}

/* Hard reset the card.  This used to pause for the same period that a
   8390 reset command required, but that shouldn't be necessary. */
static void
ne_reset_8390(struct device *dev)
{
    int tmp = inb_p(NE_BASE + NE_RESET);
    int reset_start_time = jiffies;

    if (ei_debug > 1) printk("resetting the 8390 t=%ld...", jiffies);
    ei_status.txing = 0;

    outb_p(tmp, NE_BASE + NE_RESET);
    /* This check _should_not_ be necessary, omit eventually. */
    while ((inb_p(NE_BASE+EN0_ISR) & ENISR_RESET) == 0)
	if (jiffies - reset_start_time > 2) {
	    printk("%s: ne_reset_8390() did not complete.\n", dev->name);
	    break;
	}
}

/* Block input and output, similar to the Crynwr packet driver.  If you
   porting to a new ethercard look at the packet driver source for hints.
   The NEx000 doesn't share it on-board packet memory -- you have to put
   the packet out through the "remote DMA" dataport using outb. */

static int
ne_block_input(struct device *dev, int count, char *buf, int ring_offset)
{
    int xfer_count = count;
    int nic_base = dev->base_addr;

    if (ei_status.dmaing) {
	if (ei_debug > 0)
	    printk("%s: DMAing conflict in ne_block_input."
		   "[DMAstat:%1x][irqlock:%1x]\n",
		   dev->name, ei_status.dmaing, ei_status.irqlock);
	return 0;
    }
    ei_status.dmaing |= 0x01;
    outb_p(E8390_NODMA+E8390_PAGE0+E8390_START, nic_base+ NE_CMD);
    outb_p(count & 0xff, nic_base + EN0_RCNTLO);
    outb_p(count >> 8, nic_base + EN0_RCNTHI);
    outb_p(ring_offset & 0xff, nic_base + EN0_RSARLO);
    outb_p(ring_offset >> 8, nic_base + EN0_RSARHI);
    outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
    if (ei_status.word16) {
      insw(NE_BASE + NE_DATAPORT,buf,count>>1);
      if (count & 0x01)
	buf[count-1] = inb(NE_BASE + NE_DATAPORT), xfer_count++;
    } else {
	insb(NE_BASE + NE_DATAPORT, buf, count);
    }

    /* This was for the ALPHA version only, but enough people have
       encountering problems that it is still here.  If you see
       this message you either 1) have an slightly imcompatible clone
       or 2) have noise/speed problems with your bus. */
    if (ei_debug > 1) {		/* DMA termination address check... */
	int addr, tries = 20;
	do {
	    /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here
	       -- it's broken! Check the "DMA" address instead. */
	    int high = inb_p(nic_base + EN0_RSARHI);
	    int low = inb_p(nic_base + EN0_RSARLO);
	    addr = (high << 8) + low;
	    if (((ring_offset + xfer_count) & 0xff) == low)
		break;
	} while (--tries > 0);
	if (tries <= 0)
	    printk("%s: RX transfer address mismatch,"
		   "%#4.4x (expected) vs. %#4.4x (actual).\n",
		   dev->name, ring_offset + xfer_count, addr);
    }
    ei_status.dmaing &= ~0x01;
    return ring_offset + count;
}

static void
ne_block_output(struct device *dev, int count,
		const unsigned char *buf, const int start_page)
{
    int retries = 0;
    int nic_base = NE_BASE;

    /* Round the count up for word writes.  Do we need to do this?
       What effect will an odd byte count have on the 8390?
       I should check someday. */
    if (ei_status.word16 && (count & 0x01))
      count++;
    if (ei_status.dmaing) {
	if (ei_debug > 0)
	    printk("%s: DMAing conflict in ne_block_output."
		   "[DMAstat:%1x][irqlock:%1x]\n",
		   dev->name, ei_status.dmaing, ei_status.irqlock);
	return;
    }
    ei_status.dmaing |= 0x02;
    /* We should already be in page 0, but to be safe... */
    outb_p(E8390_PAGE0+E8390_START+E8390_NODMA, nic_base + NE_CMD);

 retry:
#if defined(rw_bugfix)
    /* Handle the read-before-write bug the same way as the
       Crynwr packet driver -- the NatSemi method doesn't work.
       Actually this doesn't aways work either, but if you have
       problems with your NEx000 this is better than nothing! */
    outb_p(0x42, nic_base + EN0_RCNTLO);
    outb_p(0x00,   nic_base + EN0_RCNTHI);
    outb_p(0x42, nic_base + EN0_RSARLO);
    outb_p(0x00, nic_base + EN0_RSARHI);
    outb_p(E8390_RREAD+E8390_START, nic_base + NE_CMD);
    /* Make certain that the dummy read has occured. */
    SLOW_DOWN_IO;
    SLOW_DOWN_IO;
    SLOW_DOWN_IO;
#endif  /* rw_bugfix */

    /* Now the normal output. */
    outb_p(count & 0xff, nic_base + EN0_RCNTLO);
    outb_p(count >> 8,   nic_base + EN0_RCNTHI);
    outb_p(0x00, nic_base + EN0_RSARLO);
    outb_p(start_page, nic_base + EN0_RSARHI);

    outb_p(E8390_RWRITE+E8390_START, nic_base + NE_CMD);
    if (ei_status.word16) {
	outsw(NE_BASE + NE_DATAPORT, buf, count>>1);
    } else {
	outsb(NE_BASE + NE_DATAPORT, buf, count);
    }

    /* This was for the ALPHA version only, but enough people have
       encountering problems that it is still here. */
    if (ei_debug > 1) {		/* DMA termination address check... */
	int addr, tries = 20;
	do {
	    /* DON'T check for 'inb_p(EN0_ISR) & ENISR_RDC' here
	       -- it's broken! Check the "DMA" address instead. */
	    int high = inb_p(nic_base + EN0_RSARHI);
	    int low = inb_p(nic_base + EN0_RSARLO);
	    addr = (high << 8) + low;
	    if ((start_page << 8) + count == addr)
		break;
	} while (--tries > 0);
	if (tries <= 0) {
	    printk("%s: Tx packet transfer address mismatch,"
		   "%#4.4x (expected) vs. %#4.4x (actual).\n",
		   dev->name, (start_page << 8) + count, addr);
	    if (retries++ == 0)
		goto retry;
	}
    }
    ei_status.dmaing &= ~0x02;
    return;
}


/*
 * Local variables:
 *  compile-command: "gcc -DKERNEL -Wall -O6 -fomit-frame-pointer -I/usr/src/linux/net/tcp -c ne.c"
 *  version-control: t
 *  kept-new-versions: 5
 * End:
 */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
激情文学综合丁香| 日韩国产一二三区| 久久精品国产亚洲高清剧情介绍 | 国产精品自拍一区| 欧美羞羞免费网站| 国产精品美女久久福利网站| 麻豆精品在线视频| 欧美性大战久久久| 亚洲特级片在线| 国产精品羞羞答答xxdd| 制服丝袜亚洲色图| 一级日本不卡的影视| 成人av电影免费在线播放| 精品成人一区二区| 日本欧美在线看| 欧美天堂亚洲电影院在线播放 | 在线观看中文字幕不卡| 中文字幕免费不卡| 久久99精品国产麻豆婷婷| 欧美色图12p| 亚洲精品久久嫩草网站秘色| 成人免费av资源| 国产日韩欧美亚洲| 久久99国产精品免费网站| 欧美男同性恋视频网站| 亚洲另类春色国产| 99麻豆久久久国产精品免费优播| 久久精品视频免费| 狠狠色丁香久久婷婷综合_中| 7777精品伊人久久久大香线蕉| 一区二区三区在线免费视频| 99视频在线精品| 国产精品久久久久影视| 成人一区二区三区视频在线观看| 久久综合九色综合久久久精品综合 | 色婷婷av久久久久久久| 国产精品福利电影一区二区三区四区| 国产一区二区三区免费观看| 日韩欧美123| 免费在线观看一区| 日韩女优电影在线观看| 另类小说一区二区三区| 精品少妇一区二区三区视频免付费| 日韩成人一级片| 日韩三级视频在线看| 免费在线观看一区二区三区| 日韩网站在线看片你懂的| 日本三级亚洲精品| 亚洲一区二区在线免费看| 欧美在线999| 五月天一区二区| 日韩欧美一级精品久久| 久久99国产精品久久99果冻传媒| 精品国产青草久久久久福利| 狠狠久久亚洲欧美| 久久精品一二三| 成人丝袜高跟foot| 综合激情网...| 欧美伊人精品成人久久综合97| 亚洲成人先锋电影| 日韩欧美国产电影| 国产精品资源网站| 国产精品动漫网站| 色屁屁一区二区| 天使萌一区二区三区免费观看| 日韩一二三四区| 狠狠狠色丁香婷婷综合久久五月| 国产午夜精品一区二区三区四区| 成人不卡免费av| 一区二区高清在线| 日韩欧美亚洲另类制服综合在线| 韩国欧美国产一区| 国产精品久久久久永久免费观看| 91蝌蚪国产九色| 午夜视频在线观看一区| 精品乱人伦小说| 成人综合婷婷国产精品久久蜜臀 | 欧美电影免费观看高清完整版在线观看 | 91精品欧美综合在线观看最新 | 中文在线免费一区三区高中清不卡| 成人黄色免费短视频| 亚洲一区二区三区国产| 日韩欧美一区二区三区在线| 国产精品一二三| 一区二区三区四区高清精品免费观看| 69成人精品免费视频| 国产一区二区精品久久| 自拍偷拍欧美激情| 欧美日本一道本| 国产精品99久| 一区二区三区日韩欧美| 日韩久久免费av| 成人福利视频在线看| 婷婷国产在线综合| 中文久久乱码一区二区| 欧美日韩国产精品成人| 丰满少妇久久久久久久| 亚洲成人av电影在线| 国产人成一区二区三区影院| 91成人在线免费观看| 国产一区二区三区综合| 一区二区三区电影在线播| 日韩精品欧美成人高清一区二区| 久久久久久麻豆| 日本电影亚洲天堂一区| 美日韩一区二区| 亚洲男帅同性gay1069| 欧美成va人片在线观看| 色综合天天综合狠狠| 激情久久五月天| 一区二区三区日本| 久久久久久日产精品| 欧美人牲a欧美精品| www.性欧美| 国内外精品视频| 亚洲国产精品麻豆| 中文无字幕一区二区三区| 欧美精品v国产精品v日韩精品 | 日本不卡一二三| 亚洲人亚洲人成电影网站色| 欧美精品一区二区三区久久久 | 国产盗摄精品一区二区三区在线| 午夜伦理一区二区| 中文字幕一区二区三区精华液| 精品久久久久久综合日本欧美| 91精品1区2区| 99r国产精品| 国产精品伊人色| 美国一区二区三区在线播放| 亚洲一区二区成人在线观看| 国产精品污网站| 久久久久久一二三区| 日韩一区二区在线看| 欧美三区免费完整视频在线观看| 丁香婷婷综合色啪| 国产一区二区三区精品欧美日韩一区二区三区| 一区二区三区四区在线免费观看 | 91精品国产综合久久久久| 91污在线观看| 成人小视频在线观看| 狠狠色2019综合网| 久久精品国产一区二区三 | 综合欧美一区二区三区| 欧美韩日一区二区三区| 久久亚洲综合色| 欧美电影免费观看高清完整版 | 国产成人在线视频网站| 久久99精品视频| 日本va欧美va欧美va精品| 偷偷要91色婷婷| 五月婷婷另类国产| 午夜日韩在线电影| 日韩在线a电影| 天堂精品中文字幕在线| 五月天中文字幕一区二区| 亚洲国产日韩在线一区模特| 亚洲影院久久精品| 亚洲一二三区视频在线观看| 亚洲精品视频免费看| 亚洲精品国产精华液| 亚洲资源在线观看| 亚洲亚洲精品在线观看| 香蕉加勒比综合久久| 午夜视频在线观看一区| 日本伊人午夜精品| 捆绑调教美女网站视频一区| 久久99国产精品久久99果冻传媒| 久久99精品国产.久久久久久| 国内精品免费在线观看| 国产在线观看一区二区| 国产成人夜色高潮福利影视| 国产精品77777竹菊影视小说| 国产成人综合自拍| 成人免费av网站| 色欲综合视频天天天| 欧美视频你懂的| 欧美一级爆毛片| 久久众筹精品私拍模特| 国产欧美日韩不卡| 综合久久久久久| 亚洲在线视频网站| 日本vs亚洲vs韩国一区三区 | 亚洲一二三区不卡| 日韩中文字幕亚洲一区二区va在线| 日本成人在线电影网| 久久国产精品72免费观看| 国产成人在线免费观看| 91免费看`日韩一区二区| 欧美色网一区二区| 日韩精品一区二区三区在线| 国产情人综合久久777777| 亚洲欧美在线高清| 午夜欧美在线一二页| 久久99国内精品| bt欧美亚洲午夜电影天堂| 日本二三区不卡| 精品乱人伦一区二区三区| 中文字幕在线不卡一区二区三区| 亚洲一区二区三区四区在线观看| 人人精品人人爱|