对转换无效的映射进行访问时,将会调用 devmap_access(9E) 入口点。映射转换在以下几种情况下无效:作为对 mmap(2) 的响应通过 devmap_devmem_setup(9F) 创建映射;通过 fork(2) 复制映射或通过调用 devmap_unload(9F) 显式使映射无效。
devmap_access() 的语法如下所示:
int xxdevmap_access(devmap_cookie_t handle, void *devprivate,
offset_t offset, size_t len, uint_t type, uint_t rw);
其中:
用户进程所访问的映射的映射句柄。
指向与映射关联的驱动程序专用数据的指针。
所访问映射内的偏移。
所访问内存的长度(以字节为单位)。
访问操作的类型。
用于指定访问的方向。
系统期望 devmap_access(9E) 调用 devmap_do_ctxmgt(9F) 或 devmap_default_access(9F) 以便在 devmap_access() 返回前装入内存地址转换。对于支持上下文切换的映射,设备驱动程序应调用 devmap_do_ctxmgt()。系统会通过 devmap_access(9E) 向此例程传递所有参数以及指向驱动程序入口点 devmap_contextmgt(9E) 的指针,该指针用来处理上下文切换。对于不支持上下文切换的映射,驱动程序应调用 devmap_default_access(9F)。devmap_default_access() 的用途是调用 devmap_load(9F) 以装入用户转换。
以下示例说明了 devmap_access(9E) 入口点。该映射分为两个区域。在偏移 OFF_CTXMG 上开始并且长度为 CTXMGT_SIZE 字节的区域支持上下文管理。其余映射支持缺省访问。
#define OFF_CTXMG 0
#define CTXMGT_SIZE 0x20000
static int
xxdevmap_access(devmap_cookie_t handle, void *devprivate,
offset_t off, size_t len, uint_t type, uint_t rw)
{
offset_t diff;
int error;
if ((diff = off - OFF_CTXMG) >= 0 && diff < CTXMGT_SIZE) {
error = devmap_do_ctxmgt(handle, devprivate, off,
len, type, rw, xxdevmap_contextmgt);
} else {
error = devmap_default_access(handle, devprivate,
off, len, type, rw);
}
return (error);
}