=================================================================== RCS file: /cvs/prex-old/sys/kern/irq.c,v retrieving revision 1.1.1.1 retrieving revision 1.1.1.1.2.1 diff -u -r1.1.1.1 -r1.1.1.1.2.1 --- prex-old/sys/kern/irq.c 2008/06/03 10:38:46 1.1.1.1 +++ prex-old/sys/kern/irq.c 2008/08/13 17:12:31 1.1.1.1.2.1 @@ -67,33 +67,23 @@ #include /* forward declarations */ -static void irq_thread(u_long); +static void irq_thread(void *); -static struct irq *irq_table[NIRQS]; /* IRQ descriptor table */ -static volatile int nr_irq_locks; /* lock count for interrupt */ -static volatile int saved_irq_state; /* IRQ state saved by irq_lock() */ +static struct irq *irq_table[NIRQS]; /* IRQ descriptor table */ +static volatile int nr_irq_locks; /* lock counter */ +static volatile int saved_irq_state; /* state saved by irq_lock() */ /* * irq_attach - attach ISR and IST to the specified interrupt. - * @vector: interrupt vector number - * @prio: interrupt priority level. - * @shared: true if it allows the IRQ sharing. - * @isr: pointer to the interrupt service routine. - * @ist: pointer to the interrupt service thread. NULL for no ist. * - * irq_attach() returns irq handle which is needed for irq_detach(). - * Or, it returns -1 if it failed. - * The interrupt of attached irq will be unmasked (enabled) in this - * routine. - * + * Returns irq handle, or NULL on failure. The interrupt of + * attached irq will be unmasked (enabled) in this routine. * TODO: Interrupt sharing is not supported, for now. */ -int -irq_attach(int vector, int prio, int shared, int (*isr)(int), - void (*ist)(int)) +irq_t +irq_attach(int vector, int prio, int shared, int (*isr)(int), void (*ist)(int)) { struct irq *irq; - thread_t th; int mode; ASSERT(irq_level == 0); @@ -102,7 +92,7 @@ sched_lock(); if ((irq = kmem_alloc(sizeof(struct irq))) == NULL) { sched_unlock(); - return -1; + return NULL; } memset(irq, 0, sizeof(struct irq)); irq->vector = vector; @@ -113,35 +103,34 @@ /* * Create a new thread for IST. */ - th = kernel_thread(ISTPRIO(prio), irq_thread, (u_long)irq); - if (th == NULL) - panic("irq_attach"); - irq->thread = th; - event_init(&irq->ist_event, "interrupt"); + irq->thread = kthread_create(&irq_thread, irq, ISTPRIO(prio)); + if (irq->thread == NULL) { + kmem_free(irq); + sched_unlock(); + return NULL; + } + event_init(&irq->istevt, "interrupt"); } irq_table[vector] = irq; - mode = shared ? IMODE_LEVEL : IMODE_EDGE; - irq_lock(); + mode = shared ? IMODE_LEVEL : IMODE_EDGE; interrupt_setup(vector, mode); interrupt_unmask(vector, prio); irq_unlock(); sched_unlock(); - printk("IRQ%d attached priority=%d\n", vector, prio); - return (int)irq; + DPRINTF(("IRQ%d attached priority=%d\n", vector, prio)); + return irq; } /* * Detach an interrupt handler from the interrupt chain. - * The detached interrupt will be masked off if nobody attaches - * to it, anymore. + * The detached interrupt will be masked off if nobody + * attaches to it, anymore. */ void -irq_detach(int handle) +irq_detach(irq_t irq) { - struct irq *irq = (struct irq *)handle; - ASSERT(irq_level == 0); ASSERT(irq); ASSERT(irq->vector < NIRQS); @@ -152,7 +141,8 @@ irq_table[irq->vector] = NULL; if (irq->thread != NULL) - thread_kill(irq->thread); + kthread_terminate(irq->thread); + kmem_free(irq); } @@ -160,9 +150,9 @@ * Lock IRQ. * * All H/W interrupts are masked off. - * Caller is no need to save the interrupt state before irq_lock() - * because it is automatically restored in irq_unlock() when no one - * is locking the IRQ anymore. + * Caller is no need to save the interrupt state before + * irq_lock() because it is automatically restored in + * irq_unlock() when no one is locking the IRQ anymore. */ void irq_lock(void) @@ -173,13 +163,15 @@ interrupt_disable(); if (++nr_irq_locks == 1) saved_irq_state = s; + + ASSERT(nr_irq_locks != 0); } /* * Unlock IRQ. * - * If lock count becomes 0, the interrupt is restored to original - * state at first irq_lock() call. + * If lock count becomes 0, the interrupt is restored to + * original state at first irq_lock() call. */ void irq_unlock(void) @@ -195,7 +187,7 @@ * This is a common dispatcher to all interrupt threads. */ static void -irq_thread(u_long arg) +irq_thread(void *arg) { int vec; void (*func)(int); @@ -209,22 +201,25 @@ for (;;) { interrupt_disable(); - if (irq->ist_request <= 0) { + if (irq->istreq <= 0) { /* - * Since the interrupt is disabled above, an - * interrupt for this vector keeps pending until - * this thread enters sleep state. Thus, we don't - * lose any IST requests even if the interrupt - * is fired here. + * Since the interrupt is disabled above, + * an interrupt for this vector keeps + * pending until this thread enters sleep + * state. Thus, we don't lose any IST + * requests even if the interrupt is fired + * here. */ - sched_sleep(&irq->ist_event); + sched_sleep(&irq->istevt); } - irq->ist_request--; - ASSERT(irq->ist_request >= 0); + irq->istreq--; + ASSERT(irq->istreq >= 0); interrupt_enable(); - /* Call IST */ - (func)(vec); + /* + * Call IST + */ + (*func)(vec); } /* NOTREACHED */ } @@ -232,10 +227,10 @@ /* * Interrupt handler. * - * This routine will call the corresponding ISR for the requested - * interrupt vector. This routine is called from the code in the - * architecture dependent layer. We assumes the scheduler is already - * locked by caller. + * This routine will call the corresponding ISR for the + * requested interrupt vector. This routine is called from + * the code in the architecture dependent layer. We + * assumes the scheduler is already locked by caller. */ void irq_handler(int vector) @@ -248,46 +243,26 @@ return; /* Ignore stray interrupt */ ASSERT(irq->isr); - /* Call ISR */ - rc = (irq->isr)(vector); + /* + * Call ISR + */ + rc = (*irq->isr)(vector); if (rc == INT_CONTINUE) { - /* Kick IST */ + /* + * Kick IST + */ ASSERT(irq->ist); - irq->ist_request++; - sched_wakeup(&irq->ist_event); + irq->istreq++; + sched_wakeup(&irq->istevt); + ASSERT(irq->istreq != 0); } - irq->count++; } -#if defined(DEBUG) && defined(CONFIG_KDUMP) void -irq_dump(void) -{ - int vector; - struct irq *irq; - - printk("IRQ dump:\n"); - printk(" vector isr ist prio count\n"); - printk(" ------ -------- -------- -------- --------\n"); - - for (vector = 0; vector < NIRQS; vector++) { - irq = irq_table[vector]; - if (irq) { - printk(" %4d %08x %08x %3d %8d\n", - vector, irq->isr, irq->ist, - (irq->thread ? irq->thread->prio : 0), - irq->count); - } - } -} -#endif - -void irq_init(void) { - /* - * Start interrupt processing. - */ + + /* Start interrupt processing. */ interrupt_enable(); }