mdio 的匹配与探测

关键结构体定义

struct phy_device {
    struct mdio_device mdio;

}


struct phy_driver {
    struct mdio_driver_common mdiodrv;
}
struct mdio_driver_common {
    struct device_driver driver;
    int flags;
};

1.1 总线匹配函数


struct bus_type mdio_bus_type = {
        .name           = "mdio_bus",
        .match          = mdio_bus_match,
        .uevent         = mdio_uevent,
};

static int mdio_bus_match(struct device *dev, struct device_driver *drv)
{
        struct mdio_device *mdio = to_mdio_device(dev);

        if (of_driver_match_device(dev, drv)) //不会执行
                return 1;

        if (mdio->bus_match)
                return mdio->bus_match(dev, drv); //参考phy_device_create 调用

        return 0;
}

struct phy_device *phy_device_create(struct mii_bus *bus, int addr, int phy_id,

                                                        bool is_c45, struct phy_c45_device_ids *c45_ids)

{

        struct phy_device *dev;

        struct mdio_device *mdiodev;

        mdiodev = &dev->mdio;

        mdiodev->dev.parent = &bus->dev;

        mdiodev->dev.bus = &mdio_bus_type;

        mdiodev->dev.type = &mdio_bus_phy_type;

        mdiodev->bus = bus;

        mdiodev->bus_match = phy_bus_match; 匹配函数最终调用phy_bus_match

        mdiodev->addr = addr;

        ......

}

1.2. 匹配函数phy_bus_match

static int phy_bus_match(struct device *dev, struct device_driver *drv)
{
    struct phy_device *phydev = to_phy_device(dev);
    struct phy_driver *phydrv = to_phy_driver(drv);
    const int num_ids = ARRAY_SIZE(phydev->c45_ids.device_ids);
    int i;

    if (!(phydrv->mdiodrv.flags & MDIO_DEVICE_IS_PHY))
        return 0;

    if (phydrv->match_phy_device)
        return phydrv->match_phy_device(phydev);

    if (phydev->is_c45) {
        for (i = 1; i < num_ids; i++) {
            if (!(phydev->c45_ids.devices_in_package & (1 << i)))
                continue;

            if ((phydrv->phy_id & phydrv->phy_id_mask) ==
                (phydev->c45_ids.device_ids[i] &
                 phydrv->phy_id_mask))
                return 1;
        }
        return 0;
    } else {
        return (phydrv->phy_id & phydrv->phy_id_mask) ==
            (phydev->phy_id & phydrv->phy_id_mask);  //根据读取的phy_id 与phy_driver 匹配
    }
}

2.1 phy的probe 分析

       根据 phy_driver_register 函数,确定探测函数为phy_probe

int phy_driver_register(struct phy_driver *new_driver, struct module *owner)
{
    int retval;

    new_driver->mdiodrv.flags |= MDIO_DEVICE_IS_PHY;
    new_driver->mdiodrv.driver.name = new_driver->name;
    new_driver->mdiodrv.driver.bus = &mdio_bus_type;  
    new_driver->mdiodrv.driver.probe = phy_probe;

    //kernel 驱动模型,匹配后会调用probe 函数调用
    new_driver->mdiodrv.driver.remove = phy_remove;
    new_driver->mdiodrv.driver.owner = owner;

    return 0;
}

2.2 phy_probe 分析

        如果phy_driver 如果存在.probe ,会执行(一般不存在)

