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

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

?? 3c503.c

?? LINUX1.0源代碼,代碼條理清晰
?? C
字號:
/* 3c503.c: A 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 the 3c503 and 3c503/16.  It should be used
    in shared memory mode for best performance, although it may also work
    in programmed-I/O mode.

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

static char *version =
    "3c503.c:v0.99.15k 3/3/93 Donald Becker (becker@super.org)\n";

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

#include "dev.h"

#include "8390.h"
#include "3c503.h"

int el2_probe(struct device *dev);
int el2_pio_autoprobe(struct device *dev);
int el2probe1(int ioaddr, struct device *dev);

static int el2_open(struct device *dev);
static int el2_close(struct device *dev);
static void el2_reset_8390(struct device *dev);
static void el2_init_card(struct device *dev);
static void el2_block_output(struct device *dev, int count,
			     const unsigned char *buf, const start_page);
static int el2_block_input(struct device *dev, int count, char *buf,
			   int ring_offset);


/* This routine probes for a memory-mapped 3c503 board by looking for
   the "location register" at the end of the jumpered boot PROM space.
   This works even if a PROM isn't there.

   If the ethercard isn't found there is an optional probe for
   ethercard jumpered to programmed-I/O mode.
   */

static int ports[] = {0x300,0x310,0x330,0x350,0x250,0x280,0x2a0,0x2e0,0};

int
el2_probe(struct device *dev)
{
    int *addr, addrs[] = { 0xddffe, 0xd9ffe, 0xcdffe, 0xc9ffe, 0};
    short ioaddr = dev->base_addr;

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

    for (addr = addrs; *addr; addr++) {
	int i;
	unsigned int base_bits = *(unsigned char *)*addr;
	/* Find first set bit. */
	for(i = 7; i >= 0; i--, base_bits >>= 1)
	    if (base_bits & 0x1)
		break;
	if (base_bits != 1)
	    continue;
#ifdef HAVE_PORTRESERVE
	if (check_region(ports[i], 16))
	    continue;
#endif
	if (el2probe1(ports[i], dev))
	    return 0;
    }
#ifndef no_probe_nonshared_memory
    return el2_pio_autoprobe(dev);
#else
    return ENODEV;
#endif
}

/*  Try all of the locations that aren't obviously empty.  This touches
    a lot of locations, and is much riskier than the code above. */
int
el2_pio_autoprobe(struct device *dev)
{
    int i;
    for (i = 0; i < 8; i++) {
#ifdef HAVE_PORTRESERVE
	if (check_region(ports[i], 16))
	    continue;
#endif
	/* Reset and/or avoid any lurking NE2000 */
	if (inb_p(ports[i] + 0x408) == 0xff)
	    continue;
	if (inb(ports[i] + 0x403) == (0x80 >> i) /* Preliminary check */
	    && el2probe1(ports[i], dev))
	    return 0;
    }
    return ENODEV;
}

/* Probe for the Etherlink II card at I/O port base IOADDR,
   returning non-zero on sucess.  If found, set the station
   address and memory parameters in DEVICE. */
