分析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 }
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 }
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 }
它會做與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 }