diff options
Diffstat (limited to 'device/ds_routines.c')
-rw-r--r-- | device/ds_routines.c | 56 |
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) { |