编写 s390 通道设备驱动程序¶
- 作者:
Cornelia Huck
简介¶
本文档描述了用于驱动基于 s390 的通道连接 I/O 设备的设备驱动程序可用的接口。这包括与硬件交互的接口以及与通用驱动程序核心交互的接口。这些接口由 s390 通用 I/O 层提供。
本文档假设读者熟悉与 s390 通道 I/O 架构相关的技术术语。有关此架构的描述,请参阅 “z/Architecture: Principles of Operation”,IBM 出版物编号 SA22-7832。
虽然 s390 系统上的大多数 I/O 设备通常通过此处描述的通道 I/O 机制驱动,但还有其他各种方法(如 diag 接口)。这些不在本文档的范围之内。
s390 通用 I/O 层还提供对一些不被严格认为是 I/O 设备的设备的访问。它们也在这里考虑,尽管它们不是本文档的重点。
在内核源代码中的 S/390 驱动程序模型接口 下也可以找到一些其他信息。
css 总线¶
css 总线包含系统上可用的子通道。它们分为以下几个类别
标准 I/O 子通道,供系统使用。它们在 ccw 总线上有一个子设备,如下所述。
绑定到 vfio-ccw 驱动程序的 I/O 子通道。请参阅 vfio-ccw: 基本基础设施。
消息子通道。目前不存在 Linux 驱动程序。
CHSC 子通道(最多一个)。chsc 子通道驱动程序可用于发送异步 chsc 命令。
eADM 子通道。用于与存储级内存通信。
ccw 总线¶
ccw 总线通常包含 s390 系统可用的大部分设备。ccw 总线以用于寻址其设备的基本命令结构通道命令字 (ccw) 命名,包含所谓的通道连接设备。它们通过在 css 总线上可见的 I/O 子通道寻址。但是,通道连接设备的设备驱动程序永远不会直接与子通道交互,而只能通过 ccw 总线上的 I/O 设备(ccw 设备)进行交互。
通道连接设备的 I/O 功能¶
一些硬件结构已被转换为 C 结构,供通用 I/O 层和设备驱动程序使用。有关此处表示的硬件结构的更多信息,请查阅《操作原理》。
-
struct ccw1¶
通道命令字
定义:
struct ccw1 {
__u8 cmd_code;
__u8 flags;
__u16 count;
dma32_t cda;
};
成员
cmd_code
命令代码
flags
标志,如 IDA 寻址等。
count
字节计数
cda
数据地址
描述
ccw 是构建通道程序的基本结构,这些通道程序执行与设备或控制单元的操作。仅支持格式 1 通道命令字。
-
struct ccw0¶
通道命令字
定义:
struct ccw0 {
__u8 cmd_code;
__u32 cda : 24;
__u8 flags;
__u8 reserved;
__u16 count;
};
成员
cmd_code
命令代码
cda
数据地址
flags
标志,如 IDA 寻址等。
保留
将被忽略
count
字节计数
描述
格式 0 ccw 结构。
-
struct erw¶
扩展报告字
定义:
struct erw {
__u32 res0 : 3;
__u32 auth : 1;
__u32 pvrf : 1;
__u32 cpt : 1;
__u32 fsavf : 1;
__u32 cons : 1;
__u32 scavf : 1;
__u32 fsaf : 1;
__u32 scnt : 6;
__u32 res16 : 16;
};
成员
res0
保留
auth
授权检查
pvrf
需要路径验证标志
cpt
通道路径超时
fsavf
失败存储地址有效性标志
cons
并发感测
scavf
辅助 ccw 地址有效性标志
fsaf
失败存储地址格式
scnt
如果 cons ==
1
,则为感测计数res16
保留
-
struct erw_eadm¶
EADM 子通道扩展报告字
定义:
struct erw_eadm {
__u32 : 16;
__u32 b : 1;
__u32 r : 1;
__u32 : 14;
};
成员
b
aob 错误
r
arsb 错误
-
struct sublog¶
子通道注销区域
定义:
struct sublog {
__u32 res0 : 1;
__u32 esf : 7;
__u32 lpum : 8;
__u32 arep : 1;
__u32 fvf : 5;
__u32 sacc : 2;
__u32 termc : 2;
__u32 devsc : 1;
__u32 serr : 1;
__u32 ioerr : 1;
__u32 seqc : 3;
};
成员
res0
保留
esf
扩展状态标志
lpum
上次使用的路径掩码
arep
辅助报告
fvf
字段有效性标志
sacc
存储访问代码
termc
终止代码
devsc
设备状态检查
serr
辅助错误
ioerr
I/O 错误警报
seqc
序列代码
-
struct esw0¶
格式 0 扩展状态字 (ESW)
定义:
struct esw0 {
struct sublog sublog;
struct erw erw;
dma32_t faddr[2];
dma32_t saddr;
};
成员
sublog
子通道注销
erw
扩展报告字
faddr
失败存储地址
saddr
辅助 ccw 地址
-
struct esw1¶
格式 1 扩展状态字 (ESW)
定义:
struct esw1 {
__u8 zero0;
__u8 lpum;
__u16 zero16;
struct erw erw;
__u32 zeros[3];
};
成员
zero0
保留的零
lpum
上次使用的路径掩码
zero16
保留的零
erw
扩展报告字
零
三个全字的零
-
struct esw2¶
格式 2 扩展状态字 (ESW)
定义:
struct esw2 {
__u8 zero0;
__u8 lpum;
__u16 dcti;
struct erw erw;
__u32 zeros[3];
};
成员
zero0
保留的零
lpum
上次使用的路径掩码
dcti
设备连接时间间隔
erw
扩展报告字
零
三个全字的零
-
struct esw3¶
格式 3 扩展状态字 (ESW)
定义:
struct esw3 {
__u8 zero0;
__u8 lpum;
__u16 res;
struct erw erw;
__u32 zeros[3];
};
成员
zero0
保留的零
lpum
上次使用的路径掩码
res
保留
erw
扩展报告字
零
三个全字的零
-
struct esw_eadm¶
EADM 子通道扩展状态字 (ESW)
定义:
struct esw_eadm {
__u32 sublog;
struct erw_eadm erw;
__u32 : 32;
__u32 : 32;
__u32 : 32;
};
成员
sublog
子通道注销
erw
扩展报告字
-
struct irb¶
中断响应块
定义:
struct irb {
union scsw scsw;
union {
struct esw0 esw0;
struct esw1 esw1;
struct esw2 esw2;
struct esw3 esw3;
struct esw_eadm eadm;
} esw;
__u8 ecw[32];
};
成员
scsw
子通道状态字
esw
扩展状态字
ecw
扩展控制字
描述
当发生中断时传递给设备驱动程序的 irb。对于请求的中断,通用 I/O 层已经执行了检查,以确定字段是否有效;无效的字段始终以 0
传递。如果发生单元检查,则 ecw 可能包含感测数据;如果设备不支持并发感测,则此数据由通用 I/O 层本身检索(以便设备驱动程序永远不需要执行基本感测本身)。对于未经请求的中断,irb 将按原样传递(适用时,感测数据除外)。
-
struct ciw¶
命令信息字 (CIW) 布局
定义:
struct ciw {
__u32 et : 2;
__u32 reserved : 2;
__u32 ct : 4;
__u32 cmd : 8;
__u32 count : 16;
};
成员
et
条目类型
保留
保留位
ct
命令类型
cmd
命令代码
count
命令计数
-
struct ccw_dev_id¶
ccw 设备的唯一标识符
定义:
struct ccw_dev_id {
u8 ssid;
u16 devno;
};
成员
ssid
子通道集 id
devno
设备号
描述
此结构不是直接基于任何硬件结构。硬件通过其设备号和子通道来标识设备,子通道又通过其 id 来标识。为了获得跨子通道集的 ccw 设备的唯一标识符,引入了 struct ccw_dev_id。
-
int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1, struct ccw_dev_id *dev_id2)¶
比较两个 ccw_dev_id。
参数
struct ccw_dev_id *dev_id1
一个 ccw_dev_id。
struct ccw_dev_id *dev_id2
另一个 ccw_dev_id。
返回值
如果两个结构体逐字段相等,则返回
1
;否则返回0
。
上下文
任意
-
u8 pathmask_to_pos(u8 mask)¶
查找路径掩码中最左侧的位的位置。
参数
u8 mask
至少设置了一位的路径掩码。
ccw 设备¶
想要启动通道 I/O 的设备需要连接到 ccw 总线。与驱动程序核心的交互通过通用 I/O 层完成,该层提供了 ccw 设备和 ccw 设备驱动程序的抽象概念。
启动或终止通道 I/O 的函数都作用于 ccw 设备结构。设备驱动程序不得绕过这些函数,否则可能会发生奇怪的副作用。
-
struct ccw_device¶
通道连接的设备
定义:
struct ccw_device {
spinlock_t *ccwlock;
struct ccw_device_id id;
struct ccw_driver *drv;
struct device dev;
int online;
void (*handler) (struct ccw_device *, unsigned long, struct irb *);
};
成员
ccwlock
指向设备锁的指针
id
此设备的 ID
drv
此设备的 ccw 驱动程序
dev
嵌入的设备结构
online
设备的在线状态
handler
中断处理程序
描述
handler 是设备而不是驱动程序的成员,因为驱动程序可以为不同的 ccw 设备(多子通道驱动程序)使用不同的中断处理程序。
-
struct ccw_driver¶
通道连接设备的设备驱动程序
定义:
struct ccw_driver {
struct ccw_device_id *ids;
int (*probe) (struct ccw_device *);
void (*remove) (struct ccw_device *);
int (*set_online) (struct ccw_device *);
int (*set_offline) (struct ccw_device *);
int (*notify) (struct ccw_device *, int);
void (*path_event) (struct ccw_device *, int *);
void (*shutdown) (struct ccw_device *);
enum uc_todo (*uc_handler) (struct ccw_device *, struct irb *);
struct device_driver driver;
enum interruption_class int_class;
};
成员
ids
此驱动程序支持的 ID
probe
在探测时调用的函数
remove
在移除时调用的函数
set_online
在设置设备在线时调用
set_offline
在设置设备离线时调用
notify
通知驱动程序设备状态更改
path_event
通知驱动程序通道路径事件
shutdown
在设备关闭时调用
uc_handler
单元检查处理程序的回调
driver
嵌入的设备驱动程序结构
int_class
用于计算中断的中断类
-
int ccw_device_set_offline(struct ccw_device *cdev)¶
禁用 ccw 设备进行 I/O 操作。
参数
struct ccw_device *cdev
目标 ccw 设备
描述
此函数如果存在,则为 cdev 调用驱动程序的 set_offline() 函数,然后禁用 cdev。
返回值
成功返回
0
,失败返回负错误值。
上下文
已启用,未持有 ccw 设备锁。
-
int ccw_device_set_online(struct ccw_device *cdev)¶
启用 ccw 设备进行 I/O 操作。
参数
struct ccw_device *cdev
目标 ccw 设备
描述
此函数首先启用 cdev,然后如果存在,则为 cdev 调用驱动程序的 set_online() 函数。如果 set_online() 返回错误,则再次禁用 cdev。
返回值
成功返回
0
,失败返回负错误值。
上下文
已启用,未持有 ccw 设备锁。
-
struct ccw_device *get_ccwdev_by_dev_id(struct ccw_dev_id *dev_id)¶
从 ccw 设备 ID 获取设备。
参数
struct ccw_dev_id *dev_id
要搜索的设备的 ID
描述
此函数搜索连接到 ccw 总线的所有设备,以查找与 dev_id 匹配的设备。
返回值
如果找到设备,则其引用计数会增加并返回;否则返回
NULL
。
-
struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv, const char *bus_id)¶
从总线 ID 获取设备。
参数
struct ccw_driver *cdrv
设备所属的驱动程序。
const char *bus_id
要搜索的设备的总线 ID。
描述
此函数搜索由 cdrv 拥有的所有设备,以查找总线 ID 与 bus_id 匹配的设备。
返回值
如果找到匹配项,则会增加找到的设备的引用计数并返回;否则返回
NULL
。
-
int ccw_driver_register(struct ccw_driver *cdriver)¶
注册 ccw 驱动程序。
-
void ccw_driver_unregister(struct ccw_driver *cdriver)¶
取消注册 ccw 驱动程序。
-
int ccw_device_siosl(struct ccw_device *cdev)¶
启动日志记录。
参数
struct ccw_device *cdev
ccw 设备
描述
此函数用于在通道子系统内调用特定于模型的日志记录。
-
int ccw_device_set_options_mask(struct ccw_device *cdev, unsigned long flags)¶
设置某些选项并取消设置其余选项。
参数
struct ccw_device *cdev
要设置选项的设备
unsigned long flags
要设置的选项
描述
flags 中指定的所有标志位都会被设置,flags 中未指定的所有标志位都会被清除。
返回值
成功时返回
0
,如果标志位组合无效则返回 -EINVAL
。
-
int ccw_device_set_options(struct ccw_device *cdev, unsigned long flags)¶
设置一些选项
参数
struct ccw_device *cdev
要设置选项的设备
unsigned long flags
要设置的选项
描述
flags 中指定的所有标志位都会被设置,其余标志位保持不变。
返回值
成功时返回
0
,如果会导致无效的标志位组合则返回 -EINVAL
。
-
void ccw_device_clear_options(struct ccw_device *cdev, unsigned long flags)¶
清除一些选项
参数
struct ccw_device *cdev
要清除选项的设备
unsigned long flags
要清除的选项
描述
flags 中指定的所有标志位都会被清除,其余标志位保持不变。
-
int ccw_device_is_pathgroup(struct ccw_device *cdev)¶
确定此设备的路径是否分组
参数
struct ccw_device *cdev
ccw 设备
描述
如果存在路径组则返回非零值,否则返回零。
-
int ccw_device_is_multipath(struct ccw_device *cdev)¶
确定设备是否以多路径模式运行
参数
struct ccw_device *cdev
ccw 设备
描述
如果设备以多路径模式运行则返回非零值,否则返回零。
-
int ccw_device_clear(struct ccw_device *cdev, unsigned long intparm)¶
终止 I/O 请求处理
参数
struct ccw_device *cdev
目标 ccw 设备
unsigned long intparm
csch 结束时要返回的中断参数
描述
ccw_device_clear()
在 cdev 的子通道上调用 csch。
返回值
成功时返回
0
,如果设备未运行则返回 -ENODEV
,如果设备状态无效则返回 -EINVAL
。
上下文
禁用中断,持有 ccw 设备锁
-
int ccw_device_start_timeout_key(struct ccw_device *cdev, struct ccw1 *cpa, unsigned long intparm, __u8 lpm, __u8 key, unsigned long flags, int expires)¶
启动带有超时和密钥的 s390 通道程序
参数
struct ccw_device *cdev
目标 ccw 设备
struct ccw1 *cpa
通道程序的逻辑起始地址
unsigned long intparm
用户特定的中断参数;将会返回给 cdev 的中断处理程序。允许设备驱动程序将中断与特定的 I/O 请求关联起来。
__u8 lpm
定义要用于特定 I/O 请求的通道路径。值为 0 将使 cio 使用 opm。
__u8 key
用于 I/O 的存储密钥
unsigned long flags
附加标志;定义 I/O 处理要执行的操作。
int expires
超时值(以 jiffies 为单位)
描述
启动 S/390 通道程序。当中断到达时,会立即调用 IRQ 处理程序,延迟调用(缺少 dev-end 或需要感应),或永不调用(未注册 IRQ 处理程序)。如果通道程序在 expires 指定的时间内未完成,此函数会通知设备驱动程序。如果发生超时,通道程序将通过 xsch、hsch 或 csch 终止,并且设备的 中断处理程序将被调用,并带有一个包含 ERR_PTR(-ETIMEDOUT
) 的 irb。中断处理程序将回显此处指定的 intparm,除非通过后续调用 ccw_device_halt()
或 ccw_device_clear()
指定了另一个中断参数。
返回值
如果操作成功则返回
0
;如果设备繁忙或状态挂起则返回 -EBUSY
;如果 lpm 中未指定可操作的路径则返回 -EACCES
;如果设备未运行则返回 -ENODEV
。
上下文
禁用中断,持有 ccw 设备锁
-
int ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa, unsigned long intparm, __u8 lpm, __u8 key, unsigned long flags)¶
启动带有密钥的 s390 通道程序
参数
struct ccw_device *cdev
目标 ccw 设备
struct ccw1 *cpa
通道程序的逻辑起始地址
unsigned long intparm
用户特定的中断参数;将会返回给 cdev 的中断处理程序。允许设备驱动程序将中断与特定的 I/O 请求关联起来。
__u8 lpm
定义要用于特定 I/O 请求的通道路径。值为 0 将使 cio 使用 opm。
__u8 key
用于 I/O 的存储密钥
unsigned long flags
附加标志;定义 I/O 处理要执行的操作。
描述
启动 S/390 通道程序。当中断到达时,会立即调用 IRQ 处理程序,延迟调用(缺少 dev-end 或需要感应),或永不调用(未注册 IRQ 处理程序)。中断处理程序将回显此处指定的 intparm,除非通过后续调用 ccw_device_halt()
或 ccw_device_clear()
指定了另一个中断参数。
返回值
如果操作成功则返回
0
;如果设备繁忙或状态挂起则返回 -EBUSY
;如果 lpm 中未指定可操作的路径则返回 -EACCES
;如果设备未运行则返回 -ENODEV
。
上下文
禁用中断,持有 ccw 设备锁
-
int ccw_device_start(struct ccw_device *cdev, struct ccw1 *cpa, unsigned long intparm, __u8 lpm, unsigned long flags)¶
启动 s390 通道程序
参数
struct ccw_device *cdev
目标 ccw 设备
struct ccw1 *cpa
通道程序的逻辑起始地址
unsigned long intparm
用户特定的中断参数;将会返回给 cdev 的中断处理程序。允许设备驱动程序将中断与特定的 I/O 请求关联起来。
__u8 lpm
定义要用于特定 I/O 请求的通道路径。值为 0 将使 cio 使用 opm。
unsigned long flags
附加标志;定义 I/O 处理要执行的操作。
描述
启动 S/390 通道程序。当中断到达时,会立即调用 IRQ 处理程序,延迟调用(缺少 dev-end 或需要感应),或永不调用(未注册 IRQ 处理程序)。中断处理程序将回显此处指定的 intparm,除非通过后续调用 ccw_device_halt()
或 ccw_device_clear()
指定了另一个中断参数。
返回值
如果操作成功则返回
0
;如果设备繁忙或状态挂起则返回 -EBUSY
;如果 lpm 中未指定可操作的路径则返回 -EACCES
;如果设备未运行则返回 -ENODEV
。
上下文
禁用中断,持有 ccw 设备锁
-
int ccw_device_start_timeout(struct ccw_device *cdev, struct ccw1 *cpa, unsigned long intparm, __u8 lpm, unsigned long flags, int expires)¶
启动带有超时功能的 s390 通道程序
参数
struct ccw_device *cdev
目标 ccw 设备
struct ccw1 *cpa
通道程序的逻辑起始地址
unsigned long intparm
用户特定的中断参数;将会返回给 cdev 的中断处理程序。允许设备驱动程序将中断与特定的 I/O 请求关联起来。
__u8 lpm
定义要用于特定 I/O 请求的通道路径。值为 0 将使 cio 使用 opm。
unsigned long flags
附加标志;定义 I/O 处理要执行的操作。
int expires
超时值(以 jiffies 为单位)
描述
启动 S/390 通道程序。当中断到达时,会立即调用 IRQ 处理程序,延迟调用(缺少 dev-end 或需要感应),或永不调用(未注册 IRQ 处理程序)。如果通道程序在 expires 指定的时间内未完成,此函数会通知设备驱动程序。如果发生超时,通道程序将通过 xsch、hsch 或 csch 终止,并且设备的 中断处理程序将被调用,并带有一个包含 ERR_PTR(-ETIMEDOUT
) 的 irb。中断处理程序将回显此处指定的 intparm,除非通过后续调用 ccw_device_halt()
或 ccw_device_clear()
指定了另一个中断参数。
返回值
如果操作成功则返回
0
;如果设备繁忙或状态挂起则返回 -EBUSY
;如果 lpm 中未指定可操作的路径则返回 -EACCES
;如果设备未运行则返回 -ENODEV
。
上下文
禁用中断,持有 ccw 设备锁
-
int ccw_device_halt(struct ccw_device *cdev, unsigned long intparm)¶
暂停 I/O 请求处理
参数
struct ccw_device *cdev
目标 ccw 设备
unsigned long intparm
中断参数将在 hsch 结束后返回
描述
ccw_device_halt()
在 cdev 的子通道上调用 hsch。除非通过后续调用 ccw_device_clear()
指定了另一个中断参数,否则中断处理程序将回显此处指定的 intparm。
返回值
成功时返回
0
,设备未运行时返回 -ENODEV
,设备状态无效时返回 -EINVAL
,设备繁忙或中断挂起时返回 -EBUSY
。
上下文
禁用中断,持有 ccw 设备锁
-
int ccw_device_resume(struct ccw_device *cdev)¶
恢复通道程序的执行
参数
struct ccw_device *cdev
目标 ccw 设备
描述
ccw_device_resume()
在 cdev 的子通道上调用 rsch。
返回值
成功时返回
0
,设备未运行时返回 -ENODEV
,设备状态无效时返回 -EINVAL
,设备繁忙或中断挂起时返回 -EBUSY
。
上下文
禁用中断,持有 ccw 设备锁
-
struct ciw *ccw_device_get_ciw(struct ccw_device *cdev, __u32 ct)¶
在扩展感测数据中搜索 CIW 命令。
参数
struct ccw_device *cdev
要检查的 ccw 设备
__u32 ct
要查找的命令类型
描述
在 SenseID 期间,描述设备可用的特殊命令的命令信息字 (CIW) 可能已存储在扩展感测数据中。此函数在扩展感测数据中搜索指定命令类型的 CIW。
返回值
如果未存储扩展感测数据,或者找不到指定命令类型的 CIW,则返回
NULL
,否则返回指向指定命令类型的 CIW 的指针。
-
__u8 ccw_device_get_path_mask(struct ccw_device *cdev)¶
获取当前可用的路径
参数
struct ccw_device *cdev
要查询的 ccw 设备
返回值
如果该设备没有可用的子通道,则返回
0
,否则返回 ccw 设备子通道的当前可用路径的掩码。
-
struct channel_path_desc_fmt0 *ccw_device_get_chp_desc(struct ccw_device *cdev, int chp_idx)¶
返回新分配的通道路径描述符
参数
struct ccw_device *cdev
要获取描述符的设备
int chp_idx
通道路径的索引
描述
成功时返回与给定通道路径关联的通道路径描述数据的新分配的副本。如果出错,则返回 NULL
。
-
u8 *ccw_device_get_util_str(struct ccw_device *cdev, int chp_idx)¶
返回新分配的实用程序字符串
参数
struct ccw_device *cdev
要获取实用程序字符串的设备
int chp_idx
通道路径的索引
描述
成功时返回与给定通道路径关联的实用程序字符串的新分配的副本。如果出错,则返回 NULL
。
-
void ccw_device_get_id(struct ccw_device *cdev, struct ccw_dev_id *dev_id)¶
获取 ccw 设备 ID
参数
struct ccw_device *cdev
要获取 ID 的设备
struct ccw_dev_id *dev_id
在哪里填充值
-
int ccw_device_tm_start_timeout_key(struct ccw_device *cdev, struct tcw *tcw, unsigned long intparm, u8 lpm, u8 key, int expires)¶
执行启动功能
参数
struct ccw_device *cdev
在其上执行启动功能的 ccw 设备
struct tcw *tcw
要启动的传输命令字
unsigned long intparm
要传递给中断处理程序的用户定义参数
u8 lpm
要使用的路径的掩码
u8 key
用于存储访问的存储密钥
int expires
在中止请求之前的时间跨度(以 jiffies 为单位)
描述
在给定的 ccw 设备上启动 tcw。成功时返回零,否则返回非零值。
-
int ccw_device_tm_start_key(struct ccw_device *cdev, struct tcw *tcw, unsigned long intparm, u8 lpm, u8 key)¶
执行启动功能
参数
struct ccw_device *cdev
在其上执行启动功能的 ccw 设备
struct tcw *tcw
要启动的传输命令字
unsigned long intparm
要传递给中断处理程序的用户定义参数
u8 lpm
要使用的路径的掩码
u8 key
用于存储访问的存储密钥
描述
在给定的 ccw 设备上启动 tcw。成功时返回零,否则返回非零值。
-
int ccw_device_tm_start(struct ccw_device *cdev, struct tcw *tcw, unsigned long intparm, u8 lpm)¶
执行启动功能
参数
struct ccw_device *cdev
在其上执行启动功能的 ccw 设备
struct tcw *tcw
要启动的传输命令字
unsigned long intparm
要传递给中断处理程序的用户定义参数
u8 lpm
要使用的路径的掩码
描述
在给定的 ccw 设备上启动 tcw。成功时返回零,否则返回非零值。
-
int ccw_device_tm_start_timeout(struct ccw_device *cdev, struct tcw *tcw, unsigned long intparm, u8 lpm, int expires)¶
执行启动功能
参数
struct ccw_device *cdev
在其上执行启动功能的 ccw 设备
struct tcw *tcw
要启动的传输命令字
unsigned long intparm
要传递给中断处理程序的用户定义参数
u8 lpm
要使用的路径的掩码
int expires
在中止请求之前的时间跨度(以 jiffies 为单位)
描述
在给定的 ccw 设备上启动 tcw。成功时返回零,否则返回非零值。
-
int ccw_device_get_mdc(struct ccw_device *cdev, u8 mask)¶
累积最大数据计数
参数
struct ccw_device *cdev
累积最大数据计数的 ccw 设备
u8 mask
要使用的路径的掩码
描述
返回所有路径至少支持的传输命令的 64KB 块的数量。 返回值 0 表示失败。
-
int ccw_device_tm_intrg(struct ccw_device *cdev)¶
执行询问功能
参数
struct ccw_device *cdev
要在其上执行询问功能的 ccw 设备
描述
在给定的 ccw 设备上执行询问功能。成功返回零,否则返回非零值。
-
void ccw_device_get_schid(struct ccw_device *cdev, struct subchannel_id *schid)¶
获取子通道 ID
参数
struct ccw_device *cdev
要获取 ID 的设备
struct subchannel_id *schid
在哪里填充值
-
int ccw_device_pnso(struct ccw_device *cdev, struct chsc_pnso_area *pnso_area, u8 oc, struct chsc_pnso_resume_token resume_token, int cnc)¶
执行网络子通道操作
参数
struct ccw_device *cdev
在其上执行 PNSO 的设备
struct chsc_pnso_area *pnso_area
操作的请求和响应块
u8 oc
操作码
struct chsc_pnso_resume_token resume_token
多块响应的恢复令牌
int cnc
布尔更改通知控制
描述
pnso_area 必须由调用者使用 get_zeroed_page(GFP_KERNEL) 分配
成功时返回 0。
-
int ccw_device_get_cssid(struct ccw_device *cdev, u8 *cssid)¶
获取通道子系统 ID
参数
struct ccw_device *cdev
获取 CSSID 的设备
u8 *cssid
结果通道子系统 ID
-
int ccw_device_get_iid(struct ccw_device *cdev, u8 *iid)¶
获取 MIF 镜像 ID
参数
struct ccw_device *cdev
获取 MIF 镜像 ID 的设备
u8 *iid
结果 MIF 镜像 ID
-
int ccw_device_get_chpid(struct ccw_device *cdev, int chp_idx, u8 *chpid)¶
获取通道路径 ID
参数
struct ccw_device *cdev
获取通道路径 ID 的设备
int chp_idx
通道路径的索引
u8 *chpid
结果通道路径 ID
-
int ccw_device_get_chid(struct ccw_device *cdev, int chp_idx, u16 *chid)¶
获取与指定 CHPID 关联的通道 ID
参数
struct ccw_device *cdev
获取通道 ID 的设备
int chp_idx
通道路径的索引
u16 *chid
结果通道 ID
通道测量工具¶
通道测量工具提供了一种收集测量数据的方法,该数据由通道子系统为每个连接的通道设备提供。
-
struct cmbdata¶
用户空间的通道测量块数据
定义:
struct cmbdata {
__u64 size;
__u64 elapsed_time;
__u64 ssch_rsch_count;
__u64 sample_count;
__u64 device_connect_time;
__u64 function_pending_time;
__u64 device_disconnect_time;
__u64 control_unit_queuing_time;
__u64 device_active_only_time;
__u64 device_busy_time;
__u64 initial_command_response_time;
};
成员
大小
存储数据的大小
elapsed_time
自上次采样以来的时间
ssch_rsch_count
ssch 和 rsch 的数量
sample_count
采样数量
device_connect_time
设备连接时间
function_pending_time
函数挂起的时间
device_disconnect_time
设备断开连接时间
control_unit_queuing_time
控制单元排队的时间
device_active_only_time
仅设备活动的时间
device_busy_time
设备繁忙时间(扩展格式)
initial_command_response_time
初始命令响应时间(扩展格式)
描述
为了简单起见,所有值都存储为 64 位,尤其是在 32 位仿真模式下。所有时间值都标准化为纳秒。目前,已知两种格式,它们的区别在于此结构的大小,即仅当激活扩展通道测量工具(首次在 z990 机器中发布)时才设置最后两个成员。可能会添加更多字段,这将导致新的 ioctl 编号。
-
int enable_cmf(struct ccw_device *cdev)¶
为特定设备打开通道测量
参数
struct ccw_device *cdev
要启用的 ccw 设备
为 cdev 启用通道测量。如果在已经启用通道测量的设备上调用此函数,则会触发测量数据的重置。
返回值
成功返回 0
或负错误值。
上下文
非原子操作
-
int disable_cmf(struct ccw_device *cdev)¶
为特定设备关闭通道测量
参数
struct ccw_device *cdev
要禁用的 ccw 设备
返回值
成功返回 0
或负错误值。
上下文
非原子操作
-
u64 cmf_read(struct ccw_device *cdev, int index)¶
从当前通道测量块读取一个值
参数
struct ccw_device *cdev
要读取的通道
int index
要读取的值的索引
返回值
读取的值,如果无法读取该值,则返回 0
。
上下文
任意
-
int cmf_readall(struct ccw_device *cdev, struct cmbdata *data)¶
读取当前通道测量块
参数
struct ccw_device *cdev
要读取的通道
struct cmbdata *data
指向将填充的数据块的指针
返回值
成功返回 0
,否则返回负错误值。
上下文
任意
ccwgroup 总线¶
ccwgroup 总线仅包含用户创建的人工设备。许多网络设备(例如 qeth)实际上由多个 ccw 设备(例如 qeth 的读取、写入和数据通道)组成。ccwgroup 总线提供了一种机制来创建包含这些 ccw 设备作为从属设备的元设备,并且可以将其与网络设备关联。
ccw 组设备¶
-
struct ccwgroup_device¶
ccw 组设备
定义:
struct ccwgroup_device {
enum {
CCWGROUP_OFFLINE,
CCWGROUP_ONLINE,
} state;
unsigned int count;
struct device dev;
struct work_struct ungroup_work;
struct ccw_device *cdev[];
};
成员
状态
在线/离线状态
count
附加的从属设备数量
dev
嵌入的设备结构
ungroup_work
用于取消分组 ccwgroup 设备
cdev
可变数量的从属设备,根据需要分配
-
struct ccwgroup_driver¶
ccw 组设备的驱动程序
定义:
struct ccwgroup_driver {
int (*setup) (struct ccwgroup_device *);
void (*remove) (struct ccwgroup_device *);
int (*set_online) (struct ccwgroup_device *);
int (*set_offline) (struct ccwgroup_device *);
void (*shutdown)(struct ccwgroup_device *);
struct device_driver driver;
struct ccw_driver *ccw_driver;
};
成员
setup
在设备创建期间调用以设置设备的函数
remove
在移除时调用的函数
set_online
在设备设置为在线时调用的函数
set_offline
在设备设置为离线时调用的函数
shutdown
在设备关闭时调用的函数
driver
嵌入式驱动程序结构
ccw_driver
支持的 ccw_driver (可选)
-
int ccwgroup_set_online(struct ccwgroup_device *gdev)¶
启用 ccwgroup 设备
参数
struct ccwgroup_device *gdev
目标 ccwgroup 设备
描述
此函数尝试将 ccwgroup 设备设置为在线状态。
返回值
成功返回
0
,失败返回负错误值。
-
int ccwgroup_set_offline(struct ccwgroup_device *gdev, bool call_gdrv)¶
禁用 ccwgroup 设备
参数
struct ccwgroup_device *gdev
目标 ccwgroup 设备
bool call_gdrv
调用已注册的 gdrv set_offline 函数
描述
此函数尝试将 ccwgroup 设备设置为离线状态。
返回值
成功返回
0
,失败返回负错误值。
-
int ccwgroup_create_dev(struct device *parent, struct ccwgroup_driver *gdrv, int num_devices, const char *buf)¶
创建并注册 ccw 组设备
参数
struct device *parent
新设备的父设备
struct ccwgroup_driver *gdrv
新组设备的驱动程序
int num_devices
从属设备的数量
const char *buf
包含以逗号分隔的从属设备总线 ID 的缓冲区
描述
创建并注册一个新的 ccw 组设备,作为 parent 的子设备。从 buf 中给出的总线 ID 列表获取从属设备。
返回值
成功时返回
0
,失败时返回错误代码。
上下文
非原子操作
-
int ccwgroup_driver_register(struct ccwgroup_driver *cdriver)¶
注册 ccw 组驱动程序
-
void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver)¶
注销 ccw 组驱动程序
-
int ccwgroup_probe_ccwdev(struct ccw_device *cdev)¶
从属设备的探测函数
参数
struct ccw_device *cdev
要探测的 ccw 设备
描述
这是一个 ccw 设备的虚拟探测函数,这些 ccw 设备是 ccw 组设备中的从属设备。
返回值
始终为
0
-
void ccwgroup_remove_ccwdev(struct ccw_device *cdev)¶
从属设备的删除函数
参数
struct ccw_device *cdev
要删除的 ccw 设备
描述
这是一个 ccw 设备的删除函数,这些 ccw 设备是 ccw 组设备中的从属设备。它将 ccw 设备设置为离线,并注销嵌入的 ccw 组设备。
通用接口¶
以下部分包含的接口不仅由处理 ccw 设备的驱动程序使用,还由各种其他 s390 硬件的驱动程序使用。
适配器中断¶
公共 I/O 层提供用于处理适配器中断和中断向量的辅助函数。
-
int register_adapter_interrupt(struct airq_struct *airq)¶
注册适配器中断处理程序
参数
struct airq_struct *airq
指向适配器中断描述符的指针
描述
成功时返回 0,否则返回 -EINVAL。
-
void unregister_adapter_interrupt(struct airq_struct *airq)¶
注销适配器中断处理程序
参数
struct airq_struct *airq
指向适配器中断描述符的指针
-
struct airq_iv *airq_iv_create(unsigned long bits, unsigned long flags, unsigned long *vec)¶
创建中断向量
参数
unsigned long bits
中断向量中的位数
unsigned long flags
分配标志
unsigned long *vec
如果为 AIRQ_IV_GUESTVEC,则指向已固定客户内存的指针
描述
返回指向中断向量结构的指针
-
void airq_iv_release(struct airq_iv *iv)¶
释放中断向量
参数
struct airq_iv *iv
指向中断向量结构的指针
-
unsigned long airq_iv_alloc(struct airq_iv *iv, unsigned long num)¶
从中断向量分配 irq 位
参数
struct airq_iv *iv
指向中断向量结构的指针
unsigned long num
要分配的连续 irq 位的数量
描述
返回分配的 irq 块中第一个 irq 的位号,如果没有任何位可用或未指定 AIRQ_IV_ALLOC 标志,则返回 -1UL
-
void airq_iv_free(struct airq_iv *iv, unsigned long bit, unsigned long num)¶
释放中断向量的 irq 位
参数
struct airq_iv *iv
指向中断向量结构的指针
unsigned long bit
要释放的第一个 irq 位的编号
unsigned long num
要释放的连续 irq 位的数量
-
unsigned long airq_iv_scan(struct airq_iv *iv, unsigned long start, unsigned long end)¶
扫描中断向量以查找非零位
参数
struct airq_iv *iv
指向中断向量结构的指针
unsigned long start
搜索起始的位号
unsigned long end
搜索结束的位号
描述
返回下一个非零中断位的位号,如果在扫描完成时未找到任何非零位,则返回 -1UL。