革命尚未成功,继续看我们的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,那么就说明又出错了,仍然只能是返回

 

 

10kzalloc():双重功能函数,kmalloc 并且 memset改内存