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

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

?? snull.c

?? Linux設備驅動的經典教材, 該電子書是第三版,并附有全部配套代碼.
?? C
?? 第 1 頁 / 共 2 頁
字號:
/* * snull.c --  the Simple Network Utility * * Copyright (C) 2001 Alessandro Rubini and Jonathan Corbet * Copyright (C) 2001 O'Reilly & Associates * * The source code in this file can be freely used, adapted, * and redistributed in source or binary form, so long as an * acknowledgment appears in derived source files.  The citation * should list that the code comes from the book "Linux Device * Drivers" by Alessandro Rubini and Jonathan Corbet, published * by O'Reilly & Associates.   No warranty is attached; * we cannot take responsibility for errors or fitness for use. * * $Id: snull.c,v 1.21 2004/11/05 02:36:03 rubini Exp $ */#include <linux/config.h>#include <linux/module.h>#include <linux/init.h>#include <linux/moduleparam.h>#include <linux/sched.h>#include <linux/kernel.h> /* printk() */#include <linux/slab.h> /* kmalloc() */#include <linux/errno.h>  /* error codes */#include <linux/types.h>  /* size_t */#include <linux/interrupt.h> /* mark_bh */#include <linux/in.h>#include <linux/netdevice.h>   /* struct device, and other headers */#include <linux/etherdevice.h> /* eth_type_trans */#include <linux/ip.h>          /* struct iphdr */#include <linux/tcp.h>         /* struct tcphdr */#include <linux/skbuff.h>#include "snull.h"#include <linux/in6.h>#include <asm/checksum.h>MODULE_AUTHOR("Alessandro Rubini, Jonathan Corbet");MODULE_LICENSE("Dual BSD/GPL");/* * Transmitter lockup simulation, normally disabled. */static int lockup = 0;module_param(lockup, int, 0);static int timeout = SNULL_TIMEOUT;module_param(timeout, int, 0);/* * Do we run in NAPI mode? */static int use_napi = 0;module_param(use_napi, int, 0);/* * A structure representing an in-flight packet. */struct snull_packet {	struct snull_packet *next;	struct net_device *dev;	int	datalen;	u8 data[ETH_DATA_LEN];};int pool_size = 8;module_param(pool_size, int, 0);/* * This structure is private to each device. It is used to pass * packets in and out, so there is place for a packet */struct snull_priv {	struct net_device_stats stats;	int status;	struct snull_packet *ppool;	struct snull_packet *rx_queue;  /* List of incoming packets */	int rx_int_enabled;	int tx_packetlen;	u8 *tx_packetdata;	struct sk_buff *skb;	spinlock_t lock;};static void snull_tx_timeout(struct net_device *dev);static void (*snull_interrupt)(int, void *, struct pt_regs *);/* * Set up a device's packet pool. */void snull_setup_pool(struct net_device *dev){	struct snull_priv *priv = netdev_priv(dev);	int i;	struct snull_packet *pkt;	priv->ppool = NULL;	for (i = 0; i < pool_size; i++) {		pkt = kmalloc (sizeof (struct snull_packet), GFP_KERNEL);		if (pkt == NULL) {			printk (KERN_NOTICE "Ran out of memory allocating packet pool\n");			return;		}		pkt->dev = dev;		pkt->next = priv->ppool;		priv->ppool = pkt;	}}void snull_teardown_pool(struct net_device *dev){	struct snull_priv *priv = netdev_priv(dev);	struct snull_packet *pkt;    	while ((pkt = priv->ppool)) {		priv->ppool = pkt->next;		kfree (pkt);		/* FIXME - in-flight packets ? */	}}    /* * Buffer/pool management. */struct snull_packet *snull_get_tx_buffer(struct net_device *dev){	struct snull_priv *priv = netdev_priv(dev);	unsigned long flags;	struct snull_packet *pkt;    	spin_lock_irqsave(&priv->lock, flags);	pkt = priv->ppool;	priv->ppool = pkt->next;	if (priv->ppool == NULL) {		printk (KERN_INFO "Pool empty\n");		netif_stop_queue(dev);	}	spin_unlock_irqrestore(&priv->lock, flags);	return pkt;}void snull_release_buffer(struct snull_packet *pkt){	unsigned long flags;	struct snull_priv *priv = netdev_priv(pkt->dev);		spin_lock_irqsave(&priv->lock, flags);	pkt->next = priv->ppool;	priv->ppool = pkt;	spin_unlock_irqrestore(&priv->lock, flags);	if (netif_queue_stopped(pkt->dev) && pkt->next == NULL)		netif_wake_queue(pkt->dev);}void snull_enqueue_buf(struct net_device *dev, struct snull_packet *pkt){	unsigned long flags;	struct snull_priv *priv = netdev_priv(dev);	spin_lock_irqsave(&priv->lock, flags);	pkt->next = priv->rx_queue;  /* FIXME - misorders packets */	priv->rx_queue = pkt;	spin_unlock_irqrestore(&priv->lock, flags);}struct snull_packet *snull_dequeue_buf(struct net_device *dev){	struct snull_priv *priv = netdev_priv(dev);	struct snull_packet *pkt;	unsigned long flags;	spin_lock_irqsave(&priv->lock, flags);	pkt = priv->rx_queue;	if (pkt != NULL)		priv->rx_queue = pkt->next;	spin_unlock_irqrestore(&priv->lock, flags);	return pkt;}/* * Enable and disable receive interrupts. */static void snull_rx_ints(struct net_device *dev, int enable){	struct snull_priv *priv = netdev_priv(dev);	priv->rx_int_enabled = enable;}    /* * Open and close */int snull_open(struct net_device *dev){	/* request_region(), request_irq(), ....  (like fops->open) */	/* 	 * Assign the hardware address of the board: use "\0SNULx", where	 * x is 0 or 1. The first byte is '\0' to avoid being a multicast	 * address (the first byte of multicast addrs is odd).	 */	memcpy(dev->dev_addr, "\0SNUL0", ETH_ALEN);	if (dev == snull_devs[1])		dev->dev_addr[ETH_ALEN-1]++; /* \0SNUL1 */	netif_start_queue(dev);	return 0;}int snull_release(struct net_device *dev){    /* release ports, irq and such -- like fops->close */	netif_stop_queue(dev); /* can't transmit any more */	return 0;}/* * Configuration changes (passed on by ifconfig) */int snull_config(struct net_device *dev, struct ifmap *map){	if (dev->flags & IFF_UP) /* can't act on a running interface */		return -EBUSY;	/* Don't allow changing the I/O address */	if (map->base_addr != dev->base_addr) {		printk(KERN_WARNING "snull: Can't change I/O address\n");		return -EOPNOTSUPP;	}	/* Allow changing the IRQ */	if (map->irq != dev->irq) {		dev->irq = map->irq;        	/* request_irq() is delayed to open-time */	}	/* ignore other fields */	return 0;}/* * Receive a packet: retrieve, encapsulate and pass over to upper levels */void snull_rx(struct net_device *dev, struct snull_packet *pkt){	struct sk_buff *skb;	struct snull_priv *priv = netdev_priv(dev);	/*	 * The packet has been retrieved from the transmission	 * medium. Build an skb around it, so upper layers can handle it	 */	skb = dev_alloc_skb(pkt->datalen + 2);	if (!skb) {		if (printk_ratelimit())			printk(KERN_NOTICE "snull rx: low on mem - packet dropped\n");		priv->stats.rx_dropped++;		goto out;	}	skb_reserve(skb, 2); /* align IP on 16B boundary */  	memcpy(skb_put(skb, pkt->datalen), pkt->data, pkt->datalen);	/* Write metadata, and then pass to the receive level */	skb->dev = dev;	skb->protocol = eth_type_trans(skb, dev);	skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */	priv->stats.rx_packets++;	priv->stats.rx_bytes += pkt->datalen;	netif_rx(skb);  out:	return;}    /* * The poll implementation. */static int snull_poll(struct net_device *dev, int *budget){	int npackets = 0, quota = min(dev->quota, *budget);	struct sk_buff *skb;	struct snull_priv *priv = netdev_priv(dev);	struct snull_packet *pkt;    	while (npackets < quota && priv->rx_queue) {		pkt = snull_dequeue_buf(dev);		skb = dev_alloc_skb(pkt->datalen + 2);		if (! skb) {			if (printk_ratelimit())				printk(KERN_NOTICE "snull: packet dropped\n");			priv->stats.rx_dropped++;			snull_release_buffer(pkt);			continue;		}		skb_reserve(skb, 2); /* align IP on 16B boundary */  		memcpy(skb_put(skb, pkt->datalen), pkt->data, pkt->datalen);		skb->dev = dev;		skb->protocol = eth_type_trans(skb, dev);		skb->ip_summed = CHECKSUM_UNNECESSARY; /* don't check it */		netif_receive_skb(skb);		        	/* Maintain stats */		npackets++;		priv->stats.rx_packets++;		priv->stats.rx_bytes += pkt->datalen;		snull_release_buffer(pkt);	}	/* If we processed all packets, we're done; tell the kernel and reenable ints */	*budget -= npackets;	dev->quota -= npackets;	if (! priv->rx_queue) {		netif_rx_complete(dev);		snull_rx_ints(dev, 1);		return 0;	}	/* We couldn't process everything. */	return 1;}	            /* * The typical interrupt entry point */static void snull_regular_interrupt(int irq, void *dev_id, struct pt_regs *regs){	int statusword;	struct snull_priv *priv;	struct snull_packet *pkt = NULL;	/*	 * As usual, check the "device" pointer to be sure it is	 * really interrupting.	 * Then assign "struct device *dev"	 */	struct net_device *dev = (struct net_device *)dev_id;	/* ... and check with hw if it's really ours */	/* paranoid */	if (!dev)		return;	/* Lock the device */	priv = netdev_priv(dev);	spin_lock(&priv->lock);	/* retrieve statusword: real netdevices use I/O instructions */	statusword = priv->status;	priv->status = 0;	if (statusword & SNULL_RX_INTR) {		/* send it to snull_rx for handling */		pkt = priv->rx_queue;		if (pkt) {			priv->rx_queue = pkt->next;			snull_rx(dev, pkt);		}	}	if (statusword & SNULL_TX_INTR) {		/* a transmission is over: free the skb */		priv->stats.tx_packets++;		priv->stats.tx_bytes += priv->tx_packetlen;		dev_kfree_skb(priv->skb);

