1066 if (retval == 0) 1067 printk(KERN_INFO "USB Mass Storage support registered.\n"); 1068 1069 return retval; 1070 } 1071 1072 static void __exit usb_stor_exit(void) 1073 { 1074 US_DEBUGP("usb_stor_exit() called\n"); 1075 1076 /* Deregister the driver 1077 * This will cause disconnect() to be called for each 1078 * attached unit 1079 */ 1080 US_DEBUGP("-- calling usb_deregister()\n"); 1081 usb_deregister(&usb_storage_driver) ; 1082 } 1083 10 1084 module_init(usb_stor_init); 1085 module_exit(usb_stor_exit); 其实,module_init/module_exit 只是一个宏,通常写模块的人为了彰显自己的个性,会给自 己的初始化函数和注销函数另外起个名字,比如这里module_init(usb_stor_init)以及 module_exit(usb_stor_exit)实际上就是告诉这个世界,真正的函数是usb_stor_init 和 usb_stor_exit.这种伎俩在Linux 内核代码中屡见不鲜.见多了也就不必大惊小怪了,天要下雨 娘要嫁人,随她去吧.我们下面当然就从usb_stor_init 正式开始我们的探索之旅. 外面的世界很精彩 看代码之前,我曾经认真的思考过这么一个问题,我需要关注的仅仅是drivers/usb/storage/目 录下面那相关的3000 多行代码吗?就是这样几个文件就能让一个个不同的U盘在Linux 下面工 作起来吗? 像一开始那样把这个目录比作一个小城的话,也许,城里的月光很漂亮,她能够把人的 梦照亮,能够温暖人的心房.但我们真的就能厮守在这个城里,一生一世吗? 很不幸,问题远不是这样简单.外面的世界很精彩,作为U 盘,她需要与usb core 打交道,需要与 scsi core 打交道,需要与内存管理单元打交道,还有内核中许许多多其它模块打交道.外面的世 界 很大,远比我们想象的大. 什么是usb core?她负责实现一些核心的功能,为别的设备驱动程序提供服务,比如申请内存,比 如实现一些所有的设备都会需要的公共的函数,事实上,在usb 的世界里,一个普通的设备要正常 的工作,除了要有设备本身以外,还需要有一个叫做控制器的冬冬,老外把它叫做host controller, 和这个控制器相连接在一起的有另一个咚咚,她叫root hub,hub 我们应该不会陌生,在大学里, 有的宿舍里网口有限,但是我们这一代人上大学基本上是每人一台电脑,所以网口不够,于是有人 会使用hub,让多个人共用一个网口,这是以太网上的hub,而usb 的世界里同样有hub,其实原 理是一样的,任何支持usb 的电脑不会说只允许你只能一个时刻使用一个usb 设备,比如你插入 了u 盘,你同样还可以插入usb 键盘,还可以再插一个usb 鼠标,因为你会发现你的电脑里并不
只 是一个usb 接口.这些口实际上就是所谓的hub 口.而现实中经常是让一个usb 控制器和一个 hub 绑定在一起,专业一点说叫集成,而这个hub 也被称作root hub,换言之,和usb 控制器绑 定 在一起的hub就是系统中最根本的hub,其它的hub可以连接到她这里,然后可以延伸出去,外接 别的设备,当然也可以不用别的hub,让usb 设备直接接到root hub 上.hub 干嘛用的我们知道 了,那么usb host controller 本身是干什么用的呢?controller,控制器,顾名思义,用于控制,控 制什么,控制所有的usb 设备的通信.通常计算机的cpu 并不是直接和usb 设备打交道,而是和 控 制器打交道,他要对设备做什么,他会告诉控制器,而不是直接把指令发给设备,然后控制器再去负 责处理这件事情,他会去指挥设备执行命令,而cpu 就不用管剩下的事情,他还是该干嘛干嘛去, 控制器替他去完成剩下的事情,事情办完了再通知cpu.否则让cpu 去盯着每一个设备做每一件 事情,那是不现实的,那就好比让一个学院的院长去盯着我们每一个本科生上课,去管理我们的出 勤,只能说,不现实.所以我们就被分成了几个系,通常院长有什么指示直接跟各系领导说就可以 了, 如果他要和三个系主任说事情,他即使不把三个人都召集起来开个会,也可以给三个人各打一个 电话,打完电话他就忙他自己的事情去了,比如去和他带的女硕士风花雪月.而三个系主任就会去 安排下面的人去执行具体的任务,完了之后他们就会像院长汇报. 所以,Linux 内核开发者们,专门写了一些代码,并美其名曰usb core.时代总在发展,当年胖杨贵 妃照样迷死唐明皇,而如今人们欣赏的则是林志玲这样的魔鬼身材.同样,早期的Linux 内核,其 结 构并不是如今天这般有层次感,远不像今天这般错落有致,那时候drivers/usb/这个目录下边放 了很多很多文件,usb core 与其他各种设备的驱动程序的代码都堆砌在这里,后来,怎奈世间万 千 的变幻,总爱把有情的人分两端.于是在drivers/usb/目录下面出来了一个core 目录,就专门放 11 一些核心的代码,比如初始化整个usb 系统,初始化root hub,初始化host controller 的代码, 再后来甚至把host controller 相关的代码也单独建了一个目录,叫host 目录,这是因为usb host controller 随着时代的发展,也开始有了好几种,不再像刚开始那样只有一种,所以呢,设计 者们把一些host controller 公共的代码仍然留在core 目录下,而一些各host controller 单独 的代码则移到host 目录下面让负责各种host controller 的人去维护,常见的host controller 有三种,分别叫做EHCI,UHCI,OHCI,所以这样,出来了三个概念,usb core,usb host,usb device,即原本是一家人,却被活生生的分成了两岸三地...的确,现实总是很无奈,然而,心若知道 灵犀的方向,哪怕不能够朝夕相伴?没错,usb 通信的灵魂就是usb 协议. usb 协议将是所有usb 设备和usb 主机所必须遵循的游戏规则.这种规则也很自然的体现在了代码中.于是,我们需要了 解的不仅仅是drivers/usb/storage/目录下面的冬冬,还得去了解那外面的世界,虽然,只需要 了解一点点. 未曾开始却似结束 还是回到那个初始化函数吧,usb_stor_init,看了它的代码每一个人的心中都有一种莫名的兴 奋, 因为它太短了,就那么几行,除了两个printk 语句以外,就是一个函数的调用,usb_register. printk 不用我说,每一个有志青年都该知道,就算没见过printk 也该见过printf 吧,否则的话,
- 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: 目录下执行make 了.Ok,make 之
- 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 and 26: 22 88 * @class_dev: driver model's
- Page 27 and 28: 必须给各个地方取名,完了
- 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
- Page 77 and 78:
148 /* set up data structures for t
- Page 79 and 80:
90 * @wValue: matches the USB wValu
- Page 81 and 82:
830 void *transfer_buffer, 831 int
- Page 83 and 84:
25 { 26 x->done = 0; 27 init_waitqu
- Page 85 and 86:
都会过期,我开始怀疑,在这
- Page 87 and 88:
是实际长度,要么就是不成
- Page 89 and 90:
87 258 行,usb_pipeendpoint,定义
- Page 91 and 92:
对爱你的人掘了一条无法
- Page 93 and 94:
Type: Direct-Access ANSI SCSI revis
- Page 95 and 96:
416 /* 417 * this defines our host
- Page 97 and 98:
69 * Ioctl interface 70 * 71 * Stat
- Page 99 and 100:
155 * "is this a new device" checks
- Page 101 and 102:
241 char *proc_name; 242 243 /* 244
- Page 103 and 104:
328 * True if the low-level driver
- Page 105 and 106:
可以看到这个函数的参数
- Page 107 and 108:
451 short unsigned int max_sectors;
- Page 109 and 110:
地 说明了为啥咱们要显式
- Page 111 and 112:
usb_stor_acquire_resources()函数
- Page 113 and 114:
341 } 342 343 /* reject if target !
- Page 115 and 116:
内核的核心位置,kernel/exit.c
- Page 117 and 118:
1023 dissociate_dev(us); 1024 retur
- Page 119 and 120:
917 行,再次判断设备有没有
- Page 121 and 122:
181 182 /* fail the command if we a
- Page 123 and 124:
83 struct timer_list eh_timeout; /*
- Page 125 and 126:
123 两个scsi_done,一个是struct
- Page 127 and 128:
56 jiffie count on our counter, the
- Page 129 and 130:
中 看到如下的定义: UNUSUAL_
- Page 131 and 132:
269 memcpy(data+16, us->unusual_dev
- Page 133 and 134:
一切准备好了之后,我们就
- Page 135 and 136:
238 (sg->offset + *offset) & (PAGE_
- Page 137 and 138:
所以对于那些不能相应INQUI
- Page 139 and 140:
239 行对unsigned int sglen 赋值
- Page 141 and 142:
请求,所以这里就判断abort
- Page 143 and 144:
112 case GPCMD_READ_HEADER: what =
- Page 145 and 146:
到北京,每每只有在夜深人
- Page 147 and 148:
580 /* 581 * If we have a failure,
- Page 149 and 150:
666 memcpy(srb->cmnd, old_cmnd, MAX
- Page 151 and 152:
950 struct bulk_cb_wrap *bcb = (str
- Page 153 and 154:
1034 /* get the status again */ 103
- Page 155 and 156:
426 /* store the actual length of t
- Page 157 and 158:
后她会给host 返回一个CSW.CB
- Page 159 and 160:
296 } 297 298 US_DEBUGP("-- transfe
- Page 161 and 162:
491 * scatter-gather or not, and ac
- Page 163 and 164:
迷雾重重的 Bulk 传输(五) us
- Page 165 and 166:
然后把她赋给了result.而us->
- Page 167 and 168:
而bcs->Status,标志命令执行
- Page 169 and 170:
就必须设置US_FL_IGNORE_RESIDUE
- Page 171 and 172:
485 }; 486 这是一个字符数组
- Page 173 and 174:
srb->sense_buffer 里边的东西.S
- Page 175 and 176:
一个类似的函数,名叫usb_sto
- Page 177 and 178:
这种命令应该由mid level 来
- Page 179 and 180:
Disk /dev/sda: 146.1 GB, 1461631057
- Page 181 and 182:
through to the most significant bit
- Page 183 and 184:
1192 USB_TYPE_CLASS | USB_RECIP_INT
- Page 185 and 186:
315 行,scsi_report_device_reset(),
- Page 187 and 188:
285 US_DEBUGP("No reset during disc
- Page 189 and 190:
229 /* Wait for the aborted command
- Page 191 and 192:
两个函数中需要判断它,一
- Page 193 and 194:
associate_dev()相对应.我们来
- Page 195 and 196:
束for 死循环,从而usb_stor_con
- Page 197 and 198:
317 for (i = 1; i < us->host->max_i