您的位置:首页 > 其它

DM9000网卡驱动源码分析系列01 - platform总线

2015-12-07 14:58 337 查看
驱动的作用是使能,让设备工作,如果是网卡设备,就是能通过网卡设备收发包

对于内核来说有通用的收发包回调函数

驱动开发人员为特定的网卡开发驱动程序,然后注册回调函数到内核,这样这个特定的设备就得到内核支持

也就是说这个操作系统能通过这类网卡进行上网通信

驱动的开发也是分层的

每个设备都是自己特定的板级信息(board_info),这些信息包含生产商,生产编号,mac地址等等

如果驱动跟这些板级信息绑定在一起就会导致驱动程序要根据板级信息的改变而改变,失去了通用性

所以提出了驱动的软件架构

驱动 -- 总线 -- 设备(包含板级信息)

驱动只管驱动,设备只管设备,总线负责匹配设备和驱动,驱动则以标准途径拿到板级信息

platform就是这样的总线,它为驱动和设备都定义了规范,只要都按照规范执行,驱动和设备就能匹配

(kernel).callbacks <==> (driver).functions <======(platform).match/.probe======> (device).board_info

static int dm9000_drv_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct net_device *ndev = platform_get_drvdata(pdev);
struct board_info *db;

if (ndev) {
db = netdev_priv(ndev);
db->in_suspend = 1;

if (!netif_running(ndev))
return 0;

netif_device_detach(ndev);

/* only shutdown if not using WoL */
if (!db->wake_state)
dm9000_shutdown(ndev);
}
return 0;
}

static int dm9000_drv_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct net_device *ndev = platform_get_drvdata(pdev);
struct board_info *db = netdev_priv(ndev);

if (ndev) {
if (netif_running(ndev)) {
/* reset if we were not in wake mode to ensure if
* the device was powered off it is in a known state */
if (!db->wake_state) {
dm9000_init_dm9000(ndev);
dm9000_unmask_interrupts(db);
}

netif_device_attach(ndev);
}

db->in_suspend = 0;
}
return 0;
}

static const struct dev_pm_ops dm9000_drv_pm_ops = {
.suspend = dm9000_drv_suspend,
.resume = dm9000_drv_resume,
};

#ifdef CONFIG_OF
static const struct of_device_id dm9000_of_matches[] = {
{ .compatible = "davicom,dm9000", },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, dm9000_of_matches);
#endif

static struct platform_driver dm9000_driver = {
.driver = {
.name = "dm9000",
.pm = &dm9000_drv_pm_ops,
.of_match_table = of_match_ptr(dm9000_of_matches),
},
.probe = dm9000_probe,
.remove = dm9000_drv_remove,
};

module_platform_driver(dm9000_driver);

MODULE_AUTHOR("Sascha Hauer, Ben Dooks");
MODULE_DESCRIPTION("Davicom DM9000 network driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("platform:dm9000");platform总线对驱动的规范就是填充一个 struct platform_driver 结构体,然后调用 module_platform_driver()函数注册
如果有匹配的设备插入到系统,probe回调会被调用,反之,如果设备从系统中移除,remove回调函数会被调用

.name .of_match_table都是为了匹配设备与驱动,.of_match_table是设备树(device tree)模型的匹配

.pm是电源管理操作,休眠和恢复操作,因为CMOS电路中的功耗与电压的平方成正比,与频率成正比,为了降低功耗,在休眠时可以采取一些操作

.probe .remove将在后续章节分析
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: