diff options
author | Justus Winter <justus@gnupg.org> | 2016-02-25 22:38:40 +0100 |
---|---|---|
committer | Justus Winter <justus@gnupg.org> | 2016-02-25 22:38:40 +0100 |
commit | e1e25cd0a5f5778cf4f1e83321c8d081e2067683 (patch) | |
tree | 2ac6b7185f2c834ce1c2c4173cf2aa96f8afbbf3 /device | |
parent | 652cbc1f88f02f92096051a7ce13dcbf77e55fc4 (diff) |
Some cleanups of the userspace interrupt handling
Diffstat (limited to 'device')
-rw-r--r-- | device/intr.c | 93 |
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; |