From e0c221eea6b68c87f89eb073d7204851398fc5d8 Mon Sep 17 00:00:00 2001 From: cinap_lenrek Date: Mon, 22 Dec 2014 16:10:18 +0100 Subject: pc, pc64: fix intrdisable() to remove the Vctl entry even tho we can't disable the interrupt on apic --- sys/src/9/pc/trap.c | 53 +++++++++++++++++++++++++++++++-------------------- sys/src/9/pc64/trap.c | 53 +++++++++++++++++++++++++++++++-------------------- 2 files changed, 64 insertions(+), 42 deletions(-) diff --git a/sys/src/9/pc/trap.c b/sys/src/9/pc/trap.c index 51961577b..1eef90ea9 100644 --- a/sys/src/9/pc/trap.c +++ b/sys/src/9/pc/trap.c @@ -82,29 +82,40 @@ intrdisable(int irq, void (*f)(Ureg *, void *), void *a, int tbdf, char *name) Vctl **pv, *v; int vno; - /* - * For now, none of this will work with the APIC code, - * there is no mapping between irq and vector as the IRQ - * is pretty meaningless. - */ - if(arch->intrvecno == nil) - return -1; - vno = arch->intrvecno(irq); + if(arch->intrvecno == nil || (tbdf != BUSUNKNOWN && (irq == 0xff || irq == 0))){ + /* + * on APIC machine, irq is pretty meaningless + * and disabling a the vector is not implemented. + * however, we still want to remove the matching + * Vctl entry to prevent calling Vctl.f() with a + * stale Vctl.a pointer. + */ + irq = -1; + vno = VectorPIC; + } else { + vno = arch->intrvecno(irq); + } ilock(&vctllock); - pv = &vctl[vno]; - while (*pv && - ((*pv)->irq != irq || (*pv)->tbdf != tbdf || (*pv)->f != f || (*pv)->a != a || - strcmp((*pv)->name, name))) - pv = &((*pv)->next); - assert(*pv); - - v = *pv; - *pv = (*pv)->next; /* Link out the entry */ - - if(vctl[vno] == nil && arch->intrdisable != nil) - arch->intrdisable(irq); + for(; vno <= MaxIrqLAPIC; vno++){ + for(pv = &vctl[vno]; (v = *pv) != nil; pv = &v->next){ + if(v->isintr && (v->irq == irq || irq == -1) + && v->tbdf == tbdf && v->f == f && v->a == a + && strcmp(v->name, name) == 0) + break; + } + if(v != nil){ + *pv = v->next; + xfree(v); + + if(irq == -1) + break; + if(vctl[vno] == nil && arch->intrdisable != nil) + arch->intrdisable(irq); + } + if(irq != -1) + break; + } iunlock(&vctllock); - xfree(v); return 0; } diff --git a/sys/src/9/pc64/trap.c b/sys/src/9/pc64/trap.c index db6ff01c0..7c411f47e 100644 --- a/sys/src/9/pc64/trap.c +++ b/sys/src/9/pc64/trap.c @@ -82,29 +82,40 @@ intrdisable(int irq, void (*f)(Ureg *, void *), void *a, int tbdf, char *name) Vctl **pv, *v; int vno; - /* - * For now, none of this will work with the APIC code, - * there is no mapping between irq and vector as the IRQ - * is pretty meaningless. - */ - if(arch->intrvecno == nil) - return -1; - vno = arch->intrvecno(irq); + if(arch->intrvecno == nil || (tbdf != BUSUNKNOWN && (irq == 0xff || irq == 0))){ + /* + * on APIC machine, irq is pretty meaningless + * and disabling a the vector is not implemented. + * however, we still want to remove the matching + * Vctl entry to prevent calling Vctl.f() with a + * stale Vctl.a pointer. + */ + irq = -1; + vno = VectorPIC; + } else { + vno = arch->intrvecno(irq); + } ilock(&vctllock); - pv = &vctl[vno]; - while (*pv && - ((*pv)->irq != irq || (*pv)->tbdf != tbdf || (*pv)->f != f || (*pv)->a != a || - strcmp((*pv)->name, name))) - pv = &((*pv)->next); - assert(*pv); - - v = *pv; - *pv = (*pv)->next; /* Link out the entry */ - - if(vctl[vno] == nil && arch->intrdisable != nil) - arch->intrdisable(irq); + for(; vno <= MaxIrqLAPIC; vno++){ + for(pv = &vctl[vno]; (v = *pv) != nil; pv = &v->next){ + if(v->isintr && (v->irq == irq || irq == -1) + && v->tbdf == tbdf && v->f == f && v->a == a + && strcmp(v->name, name) == 0) + break; + } + if(v != nil){ + *pv = v->next; + xfree(v); + + if(irq == -1) + break; + if(vctl[vno] == nil && arch->intrdisable != nil) + arch->intrdisable(irq); + } + if(irq != -1) + break; + } iunlock(&vctllock); - xfree(v); return 0; } -- cgit v1.2.3