x86: add deregister_irq()
It's about as good as register_irq().
Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
diff --git a/kern/arch/riscv/trap.c b/kern/arch/riscv/trap.c
index d3be282..78150be 100644
--- a/kern/arch/riscv/trap.c
+++ b/kern/arch/riscv/trap.c
@@ -350,6 +350,12 @@
return -1;
}
+int deregister_irq(int vector, uint32_t tbdf)
+{
+ printk("%s not implemented\n", __FUNCTION);
+ return -1;
+}
+
int route_irqs(int cpu_vec, int coreid)
{
printk("%s not implemented\n", __FUNCTION);
diff --git a/kern/arch/x86/trap.c b/kern/arch/x86/trap.c
index 16cdc5c..799d6e3 100644
--- a/kern/arch/x86/trap.c
+++ b/kern/arch/x86/trap.c
@@ -815,6 +815,29 @@
return irq_h;
}
+int deregister_irq(int vector, uint32_t tbdf)
+{
+ struct irq_handler *irq_h, **pp;
+
+ pp = &irq_handlers[vector];
+ spin_lock_irqsave(&irq_handler_wlock);
+ while ((irq_h = *pp)) {
+ if (irq_h->tbdf == tbdf) {
+ rcu_assign_pointer(*pp, irq_h->next);
+ break;
+ }
+ pp = &irq_h->next;
+ }
+ spin_unlock_irqsave(&irq_handler_wlock);
+ if (!irq_h) {
+ warn("No IRQ V: %d TBDF: %x to unregister!", vector, tbdf);
+ return -1;
+ }
+ synchronize_rcu();
+ kfree(irq_h);
+ return 0;
+}
+
/* These routing functions only allow the routing of an irq to a single core.
* If we want to route to multiple cores, we'll probably need to set up logical
* groups or something and take some additional parameters. */
diff --git a/kern/include/trap.h b/kern/include/trap.h
index 66d0d1b..c3ae8d1 100644
--- a/kern/include/trap.h
+++ b/kern/include/trap.h
@@ -16,6 +16,7 @@
void idt_init(void);
struct irq_handler *register_irq(int irq, isr_t handler, void *irq_arg,
uint32_t tbdf);
+int deregister_irq(int vector, uint32_t tbdf);
int route_irqs(int cpu_vec, int coreid);
void print_trapframe(struct hw_trapframe *hw_tf);
void print_swtrapframe(struct sw_trapframe *sw_tf);