diff --git a/sys/src/9/pc/io.h b/sys/src/9/pc/io.h index 01204ffa3..d0113af69 100644 --- a/sys/src/9/pc/io.h +++ b/sys/src/9/pc/io.h @@ -48,15 +48,19 @@ enum { typedef struct Vctl { Vctl* next; /* handlers on this vector */ - char name[KNAMELEN]; /* of driver */ + void (*f)(Ureg*, void*); /* handler to call */ + void* a; /* argument to call it with */ + int isintr; /* interrupt or fault/trap */ - int irq; - int tbdf; + int (*isr)(int); /* get isr bit for this irq */ int (*eoi)(int); /* eoi */ - void (*f)(Ureg*, void*); /* handler to call */ - void* a; /* argument to call it with */ + void (*disable)(Vctl*); + int irq; + int tbdf; + + char name[KNAMELEN]; /* of driver */ } Vctl; enum { diff --git a/sys/src/9/pc/mp.c b/sys/src/9/pc/mp.c index 87aca1b1c..591fc6735 100644 --- a/sys/src/9/pc/mp.c +++ b/sys/src/9/pc/mp.c @@ -469,6 +469,15 @@ htmsienable(Pcidev *pdev) return -1; } +static void +msiintrdisable(Vctl *v) +{ + Pcidev *pci; + + if((pci = pcimatchtbdf(v->tbdf)) != nil) + pcimsidisable(pci); +} + static int msiintrenable(Vctl *v) { @@ -493,6 +502,7 @@ msiintrenable(Vctl *v) cpu = mpintrcpu(); if(pcimsienable(pci, 0xFEE00000ULL | (cpu << 12), vno | (1<<14)) < 0) return -1; + v->disable = msiintrdisable; v->isr = lapicisr; v->eoi = lapiceoi; return vno; diff --git a/sys/src/9/pc/trap.c b/sys/src/9/pc/trap.c index faaf90101..cca5a53c8 100644 --- a/sys/src/9/pc/trap.c +++ b/sys/src/9/pc/trap.c @@ -89,8 +89,7 @@ intrdisable(int irq, void (*f)(Ureg *, void *), void *a, int tbdf, char *name) irq = 9; 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. + * on APIC machine, irq is pretty meaningless. * however, we still want to remove the matching * Vctl entry to prevent calling Vctl.f() with a * stale Vctl.a pointer. @@ -109,6 +108,8 @@ intrdisable(int irq, void (*f)(Ureg *, void *), void *a, int tbdf, char *name) break; } if(v != nil){ + if(v->disable != nil) + (*v->disable)(v); *pv = v->next; xfree(v); diff --git a/sys/src/9/pc64/trap.c b/sys/src/9/pc64/trap.c index b7e71a919..25b6510fa 100644 --- a/sys/src/9/pc64/trap.c +++ b/sys/src/9/pc64/trap.c @@ -111,6 +111,8 @@ intrdisable(int irq, void (*f)(Ureg *, void *), void *a, int tbdf, char *name) break; } if(v != nil){ + if(v->disable != nil) + (*v->disable)(v); *pv = v->next; xfree(v);