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 that16 * 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 end24 * up dumping the wake events if we disable this. There is already25 * 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 }