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

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

?? skeleton.c

?? LINUX1.0源代碼,代碼條理清晰
?? C
字號:
/* skeleton.c: A sample network driver core for linux. */
/*
	Written 1993 by Donald Becker.
	Copyright 1993 United States Government as represented by the Director,
	National Security Agency.  This software may only be used and distributed
	according to the terms of the GNU Public License as modified by SRC,
	incorporated herein by reference.

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

	This file is an outline for writing a network device driver for the
	the Linux operating system.

	To write (or understand) a driver, have a look at the "loopback.c" file to
	get a feel of what is going on, and then use the code below as a skeleton
	for the new driver.

*/

static char *version =
	"skeleton.c:v0.05 11/16/93 Donald Becker (becker@super.org)\n";

/* Always include 'config.h' first in case the user wants to turn on
   or override something. */
#include <linux/config.h>

/*
  Sources:
	List your sources of programming information to document that
	the driver is your own creation, and give due credit to others
	that contributed to the work.  Remember that GNU project code
	cannot use proprietary or trade secret information.	 Interface
	definitions are generally considered non-copyrightable to the
	extent that the same names and structures must be used to be
	compatible.

	Finally, keep in mind that the Linux kernel is has an API, not
	ABI.  Proprietary object-code-only distributions are not permitted
	under the GPL.
*/

#include <linux/kernel.h>
#include <linux/sched.h>
#include <linux/types.h>
#include <linux/fcntl.h>
#include <linux/interrupt.h>
#include <linux/ptrace.h>
#include <linux/ioport.h>
#include <linux/in.h>
#include <linux/malloc.h>
#include <linux/string.h>
#include <asm/system.h>
#include <asm/bitops.h>
#include <asm/io.h>
#include <asm/dma.h>
#include <errno.h>

#include "dev.h"
#include "eth.h"
#include "skbuff.h"
#include "arp.h"

#ifndef HAVE_AUTOIRQ
/* From auto_irq.c, in ioport.h for later versions. */
extern void autoirq_setup(int waittime);
extern int autoirq_report(int waittime);
/* The map from IRQ number (as passed to the interrupt handler) to
   'struct device'. */
extern struct device *irq2dev_map[16];
#endif

#ifndef HAVE_ALLOC_SKB
#define alloc_skb(size, priority) (struct sk_buff *) kmalloc(size,priority)
#define kfree_skbmem(addr, size) kfree_s(addr,size);
#endif

#ifndef HAVE_PORTRESERVE
#define check_region(ioaddr, size) 		0
#define	snarf_region(ioaddr, size);		do ; while (0)
#endif

/* use 0 for production, 1 for verification, >2 for debug */
#ifndef NET_DEBUG
#define NET_DEBUG 2
#endif
static unsigned int net_debug = NET_DEBUG;

/* Information that need to be kept for each board. */
struct net_local {
	struct enet_statistics stats;
	long open_time;				/* Useless example local info. */
};

/* The number of low I/O ports used by the ethercard. */
#define ETHERCARD_TOTAL_SIZE	16

/* The station (ethernet) address prefix, used for IDing the board. */
#define SA_ADDR0 0x00
#define SA_ADDR1 0x42
#define SA_ADDR2 0x65

/* Index to functions, as function prototypes. */

extern int netcard_probe(struct device *dev);

static int netcard_probe1(struct device *dev, short ioaddr);
static int net_open(struct device *dev);
static int	net_send_packet(struct sk_buff *skb, struct device *dev);
static void net_interrupt(int reg_ptr);
static void net_rx(struct device *dev);
static int net_close(struct device *dev);
static struct enet_statistics *net_get_stats(struct device *dev);
#ifdef HAVE_MULTICAST
static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
#endif

/* Example routines you must write ;->. */
#define tx_done(dev) 1
extern void	hardware_send_packet(short ioaddr, char *buf, int length);
extern void chipset_init(struct device *dev, int startp);


/* Check for a network adaptor of this type, and return '0' iff one exists.
   If dev->base_addr == 0, probe all likely locations.
   If dev->base_addr == 1, always return failure.
   If dev->base_addr == 2, alloate space for the device and return success
   (detachable devices only).
   */
