Writing Device Drivers

devmap_access()

int xxdevmap_access(devmap_cookie_t handle, void *devprivate,
 	offset_t offset, size_t len, u_int type, u_int rw);

This entry point is called when an access is made to a mapping whose translations are invalid. Mapping translations are invalidated when the mapping is created with devmap_devmem_setup(9F) in response to mmap(2), duplicated by fork(2), or explicitly invalidated by a call to devmap_unload(9F).

handle is the mapping handle of the mapping that was accessed by a user process.

devprivate is a pointer to the driver private data associated with the mapping.

offset is the offset within the mapping that was accessed.

len is the length in bytes of the memory being accessed.

type is the type of access operation.

rw specifies the direction of access.

The system expects devmap_access(9E) to call either devmap_do_ctxmgt(9F) or devmap_default_access(9F) to load the memory address translations before it returns. For mappings that support context switching, the device driver should call devmap_do_ctxmgt(9F). This routine is passed all parameters from devmap_access(9E), and in addition a pointer to the driver entry point devmap_contextmgt(9E), which handles the context switching. For mappings that do not support context switching, the driver should call devmap_default_access(9F), whose only purpose is to call devmap_load(9F) to load the user translation.

Example 12-3 shows an example of a devmap_access(9E) entry point. The mapping is devided into two regions. The region starting at offset OFF_CTXMG with a length of CTXMGT_SIZE bytes supports context management. The rest of the mapping supports default access.


Example 12-3 devmap_access(9E) Routine

#define OFF_CTXMG						0
#define CTXMGT_SIZE						0x20000		
static int
xxdevmap_access(devmap_cookie_t handle, void *devprivate,
        	offset_t off, size_t len, u_int type, u_int 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);
}