【linux驅動分析】之dm9000驅動分析(七):dm9000的卸載掛起和恢復以及打開和停止

分析dm9000的卸載,掛起和恢復,以及dm9000的打開和停止。涉及到的函數爲:
 1 static int __devexit
 2   dm9000_drv_remove(struct platform_device *pdev)
 3 static int
 4  dm9000_drv_suspend(struct device *dev)
 5 static int
 6  dm9000_drv_resume(struct device *dev)
 7 static int
 8  dm9000_open(struct net_device *dev)
 9 static int
10  dm9000_stop(struct net_device *ndev)
一、卸載驅動
驅動中可以看到,在模塊卸載時執行
platform_driver_unregister(&dm9000_driver);
在卸載platform_driver時會執行remove函數,remove函數的功能是把設備從內核中移除,釋放內存區域。下面給出dm9000_drv_remove函數的代碼:
 1 static int __devexit
 2 dm9000_drv_remove(struct platform_device *pdev)
 3 {
 4     struct net_device *ndev = platform_get_drvdata(pdev);
 5 
 6     platform_set_drvdata(pdev, NULL);
 7 
 8     unregister_netdev(ndev);
 9     dm9000_release_board(pdev, netdev_priv(ndev));
10     free_netdev(ndev);        /* free device structure */
11 
12     dev_dbg(&pdev->dev, "released and freed device\n");
13     return 0;
14 }
15 
16 
17 /* dm9000_release_board
18  *
19  * release a board, and any mapped resources
20  */
21 
22 static void
23 dm9000_release_board(struct platform_device *pdev, struct board_info *db)
24 {
25     /* unmap our resources */
26 
27     iounmap(db->io_addr);
28     iounmap(db->io_data);
29 
30     /* release the resources */
31 
32     release_resource(db->data_req);
33     kfree(db->data_req);
34 
35     release_resource(db->addr_req);
36     kfree(db->addr_req);
37 }
二、關於電源管理的設備的掛起和恢複函數

suspend函數並不真正把設備從內核中移除,而只是標誌設備爲removed狀態,並設置掛起標誌位爲1,最後關閉設備。

resume函數將掛起的設備復位並初始化,軟後將設備標誌爲attached狀態,並設置掛起標誌位爲0。

 1 static int
 2 dm9000_drv_suspend(struct device *dev)
 3 {
 4     struct platform_device *pdev = to_platform_device(dev);
 5     struct net_device *ndev = platform_get_drvdata(pdev);
 6     board_info_t *db;
 7 
 8     if (ndev) {
 9         db = netdev_priv(ndev);
10         db->in_suspend = 1;
11 
12         if (!netif_running(ndev))
13             return 0;
14 
15         netif_device_detach(ndev);
16 
17         /* only shutdown if not using WoL */
18         if (!db->wake_state)
19             dm9000_shutdown(ndev);
20     }
21     return 0;
22 }
23 
24 static int
25 dm9000_drv_resume(struct device *dev)
26 {
27     struct platform_device *pdev = to_platform_device(dev);
28     struct net_device *ndev = platform_get_drvdata(pdev);
29     board_info_t *db = netdev_priv(ndev);
30 
31     if (ndev) {
32         if (netif_running(ndev)) {
33             /* reset if we were not in wake mode to ensure if
34              * the device was powered off it is in a known state */
35             if (!db->wake_state) {
36                 dm9000_reset(db);
37                 dm9000_init_dm9000(ndev);
38             }
39 
40             netif_device_attach(ndev);
41         }
42 
43         db->in_suspend = 0;
44     }
45     return 0;
46 }

三、dm9000的打開和停止

