Scsi - Index of
Scsi - Index of Scsi - Index of
131 container_of(intf->dev.parent, struct usb_device, dev) 23 嗬,贴这么长一段,怎么又是注释为主啊?知足吧,Linux 代码中注释实在是太少了,等你真的需要认真看某 一 个模块的时候你就会嫌注释少了.这个结构体是一个贯穿整个U 盘驱动程序的,所以虽然我们不用去深入了 解,但是需要记住,整个U 盘驱动程序在后面任何一处提到的struct usb_interface 都是同一个变量,这个 变量是在usb core 总线扫描的时候就申请好了的.我们只需贯彻鲁迅先生的拿来主义即可,直接用就是了. 比如前面说过的storage_probe(struct usb_interface *intf,const struct usb_device_id *id),storage_disconnect(struct usb_interface *intf)这两个函数中的那个参数intf. 而这里130 行这个宏-interface_to_usbdev,也会用得着的,顾名思义,就是从一个struct usb_interface 转换成一个struct usb_device,我们说过了,有些函数需要的参数就是struct usb_device,而不是 usb_interface,所以这种转换是经常会用到的,而这个宏,usb core 的设计者们也为我们准备好了,除了感 激,我们还能说什么呢? 从协议中来,到协议中去(下) 如果你是急性子,那这时候你一定很想开始看storage_probe 函数了,因为整个U 盘的工作就是 从这里开始的.不过,莎士比亚说过,磨刀不误砍柴功.不妨继续花点时间,至少把四大关键词中最 后一个给弄明白了, 前面我们已经了解了device,configuration,interface,还剩最后一个endpoint.USB通信的最 基本的形式就是通过endpoint,道上的兄弟管这个叫做端点,一个接口有一个或多个端点,而作 为像U 盘这样的存储设备吧,它至少有一个控制端点,两个bulk 端点.这些端点都是干嘛的?说来 话长,真是一言难尽哪. usb 协议里规定了,usb 设备有四种通信方式,分别是控制传输,中断传输,批量传输,等时传输.其 中,等时传输显然是用于音频和视频一类的设备,这类设备期望能够有个比较稳定的数据流,比如 你在网上QQ 视频聊天,肯定希望每分钟传输的图像/声音速率是比较稳定的,不能说这一分钟对 方看到你在向她向你深情表白,可是下一分钟却看见画面停滞在那里,只能看到你那傻样一动不 动,你说这不浪费感情嘛.所以,每一个有良知的男人都应该知道,usb-storage 里边肯定不会用 到等时传输.因为我们只管copy 一个文件,管它第一秒和第二秒的传输有什么区别,只要几十秒 内传完了就ok. 相比之下,等时传输是四种传输中最麻烦的,所以,U 盘里边用不着,那您就偷着乐去吧.不过我要 说,中断传输也用不着,对于U 盘来说,的确用不着,虽然说usb mass storage 的协议里边有一 个叫做CBI 的传输协议,CBI 就是Control/Bulk/Interrupt,即控制/批量/中断,这三种传输都会 用到,但这种传输协议并不适用于U 盘,U 盘使用的是一个叫做Bulk-Only 的传输协议.使用这种 协议的设备只有两种传输方式,一种是批量传输,另一种是控制传输,控制传输是任何一种usb 设 备都必须支持的,它专门用于传输一些控制信息.比如我想查询一下关于这个interface 的一些信 息,那么就用控制传输,而bulk 传输,它就是U 盘的主要工作了,读写数据,这种情况就得用bulk 传输.具体的传输我们后面再讲. 好了,知道了传输方式,就可以来认识endpoint 了.和endpoint 齐名的有一个叫做管道,或者有 文化的人管这个叫pipe.endpoint 就是通信的发送或者接收点,你要发送数据,那你只要把数据 发送到正确的端点那里就可以了.之所以U盘有两个bulk 端点,是因为端点也是有方向的,一个叫 做Bulk in,一个叫做Bulk out,从usb 主机到设备称为out,从设备到主机称为in.而管道,实际 上只是为了让我们能够找到端点,就相当于我们日常说的邮编地址,比如一个国家,为了通信,我们
必须给各个地方取名,完了给各条大大小小的路取名,比如你要揭发你们那里的官员腐败,你要去 24 上访,你从某偏僻的小县城出发,要到北京来上访,那你的这个端点(endpoint)就是北京,而你得 知道你来北京的路线,那这个从你们县城到北京的路线就算一条管道.有人好奇的问了,管道应该 有两端吧,一个端点是北京,那另一个端点呢?答案是,这条管道有些特殊,就比如上访,我们只需要 知道一端是北京,而另一端是哪里无所谓,因为不管你在哪里你都得到北京来上访.没听说过你在 山西你可以上访,你要在宁夏还不能上访了,没这事对吧. 严格来说,管道的另一端应该是usb 主机,即前面说的那个host,usb 协议里边也是这么说的,协 议里边说pipes 代表着一种能力,怎样一种能力呢,在主机和设备上的端点之间移动数据,听上去 挺玄的.因为事实上,usb 里边所有的数据传输都是有主机发起的.一切都是以主机为核心,各种设 备紧紧围绕在主机周围.所以呢,usb core 里边很多函数就是,为了让usb host 能够正确的完成 数据传输或者说传输调度,就得告诉host 这么一个pipe,换言之,它得知道自己这次调度的数据 是传送给谁或者从谁那里传输过来.不过有人又要问了,比如说我要从U 盘里读一个文件,那我告 诉usb host 某个端点能有用吗?那个文件又不是存放在一个端点里边,它不该是存放在U盘里边 吗?这个就只能在后面的代码里去知道了.实际上端点这东西是一个很虚的东西,它的身上充分体 现了我国军事思想中的声东击西的想法,即数据本身并不是在端点里,但是看上去却觉得仿佛在 端点里.这一切的谜团,让我们在storage_probe()函数里去慢慢解开吧. 梦开始的地方 对于整个usb-storage 模块,usb_stor_init()是它的开始,然而,对于U 盘驱动程序来说,它真正 驱使U 盘工作却是始于storage_probe(). 两条平行线只要相交,就注定开始纠缠一生,不管中间是否短暂分离. usbcore 为设备找到了适合 她的驱动程序,或者为驱动程序找到了他所支持的设备,但这只是表明双方的第一印象还可以,但 彼此是否真的适合对方还需要进一步的了解.毋庸置疑,了解对方的第一步是,知道她有哪些爱好, 她的生日,她的星座,喜欢吃什么,而U 盘driver 则会调用函数storage_probe()去认识对方,她 是个什么样的设备,她的生活习惯是?她的联系方式是?这里调用了四个函数 get_device_info,get_protocol,get_transport,get_pipes. 当然还有一些别人并不了解的 冬冬你也会知道,比如她的三围,这里对应的就是usb_stor_Bulk_man_lun(). 整个U 盘驱动这部大戏,由storage_probe 开始,由storage_disconnect 结束.其 中,storage_probe 这个函数占了相当大的篇幅.我们一段一段来看.这两个函数都来自 drivers/usb/storage/usb.c 中: 926 /* Probe to see if we can drive a newly-connected USB device */ 927 static int storage_probe(struct usb_interface *intf, 928 const struct usb_device_id *id) 929 { 930 struct us_data *us; 931 const int id_index = id - storage_usb_ids; 932 int result; 933 934 US_DEBUGP("USB Mass Storage device detected\n"); 935 936 /* Allocate the us_data structure and initialize the mutexes */ 937 us = (struct us_data *) kmalloc(sizeof(*us), GFP_KERNEL);
- Page 1 and 2: 摘要 ............................
- Page 3 and 4: 迷雾重重的Bulk 传输(二)....
- Page 5 and 6: 引子 也许是在复旦养成了
- Page 7 and 8: usb.h datafab.h dpcm.h initializers
- Page 9 and 10: 的Linux 内核划分为许许多
- Page 11 and 12: 目录下执行make 了.Ok,make 之
- Page 13 and 14: 只 是一个usb 接口.这些口
- Page 15 and 16: 中也定义了这么一些数据
- Page 17 and 18: 511 * @driver: the driver model cor
- Page 19 and 20: 233 .owner = THIS_MODULE, 234 .name
- Page 21 and 22: 91 * construct these entries. Each
- Page 23 and 24: 324 struct usb_host_config *actconf
- Page 25: 22 88 * @class_dev: driver model's
- Page 29 and 30: 26 136 trans_cmnd transport; /* tra
- Page 31 and 32: 944 init_MUTEX_LOCKED(&(us->sema));
- Page 33 and 34: 147 #if !defined(CONFIG_BLK_DEV_UB)
- Page 35 and 36: 124 #define USB_DEVICE_ID_MATCH_DEV
- Page 37 and 38: intf 来代替. us 之所以重要,
- Page 39 and 40: 睡眠,那就得用GPF_ATOMIC,这
- Page 41 and 42: 504 if (msg >= 0 && !(unusual_dev->
- Page 43 and 44: 179 } 180 181 static struct us_unus
- Page 45 and 46: 711 /* Submitted by Hartmut Wahl */
- Page 47 and 48: 3. useProtocol 为US_SC_DEVICE, use
- Page 49 and 50: Bus 004 Device 001: ID 0000:0000 Bu
- Page 51 and 52: 993 result = get_pipes(us); 994 if
- Page 53 and 54: 631 us->transport_reset = usb_stor_
- Page 55 and 56: 659 us->max_lun = 0; 660 break; 661
- Page 57 and 58: 740 /* Calculate and store the pipe
- Page 59 and 60: storage 会有两个bulk 端点,用
- Page 61 and 62: 比如说,复旦大学,有一个主
- Page 63 and 64: 1079 #define PIPE_ISOCHRONOUS 0 108
- Page 65 and 66: 782 us->unusual_dev->initFunction(u
- Page 67 and 68: 630 * each frame is in the fields o
- Page 69 and 70: 716 * Bulk URBs may 717 * use the U
- Page 71 and 72: 802 int number_of_packets; /* (in)
- Page 73 and 74: 先说互斥锁.它诞生于这样
- Page 75 and 76: 920 US_DEBUGP("GetMaxLUN command re
必须给各个地方取名,完了给各条大大小小的路取名,比如你要揭发你们那里的官员腐败,你要去<br />
24<br />
上访,你从某偏僻的小县城出发,要到北京来上访,那你的这个端点(endpoint)就是北京,而你得<br />
知道你来北京的路线,那这个从你们县城到北京的路线就算一条管道.有人好奇的问了,管道应该<br />
有两端吧,一个端点是北京,那另一个端点呢?答案是,这条管道有些特殊,就比如上访,我们只需要<br />
知道一端是北京,而另一端是哪里无所谓,因为不管你在哪里你都得到北京来上访.没听说过你在<br />
山西你可以上访,你要在宁夏还不能上访了,没这事对吧.<br />
严格来说,管道的另一端应该是usb 主机,即前面说的那个host,usb 协议里边也是这么说的,协<br />
议里边说pipes 代表着一种能力,怎样一种能力呢,在主机和设备上的端点之间移动数据,听上去<br />
挺玄的.因为事实上,usb 里边所有的数据传输都是有主机发起的.一切都是以主机为核心,各种设<br />
备紧紧围绕在主机周围.所以呢,usb core 里边很多函数就是,为了让usb host 能够正确的完成<br />
数据传输或者说传输调度,就得告诉host 这么一个pipe,换言之,它得知道自己这次调度的数据<br />
是传送给谁或者从谁那里传输过来.不过有人又要问了,比如说我要从U 盘里读一个文件,那我告<br />
诉usb host 某个端点能有用吗?那个文件又不是存放在一个端点里边,它不该是存放在U盘里边<br />
吗?这个就只能在后面的代码里去知道了.实际上端点这东西是一个很虚的东西,它的身上充分体<br />
现了我国军事思想中的声东击西的想法,即数据本身并不是在端点里,但是看上去却觉得仿佛在<br />
端点里.这一切的谜团,让我们在storage_probe()函数里去慢慢解开吧.<br />
梦开始的地方<br />
对于整个usb-storage 模块,usb_stor_init()是它的开始,然而,对于U 盘驱动程序来说,它真正<br />
驱使U 盘工作却是始于storage_probe().<br />
两条平行线只要相交,就注定开始纠缠一生,不管中间是否短暂分离. usbcore 为设备找到了适合<br />
她的驱动程序,或者为驱动程序找到了他所支持的设备,但这只是表明双方的第一印象还可以,但<br />
彼此是否真的适合对方还需要进一步的了解.毋庸置疑,了解对方的第一步是,知道她有哪些爱好,<br />
她的生日,她的星座,喜欢吃什么,而U 盘driver 则会调用函数storage_probe()去认识对方,她<br />
是个什么样的设备,她的生活习惯是?她的联系方式是?这里调用了四个函数<br />
get_device_info,get_protocol,get_transport,get_pipes. 当然还有一些别人并不了解的<br />
冬冬你也会知道,比如她的三围,这里对应的就是usb_stor_Bulk_man_lun().<br />
整个U 盘驱动这部大戏,由storage_probe 开始,由storage_disconnect 结束.其<br />
中,storage_probe 这个函数占了相当大的篇幅.我们一段一段来看.这两个函数都来自<br />
drivers/usb/storage/usb.c 中:<br />
926 /* Probe to see if we can drive a newly-connected USB device */<br />
927 static int storage_probe(struct usb_interface *intf,<br />
928 const struct usb_device_id *id)<br />
929 {<br />
930 struct us_data *us;<br />
931 const int id_index = id - storage_usb_ids;<br />
932 int result;<br />
933<br />
934 US_DEBUGP("USB Mass Storage device detected\n");<br />
935<br />
936 /* Allocate the us_data structure and initialize the mutexes */<br />
937 us = (struct us_data *) kmalloc(size<strong>of</strong>(*us), GFP_KERNEL);