int
netcard_probe(struct device *dev)
{
	int *port, ports[] = {0x300, 0x280, 0};
	int base_addr = dev->base_addr;

	if (base_addr > 0x1ff)		/* Check a single specified location. */
		return netcard_probe1(dev, base_addr);
	else if (base_addr > 0)		/* Don't probe at all. */
		return ENXIO;

	for (port = &ports[0]; *port; port++) {
		int ioaddr = *port;
		if (check_region(ioaddr, ETHERCARD_TOTAL_SIZE))
			continue;
		if (inb(ioaddr) != 0x57)
			continue;
		dev->base_addr = ioaddr;
		if (netcard_probe1(dev, ioaddr) == 0)
			return 0;
	}

	dev->base_addr = base_addr;
	return ENODEV;
}

int netcard_probe1(struct device *dev, short ioaddr)
{
	unsigned char station_addr[6];
	int i;

	/* Read the station address PROM.  */
	for (i = 0; i < 6; i++) {
		station_addr[i] = inb(ioaddr + i);
	}
	/* Check the first three octets of the S.A. for the manufactor's code. */ 
	if (station_addr[0] != SA_ADDR0
		||	 station_addr[1] != SA_ADDR1 || station_addr[2] != SA_ADDR2) {
		return ENODEV;
	}

	printk("%s: %s found at %#3x, IRQ %d.\n", dev->name,
		   "network card", dev->base_addr, dev->irq);

#ifdef jumpered_interrupts
	/* If this board has jumpered interrupts, snarf the interrupt vector
	   now.	 There is no point in waiting since no other device can use
	   the interrupt, and this marks the 'irqaction' as busy. */

	if (dev->irq == -1)
		;			/* Do nothing: a user-level program will set it. */
	else if (dev->irq < 2) {	/* "Auto-IRQ" */
		autoirq_setup(0);
		/* Trigger an interrupt here. */

		dev->irq = autoirq_report(0);
		if (net_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;

	{	 int irqval = request_irq(dev->irq, &net_interrupt);
		 if (irqval) {
			 printk ("%s: unable to get IRQ %d (irqval=%d).\n", dev->name,
					 dev->irq, irqval);
			 return EAGAIN;
		 }
	 }
#endif	/* jumpered interrupt */

	/* Grab the region so we can find another board if autoIRQ fails. */
	snarf_region(ioaddr, ETHERCARD_TOTAL_SIZE);

	if (net_debug)
		printk(version);

	/* Initialize the device structure. */
	dev->priv = kmalloc(sizeof(struct net_local), GFP_KERNEL);
	memset(dev->priv, 0, sizeof(struct net_local));

	dev->open		= net_open;
	dev->stop		= net_close;
	dev->hard_start_xmit = net_send_packet;
	dev->get_stats	= net_get_stats;
#ifdef HAVE_MULTICAST
	dev->set_multicast_list = &set_multicast_list;
#endif

	/* Fill in the fields of the device structure with ethernet-generic values.
	   This should be in a common file instead of per-driver.  */
	for (i = 0; i < DEV_NUMBUFFS; i++)
		dev->buffs[i] = NULL;

	dev->hard_header	= eth_header;
	dev->add_arp		= eth_add_arp;
	dev->queue_xmit		= dev_queue_xmit;
	dev->rebuild_header	= eth_rebuild_header;
	dev->type_trans		= eth_type_trans;

	dev->type			= ARPHRD_ETHER;
	dev->hard_header_len = ETH_HLEN;
	dev->mtu			= 1500; /* eth_mtu */
	dev->addr_len		= ETH_ALEN;
	for (i = 0; i < ETH_ALEN; i++) {
		dev->broadcast[i]=0xff;
	}

	/* New-style flags. */
	dev->flags			= IFF_BROADCAST;
	dev->family			= AF_INET;
	dev->pa_addr		= 0;
	dev->pa_brdaddr		= 0;
	dev->pa_mask		= 0;
	dev->pa_alen		= sizeof(unsigned long);

	return 0;
}


/* Open/initialize the board.  This is called (in the current kernel)
   sometime after booting when the 'ifconfig' program is run.

   This routine should set everything up anew at each open, even
   registers that "should" only need to be set once at boot, so that
   there is non-reboot way to recover if something goes wrong.
   */
static int
net_open(struct device *dev)
{
	struct net_local *lp = (struct net_local *)dev->priv;
	int ioaddr = dev->base_addr;

	/* This is used if the interrupt line can turned off (shared).
	   See 3c503.c for an example of selecting the IRQ at config-time. */
	if (request_irq(dev->irq, &net_interrupt)) {
		return -EAGAIN;
	}


	/* Always snarf a DMA channel after the IRQ. */
	if (request_dma(dev->dma)) {
		free_irq(dev->irq);
		return -EAGAIN;
	}
	irq2dev_map[dev->irq] = dev;

	/* Reset the hardware here. */
	/*chipset_init(dev, 1);*/
	outb(0x00, ioaddr);
	lp->open_time = jiffies;

	dev->tbusy = 0;
	dev->interrupt = 0;
	dev->start = 1;
	return 0;
}

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

	if (dev->tbusy) {
		/* If we get here, some higher level has decided we are broken.
		   There should really be a "kick me" function call instead. */
		int tickssofar = jiffies - dev->trans_start;
		if (tickssofar < 5)
			return 1;
		printk("%s: transmit timed out, %s?\n", dev->name,
			   tx_done(dev) ? "IRQ conflict" : "network cable problem");
		/* Try to restart the adaptor. */
		chipset_init(dev, 1);
		dev->tbusy=0;
		dev->trans_start = jiffies;
	}

	/* If some higher layer thinks we've missed an tx-done interrupt
	   we are passed NULL. Caution: dev_tint() handles the cli()/sti()
	   itself. */
	if (skb == NULL) {
		dev_tint(dev);
		return 0;
	}

	/* For ethernet, fill in the header.  This should really be done by a
	   higher level, rather than duplicated for each ethernet adaptor. */
	if (!skb->arp  &&  dev->rebuild_header(skb->data, dev)) {
		skb->dev = dev;
		arp_queue (skb);
		return 0;
	}
	skb->arp=1;

	/* 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);
	else {
		short length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN;
		unsigned char *buf = skb->data;

		hardware_send_packet(ioaddr, buf, length);
		dev->trans_start = jiffies;
	}
	if (skb->free)
		kfree_skb (skb, FREE_WRITE);

	/* You might need to clean up and record Tx statistics here. */
	if (inw(ioaddr) == /*RU*/81)
		lp->stats.tx_aborted_errors++;

	return 0;
}

/* The typical workload of the driver:
   Handle the network interface interrupts. */
static void
net_interrupt(int reg_ptr)
{
	int irq = -(((struct pt_regs *)reg_ptr)->orig_eax+2);
	struct device *dev = (struct device *)(irq2dev_map[irq]);
	struct net_local *lp;
	int ioaddr, status, boguscount = 0;

	if (dev == NULL) {
		printk ("net_interrupt(): irq %d for unknown device.\n", irq);
		return;
	}
	dev->interrupt = 1;

	ioaddr = dev->base_addr;
	lp = (struct net_local *)dev->priv;
	status = inw(ioaddr + 0);

	do {
		if (status /*& RX_INTR*/) {
			/* Got a packet(s). */
			net_rx(dev);
		}
		if (status /*& TX_INTR*/) {
			lp->stats.tx_packets++;
			dev->tbusy = 0;
			mark_bh(INET_BH);	/* Inform upper layers. */
		}
		if (status /*& COUNTERS_INTR*/) {
			/* Increment the appropriate 'localstats' field. */
			lp->stats.tx_window_errors++;
		}
	} while (++boguscount < 20) ;

	return;
}

/* We have a good packet(s), get it/them out of the buffers. */
static void
net_rx(struct device *dev)
{
	struct net_local *lp = (struct net_local *)dev->priv;
	int ioaddr = dev->base_addr;
	int boguscount = 10;

	do {
		int status = inw(ioaddr);
		int pkt_len = inw(ioaddr);
	  
		if (pkt_len == 0)		/* Read all the frames? */
			break;			/* Done for now */

		if (status & 0x40) {	/* There was an error. */
			lp->stats.rx_errors++;
			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. */
			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, dropping packet.\n", dev->name);
				lp->stats.rx_dropped++;
				break;
			}
			skb->mem_len = sksize;
			skb->mem_addr = skb;
			skb->len = pkt_len;
			skb->dev = dev;

			/* 'skb->data' points to the start of sk_buff data area. */
			memcpy(skb->data, (void*)dev->rmem_start,
				   pkt_len);
			/* or */
			insw(ioaddr, skb->data, (pkt_len + 1) >> 1);

#ifdef HAVE_NETIF_RX
			netif_rx(skb);
#else
			skb->lock = 0;
			if (dev_rint((unsigned char*)skb, pkt_len, IN_SKBUFF, dev) != 0) {
				kfree_s(skb, sksize);
				lp->stats.rx_dropped++;
				break;
			}
#endif
			lp->stats.rx_packets++;
		}
	} while (--boguscount);

	/* If any worth-while packets have been received, dev_rint()
	   has done a mark_bh(INET_BH) for us and will work on them
	   when we get to the bottom-half routine. */
	return;
}

