对转换无效的映射进行访问时,将会调用 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); }