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.

具体到usb storage,我们不管信号量和锁在Linux 中是怎么实现的,它们之间是否有区别对我们来说也<br />

无所谓,事实上,usb-storage 中使用的都是锁,即便是信号量,也是把它当成锁来使用,可曾记得我们当初<br />

把<br />

信号量的初始化为1 了?当信号量初始化为1,那么对我们来说,它就相当于退化为一把锁了.而锁,只有两种<br />

状态,上锁和解锁.<br />

此前我们见过很多次两组函数,但我们一直绝口不提.<br />

她们就是scsi_lock()和scsi_unlock(),以及down(&us->dev_semaphore)和<br />

up(&us->dev_semaphore).<br />

先来看第一组.她们是我们自己定义的宏.来自drivers/usb/storage/usb.h.<br />

174 /* The scsi_lock() and scsi_unlock() macros protect the sm_state and the<br />

175 * single queue element srb for write access */<br />

176 #define scsi_unlock(host) spin_unlock_irq(host->host_lock)<br />

177 #define scsi_lock(host) spin_lock_irq(host->host_lock)<br />

显然,这两个函数就像牛郎织女一样,是一对.而她们的作用,就是利用自旋锁来保护资源,这把锁就是<br />

struct <strong>Scsi</strong>_Host 的一个成员spinlock_t *host_lock.那么在什么情况下需要使用这两个自旋锁函数来<br />

保护资源呢?<br />

当你要写us->srb 的时候,(不是写us->srb 的元素,而是写us->srb,比如令us->srb=NULL),这种时<br />

候,你需要使用这把自旋锁.另一种情况是,当你调用scsi mid layer(scsi 中层)的函数时,有时候这些函数<br />

要求调用者拥有这把锁,即host_lock.<br />

搜索一下,发现一共有7 处使用了scsi_lock.<br />

我们列举一些来.<br />

第一处,drivers/usb/storage/usb.c:usb_stor_release_resources()函数中,<br />

839 scsi_lock(us->host);<br />

840 us->srb = NULL;<br />

841 scsi_unlock(us->host);<br />

199<br />

这个不用解释了吧,赤裸裸的写us->srb,自然要用scsi_lock/scsi_unlock.<br />

第二处,drivers/usb/storage/transport.c:usb_stor_reset_common()函数中,<br />

1121 scsi_lock(us->host);<br />

1122 usb_stor_report_device_reset(us);<br />

1123 set_bit(US_FLIDX_RESETTING, &us->flags);<br />

1124 clear_bit(US_FLIDX_ABORTING, &us->flags);<br />

1125 scsi_unlock(us->host);<br />

这就是第二种情况,因为这里调用了usb_stor_report_device_reset(),这个函数来自<br />

drivers/usb/storage/scsiglue.c,也是我们定义的,<br />

308 /* Report a driver-initiated device reset to the SCSI layer.<br />

309 * Calling this for a SCSI-initiated reset is unnecessary but harmless.<br />

310 * The caller must own the SCSI host lock. */<br />

311 void usb_stor_report_device_reset(struct us_data *us)<br />

312 {<br />

313 int i;<br />

314<br />

315 scsi_report_device_reset(us->host, 0, 0);<br />

316 if (us->flags & US_FL_SCM_MULT_TARG) {

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

Saved successfully!

Ooh no, something went wrong!