|
|
1.1.1.2 ! root 1: /* 1.1 root 2: * Mach Operating System 3: * Copyright (c) 1993-1989 Carnegie Mellon University 4: * All Rights Reserved. 1.1.1.2 ! root 5: * 1.1 root 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. 1.1.1.2 ! root 11: * 1.1 root 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. 1.1.1.2 ! root 15: * 1.1 root 16: * Carnegie Mellon requests users of this software to return to 1.1.1.2 ! root 17: * 1.1 root 18: * Software Distribution Coordinator or [email protected] 19: * School of Computer Science 20: * Carnegie Mellon University 21: * Pittsburgh PA 15213-3890 1.1.1.2 ! root 22: * 1.1 root 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++; 1.1.1.2 ! root 336: #endif /* lint */ 1.1 root 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); 1.1.1.2 ! root 355: #else /* NORMA_VM */ 1.1 root 356: object = vm_object_lookup(pager_request); 1.1.1.2 ! root 357: #endif /* NORMA_VM */ 1.1 root 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"); 1.1.1.2 ! root 378: 1.1 root 379: device = ds->device; 380: mach_device_reference(device); 381: dev_pager_deallocate(ds); 1.1.1.2 ! root 382: 1.1 root 383: /* 384: * Package the read for the device driver. 385: */ 386: io_req_alloc(ior, 0); 1.1.1.2 ! root 387: 1.1 root 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; 1.1.1.2 ! root 401: 1.1 root 402: result = (*device->dev_ops->d_read)(device->dev_number, ior); 403: if (result == D_IO_QUEUED) 404: return (KERN_SUCCESS); 1.1.1.2 ! root 405: 1.1 root 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); 1.1.1.2 ! root 432: bzero( (char *) (&ior->io_data[ior->io_count - 1.1 root 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++; 1.1.1.2 ! root 703: #endif /* lint */ 1.1 root 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++; 1.1.1.2 ! root 717: #endif /* lint */ 1.1 root 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.