Change IPL when bridge's interrupt handler calls child device's

interrupt handler (This solution is not very good).
This commit is contained in:
haya 2000-06-08 10:28:28 +00:00
parent 4810a01fcf
commit b6a821f042
2 changed files with 46 additions and 4 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: pccbb.c,v 1.40 2000/06/07 09:02:46 haya Exp $ */
/* $NetBSD: pccbb.c,v 1.41 2000/06/08 10:28:28 haya Exp $ */
/*
* Copyright (c) 1998, 1999 and 2000
@ -593,6 +593,11 @@ pccbb_pci_callback(self)
return;
}
intrstr = pci_intr_string(pc, ih);
/*
* XXX pccbbintr should be called under the priority lower
* than any other hard interrputs.
*/
sc->sc_ih = pci_intr_establish(pc, ih, IPL_BIO, pccbbintr, sc);
if (sc->sc_ih == NULL) {
@ -972,9 +977,44 @@ pccbbintr_function(sc)
{
int retval = 0, val;
struct pccbb_intrhand_list *pil;
int s, splchanged;
for (pil = sc->sc_pil; pil != NULL; pil = pil->pil_next) {
val = (*pil->pil_func) (pil->pil_arg);
/*
* XXX priority change. gross. I use if-else
* sentense instead of switch-case sentense because of
* avoiding duplicate case value error. More than one
* IPL_XXX use same value. It depends on
* implimentation.
*/
splchanged = 1;
if (pil->pil_level == IPL_SERIAL) {
s = splserial();
} else if (pil->pil_level == IPL_HIGH) {
s = splhigh();
} else if (pil->pil_level == IPL_CLOCK) {
s = splclock();
} else if (pil->pil_level == IPL_AUDIO) {
s = splaudio();
} else if (pil->pil_level == IPL_IMP) {
s = splimp();
} else if (pil->pil_level == IPL_TTY) {
s = spltty();
} else if (pil->pil_level == IPL_SOFTSERIAL) {
s = splsoftserial();
} else if (pil->pil_level == IPL_NET) {
s = splnet();
} else {
splchanged = 0;
/* XXX: ih lower than IPL_BIO runs w/ IPL_BIO. */
}
val = (*pil->pil_func)(pil->pil_arg);
if (splchanged != 0) {
splx(s);
}
retval = retval == 1 ? 1 :
retval == 0 ? val : val != 0 ? val : retval;
}
@ -1594,7 +1634,7 @@ pccbb_cb_intr_disestablish(ct, ih)
* order not to call the interrupt handlers of child devices when
* a card-deletion interrupt occurs.
*
* The arguments irq and level are not used.
* The arguments irq is not used because pccbb selects intr vector.
*/
static void *
pccbb_intr_establish(sc, irq, level, func, arg)
@ -1638,6 +1678,7 @@ pccbb_intr_establish(sc, irq, level, func, arg)
newpil->pil_func = func;
newpil->pil_arg = arg;
newpil->pil_level = level;
newpil->pil_next = NULL;
if (sc->sc_pil == NULL) {

View File

@ -1,4 +1,4 @@
/* $NetBSD: pccbbvar.h,v 1.12 2000/03/23 07:01:40 thorpej Exp $ */
/* $NetBSD: pccbbvar.h,v 1.13 2000/06/08 10:28:29 haya Exp $ */
/*
* Copyright (c) 1999 HAYAKAWA Koichi. All rights reserved.
*
@ -169,6 +169,7 @@ struct pccbb_softc {
struct pccbb_intrhand_list {
int (*pil_func) __P((void *));
void *pil_arg;
int pil_level;
struct pccbb_intrhand_list *pil_next;
};