1、打開函數dm9000_open
 1 /*
 2  *  Open the interface.
 3  *  The interface is opened whenever "ifconfig" actives it.
 4  */
 5 static int
 6 dm9000_open(struct net_device *dev)
 7 {
 8     board_info_t *db = netdev_priv(dev);
 9     unsigned long irqflags = db->irq_res->flags & IRQF_TRIGGER_MASK;
10 
11     /* db結構體中的成員msg_enble,在probe函數中賦值爲NETIF_MSG_LINK */
12     if (netif_msg_ifup(db))
13         dev_dbg(db->dev, "enabling %s\n", dev->name);
14 
15     /* If there is no IRQ type specified, default to something that
16      * may work, and tell the user that this is a problem */
17 
18     if (irqflags == IRQF_TRIGGER_NONE)
19         dev_warn(db->dev, "WARNING: no IRQ resource flags set.\n");
20 
21     irqflags |= IRQF_SHARED;
22     /* 申請中斷,中斷函數dm9000_interrupt */
23     if (request_irq(dev->irq, dm9000_interrupt, irqflags, dev->name, dev))
24         return -EAGAIN;
25 
26     /* GPIO0 on pre-activate PHY, Reg 1F is not set by reset */
27     iow(db, DM9000_GPR, 0);    /* REG_1F bit0 activate phyxcer */
28     mdelay(1); /* delay needs by DM9000B */
29 
30     /* Initialize DM9000 board */
31     dm9000_reset(db);
32     /* dm9000初始化,下面會對這個函數做詳細分析 */
33     dm9000_init_dm9000(dev);
34 
35     /* Init driver variable */
36     db->dbug_cnt = 0;
37 
38     /* 檢查mii接口 
39      * Returns 1 if the duplex mode changed, 0 if not.
40      * If the media type is forced, always returns 0.
41      * */
42     mii_check_media(&db->mii, netif_msg_link(db), 1);
43     /* 開啓網絡接口數據發送隊列 */
44     netif_start_queue(dev);
45     /*延時一段時間執行dm9000_poll_work,原來在probe函數裏把這個函數加入了工作隊列,現在來調度執行*/
46     dm9000_schedule_poll(db);
47 
48     return 0;
49 }
2、dm9000_init_dm9000函數
 1 /*
 2  * Initialize dm9000 board
 3  */
 4 static void
 5 dm9000_init_dm9000(struct net_device *dev)
 6 {
 7     board_info_t *db = netdev_priv(dev);
 8     unsigned int imr;
 9     unsigned int ncr;
10 
11     dm9000_dbg(db, 1, "entering %s\n", __func__);
12 
13     /* I/O mode */
14     db->io_mode = ior(db, DM9000_ISR) >> 6;    /* ISR bit7:6 keeps I/O mode */
15 
16     /* Checksum mode */
17     dm9000_set_rx_csum_unlocked(dev, db->rx_csum);
18 
19     iow(db, DM9000_GPCR, GPCR_GEP_CNTL);    /* Let GPIO0 output */
20 
21     ncr = (db->flags & DM9000_PLATF_EXT_PHY) ? NCR_EXT_PHY : 0;
22 
23     /* if wol is needed, then always set NCR_WAKEEN otherwise we end
24      * up dumping the wake events if we disable this. There is already
25      * a wake-mask in DM9000_WCR */
26     if (db->wake_supported)
27         ncr |= NCR_WAKEEN;
28 
29     iow(db, DM9000_NCR, ncr);
30 
31     /* Program operating register */
32     iow(db, DM9000_TCR, 0);            /* TX Polling clear */
33     iow(db, DM9000_BPTR, 0x3f);    /* Less 3Kb, 200us */
34     iow(db, DM9000_FCR, 0xff);    /* Flow Control */
35     iow(db, DM9000_SMCR, 0);        /* Special Mode */
36     /* clear TX status */
37     iow(db, DM9000_NSR, NSR_WAKEST | NSR_TX2END | NSR_TX1END);
38     iow(db, DM9000_ISR, ISR_CLR_STATUS); /* Clear interrupt status */
39 
40     /* Set address filter table */
41     dm9000_hash_table_unlocked(dev);
42 
43     imr = IMR_PAR | IMR_PTM | IMR_PRM;
44     if (db->type != TYPE_DM9000E)
45         imr |= IMR_LNKCHNG;
46 
47     db->imr_all = imr;
48 
49     /* Enable TX/RX interrupt mask */
50     iow(db, DM9000_IMR, imr);
51 
52     /* Init Driver variable */
53     db->tx_pkt_cnt = 0;
54     db->queue_pkt_len = 0;
55     dev->trans_start = jiffies;
56 }
3、停止函數dm9000_stop
它會做與dm9000_stop相反的事情。
 1 /*
 2  * Stop the interface.
 3  * The interface is stopped when it is brought.
 4  */
 5 static int
 6 dm9000_stop(struct net_device *ndev)
 7 {
 8     board_info_t *db = netdev_priv(ndev);
 9 
10     if (netif_msg_ifdown(db))
11         dev_dbg(db->dev, "shutting down %s\n", ndev->name);
12 
13     cancel_delayed_work_sync(&db->phy_poll);
14 
15     netif_stop_queue(ndev);
16     netif_carrier_off(ndev);
17 
18     /* free interrupt */
19     free_irq(ndev->irq, ndev);
20 
21     dm9000_shutdown(ndev);
22 
23     return 0;
24 }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章