Annotation of Gnu-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: #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.