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.

看出区别了吗?没错,最下面多了一项,这是一个Leidisk 生产的U盘.这里本没有一个真实的host,但是写<br />

代码的高手们却让你觉得也许似乎大概有,甚至连scsi core 都被欺骗了一样.那么这些高手们是如何实现<br />

的呢?让我们来慢慢的看,让我们来看看这个神奇的host 究竟是如何出现的,看看它是否像如今的房价一<br />

样,<br />

是否像林志玲的胸一样,看着坚挺,实际里面全是泡沫...<br />

谁是最变态的结构体<br />

scsi 子系统里的设备使用scsi 命令来通信,scsi spec 定义了一大堆的命令,spec 里称这个为命令集,即<br />

所谓的command set.其中一些命令是每一个scsi 设备都必须支持的,另一些命令则是可选的.而作为U<br />

盘,它所支持的是scsi transparent command set,所以它基本上就是支持所有的scsi 命令了,不过我们<br />

其实并不关心任何一个具体的命令,只需要了解一些最基本的命令就是了.比如我们需要知道,所有的scsi<br />

设备都至少需要支持以下这四个scsi 命令:INQUIRY,REQUEST SENSE,SEND DIAGNOSTIC,TEST<br />

UNIT READY.一会我们在代码中会遇见其中的几个,暂且不表.另外对于磁盘设备,它还需要支持另外一些<br />

命令,比如读方面的READ 命令,写方面的WRITE 命令,又比如我们经常做的格式化操作,它就对应<br />

FORMAT UNIT 命令.对于磁盘这样的设备,SCSI 协议里边称它为direct-access devices.这就是为什么<br />

你刚才在cat /proc/scsi/scsi 的输出中能看到一个”Type:Direct-Access”这么一项.<br />

知道了scsi 总线上使用scsi 命令来通信,那么我们下一步需要知道scsi host 的作用,它主要就是负责发<br />

送命令给设备,然后设备就去执行命令.所以scsi host 也被称为initiator(发起者),而scsi 设备被称为<br />

target(目的地).<br />

那么我们就知道,如果我们没有scsi host,但是我们有遵守scsi 协议接受scsi 命令的device,那怎么办?<br />

谁来发起命令?没有硬件我们用软件,命令是谁传递过来的?应用层?或者scsi core?不管是谁,只要我们能<br />

够把上层的命令传递给设备,那就Ok 了对不对?scsi 核心层把一切都做好了,我们只要为一个scsi host<br />

申<br />

请相应的数据结构,让命令来了能够发送给设备,能够让设备接收到命令,那就万事大吉了对不对?或者说整<br />

个usb-storage 的真正的功能也就实现了对不对?到这里我们就可以开始继续来看我们的代码了.别忘了<br />

我们还在usb_stor_acquire_resources()函数中,只不过刚刚讲完usb_stor_Bulk_max_lun()函数而<br />

已.<br />

781 行,us->unusual_dev->initFunction 是什么?不要说你一点印象也没有.在分析<br />

unusual_devs.h 文件的时候曾经专门举过例子的,说有些设备需要一些初始化函数,它就定义在<br />

unusual_devs.h 文件中,而我们通过UNUSUAL_DEV 的定义已经把这些初始化函数给赋给了<br />

us->unusual_dev 的initFunction 指针了.所以这时候,在传输开始之前,我们判断,是不是有这样一个函<br />

数,即这个函数指针是否为空,如果不为空,很好办,执行这个函数就是了.比如当时我们举例子的时候说的那<br />

两个惠普的CD 刻录机就有个初始化函数init_8200e,那么就让它执行好了.当然,一般的设备肯定不需要<br />

这么一个函数.至于传递给这个函数的参数,在struct us_unusual_dev 结构体定义的时候,就把这个函数<br />

需要什么样的参数定义好了,需要的就是一个struct us_data *,那么很自然,传递的就是us.<br />

然后790 行,scsi_host_alloc 就是scsi 子系统提供的函数,它的作用就是申请一个scsi host 相应的数<br />

据结构.不过我们要注意的是它的参数,尤其是第一个参数, &usb_stor_host_template,其实这是一个<br />

93<br />

struct scsi_host_template 的结构体指针,从这一刻开始,我们需要开始了解<br />

drivers/usb/storage/scsiglue.c 这个文件了,glue 就是胶水的意思,与scsi 相关联的代码我们就都准<br />

备<br />

在这个文件里了.<br />

usb_stor_host_template 的定义就在drivers/usb/storage/scsiglue.c 中,

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

Saved successfully!

Ooh no, something went wrong!