int
el2probe1(int ioaddr, struct device *dev)
{
    int i, iobase_reg, membase_reg, saved_406;
    unsigned char *station_addr = dev->dev_addr;

    /* We verify that it's a 3C503 board by checking the first three octets
       of its ethernet address. */
    printk("3c503 probe at %#3x:", ioaddr);
    iobase_reg = inb(ioaddr+0x403);
    membase_reg = inb(ioaddr+0x404);
    /* Verify ASIC register that should be 0 or have a single bit set. */
    if (   (iobase_reg  & (iobase_reg - 1))
	|| (membase_reg & (membase_reg - 1))) {
	printk("  not found.\n");
	return 0;
    }
    saved_406 = inb_p(ioaddr + 0x406);
    outb_p(ECNTRL_RESET|ECNTRL_THIN, ioaddr + 0x406); /* Reset it... */
    outb_p(ECNTRL_THIN, ioaddr + 0x406);
    /* Map the station addr PROM into the lower I/O ports. */
    outb(ECNTRL_SAPROM|ECNTRL_THIN, ioaddr + 0x406);
    for (i = 0; i < ETHER_ADDR_LEN; i++) {
	printk(" %2.2X", (station_addr[i] = inb(ioaddr + i)));
    }
    if ( station_addr[0] != 0x02
	|| station_addr[1] != 0x60
	|| station_addr[2] != 0x8c) {
	printk("  3C503 not found.\n");
	/* Restore the register we frobbed. */
	outb(saved_406, ioaddr + 0x406);
	return 0;
    }

#ifdef HAVE_PORTRESERVE
    snarf_region(ioaddr, 16);
#endif
    ethdev_init(dev);

    /* Map the 8390 back into the window. */
    outb(ECNTRL_THIN, ioaddr + 0x406);
    dev->base_addr = ioaddr;
    /* Probe for, turn on and clear the board's shared memory. */
    if (ei_debug > 2) printk(" memory jumpers %2.2x ", membase_reg);
    outb(EGACFR_NORM, ioaddr + 0x405);	/* Enable RAM */

    /* This should be probed for (or set via an ioctl()) at run-time.
       Right now we use a sleazy hack to pass in the interface number
       at boot-time via the low bits of the mem_end field.  That value is
       unused, and the low bits would be discarded even if it was used. */
#if defined(EI8390_THICK) || defined(EL2_AUI)
    ei_status.interface_num = 1;
#else
    ei_status.interface_num = dev->mem_end & 0xf;
#endif

    if ((membase_reg & 0xf0) == 0) {
	dev->mem_start = 0;
    } else {
	dev->mem_start = ((membase_reg & 0xc0) ? 0xD8000 : 0xC8000) +
	    ((membase_reg & 0xA0) ? 0x4000 : 0);

#define EL2_MEMSIZE (EL2SM_STOP_PG - EL2SM_START_PG)*256
#ifdef EL2MEMTEST
	/* This has never found an error, but someone might care. */
	{			/* Check the card's memory. */
	    int *mem_base = (int *)dev->mem_start;
	    int memtest_value = 0xbbadf00d;
	    mem_base[0] = 0xba5eba5e;
	    for (i = 1; i < EL2_MEMSIZE/sizeof(mem_base[0]); i++) {
		mem_base[i] = memtest_value;
		if (mem_base[0] != 0xba5eba5e
		    || mem_base[i] != memtest_value) {
		    printk(" memory failure or memory address conflict.\n");
		    dev->mem_start = 0;
		    break;
		}
		memtest_value += 0x55555555;
		mem_base[i] = 0;
	    }
	}
#endif  /* EL2MEMTEST */
	/* Divide the on-board memory into a single maximum-sized transmit
	   (double-sized for ping-pong transmit) buffer at the base, and
	   use the rest as a receive ring. */
	dev->mem_end = dev->rmem_end = dev->mem_start + EL2_MEMSIZE;
	dev->rmem_start = TX_PAGES*256 + dev->mem_start;
    }

    /* Finish setting the board's parameters. */
    ei_status.name = "3C503";
    ei_status.tx_start_page = EL2SM_START_PG;
    ei_status.rx_start_page = EL2SM_START_PG + TX_PAGES;
    ei_status.stop_page = EL2SM_STOP_PG;
    ei_status.reset_8390 = &el2_reset_8390;
    ei_status.block_input = &el2_block_input;
    ei_status.block_output = &el2_block_output;

    if (dev->irq == 2)
	dev->irq = 9;
    else if (dev->irq > 5 && dev->irq != 9) {
	printk("\n3c503: configured interrupt %d invalid, using autoIRQ.\n",
	       dev->irq);
	dev->irq = 0;
    }

    ei_status.saved_irq = dev->irq;

    dev->start = 0;
    dev->open = &el2_open;
    dev->stop = &el2_close;

    if (dev->mem_start)
	printk("\n%s: %s with shared memory at %#6lx-%#6lx,\n",
	       dev->name, ei_status.name, dev->mem_start, dev->mem_end-1);
    else
	printk("\n%s: %s using programmed I/O (REJUMPER for SHARED MEMORY).\n",
	       dev->name, ei_status.name);
    if (ei_debug > 1)
	printk(version);

    return ioaddr;
}

static int
el2_open(struct device *dev)
{

    if (dev->irq < 2) {
	int irqlist[] = {5, 9, 3, 4, 0};
	int *irqp = irqlist;

	outb(EGACFR_NORM, E33G_GACFR);	/* Enable RAM and interrupts. */
	do {
	    if (request_irq (*irqp, NULL) != -EBUSY) {
		/* Twinkle the interrupt, and check if it's seen. */
		autoirq_setup(0);
		outb_p(0x04 << ((*irqp == 9) ? 2 : *irqp), E33G_IDCFR);
		outb_p(0x00, E33G_IDCFR);
		if (*irqp == autoirq_report(0)	 /* It's a good IRQ line! */
		    && request_irq (dev->irq = *irqp, &ei_interrupt) == 0)
		    break;
	    }
	} while (*++irqp);
	if (*irqp == 0) {
	    outb(EGACFR_IRQOFF, E33G_GACFR);	/* disable interrupts. */
	    return -EAGAIN;
	}
    } else {
	if (request_irq(dev->irq, &ei_interrupt)) {
	    return -EAGAIN;
	}
    }
    el2_init_card(dev);
    return ei_open(dev);
}

