- 论坛徽章:
- 0
|
Host: scsi3 Channel: 00 Id: 00 Lun: 00
Vendor: Leidisk Model: USB Flash Drive Rev:
Type: Direct-Access ANSI SCSI revision: 02
看出区别了吗?没错,最下面多了一项,这是一个Leidisk 生产的U 盘.这里本没有一个真实的host,但是写
代码的高手们却让你觉得也许似乎大概有,甚至连scsi core 都被欺骗了一样.那么这些高手们是如何实现
的呢?让我们来慢慢的看,让我们来看看这个神奇的host 究竟是如何出现的,看看它是否像如今的房价一样,
是否像林志玲的胸一样,看着坚挺,实际里面全是泡沫...
谁是最变态的结构体
scsi 子系统里的设备使用scsi 命令来通信,scsi spec 定义了一大堆的命令,spec 里称这个为命令集,即
所谓的command set.其中一些命令是每一个scsi 设备都必须支持的,另一些命令则是可选的.而作为U
盘,它所支持的是scsi transparent command set, 所以它基本上就是支持所有的scsi 命令了,不过我们
其实并不关心任何一个具体的命令,只需要了解一些最基本的命令就是了.比如我们需要知道,所有的scsi
设备都至少需要支持以下这四个scsi 命令:INQUIRY,REQUEST SENSE,SEND DIAGNOSTIC,TEST
UNIT READY.一会我们在代码中会遇见其中的几个,暂且不表.另外对于磁盘设备,它还需要支持另外一些
命令,比如读方面的READ 命令,写方面的WRITE 命令,又比如我们经常做的格式化操作,它就对应
FORMAT UNIT 命令.对于磁盘这样的设备,SCSI 协议里边称它为direct-access devices. 这就是为什么
你刚才在cat /proc/scsi/scsi 的输出中能看到一个”Type irect-Access” 这么一项.
知道了scsi 总线上使用scsi 命令来通信,那么我们下一步需要知道scsi host 的作用,它主要就是负责发
送命令给设备,然后设备就去执行命令.所以scsi host 也被称为initiator( 发起者),而scsi 设备被称为
target(目的地).
那么我们就知道,如果我们没有scsi host, 但是我们有遵守scsi 协议接受scsi 命令的device, 那怎么办?
谁来发起命令?没有硬件我们用软件,命令是谁传递过来的?应用层?或者scsi core? 不管是谁,只要我们能
够把上层的命令传递给设备,那就Ok 了对不对?scsi 核心层把一切都做好了,我们只要为一个scsi host 申
请相应的数据结构,让命令来了能够发送给设备,能够让设备接收到命令,那就万事大吉了对不对?或者说整
个usb-storage 的真正的功能也就实现了对不对?到这里我们就可以开始继续来看我们的代码了.别忘了
我们还在usb_stor_acquire_resources() 函数中,只不过刚刚讲完usb_stor_Bulk_max_lun() 函数而
已.
781 行,us->unusual_dev->initFunction 是什么?不要说你一点印象也没有.在分析
unusual_devs.h 文件的时候曾经专门举过例子的,说有些设备需要一些初始化函数,它就定义在
unusual_devs.h 文件中,而我们通过UNUSUAL_DEV 的定义已经把这些初始化函数给赋给了
us->unusual_dev 的initFunction 指针了.所以这时候,在传输开始之前,我们判断,是不是有这样一个函
数,即这个函数指针是否为空,如果不为空,很好办,执行这个函数就是了.比如当时我们举例子的时候说的那
两个惠普的CD 刻录机就有个初始化函数init_8200e, 那么就让它执行好了.当然,一般的设备肯定不需要
这么一个函数.至于传递给这个函数的参数,在struct us_unusual_dev 结构体定义的时候,就把这个函数
需要什么样的参数定义好了,需要的就是一个struct us_data *, 那么很自然,传递的就是us.
然后790 行,scsi_host_alloc 就是scsi 子系统提供的函数,它的作用就是申请一个scsi host 相应的数
据结构.不过我们要注意的是它的参数,尤其是第一个参数, &usb_stor_host_template, 其实这是一个 |
|