midio驱动
来源:互联网 发布:淘宝卫浴好店 编辑:程序博客网 时间:2024/06/07 07:26
linux网络设备—mdio总线
2013年09月17日 ⁄ 综合 ⁄ 共 2575字 ⁄ 字号 小 中 大 ⁄ 评论关闭
<iframe id="iframeu1788635_0" src="http://pos.baidu.com/acom?rdid=1788635&dc=2&di=u1788635&dri=0&dis=0&dai=2&ps=236x1165&dcb=BAIDU_UNION_define&dtm=BAIDU_DUP_SETJSONADSLOT&dvi=0.0&dci=-1&dpt=none&tsr=0&tpr=1455863629875&ti=linux%E7%BD%91%E7%BB%9C%E8%AE%BE%E5%A4%87%E2%80%94mdio%E6%80%BB%E7%BA%BF%20%7C%20%E5%AD%A6%E6%AD%A5%E5%9B%AD&ari=1&dbv=2&drs=1&pcs=1879x891&pss=1879x256&cfv=17&cpl=18&chi=1&cce=true&cec=UTF-8&tlm=1455834829&ltu=http%3A%2F%2Fwww.xuebuyuan.com%2F1722839.html&ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3DXj4k2CEgYRC13eeGTTCNGffhPsDvLGk-XMmMLBQEDdKw8UiKBEV6B2O4cUtaA82C%26wd%3D%26eqid%3De9ea931e000230b90000000356c6b6a9&ecd=1&psr=1920x1080&par=1920x1040&pis=-1x-1&ccd=32&cja=true&cmi=42&col=zh-CN&cdo=-1&tcn=1455863630&qn=90a9d0aa836d9116&tt=1455863629859.109.3245.3245" width="336" height="280" align="center,center" vspace="0" hspace="0" marginwidth="0" marginheight="0" scrolling="no" frameborder="0" allowtransparency="true" style="margin: 0px; padding: 0px; border-width: 0px; background-color: transparent; vertical-align: bottom;"></iframe>
一.结构体
[cpp] view plain copyprint?
- struct mii_bus {
- const char *name; //总线名
- char id[MII_BUS_ID_SIZE]; //id
- void *priv; //私有数据
- int (*read)(struct mii_bus *bus, int phy_id, int regnum); //读方法
- int (*write)(struct mii_bus *bus, int phy_id, int regnum, u16 val); //写方法
- int (*reset)(struct mii_bus *bus); //复位
- struct mutex mdio_lock;
- struct device *parent; //父设备
- enum {
- MDIOBUS_ALLOCATED = 1,
- MDIOBUS_REGISTERED,
- MDIOBUS_UNREGISTERED,
- MDIOBUS_RELEASED,
- } state; //总线状态
- struct device dev; //设备文件
- struct phy_device *phy_map[PHY_MAX_ADDR]; //PHY设备数组
- u32 phy_mask;
- int *irq; //中断
- };
struct mii_bus {const char *name;//总线名char id[MII_BUS_ID_SIZE];//idvoid *priv;//私有数据int (*read)(struct mii_bus *bus, int phy_id, int regnum);//读方法int (*write)(struct mii_bus *bus, int phy_id, int regnum, u16 val);//写方法int (*reset)(struct mii_bus *bus);//复位struct mutex mdio_lock;struct device *parent;//父设备enum {MDIOBUS_ALLOCATED = 1,MDIOBUS_REGISTERED,MDIOBUS_UNREGISTERED,MDIOBUS_RELEASED,} state;//总线状态struct device dev;//设备文件struct phy_device *phy_map[PHY_MAX_ADDR];//PHY设备数组u32 phy_mask;int *irq;//中断};
二.初始化过程
在phy_init函数中调用了mdio_bus_init初始化mdio总线
[cpp] view plain copyprint?
- int __init mdio_bus_init(void)
- {
- int ret;
- ret = class_register(&mdio_bus_class); //注册设备类
- if (!ret) {
- ret = bus_register(&mdio_bus_type); //注册mdio总线
- if (ret)
- class_unregister(&mdio_bus_class);
- }
- return ret;
- }
int __init mdio_bus_init(void){int ret;ret = class_register(&mdio_bus_class);//注册设备类if (!ret) {ret = bus_register(&mdio_bus_type);//注册mdio总线if (ret)class_unregister(&mdio_bus_class);}return ret;}
设备类"/sys/class/mdio_bus"
[cpp] view plain copyprint?
- static struct class mdio_bus_class = {
- .name = "mdio_bus",
- .dev_release = mdiobus_release,
- };
static struct class mdio_bus_class = {.name= "mdio_bus",.dev_release= mdiobus_release,};
总线类型"/sys/bus/mdio"
[cpp] view plain copyprint?
- struct bus_type mdio_bus_type = {
- .name = "mdio_bus",
- .match = mdio_bus_match, //匹配方法
- .pm = MDIO_BUS_PM_OPS,
- };
- EXPORT_SYMBOL(mdio_bus_type);
struct bus_type mdio_bus_type = {.name= "mdio_bus",.match= mdio_bus_match,//匹配方法.pm= MDIO_BUS_PM_OPS,};EXPORT_SYMBOL(mdio_bus_type);
三.mdio总线注册
1.调用mdiobus_alloc函数分配内存
[cpp] view plain copyprint?
- struct mii_bus *mdiobus_alloc(void)
- {
- struct mii_bus *bus;
- bus = kzalloc(sizeof(*bus), GFP_KERNEL); //分配内存
- if (bus != NULL)
- bus->state = MDIOBUS_ALLOCATED;
- return bus;
- }
- EXPORT_SYMBOL(mdiobus_alloc);
struct mii_bus *mdiobus_alloc(void){struct mii_bus *bus;bus = kzalloc(sizeof(*bus), GFP_KERNEL);//分配内存if (bus != NULL)bus->state = MDIOBUS_ALLOCATED;return bus;}EXPORT_SYMBOL(mdiobus_alloc);
2.填充mii_bus的结构体成员
[cpp] view plain copyprint?
- mii_bus->name = ;
- mii_bus->read = ;
- mii_bus->write = ;
- mii_bus->reset = ;
- mii_bus->parent = ;
- mii_bus->priv = ;
- mii_bus->id = ;
mii_bus->name = ;mii_bus->read = ;mii_bus->write= ;mii_bus->reset= ;mii_bus->parent= ;mii_bus->priv = ;mii_bus->id= ;
3.注册mii_bus
[cpp] view plain copyprint?
- int mdiobus_register(struct mii_bus *bus)
- {
- int i, err;
- if (NULL == bus || NULL == bus->name || NULL == bus->read ||NULL == bus->write)
- return -EINVAL;
- BUG_ON(bus->state != MDIOBUS_ALLOCATED &&bus->state != MDIOBUS_UNREGISTERED);
- bus->dev.parent = bus->parent;
- bus->dev.class = &mdio_bus_class; //总线设备类"/sys/bus/mdio_bus"
- bus->dev.groups = NULL;
- dev_set_name(&bus->dev, "%s", bus->id); //设置总线设备名
- err = device_register(&bus->dev); //注册设备文件
- if (err) {
- printk(KERN_ERR "mii_bus %s failed to register\n", bus->id);
- return -EINVAL;
- }
- mutex_init(&bus->mdio_lock);
- if (bus->reset)
- bus->reset(bus); //总线复位
- for (i = 0; i < PHY_MAX_ADDR; i++) {
- if ((bus->phy_mask & (1 << i)) == 0) {
- struct phy_device *phydev;
- phydev = mdiobus_scan(bus, i); //扫描phy设备
- if (IS_ERR(phydev)) {
- err = PTR_ERR(phydev);
- goto error;
- }
- }
- }
- bus->state = MDIOBUS_REGISTERED; //状态设置为已注册
- pr_info("%s: probed\n", bus->name);
- return 0;
- error:
- while (--i >= 0) {
- if (bus->phy_map[i])
- device_unregister(&bus->phy_map[i]->dev);
- }
- device_del(&bus->dev);
- return err;
- }
- EXPORT_SYMBOL(mdiobus_register);
int mdiobus_register(struct mii_bus *bus){int i, err;if (NULL == bus || NULL == bus->name || NULL == bus->read ||NULL == bus->write)return -EINVAL;BUG_ON(bus->state != MDIOBUS_ALLOCATED &&bus->state != MDIOBUS_UNREGISTERED);bus->dev.parent = bus->parent;bus->dev.class = &mdio_bus_class;//总线设备类"/sys/bus/mdio_bus"bus->dev.groups = NULL;dev_set_name(&bus->dev, "%s", bus->id);//设置总线设备名err = device_register(&bus->dev);//注册设备文件if (err) {printk(KERN_ERR "mii_bus %s failed to register\n", bus->id);return -EINVAL;}mutex_init(&bus->mdio_lock);if (bus->reset)bus->reset(bus);//总线复位for (i = 0; i < PHY_MAX_ADDR; i++) {if ((bus->phy_mask & (1 << i)) == 0) {struct phy_device *phydev;phydev = mdiobus_scan(bus, i);//扫描phy设备if (IS_ERR(phydev)) {err = PTR_ERR(phydev);goto error;}}}bus->state = MDIOBUS_REGISTERED;//状态设置为已注册pr_info("%s: probed\n", bus->name);return 0;error:while (--i >= 0) {if (bus->phy_map[i])device_unregister(&bus->phy_map[i]->dev);}device_del(&bus->dev);return err;}EXPORT_SYMBOL(mdiobus_register);
调用了mdiobus_scan函数
[cpp] view plain copyprint?
- struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr)
- {
- struct phy_device *phydev;
- int err;
- phydev = get_phy_device(bus, addr); //获取创建phy设备
- if (IS_ERR(phydev) || phydev == NULL)
- return phydev;
- err = phy_device_register(phydev); //注册phy设备
- if (err) {
- phy_device_free(phydev);
- return NULL;
- }
- return phydev;
- }
- EXPORT_SYMBOL(mdiobus_scan);
struct phy_device *mdiobus_scan(struct mii_bus *bus, int addr){struct phy_device *phydev;int err;phydev = get_phy_device(bus, addr);//获取创建phy设备if (IS_ERR(phydev) || phydev == NULL)return phydev;err = phy_device_register(phydev);//注册phy设备if (err) {phy_device_free(phydev);return NULL;}return phydev;}EXPORT_SYMBOL(mdiobus_scan);
动态地创建了PHY设备
四.mii、mdio、phy、mac关系图
阅读全文
0 0
- midio驱动
- 驱动
- 驱动
- 驱动
- 驱动
- 驱动
- 驱动
- 驱动
- 驱动
- 驱动
- Linux 驱动--ADC驱动
- Linux 驱动--ADC驱动 .
- Linux驱动---按键驱动
- Linux 驱动--ADC驱动
- 驱动层-input驱动
- 《Linux驱动》驱动注册
- linux驱动--LED驱动
- i2c驱动--驱动框架
- 解决Mysql错误[1040]Too many connections
- 观察者模式
- [UVA1626]Brackets sequence(dp)
- ubuntu17.04 Linux install xmapp zentao
- OkHttp Wiki翻译(四)使用说明
- midio驱动
- LeetCode 3. Longest Substring Without Repeating Characters [Medium]
- Java 代码规范,你应该知道的一些工具和用法
- 数据库更新总结
- python中join()函数讲解
- 数据库更新总结二
- 多态、接口
- 创造者模式
- <c:catch>标签的简单使用