Ejemplo n.º 1
0
void snull_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
    int statusword;
    struct snull_priv *privptr;
    /*
     * 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 */
    privptr = (struct snull_priv *)(dev->priv);
    spin_lock(&privptr->lock);

    /* retrieve statusword: real netdevices use I/O instructions */
    statusword = privptr->status;
    if (statusword & SNULL_RX_INTR) {
        /* send it to snull_rx for handling */
        snull_rx(dev, privptr->rx_packetlen, privptr->rx_packetdata);
    }
    if (statusword & SNULL_TX_INTR) {
        /* a transmission is over: free the skb */
        privptr->stats.tx_packets++;
        privptr->stats.tx_bytes += privptr->tx_packetlen;
        dev_kfree_skb(privptr->skb);
    }

    /* Unlock the device and we are done */
    spin_unlock(&privptr->lock);
    return;
}
Ejemplo n.º 2
0
void snull_interrupt(int irq, void *dev_id, struct pt_regs *regs)
{
    int statusword;
    struct snull_priv *privptr;
    /*
     * As usual, check the "device" pointer for shared handlers.
     * Then assign "struct device *dev"
     */
#if 0 && defined(LINUX_20)
    /* This is the way to do things for non-shared handlers */
    struct device *dev = (struct device *)(irq2dev_map[irq]);
#else
    /* Otherwise use this SA_SHIRQ-safe approach */
    struct net_device *dev = (struct net_device *)dev_id;
    /* ... and check with hw if it's really ours */
#endif

    if (!dev /*paranoid*/ ) return;

    /* Lock the device */
    privptr = (struct snull_priv *)(dev->priv);
    spin_lock(&privptr->lock);
    dev->interrupt = 1;

    /* retrieve statusword: real netdevices use inb() or inw() */
    statusword = privptr->status;
    if (statusword & SNULL_RX_INTR) {
        /* send it to snull_rx for handling */
        snull_rx(dev, privptr->rx_packetlen, privptr->rx_packetdata);
    }
    if (statusword & SNULL_TX_INTR) {
        /* a transmission is over: tell we are no more busy */
        privptr->stats.tx_packets++;
#ifndef LINUX_20
        privptr->stats.tx_bytes += privptr->tx_packetlen;
#endif
        dev_kfree_skb(privptr->skb);
    }
    spin_unlock(&privptr->lock);
    dev->interrupt = 0;
    return;
}
Ejemplo n.º 3
0
/*
  中断处理,此程序中没有硬件,因此,没有真正的硬件中断,只是模拟中断,在发送完网络数据包之后,会产生中断
  用来通知内核已经发送完数据包,当新的数据包到达网络接口时,会发生中断,通知新的数据包已经到来了
*/
  void snull_interrupt(int irq, void *dev_id, struct pt_regs *regs)
  {
    printk("snull_interrupt\n");

    int statusword;//用来标识是发送完毕还是接收到新的数据包
    struct net_device *dev = (struct net_device *)dev_id;
    struct snull_priv *priv = netdev_priv(dev);
    
    /* 检查这个设备的真伪 */
    if (!dev) {
        return;
    }

    /* 自旋锁上锁 */
    spin_lock(&priv->lock);

    /* 获取中断类型 */
    statusword = priv->status;
    priv->status = 0;

    //如果是接收
    if (statusword & SNULL_RX_INTR) 
    {
        /* 调用上层函数处理 */
        snull_rx(dev, priv->rx_packetlen, priv->rx_packetdata);
    }

    //如果发送完毕
    if (statusword & SNULL_TX_INTR) 
    {
        /* 更新计数信息 */
        priv->stats.tx_packets++;
        priv->stats.tx_bytes += priv->tx_packetlen;
        dev_kfree_skb(priv->skb);//释放skb套接字缓冲区
    }

    /* 释放自旋锁 */
    spin_unlock(&priv->lock);

    return;
}