编写 s390 通道设备驱动程序

作者:

Cornelia Huck

简介

本文档描述了可用于驱动基于 s390 的通道连接 I/O 设备的设备驱动程序的接口。这包括用于与硬件交互的接口和用于与通用驱动程序核心交互的接口。这些接口由 s390 通用 I/O 层提供。

本文档假定熟悉与 s390 通道 I/O 架构相关的技术术语。有关此架构的描述,请参阅 IBM 出版物 SA22-7832,“z/Architecture:操作原理”。

虽然 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 是用于寻址其设备的基本命令结构,ccw 总线包含所谓的通道连接设备。它们通过 I/O 子通道寻址,这些子通道在 css 总线上可见。但是,用于通道连接设备的设备驱动程序永远不会直接与子通道交互,而只会通过 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

中断处理程序

描述

由于驱动程序可以为不同的 ccw 设备(多子通道驱动程序)具有不同的中断处理程序,因此 handler 是设备而不是驱动程序的成员。

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 驱动程序

参数

struct ccw_driver *cdriver

要注册的驱动程序

描述

此函数主要是 driver_register() 的一个包装器。

返回值

成功时返回 0,失败时返回负错误值。

void ccw_driver_unregister(struct ccw_driver *cdriver)

注销一个 ccw 驱动程序

参数

struct ccw_driver *cdriver

要注销的驱动程序

描述

此函数主要是 driver_unregister() 的一个包装器。

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

以节拍为单位的超时值

描述

启动 S/390 通道程序。当中断到达时,将立即、延迟(缺少 dev-end 或需要感应)或从不(未注册 IRQ 处理程序)调用 IRQ 处理程序。如果在 expires 指定的时间内通道程序未完成,则此函数会通知设备驱动程序。如果发生超时,则通道程序将通过 xsch、hsch 或 csch 终止,并且设备的 中断处理程序将使用包含 ERR_PTR(-ETIMEDOUT) 的 irb 进行调用。除非通过后续调用 ccw_device_halt()ccw_device_clear() 来指定另一个中断参数,否则中断处理程序将回显此处指定的 intparm

返回值

如果操作成功,则返回 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 通道程序。当中断到达时,将立即、延迟(缺少 dev-end 或需要感应)或从不(未注册 IRQ 处理程序)调用 IRQ 处理程序。除非通过后续调用 ccw_device_halt()ccw_device_clear() 来指定另一个中断参数,否则中断处理程序将回显此处指定的 intparm

返回值

如果操作成功,则返回 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 通道程序。当中断到达时,将立即、延迟(缺少 dev-end 或需要感应)或从不(未注册 IRQ 处理程序)调用 IRQ 处理程序。除非通过后续调用 ccw_device_halt()ccw_device_clear() 来指定另一个中断参数,否则中断处理程序将回显此处指定的 intparm

返回值

如果操作成功,则返回 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

以节拍为单位的超时值

描述

启动 S/390 通道程序。当中断到达时,将立即、延迟(缺少 dev-end 或需要感应)或从不(未注册 IRQ 处理程序)调用 IRQ 处理程序。如果在 expires 指定的时间内通道程序未完成,则此函数会通知设备驱动程序。如果发生超时,则通道程序将通过 xsch、hsch 或 csch 终止,并且设备的 中断处理程序将使用包含 ERR_PTR(-ETIMEDOUT) 的 irb 进行调用。除非通过后续调用 ccw_device_halt()ccw_device_clear() 来指定另一个中断参数,否则中断处理程序将回显此处指定的 intparm

返回值

如果操作成功,则返回 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

要使用的路径的掩码

描述

返回所有路径至少支持的传输命令的 64K 字节块的数量。 返回值 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 设备作为从设备,并且可以与 netdevice 相关联。

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 组驱动程序

参数

struct ccwgroup_driver *cdriver

要注册的驱动程序

描述

此函数主要是 driver_register() 的一个包装器。

void ccwgroup_driver_unregister(struct ccwgroup_driver *cdriver)

注销 ccw 组驱动程序

参数

struct ccwgroup_driver *cdriver

要注销的驱动程序

描述

此函数主要是 driver_unregister() 的一个包装器。

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。