summaryrefslogtreecommitdiff
path: root/device
diff options
context:
space:
mode:
authorJustus Winter <justus@gnupg.org>2016-02-25 22:38:40 +0100
committerJustus Winter <justus@gnupg.org>2016-02-25 22:38:40 +0100
commite1e25cd0a5f5778cf4f1e83321c8d081e2067683 (patch)
tree2ac6b7185f2c834ce1c2c4173cf2aa96f8afbbf3 /device
parent652cbc1f88f02f92096051a7ce13dcbf77e55fc4 (diff)
Some cleanups of the userspace interrupt handling
Diffstat (limited to 'device')
-rw-r--r--device/intr.c93
1 files changed, 46 insertions, 47 deletions
diff --git a/device/intr.c b/device/intr.c
index 986f0ee..177c095 100644
--- a/device/intr.c
+++ b/device/intr.c
@@ -25,18 +25,6 @@ static queue_head_t intr_queue;
/* The total number of unprocessed interrupts. */
static int tot_num_intr;
-static struct intr_entry *
-search_intr (int line, ipc_port_t dest)
-{
- struct intr_entry *e;
- queue_iterate (&intr_queue, e, struct intr_entry *, chain)
- {
- if (e->dest == dest && e->line == line)
- return e;
- }
- return NULL;
-}
-
/* This function can only be used in the interrupt handler. */
boolean_t
queue_intr (struct intr_entry *e)
@@ -46,9 +34,10 @@ queue_intr (struct intr_entry *e)
* been destroyed and I destroy it now. */
if (e->dest && e->dest->ip_references == 1)
{
+ /* JW: I don't like running this from an interrupt handler. */
ipc_port_release (e->dest);
e->dest = NULL;
- printk ("irq handler %d: release an dead delivery port\n", e->line);
+ printf ("irq handler %d: release an dead delivery port\n", e->line);
return FALSE;
}
@@ -74,21 +63,22 @@ insert_intr_entry (int line, ipc_port_t dest, struct intr_entry **entry)
new = (struct intr_entry *) kalloc (sizeof (*new));
if (new == NULL)
return D_NO_MEMORY;
-
- /* check whether the intr entry has been in the queue. */
- cli ();
- e = search_intr (line, dest);
- if (e)
- {
- printf ("the interrupt entry for line %d and port %p has been inserted\n",
- line, dest);
- free = 1;
- err = D_ALREADY_OPEN;
- goto out;
- }
new->line = line;
new->dest = dest;
new->interrupts = 0;
+
+ /* check whether the intr entry has been in the queue. */
+ cli ();
+ queue_iterate (&intr_queue, e, struct intr_entry *, chain)
+ if (e->dest == dest && e->line == line)
+ {
+ printf ("the interrupt entry for line %d and port %p "
+ "has already been inserted before.\n",
+ line, dest);
+ free = 1;
+ err = D_ALREADY_OPEN;
+ goto out;
+ }
queue_enter (&intr_queue, new, struct intr_entry *, chain);
out:
sti ();
@@ -98,6 +88,30 @@ out:
return err;
}
+mach_intr_notification_t mach_intr_notification_template;
+
+static void
+init_mach_intr_notification (mach_intr_notification_t *n)
+{
+ mach_msg_header_t *m = &n->intr_header;
+ mach_msg_type_t *t = &n->intr_type;
+
+ m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0);
+ m->msgh_size = sizeof *n;
+ m->msgh_seqno = INTR_NOTIFY_MSGH_SEQNO;
+ m->msgh_local_port = MACH_PORT_NULL;
+ m->msgh_remote_port = MACH_PORT_NULL;
+ m->msgh_id = MACH_INTR_NOTIFY;
+
+ t->msgt_name = MACH_MSG_TYPE_INTEGER_32;
+ t->msgt_size = 32;
+ t->msgt_number = 1;
+ t->msgt_inline = TRUE;
+ t->msgt_longform = FALSE;
+ t->msgt_deallocate = FALSE;
+ t->msgt_unused = 0;
+}
+
void
intr_thread ()
{
@@ -105,10 +119,10 @@ intr_thread ()
int line;
ipc_port_t dest;
queue_init (&intr_queue);
-
+ init_mach_intr_notification (&mach_intr_notification_template);
+
for (;;)
{
- assert_wait ((event_t) &intr_thread, FALSE);
cli ();
while (tot_num_intr)
{
@@ -148,7 +162,9 @@ intr_thread ()
}
}
sti ();
- thread_block (NULL);
+
+ assert_wait ((event_t) &intr_thread, FALSE);
+ thread_block (thread_no_continuation);
}
}
@@ -163,29 +179,12 @@ deliver_intr (int line, ipc_port_t dest_port)
return FALSE;
kmsg = ikm_alloc(sizeof *n);
- if (kmsg == IKM_NULL)
+ if (kmsg == IKM_NULL)
return FALSE;
ikm_init(kmsg, sizeof *n);
n = (mach_intr_notification_t *) &kmsg->ikm_header;
-
- mach_msg_header_t *m = &n->intr_header;
- mach_msg_type_t *t = &n->intr_type;
-
- m->msgh_bits = MACH_MSGH_BITS(MACH_MSG_TYPE_PORT_SEND, 0);
- m->msgh_size = sizeof *n;
- m->msgh_seqno = INTR_NOTIFY_MSGH_SEQNO;
- m->msgh_local_port = MACH_PORT_NULL;
- m->msgh_remote_port = MACH_PORT_NULL;
- m->msgh_id = MACH_INTR_NOTIFY;
-
- t->msgt_name = MACH_MSG_TYPE_INTEGER_32;
- t->msgt_size = 32;
- t->msgt_number = 1;
- t->msgt_inline = TRUE;
- t->msgt_longform = FALSE;
- t->msgt_deallocate = FALSE;
- t->msgt_unused = 0;
+ *n = mach_intr_notification_template;
n->intr_header.msgh_remote_port = dest;
n->line = line;