static int
el2_close(struct device *dev)
{
    free_irq(dev->irq);
    dev->irq = ei_status.saved_irq;
    irq2dev_map[dev->irq] = NULL;
    outb(EGACFR_IRQOFF, E33G_GACFR);	/* disable interrupts. */

    NS8390_init(dev, 0);

    return 0;
}

/* This is called whenever we have a unrecoverable failure:
       transmit timeout
       Bad ring buffer packet header
 */
static void
el2_reset_8390(struct device *dev)
{
    if (ei_debug > 1) {
	printk("%s: Resetting the 3c503 board...", dev->name);
	printk("%#x=%#02x %#x=%#02x %#x=%#02x...", E33G_IDCFR, inb(E33G_IDCFR),
	       E33G_CNTRL, inb(E33G_CNTRL), E33G_GACFR, inb(E33G_GACFR));
    }
    outb_p(ECNTRL_RESET|ECNTRL_THIN, E33G_CNTRL);
    ei_status.txing = 0;
    outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
    el2_init_card(dev);
    if (ei_debug > 1) printk("done\n");
}

/* Initialize the 3c503 GA registers after a reset. */
static void
el2_init_card(struct device *dev)
{
    /* Unmap the station PROM and select the DIX or BNC connector. */
    outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);

    /* Set ASIC copy of rx's first and last+1 buffer pages */
    /* These must be the same as in the 8390. */
    outb(ei_status.rx_start_page, E33G_STARTPG);
    outb(ei_status.stop_page,  E33G_STOPPG);

    /* Point the vector pointer registers somewhere ?harmless?. */
    outb(0xff, E33G_VP2);	/* Point at the ROM restart location 0xffff0 */
    outb(0xff, E33G_VP1);
    outb(0x00, E33G_VP0);
    /* Turn off all interrupts until we're opened. */
    outb_p(0x00,  dev->base_addr + EN0_IMR);
    /* Enable IRQs iff started. */
    outb(EGACFR_NORM, E33G_GACFR);

    /* Set the interrupt line. */
    outb_p((0x04 << (dev->irq == 9 ? 2 : dev->irq)), E33G_IDCFR);
    outb_p(8, E33G_DRQCNT);		/* Set burst size to 8 */
    outb_p(0x20, E33G_DMAAH);	/* Put a valid addr in the GA DMA */
    outb_p(0x00, E33G_DMAAL);
    return;			/* We always succeed */
}

/* Either use the shared memory (if enabled on the board) or put the packet
   out through the ASIC FIFO.  The latter is probably much slower. */
