分类:
2010-04-13 14:32:40
SCSI(小型计算机系统接口)总线是一种高效的点对点数据总线,它最多可以支持8个设备,其中包括多个主设备。每个设备有唯一的标志符并可以通过盘上的跳线来设置。在总线上的两个设备间数据可以以同步或异步方式,在32位数据宽度下传输率为40M字节来交换数据。SCSI总线上可以在设备间同时传输数据与状态信息。initiator设备和target设备间的执行步骤最多可以包括8个不同的阶段。你可以从总线上5个信号来分辨SCSI总线的当前阶段。这8个阶段是:
Linux SCSI子系统由两个基本部分组成,每个由一个数据结构来表示。
SCSI子系统的初始化非常复杂,它必须反映处SCSI总线及其设备的动态性。Linux在启动时初始化SCSI子系统。 如果它找到一个SCSI控制器(即SCSI hosts)则会扫描此SCSI总线来找出总线上的所有设备。然后初始化这些设备并通过普通文件和buffer cache块设备操作使Linux核心的其它部分能使用这些设备。初始化过程分成四个阶段:
首先Linux将找出在系统核心连接时被连入核心的哪种类型的SCSI主机适配器或控制器有硬件需要控制。每个 核心中的SCSI host在builtin_scsi_hosts数组中有一个Scsi_Host_Template入口。而Scsi_Host_Template结构中包含执行特定SCSI host操作, 如检测连到此SCSI host的SCSI设备的例程的入口指针。这些例程在SCSI 子系统进行自我配置时使用同时它们还是支持此host类型的SCSI设备驱动的一部分。每个被检测的SCSI host, 即与真正SCSI设备连接的host将其自身的Scsi_Host_Template结构添加到活动SCSI hosts的scsi_hosts结构链表中去。每个被检测host类型的实例用一个scsi_hostlist链表中的Scsi_Host结构来表示。例如一个包含两个NCR810 PCI SCSI控制器的系统的链表中将有两个Scsi_Host入口,每个控制器对应一个。每个Scsi_Host 指向一个代表器设备驱动的Scsi_Host_Template。
现在每个SCSI host已经找到,SCSI子系统必须找出哪些SCSI设备连接哪个host的总线。SCSI设备的编号是 从0到7,对于一条SCSI总线上连接的各个设备,其设备编号或SCSI标志符是唯一的。SCSI标志符可以通过设 备上的跳线来设置。SCSI初始化代码通过在SCSI总线上发送一个TEST_UNIT_READY命令来找出每个SCSI设备。 当设备作出相应时其标志符通过一个ENQUIRY命令来读取。Linux将从中得到生产厂商的名称和设备模式以及 修订版本号。SCSI命令由一个Scsi_Cmnd结构来表示同时这些命令通过调用Scsi_Host_Template结构中的设备 驱动例程传递到此SCSI host的设备驱动中。被找到的每个SCSI设备用一个Scsi_Device结构来表示,每个指向 其父Scsi_Host结构。所有这些Scsi_Device结构被添加到scsi_device链表中。图8.4给出了这些主要数据结构 间的关系。
一共有四种SCSI设备类型:磁盘,磁带机,CD-ROM和普通SCSI设备。每种类型的SCSI设备以不同的主块设备 类型单独登记到核心中。如果有多个类型的SCSI设备存在则它们只登记自身。每个SCSI设备类型,如SCSI磁盘 维护着其自身的设备列表。它使用这些表将核心块操作(file或者buffer cache)定向到正确的设备驱动或 SCSI host上。每种SCSI设备类型用一个Scsi_Device_Template结构来表示。此结构中包含此类型SCSI设备的 信息以及执行各种任务的例程的入口地址。换句话说,如果SCSI子系统希望连接一个SCSI磁盘设备它将调用 SCSI磁盘类型连接例程。如果有多个该种类型的SCSI设备被检测到则此Scsi_Type_Template结构将被添加到 scsi_devicelist链表中。
SCSI子系统的最后一个阶段是为每个已登记的Scsi_Device_Template结构调用finish函数。对于SCSI磁盘类型 设备它将驱动所有SCSI磁盘并记录其磁盘布局。同时还将添加一个表示所有连接在一起的SCSI磁盘的gendisk 结构,如图8.3。
一旦SCSI子系统初始化完成这些SCSI设备就可以使用了。每个活动的SCSI设备类型将其自身登记到核心以便 Linux正确定向块设备请求。这些请求可以是通过blk_dev的buffer cache请求也可以是通过blkdevs的文件 操作。以一个包含多个EXT2文件系统分区的SCSI磁盘驱动器为例,当安装其中一个EXT2分区时系统是怎样将 核心缓冲请求定向到正确的SCSI磁盘的呢?
每个对SCSI磁盘分区的块读写请求将导致一个新的request结构被添加到对应此SCSI磁盘的blk_dev数组中的 current_request链表中。如果此request正在被处理则buffer cache无需作任何工作;否则它必须通知SCSI 磁盘子系统去处理它的请求队列。系统中每个SCSI磁盘用一个Scsi_Disk结构来表示。例如/dev/sdb1的主设备 号为8而从设备号为17;这样产生一个索引值1。每个Scsi_Disk结构包含一个指向表示此设备的Scsi_Device 结构。这样反过来又指向拥有它的Scsi_Host结果。这个来自buffer cache的request结构将被转换成一个描 叙SCSI命令的Scsi_Cmd结构,这个SCSI命令将发送到此SCSI设备同时被排入表示此设备的Scsi_Host结构。一 旦有适当的数据块需要读写,这些请求将被独立的SCSI设备驱动来处理。