File: [local] / funnyos / kern / kern_irq.c (download)
Revision 1.3, Sun Dec 16 23:24:59 2007 UTC (16 years, 9 months ago) by nbrk
Branch: MAIN
CVS Tags: HEAD Changes since 1.2: +10 -6 lines
fix linked list logic (irqtable) to correct link more than one element.
|
/*
* $Id: kern_irq.c,v 1.3 2007/12/16 23:24:59 nbrk 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, *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);
}