本帖最后由 robe.zhang 于 2021-10-17 18:27 编辑
【米尔MYS-8MMX试用】linuxUSB 总线匹配规则
linux 中USB 驱动代码是通用的,跨平台架构,所有linux 上的 usb 驱动代码都是一样的。不仅仅 米尔MYS-8MMX 开发板是这样,其他 NXP imx8m 平台也是这样,其他架构的 USB 总线都是这样。本文适用于一切linux 系统,只是以米尔MYS-8MMX开发板的源码来追踪分析的
linux USB驱动框架比较复杂,比I2C、SPI,TTY 框架复杂的多,但是仍然遵循 linux 驱动模型,按照linux驱动模型一点点追踪还是可以搞明白的
本文先说 linux USB 总线设备和驱动匹配规则,追踪代码:
总线模块初始化: 第 994 行注册usb总线: 总线中仅有四个成员: 分析 usb_device_match 函数,就是匹配规则: 第 796 – 804 行:是 usbdevice 匹配规则。 第 805 – 823 行:是 usbdevice interface 匹配规则。
usb device 匹配规则: 匹配规则相当简单,简单到只要确认设备类型,驱动类型的一个参数,搞定。 并且linux 系统中只有一个 usbdriver,那就是 所有usb 设备插入电脑,usb hub会枚举并添加USB设备,usb driver 立马匹配并运行probe成员函数,使用USB设备的描述符信息注册 interface endpoint 设备。 (为什么是usb hub,不理解的可以看usb协议和usb网络拓扑) Generic_probe 函数 usb_choose_configuration 函数选择一个配置: usb_set_configuration 函数用此设置usb设备 初始化所有interfaces 设备 注册 interfaces 设备 注册 endpoint 设备: usb device interface 匹配规则 设备类型是 interfaces: 驱动也必须是 interfaces 驱动才会继续匹配,不然之间返回
匹配时先匹配 driver 的 id_table,匹配则成功直接返回 Id_table 不匹配的话,则继续匹配 dynids,匹配则成功直接返回,不匹配就失败了。 Linux usb 总线匹配规则: Usb device 和usb devicedriver 匹配,并且一定会成功。匹配结束。 Usb interfaces 和usbinterfaces driver 匹配,先匹配driver 的Id_table,成功返回,不成功继续匹配 dynids,成功返回,不成功也返回。匹配结束。
不管是 id_table 匹配,还是dynids 匹配,都调用了同一个函数 usb_match_one_id
usb_match_one_id 先用 usb 设备和 id_table 匹配,适配成功继续 interface 设备和 id_table 匹配,此过程中,任何一项适配失败,终止此过程,进入 dynids 匹配。 dynids 匹配同样调用了 usb_match_one_id函数,先用 usb 设备和 id_table 匹配,适配成功继续 interface 设备和 id_table 匹配,此过程中,任何一项适配失败,终止此过程,整个匹配过程结束,返回。 详细适配过程:
匹配过程比较杂乱,上结论: Usb 设备匹配成功的话,一定是以下两种情况,其他所有的情况都匹配不成功。 1,驱动的 id_table和device描述符匹配成功,并且和interfaces 描述符也匹配成功。 2,驱动的 dynids和device描述符匹配成功,并且和interfaces 描述符也匹配成功。 和device描述符匹配成功的话,凡是驱动中有的以下这些项,必须匹配成功,否则匹配失败:
和interfaces 描述符匹配成功的话,凡是驱动中有的以下这些项,必须匹配成功,否则匹配失败:
|