From e522045e0d2f2e3aaa5694e9e83ca2621ed5b9dc Mon Sep 17 00:00:00 2001 From: Samuel Thibault Date: Mon, 30 Mar 2020 00:15:44 +0200 Subject: Rename DDE-based libmachdev to libmachdevdde --- Makefile | 2 +- dde_e100/Makefile | 2 +- dde_e1000/Makefile | 2 +- dde_ne2k_pci/Makefile | 2 +- dde_pcnet32/Makefile | 2 +- dde_rtl8139/Makefile | 2 +- libmachdev/Makefile | 35 --- libmachdev/block.c | 314 ------------------- libmachdev/dev_hdr.h | 133 -------- libmachdev/device_emul.h | 65 ---- libmachdev/ds_routines.c | 341 -------------------- libmachdev/ds_routines.h | 57 ---- libmachdev/errno-base.h | 39 --- libmachdev/if_ether.h | 87 ----- libmachdev/if_hdr.h | 165 ---------- libmachdev/io_req.h | 135 -------- libmachdev/linux-errno.h | 109 ------- libmachdev/mach.defs | 715 ------------------------------------------ libmachdev/mach_glue.h | 41 --- libmachdev/machdev.h | 33 -- libmachdev/mig-decls.h | 50 --- libmachdev/mig-mutate.h | 36 --- libmachdev/misc.c | 50 --- libmachdev/net.c | 662 -------------------------------------- libmachdev/queue.c | 131 -------- libmachdev/queue.h | 370 ---------------------- libmachdev/trivfs_server.c | 171 ---------- libmachdev/util.h | 35 --- libmachdev/vm_param.h | 7 - libmachdevdde/Makefile | 35 +++ libmachdevdde/block.c | 314 +++++++++++++++++++ libmachdevdde/dev_hdr.h | 133 ++++++++ libmachdevdde/device_emul.h | 65 ++++ libmachdevdde/ds_routines.c | 341 ++++++++++++++++++++ libmachdevdde/ds_routines.h | 57 ++++ libmachdevdde/errno-base.h | 39 +++ libmachdevdde/if_ether.h | 87 +++++ libmachdevdde/if_hdr.h | 165 ++++++++++ libmachdevdde/io_req.h | 135 ++++++++ libmachdevdde/linux-errno.h | 109 +++++++ libmachdevdde/mach.defs | 715 ++++++++++++++++++++++++++++++++++++++++++ libmachdevdde/mach_glue.h | 41 +++ libmachdevdde/machdev.h | 33 ++ libmachdevdde/mig-decls.h | 50 +++ libmachdevdde/mig-mutate.h | 36 +++ libmachdevdde/misc.c | 50 +++ libmachdevdde/net.c | 662 ++++++++++++++++++++++++++++++++++++++ libmachdevdde/queue.c | 131 ++++++++ libmachdevdde/queue.h | 370 ++++++++++++++++++++++ libmachdevdde/trivfs_server.c | 171 ++++++++++ libmachdevdde/util.h | 35 +++ libmachdevdde/vm_param.h | 7 + windhoek/Makefile | 2 +- 53 files changed, 3788 insertions(+), 3788 deletions(-) delete mode 100644 libmachdev/Makefile delete mode 100644 libmachdev/block.c delete mode 100644 libmachdev/dev_hdr.h delete mode 100644 libmachdev/device_emul.h delete mode 100644 libmachdev/ds_routines.c delete mode 100644 libmachdev/ds_routines.h delete mode 100644 libmachdev/errno-base.h delete mode 100644 libmachdev/if_ether.h delete mode 100644 libmachdev/if_hdr.h delete mode 100644 libmachdev/io_req.h delete mode 100644 libmachdev/linux-errno.h delete mode 100644 libmachdev/mach.defs delete mode 100644 libmachdev/mach_glue.h delete mode 100644 libmachdev/machdev.h delete mode 100644 libmachdev/mig-decls.h delete mode 100644 libmachdev/mig-mutate.h delete mode 100644 libmachdev/misc.c delete mode 100644 libmachdev/net.c delete mode 100644 libmachdev/queue.c delete mode 100644 libmachdev/queue.h delete mode 100644 libmachdev/trivfs_server.c delete mode 100644 libmachdev/util.h delete mode 100644 libmachdev/vm_param.h create mode 100644 libmachdevdde/Makefile create mode 100644 libmachdevdde/block.c create mode 100644 libmachdevdde/dev_hdr.h create mode 100644 libmachdevdde/device_emul.h create mode 100644 libmachdevdde/ds_routines.c create mode 100644 libmachdevdde/ds_routines.h create mode 100644 libmachdevdde/errno-base.h create mode 100644 libmachdevdde/if_ether.h create mode 100644 libmachdevdde/if_hdr.h create mode 100644 libmachdevdde/io_req.h create mode 100644 libmachdevdde/linux-errno.h create mode 100644 libmachdevdde/mach.defs create mode 100644 libmachdevdde/mach_glue.h create mode 100644 libmachdevdde/machdev.h create mode 100644 libmachdevdde/mig-decls.h create mode 100644 libmachdevdde/mig-mutate.h create mode 100644 libmachdevdde/misc.c create mode 100644 libmachdevdde/net.c create mode 100644 libmachdevdde/queue.c create mode 100644 libmachdevdde/queue.h create mode 100644 libmachdevdde/trivfs_server.c create mode 100644 libmachdevdde/util.h create mode 100644 libmachdevdde/vm_param.h diff --git a/Makefile b/Makefile index 9efd5477e..d755c0f9b 100644 --- a/Makefile +++ b/Makefile @@ -33,7 +33,7 @@ lib-subdirs = libshouldbeinlibc libihash libiohelp libports libthreads \ libbpf \ ifneq ($(LIBPCIACCESS),no) -lib-subdirs += libmachdev libddekit +lib-subdirs += libmachdevdde libddekit endif # Hurd programs diff --git a/dde_e100/Makefile b/dde_e100/Makefile index f8ce6063c..ce66468e6 100644 --- a/dde_e100/Makefile +++ b/dde_e100/Makefile @@ -7,7 +7,7 @@ TARGET = dde_e100 SRC_C = main.c e100.c -LIBS += $(libmachdev_path) -ldde_linux26.o -ldde_linux26_net $(libddekit_path) -lfshelp -ltrivfs -lpciaccess -lpthread -lshouldbeinlibc -lports $(libslab_path) $(libbpf_path) +LIBS += $(libmachdevdde_path) -ldde_linux26.o -ldde_linux26_net $(libddekit_path) -lfshelp -ltrivfs -lpciaccess -lpthread -lshouldbeinlibc -lports $(libslab_path) $(libbpf_path) CFLAGS += -g -I$(PKGDIR)/include -I$(BUILDDIR)/include # DDE configuration diff --git a/dde_e1000/Makefile b/dde_e1000/Makefile index 2062d0b53..5e8d21862 100644 --- a/dde_e1000/Makefile +++ b/dde_e1000/Makefile @@ -7,7 +7,7 @@ TARGET = dde_e1000 SRC_C = main.c e1000_ethtool.c e1000_hw.c e1000_main.c e1000_param.c -LIBS += $(libmachdev_path) -ldde_linux26.o -ldde_linux26_net $(libddekit_path) -lfshelp -ltrivfs -lpciaccess -lpthread -lshouldbeinlibc -lports $(libslab_path) $(libbpf_path) +LIBS += $(libmachdevdde_path) -ldde_linux26.o -ldde_linux26_net $(libddekit_path) -lfshelp -ltrivfs -lpciaccess -lpthread -lshouldbeinlibc -lports $(libslab_path) $(libbpf_path) CFLAGS += -g -I$(PKGDIR)/include -I$(BUILDDIR)/include # DDE configuration diff --git a/dde_ne2k_pci/Makefile b/dde_ne2k_pci/Makefile index 293968569..2cea19ddc 100644 --- a/dde_ne2k_pci/Makefile +++ b/dde_ne2k_pci/Makefile @@ -9,7 +9,7 @@ TARGET = dde_ne2k_pci SRC_C = main.c ne2k-pci.c 8390.c -LIBS += $(libmachdev_path) -ldde_linux26.o -ldde_linux26_net $(libddekit_path) -lfshelp -ltrivfs -lpciaccess -lpthread -lshouldbeinlibc -lports $(libslab_path) $(libbpf_path) +LIBS += $(libmachdevdde_path) -ldde_linux26.o -ldde_linux26_net $(libddekit_path) -lfshelp -ltrivfs -lpciaccess -lpthread -lshouldbeinlibc -lports $(libslab_path) $(libbpf_path) CFLAGS += -g -I$(PKGDIR)/include -I$(BUILDDIR)/include # DDE configuration diff --git a/dde_pcnet32/Makefile b/dde_pcnet32/Makefile index 1bf47c4cf..006f93a24 100644 --- a/dde_pcnet32/Makefile +++ b/dde_pcnet32/Makefile @@ -7,7 +7,7 @@ TARGET = dde_pcnet32 SRC_C = main.c pcnet32.c -LIBS += $(libmachdev_path) -ldde_linux26.o -ldde_linux26_net $(libddekit_path) -lfshelp -ltrivfs -lpciaccess -lpthread -lshouldbeinlibc -lports $(libslab_path) $(libbpf_path) +LIBS += $(libmachdevdde_path) -ldde_linux26.o -ldde_linux26_net $(libddekit_path) -lfshelp -ltrivfs -lpciaccess -lpthread -lshouldbeinlibc -lports $(libslab_path) $(libbpf_path) CFLAGS += -g -I$(PKGDIR)/include -I$(BUILDDIR)/include # DDE configuration diff --git a/dde_rtl8139/Makefile b/dde_rtl8139/Makefile index 95b6fa0ae..d22d41cf6 100644 --- a/dde_rtl8139/Makefile +++ b/dde_rtl8139/Makefile @@ -9,7 +9,7 @@ TARGET = dde_rtl8139 SRC_C = main.c 8139cp.c -LIBS += $(libmachdev_path) -ldde_linux26.o -ldde_linux26_net $(libddekit_path) -lfshelp -ltrivfs -lpciaccess -lpthread -lshouldbeinlibc -lports $(libslab_path) $(libbpf_path) +LIBS += $(libmachdevdde_path) -ldde_linux26.o -ldde_linux26_net $(libddekit_path) -lfshelp -ltrivfs -lpciaccess -lpthread -lshouldbeinlibc -lports $(libslab_path) $(libbpf_path) CFLAGS += -g -I$(PKGDIR)/include -I$(BUILDDIR)/include # DDE configuration diff --git a/libmachdev/Makefile b/libmachdev/Makefile deleted file mode 100644 index 77d2a342f..000000000 --- a/libmachdev/Makefile +++ /dev/null @@ -1,35 +0,0 @@ -# Copyright (C) 2009 Free Software Foundation, Inc. -# This file is part of the GNU Hurd. -# -# The GNU Hurd is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# The GNU Hurd is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with the GNU Hurd; see the file COPYING. If not, write to -# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - -dir := libmachdev -makemode := library -libname = libmachdev - -SRCS = deviceUser.c machUser.c net.c ds_routines.c queue.c trivfs_server.c \ - device_replyUser.c deviceServer.c notifyServer.c misc.c -#block.c -LCLHDRS = dev_hdr.h device_emul.h ds_routines.h vm_param.h \ - util.h queue.h io_req.h if_ether.h machdev.h linux-errno.h \ - errno-base.h -installhdrs = machdev.h -HURDLIBS = ports trivfs bpf ddekit -LDLIBS += -lpthread -OBJS = $(SRCS:.c=.o) $(MIGSTUBS) -MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h -device-MIGSFLAGS="-DMACH_PAYLOAD_TO_PORT=ports_payload_get_name" - -include ../Makeconf diff --git a/libmachdev/block.c b/libmachdev/block.c deleted file mode 100644 index 799620726..000000000 --- a/libmachdev/block.c +++ /dev/null @@ -1,314 +0,0 @@ -/* - * Linux block driver support. - * - * Copyright (C) 1996 The University of Utah and the Computer Systems - * Laboratory at the University of Utah (CSL) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Author: Shantanu Goel, University of Utah CSL - */ - -#include -#include -#include -#include - -#include "mach_U.h" - -#include -#include - -#define MACH_INCLUDE - -#include - -#include "ds_routines.h" -#include "vm_param.h" -#include "device_reply_U.h" -#include "dev_hdr.h" -#include "util.h" -#include "mach_glue.h" - -/* for submit_bio(). But it might not be very proper to keep - * my own definitions of these macros. */ -#define READ 0 -#define WRITE 1 - -/* One of these is associated with each open instance of a device. */ -struct block_data -{ - struct port_info port; /* device port */ - struct emul_device device; /* generic device structure */ - dev_mode_t mode; - struct block_device *dev; -}; - -/* Return a send right associated with network device ND. */ -static mach_port_t -dev_to_port (void *nd) -{ - return (nd - ? ports_get_send_right (nd) - : MACH_PORT_NULL); -} - -static struct device_emulation_ops linux_block_emulation_ops; - -#define DISK_NAME_LEN 32 - -/* Parse the device NAME. - Set *SLICE to be the DOS partition and - *PART the BSD/Mach partition, if any. */ -static char * -translate_name (char *name, int *slice, int *part) -{ - char *p, *q, *end; - char *ret; - int disk_num; - - /* Parse name into name, unit, DOS partition (slice) and partition. */ - for (*slice = 0, *part = -1, p = name; isalpha (*p); p++) - ; - if (p == name || ! isdigit (*p)) - return NULL; - end = p; - disk_num = strtol (p, &p, 0); - if (disk_num < 0 || disk_num > 26) - return NULL; -// do -// p++; -// while (isdigit (*p)); - if (*p) - { - q = p; - if (*q == 's' && isdigit (*(q + 1))) - { - q++; - do - *slice = *slice * 10 + *q++ - '0'; - while (isdigit (*q)); - if (! *q) - goto find_major; - } - if (! isalpha (*q) || *(q + 1)) - return NULL; - *part = *q - 'a'; - } - -find_major: - ret = malloc (DISK_NAME_LEN); - sprintf (ret, "hd%c", 'a' + disk_num); - return ret; -} - -static io_return_t -device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type, - dev_mode_t mode, char *name, device_t *devp, - mach_msg_type_name_t *devicePoly) -{ - io_return_t err = D_SUCCESS; - struct block_data *bd = NULL; - int slice, part; - char *dev_name = NULL; - int dev_err; - - // TODO I need to check whether the device has been opened before. - // if it has been opened with the same `flag', return the same port, - // otherwise, return a different port. - // I need to have a reference to count the number of open. - dev_name = translate_name (name, &slice, &part); - if (dev_name == NULL) - return D_NO_SUCH_DEVICE; - - err = create_device_port (sizeof (*bd), &bd); - if (err) - { - ddekit_printf ("after create_device_port: cannot create a port\n"); - goto out; - } - bd->dev = open_block_dev (dev_name, slice, mode); - dev_err = (int) bd->dev; - if (dev_err < 0) - { - ddekit_printf ("open_block_dev %s fails with %d\n", dev_name, bd->dev); - err = linux_to_mach_error (dev_err); - goto out; - } - bd->device.emul_data = bd; - bd->device.emul_ops = &linux_block_emulation_ops; - bd->mode = mode; - -out: - free (dev_name); - if (err) - { - if (bd) - { - ports_destroy_right (bd); - bd = NULL; - } - } - else - { - *devp = ports_get_send_right (bd); - ports_port_deref (bd); - *devicePoly = MACH_MSG_TYPE_MOVE_SEND; - } - return err; -} - -static io_return_t -device_write (void *d, mach_port_t reply_port, - mach_msg_type_name_t reply_port_type, dev_mode_t mode, - recnum_t bn, io_buf_ptr_t data, unsigned int count, - int *bytes_written) -{ - struct block_data *bd = d; - /* the number of pages that contain DATA. */ - int npages = (((int) data + count) - ((int) data & ~PAGE_MASK) - + PAGE_MASK) / PAGE_SIZE; - io_return_t err = D_SUCCESS; - int i; - int writes = 0; - - void write_done (int err) - { - int len = err ? 0 : count; - // TODO maybe I should send the reply as long as there is an error. - writes--; - if (writes == 0) - { - err = linux_to_mach_error (err); - ds_device_write_reply (reply_port, reply_port_type, err, len); - } - } - - /* the data is at the beginning of a page. */ - if ((int) data & ~PAGE_MASK) - return D_INVALID_OPERATION; - - if ((bd->mode & D_WRITE) == 0) - return D_INVALID_OPERATION; - - for (i = 0; i < npages; i++) - { - int size = PAGE_SIZE - ((int) data &~PAGE_MASK) > count ? - count : PAGE_SIZE - ((int) data &~PAGE_MASK); - - err = block_dev_rw (bd->dev, bn, data, size, WRITE, write_done); - if (err) - break; - bn += size >> 9; - data += size; - count -= size; - writes++; - } - if (writes) - return MIG_NO_REPLY; - return linux_to_mach_error (err); -} - -static io_return_t -device_read (void *d, mach_port_t reply_port, - mach_msg_type_name_t reply_port_type, dev_mode_t mode, - recnum_t bn, int count, io_buf_ptr_t *data, - unsigned *bytes_read) -{ - struct block_data *bd = d; - io_return_t err = D_SUCCESS; - int i; - int reads = 0; - char *buf; - int npages = (count + PAGE_SIZE - 1) / PAGE_SIZE; - int rest = count; - - void read_done (int err) - { - int len = err ? 0 : count; - reads--; - if (reads == 0) - { - err = linux_to_mach_error (err); - ds_device_read_reply (reply_port, reply_port_type, err, buf, len); - } - } - - if ((bd->mode & D_READ) == 0) - return D_INVALID_OPERATION; - - if (count == 0) - return 0; - - *data = 0; - buf = mmap (NULL, npages * PAGE_SIZE, PROT_READ|PROT_WRITE, - MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); - if (buf == MAP_FAILED) - return errno; - - ddekit_printf ("read %d pages.\n", npages); - for (i = 0; i < npages; i++) - { - int size = rest > PAGE_SIZE ? PAGE_SIZE : rest; - ddekit_printf ("read %d bytes starting from %d\n", size, bn); - - err = block_dev_rw (bd->dev, bn, buf + i * PAGE_SIZE, - size, READ, read_done); - if (err) - break; - bn += size >> 9; - rest -= size; - reads++; - } - // TODO when should I deallocate the buffer? - if (reads) - return MIG_NO_REPLY; - return linux_to_mach_error (err); -} - -static io_return_t -device_get_status (void *d, dev_flavor_t flavor, dev_status_t status, - mach_msg_type_number_t *count) -{ - struct block_data *bd = (struct block_data *) d; - return D_SUCCESS; -} - -static struct device_emulation_ops linux_block_emulation_ops = -{ - NULL, - NULL, - NULL, - dev_to_port, - device_open, - NULL, - device_write, - NULL, - device_read, - NULL, - NULL, - device_get_status, - NULL, - NULL, - NULL, - NULL, - NULL -}; - -void register_block() -{ - extern void reg_dev_emul (struct device_emulation_ops *ops); - reg_dev_emul (&linux_block_emulation_ops); -} diff --git a/libmachdev/dev_hdr.h b/libmachdev/dev_hdr.h deleted file mode 100644 index 79edc43a3..000000000 --- a/libmachdev/dev_hdr.h +++ /dev/null @@ -1,133 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - * Author: David B. Golub, Carnegie Mellon University - * Date: 3/89 - */ - -/* - * Mach device emulation definitions (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 - */ - -#ifndef _DEVICE_DEV_HDR_H_ -#define _DEVICE_DEV_HDR_H_ - -#include -#include -#include -#include - -#include "device_emul.h" - -/* - * Operations list for major device types. - */ -struct dev_ops { - char * d_name; /* name for major device */ - int (*d_open)(); /* open device */ - int (*d_close)(); /* close device */ - int (*d_read)(); /* read */ - int (*d_write)(); /* write */ - int (*d_getstat)(); /* get status/control */ - int (*d_setstat)(); /* set status/control */ - vm_offset_t (*d_mmap)(); /* map memory */ - int (*d_async_in)();/* asynchronous input setup */ - int (*d_reset)(); /* reset device */ - int (*d_port_death)(); - /* clean up reply ports */ - int d_subdev; /* number of sub-devices per - unit */ - int (*d_dev_info)(); /* driver info for kernel */ -}; -typedef struct dev_ops *dev_ops_t; - -/* This structure is associated with each open device port. - * The port representing the device points to this structure. */ -struct emul_device -{ - struct device_emulation_ops *emul_ops; - void *emul_data; -}; - -typedef struct emul_device *emul_device_t; - -#define DEVICE_NULL ((device_t) 0) - -/* - * Generic device header. May be allocated with the device, - * or built when the device is opened. - */ -struct mach_device { - struct port_info port; - struct emul_device dev; /* the real device structure */ -}; -typedef struct mach_device *mach_device_t; -#define MACH_DEVICE_NULL ((mach_device_t)0) - -/* - * To find and remove device entries - */ -mach_device_t device_lookup(char *); /* by name */ - -/* - * To find and remove port-to-device mappings - */ -void dev_port_enter(mach_device_t); -void dev_port_remove(mach_device_t); - -/* - * To call a routine on each device - */ -boolean_t dev_map(boolean_t (*)(), mach_port_t); - -/* - * To lock and unlock state and open-count - */ -#define device_lock(device) pthread_mutex_lock(&(device)->lock) -#define device_unlock(device) pthread_mutex_unlock(&(device)->lock) - -#endif /* _DEVICE_DEV_HDR_H_ */ diff --git a/libmachdev/device_emul.h b/libmachdev/device_emul.h deleted file mode 100644 index e27799cbd..000000000 --- a/libmachdev/device_emul.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * Mach device emulation definitions (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 - */ - -#ifndef _I386AT_DEVICE_EMUL_H_ -#define _I386AT_DEVICE_EMUL_H_ - -#include - -/* Each emulation layer provides these operations. */ -struct device_emulation_ops -{ - void (*init) (void); - void (*reference) (void *); - void (*dealloc) (void *); - mach_port_t (*dev_to_port) (void *); - io_return_t (*open) (mach_port_t, mach_msg_type_name_t, - dev_mode_t, char *, device_t *, - mach_msg_type_name_t *type); - io_return_t (*close) (void *); - io_return_t (*write) (void *, mach_port_t, mach_msg_type_name_t, - dev_mode_t, recnum_t, io_buf_ptr_t, unsigned, int *); - io_return_t (*write_inband) (void *, mach_port_t, mach_msg_type_name_t, - dev_mode_t, recnum_t, io_buf_ptr_inband_t, - unsigned, int *); - io_return_t (*read) (void *, mach_port_t, mach_msg_type_name_t, - dev_mode_t, recnum_t, int, io_buf_ptr_t *, unsigned *); - io_return_t (*read_inband) (void *, mach_port_t, mach_msg_type_name_t, - dev_mode_t, recnum_t, int, char *, unsigned *); - io_return_t (*set_status) (void *, dev_flavor_t, dev_status_t, - mach_msg_type_number_t); - io_return_t (*get_status) (void *, dev_flavor_t, dev_status_t, - mach_msg_type_number_t *); - io_return_t (*set_filter) (void *, mach_port_t, int, filter_t [], unsigned); - io_return_t (*map) (void *, vm_prot_t, vm_offset_t, - vm_size_t, mach_port_t *, boolean_t); - void (*no_senders) (mach_no_senders_notification_t *); - io_return_t (*write_trap) (void *, dev_mode_t, - recnum_t, vm_offset_t, vm_size_t); - io_return_t (*writev_trap) (void *, dev_mode_t, - recnum_t, io_buf_vec_t *, vm_size_t); -}; - -#endif /* _I386AT_DEVICE_EMUL_H_ */ diff --git a/libmachdev/ds_routines.c b/libmachdev/ds_routines.c deleted file mode 100644 index e9fbe9445..000000000 --- a/libmachdev/ds_routines.c +++ /dev/null @@ -1,341 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1993,1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - * Author: David B. Golub, Carnegie Mellon University - * Date: 3/89 - */ - -/* - * 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 -#include - -#include - -#include "vm_param.h" -#include "device_S.h" -#include "notify_S.h" -#include "io_req.h" -#include "dev_hdr.h" -#include "util.h" -#include "queue.h" -#include "mach_glue.h" - -struct port_bucket *device_bucket; -struct port_class *dev_class; - -#define NUM_EMULATION num_emul -#define MAX_NUM_EMULATION 32 - -/* List of emulations. */ -static struct device_emulation_ops *emulation_list[MAX_NUM_EMULATION]; -static int num_emul; - -boolean_t is_master_device (mach_port_t port); - -/* - * What follows is the interface for the native Mach devices. - */ - -/* Implementation of device interface */ -io_return_t -ds_device_open (mach_port_t open_port, mach_port_t reply_port, - mach_msg_type_name_t reply_port_type, dev_mode_t mode, - char *name, device_t *devp, mach_msg_type_name_t *devicePoly) -{ - int i; - io_return_t err = D_NO_SUCH_DEVICE; - - /* Open must be called on the master device port. */ - if (!is_master_device (open_port)) - return D_INVALID_OPERATION; - - /* There must be a reply port. */ - if (! MACH_PORT_VALID (reply_port)) - { - fprintf (stderr, "ds_* invalid reply port\n"); - 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, devicePoly); - if (err != D_NO_SUCH_DEVICE) - break; - } - - return err; -} - -io_return_t -ds_device_close (struct mach_device *device) -{ - io_return_t ret; - - if (device == NULL) - return D_NO_SUCH_DEVICE; - - ret = (device->dev.emul_ops->close - ? (*device->dev.emul_ops->close) (device->dev.emul_data) - : D_SUCCESS); - return ret; -} - -io_return_t -ds_device_write (struct mach_device *device, mach_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) -{ - io_return_t ret; - - if (data == 0) - return D_INVALID_SIZE; - - if (device == NULL) - return D_NO_SUCH_DEVICE; - - if (! device->dev.emul_ops->write) - return D_INVALID_OPERATION; - - ret = (*device->dev.emul_ops->write) (device->dev.emul_data, reply_port, - reply_port_type, mode, recnum, - data, count, bytes_written); - return ret; -} - -io_return_t -ds_device_write_inband (struct mach_device *device, mach_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) -{ - io_return_t ret; - - if (data == 0) - return D_INVALID_SIZE; - - if (device == NULL) - return D_NO_SUCH_DEVICE; - - if (! device->dev.emul_ops->write_inband) - return D_INVALID_OPERATION; - - ret = (*device->dev.emul_ops->write_inband) (device->dev.emul_data, - reply_port, reply_port_type, - mode, recnum, - data, count, bytes_written); - return ret; -} - -io_return_t -ds_device_read (struct mach_device *device, mach_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) -{ - io_return_t ret; - - if (device == NULL) - return D_NO_SUCH_DEVICE; - - if (! device->dev.emul_ops->read) - return D_INVALID_OPERATION; - - ret = (*device->dev.emul_ops->read) (device->dev.emul_data, reply_port, - reply_port_type, mode, recnum, - count, data, bytes_read); - return ret; -} - -io_return_t -ds_device_read_inband (struct mach_device *device, mach_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) -{ - io_return_t ret; - - if (device == NULL) - return D_NO_SUCH_DEVICE; - - if (! device->dev.emul_ops->read_inband) - return D_INVALID_OPERATION; - - ret = (*device->dev.emul_ops->read_inband) (device->dev.emul_data, - reply_port, - reply_port_type, mode, recnum, - count, data, bytes_read); - return ret; -} - -io_return_t -ds_device_set_status (struct mach_device *device, dev_flavor_t flavor, - dev_status_t status, mach_msg_type_number_t status_count) -{ - io_return_t ret; - - if (device == NULL) - return D_NO_SUCH_DEVICE; - - if (! device->dev.emul_ops->set_status) - return D_INVALID_OPERATION; - - ret = (*device->dev.emul_ops->set_status) (device->dev.emul_data, flavor, - status, status_count); - return ret; -} - -io_return_t -ds_device_get_status (struct mach_device *device, dev_flavor_t flavor, - dev_status_t status, - mach_msg_type_number_t *status_count) -{ - io_return_t ret; - - if (device == NULL) - return D_NO_SUCH_DEVICE; - - if (! device->dev.emul_ops->get_status) - return D_INVALID_OPERATION; - - ret = (*device->dev.emul_ops->get_status) (device->dev.emul_data, flavor, - status, status_count); - return ret; -} - -io_return_t -ds_device_set_filter (struct mach_device *device, mach_port_t receive_port, - int priority, filter_t *filter, unsigned filter_count) -{ - io_return_t ret; - - if (device == NULL) - return D_NO_SUCH_DEVICE; - - if (! device->dev.emul_ops->set_filter) - return D_INVALID_OPERATION; - - ret = (*device->dev.emul_ops->set_filter) (device->dev.emul_data, - receive_port, - priority, filter, filter_count); - return ret; -} - -io_return_t -ds_device_map (struct mach_device *device, vm_prot_t prot, vm_offset_t offset, - vm_size_t size, mach_port_t *pager, boolean_t unmap) -{ - /* Refuse if device is dead or not completely open. */ - if (device == NULL) - return D_NO_SUCH_DEVICE; - - return D_INVALID_OPERATION; -} - -error_t -create_device_port (size_t size, void *result) -{ - return ports_create_port (dev_class, device_bucket, - size, result); -} - -void mach_device_init() -{ - int i; - - device_bucket = ports_create_bucket (); - dev_class = ports_create_class (0, 0); - - for (i = 0; i < NUM_EMULATION; i++) { - if (emulation_list[i]->init) - emulation_list[i]->init(); - } -} - -static int -demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp) -{ - mig_routine_t routine; - if ((routine = device_server_routine (inp)) || - (routine = notify_server_routine (inp))) - { - (*routine) (inp, outp); - return TRUE; - } - else - return FALSE; -} - -void reg_dev_emul (struct device_emulation_ops *ops) -{ - emulation_list[num_emul++] = ops; -} - -void * ds_server(void *arg) -{ - /* This thread calls Linux functions, - * so I need to make it known to the Linux environment. */ - l4dde26_process_from_ddekit (ddekit_thread_myself ()); - - /* Launch. */ - do - { - ports_manage_port_operations_one_thread (device_bucket, demuxer, 0); - } while (1); - - return NULL; -} diff --git a/libmachdev/ds_routines.h b/libmachdev/ds_routines.h deleted file mode 100644 index 3706aa586..000000000 --- a/libmachdev/ds_routines.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - * Author: David B. Golub, Carnegie Mellon University - * Date: 8/89 - * - * Device service utility routines. - */ - -#ifndef DS_ROUTINES_H -#define DS_ROUTINES_H - -#include - -#include "io_req.h" - -/* - * Map for device IO memory. - */ -//vm_map_t device_io_map; - -kern_return_t device_read_alloc(io_req_t, vm_size_t); -kern_return_t device_write_get(io_req_t, boolean_t *); -boolean_t device_write_dealloc(io_req_t); - -boolean_t ds_open_done(io_req_t); -boolean_t ds_read_done(io_req_t); -boolean_t ds_write_done(io_req_t); - -void iowait (io_req_t ior); - -error_t create_device_port (size_t size, void *result); - -#endif /* DS_ROUTINES_H */ diff --git a/libmachdev/errno-base.h b/libmachdev/errno-base.h deleted file mode 100644 index 651159785..000000000 --- a/libmachdev/errno-base.h +++ /dev/null @@ -1,39 +0,0 @@ -#ifndef _ASM_GENERIC_ERRNO_BASE_H -#define _ASM_GENERIC_ERRNO_BASE_H - -#define EPERM 1 /* Operation not permitted */ -#define ENOENT 2 /* No such file or directory */ -#define ESRCH 3 /* No such process */ -#define EINTR 4 /* Interrupted system call */ -#define EIO 5 /* I/O error */ -#define ENXIO 6 /* No such device or address */ -#define E2BIG 7 /* Argument list too long */ -#define ENOEXEC 8 /* Exec format error */ -#define EBADF 9 /* Bad file number */ -#define ECHILD 10 /* No child processes */ -#define EAGAIN 11 /* Try again */ -#define ENOMEM 12 /* Out of memory */ -#define EACCES 13 /* Permission denied */ -#define EFAULT 14 /* Bad address */ -#define ENOTBLK 15 /* Block device required */ -#define EBUSY 16 /* Device or resource busy */ -#define EEXIST 17 /* File exists */ -#define EXDEV 18 /* Cross-device link */ -#define ENODEV 19 /* No such device */ -#define ENOTDIR 20 /* Not a directory */ -#define EISDIR 21 /* Is a directory */ -#define EINVAL 22 /* Invalid argument */ -#define ENFILE 23 /* File table overflow */ -#define EMFILE 24 /* Too many open files */ -#define ENOTTY 25 /* Not a typewriter */ -#define ETXTBSY 26 /* Text file busy */ -#define EFBIG 27 /* File too large */ -#define ENOSPC 28 /* No space left on device */ -#define ESPIPE 29 /* Illegal seek */ -#define EROFS 30 /* Read-only file system */ -#define EMLINK 31 /* Too many links */ -#define EPIPE 32 /* Broken pipe */ -#define EDOM 33 /* Math argument out of domain of func */ -#define ERANGE 34 /* Math result not representable */ - -#endif diff --git a/libmachdev/if_ether.h b/libmachdev/if_ether.h deleted file mode 100644 index 29974674a..000000000 --- a/libmachdev/if_ether.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * Global definitions for the Ethernet IEEE 802.3 interface. - * - * Version: @(#)if_ether.h 1.0.1a 02/08/94 - * - * Author: Fred N. van Kempen, - * Donald Becker, - * Alan Cox, - * Steve Whitehouse, - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ - -#ifndef _LINUX_IF_ETHER_H -#define _LINUX_IF_ETHER_H - -/* - * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble - * and FCS/CRC (frame check sequence). - */ - -#define ETH_ALEN 6 /* Octets in one ethernet addr */ -#define ETH_HLEN 14 /* Total octets in header. */ -#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ -#define ETH_DATA_LEN 1500 /* Max. octets in payload */ -#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ - -/* - * These are the defined Ethernet Protocol ID's. - */ - -#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */ -#define ETH_P_ECHO 0x0200 /* Ethernet Echo packet */ -#define ETH_P_PUP 0x0400 /* Xerox PUP packet */ -#define ETH_P_IP 0x0800 /* Internet Protocol packet */ -#define ETH_P_X25 0x0805 /* CCITT X.25 */ -#define ETH_P_ARP 0x0806 /* Address Resolution packet */ -#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */ -#define ETH_P_DEC 0x6000 /* DEC Assigned proto */ -#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */ -#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */ -#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */ -#define ETH_P_LAT 0x6004 /* DEC LAT */ -#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */ -#define ETH_P_CUST 0x6006 /* DEC Customer use */ -#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */ -#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */ -#define ETH_P_ATALK 0x809B /* Appletalk DDP */ -#define ETH_P_AARP 0x80F3 /* Appletalk AARP */ -#define ETH_P_IPX 0x8137 /* IPX over DIX */ -#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ - -/* - * Non DIX types. Won't clash for 1500 types. - */ - -#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */ -#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */ -#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */ -#define ETH_P_802_2 0x0004 /* 802.2 frames */ -#define ETH_P_SNAP 0x0005 /* Internal only */ -#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */ -#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/ -#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */ -#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */ -#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/ -#define ETH_P_TR_802_2 0x0011 /* 802.2 frames */ - -/* - * This is an Ethernet frame header. - */ - -struct ethhdr -{ - unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ - unsigned char h_source[ETH_ALEN]; /* source ether addr */ - unsigned short h_proto; /* packet type ID field */ -}; - -#endif /* _LINUX_IF_ETHER_H */ diff --git a/libmachdev/if_hdr.h b/libmachdev/if_hdr.h deleted file mode 100644 index b20f7e354..000000000 --- a/libmachdev/if_hdr.h +++ /dev/null @@ -1,165 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - * Taken from (bsd)net/if.h. Modified for MACH kernel. - */ -/* - * Copyright (c) 1982, 1986 Regents of the University of California. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 4. The name of the Laboratory may not be used to endorse or promote - * products derived from this software without specific prior written - * permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * @(#)if.h 7.3 (Berkeley) 6/27/88 - */ - -#ifndef _IF_HDR_ -#define _IF_HDR_ - -#include -#include -#include - -#if 0 -/* - * Queue for network output and filter input. - */ -struct ifqueue { - queue_head_t ifq_head; /* queue of io_req_t */ - int ifq_len; /* length of queue */ - int ifq_maxlen; /* maximum length of queue */ - int ifq_drops; /* number of packets dropped - because queue full */ - decl_simple_lock_data(, - ifq_lock) /* lock for queue and counters */ -}; -#endif - -/* - * Header for network interface drivers. - */ -struct ifnet { - short if_unit; /* unit number */ - short if_flags; /* up/down, broadcast, etc. */ - short if_timer; /* time until if_watchdog called */ - short if_mtu; /* maximum transmission unit */ - short if_header_size; /* length of header */ - short if_header_format; /* format of hardware header */ - short if_address_size; /* length of hardware address */ - short if_alloc_size; /* size of read buffer to allocate */ - char *if_address; /* pointer to hardware address */ -// struct ifqueue if_snd; /* output queue */ - if_filter_list_t port_list; - pthread_mutex_t if_rcv_port_list_lock;/* lock for input filter list */ - pthread_mutex_t if_snd_port_list_lock;/* lock for output filter list */ -/* statistics */ - int if_ipackets; /* packets received */ - int if_ierrors; /* input errors */ - int if_opackets; /* packets sent */ - int if_oerrors; /* output errors */ - int if_collisions; /* collisions on csma interfaces */ - int if_rcvdrops; /* packets received but dropped */ -}; - -#define IFF_UP 0x0001 /* interface is up */ -#define IFF_BROADCAST 0x0002 /* interface can broadcast */ -#define IFF_DEBUG 0x0004 /* turn on debugging */ -#define IFF_LOOPBACK 0x0008 /* is a loopback net */ -#define IFF_POINTOPOINT 0x0010 /* point-to-point link */ -#define IFF_RUNNING 0x0040 /* resources allocated */ -#define IFF_NOARP 0x0080 /* no address resolution protocol */ -#define IFF_PROMISC 0x0100 /* receive all packets */ -#define IFF_ALLMULTI 0x0200 /* receive all multicast packets */ -#define IFF_BRIDGE 0x0100 /* support token ring routing field */ -#define IFF_SNAP 0x0200 /* support extended sap header */ - -/* internal flags only: */ -#define IFF_CANTCHANGE (IFF_BROADCAST | IFF_POINTOPOINT | IFF_RUNNING) - -/* - * Output queues (ifp->if_snd) - * have queues of messages stored on ifqueue structures. Entries - * are added to and deleted from these structures by these macros, which - * should be called with ipl raised to splimp(). - * XXX locking XXX - */ - -#define IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen) -#define IF_DROP(ifq) ((ifq)->ifq_drops++) -#define IF_ENQUEUE(ifq, ior) { \ - simple_lock(&(ifq)->ifq_lock); \ - enqueue_tail(&(ifq)->ifq_head, (queue_entry_t)ior); \ - (ifq)->ifq_len++; \ - simple_unlock(&(ifq)->ifq_lock); \ -} -#define IF_PREPEND(ifq, ior) { \ - simple_lock(&(ifq)->ifq_lock); \ - enqueue_head(&(ifq)->ifq_head, (queue_entry_t)ior); \ - (ifq)->ifq_len++; \ - simple_unlock(&(ifq)->ifq_lock); \ -} - -#define IF_DEQUEUE(ifq, ior) { \ - simple_lock(&(ifq)->ifq_lock); \ - if (((ior) = (io_req_t)dequeue_head(&(ifq)->ifq_head)) != 0) \ - (ifq)->ifq_len--; \ - simple_unlock(&(ifq)->ifq_lock); \ -} - -#define IFQ_MAXLEN 50 - -#define IFQ_INIT(ifq) { \ - queue_init(&(ifq)->ifq_head); \ - simple_lock_init(&(ifq)->ifq_lock); \ - (ifq)->ifq_len = 0; \ - (ifq)->ifq_maxlen = IFQ_MAXLEN; \ - (ifq)->ifq_drops = 0; \ -} - -#define IFNET_SLOWHZ 1 /* granularity is 1 second */ - -#endif /* _IF_HDR_ */ diff --git a/libmachdev/io_req.h b/libmachdev/io_req.h deleted file mode 100644 index 9c810542d..000000000 --- a/libmachdev/io_req.h +++ /dev/null @@ -1,135 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - * Author: David B. Golub, Carnegie Mellon University - * Date: 10/88 - */ - -#ifndef _IO_REQ_ -#define _IO_REQ_ - -#include -#include - -#include "dev_hdr.h" - -/* - * IO request element, queued on device for delayed replies. - */ -typedef struct io_req *io_req_t; -struct io_req { - struct io_req * io_next; /* next, ... */ - struct io_req * io_prev; /* prev pointers: link in done, - defered, or in-progress list */ - mach_device_t io_device; /* pointer to open-device structure */ - char * io_dev_ptr; /* pointer to driver structure - - filled in by driver if necessary */ - int io_unit; /* unit number ('minor') of device */ - int io_op; /* IO operation */ - dev_mode_t io_mode; /* operation mode (wait, truncate) */ - recnum_t io_recnum; /* starting record number for - random-access devices */ - - union io_un { - io_buf_ptr_t data; /* data, for IO requests */ - } io_un; -#define io_data io_un.data - - long io_count; /* amount requested */ - long io_alloc_size; /* amount allocated */ - long io_residual; /* amount NOT done */ - io_return_t io_error; /* error code */ - /* call when done - returns TRUE if IO really finished */ - boolean_t (*io_done)(io_req_t); - mach_port_t io_reply_port; /* reply port, for asynchronous - messages */ - mach_msg_type_name_t io_reply_port_type; - /* send or send-once right? */ - struct io_req * io_link; /* forward link (for driver header) */ - struct io_req * io_rlink; /* reverse link (for driver header) */ -// vm_map_copy_t io_copy; /* vm_map_copy obj. for this op. */ - long io_total; /* total op size, for write */ - pthread_mutex_t io_req_lock; -// decl_simple_lock_data(,io_req_lock) - /* Lock for this structure */ - long io_physrec; /* mapping to the physical block - number */ - long io_rectotal; /* total number of blocks to move */ -}; - -/* - * LOCKING NOTE: Operations on io_req's are in general single threaded by - * the invoking code, obviating the need for a lock. The usual IO_CALL - * path through the code is: Initiating thread hands io_req to device driver, - * driver passes it to io_done thread, io_done thread sends reply message. No - * locking is needed in this sequence. Unfortunately, a synchronous wait - * for a buffer requires a lock to avoid problems if the wait and interrupt - * happen simultaneously on different processors. - */ - -#define ior_lock(ior) pthread_mutex_lock(&(ior)->io_req_lock) -#define ior_unlock(ior) pthread_mutex_unlock(&(ior)->io_req_lock) - -/* - * Flags and operations - */ - -#define IO_WRITE 0x00000000 /* operation is write */ -#define IO_READ 0x00000001 /* operation is read */ -#define IO_OPEN 0x00000002 /* operation is open */ -#define IO_DONE 0x00000100 /* operation complete */ -#define IO_ERROR 0x00000200 /* error on operation */ -#define IO_BUSY 0x00000400 /* operation in progress */ -#define IO_WANTED 0x00000800 /* wakeup when no longer BUSY */ -#define IO_BAD 0x00001000 /* bad disk block */ -#define IO_CALL 0x00002000 /* call io_done_thread when done */ -#define IO_INBAND 0x00004000 /* mig call was inband */ -#define IO_INTERNAL 0x00008000 /* internal, device-driver specific */ -#define IO_LOANED 0x00010000 /* ior loaned by another module */ - -#define IO_SPARE_START 0x00020000 /* start of spare flags */ - -/* - * Standard completion routine for io_requests. - */ -void iodone(io_req_t); - -/* - * Macros to allocate and free IORs - will convert to zones later. - */ -#define io_req_alloc(ior,size) \ - MACRO_BEGIN \ - (ior) = (io_req_t)malloc(sizeof(struct io_req)); \ - pthread_mutex_init(&(ior)->io_req_lock, NULL); \ - MACRO_END - -#define io_req_free(ior) \ - (free(ior)) - - -//zone_t io_inband_zone; /* for inband reads */ - -#endif /* _IO_REQ_ */ diff --git a/libmachdev/linux-errno.h b/libmachdev/linux-errno.h deleted file mode 100644 index be764a897..000000000 --- a/libmachdev/linux-errno.h +++ /dev/null @@ -1,109 +0,0 @@ -#ifndef _ASM_GENERIC_ERRNO_H -#define _ASM_GENERIC_ERRNO_H - -#include - -#define EDEADLK 35 /* Resource deadlock would occur */ -#define ENAMETOOLONG 36 /* File name too long */ -#define ENOLCK 37 /* No record locks available */ -#define ENOSYS 38 /* Function not implemented */ -#define ENOTEMPTY 39 /* Directory not empty */ -#define ELOOP 40 /* Too many symbolic links encountered */ -#define EWOULDBLOCK EAGAIN /* Operation would block */ -#define ENOMSG 42 /* No message of desired type */ -#define EIDRM 43 /* Identifier removed */ -#define ECHRNG 44 /* Channel number out of range */ -#define EL2NSYNC 45 /* Level 2 not synchronized */ -#define EL3HLT 46 /* Level 3 halted */ -#define EL3RST 47 /* Level 3 reset */ -#define ELNRNG 48 /* Link number out of range */ -#define EUNATCH 49 /* Protocol driver not attached */ -#define ENOCSI 50 /* No CSI structure available */ -#define EL2HLT 51 /* Level 2 halted */ -#define EBADE 52 /* Invalid exchange */ -#define EBADR 53 /* Invalid request descriptor */ -#define EXFULL 54 /* Exchange full */ -#define ENOANO 55 /* No anode */ -#define EBADRQC 56 /* Invalid request code */ -#define EBADSLT 57 /* Invalid slot */ - -#define EDEADLOCK EDEADLK - -#define EBFONT 59 /* Bad font file format */ -#define ENOSTR 60 /* Device not a stream */ -#define ENODATA 61 /* No data available */ -#define ETIME 62 /* Timer expired */ -#define ENOSR 63 /* Out of streams resources */ -#define ENONET 64 /* Machine is not on the network */ -#define ENOPKG 65 /* Package not installed */ -#define EREMOTE 66 /* Object is remote */ -#define ENOLINK 67 /* Link has been severed */ -#define EADV 68 /* Advertise error */ -#define ESRMNT 69 /* Srmount error */ -#define ECOMM 70 /* Communication error on send */ -#define EPROTO 71 /* Protocol error */ -#define EMULTIHOP 72 /* Multihop attempted */ -#define EDOTDOT 73 /* RFS specific error */ -#define EBADMSG 74 /* Not a data message */ -#define EOVERFLOW 75 /* Value too large for defined data type */ -#define ENOTUNIQ 76 /* Name not unique on network */ -#define EBADFD 77 /* File descriptor in bad state */ -#define EREMCHG 78 /* Remote address changed */ -#define ELIBACC 79 /* Can not access a needed shared library */ -#define ELIBBAD 80 /* Accessing a corrupted shared library */ -#define ELIBSCN 81 /* .lib section in a.out corrupted */ -#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ -#define ELIBEXEC 83 /* Cannot exec a shared library directly */ -#define EILSEQ 84 /* Illegal byte sequence */ -#define ERESTART 85 /* Interrupted system call should be restarted */ -#define ESTRPIPE 86 /* Streams pipe error */ -#define EUSERS 87 /* Too many users */ -#define ENOTSOCK 88 /* Socket operation on non-socket */ -#define EDESTADDRREQ 89 /* Destination address required */ -#define EMSGSIZE 90 /* Message too long */ -#define EPROTOTYPE 91 /* Protocol wrong type for socket */ -#define ENOPROTOOPT 92 /* Protocol not available */ -#define EPROTONOSUPPORT 93 /* Protocol not supported */ -#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ -#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ -#define EPFNOSUPPORT 96 /* Protocol family not supported */ -#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ -#define EADDRINUSE 98 /* Address already in use */ -#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ -#define ENETDOWN 100 /* Network is down */ -#define ENETUNREACH 101 /* Network is unreachable */ -#define ENETRESET 102 /* Network dropped connection because of reset */ -#define ECONNABORTED 103 /* Software caused connection abort */ -#define ECONNRESET 104 /* Connection reset by peer */ -#define ENOBUFS 105 /* No buffer space available */ -#define EISCONN 106 /* Transport endpoint is already connected */ -#define ENOTCONN 107 /* Transport endpoint is not connected */ -#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ -#define ETOOMANYREFS 109 /* Too many references: cannot splice */ -#define ETIMEDOUT 110 /* Connection timed out */ -#define ECONNREFUSED 111 /* Connection refused */ -#define EHOSTDOWN 112 /* Host is down */ -#define EHOSTUNREACH 113 /* No route to host */ -#define EALREADY 114 /* Operation already in progress */ -#define EINPROGRESS 115 /* Operation now in progress */ -#define ESTALE 116 /* Stale NFS file handle */ -#define EUCLEAN 117 /* Structure needs cleaning */ -#define ENOTNAM 118 /* Not a XENIX named type file */ -#define ENAVAIL 119 /* No XENIX semaphores available */ -#define EISNAM 120 /* Is a named type file */ -#define EREMOTEIO 121 /* Remote I/O error */ -#define EDQUOT 122 /* Quota exceeded */ - -#define ENOMEDIUM 123 /* No medium found */ -#define EMEDIUMTYPE 124 /* Wrong medium type */ -#define ECANCELED 125 /* Operation Canceled */ -#define ENOKEY 126 /* Required key not available */ -#define EKEYEXPIRED 127 /* Key has expired */ -#define EKEYREVOKED 128 /* Key has been revoked */ -#define EKEYREJECTED 129 /* Key was rejected by service */ - -/* for robust mutexes */ -#define EOWNERDEAD 130 /* Owner died */ -#define ENOTRECOVERABLE 131 /* State not recoverable */ - -#endif diff --git a/libmachdev/mach.defs b/libmachdev/mach.defs deleted file mode 100644 index 2750bcd52..000000000 --- a/libmachdev/mach.defs +++ /dev/null @@ -1,715 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University. - * Copyright (c) 1993,1994 The University of Utah and - * the Computer Systems Laboratory (CSL). - * All rights reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF - * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY - * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF - * THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - * Matchmaker definitions file for Mach kernel interface. - */ - -subsystem -#if KERNEL_USER - KernelUser -#endif /* KERNEL_USER */ -#if KERNEL_SERVER - KernelServer -#endif /* KERNEL_SERVER */ - mach 2000; - -#ifdef KERNEL_USER -userprefix r_; -#endif /* KERNEL_USER */ - -#include -#include - -skip; /* old port_allocate */ -skip; /* old port_deallocate */ -skip; /* old port_enable */ -skip; /* old port_disable */ -skip; /* old port_select */ -skip; /* old port_set_backlog */ -skip; /* old port_status */ - -/* - * Create a new task with an empty set of IPC rights, - * and having an address space constructed from the - * target task (or empty, if inherit_memory is FALSE). - */ -routine task_create( - target_task : task_t; - inherit_memory : boolean_t; - out child_task : task_t); - -/* - * Destroy the target task, causing all of its threads - * to be destroyed, all of its IPC rights to be deallocated, - * and all of its address space to be deallocated. - */ -routine task_terminate( - target_task : task_t); - -/* - * Get user-level handler entry points for all - * emulated system calls. - */ -routine task_get_emulation_vector( - task : task_t; - out vector_start : int; - out emulation_vector: emulation_vector_t); - -/* - * Establish user-level handlers for the specified - * system calls. Non-emulated system calls are specified - * with emulation_vector[i] == EML_ROUTINE_NULL. - */ -routine task_set_emulation_vector( - task : task_t; - vector_start : int; - emulation_vector: emulation_vector_t); - - -/* - * Returns the set of threads belonging to the target task. - */ -routine task_threads( - target_task : task_t; - out thread_list : thread_array_t); - -/* - * Returns information about the target task. - */ -routine task_info( - target_task : task_t; - flavor : int; - out task_info_out : task_info_t, CountInOut); - - -skip; /* old task_status */ -skip; /* old task_set_notify */ -skip; /* old thread_create */ - -/* - * Destroy the target thread. - */ -routine thread_terminate( - target_thread : thread_t); - -/* - * Return the selected state information for the target - * thread. If the thread is currently executing, the results - * may be stale. [Flavor THREAD_STATE_FLAVOR_LIST provides a - * list of valid flavors for the target thread.] - */ -routine thread_get_state( - target_thread : thread_t; - flavor : int; - out old_state : thread_state_t, CountInOut); - -/* - * Set the selected state information for the target thread. - * If the thread is currently executing, the state change - * may be ill-defined. - */ -routine thread_set_state( - target_thread : thread_t; - flavor : int; - new_state : thread_state_t); - -/* - * Returns information about the target thread. - */ -routine thread_info( - target_thread : thread_t; - flavor : int; - out thread_info_out : thread_info_t, CountInOut); - -skip; /* old thread_mutate */ - -/* - * Allocate zero-filled memory in the address space - * of the target task, either at the specified address, - * or wherever space can be found (if anywhere is TRUE), - * of the specified size. The address at which the - * allocation actually took place is returned. - */ -#ifdef EMULATOR -skip; /* the emulator redefines vm_allocate using vm_map */ -#else /* EMULATOR */ -routine vm_allocate( - target_task : vm_task_t; - inout address : vm_address_t; - size : vm_size_t; - anywhere : boolean_t); -#endif /* EMULATOR */ - -skip; /* old vm_allocate_with_pager */ - -/* - * Deallocate the specified range from the virtual - * address space of the target task. - */ -routine vm_deallocate( - target_task : vm_task_t; - address : vm_address_t; - size : vm_size_t); - -/* - * Set the current or maximum protection attribute - * for the specified range of the virtual address - * space of the target task. The current protection - * limits the memory access rights of threads within - * the task; the maximum protection limits the accesses - * that may be given in the current protection. - * Protections are specified as a set of {read, write, execute} - * *permissions*. - */ -routine vm_protect( - target_task : vm_task_t; - address : vm_address_t; - size : vm_size_t; - set_maximum : boolean_t; - new_protection : vm_prot_t); - -/* - * Set the inheritance attribute for the specified range - * of the virtual address space of the target task. - * The inheritance value is one of {none, copy, share}, and - * specifies how the child address space should acquire - * this memory at the time of a task_create call. - */ -routine vm_inherit( - target_task : vm_task_t; - address : vm_address_t; - size : vm_size_t; - new_inheritance : vm_inherit_t); - -/* - * Returns the contents of the specified range of the - * virtual address space of the target task. [The - * range must be aligned on a virtual page boundary, - * and must be a multiple of pages in extent. The - * protection on the specified range must permit reading.] - */ -routine vm_read( - target_task : vm_task_t; - address : vm_address_t; - size : vm_size_t; - out data : pointer_t); - -/* - * Writes the contents of the specified range of the - * virtual address space of the target task. [The - * range must be aligned on a virtual page boundary, - * and must be a multiple of pages in extent. The - * protection on the specified range must permit writing.] - */ -routine vm_write( - target_task : vm_task_t; - address : vm_address_t; - data : pointer_t); - -/* - * Copy the contents of the source range of the virtual - * address space of the target task to the destination - * range in that same address space. [Both of the - * ranges must be aligned on a virtual page boundary, - * and must be multiples of pages in extent. The - * protection on the source range must permit reading, - * and the protection on the destination range must - * permit writing.] - */ -routine vm_copy( - target_task : vm_task_t; - source_address : vm_address_t; - size : vm_size_t; - dest_address : vm_address_t); - -/* - * Returns information about the contents of the virtual - * address space of the target task at the specified - * address. The returned protection, inheritance, sharing - * and memory object values apply to the entire range described - * by the address range returned; the memory object offset - * corresponds to the beginning of the address range. - * [If the specified address is not allocated, the next - * highest address range is described. If no addresses beyond - * the one specified are allocated, the call returns KERN_NO_SPACE.] - */ -routine vm_region( - target_task : vm_task_t; - inout address : vm_address_t; - out size : vm_size_t; - out protection : vm_prot_t; - out max_protection : vm_prot_t; - out inheritance : vm_inherit_t; - out is_shared : boolean_t; - /* avoid out-translation of the argument */ - out object_name : memory_object_name_t = - MACH_MSG_TYPE_MOVE_SEND - ctype: mach_port_t; - out offset : vm_offset_t); - -/* - * Return virtual memory statistics for the host - * on which the target task resides. [Note that the - * statistics are not specific to the target task.] - */ -routine vm_statistics( - target_task : vm_task_t; - out vm_stats : vm_statistics_data_t); - -skip; /* old task_by_u*x_pid */ -skip; /* old vm_pageable */ - -/* - * Stash a handful of ports for the target task; child - * tasks inherit this stash at task_create time. - */ -routine mach_ports_register( - target_task : task_t; - init_port_set : mach_port_array_t = - ^array[] of mach_port_t); - -/* - * Retrieve the stashed ports for the target task. - */ -routine mach_ports_lookup( - target_task : task_t; - out init_port_set : mach_port_array_t = - ^array[] of mach_port_t); - -skip; /* old u*x_pid */ -skip; /* old netipc_listen */ -skip; /* old netipc_ignore */ - -/* - * Provide the data contents of a range of the given memory - * object, with the access restriction specified. [Only - * whole virtual pages of data can be accepted; partial pages - * will be discarded. Data should be provided on request, but - * may be provided in advance as desired. When data already - * held by this kernel is provided again, the new data is ignored. - * The access restriction is the subset of {read, write, execute} - * which are prohibited. The kernel may not provide any data (or - * protection) consistency among pages with different virtual page - * alignments within the same object.] - */ -simpleroutine memory_object_data_provided( - memory_control : memory_object_control_t; - offset : vm_offset_t; - data : pointer_t; - lock_value : vm_prot_t); - -/* - * Indicate that a range of the given temporary memory object does - * not exist, and that the backing memory object should be used - * instead (or zero-fill memory be used, if no backing object exists). - * [This call is intended for use only by the default memory manager. - * It should not be used to indicate a real error -- - * memory_object_data_error should be used for that purpose.] - */ -simpleroutine memory_object_data_unavailable( - memory_control : memory_object_control_t; - offset : vm_offset_t; - size : vm_size_t); - -/* - * Retrieves the attributes currently associated with - * a memory object. - */ -routine memory_object_get_attributes( - memory_control : memory_object_control_t; - out object_ready : boolean_t; - out may_cache : boolean_t; - out copy_strategy : memory_object_copy_strategy_t); - -/* - * Sets the default memory manager, the port to which - * newly-created temporary memory objects are delivered. - * [See (memory_object_default)memory_object_create.] - * The old memory manager port is returned. - */ -routine vm_set_default_memory_manager( - host_priv : host_priv_t; - inout default_manager : mach_port_make_send_t); - -skip; /* old pager_flush_request */ - -/* - * Control use of the data associated with the given - * memory object. For each page in the given range, - * perform the following operations, in order: - * 1) restrict access to the page (disallow - * forms specified by "prot"); - * 2) write back modifications (if "should_return" - * is RETURN_DIRTY and the page is dirty, or - * "should_return" is RETURN_ALL and the page - * is either dirty or precious); and, - * 3) flush the cached copy (if "should_flush" - * is asserted). - * The set of pages is defined by a starting offset - * ("offset") and size ("size"). Only pages with the - * same page alignment as the starting offset are - * considered. - * - * A single acknowledgement is sent (to the "reply_to" - * port) when these actions are complete. - * - * There are two versions of this routine because IPC distinguishes - * between booleans and integers (a 2-valued integer is NOT a - * boolean). The new routine is backwards compatible at the C - * language interface. - */ - -skip; /* old xxx_memory_object_lock_request */ - -simpleroutine memory_object_lock_request( - memory_control : memory_object_control_t; - offset : vm_offset_t; - size : vm_size_t; - should_return : memory_object_return_t; - should_flush : boolean_t; - lock_value : vm_prot_t; - reply_to : mach_port_t = - MACH_MSG_TYPE_MAKE_SEND_ONCE|polymorphic); - -skip; /* old xxx_task_get_emulation_vector */ -skip; /* old xxx_task_set_emulation_vector */ -skip; /* old xxx_host_info */ -skip; /* old xxx_slot_info */ -skip; /* old xxx_cpu_control */ -skip; /* old thread_statistics */ -skip; /* old task_statistics */ -skip; /* old netport_init */ -skip; /* old netport_enter */ -skip; /* old netport_remove */ -skip; /* old thread_set_priority */ - -/* - * Increment the suspend count for the target task. - * No threads within a task may run when the suspend - * count for that task is non-zero. - */ -routine task_suspend( - target_task : task_t); - -/* - * Decrement the suspend count for the target task, - * if the count is currently non-zero. If the resulting - * suspend count is zero, then threads within the task - * that also have non-zero suspend counts may execute. - */ -routine task_resume( - target_task : task_t); - -/* - * Returns the current value of the selected special port - * associated with the target task. - */ -routine task_get_special_port( - task : task_t; - which_port : int; - out special_port : mach_port_t); - -/* - * Set one of the special ports associated with the - * target task. - */ -routine task_set_special_port( - task : task_t; - which_port : int; - special_port : mach_port_t); - -skip; /* old xxx_task_info */ - - -/* - * Create a new thread within the target task, returning - * the port representing that new thread. The - * initial execution state of the thread is undefined. - */ -routine thread_create( - parent_task : task_t; - out child_thread : thread_t); - -/* - * Increment the suspend count for the target thread. - * Once this call has completed, the thread will not - * execute any further user or meta- instructions. - * Once suspended, a thread may not execute again until - * its suspend count is zero, and the suspend count - * for its task is also zero. - */ -routine thread_suspend( - target_thread : thread_t); - -/* - * Decrement the suspend count for the target thread, - * if that count is not already zero. - */ -routine thread_resume( - target_thread : thread_t); - -/* - * Cause any user or meta- instructions currently being - * executed by the target thread to be aborted. [Meta- - * instructions consist of the basic traps for IPC - * (e.g., msg_send, msg_receive) and self-identification - * (e.g., task_self, thread_self, thread_reply). Calls - * described by MiG interfaces are not meta-instructions - * themselves.] - */ -routine thread_abort( - target_thread : thread_t); - -skip; /* old xxx_thread_get_state */ -skip; /* old xxx_thread_set_state */ - -/* - * Returns the current value of the selected special port - * associated with the target thread. - */ -routine thread_get_special_port( - thread : thread_t; - which_port : int; - out special_port : mach_port_t); - -/* - * Set one of the special ports associated with the - * target thread. - */ -routine thread_set_special_port( - thread : thread_t; - which_port : int; - special_port : mach_port_t); - -skip; /* old xxx_thread_info */ - -/* - * Establish a user-level handler for the specified - * system call. - */ -routine task_set_emulation( - target_port : task_t; - routine_entry_pt: vm_address_t; - routine_number : int); - -/* - * Establish restart pc for interrupted atomic sequences. - * This reuses the message number for the old task_get_io_port. - * See task_info.h for description of flavors. - * - */ -routine task_ras_control( - target_task : task_t; - basepc : vm_address_t; - boundspc : vm_address_t; - flavor : int); - - - -skip; /* old host_ipc_statistics */ -skip; /* old port_names */ -skip; /* old port_type */ -skip; /* old port_rename */ -skip; /* old port_allocate */ -skip; /* old port_deallocate */ -skip; /* old port_set_backlog */ -skip; /* old port_status */ -skip; /* old port_set_allocate */ -skip; /* old port_set_deallocate */ -skip; /* old port_set_add */ -skip; /* old port_set_remove */ -skip; /* old port_set_status */ -skip; /* old port_insert_send */ -skip; /* old port_extract_send */ -skip; /* old port_insert_receive */ -skip; /* old port_extract_receive */ - -/* - * Map a user-defined memory object into the virtual address - * space of the target task. If desired (anywhere is TRUE), - * the kernel will find a suitable address range of the - * specified size; else, the specific address will be allocated. - * - * The beginning address of the range will be aligned on a virtual - * page boundary, be at or beyond the address specified, and - * meet the mask requirements (bits turned on in the mask must not - * be turned on in the result); the size of the range, in bytes, - * will be rounded up to an integral number of virtual pages. - * - * The memory in the resulting range will be associated with the - * specified memory object, with the beginning of the memory range - * referring to the specified offset into the memory object. - * - * The mapping will take the current and maximum protections and - * the inheritance attributes specified; see the vm_protect and - * vm_inherit calls for a description of these attributes. - * - * If desired (copy is TRUE), the memory range will be filled - * with a copy of the data from the memory object; this copy will - * be private to this mapping in this target task. Otherwise, - * the memory in this mapping will be shared with other mappings - * of the same memory object at the same offset (in this task or - * in other tasks). [The Mach kernel only enforces shared memory - * consistency among mappings on one host with similar page alignments. - * The user-defined memory manager for this object is responsible - * for further consistency.] - */ -#ifdef EMULATOR -routine htg_vm_map( - target_task : vm_task_t; - ureplyport reply_port : mach_port_make_send_once_t; - inout address : vm_address_t; - size : vm_size_t; - mask : vm_address_t; - anywhere : boolean_t; - memory_object : memory_object_t; - offset : vm_offset_t; - copy : boolean_t; - cur_protection : vm_prot_t; - max_protection : vm_prot_t; - inheritance : vm_inherit_t); -#else /* EMULATOR */ -routine vm_map( - target_task : vm_task_t; - inout address : vm_address_t; - size : vm_size_t; - mask : vm_address_t; - anywhere : boolean_t; - memory_object : memory_object_t; - offset : vm_offset_t; - copy : boolean_t; - cur_protection : vm_prot_t; - max_protection : vm_prot_t; - inheritance : vm_inherit_t); -#endif /* EMULATOR */ - -/* - * Indicate that a range of the specified memory object cannot - * be provided at this time. [Threads waiting for memory pages - * specified by this call will experience a memory exception. - * Only threads waiting at the time of the call are affected.] - */ -simpleroutine memory_object_data_error( - memory_control : memory_object_control_t; - offset : vm_offset_t; - size : vm_size_t; - error_value : kern_return_t); - -/* - * Make decisions regarding the use of the specified - * memory object. - */ -simpleroutine memory_object_set_attributes( - memory_control : memory_object_control_t; - object_ready : boolean_t; - may_cache : boolean_t; - copy_strategy : memory_object_copy_strategy_t); - -/* - */ -simpleroutine memory_object_destroy( - memory_control : memory_object_control_t; - reason : kern_return_t); - -/* - * Provide the data contents of a range of the given memory - * object, with the access restriction specified, optional - * precious attribute, and reply message. [Only - * whole virtual pages of data can be accepted; partial pages - * will be discarded. Data should be provided on request, but - * may be provided in advance as desired. When data already - * held by this kernel is provided again, the new data is ignored. - * The access restriction is the subset of {read, write, execute} - * which are prohibited. The kernel may not provide any data (or - * protection) consistency among pages with different virtual page - * alignments within the same object. The precious value controls - * how the kernel treats the data. If it is FALSE, the kernel treats - * its copy as a temporary and may throw it away if it hasn't been - * changed. If the precious value is TRUE, the kernel treats its - * copy as a data repository and promises to return it to the manager; - * the manager may tell the kernel to throw it away instead by flushing - * and not cleaning the data -- see memory_object_lock_request. The - * reply_to port is for a compeletion message; it will be - * memory_object_supply_completed.] - */ - -simpleroutine memory_object_data_supply( - memory_control : memory_object_control_t; - offset : vm_offset_t; - data : pointer_t, Dealloc[]; - lock_value : vm_prot_t; - precious : boolean_t; - reply_to : mach_port_t = - MACH_MSG_TYPE_MAKE_SEND_ONCE|polymorphic); - -simpleroutine memory_object_ready( - memory_control : memory_object_control_t; - may_cache : boolean_t; - copy_strategy : memory_object_copy_strategy_t); - -simpleroutine memory_object_change_attributes( - memory_control : memory_object_control_t; - may_cache : boolean_t; - copy_strategy : memory_object_copy_strategy_t; - reply_to : mach_port_t = - MACH_MSG_TYPE_MAKE_SEND_ONCE|polymorphic); - -skip; /* old host_callout_statistics_reset */ -skip; /* old port_set_select */ -skip; /* old port_set_backup */ - -/* - * Set/Get special properties of memory associated - * to some virtual address range, such as cachability, - * migrability, replicability. Machine-dependent. - */ -routine vm_machine_attribute( - target_task : vm_task_t; - address : vm_address_t; - size : vm_size_t; - attribute : vm_machine_attribute_t; - inout value : vm_machine_attribute_val_t); - -skip; /* old host_fpa_counters_reset */ - -/* - * This routine is created for allocating DMA buffers. - * We are going to get a contiguous physical memory - * and its physical address in addition to the virtual address. - */ -routine vm_allocate_contiguous( - host_priv : host_priv_t; - target_task : vm_task_t; - out vaddr : vm_address_t; - out paddr : vm_address_t; - size : vm_size_t); - -/* - * There is no more room in this interface for additional calls. - */ diff --git a/libmachdev/mach_glue.h b/libmachdev/mach_glue.h deleted file mode 100644 index 7b1225833..000000000 --- a/libmachdev/mach_glue.h +++ /dev/null @@ -1,41 +0,0 @@ -#ifndef __MACH_GLUE_H__ -#define __MACH_GLUE_H__ - -/* network */ -#include - -#include - -struct sk_buff; -struct net_device; -void skb_done_queue(struct sk_buff *skb); -struct sk_buff *skb_done_dequeue(); -void *skb_reply(struct sk_buff *skb); - -int netdev_flags(struct net_device *dev); -char *netdev_addr(struct net_device *dev); -char *netdev_name (struct net_device *dev); -unsigned int netdev_mtu (struct net_device *dev); -unsigned short netdev_header_len (struct net_device *dev); -unsigned short netdev_type (struct net_device *dev); -unsigned char netdev_addr_len (struct net_device *dev); - -int dev_change_flags (struct net_device *dev, short flags); -int linux_pkg_xmit (char *pkg_data, int len, void *del_data, - int (*del_func) (struct sk_buff *, void *), - struct net_device *dev); -struct net_device *search_netdev (char *name); -void kfree_skb (struct sk_buff *skb); -int dev_open(struct net_device *dev); -void *l4dde26_register_rx_callback(void *cb); -void skb_done_head_init(); - -/* block device */ -struct block_device; -struct block_device *open_block_dev (char *name, int part, dev_mode_t mode); -int block_dev_rw (struct block_device *dev, int sectornr, - char *data, int count, int rw, void (*write_done) (int err)); - -int l4dde26_process_from_ddekit(ddekit_thread_t *t); - -#endif diff --git a/libmachdev/machdev.h b/libmachdev/machdev.h deleted file mode 100644 index b9186fbaf..000000000 --- a/libmachdev/machdev.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - Copyright (C) 2010 Free Software Foundation, Inc. - Written by Zheng Da. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2, or (at your option) - any later version. - - The GNU Hurd is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with the GNU Hurd; see the file COPYING. If not, write to - the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* This file declares interfaces used by driver programs. */ - -#ifndef __MACHDEV_H__ -#define __MACHDEV_H__ - -void * ds_server(void *); -void mach_device_init(void); -void register_net(void); -void register_block(void); -void trivfs_server(void); -int trivfs_init(void); - -#endif diff --git a/libmachdev/mig-decls.h b/libmachdev/mig-decls.h deleted file mode 100644 index 8302029d2..000000000 --- a/libmachdev/mig-decls.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - Copyright (C) 2014 Free Software Foundation, Inc. - Written by Justus Winter. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with the GNU Hurd. If not, see . */ - -#ifndef __LIBMACHDEV_MIG_DECLS_H__ -#define __LIBMACHDEV_MIG_DECLS_H__ - -#include -#include "dev_hdr.h" - -extern struct port_bucket *device_bucket; -extern struct port_class *dev_class; - -/* Called by server stub functions. */ - -static inline struct mach_device * __attribute__ ((unused)) -begin_using_device_port (mach_port_t port) -{ - return ports_lookup_port (device_bucket, port, dev_class); -} - -static inline struct mach_device * __attribute__ ((unused)) -begin_using_device_payload (unsigned long payload) -{ - return ports_lookup_payload (device_bucket, payload, dev_class); -} - -static inline void __attribute__ ((unused)) -end_using_device (struct mach_device *p) -{ - if (p) - ports_port_deref (p); -} - -#endif /* __LIBMACHDEV_MIG_DECLS_H__ */ diff --git a/libmachdev/mig-mutate.h b/libmachdev/mig-mutate.h deleted file mode 100644 index 902ff166f..000000000 --- a/libmachdev/mig-mutate.h +++ /dev/null @@ -1,36 +0,0 @@ -/* - Copyright (C) 2014 Free Software Foundation, Inc. - Written by Justus Winter. - - This file is part of the GNU Hurd. - - The GNU Hurd is free software; you can redistribute it and/or - modify it under the terms of the GNU General Public License as - published by the Free Software Foundation; either version 2, or (at - your option) any later version. - - The GNU Hurd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - General Public License for more details. - - You should have received a copy of the GNU General Public License - along with the GNU Hurd. If not, see . */ - -#define NOTIFY_INTRAN \ - port_info_t begin_using_port_info_port (mach_port_t) -#define NOTIFY_INTRAN_PAYLOAD \ - port_info_t begin_using_port_info_payload -#define NOTIFY_DESTRUCTOR \ - end_using_port_info (port_info_t) -#define NOTIFY_IMPORTS \ - import "libports/mig-decls.h"; - -#define DEVICE_INTRAN \ - mach_device_t begin_using_device_port (mach_port_t) -#define DEVICE_INTRAN_PAYLOAD \ - mach_device_t begin_using_device_payload -#define DEVICE_DESTRUCTOR \ - end_using_device (mach_device_t) -#define DEVICE_IMPORTS \ - import "libmachdev/mig-decls.h"; diff --git a/libmachdev/misc.c b/libmachdev/misc.c deleted file mode 100644 index 977159bd3..000000000 --- a/libmachdev/misc.c +++ /dev/null @@ -1,50 +0,0 @@ -#include -#include - -#include - -#include "linux-errno.h" - -int -linux_to_mach_error (int err) -{ - switch (err) - { - case 0: - return D_SUCCESS; - - case -EPERM: - return D_INVALID_OPERATION; - - case -EIO: - return D_IO_ERROR; - - case -ENXIO: - return D_NO_SUCH_DEVICE; - - case -EACCES: - return D_INVALID_OPERATION; - - case -EFAULT: - return D_INVALID_SIZE; - - case -EBUSY: - return D_ALREADY_OPEN; - - case -EINVAL: - return D_INVALID_SIZE; - - case -EROFS: - return D_READ_ONLY; - - case -EWOULDBLOCK: - return D_WOULD_BLOCK; - - case -ENOMEM: - return D_NO_MEMORY; - - default: - ddekit_printf ("linux_to_mach_error: unknown code %d\n", err); - return D_IO_ERROR; - } -} diff --git a/libmachdev/net.c b/libmachdev/net.c deleted file mode 100644 index 220121aac..000000000 --- a/libmachdev/net.c +++ /dev/null @@ -1,662 +0,0 @@ -/* - * Linux network driver support. - * - * Copyright (C) 1996 The University of Utah and the Computer Systems - * Laboratory at the University of Utah (CSL) - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. - * - * Author: Shantanu Goel, University of Utah CSL - */ - -/* - * INET An implementation of the TCP/IP protocol suite for the LINUX - * operating system. INET is implemented using the BSD Socket - * interface as the means of communication with the user level. - * - * Ethernet-type device handling. - * - * Version: @(#)eth.c 1.0.7 05/25/93 - * - * Authors: Ross Biro, - * Fred N. van Kempen, - * Mark Evans, - * Florian La Roche, - * Alan Cox, - * - * Fixes: - * Mr Linux : Arp problems - * Alan Cox : Generic queue tidyup (very tiny here) - * Alan Cox : eth_header ntohs should be htons - * Alan Cox : eth_rebuild_header missing an htons and - * minor other things. - * Tegge : Arp bug fixes. - * Florian : Removed many unnecessary functions, code cleanup - * and changes for new arp and skbuff. - * Alan Cox : Redid header building to reflect new format. - * Alan Cox : ARP only when compiled with CONFIG_INET - * Greg Page : 802.2 and SNAP stuff. - * Alan Cox : MAC layer pointers/new format. - * Paul Gortmaker : eth_copy_and_sum shouldn't csum padding. - * Alan Cox : Protect against forwarding explosions with - * older network drivers and IFF_ALLMULTI - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version - * 2 of the License, or (at your option) any later version. - */ -#include -#include -#include -#include - -#include "mach_U.h" - -#include -#include - -#define MACH_INCLUDE - -#include "ds_routines.h" -#include "vm_param.h" -#include "device_reply_U.h" -#include "dev_hdr.h" -#include "if_ether.h" -#include "util.h" -#include "mach_glue.h" -#include "if_hdr.h" - -#define ether_header ethhdr - -/* One of these is associated with each instance of a device. */ -struct net_data -{ - struct port_info port; /* device port */ - struct emul_device device; /* generic device structure */ - struct ifnet ifnet; /* Mach ifnet structure (needed for filters) */ - struct net_device *dev; /* Linux network device structure */ - struct net_data *next; -}; - -struct skb_reply -{ - mach_port_t reply; - mach_msg_type_name_t reply_type; - int pkglen; -}; - -static struct net_data *nd_head; - -/* Forward declarations. */ - -extern struct device_emulation_ops linux_net_emulation_ops; - -static mach_msg_type_t header_type = -{ - MACH_MSG_TYPE_BYTE, - 8, - NET_HDW_HDR_MAX, - TRUE, - FALSE, - FALSE, - 0 -}; - -static mach_msg_type_t packet_type = -{ - MACH_MSG_TYPE_BYTE, /* name */ - 8, /* size */ - 0, /* number */ - TRUE, /* inline */ - FALSE, /* longform */ - FALSE /* deallocate */ -}; - -static struct net_data *search_nd (struct net_device *dev) -{ - struct net_data *nd = nd_head; - - //TODO protected by locks. - while (nd) - { - if (nd->dev == dev) - return nd; - nd = nd->next; - } - return NULL; -} - -/* Linux kernel network support routines. */ - -/* actions before freeing the sk_buff SKB. - * If it returns 1, the packet will be deallocated later. */ -static int -pre_kfree_skb (struct sk_buff *skb, void *data) -{ - struct skb_reply *reply = data; - extern void wakeup_io_done_thread (); - - /* Queue sk_buff on done list if there is a - page list attached or we need to send a reply. - Wakeup the iodone thread to process the list. */ - if (reply && MACH_PORT_VALID (reply->reply)) - { - if (MACH_PORT_VALID (reply->reply)) - { - ds_device_write_reply (reply->reply, reply->reply_type, - 0, reply->pkglen); - reply->reply = MACH_PORT_NULL; - } - } - /* deallocate skb_reply before freeing the packet. */ - free (data); - return 0; -} - -/* - * Deliver the message to all right pfinet servers that - * connects to the virtual network interface. - */ -int -deliver_msg(struct net_rcv_msg *msg, if_filter_list_t *ifp) -{ - mach_msg_return_t err; - queue_head_t *if_port_list; - net_rcv_port_t infp, nextfp; - - msg->msg_hdr.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0); - /* remember message sizes must be rounded up */ - msg->msg_hdr.msgh_local_port = MACH_PORT_NULL; - msg->msg_hdr.msgh_kind = MACH_MSGH_KIND_NORMAL; - msg->msg_hdr.msgh_id = NET_RCV_MSG_ID; - - if_port_list = &ifp->if_rcv_port_list; - FILTER_ITERATE (if_port_list, infp, nextfp, &infp->input) - { - mach_port_t dest; - net_hash_entry_t entp, *hash_headp; - int ret_count; - - entp = (net_hash_entry_t) 0; - ret_count = bpf_do_filter (infp, - msg->packet + sizeof (struct packet_header), - msg->net_rcv_msg_packet_count, msg->header, - sizeof (struct ethhdr), &hash_headp, &entp); - if (entp == (net_hash_entry_t) 0) - dest = infp->rcv_port; - else - dest = entp->rcv_port; - - if (ret_count) - { - msg->msg_hdr.msgh_remote_port = dest; - err = mach_msg ((mach_msg_header_t *)msg, - MACH_SEND_MSG|MACH_SEND_TIMEOUT, - msg->msg_hdr.msgh_size, 0, MACH_PORT_NULL, - 0, MACH_PORT_NULL); - if (err != MACH_MSG_SUCCESS) - { - /* TODO: remove from filter */ - } - } - } - FILTER_ITERATE_END - - return 0; -} - -/* Accept packet SKB received on an interface. */ -static void -netif_rx_handle (char *data, int len, struct net_device *dev) -{ - int pack_size; - struct net_rcv_msg net_msg; - struct ether_header *eh; - struct packet_header *ph; - struct net_data *nd; - - nd = search_nd(dev); - assert (nd); - - pack_size = len - sizeof (struct ethhdr); - /* remember message sizes must be rounded up */ - net_msg.msg_hdr.msgh_size = - (((mach_msg_size_t) (sizeof (struct net_rcv_msg) - - sizeof net_msg.sent - + sizeof (struct packet_header) - - NET_RCV_MAX + pack_size)) + 3) & ~3; - - /* Copy packet into message buffer. */ - eh = (struct ether_header *) (net_msg.header); - ph = (struct packet_header *) (net_msg.packet); - memcpy (eh, data, sizeof (struct ether_header)); - /* packet is prefixed with a struct packet_header, - see include/device/net_status.h. */ - memcpy (ph + 1, data + sizeof (struct ether_header), pack_size); - ph->type = eh->h_proto; - ph->length = pack_size + sizeof (struct packet_header); - - net_msg.sent = FALSE; /* Mark packet as received. */ - - net_msg.header_type = header_type; - net_msg.packet_type = packet_type; - net_msg.net_rcv_msg_packet_count = ph->length; - deliver_msg (&net_msg, &nd->ifnet.port_list); -} - -/* Mach device interface routines. */ - -/* Return a send right associated with network device ND. */ -static mach_port_t -dev_to_port (void *nd) -{ - return (nd - ? ports_get_send_right (nd) - : MACH_PORT_NULL); -} - -/* - * Initialize send and receive queues on an interface. - */ -void if_init_queues(ifp) - register struct ifnet *ifp; -{ -// IFQ_INIT(&ifp->if_snd); - queue_init(&ifp->port_list.if_rcv_port_list); - queue_init(&ifp->port_list.if_snd_port_list); - pthread_mutex_init(&ifp->if_rcv_port_list_lock, NULL); - pthread_mutex_init(&ifp->if_snd_port_list_lock, NULL); -} - -static io_return_t -device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type, - dev_mode_t mode, char *name, device_t *devp, - mach_msg_type_name_t *devicePoly) -{ - io_return_t err = D_SUCCESS; - struct net_device *dev; - struct net_data *nd; - struct ifnet *ifp; - - /* Search for the device. */ - dev = search_netdev (name); - if (!dev) - { - fprintf (stderr, "after search_netdev: cannot find %s\n", name); - return D_NO_SUCH_DEVICE; - } - - /* Allocate and initialize device data if this is the first open. */ - nd = search_nd (dev); - if (!nd) - { - char *name; - - err = create_device_port (sizeof (*nd), &nd); - if (err) - { - fprintf (stderr, "after create_device_port: cannot create a port\n"); - goto out; - } - - nd->dev = dev; - nd->device.emul_data = nd; - nd->device.emul_ops = &linux_net_emulation_ops; - nd->next = nd_head; - nd_head = nd; - - ifp = &nd->ifnet; - name = netdev_name (dev); - ifp->if_unit = name[strlen (name) - 1] - '0'; - ifp->if_flags = IFF_UP | IFF_RUNNING; - ifp->if_mtu = netdev_mtu (dev); - ifp->if_header_size = netdev_header_len (dev); - ifp->if_header_format = netdev_type (dev); - ifp->if_address_size = netdev_addr_len (dev); - ifp->if_address = netdev_addr (dev); - if_init_queues (ifp); - - if ((err = dev_open(dev)) < 0) - { - fprintf (stderr, "after dev_open: cannot open the device\n"); - err = linux_to_mach_error (err); - } - - out: - if (err) - { - if (nd) - { - ports_destroy_right (nd); - nd = NULL; - } - } - else - { -#if 0 - /* IPv6 heavily relies on multicasting (especially router and - neighbor solicits and advertisements), so enable reception of - those multicast packets by setting `LINUX_IFF_ALLMULTI'. */ - dev->flags |= LINUX_IFF_UP | LINUX_IFF_RUNNING | LINUX_IFF_ALLMULTI; - skb_queue_head_init (&dev->buffs[0]); - - if (dev->set_multicast_list) - dev->set_multicast_list (dev); -#endif - } - } - - if (nd) - { - *devp = ports_get_right (nd); - *devicePoly = MACH_MSG_TYPE_MAKE_SEND; - } - return err; -} - -static io_return_t -device_write (void *d, mach_port_t reply_port, - mach_msg_type_name_t reply_port_type, dev_mode_t mode, - recnum_t bn, io_buf_ptr_t data, unsigned int count, - int *bytes_written) -{ - struct net_data *nd = d; - struct net_device *dev = nd->dev; - struct skb_reply *skb_reply = malloc (sizeof (*skb_reply)); - error_t err; - - if (skb_reply == NULL) - return D_NO_MEMORY; - - skb_reply->pkglen = count; - skb_reply->reply = reply_port; - skb_reply->reply_type = reply_port_type; - - err = linux_pkg_xmit (data, count, skb_reply, pre_kfree_skb, dev); - vm_deallocate (mach_task_self (), (vm_address_t) data, count); - if (err) - return linux_to_mach_error (err); - - /* Send packet to filters. */ - // TODO should I deliver the packet to other network stacks? -#if 0 - { - struct packet_header *packet; - struct ether_header *header; - ipc_kmsg_t kmsg; - - kmsg = net_kmsg_get (); - - if (kmsg != IKM_NULL) - { - /* Suitable for Ethernet only. */ - header = (struct ether_header *) (net_kmsg (kmsg)->header); - packet = (struct packet_header *) (net_kmsg (kmsg)->packet); - memcpy (header, skb->data, sizeof (struct ether_header)); - - /* packet is prefixed with a struct packet_header, - see include/device/net_status.h. */ - memcpy (packet + 1, skb->data + sizeof (struct ether_header), - skb->len - sizeof (struct ether_header)); - packet->length = skb->len - sizeof (struct ether_header) - + sizeof (struct packet_header); - packet->type = header->ether_type; - net_kmsg (kmsg)->sent = TRUE; /* Mark packet as sent. */ - s = splimp (); - net_packet (&dev->net_data->ifnet, kmsg, packet->length, - ethernet_priority (kmsg)); - splx (s); - } - } -#endif - - return MIG_NO_REPLY; -} - -/* - * Other network operations - */ -static io_return_t -net_getstat(ifp, flavor, status, count) - struct ifnet *ifp; - dev_flavor_t flavor; - dev_status_t status; /* pointer to OUT array */ - natural_t *count; /* OUT */ -{ -#define ETHERMTU 1500 - switch (flavor) { - case NET_STATUS: - { - register struct net_status *ns = (struct net_status *)status; - - if (*count < NET_STATUS_COUNT) - return (D_INVALID_OPERATION); - - ns->min_packet_size = ifp->if_header_size; - ns->max_packet_size = ifp->if_header_size + ifp->if_mtu; - ns->header_format = ifp->if_header_format; - ns->header_size = ifp->if_header_size; - ns->address_size = ifp->if_address_size; - ns->flags = ifp->if_flags; - ns->mapped_size = 0; - - *count = NET_STATUS_COUNT; - break; - } - case NET_ADDRESS: - { - register int addr_byte_count; - register int addr_int_count; - register int i; - - addr_byte_count = ETH_ALEN; - addr_int_count = (addr_byte_count + (sizeof(int)-1)) - / sizeof(int); - - if (*count < addr_int_count) - { - /* XXX debug hack. */ - printf ("net_getstat: count: %d, addr_int_count: %d\n", - *count, addr_int_count); - return (D_INVALID_OPERATION); - } - - memcpy(status, ifp->if_address, addr_byte_count); - if (addr_byte_count < addr_int_count * sizeof(int)) - memset((char *)status + addr_byte_count, 0, - (addr_int_count * sizeof(int) - - addr_byte_count)); - - for (i = 0; i < addr_int_count; i++) { - register int word; - - word = status[i]; - status[i] = htonl(word); - } - *count = addr_int_count; - break; - } - default: - return (D_INVALID_OPERATION); - } - return (D_SUCCESS); -} - -static io_return_t -device_get_status (void *d, dev_flavor_t flavor, dev_status_t status, - mach_msg_type_number_t *count) -{ - struct net_data *net = (struct net_data *) d; - - if (flavor == NET_FLAGS) - { - if (*count != 1) - return D_INVALID_SIZE; - - *(int *) status = netdev_flags (net->dev); - return D_SUCCESS; - } - -#if 0 - if(flavor >= SIOCIWFIRST && flavor <= SIOCIWLAST) - { - /* handle wireless ioctl */ - if(! IW_IS_GET(flavor)) - return D_INVALID_OPERATION; - - if(*count * sizeof(int) < sizeof(struct ifreq)) - return D_INVALID_OPERATION; - - struct net_data *nd = d; - struct linux_device *dev = nd->dev; - - if(! dev->do_ioctl) - return D_INVALID_OPERATION; - - int result; - - if (flavor == SIOCGIWRANGE || flavor == SIOCGIWENCODE - || flavor == SIOCGIWESSID || flavor == SIOCGIWNICKN - || flavor == SIOCGIWSPY) - { - /* - * These ioctls require an `iw_point' as their argument (i.e. - * they want to return some data to userspace. - * Therefore supply some sane values and carry the data back - * to userspace right behind the `struct iwreq'. - */ - struct iw_point *iwp = &((struct iwreq *) status)->u.data; - iwp->length = *count * sizeof (dev_status_t) - sizeof (struct ifreq); - iwp->pointer = (void *) status + sizeof (struct ifreq); - - result = dev->do_ioctl (dev, (struct ifreq *) status, flavor); - - *count = ((sizeof (struct ifreq) + iwp->length) - / sizeof (dev_status_t)); - if (iwp->length % sizeof (dev_status_t)) - (*count) ++; - } - else - { - *count = sizeof(struct ifreq) / sizeof(int); - result = dev->do_ioctl(dev, (struct ifreq *) status, flavor); - } - - return result ? D_IO_ERROR : D_SUCCESS; - } - else -#endif - { - /* common get_status request */ - return net_getstat (&net->ifnet, flavor, status, count); - } -} - -static io_return_t -device_set_status(void *d, dev_flavor_t flavor, dev_status_t status, - mach_msg_type_number_t count) -{ - if (flavor == NET_FLAGS) - { - if (count != 1) - return D_INVALID_SIZE; - - int flags = *(int *) status; - struct net_data *net = (struct net_data *) d; - - dev_change_flags (net->dev, flags); - - return D_SUCCESS; - } - return D_INVALID_OPERATION; - -#if 0 - if(flavor < SIOCIWFIRST || flavor > SIOCIWLAST) - return D_INVALID_OPERATION; - - if(! IW_IS_SET(flavor)) - return D_INVALID_OPERATION; - - if(count * sizeof(int) < sizeof(struct ifreq)) - return D_INVALID_OPERATION; - - struct net_data *nd = d; - struct linux_device *dev = nd->dev; - - if(! dev->do_ioctl) - return D_INVALID_OPERATION; - - if((flavor == SIOCSIWENCODE || flavor == SIOCSIWESSID - || flavor == SIOCSIWNICKN || flavor == SIOCSIWSPY) - && ((struct iwreq *) status)->u.data.pointer) - { - struct iw_point *iwp = &((struct iwreq *) status)->u.data; - - /* safety check whether the status array is long enough ... */ - if(count * sizeof(int) < sizeof(struct ifreq) + iwp->length) - return D_INVALID_OPERATION; - - /* make sure, iwp->pointer points to the correct address */ - if(iwp->pointer) iwp->pointer = (void *) status + sizeof(struct ifreq); - } - - int result = dev->do_ioctl(dev, (struct ifreq *) status, flavor); - return result ? D_IO_ERROR : D_SUCCESS; -#endif -} - - -static io_return_t -device_set_filter (void *d, mach_port_t port, int priority, - filter_t * filter, unsigned filter_count) -{ - return net_set_filter (&((struct net_data *) d)->ifnet.port_list, - port, priority, filter, filter_count); -} - -/* Do any initialization required for network devices. */ -static void linux_net_emulation_init () -{ - skb_done_head_init(); - l4dde26_register_rx_callback(netif_rx_handle); -} - -struct device_emulation_ops linux_net_emulation_ops = -{ - linux_net_emulation_init, - NULL, - NULL, - dev_to_port, - device_open, - NULL, - device_write, - NULL, - NULL, - NULL, - device_set_status, - device_get_status, - device_set_filter, - NULL, - NULL, - NULL, - NULL -}; - -void register_net() -{ - extern void reg_dev_emul (struct device_emulation_ops *ops); - reg_dev_emul (&linux_net_emulation_ops); -} diff --git a/libmachdev/queue.c b/libmachdev/queue.c deleted file mode 100644 index a43a21b0e..000000000 --- a/libmachdev/queue.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon - * the rights to redistribute these changes. - */ -/* - * Routines to implement queue package. - */ - -#include "queue.h" - - - -/* - * Insert element at head of queue. - */ -void enqueue_head( - register queue_t que, - register queue_entry_t elt) -{ - elt->next = que->next; - elt->prev = que; - elt->next->prev = elt; - que->next = elt; -} - -/* - * Insert element at tail of queue. - */ -void enqueue_tail( - register queue_t que, - register queue_entry_t elt) -{ - elt->next = que; - elt->prev = que->prev; - elt->prev->next = elt; - que->prev = elt; -} - -/* - * Remove and return element at head of queue. - */ -queue_entry_t dequeue_head( - register queue_t que) -{ - register queue_entry_t elt; - - if (que->next == que) - return((queue_entry_t)0); - - elt = que->next; - elt->next->prev = que; - que->next = elt->next; - return(elt); -} - -/* - * Remove and return element at tail of queue. - */ -queue_entry_t dequeue_tail( - register queue_t que) -{ - register queue_entry_t elt; - - if (que->prev == que) - return((queue_entry_t)0); - - elt = que->prev; - elt->prev->next = que; - que->prev = elt->prev; - return(elt); -} - -/* - * Remove arbitrary element from queue. - * Does not check whether element is on queue - the world - * will go haywire if it isn't. - */ - -/*ARGSUSED*/ -void remqueue( - queue_t que, - register queue_entry_t elt) -{ - elt->next->prev = elt->prev; - elt->prev->next = elt->next; -} - -/* - * Routines to directly imitate the VAX hardware queue - * package. - */ -void insque( - register struct queue_entry *entry, - register struct queue_entry *pred) -{ - entry->next = pred->next; - entry->prev = pred; - (pred->next)->prev = entry; - pred->next = entry; -} - -struct queue_entry -*remque( - register struct queue_entry *elt) -{ - (elt->next)->prev = elt->prev; - (elt->prev)->next = elt->next; - return(elt); -} - diff --git a/libmachdev/queue.h b/libmachdev/queue.h deleted file mode 100644 index 86ef74dc6..000000000 --- a/libmachdev/queue.h +++ /dev/null @@ -1,370 +0,0 @@ -/* - * Mach Operating System - * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University - * All Rights Reserved. - * - * Permission to use, copy, modify and distribute this software and its - * documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR - * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie Mellon rights - * to redistribute these changes. - */ -/* - * File: queue.h - * Author: Avadis Tevanian, Jr. - * Date: 1985 - * - * Type definitions for generic queues. - * - */ - -#ifndef _KERN_QUEUE_H_ -#define _KERN_QUEUE_H_ - -#include - -/* - * Queue of abstract objects. Queue is maintained - * within that object. - * - * Supports fast removal from within the queue. - * - * How to declare a queue of elements of type "foo_t": - * In the "*foo_t" type, you must have a field of - * type "queue_chain_t" to hold together this queue. - * There may be more than one chain through a - * "foo_t", for use by different queues. - * - * Declare the queue as a "queue_t" type. - * - * Elements of the queue (of type "foo_t", that is) - * are referred to by reference, and cast to type - * "queue_entry_t" within this module. - */ - -/* - * A generic doubly-linked list (queue). - */ - -struct queue_entry { - struct queue_entry *next; /* next element */ - struct queue_entry *prev; /* previous element */ -}; - -typedef struct queue_entry *queue_t; -typedef struct queue_entry queue_head_t; -typedef struct queue_entry queue_chain_t; -typedef struct queue_entry *queue_entry_t; - -/* - * enqueue puts "elt" on the "queue". - * dequeue returns the first element in the "queue". - * remqueue removes the specified "elt" from the specified "queue". - */ - -#define enqueue(queue,elt) enqueue_tail(queue, elt) -#define dequeue(queue) dequeue_head(queue) - -void enqueue_head(queue_t, queue_entry_t); -void enqueue_tail(queue_t, queue_entry_t); -queue_entry_t dequeue_head(queue_t); -queue_entry_t dequeue_tail(queue_t); -void remqueue(queue_t, queue_entry_t); -void insque(queue_entry_t, queue_entry_t); - -/* - * Macro: queue_init - * Function: - * Initialize the given queue. - * Header: - * void queue_init(q) - * queue_t q; *MODIFIED* - */ -#define queue_init(q) ((q)->next = (q)->prev = q) - -/* - * Macro: queue_first - * Function: - * Returns the first entry in the queue, - * Header: - * queue_entry_t queue_first(q) - * queue_t q; *IN* - */ -#define queue_first(q) ((q)->next) - -/* - * Macro: queue_next - * Function: - * Returns the entry after an item in the queue. - * Header: - * queue_entry_t queue_next(qc) - * queue_t qc; - */ -#define queue_next(qc) ((qc)->next) - -/* - * Macro: queue_last - * Function: - * Returns the last entry in the queue. - * Header: - * queue_entry_t queue_last(q) - * queue_t q; *IN* - */ -#define queue_last(q) ((q)->prev) - -/* - * Macro: queue_prev - * Function: - * Returns the entry before an item in the queue. - * Header: - * queue_entry_t queue_prev(qc) - * queue_t qc; - */ -#define queue_prev(qc) ((qc)->prev) - -/* - * Macro: queue_end - * Function: - * Tests whether a new entry is really the end of - * the queue. - * Header: - * boolean_t queue_end(q, qe) - * queue_t q; - * queue_entry_t qe; - */ -#define queue_end(q, qe) ((q) == (qe)) - -/* - * Macro: queue_empty - * Function: - * Tests whether a queue is empty. - * Header: - * boolean_t queue_empty(q) - * queue_t q; - */ -#define queue_empty(q) queue_end((q), queue_first(q)) - - -/*----------------------------------------------------------------*/ -/* - * Macros that operate on generic structures. The queue - * chain may be at any location within the structure, and there - * may be more than one chain. - */ - -/* - * Macro: queue_enter - * Function: - * Insert a new element at the tail of the queue. - * Header: - * void queue_enter(q, elt, type, field) - * queue_t q; - * elt; - * is what's in our queue - * is the chain field in (*) - */ -#define queue_enter(head, elt, type, field) \ -{ \ - register queue_entry_t prev; \ - \ - prev = (head)->prev; \ - if ((head) == prev) { \ - (head)->next = (queue_entry_t) (elt); \ - } \ - else { \ - ((type)prev)->field.next = (queue_entry_t)(elt);\ - } \ - (elt)->field.prev = prev; \ - (elt)->field.next = head; \ - (head)->prev = (queue_entry_t) elt; \ -} - -/* - * Macro: queue_enter_first - * Function: - * Insert a new element at the head of the queue. - * Header: - * void queue_enter_first(q, elt, type, field) - * queue_t q; - * elt; - * is what's in our queue - * is the chain field in (*) - */ -#define queue_enter_first(head, elt, type, field) \ -{ \ - register queue_entry_t next; \ - \ - next = (head)->next; \ - if ((head) == next) { \ - (head)->prev = (queue_entry_t) (elt); \ - } \ - else { \ - ((type)next)->field.prev = (queue_entry_t)(elt);\ - } \ - (elt)->field.next = next; \ - (elt)->field.prev = head; \ - (head)->next = (queue_entry_t) elt; \ -} - -/* - * Macro: queue_field [internal use only] - * Function: - * Find the queue_chain_t (or queue_t) for the - * given element (thing) in the given queue (head) - */ -#define queue_field(head, thing, type, field) \ - (((head) == (thing)) ? (head) : &((type)(thing))->field) - -/* - * Macro: queue_remove - * Function: - * Remove an arbitrary item from the queue. - * Header: - * void queue_remove(q, qe, type, field) - * arguments as in queue_enter - */ -#define queue_remove(head, elt, type, field) \ -{ \ - register queue_entry_t next, prev; \ - \ - next = (elt)->field.next; \ - prev = (elt)->field.prev; \ - \ - if ((head) == next) \ - (head)->prev = prev; \ - else \ - ((type)next)->field.prev = prev; \ - \ - if ((head) == prev) \ - (head)->next = next; \ - else \ - ((type)prev)->field.next = next; \ -} - -/* - * Macro: queue_remove_first - * Function: - * Remove and return the entry at the head of - * the queue. - * Header: - * queue_remove_first(head, entry, type, field) - * entry is returned by reference - */ -#define queue_remove_first(head, entry, type, field) \ -{ \ - register queue_entry_t next; \ - \ - (entry) = (type) ((head)->next); \ - next = (entry)->field.next; \ - \ - if ((head) == next) \ - (head)->prev = (head); \ - else \ - ((type)(next))->field.prev = (head); \ - (head)->next = next; \ -} - -/* - * Macro: queue_remove_last - * Function: - * Remove and return the entry at the tail of - * the queue. - * Header: - * queue_remove_last(head, entry, type, field) - * entry is returned by reference - */ -#define queue_remove_last(head, entry, type, field) \ -{ \ - register queue_entry_t prev; \ - \ - (entry) = (type) ((head)->prev); \ - prev = (entry)->field.prev; \ - \ - if ((head) == prev) \ - (head)->next = (head); \ - else \ - ((type)(prev))->field.next = (head); \ - (head)->prev = prev; \ -} - -/* - * Macro: queue_assign - */ -#define queue_assign(to, from, type, field) \ -{ \ - ((type)((from)->prev))->field.next = (to); \ - ((type)((from)->next))->field.prev = (to); \ - *to = *from; \ -} - -/* - * Macro: queue_iterate - * Function: - * iterate over each item in the queue. - * Generates a 'for' loop, setting elt to - * each item in turn (by reference). - * Header: - * queue_iterate(q, elt, type, field) - * queue_t q; - * elt; - * is what's in our queue - * is the chain field in (*) - */ -#define queue_iterate(head, elt, type, field) \ - for ((elt) = (type) queue_first(head); \ - !queue_end((head), (queue_entry_t)(elt)); \ - (elt) = (type) queue_next(&(elt)->field)) - - - -/*----------------------------------------------------------------*/ -/* - * Define macros for queues with locks. - */ -struct mpqueue_head { - struct queue_entry head; /* header for queue */ - pthread_mutex_t lock; /* lock for queue */ -}; - -typedef struct mpqueue_head mpqueue_head_t; - -#define round_mpq(size) (size) - -#define mpqueue_init(q) \ - { \ - queue_init(&(q)->head); \ - pthread_mutex_init(&(q)->lock, NULL); \ - } - -#define mpenqueue_tail(q, elt) \ - pthread_mutex_lock(&(q)->lock); \ - enqueue_tail(&(q)->head, elt); \ - pthread_mutex_unlock(&(q)->lock); - -#define mpdequeue_head(q, elt) \ - pthread_mutex_lock(&(q)->lock); \ - if (queue_empty(&(q)->head)) \ - *(elt) = 0; \ - else \ - *(elt) = dequeue_head(&(q)->head); \ - pthread_mutex_unlock(&(q)->lock); - -/* - * Old queue stuff, will go away soon. - */ - -#endif /* _KERN_QUEUE_H_ */ diff --git a/libmachdev/trivfs_server.c b/libmachdev/trivfs_server.c deleted file mode 100644 index 3c0578fa0..000000000 --- a/libmachdev/trivfs_server.c +++ /dev/null @@ -1,171 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include - -#include "device_S.h" -#include "notify_S.h" - -static struct port_bucket *port_bucket; - -/* Trivfs hooks. */ -int trivfs_fstype = FSTYPE_MISC; -int trivfs_fsid = 0; -int trivfs_support_read = 0; -int trivfs_support_write = 0; -int trivfs_support_exec = 0; -int trivfs_allow_open = O_READ | O_WRITE; - -/* Our port classes. */ -struct port_class *trivfs_protid_class; -struct port_class *trivfs_cntl_class; - -/* Implementation of notify interface */ -kern_return_t -do_mach_notify_port_deleted (struct port_info *pi, - mach_port_t name) -{ - return EOPNOTSUPP; -} - -kern_return_t -do_mach_notify_msg_accepted (struct port_info *pi, - mach_port_t name) -{ - return EOPNOTSUPP; -} - -kern_return_t -do_mach_notify_port_destroyed (struct port_info *pi, - mach_port_t port) -{ - return EOPNOTSUPP; -} - -kern_return_t -do_mach_notify_no_senders (struct port_info *pi, - mach_port_mscount_t mscount) -{ - return ports_do_mach_notify_no_senders (pi, mscount); -} - -kern_return_t -do_mach_notify_send_once (struct port_info *pi) -{ - return EOPNOTSUPP; -} - -kern_return_t -do_mach_notify_dead_name (struct port_info *pi, - mach_port_t name) -{ - return EOPNOTSUPP; -} - -boolean_t -is_master_device (mach_port_t port) -{ - struct port_info *pi = ports_lookup_port (port_bucket, port, - trivfs_protid_class); - if (pi == NULL) - return FALSE; - - ports_port_deref (pi); - return TRUE; -} - -error_t -trivfs_append_args (struct trivfs_control *fsys, char **argz, size_t *argz_len) -{ - error_t err = 0; - -#define ADD_OPT(fmt, args...) \ - do { char buf[100]; \ - if (! err) { \ - snprintf (buf, sizeof buf, fmt , ##args); \ - err = argz_add (argz, argz_len, buf); } } while (0) - -#undef ADD_OPT - return err; -} - -int trivfs_init() -{ - port_bucket = ports_create_bucket (); - trivfs_cntl_class = ports_create_class (trivfs_clean_cntl, 0); - trivfs_protid_class = ports_create_class (trivfs_clean_protid, 0); - return 0; -} - -error_t -trivfs_goaway (struct trivfs_control *fsys, int flags) -{ - int count; - - /* Stop new requests. */ - ports_inhibit_class_rpcs (trivfs_cntl_class); - ports_inhibit_class_rpcs (trivfs_protid_class); - - count = ports_count_class (trivfs_protid_class); - - if (count && !(flags & FSYS_GOAWAY_FORCE)) - { - /* We won't go away, so start things going again... */ - ports_enable_class (trivfs_protid_class); - ports_resume_class_rpcs (trivfs_cntl_class); - ports_resume_class_rpcs (trivfs_protid_class); - return EBUSY; - } - - pci_system_cleanup (); - exit (0); -} - -static int -demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp) -{ - mig_routine_t routine; - if ((routine = device_server_routine (inp)) || - (routine = notify_server_routine (inp)) || - (routine = NULL, trivfs_demuxer (inp, outp))) - { - if (routine) - (*routine) (inp, outp); - return TRUE; - } - else - return FALSE; -} - -void -trivfs_modify_stat (struct trivfs_protid *cred, io_statbuf_t *stat) -{ -} - -void trivfs_server() -{ - mach_port_t bootstrap; - struct trivfs_control *fsys; - int err; - - task_get_bootstrap_port (mach_task_self (), &bootstrap); - if (bootstrap == MACH_PORT_NULL) - error (1, 0, "must be started as a translator"); - - /* Reply to our parent. */ - err = trivfs_startup (bootstrap, 0, - trivfs_cntl_class, port_bucket, - trivfs_protid_class, port_bucket, &fsys); - mach_port_deallocate (mach_task_self (), bootstrap); - if (err) - error (1, err, "Contacting parent"); - - /* Launch. */ - do - { - ports_manage_port_operations_one_thread (port_bucket, demuxer, 0); - } while (trivfs_goaway (fsys, 0)); -} diff --git a/libmachdev/util.h b/libmachdev/util.h deleted file mode 100644 index 1c62b0d6c..000000000 --- a/libmachdev/util.h +++ /dev/null @@ -1,35 +0,0 @@ -#ifndef __UTIL_H__ -#define __UTIL_H__ - -#include - -#define panic(format, ...) do \ -{ \ - char buf[1024]; \ - snprintf (buf, 1024, "devnode: %s", format); \ - fprintf (stderr , buf, ## __VA_ARGS__); \ - fflush (stderr); \ - abort (); \ -} while (0) - -#define DEBUG - -#ifdef DEBUG - -#define debug(format, ...) do \ -{ \ - char buf[1024]; \ - snprintf (buf, 1024, "pcnet32: %s: %s\n", __func__, format); \ - fprintf (stderr , buf, ## __VA_ARGS__); \ - fflush (stderr); \ -} while (0) - -#else - -#define debug(format, ...) do {} while (0) - -#endif - -int linux_to_mach_error (int err); - -#endif diff --git a/libmachdev/vm_param.h b/libmachdev/vm_param.h deleted file mode 100644 index 7b615c8a0..000000000 --- a/libmachdev/vm_param.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef __VM_PARAM_H__ -#define __VM_PARAM_H__ - -#define PAGE_SIZE __vm_page_size -#define PAGE_MASK (PAGE_SIZE-1) - -#endif diff --git a/libmachdevdde/Makefile b/libmachdevdde/Makefile new file mode 100644 index 000000000..1ce7d163a --- /dev/null +++ b/libmachdevdde/Makefile @@ -0,0 +1,35 @@ +# Copyright (C) 2009 Free Software Foundation, Inc. +# This file is part of the GNU Hurd. +# +# The GNU Hurd is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2, or (at your option) +# any later version. +# +# The GNU Hurd is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with the GNU Hurd; see the file COPYING. If not, write to +# the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + +dir := libmachdevdde +makemode := library +libname = libmachdevdde + +SRCS = deviceUser.c machUser.c net.c ds_routines.c queue.c trivfs_server.c \ + device_replyUser.c deviceServer.c notifyServer.c misc.c +#block.c +LCLHDRS = dev_hdr.h device_emul.h ds_routines.h vm_param.h \ + util.h queue.h io_req.h if_ether.h machdev.h linux-errno.h \ + errno-base.h +installhdrs = machdev.h +HURDLIBS = ports trivfs bpf ddekit +LDLIBS += -lpthread +OBJS = $(SRCS:.c=.o) $(MIGSTUBS) +MIGSFLAGS = -imacros $(srcdir)/mig-mutate.h +device-MIGSFLAGS="-DMACH_PAYLOAD_TO_PORT=ports_payload_get_name" + +include ../Makeconf diff --git a/libmachdevdde/block.c b/libmachdevdde/block.c new file mode 100644 index 000000000..799620726 --- /dev/null +++ b/libmachdevdde/block.c @@ -0,0 +1,314 @@ +/* + * Linux block driver support. + * + * Copyright (C) 1996 The University of Utah and the Computer Systems + * Laboratory at the University of Utah (CSL) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Shantanu Goel, University of Utah CSL + */ + +#include +#include +#include +#include + +#include "mach_U.h" + +#include +#include + +#define MACH_INCLUDE + +#include + +#include "ds_routines.h" +#include "vm_param.h" +#include "device_reply_U.h" +#include "dev_hdr.h" +#include "util.h" +#include "mach_glue.h" + +/* for submit_bio(). But it might not be very proper to keep + * my own definitions of these macros. */ +#define READ 0 +#define WRITE 1 + +/* One of these is associated with each open instance of a device. */ +struct block_data +{ + struct port_info port; /* device port */ + struct emul_device device; /* generic device structure */ + dev_mode_t mode; + struct block_device *dev; +}; + +/* Return a send right associated with network device ND. */ +static mach_port_t +dev_to_port (void *nd) +{ + return (nd + ? ports_get_send_right (nd) + : MACH_PORT_NULL); +} + +static struct device_emulation_ops linux_block_emulation_ops; + +#define DISK_NAME_LEN 32 + +/* Parse the device NAME. + Set *SLICE to be the DOS partition and + *PART the BSD/Mach partition, if any. */ +static char * +translate_name (char *name, int *slice, int *part) +{ + char *p, *q, *end; + char *ret; + int disk_num; + + /* Parse name into name, unit, DOS partition (slice) and partition. */ + for (*slice = 0, *part = -1, p = name; isalpha (*p); p++) + ; + if (p == name || ! isdigit (*p)) + return NULL; + end = p; + disk_num = strtol (p, &p, 0); + if (disk_num < 0 || disk_num > 26) + return NULL; +// do +// p++; +// while (isdigit (*p)); + if (*p) + { + q = p; + if (*q == 's' && isdigit (*(q + 1))) + { + q++; + do + *slice = *slice * 10 + *q++ - '0'; + while (isdigit (*q)); + if (! *q) + goto find_major; + } + if (! isalpha (*q) || *(q + 1)) + return NULL; + *part = *q - 'a'; + } + +find_major: + ret = malloc (DISK_NAME_LEN); + sprintf (ret, "hd%c", 'a' + disk_num); + return ret; +} + +static io_return_t +device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type, + dev_mode_t mode, char *name, device_t *devp, + mach_msg_type_name_t *devicePoly) +{ + io_return_t err = D_SUCCESS; + struct block_data *bd = NULL; + int slice, part; + char *dev_name = NULL; + int dev_err; + + // TODO I need to check whether the device has been opened before. + // if it has been opened with the same `flag', return the same port, + // otherwise, return a different port. + // I need to have a reference to count the number of open. + dev_name = translate_name (name, &slice, &part); + if (dev_name == NULL) + return D_NO_SUCH_DEVICE; + + err = create_device_port (sizeof (*bd), &bd); + if (err) + { + ddekit_printf ("after create_device_port: cannot create a port\n"); + goto out; + } + bd->dev = open_block_dev (dev_name, slice, mode); + dev_err = (int) bd->dev; + if (dev_err < 0) + { + ddekit_printf ("open_block_dev %s fails with %d\n", dev_name, bd->dev); + err = linux_to_mach_error (dev_err); + goto out; + } + bd->device.emul_data = bd; + bd->device.emul_ops = &linux_block_emulation_ops; + bd->mode = mode; + +out: + free (dev_name); + if (err) + { + if (bd) + { + ports_destroy_right (bd); + bd = NULL; + } + } + else + { + *devp = ports_get_send_right (bd); + ports_port_deref (bd); + *devicePoly = MACH_MSG_TYPE_MOVE_SEND; + } + return err; +} + +static io_return_t +device_write (void *d, mach_port_t reply_port, + mach_msg_type_name_t reply_port_type, dev_mode_t mode, + recnum_t bn, io_buf_ptr_t data, unsigned int count, + int *bytes_written) +{ + struct block_data *bd = d; + /* the number of pages that contain DATA. */ + int npages = (((int) data + count) - ((int) data & ~PAGE_MASK) + + PAGE_MASK) / PAGE_SIZE; + io_return_t err = D_SUCCESS; + int i; + int writes = 0; + + void write_done (int err) + { + int len = err ? 0 : count; + // TODO maybe I should send the reply as long as there is an error. + writes--; + if (writes == 0) + { + err = linux_to_mach_error (err); + ds_device_write_reply (reply_port, reply_port_type, err, len); + } + } + + /* the data is at the beginning of a page. */ + if ((int) data & ~PAGE_MASK) + return D_INVALID_OPERATION; + + if ((bd->mode & D_WRITE) == 0) + return D_INVALID_OPERATION; + + for (i = 0; i < npages; i++) + { + int size = PAGE_SIZE - ((int) data &~PAGE_MASK) > count ? + count : PAGE_SIZE - ((int) data &~PAGE_MASK); + + err = block_dev_rw (bd->dev, bn, data, size, WRITE, write_done); + if (err) + break; + bn += size >> 9; + data += size; + count -= size; + writes++; + } + if (writes) + return MIG_NO_REPLY; + return linux_to_mach_error (err); +} + +static io_return_t +device_read (void *d, mach_port_t reply_port, + mach_msg_type_name_t reply_port_type, dev_mode_t mode, + recnum_t bn, int count, io_buf_ptr_t *data, + unsigned *bytes_read) +{ + struct block_data *bd = d; + io_return_t err = D_SUCCESS; + int i; + int reads = 0; + char *buf; + int npages = (count + PAGE_SIZE - 1) / PAGE_SIZE; + int rest = count; + + void read_done (int err) + { + int len = err ? 0 : count; + reads--; + if (reads == 0) + { + err = linux_to_mach_error (err); + ds_device_read_reply (reply_port, reply_port_type, err, buf, len); + } + } + + if ((bd->mode & D_READ) == 0) + return D_INVALID_OPERATION; + + if (count == 0) + return 0; + + *data = 0; + buf = mmap (NULL, npages * PAGE_SIZE, PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, 0, 0); + if (buf == MAP_FAILED) + return errno; + + ddekit_printf ("read %d pages.\n", npages); + for (i = 0; i < npages; i++) + { + int size = rest > PAGE_SIZE ? PAGE_SIZE : rest; + ddekit_printf ("read %d bytes starting from %d\n", size, bn); + + err = block_dev_rw (bd->dev, bn, buf + i * PAGE_SIZE, + size, READ, read_done); + if (err) + break; + bn += size >> 9; + rest -= size; + reads++; + } + // TODO when should I deallocate the buffer? + if (reads) + return MIG_NO_REPLY; + return linux_to_mach_error (err); +} + +static io_return_t +device_get_status (void *d, dev_flavor_t flavor, dev_status_t status, + mach_msg_type_number_t *count) +{ + struct block_data *bd = (struct block_data *) d; + return D_SUCCESS; +} + +static struct device_emulation_ops linux_block_emulation_ops = +{ + NULL, + NULL, + NULL, + dev_to_port, + device_open, + NULL, + device_write, + NULL, + device_read, + NULL, + NULL, + device_get_status, + NULL, + NULL, + NULL, + NULL, + NULL +}; + +void register_block() +{ + extern void reg_dev_emul (struct device_emulation_ops *ops); + reg_dev_emul (&linux_block_emulation_ops); +} diff --git a/libmachdevdde/dev_hdr.h b/libmachdevdde/dev_hdr.h new file mode 100644 index 000000000..79edc43a3 --- /dev/null +++ b/libmachdevdde/dev_hdr.h @@ -0,0 +1,133 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * Author: David B. Golub, Carnegie Mellon University + * Date: 3/89 + */ + +/* + * Mach device emulation definitions (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 + */ + +#ifndef _DEVICE_DEV_HDR_H_ +#define _DEVICE_DEV_HDR_H_ + +#include +#include +#include +#include + +#include "device_emul.h" + +/* + * Operations list for major device types. + */ +struct dev_ops { + char * d_name; /* name for major device */ + int (*d_open)(); /* open device */ + int (*d_close)(); /* close device */ + int (*d_read)(); /* read */ + int (*d_write)(); /* write */ + int (*d_getstat)(); /* get status/control */ + int (*d_setstat)(); /* set status/control */ + vm_offset_t (*d_mmap)(); /* map memory */ + int (*d_async_in)();/* asynchronous input setup */ + int (*d_reset)(); /* reset device */ + int (*d_port_death)(); + /* clean up reply ports */ + int d_subdev; /* number of sub-devices per + unit */ + int (*d_dev_info)(); /* driver info for kernel */ +}; +typedef struct dev_ops *dev_ops_t; + +/* This structure is associated with each open device port. + * The port representing the device points to this structure. */ +struct emul_device +{ + struct device_emulation_ops *emul_ops; + void *emul_data; +}; + +typedef struct emul_device *emul_device_t; + +#define DEVICE_NULL ((device_t) 0) + +/* + * Generic device header. May be allocated with the device, + * or built when the device is opened. + */ +struct mach_device { + struct port_info port; + struct emul_device dev; /* the real device structure */ +}; +typedef struct mach_device *mach_device_t; +#define MACH_DEVICE_NULL ((mach_device_t)0) + +/* + * To find and remove device entries + */ +mach_device_t device_lookup(char *); /* by name */ + +/* + * To find and remove port-to-device mappings + */ +void dev_port_enter(mach_device_t); +void dev_port_remove(mach_device_t); + +/* + * To call a routine on each device + */ +boolean_t dev_map(boolean_t (*)(), mach_port_t); + +/* + * To lock and unlock state and open-count + */ +#define device_lock(device) pthread_mutex_lock(&(device)->lock) +#define device_unlock(device) pthread_mutex_unlock(&(device)->lock) + +#endif /* _DEVICE_DEV_HDR_H_ */ diff --git a/libmachdevdde/device_emul.h b/libmachdevdde/device_emul.h new file mode 100644 index 000000000..e27799cbd --- /dev/null +++ b/libmachdevdde/device_emul.h @@ -0,0 +1,65 @@ +/* + * Mach device emulation definitions (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 + */ + +#ifndef _I386AT_DEVICE_EMUL_H_ +#define _I386AT_DEVICE_EMUL_H_ + +#include + +/* Each emulation layer provides these operations. */ +struct device_emulation_ops +{ + void (*init) (void); + void (*reference) (void *); + void (*dealloc) (void *); + mach_port_t (*dev_to_port) (void *); + io_return_t (*open) (mach_port_t, mach_msg_type_name_t, + dev_mode_t, char *, device_t *, + mach_msg_type_name_t *type); + io_return_t (*close) (void *); + io_return_t (*write) (void *, mach_port_t, mach_msg_type_name_t, + dev_mode_t, recnum_t, io_buf_ptr_t, unsigned, int *); + io_return_t (*write_inband) (void *, mach_port_t, mach_msg_type_name_t, + dev_mode_t, recnum_t, io_buf_ptr_inband_t, + unsigned, int *); + io_return_t (*read) (void *, mach_port_t, mach_msg_type_name_t, + dev_mode_t, recnum_t, int, io_buf_ptr_t *, unsigned *); + io_return_t (*read_inband) (void *, mach_port_t, mach_msg_type_name_t, + dev_mode_t, recnum_t, int, char *, unsigned *); + io_return_t (*set_status) (void *, dev_flavor_t, dev_status_t, + mach_msg_type_number_t); + io_return_t (*get_status) (void *, dev_flavor_t, dev_status_t, + mach_msg_type_number_t *); + io_return_t (*set_filter) (void *, mach_port_t, int, filter_t [], unsigned); + io_return_t (*map) (void *, vm_prot_t, vm_offset_t, + vm_size_t, mach_port_t *, boolean_t); + void (*no_senders) (mach_no_senders_notification_t *); + io_return_t (*write_trap) (void *, dev_mode_t, + recnum_t, vm_offset_t, vm_size_t); + io_return_t (*writev_trap) (void *, dev_mode_t, + recnum_t, io_buf_vec_t *, vm_size_t); +}; + +#endif /* _I386AT_DEVICE_EMUL_H_ */ diff --git a/libmachdevdde/ds_routines.c b/libmachdevdde/ds_routines.c new file mode 100644 index 000000000..e9fbe9445 --- /dev/null +++ b/libmachdevdde/ds_routines.c @@ -0,0 +1,341 @@ +/* + * Mach Operating System + * Copyright (c) 1993,1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * Author: David B. Golub, Carnegie Mellon University + * Date: 3/89 + */ + +/* + * 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 +#include + +#include + +#include "vm_param.h" +#include "device_S.h" +#include "notify_S.h" +#include "io_req.h" +#include "dev_hdr.h" +#include "util.h" +#include "queue.h" +#include "mach_glue.h" + +struct port_bucket *device_bucket; +struct port_class *dev_class; + +#define NUM_EMULATION num_emul +#define MAX_NUM_EMULATION 32 + +/* List of emulations. */ +static struct device_emulation_ops *emulation_list[MAX_NUM_EMULATION]; +static int num_emul; + +boolean_t is_master_device (mach_port_t port); + +/* + * What follows is the interface for the native Mach devices. + */ + +/* Implementation of device interface */ +io_return_t +ds_device_open (mach_port_t open_port, mach_port_t reply_port, + mach_msg_type_name_t reply_port_type, dev_mode_t mode, + char *name, device_t *devp, mach_msg_type_name_t *devicePoly) +{ + int i; + io_return_t err = D_NO_SUCH_DEVICE; + + /* Open must be called on the master device port. */ + if (!is_master_device (open_port)) + return D_INVALID_OPERATION; + + /* There must be a reply port. */ + if (! MACH_PORT_VALID (reply_port)) + { + fprintf (stderr, "ds_* invalid reply port\n"); + 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, devicePoly); + if (err != D_NO_SUCH_DEVICE) + break; + } + + return err; +} + +io_return_t +ds_device_close (struct mach_device *device) +{ + io_return_t ret; + + if (device == NULL) + return D_NO_SUCH_DEVICE; + + ret = (device->dev.emul_ops->close + ? (*device->dev.emul_ops->close) (device->dev.emul_data) + : D_SUCCESS); + return ret; +} + +io_return_t +ds_device_write (struct mach_device *device, mach_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) +{ + io_return_t ret; + + if (data == 0) + return D_INVALID_SIZE; + + if (device == NULL) + return D_NO_SUCH_DEVICE; + + if (! device->dev.emul_ops->write) + return D_INVALID_OPERATION; + + ret = (*device->dev.emul_ops->write) (device->dev.emul_data, reply_port, + reply_port_type, mode, recnum, + data, count, bytes_written); + return ret; +} + +io_return_t +ds_device_write_inband (struct mach_device *device, mach_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) +{ + io_return_t ret; + + if (data == 0) + return D_INVALID_SIZE; + + if (device == NULL) + return D_NO_SUCH_DEVICE; + + if (! device->dev.emul_ops->write_inband) + return D_INVALID_OPERATION; + + ret = (*device->dev.emul_ops->write_inband) (device->dev.emul_data, + reply_port, reply_port_type, + mode, recnum, + data, count, bytes_written); + return ret; +} + +io_return_t +ds_device_read (struct mach_device *device, mach_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) +{ + io_return_t ret; + + if (device == NULL) + return D_NO_SUCH_DEVICE; + + if (! device->dev.emul_ops->read) + return D_INVALID_OPERATION; + + ret = (*device->dev.emul_ops->read) (device->dev.emul_data, reply_port, + reply_port_type, mode, recnum, + count, data, bytes_read); + return ret; +} + +io_return_t +ds_device_read_inband (struct mach_device *device, mach_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) +{ + io_return_t ret; + + if (device == NULL) + return D_NO_SUCH_DEVICE; + + if (! device->dev.emul_ops->read_inband) + return D_INVALID_OPERATION; + + ret = (*device->dev.emul_ops->read_inband) (device->dev.emul_data, + reply_port, + reply_port_type, mode, recnum, + count, data, bytes_read); + return ret; +} + +io_return_t +ds_device_set_status (struct mach_device *device, dev_flavor_t flavor, + dev_status_t status, mach_msg_type_number_t status_count) +{ + io_return_t ret; + + if (device == NULL) + return D_NO_SUCH_DEVICE; + + if (! device->dev.emul_ops->set_status) + return D_INVALID_OPERATION; + + ret = (*device->dev.emul_ops->set_status) (device->dev.emul_data, flavor, + status, status_count); + return ret; +} + +io_return_t +ds_device_get_status (struct mach_device *device, dev_flavor_t flavor, + dev_status_t status, + mach_msg_type_number_t *status_count) +{ + io_return_t ret; + + if (device == NULL) + return D_NO_SUCH_DEVICE; + + if (! device->dev.emul_ops->get_status) + return D_INVALID_OPERATION; + + ret = (*device->dev.emul_ops->get_status) (device->dev.emul_data, flavor, + status, status_count); + return ret; +} + +io_return_t +ds_device_set_filter (struct mach_device *device, mach_port_t receive_port, + int priority, filter_t *filter, unsigned filter_count) +{ + io_return_t ret; + + if (device == NULL) + return D_NO_SUCH_DEVICE; + + if (! device->dev.emul_ops->set_filter) + return D_INVALID_OPERATION; + + ret = (*device->dev.emul_ops->set_filter) (device->dev.emul_data, + receive_port, + priority, filter, filter_count); + return ret; +} + +io_return_t +ds_device_map (struct mach_device *device, vm_prot_t prot, vm_offset_t offset, + vm_size_t size, mach_port_t *pager, boolean_t unmap) +{ + /* Refuse if device is dead or not completely open. */ + if (device == NULL) + return D_NO_SUCH_DEVICE; + + return D_INVALID_OPERATION; +} + +error_t +create_device_port (size_t size, void *result) +{ + return ports_create_port (dev_class, device_bucket, + size, result); +} + +void mach_device_init() +{ + int i; + + device_bucket = ports_create_bucket (); + dev_class = ports_create_class (0, 0); + + for (i = 0; i < NUM_EMULATION; i++) { + if (emulation_list[i]->init) + emulation_list[i]->init(); + } +} + +static int +demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp) +{ + mig_routine_t routine; + if ((routine = device_server_routine (inp)) || + (routine = notify_server_routine (inp))) + { + (*routine) (inp, outp); + return TRUE; + } + else + return FALSE; +} + +void reg_dev_emul (struct device_emulation_ops *ops) +{ + emulation_list[num_emul++] = ops; +} + +void * ds_server(void *arg) +{ + /* This thread calls Linux functions, + * so I need to make it known to the Linux environment. */ + l4dde26_process_from_ddekit (ddekit_thread_myself ()); + + /* Launch. */ + do + { + ports_manage_port_operations_one_thread (device_bucket, demuxer, 0); + } while (1); + + return NULL; +} diff --git a/libmachdevdde/ds_routines.h b/libmachdevdde/ds_routines.h new file mode 100644 index 000000000..3706aa586 --- /dev/null +++ b/libmachdevdde/ds_routines.h @@ -0,0 +1,57 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * Author: David B. Golub, Carnegie Mellon University + * Date: 8/89 + * + * Device service utility routines. + */ + +#ifndef DS_ROUTINES_H +#define DS_ROUTINES_H + +#include + +#include "io_req.h" + +/* + * Map for device IO memory. + */ +//vm_map_t device_io_map; + +kern_return_t device_read_alloc(io_req_t, vm_size_t); +kern_return_t device_write_get(io_req_t, boolean_t *); +boolean_t device_write_dealloc(io_req_t); + +boolean_t ds_open_done(io_req_t); +boolean_t ds_read_done(io_req_t); +boolean_t ds_write_done(io_req_t); + +void iowait (io_req_t ior); + +error_t create_device_port (size_t size, void *result); + +#endif /* DS_ROUTINES_H */ diff --git a/libmachdevdde/errno-base.h b/libmachdevdde/errno-base.h new file mode 100644 index 000000000..651159785 --- /dev/null +++ b/libmachdevdde/errno-base.h @@ -0,0 +1,39 @@ +#ifndef _ASM_GENERIC_ERRNO_BASE_H +#define _ASM_GENERIC_ERRNO_BASE_H + +#define EPERM 1 /* Operation not permitted */ +#define ENOENT 2 /* No such file or directory */ +#define ESRCH 3 /* No such process */ +#define EINTR 4 /* Interrupted system call */ +#define EIO 5 /* I/O error */ +#define ENXIO 6 /* No such device or address */ +#define E2BIG 7 /* Argument list too long */ +#define ENOEXEC 8 /* Exec format error */ +#define EBADF 9 /* Bad file number */ +#define ECHILD 10 /* No child processes */ +#define EAGAIN 11 /* Try again */ +#define ENOMEM 12 /* Out of memory */ +#define EACCES 13 /* Permission denied */ +#define EFAULT 14 /* Bad address */ +#define ENOTBLK 15 /* Block device required */ +#define EBUSY 16 /* Device or resource busy */ +#define EEXIST 17 /* File exists */ +#define EXDEV 18 /* Cross-device link */ +#define ENODEV 19 /* No such device */ +#define ENOTDIR 20 /* Not a directory */ +#define EISDIR 21 /* Is a directory */ +#define EINVAL 22 /* Invalid argument */ +#define ENFILE 23 /* File table overflow */ +#define EMFILE 24 /* Too many open files */ +#define ENOTTY 25 /* Not a typewriter */ +#define ETXTBSY 26 /* Text file busy */ +#define EFBIG 27 /* File too large */ +#define ENOSPC 28 /* No space left on device */ +#define ESPIPE 29 /* Illegal seek */ +#define EROFS 30 /* Read-only file system */ +#define EMLINK 31 /* Too many links */ +#define EPIPE 32 /* Broken pipe */ +#define EDOM 33 /* Math argument out of domain of func */ +#define ERANGE 34 /* Math result not representable */ + +#endif diff --git a/libmachdevdde/if_ether.h b/libmachdevdde/if_ether.h new file mode 100644 index 000000000..29974674a --- /dev/null +++ b/libmachdevdde/if_ether.h @@ -0,0 +1,87 @@ +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Global definitions for the Ethernet IEEE 802.3 interface. + * + * Version: @(#)if_ether.h 1.0.1a 02/08/94 + * + * Author: Fred N. van Kempen, + * Donald Becker, + * Alan Cox, + * Steve Whitehouse, + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ + +#ifndef _LINUX_IF_ETHER_H +#define _LINUX_IF_ETHER_H + +/* + * IEEE 802.3 Ethernet magic constants. The frame sizes omit the preamble + * and FCS/CRC (frame check sequence). + */ + +#define ETH_ALEN 6 /* Octets in one ethernet addr */ +#define ETH_HLEN 14 /* Total octets in header. */ +#define ETH_ZLEN 60 /* Min. octets in frame sans FCS */ +#define ETH_DATA_LEN 1500 /* Max. octets in payload */ +#define ETH_FRAME_LEN 1514 /* Max. octets in frame sans FCS */ + +/* + * These are the defined Ethernet Protocol ID's. + */ + +#define ETH_P_LOOP 0x0060 /* Ethernet Loopback packet */ +#define ETH_P_ECHO 0x0200 /* Ethernet Echo packet */ +#define ETH_P_PUP 0x0400 /* Xerox PUP packet */ +#define ETH_P_IP 0x0800 /* Internet Protocol packet */ +#define ETH_P_X25 0x0805 /* CCITT X.25 */ +#define ETH_P_ARP 0x0806 /* Address Resolution packet */ +#define ETH_P_BPQ 0x08FF /* G8BPQ AX.25 Ethernet Packet [ NOT AN OFFICIALLY REGISTERED ID ] */ +#define ETH_P_DEC 0x6000 /* DEC Assigned proto */ +#define ETH_P_DNA_DL 0x6001 /* DEC DNA Dump/Load */ +#define ETH_P_DNA_RC 0x6002 /* DEC DNA Remote Console */ +#define ETH_P_DNA_RT 0x6003 /* DEC DNA Routing */ +#define ETH_P_LAT 0x6004 /* DEC LAT */ +#define ETH_P_DIAG 0x6005 /* DEC Diagnostics */ +#define ETH_P_CUST 0x6006 /* DEC Customer use */ +#define ETH_P_SCA 0x6007 /* DEC Systems Comms Arch */ +#define ETH_P_RARP 0x8035 /* Reverse Addr Res packet */ +#define ETH_P_ATALK 0x809B /* Appletalk DDP */ +#define ETH_P_AARP 0x80F3 /* Appletalk AARP */ +#define ETH_P_IPX 0x8137 /* IPX over DIX */ +#define ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ + +/* + * Non DIX types. Won't clash for 1500 types. + */ + +#define ETH_P_802_3 0x0001 /* Dummy type for 802.3 frames */ +#define ETH_P_AX25 0x0002 /* Dummy protocol id for AX.25 */ +#define ETH_P_ALL 0x0003 /* Every packet (be careful!!!) */ +#define ETH_P_802_2 0x0004 /* 802.2 frames */ +#define ETH_P_SNAP 0x0005 /* Internal only */ +#define ETH_P_DDCMP 0x0006 /* DEC DDCMP: Internal only */ +#define ETH_P_WAN_PPP 0x0007 /* Dummy type for WAN PPP frames*/ +#define ETH_P_PPP_MP 0x0008 /* Dummy type for PPP MP frames */ +#define ETH_P_LOCALTALK 0x0009 /* Localtalk pseudo type */ +#define ETH_P_PPPTALK 0x0010 /* Dummy type for Atalk over PPP*/ +#define ETH_P_TR_802_2 0x0011 /* 802.2 frames */ + +/* + * This is an Ethernet frame header. + */ + +struct ethhdr +{ + unsigned char h_dest[ETH_ALEN]; /* destination eth addr */ + unsigned char h_source[ETH_ALEN]; /* source ether addr */ + unsigned short h_proto; /* packet type ID field */ +}; + +#endif /* _LINUX_IF_ETHER_H */ diff --git a/libmachdevdde/if_hdr.h b/libmachdevdde/if_hdr.h new file mode 100644 index 000000000..b20f7e354 --- /dev/null +++ b/libmachdevdde/if_hdr.h @@ -0,0 +1,165 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * Taken from (bsd)net/if.h. Modified for MACH kernel. + */ +/* + * Copyright (c) 1982, 1986 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 4. The name of the Laboratory may not be used to endorse or promote + * products derived from this software without specific prior written + * permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * @(#)if.h 7.3 (Berkeley) 6/27/88 + */ + +#ifndef _IF_HDR_ +#define _IF_HDR_ + +#include +#include +#include + +#if 0 +/* + * Queue for network output and filter input. + */ +struct ifqueue { + queue_head_t ifq_head; /* queue of io_req_t */ + int ifq_len; /* length of queue */ + int ifq_maxlen; /* maximum length of queue */ + int ifq_drops; /* number of packets dropped + because queue full */ + decl_simple_lock_data(, + ifq_lock) /* lock for queue and counters */ +}; +#endif + +/* + * Header for network interface drivers. + */ +struct ifnet { + short if_unit; /* unit number */ + short if_flags; /* up/down, broadcast, etc. */ + short if_timer; /* time until if_watchdog called */ + short if_mtu; /* maximum transmission unit */ + short if_header_size; /* length of header */ + short if_header_format; /* format of hardware header */ + short if_address_size; /* length of hardware address */ + short if_alloc_size; /* size of read buffer to allocate */ + char *if_address; /* pointer to hardware address */ +// struct ifqueue if_snd; /* output queue */ + if_filter_list_t port_list; + pthread_mutex_t if_rcv_port_list_lock;/* lock for input filter list */ + pthread_mutex_t if_snd_port_list_lock;/* lock for output filter list */ +/* statistics */ + int if_ipackets; /* packets received */ + int if_ierrors; /* input errors */ + int if_opackets; /* packets sent */ + int if_oerrors; /* output errors */ + int if_collisions; /* collisions on csma interfaces */ + int if_rcvdrops; /* packets received but dropped */ +}; + +#define IFF_UP 0x0001 /* interface is up */ +#define IFF_BROADCAST 0x0002 /* interface can broadcast */ +#define IFF_DEBUG 0x0004 /* turn on debugging */ +#define IFF_LOOPBACK 0x0008 /* is a loopback net */ +#define IFF_POINTOPOINT 0x0010 /* point-to-point link */ +#define IFF_RUNNING 0x0040 /* resources allocated */ +#define IFF_NOARP 0x0080 /* no address resolution protocol */ +#define IFF_PROMISC 0x0100 /* receive all packets */ +#define IFF_ALLMULTI 0x0200 /* receive all multicast packets */ +#define IFF_BRIDGE 0x0100 /* support token ring routing field */ +#define IFF_SNAP 0x0200 /* support extended sap header */ + +/* internal flags only: */ +#define IFF_CANTCHANGE (IFF_BROADCAST | IFF_POINTOPOINT | IFF_RUNNING) + +/* + * Output queues (ifp->if_snd) + * have queues of messages stored on ifqueue structures. Entries + * are added to and deleted from these structures by these macros, which + * should be called with ipl raised to splimp(). + * XXX locking XXX + */ + +#define IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen) +#define IF_DROP(ifq) ((ifq)->ifq_drops++) +#define IF_ENQUEUE(ifq, ior) { \ + simple_lock(&(ifq)->ifq_lock); \ + enqueue_tail(&(ifq)->ifq_head, (queue_entry_t)ior); \ + (ifq)->ifq_len++; \ + simple_unlock(&(ifq)->ifq_lock); \ +} +#define IF_PREPEND(ifq, ior) { \ + simple_lock(&(ifq)->ifq_lock); \ + enqueue_head(&(ifq)->ifq_head, (queue_entry_t)ior); \ + (ifq)->ifq_len++; \ + simple_unlock(&(ifq)->ifq_lock); \ +} + +#define IF_DEQUEUE(ifq, ior) { \ + simple_lock(&(ifq)->ifq_lock); \ + if (((ior) = (io_req_t)dequeue_head(&(ifq)->ifq_head)) != 0) \ + (ifq)->ifq_len--; \ + simple_unlock(&(ifq)->ifq_lock); \ +} + +#define IFQ_MAXLEN 50 + +#define IFQ_INIT(ifq) { \ + queue_init(&(ifq)->ifq_head); \ + simple_lock_init(&(ifq)->ifq_lock); \ + (ifq)->ifq_len = 0; \ + (ifq)->ifq_maxlen = IFQ_MAXLEN; \ + (ifq)->ifq_drops = 0; \ +} + +#define IFNET_SLOWHZ 1 /* granularity is 1 second */ + +#endif /* _IF_HDR_ */ diff --git a/libmachdevdde/io_req.h b/libmachdevdde/io_req.h new file mode 100644 index 000000000..9c810542d --- /dev/null +++ b/libmachdevdde/io_req.h @@ -0,0 +1,135 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * Author: David B. Golub, Carnegie Mellon University + * Date: 10/88 + */ + +#ifndef _IO_REQ_ +#define _IO_REQ_ + +#include +#include + +#include "dev_hdr.h" + +/* + * IO request element, queued on device for delayed replies. + */ +typedef struct io_req *io_req_t; +struct io_req { + struct io_req * io_next; /* next, ... */ + struct io_req * io_prev; /* prev pointers: link in done, + defered, or in-progress list */ + mach_device_t io_device; /* pointer to open-device structure */ + char * io_dev_ptr; /* pointer to driver structure - + filled in by driver if necessary */ + int io_unit; /* unit number ('minor') of device */ + int io_op; /* IO operation */ + dev_mode_t io_mode; /* operation mode (wait, truncate) */ + recnum_t io_recnum; /* starting record number for + random-access devices */ + + union io_un { + io_buf_ptr_t data; /* data, for IO requests */ + } io_un; +#define io_data io_un.data + + long io_count; /* amount requested */ + long io_alloc_size; /* amount allocated */ + long io_residual; /* amount NOT done */ + io_return_t io_error; /* error code */ + /* call when done - returns TRUE if IO really finished */ + boolean_t (*io_done)(io_req_t); + mach_port_t io_reply_port; /* reply port, for asynchronous + messages */ + mach_msg_type_name_t io_reply_port_type; + /* send or send-once right? */ + struct io_req * io_link; /* forward link (for driver header) */ + struct io_req * io_rlink; /* reverse link (for driver header) */ +// vm_map_copy_t io_copy; /* vm_map_copy obj. for this op. */ + long io_total; /* total op size, for write */ + pthread_mutex_t io_req_lock; +// decl_simple_lock_data(,io_req_lock) + /* Lock for this structure */ + long io_physrec; /* mapping to the physical block + number */ + long io_rectotal; /* total number of blocks to move */ +}; + +/* + * LOCKING NOTE: Operations on io_req's are in general single threaded by + * the invoking code, obviating the need for a lock. The usual IO_CALL + * path through the code is: Initiating thread hands io_req to device driver, + * driver passes it to io_done thread, io_done thread sends reply message. No + * locking is needed in this sequence. Unfortunately, a synchronous wait + * for a buffer requires a lock to avoid problems if the wait and interrupt + * happen simultaneously on different processors. + */ + +#define ior_lock(ior) pthread_mutex_lock(&(ior)->io_req_lock) +#define ior_unlock(ior) pthread_mutex_unlock(&(ior)->io_req_lock) + +/* + * Flags and operations + */ + +#define IO_WRITE 0x00000000 /* operation is write */ +#define IO_READ 0x00000001 /* operation is read */ +#define IO_OPEN 0x00000002 /* operation is open */ +#define IO_DONE 0x00000100 /* operation complete */ +#define IO_ERROR 0x00000200 /* error on operation */ +#define IO_BUSY 0x00000400 /* operation in progress */ +#define IO_WANTED 0x00000800 /* wakeup when no longer BUSY */ +#define IO_BAD 0x00001000 /* bad disk block */ +#define IO_CALL 0x00002000 /* call io_done_thread when done */ +#define IO_INBAND 0x00004000 /* mig call was inband */ +#define IO_INTERNAL 0x00008000 /* internal, device-driver specific */ +#define IO_LOANED 0x00010000 /* ior loaned by another module */ + +#define IO_SPARE_START 0x00020000 /* start of spare flags */ + +/* + * Standard completion routine for io_requests. + */ +void iodone(io_req_t); + +/* + * Macros to allocate and free IORs - will convert to zones later. + */ +#define io_req_alloc(ior,size) \ + MACRO_BEGIN \ + (ior) = (io_req_t)malloc(sizeof(struct io_req)); \ + pthread_mutex_init(&(ior)->io_req_lock, NULL); \ + MACRO_END + +#define io_req_free(ior) \ + (free(ior)) + + +//zone_t io_inband_zone; /* for inband reads */ + +#endif /* _IO_REQ_ */ diff --git a/libmachdevdde/linux-errno.h b/libmachdevdde/linux-errno.h new file mode 100644 index 000000000..be764a897 --- /dev/null +++ b/libmachdevdde/linux-errno.h @@ -0,0 +1,109 @@ +#ifndef _ASM_GENERIC_ERRNO_H +#define _ASM_GENERIC_ERRNO_H + +#include + +#define EDEADLK 35 /* Resource deadlock would occur */ +#define ENAMETOOLONG 36 /* File name too long */ +#define ENOLCK 37 /* No record locks available */ +#define ENOSYS 38 /* Function not implemented */ +#define ENOTEMPTY 39 /* Directory not empty */ +#define ELOOP 40 /* Too many symbolic links encountered */ +#define EWOULDBLOCK EAGAIN /* Operation would block */ +#define ENOMSG 42 /* No message of desired type */ +#define EIDRM 43 /* Identifier removed */ +#define ECHRNG 44 /* Channel number out of range */ +#define EL2NSYNC 45 /* Level 2 not synchronized */ +#define EL3HLT 46 /* Level 3 halted */ +#define EL3RST 47 /* Level 3 reset */ +#define ELNRNG 48 /* Link number out of range */ +#define EUNATCH 49 /* Protocol driver not attached */ +#define ENOCSI 50 /* No CSI structure available */ +#define EL2HLT 51 /* Level 2 halted */ +#define EBADE 52 /* Invalid exchange */ +#define EBADR 53 /* Invalid request descriptor */ +#define EXFULL 54 /* Exchange full */ +#define ENOANO 55 /* No anode */ +#define EBADRQC 56 /* Invalid request code */ +#define EBADSLT 57 /* Invalid slot */ + +#define EDEADLOCK EDEADLK + +#define EBFONT 59 /* Bad font file format */ +#define ENOSTR 60 /* Device not a stream */ +#define ENODATA 61 /* No data available */ +#define ETIME 62 /* Timer expired */ +#define ENOSR 63 /* Out of streams resources */ +#define ENONET 64 /* Machine is not on the network */ +#define ENOPKG 65 /* Package not installed */ +#define EREMOTE 66 /* Object is remote */ +#define ENOLINK 67 /* Link has been severed */ +#define EADV 68 /* Advertise error */ +#define ESRMNT 69 /* Srmount error */ +#define ECOMM 70 /* Communication error on send */ +#define EPROTO 71 /* Protocol error */ +#define EMULTIHOP 72 /* Multihop attempted */ +#define EDOTDOT 73 /* RFS specific error */ +#define EBADMSG 74 /* Not a data message */ +#define EOVERFLOW 75 /* Value too large for defined data type */ +#define ENOTUNIQ 76 /* Name not unique on network */ +#define EBADFD 77 /* File descriptor in bad state */ +#define EREMCHG 78 /* Remote address changed */ +#define ELIBACC 79 /* Can not access a needed shared library */ +#define ELIBBAD 80 /* Accessing a corrupted shared library */ +#define ELIBSCN 81 /* .lib section in a.out corrupted */ +#define ELIBMAX 82 /* Attempting to link in too many shared libraries */ +#define ELIBEXEC 83 /* Cannot exec a shared library directly */ +#define EILSEQ 84 /* Illegal byte sequence */ +#define ERESTART 85 /* Interrupted system call should be restarted */ +#define ESTRPIPE 86 /* Streams pipe error */ +#define EUSERS 87 /* Too many users */ +#define ENOTSOCK 88 /* Socket operation on non-socket */ +#define EDESTADDRREQ 89 /* Destination address required */ +#define EMSGSIZE 90 /* Message too long */ +#define EPROTOTYPE 91 /* Protocol wrong type for socket */ +#define ENOPROTOOPT 92 /* Protocol not available */ +#define EPROTONOSUPPORT 93 /* Protocol not supported */ +#define ESOCKTNOSUPPORT 94 /* Socket type not supported */ +#define EOPNOTSUPP 95 /* Operation not supported on transport endpoint */ +#define EPFNOSUPPORT 96 /* Protocol family not supported */ +#define EAFNOSUPPORT 97 /* Address family not supported by protocol */ +#define EADDRINUSE 98 /* Address already in use */ +#define EADDRNOTAVAIL 99 /* Cannot assign requested address */ +#define ENETDOWN 100 /* Network is down */ +#define ENETUNREACH 101 /* Network is unreachable */ +#define ENETRESET 102 /* Network dropped connection because of reset */ +#define ECONNABORTED 103 /* Software caused connection abort */ +#define ECONNRESET 104 /* Connection reset by peer */ +#define ENOBUFS 105 /* No buffer space available */ +#define EISCONN 106 /* Transport endpoint is already connected */ +#define ENOTCONN 107 /* Transport endpoint is not connected */ +#define ESHUTDOWN 108 /* Cannot send after transport endpoint shutdown */ +#define ETOOMANYREFS 109 /* Too many references: cannot splice */ +#define ETIMEDOUT 110 /* Connection timed out */ +#define ECONNREFUSED 111 /* Connection refused */ +#define EHOSTDOWN 112 /* Host is down */ +#define EHOSTUNREACH 113 /* No route to host */ +#define EALREADY 114 /* Operation already in progress */ +#define EINPROGRESS 115 /* Operation now in progress */ +#define ESTALE 116 /* Stale NFS file handle */ +#define EUCLEAN 117 /* Structure needs cleaning */ +#define ENOTNAM 118 /* Not a XENIX named type file */ +#define ENAVAIL 119 /* No XENIX semaphores available */ +#define EISNAM 120 /* Is a named type file */ +#define EREMOTEIO 121 /* Remote I/O error */ +#define EDQUOT 122 /* Quota exceeded */ + +#define ENOMEDIUM 123 /* No medium found */ +#define EMEDIUMTYPE 124 /* Wrong medium type */ +#define ECANCELED 125 /* Operation Canceled */ +#define ENOKEY 126 /* Required key not available */ +#define EKEYEXPIRED 127 /* Key has expired */ +#define EKEYREVOKED 128 /* Key has been revoked */ +#define EKEYREJECTED 129 /* Key was rejected by service */ + +/* for robust mutexes */ +#define EOWNERDEAD 130 /* Owner died */ +#define ENOTRECOVERABLE 131 /* State not recoverable */ + +#endif diff --git a/libmachdevdde/mach.defs b/libmachdevdde/mach.defs new file mode 100644 index 000000000..2750bcd52 --- /dev/null +++ b/libmachdevdde/mach.defs @@ -0,0 +1,715 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988 Carnegie Mellon University. + * Copyright (c) 1993,1994 The University of Utah and + * the Computer Systems Laboratory (CSL). + * All rights reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON, THE UNIVERSITY OF UTAH AND CSL ALLOW FREE USE OF + * THIS SOFTWARE IN ITS "AS IS" CONDITION, AND DISCLAIM ANY LIABILITY + * OF ANY KIND FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF + * THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * Matchmaker definitions file for Mach kernel interface. + */ + +subsystem +#if KERNEL_USER + KernelUser +#endif /* KERNEL_USER */ +#if KERNEL_SERVER + KernelServer +#endif /* KERNEL_SERVER */ + mach 2000; + +#ifdef KERNEL_USER +userprefix r_; +#endif /* KERNEL_USER */ + +#include +#include + +skip; /* old port_allocate */ +skip; /* old port_deallocate */ +skip; /* old port_enable */ +skip; /* old port_disable */ +skip; /* old port_select */ +skip; /* old port_set_backlog */ +skip; /* old port_status */ + +/* + * Create a new task with an empty set of IPC rights, + * and having an address space constructed from the + * target task (or empty, if inherit_memory is FALSE). + */ +routine task_create( + target_task : task_t; + inherit_memory : boolean_t; + out child_task : task_t); + +/* + * Destroy the target task, causing all of its threads + * to be destroyed, all of its IPC rights to be deallocated, + * and all of its address space to be deallocated. + */ +routine task_terminate( + target_task : task_t); + +/* + * Get user-level handler entry points for all + * emulated system calls. + */ +routine task_get_emulation_vector( + task : task_t; + out vector_start : int; + out emulation_vector: emulation_vector_t); + +/* + * Establish user-level handlers for the specified + * system calls. Non-emulated system calls are specified + * with emulation_vector[i] == EML_ROUTINE_NULL. + */ +routine task_set_emulation_vector( + task : task_t; + vector_start : int; + emulation_vector: emulation_vector_t); + + +/* + * Returns the set of threads belonging to the target task. + */ +routine task_threads( + target_task : task_t; + out thread_list : thread_array_t); + +/* + * Returns information about the target task. + */ +routine task_info( + target_task : task_t; + flavor : int; + out task_info_out : task_info_t, CountInOut); + + +skip; /* old task_status */ +skip; /* old task_set_notify */ +skip; /* old thread_create */ + +/* + * Destroy the target thread. + */ +routine thread_terminate( + target_thread : thread_t); + +/* + * Return the selected state information for the target + * thread. If the thread is currently executing, the results + * may be stale. [Flavor THREAD_STATE_FLAVOR_LIST provides a + * list of valid flavors for the target thread.] + */ +routine thread_get_state( + target_thread : thread_t; + flavor : int; + out old_state : thread_state_t, CountInOut); + +/* + * Set the selected state information for the target thread. + * If the thread is currently executing, the state change + * may be ill-defined. + */ +routine thread_set_state( + target_thread : thread_t; + flavor : int; + new_state : thread_state_t); + +/* + * Returns information about the target thread. + */ +routine thread_info( + target_thread : thread_t; + flavor : int; + out thread_info_out : thread_info_t, CountInOut); + +skip; /* old thread_mutate */ + +/* + * Allocate zero-filled memory in the address space + * of the target task, either at the specified address, + * or wherever space can be found (if anywhere is TRUE), + * of the specified size. The address at which the + * allocation actually took place is returned. + */ +#ifdef EMULATOR +skip; /* the emulator redefines vm_allocate using vm_map */ +#else /* EMULATOR */ +routine vm_allocate( + target_task : vm_task_t; + inout address : vm_address_t; + size : vm_size_t; + anywhere : boolean_t); +#endif /* EMULATOR */ + +skip; /* old vm_allocate_with_pager */ + +/* + * Deallocate the specified range from the virtual + * address space of the target task. + */ +routine vm_deallocate( + target_task : vm_task_t; + address : vm_address_t; + size : vm_size_t); + +/* + * Set the current or maximum protection attribute + * for the specified range of the virtual address + * space of the target task. The current protection + * limits the memory access rights of threads within + * the task; the maximum protection limits the accesses + * that may be given in the current protection. + * Protections are specified as a set of {read, write, execute} + * *permissions*. + */ +routine vm_protect( + target_task : vm_task_t; + address : vm_address_t; + size : vm_size_t; + set_maximum : boolean_t; + new_protection : vm_prot_t); + +/* + * Set the inheritance attribute for the specified range + * of the virtual address space of the target task. + * The inheritance value is one of {none, copy, share}, and + * specifies how the child address space should acquire + * this memory at the time of a task_create call. + */ +routine vm_inherit( + target_task : vm_task_t; + address : vm_address_t; + size : vm_size_t; + new_inheritance : vm_inherit_t); + +/* + * Returns the contents of the specified range of the + * virtual address space of the target task. [The + * range must be aligned on a virtual page boundary, + * and must be a multiple of pages in extent. The + * protection on the specified range must permit reading.] + */ +routine vm_read( + target_task : vm_task_t; + address : vm_address_t; + size : vm_size_t; + out data : pointer_t); + +/* + * Writes the contents of the specified range of the + * virtual address space of the target task. [The + * range must be aligned on a virtual page boundary, + * and must be a multiple of pages in extent. The + * protection on the specified range must permit writing.] + */ +routine vm_write( + target_task : vm_task_t; + address : vm_address_t; + data : pointer_t); + +/* + * Copy the contents of the source range of the virtual + * address space of the target task to the destination + * range in that same address space. [Both of the + * ranges must be aligned on a virtual page boundary, + * and must be multiples of pages in extent. The + * protection on the source range must permit reading, + * and the protection on the destination range must + * permit writing.] + */ +routine vm_copy( + target_task : vm_task_t; + source_address : vm_address_t; + size : vm_size_t; + dest_address : vm_address_t); + +/* + * Returns information about the contents of the virtual + * address space of the target task at the specified + * address. The returned protection, inheritance, sharing + * and memory object values apply to the entire range described + * by the address range returned; the memory object offset + * corresponds to the beginning of the address range. + * [If the specified address is not allocated, the next + * highest address range is described. If no addresses beyond + * the one specified are allocated, the call returns KERN_NO_SPACE.] + */ +routine vm_region( + target_task : vm_task_t; + inout address : vm_address_t; + out size : vm_size_t; + out protection : vm_prot_t; + out max_protection : vm_prot_t; + out inheritance : vm_inherit_t; + out is_shared : boolean_t; + /* avoid out-translation of the argument */ + out object_name : memory_object_name_t = + MACH_MSG_TYPE_MOVE_SEND + ctype: mach_port_t; + out offset : vm_offset_t); + +/* + * Return virtual memory statistics for the host + * on which the target task resides. [Note that the + * statistics are not specific to the target task.] + */ +routine vm_statistics( + target_task : vm_task_t; + out vm_stats : vm_statistics_data_t); + +skip; /* old task_by_u*x_pid */ +skip; /* old vm_pageable */ + +/* + * Stash a handful of ports for the target task; child + * tasks inherit this stash at task_create time. + */ +routine mach_ports_register( + target_task : task_t; + init_port_set : mach_port_array_t = + ^array[] of mach_port_t); + +/* + * Retrieve the stashed ports for the target task. + */ +routine mach_ports_lookup( + target_task : task_t; + out init_port_set : mach_port_array_t = + ^array[] of mach_port_t); + +skip; /* old u*x_pid */ +skip; /* old netipc_listen */ +skip; /* old netipc_ignore */ + +/* + * Provide the data contents of a range of the given memory + * object, with the access restriction specified. [Only + * whole virtual pages of data can be accepted; partial pages + * will be discarded. Data should be provided on request, but + * may be provided in advance as desired. When data already + * held by this kernel is provided again, the new data is ignored. + * The access restriction is the subset of {read, write, execute} + * which are prohibited. The kernel may not provide any data (or + * protection) consistency among pages with different virtual page + * alignments within the same object.] + */ +simpleroutine memory_object_data_provided( + memory_control : memory_object_control_t; + offset : vm_offset_t; + data : pointer_t; + lock_value : vm_prot_t); + +/* + * Indicate that a range of the given temporary memory object does + * not exist, and that the backing memory object should be used + * instead (or zero-fill memory be used, if no backing object exists). + * [This call is intended for use only by the default memory manager. + * It should not be used to indicate a real error -- + * memory_object_data_error should be used for that purpose.] + */ +simpleroutine memory_object_data_unavailable( + memory_control : memory_object_control_t; + offset : vm_offset_t; + size : vm_size_t); + +/* + * Retrieves the attributes currently associated with + * a memory object. + */ +routine memory_object_get_attributes( + memory_control : memory_object_control_t; + out object_ready : boolean_t; + out may_cache : boolean_t; + out copy_strategy : memory_object_copy_strategy_t); + +/* + * Sets the default memory manager, the port to which + * newly-created temporary memory objects are delivered. + * [See (memory_object_default)memory_object_create.] + * The old memory manager port is returned. + */ +routine vm_set_default_memory_manager( + host_priv : host_priv_t; + inout default_manager : mach_port_make_send_t); + +skip; /* old pager_flush_request */ + +/* + * Control use of the data associated with the given + * memory object. For each page in the given range, + * perform the following operations, in order: + * 1) restrict access to the page (disallow + * forms specified by "prot"); + * 2) write back modifications (if "should_return" + * is RETURN_DIRTY and the page is dirty, or + * "should_return" is RETURN_ALL and the page + * is either dirty or precious); and, + * 3) flush the cached copy (if "should_flush" + * is asserted). + * The set of pages is defined by a starting offset + * ("offset") and size ("size"). Only pages with the + * same page alignment as the starting offset are + * considered. + * + * A single acknowledgement is sent (to the "reply_to" + * port) when these actions are complete. + * + * There are two versions of this routine because IPC distinguishes + * between booleans and integers (a 2-valued integer is NOT a + * boolean). The new routine is backwards compatible at the C + * language interface. + */ + +skip; /* old xxx_memory_object_lock_request */ + +simpleroutine memory_object_lock_request( + memory_control : memory_object_control_t; + offset : vm_offset_t; + size : vm_size_t; + should_return : memory_object_return_t; + should_flush : boolean_t; + lock_value : vm_prot_t; + reply_to : mach_port_t = + MACH_MSG_TYPE_MAKE_SEND_ONCE|polymorphic); + +skip; /* old xxx_task_get_emulation_vector */ +skip; /* old xxx_task_set_emulation_vector */ +skip; /* old xxx_host_info */ +skip; /* old xxx_slot_info */ +skip; /* old xxx_cpu_control */ +skip; /* old thread_statistics */ +skip; /* old task_statistics */ +skip; /* old netport_init */ +skip; /* old netport_enter */ +skip; /* old netport_remove */ +skip; /* old thread_set_priority */ + +/* + * Increment the suspend count for the target task. + * No threads within a task may run when the suspend + * count for that task is non-zero. + */ +routine task_suspend( + target_task : task_t); + +/* + * Decrement the suspend count for the target task, + * if the count is currently non-zero. If the resulting + * suspend count is zero, then threads within the task + * that also have non-zero suspend counts may execute. + */ +routine task_resume( + target_task : task_t); + +/* + * Returns the current value of the selected special port + * associated with the target task. + */ +routine task_get_special_port( + task : task_t; + which_port : int; + out special_port : mach_port_t); + +/* + * Set one of the special ports associated with the + * target task. + */ +routine task_set_special_port( + task : task_t; + which_port : int; + special_port : mach_port_t); + +skip; /* old xxx_task_info */ + + +/* + * Create a new thread within the target task, returning + * the port representing that new thread. The + * initial execution state of the thread is undefined. + */ +routine thread_create( + parent_task : task_t; + out child_thread : thread_t); + +/* + * Increment the suspend count for the target thread. + * Once this call has completed, the thread will not + * execute any further user or meta- instructions. + * Once suspended, a thread may not execute again until + * its suspend count is zero, and the suspend count + * for its task is also zero. + */ +routine thread_suspend( + target_thread : thread_t); + +/* + * Decrement the suspend count for the target thread, + * if that count is not already zero. + */ +routine thread_resume( + target_thread : thread_t); + +/* + * Cause any user or meta- instructions currently being + * executed by the target thread to be aborted. [Meta- + * instructions consist of the basic traps for IPC + * (e.g., msg_send, msg_receive) and self-identification + * (e.g., task_self, thread_self, thread_reply). Calls + * described by MiG interfaces are not meta-instructions + * themselves.] + */ +routine thread_abort( + target_thread : thread_t); + +skip; /* old xxx_thread_get_state */ +skip; /* old xxx_thread_set_state */ + +/* + * Returns the current value of the selected special port + * associated with the target thread. + */ +routine thread_get_special_port( + thread : thread_t; + which_port : int; + out special_port : mach_port_t); + +/* + * Set one of the special ports associated with the + * target thread. + */ +routine thread_set_special_port( + thread : thread_t; + which_port : int; + special_port : mach_port_t); + +skip; /* old xxx_thread_info */ + +/* + * Establish a user-level handler for the specified + * system call. + */ +routine task_set_emulation( + target_port : task_t; + routine_entry_pt: vm_address_t; + routine_number : int); + +/* + * Establish restart pc for interrupted atomic sequences. + * This reuses the message number for the old task_get_io_port. + * See task_info.h for description of flavors. + * + */ +routine task_ras_control( + target_task : task_t; + basepc : vm_address_t; + boundspc : vm_address_t; + flavor : int); + + + +skip; /* old host_ipc_statistics */ +skip; /* old port_names */ +skip; /* old port_type */ +skip; /* old port_rename */ +skip; /* old port_allocate */ +skip; /* old port_deallocate */ +skip; /* old port_set_backlog */ +skip; /* old port_status */ +skip; /* old port_set_allocate */ +skip; /* old port_set_deallocate */ +skip; /* old port_set_add */ +skip; /* old port_set_remove */ +skip; /* old port_set_status */ +skip; /* old port_insert_send */ +skip; /* old port_extract_send */ +skip; /* old port_insert_receive */ +skip; /* old port_extract_receive */ + +/* + * Map a user-defined memory object into the virtual address + * space of the target task. If desired (anywhere is TRUE), + * the kernel will find a suitable address range of the + * specified size; else, the specific address will be allocated. + * + * The beginning address of the range will be aligned on a virtual + * page boundary, be at or beyond the address specified, and + * meet the mask requirements (bits turned on in the mask must not + * be turned on in the result); the size of the range, in bytes, + * will be rounded up to an integral number of virtual pages. + * + * The memory in the resulting range will be associated with the + * specified memory object, with the beginning of the memory range + * referring to the specified offset into the memory object. + * + * The mapping will take the current and maximum protections and + * the inheritance attributes specified; see the vm_protect and + * vm_inherit calls for a description of these attributes. + * + * If desired (copy is TRUE), the memory range will be filled + * with a copy of the data from the memory object; this copy will + * be private to this mapping in this target task. Otherwise, + * the memory in this mapping will be shared with other mappings + * of the same memory object at the same offset (in this task or + * in other tasks). [The Mach kernel only enforces shared memory + * consistency among mappings on one host with similar page alignments. + * The user-defined memory manager for this object is responsible + * for further consistency.] + */ +#ifdef EMULATOR +routine htg_vm_map( + target_task : vm_task_t; + ureplyport reply_port : mach_port_make_send_once_t; + inout address : vm_address_t; + size : vm_size_t; + mask : vm_address_t; + anywhere : boolean_t; + memory_object : memory_object_t; + offset : vm_offset_t; + copy : boolean_t; + cur_protection : vm_prot_t; + max_protection : vm_prot_t; + inheritance : vm_inherit_t); +#else /* EMULATOR */ +routine vm_map( + target_task : vm_task_t; + inout address : vm_address_t; + size : vm_size_t; + mask : vm_address_t; + anywhere : boolean_t; + memory_object : memory_object_t; + offset : vm_offset_t; + copy : boolean_t; + cur_protection : vm_prot_t; + max_protection : vm_prot_t; + inheritance : vm_inherit_t); +#endif /* EMULATOR */ + +/* + * Indicate that a range of the specified memory object cannot + * be provided at this time. [Threads waiting for memory pages + * specified by this call will experience a memory exception. + * Only threads waiting at the time of the call are affected.] + */ +simpleroutine memory_object_data_error( + memory_control : memory_object_control_t; + offset : vm_offset_t; + size : vm_size_t; + error_value : kern_return_t); + +/* + * Make decisions regarding the use of the specified + * memory object. + */ +simpleroutine memory_object_set_attributes( + memory_control : memory_object_control_t; + object_ready : boolean_t; + may_cache : boolean_t; + copy_strategy : memory_object_copy_strategy_t); + +/* + */ +simpleroutine memory_object_destroy( + memory_control : memory_object_control_t; + reason : kern_return_t); + +/* + * Provide the data contents of a range of the given memory + * object, with the access restriction specified, optional + * precious attribute, and reply message. [Only + * whole virtual pages of data can be accepted; partial pages + * will be discarded. Data should be provided on request, but + * may be provided in advance as desired. When data already + * held by this kernel is provided again, the new data is ignored. + * The access restriction is the subset of {read, write, execute} + * which are prohibited. The kernel may not provide any data (or + * protection) consistency among pages with different virtual page + * alignments within the same object. The precious value controls + * how the kernel treats the data. If it is FALSE, the kernel treats + * its copy as a temporary and may throw it away if it hasn't been + * changed. If the precious value is TRUE, the kernel treats its + * copy as a data repository and promises to return it to the manager; + * the manager may tell the kernel to throw it away instead by flushing + * and not cleaning the data -- see memory_object_lock_request. The + * reply_to port is for a compeletion message; it will be + * memory_object_supply_completed.] + */ + +simpleroutine memory_object_data_supply( + memory_control : memory_object_control_t; + offset : vm_offset_t; + data : pointer_t, Dealloc[]; + lock_value : vm_prot_t; + precious : boolean_t; + reply_to : mach_port_t = + MACH_MSG_TYPE_MAKE_SEND_ONCE|polymorphic); + +simpleroutine memory_object_ready( + memory_control : memory_object_control_t; + may_cache : boolean_t; + copy_strategy : memory_object_copy_strategy_t); + +simpleroutine memory_object_change_attributes( + memory_control : memory_object_control_t; + may_cache : boolean_t; + copy_strategy : memory_object_copy_strategy_t; + reply_to : mach_port_t = + MACH_MSG_TYPE_MAKE_SEND_ONCE|polymorphic); + +skip; /* old host_callout_statistics_reset */ +skip; /* old port_set_select */ +skip; /* old port_set_backup */ + +/* + * Set/Get special properties of memory associated + * to some virtual address range, such as cachability, + * migrability, replicability. Machine-dependent. + */ +routine vm_machine_attribute( + target_task : vm_task_t; + address : vm_address_t; + size : vm_size_t; + attribute : vm_machine_attribute_t; + inout value : vm_machine_attribute_val_t); + +skip; /* old host_fpa_counters_reset */ + +/* + * This routine is created for allocating DMA buffers. + * We are going to get a contiguous physical memory + * and its physical address in addition to the virtual address. + */ +routine vm_allocate_contiguous( + host_priv : host_priv_t; + target_task : vm_task_t; + out vaddr : vm_address_t; + out paddr : vm_address_t; + size : vm_size_t); + +/* + * There is no more room in this interface for additional calls. + */ diff --git a/libmachdevdde/mach_glue.h b/libmachdevdde/mach_glue.h new file mode 100644 index 000000000..7b1225833 --- /dev/null +++ b/libmachdevdde/mach_glue.h @@ -0,0 +1,41 @@ +#ifndef __MACH_GLUE_H__ +#define __MACH_GLUE_H__ + +/* network */ +#include + +#include + +struct sk_buff; +struct net_device; +void skb_done_queue(struct sk_buff *skb); +struct sk_buff *skb_done_dequeue(); +void *skb_reply(struct sk_buff *skb); + +int netdev_flags(struct net_device *dev); +char *netdev_addr(struct net_device *dev); +char *netdev_name (struct net_device *dev); +unsigned int netdev_mtu (struct net_device *dev); +unsigned short netdev_header_len (struct net_device *dev); +unsigned short netdev_type (struct net_device *dev); +unsigned char netdev_addr_len (struct net_device *dev); + +int dev_change_flags (struct net_device *dev, short flags); +int linux_pkg_xmit (char *pkg_data, int len, void *del_data, + int (*del_func) (struct sk_buff *, void *), + struct net_device *dev); +struct net_device *search_netdev (char *name); +void kfree_skb (struct sk_buff *skb); +int dev_open(struct net_device *dev); +void *l4dde26_register_rx_callback(void *cb); +void skb_done_head_init(); + +/* block device */ +struct block_device; +struct block_device *open_block_dev (char *name, int part, dev_mode_t mode); +int block_dev_rw (struct block_device *dev, int sectornr, + char *data, int count, int rw, void (*write_done) (int err)); + +int l4dde26_process_from_ddekit(ddekit_thread_t *t); + +#endif diff --git a/libmachdevdde/machdev.h b/libmachdevdde/machdev.h new file mode 100644 index 000000000..b9186fbaf --- /dev/null +++ b/libmachdevdde/machdev.h @@ -0,0 +1,33 @@ +/* + Copyright (C) 2010 Free Software Foundation, Inc. + Written by Zheng Da. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2, or (at your option) + any later version. + + The GNU Hurd is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the GNU Hurd; see the file COPYING. If not, write to + the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ + +/* This file declares interfaces used by driver programs. */ + +#ifndef __MACHDEV_H__ +#define __MACHDEV_H__ + +void * ds_server(void *); +void mach_device_init(void); +void register_net(void); +void register_block(void); +void trivfs_server(void); +int trivfs_init(void); + +#endif diff --git a/libmachdevdde/mig-decls.h b/libmachdevdde/mig-decls.h new file mode 100644 index 000000000..8302029d2 --- /dev/null +++ b/libmachdevdde/mig-decls.h @@ -0,0 +1,50 @@ +/* + Copyright (C) 2014 Free Software Foundation, Inc. + Written by Justus Winter. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the GNU Hurd. If not, see . */ + +#ifndef __LIBMACHDEV_MIG_DECLS_H__ +#define __LIBMACHDEV_MIG_DECLS_H__ + +#include +#include "dev_hdr.h" + +extern struct port_bucket *device_bucket; +extern struct port_class *dev_class; + +/* Called by server stub functions. */ + +static inline struct mach_device * __attribute__ ((unused)) +begin_using_device_port (mach_port_t port) +{ + return ports_lookup_port (device_bucket, port, dev_class); +} + +static inline struct mach_device * __attribute__ ((unused)) +begin_using_device_payload (unsigned long payload) +{ + return ports_lookup_payload (device_bucket, payload, dev_class); +} + +static inline void __attribute__ ((unused)) +end_using_device (struct mach_device *p) +{ + if (p) + ports_port_deref (p); +} + +#endif /* __LIBMACHDEV_MIG_DECLS_H__ */ diff --git a/libmachdevdde/mig-mutate.h b/libmachdevdde/mig-mutate.h new file mode 100644 index 000000000..902ff166f --- /dev/null +++ b/libmachdevdde/mig-mutate.h @@ -0,0 +1,36 @@ +/* + Copyright (C) 2014 Free Software Foundation, Inc. + Written by Justus Winter. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with the GNU Hurd. If not, see . */ + +#define NOTIFY_INTRAN \ + port_info_t begin_using_port_info_port (mach_port_t) +#define NOTIFY_INTRAN_PAYLOAD \ + port_info_t begin_using_port_info_payload +#define NOTIFY_DESTRUCTOR \ + end_using_port_info (port_info_t) +#define NOTIFY_IMPORTS \ + import "libports/mig-decls.h"; + +#define DEVICE_INTRAN \ + mach_device_t begin_using_device_port (mach_port_t) +#define DEVICE_INTRAN_PAYLOAD \ + mach_device_t begin_using_device_payload +#define DEVICE_DESTRUCTOR \ + end_using_device (mach_device_t) +#define DEVICE_IMPORTS \ + import "libmachdev/mig-decls.h"; diff --git a/libmachdevdde/misc.c b/libmachdevdde/misc.c new file mode 100644 index 000000000..977159bd3 --- /dev/null +++ b/libmachdevdde/misc.c @@ -0,0 +1,50 @@ +#include +#include + +#include + +#include "linux-errno.h" + +int +linux_to_mach_error (int err) +{ + switch (err) + { + case 0: + return D_SUCCESS; + + case -EPERM: + return D_INVALID_OPERATION; + + case -EIO: + return D_IO_ERROR; + + case -ENXIO: + return D_NO_SUCH_DEVICE; + + case -EACCES: + return D_INVALID_OPERATION; + + case -EFAULT: + return D_INVALID_SIZE; + + case -EBUSY: + return D_ALREADY_OPEN; + + case -EINVAL: + return D_INVALID_SIZE; + + case -EROFS: + return D_READ_ONLY; + + case -EWOULDBLOCK: + return D_WOULD_BLOCK; + + case -ENOMEM: + return D_NO_MEMORY; + + default: + ddekit_printf ("linux_to_mach_error: unknown code %d\n", err); + return D_IO_ERROR; + } +} diff --git a/libmachdevdde/net.c b/libmachdevdde/net.c new file mode 100644 index 000000000..220121aac --- /dev/null +++ b/libmachdevdde/net.c @@ -0,0 +1,662 @@ +/* + * Linux network driver support. + * + * Copyright (C) 1996 The University of Utah and the Computer Systems + * Laboratory at the University of Utah (CSL) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. + * + * Author: Shantanu Goel, University of Utah CSL + */ + +/* + * INET An implementation of the TCP/IP protocol suite for the LINUX + * operating system. INET is implemented using the BSD Socket + * interface as the means of communication with the user level. + * + * Ethernet-type device handling. + * + * Version: @(#)eth.c 1.0.7 05/25/93 + * + * Authors: Ross Biro, + * Fred N. van Kempen, + * Mark Evans, + * Florian La Roche, + * Alan Cox, + * + * Fixes: + * Mr Linux : Arp problems + * Alan Cox : Generic queue tidyup (very tiny here) + * Alan Cox : eth_header ntohs should be htons + * Alan Cox : eth_rebuild_header missing an htons and + * minor other things. + * Tegge : Arp bug fixes. + * Florian : Removed many unnecessary functions, code cleanup + * and changes for new arp and skbuff. + * Alan Cox : Redid header building to reflect new format. + * Alan Cox : ARP only when compiled with CONFIG_INET + * Greg Page : 802.2 and SNAP stuff. + * Alan Cox : MAC layer pointers/new format. + * Paul Gortmaker : eth_copy_and_sum shouldn't csum padding. + * Alan Cox : Protect against forwarding explosions with + * older network drivers and IFF_ALLMULTI + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include +#include +#include +#include + +#include "mach_U.h" + +#include +#include + +#define MACH_INCLUDE + +#include "ds_routines.h" +#include "vm_param.h" +#include "device_reply_U.h" +#include "dev_hdr.h" +#include "if_ether.h" +#include "util.h" +#include "mach_glue.h" +#include "if_hdr.h" + +#define ether_header ethhdr + +/* One of these is associated with each instance of a device. */ +struct net_data +{ + struct port_info port; /* device port */ + struct emul_device device; /* generic device structure */ + struct ifnet ifnet; /* Mach ifnet structure (needed for filters) */ + struct net_device *dev; /* Linux network device structure */ + struct net_data *next; +}; + +struct skb_reply +{ + mach_port_t reply; + mach_msg_type_name_t reply_type; + int pkglen; +}; + +static struct net_data *nd_head; + +/* Forward declarations. */ + +extern struct device_emulation_ops linux_net_emulation_ops; + +static mach_msg_type_t header_type = +{ + MACH_MSG_TYPE_BYTE, + 8, + NET_HDW_HDR_MAX, + TRUE, + FALSE, + FALSE, + 0 +}; + +static mach_msg_type_t packet_type = +{ + MACH_MSG_TYPE_BYTE, /* name */ + 8, /* size */ + 0, /* number */ + TRUE, /* inline */ + FALSE, /* longform */ + FALSE /* deallocate */ +}; + +static struct net_data *search_nd (struct net_device *dev) +{ + struct net_data *nd = nd_head; + + //TODO protected by locks. + while (nd) + { + if (nd->dev == dev) + return nd; + nd = nd->next; + } + return NULL; +} + +/* Linux kernel network support routines. */ + +/* actions before freeing the sk_buff SKB. + * If it returns 1, the packet will be deallocated later. */ +static int +pre_kfree_skb (struct sk_buff *skb, void *data) +{ + struct skb_reply *reply = data; + extern void wakeup_io_done_thread (); + + /* Queue sk_buff on done list if there is a + page list attached or we need to send a reply. + Wakeup the iodone thread to process the list. */ + if (reply && MACH_PORT_VALID (reply->reply)) + { + if (MACH_PORT_VALID (reply->reply)) + { + ds_device_write_reply (reply->reply, reply->reply_type, + 0, reply->pkglen); + reply->reply = MACH_PORT_NULL; + } + } + /* deallocate skb_reply before freeing the packet. */ + free (data); + return 0; +} + +/* + * Deliver the message to all right pfinet servers that + * connects to the virtual network interface. + */ +int +deliver_msg(struct net_rcv_msg *msg, if_filter_list_t *ifp) +{ + mach_msg_return_t err; + queue_head_t *if_port_list; + net_rcv_port_t infp, nextfp; + + msg->msg_hdr.msgh_bits = MACH_MSGH_BITS (MACH_MSG_TYPE_COPY_SEND, 0); + /* remember message sizes must be rounded up */ + msg->msg_hdr.msgh_local_port = MACH_PORT_NULL; + msg->msg_hdr.msgh_kind = MACH_MSGH_KIND_NORMAL; + msg->msg_hdr.msgh_id = NET_RCV_MSG_ID; + + if_port_list = &ifp->if_rcv_port_list; + FILTER_ITERATE (if_port_list, infp, nextfp, &infp->input) + { + mach_port_t dest; + net_hash_entry_t entp, *hash_headp; + int ret_count; + + entp = (net_hash_entry_t) 0; + ret_count = bpf_do_filter (infp, + msg->packet + sizeof (struct packet_header), + msg->net_rcv_msg_packet_count, msg->header, + sizeof (struct ethhdr), &hash_headp, &entp); + if (entp == (net_hash_entry_t) 0) + dest = infp->rcv_port; + else + dest = entp->rcv_port; + + if (ret_count) + { + msg->msg_hdr.msgh_remote_port = dest; + err = mach_msg ((mach_msg_header_t *)msg, + MACH_SEND_MSG|MACH_SEND_TIMEOUT, + msg->msg_hdr.msgh_size, 0, MACH_PORT_NULL, + 0, MACH_PORT_NULL); + if (err != MACH_MSG_SUCCESS) + { + /* TODO: remove from filter */ + } + } + } + FILTER_ITERATE_END + + return 0; +} + +/* Accept packet SKB received on an interface. */ +static void +netif_rx_handle (char *data, int len, struct net_device *dev) +{ + int pack_size; + struct net_rcv_msg net_msg; + struct ether_header *eh; + struct packet_header *ph; + struct net_data *nd; + + nd = search_nd(dev); + assert (nd); + + pack_size = len - sizeof (struct ethhdr); + /* remember message sizes must be rounded up */ + net_msg.msg_hdr.msgh_size = + (((mach_msg_size_t) (sizeof (struct net_rcv_msg) + - sizeof net_msg.sent + + sizeof (struct packet_header) + - NET_RCV_MAX + pack_size)) + 3) & ~3; + + /* Copy packet into message buffer. */ + eh = (struct ether_header *) (net_msg.header); + ph = (struct packet_header *) (net_msg.packet); + memcpy (eh, data, sizeof (struct ether_header)); + /* packet is prefixed with a struct packet_header, + see include/device/net_status.h. */ + memcpy (ph + 1, data + sizeof (struct ether_header), pack_size); + ph->type = eh->h_proto; + ph->length = pack_size + sizeof (struct packet_header); + + net_msg.sent = FALSE; /* Mark packet as received. */ + + net_msg.header_type = header_type; + net_msg.packet_type = packet_type; + net_msg.net_rcv_msg_packet_count = ph->length; + deliver_msg (&net_msg, &nd->ifnet.port_list); +} + +/* Mach device interface routines. */ + +/* Return a send right associated with network device ND. */ +static mach_port_t +dev_to_port (void *nd) +{ + return (nd + ? ports_get_send_right (nd) + : MACH_PORT_NULL); +} + +/* + * Initialize send and receive queues on an interface. + */ +void if_init_queues(ifp) + register struct ifnet *ifp; +{ +// IFQ_INIT(&ifp->if_snd); + queue_init(&ifp->port_list.if_rcv_port_list); + queue_init(&ifp->port_list.if_snd_port_list); + pthread_mutex_init(&ifp->if_rcv_port_list_lock, NULL); + pthread_mutex_init(&ifp->if_snd_port_list_lock, NULL); +} + +static io_return_t +device_open (mach_port_t reply_port, mach_msg_type_name_t reply_port_type, + dev_mode_t mode, char *name, device_t *devp, + mach_msg_type_name_t *devicePoly) +{ + io_return_t err = D_SUCCESS; + struct net_device *dev; + struct net_data *nd; + struct ifnet *ifp; + + /* Search for the device. */ + dev = search_netdev (name); + if (!dev) + { + fprintf (stderr, "after search_netdev: cannot find %s\n", name); + return D_NO_SUCH_DEVICE; + } + + /* Allocate and initialize device data if this is the first open. */ + nd = search_nd (dev); + if (!nd) + { + char *name; + + err = create_device_port (sizeof (*nd), &nd); + if (err) + { + fprintf (stderr, "after create_device_port: cannot create a port\n"); + goto out; + } + + nd->dev = dev; + nd->device.emul_data = nd; + nd->device.emul_ops = &linux_net_emulation_ops; + nd->next = nd_head; + nd_head = nd; + + ifp = &nd->ifnet; + name = netdev_name (dev); + ifp->if_unit = name[strlen (name) - 1] - '0'; + ifp->if_flags = IFF_UP | IFF_RUNNING; + ifp->if_mtu = netdev_mtu (dev); + ifp->if_header_size = netdev_header_len (dev); + ifp->if_header_format = netdev_type (dev); + ifp->if_address_size = netdev_addr_len (dev); + ifp->if_address = netdev_addr (dev); + if_init_queues (ifp); + + if ((err = dev_open(dev)) < 0) + { + fprintf (stderr, "after dev_open: cannot open the device\n"); + err = linux_to_mach_error (err); + } + + out: + if (err) + { + if (nd) + { + ports_destroy_right (nd); + nd = NULL; + } + } + else + { +#if 0 + /* IPv6 heavily relies on multicasting (especially router and + neighbor solicits and advertisements), so enable reception of + those multicast packets by setting `LINUX_IFF_ALLMULTI'. */ + dev->flags |= LINUX_IFF_UP | LINUX_IFF_RUNNING | LINUX_IFF_ALLMULTI; + skb_queue_head_init (&dev->buffs[0]); + + if (dev->set_multicast_list) + dev->set_multicast_list (dev); +#endif + } + } + + if (nd) + { + *devp = ports_get_right (nd); + *devicePoly = MACH_MSG_TYPE_MAKE_SEND; + } + return err; +} + +static io_return_t +device_write (void *d, mach_port_t reply_port, + mach_msg_type_name_t reply_port_type, dev_mode_t mode, + recnum_t bn, io_buf_ptr_t data, unsigned int count, + int *bytes_written) +{ + struct net_data *nd = d; + struct net_device *dev = nd->dev; + struct skb_reply *skb_reply = malloc (sizeof (*skb_reply)); + error_t err; + + if (skb_reply == NULL) + return D_NO_MEMORY; + + skb_reply->pkglen = count; + skb_reply->reply = reply_port; + skb_reply->reply_type = reply_port_type; + + err = linux_pkg_xmit (data, count, skb_reply, pre_kfree_skb, dev); + vm_deallocate (mach_task_self (), (vm_address_t) data, count); + if (err) + return linux_to_mach_error (err); + + /* Send packet to filters. */ + // TODO should I deliver the packet to other network stacks? +#if 0 + { + struct packet_header *packet; + struct ether_header *header; + ipc_kmsg_t kmsg; + + kmsg = net_kmsg_get (); + + if (kmsg != IKM_NULL) + { + /* Suitable for Ethernet only. */ + header = (struct ether_header *) (net_kmsg (kmsg)->header); + packet = (struct packet_header *) (net_kmsg (kmsg)->packet); + memcpy (header, skb->data, sizeof (struct ether_header)); + + /* packet is prefixed with a struct packet_header, + see include/device/net_status.h. */ + memcpy (packet + 1, skb->data + sizeof (struct ether_header), + skb->len - sizeof (struct ether_header)); + packet->length = skb->len - sizeof (struct ether_header) + + sizeof (struct packet_header); + packet->type = header->ether_type; + net_kmsg (kmsg)->sent = TRUE; /* Mark packet as sent. */ + s = splimp (); + net_packet (&dev->net_data->ifnet, kmsg, packet->length, + ethernet_priority (kmsg)); + splx (s); + } + } +#endif + + return MIG_NO_REPLY; +} + +/* + * Other network operations + */ +static io_return_t +net_getstat(ifp, flavor, status, count) + struct ifnet *ifp; + dev_flavor_t flavor; + dev_status_t status; /* pointer to OUT array */ + natural_t *count; /* OUT */ +{ +#define ETHERMTU 1500 + switch (flavor) { + case NET_STATUS: + { + register struct net_status *ns = (struct net_status *)status; + + if (*count < NET_STATUS_COUNT) + return (D_INVALID_OPERATION); + + ns->min_packet_size = ifp->if_header_size; + ns->max_packet_size = ifp->if_header_size + ifp->if_mtu; + ns->header_format = ifp->if_header_format; + ns->header_size = ifp->if_header_size; + ns->address_size = ifp->if_address_size; + ns->flags = ifp->if_flags; + ns->mapped_size = 0; + + *count = NET_STATUS_COUNT; + break; + } + case NET_ADDRESS: + { + register int addr_byte_count; + register int addr_int_count; + register int i; + + addr_byte_count = ETH_ALEN; + addr_int_count = (addr_byte_count + (sizeof(int)-1)) + / sizeof(int); + + if (*count < addr_int_count) + { + /* XXX debug hack. */ + printf ("net_getstat: count: %d, addr_int_count: %d\n", + *count, addr_int_count); + return (D_INVALID_OPERATION); + } + + memcpy(status, ifp->if_address, addr_byte_count); + if (addr_byte_count < addr_int_count * sizeof(int)) + memset((char *)status + addr_byte_count, 0, + (addr_int_count * sizeof(int) + - addr_byte_count)); + + for (i = 0; i < addr_int_count; i++) { + register int word; + + word = status[i]; + status[i] = htonl(word); + } + *count = addr_int_count; + break; + } + default: + return (D_INVALID_OPERATION); + } + return (D_SUCCESS); +} + +static io_return_t +device_get_status (void *d, dev_flavor_t flavor, dev_status_t status, + mach_msg_type_number_t *count) +{ + struct net_data *net = (struct net_data *) d; + + if (flavor == NET_FLAGS) + { + if (*count != 1) + return D_INVALID_SIZE; + + *(int *) status = netdev_flags (net->dev); + return D_SUCCESS; + } + +#if 0 + if(flavor >= SIOCIWFIRST && flavor <= SIOCIWLAST) + { + /* handle wireless ioctl */ + if(! IW_IS_GET(flavor)) + return D_INVALID_OPERATION; + + if(*count * sizeof(int) < sizeof(struct ifreq)) + return D_INVALID_OPERATION; + + struct net_data *nd = d; + struct linux_device *dev = nd->dev; + + if(! dev->do_ioctl) + return D_INVALID_OPERATION; + + int result; + + if (flavor == SIOCGIWRANGE || flavor == SIOCGIWENCODE + || flavor == SIOCGIWESSID || flavor == SIOCGIWNICKN + || flavor == SIOCGIWSPY) + { + /* + * These ioctls require an `iw_point' as their argument (i.e. + * they want to return some data to userspace. + * Therefore supply some sane values and carry the data back + * to userspace right behind the `struct iwreq'. + */ + struct iw_point *iwp = &((struct iwreq *) status)->u.data; + iwp->length = *count * sizeof (dev_status_t) - sizeof (struct ifreq); + iwp->pointer = (void *) status + sizeof (struct ifreq); + + result = dev->do_ioctl (dev, (struct ifreq *) status, flavor); + + *count = ((sizeof (struct ifreq) + iwp->length) + / sizeof (dev_status_t)); + if (iwp->length % sizeof (dev_status_t)) + (*count) ++; + } + else + { + *count = sizeof(struct ifreq) / sizeof(int); + result = dev->do_ioctl(dev, (struct ifreq *) status, flavor); + } + + return result ? D_IO_ERROR : D_SUCCESS; + } + else +#endif + { + /* common get_status request */ + return net_getstat (&net->ifnet, flavor, status, count); + } +} + +static io_return_t +device_set_status(void *d, dev_flavor_t flavor, dev_status_t status, + mach_msg_type_number_t count) +{ + if (flavor == NET_FLAGS) + { + if (count != 1) + return D_INVALID_SIZE; + + int flags = *(int *) status; + struct net_data *net = (struct net_data *) d; + + dev_change_flags (net->dev, flags); + + return D_SUCCESS; + } + return D_INVALID_OPERATION; + +#if 0 + if(flavor < SIOCIWFIRST || flavor > SIOCIWLAST) + return D_INVALID_OPERATION; + + if(! IW_IS_SET(flavor)) + return D_INVALID_OPERATION; + + if(count * sizeof(int) < sizeof(struct ifreq)) + return D_INVALID_OPERATION; + + struct net_data *nd = d; + struct linux_device *dev = nd->dev; + + if(! dev->do_ioctl) + return D_INVALID_OPERATION; + + if((flavor == SIOCSIWENCODE || flavor == SIOCSIWESSID + || flavor == SIOCSIWNICKN || flavor == SIOCSIWSPY) + && ((struct iwreq *) status)->u.data.pointer) + { + struct iw_point *iwp = &((struct iwreq *) status)->u.data; + + /* safety check whether the status array is long enough ... */ + if(count * sizeof(int) < sizeof(struct ifreq) + iwp->length) + return D_INVALID_OPERATION; + + /* make sure, iwp->pointer points to the correct address */ + if(iwp->pointer) iwp->pointer = (void *) status + sizeof(struct ifreq); + } + + int result = dev->do_ioctl(dev, (struct ifreq *) status, flavor); + return result ? D_IO_ERROR : D_SUCCESS; +#endif +} + + +static io_return_t +device_set_filter (void *d, mach_port_t port, int priority, + filter_t * filter, unsigned filter_count) +{ + return net_set_filter (&((struct net_data *) d)->ifnet.port_list, + port, priority, filter, filter_count); +} + +/* Do any initialization required for network devices. */ +static void linux_net_emulation_init () +{ + skb_done_head_init(); + l4dde26_register_rx_callback(netif_rx_handle); +} + +struct device_emulation_ops linux_net_emulation_ops = +{ + linux_net_emulation_init, + NULL, + NULL, + dev_to_port, + device_open, + NULL, + device_write, + NULL, + NULL, + NULL, + device_set_status, + device_get_status, + device_set_filter, + NULL, + NULL, + NULL, + NULL +}; + +void register_net() +{ + extern void reg_dev_emul (struct device_emulation_ops *ops); + reg_dev_emul (&linux_net_emulation_ops); +} diff --git a/libmachdevdde/queue.c b/libmachdevdde/queue.c new file mode 100644 index 000000000..a43a21b0e --- /dev/null +++ b/libmachdevdde/queue.c @@ -0,0 +1,131 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon + * the rights to redistribute these changes. + */ +/* + * Routines to implement queue package. + */ + +#include "queue.h" + + + +/* + * Insert element at head of queue. + */ +void enqueue_head( + register queue_t que, + register queue_entry_t elt) +{ + elt->next = que->next; + elt->prev = que; + elt->next->prev = elt; + que->next = elt; +} + +/* + * Insert element at tail of queue. + */ +void enqueue_tail( + register queue_t que, + register queue_entry_t elt) +{ + elt->next = que; + elt->prev = que->prev; + elt->prev->next = elt; + que->prev = elt; +} + +/* + * Remove and return element at head of queue. + */ +queue_entry_t dequeue_head( + register queue_t que) +{ + register queue_entry_t elt; + + if (que->next == que) + return((queue_entry_t)0); + + elt = que->next; + elt->next->prev = que; + que->next = elt->next; + return(elt); +} + +/* + * Remove and return element at tail of queue. + */ +queue_entry_t dequeue_tail( + register queue_t que) +{ + register queue_entry_t elt; + + if (que->prev == que) + return((queue_entry_t)0); + + elt = que->prev; + elt->prev->next = que; + que->prev = elt->prev; + return(elt); +} + +/* + * Remove arbitrary element from queue. + * Does not check whether element is on queue - the world + * will go haywire if it isn't. + */ + +/*ARGSUSED*/ +void remqueue( + queue_t que, + register queue_entry_t elt) +{ + elt->next->prev = elt->prev; + elt->prev->next = elt->next; +} + +/* + * Routines to directly imitate the VAX hardware queue + * package. + */ +void insque( + register struct queue_entry *entry, + register struct queue_entry *pred) +{ + entry->next = pred->next; + entry->prev = pred; + (pred->next)->prev = entry; + pred->next = entry; +} + +struct queue_entry +*remque( + register struct queue_entry *elt) +{ + (elt->next)->prev = elt->prev; + (elt->prev)->next = elt->next; + return(elt); +} + diff --git a/libmachdevdde/queue.h b/libmachdevdde/queue.h new file mode 100644 index 000000000..86ef74dc6 --- /dev/null +++ b/libmachdevdde/queue.h @@ -0,0 +1,370 @@ +/* + * Mach Operating System + * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University + * All Rights Reserved. + * + * Permission to use, copy, modify and distribute this software and its + * documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR + * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie Mellon rights + * to redistribute these changes. + */ +/* + * File: queue.h + * Author: Avadis Tevanian, Jr. + * Date: 1985 + * + * Type definitions for generic queues. + * + */ + +#ifndef _KERN_QUEUE_H_ +#define _KERN_QUEUE_H_ + +#include + +/* + * Queue of abstract objects. Queue is maintained + * within that object. + * + * Supports fast removal from within the queue. + * + * How to declare a queue of elements of type "foo_t": + * In the "*foo_t" type, you must have a field of + * type "queue_chain_t" to hold together this queue. + * There may be more than one chain through a + * "foo_t", for use by different queues. + * + * Declare the queue as a "queue_t" type. + * + * Elements of the queue (of type "foo_t", that is) + * are referred to by reference, and cast to type + * "queue_entry_t" within this module. + */ + +/* + * A generic doubly-linked list (queue). + */ + +struct queue_entry { + struct queue_entry *next; /* next element */ + struct queue_entry *prev; /* previous element */ +}; + +typedef struct queue_entry *queue_t; +typedef struct queue_entry queue_head_t; +typedef struct queue_entry queue_chain_t; +typedef struct queue_entry *queue_entry_t; + +/* + * enqueue puts "elt" on the "queue". + * dequeue returns the first element in the "queue". + * remqueue removes the specified "elt" from the specified "queue". + */ + +#define enqueue(queue,elt) enqueue_tail(queue, elt) +#define dequeue(queue) dequeue_head(queue) + +void enqueue_head(queue_t, queue_entry_t); +void enqueue_tail(queue_t, queue_entry_t); +queue_entry_t dequeue_head(queue_t); +queue_entry_t dequeue_tail(queue_t); +void remqueue(queue_t, queue_entry_t); +void insque(queue_entry_t, queue_entry_t); + +/* + * Macro: queue_init + * Function: + * Initialize the given queue. + * Header: + * void queue_init(q) + * queue_t q; *MODIFIED* + */ +#define queue_init(q) ((q)->next = (q)->prev = q) + +/* + * Macro: queue_first + * Function: + * Returns the first entry in the queue, + * Header: + * queue_entry_t queue_first(q) + * queue_t q; *IN* + */ +#define queue_first(q) ((q)->next) + +/* + * Macro: queue_next + * Function: + * Returns the entry after an item in the queue. + * Header: + * queue_entry_t queue_next(qc) + * queue_t qc; + */ +#define queue_next(qc) ((qc)->next) + +/* + * Macro: queue_last + * Function: + * Returns the last entry in the queue. + * Header: + * queue_entry_t queue_last(q) + * queue_t q; *IN* + */ +#define queue_last(q) ((q)->prev) + +/* + * Macro: queue_prev + * Function: + * Returns the entry before an item in the queue. + * Header: + * queue_entry_t queue_prev(qc) + * queue_t qc; + */ +#define queue_prev(qc) ((qc)->prev) + +/* + * Macro: queue_end + * Function: + * Tests whether a new entry is really the end of + * the queue. + * Header: + * boolean_t queue_end(q, qe) + * queue_t q; + * queue_entry_t qe; + */ +#define queue_end(q, qe) ((q) == (qe)) + +/* + * Macro: queue_empty + * Function: + * Tests whether a queue is empty. + * Header: + * boolean_t queue_empty(q) + * queue_t q; + */ +#define queue_empty(q) queue_end((q), queue_first(q)) + + +/*----------------------------------------------------------------*/ +/* + * Macros that operate on generic structures. The queue + * chain may be at any location within the structure, and there + * may be more than one chain. + */ + +/* + * Macro: queue_enter + * Function: + * Insert a new element at the tail of the queue. + * Header: + * void queue_enter(q, elt, type, field) + * queue_t q; + * elt; + * is what's in our queue + * is the chain field in (*) + */ +#define queue_enter(head, elt, type, field) \ +{ \ + register queue_entry_t prev; \ + \ + prev = (head)->prev; \ + if ((head) == prev) { \ + (head)->next = (queue_entry_t) (elt); \ + } \ + else { \ + ((type)prev)->field.next = (queue_entry_t)(elt);\ + } \ + (elt)->field.prev = prev; \ + (elt)->field.next = head; \ + (head)->prev = (queue_entry_t) elt; \ +} + +/* + * Macro: queue_enter_first + * Function: + * Insert a new element at the head of the queue. + * Header: + * void queue_enter_first(q, elt, type, field) + * queue_t q; + * elt; + * is what's in our queue + * is the chain field in (*) + */ +#define queue_enter_first(head, elt, type, field) \ +{ \ + register queue_entry_t next; \ + \ + next = (head)->next; \ + if ((head) == next) { \ + (head)->prev = (queue_entry_t) (elt); \ + } \ + else { \ + ((type)next)->field.prev = (queue_entry_t)(elt);\ + } \ + (elt)->field.next = next; \ + (elt)->field.prev = head; \ + (head)->next = (queue_entry_t) elt; \ +} + +/* + * Macro: queue_field [internal use only] + * Function: + * Find the queue_chain_t (or queue_t) for the + * given element (thing) in the given queue (head) + */ +#define queue_field(head, thing, type, field) \ + (((head) == (thing)) ? (head) : &((type)(thing))->field) + +/* + * Macro: queue_remove + * Function: + * Remove an arbitrary item from the queue. + * Header: + * void queue_remove(q, qe, type, field) + * arguments as in queue_enter + */ +#define queue_remove(head, elt, type, field) \ +{ \ + register queue_entry_t next, prev; \ + \ + next = (elt)->field.next; \ + prev = (elt)->field.prev; \ + \ + if ((head) == next) \ + (head)->prev = prev; \ + else \ + ((type)next)->field.prev = prev; \ + \ + if ((head) == prev) \ + (head)->next = next; \ + else \ + ((type)prev)->field.next = next; \ +} + +/* + * Macro: queue_remove_first + * Function: + * Remove and return the entry at the head of + * the queue. + * Header: + * queue_remove_first(head, entry, type, field) + * entry is returned by reference + */ +#define queue_remove_first(head, entry, type, field) \ +{ \ + register queue_entry_t next; \ + \ + (entry) = (type) ((head)->next); \ + next = (entry)->field.next; \ + \ + if ((head) == next) \ + (head)->prev = (head); \ + else \ + ((type)(next))->field.prev = (head); \ + (head)->next = next; \ +} + +/* + * Macro: queue_remove_last + * Function: + * Remove and return the entry at the tail of + * the queue. + * Header: + * queue_remove_last(head, entry, type, field) + * entry is returned by reference + */ +#define queue_remove_last(head, entry, type, field) \ +{ \ + register queue_entry_t prev; \ + \ + (entry) = (type) ((head)->prev); \ + prev = (entry)->field.prev; \ + \ + if ((head) == prev) \ + (head)->next = (head); \ + else \ + ((type)(prev))->field.next = (head); \ + (head)->prev = prev; \ +} + +/* + * Macro: queue_assign + */ +#define queue_assign(to, from, type, field) \ +{ \ + ((type)((from)->prev))->field.next = (to); \ + ((type)((from)->next))->field.prev = (to); \ + *to = *from; \ +} + +/* + * Macro: queue_iterate + * Function: + * iterate over each item in the queue. + * Generates a 'for' loop, setting elt to + * each item in turn (by reference). + * Header: + * queue_iterate(q, elt, type, field) + * queue_t q; + * elt; + * is what's in our queue + * is the chain field in (*) + */ +#define queue_iterate(head, elt, type, field) \ + for ((elt) = (type) queue_first(head); \ + !queue_end((head), (queue_entry_t)(elt)); \ + (elt) = (type) queue_next(&(elt)->field)) + + + +/*----------------------------------------------------------------*/ +/* + * Define macros for queues with locks. + */ +struct mpqueue_head { + struct queue_entry head; /* header for queue */ + pthread_mutex_t lock; /* lock for queue */ +}; + +typedef struct mpqueue_head mpqueue_head_t; + +#define round_mpq(size) (size) + +#define mpqueue_init(q) \ + { \ + queue_init(&(q)->head); \ + pthread_mutex_init(&(q)->lock, NULL); \ + } + +#define mpenqueue_tail(q, elt) \ + pthread_mutex_lock(&(q)->lock); \ + enqueue_tail(&(q)->head, elt); \ + pthread_mutex_unlock(&(q)->lock); + +#define mpdequeue_head(q, elt) \ + pthread_mutex_lock(&(q)->lock); \ + if (queue_empty(&(q)->head)) \ + *(elt) = 0; \ + else \ + *(elt) = dequeue_head(&(q)->head); \ + pthread_mutex_unlock(&(q)->lock); + +/* + * Old queue stuff, will go away soon. + */ + +#endif /* _KERN_QUEUE_H_ */ diff --git a/libmachdevdde/trivfs_server.c b/libmachdevdde/trivfs_server.c new file mode 100644 index 000000000..3c0578fa0 --- /dev/null +++ b/libmachdevdde/trivfs_server.c @@ -0,0 +1,171 @@ +#include +#include +#include +#include +#include +#include +#include + +#include "device_S.h" +#include "notify_S.h" + +static struct port_bucket *port_bucket; + +/* Trivfs hooks. */ +int trivfs_fstype = FSTYPE_MISC; +int trivfs_fsid = 0; +int trivfs_support_read = 0; +int trivfs_support_write = 0; +int trivfs_support_exec = 0; +int trivfs_allow_open = O_READ | O_WRITE; + +/* Our port classes. */ +struct port_class *trivfs_protid_class; +struct port_class *trivfs_cntl_class; + +/* Implementation of notify interface */ +kern_return_t +do_mach_notify_port_deleted (struct port_info *pi, + mach_port_t name) +{ + return EOPNOTSUPP; +} + +kern_return_t +do_mach_notify_msg_accepted (struct port_info *pi, + mach_port_t name) +{ + return EOPNOTSUPP; +} + +kern_return_t +do_mach_notify_port_destroyed (struct port_info *pi, + mach_port_t port) +{ + return EOPNOTSUPP; +} + +kern_return_t +do_mach_notify_no_senders (struct port_info *pi, + mach_port_mscount_t mscount) +{ + return ports_do_mach_notify_no_senders (pi, mscount); +} + +kern_return_t +do_mach_notify_send_once (struct port_info *pi) +{ + return EOPNOTSUPP; +} + +kern_return_t +do_mach_notify_dead_name (struct port_info *pi, + mach_port_t name) +{ + return EOPNOTSUPP; +} + +boolean_t +is_master_device (mach_port_t port) +{ + struct port_info *pi = ports_lookup_port (port_bucket, port, + trivfs_protid_class); + if (pi == NULL) + return FALSE; + + ports_port_deref (pi); + return TRUE; +} + +error_t +trivfs_append_args (struct trivfs_control *fsys, char **argz, size_t *argz_len) +{ + error_t err = 0; + +#define ADD_OPT(fmt, args...) \ + do { char buf[100]; \ + if (! err) { \ + snprintf (buf, sizeof buf, fmt , ##args); \ + err = argz_add (argz, argz_len, buf); } } while (0) + +#undef ADD_OPT + return err; +} + +int trivfs_init() +{ + port_bucket = ports_create_bucket (); + trivfs_cntl_class = ports_create_class (trivfs_clean_cntl, 0); + trivfs_protid_class = ports_create_class (trivfs_clean_protid, 0); + return 0; +} + +error_t +trivfs_goaway (struct trivfs_control *fsys, int flags) +{ + int count; + + /* Stop new requests. */ + ports_inhibit_class_rpcs (trivfs_cntl_class); + ports_inhibit_class_rpcs (trivfs_protid_class); + + count = ports_count_class (trivfs_protid_class); + + if (count && !(flags & FSYS_GOAWAY_FORCE)) + { + /* We won't go away, so start things going again... */ + ports_enable_class (trivfs_protid_class); + ports_resume_class_rpcs (trivfs_cntl_class); + ports_resume_class_rpcs (trivfs_protid_class); + return EBUSY; + } + + pci_system_cleanup (); + exit (0); +} + +static int +demuxer (mach_msg_header_t *inp, mach_msg_header_t *outp) +{ + mig_routine_t routine; + if ((routine = device_server_routine (inp)) || + (routine = notify_server_routine (inp)) || + (routine = NULL, trivfs_demuxer (inp, outp))) + { + if (routine) + (*routine) (inp, outp); + return TRUE; + } + else + return FALSE; +} + +void +trivfs_modify_stat (struct trivfs_protid *cred, io_statbuf_t *stat) +{ +} + +void trivfs_server() +{ + mach_port_t bootstrap; + struct trivfs_control *fsys; + int err; + + task_get_bootstrap_port (mach_task_self (), &bootstrap); + if (bootstrap == MACH_PORT_NULL) + error (1, 0, "must be started as a translator"); + + /* Reply to our parent. */ + err = trivfs_startup (bootstrap, 0, + trivfs_cntl_class, port_bucket, + trivfs_protid_class, port_bucket, &fsys); + mach_port_deallocate (mach_task_self (), bootstrap); + if (err) + error (1, err, "Contacting parent"); + + /* Launch. */ + do + { + ports_manage_port_operations_one_thread (port_bucket, demuxer, 0); + } while (trivfs_goaway (fsys, 0)); +} diff --git a/libmachdevdde/util.h b/libmachdevdde/util.h new file mode 100644 index 000000000..1c62b0d6c --- /dev/null +++ b/libmachdevdde/util.h @@ -0,0 +1,35 @@ +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include + +#define panic(format, ...) do \ +{ \ + char buf[1024]; \ + snprintf (buf, 1024, "devnode: %s", format); \ + fprintf (stderr , buf, ## __VA_ARGS__); \ + fflush (stderr); \ + abort (); \ +} while (0) + +#define DEBUG + +#ifdef DEBUG + +#define debug(format, ...) do \ +{ \ + char buf[1024]; \ + snprintf (buf, 1024, "pcnet32: %s: %s\n", __func__, format); \ + fprintf (stderr , buf, ## __VA_ARGS__); \ + fflush (stderr); \ +} while (0) + +#else + +#define debug(format, ...) do {} while (0) + +#endif + +int linux_to_mach_error (int err); + +#endif diff --git a/libmachdevdde/vm_param.h b/libmachdevdde/vm_param.h new file mode 100644 index 000000000..7b615c8a0 --- /dev/null +++ b/libmachdevdde/vm_param.h @@ -0,0 +1,7 @@ +#ifndef __VM_PARAM_H__ +#define __VM_PARAM_H__ + +#define PAGE_SIZE __vm_page_size +#define PAGE_MASK (PAGE_SIZE-1) + +#endif diff --git a/windhoek/Makefile b/windhoek/Makefile index 91646bba0..08723913e 100644 --- a/windhoek/Makefile +++ b/windhoek/Makefile @@ -27,7 +27,7 @@ SRC_C += $(IDEFILES) \ $(CDROMFILES) \ $(PARTITIONFILES) -LIBS += --whole-archive --no-whole-archive ../libmachdev/libmachdev.a \ +LIBS += --whole-archive --no-whole-archive ../libmachdevdde/libmachdevdde.a \ -ldde_linux26.o -ldde_linux26_block ../libddekit/libddekit.a \ -lfshelp -ltrivfs -lpciaccess -lthreads -lshouldbeinlibc \ -lports -lhurd-slab -- cgit v1.2.3