【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 }

【linux驱动分析】之dm9000驱动分析(七):dm9000的卸载挂起和恢复以及打开和停止,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。