summaryrefslogtreecommitdiff
path: root/device
diff options
context:
space:
mode:
authorJustus Winter <justus@gnupg.org>2016-02-28 00:12:03 +0100
committerJustus Winter <justus@gnupg.org>2016-02-28 00:15:22 +0100
commit21d23d630eef3e4d830486389ecdee4bfd6c504a (patch)
tree5b6ea5a13a6bd0fd99fe006e2f729f8189a4666a /device
parent7ae251bd9cdc26e03eb3300ace23209bc50493e6 (diff)
Cleanupsjustus/dde-0
Diffstat (limited to 'device')
-rw-r--r--device/ds_routines.c23
-rw-r--r--device/ds_routines.h3
-rw-r--r--device/interrupt.h3
-rw-r--r--device/intr.c74
4 files changed, 41 insertions, 62 deletions
diff --git a/device/ds_routines.c b/device/ds_routines.c
index d866acc..ec26044 100644
--- a/device/ds_routines.c
+++ b/device/ds_routines.c
@@ -326,7 +326,6 @@ experimental_device_intr_register (ipc_port_t master_port, int line,
#ifdef MACH_XEN
return D_INVALID_OPERATION;
#else /* MACH_XEN */
- struct intr_entry *entry;
io_return_t ret;
/* Open must be called on the master device port. */
@@ -336,15 +335,7 @@ experimental_device_intr_register (ipc_port_t master_port, int line,
if (receive_port == IP_NULL)
return D_INVALID_OPERATION;
- /* XXX: move to arch-specific */
- if (line < 0 || line >= 16)
- return D_INVALID_OPERATION;
-
- ret = insert_intr_entry (line, receive_port, &entry);
- if (ret)
- return ret;
-
- return install_user_intr_handler (line, flags, entry);
+ return insert_intr_entry (line, receive_port);
#endif /* MACH_XEN */
}
@@ -1832,18 +1823,6 @@ kern_return_t
experimental_device_intr_enable(ipc_port_t master_port, int line, char status)
{
return D_INVALID_OPERATION;
-#ifdef MACH_XEN
- return D_INVALID_OPERATION;
-#else /* MACH_XEN */
- if (master_port != master_device_port)
- return D_INVALID_OPERATION;
-
- if (! status)
- return D_INVALID_OPERATION;
-
- enable_irq (line);
- return 0;
-#endif /* MACH_XEN */
}
struct device_emulation_ops mach_device_emulation_ops =
diff --git a/device/ds_routines.h b/device/ds_routines.h
index e9f115f..c0543cb 100644
--- a/device/ds_routines.h
+++ b/device/ds_routines.h
@@ -83,7 +83,4 @@ io_return_t ds_device_writev_trap(
io_buf_vec_t *iovec,
vm_size_t count);
-/* XXX arch-specific */
-extern ipc_port_t intr_rcv_ports[16];
-
#endif /* DS_ROUTINES_H */
diff --git a/device/interrupt.h b/device/interrupt.h
index 1987ffc..855f163 100644
--- a/device/interrupt.h
+++ b/device/interrupt.h
@@ -20,8 +20,7 @@
struct intr_entry;
boolean_t queue_intr (struct intr_entry *e);
-kern_return_t insert_intr_entry (int line, ipc_port_t dest,
- struct intr_entry **entry);
+kern_return_t insert_intr_entry (int line, ipc_port_t notification_port);
boolean_t intr_entry_notify (mach_msg_header_t *msg);
void intr_thread (void);
diff --git a/device/intr.c b/device/intr.c
index 20a888c..85915cd 100644
--- a/device/intr.c
+++ b/device/intr.c
@@ -35,7 +35,7 @@ struct intr_entry
{
ipc_port_t port; /* We receive notifications on this port. */
queue_chain_t chain;
- ipc_port_t dest;
+ ipc_port_t notification_port;
int line;
/* The number of interrupts occur since last run of intr_thread. */
int interrupts;
@@ -62,9 +62,7 @@ queue_intr (struct intr_entry *e)
* This entry exists in the queue until
* the corresponding interrupt port is removed.*/
kern_return_t
-insert_intr_entry (int line,
- ipc_port_t dest,
- struct intr_entry **entry)
+insert_intr_entry (int line, ipc_port_t notification_port)
{
kern_return_t err = 0;
unsigned long flags;
@@ -73,6 +71,10 @@ insert_intr_entry (int line,
ipc_port_t dnnotify;
ipc_port_request_index_t dnindex;
+ /* XXX: move to arch-specific */
+ if (line < 0 || line >= 16)
+ return D_INVALID_OPERATION;
+
new = (struct intr_entry *) kmem_cache_alloc (&intr_entry_cache);
if (new == NULL)
return D_NO_MEMORY;
@@ -89,41 +91,41 @@ insert_intr_entry (int line,
ipc_kobject_set (new->port, (ipc_kobject_t) new, IKOT_INTR_ENTRY);
new->line = line;
- new->dest = dest;
+ new->notification_port = notification_port;
new->interrupts = 0;
/* Register a dead-name notification so that we are notified if the
userspace handler dies. */
dnnotify = ipc_port_make_sonce (new->port);
- ip_lock (dest);
+ ip_lock (notification_port);
/* We use a bogus port name. We don't need it to distinguish the
notifications because we register just one per object. */
retry:
- err = ipc_port_dnrequest (dest, (mach_port_t) 1, dnnotify, &dnindex);
+ err = ipc_port_dnrequest (notification_port, (mach_port_t) 1, dnnotify, &dnindex);
if (err)
{
- err = ipc_port_dngrow (dest);
- /* dest is unlocked */
+ err = ipc_port_dngrow (notification_port);
+ /* notification_port is unlocked */
if (err != KERN_SUCCESS)
{
ipc_port_release_sonce (dnnotify);
kmem_cache_free (&intr_entry_cache, (vm_offset_t) new);
return err;
}
- ip_lock (dest);
+ ip_lock (notification_port);
goto retry;
}
- /* dest is locked. dnindex is only valid until we unlock it and we
+ /* notification_port is locked. dnindex is only valid until we unlock it and we
might decide to cancel. */
/* check whether the intr entry has been in the queue. */
cpu_intr_save (&flags);
queue_iterate (&intr_queue, e, struct intr_entry *, chain)
- if (e->dest == dest && e->line == line)
+ if (e->notification_port == notification_port && e->line == line)
{
printf ("the interrupt entry for line %d and port %p "
"has already been inserted before.\n",
- line, dest);
+ line, notification_port);
free = 1;
err = D_ALREADY_OPEN;
goto out;
@@ -133,16 +135,19 @@ insert_intr_entry (int line,
cpu_intr_restore (flags);
if (free)
{
- ipc_port_dncancel (new->dest, (mach_port_t) 1, dnindex);
- ip_unlock (new->dest);
+ ipc_port_dncancel (new->notification_port, (mach_port_t) 1, dnindex);
+ ip_unlock (new->notification_port);
ipc_port_release_sonce (dnnotify);
ipc_port_dealloc_kernel (new->port);
- ipc_port_release_send (new->dest);
+ ipc_port_release_send (new->notification_port);
kmem_cache_free (&intr_entry_cache, (vm_offset_t) new);
}
else
- ip_unlock (new->dest);
- *entry = new;
+ ip_unlock (new->notification_port);
+
+ if (! err)
+ err = install_user_intr_handler (line, flags, new);
+
return err;
}
@@ -173,6 +178,7 @@ intr_entry_notify (mach_msg_header_t *msg)
if (msg->msgh_id == MACH_NOTIFY_NO_SENDERS)
{
+ /* XXX uses internal Linux IRQ handling function. */
extern void enable_irq (unsigned int irq_nr);
mach_no_senders_notification_t *ns;
@@ -181,7 +187,7 @@ intr_entry_notify (mach_msg_header_t *msg)
((ipc_port_t) ns->not_header.msgh_remote_port);
assert (entry);
- enable_irq (entry->line); /* entry is not locked here */
+ enable_irq (entry->line);
return TRUE;
}
else if (msg->msgh_id == MACH_NOTIFY_DEAD_NAME)
@@ -203,10 +209,9 @@ intr_entry_notify (mach_msg_header_t *msg)
cpu_intr_restore (flags);
ipc_port_dealloc_kernel (entry->port);
- ipc_port_release_send (entry->dest);
+ ipc_port_release_send (entry->notification_port);
kmem_cache_free (&intr_entry_cache, (vm_offset_t) entry);
- /* XXX cancel no-senders notification here */
printf ("irq handler %d: userspace handler died\n", line);
return TRUE;
}
@@ -243,14 +248,16 @@ init_mach_intr_notification (mach_intr_notification_t *n)
}
static boolean_t
-deliver_intr (int line, ipc_port_t dest_port, ipc_port_t interrupt_port)
+deliver_intr (int line, ipc_port_t notification_port, ipc_port_t interrupt_port)
{
ipc_kmsg_t kmsg;
mach_intr_notification_t *n;
ipc_port_t sright, sonce, old;
- mach_port_t dest = (mach_port_t) dest_port;
- if (dest == MACH_PORT_NULL)
+ if (notification_port == IP_NULL)
+ return FALSE;
+
+ if (interrupt_port == IP_NULL)
return FALSE;
kmsg = ikm_alloc(sizeof *n);
@@ -270,12 +277,12 @@ deliver_intr (int line, ipc_port_t dest_port, ipc_port_t interrupt_port)
if (old != IP_NULL)
ipc_port_release_sonce (old);
- n->intr_header.msgh_remote_port = dest;
+ n->intr_header.msgh_remote_port = (mach_port_t) notification_port;
n->intr_header.msgh_local_port = (mach_port_t) sright;
n->line = line;
- ipc_port_copy_send (dest_port);
- ipc_mqueue_send_always(kmsg);
+ ipc_port_copy_send (notification_port);
+ ipc_mqueue_send_always (kmsg);
return TRUE;
}
@@ -283,9 +290,6 @@ deliver_intr (int line, ipc_port_t dest_port, ipc_port_t interrupt_port)
void
intr_thread ()
{
- struct intr_entry *e;
- int line;
- ipc_port_t dest;
queue_init (&intr_queue);
init_mach_intr_notification (&mach_intr_notification_template);
@@ -294,6 +298,7 @@ intr_thread ()
for (;;)
{
+ struct intr_entry *e;
unsigned long flags;
assert_wait ((event_t) &intr_thread, FALSE);
cpu_intr_save (&flags);
@@ -302,16 +307,15 @@ intr_thread ()
queue_iterate (&intr_queue, e, struct intr_entry *, chain)
if (e->interrupts)
{
- int ok;
+ int line = e->line;
+ ipc_port_t notification_port = e->notification_port;
ipc_port_t interrupt_port = e->port;
- int count = e->interrupts;
- line = e->line;
- dest = e->dest;
+
assert (e->interrupts == 1);
e->interrupts--;
cpu_intr_restore (flags);
- deliver_intr (line, dest, interrupt_port);
+ deliver_intr (line, notification_port, interrupt_port);
cpu_intr_save (&flags);