diff options
author | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2019-11-12 00:16:06 +0100 |
---|---|---|
committer | Samuel Thibault <samuel.thibault@ens-lyon.org> | 2019-11-12 00:16:06 +0100 |
commit | 72cb75d88122797e7988aac61315cd167d21b169 (patch) | |
tree | a17e53305804eb78f48d38e582e6958c674cf4a2 | |
parent | d84f24b13961c7a475662d77fc3656bb799d0974 (diff) |
Make userland irqs use counting, so both Linux and dde can mask interrupt as appropriate
-rw-r--r-- | device/ds_routines.c | 17 | ||||
-rw-r--r-- | device/intr.c | 6 | ||||
-rw-r--r-- | linux/dev/arch/i386/kernel/irq.c | 4 |
3 files changed, 18 insertions, 9 deletions
diff --git a/device/ds_routines.c b/device/ds_routines.c index 06fe4e96..e7bcc564 100644 --- a/device/ds_routines.c +++ b/device/ds_routines.c @@ -346,11 +346,18 @@ ds_device_intr_register (ipc_port_t master_port, int line, // in order to handle the case that the device driver crashes and restarts. ret = install_user_intr_handler (line, flags, receive_port); - /* If the port is installed successfully, increase its reference by 1. - * Thus, the port won't be destroyed after its task is terminated. */ 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); + /* 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; #endif /* MACH_XEN */ } @@ -1844,11 +1851,13 @@ ds_device_intr_enable(ipc_port_t master_port, int line, char status) if (master_port != master_device_port) return D_INVALID_OPERATION; + /* FIXME: should count how many disable/enable was done for a given receiving + * port, to be able to restore proper count on crashes */ if (status) /* TODO: better name for generic-to-arch-specific call */ - enable_irq (line); + __enable_irq (line); else - disable_irq (line); + __disable_irq (line); return 0; #endif /* MACH_XEN */ } diff --git a/device/intr.c b/device/intr.c index cf5d93f6..fb423282 100644 --- a/device/intr.c +++ b/device/intr.c @@ -41,7 +41,11 @@ queue_intr (int line, ipc_port_t dest) { extern void intr_thread (); struct intr_entry *e; - + + /* Until userland has handled the IRQ in the driver, we have to keep it + * disabled. Level-triggered interrupts would keep raising otherwise. */ + __disable_irq (line); + cli (); e = search_intr (line, dest); assert (e); diff --git a/linux/dev/arch/i386/kernel/irq.c b/linux/dev/arch/i386/kernel/irq.c index 5a2e4ad0..ae3fa070 100644 --- a/linux/dev/arch/i386/kernel/irq.c +++ b/linux/dev/arch/i386/kernel/irq.c @@ -129,12 +129,8 @@ linux_intr (int irq) } else { - /* We disable the irq here and it will be enabled - * after the interrupt is handled by the user space driver. */ - disable_irq (irq); queue_intr (irq, action->delivery_port); } - } else if (action->handler) action->handler (irq, action->dev_id, ®s); |