pc, pc64: implement disabling of msi interrupts
This commit is contained in:
parent
2594b99629
commit
0f56fefd45
4 changed files with 24 additions and 7 deletions
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
Loading…
Reference in a new issue