简介

上一节整体介绍了usb host框架,分析了其中的phy层。这一节我们分析usb 框架中的hcd层。Exynos 4412的USB 2.0的 Host Controller包含USB 2.0 EHCI Host Controller和 USB 1.1 OHCI Host Controller,我这里只讲EHCI Host Controller。

框架图

hcd层以stuct usb_hcd为核心。它主要有两个功能,一个是通过ehci_hcd去操作phy层,一个是通过hc_driver去操作上层传递下来的urb数据包。

hcd

先来看下hcd相关的dts

# exynos4.dtsi
exynos_usbphy: exynos-usbphy@125B0000 {compatible = "samsung,exynos4210-usb2-phy";reg = <0x125B0000 0x100>;samsung,pmureg-phandle = <&pmu_system_controller>;clocks = <&clock CLK_USB_DEVICE>, <&clock CLK_XUSBXTI>;clock-names = "phy", "ref";#phy-cells = <1>;status = "disabled";
};
# exynos4412.dtsi
&exynos_usbphy {compatible = "samsung,exynos4x12-usb2-phy";samsung,sysreg-phandle = <&sys_reg>;
};
# exynos4412-tiny4412.dts
&exynos_usbphy {status = "okay";
};
# exynos4.dtsi
ehci: ehci@12580000 {compatible = "samsung,exynos4210-ehci";reg = <0x12580000 0x100>;interrupts = <GIC_SPI 70 IRQ_TYPE_LEVEL_HIGH>;clocks = <&clock CLK_USB_HOST>;clock-names = "usbhost";status = "disabled";#address-cells = <1>;#size-cells = <0>;
//exynos_ehci_get_phy中of_property_read_u32(child, "reg", &phy_number)获取到reg的值,然后作为port@0 {// 通过of_property_read_u32(child, "reg", &phy_number); 解析“reg”属性//在_of_phy_get中解析“phys”属性reg = <0>;                     //被解析成数组的下标 drv->instances[0].phyphys = <&exynos_usbphy 1>;   //1代表 hoststatus = "disabled";};port@1 {reg = <1>;                   //被解析成数组的下标 drv->instances[1].phyphys = <&exynos_usbphy 2>;   //2代表 hsci0status = "disabled";};port@2 {reg = <2>;                  //被解析成数组的下标 drv->instances[2].phyphys = <&exynos_usbphy 3>;   //3代表 hsci1status = "disabled";};
};
# exynos4412-tiny4412.dts
&ehci {status = "okay";port@0 {status = "okay";};port@1 {status = "okay";};port@2 {status = "okay";};
};

相关的驱动会匹配到/drivers/usb/host/ehci-exynos.c,来看下它的probe函数

