革命尚未成功,继续看我们的HUB
1、 usb设备能够使用条件:一个是 usbcore,这就是核心模块,另一个是主机控制器的驱动程序
usb host controller.一个是 echi的,三个是uhci,就是host controller 的接口;
hub:叫做集线器(设备与host control)
2、 root hub:
Root Hub 上可以连接别的设备,可以连接 U 盘,可以连接usb 鼠标,同样也可以连接另一个 hub.所谓 hub,就是用来级连;
通常做芯片的同志们会把 Host Controller 和 Root Hub 集成在一起.特别是 PC 主机上,通常你就只能看到接口,看不到 Root Hub
subsys_initcall(usb_init)的意思就是告诉我们 usb_init 是我们真正的初始化函数,而 usb_exit()将是整个 usb 子系统的结束时的清理函数.
3、 你必须明白,当初 storage_probe()被调用是发生在 usb-storage 模块被加载了并且检测到了有设备插入之后的情况下,也就是说有两个前提,
第一个 usb-storage 被加载了,
第二个设备插入了被检测到了,
于是storage_probe()被调用.
而 hub,说她特别,我可绝不是忽悠你.hub 本身就是两种,一种是普通
的hub,一种是root hub.对于普通hub,它完全可能也是和U盘一样,在某个时刻被你插入,然后
这种情况下hub_probe被调用,但是对于root hub就不需要这么多废话了,root hub肯定是有的,只要你有host controller,就一定会有 root hub,所以hub_probe()基本上是很自然的就被调用了,不用说非得等待某个插入事件的发生,没这个必要.
4、 事实上,每一次调用 kthread_run()之后,我们都会用一个IS_ERR()来判断指针是否有效. kthread_run()也会申请内存,但非kmalloc申请的内存 ,IS_ERR()为1就表示指针有错,或者准确一点说叫做指针无效. 每次调用完 kthread_run()之后要用 IS_ERR()来检测一下返回的指针.如果IS_ERR()返回值是0,那么说明没有问题,于是return 0,也就是说usb_hub_init()就这么结束了.
5、 内核指针:有三种情况,一种是有效指针,一种是 NULL,空指针,一种是错误指针,或者说无效指针.而所谓的错误指针就是指其已经到达了最后一个page.
比如对于32bit的系统来说,内核空间最高地址 0xffffffff,那么最后一个 page 就是指的 0xfffff000~0xffffffff(假设4k一个page).这段地址是被保留的,一般人不得越雷池半步,如果你发现你的一个指针指向这个范围中的某个地址,那么恭喜你,你的代码肯定出错了.
6、 IS_ERR():对于Linux内核来说,不管任何体系结构,最多最多,错误号不会超过 4095.而 4095 又正好是比 4k 小 1,即 4096 减 1.而我们知道一个page可能是4k,这里的 IS_ERR(),它就是判断 kthread_run()返回的指针是否有错,如果指针并不是指向最后一个 page,那么没有问题,申请成功了,如果指针指向了最后一个 page,那么说明实际上这不是一个有效的指针,这个指针里保存的实际上是一种错误代码.而通常很常用的方法就是先用IS_ERR()来判断是否是错误,然后如果是,那么就调用PTR_ERR()来返回这个错误代码
7、 Hup驱动的思想:
总分总结构,
A:先设置一个链表,hub_event_list,设置一个总的函数hub_events(),这是总,
B:然后每一个 hub 都有一个 event_list,每当有一个 hub 的 event_list出现了变化,就把它的 event_list 插入到 hub_event_list 中来,这是分,
C:然后触发总函数hub_events(),这又是总,然后在 hub_events()里又根据 event_list 来确定是哪个 struct usb_hub,或者说是哪个 hub 有事情,又针对该 hub 进行具体处理,这又是分.
这就是 Linux 中hub驱动的中心思想
8、 TIF 就是 thread info 的意思,众所周知,struct task_struct 是一个表示进程的结构体,而除此之外,又有一个叫做struct thread_info的结构体来代表内核线程
9、 Endpoint.spec规定了hub就是一个endpoint,中断endpoint,因为hub的传输是中断传输.当然还有控制传输,但是因为控制传输是每一个设备都必须支持的,即每一个usb 设备都会有一个控制端点,所以在 desc->desc.bNumEndpoints 中是不包含那个大家都有的控制端点的.因此如果这个值不为 1,那么就说明又出错了,仍然只能是返回
10、kzalloc():双重功能函数,kmalloc 并且 memset改内存