Added the functions intr_claim() and intr_release(). These are front

ends for irq_claim() and irq_release() that will allocate and free
memory for the irqhandler structure.
Added an irqblock array that provides a quick reference to all the
interrupts that should be blocked when a particular interrupt is
received. The irq_claim() and irq_release() functions now update the
irqblock array.
This commit is contained in:
mark 1997-01-06 02:30:21 +00:00
parent b34fcd542a
commit c87f4e3785
2 changed files with 202 additions and 10 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: irqhandler.c,v 1.12 1996/12/27 02:01:02 mark Exp $ */
/* $NetBSD: irqhandler.c,v 1.13 1997/01/06 02:30:21 mark Exp $ */
/*
* Copyright (c) 1994-1996 Mark Brinicombe.
@ -46,6 +46,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/syslog.h>
#include <sys/malloc.h>
#include <vm/vm.h>
#include <net/netisr.h>
@ -68,6 +69,8 @@ u_int spl_mask;
u_int soft_interrupts;
extern u_int intrcnt[];
u_int irqblock[NIRQS];
typedef struct {
vm_offset_t physical;
vm_offset_t virtual;
@ -79,7 +82,6 @@ extern char *_intrnames;
/* Prototypes */
int podule_irqhandler __P((void));
int irq_claim __P((int irq, irqhandler_t *handler));
extern void zero_page_readonly __P((void));
extern void zero_page_readwrite __P((void));
extern int fiq_setregs __P((fiqhandler_t *));
@ -102,10 +104,12 @@ irq_init()
{
int loop;
/* Clear all the IRQ handlers */
/* Clear all the IRQ handlers and the irq block masks */
for (loop = 0; loop < NIRQS; ++loop)
for (loop = 0; loop < NIRQS; ++loop) {
irqhandlers[loop] = NULL;
irqblock[loop] = 0;
}
/* Clear the FIQ handler */
@ -162,6 +166,7 @@ irq_claim(irq, handler)
irqhandler_t *handler;
{
int level;
int loop;
#ifdef DIAGNOSTIC
/* Sanity check */
@ -250,6 +255,33 @@ irq_claim(irq, handler)
#endif
}
/*
* We now need to update the irqblock array. This array indicates
* what other interrupts should be blocked when interrupt is asserted
* This basically emulates hardware interrupt priorities e.g. by blocking
* all other IPL_BIO interrupts with an IPL_BIO interrupt is asserted.
* For each interrupt we find the highest IPL and set the block mask to
* the interrupt mask for that level.
*/
for (loop = 0; loop < NIRQS; ++loop) {
irqhandler_t *ptr;
ptr = irqhandlers[loop];
if (ptr) {
/* There is at least 1 handler so scan the chain */
level = ptr->ih_level;
while (ptr) {
if (ptr->ih_level > level)
level = ptr->ih_level;
ptr = ptr->ih_next;
}
irqblock[loop] = ~irqmasks[level];
} else
/* No handlers for this irq so nothing to block */
irqblock[loop] = 0;
}
#if NPODULEBUS > 0
/*
* Is this an expansion card IRQ and is there a PODULE IRQ handler
@ -284,6 +316,7 @@ irq_release(irq, handler)
irqhandler_t *handler;
{
int level;
int loop;
irqhandler_t *irqhand;
irqhandler_t **prehand;
extern char *_intrnames;
@ -369,7 +402,6 @@ irq_release(irq, handler)
level = ptr->ih_level - 1;
ptr = ptr->ih_next;
}
while (level >= 0) {
irqmasks[level] |= (1 << irq);
--level;
@ -377,6 +409,33 @@ irq_release(irq, handler)
}
}
/*
* We now need to update the irqblock array. This array indicates
* what other interrupts should be blocked when interrupt is asserted
* This basically emulates hardware interrupt priorities e.g. by blocking
* all other IPL_BIO interrupts with an IPL_BIO interrupt is asserted.
* For each interrupt we find the highest IPL and set the block mask to
* the interrupt mask for that level.
*/
for (loop = 0; loop < NIRQS; ++loop) {
irqhandler_t *ptr;
ptr = irqhandlers[loop];
if (ptr) {
/* There is at least 1 handler so scan the chain */
level = ptr->ih_level;
while (ptr) {
if (ptr->ih_level > level)
level = ptr->ih_level;
ptr = ptr->ih_next;
}
irqblock[loop] = ~irqmasks[level];
} else
/* No handlers for this irq so nothing to block */
irqblock[loop] = 0;
}
/*
* Disable the appropriate mask bit if there are no handlers left for
* this IRQ.
@ -391,6 +450,43 @@ irq_release(irq, handler)
}
void *
intr_claim(irq, level, name, ih_func, ih_arg)
int irq;
int level;
const char *name;
int (*ih_func) __P((void *));
void *ih_arg;
{
irqhandler_t *ih;
ih = malloc(sizeof(*ih), M_DEVBUF, M_NOWAIT);
if (!ih)
panic("intr_claim(): Cannot malloc handler memory\n");
ih->ih_level = level;
ih->ih_name = name;
ih->ih_func = ih_func;
ih->ih_arg = ih_arg;
ih->ih_flags = 0;
if (irq_claim(irq, ih) != 0)
return(NULL);
return(ih);
}
void
intr_release(arg)
void *arg;
{
irqhandler_t *ih = (irqhandler_t *)arg;
if (irq_release(ih->ih_num, ih) == 0)
free(ih, M_DEVBUF);
}
u_int
disable_interrupts(mask)
u_int mask;

View File

@ -1,4 +1,4 @@
/* $NetBSD: iomd_irqhandler.c,v 1.12 1996/12/27 02:01:02 mark Exp $ */
/* $NetBSD: iomd_irqhandler.c,v 1.13 1997/01/06 02:30:21 mark Exp $ */
/*
* Copyright (c) 1994-1996 Mark Brinicombe.
@ -46,6 +46,7 @@
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/syslog.h>
#include <sys/malloc.h>
#include <vm/vm.h>
#include <net/netisr.h>
@ -68,6 +69,8 @@ u_int spl_mask;
u_int soft_interrupts;
extern u_int intrcnt[];
u_int irqblock[NIRQS];
typedef struct {
vm_offset_t physical;
vm_offset_t virtual;
@ -79,7 +82,6 @@ extern char *_intrnames;
/* Prototypes */
int podule_irqhandler __P((void));
int irq_claim __P((int irq, irqhandler_t *handler));
extern void zero_page_readonly __P((void));
extern void zero_page_readwrite __P((void));
extern int fiq_setregs __P((fiqhandler_t *));
@ -102,10 +104,12 @@ irq_init()
{
int loop;
/* Clear all the IRQ handlers */
/* Clear all the IRQ handlers and the irq block masks */
for (loop = 0; loop < NIRQS; ++loop)
for (loop = 0; loop < NIRQS; ++loop) {
irqhandlers[loop] = NULL;
irqblock[loop] = 0;
}
/* Clear the FIQ handler */
@ -162,6 +166,7 @@ irq_claim(irq, handler)
irqhandler_t *handler;
{
int level;
int loop;
#ifdef DIAGNOSTIC
/* Sanity check */
@ -250,6 +255,33 @@ irq_claim(irq, handler)
#endif
}
/*
* We now need to update the irqblock array. This array indicates
* what other interrupts should be blocked when interrupt is asserted
* This basically emulates hardware interrupt priorities e.g. by blocking
* all other IPL_BIO interrupts with an IPL_BIO interrupt is asserted.
* For each interrupt we find the highest IPL and set the block mask to
* the interrupt mask for that level.
*/
for (loop = 0; loop < NIRQS; ++loop) {
irqhandler_t *ptr;
ptr = irqhandlers[loop];
if (ptr) {
/* There is at least 1 handler so scan the chain */
level = ptr->ih_level;
while (ptr) {
if (ptr->ih_level > level)
level = ptr->ih_level;
ptr = ptr->ih_next;
}
irqblock[loop] = ~irqmasks[level];
} else
/* No handlers for this irq so nothing to block */
irqblock[loop] = 0;
}
#if NPODULEBUS > 0
/*
* Is this an expansion card IRQ and is there a PODULE IRQ handler
@ -284,6 +316,7 @@ irq_release(irq, handler)
irqhandler_t *handler;
{
int level;
int loop;
irqhandler_t *irqhand;
irqhandler_t **prehand;
extern char *_intrnames;
@ -369,7 +402,6 @@ irq_release(irq, handler)
level = ptr->ih_level - 1;
ptr = ptr->ih_next;
}
while (level >= 0) {
irqmasks[level] |= (1 << irq);
--level;
@ -377,6 +409,33 @@ irq_release(irq, handler)
}
}
/*
* We now need to update the irqblock array. This array indicates
* what other interrupts should be blocked when interrupt is asserted
* This basically emulates hardware interrupt priorities e.g. by blocking
* all other IPL_BIO interrupts with an IPL_BIO interrupt is asserted.
* For each interrupt we find the highest IPL and set the block mask to
* the interrupt mask for that level.
*/
for (loop = 0; loop < NIRQS; ++loop) {
irqhandler_t *ptr;
ptr = irqhandlers[loop];
if (ptr) {
/* There is at least 1 handler so scan the chain */
level = ptr->ih_level;
while (ptr) {
if (ptr->ih_level > level)
level = ptr->ih_level;
ptr = ptr->ih_next;
}
irqblock[loop] = ~irqmasks[level];
} else
/* No handlers for this irq so nothing to block */
irqblock[loop] = 0;
}
/*
* Disable the appropriate mask bit if there are no handlers left for
* this IRQ.
@ -391,6 +450,43 @@ irq_release(irq, handler)
}
void *
intr_claim(irq, level, name, ih_func, ih_arg)
int irq;
int level;
const char *name;
int (*ih_func) __P((void *));
void *ih_arg;
{
irqhandler_t *ih;
ih = malloc(sizeof(*ih), M_DEVBUF, M_NOWAIT);
if (!ih)
panic("intr_claim(): Cannot malloc handler memory\n");
ih->ih_level = level;
ih->ih_name = name;
ih->ih_func = ih_func;
ih->ih_arg = ih_arg;
ih->ih_flags = 0;
if (irq_claim(irq, ih) != 0)
return(NULL);
return(ih);
}
void
intr_release(arg)
void *arg;
{
irqhandler_t *ih = (irqhandler_t *)arg;
if (irq_release(ih->ih_num, ih) == 0)
free(ih, M_DEVBUF);
}
u_int
disable_interrupts(mask)
u_int mask;