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.

305 US_SC_DEVICE, US_PR_DEVICE, NULL,<br />

306 US_FL_IGNORE_RESIDUE ),<br />

一般的设备是不会设置这个flag 的,但是确实有那么一些设备是设了这个flag 的,查一查<br />

drivers/usb/storage/unusual_devs.h,发现Tekom 公司的数码相机全都有这么一个问题.这个flag<br />

的<br />

意思很明确,对于这类设备不需要管在乎CSW 中的那个dCSWDataResidue,因为十有八九这个字节汇报<br />

的东西是错的,是不准的,当然这也就是有一个硬件bug 的例子了.所以这里判断的就是这个flag 没有设,<br />

或<br />

者srb->sc_data_direction 等于DMA_TO_DEVICE,这种情况下,发送给设备的数据长度不应该超过<br />

transfer_length.而1064 行srb->resid 本来是我们传递给usb_stor_bulk_transfer_sg 的参数,记<br />

录<br />

的就是剩下的数据长度,(比如期待值是10,传递了8,那么剩余就是2.白痴都知道.),而residue 刚刚被再次<br />

赋值了,不是原来的residue 就是transfer_length,要知道原来的residue 等于dCSWDataResidue,这<br />

是设备传递过来的,换言之,是硬件传来的数据,它未必就和我们软件得来的相同.所以srb->resid 这时候<br />

就<br />

等于residue 了,以硬件的为准呗.不过我想说的是,这几行代码实际上涉及到一个鲜为人知的花絮,如今这<br />

个世界每天都有人爆料,每天都有人炮轰别人,以至于我们常说生活就像宋祖德的嘴,你永远都不知道下一个<br />

倒霉的会是谁.不过这里我只爆料不炮轰.首先你看这段代码的时候,一定不明白为什么要判断传输方向是不<br />

是DMA_TO_DEVICE 对吧,其实这里又是一个硬件的bug,开发设备驱动这东西,最讲究的就是实战,尤其<br />

是像usb-storage 这么一个通用的模块,它要支持各种各样的设备,不管你是三星家的还是索尼家的,只要<br />

你生产的是usb mass storage 设备,而且你又不准备自己专门写一个设备驱动,那么我们这个<br />

usb-storage 就应该支持你这个设备.而,在实战中,我们发现,有些设备,他们在执行读操作的时候,经常会<br />

在状态阶段汇报一个错误的dCSWDataResidue,就是说比如本来没有传输完全顺利,该传几个字节就传<br />

了几个字节,按理说这种情况,dCSWDataResidue 应该是记录着0,可是实际上这些设备却把这个值设成<br />

了某个正数,你说这不是胡来吗?而如果我们发现这个值是正数,那么当我们向scsi 核心层反映我们我们这<br />

个命令的结果的时候就会说这个命令执行失败了.但事实上这些设备执行读操作并没有问题,这种情况属于<br />

谎报军情,罪该论斩.所以我们这里就加入这么一个标志,对于读操作,即方向为DMA_FROM_DEVICE 的<br />

情<br />

况,咱们就忽略这个dCSWDataResidue,换言之,也就是忽略residue,我们直接返回给scsi 那边<br />

169<br />

srb->resid 就可以了.反之,对于写操作,即方向为DMA_TO_DEVICE 的操作,我们当然不愿意无缘无故<br />

的<br />

抛弃有效的dCSWDataResidue 啦.所以对于DMA_TO_DEVICE 的情况,我们最终返回给scsi 核心层<br />

的<br />

srb->resid 是以srb->resid 和residue 中那个大一点的为准.这就是为什么我们这里要判断或者我们设<br />

置了US_FL_IGNORE_RESIDUE这么一个flag,或者我们执行的是读操作,对于这两种情况我们要忽略掉<br />

residue,反之我们就不忽略.不过有趣的是,三年前,某个老外去开源社区抱怨,说他买了一个中国厂商生产<br />

的MP3,该设备在写操作的时候老是莫名其妙的报错,但是在Windows 下却用得好好的.最后大家一分析,<br />

发现问题就是在这里,即这个设备在写的时候会误报dCSWDataResidue,用社区里面那些伙计的话说就<br />

是,这种设备在执行写命令的时候,会往dCSWDataResidue 填写垃圾信息.本来写操作是正确的执行了,<br />

可<br />

是偏偏要让scsi 那边以为操作没有执行成功.所以,某位帅哥就提交了一个patch,把这个判断方向的代码<br />

去<br />

掉了,因为反正读写都有可能出问题,那么干脆甭判断了,都给忽略掉得了,也因此,对于这种有问题的设备,

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

Saved successfully!

Ooh no, something went wrong!