summaryrefslogtreecommitdiff
path: root/device/ds_routines.c
diff options
context:
space:
mode:
Diffstat (limited to 'device/ds_routines.c')
-rw-r--r--device/ds_routines.c56
1 files changed, 55 insertions, 1 deletions
diff --git a/device/ds_routines.c b/device/ds_routines.c
index 78ff51fe..28be3467 100644
--- a/device/ds_routines.c
+++ b/device/ds_routines.c
@@ -340,7 +340,7 @@ ds_device_intr_register (device_t dev, int id,
if (! name_equal(mdev->dev_ops->d_name, 3, "irq"))
return D_INVALID_OPERATION;
- user_intr_t *e = insert_intr_entry (&irqtab, id, receive_port);
+ user_intr_t *e = insert_intr_entry (&irqtab, id, receive_port, 0);
if (!e)
return D_NO_MEMORY;
@@ -357,6 +357,48 @@ ds_device_intr_register (device_t dev, int id,
return err;
}
+static ipc_port_t intr_receive_ports[16];
+io_return_t
+experimental_device_intr_register (ipc_port_t master_port, int line,
+ int id, int flags, ipc_port_t receive_port)
+{
+ io_return_t ret;
+ /* Open must be called on the master device port. */
+ if (master_port != master_device_port)
+ return D_INVALID_OPERATION;
+
+ /* XXX: move to arch-specific */
+ if (line < 0 || line >= 16)
+ return D_INVALID_OPERATION;
+
+ if (flags != 0x04000000)
+ return D_INVALID_OPERATION;
+
+ user_intr_t *user_intr = insert_intr_entry (&irqtab, line, receive_port, 1);
+ if (!user_intr)
+ return D_NO_MEMORY;
+
+ // TODO The original port should be replaced
+ // when the same device driver calls it again,
+ // in order to handle the case that the device driver crashes and restarts.
+ ret = install_user_intr_handler (&irqtab, line, 0, user_intr);
+
+ if (ret == 0)
+ {
+ /* If the port is installed successfully, increase its reference by 1.
+ * Thus, the port won't be destroyed after its task is terminated. */
+ ip_reference (receive_port);
+
+ intr_receive_ports[line] = receive_port;
+ /* For now netdde calls device_intr_enable once after registration. Assume
+ * it does so for now. When we move to IRQ acknowledgment convention we will
+ * change this. */
+ __disable_irq (line);
+ }
+
+ return ret;
+}
+
kern_return_t
ds_device_intr_ack (device_t dev, ipc_port_t receive_port)
{
@@ -373,6 +415,18 @@ ds_device_intr_ack (device_t dev, ipc_port_t receive_port)
return irq_acknowledge(receive_port);
}
+kern_return_t
+experimental_device_intr_enable(ipc_port_t master_port, int line, char status)
+{
+ if (master_port != master_device_port)
+ return D_INVALID_OPERATION;
+
+ if (status != 1)
+ return D_INVALID_OPERATION;
+
+ return irq_acknowledge(intr_receive_ports[line]);
+}
+
boolean_t
ds_notify (mach_msg_header_t *msg)
{