07.06.2013 Views

Scsi - Index of

Scsi - Index of

Scsi - Index of

SHOW MORE
SHOW LESS

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.不过需要注意,

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

Saved successfully!

Ooh no, something went wrong!