24、去抖动技术
原则上,spec规定,只有持续了100ms的插入才算真正的插入,或者说才算稳定的插入.hub_port_debounce 就是干这件事情的,这个函数会让你至少等待 100ms,如果设备依然在,那说明稳定了;
25、printk_ratelimit: 是 printk 的变种,printk_ratelimit 的用途就是当你某条消息可能会重复的被多次打印的,甚至极限情况下,打印个成千上万条,直接导致日志文件溢出,把别的信息都冲掉了,所以这样是不好的,于是进化出来一个 printk_ratelimit(),它会控制打印消息的频率,如果短期内连续出现打印消息,那么它把消息抛弃,这种情况下这个函数返回 0,所以,只有返回非 0值的情况下才会真正打印.
26、hub是如何去实现调用设备提供的probe接口:
首先:一个usb设备申请内存空间,设置它的状态,把它复位,为它设置地址,获取它的描述符,然后就向设备模型中添加这么一个设备,再然后会为这个设备寻找它的驱动程序,再然后驱动程序提供的 probe()函数就会被调用.
从 usb 这边来说,只要调用 device_add 这么一个函数向设备模型核心层添加设备就够了,剩下的事情设备模型层会去处理,这就是设备模型的优点,所以也叫统一的设备模型.就是说不管你是 pci 还是 usb还是 scsi,
总线驱动的工作:是申请并建立总线的数据结构,
设备驱动的工作:是往这条总线上注册,调用 driver_add,
而设备这边也是一样,也往该总线上注册,即调用 device_add.而driver_add 就会在总线上寻找每一个设备,如果找到了自己支持的设备,并且该设备没有和别的驱动相绑定,那么就绑定它.反过来,设备这边的做法也一样,device_add 在总线上寻找每一个设备驱动,找到了合适的就绑定它.最后,调用 probe 函数,然后兵权就交给了设备驱动.整个这个过程就叫做 usb 设备初始化
27、endpoint 0(SET_CONFIG_TRIES)
endpoint 0.0号端点是usb spec 中一个特殊的端点;
usb spec中是这样规定的,所有的USB设备都有一个默认的控制管道.英文叫Default Control Pipe.与这条管道对应的端点叫做0号端点,也就是传说中的 endpoint zero.这个端点的信息不需要纪录在配置描述符里,就是说并没有一个专门的端点描述符来描述这个 0 号端点,因为不需要,原因是 endpoint zero 基本上所有的特性都是在 spec 规定好了的;
maximum packet size:每个端点都有这么一个特性,即告诉你该端点能够发送或者接收的包的最大值.
对于通常的端点来说,这个值被保存在该端点描述符中的 wMaxPacketSize 这一个 field,
对于端点 0,由于它自己没有一个描述符,而每个设备又都有这么一个端点,所以这个信息被保存在了设备描述符里,所以我们在设备描述符里可以看到这么一项, ,而且 spec 还规定了,这个值只能是 8,16,32 或者 64 这四者之一,而且,如果一个设备工作在高速模式,这个值还只能是 64,取别的值都不行.
Linux vs Windows to get bMaxPacketSize0
Linux:
max packet size只能是8,16,32或者64,这也就是说,至少你得是8吧,而我们惊人的发现,设备描述符公共是 18 个bytes,其中,第 byte7 恰恰就是 bMaxPacketSize0,byte0到 byte7 算起来就是 8个字节,那也就是说,我先读8个字节,然后设备返回 device descriptor
的前8个字节,于是我就知道它真正的max packet size了,于是我再读一次,这次才把整个描述
符 18 个字节都给读出来,不就 ok 了吗?我靠,写代码的你们他妈的太有才了.
Windows:
直接发送64个字节的请求过去,即要求你设备返回64个字节过来,如果你设备端点0的max packet size是32或者64,那么你反正只要把18个字节的设备描述传递过来就可以了,但是如果你设备端点 0的 max packet size就是 8或者 16,而设备描述符是 18个字节,一次肯定传递不完,那么你必然是传递了一次以后还等待着继续传递,但是我从驱动角度来说,我只要获得了 8 个字节就够了,而对于设备,你不是等着继续传吗,我直接对你做一次reset,让你复位,这样不就清掉了你剩下的想传的数据了么?然后我获得了前 8个字节我就可以知道你真正的 max packet size,然后我就按这个真正的最大值来进行下面的传输,首先就是获得你那个 18 个字节的真正的完整的设备描述符.这样子,也就达到了目的了.这就是 Windows下面的处理方法.
本文转自 曾永刚 51CTO博客,原文链接:http://blog.51cto.com/zyg0227/557040