1006 size_t bytes; 1007 1008 /* 1009 * members below are private to usbcore, 1010 * and are not provided for driver access! 1011 */ 1012 spinlock_t lock; 1013 1014 struct usb_device *dev; 1015 int pipe; 1016 struct scatterlist *sg; 1017 int nents; 1018 1019 int entries; 1020 struct urb **urbs; 1021 1022 int count; 1023 struct completion complete; 1024 }; 整个usb 系统都会使用这个数据结构,如果我们希望使用scatter gather 方式的话.usb core 已经为 我们准备好了数据结构和相应的函数,我们只需要调用即可.一共有三个函数,她们是 usb_sg_init,usb_sg_wait,usb_sg_cancel.我们要提交一个sg 请求,需要做的是,先用usb_sg_init 来 初始化请求,然后usb_sg_wait()正式提交,然后我们该做的就都做了.如果想撤销一个sg 请求,那么调用 usb_sg_cancel 即可. 咱们虽说不用仔细去看着三个函数内部是如何实现的,但至少得知道该传递什么参数吧.不妨来仔细看一 下usb_sg_init()被调用时传递给她的参数.头一个刚才已经说了,就是sg request,第二个,需要告诉她是 哪个usb设备要发送或接收数据,咱们给她传递的是us->pusb_dev,第三个,是哪个pipe,这个没什么好说 的,pipe 是上面一路传下来的.第四个参数,这是专门适用于中断传输的,被传输中断端点的轮询率,对于 165 bulk 传输,直接忽略,所以咱们传递了0.第五个和第六个参数就分别是sg 数组和sg 数组中元素的个数.然 后第七个参数,length,传递的就是咱们希望传输的数据长度,最后一个是SLAB flag,内存申请相关的一个 flag.如果驱动程序处于block I/O 路径中应该使用GFP_NOIO,咱们这里SLAB_NOIO 实际上是一个宏, 实际上就是GFP_NOIO.不要问我为什么用SLAB_NOIO 或者说GFP_NOIO,无可奉告.(如果你真的想知 道为什么的话,回去看当初我们是如何调用usb_submit_urb()的,理由当时就已经讲过了.)这个函数成功 返回值为0,否则返回负的错误码.初始化好了之后就可以为us->flags 设置US_FLIDX_SG_ACTIVE 了, 对这个flag 陌生吗?还是回去看usb_submit_urb(),当时我们也为urb 设置了这么一个 flag,US_FLDX_URB_ACTIVE,其实历史总是惊人的相似.当初我们对待urb 的方式和如今对待sg request 的方式几乎一样.所以其实是很好理解的. 对比一下当初调用usb_submit_urb()的代码,就会发现464 到471 这一段我们不会陌生,当年咱们提 交urb 之前就有这么一段,usb_stor_msg_common()函数中,只不过那时候是urb 而不是sg,这两段代 码之间何其的相似!只是年年岁岁花相似,岁岁年年人不同啊!然后474 行,usb_sg_wait()函数得到调用. 她所需要的参数就是sg request 的地址,咱们传递了us->current_sg 的地址给她.这个函数结 束,US_FLIDX_SG_ACTIVE 这个flag 就可以clear 掉了.返回值被保存在us->current_sg.status 中,
然后把她赋给了result.而us->current_sg.bytes 保存了实际传输的长度,把她赋给*act_len,然后返回 之前,once more,调用interpret_urb_result()转换一下结果. 最后,usb_stor_bulk_transfer_sg()函数返回之前还做了一件事,将剩下的长度赋值给了 *residual.*residual 是形参,实参是&srb->resid.而最终usb_stor_bulk_transfer_sg()返回的值就 是 interpret_urb_result()翻译过来的值.但是需要明白的一点是,这个函数的返回就意味着Bulk 传输中的 关键阶段,即数据阶段的结束.剩下一个阶段就是状态阶段了,要传递的是CSW,就像当初传递CBW 一样. 回到usb_stor_Bulk_transport()函数中来,判断结果是否为USB_STOR_XFER_ERROR 或者 USB_STOR_XFER_LONG,前者表示出错,这没啥好说的.而后者表示设备试图发送的数据比咱们需要的 数据要多,这种情况咱们使用一个fake sense data 来向上层汇报,出错了,但是和一般的出错不一样的是, 告诉上层,这个命令别再重发了.fake_sense 刚开始初始化为0,这里设置为1,后面将会用到.到时候再看. 目前只需要知道的是,这种情况并不是不存在,实际上usb mass storage bulk-only spec 里边就定义了 这种情况,spec 说了对这种情况,下一个阶段还是要照样进行.至于设备干嘛要这样做,那就只有天知道了, 就是说你明明只是对他说,”给我十块钱”,他却硬塞给你一百块钱.(我只是打个比方,别做梦了.)文雅一点说, 这叫,原想采撷一枚红叶,你却给了我整个的枫林. 最后, 解释一点,USB_STOR_XFER_LONG 只是我们自己定义的一个宏, 实际上是由 interpret_urb_result()翻译过来的,真正的从usb core 那一层传递过来的结果是叫做-EOVERFLOW, 这一点在interpret_urb_result 函数中能找到对应关系.-EOVERFLOW 我们就常见了,顾名思义,就是溢 出. 最后的最后,再解释一点,实际上usb core 这一层做的最人性化的一点就是对urb 和对sg 的处理了.写 代码的人喜欢把数据传输具体化为request,urb 和sg 都被化作request,即请求.而usb core 的能耐就 是 让你写设备驱动的人能够只要申请一个请求,调用usb core 提供的函数进行初始化,然后调用usb core 提 供的函数进行提交,这些步骤都是固定的,完全就像使用傻瓜照相机一样,然后进程可以睡眠,或者可以干别 的事情,完事之后usb core 会通知你.然后你就可以接下来干别的事情了.我做一个比方,就好比你考四六 级, 找了一个枪手,让他去给你考,你只要告诉他你的基本信息,把你的准考证给他,然后你就不用管别的什么了, 剩下的事情他会去处理,然后你也不用担心完事之后他不会通知你,这简直是不容置疑的,因为你还没给钱 呢. 明白了不,小朋友? 166 迷雾重重的 Bulk 传输(六) 接下来咱们该看看如何处理CSW 了.1018 行,usb_stor_bulk_transfer_buf()函数再一次被调用,这 次是获得CSW,期望长度是US_BULK_CS_WRAP_LEN,这个宏来自 drivers/usb/storage/transport.h 中: 109 #define US_BULK_CS_WRAP_LEN 13 13 对应CSW 的长度,13 个bytes.而cswlen 记录了实际传输的长度.1025 行,如果返回值是 USB_STOR_XFER_SHORT,表明数据传少了,没有达到我们期望的那么多,而假如cswlen 又等于0,那么 说明没有获得真正的CSW,正如注释所说,有些变态的设备会在数据阶段末尾多加一些0 长度的包进来,这 就意味着咱们并没有获得CSW,于是重新执行一次usb_stor_bulk_transfer_buf(),再获得一次.(旁白: 数据传输失败了可以重来一次,你我失去的青春能重来一次么?唉,人生没有彩排,天天都是现场直播.) 1032 行,如果result 等于USB_STOR_XFER_STALLED,在interpret_urb_result 中查找一
- 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 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: 迷雾重重的 Bulk 传输(五) 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