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.

123<br />

两个scsi_done,一个是struct scsi_cmnd *srb 的成员指针,一个是scsi 核心层的函数名.虽然它们同名,<br />

但是是两个不同的冬冬,就好像满世界都是叫张伟,王伟,李伟,刘伟的一样,名字相同人不同,很正常.<br />

最后,192 行,令us->srb 等于这个srb.而193 行,这正是我们苦苦寻找的代码,正是这个<br />

up(&us->sema),唤醒了我们的守护进程.之后,195 行,这个函数本身就结束了,像烟花熄灭,像夜空沉寂.<br />

而我们显然就该去看那个usb_stor_control_thread()了.因为,她醒了,她终于醒了.<br />

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

燕子去了,有再来的时候;杨柳枯了,有再青的时候;桃花谢了,有再开的时候;老婆离了,有再找的时候,孩子<br />

跑了,有回来的时候;煮熟的鸭子飞了,有飞回来的时候.一个函数没讲完就跳走了,有再回来的时候.其实,那<br />

些人,那些事,终究不曾远离.<br />

于是,她再一次进入我们的视野.<br />

她就是usb_stor_control_thread().唤醒她的是来自queuecommand 的up(&(us->sema)),<br />

us->srb 被赋值为srb,而srb 是来自scsi 核心层在调用queuecommand 时候传递进来的参数.聚焦<br />

usb_stor_control_thread(),309 行, 前面说过,关于dev_semaphore 这把锁我们必须在看完整个模<br />

块之后再来总较高的角度来看,所以这里自然先跳过.<br />

312 行,没啥好说的,如果传进来的是NULL,那么还是退出吧.别无选择.(为什么命令是空就说明要结束了?<br />

因为如果srb 是空,那么scsi core 是不会调用queuecommand 的,道理不用说了吧,scsi core 也不傻,<br />

都没有命令它还调用底层的函数干嘛,吃错药了?那么queuecommand 没有调用的话是谁唤醒了这个守<br />

护进程?我们前面说了,唤醒它的有两个地方,一个是queuecommand,另一个就是模块要卸载了,准确的说<br />

是usb_stor_release_resources()函数,日后等我们遇到了这个函数再看吧,总之就是说当这个模块都要<br />

释放资源了,这时候srb 肯定会被设为NULL,然后这种情况下唤醒了我们这个守护进程,于是才有了这里这<br />

个判断语句.)<br />

318 行,host 也是一把锁,这把锁我们也到最后再来看.暂且不表.<br />

321 行至331 行,又是判断两个flag 有没有被设置,第二个不用多说了,看都看腻了,老是判断设备有没有<br />

被拔出,要是你的U 盘插进去了永远不拔出来,那么你可以把这个flag 相关的代码都删了,当然事实上是你<br />

不可能不拔出来,热插拔本来就是usb 设备的一大特性.所以你就能理解写代码的哥们儿为什么这么煞费苦<br />

心的去判断设备是不是已经不在了.那么第一个flag 呢,US_FLDX_TIMED_OUT,这个flag 的含义也如其<br />

字面意义一样,超时了,超时的概念在计算机的世界里比比皆是.不过对于这个flag,设置它的函数是<br />

command_abort,这个函数也是咱们提供的,由scsi 核心层去调用,由它那边负责计时,到了超时的时间它<br />

就调用command_abort.我们稍候会看,先不急.<br />

338 行,判断srb 的一个成员sc_data_direction, 先看DMA_BIDIRECTIONAL 这个宏.这个宏定义于<br />

include/linux/dma-mapping.h 中,<br />

7 /* These definitions mirror those in pci.h, so they can be used<br />

8 * interchangeably with their PCI_ counterparts */<br />

9 enum dma_data_direction {<br />

124<br />

10 DMA_BIDIRECTIONAL = 0,<br />

11 DMA_TO_DEVICE = 1,<br />

12 DMA_FROM_DEVICE = 2,<br />

13 DMA_NONE = 3,<br />

14 };<br />

在scsi_cmnd 结构体里边,有这么两个成员,

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

Saved successfully!

Ooh no, something went wrong!