static int phy_probe(struct device *dev)
{
    struct phy_device *phydev = to_phy_device(dev);
    struct device_driver *drv = phydev->mdio.dev.driver;
    struct phy_driver *phydrv = to_phy_driver(drv);
    int err = 0;

    phydev->drv = phydrv;

    .......
    phydev->state = PHY_READY;

    if (phydev->drv->probe) {
        /* Deassert the reset signal */
        phy_device_reset(phydev, 0);

        err = phydev->drv->probe(phydev);
        if (err) {
            /* Assert the reset signal */
            phy_device_reset(phydev, 1);
        }
    }

    mutex_unlock(&phydev->lock);

    return err;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/9704.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

码题杯 世界警察 思想:双指针

https://www.matiji.net/exam/brushquestion/4/4446/16A92C42378232DEB56179D9C70DC45C 双指针 思路是这样的&#xff0c;首先r指针向右走&#xff0c;如果r指针遇到了和l指针一样的&#xff0c;那么l指针就&#xff0c;一直加到r指针的位置&#xff0c;此时a[l]a[r]&#xff0…

Flutter 首次亮相 Google Cloud Next 大会

作者 / Kelvin Boateng Flutter 团队在近期首次参加了 Google Cloud Next 大会&#xff0c;这意味着 Flutter 在开发社区中的影响力正在日益增长。 Google Cloud Next https://cloud.withgoogle.com/next 我们与 Google Cloud、Firebase、Very Good Ventures 和 Serverpod 的团…

双向链表(详解)

在单链表专题中我们提到链表的分类&#xff0c;其中提到了带头双向循环链表&#xff0c;今天小编将详细讲下双向链表。 话不多说&#xff0c;直接上货。 1.双向链表的结构 带头双向循环链表 注意 这几的“带头”跟前面我们说的“头节点”是两个概念&#xff0c;实际前面的在…

【大学物理】东北大学-马文蔚听课笔记

4.1刚体的定轴转动_哔哩哔哩_bilibili 此笔记为课堂学习笔记~ 4.1刚体的定轴转动 基本教学要求 什么时刚体呢&#xff1f; 研究刚体运动切口 平动&#xff1a;刚体中所有的点的运动轨迹都完全相同。 转动&#xff1a;分为&#xffe5;定轴转动和非定轴转动 刚体转动的角速度…

【Unity 2D物理系统:触发】

在Unity的2D物理系统中&#xff0c;触发器&#xff08;Trigger&#xff09;是一种特殊的碰撞检测机制&#xff0c;它允许开发者检测到物体进入或离开特定区域时发生的动作&#xff0c;而不会影响物体的实际物理运动。触发器通常用于非物理交互的场景&#xff0c;如检测玩家进入…

vue3 antd-vue 超简单方式实现a-table跨页勾选

一、效果如下&#xff1a; 第一页勾选了2&#xff0c; 3&#xff0c; 4 翻到第三页勾选24&#xff0c; 25 回显&#xff0c;如比返回第一页的时候触发分页改变&#xff0c; 在映射中的第一页的数据给到a-table绑定的state.selectedRowKeys即可&#xff0c;如下方法 二、勾选思路…

管理层、团队、效能指标 如何平衡

管理层、团队、效能指标 如何平衡 效能指标效能指标是团队成长的唯一标准吗&#xff1f;管理层、团队和效能指标之间应该保持怎样的距离&#xff1f;效能治理容易踩进哪些陷阱&#xff1f;在团队中&#xff0c;效能治理最重要的是什么&#xff1f; 在说到管理层、团队和效能指标…

Netty底层数据交互源码分析

文章目录 1. 前题回顾2. 主线流程源码分析3. Netty底层的零拷贝4. ByteBuf内存池设计 书接上文 1. 前题回顾 上一篇博客我们分析了Netty服务端启动的底层原理&#xff0c;主要就是将EventLoop里面的线程注册到了Select中&#xff0c;然后调用select方法监听客户端连接&#xf…

深入了解模拟和存根:提高单元测试质量的关键技术

一、引言 在进行单元测试时&#xff0c;我们经常会遇到对外部资源的依赖&#xff0c;如数据库、网络接口等。模拟&#xff08;Mocking&#xff09;和存根&#xff08;Stubbing&#xff09;是两种帮助我们模拟这些外部资源&#xff0c;使我们能够在隔离环境中测试单元的方法。在…

iOS面试题链接汇总

iOS开发三年经验 靠这份面试题让我从15k到25k - 简书 2021年&#xff0c;整理的iOS高频面试题及答案&#xff08;总会有你需要的&#xff09; - 知乎 iOS面试&#xff08;内含面试全流程&#xff0c;面试准备工作面试题等&#xff09;-CSDN博客 runtime: 阿里、字节 一套高效…

Java中静态代理和动态代理设计模式应用实例举例?

静态代理实例 假设我们有一个需求&#xff0c;要记录一个服务接口IService的所有方法调用的开始和结束时间&#xff0c;以此来监控服务的性能。我们可以使用静态代理模式来实现这个需求。 1. 定义服务接口 IService.java: Java 1public interface IService { 2 void serv…

分布式任务调度框架xxl-job使用手册

官网地址和文档地址&#xff1a;https://www.xuxueli.com/xxl-job/ 一、快速入门 1.1 下载源码 https://github.com/xuxueli/xxl-job https://gitee.com/xuxueli0323/xxl-job 下载完成后有以下模块 1.2 初始化数据库 官方指定mysql8.0&#xff0c;但我是mysql5.7 执行/xxl…

PyQt6--Python桌面开发(6.QLineEdit单行文本框)

QLineEdit单行文本框 import sys import time from PyQt6.QtGui import QValidator,QIntValidator from PyQt6.QtWidgets import QApplication,QLabel,QLineEdit from PyQt6 import uicif __name__ __main__:appQApplication(sys.argv)uiuic.loadUi("./QLine单行文本框.u…

Qt 6.7功能介绍

Qt 6.7为我们所有喜欢在构建现代应用程序和用户体验时获得乐趣的人提供了许多大大小小的改进。一些新增内容作为技术预览发布&#xff0c;接下来我们就一起来看看吧&#xff1a; 将C20与Qt一起使用 对于许多编译器工具链来说&#xff0c;C20仍然是可选的和实验性的&#xff0c;…

PVE 脚本工具 pve_source | Pve_Tools

pve_source 安装 wget -q -O /root/pve_source.tar.gz https://bbs.x86pi.cn/file/topic/2023-11-28/file/01ac88d7d2b840cb88c15cb5e19d4305b2.gz && tar zxvf /root/pve_source.tar.gz && /root/./pve_source 脚本加载成功出现使用协议&#xff0c;输入 Y&…

台服dnf局域网搭建,学习用笔记

台服dnf局域网搭建 前置条件虚拟机初始化上传安装脚本以及其他文件至虚拟机密钥publickey.pem客户端配置如果IP地址填写有误&#xff0c;批量修改IP地址 前置条件 安装有vmvarecentos7.6镜像&#xff1a;https://mirrors.tuna.tsinghua.edu.cn/centos-vault/7.6.1810/isos/x86…

Python注意事项【自我维护版】

各位大佬好 &#xff0c;这里是阿川的博客 &#xff0c; 祝您变得更强 个人主页&#xff1a;在线OJ的阿川 大佬的支持和鼓励&#xff0c;将是我成长路上最大的动力 阿川水平有限&#xff0c;如有错误&#xff0c;欢迎大佬指正 本篇博客在之前的博客上进行的维护 创建Python…

Day7 字符串和常用数据结构

文章目录 字符串和常用数据结构使用字符串使用列表生成式和生成器使用元组使用集合使用字典练习练习1&#xff1a;在屏幕上显示跑马灯文字。练习2&#xff1a;设计一个函数产生指定长度的验证码&#xff0c;验证码由大小写字母和数字构成。练习3&#xff1a;设计一个函数返回给…

linux下使用jexus部署aspnet站点

1.运行环境 Centos 7 安装dos2unix工具 yum install dos2unix 安装jexus curl https://jexus.org/release/x64/install.sh|sudo sh2.网站部署 2.1. 将windows下的网站发布包Msc_qingdao_admin.zip上传到linux中&#xff0c; 然后解压后放入/var/www(没有则创建)目录下 r…

福昕PDF阅读器取消手型工具鼠标点击翻页

前言&#xff1a; 本文介绍如何关闭福昕PDF阅读器取消手型工具鼠标点击翻页&#xff0c;因为这样真的很容易误触发PDF翻页&#xff0c;使用起来让人窝火。 引用&#xff1a; NA 正文&#xff1a; 新版的福昕PDF阅读器默认打开了“使用手型工具阅读文章”这个勾选项&#x…