summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--deva/ChangeLog14
-rw-r--r--deva/Makefile.am3
-rw-r--r--deva/deva.c10
-rw-r--r--deva/deva.h18
-rw-r--r--deva/device-console.c (renamed from deva/deva-class.c)163
-rw-r--r--deva/device.c146
-rw-r--r--deva/device.h73
7 files changed, 295 insertions, 132 deletions
diff --git a/deva/ChangeLog b/deva/ChangeLog
index 2018351..a5ea0cd 100644
--- a/deva/ChangeLog
+++ b/deva/ChangeLog
@@ -1,3 +1,17 @@
+2005-02-01 Marcus Brinkmann <marcus@gnu.org>
+
+ * deva.h (deva_alloc): Renamed to device_alloc.
+ (deva_class_init): Renamed to device_class_init and add new device
+ type argument.
+ (enum device_type): New enum.
+ * deva.c (create_bootstrap_caps): Call device_alloc, not
+ deva_alloc, and pass device type argument.
+ (main): Call device_class_init, not deva_class_init.
+ * deva-class.c: Removed file.
+ * device.h, device.c, device-console.c: New files.
+ * Makefile.am (deva_SOURCES): Remove deva-class.c and add
+ device.h, device.c, device-console.c.
+
2005-01-11 Neal H. Walfield <neal@gnu.org>
* Makefile.am (deva_SOURCES): Remove physmem-user.h and
diff --git a/deva/Makefile.am b/deva/Makefile.am
index bffa984..9ab43c1 100644
--- a/deva/Makefile.am
+++ b/deva/Makefile.am
@@ -32,7 +32,8 @@ deva_SOURCES = $(ARCH_SOURCES) \
output.h output.c \
mmap.c malloc-wrap.c \
task-user.h task-user.c \
- deva.h deva.c deva-class.c
+ deva.h deva.c \
+ device.h device.c device-console.c device-serial.c
# Doug Lea's malloc is included by malloc-wrap.c.
EXTRA_deva_SOURCES = malloc.c
diff --git a/deva/deva.c b/deva/deva.c
index 7597d59..47c44d2 100644
--- a/deva/deva.c
+++ b/deva/deva.c
@@ -77,9 +77,9 @@ create_bootstrap_caps (hurd_cap_bucket_t bucket)
l4_accept (L4_UNTYPED_WORDS_ACCEPTOR);
/* FIXME: Allocate a system console driver. */
- err = deva_alloc (&obj);
+ err = device_alloc (&obj, DEVICE_CONSOLE);
if (err)
- panic ("deva_alloc: %i\n", err);
+ panic ("device_alloc: %i\n", err);
hurd_cap_obj_unlock (obj);
while (1)
@@ -101,7 +101,7 @@ create_bootstrap_caps (hurd_cap_bucket_t bucket)
}
else
{
- debug ("Creating deva cap for 0x%x:", task_id);
+ debug ("Creating console device cap for 0x%x:", task_id);
err = hurd_cap_bucket_inject (bucket, obj, task_id, &cap);
if (err)
@@ -232,9 +232,9 @@ main (int argc, char *argv[])
server_thread = setup_threads ();
- err = deva_class_init ();
+ err = device_class_init ();
if (err)
- panic ("deva_class_init: %i\n", err);
+ panic ("device_class_init: %i\n", err);
err = hurd_cap_bucket_create (&bucket);
if (err)
diff --git a/deva/deva.h b/deva/deva.h
index 6b52fb5..f2a47a5 100644
--- a/deva/deva.h
+++ b/deva/deva.h
@@ -42,11 +42,17 @@ int main (int argc, char *argv[]);
void switch_thread (l4_thread_id_t from, l4_thread_id_t to);
-/* Deva objects. */
+/* Device objects. */
-/* Initialize the task class subsystem. */
-error_t deva_class_init ();
+/* Initialize the device class subsystem. */
+error_t device_class_init ();
-/* Allocate a new deva object. The object returned is locked and has
- one reference. */
-error_t deva_alloc (hurd_cap_obj_t *r_obj);
+enum device_type
+ {
+ DEVICE_CONSOLE = 0,
+ DEVICE_SERIAL = 1
+ };
+
+/* Allocate a new device object. The object returned is locked and
+ has one reference. */
+error_t device_alloc (hurd_cap_obj_t *r_obj, enum device_type type);
diff --git a/deva/deva-class.c b/deva/device-console.c
index dd7acb3..6185b85 100644
--- a/deva/deva-class.c
+++ b/deva/device-console.c
@@ -1,5 +1,5 @@
-/* deva-class.c - Deva class for the deva server.
- Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+/* device-console.c - A small console device, until we have the real thing.
+ Copyright (C) 2005 Free Software Foundation, Inc.
Written by Marcus Brinkmann.
This file is part of the GNU Hurd.
@@ -23,32 +23,27 @@
#include <config.h>
#endif
-#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
+#include <sys/io.h>
#include <l4.h>
-#include <hurd/cap-server.h>
+
#include <hurd/wortel.h>
-#include "deva.h"
+#include "output.h"
+
+#include "device.h"
+
/* Do not even think about improving the console! The code here is
only for testing. Go do something useful. Work on the real device
driver framework. */
-#define SIMPLE_CONSOLE 1
-
-#ifdef SIMPLE_CONSOLE
-
-#include <sys/io.h>
-
-pthread_mutex_t console_lock = PTHREAD_MUTEX_INITIALIZER;
-pthread_cond_t console_cond = PTHREAD_COND_INITIALIZER;
-#define CONSOLE_MAX 256
-unsigned char console_input[CONSOLE_MAX];
-unsigned int console_input_len;
static void *
-console_irq_handler (void *unused)
+console_irq_handler (void *_console)
{
+ device_t *dev = (device_t *) _console;
l4_word_t result;
l4_thread_id_t irq;
l4_msg_tag_t tag;
@@ -87,12 +82,12 @@ console_irq_handler (void *unused)
b = '\x00';
}
- pthread_mutex_lock (&console_lock);
+ pthread_mutex_lock (&dev->console.lock);
if (b == '\x1b')
asm volatile ("int $3");
else if (b != '\x00')
{
- if (console_input_len == CONSOLE_MAX)
+ if (dev->console.input_len == CONSOLE_MAX)
{
putchar ('^');
putchar ('G');
@@ -100,12 +95,12 @@ console_irq_handler (void *unused)
else
{
putchar (b);
- if (!console_input_len)
- pthread_cond_broadcast (&console_cond);
- console_input[console_input_len++] = b;
+ if (!dev->console.input_len)
+ pthread_cond_broadcast (&dev->console.cond);
+ dev->console.input[dev->console.input_len++] = b;
}
}
- pthread_mutex_unlock (&console_lock);
+ pthread_mutex_unlock (&dev->console.lock);
l4_load_mr (0, 0);
l4_reply_receive (irq);
@@ -114,7 +109,7 @@ console_irq_handler (void *unused)
static void
-console_init (void)
+console_init (device_t *dev)
{
error_t err;
l4_thread_id_t irq_handler_tid;
@@ -126,127 +121,55 @@ console_init (void)
err = pthread_create_from_l4_tid_np (&irq_handler, NULL,
irq_handler_tid, console_irq_handler,
- NULL);
+ dev);
if (err)
panic ("Can not create the irq handler thread: %i", err);
pthread_detach (irq_handler);
}
-#endif /* SIMPLE_CONSOLE */
-
-
-struct deva
-{
- /* FIXME: More stuff. */
- int foo;
-};
-typedef struct deva *deva_t;
-
-
-static void
-deva_reinit (hurd_cap_class_t cap_class, hurd_cap_obj_t obj)
-{
- deva_t deva = hurd_cap_obj_to_user (deva_t, obj);
-
- /* FIXME: Release resources. */
-}
-
-error_t
-deva_io_read (hurd_cap_rpc_context_t ctx)
+static error_t
+console_io_read (device_t *dev, int *chr)
{
-#ifdef SIMPLE_CONSOLE
unsigned char b = '\x00';
-
- pthread_mutex_lock (&console_lock);
- while (!console_input_len)
- pthread_cond_wait (&console_cond, &console_lock);
- b = console_input[--console_input_len];
- pthread_mutex_unlock (&console_lock);
- /* Prepare reply message. */
- l4_msg_clear (ctx->msg);
- l4_msg_append_word (ctx->msg, (l4_word_t) b);
+ pthread_mutex_lock (&dev->console.lock);
+ while (!dev->console.input_len)
+ pthread_cond_wait (&dev->console.cond, &dev->console.lock);
+ b = dev->console.input[0];
+ dev->console.input_len--;
+ memmove (&dev->console.input[0], &dev->console.input[1],
+ dev->console.input_len);
+ pthread_mutex_unlock (&dev->console.lock);
+
+ *chr = b;
-#endif
return 0;
}
-error_t
-deva_io_write (hurd_cap_rpc_context_t ctx)
+static error_t
+console_io_write (device_t *dev, int chr)
{
-#ifdef SIMPLE_CONSOLE
- l4_word_t chr;
-
- chr = l4_msg_word (ctx->msg, 1);
putchar ((unsigned char) chr);
-#endif
return 0;
}
-
-error_t
-deva_demuxer (hurd_cap_rpc_context_t ctx)
-{
- error_t err = 0;
-
- switch (l4_msg_label (ctx->msg))
- {
- /* DEVA_IO_READ */
- case 768:
- err = deva_io_read (ctx);
- break;
-
- /* DEVA_IO_WRITE */
- case 769:
- err = deva_io_write (ctx);
- break;
-
- default:
- err = EOPNOTSUPP;
- }
-
- return err;
-}
-
-
-static struct hurd_cap_class deva_class;
-
-/* Initialize the deva class subsystem. */
+/* Create a new console device in DEV. */
error_t
-deva_class_init ()
+device_console_init (device_t *dev)
{
-#ifdef SIMPLE_CONSOLE
- console_init ();
-#endif
-
- return hurd_cap_class_init (&deva_class, deva_t,
- NULL, NULL, deva_reinit, NULL,
- deva_demuxer);
-}
-
-
-/* Allocate a new deva object. The object returned is locked and has
- one reference. */
-error_t
-deva_alloc (hurd_cap_obj_t *r_obj)
-{
- error_t err;
- hurd_cap_obj_t obj;
- deva_t deva;
-
- err = hurd_cap_class_alloc (&deva_class, &obj);
- if (err)
- return err;
-
- deva = hurd_cap_obj_to_user (deva_t, obj);
+ dev->io_read = console_io_read;
+ dev->io_write = console_io_write;
+ dev->console.lock = (pthread_mutex_t) PTHREAD_MUTEX_INITIALIZER;
+ dev->console.cond = (pthread_cond_t) PTHREAD_COND_INITIALIZER;
+ dev->console.input_len = 0;
- /* FIXME: Add some stuff. */
+ /* We know this is only called once, so what the hell. */
+ console_init (dev);
- *r_obj = obj;
return 0;
}
diff --git a/deva/device.c b/deva/device.c
new file mode 100644
index 0000000..5494c5c
--- /dev/null
+++ b/deva/device.c
@@ -0,0 +1,146 @@
+/* deva-class.c - Deva class for the deva server.
+ Copyright (C) 2003, 2004 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#if HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <l4.h>
+#include <hurd/cap-server.h>
+
+#include "deva.h"
+#include "device.h"
+
+
+static void
+device_reinit (hurd_cap_class_t cap_class, hurd_cap_obj_t obj)
+{
+ device_t *dev = hurd_cap_obj_to_user (device_t *, obj);
+
+ /* FIXME: Release resources. */
+}
+
+
+static error_t
+device_io_read (hurd_cap_rpc_context_t ctx)
+{
+ error_t err;
+ device_t *dev = hurd_cap_obj_to_user (device_t *, ctx->obj);
+ int chr;
+
+ err = (*dev->io_read) (dev, &chr);
+ if (err)
+ return err;
+
+ /* Prepare reply message. */
+ l4_msg_clear (ctx->msg);
+ l4_msg_append_word (ctx->msg, (l4_word_t) chr);
+
+ return 0;
+}
+
+
+static error_t
+device_io_write (hurd_cap_rpc_context_t ctx)
+{
+ device_t *dev = hurd_cap_obj_to_user (device_t *, ctx->obj);
+ int chr;
+
+ chr = (int) l4_msg_word (ctx->msg, 1);
+
+ return (*dev->io_write) (dev, chr);
+}
+
+
+static error_t
+device_demuxer (hurd_cap_rpc_context_t ctx)
+{
+ error_t err = 0;
+
+ switch (l4_msg_label (ctx->msg))
+ {
+ /* DEVICE_IO_READ */
+ case 768:
+ err = device_io_read (ctx);
+ break;
+
+ /* DEVICE_IO_WRITE */
+ case 769:
+ err = device_io_write (ctx);
+ break;
+
+ default:
+ err = EOPNOTSUPP;
+ }
+
+ return err;
+}
+
+
+
+static struct hurd_cap_class device_class;
+
+/* Initialize the device class subsystem. */
+error_t
+device_class_init ()
+{
+ return hurd_cap_class_init (&device_class, device_t *,
+ NULL, NULL, device_reinit, NULL,
+ device_demuxer);
+}
+
+
+/* Allocate a new device object. The object returned is locked and
+ has one reference. */
+error_t
+device_alloc (hurd_cap_obj_t *r_obj, enum device_type type)
+{
+ error_t err;
+ hurd_cap_obj_t obj;
+ device_t *dev;
+
+ err = hurd_cap_class_alloc (&device_class, &obj);
+ if (err)
+ return err;
+
+ dev = hurd_cap_obj_to_user (device_t *, obj);
+
+ switch (type)
+ {
+ case DEVICE_CONSOLE:
+ device_console_init (dev);
+ break;
+
+ case DEVICE_SERIAL:
+#if 0
+ device_serial_init (dev);
+#endif
+ break;
+
+ default:
+ break;
+ }
+
+ *r_obj = obj;
+ return 0;
+}
diff --git a/deva/device.h b/deva/device.h
new file mode 100644
index 0000000..03491d8
--- /dev/null
+++ b/deva/device.h
@@ -0,0 +1,73 @@
+/* device.h - A small device interface, until we have the real thing.
+ Copyright (C) 2005 Free Software Foundation, Inc.
+ Written by Marcus Brinkmann.
+
+ 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 Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, 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
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef DEVICE_H
+#define DEVICE_H 1
+
+#include <errno.h>
+
+
+typedef struct device device_t;
+
+struct device
+{
+ /* Read a single character from DEV and return it in CHR. */
+ error_t (*io_read) (device_t *dev, int *chr);
+
+ /* Write the single character CHR to DEV. */
+ error_t (*io_write) (device_t *dev, int chr);
+
+ /* Private data area. */
+ union
+ {
+ /* The data used by the console driver. */
+ struct console_data
+ {
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+#define CONSOLE_MAX 256
+ unsigned char input[CONSOLE_MAX];
+ unsigned int input_len;
+ } console;
+
+ /* The data used by the serial driver. */
+ struct serial_data
+ {
+ pthread_mutex_t lock;
+ pthread_cond_t cond;
+#define SERIAL_MAX 128
+ unsigned char input[SERIAL_MAX];
+ unsigned int input_len;
+ unsigned char output[SERIAL_MAX];
+ unsigned int output_len;
+ } serial;
+ };
+};
+;
+
+
+/* Create a new console device in DEV. */
+error_t device_console_init (device_t *dev);
+
+/* Create a new serial device in DEV. */
+error_t device_serial_init (device_t *dev);
+
+#endif /* DEVICE_H */