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