快速业务通道

深入浅出Linux设备驱动编程--复杂设备驱动

作者 佚名技术 来源 Linux系统 浏览 发布时间 2012-05-16
the URB within the USB subsystem */
if (usb_submit_urb(&sample->urb)) {
kfree(sample);
return NULL;
}
/* announce yourself */
printk(KERN_INFO "usbsample: probe successful for %s (maxp is %i)n",
sample->name, sample->maxp); /*
* here you might MOD_INC_USE_COUNT; if you do, you''ll need to unplug
* the device or the devices before being able to unload the module
*/ /* and return the new structure */
return sample;
}
在网络设备驱动的编写中,我们特别关心的就是数据的收、发及中断.网络设备驱动程序的层次如下:

网络设备接收到报文后将其传入上层:
/*
* Receive a packet: retrieve, encapsulate and pass over to upper levels
*/
void snull_rx(struct net_device *dev, int len, unsigned char *buf)
{
struct sk_buff *skb;
struct snull_priv *priv = (struct snull_priv *) dev->priv; /*
* The packet has been retrieved from the transmission
* medium. Build an skb around it, so upper layers can handle it
*/
skb = dev_alloc_skb(len 2);
if (!skb) {
printk("snull rx: low on mem - packet droppedn");
priv->stats.rx_dropped ;
return;
}
skb_reserve(skb, 2); /* align IP on 16B boundary */
memcpy(skb_put(skb, len), buf, len); /* 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 ;
#ifndef LINUX_20
priv->stats.rx_bytes = len;
#endif
netif_rx(skb);
return;
}
在中断到来时接收报文信息:
void snull_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
int statusword;
struct snull_priv *priv;
/*
* As usual, check the "device" pointer for shared handlers.
* Then assign "struct device *dev"
*/
struct net_device *dev = (struct net_device *)dev_id;
/* ... and check with hw if it''s really ours */if (!dev /*paranoid*/ ) return; /* Lock the device */
priv = (struct snull_priv *) dev->priv;
spin_lock(&priv->lock); /* retrieve statusword: real netdevices use I/O instructions */
statusword = priv->status;
if (statusword & SNULL_RX_INTR) {
/* send it to snull_rx for handling */
snull_rx(dev, priv->rx_packetlen, priv->rx_packetdata);
}
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);
} /* Unlock the device and we are done */
spin_unlock(&priv->lock);
return;
}
而发送报文则分为两个层次,一个层次是内核调用,一个层次完成真正的硬件上的发送:
/*
* Transmit a packet (called by the kernel)
*/
int snull_tx(struct sk_buff *skb, struct net_device *dev)
{
int len;
char *data;
struct snull_priv *priv = (struct snull_priv *) dev->priv; #ifndef LINUX_24
if (dev->tbusy || s

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号