/* * $Id: kern_irq.c,v 1.3 2007/12/16 23:24:59 nbrk Exp $ */ #include #include #include #include #include /* * System interrupt vectors to be used by (some) interrupt controller unit. */ struct intr_vector *irqtable = NULL; void intr_establish(uint8_t intrno, struct device *device, void (*intrfunc)(struct device *)) { /* * Add interrupt vector to irqtable. */ struct intr_vector *ivp, *previvp; ivp = irqtable; if (ivp == NULL) { /* first element in list */ /* allocate space for this (first) vector */ ivp = kmalloc(sizeof(struct intr_vector)); if (ivp == NULL) panic("failed to allocate initial space for interrupt table\n"); ivp->iv_intrno = intrno; ivp->iv_device = device; ivp->iv_intrfunc = intrfunc; ivp->iv_next = NULL; irqtable = ivp; } else { /* walk through the list */ while(ivp->iv_next != NULL) { if (ivp->iv_intrno == intrno) panic("failed to establish interrupt (intrno %d already set by other device)\n", intrno); ivp = ivp->iv_next; } /* found last entry */ previvp = ivp; ivp = ivp->iv_next; /* allocate space */ ivp = kmalloc(sizeof(struct intr_vector)); if (ivp == NULL) panic("failed to allocate space for interrupt vector\n"); ivp->iv_intrno = intrno; ivp->iv_device = device; ivp->iv_intrfunc = intrfunc; ivp->iv_next = NULL; /* link previous entry */ previvp->iv_next = ivp; } } void intr_disestablish(uint8_t intrno) { /* * Delete interrupt vector from vectors irqtable. */ /* TODO when kfree() will be implemented */ } void intr_execute(uint8_t intrno) { /* * Find intrno in irqtable and call interrupt handler of driver associated with this line. * Pass struct device * into that handler to disguise between driver instances. */ struct intr_vector *ivp; ivp = irqtable; if (ivp == NULL) /* none vectors are configured yet */ panic("failed to execute intr handler (irqtable is not configured yet)\n"); /* look for our handler */ while(ivp != NULL) { if (ivp->iv_intrno == intrno) { /* jump off */ ivp->iv_intrfunc(ivp->iv_device); return; } ivp = ivp->iv_next; } /* * Search stopped on NULL. */ /* XXX really panic here? */ panic("failed to execute intr handler for intr %d (irqtable record not found)\n", intrno); }