Hub正常工作后,主控制器就会定时询问hub是否有中断产生,当hub端口上有一个设备插入或拔除,hub就向主控制器发送urb请求,即把hub端口的变化状况告诉主控制器,这是通过urb请求来完成的,主机在处理完了这个urb后,就会调用urb所提供的完成函数,来调用hub的中断函数,即hub_irq。

 

Hub_irq是hub的中断处理函数,处理程序首先判断主控制器处理urb的结果状态,如果状态是OK的,则继续处理。

1.扫描hub的所有端口,确定是哪个端口发生了变化。端口是用位图来表示的,一个long型数据可以表示32个hub端口(每位表示一个端口),有多少个端口,就用多少位表示,而8位用一个字节表示,因此,最后的使用的位都是转化成了字节的的,比如一个hub有18个端口,则需要用18位来表示,但是一个字节只有8位,因此,需要用3个字节才能表示完。

2.调用kick_khubd函数,把当前hub加入到hub驱动队列hub_event_list中,然后唤醒hub守护进程wake_up(khubd_wait),开始解析hub发生的事情了。

3.hub_thread被唤醒后,将得到执行,hub_events也将得到执行

4.hub_events是分析hub事件的主函数,hub分析的相关内容都在这里执行。这个函数是一个大的死循环。

5.Hub_events处理流程

5.1先从hub_event_list中取出此次处理的hub节点,并把hub节点从原来的队列中删除,使之独立于任何链表,因为我们处理完事件后,hub结构体就要删除,因此不能保留在任何队列中。hub可以是根hub,也可以是接到根hub上的子hub,只是,不论是什么hub,都使用同样的守护进程了。

5.2.通过宏转换,找到hub节点对以的hub结构体,进而得到hub结构体对应的usb结构体,以及hub接口结构体usb_intfdev,得到这三个结构体是这个函数处理的关键。

5.3.锁住当前的hub树,因为hub只有一个守护进程,所有的hub都使用这个守护进程,而守护进程每次只能服务一个hub,因此,只要有一个hub在使用这个守护进程,就需要锁住,以防止其他hub的使用。

5.4.按位检索hub每个端口是否正在执行reset或resume操作,注意是从1开始检索的,位0表示整个hub的情况,如果当前端口正在执行reset或resume操作,则跳过对这端口的检查,否则,测试这个端口是否有状态改变,如果没有状态改变,也跳过此端口。

5.5.如果端口有状态改变,则判断端口是发生了什么状态的改变,有以下的状态

#define USB_PORT_STAT_C_CONNECTION    0x0001

#define USB_PORT_STAT_C_ENABLE              0x0002

#define USB_PORT_STAT_C_SUSPEND           0x0004

#define USB_PORT_STAT_C_OVERCURRENT  0x0008

#define USB_PORT_STAT_C_RESET         0x0010

 

5.6.确定有状态改变后,就开始对有改变的端口的状态进行进一步的处理,此时的处理,就要根据刚刚分析得到的各种状态,分开进行处理。

5.7.首先要确定端口是否还有设备,如果有,则要把设备删除,原因是,hub端口上有两种状态发生转换,1为端口从无设备到有设备的状态,此时设备还在认证中,因此端口不应该有设备,2是端口从有到无设备的转换,此时检测到还有设备,表示设备还没有被移除,因此,需要直接把设备disable掉。

5.8.把设备disable掉的动作,需要进行反弹的检查,一个设备至少需要100ms的时间,才能表示此状态是稳定的,因此,等100ms后再判断端口是否是disable了,就可以判断了

5.9.判断设备状态为无设备插入时,需要检测是否是端口电源被disable掉了,如果是,则需要开启端口电源,如果电源是开启的,则表示设备有误,结束判断,返回上层。

5.10.经过上面的判断,能执行到这里,表示端口是有设备插入了,此时,就需要要分析端口的状态了,对端口的分析,可以尝试4次,主要是为了排除各种干扰。

5.11.为即将到来的设备分配空间(struct usb_device),对这个即将到来的设备的设备结构体设置状态为连接状态,速度为未知,电源为hub分配给的,这些都是默认状态。

