07.06.2013 Views

Scsi - Index of

Scsi - Index of

Scsi - Index of

SHOW MORE
SHOW LESS

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 中查找一

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!