Chinaunix首页 | 论坛 | 博客
  • 博客访问: 268046
  • 博文数量: 60
  • 博客积分: 2010
  • 博客等级: 大尉
  • 技术积分: 820
  • 用 户 组: 普通用户
  • 注册时间: 2010-01-18 00:28
文章分类

全部博文(60)

文章存档

2010年(60)

我的朋友

分类:

2010-04-13 14:32:40

SCSI(小型计算机系统接口)总线是一种高效的点对点数据总线,它最多可以支持8个设备,其中包括多个主设备。每个设备有唯一的标志符并可以通过盘上的跳线来设置。在总线上的两个设备间数据可以以同步或异步方式,在32位数据宽度下传输率为40M字节来交换数据。SCSI总线上可以在设备间同时传输数据与状态信息。initiator设备和target设备间的执行步骤最多可以包括8个不同的阶段。你可以从总线上5个信号来分辨SCSI总线的当前阶段。这8个阶段是:

BUS FREE
当前没有设备在控制总线且总线上无事务发生。
ARBITRATION
一个SCSI设备试图取得SCSI总线的控制权,这时它将其SCSI标志符放置到地址引脚上。具有最高SCSI标志符编号的设备将获得总线控制权。
SELECTION
当设备通过仲裁成功地取得了对SCSI总线的控制权后它必须向它准备发送命令的那个SCSI设备发出信号。具体做法是将目标设备的SCSI标志符放置在地址引脚上进行声明。
RESELECTION
在一个请求的处理过程中SCSI设备可能会断开连接。目标(target)设备将再次选择启动设备 (initiator)。不是所有的SCSI设备都支持此阶段。
COMMAND
此阶段中initiator设备将向target设备发送6、10或12字节命令。
DATA IN, DATA OUT
此阶段中数据将在initiator设备和target设备间传输。
STATUS
所有命令完毕后将进入此阶段,此时允许target设备向initiator设备发送状态信息以指示操作成功与否。
MESSAGE IN, MESSAGE OUT
此阶段附加信息将在initiator设备和target设备间传输。

Linux SCSI子系统由两个基本部分组成,每个由一个数据结构来表示。

host
一个SCSI host即一个硬件设备:SCSI控制权。NCR 810 PCI SCSI控制权即一种SCSI host。在Linux 系统中可以存在相同类型的多个SCSI控制权,每个由一个单独的SCSI host来表示。这意味着一个SCSI设备驱动可以控制多个控制权实例。SCSI host总是SCSI命令的initiator设备。
Device
虽然SCSI支持多种类型设备如磁带机、CD-ROM等等,但最常见的SCSI设备是SCSI磁盘。SCSI设备总是SCSI命令的target。这些设备必须区别对待,例如象CD-ROM或者磁带机这种可移动设备,Linux 必须检测介质是否已经移动。不同的磁盘类型有不同的主设备号,这样Linux可以将块设备请求发送到正确的SCSI设备。

初始化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


图8.4 SCSI数据结构

现在每个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设备驱动来处理。

阅读(1228) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~