5.12.准备为设备分配地址,此时是子系统软件的操作,就是查看总线上128位位图中,哪位为0的,就选择出来,查找的方式是从上次记录的下一位开始查找,如果超过128了还没有找到,就接着从0开始查找,即如果频繁的拔插usb设备,即使只有一个设备,则每次插入,设备地址都会增加1,直到到达128后,从0接着开始,此时的设备地址,还不是设备的真实地址,因为还没有发送给设备。

5.13.复位设备,通过对设备的复位来达到使能设备的目的,此时,如果复位成功,则设备的状态将成为USB_STATE_DEFAULT状态,主控制器就可以通过控制端口获得设备的描述符符,通过对设备描述符的解析,可以得到设备的速度,从而可以根据速度猜测控制端口的空间大小。

5.14.得到控制端点的大小后,就开始准备往控制端点发送urb请求,获得设备的真正的设备描述符。

5.15.获得设备描述符时分两种模式,新模式和旧模式,每种模式最多试两次,每次可以最多读三回端口。对于新模式,需要分配一个64字节的空间,用于接收从设备返回的设备描述符。通过获得的设备描述符来判断端口的类别是不是确实是设备类别的,如果是,则只需要读取一次端口,就可以判断是设备描述符了,把描述符中记录的端口的空间大小给刚刚申请的空间的对应字节赋值了。

5.16.复位设备,准备给设备设置刚刚系统选择好,但还没有设置的那个地址,这个设置可以最多尝试设置两次,之间要停留200ms。

5.17.一旦设置成功,就要把设备的状态转变为地址状态(USB_STATE_ADDRESS),同时把控制端口0给disable掉,这样,这个端口上的urb链表都被清除了。

5.18.如果新的模式能走到这里,就表明新模式成功的获得了设备描述符了,因此旧模式就不要试了,而旧模式是分两次来获得设备的描述符的,第一次是发送要求获得8字节的urb请求,经过这个请求得到的数据,就可以知道设备的端口大小到达是多大,再按照获得的端口大小,获得端口的真实的设备描述符。

5.19.接下来,就要开始把这个设备加入设备模式中去了(usb_new_device)。

5.20.首先,要获得设备的配置描述符,注意,只有设备才有配置,接口,端口都是没有配置的,接口有设置。设备有多少个配置,就要分配多少个配置的空间,用于接收,而有多少个配置,已经在设备描述符中获得了,这时只需要从设备中读取就可以。

5.21.设置配置描述符指针,同样有多少个配置多少个这样的指针

5.22.一个配置描述符有9个字节,此时需要分配出这个空间,用于接收从设备中读回的配置描述符。

5.23.循环读取设备中的配置描述符,并把读回的数据放在设备结构体中的相应位置,之后,从配置中获得接口数,接口设置,以及接口下面的端点,通通都是在这里分析的,好长的几个函数。

5.24.接着,把设备添加到设备模型中去,这部分工作由设备模型完成,主要包括完成了设备链表的添加,和查找设备驱动程序的,此处是设备的驱动,usb系统只有一个设备驱动,而且是系统已经做好的,当设备里的接口被添加时,我们的编写的驱动,就是在这里被调用,用来判断驱动是否符合设备的了。

5.25.扫描设备的所有配置,选择最优的当前配置,再用选中的这个配置去设置设备。

5.26.到此,设备的配置,设置,什么都配置妥当了,系统就可以正常的使用设备了。 

