]> git.lizzy.rs Git - plan9front.git/commitdiff
pc, pc64: fix intrdisable() to remove the Vctl entry even tho we can't disable the...
authorcinap_lenrek <cinap_lenrek@felloff.net>
Mon, 22 Dec 2014 15:10:18 +0000 (16:10 +0100)
committercinap_lenrek <cinap_lenrek@felloff.net>
Mon, 22 Dec 2014 15:10:18 +0000 (16:10 +0100)
sys/src/9/pc/trap.c
sys/src/9/pc64/trap.c

index 51961577bb2e39efa5e673afe6ca22892483f211..1eef90ea9e3154b67122c3a5dd271e1457448f4d 100644 (file)
@@ -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;
 }
 
index db6ff01c0ea579fdce288d932eb47db7955bdcea..7c411f47ece8ea3e35f95aedb55b2947ee7f5dff 100644 (file)
@@ -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;
 }