Annotation of OSKit-Mach/device/dev_pager.c, revision 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.