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

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

?? skeleton.c

?? <Linux1.0核心游記>電子書+書后源碼+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#endifstatic 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_MULTICASTstatic void set_multicast_list(struct device *dev, int num_addrs, void *addrs);#endif/* Example routines you must write ;->. */#define tx_done(dev) 1extern 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).   */intnetcard_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 intnet_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 intnet_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 voidnet_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 voidnet_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 intnet_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 voidset_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一区二区三区免费野_久草精品视频
欧美一区二区三区性视频| 国产精品资源网| 久久精品亚洲一区二区三区浴池 | 色综合天天综合狠狠| 日韩av电影一区| 亚洲欧美日本在线| 26uuuu精品一区二区| 欧洲精品在线观看| 大美女一区二区三区| 麻豆91免费观看| 亚洲韩国一区二区三区| 国产精品毛片无遮挡高清| 精品美女被调教视频大全网站| 色综合视频一区二区三区高清| 国产精品一区专区| 蜜臂av日日欢夜夜爽一区| 亚洲精品乱码久久久久久久久| 久久免费的精品国产v∧| 欧美人狂配大交3d怪物一区| 色综合久久天天| av一区二区三区黑人| 韩国av一区二区三区四区| 亚洲va欧美va人人爽午夜| 亚洲女子a中天字幕| 国产精品麻豆99久久久久久| 欧美精品一区二区高清在线观看| 在线成人av影院| 欧美亚洲国产怡红院影院| 成人黄色软件下载| 国产成人av一区二区三区在线| 久久精品国产久精国产| 免费观看一级欧美片| 亚洲一区二区黄色| 亚洲国产精品久久久男人的天堂| 亚洲品质自拍视频| 亚洲色图一区二区| 国产精品久久久久三级| 国产清纯白嫩初高生在线观看91| 欧美一区二区网站| 欧美电视剧在线看免费| 精品日韩在线一区| 精品国产一区二区三区不卡| ww亚洲ww在线观看国产| 337p粉嫩大胆噜噜噜噜噜91av| 日韩一区和二区| 精品免费国产二区三区| 久久免费精品国产久精品久久久久| 欧美精品一区二区三| 国产清纯美女被跳蛋高潮一区二区久久w | 日韩美女视频一区二区 | 日韩欧美资源站| 日韩欧美国产一区二区三区 | 亚洲一区二区三区四区五区中文 | 亚洲一卡二卡三卡四卡| 亚洲国产另类av| 蜜臀精品一区二区三区在线观看| 蜜臀av亚洲一区中文字幕| 国内外精品视频| 成人动漫一区二区三区| 日本丶国产丶欧美色综合| 欧美色涩在线第一页| 91精品国产麻豆国产自产在线| 欧美电影免费观看完整版| 国产欧美精品一区二区三区四区| 亚洲欧洲精品一区二区三区 | 欧美猛男超大videosgay| 日韩精品自拍偷拍| 国产亚洲精品久| 一区二区三区四区精品在线视频| 亚洲电影一级黄| 久草这里只有精品视频| 成人午夜av在线| 欧美日韩黄色一区二区| 久久久久久亚洲综合| 亚洲视频网在线直播| 日韩成人免费电影| 国产99久久久国产精品潘金| 色妹子一区二区| 精品乱人伦小说| 亚洲男帅同性gay1069| 日本aⅴ免费视频一区二区三区| 国产乱码精品1区2区3区| 在线免费观看一区| 日韩精品中文字幕在线一区| 国产精品理论在线观看| 日韩和欧美的一区| 成人视屏免费看| 777午夜精品免费视频| 国产欧美日韩精品在线| 日韩电影在线观看一区| 成人黄色在线网站| 精品少妇一区二区三区日产乱码| 亚洲欧美日韩国产中文在线| 久久er99热精品一区二区| 日本韩国精品一区二区在线观看| 精品美女一区二区三区| 亚洲韩国一区二区三区| 成人高清伦理免费影院在线观看| 91超碰这里只有精品国产| 综合久久国产九一剧情麻豆| 狠狠色丁香久久婷婷综| 欧美男女性生活在线直播观看| 国产精品久久久久9999吃药| 久久se这里有精品| 51久久夜色精品国产麻豆| 日韩理论片一区二区| 国产精品综合久久| 欧美刺激脚交jootjob| 一卡二卡三卡日韩欧美| www.日本不卡| 久久影院视频免费| 久久99国产精品久久| 欧美日本在线看| 亚洲午夜免费电影| 91网址在线看| 国产精品无圣光一区二区| 精品在线你懂的| 日韩视频一区在线观看| 亚洲123区在线观看| 91国偷自产一区二区三区观看| 国产精品伦一区| 99在线视频精品| 中文字幕人成不卡一区| 大白屁股一区二区视频| 久久精品亚洲精品国产欧美kt∨| 久久精品国产秦先生| 欧美一区二区在线不卡| 日韩和的一区二区| 欧美一区二区福利视频| 日本午夜精品视频在线观看 | 国产宾馆实践打屁股91| 久久蜜桃av一区二区天堂| 日韩精品福利网| 欧美一区二区三区影视| 日本美女一区二区| 日韩三级免费观看| 久久精品国产秦先生| 精品国产精品网麻豆系列| 美女久久久精品| 精品电影一区二区三区| 激情欧美一区二区| 国产亚洲成aⅴ人片在线观看| 国产精品1区2区3区| 国产欧美日韩中文久久| youjizz国产精品| 亚洲制服丝袜一区| 欧美日韩午夜影院| 久久精品噜噜噜成人av农村| 久久久亚洲高清| 99国产精品99久久久久久| 一区二区三区蜜桃网| 欧美高清dvd| 国产在线麻豆精品观看| 中文幕一区二区三区久久蜜桃| 91亚洲国产成人精品一区二区三| 一级女性全黄久久生活片免费| 欧美美女直播网站| 国产一区三区三区| 亚洲欧美自拍偷拍色图| 欧美日韩一区二区三区在线 | ...av二区三区久久精品| 精品视频999| 蜜桃一区二区三区在线观看| 国产午夜亚洲精品羞羞网站| 99国产欧美另类久久久精品| 亚洲国产精品一区二区www在线| 91精品国产黑色紧身裤美女| 国产最新精品免费| 一区二区三区在线视频免费| 337p亚洲精品色噜噜狠狠| 国产成人免费网站| 亚洲一区二区三区在线| 亚洲精品在线观| 色噜噜狠狠色综合欧洲selulu| 日韩在线卡一卡二| 日本一区二区不卡视频| 欧美三日本三级三级在线播放| 国产一区二区美女| 亚洲最快最全在线视频| 精品国产一区二区三区av性色| 91视视频在线直接观看在线看网页在线看| 亚洲国产综合在线| 欧美激情综合五月色丁香 | 欧美一区二区不卡视频| 不卡欧美aaaaa| 日韩国产一二三区| 中文字幕一区二区三| 91精品国产91久久久久久最新毛片| 东方欧美亚洲色图在线| 石原莉奈在线亚洲二区| 亚洲欧美怡红院| 日韩精品一区二区三区在线| 在线亚洲精品福利网址导航| 国产九九视频一区二区三区| 亚洲超丰满肉感bbw| 成人免费在线观看入口| 精品国产乱码久久久久久影片| 欧洲在线/亚洲| 不卡视频在线观看| 国产一区二区在线看|