|
|
1.1 ! root 1: /* ! 2: * Mach device server routines (i386at version). ! 3: * ! 4: * Copyright (c) 1996 The University of Utah and ! 5: * the Computer Systems Laboratory at the University of Utah (CSL). ! 6: * All rights reserved. ! 7: * ! 8: * Permission to use, copy, modify and distribute this software is hereby ! 9: * granted provided that (1) source code retains these copyright, permission, ! 10: * and disclaimer notices, and (2) redistributions including binaries ! 11: * reproduce the notices in supporting documentation, and (3) all advertising ! 12: * materials mentioning features or use of this software display the following ! 13: * acknowledgement: ``This product includes software developed by the ! 14: * Computer Systems Laboratory at the University of Utah.'' ! 15: * ! 16: * THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF THIS SOFTWARE IN ITS "AS ! 17: * IS" CONDITION. THE UNIVERSITY OF UTAH AND CSL DISCLAIM ANY LIABILITY OF ! 18: * ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. ! 19: * ! 20: * CSL requests users of this software to return to [email protected] any ! 21: * improvements that they make and grant CSL redistribution rights. ! 22: * ! 23: * Author: Shantanu Goel, University of Utah CSL ! 24: */ ! 25: ! 26: #include <mach/boolean.h> ! 27: #include <mach/kern_return.h> ! 28: #include <mach/mig_errors.h> ! 29: #include <mach/port.h> ! 30: #include <mach/notify.h> ! 31: ! 32: #include <device/device_types.h> ! 33: #include <device/device_port.h> ! 34: #include "device_interface.h" ! 35: ! 36: #include <i386at/dev_hdr.h> ! 37: #include <i386at/device_emul.h> ! 38: #include <i386/device-drivers.h> ! 39: ! 40: extern struct device_emulation_ops mach_device_emulation_ops; ! 41: #ifdef LINUX_DEV ! 42: extern struct device_emulation_ops linux_block_emulation_ops; ! 43: #ifdef CONFIG_INET ! 44: extern struct device_emulation_ops linux_net_emulation_ops; ! 45: #endif ! 46: #endif ! 47: ! 48: /* List of emulations. */ ! 49: static struct device_emulation_ops *emulation_list[] = ! 50: { ! 51: #ifdef LINUX_DEV ! 52: &linux_block_emulation_ops, ! 53: #ifdef CONFIG_INET ! 54: &linux_net_emulation_ops, ! 55: #endif ! 56: #endif ! 57: &mach_device_emulation_ops, ! 58: }; ! 59: ! 60: #define NUM_EMULATION (sizeof (emulation_list) / sizeof (emulation_list[0])) ! 61: ! 62: io_return_t ! 63: ds_device_open (ipc_port_t open_port, ipc_port_t reply_port, ! 64: mach_msg_type_name_t reply_port_type, dev_mode_t mode, ! 65: char *name, device_t *devp) ! 66: { ! 67: int i; ! 68: device_t dev; ! 69: io_return_t err; ! 70: ! 71: /* Open must be called on the master device port. */ ! 72: if (open_port != master_device_port) ! 73: return D_INVALID_OPERATION; ! 74: ! 75: /* There must be a reply port. */ ! 76: if (! IP_VALID (reply_port)) ! 77: { ! 78: printf ("ds_* invalid reply port\n"); ! 79: Debugger ("ds_* reply_port"); ! 80: return MIG_NO_REPLY; ! 81: } ! 82: ! 83: /* Call each emulation's open routine to find the device. */ ! 84: for (i = 0; i < NUM_EMULATION; i++) ! 85: { ! 86: err = (*emulation_list[i]->open) (reply_port, reply_port_type, ! 87: mode, name, devp); ! 88: if (err != D_NO_SUCH_DEVICE) ! 89: break; ! 90: } ! 91: ! 92: return err; ! 93: } ! 94: ! 95: io_return_t ! 96: ds_device_close (device_t dev) ! 97: { ! 98: if (dev == DEVICE_NULL) ! 99: return D_NO_SUCH_DEVICE; ! 100: return (dev->emul_ops->close ! 101: ? (*dev->emul_ops->close) (dev->emul_data) ! 102: : D_SUCCESS); ! 103: } ! 104: ! 105: io_return_t ! 106: ds_device_write (device_t dev, ipc_port_t reply_port, ! 107: mach_msg_type_name_t reply_port_type, dev_mode_t mode, ! 108: recnum_t recnum, io_buf_ptr_t data, unsigned int count, ! 109: int *bytes_written) ! 110: { ! 111: if (dev == DEVICE_NULL) ! 112: return D_NO_SUCH_DEVICE; ! 113: if (! data) ! 114: return D_INVALID_SIZE; ! 115: if (! dev->emul_ops->write) ! 116: return D_INVALID_OPERATION; ! 117: return (*dev->emul_ops->write) (dev->emul_data, reply_port, ! 118: reply_port_type, mode, recnum, ! 119: data, count, bytes_written); ! 120: } ! 121: ! 122: io_return_t ! 123: ds_device_write_inband (device_t dev, ipc_port_t reply_port, ! 124: mach_msg_type_name_t reply_port_type, ! 125: dev_mode_t mode, recnum_t recnum, ! 126: io_buf_ptr_inband_t data, unsigned count, ! 127: int *bytes_written) ! 128: { ! 129: if (dev == DEVICE_NULL) ! 130: return D_NO_SUCH_DEVICE; ! 131: if (! data) ! 132: return D_INVALID_SIZE; ! 133: if (! dev->emul_ops->write_inband) ! 134: return D_INVALID_OPERATION; ! 135: return (*dev->emul_ops->write_inband) (dev->emul_data, reply_port, ! 136: reply_port_type, mode, recnum, ! 137: data, count, bytes_written); ! 138: } ! 139: ! 140: io_return_t ! 141: ds_device_read (device_t dev, ipc_port_t reply_port, ! 142: mach_msg_type_name_t reply_port_type, dev_mode_t mode, ! 143: recnum_t recnum, int count, io_buf_ptr_t *data, ! 144: unsigned *bytes_read) ! 145: { ! 146: if (dev == DEVICE_NULL) ! 147: return D_NO_SUCH_DEVICE; ! 148: if (! dev->emul_ops->read) ! 149: return D_INVALID_OPERATION; ! 150: return (*dev->emul_ops->read) (dev->emul_data, reply_port, ! 151: reply_port_type, mode, recnum, ! 152: count, data, bytes_read); ! 153: } ! 154: ! 155: io_return_t ! 156: ds_device_read_inband (device_t dev, ipc_port_t reply_port, ! 157: mach_msg_type_name_t reply_port_type, dev_mode_t mode, ! 158: recnum_t recnum, int count, char *data, ! 159: unsigned *bytes_read) ! 160: { ! 161: if (dev == DEVICE_NULL) ! 162: return D_NO_SUCH_DEVICE; ! 163: if (! dev->emul_ops->read_inband) ! 164: return D_INVALID_OPERATION; ! 165: return (*dev->emul_ops->read_inband) (dev->emul_data, reply_port, ! 166: reply_port_type, mode, recnum, ! 167: count, data, bytes_read); ! 168: } ! 169: ! 170: io_return_t ! 171: ds_device_set_status (device_t dev, dev_flavor_t flavor, ! 172: dev_status_t status, mach_msg_type_number_t status_count) ! 173: { ! 174: if (dev == DEVICE_NULL) ! 175: return D_NO_SUCH_DEVICE; ! 176: if (! dev->emul_ops->set_status) ! 177: return D_INVALID_OPERATION; ! 178: ! 179: return (*dev->emul_ops->set_status) (dev->emul_data, flavor, status, ! 180: status_count); ! 181: } ! 182: ! 183: io_return_t ! 184: ds_device_get_status (device_t dev, dev_flavor_t flavor, dev_status_t status, ! 185: mach_msg_type_number_t *status_count) ! 186: { ! 187: if (dev == DEVICE_NULL) ! 188: return D_NO_SUCH_DEVICE; ! 189: if (! dev->emul_ops->get_status) ! 190: return D_INVALID_OPERATION; ! 191: ! 192: return (*dev->emul_ops->get_status) (dev->emul_data, flavor, status, ! 193: status_count); ! 194: } ! 195: ! 196: io_return_t ! 197: ds_device_set_filter (device_t dev, ipc_port_t receive_port, int priority, ! 198: filter_t *filter, unsigned filter_count) ! 199: { ! 200: if (dev == DEVICE_NULL) ! 201: return D_NO_SUCH_DEVICE; ! 202: if (! dev->emul_ops->set_filter) ! 203: return D_INVALID_OPERATION; ! 204: return (*dev->emul_ops->set_filter) (dev->emul_data, receive_port, ! 205: priority, filter, filter_count); ! 206: } ! 207: ! 208: io_return_t ! 209: ds_device_map (device_t dev, vm_prot_t prot, vm_offset_t offset, ! 210: vm_size_t size, ipc_port_t *pager, boolean_t unmap) ! 211: { ! 212: if (dev == DEVICE_NULL) ! 213: return D_NO_SUCH_DEVICE; ! 214: if (! dev->emul_ops->map) ! 215: return D_INVALID_OPERATION; ! 216: return (*dev->emul_ops->map) (dev->emul_data, prot, ! 217: offset, size, pager, unmap); ! 218: } ! 219: ! 220: boolean_t ! 221: ds_notify (mach_msg_header_t *msg) ! 222: { ! 223: if (msg->msgh_id == MACH_NOTIFY_NO_SENDERS) ! 224: { ! 225: device_t dev; ! 226: mach_no_senders_notification_t *ns; ! 227: ! 228: ns = (mach_no_senders_notification_t *) msg; ! 229: dev = (device_t) ns->not_header.msgh_remote_port; ! 230: if (dev->emul_ops->no_senders) ! 231: (*dev->emul_ops->no_senders) (ns); ! 232: return TRUE; ! 233: } ! 234: ! 235: printf ("ds_notify: strange notification %d\n", msg->msgh_id); ! 236: return FALSE; ! 237: } ! 238: ! 239: io_return_t ! 240: ds_device_write_trap (device_t dev, dev_mode_t mode, ! 241: recnum_t recnum, vm_offset_t data, vm_size_t count) ! 242: { ! 243: if (dev == DEVICE_NULL) ! 244: return D_NO_SUCH_DEVICE; ! 245: if (! dev->emul_ops->write_trap) ! 246: return D_INVALID_OPERATION; ! 247: return (*dev->emul_ops->write_trap) (dev->emul_data, ! 248: mode, recnum, data, count); ! 249: } ! 250: ! 251: io_return_t ! 252: ds_device_writev_trap (device_t dev, dev_mode_t mode, ! 253: recnum_t recnum, io_buf_vec_t *iovec, vm_size_t count) ! 254: { ! 255: if (dev == DEVICE_NULL) ! 256: return D_NO_SUCH_DEVICE; ! 257: if (! dev->emul_ops->writev_trap) ! 258: return D_INVALID_OPERATION; ! 259: return (*dev->emul_ops->writev_trap) (dev->emul_data, ! 260: mode, recnum, iovec, count); ! 261: } ! 262: ! 263: void ! 264: device_reference (device_t dev) ! 265: { ! 266: if (dev->emul_ops->reference) ! 267: (*dev->emul_ops->reference) (dev->emul_data); ! 268: } ! 269: ! 270: void ! 271: device_deallocate (device_t dev) ! 272: { ! 273: if (dev->emul_ops->dealloc) ! 274: (*dev->emul_ops->dealloc) (dev->emul_data); ! 275: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.