|   当前位置: 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; } 
             | 
         
    
 
		    
                       
		      
		      
		   | 
		 
               
	     | 
	   
	  
	    | 
	      ↑返回顶部
	       
	      打印本页
	       
	      关闭窗口↓
	       
	     | 
	   
	  
	    
	       
	      
	      
	      
             | 
           
         
        | 
       
        
	  
	  
          
          
         
         
         
         
         
         
         
         
         
         
         
         
	  
        |