--- Gnu-Mach/device/ds_routines.c 2020/09/02 04:43:03 1.1.1.3 +++ Gnu-Mach/device/ds_routines.c 2020/09/02 04:45:33 1.1.1.4 @@ -28,7 +28,33 @@ * Date: 3/89 */ -#include +/* + * Mach device server routines (i386at version). + * + * Copyright (c) 1996 The University of Utah and + * the Computer Systems Laboratory at the University of Utah (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software is hereby + * granted provided that (1) source code retains these copyright, permission, + * and disclaimer notices, and (2) redistributions including binaries + * reproduce the notices in supporting documentation, and (3) all advertising + * materials mentioning features or use of this software display the following + * acknowledgement: ``This product includes software developed by the + * Computer Systems Laboratory at the University of Utah.'' + * + * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS + * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF + * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * CSL requests users of this software to return to csl-dist@cs.utah.edu any + * improvements that they make and grant CSL redistribution rights. + * + * Author: Shantanu Goel, University of Utah CSL + */ + +#include +#include #include #include @@ -36,6 +62,7 @@ #include #include #include +#include #include /* spl definitions */ #include @@ -43,8 +70,10 @@ #include #include +#include +#include #include -#include +#include #include #include #include @@ -52,6 +81,7 @@ #include #include #include +#include #include #include @@ -60,112 +90,345 @@ #include #include #include -#include "device_reply.h" +#include +#include #include + +#ifdef LINUX_DEV +extern struct device_emulation_ops linux_block_emulation_ops; +#ifdef CONFIG_INET +extern struct device_emulation_ops linux_net_emulation_ops; +extern void free_skbuffs (); +#ifdef CONFIG_PCMCIA +extern struct device_emulation_ops linux_pcmcia_emulation_ops; +#endif /* CONFIG_PCMCIA */ +#endif /* CONFIG_INET */ +#endif /* LINUX_DEV */ +#ifdef MACH_HYP +extern struct device_emulation_ops hyp_block_emulation_ops; +extern struct device_emulation_ops hyp_net_emulation_ops; +#endif /* MACH_HYP */ +extern struct device_emulation_ops mach_device_emulation_ops; -#ifdef i386 -#include +/* List of emulations. */ +static struct device_emulation_ops *emulation_list[] = +{ #ifdef LINUX_DEV -#include -#endif -#endif + &linux_block_emulation_ops, +#ifdef CONFIG_INET + &linux_net_emulation_ops, +#ifdef CONFIG_PCMCIA + &linux_pcmcia_emulation_ops, +#endif /* CONFIG_PCMCIA */ +#endif /* CONFIG_INET */ +#endif /* LINUX_DEV */ +#ifdef MACH_HYP + &hyp_block_emulation_ops, + &hyp_net_emulation_ops, +#endif /* MACH_HYP */ + &mach_device_emulation_ops, +}; + +static struct vm_map device_io_map_store; +vm_map_t device_io_map = &device_io_map_store; + +#define NUM_EMULATION (sizeof (emulation_list) / sizeof (emulation_list[0])) + +io_return_t +ds_device_open (ipc_port_t open_port, ipc_port_t reply_port, + mach_msg_type_name_t reply_port_type, dev_mode_t mode, + char *name, device_t *devp) +{ + int i; + io_return_t err; + + /* Open must be called on the master device port. */ + if (open_port != master_device_port) + return D_INVALID_OPERATION; + + /* There must be a reply port. */ + if (! IP_VALID (reply_port)) + { + printf ("ds_* invalid reply port\n"); + SoftDebugger ("ds_* reply_port"); + return MIG_NO_REPLY; + } + + /* Call each emulation's open routine to find the device. */ + for (i = 0; i < NUM_EMULATION; i++) + { + err = (*emulation_list[i]->open) (reply_port, reply_port_type, + mode, name, devp); + if (err != D_NO_SUCH_DEVICE) + break; + } + + return err; +} + +io_return_t +ds_device_close (device_t dev) +{ + /* Refuse if device is dead or not completely open. */ + if (dev == DEVICE_NULL) + return D_NO_SUCH_DEVICE; + + return (dev->emul_ops->close + ? (*dev->emul_ops->close) (dev->emul_data) + : D_SUCCESS); +} + +io_return_t +ds_device_write (device_t dev, ipc_port_t reply_port, + mach_msg_type_name_t reply_port_type, dev_mode_t mode, + recnum_t recnum, io_buf_ptr_t data, unsigned int count, + int *bytes_written) +{ + /* Refuse if device is dead or not completely open. */ + if (dev == DEVICE_NULL) + return D_NO_SUCH_DEVICE; + + if (data == 0) + return D_INVALID_SIZE; + + if (! dev->emul_ops->write) + return D_INVALID_OPERATION; + + return (*dev->emul_ops->write) (dev->emul_data, reply_port, + reply_port_type, mode, recnum, + data, count, bytes_written); +} + +io_return_t +ds_device_write_inband (device_t dev, ipc_port_t reply_port, + mach_msg_type_name_t reply_port_type, + dev_mode_t mode, recnum_t recnum, + io_buf_ptr_inband_t data, unsigned count, + int *bytes_written) +{ + /* Refuse if device is dead or not completely open. */ + if (dev == DEVICE_NULL) + return D_NO_SUCH_DEVICE; + + if (data == 0) + return D_INVALID_SIZE; + + if (! dev->emul_ops->write_inband) + return D_INVALID_OPERATION; + + return (*dev->emul_ops->write_inband) (dev->emul_data, reply_port, + reply_port_type, mode, recnum, + data, count, bytes_written); +} + +io_return_t +ds_device_read (device_t dev, ipc_port_t reply_port, + mach_msg_type_name_t reply_port_type, dev_mode_t mode, + recnum_t recnum, int count, io_buf_ptr_t *data, + unsigned *bytes_read) +{ + /* Refuse if device is dead or not completely open. */ + if (dev == DEVICE_NULL) + return D_NO_SUCH_DEVICE; + + if (! dev->emul_ops->read) + return D_INVALID_OPERATION; + + return (*dev->emul_ops->read) (dev->emul_data, reply_port, + reply_port_type, mode, recnum, + count, data, bytes_read); +} + +io_return_t +ds_device_read_inband (device_t dev, ipc_port_t reply_port, + mach_msg_type_name_t reply_port_type, dev_mode_t mode, + recnum_t recnum, int count, char *data, + unsigned *bytes_read) +{ + /* Refuse if device is dead or not completely open. */ + if (dev == DEVICE_NULL) + return D_NO_SUCH_DEVICE; + + if (! dev->emul_ops->read_inband) + return D_INVALID_OPERATION; + + return (*dev->emul_ops->read_inband) (dev->emul_data, reply_port, + reply_port_type, mode, recnum, + count, data, bytes_read); +} + +io_return_t +ds_device_set_status (device_t dev, dev_flavor_t flavor, + dev_status_t status, mach_msg_type_number_t status_count) +{ + /* Refuse if device is dead or not completely open. */ + if (dev == DEVICE_NULL) + return D_NO_SUCH_DEVICE; + + if (! dev->emul_ops->set_status) + return D_INVALID_OPERATION; + + return (*dev->emul_ops->set_status) (dev->emul_data, flavor, status, + status_count); +} + +io_return_t +ds_device_get_status (device_t dev, dev_flavor_t flavor, dev_status_t status, + mach_msg_type_number_t *status_count) +{ + /* Refuse if device is dead or not completely open. */ + if (dev == DEVICE_NULL) + return D_NO_SUCH_DEVICE; + + if (! dev->emul_ops->get_status) + return D_INVALID_OPERATION; + + return (*dev->emul_ops->get_status) (dev->emul_data, flavor, status, + status_count); +} + +io_return_t +ds_device_set_filter (device_t dev, ipc_port_t receive_port, int priority, + filter_t *filter, unsigned filter_count) +{ + /* Refuse if device is dead or not completely open. */ + if (dev == DEVICE_NULL) + return D_NO_SUCH_DEVICE; + + if (! dev->emul_ops->set_filter) + return D_INVALID_OPERATION; + + return (*dev->emul_ops->set_filter) (dev->emul_data, receive_port, + priority, filter, filter_count); +} + +io_return_t +ds_device_map (device_t dev, vm_prot_t prot, vm_offset_t offset, + vm_size_t size, ipc_port_t *pager, boolean_t unmap) +{ + /* Refuse if device is dead or not completely open. */ + if (dev == DEVICE_NULL) + return D_NO_SUCH_DEVICE; + + if (! dev->emul_ops->map) + return D_INVALID_OPERATION; + + return (*dev->emul_ops->map) (dev->emul_data, prot, + offset, size, pager, unmap); +} + +boolean_t +ds_notify (mach_msg_header_t *msg) +{ + if (msg->msgh_id == MACH_NOTIFY_NO_SENDERS) + { + device_t dev; + mach_no_senders_notification_t *ns; + + ns = (mach_no_senders_notification_t *) msg; + dev = dev_port_lookup((ipc_port_t) ns->not_header.msgh_remote_port); + assert(dev); + if (dev->emul_ops->no_senders) + (*dev->emul_ops->no_senders) (ns); + return TRUE; + } + + printf ("ds_notify: strange notification %d\n", msg->msgh_id); + return FALSE; +} + +io_return_t +ds_device_write_trap (device_t dev, dev_mode_t mode, + recnum_t recnum, vm_offset_t data, vm_size_t count) +{ + /* Refuse if device is dead or not completely open. */ + if (dev == DEVICE_NULL) + return D_NO_SUCH_DEVICE; + + if (! dev->emul_ops->write_trap) + return D_INVALID_OPERATION; + + return (*dev->emul_ops->write_trap) (dev->emul_data, + mode, recnum, data, count); +} + +io_return_t +ds_device_writev_trap (device_t dev, dev_mode_t mode, + recnum_t recnum, io_buf_vec_t *iovec, vm_size_t count) +{ + /* Refuse if device is dead or not completely open. */ + if (dev == DEVICE_NULL) + return D_NO_SUCH_DEVICE; + + if (! dev->emul_ops->writev_trap) + return D_INVALID_OPERATION; + + return (*dev->emul_ops->writev_trap) (dev->emul_data, + mode, recnum, iovec, count); +} + +void +device_reference (device_t dev) +{ + /* Refuse if device is dead or not completely open. */ + if (dev == DEVICE_NULL) + return; + + if (dev->emul_ops->reference) + (*dev->emul_ops->reference) (dev->emul_data); +} + +void +device_deallocate (device_t dev) +{ + /* Refuse if device is dead or not completely open. */ + if (dev == DEVICE_NULL) + return; + + if (dev->emul_ops->dealloc) + (*dev->emul_ops->dealloc) (dev->emul_data); +} + +/* + * What follows is the interface for the native Mach devices. + */ -#ifdef i386 ipc_port_t -mach_convert_device_to_port (void *d) +mach_convert_device_to_port (mach_device_t device) { ipc_port_t port; - mach_device_t device = d; if (! device) return IP_NULL; + device_lock(device); + if (device->state == DEV_STATE_OPEN) port = ipc_port_make_send(device->port); else port = IP_NULL; + device_unlock(device); + mach_device_deallocate(device); + return port; } -#endif /* i386 */ -#ifdef i386 static io_return_t device_open(reply_port, reply_port_type, mode, name, device_p) -#else -io_return_t -ds_device_open(open_port, reply_port, reply_port_type, - mode, name, device_p) - ipc_port_t open_port; -#endif ipc_port_t reply_port; mach_msg_type_name_t reply_port_type; dev_mode_t mode; char * name; device_t *device_p; /* out */ { - register mach_device_t device; - register kern_return_t result; - register io_req_t ior; - char namebuf[64]; + mach_device_t device; + kern_return_t result; + io_req_t ior; ipc_port_t notify; -#ifndef i386 - /* - * Open must be called on the master device port. - */ - if (open_port != master_device_port) - return (D_INVALID_OPERATION); - - /* - * There must be a reply port. - */ - if (!IP_VALID(reply_port)) { - printf("ds_* invalid reply port\n"); - Debugger("ds_* reply_port"); - return (MIG_NO_REPLY); /* no sense in doing anything */ - } - -#if NORMA_DEVICE - /* - * Map global device name to + local device name. - */ - if (name[0] != '<') { - extern char *dev_forward_name(); - - name = dev_forward_name(name, namebuf, sizeof(namebuf)); - } - /* - * Look for explicit node specifier, e.g., <2>sd0a. - * If found, then forward request to correct device server. - * If not found, then remove '' and process locally. - * - * XXX should handle send-right reply_port as well as send-once XXX - */ - if (name[0] == '<') { - char *n; - int node = 0; - - for (n = &name[1]; *n != '>'; n++) { - if (*n >= '0' && *n <= '9') { - node = 10 * node + (*n - '0'); - } else { - return (D_NO_SUCH_DEVICE); - } - } - if (node == node_self()) { - name = &n[1]; /* skip trailing '>' */ - } else { - forward_device_open_send(remote_device(node), - reply_port, mode, name); - return (MIG_NO_REPLY); - } - } -#endif /* NORMA_DEVICE */ -#endif /* ! i386 */ - /* * Find the device. */ @@ -202,11 +465,7 @@ ds_device_open(open_port, reply_port, re device->open_count++; device_unlock(device); -#ifdef i386 *device_p = &device->dev; -#else - *device_p = device; -#endif return (D_SUCCESS); /* * Return deallocates device reference while acquiring @@ -279,10 +538,10 @@ ds_device_open(open_port, reply_port, re boolean_t ds_open_done(ior) - register io_req_t ior; + io_req_t ior; { kern_return_t result; - register mach_device_t device; + mach_device_t device; device = ior->io_device; result = ior->io_error; @@ -330,32 +589,17 @@ ds_open_done(ior) (void) ds_device_open_reply(ior->io_reply_port, ior->io_reply_port_type, result, -#ifdef i386 - (mach_convert_device_to_port - (device))); -#else - convert_device_to_port(device)); -#endif + mach_convert_device_to_port(device)); } else mach_device_deallocate(device); return (TRUE); } -#ifdef i386 static io_return_t device_close(device) -#else -io_return_t -ds_device_close(device) -#endif - register mach_device_t device; + mach_device_t device; { -#ifndef i386 - if (device == DEVICE_NULL) - return (D_NO_SUCH_DEVICE); -#endif - device_lock(device); /* @@ -415,17 +659,10 @@ ds_device_close(device) /* * Write to a device. */ -#ifdef i386 static io_return_t -device_write(d, reply_port, reply_port_type, mode, recnum, +device_write(device, reply_port, reply_port_type, mode, recnum, data, data_count, bytes_written) - void *d; -#else -io_return_t -ds_device_write(device, reply_port, reply_port_type, mode, recnum, - data, data_count, bytes_written) - register mach_device_t device; -#endif + mach_device_t device; ipc_port_t reply_port; mach_msg_type_name_t reply_port_type; dev_mode_t mode; @@ -434,28 +671,12 @@ ds_device_write(device, reply_port, repl unsigned int data_count; int *bytes_written; /* out */ { -#ifdef i386 - register mach_device_t device = d; -#endif - register io_req_t ior; - register io_return_t result; - -#ifndef i386 - /* - * Refuse if device is dead or not completely open. - */ - if (device == DEVICE_NULL) - return (D_NO_SUCH_DEVICE); -#endif + io_req_t ior; + io_return_t result; if (device->state != DEV_STATE_OPEN) return (D_NO_SUCH_DEVICE); -#ifndef i386 - if (data == 0) - return (D_INVALID_SIZE); -#endif - /* * XXX Need logic to reject ridiculously big requests. */ @@ -529,17 +750,10 @@ ds_device_write(device, reply_port, repl /* * Write to a device, but memory is in message. */ -#ifdef i386 static io_return_t -device_write_inband(d, reply_port, reply_port_type, mode, recnum, +device_write_inband(device, reply_port, reply_port_type, mode, recnum, data, data_count, bytes_written) - void *d; -#else -io_return_t -ds_device_write_inband(device, reply_port, reply_port_type, mode, recnum, - data, data_count, bytes_written) - register mach_device_t device; -#endif + mach_device_t device; ipc_port_t reply_port; mach_msg_type_name_t reply_port_type; dev_mode_t mode; @@ -548,28 +762,12 @@ ds_device_write_inband(device, reply_por unsigned int data_count; int *bytes_written; /* out */ { -#ifdef i386 - register mach_device_t device = d; -#endif - register io_req_t ior; - register io_return_t result; - -#ifndef i386 - /* - * Refuse if device is dead or not completely open. - */ - if (device == DEVICE_NULL) - return (D_NO_SUCH_DEVICE); -#endif + io_req_t ior; + io_return_t result; if (device->state != DEV_STATE_OPEN) return (D_NO_SUCH_DEVICE); -#ifndef i386 - if (data == 0) - return (D_INVALID_SIZE); -#endif - /* XXX note that a CLOSE may proceed at any point */ /* @@ -627,12 +825,12 @@ ds_device_write_inband(device, reply_por */ kern_return_t device_write_get(ior, wait) - register io_req_t ior; + io_req_t ior; boolean_t *wait; { vm_map_copy_t io_copy; vm_offset_t new_addr; - register kern_return_t result; + kern_return_t result; int bsize; vm_size_t min_size; @@ -658,8 +856,8 @@ device_write_get(ior, wait) */ if (ior->io_op & IO_INBAND) { assert(ior->io_count <= sizeof (io_buf_ptr_inband_t)); - new_addr = zalloc(io_inband_zone); - bcopy((void*)ior->io_data, (void*)new_addr, ior->io_count); + new_addr = kmem_cache_alloc(&io_inband_cache); + memcpy((void*)new_addr, ior->io_data, ior->io_count); ior->io_data = (io_buf_ptr_t)new_addr; ior->io_alloc_size = sizeof (io_buf_ptr_inband_t); @@ -722,10 +920,9 @@ device_write_get(ior, wait) */ boolean_t device_write_dealloc(ior) - register io_req_t ior; + io_req_t ior; { vm_map_copy_t new_copy = VM_MAP_COPY_NULL; - register vm_map_copy_t io_copy; kern_return_t result; vm_offset_t size_to_do; @@ -738,7 +935,7 @@ device_write_dealloc(ior) * Inband case. */ if (ior->io_op & IO_INBAND) { - zfree(io_inband_zone, (vm_offset_t)ior->io_data); + kmem_cache_free(&io_inband_cache, (vm_offset_t)ior->io_data); return (TRUE); } @@ -750,12 +947,12 @@ device_write_dealloc(ior) * To prevent a possible deadlock with the default pager, * we have to release space in the device_io_map before * we allocate any memory. (Which vm_map_copy_invoke_cont - * might do.) See the discussion in ds_init. + * might do.) See the discussion in mach_device_init. */ kmem_io_map_deallocate(device_io_map, trunc_page(ior->io_data), - (vm_size_t) ior->io_alloc_size); + ior->io_alloc_size); if (vm_map_copy_has_cont(io_copy)) { @@ -773,7 +970,7 @@ device_write_dealloc(ior) } if (result == KERN_SUCCESS && new_copy != VM_MAP_COPY_NULL) { - register int res; + int res; /* * We have a new continuation, reset the ior to @@ -824,15 +1021,15 @@ device_write_dealloc(ior) */ boolean_t ds_write_done(ior) - register io_req_t ior; + io_req_t ior; { /* * device_write_dealloc discards the data that has been * written, but may decide that there is more to write. */ while (!device_write_dealloc(ior)) { - register io_return_t result; - register mach_device_t device; + io_return_t result; + mach_device_t device; /* * More IO to do -- invoke it. @@ -868,17 +1065,10 @@ ds_write_done(ior) /* * Read from a device. */ -#ifdef i386 static io_return_t -device_read(d, reply_port, reply_port_type, mode, recnum, +device_read(device, reply_port, reply_port_type, mode, recnum, bytes_wanted, data, data_count) - void *d; -#else -io_return_t -ds_device_read(device, reply_port, reply_port_type, mode, recnum, - bytes_wanted, data, data_count) - register mach_device_t device; -#endif + mach_device_t device; ipc_port_t reply_port; mach_msg_type_name_t reply_port_type; dev_mode_t mode; @@ -887,24 +1077,8 @@ ds_device_read(device, reply_port, reply io_buf_ptr_t *data; /* out */ unsigned int *data_count; /* out */ { -#ifdef i386 - register mach_device_t device = d; -#endif - register io_req_t ior; - register io_return_t result; - -#ifdef lint - *data = *data; - *data_count = *data_count; -#endif /* lint */ - -#ifndef i386 - /* - * Refuse if device is dead or not completely open. - */ - if (device == DEVICE_NULL) - return (D_NO_SUCH_DEVICE); -#endif + io_req_t ior; + io_return_t result; if (device->state != DEV_STATE_OPEN) return (D_NO_SUCH_DEVICE); @@ -916,7 +1090,7 @@ ds_device_read(device, reply_port, reply */ if (!IP_VALID(reply_port)) { printf("ds_* invalid reply port\n"); - Debugger("ds_* reply_port"); + SoftDebugger("ds_* reply_port"); return (MIG_NO_REPLY); /* no sense in doing anything */ } @@ -968,17 +1142,10 @@ ds_device_read(device, reply_port, reply /* * Read from a device, but return the data 'inband.' */ -#ifdef i386 static io_return_t -device_read_inband(d, reply_port, reply_port_type, mode, recnum, +device_read_inband(device, reply_port, reply_port_type, mode, recnum, bytes_wanted, data, data_count) - void *d; -#else -io_return_t -ds_device_read_inband(device, reply_port, reply_port_type, mode, recnum, - bytes_wanted, data, data_count) - register mach_device_t device; -#endif + mach_device_t device; ipc_port_t reply_port; mach_msg_type_name_t reply_port_type; dev_mode_t mode; @@ -987,24 +1154,8 @@ ds_device_read_inband(device, reply_port char *data; /* pointer to OUT array */ unsigned int *data_count; /* out */ { -#ifdef i386 - register mach_device_t device = d; -#endif - register io_req_t ior; - register io_return_t result; - -#ifdef lint - *data = *data; - *data_count = *data_count; -#endif /* lint */ - -#ifndef i386 - /* - * Refuse if device is dead or not completely open. - */ - if (device == DEVICE_NULL) - return (D_NO_SUCH_DEVICE); -#endif + io_req_t ior; + io_return_t result; if (device->state != DEV_STATE_OPEN) return (D_NO_SUCH_DEVICE); @@ -1016,7 +1167,7 @@ ds_device_read_inband(device, reply_port */ if (!IP_VALID(reply_port)) { printf("ds_* invalid reply port\n"); - Debugger("ds_* reply_port"); + SoftDebugger("ds_* reply_port"); return (MIG_NO_REPLY); /* no sense in doing anything */ } @@ -1067,13 +1218,12 @@ ds_device_read_inband(device, reply_port return (MIG_NO_REPLY); /* reply has already been sent. */ } - /* * Allocate wired-down memory for device read. */ kern_return_t device_read_alloc(ior, size) - register io_req_t ior; - register vm_size_t size; + io_req_t ior; + vm_size_t size; { vm_offset_t addr; kern_return_t kr; @@ -1085,7 +1235,7 @@ kern_return_t device_read_alloc(ior, siz return (KERN_SUCCESS); if (ior->io_op & IO_INBAND) { - ior->io_data = (io_buf_ptr_t) zalloc(io_inband_zone); + ior->io_data = (io_buf_ptr_t) kmem_cache_alloc(&io_inband_cache); ior->io_alloc_size = sizeof(io_buf_ptr_inband_t); } else { size = round_page(size); @@ -1105,7 +1255,7 @@ boolean_t ds_read_done(ior) { vm_offset_t start_data, end_data; vm_offset_t start_sent, end_sent; - register vm_size_t size_read; + vm_size_t size_read; if (ior->io_error) size_read = 0; @@ -1124,9 +1274,9 @@ boolean_t ds_read_done(ior) * Zero memory that the device did not fill. */ if (start_sent < start_data) - bzero((char *)start_sent, start_data - start_sent); + memset((char *)start_sent, 0, start_data - start_sent); if (end_sent > end_data) - bzero((char *)end_data, end_sent - end_data); + memset((char *)end_data, 0, end_sent - end_data); /* @@ -1135,8 +1285,8 @@ boolean_t ds_read_done(ior) * may think that they are clean. */ { - register vm_offset_t touch; - register int c; + vm_offset_t touch; + int c; for (touch = start_sent; touch < end_sent; touch += PAGE_SIZE) { c = *(volatile char *)touch; @@ -1178,9 +1328,9 @@ boolean_t ds_read_done(ior) if (ior->io_count != 0) { if (ior->io_op & IO_INBAND) { if (ior->io_alloc_size > 0) - zfree(io_inband_zone, (vm_offset_t)ior->io_data); + kmem_cache_free(&io_inband_cache, (vm_offset_t)ior->io_data); } else { - register vm_offset_t end_alloc; + vm_offset_t end_alloc; end_alloc = start_sent + round_page(ior->io_alloc_size); if (end_alloc > end_sent) @@ -1195,31 +1345,13 @@ boolean_t ds_read_done(ior) return (TRUE); } -#ifdef i386 static io_return_t -device_set_status(d, flavor, status, status_count) - void *d; -#else -io_return_t -ds_device_set_status(device, flavor, status, status_count) - register mach_device_t device; -#endif +device_set_status(device, flavor, status, status_count) + mach_device_t device; dev_flavor_t flavor; dev_status_t status; mach_msg_type_number_t status_count; { -#ifdef i386 - register mach_device_t device = d; -#endif - -#ifndef i386 - /* - * Refuse if device is dead or not completely open. - */ - if (device == DEVICE_NULL) - return (D_NO_SUCH_DEVICE); -#endif - if (device->state != DEV_STATE_OPEN) return (D_NO_SUCH_DEVICE); @@ -1231,31 +1363,13 @@ ds_device_set_status(device, flavor, sta status_count)); } -#ifdef i386 -io_return_t -mach_device_get_status(d, flavor, status, status_count) - void *d; -#else io_return_t -ds_device_get_status(device, flavor, status, status_count) - register mach_device_t device; -#endif +mach_device_get_status(device, flavor, status, status_count) + mach_device_t device; dev_flavor_t flavor; dev_status_t status; /* pointer to OUT array */ mach_msg_type_number_t *status_count; /* out */ { -#ifdef i386 - register mach_device_t device = d; -#endif - -#ifndef i386 - /* - * Refuse if device is dead or not completely open. - */ - if (device == DEVICE_NULL) - return (D_NO_SUCH_DEVICE); -#endif - if (device->state != DEV_STATE_OPEN) return (D_NO_SUCH_DEVICE); @@ -1267,32 +1381,14 @@ ds_device_get_status(device, flavor, sta status_count)); } -#ifdef i386 static io_return_t -device_set_filter(d, receive_port, priority, filter, filter_count) - void *d; -#else -io_return_t -ds_device_set_filter(device, receive_port, priority, filter, filter_count) - register mach_device_t device; -#endif +device_set_filter(device, receive_port, priority, filter, filter_count) + mach_device_t device; ipc_port_t receive_port; int priority; filter_t filter[]; /* pointer to IN array */ unsigned int filter_count; { -#ifdef i386 - register mach_device_t device = d; -#endif - -#ifndef i386 - /* - * Refuse if device is dead or not completely open. - */ - if (device == DEVICE_NULL) - return (D_NO_SUCH_DEVICE); -#endif - if (device->state != DEV_STATE_OPEN) return (D_NO_SUCH_DEVICE); @@ -1311,39 +1407,18 @@ ds_device_set_filter(device, receive_por filter_count)); } -#ifdef i386 static io_return_t -device_map(d, protection, offset, size, pager, unmap) - void *d; -#else -io_return_t -ds_device_map(device, protection, offset, size, pager, unmap) - register mach_device_t device; -#endif +device_map(device, protection, offset, size, pager, unmap) + mach_device_t device; vm_prot_t protection; vm_offset_t offset; vm_size_t size; ipc_port_t *pager; /* out */ boolean_t unmap; /* ? */ { -#ifdef i386 - register mach_device_t device = d; -#endif - -#ifdef lint - unmap = unmap; -#endif /* lint */ if (protection & ~VM_PROT_ALL) return (KERN_INVALID_ARGUMENT); -#ifndef i386 - /* - * Refuse if device is dead or not completely open. - */ - if (device == DEVICE_NULL) - return (D_NO_SUCH_DEVICE); -#endif - if (device->state != DEV_STATE_OPEN) return (D_NO_SUCH_DEVICE); @@ -1356,45 +1431,24 @@ ds_device_map(device, protection, offset /* * Doesn't do anything (yet). */ -#ifdef i386 static void -#else -void -#endif ds_no_senders(notification) mach_no_senders_notification_t *notification; { - printf("ds_no_senders called! device_port=0x%x count=%d\n", + printf("ds_no_senders called! device_port=0x%lx count=%d\n", notification->not_header.msgh_remote_port, notification->not_count); } -#ifndef i386 -boolean_t -ds_notify(msg) - mach_msg_header_t *msg; -{ - switch (msg->msgh_id) { - case MACH_NOTIFY_NO_SENDERS: - ds_no_senders((mach_no_senders_notification_t *) msg); - return TRUE; - - default: - printf("ds_notify: strange notification %d\n", msg->msgh_id); - return FALSE; - } -} -#endif - queue_head_t io_done_list; decl_simple_lock_data(, io_done_list_lock) #define splio splsched /* XXX must block ALL io devices */ void iodone(ior) - register io_req_t ior; + io_req_t ior; { - register spl_t s; + spl_t s; /* * If this ior was loaned to us, return it directly. @@ -1428,10 +1482,10 @@ void iodone(ior) void io_done_thread_continue() { for (;;) { - register spl_t s; - register io_req_t ior; + spl_t s; + io_req_t ior; -#if defined (i386) && defined (LINUX_DEV) && defined (CONFIG_INET) +#if defined (LINUX_DEV) && defined (CONFIG_INET) free_skbuffs (); #endif s = splio(); @@ -1473,22 +1527,20 @@ void io_done_thread() /*NOTREACHED*/ } -#define DEVICE_IO_MAP_SIZE (2 * 1024 * 1024) +#define DEVICE_IO_MAP_SIZE (16 * 1024 * 1024) -extern void ds_trap_init(void); /* forward */ +static void mach_device_trap_init(void); /* forward */ -void ds_init() +void mach_device_init() { vm_offset_t device_io_min, device_io_max; queue_init(&io_done_list); simple_lock_init(&io_done_list_lock); - device_io_map = kmem_suballoc(kernel_map, - &device_io_min, - &device_io_max, - DEVICE_IO_MAP_SIZE, - FALSE); + kmem_submap(device_io_map, kernel_map, &device_io_min, &device_io_max, + DEVICE_IO_MAP_SIZE, FALSE); + /* * If the kernel receives many device_write requests, the * device_io_map might run out of space. To prevent @@ -1508,13 +1560,10 @@ void ds_init() */ device_io_map->wait_for_space = TRUE; - io_inband_zone = zinit(sizeof(io_buf_ptr_inband_t), - 1000 * sizeof(io_buf_ptr_inband_t), - 10 * sizeof(io_buf_ptr_inband_t), - FALSE, - "io inband read buffers"); + kmem_cache_init(&io_inband_cache, "io_buf_ptr_inband", + sizeof(io_buf_ptr_inband_t), 0, NULL, NULL, NULL, 0); - ds_trap_init(); + mach_device_trap_init(); } void iowait(ior) @@ -1548,32 +1597,29 @@ void iowait(ior) */ #define IOTRAP_REQSIZE 2048 -zone_t io_trap_zone; +struct kmem_cache io_trap_cache; /* - * Initialization. Called from ds_init(). + * Initialization. Called from mach_device_init(). */ -void -ds_trap_init(void) +static void +mach_device_trap_init(void) { - io_trap_zone = zinit(IOTRAP_REQSIZE, - 256 * IOTRAP_REQSIZE, - 16 * IOTRAP_REQSIZE, - FALSE, - "wired device trap buffers"); + kmem_cache_init(&io_trap_cache, "io_req", IOTRAP_REQSIZE, 0, + NULL, NULL, NULL, 0); } /* * Allocate an io_req_t. - * Currently zalloc's from io_trap_zone. + * Currently allocates from io_trap_cache. * - * Could have lists of different size zones. + * Could have lists of different size caches. * Could call a device-specific routine. */ io_req_t ds_trap_req_alloc(mach_device_t device, vm_size_t data_size) { - return (io_req_t) zalloc(io_trap_zone); + return (io_req_t) kmem_cache_alloc(&io_trap_cache); } /* @@ -1582,14 +1628,14 @@ ds_trap_req_alloc(mach_device_t device, boolean_t ds_trap_write_done(io_req_t ior) { - register mach_device_t dev; + mach_device_t dev; dev = ior->io_device; /* * Should look at reply port and maybe send a message. */ - zfree(io_trap_zone, (vm_offset_t) ior); + kmem_cache_free(&io_trap_cache, (vm_offset_t) ior); /* * Give up device reference from ds_write_trap. @@ -1601,33 +1647,13 @@ ds_trap_write_done(io_req_t ior) /* * Like device_write except that data is in user space. */ -#ifdef i386 static io_return_t -device_write_trap (void *d, dev_mode_t mode, +device_write_trap (mach_device_t device, dev_mode_t mode, recnum_t recnum, vm_offset_t data, vm_size_t data_count) -#else -io_return_t -ds_device_write_trap(device_t device, - dev_mode_t mode, - recnum_t recnum, - vm_offset_t data, - vm_size_t data_count) -#endif { -#ifdef i386 - mach_device_t device = d; -#endif io_req_t ior; io_return_t result; -#ifndef i386 - /* - * Refuse if device is dead or not completely open. - */ - if (device == DEVICE_NULL) - return (D_NO_SUCH_DEVICE); -#endif - if (device->state != DEV_STATE_OPEN) return (D_NO_SUCH_DEVICE); @@ -1685,40 +1711,20 @@ ds_device_write_trap(device_t device, */ mach_device_deallocate(device); - zfree(io_trap_zone, (vm_offset_t) ior); + kmem_cache_free(&io_trap_cache, (vm_offset_t) ior); return (result); } -#ifdef i386 static io_return_t -device_writev_trap (void *d, dev_mode_t mode, +device_writev_trap (mach_device_t device, dev_mode_t mode, recnum_t recnum, io_buf_vec_t *iovec, vm_size_t iocount) -#else -io_return_t -ds_device_writev_trap(device_t device, - dev_mode_t mode, - recnum_t recnum, - io_buf_vec_t *iovec, - vm_size_t iocount) -#endif { -#ifdef i386 - mach_device_t device = d; -#endif io_req_t ior; io_return_t result; io_buf_vec_t stack_iovec[16]; /* XXX */ vm_size_t data_count; int i; -#ifndef i386 - /* - * Refuse if device is dead or not completely open. - */ - if (device == DEVICE_NULL) - return (D_NO_SUCH_DEVICE); -#endif - if (device->state != DEV_STATE_OPEN) return (D_NO_SUCH_DEVICE); @@ -1796,16 +1802,15 @@ ds_device_writev_trap(device_t device, */ mach_device_deallocate(device); - zfree(io_trap_zone, (vm_offset_t) ior); + kmem_cache_free(&io_trap_cache, (vm_offset_t) ior); return (result); } -#ifdef i386 struct device_emulation_ops mach_device_emulation_ops = { - mach_device_reference, - mach_device_deallocate, - mach_convert_device_to_port, + (void*) mach_device_reference, + (void*) mach_device_deallocate, + (void*) mach_convert_device_to_port, device_open, device_close, device_write, @@ -1817,7 +1822,6 @@ struct device_emulation_ops mach_device_ device_set_filter, device_map, ds_no_senders, - device_write_trap, - device_writev_trap + (void*) device_write_trap, + (void*) device_writev_trap }; -#endif