世界上最遥远的距离,
不是生与死,
而是我就站在你面前,
你却不知道我爱你.
世界上最遥远的距离,
不是我就站在你面前,
你却不知道我爱你,
而是明明知道彼此相爱,
却不能在一起.
世界上最遥远的距离,
不是明明知道彼此相爱,
却不能在一起,
而是明明无法抵挡这股想念,
却还得故意装作丝毫没有把你放在心里.
世界上最遥远的距离,
不是明明无法抵挡这股想念,
却还得故意装作丝毫没有把你放在心里,
而是用自己冷默的心,
对爱你的人掘了一条无法跨越的沟渠.
曾经天真的以为代码看到这里,该出场的函数也都出场了,该出场的数据结构也都出场了,不会有什么新鲜的冬冬了.曾经天真的以为我们即将知道整个驱动是如何工作的了.未曾想到,我们距离完全了解整个故事还有一光年.挡在我们面前的,是scsi. 的确,看一个U盘驱动不仅仅是要了解usb协议,还要懂scsi协议,要知道U盘它不仅仅是usb设备,它还是”盘”,它要存储数据,所以才叫它usb mass storage,所以才叫它海量存储,而U盘,它所遵循的传输协议叫bulk-only传输,它所遵循的指令集叫做SCSI transparent command sets.换句话说,U盘究竟怎么通信?使用scsi命令.你不懂scsi协议行吗?
没办法,如果你对scsi协议完全不了解.那么对不起,先抽点空熟悉一下scsi协议,熟悉一下scsi命令集吧.不要说你没有时间,雷锋同志说的好,时间就像乳沟,只要肯挤,总是有的.去google一把吧,去百度一把吧.我们在这里等你.
如果你真的不去看,那好吧,我假设你了解一点吧,什么是scsi?无非也是一类总线.不过我们通常大多数普通人并不会接触scsi,公司里边用得多,比如scsi硬盘,校园里边大学生通常不用scsi硬盘,用ide硬盘.每种硬盘都有它的市场.就像每个明星都有它的fans一样.于是我们知道这个世界上有玉米,有凉粉,有盒饭.那么常见的硬盘就是scsi硬盘和ide硬盘.scsi硬盘属于scsi设备中的一种,有设备就有总线,有总线就有协议,所以我们知道了这个世界上有一种协议叫做scsi协议,就好比我们usb世界里有usb协议一样.时下流行的是SCSI-2协议.Linux内核代码中自然也按这个协议来为scsi设备准备设备驱动程序.
关于scsi,drivers目录下面当然也有一个子目录是属于它的,那就是drivers/scsi目录.如果你有雅兴用ls命令看一下,你会发现这下面的文件那是相当的多.如果你真的很感兴趣,那么请从Kconfig文件和Makefile文件开始看起.去深入了解一下Linux整个scsi子系统是怎么工作的.我就不奉陪了.不过正如我们曾经介绍过的2.6中伟大的设备模型实现了这么一件事情,不管你是pci还是usb还是scsi,都给你定义一条总线,然后总线上面两棵树,一棵是设备,一棵是驱动,对于设备这棵树,pci有pci的扫描方法,usb有usb的扫描方法,scsi有scsi的扫描方法,总之这个过程被称为总线枚举,枚举完了之后设备这棵树就建立好了,同时drivers这棵树也会一步一步建立.每类设备有它自己的比较方法,要是合适,就把一个设备和一个驱动绑定起来,这样子,驱动程序提供的函数自然就会在需要的时候被调用,那么,谁来调用?
Ok,如果你是代码设计者,你会怎么处理?你打算如何为整个scsi系统规划代码?不知道?真的不知道?那么我真的羡慕你这么年轻就认识我了.不过,可惜,我也不知道.经过在复旦四年的大学教育,我已经被训练成了一名合格的人渣.这几年里我们关注的只是璩美凤的被偷拍事件,只是赵忠祥的录音事件,只是李金斗的嫖娼事件,只是阿丘的包二奶事件,却从未曾关注过自己应该学点什么,作为一名生在红旗下长在新中国的共产主义接班人,惭愧啊!
算了,不知道就不知道吧,让我们来思考一下.就像usb子系统那边一样,usb那边有一部分核心代码,被称为usb core,那么scsi这边自然也应该有这么一部分代码吧,也叫scsi core,这你没意见吧.usb那边弄了一个usb host目录,然后各种设备也分了类,比如storage设备,比如input设备,比如serial设备,比如image设备,那是因为usb的世界里有两个角色,一个是host,一个是设备,那scsi这边是不是也可以这样呢?先不说可不可以这样,事实情况是,没有这样,所有的冬冬都一股脑儿堆在drivers/scsi/目录下面,有朝一日你要是混入了开发队伍中,你不妨提议把这个目录整理一下,别像现在这样,至少看上去整齐一点,乱七八糟不象话.不过也许开发者们有他们自己的理由吧,他们也许没有时间,那么你可以告诉他们雷锋同志是如何说的.开发者们把scsi设备分成了四类,于是他们写了四个模块来为这些设备做驱动程序.这四个模块是sd_mod.ko,sr_mod.ko,st.ko,sg.ko.如果你正在Linux下使用U盘,那么用lsmod查看一下当前安装的模块,你一定会看到一个叫做sd_mod的模块,一定会看到一个叫做scsi_mod的模块,scsi_mod.ko正是scsi的核心模块,即所谓的scsi core.那么scsi host呢?host同样也有一个模块,这就得看你具体用的是什么host了,行话管这个叫HBA,即host bus adapter.而相应的驱动程序就叫Host Bus Adapter driver了.正如在usb系统中,所有的总线上的活动都是以host为主的,而scsi也是如此,所有的设备也都是围着host转.即使地球不自转了,设备仍然要围着host转.不过你会很奇怪,即使你的机器里没有一个叫做HBA的冬冬,可是你的U盘还是能用啊,这是怎么回事?没错,怪事年年有,今年特别多,Linux内核代码虽然繁华美丽,对我们来说,却常是朦胧不真实.设计者们是如何处理usb-storage和scsi的接口的呢?他们用代码虚拟了一个scsi host.所以,如果你用cat /proc/scsi/scsi命令,就可以看看scsi设备中U盘是怎么被描述的.
下面是没有插U盘的一个例子:
localhost:~ # cat /proc/scsi/scsi
Attached devices:
Host: scsi0 Channel: 00 Id: 08 Lun: 00
Vendor: DP Model: BACKPLANE Rev: 1.00
Type: Enclosure ANSI SCSI revision: 05
Host: scsi0 Channel: 02 Id: 00 Lun: 00
Vendor: DELL Model: PERC 5/i Rev: 1.00
Type: Direct-Access ANSI SCSI revision: 05
Host: scsi1 Channel: 00 Id: 00 Lun: 00
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Enclosure ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 00
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Direct-Access ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 01
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Direct-Access ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 02
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Direct-Access ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 03
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Direct-Access ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 04
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Direct-Access ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 05
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Direct-Access ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 06
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Direct-Access ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 07
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Direct-Access ANSI SCSI revision: 03
而下面第二条是机器里有U盘的情况:
localhost:~ # cat /proc/scsi/scsi
Attached devices:
Host: scsi0 Channel: 00 Id: 08 Lun: 00
Vendor: DP Model: BACKPLANE Rev: 1.00
Type: Enclosure ANSI SCSI revision: 05
Host: scsi0 Channel: 02 Id: 00 Lun: 00
Vendor: DELL Model: PERC 5/i Rev: 1.00
Type: Direct-Access ANSI SCSI revision: 05
Host: scsi1 Channel: 00 Id: 00 Lun: 00
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Enclosure ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 00
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Direct-Access ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 01
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Direct-Access ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 02
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Direct-Access ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 03
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Direct-Access ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 04
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Direct-Access ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 05
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Direct-Access ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 06
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Direct-Access ANSI SCSI revision: 03
Host: scsi1 Channel: 00 Id: 01 Lun: 07
Vendor: SUN Model: StorEdge 3510 Rev: 415F
Type: Direct-Access ANSI SCSI revision: 03
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究竟是如何出现的,看看它是否像如今的房价一样,是否像林志玲的胸一样,看着坚挺,实际里面全是泡沫...