第 1 部分针对 Oracle Solaris 平台设计设备驱动程序
9. 直接内存访问 (Direct Memory Access, DMA)
14. 分层驱动程序接口 (Layered Driver Interface, LDI)
Sun 公用 SCSI 体系结构 (Sun Common SCSI Architecture, SCSA) 是用于将 SCSI 命令从目标驱动程序传输到主机总线适配器驱动程序的 Oracle Solaris DDI/DKI 编程接口。该接口与主机总线适配器硬件的类型、平台、处理器体系结构以及通过该接口传输的 SCSI 命令无关。
只要符合 SCSA,目标驱动程序便可以将 SCSI 命令传送给目标设备,而无需了解主机总线适配器的硬件实现。
SCSA 在概念上将生成 SCSI 命令与通过 SCSI 总线传输命令和数据这两个过程分离开来。该体系结构定义了高级别软件组件与低级别软件组件之间的软件接口。较高级别的软件组件由一个或多个 SCSI 目标驱动程序组成,这些驱动程序可将 I/O 请求转换为适用于外围设备的 SCSI 命令。以下示例说明了 SCSI 体系结构。
较低级别的软件组件由 SCSA 接口层和一个或多个主机总线适配器驱动程序组成。目标驱动程序负责生成执行所需功能需要的正确 SCSI 命令,并负责处理结果。
以下步骤介绍读取或写入请求的常规控制流程(假定没有发生传输错误)。
调用目标驱动程序的 read(9E) 或 write(9E) 入口点。使用 physio(9F) 锁定内存,准备 buf 结构并调用策略例程。
目标驱动程序的 strategy(9E) 例程将检查请求。然后,strategy() 通过使用 scsi_init_pkt(9F) 来分配 scsi_pkt(9S)。目标驱动程序初始化包,并使用 scsi_setup_cdb(9F) 函数设置 SCSI 命令描述符块 (command descriptor block, CDB)。目标驱动程序还指定超时。然后,该驱动程序提供一个指向回调函数的指针。完成命令后,主机总线适配器驱动程序将调用该回调函数。buf(9S) 指针应保存在 SCSI 包的目标专用空间中。
目标驱动程序使用 scsi_transport(9F) 将包提交给主机总线适配器驱动程序。然后,目标驱动程序可以自由接受其他请求。目标驱动程序不应在包的传输过程中对其进行访问。如果主机总线适配器驱动程序或目标支持排队,则可以在传输包时提交新请求。
一旦 SCSI 总线空闲而且目标不繁忙,主机总线适配器驱动程序便会选择该目标并传递 CDB。目标驱动程序将执行命令。然后,目标执行所请求的数据传输。
目标发送完成状态并且命令完成后,主机总线适配器驱动程序会通知目标驱动程序。要执行通知,主机应调用 SCSI 包中指定的完成函数。此时,主机总线适配器驱动程序不再负责处理该包,同时目标驱动程序重新获得了对该包的拥有权。
SCSI 包的完成例程将分析返回的信息。然后,完成例程会确定 SCSI 操作是否成功。如果出现故障,目标驱动程序将再次调用 scsi_transport(9F) 以重试命令。如果主机总线适配器驱动程序不支持自动请求检测,则目标驱动程序必须在出现检查条件时,提交请求检测包才能检索检测数据。
成功完成上述操作后或者如果无法重试命令,目标驱动程序将调用 scsi_destroy_pkt(9F)。scsi_destroy_pkt () 将同步数据。然后,scsi_destroy_pkt() 释放包。如果在释放包之前目标驱动程序需要访问数据,则调用 scsi_sync_pkt(9F)。
最后,目标驱动程序将通知请求应用程序读取或写入事务已完成。该通知是在执行了字符设备的驱动程序中的 read(9E) 入口点并返回后进行的。否则,会通过 biodone(9F) 间接发出通知。
SCSA 允许以重叠方式和排队方式在进程的各个点执行多个此类操作。在该模型中,系统资源由主机总线适配器驱动程序负责管理。借助软件接口并使用不同复杂程度的 SCSI 总线适配器,可以在主机总线适配器驱动程序中执行目标驱动程序函数。
SCSA 定义了多种函数,用于管理资源的分配和释放、控制状态的检测和设置以及 SCSI 命令的传输。下表中列出了这些函数。
表 17-1 标准 SCSA 函数
|