|
|
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, ©); ! 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.