W3Cschool
恭喜您成為首批注冊(cè)用戶
獲得88經(jīng)驗(yàn)值獎(jiǎng)勵(lì)
大部分硬件接口通過(guò)一個(gè)中斷處理來(lái)控制. 硬件中斷處理器來(lái)發(fā)出 2 種可能的信號(hào): 一個(gè)新報(bào)文到了或者一個(gè)外出報(bào)文的發(fā)送完成了. 網(wǎng)絡(luò)接口也能夠產(chǎn)生中斷來(lái)指示錯(cuò)誤, 例如狀態(tài)改變, 等等.
通常的中斷過(guò)程能夠告知新報(bào)文到達(dá)中斷和發(fā)送完成通知的區(qū)別, 通過(guò)檢查物理設(shè)備中的狀態(tài)寄存器. snull 接口類似地工作, 但是它的狀態(tài)字在軟件中實(shí)現(xiàn), 位于 dev->priv. 網(wǎng)絡(luò)接口的中斷處理看來(lái)如此:
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;
}
中斷處理的第一個(gè)任務(wù)是取一個(gè)指向正確 net_device 結(jié)構(gòu)的指針. 這個(gè)指針通常來(lái)自作為參數(shù)收到的 dev_id 指針.
中斷處理的有趣部分處理"發(fā)送結(jié)束"的情況. 在這個(gè)情況下, 統(tǒng)計(jì)量被更新, 調(diào)用 dev_kfree_skb 來(lái)返回 socket 緩存給系統(tǒng). 實(shí)際上, 有這個(gè)函數(shù)的 3 個(gè)變體可以調(diào)用:
dev_kfree_skb(struct sk_buff *skb);
這個(gè)版本應(yīng)當(dāng)在你知道你的代碼不會(huì)在中斷上下文中運(yùn)行時(shí)調(diào)用. 因?yàn)?snull 沒(méi)有實(shí)際的硬件中斷, 我們使用這個(gè)版本.
dev_kfree_skb_irq(struct sk_buff *skb);
如果你知道會(huì)在中斷處理中釋放緩存, 使用這個(gè)版本, 它對(duì)這個(gè)情況做了優(yōu)化.
dev_kfree_skb_any(struct sk_buff *skb);
如果相關(guān)代碼可能在中斷或非中斷上下文運(yùn)行時(shí), 使用這個(gè)版本.
最后, 如果你的驅(qū)動(dòng)已暫時(shí)停止了發(fā)送隊(duì)列, 這常常是用 netif_wake_queue 重啟它的地方.
報(bào)文的接收, 相比于發(fā)送, 不需要特別的中斷處理. 調(diào)用 snull_rx (我們已經(jīng)見(jiàn)過(guò))就是全部所需.
Copyright©2021 w3cschool編程獅|閩ICP備15016281號(hào)-3|閩公網(wǎng)安備35020302033924號(hào)
違法和不良信息舉報(bào)電話:173-0602-2364|舉報(bào)郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號(hào)
聯(lián)系方式:
更多建議: