ICode9

精准搜索请尝试: 精确搜索
首页 > 系统相关> 文章详细

linux 内核 usb驱动分析

2019-09-21 10:03:15  阅读:706  来源: 互联网

标签:dwc3 usb hub probe 接口 内核 linux 设备


本文基于ti的am5728平台,4.14.79版本内核,DesignWare USB3.0方案,xhci主机控制器。简单分析 USB 主机控制器驱动 根 Hub 的注册过程,以及 USB设备的枚举过程,并不涉及USB协议,单纯分析驱动框架流程。无论是hub还是普通的usb设备,它们注册到 usb_bus_type 都会经历两次 Match ,因为第一次注册进来时,是将整个设备作为一个 device 注册,然后在通用的 devices 驱动程序 usb_generic_driver 的 generic_probe 函数中,将该设备的所有接口进行设置并将这些接口注册到 usb_bus_type 。如果是Hub设备的接口,则会调用 hub_probe,如果是其他设备则调用 xx_probe 函数。如果是 Hub 的话,usb主机会监测hub端口变化,如果有变化会分配一个usb_devices 注册到 usb_bus_type 重复前边的步骤。

omap wc3设备树节点 

		omap_dwc3_1: omap_dwc3_1@48880000 {
			compatible = "ti,dwc3";
			ti,hwmods = "usb_otg_ss1";
			reg = <0x48880000 0x10000>;
			interrupts = <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
			#address-cells = <1>;
			#size-cells = <1>;
			utmi-mode = <2>;
			ranges;
			usb1: usb@48890000 {
				compatible = "snps,dwc3";
				reg = <0x48890000 0x17000>;
				interrupts = <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
					     <GIC_SPI 71 IRQ_TYPE_LEVEL_HIGH>,
					     <GIC_SPI 72 IRQ_TYPE_LEVEL_HIGH>;
				interrupt-names = "peripheral",
						  "host",
						  "otg";
				phys = <&usb2_phy1>, <&usb3_phy1>;
				phy-names = "usb2-phy", "usb3-phy";
				maximum-speed = "super-speed";
				dr_mode = "host";
				snps,dis_u3_susphy_quirk;
				snps,dis_u2_susphy_quirk;
			};
		};

 

流程图:

1. 主机控制器驱动的注册。先从设备树解析注册omap_dwc3节点,与dwc3_omap_driver匹配并调用dwc3_omap_probe,dwc3_omap_probe里再解析omap_dwc3节点下的子节点usb@48890000,与dwc3_driver匹配后调用dwc3_probe,会根据usb节点配置的模式再去注册真正的usb控制器。如果是host模式,则会调用dwc3_host_init函数注册xhci主机控制器设备,与usb_xhci_driver匹配并调用xhci_plat_probe.

2. usb主机控制器驱动的probe过程,分配usb_hcd,然后添加到系统中,一个主控制器对应一条usb总线,一个主控制器绑定着一个root hub,一个root hub对应于一个usb_device,然后注册此root  hub,主要是调用usb_new_device。每个usb设备(usb_device)有一种或多种配置,每种配置有一个或多个接口,一个接口有一种或多种设置,一种设置有一个或多个端点。为了获取并解析这些描述符,usb_new_device调用usb_configure_device,然后将设备添加到内核。每个usb设备都有一个控制端点。它通常用于配置设备,获取设备信息,发送命令到设备,或者获取设备的状态报告,usb_new_device中调用了函数usb_create_ep_devs。

3. 当root hub这个usb_device添加到系统中时,系统中也有一个usb_device_driver(注意,不是usb_driver,一个是对应usb设备,一个对应usb接口)叫做usb_generic_driver,匹配上之后就会调用generic_probe,在这个函数里面调用usb_choose_configuration为设备选择一个合理的配置,到此就可以用选定配置下的所有描述符进行设备配置了。函数usb_set_configuration就是完成此项功能。在函数usb_set_configuration中将设备的所有接口都添加到内核device_add(&intf->dev)。这些接口设备的总线类型也是usb_bus_type,不过设备类型为usb_if_device_type。

4. 接口添加到系统中了,当然要匹配接口驱动。恰好系统中有一个usb_driver为hub_driver,它是为hub接口准备的。接口又分为hub的接口和usb设备的接口。如果是设备的接口,如果匹配上了后就调用probe函数,做相应的初始化、设备模型建立等工作,例如usb storage驱动,usb hid驱动。如果是hub的接口,就调用hub_probe。
 

参考:
USB主机控制器驱动——OHCI分析:https://blog.csdn.net/lizuobin2/article/details/51931161
USB驱动框架分析1:https://blog.csdn.net/xuao20060793/article/details/46530481

标签:dwc3,usb,hub,probe,接口,内核,linux,设备
来源: https://blog.csdn.net/z1026544682/article/details/101023041

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有