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