Return to kern_irq.c CVS log | Up to [local] / funnyos / kern |
File: [local] / funnyos / kern / kern_irq.c (download)
Revision 1.1, Fri Nov 2 11:40:02 2007 UTC (16 years, 6 months ago) by init
first steps towards interrupts support; intr_establish() and intr_disestablish() can be used by devconfig to register (and unregister) interrupts handlers during device attachment. intr_execute() is used to quick execute (registered) handler by passed intrno. still more work to do. |
/* * $Id: kern_irq.c,v 1.1 2007/11/02 11:40:02 init Exp $ */ #include <sys/types.h> #include <sys/device.h> #include <sys/mem.h> #include <sys/kern_irq.h> #include <libkern/printf.h> /* * 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; 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; } else { /* walk through the list */ do { /* check if this interrupt line already binded */ if (ivp->iv_intrno == intrno) panic("failed to establish interrupt (intrno %d already set by other device)\n", intrno); /* become next element */ ivp = ivp->iv_next; } while(ivp != NULL); /* 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; } } 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); }