?? 快捷鍵說明

復制代碼 Ctrl + C
搜索代碼 Ctrl + F
全屏模式 F11
切換主題 Ctrl + Shift + D
顯示快捷鍵 ?
增大字號 Ctrl + =
減小字號 Ctrl + -
亚洲欧美第一页_禁久久精品乱码_粉嫩av一区二区三区免费野_久草精品视频
日韩欧美黄色影院| 不卡电影一区二区三区| 一区二区在线观看视频 | 亚洲成人黄色影院| 亚洲一区二区三区四区在线| 国产精品传媒视频| 最新久久zyz资源站| 国产精品高清亚洲| 一区二区在线观看视频| 亚洲裸体xxx| 午夜久久电影网| 蜜桃视频第一区免费观看| 亚洲国产精品影院| 蜜臀国产一区二区三区在线播放 | 久久免费视频色| 中文乱码免费一区二区| 亚洲视频在线一区二区| 亚洲美腿欧美偷拍| 日本午夜一本久久久综合| 日本最新不卡在线| 国产激情偷乱视频一区二区三区| 成人午夜私人影院| 一本色道久久综合亚洲aⅴ蜜桃| 99久久er热在这里只有精品15| 91色视频在线| 欧美日韩一二三区| 精品国产伦一区二区三区观看体验| 久久久久久久久久久久电影| 亚洲精品欧美在线| 日韩成人精品在线| 成人性生交大片免费看在线播放| 91在线精品秘密一区二区| 欧美性大战久久久久久久蜜臀| 日韩一区二区精品在线观看| 国产亚洲精品中文字幕| 亚洲精品成人悠悠色影视| 免费成人结看片| 成+人+亚洲+综合天堂| 欧美日韩一级二级| 国产精品天天看| 蜜乳av一区二区三区| 不卡一区中文字幕| 91精品国产免费| 亚洲视频一区在线| 激情欧美一区二区| 欧美性xxxxxx少妇| 136国产福利精品导航| 亚洲国产视频在线| 高清在线不卡av| 日韩欧美成人一区| 一区二区三区91| 高清不卡在线观看| 欧美一二三四在线| 亚洲一区在线观看视频| 成人高清av在线| 26uuu国产电影一区二区| 亚洲一区二区三区三| av不卡在线播放| 久久久www成人免费无遮挡大片| 亚洲精品日日夜夜| 国产成人免费视频网站高清观看视频 | 精品欧美一区二区在线观看| 一区二区视频在线| 91在线观看一区二区| 国产色爱av资源综合区| 久久精品国产999大香线蕉| 91老司机福利 在线| 国产精品色哟哟| 国产专区综合网| 欧美成人a在线| 捆绑调教美女网站视频一区| 欧美色窝79yyyycom| 亚洲色图在线看| 91小视频免费观看| 国产人久久人人人人爽| 国产在线精品国自产拍免费| 欧美变态凌虐bdsm| 久久精品二区亚洲w码| 欧美电视剧免费观看| 蜜臀av亚洲一区中文字幕| 91精品国产色综合久久| 蜜桃av噜噜一区二区三区小说| 91精品国产乱码久久蜜臀| 日韩vs国产vs欧美| 日韩三级免费观看| 国产乱一区二区| 久久久精品黄色| 91在线免费播放| 亚洲乱码国产乱码精品精98午夜| 一本久久综合亚洲鲁鲁五月天 | 免费观看在线色综合| 欧美一区二区三区啪啪| 蜜桃视频一区二区| 国产欧美日韩卡一| 91丨porny丨蝌蚪视频| 亚洲综合免费观看高清在线观看| 欧美性猛交一区二区三区精品| 首页国产丝袜综合| 国产亚洲成年网址在线观看| 国产91精品精华液一区二区三区| 亚洲欧美日韩国产综合| 欧美亚洲高清一区| 美洲天堂一区二卡三卡四卡视频| 久久精品亚洲一区二区三区浴池| av一区二区久久| 亚洲高清一区二区三区| 欧美一级欧美一级在线播放| 国产精品一区二区不卡| 亚洲美女在线国产| 精品国产一区二区三区av性色 | 7777精品伊人久久久大香线蕉最新版| 天天亚洲美女在线视频| 国产午夜亚洲精品不卡 | 日韩高清不卡在线| 国产精品无码永久免费888| 欧美日韩性生活| 丁香亚洲综合激情啪啪综合| 亚洲国产精品麻豆| 国产精品日日摸夜夜摸av| 7878成人国产在线观看| 成人黄色在线网站| 久久99久久99| 亚洲一区二区精品久久av| 中文字幕欧美国产| 日韩欧美在线网站| 日本乱人伦aⅴ精品| 国产麻豆欧美日韩一区| 亚洲mv大片欧洲mv大片精品| 欧美激情自拍偷拍| 精品入口麻豆88视频| 欧美三级在线视频| 色综合久久综合中文综合网| 国产伦理精品不卡| 另类小说综合欧美亚洲| 亚洲成人自拍偷拍| 17c精品麻豆一区二区免费| 国产日韩欧美综合一区| 日韩一区二区免费高清| 在线免费观看视频一区| 波多野结衣在线一区| 国产99久久久精品| 国产东北露脸精品视频| 免费xxxx性欧美18vr| 午夜电影网一区| 亚洲一区二区三区四区的| 亚洲欧美激情在线| 亚洲国产精品二十页| 久久久久久久久久久久久女国产乱| 91精品国产色综合久久不卡蜜臀| 91国偷自产一区二区三区观看| 懂色中文一区二区在线播放| 国产精品一二三在| 国产成人av电影在线| 国产精品一区二区在线播放 | 日韩一区二区三区四区| 欧美电影在哪看比较好| 欧美精品日韩精品| 欧美猛男男办公室激情| 欧美日高清视频| 日韩视频一区二区在线观看| 日韩午夜精品视频| 亚洲精品在线三区| 欧美国产欧美亚州国产日韩mv天天看完整| 久久综合色婷婷| 国产性色一区二区| 亚洲人成网站色在线观看| 一区二区在线电影| 日韩电影免费一区| 国产一区二区福利| 不卡的av电影| 精品视频在线免费看| 欧美一区二区三区在线视频| 日韩亚洲欧美中文三级| 久久中文娱乐网| 日韩美女视频19| 五月天激情综合| 国产成人三级在线观看| 欧美综合亚洲图片综合区| 在线免费观看日本欧美| 91精品国产色综合久久ai换脸 | 美脚の诱脚舐め脚责91| 国产激情偷乱视频一区二区三区| 91免费版pro下载短视频| 欧美三区在线观看| 精品国产区一区| 亚洲美女一区二区三区| 麻豆精品视频在线观看免费| 风流少妇一区二区| 欧美人妖巨大在线| 国产精品无遮挡| 免费日本视频一区| 成人午夜电影久久影院| 欧美视频你懂的| 国产欧美日韩一区二区三区在线观看| 亚洲图片欧美激情| 久久99精品国产| 欧美色倩网站大全免费| 国产精品麻豆久久久| 免费观看日韩av| 欧美影院一区二区|