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 设备再次在该子通道上运行,它们将被再次移动到适当的子通道。
您应该通过其总线 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
设备通过哪些 chpids 连接。
- 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,设备将像往常一样被删除(即使未注册任何 notify 函数)。如果驱动程序想要保留该设备,则会将其移动到断开连接状态。
在断开连接状态下,设备再次运行 (CIO_OPER)。公共 I/O 层对设备编号和设备/CU 执行一些健全性检查,以合理确定它是否仍然是同一设备。如果不是,则删除旧设备并注册一个新设备。通过 notify 函数的返回代码,设备驱动程序发出信号,表明它是否希望将设备取回:!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 设备组成的设备,如 qeth 或 ctc。
ccw 驱动程序提供了一个“group”属性。将 ccw 设备的总线 ID 管道到此属性会创建一个由这些 ccw 设备组成的 ccwgroup 设备(如果可能)。此 ccwgroup 设备可以像普通 ccw 设备一样设置为上线或下线。
每个 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 逻辑上设置为上线/下线。将“on”管道到在线 chpid 会触发 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 连接。
Netiucv 连接显示在 devices/iucv/ 下,作为“netiucv<ifnum>”。接口编号按顺序分配给通过“connection”属性定义的连接。
- user
显示连接伙伴。
- buffer
最大缓冲区大小。管道到它可以更改缓冲区大小。