第 4 章. 接口

此驱动程序支持以下系统调用,其中大多数是 Linux 中字符设备驱动程序的典型调用。它们是

从 Linux 应用程序角度来看,这些调用的接口在 “man” 页(第 2 节)中有详细文档。

用户应用程序通过在 sg 设备文件名上使用 open() 系统调用来访问 sg 驱动程序。每个 sg 设备文件名对应于一个(潜在地)连接的 SCSI 设备。这些通常位于/dev目录下。以下是一些 sg 设备文件名
$ ls -l /dev/sg[01]
crw-rw----    1 root     disk      21,   0 Aug 30 16:30 /dev/sg0
crw-rw----    1 root     disk      21,   1 Aug 30 16:30 /dev/sg1
权限开头的 “c” 表示字符设备。“others” 缺少读取或写入权限是谨慎的安全措施。所有 sg 设备名称的主设备号都是 21,而次设备号与设备文件名中 “sg” 后面的数字相同。当设备文件系统 (devfs) 在系统上处于活动状态时,主要的 sg 设备文件名位于信息丰富的子树的底部
$ cd /dev/scsi/host1/bus0/target0/lun0
$ ls -l generic
crw-r-----    1 root     root      21,   1 Dec 31  1969 generic
在 devfs 下(当其守护程序 [devfsd] 运行时),通常会有一个从/dev/sg1/dev/scsi/host1/bus0/target0/lun0/generic的符号链接。 这样做是为了让寻找简写设备文件名的现有应用程序不会感到意外。devfs 的一个优点是只有连接的 SCSI 设备才会出现在/dev/scsi子树中。

sg v3 中的一个重要新增功能是名为 SG_IO 的 ioctl(),其功能等同于 write() 后跟阻塞 read()。在某些情况下,write()/read() 组合比 SG_IO 具有优势(例如,命令排队),并继续受到支持。

基于 sg_header 结构的现有(和原始)sg 接口仍然可以使用之前的 write()/read() 序列。 SG_IO ioctl 只接受基于 sg_io_hdr_t 结构的新接口。

因此,sg v3 驱动程序具有一个 write() 调用,它可以接受旧的 sg_header 结构或新的 sg_io_hdr_t 结构。 write() 调用根据传递的标头的第二个整数位置(即 sg_header::reply_len 或 sg_io_hdr_t::dxfer_direction)来决定正在使用哪个接口。 如果它是正数,则假定为旧接口。 如果它是负数,则假定为新接口。 新接口中 “dxfer_direction” 中放置的方向常量已被选择为负值。

如果使用 sg_io_hdr_t 接口将请求发送到 write(),则获取响应的相应 read() 也必须使用 sg_io_hdr_t 接口。 相同的规则适用于 sg_header 接口。

本文档重点介绍 sg 版本 3 驱动程序中引入的 sg_io_hdr_t 接口。 有关旧的 sg_header 接口的定义,请参阅 sg 版本 2 文档。 附录 B 中给出了简要描述。