S/390 驱动模型接口¶
1. CCW 设备¶
所有可以通过 ccw 寻址的设备都称为“CCW 设备” - 即使它们实际上不是由 ccw 驱动的。
所有 ccw 设备都通过子通道访问,这反映在 devices/ 下的结构中
devices/
- system/
- css0/
- 0.0.0000/0.0.0815/
- 0.0.0001/0.0.4711/
- 0.0.0002/
- 0.1.0000/0.1.1234/
...
- defunct/
在这个例子中,设备 0815 通过子通道集 0 中的子通道 0 访问,设备 4711 通过子通道集 0 中的子通道 1 访问,子通道 2 是非 I/O 子通道。设备 1234 通过子通道集 1 中的子通道 0 访问。
名为 'defunct' 的子通道不代表系统上的任何真实子通道;它是一个伪子通道,如果断开连接的 ccw 设备被另一个在其先前子通道上变为可操作的 ccw 设备取代,则断开连接的 ccw 设备会被移动到该伪子通道。如果 ccw 设备在该子通道上再次变为可操作,它们将再次被移动到正确的子通道。
您应该通过其总线 ID (例如 0.0.4711) 寻址 ccw 设备;该设备可以在 bus/ccw/devices/ 下找到。
所有 ccw 设备都通过 sysfs 导出一些数据。
- cutype
控制单元类型/型号。
- devtype
设备类型/型号(如果适用)。
- availability
对于已断开连接的设备,可以是“good”或“boxed”;“no path”或“no device”。
- online
用于将设备设置为在线和离线的接口。在设备断开连接的特殊情况下(请参阅 1.2 下的 notify 函数),将 0 管道传输到 online 将强制删除设备。
设备驱动程序可以添加条目以导出每个设备的数据和接口。
在每个子通道的基础上也导出一些数据(请参阅 bus/css/devices/ 下)
- chpids
设备通过哪个 chpid 连接。
- pimpampom
已安装路径、可用路径和操作路径掩码。
也可能存在其他数据,例如用于块设备的数据。
1.1 启动 ccw 设备¶
这分几个步骤完成。
每个驱动程序可以提供一个或多个参数接口,可以在其中指定参数。这些接口也属于驱动程序的职责范围。
如果需要,在执行 a. 之后,最终通过 'online' 接口启动设备。
1.2 编写 ccw 设备的驱动程序¶
基本 struct ccw_device
和 struct ccw_driver
数据结构可以在 include/asm/ccwdev.h 下找到
struct ccw_device {
spinlock_t *ccwlock;
struct ccw_device_private *private;
struct ccw_device_id id;
struct ccw_driver *drv;
struct device dev;
int online;
void (*handler) (struct ccw_device *dev, unsigned long intparm,
struct irb *irb);
};
struct ccw_driver {
struct module *owner;
struct ccw_device_id *ids;
int (*probe) (struct ccw_device *);
int (*remove) (struct ccw_device *);
int (*set_online) (struct ccw_device *);
int (*set_offline) (struct ccw_device *);
int (*notify) (struct ccw_device *, int);
struct device_driver driver;
char *name;
};
“private” 字段包含仅用于内部 i/o 操作的数据,设备驱动程序无法使用。
每个驱动程序都应在 MODULE_DEVICE_TABLE 中声明它感兴趣的 CU 类型/型号和/或设备类型/型号。此信息稍后可以在 struct ccw_device_id 字段中找到
struct ccw_device_id {
__u16 match_flags;
__u16 cu_type;
__u16 dev_type;
__u8 cu_model;
__u8 dev_model;
unsigned long driver_info;
};
ccw_driver 中的函数应按以下方式使用
- probe
设备层为驱动程序感兴趣的每个设备调用此函数。驱动程序应仅分配私有结构以放入 dev->driver_data 并创建属性(如果需要)。此外,中断处理程序(见下文)应在此处设置。
int (*probe) (struct ccw_device *cdev);
- 参数
- cdev
要探测的设备。
- remove
当删除驱动程序、设备或模块时,设备层会调用此函数。驱动程序应在此处执行清理。
int (*remove) (struct ccw_device *cdev);
- 参数
- cdev
要删除的设备。
- set_online
当设备通过 'online' 属性激活时,通用 I/O 层会调用此函数。驱动程序应在此处最终设置并激活设备。
int (*set_online) (struct ccw_device *);
- 参数
- cdev
要激活的设备。通用层已验证该设备尚未在线。
- set_offline:当设备通过 'online' 属性停用时,通用 I/O 层会调用此函数。
驱动程序应关闭设备,但不应取消分配其私有数据。
int (*set_offline) (struct ccw_device *);
- 参数
- cdev
- 要停用的设备。通用层已
验证该设备在线。
- notify
对于设备的一些状态更改,通用 I/O 层会调用此函数。
发信号给驱动程序的是
在在线状态下,设备已分离 (CIO_GONE) 或最后一个路径已消失 (CIO_NO_PATH)。驱动程序必须返回 !0 以保留设备;对于返回代码 0,设备将像往常一样被删除(当没有注册通知函数时也是如此)。如果驱动程序想要保留该设备,则会将其移动到断开连接状态。
在断开连接状态下,设备再次可操作 (CIO_OPER)。通用 I/O 层会对设备编号和设备/CU 执行一些健全性检查,以合理确保它仍然是同一设备。如果不是,则会删除旧设备并注册新设备。通过通知函数的返回代码,设备驱动程序会发出信号,指示它是否想要该设备:!0 表示保留,0 表示删除设备并重新注册。
int (*notify) (struct ccw_device *, int);
- 参数
- cdev
状态已更改的设备。
- event
发生的事件。这可以是 CIO_GONE、CIO_NO_PATH 或 CIO_OPER 之一。
struct ccw_device
的 handler 字段旨在设置为设备的中断处理程序。为了适应使用多个不同处理程序(例如,多子通道设备)的驱动程序,这是 ccw_device 的成员,而不是 ccw_driver 的成员。在调用驱动程序之前的 set_online() 处理期间,处理程序会在通用层注册,并在调用驱动程序之后的 set_offline() 期间注销。此外,在注册/注销之后,会执行路径分组或路径组的解散(如果适用)。
void (*handler) (struct ccw_device *dev, unsigned long intparm, struct irb *irb);
- 参数:dev - 为其调用处理程序的设备
- intparm - intparm,允许设备驱动程序识别
与中断关联的 i/o,或将中断识别为未经请求的中断。
- irb - 中断响应块,其中包含累积的
状态。
设备驱动程序是从通用 ccw_device 层调用的,可以从 irb 参数检索有关中断的信息。
1.3 ccwgroup 设备¶
ccwgroup 机制旨在处理由多个 ccw 设备组成的设备,例如 lcs 或 ctc。
ccw 驱动程序提供一个“group”属性。将 ccw 设备的总线 ID 管道传输到此属性会创建一个由这些 ccw 设备组成的 ccwgroup 设备(如果可能)。可以像普通 ccw 设备一样将此 ccwgroup 设备设置为在线或离线。
每个 ccwgroup 设备还提供一个 “ungroup” 属性来再次销毁设备(仅在离线时)。这是一种通用的 ccwgroup 机制(驱动程序无需实现任何超出正常删除例程的功能)。
作为 ccwgroup 设备成员的 ccw 设备在其设备结构的 driver_data 中包含指向 ccwgroup 设备的指针。驱动程序不得触摸此字段 - 它应使用 ccwgroup 设备的 driver_data 来存储其私有数据。
要实现 ccwgroup 驱动程序,请参阅 include/asm/ccwgroup.h。请记住,大多数驱动程序都需要同时实现 ccwgroup 和 ccw 驱动程序。
2. 通道路径¶
通道路径像子通道一样显示在通道子系统根目录 (css0) 下,并称为 'chp0.<chpid>'。它们没有驱动程序,也不属于任何总线。请注意,与 2.4 中的 /proc/chpids 不同,通道路径对象仅反映逻辑状态,而不反映物理状态,因为由于缺少机器支持,我们无法始终如一地跟踪后者(我们无论如何都不需要了解它)。
- status
可以是“online”或“offline”。管道传输 “on” 或 “off” 会在逻辑上将 chpid 设置为在线/离线。向在线 chpid 管道传输 “on” 会为 chpid 连接的所有设备触发路径重新探测。这可以用来强制内核重新使用用户知道在线的通道路径,但机器尚未为其创建机器检查。
- type
通道路径的物理类型。
- shared
通道路径是否共享。
- cmg
通道测量组。
3. 系统设备¶
3.1 xpram¶
xpram 在 devices/system/ 下显示为 ‘xpram’。
3.2 cpus¶
对于每个 cpu,会在 devices/system/cpu/ 下创建一个目录。 每个 cpu 都有一个 ‘online’ 属性,该属性可以是 0 或 1。
4. 其他设备¶
4.1 Netiucv¶
netiucv 驱动程序在 bus/iucv/drivers/netiucv 下创建一个名为 ‘connection’ 的属性。 通过管道传输到此属性会创建一个新的 netiucv 连接到指定的 host。
Netiucv 连接在 devices/iucv/ 下显示为 “netiucv<ifnum>”。 接口编号会按顺序分配给通过 ‘connection’ 属性定义的连接。
- user
显示连接伙伴。
- buffer
最大缓冲区大小。通过管道传输到此属性可以更改缓冲区大小。