pc, pc64: implement disabling of msi interrupts

front
cinap_lenrek 2020-11-21 21:48:25 +01:00
parent 2594b99629
commit 0f56fefd45
4 changed files with 24 additions and 7 deletions

View File

@ -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 {

View File

@ -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;

View File

@ -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);

View File

@ -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);