当前位置: 首页 > news >正文

Linux USB Host-Controller的初始化代码框架分析【转】

转自:http://blog.csdn.net/zkami/article/details/2496770

usb_hcd_omap_probe (const struct hc_driver *driver) (dev/ohci/ohci-omap.c)
在模块初始化时被platform_driver_register()调用,用来初始化与ohci_hcd_omap_driver
相匹配的usb主控制器.
->usb_create_hcd(driver);   创建一个代表host-controller的数据结构(struct usb_hcd)并初始化 core/hcd.h 
        ->hcd = kzalloc(sizeof(*hcd) + driver->hcd_priv_size, GFP_KERNEL); 为struct usb_hcd分配一块内存  
        ->usb_bus_init (struct usb_bus *bus); (hcd.c) 初始化代表usb bus的数据结构(struct usb_bus)
        ->初始化struct usb_hcd的定时器,工作队列
->填充struct usb_hcd的rsrc_start字段:host-controller memory/io的起始物理地址
    rsrc_len字段:host-controller memory/io的长度
    regs字段:host-controller memory/io映射的内核虚拟地址。
->ohci_hcd_init(struct ohci_hcd *ohci);    (dev/ohci/ohci-mem.c)
->usb_add_hcd(struct usb_hcd *hcd,unsigned int irqnum, unsigned long irqflags)    (/core/hcd.h)
    完成struct usb_hcd剩余的初始化工作
        ->hcd_buffer_create(hcd):创建dmapool
        ->usb_register_bus(usb_bus):注册usb bus
        ->usb_alloc_dev(NULL, &hcd->self, 0): (core/usb.c)
            处理主控制器hcd上的根Hub(hcd->self.root_hub),这里做的就是为Root Hub申请了一个struct                usb_device结构体,并且初始化, 将返回值赋给指针rhdev. Root Hub的parent指针指向了Controller本身.
        ->ohci_omap_init:完成omap硬件的init工作  
            ->otg_get_transceiver();
            ->otg_set_host(ohci->transceiver, &ohci_to_hcd(ohci)->self);    
                针对OTG特性进行的初始化,后面分析
            ->ohci_init(struct ohci_hcd *ohci); (host/ohci-hcd.c)
                    ->为ohci->hcca分配空间
                    ->ohci_mem_init() 创建ohci->td_cache和ohci->ed_cache的dma_pool
        ->request_irq(irqnum, &usb_hcd_irq, irqflags,hcd->irq_descr, hcd)
           注册中断处理函数.其中中断号是irqnum, 中断服务程序是usb_hcd_irq(struct usb_hcd *hcd) (ohci-hcd.c).
           根据usb2.0 spec定义的中断类型有:usb_hcd_irq()根据具体类型执行相应操作,后面分析.
           #define OHCI_INTR_SO    (1 << 0)    /* scheduling overrun */
           #define OHCI_INTR_WDH    (1 << 1)    /* writeback of done_head */
           #define OHCI_INTR_SF    (1 << 2)    /* start frame */
           #define OHCI_INTR_RD    (1 << 3)    /* resume detect */
           #define OHCI_INTR_UE    (1 << 4)    /* unrecoverable error */
           #define OHCI_INTR_FNO    (1 << 5)    /* frame number overflow */
           #define OHCI_INTR_RHSC    (1 << 6)    /* root hub status change */
           #define OHCI_INTR_OC    (1 << 30)    /* ownership change */
           #define OHCI_INTR_MIE    (1 << 31)    /* master interrupt enable */
        ->ohci_omap_start(struct usb_hcd *hcd):启动OHCI
              ->ohci_run(struct ohci_hcd *ohci) (ohci-hcd.c)
                  Start an OHCI controller, set the BUS operational resets USB and controller
                  enable interrupts 根据spec写相应寄存器来启动OHCI HC
              ->ohci_stop(struct usb_hcd *hcd)
                  ohci_run失败的话,释放一些资源和已申请的中断, 释放ohci的ed/td cache以及ohci-hcca
        ->register_root_hub(struct usb_hcd) (core/hcd.c)
              ->usb_set_device_state(usb_device, usb_device_state)
                 是roothub的话仅将new_state赋给udev->state,否则根据usb_device_state作不同处理
              ->usb_get_device_descriptor(usb_dev, USB_DT_DEVICE_SIZE) 获取roothub的设备描述符
                      ->usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, size);返回设备描述符,后面分析
              ->usb_new_device(usb_dev)       配置并注册usb设备 (hub.c)
                      ->usb_configure_device(udev); (hub.c)    读取设备的配置信息
                          ->usb_get_configuration(udev);
                          ->usb_cache_string() 读取设备以下三个信息(字符描述符):product, manufacturer, serial
                          ->usb_configure_device_otg(udev);
                      ->usb_autoresume_device(udev->parent);  建立usb设备的父子关系
                      ->device_add(&udev->dev);   
                         注册usb设备: 将设备加载到总线上(添加到总线的设备队列中),并为该设备搜索与之匹配的驱动
                      ->usb_set_device_state(udev, USB_STATE_NOTATTACHED);
              ->usb_hc_died (hcd);
        ->usb_hcd_poll_rh_status(usb_hcd)    hcd.c
            获取“根Hub状态变化”的具体信息,并将该信息递交给usb_hcd->status_urb
                ->ohci_hub_status_data(usb_hcd, buf)
                    首先: 读取根Hub"状态变化信息",并将其存放于buffer中
                      ->ohci_root_hub_state_changes(ohci, changed, any_connected);
                      根据主控制器在设备接入前的状态(如SUSPEND),将主控制器状态设置为中断发生后的下一状态(如OPERATION), 并判断根Hub是否需要继续轮询(poll_rh等于表示需要继续轮询)
                          ->ohci_rh_suspend(ohci, 1);  pm方面以后分析
                          ->ohci_rh_resume(ohci);      pm方面以后分析
                          ->usb_hcd_resume_root_hub(ohci_to_hcd(ohci));    pm方面以后分析
                    然后: 将保存于buffer中的root hub"状态变化信息"传递给usb_hcd->status_urb并将该urb提交给root hub驱动层
                -> usb_hcd_unlink_urb_from_ep()
                -> usb_hcd_giveback_urb()
                -> mod_timer() 调整roothub定时器使其再次进入定时器队列

