linux網卡驅動dm9000_poll_work函數分析

static void
dm9000_poll_work(struct work_struct *w)
{
struct delayed_work *dw = container_of(w, struct delayed_work, work);//獲得結構體struct delayed_work,詳見註釋一                                                                                                                       
board_info_t *db = container_of(dw, board_info_t, phy_poll);//獲得結構體board_info_t的入口地址,這句話的意思同上                                                                                                                                  
struct net_device *ndev = db->ndev;

if (db->flags & DM9000_PLATF_SIMPLE_PHY &&
    !(db->flags & DM9000_PLATF_EXT_PHY)) {
unsigned nsr = dm9000_read_locked(db, DM9000_NSR);//讀取網絡狀態寄存器的值
unsigned old_carrier = netif_carrier_ok(ndev) ? 1 : 0; //檢查載體是否在設備上,即檢查鏈接狀態
unsigned new_carrier;

new_carrier = (nsr & NSR_LINKST) ? 1 : 0;  //若鏈接上則爲1,否則爲0

if (old_carrier != new_carrier) {
if (netif_msg_link(db))//是否鏈接上
dm9000_show_carrier(db, new_carrier, nsr);//如果臉上了,顯示一些網絡link後的信息,如速度,全\半雙工

if (!new_carrier)
netif_carrier_off(ndev);//沒連上則clear carrier
else
netif_carrier_on(ndev);//連上了則set carrier
}
} else
mii_check_media(&db->mii, netif_msg_link(db), 0);//檢測雙工模式是否改變
if (netif_running(ndev))//檢測設備是否被啓動了
dm9000_schedule_poll(db);//關於這個函數我們在註釋二里要好好說道說道
}

註釋一:
struct delayed_work {
struct work_struct work;
struct timer_list timer;
};
container_of(w, struct delayed_work, work)這行代碼的含義就是一個地址減去它在結構體struct delayed_work中偏移量,從而得到struct delayed_work結構體的入口地址。這個函數裏面有三個參數,第一個是地址,第二個是結構體類型,第三個是結構體裏成員的名字。實現的功能就是由結構體的成員得到整個結構體的指針。

註釋二:在dm9000_probe函數中有過這麼一句代碼:INIT_DELAYED_WORK(&db->phy_poll, dm9000_poll_work);這行代碼的含義就是用於初始化一個任務dm9000_poll_work,將db->phy_poll結構體中的work指向dm9000_poll_work;
 之後如果希望調用dm9000_poll_work這個函數,只需要用一句schedule_delayed_work()就可以了,那麼什麼時候調用函數schedule_delayed_work呢,我們在函數dm9000_interrupt和dm9000_schedule_poll中發現了答案;中斷中要求1個延時後調用schedule_delayed_work,即dm9000_poll_work函數來檢測並顯示網絡信息,而dm9000_schedule_poll只是對於TYPE_DM9000E類型的網卡進行了一個HZ*2的延時調用。那麼dm9000_schedule_poll什麼時候被調用呢,函數dm9000_open和dm9000_poll_work中都存在。我們再來總結一下,我們在本函數中調用了函數dm9000_schedule_poll,在dm9000_schedule_poll中調用了schedule_delayed_work函數,而這個函數又可以讓函數dm9000_poll_work得到執行,那麼只要網絡是up的,dm9000_poll_work每隔一段時間就會執行一次。

發佈了26 篇原創文章 · 獲贊 21 · 訪問量 20萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章