Annotation of Gnu-Mach/device/dev_pager.c, revision 1.1.1.1

1.1       root        1: /* 
                      2:  * Mach Operating System
                      3:  * Copyright (c) 1993-1989 Carnegie Mellon University
                      4:  * All Rights Reserved.
                      5:  * 
                      6:  * Permission to use, copy, modify and distribute this software and its
                      7:  * documentation is hereby granted, provided that both the copyright
                      8:  * notice and this permission notice appear in all copies of the
                      9:  * software, derivative works or modified versions, and any portions
                     10:  * thereof, and that both notices appear in supporting documentation.
                     11:  * 
                     12:  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
                     13:  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
                     14:  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
                     15:  * 
                     16:  * Carnegie Mellon requests users of this software to return to
                     17:  * 
                     18:  *  Software Distribution Coordinator  or  [email protected]
                     19:  *  School of Computer Science
                     20:  *  Carnegie Mellon University
                     21:  *  Pittsburgh PA 15213-3890
                     22:  * 
                     23:  * any improvements or extensions that they make and grant Carnegie Mellon
                     24:  * the rights to redistribute these changes.
                     25:  */
                     26: /*
                     27:  *     Author: David B. Golub, Carnegie Mellon University
                     28:  *     Date:   3/89
                     29:  *
                     30:  *     Device pager.
                     31:  */
                     32: #include <norma_vm.h>
                     33: 
                     34: #include <mach/boolean.h>
                     35: #include <mach/port.h>
                     36: #include <mach/message.h>
                     37: #include <mach/std_types.h>
                     38: #include <mach/mach_types.h>
                     39: 
                     40: #include <ipc/ipc_port.h>
                     41: #include <ipc/ipc_space.h>
                     42: 
                     43: #include <kern/queue.h>
                     44: #include <kern/zalloc.h>
                     45: #include <kern/kalloc.h>
                     46: 
                     47: #include <vm/vm_page.h>
                     48: #include <vm/vm_kern.h>
                     49: 
                     50: #include <device/device_types.h>
                     51: #include <device/ds_routines.h>
                     52: #include <device/dev_hdr.h>
                     53: #include <device/io_req.h>
                     54: 
                     55: extern vm_offset_t     block_io_mmap();        /* dummy routine to allow
                     56:                                                   mmap for block devices */
                     57: 
                     58: /*
                     59:  *     The device pager routines are called directly from the message
                     60:  *     system (via mach_msg), and thus run in the kernel-internal
                     61:  *     environment.  All ports are in internal form (ipc_port_t),
                     62:  *     and must be correctly reference-counted in order to be saved
                     63:  *     in other data structures.  Kernel routines may be called
                     64:  *     directly.  Kernel types are used for data objects (tasks,
                     65:  *     memory objects, ports).  The only IPC routines that may be
                     66:  *     called are ones that masquerade as the kernel task (via
                     67:  *     msg_send_from_kernel).
                     68:  *
                     69:  *     Port rights and references are maintained as follows:
                     70:  *             Memory object port:
                     71:  *                     The device_pager task has all rights.
                     72:  *             Memory object control port:
                     73:  *                     The device_pager task has only send rights.
                     74:  *             Memory object name port:
                     75:  *                     The device_pager task has only send rights.
                     76:  *                     The name port is not even recorded.
                     77:  *     Regardless how the object is created, the control and name
                     78:  *     ports are created by the kernel and passed through the memory
                     79:  *     management interface.
                     80:  *
                     81:  *     The device_pager assumes that access to its memory objects
                     82:  *     will not be propagated to more that one host, and therefore
                     83:  *     provides no consistency guarantees beyond those made by the
                     84:  *     kernel.
                     85:  *
                     86:  *     In the event that more than one host attempts to use a device
                     87:  *     memory object, the device_pager will only record the last set
                     88:  *     of port names.  [This can happen with only one host if a new
                     89:  *     mapping is being established while termination of all previous
                     90:  *     mappings is taking place.]  Currently, the device_pager assumes
                     91:  *     that its clients adhere to the initialization and termination
                     92:  *     protocols in the memory management interface; otherwise, port
                     93:  *     rights or out-of-line memory from erroneous messages may be
                     94:  *     allowed to accumulate.
                     95:  *
                     96:  *     [The phrase "currently" has been used above to denote aspects of
                     97:  *     the implementation that could be altered without changing the rest
                     98:  *     of the basic documentation.]
                     99:  */
                    100: 
                    101: /*
                    102:  * Basic device pager structure.
                    103:  */
                    104: struct dev_pager {
                    105:        decl_simple_lock_data(, lock)   /* lock for reference count */
                    106:        int             ref_count;      /* reference count */
                    107:        int             client_count;   /* How many memory_object_create
                    108:                                         * calls have we received */
                    109:        ipc_port_t      pager;          /* pager port */
                    110:        ipc_port_t      pager_request;  /* Known request port */
                    111:        ipc_port_t      pager_name;     /* Known name port */
                    112:        mach_device_t   device;         /* Device handle */
                    113:        int             type;           /* to distinguish */
                    114: #define DEV_PAGER_TYPE 0
                    115: #define CHAR_PAGER_TYPE        1
                    116:        /* char pager specifics */
                    117:        int             prot;
                    118:        vm_size_t       size;
                    119: };
                    120: typedef struct dev_pager *dev_pager_t;
                    121: #define        DEV_PAGER_NULL  ((dev_pager_t)0)
                    122: 
                    123: 
                    124: zone_t         dev_pager_zone;
                    125: 
                    126: void dev_pager_reference(register dev_pager_t  ds)
                    127: {
                    128:        simple_lock(&ds->lock);
                    129:        ds->ref_count++;
                    130:        simple_unlock(&ds->lock);
                    131: }
                    132: 
                    133: void dev_pager_deallocate(register dev_pager_t ds)
                    134: {
                    135:        simple_lock(&ds->lock);
                    136:        if (--ds->ref_count > 0) {
                    137:            simple_unlock(&ds->lock);
                    138:            return;
                    139:        }
                    140: 
                    141:        simple_unlock(&ds->lock);
                    142:        zfree(dev_pager_zone, (vm_offset_t)ds);
                    143: }
                    144: 
                    145: /*
                    146:  * A hash table of ports for device_pager backed objects.
                    147:  */
                    148: 
                    149: #define        DEV_PAGER_HASH_COUNT            127
                    150: 
                    151: struct dev_pager_entry {
                    152:        queue_chain_t   links;
                    153:        ipc_port_t      name;
                    154:        dev_pager_t     pager_rec;
                    155: };
                    156: typedef struct dev_pager_entry *dev_pager_entry_t;
                    157: 
                    158: queue_head_t   dev_pager_hashtable[DEV_PAGER_HASH_COUNT];
                    159: zone_t         dev_pager_hash_zone;
                    160: decl_simple_lock_data(,
                    161:                dev_pager_hash_lock)
                    162: 
                    163: #define        dev_pager_hash(name_port) \
                    164:                (((natural_t)(name_port) & 0xffffff) % DEV_PAGER_HASH_COUNT)
                    165: 
                    166: void dev_pager_hash_init(void)
                    167: {
                    168:        register int    i;
                    169:        register vm_size_t      size;
                    170: 
                    171:        size = sizeof(struct dev_pager_entry);
                    172:        dev_pager_hash_zone = zinit(
                    173:                                size,
                    174:                                size * 1000,
                    175:                                PAGE_SIZE,
                    176:                                FALSE,
                    177:                                "dev_pager port hash");
                    178:        for (i = 0; i < DEV_PAGER_HASH_COUNT; i++)
                    179:            queue_init(&dev_pager_hashtable[i]);
                    180:        simple_lock_init(&dev_pager_hash_lock);
                    181: }
                    182: 
                    183: void dev_pager_hash_insert(
                    184:        ipc_port_t      name_port,
                    185:        dev_pager_t     rec)
                    186: {
                    187:        register dev_pager_entry_t new_entry;
                    188: 
                    189:        new_entry = (dev_pager_entry_t) zalloc(dev_pager_hash_zone);
                    190:        new_entry->name = name_port;
                    191:        new_entry->pager_rec = rec;
                    192: 
                    193:        simple_lock(&dev_pager_hash_lock);
                    194:        queue_enter(&dev_pager_hashtable[dev_pager_hash(name_port)],
                    195:                        new_entry, dev_pager_entry_t, links);
                    196:        simple_unlock(&dev_pager_hash_lock);
                    197: }
                    198: 
                    199: void dev_pager_hash_delete(ipc_port_t  name_port)
                    200: {
                    201:        register queue_t        bucket;
                    202:        register dev_pager_entry_t      entry;
                    203: 
                    204:        bucket = &dev_pager_hashtable[dev_pager_hash(name_port)];
                    205: 
                    206:        simple_lock(&dev_pager_hash_lock);
                    207:        for (entry = (dev_pager_entry_t)queue_first(bucket);
                    208:             !queue_end(bucket, &entry->links);
                    209:             entry = (dev_pager_entry_t)queue_next(&entry->links)) {
                    210:            if (entry->name == name_port) {
                    211:                queue_remove(bucket, entry, dev_pager_entry_t, links);
                    212:                break;
                    213:            }
                    214:        }
                    215:        simple_unlock(&dev_pager_hash_lock);
                    216:        if (entry)
                    217:            zfree(dev_pager_hash_zone, (vm_offset_t)entry);
                    218: }
                    219: 
                    220: dev_pager_t dev_pager_hash_lookup(ipc_port_t   name_port)
                    221: {
                    222:        register queue_t        bucket;
                    223:        register dev_pager_entry_t      entry;
                    224:        register dev_pager_t    pager;
                    225: 
                    226:        bucket = &dev_pager_hashtable[dev_pager_hash(name_port)];
                    227: 
                    228:        simple_lock(&dev_pager_hash_lock);
                    229:        for (entry = (dev_pager_entry_t)queue_first(bucket);
                    230:             !queue_end(bucket, &entry->links);
                    231:             entry = (dev_pager_entry_t)queue_next(&entry->links)) {
                    232:            if (entry->name == name_port) {
                    233:                pager = entry->pager_rec;
                    234:                dev_pager_reference(pager);
                    235:                simple_unlock(&dev_pager_hash_lock);
                    236:                return (pager);
                    237:            }
                    238:        }
                    239:        simple_unlock(&dev_pager_hash_lock);
                    240:        return (DEV_PAGER_NULL);
                    241: }
                    242: 
                    243: kern_return_t  device_pager_setup(
                    244:        mach_device_t   device,
                    245:        int             prot,
                    246:        vm_offset_t     offset,
                    247:        vm_size_t       size,
                    248:        mach_port_t     *pager)
                    249: {
                    250:        register dev_pager_t    d;
                    251: 
                    252:        /*
                    253:         *      Verify the device is indeed mappable
                    254:         */
                    255:        if (!device->dev_ops->d_mmap || (device->dev_ops->d_mmap == nomap))
                    256:                return (D_INVALID_OPERATION);
                    257: 
                    258:        /*
                    259:         *      Allocate a structure to hold the arguments
                    260:         *      and port to represent this object.
                    261:         */
                    262: 
                    263:        d = dev_pager_hash_lookup((ipc_port_t)device);  /* HACK */
                    264:        if (d != DEV_PAGER_NULL) {
                    265:                *pager = (mach_port_t) ipc_port_make_send(d->pager);
                    266:                dev_pager_deallocate(d);
                    267:                return (D_SUCCESS);
                    268:        }
                    269: 
                    270:        d = (dev_pager_t) zalloc(dev_pager_zone);
                    271:        if (d == DEV_PAGER_NULL)
                    272:                return (KERN_RESOURCE_SHORTAGE);
                    273: 
                    274:        simple_lock_init(&d->lock);
                    275:        d->ref_count = 1;
                    276: 
                    277:        /*
                    278:         * Allocate the pager port.
                    279:         */
                    280:        d->pager = ipc_port_alloc_kernel();
                    281:        if (d->pager == IP_NULL) {
                    282:                dev_pager_deallocate(d);
                    283:                return (KERN_RESOURCE_SHORTAGE);
                    284:        }
                    285: 
                    286:        d->client_count = 0;
                    287:        d->pager_request = IP_NULL;
                    288:        d->pager_name = IP_NULL;
                    289:        d->device = device;
                    290:        mach_device_reference(device);
                    291:        d->prot = prot;
                    292:        d->size = round_page(size);
                    293:        if (device->dev_ops->d_mmap == block_io_mmap) {
                    294:                d->type = DEV_PAGER_TYPE;
                    295:        } else {
                    296:                d->type = CHAR_PAGER_TYPE;
                    297:        }
                    298: 
                    299:        dev_pager_hash_insert(d->pager, d);
                    300:        dev_pager_hash_insert((ipc_port_t)device, d);   /* HACK */
                    301: 
                    302:        *pager = (mach_port_t) ipc_port_make_send(d->pager);
                    303:        return (KERN_SUCCESS);
                    304: }
                    305: 
                    306: /*
                    307:  *     Routine:        device_pager_release
                    308:  *     Purpose:
                    309:  *             Relinquish any references or rights that were
                    310:  *             associated with the result of a call to
                    311:  *             device_pager_setup.
                    312:  */
                    313: void   device_pager_release(memory_object_t    object)
                    314: {
                    315:        if (MACH_PORT_VALID(object))
                    316:                ipc_port_release_send((ipc_port_t) object);
                    317: }
                    318: 
                    319: boolean_t      device_pager_debug = FALSE;
                    320: 
                    321: boolean_t      device_pager_data_request_done();       /* forward */
                    322: boolean_t      device_pager_data_write_done();         /* forward */
                    323: 
                    324: 
                    325: kern_return_t  device_pager_data_request(
                    326:        ipc_port_t      pager,
                    327:        ipc_port_t      pager_request,
                    328:        vm_offset_t     offset,
                    329:        vm_size_t       length,
                    330:        vm_prot_t       protection_required)
                    331: {
                    332:        register dev_pager_t    ds;
                    333: 
                    334: #ifdef lint
                    335:        protection_required++;
                    336: #endif lint
                    337: 
                    338:        if (device_pager_debug)
                    339:                printf("(device_pager)data_request: pager=%d, offset=0x%x, length=0x%x\n",
                    340:                        pager, offset, length);
                    341: 
                    342:        ds = dev_pager_hash_lookup((ipc_port_t)pager);
                    343:        if (ds == DEV_PAGER_NULL)
                    344:                panic("(device_pager)data_request: lookup failed");
                    345: 
                    346:        if (ds->pager_request != pager_request)
                    347:                panic("(device_pager)data_request: bad pager_request");
                    348: 
                    349:        if (ds->type == CHAR_PAGER_TYPE) {
                    350:            register vm_object_t        object;
                    351:            vm_offset_t                 device_map_page(void *,vm_offset_t);
                    352: 
                    353: #if    NORMA_VM
                    354:            object = vm_object_lookup(pager);
                    355: #else  NORMA_VM
                    356:            object = vm_object_lookup(pager_request);
                    357: #endif NORMA_VM
                    358:            if (object == VM_OBJECT_NULL) {
                    359:                    (void) r_memory_object_data_error(pager_request,
                    360:                                                      offset, length,
                    361:                                                      KERN_FAILURE);
                    362:                    dev_pager_deallocate(ds);
                    363:                    return (KERN_SUCCESS);
                    364:            }
                    365: 
                    366:            vm_object_page_map(object,
                    367:                               offset, length,
                    368:                               device_map_page, (char *)ds);
                    369: 
                    370:            vm_object_deallocate(object);
                    371:        }
                    372:        else {
                    373:            register io_req_t           ior;
                    374:            register mach_device_t      device;
                    375:            io_return_t                 result;
                    376: 
                    377:            panic("(device_pager)data_request: dev pager");
                    378:            
                    379:            device = ds->device;
                    380:            mach_device_reference(device);
                    381:            dev_pager_deallocate(ds);
                    382:            
                    383:            /*
                    384:             * Package the read for the device driver.
                    385:             */
                    386:            io_req_alloc(ior, 0);
                    387:            
                    388:            ior->io_device      = device;
                    389:            ior->io_unit        = device->dev_number;
                    390:            ior->io_op          = IO_READ | IO_CALL;
                    391:            ior->io_mode        = 0;
                    392:            ior->io_recnum      = offset / device->bsize;
                    393:            ior->io_data        = 0;            /* driver must allocate */
                    394:            ior->io_count       = length;
                    395:            ior->io_alloc_size  = 0;            /* no data allocated yet */
                    396:            ior->io_residual    = 0;
                    397:            ior->io_error       = 0;
                    398:            ior->io_done        = device_pager_data_request_done;
                    399:            ior->io_reply_port  = pager_request;
                    400:            ior->io_reply_port_type = MACH_MSG_TYPE_PORT_SEND;
                    401:            
                    402:            result = (*device->dev_ops->d_read)(device->dev_number, ior);
                    403:            if (result == D_IO_QUEUED)
                    404:                return (KERN_SUCCESS);
                    405:            
                    406:            /*
                    407:             * Return by queuing IOR for io_done thread, to reply in
                    408:             * correct environment (kernel).
                    409:             */
                    410:            ior->io_error = result;
                    411:            iodone(ior);
                    412:        }
                    413: 
                    414:        dev_pager_deallocate(ds);
                    415: 
                    416:        return (KERN_SUCCESS);
                    417: }
                    418: 
                    419: /*
                    420:  * Always called by io_done thread.
                    421:  */
                    422: boolean_t device_pager_data_request_done(register io_req_t     ior)
                    423: {
                    424:        vm_offset_t     start_alloc, end_alloc;
                    425:        vm_size_t       size_read;
                    426: 
                    427:        if (ior->io_error == D_SUCCESS) {
                    428:            size_read = ior->io_count;
                    429:            if (ior->io_residual) {
                    430:                if (device_pager_debug)
                    431:                    printf("(device_pager)data_request_done: r: 0x%x\n",ior->io_residual);
                    432:                bzero( (char *) (&ior->io_data[ior->io_count - 
                    433:                                               ior->io_residual]),
                    434:                      (unsigned) ior->io_residual);
                    435:            }
                    436:        } else {
                    437:            size_read = ior->io_count - ior->io_residual;
                    438:        }
                    439: 
                    440:        start_alloc = trunc_page((vm_offset_t)ior->io_data);
                    441:        end_alloc   = start_alloc + round_page(ior->io_alloc_size);
                    442: 
                    443:        if (ior->io_error == D_SUCCESS) {
                    444:            vm_map_copy_t copy;
                    445:            kern_return_t kr;
                    446: 
                    447:            kr = vm_map_copyin(kernel_map, (vm_offset_t)ior->io_data,
                    448:                                size_read, TRUE, &copy);
                    449:            if (kr != KERN_SUCCESS)
                    450:                panic("device_pager_data_request_done");
                    451: 
                    452:            (void) r_memory_object_data_provided(
                    453:                                        ior->io_reply_port,
                    454:                                        ior->io_recnum * ior->io_device->bsize,
                    455:                                        (vm_offset_t)copy,
                    456:                                        size_read,
                    457:                                        VM_PROT_NONE);
                    458:        }
                    459:        else {
                    460:            (void) r_memory_object_data_error(
                    461:                                        ior->io_reply_port,
                    462:                                        ior->io_recnum * ior->io_device->bsize,
                    463:                                        (vm_size_t)ior->io_count,
                    464:                                        ior->io_error);
                    465:        }
                    466: 
                    467:        (void)vm_deallocate(kernel_map,
                    468:                            start_alloc,
                    469:                            end_alloc - start_alloc);
                    470:        mach_device_deallocate(ior->io_device);
                    471:        return (TRUE);
                    472: }
                    473: 
                    474: kern_return_t device_pager_data_write(
                    475:        ipc_port_t              pager,
                    476:        ipc_port_t              pager_request,
                    477:        register vm_offset_t    offset,
                    478:        register pointer_t      addr,
                    479:        vm_size_t               data_count)
                    480: {
                    481:        register dev_pager_t    ds;
                    482:        register mach_device_t  device;
                    483:        register io_req_t       ior;
                    484:        kern_return_t           result;
                    485: 
                    486:        panic("(device_pager)data_write: called");
                    487: 
                    488:        ds = dev_pager_hash_lookup((ipc_port_t)pager);
                    489:        if (ds == DEV_PAGER_NULL)
                    490:                panic("(device_pager)data_write: lookup failed");
                    491: 
                    492:        if (ds->pager_request != pager_request)
                    493:                panic("(device_pager)data_write: bad pager_request");
                    494: 
                    495:        if (ds->type == CHAR_PAGER_TYPE)
                    496:                panic("(device_pager)data_write: char pager");
                    497: 
                    498:        device = ds->device;
                    499:        mach_device_reference(device);
                    500:        dev_pager_deallocate(ds);
                    501: 
                    502:        /*
                    503:         * Package the write request for the device driver.
                    504:         */
                    505:        io_req_alloc(ior, data_count);
                    506: 
                    507:        ior->io_device          = device;
                    508:        ior->io_unit            = device->dev_number;
                    509:        ior->io_op              = IO_WRITE | IO_CALL;
                    510:        ior->io_mode            = 0;
                    511:        ior->io_recnum          = offset / device->bsize;
                    512:        ior->io_data            = (io_buf_ptr_t)addr;
                    513:        ior->io_count           = data_count;
                    514:        ior->io_alloc_size      = data_count;   /* amount to deallocate */
                    515:        ior->io_residual        = 0;
                    516:        ior->io_error           = 0;
                    517:        ior->io_done            = device_pager_data_write_done;
                    518:        ior->io_reply_port      = IP_NULL;
                    519: 
                    520:        result = (*device->dev_ops->d_write)(device->dev_number, ior);
                    521: 
                    522:        if (result != D_IO_QUEUED) {
                    523:            device_write_dealloc(ior);
                    524:            io_req_free((vm_offset_t)ior);
                    525:            mach_device_deallocate(device);
                    526:        }
                    527: 
                    528:        return (KERN_SUCCESS);
                    529: }
                    530: 
                    531: boolean_t device_pager_data_write_done(ior)
                    532:        register io_req_t       ior;
                    533: {
                    534:        device_write_dealloc(ior);
                    535:        mach_device_deallocate(ior->io_device);
                    536: 
                    537:        return (TRUE);
                    538: }
                    539: 
                    540: kern_return_t device_pager_copy(
                    541:        ipc_port_t              pager,
                    542:        ipc_port_t              pager_request,
                    543:        register vm_offset_t    offset,
                    544:        register vm_size_t      length,
                    545:        ipc_port_t              new_pager)
                    546: {
                    547:        panic("(device_pager)copy: called");
                    548: }
                    549: 
                    550: kern_return_t
                    551: device_pager_supply_completed(
                    552:        ipc_port_t pager,
                    553:        ipc_port_t pager_request,
                    554:        vm_offset_t offset,
                    555:        vm_size_t length,
                    556:        kern_return_t result,
                    557:        vm_offset_t error_offset)
                    558: {
                    559:        panic("(device_pager)supply_completed: called");
                    560: }
                    561: 
                    562: kern_return_t
                    563: device_pager_data_return(
                    564:        ipc_port_t              pager,
                    565:        ipc_port_t              pager_request,
                    566:        vm_offset_t             offset,
                    567:        register pointer_t      addr,
                    568:        vm_size_t               data_cnt,
                    569:        boolean_t               dirty,
                    570:        boolean_t               kernel_copy)
                    571: {
                    572:        panic("(device_pager)data_return: called");
                    573: }
                    574: 
                    575: kern_return_t
                    576: device_pager_change_completed(
                    577:        ipc_port_t pager,
                    578:        boolean_t may_cache,
                    579:        memory_object_copy_strategy_t copy_strategy)
                    580: {
                    581:        panic("(device_pager)change_completed: called");
                    582: }
                    583: 
                    584: /*
                    585:  *     The mapping function takes a byte offset, but returns
                    586:  *     a machine-dependent page frame number.  We convert
                    587:  *     that into something that the pmap module will
                    588:  *     accept later.
                    589:  */
                    590: vm_offset_t device_map_page(
                    591:        void            *dsp,
                    592:        vm_offset_t     offset)
                    593: {
                    594:        register dev_pager_t    ds = (dev_pager_t) dsp;
                    595: 
                    596:        return pmap_phys_address(
                    597:                   (*(ds->device->dev_ops->d_mmap))
                    598:                        (ds->device->dev_number, offset, ds->prot));
                    599: }
                    600: 
                    601: kern_return_t device_pager_init_pager(
                    602:        ipc_port_t      pager,
                    603:        ipc_port_t      pager_request,
                    604:        ipc_port_t      pager_name,
                    605:        vm_size_t       pager_page_size)
                    606: {
                    607:        register dev_pager_t    ds;
                    608: 
                    609:        if (device_pager_debug)
                    610:                printf("(device_pager)init: pager=%d, request=%d, name=%d\n",
                    611:                       pager, pager_request, pager_name);
                    612: 
                    613:        assert(pager_page_size == PAGE_SIZE);
                    614:        assert(IP_VALID(pager_request));
                    615:        assert(IP_VALID(pager_name));
                    616: 
                    617:        ds = dev_pager_hash_lookup(pager);
                    618:        assert(ds != DEV_PAGER_NULL);
                    619: 
                    620:        assert(ds->client_count == 0);
                    621:        assert(ds->pager_request == IP_NULL);
                    622:        assert(ds->pager_name == IP_NULL);
                    623: 
                    624:        ds->client_count = 1;
                    625: 
                    626:        /*
                    627:         * We save the send rights for the request and name ports.
                    628:         */
                    629: 
                    630:        ds->pager_request = pager_request;
                    631:        ds->pager_name = pager_name;
                    632: 
                    633:        if (ds->type == CHAR_PAGER_TYPE) {
                    634:            /*
                    635:             * Reply that the object is ready
                    636:             */
                    637:            (void) r_memory_object_set_attributes(pager_request,
                    638:                                                TRUE,   /* ready */
                    639:                                                FALSE,  /* do not cache */
                    640:                                                MEMORY_OBJECT_COPY_NONE);
                    641:        } else {
                    642:            (void) r_memory_object_set_attributes(pager_request,
                    643:                                                TRUE,   /* ready */
                    644:                                                TRUE,   /* cache */
                    645:                                                MEMORY_OBJECT_COPY_DELAY);
                    646:        }
                    647: 
                    648:        dev_pager_deallocate(ds);
                    649:        return (KERN_SUCCESS);
                    650: }
                    651: 
                    652: kern_return_t device_pager_terminate(
                    653:        ipc_port_t      pager,
                    654:        ipc_port_t      pager_request,
                    655:        ipc_port_t      pager_name)
                    656: {
                    657:        register dev_pager_t    ds;
                    658: 
                    659:        assert(IP_VALID(pager_request));
                    660:        assert(IP_VALID(pager_name));
                    661: 
                    662:        ds = dev_pager_hash_lookup(pager);
                    663:        assert(ds != DEV_PAGER_NULL);
                    664: 
                    665:        assert(ds->client_count == 1);
                    666:        assert(ds->pager_request == pager_request);
                    667:        assert(ds->pager_name == pager_name);
                    668: 
                    669:        dev_pager_hash_delete(ds->pager);
                    670:        dev_pager_hash_delete((ipc_port_t)ds->device);  /* HACK */
                    671:        mach_device_deallocate(ds->device);
                    672: 
                    673:        /* release the send rights we have saved from the init call */
                    674: 
                    675:        ipc_port_release_send(pager_request);
                    676:        ipc_port_release_send(pager_name);
                    677: 
                    678:        /* release the naked receive rights we just acquired */
                    679: 
                    680:        ipc_port_release_receive(pager_request);
                    681:        ipc_port_release_receive(pager_name);
                    682: 
                    683:        /* release the kernel's receive right for the pager port */
                    684: 
                    685:        ipc_port_dealloc_kernel(pager);
                    686: 
                    687:        /* once for ref from lookup, once to make it go away */
                    688:        dev_pager_deallocate(ds);
                    689:        dev_pager_deallocate(ds);
                    690: 
                    691:        return (KERN_SUCCESS);
                    692: }
                    693: 
                    694: kern_return_t device_pager_data_unlock(
                    695:        ipc_port_t memory_object,
                    696:        ipc_port_t memory_control_port,
                    697:        vm_offset_t offset,
                    698:        vm_size_t length,
                    699:        vm_prot_t desired_access)
                    700: {
                    701: #ifdef lint
                    702:        memory_object++; memory_control_port++; offset++; length++; desired_access++;
                    703: #endif lint
                    704: 
                    705:        panic("(device_pager)data_unlock: called");
                    706:        return (KERN_FAILURE);
                    707: }
                    708: 
                    709: kern_return_t device_pager_lock_completed(
                    710:        ipc_port_t      memory_object,
                    711:        ipc_port_t      pager_request_port,
                    712:        vm_offset_t     offset,
                    713:        vm_size_t       length)
                    714: {
                    715: #ifdef lint
                    716:        memory_object++; pager_request_port++; offset++; length++;
                    717: #endif lint
                    718: 
                    719:        panic("(device_pager)lock_completed: called");
                    720:        return (KERN_FAILURE);
                    721: }
                    722: 
                    723: void device_pager_init(void)
                    724: {
                    725:        register vm_size_t      size;
                    726: 
                    727:        /*
                    728:         * Initialize zone of paging structures.
                    729:         */
                    730:        size = sizeof(struct dev_pager);
                    731:        dev_pager_zone = zinit(size,
                    732:                                (vm_size_t) size * 1000,
                    733:                                PAGE_SIZE,
                    734:                                FALSE,
                    735:                                "device pager structures");
                    736: 
                    737:        /*
                    738:         *      Initialize the name port hashing stuff.
                    739:         */
                    740:        dev_pager_hash_init();
                    741: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.