17.7. 中斷處理

2018-02-24 15:50 更新

17.7.?中斷處理

大部分硬件接口通過一個中斷處理來控制. 硬件中斷處理器來發(fā)出 2 種可能的信號: 一個新報文到了或者一個外出報文的發(fā)送完成了. 網(wǎng)絡(luò)接口也能夠產(chǎn)生中斷來指示錯誤, 例如狀態(tài)改變, 等等.

通常的中斷過程能夠告知新報文到達中斷和發(fā)送完成通知的區(qū)別, 通過檢查物理設(shè)備中的狀態(tài)寄存器. snull 接口類似地工作, 但是它的狀態(tài)字在軟件中實現(xiàn), 位于 dev->priv. 網(wǎng)絡(luò)接口的中斷處理看來如此:


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);

    }

    /* Unlock the device and we are done */
    spin_unlock(&priv->lock);
    if (pkt) snull_release_buffer(pkt); /* Do this outside the lock! */
    return;

}

中斷處理的第一個任務(wù)是取一個指向正確 net_device 結(jié)構(gòu)的指針. 這個指針通常來自作為參數(shù)收到的 dev_id 指針.

中斷處理的有趣部分處理"發(fā)送結(jié)束"的情況. 在這個情況下, 統(tǒng)計量被更新, 調(diào)用 dev_kfree_skb 來返回 socket 緩存給系統(tǒng). 實際上, 有這個函數(shù)的 3 個變體可以調(diào)用:

dev_kfree_skb(struct sk_buff *skb);
這個版本應(yīng)當在你知道你的代碼不會在中斷上下文中運行時調(diào)用. 因為 snull 沒有實際的硬件中斷, 我們使用這個版本.

dev_kfree_skb_irq(struct sk_buff *skb);
如果你知道會在中斷處理中釋放緩存, 使用這個版本, 它對這個情況做了優(yōu)化.

dev_kfree_skb_any(struct sk_buff *skb);
如果相關(guān)代碼可能在中斷或非中斷上下文運行時, 使用這個版本.

最后, 如果你的驅(qū)動已暫時停止了發(fā)送隊列, 這常常是用 netif_wake_queue 重啟它的地方.

報文的接收, 相比于發(fā)送, 不需要特別的中斷處理. 調(diào)用 snull_rx (我們已經(jīng)見過)就是全部所需.

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號