Change IPL when bridge's interrupt handler calls child device's
interrupt handler (This solution is not very good).
This commit is contained in:
parent
4810a01fcf
commit
b6a821f042
@ -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) {
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user