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

unix.superglobalmegacorp.com

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