当前位置: Home > Linux > 设备驱动 > 文章 |
|
Linux设备驱动编程之复杂设备驱动
|
文章来源: 天极开发
文章作者: 宋宝华
发布时间: 2006-11-01
字体:
[大
中
小]
|
|
网络设备接收到报文后将其传入上层:
/* * 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 dropped\n"); 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; }
|
|
|
↑返回顶部
打印本页
关闭窗口↓
|
|
|
|