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.

120 */<br />

121 #define SAM_STAT_GOOD 0x00<br />

其实就是0,咱们完成了工作之后把srb->result 设为0,以后自有scsi 那边的函数会去检测.不用咱们管<br />

了.<br />

然后咱们进入到381 行,更确切的是,385 行,srb->scsi_done()函数会被调用,srb->scsi_done()实际<br />

上是一个函数指针,咱们在queuecommand中令她等于scsi_done,咱们被要求在完成了该做的事情之后<br />

调用这个函数,剩下的事情scsi 核心层会去处理.<br />

酱紫,针对queuecommand 传递进来INQUIRY 命令的情况,该做的就都做了.<br />

最后单独解释一下,给那些喜欢打破沙锅问到底的无聊人士:<br />

First <strong>of</strong> all, 好端端的传输数据为什么要分散成好多个scatter gather list,这不是自找麻烦吗?关于这<br />

个问题,曾经我单纯的以为,也许只有支离破碎才是美.后来我意识到,SCSI 层包括usb-storage 之所以要<br />

使用scatter gather 是因为这一特性允许系统在一个SCSI 命令中传输多个物理上不连续的buffers.<br />

关于kmap()和kunmap().这两个函数是干嘛的?为什么要映射?小时候妈妈没有告诉过你吗?将来你长<br />

大了,等你熟悉了Linux 内核中的内存管理部分你就会知道,这个世界上有一个地址,叫做物理地址,还有一<br />

个地址叫做内核地址,struct page 代表的是物理地址,内核用这个结构体来代表每一个物理page,或者说<br />

物理页,显然我们代码中不能直接操作物理地址,memcpy 这个函数根本就不认识物理地址,它只能使用内<br />

核地址.所以我们需要把物理地址映射到内核地址空间中来.kmap()从事的正是这项伟大的工作.不过写过<br />

代码的人了解kmap()更多的和high memory 打交道的时候认识的,此乃题外话,不表.<br />

彼岸花的传说(The End)<br />

解决了这个INQUIRY 的问题,我们就可以继续往下走了,373 行,这就是真正的Bulk 传输的地<br />

方,proto_handler()就是正儿八经的处理SCSI 命令的函数指针.而usb_stor_control_thread 之前的<br />

所<br />

有代码就是为了判断是不是有必要调用proto_handler(),比如超时了,比如模块该卸载了,比如设置了断<br />

开flag 了,比如要处理的就是这个有问题的INQUIRY,等等这些情况都需要先排除了才有必要到达这里来<br />

执行真正的命令.实际上这就是先从宏观上来控制,保证我们走的是一条正确的道路,而不至于是沿着错误的<br />

道路走半天,毕竟,在错误的路上,就算奔跑也没有用!别说奔跑了,裸奔也没有用!<br />

139<br />

我们倒是先不急着到proto_handler 里边去看,先把外边的代码看完.小时候,我们不都天真的以为,外面<br />

的世界很精彩么?我们先跳过proto_handler(),把usb_stor_control_thread()中剩下的代码看完,从而<br />

完整的了解这个守护进程究竟是如何循环的.<br />

382 行,只要刚才的命令的结果即srb->result 不为DID_ABORT,那么就是成功执行了.于是我们就调<br />

用scsi_done 函数.<br />

387行,SkipForAbort,就是一个行标志,对应前面的那个goto SkipForAbort 语句. 记得大学期间,学到<br />

谭浩强大哥那本书中goto 的时候,老师总是会告诫大家,不要乱用goto 语句,这是不好的编程习惯,不过在<br />

Linux 内核源代码中,goto 语句却是比比皆是,真让人为这些写Linux 源代码的同志们的C 语言水平担心<br />

啊,<br />

肯定在校期间没有好好念书,辜负了家长殷切的期望啊.算了,不说他们了,这_________些家伙少年不识愁滋<br />

味.我们<br />

继续说Linux,396 行,前面的注释也说得很清楚了,如果是设置了US_FLIDX_TIMED_OUT那么就唤醒设<br />

这个flag 的进程,其实就是唤醒command_abort,后面我们会讲command_abort().这里之所以判断这<br />

个flag 而不是判断srb->result==DID_ABORT 注释里说得也很清楚,因为有可能是在usb 传输结束之<br />

后才收到的abort 命令,换言之,即便你的srb->result 不为DID_ABORT 也可能最新又接到了abort 的

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

Saved successfully!

Ooh no, something went wrong!