///drivers/usb/host/ehci-hcd.c
static const struct hc_driver ehci_hc_driver = {.product_desc =       "EHCI Host Controller",/*  generic hardware linkage */.irq =         ehci_irq,....../* managing i/o requests and associated device resources */.urb_enqueue =       ehci_urb_enqueue,.urb_dequeue =        ehci_urb_dequeue,/* scheduling support*/.get_frame_number =    ehci_get_frame,/* root hub support */.hub_status_data =    ehci_hub_status_data,.hub_control =        ehci_hub_control,
};
///drivers/usb/host/ehci-exynos.c
static struct hc_driver __read_mostly exynos_ehci_hc_driver;//这个就是 struct hc_driver ehci_hc_driver
static int exynos_ehci_get_phy(struct device *dev,struct exynos_ehci_hcd *exynos_ehci)
{struct device_node *child;struct phy *phy;int phy_number;/* Get PHYs for the controller */for_each_available_child_of_node(dev->of_node, child) {ret = of_property_read_u32(child, "reg", &phy_number);//对应dts reg = <0>; reg = <1>;这些属性 phy = devm_of_phy_get(dev, child, NULL);--->//这个函数将间接使用samsung_usb2_phy_xlate来取得上一节初始化的phy---> phy = of_phy_get(np, con_id) --->--->  phy = _of_phy_get(np, index)  ---->---->   struct phy *_of_phy_get(struct device_node *np, int index){//获取到 phys = <&exynos_usbphy 1>; 后面的参数ret = of_parse_phandle_with_args(np, "phys", "#phy-cells",index, &args);//调用samsung_usb2_phy_xlatephy = phy_provider->of_xlate(phy_provider->dev, &args);   ---->--->samsung_usb2_phy_xlate(struct device *dev,struct of_phandle_args *args){ //所以dts的phys属性的参数:1代表host,2代表hsic0,3代表hsic1return drv->instances[args->args[0]].phy;}}exynos_ehci->phy[phy_number] = phy;
}
static int exynos_ehci_probe(struct platform_device *pdev)
{struct exynos_ehci_hcd *exynos_ehci;struct usb_hcd *hcd;struct ehci_hcd *ehci;hcd = usb_create_hcd(&exynos_ehci_hc_driver,    //把ehci_hc_driver赋值给hcd->driver&pdev->dev, dev_name(&pdev->dev));/* usb_hcd的priv域是ehci_hcd,然后ehci_hcd的piv域是exynos_ehci_hcd  具体关系可以看框架图*/exynos_ehci = to_exynos_ehci(hcd); err = exynos_ehci_get_phy(&pdev->dev, exynos_ehci); //获得在上一节初始化phy到struct exynos_ehci_hcderr = exynos_ehci_phy_enable(&pdev->dev);        --->---> static int exynos_ehci_phy_enable(struct device *dev) {phy_power_on(exynos_ehci->phy[i]);    ----->--->  int phy_power_on(struct phy *phy)    { /* /drivers/phy/phy-core.c */phy->ops->power_on(phy)      ---->   ----> static int samsung_usb2_phy_power_on(struct phy *phy){//到了这里就是上一节phy层的调用了,可以直接看上一节的内容。这里就是去设置寄存器}}}usb_add_hcd(hcd, irq, IRQF_SHARED) ---->---->int usb_add_hcd(struct usb_hcd *hcd,unsigned int irqnum, unsigned long irqflags){retval = usb_register_bus(&hcd->self);    //注册总线,因为hcd本身就是总线usb_hcd_request_irqs(hcd, irqnum, irqflags)request_irq(irqnum, &usb_hcd_irq, irqflags,hcd->irq_descr, hcd);        //注册中断处理函数register_root_hub --->---> usb_new_device   --->----> device_add/* * device_add之后会调用probe函数,由于这个device是个hub,所以会调用hub_probe* hub 1-0:1.0: USB hub found* hub 1-0:1.0: 3 ports detected*/}
}

总结一下,当dts到ehci driver匹配到之后会调用exynos_ehci_probe,probe函数会去创建usb_hcd,ehci_hcd和exynos_ehci_hcd,然后通过exynos_ehci_get_phy获取到在phy层初始化的phy,根据dts的指定,我这里获取到的是host、hsci0、hsci1这三个phy,然后通过phy的相关接口去使能对应的phy链路。最后把hcd添加到总线,注册它的中断处理函数,注册root hub。hub这一块我们下一节再讲。

tiny4412 linux-4.2 移植(七)USB 2.0 host框架(2)hcd(ehci主机控制器)相关推荐

  1. tiny4412 linux-4.2 移植(七)USB 2.0 host框架(1)phy

    简介 本文主要讲述usb 2.0 host 中struct phy.struct usb_hcd.struct usb_hub.struct usb_port以及struct urb之间的关系.hcd ...

  2. tiny4412 linux-4.2 移植(九)USB 2.0 host框架(4)支持otg

    由于前面支持了usb host,这里要支持otg模式就比较简单了. make menuconfig打开支持OTG | Symbol: USB_OTG [=n] || Type : bool || Pr ...

  3. linux查看usb3.0还是2.0,Linux分辨电脑是否有USB 3.0接口的命令行 怎么看电脑用独立显卡还是集成显卡...

    延伸:怎么看电脑用独立显卡还是集成显卡 描述:方法一.通过接口来判断我们在主机箱后面的接口上,看你的链接数据线的接口接上了哪个接口,如果是连接集成显卡的话那就是连接到竖的的接口上,因为集成显卡的VGA ...

  4. linux添加ax88772b驱动,佳能 USB 2.0 to Fast Ethernet AX88772B 驱动程序下载-更新佳能软件(以太网控制器)...

    ASIX USB 2.0 to Fast Ethernet AX88772B 驱动程序下载 如何手动下载和更新: 你可以通过 %%os%% 或通过执行 Windows® 更新获取基本的 USB 2.0 ...

  5. USB 2.0规范中译本 第二章 术语和缩写

    第二章 术语和缩写 本章列出并定义了本规范中使用的术语和缩写 ACK 表示肯定确认的握手数据包. Active Device 已通电但未处于挂起状态的设备. Asynchronous Data 异步数 ...

  6. USB 2.0 眼图测试

    一. USB 2.0 测试内容 USB 信号质量需要测试有:眼图测试.信号速率.包尾宽度. JK 抖动. KJ 抖动.连续抖动.单调性测试.上升下降时间,详细如下图: 二. USB 2.0 测试命令和 ...

  7. USB | 2. 最新USB 4.0规范解析及一致性测试

    Update: 2022 / 10 / 11 USB | 2. 最新USB 4.0规范解析及一致性测试 目录 背景 USB 1.0 - 4.0 Type-C 接口 拓扑结构 USB 4 USB Typ ...

  8. Linux那些事儿 之 戏说USB(24)设备的生命线(七)

    算是进入了HCD的片儿区,这里的老大不是帮派头目也不是巡逻片儿警,而是几个结构.在HCD这个片儿区,这个山头儿,王中之王就是include/linux/usb/hcd.h里定义的struct usb_ ...

  9. Linux系统移植实验---USB驱动的移植

    实验八 USB驱动的移植 [实验目的] USB接口是现在计算机系统中最通用的一种接口, 说明:在本系统移植课程实验中命令行提示符 "$"表示是在主机上执行,"#" ...

最新文章

  1. Android学习——R文件丢失异常原因汇总
  2. javacript实现不被浏览器拦截打开新窗口
  3. csu 1756(数论+去重)
  4. URAL 1152. False Mirrors(DP)
  5. 通过 GitHub Actions 自动创建 Github Release
  6. 浅淡Kubernetes 与容器技术体系的最佳方法
  7. 容器编排技术 -- Kubernetes 使用Service暴露应用
  8. 新农大计算机学院照片,【新生指南】小团带你逛校园(内附农大全景图~)
  9. 計算機二級-java-03
  10. PostgreSQL 12系统表(11)pg_user
  11. Atitit freemarker模板总结 D:\workspace\springboothelloword\src\com\attilax\util\TempleteFreemarkerUtil.
  12. WPF-使用代码创建Grid行与列,并将控件添加到Grid中的指定行指定列
  13. 数据结构—队列的C语言实现
  14. R、冗余分析(RDA)、ggplot2、置信椭圆
  15. 选购家用安防摄像头,考虑室内还是室外,无线还是有线
  16. 用css动态实现圆环百分比分配——初探css3动画
  17. Photoshop——矫正变形图像
  18. 从简历被拒到收割今日头条offer,我花了一年时间
  19. DNS服务器优化的几种方式
  20. 爬虫python书籍-python爬虫有哪些书

热门文章

  1. C#--实例选号器生成随机数
  2. AVVR电线电缆的介绍使用
  3. ViewBag 和 ViewData 的传值
  4. python做上位机读usb数据_使用python实现win10系统和arduino usb串口通信
  5. 用DIV+CSS技术设计的个人电影网站-web前端网页制作课作业---电影介绍 5页
  6. MySQL修改root用户密码
  7. 基因分子生物学~遗传信息传递与遗传密码关键
  8. 一文教会你何为重绘、回流?
  9. 数组转字符串的方法(3种)
  10. 【转】MetInfo米拓后台操作修改汇总