summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoland McGrath <roland@gnu.org>2003-02-28 08:55:18 +0000
committerThomas Schwinge <tschwinge@gnu.org>2009-06-17 23:50:21 +0200
commitdc111f3b3ea4c1c7296006911e578392516c7faa (patch)
tree4de9bf77056dde283d01f8b6a1a50e37cdae316c
parent0f6d506d705226d2f87830e0fa9ea83d733a444e (diff)
2003-02-28 Roland McGrath <roland@frob.com>
* oskit/osenv_irq.c (console_irq, console_irq_handler): New variables. (irq_alloc, irq_free): Implement special kludge with console_irq. * oskit/ds_osenv.c (ds_osenv_init): Set console_irq before initializing the minimal interrupt-driven console.
-rw-r--r--oskit/ds_osenv.c4
-rw-r--r--oskit/osenv_irq.c59
2 files changed, 58 insertions, 5 deletions
diff --git a/oskit/ds_osenv.c b/oskit/ds_osenv.c
index 407556bb..13591161 100644
--- a/oskit/ds_osenv.c
+++ b/oskit/ds_osenv.c
@@ -16,6 +16,8 @@ extern int serial_console; /* base_console_init.c */
oskit_stream_t *ds_console_stream;
+extern int console_irq; /* kludge in osenv_irq.c */
+
void
ds_osenv_init (void)
@@ -44,6 +46,7 @@ ds_osenv_init (void)
param.c_lflag &= ~ECHO;
param.c_iflag &= ~ICRNL;
param.c_oflag &= ~OPOST;
+ console_irq = -1;
rc = cq_com_console_init (port, &param,
oskit_create_osenv_irq (),
intr,
@@ -53,6 +56,7 @@ ds_osenv_init (void)
else
{
oskit_osenv_intr_t *intr = oskit_create_osenv_intr ();
+ console_irq = -1;
rc = cq_direct_console_init (oskit_create_osenv_irq (),
intr,
oskit_create_osenv_sleep (intr),
diff --git a/oskit/osenv_irq.c b/oskit/osenv_irq.c
index 8ebb92e5..0d7c1a7f 100644
--- a/oskit/osenv_irq.c
+++ b/oskit/osenv_irq.c
@@ -118,6 +118,16 @@ irq_release(oskit_osenv_irq_t *s)
return 1;
}
+
+/* This is a special kludge for the minimal console. If console_irq is -1
+ during the first irq_alloc, we set it to the irq being allocated.
+ Thereafter, allocating that irq will silently succeed and override
+ the handler installed for the minimal console, which we save in
+ console_irq_handler; freeing that irq will restore the console handler. */
+
+int console_irq;
+static struct int_handler *console_irq_handler;
+
static OSKIT_COMDECL_U
irq_alloc(oskit_osenv_irq_t *o, int irq,
void (*handler)(void *), void *data, int flags)
@@ -153,6 +163,29 @@ irq_alloc(oskit_osenv_irq_t *o, int irq,
temp->data = data;
temp->next = NULL;
+ /* Special hack for the minimal com and direct console devices. */
+ if (console_irq == -1) {
+ /* ds_osenv_init sets console_irq to -1 while initializing the
+ console, so we know this is the irq being allocated for it.
+ XXX we assume there is only one!
+ */
+ assert (first_time);
+ console_irq = irq;
+ }
+ else if (irq == console_irq && console_irq_handler == NULL) {
+ /* Attempting to re-allocate the console's irq.
+ This must be a real device driver taking over
+ from the minimal console. Let it. */
+ assert (! first_time);
+ assert (handlers[irq] != NULL);
+ console_irq_handler = handlers[irq];
+ osenv_log(OSENV_LOG_DEBUG,
+ "irq %d stolen from console\n", irq);
+ handlers[irq] = temp;
+ shareable[irq] = (flags & OSENV_IRQ_SHAREABLE) != 0;
+ return 0;
+ }
+
/*
* Fail if the irq is already in use
* and either the new handler or the existing handler
@@ -208,11 +241,27 @@ irq_free(oskit_osenv_irq_t *o, int irq,
if (temp != NULL &&
temp->func == handler && temp->data == data &&
temp->next == NULL) {
- osenv_irq_disable(irq);
- handlers[irq] = NULL;
- intpri[irq] = SPL0;
- ivect[irq] = intnull;
- iunit[irq] = irq;
+ if (irq == console_irq) {
+ /* Special hack for the minimal console's irq.
+ Restore the console's handler now that no real
+ driver is using it.
+ XXX this is probably not actually useful since
+ the driver won't have left the device in the same
+ state the minimal console driver expects.
+ */
+ handlers[irq] = console_irq_handler;
+ shareable[irq] = 0;
+ console_irq_handler = NULL;
+ osenv_log(OSENV_LOG_DEBUG,
+ "irq %d returned to console\n", irq);
+ }
+ else {
+ osenv_irq_disable(irq);
+ handlers[irq] = NULL;
+ intpri[irq] = SPL0;
+ ivect[irq] = intnull;
+ iunit[irq] = irq;
+ }
kfree(temp, sizeof(struct int_handler));
return;
}