|
|
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.