Sun Microsystems, Inc.
spacerspacer
spacer www.sun.com docs.sun.com |
spacer
black dot
 
 
13.  Device Context Management Context Management Operation Device Context Management Entry Points devmap_contextmgt() Entry Point  Previous   Contents   Next 
   
 

devmap_dup() Entry Point

The syntax for devmap_dup(9E) is:

int xxdevmap_dup(devmap_cookie_t handle, void *devprivate,
    devmap_cookie_t new_handle, void **new_devprivate);

This entry point is called when a device mapping is duplicated, for example, by a user process calling fork(2). The driver is expected to generate new driver private data for the new mapping.

handle

Mapping handle of the mapping being duplicated

new_handle

Mapping handle of the mapping that was duplicated

devprivate

Pointer to the driver private data associated with the mapping being duplicated

*new_devprivate

Should be set to point to the new driver private data for the new mapping

Mappings created with devmap_dup() will, by default, have their mapping translations invalidated. This will force a call to the devmap_access(9E) entry point the first time the mapping is accessed.

Example 13-4 shows a devmap_dup() routine.


Example 13-4 devmap_dup(9E) Routine

static int
xxdevmap_dup(devmap_cookie_t handle, void *devprivate,
    devmap_cookie_t new_handle, void **new_devprivate)
{
        struct xxctx *ctxp = devprivate;
        struct xxstate *xsp = ctxp->xsp;
        struct xxctx *newctx;
        /* Create a new context for the duplicated mapping */
        newctx = kmem_alloc(sizeof (struct xxctx), KM_SLEEP);
        newctx->xsp = xsp;
        newctx->handle = new_handle;
        newctx->offset = ctxp->offset;
        newctx->flags = ctxp->flags;
        newctx->len = ctxp->len;
        mutex_enter(&xsp->ctx_lock);
        if (ctxp->flags & MAP_PRIVATE) {
                newctx->context = kmem_alloc(XXCTX_SIZE, KM_SLEEP);
                bcopy(ctxp->context, newctx->context, XXCTX_SIZE);
        } else {
                newctx->context = xsp->ctx_shared;
        }
        mutex_exit(&xsp->ctx_lock);
        *new_devprivate = newctx;
        return(0);
}

devmap_unmap() Entry Point

The syntax for devmap_unmap(9E) is a s follows:

void xxdevmap_unmap(devmap_cookie_t handle, void *devprivate,
    offset_t off, size_t len, devmap_cookie_t new_handle1,
    void **new_devprivate1, devmap_cookie_t new_handle2,
    void **new_devprivate2);

This entry point is called when a mapping is unmapped. This can be caused by a user process exiting or calling the munmap(2) system call.

handle

Mapping handle of the mapping being freed.

devprivate

Pointer to the driver private data associated with the mapping.

off

Offset within the logical device memory at which the unmapping begins.

len

Length in bytes of the memory being unmapped.

new_handle1

Handle that the system uses to describe the new region that ends at off - 1. new_handle1 may be NULL.

new_devprivate1

Pointer to be filled in by the driver with the driver -private mapping data for the new region that ends at off - 1. It is ignored if new_handle1 is NULL.

new_handle2

Handle that the system uses to describe the new region that begins at off + len. new_handle2 may be NULL.

new_devprivate2

Pointer to be filled in by the driver with the driver private mapping data for the new region that begins at off + len. It is ignored if new_handle2 is NULL.

The devmap_unmap() routine is expected to free any driver private resources that were allocated when this mapping was created, either by devmap_map(9E) or by devmap_dup(9E). If only a part of the mapping is being unmapped, the driver must allocate a new private data for the remaining mapping before freeing the old private data. There is no need to call devmap_unload(9F) on the handle of the mapping being freed, even if it is the mapping with the valid translations. However, to prevent future problems in devmap_access(9E), the device driver should make sure that its representation of the current mapping is set to "no current mapping".

Example 13-5 shows an example of a devmap_unmap() routine.


Example 13-5 devmap_unmap(9E) Routine

static void
xxdevmap_unmap(devmap_cookie_t handle, void *devprivate,
    offset_t off, size_t len, devmap_cookie_t new_handle1,
    void **new_devprivate1, devmap_cookie_t new_handle2,
    void **new_devprivate2)
{
        struct xxctx *ctxp = devprivate;
        struct xxstate *xsp = ctxp->xsp;
        mutex_enter(&xsp->ctx_lock);

        /*
         * If new_handle1 is not NULL, we are unmapping
         * at the end of the mapping.
         */
        if (new_handle1 != NULL) {
                /* Create a new context structure for the mapping */
                newctx = kmem_alloc(sizeof (struct xxctx), KM_SLEEP);
                newctx->xsp = xsp;
                   if (ctxp->flags & MAP_PRIVATE) {
                           /* allocate memory for the private context
                           /* and copy it */
                        newctx->context = kmem_alloc(XXCTX_SIZE, KM_SLEEP);
                        bcopy(ctxp->context, newctx->context, XXCTX_SIZE);
                } else {
                        /* point to the shared context */
                        newctx->context = xsp->ctx_shared;
                }
                newctx->handle = new_handle1;
                newctx->offset = ctxp->offset;
                newctx->len = off - ctxp->offset;
                *new_devprivate1 = newctx;
        }
        /*
         * If new_handle2 is not NULL, we are unmapping
         * at the beginning of the mapping.
         */
        if (new_handle2 != NULL) {
                /* Create a new context for the mapping */
                newctx = kmem_alloc(sizeof (struct xxctx), KM_SLEEP);
                newctx->xsp = xsp;
                if (ctxp->flags & MAP_PRIVATE) {
                        newctx->context = kmem_alloc(XXCTX_SIZE, KM_SLEEP);
                        bcopy(ctxp->context, newctx->context, XXCTX_SIZE);
                } else {
                        newctx->context = xsp->ctx_shared;
                }
                newctx->handle = new_handle2;
                newctx->offset = off + len;
                newctx->flags = ctxp->flags;
                newctx->len = ctxp->len - (off + len - ctxp->off);
                *new_devprivate2 = newctx;
        }
        if (xsp->current_ctx == ctxp)
                xsp->current_ctx = NULL;
        mutex_exit(&xsp->ctx_lock);
        if (ctxp->flags & MAP_PRIVATE)
                kmem_free(ctxp->context, XXCTX_SIZE);
        kmem_free(ctxp, sizeof (struct xxctx));
}

 
 
 
  Previous   Contents   Next