/* The inverse routine to net_open(). */
static int
net_close(struct device *dev)
{
	struct net_local *lp = (struct net_local *)dev->priv;
	int ioaddr = dev->base_addr;

	lp->open_time = 0;

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

	/* Flush the Tx and disable Rx here. */

	disable_dma(dev->dma);

	/* If not IRQ or DMA jumpered, free up the line. */
	outw(0x00, ioaddr+0);		/* Release the physical interrupt line. */

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

	irq2dev_map[dev->irq] = 0;

	/* Update the statistics here. */

	return 0;

}

/* Get the current statistics.	This may be called with the card open or
   closed. */
static struct enet_statistics *
net_get_stats(struct device *dev)
{
	struct net_local *lp = (struct net_local *)dev->priv;
	short ioaddr = dev->base_addr;

	cli();
	/* Update the statistics from the device registers. */
	lp->stats.rx_missed_errors = inw(ioaddr+1);
	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;
	if (num_addrs) {
		outw(69, ioaddr);		/* Enable promiscuous mode */
	} else
		outw(99, ioaddr);		/* Disable promiscuous mode, use normal mode */
}
#endif

/*
 * Local variables:
 *  compile-command: "gcc -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c skeleton.c"
 *  version-control: t
 *  kept-new-versions: 5
 *  tab-width: 4
 * End:
 */

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
欧美精品在线观看一区二区| 91免费在线视频观看| 亚洲国产视频直播| 国产精品久久久久9999吃药| 国产欧美日韩一区二区三区在线观看| 欧美精品一区二区精品网| www亚洲一区| 国产亚洲欧美在线| 国产精品毛片a∨一区二区三区| 国产精品久久久久久久久免费丝袜| 亚洲国产精品av| 伊人性伊人情综合网| 丝袜亚洲精品中文字幕一区| 免费成人你懂的| 丰满岳乱妇一区二区三区| 成人国产精品免费观看| 日本丶国产丶欧美色综合| 91麻豆精品国产自产在线观看一区| 日韩一区二区在线观看视频 | 伊人开心综合网| 亚洲国产日韩a在线播放性色| 亚洲aaa精品| 国产精品一区二区男女羞羞无遮挡| 粉嫩av一区二区三区| 91免费视频网| 日韩欧美二区三区| 国产精品蜜臀av| 天天综合天天综合色| 老司机免费视频一区二区三区| 国产成人精品免费网站| 欧美亚洲一区二区三区四区| 欧美精品一区二区久久久| 亚洲色图都市小说| 国产一区二区剧情av在线| 色先锋aa成人| 欧美国产精品久久| 五月婷婷另类国产| 成人一级黄色片| 日韩精品一区二区三区四区| 亚洲欧美乱综合| 极品瑜伽女神91| 欧美日韩国产电影| 国产精品久久久久婷婷| 秋霞国产午夜精品免费视频| 成人av集中营| 国产亚洲成年网址在线观看| 日本在线观看不卡视频| 91浏览器在线视频| 日本一区二区视频在线观看| 免费视频最近日韩| 欧美日韩精品一区二区三区蜜桃| 亚洲国产成人在线| 免费观看在线综合| 欧美日韩国产高清一区二区三区| 亚洲色图欧美激情| 丁香一区二区三区| 久久久久久久性| 麻豆国产精品视频| 欧美一级黄色大片| 日韩电影在线一区二区三区| 欧美影视一区在线| 亚洲最大色网站| 欧美在线免费视屏| 亚洲激情中文1区| aaa欧美日韩| 中文字幕一区二区三| 国产suv一区二区三区88区| 精品欧美乱码久久久久久1区2区| 日日噜噜夜夜狠狠视频欧美人| 在线精品观看国产| 亚洲一区二区三区视频在线| 91极品视觉盛宴| 亚洲一二三四在线| 欧美日韩在线播放| 日本怡春院一区二区| 欧美绝品在线观看成人午夜影视| 亚洲小说欧美激情另类| 欧美中文字幕一区二区三区| 亚洲午夜电影在线观看| 欧美精品久久天天躁| 久久国产成人午夜av影院| 日韩精品一区二区三区swag| 国产一区二区电影| 欧美激情综合网| 99国产一区二区三精品乱码| 一区二区三区欧美亚洲| 欧美日韩成人综合| 久久电影网站中文字幕| 2017欧美狠狠色| 成人黄色小视频在线观看| 一区二区三区在线高清| 在线播放日韩导航| 国产高清亚洲一区| 亚洲精品免费播放| 欧美一区二区三区不卡| 高清av一区二区| 亚洲在线视频网站| 欧美一区二区视频在线观看2022 | 亚洲久草在线视频| 欧美日韩国产三级| 国产精品一区在线观看乱码| 国产精品久久久久久久久搜平片 | 亚洲一区国产视频| 日韩欧美成人激情| 99精品欧美一区| 免费观看在线综合色| 国产精品麻豆一区二区| 9191成人精品久久| 成人网男人的天堂| 亚洲成人激情社区| 中文字幕乱码日本亚洲一区二区| 在线免费不卡视频| 国产麻豆一精品一av一免费| 亚洲最大色网站| 中国av一区二区三区| 欧美精品色一区二区三区| 国产成人99久久亚洲综合精品| 午夜在线成人av| 精品国产一区二区亚洲人成毛片| 色综合一区二区三区| 韩国成人在线视频| 三级亚洲高清视频| 亚洲精品水蜜桃| 中文字幕在线一区免费| 精品国产91乱码一区二区三区 | 久久久久久久网| 欧美日韩aaa| 欧美在线看片a免费观看| 成人福利视频在线看| 奇米影视一区二区三区| 亚洲国产成人av| 亚洲麻豆国产自偷在线| 国产精品国产馆在线真实露脸| 精品日韩一区二区| 91精品国产综合久久精品app| 日本韩国精品一区二区在线观看| 懂色av一区二区夜夜嗨| 国产在线日韩欧美| 九一九一国产精品| 蜜桃在线一区二区三区| 午夜精品福利视频网站| 亚洲444eee在线观看| 亚洲自拍偷拍欧美| 亚洲一区二区视频在线| 亚洲激情成人在线| 夜色激情一区二区| 亚洲午夜在线电影| 亚洲成a人v欧美综合天堂下载| 亚洲黄色免费电影| 亚洲成人1区2区| 奇米一区二区三区| 麻豆成人在线观看| 国产乱码精品一区二区三区av | 日韩一区二区三区视频| 91麻豆精品91久久久久久清纯| 欧美日韩免费观看一区三区| 欧美三级日韩三级国产三级| 欧美吞精做爰啪啪高潮| 91精品午夜视频| 久久综合色天天久久综合图片| ww久久中文字幕| 一色桃子久久精品亚洲| 亚洲自拍另类综合| 日日摸夜夜添夜夜添亚洲女人| 蜜臀av亚洲一区中文字幕| 国产精品白丝av| 91福利区一区二区三区| 91精品国产入口| 国产日韩欧美精品综合| 亚洲色图自拍偷拍美腿丝袜制服诱惑麻豆 | 亚洲自拍偷拍图区| 三级久久三级久久| 国产精品99久久久久久久vr| 成人av在线观| 777奇米四色成人影色区| 久久网站热最新地址| 日韩理论片一区二区| 五月激情六月综合| 岛国精品在线播放| 欧美色图免费看| 国产校园另类小说区| 亚洲国产美女搞黄色| 国产一区啦啦啦在线观看| 色天使色偷偷av一区二区| 精品国产欧美一区二区| 一区二区三区在线视频观看| 麻豆精品一区二区av白丝在线| 大胆亚洲人体视频| 欧美一级淫片007| 亚洲色图制服诱惑 | 欧美日韩aaaaaa| 亚洲国产精品成人久久综合一区| 午夜精品一区二区三区电影天堂| 国产伦精品一区二区三区视频青涩| 日本道在线观看一区二区| 日韩欧美一区在线| 亚洲视频一二三区| 国产精华液一区二区三区| 在线不卡一区二区| 亚洲免费观看高清完整版在线观看熊 |