static void
el2_block_output(struct device *dev, int count,
		 const unsigned char *buf, const start_page)
{
    int i;				/* Buffer index */
    int boguscount = 0;		/* timeout counter */

    /* This should really be set with during an open(). */
    outb(EGACFR_NORM, E33G_GACFR);	/* Enable RAM and interrupts. */

    if (dev->mem_start) {	/* Shared memory transfer */
	void *dest_addr = (void *)(dev->mem_start +
	    ((start_page - ei_status.tx_start_page) << 8));
	memcpy(dest_addr, buf, count);
	if (ei_debug > 2  &&  memcmp(dest_addr, buf, count))
	    printk("%s: 3c503 send_packet() bad memory copy @ %#5x.\n",
		   dev->name, (int) dest_addr);
	return;
    }
    /* No shared memory, put the packet out the slow way. */
    /* Set up then start the internal memory transfer to Tx Start Page */
    outb(0x00, E33G_DMAAL);
    outb_p(start_page, E33G_DMAAH);
    outb_p((ei_status.interface_num ? ECNTRL_AUI : ECNTRL_THIN ) | ECNTRL_OUTPUT
	   | ECNTRL_START, E33G_CNTRL);

    /* This is the byte copy loop: it should probably be tuned for
       for speed once everything is working.  I think it is possible
       to output 8 bytes between each check of the status bit. */
    for(i = 0; i < count; i++) {
	if (i % 8 == 0)
	    while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
		if (++boguscount > (i<<3) + 32) {
		    printk("%s: FIFO blocked in el2_block_output (at %d of %d, bc=%d).\n",
			   dev->name, i, count, boguscount);
		    return;
		}
	outb(buf[i], E33G_FIFOH);
    }
    outb_p(ei_status.interface_num==0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
    return;
}

/* Returns the new ring pointer. */
static int
el2_block_input(struct device *dev, int count, char *buf, int ring_offset)
{
    int boguscount = 0;
    int end_of_ring = dev->rmem_end;
    unsigned int i;

    /* Maybe enable shared memory just be to be safe... nahh.*/
    if (dev->mem_start) {	/* Use the shared memory. */
	ring_offset -= (EL2SM_START_PG<<8);
	if (dev->mem_start + ring_offset + count > end_of_ring) {
	    /* We must wrap the input move. */
	    int semi_count = end_of_ring - (dev->mem_start + ring_offset);
	    memcpy(buf, (char *)dev->mem_start + ring_offset, semi_count);
	    count -= semi_count;
	    memcpy(buf + semi_count, (char *)dev->rmem_start, count);
	    return dev->rmem_start + count;
	}
	memcpy(buf, (char *)dev->mem_start + ring_offset, count);
	return ring_offset + count;
    }
    /* No shared memory, use programmed I/O. */
    outb(ring_offset & 0xff, E33G_DMAAL);
    outb_p((ring_offset >> 8) & 0xff, E33G_DMAAH);
    outb_p((ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI) | ECNTRL_INPUT
	   | ECNTRL_START, E33G_CNTRL);

    /* This is the byte copy loop: it should probably be tuned for
       for speed once everything is working. */
    for(i = 0; i < count; i++) {
	if (i % 8 == 0)
	    while ((inb(E33G_STATUS) & ESTAT_DPRDY) == 0)
		if (++boguscount > (i<<3) + 32) {
		    printk("%s: FIFO blocked in el2_block_input() (at %d of %d, bc=%d).\n",
			   dev->name, i, count, boguscount);
		    boguscount = 0;
		    break;
		}
	buf[i] = inb_p(E33G_FIFOH);
    }
    outb_p(ei_status.interface_num == 0 ? ECNTRL_THIN : ECNTRL_AUI, E33G_CNTRL);
    return 0;
}

/*
 * Local variables:
 *  version-control: t
 *  kept-new-versions: 5
 * End:
 */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
免费一区二区视频| 欧美精品一区二区三区视频 | 国产三级一区二区| 国产精品美女久久久久久| 亚洲蜜臀av乱码久久精品| 天天综合色天天综合| 国产麻豆视频一区| 在线中文字幕不卡| 精品乱人伦小说| 亚洲欧美激情在线| 国内精品不卡在线| 在线视频欧美区| 久久夜色精品国产噜噜av| 亚洲欧美日韩国产一区二区三区| 日本aⅴ免费视频一区二区三区| 国产成人午夜精品5599| 欧美日韩中文字幕一区二区| 久久久久高清精品| 亚洲国产综合在线| 国产成人在线影院| 欧美精品色一区二区三区| 国产日韩欧美激情| 日本伊人色综合网| 91在线视频网址| 日韩欧美在线综合网| 亚洲欧美偷拍卡通变态| 国产在线播放一区二区三区| 欧美在线观看一区| 国产精品三级电影| 麻豆精品一区二区av白丝在线| 99久久婷婷国产综合精品电影 | 蜜臀91精品一区二区三区 | 日韩伦理av电影| 久久精品国产久精国产爱| 色婷婷精品久久二区二区蜜臀av| 欧美xxxx老人做受| 日日嗨av一区二区三区四区| 色综合久久99| 欧美高清在线一区二区| 老司机精品视频导航| 欧美丝袜自拍制服另类| 国产精品传媒视频| 国产成人啪免费观看软件 | 久久99精品久久久久久动态图 | 亚洲欧美日韩国产另类专区| 国产白丝精品91爽爽久久| 欧美成人国产一区二区| 日韩和欧美一区二区三区| 色综合久久99| 国产精品国产自产拍高清av王其| 韩国欧美一区二区| 日韩一区二区精品在线观看| 亚洲图片欧美综合| 欧美性做爰猛烈叫床潮| 亚洲欧美国产77777| www.日本不卡| 国产精品乱码妇女bbbb| 国产精品一区二区久久精品爱涩| 欧美一级日韩不卡播放免费| 亚洲成av人影院| 欧美亚洲免费在线一区| 一区二区三区久久| 色噜噜偷拍精品综合在线| 国产精品国产三级国产| av网站免费线看精品| 中文在线免费一区三区高中清不卡| 韩国av一区二区| 久久久久久一级片| 国产精品羞羞答答xxdd| 久久综合色播五月| 国产乱人伦偷精品视频不卡| ww久久中文字幕| 国产精品资源站在线| 久久久精品黄色| 国产高清不卡二三区| 欧美激情一区二区在线| 国产v日产∨综合v精品视频| 国产精品午夜电影| 91亚洲精品乱码久久久久久蜜桃 | 99久久国产综合精品色伊| 国产精品久久国产精麻豆99网站| 成人app在线| 亚洲免费在线播放| 精品视频999| 日韩av高清在线观看| 日韩欧美亚洲国产另类 | 国产精品麻豆欧美日韩ww| 99久久综合色| 一区二区三区在线免费| 欧美丝袜丝nylons| 免费在线观看精品| 久久蜜臀精品av| proumb性欧美在线观看| 一区二区三区产品免费精品久久75| 欧美综合视频在线观看| 日韩经典中文字幕一区| 日韩一区二区在线观看视频播放| 精品无码三级在线观看视频| 国产欧美一区二区精品仙草咪| av一区二区久久| 五月天亚洲婷婷| 久久这里都是精品| 99精品久久只有精品| 亚洲成在线观看| 久久综合色播五月| 91麻豆成人久久精品二区三区| 亚洲国产三级在线| 精品少妇一区二区三区在线播放| 成人精品鲁一区一区二区| 亚洲资源在线观看| 日韩免费福利电影在线观看| 成人sese在线| 亚洲成年人影院| 国产日韩欧美精品一区| 欧美日韩精品一区二区三区蜜桃| 免费一级片91| 亚洲国产精品成人久久综合一区| 欧美日韩一区国产| 国产精品亚洲一区二区三区妖精 | 欧美精品v国产精品v日韩精品| 精品亚洲国产成人av制服丝袜| 亚洲日本乱码在线观看| 日韩欧美第一区| 99久精品国产| 另类小说色综合网站| 国产精品二三区| 91麻豆精品国产综合久久久久久| 国产丶欧美丶日本不卡视频| 亚洲国产综合在线| 国产欧美日韩在线| 欧美日本国产视频| av激情综合网| 久久精品国产精品亚洲红杏| 一区二区三区四区不卡在线 | 久久99精品国产.久久久久久| 亚洲天天做日日做天天谢日日欢| 日韩三级免费观看| 色综合中文字幕国产| 麻豆成人在线观看| 亚洲精品视频自拍| 国产欧美日韩不卡免费| 欧美一级二级在线观看| 日本精品一区二区三区四区的功能| 精品一区二区三区免费视频| 亚洲尤物在线视频观看| 国产精品欧美经典| 日韩精品一区二区三区四区| 91久久香蕉国产日韩欧美9色| 国产高清精品久久久久| 毛片av一区二区三区| 亚洲一区二区成人在线观看| 国产精品久久久久久久久免费相片 | 精品国产一区二区精华| 欧美日韩中文国产| 91亚洲精品久久久蜜桃| 成人午夜视频网站| 国产制服丝袜一区| 琪琪久久久久日韩精品| 一二三四区精品视频| 国产精品伦理一区二区| 国产性色一区二区| 日韩精品一区二区三区中文精品| 欧美日韩国产美| 91搞黄在线观看| jlzzjlzz亚洲日本少妇| 懂色av一区二区三区免费看| 黄色日韩三级电影| 美国毛片一区二区| 青青草一区二区三区| 午夜精品国产更新| 亚洲国产成人av网| 亚洲高清免费视频| 亚洲一区二区三区美女| 夜夜嗨av一区二区三区| 亚洲日本中文字幕区| 中文字幕亚洲成人| 国产精品伦理在线| 亚洲欧美在线aaa| 中文字幕永久在线不卡| 国产精品无人区| 亚洲视频免费在线| 亚洲人成精品久久久久| 亚洲人成网站影音先锋播放| 亚洲日本在线a| 亚洲一区在线看| 亚洲国产日韩综合久久精品| 午夜影视日本亚洲欧洲精品| 亚洲国产成人av| 日韩精品三区四区| 麻豆精品在线播放| 国产精品一区久久久久| 成人视屏免费看| 99久久er热在这里只有精品15 | 亚洲综合区在线| 亚洲高清在线精品| 日本va欧美va精品发布| 加勒比av一区二区| 国产999精品久久久久久| 成人黄色在线看| 91丨porny丨国产|