Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
后她会给host 返回一个CSW.CBW 实际上是命令的封装包,而CSW 实际上是状态的封装包.(命令执行<br />
后<br />
的状态,成功,失败,浪里看不出有未有...所以需要使用这么一个状态包). 至于你说为啥要把命令以及反映<br />
命令执行成功与否的状态包装起来,那很简单, 包装是房子富丽堂皇的外壳,包装是丑妇手上绚丽的太阳伞,<br />
包装是模特在舞台上走出的一字猫步.爱美之心人皆有之,设计spec 的人也不例外.<br />
这时候我们就可以看看usb_stor_Bulk_transport()函数中,调用usb_stor_bulk_transfer_buf()之<br />
前的那几行究竟在干嘛了.很明显,这些行都是在为usb_stor_bulk_transfer_buf()这个函数调用做准备,<br />
对应于那些三级片中的前戏,真正精彩的部分还是在usb_stor_bulk_transfer_buf()中,但前戏的存在必<br />
然是合理的,毕竟,子曾经曰过:没有激情的拥吻,何来床上的翻滚.所以我们来具体看看这部分前戏.(唉,沦为<br />
今天这样一个优秀的大学生,不能怪复旦,主要是自己没有坚强的意志品质啊!)<br />
950 行,struct bulk_cb_wrap *bcb,赋值为(struct bulk_cb_wrap *) us->iobuf,951 行,struct<br />
bulk_cs_wrap *bcs,也赋值为(struct bulk_cb_wrap *) us->iobuf,然后定义一个unsigned int 的变<br />
量transfer_length,赋值为srb->request_bufflen.然后接下来就开始为bcb 的各成员赋值了.我们不妨<br />
看一下usb mass storage spec 中的两张图片,一张是CBW 的格式,一张是CSW 的格式,<br />
157<br />
这是CBW,<br />
而这,就是CSW.<br />
959 行, bcb->Signature=cpu_to_le32(US_BULK_CB_SIGN),Signature 对应usb mass<br />
storage<br />
spec 中CBW 的前四个bytes,即dCBWSignature,US_BULK_CB_SIGN 这个宏定义于<br />
drivers/usb/storage/transport.h 中,<br />
96 #define US_BULK_CB_SIGN 0x43425355 /*spells out USBC */<br />
也不知道是哪个傻X 规定的,只有把dCBWSignature 里边写上43425355h 才能标志着个数据包是一个<br />
CBW.另外,CBW的传输全是遵守little endian 的,所以cpu_to_le32()这个宏需要使用,来转换数据格式.<br />
然后bcb->DataTransferLength 对应CBW中的dCBWDataTransferLength.这个就是标志host<br />
希望这个endpoint 传输多少个bytes 的数据.这里把cpu_to_le32(transfer_length)赋给了她.而<br />
transfer_length 刚才已经说了,就是srb->request_bufflen. 其实这几个变量名换来换去最重要记录<br />
的<br />
还是同一样东西.<br />
158<br />
bcb->Flags,对应于CBW 中的bmCBWFlags,bcb->Flags = srb->sc_data_direction ==<br />
DMA_FROM_DEVICE ? 1 Tag = srb->serial_number,这个Tag 对应CBW中的dCBWTag,这个dCBWTag 的意义在<br />
于,host 会send 出去,而device 将会把这个Tag 的内容给打印出来,确切的说,device 会回送一个CSW<br />
回来,而在CSW中会有一个dCSWTag,她的内容和这个dCBWTag 是一样的,所以实际上这就跟接头暗号<br />
似的.每一个scsi 命令都会被赋上一个serial_number,这里把她用在了Tag 上.<br />
bcb->Lun = srb->device->lun,很简单,对应CBW 中的bCBWLUN,就是表征这个命令是发给哪个<br />
LUN 的,我们知道一个设备如果支持多个LUN,那么显然每个LUN 会有一个编号.比如咱们要读写u 盘上<br />
的<br />
某个分区,那么当然得指明是哪个分区了.如果设备不支持多个lun,那么这儿会被设置为0.不过需要注意,