Usb设备驱动3:root hub守护进程2相关推荐

  1. WDF开发USB设备驱动教程(1)

    PDF下载地址(1.2版):链接地址 CY001开发板讨论帖:链接地址 注:本文档新版本已出,请在博客中查找,或下载PDF全文文档. 链接地址WDF开发USB设备驱动教程 by 张佩 文档说明 作者写 ...

  2. Linux设备驱动之usb设备驱动详解

    原文地址:http://blog.csdn.net/chenjin_zhong/article/details/6329316 1.Linux usb设备驱动框架 USB是通用串行总线的总称,Linu ...

  3. 第八章 USB 设备驱动移植

    8.1 USB协议     USB协议系统主要组成,总线拓扑结构,内部层次关系,数据流模式,USB调度等等         8.1.1 主要组成部分             USB的连接部分,USB的 ...

  4. Linux usb设备驱动

    原文地址:http://blog.csdn.net/chenjin_zhong/article/details/6329316 1.Linux usb设备驱动框架 USB是通用串行总线的总称,Linu ...

  5. Linux设备驱动:USB设备驱动

    1.Linux设备驱动 设备驱动时操作系统内核和机器硬件之间的接口,为应用程序屏蔽了硬件的细节,由一组函数和一些私有数据组成,结构体内包含设备驱动所需要的所有资源,即驱动器对象所拥有的属性及成员.应用 ...

  6. Linux usb设备驱动详解

    1.Linux usb设备驱动框架 USB是通用串行总线的总称,Linux内核几乎支持所有的usb设备,包括键盘,鼠标,打印机,modem,扫描仪.Linux的usb驱动分为主机驱动与gadget驱动 ...

  7. 浅谈Linux USB设备驱动

    1.USB基础介绍 1-1.USB硬件接口介绍 USB接口在硬件上总共有四根线组成VCC.D+.D-.GND,通过计算D+和D-的差值来确定数据.USB设备在传输速率上可以分为低速(1.5Mbps). ...

  8. 71 linux usb设备驱动

    usb接口有大,小口之分 usb有主机(host,大口)/设备(otg, 小口)工作模式 usb主机可以主动去操作设备, 主机接口由4根线(vcc, gnd, d+, d-) usb设备被主机操作, ...

  9. linux usb驱动 probe,linux USB设备驱动之2:usb设备的probe全过程

    本文将详细讲述2.6.22下的一个USB设备插上linux系统的PC后是如何一步一步调到我们的usb设备驱动的probe函数的,我们知道我们的USB驱动的probe函数中的一个参数是interface ...

最新文章

  1. Eclipse 无限编译Invoking 'Maven Project Builder'导致卡主
  2. html5/css3响应式页面开发总结
  3. 微软自夸Edge浏览器的电源效率
  4. Tomcat7性能优化
  5. CentOS 7 安装并启动Nginx
  6. Python PyCharm利用PyQt5使QPlainTextEdit支持拖放文件,类提升,重写QPlainTextEdit类
  7. JavaScript范围介绍
  8. java中引用数组_javaOO——引用数组
  9. iOS输入框禁止输入emoji表情
  10. mysql配置数据库的不同权限用户
  11. 和利时dcs系统服务器设置,和利时DCS系统组态流程
  12. 【Centos7】配置网卡之添加vlan tag(vlan 标签)
  13. 【企业为什么要进行数字化转型】之数字时代新模式
  14. 高级英语(张汉熙版)第一册学习笔记(原文及全文翻译)——8 - But What‘s a Dictionary For?(词典的用途究竟何在?)
  15. 1]解决java.util.concurrent.RejectedExecutionException
  16. 汇编语言程序设计-贺利坚-专题视频课程
  17. python嵩天课后题答案第三章_python语言程序设计基础(嵩天)第三章课后习题部分个人练习...
  18. CCNP——EIGRP认证
  19. 飞思卡尔 Target Speed Change Detected - New Speed 16.00MHz解决方案
  20. Bribe the Prisoners SPOJ - GCJ1C09C

热门文章

  1. ISA2006标准版无人值守安装
  2. [导入]java快速开发平台ajf之ORM组件
  3. 面试题—Mysql篇
  4. Android魔法(第二弹)——一步步实现淹没、展开效果
  5. 很好的PHP分页类(调试过)
  6. ESP8266 wifi干扰、钓鱼实现
  7. BigDecimal的用法
  8. You are running Composer with SSL/TLS protection disabled.
  9. C++笔记(2017/2/9)
  10. maven打包项目的时候找不到jar包,但是项目里面改已经有相关jar包