You also want an ePaper? Increase the reach of your titles
YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.
然后把她赋给了result.而us->current_sg.bytes 保存了实际传输的长度,把她赋给*act_len,然后返回<br />
之前,once more,调用interpret_urb_result()转换一下结果.<br />
最后,usb_stor_bulk_transfer_sg()函数返回之前还做了一件事,将剩下的长度赋值给了<br />
*residual.*residual 是形参,实参是&srb->resid.而最终usb_stor_bulk_transfer_sg()返回的值就<br />
是<br />
interpret_urb_result()翻译过来的值.但是需要明白的一点是,这个函数的返回就意味着Bulk 传输中的<br />
关键阶段,即数据阶段的结束.剩下一个阶段就是状态阶段了,要传递的是CSW,就像当初传递CBW 一样.<br />
回到usb_stor_Bulk_transport()函数中来,判断结果是否为USB_STOR_XFER_ERROR 或者<br />
USB_STOR_XFER_LONG,前者表示出错,这没啥好说的.而后者表示设备试图发送的数据比咱们需要的<br />
数据要多,这种情况咱们使用一个fake sense data 来向上层汇报,出错了,但是和一般的出错不一样的是,<br />
告诉上层,这个命令别再重发了.fake_sense 刚开始初始化为0,这里设置为1,后面将会用到.到时候再看.<br />
目前只需要知道的是,这种情况并不是不存在,实际上usb mass storage bulk-only spec 里边就定义了<br />
这种情况,spec 说了对这种情况,下一个阶段还是要照样进行.至于设备干嘛要这样做,那就只有天知道了,<br />
就是说你明明只是对他说,”给我十块钱”,他却硬塞给你一百块钱.(我只是打个比方,别做梦了.)文雅一点说,<br />
这叫,原想采撷一枚红叶,你却给了我整个的枫林.<br />
最后, 解释一点,USB_STOR_XFER_LONG 只是我们自己定义的一个宏, 实际上是由<br />
interpret_urb_result()翻译过来的,真正的从usb core 那一层传递过来的结果是叫做-EOVERFLOW,<br />
这一点在interpret_urb_result 函数中能找到对应关系.-EOVERFLOW 我们就常见了,顾名思义,就是溢<br />
出.<br />
最后的最后,再解释一点,实际上usb core 这一层做的最人性化的一点就是对urb 和对sg 的处理了.写<br />
代码的人喜欢把数据传输具体化为request,urb 和sg 都被化作request,即请求.而usb core 的能耐就<br />
是<br />
让你写设备驱动的人能够只要申请一个请求,调用usb core 提供的函数进行初始化,然后调用usb core 提<br />
供的函数进行提交,这些步骤都是固定的,完全就像使用傻瓜照相机一样,然后进程可以睡眠,或者可以干别<br />
的事情,完事之后usb core 会通知你.然后你就可以接下来干别的事情了.我做一个比方,就好比你考四六<br />
级,<br />
找了一个枪手,让他去给你考,你只要告诉他你的基本信息,把你的准考证给他,然后你就不用管别的什么了,<br />
剩下的事情他会去处理,然后你也不用担心完事之后他不会通知你,这简直是不容置疑的,因为你还没给钱<br />
呢.<br />
明白了不,小朋友?<br />
166<br />
迷雾重重的 Bulk 传输(六)<br />
接下来咱们该看看如何处理CSW 了.1018 行,usb_stor_bulk_transfer_buf()函数再一次被调用,这<br />
次是获得CSW,期望长度是US_BULK_CS_WRAP_LEN,这个宏来自<br />
drivers/usb/storage/transport.h 中:<br />
109 #define US_BULK_CS_WRAP_LEN 13<br />
13 对应CSW 的长度,13 个bytes.而cswlen 记录了实际传输的长度.1025 行,如果返回值是<br />
USB_STOR_XFER_SHORT,表明数据传少了,没有达到我们期望的那么多,而假如cswlen 又等于0,那么<br />
说明没有获得真正的CSW,正如注释所说,有些变态的设备会在数据阶段末尾多加一些0 长度的包进来,这<br />
就意味着咱们并没有获得CSW,于是重新执行一次usb_stor_bulk_transfer_buf(),再获得一次.(旁白:<br />
数据传输失败了可以重来一次,你我失去的青春能重来一次么?唉,人生没有彩排,天天都是现场直播.)<br />
1032 行,如果result 等于USB_STOR_XFER_STALLED,在interpret_urb_result 中查找一