转载于:https://www.cnblogs.com/sky-heaven/p/4992204.html

相关文章:

  • request和request.form和request.querystring的区别
  • 【小窍门】浏览器兼容圆角Border-radius的问题
  • intellij (org.jdom.input.JDOMParseException) Error on line 1: 前言中不允许有内容。
  • 需求工程-软件需求模式读书笔记3
  • TCPdump抓包命令详解--摘
  • JavaScript中事件处理
  • 指令汇B新闻客户端开发(六) 浅谈屏幕适配解决方案
  • 重磅推荐:Android_JNI整套视频分享
  • ReactiveCocoa概念解释进阶篇
  • Application.EnableVisualStyles();
  • 【转】.Net高级技术——IDisposable
  • [转]通过脚本添加登陆/注销/开机/关机脚本
  • 学习 AngularJS (三) module
  • Json序列化之.NET开源类库Newtonsoft.Json
  • C/C++ 库函数 是否调用 WinAPI
  • Google 是如何开发 Web 框架的
  • const let
  • DataBase in Android
  • ES10 特性的完整指南
  • es6
  • Invalidate和postInvalidate的区别
  • maya建模与骨骼动画快速实现人工鱼
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • React-生命周期杂记
  • Redis 懒删除(lazy free)简史
  • Spring核心 Bean的高级装配
  • 分享几个不错的工具
  • 给第三方使用接口的 URL 签名实现
  • 聊聊spring cloud的LoadBalancerAutoConfiguration
  • 入口文件开始,分析Vue源码实现
  • 数组的操作
  • 源码安装memcached和php memcache扩展
  • 终端用户监控:真实用户监控还是模拟监控?
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • (1)安装hadoop之虚拟机准备(配置IP与主机名)
  • (22)C#传智:复习,多态虚方法抽象类接口,静态类,String与StringBuilder,集合泛型List与Dictionary,文件类,结构与类的区别
  • (4)事件处理——(2)在页面加载的时候执行任务(Performing tasks on page load)...
  • (zhuan) 一些RL的文献(及笔记)
  • (第61天)多租户架构(CDB/PDB)
  • (二)Eureka服务搭建,服务注册,服务发现
  • (二)hibernate配置管理
  • (二开)Flink 修改源码拓展 SQL 语法
  • (算法设计与分析)第一章算法概述-习题
  • .NET Remoting学习笔记(三)信道
  • .NET/C# 解压 Zip 文件时出现异常:System.IO.InvalidDataException: 找不到中央目录结尾记录。
  • .NET国产化改造探索(一)、VMware安装银河麒麟
  • .Net开发笔记(二十)创建一个需要授权的第三方组件
  • .NET框架
  • .project文件
  • @Autowired和@Resource的区别
  • [1525]字符统计2 (哈希)SDUT
  • [8481302]博弈论 斯坦福game theory stanford week 1
  • [AMQP Connection 127.0.0.1:5672] An unexpected connection driver error occured
  • [C++]四种方式求解最大子序列求和问题
  • [English]英语积累本