merge
This commit is contained in:
commit
59308f15dd
|
@ -383,16 +383,16 @@ rtl8169miimiw(Mii* mii, int pa, int ra, int data)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
rtl8169mii(Ctlr* ctlr)
|
rtl8169mii(Ether *edev)
|
||||||
{
|
{
|
||||||
|
Ctlr *ctlr = edev->ctlr;
|
||||||
MiiPhy *phy;
|
MiiPhy *phy;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Link management.
|
* Link management.
|
||||||
*/
|
*/
|
||||||
if((ctlr->mii = malloc(sizeof(Mii))) == nil)
|
ctlr->mii = smalloc(sizeof(Mii));
|
||||||
return -1;
|
|
||||||
ctlr->mii->mir = rtl8169miimir;
|
ctlr->mii->mir = rtl8169miimir;
|
||||||
ctlr->mii->miw = rtl8169miimiw;
|
ctlr->mii->miw = rtl8169miimiw;
|
||||||
ctlr->mii->ctlr = ctlr;
|
ctlr->mii->ctlr = ctlr;
|
||||||
|
@ -420,22 +420,20 @@ rtl8169mii(Ctlr* ctlr)
|
||||||
csr8w(ctlr, Ldps, 1); /* magic */
|
csr8w(ctlr, Ldps, 1); /* magic */
|
||||||
rtl8169miimiw(ctlr->mii, 1, 0x0B, 0x0000); /* magic */
|
rtl8169miimiw(ctlr->mii, 1, 0x0B, 0x0000); /* magic */
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mii(ctlr->mii, (1<<1)) == 0 || (phy = ctlr->mii->curphy) == nil){
|
if(mii(ctlr->mii, (1<<1)) == 0 || (phy = ctlr->mii->curphy) == nil){
|
||||||
free(ctlr->mii);
|
error("no phy");
|
||||||
ctlr->mii = nil;
|
return;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
print("rtl8169: oui %#ux phyno %d, macv = %#8.8ux phyv = %#4.4ux\n",
|
|
||||||
phy->oui, phy->phyno, ctlr->macv, ctlr->phyv);
|
print("#l%d: rtl8169: oui %#ux phyno %d, macv = %#8.8ux phyv = %#4.4ux\n",
|
||||||
|
edev->ctlrno, phy->oui, phy->phyno, ctlr->macv, ctlr->phyv);
|
||||||
|
|
||||||
miireset(ctlr->mii);
|
miireset(ctlr->mii);
|
||||||
|
|
||||||
microdelay(100);
|
microdelay(100);
|
||||||
|
|
||||||
miiane(ctlr->mii, ~0, ~0, ~0);
|
miiane(ctlr->mii, ~0, ~0, ~0);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -615,6 +613,8 @@ static void
|
||||||
rtl8169halt(Ctlr* ctlr)
|
rtl8169halt(Ctlr* ctlr)
|
||||||
{
|
{
|
||||||
csr8w(ctlr, Cr, 0);
|
csr8w(ctlr, Cr, 0);
|
||||||
|
|
||||||
|
ctlr->imr = 0;
|
||||||
csr16w(ctlr, Imr, 0);
|
csr16w(ctlr, Imr, 0);
|
||||||
csr16w(ctlr, Isr, ~0);
|
csr16w(ctlr, Isr, ~0);
|
||||||
}
|
}
|
||||||
|
@ -648,6 +648,7 @@ rtl8169replenish(Ctlr* ctlr)
|
||||||
D *d;
|
D *d;
|
||||||
int x;
|
int x;
|
||||||
Block *bp;
|
Block *bp;
|
||||||
|
u64int pa;
|
||||||
|
|
||||||
x = ctlr->rdt;
|
x = ctlr->rdt;
|
||||||
while(NEXT(x, ctlr->nrd) != ctlr->rdh){
|
while(NEXT(x, ctlr->nrd) != ctlr->rdh){
|
||||||
|
@ -658,9 +659,10 @@ rtl8169replenish(Ctlr* ctlr)
|
||||||
}
|
}
|
||||||
ctlr->rb[x] = bp;
|
ctlr->rb[x] = bp;
|
||||||
ctlr->nrq++;
|
ctlr->nrq++;
|
||||||
|
pa = PCIWADDR(bp->rp);
|
||||||
d = &ctlr->rd[x];
|
d = &ctlr->rd[x];
|
||||||
d->addrlo = PCIWADDR(bp->rp);
|
d->addrlo = pa;
|
||||||
d->addrhi = 0;
|
d->addrhi = pa >> 32;
|
||||||
coherence();
|
coherence();
|
||||||
d->control = (d->control & Eor) | Own | BALLOC(bp);
|
d->control = (d->control & Eor) | Own | BALLOC(bp);
|
||||||
x = NEXT(x, ctlr->nrd);
|
x = NEXT(x, ctlr->nrd);
|
||||||
|
@ -668,19 +670,22 @@ rtl8169replenish(Ctlr* ctlr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
rtl8169init(Ether* edev)
|
rtl8169init(Ether* edev)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
u32int r;
|
u32int r;
|
||||||
Block *bp;
|
Block *bp;
|
||||||
Ctlr *ctlr;
|
Ctlr *ctlr;
|
||||||
|
u64int pa;
|
||||||
u16int cplusc;
|
u16int cplusc;
|
||||||
|
|
||||||
ctlr = edev->ctlr;
|
ctlr = edev->ctlr;
|
||||||
ilock(ctlr);
|
ilock(ctlr);
|
||||||
|
if(rtl8169reset(ctlr) < 0){
|
||||||
rtl8169reset(ctlr);
|
iunlock(ctlr);
|
||||||
|
error("reset failed");
|
||||||
|
}
|
||||||
|
|
||||||
memset(ctlr->td, 0, sizeof(D)*ctlr->ntd);
|
memset(ctlr->td, 0, sizeof(D)*ctlr->ntd);
|
||||||
ctlr->tdh = ctlr->tdt = ctlr->ntq = 0;
|
ctlr->tdh = ctlr->tdt = ctlr->ntq = 0;
|
||||||
|
@ -716,10 +721,13 @@ rtl8169init(Ether* edev)
|
||||||
}
|
}
|
||||||
csr16w(ctlr, Cplusc, cplusc);
|
csr16w(ctlr, Cplusc, cplusc);
|
||||||
|
|
||||||
csr32w(ctlr, Tnpds+4, 0);
|
pa = PCIWADDR(ctlr->td);
|
||||||
csr32w(ctlr, Tnpds, PCIWADDR(ctlr->td));
|
csr32w(ctlr, Tnpds+4, pa>>32);
|
||||||
csr32w(ctlr, Rdsar+4, 0);
|
csr32w(ctlr, Tnpds, pa);
|
||||||
csr32w(ctlr, Rdsar, PCIWADDR(ctlr->rd));
|
|
||||||
|
pa = PCIWADDR(ctlr->rd);
|
||||||
|
csr32w(ctlr, Rdsar+4, pa>>32);
|
||||||
|
csr32w(ctlr, Rdsar, pa);
|
||||||
|
|
||||||
csr8w(ctlr, Cr, Te|Re);
|
csr8w(ctlr, Cr, Te|Re);
|
||||||
|
|
||||||
|
@ -755,8 +763,6 @@ rtl8169init(Ether* edev)
|
||||||
csr32w(ctlr, Mpc, 0);
|
csr32w(ctlr, Mpc, 0);
|
||||||
|
|
||||||
iunlock(ctlr);
|
iunlock(ctlr);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -766,69 +772,80 @@ rtl8169reseter(void *arg)
|
||||||
Ctlr *ctlr;
|
Ctlr *ctlr;
|
||||||
|
|
||||||
edev = arg;
|
edev = arg;
|
||||||
|
while(waserror())
|
||||||
|
;
|
||||||
for(;;){
|
for(;;){
|
||||||
rtl8169init(edev);
|
|
||||||
|
|
||||||
ctlr = edev->ctlr;
|
ctlr = edev->ctlr;
|
||||||
qunlock(&ctlr->alock);
|
|
||||||
|
|
||||||
while(waserror())
|
|
||||||
;
|
|
||||||
sleep(&ctlr->reset, return0, nil);
|
sleep(&ctlr->reset, return0, nil);
|
||||||
poperror();
|
rtl8169init(edev);
|
||||||
|
|
||||||
qlock(&ctlr->alock);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rtl8169interrupt(Ureg*, void* arg);
|
||||||
|
|
||||||
static void
|
static void
|
||||||
rtl8169attach(Ether* edev)
|
rtl8169attach(Ether* edev)
|
||||||
{
|
{
|
||||||
int timeo;
|
|
||||||
Ctlr *ctlr;
|
Ctlr *ctlr;
|
||||||
|
|
||||||
ctlr = edev->ctlr;
|
ctlr = edev->ctlr;
|
||||||
qlock(&ctlr->alock);
|
qlock(&ctlr->alock);
|
||||||
if(!ctlr->init){
|
if(ctlr->init){
|
||||||
ctlr->ntd = Ntd;
|
qunlock(&ctlr->alock);
|
||||||
ctlr->nrd = Nrd;
|
return;
|
||||||
ctlr->tb = malloc(ctlr->ntd*sizeof(Block*));
|
|
||||||
ctlr->rb = malloc(ctlr->nrd*sizeof(Block*));
|
|
||||||
ctlr->td = mallocalign(sizeof(D)*ctlr->ntd, 256, 0, 0);
|
|
||||||
ctlr->rd = mallocalign(sizeof(D)*ctlr->nrd, 256, 0, 0);
|
|
||||||
ctlr->dtcc = mallocalign(sizeof(Dtcc), 64, 0, 0);
|
|
||||||
if(ctlr->rb == nil || ctlr->rb == nil ||
|
|
||||||
ctlr->rd == nil || ctlr->rd == nil || ctlr->dtcc == nil){
|
|
||||||
free(ctlr->tb);
|
|
||||||
ctlr->tb = nil;
|
|
||||||
free(ctlr->rb);
|
|
||||||
ctlr->rb = nil;
|
|
||||||
free(ctlr->td);
|
|
||||||
ctlr->td = nil;
|
|
||||||
free(ctlr->rd);
|
|
||||||
ctlr->rd = nil;
|
|
||||||
free(ctlr->dtcc);
|
|
||||||
ctlr->dtcc = nil;
|
|
||||||
qunlock(&ctlr->alock);
|
|
||||||
error(Enomem);
|
|
||||||
}
|
|
||||||
ctlr->init = 1;
|
|
||||||
kproc("rtl8169", rtl8169reseter, edev);
|
|
||||||
|
|
||||||
/* rtl8169reseter() does qunlock(&ctlr->alock) when complete */
|
|
||||||
qlock(&ctlr->alock);
|
|
||||||
}
|
}
|
||||||
|
if(waserror()){
|
||||||
|
print("#l%d: rtl8169: %s\n", edev->ctlrno, up->errstr);
|
||||||
|
qunlock(&ctlr->alock);
|
||||||
|
nexterror();
|
||||||
|
}
|
||||||
|
ctlr->ntd = Ntd;
|
||||||
|
ctlr->nrd = Nrd;
|
||||||
|
|
||||||
|
ctlr->tb = malloc(ctlr->ntd*sizeof(Block*));
|
||||||
|
ctlr->rb = malloc(ctlr->nrd*sizeof(Block*));
|
||||||
|
ctlr->td = mallocalign(sizeof(D)*ctlr->ntd, 256, 0, 0);
|
||||||
|
ctlr->rd = mallocalign(sizeof(D)*ctlr->nrd, 256, 0, 0);
|
||||||
|
ctlr->dtcc = mallocalign(sizeof(Dtcc), 64, 0, 0);
|
||||||
|
if(waserror()){
|
||||||
|
free(ctlr->tb);
|
||||||
|
ctlr->tb = nil;
|
||||||
|
free(ctlr->rb);
|
||||||
|
ctlr->rb = nil;
|
||||||
|
free(ctlr->td);
|
||||||
|
ctlr->td = nil;
|
||||||
|
free(ctlr->rd);
|
||||||
|
ctlr->rd = nil;
|
||||||
|
free(ctlr->dtcc);
|
||||||
|
ctlr->dtcc = nil;
|
||||||
|
nexterror();
|
||||||
|
}
|
||||||
|
|
||||||
|
if(ctlr->tb == nil || ctlr->rb == nil
|
||||||
|
|| ctlr->td == nil || ctlr->rd == nil
|
||||||
|
|| ctlr->dtcc == nil)
|
||||||
|
error(Enomem);
|
||||||
|
|
||||||
|
pcisetbme(ctlr->pcidev);
|
||||||
|
intrenable(edev->irq, rtl8169interrupt, edev, edev->tbdf, edev->name);
|
||||||
|
if(waserror()){
|
||||||
|
rtl8169halt(ctlr);
|
||||||
|
pciclrbme(ctlr->pcidev);
|
||||||
|
intrdisable(edev->irq, rtl8169interrupt, edev, edev->tbdf, edev->name);
|
||||||
|
nexterror();
|
||||||
|
}
|
||||||
|
|
||||||
|
rtl8169init(edev);
|
||||||
|
rtl8169mii(edev);
|
||||||
|
ctlr->init = 1;
|
||||||
|
|
||||||
|
poperror();
|
||||||
|
poperror();
|
||||||
|
|
||||||
|
kproc("rtl8169", rtl8169reseter, edev);
|
||||||
|
|
||||||
qunlock(&ctlr->alock);
|
qunlock(&ctlr->alock);
|
||||||
|
poperror();
|
||||||
/*
|
|
||||||
* Wait for link to be ready.
|
|
||||||
*/
|
|
||||||
for(timeo = 0; timeo < 35; timeo++){
|
|
||||||
if(miistatus(ctlr->mii) == 0)
|
|
||||||
break;
|
|
||||||
delay(100); /* print fewer miistatus messages */
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -866,6 +883,7 @@ rtl8169transmit(Ether* edev)
|
||||||
D *d;
|
D *d;
|
||||||
Block *bp;
|
Block *bp;
|
||||||
Ctlr *ctlr;
|
Ctlr *ctlr;
|
||||||
|
u64int pa;
|
||||||
int x;
|
int x;
|
||||||
|
|
||||||
ctlr = edev->ctlr;
|
ctlr = edev->ctlr;
|
||||||
|
@ -894,9 +912,10 @@ rtl8169transmit(Ether* edev)
|
||||||
if((bp = qget(edev->oq)) == nil)
|
if((bp = qget(edev->oq)) == nil)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
pa = PCIWADDR(bp->rp);
|
||||||
d = &ctlr->td[x];
|
d = &ctlr->td[x];
|
||||||
d->addrlo = PCIWADDR(bp->rp);
|
d->addrlo = pa;
|
||||||
d->addrhi = 0;
|
d->addrhi = pa >> 32;
|
||||||
coherence();
|
coherence();
|
||||||
d->control = (d->control & Eor) | Own | Fs | Ls | BLEN(bp);
|
d->control = (d->control & Eor) | Own | Fs | Ls | BLEN(bp);
|
||||||
|
|
||||||
|
@ -990,7 +1009,6 @@ rtl8169receive(Ether* edev)
|
||||||
static void
|
static void
|
||||||
rtl8169restart(Ctlr *ctlr)
|
rtl8169restart(Ctlr *ctlr)
|
||||||
{
|
{
|
||||||
ctlr->imr = 0;
|
|
||||||
rtl8169halt(ctlr);
|
rtl8169halt(ctlr);
|
||||||
wakeup(&ctlr->reset);
|
wakeup(&ctlr->reset);
|
||||||
}
|
}
|
||||||
|
@ -1037,6 +1055,14 @@ rtl8169interrupt(Ureg*, void* arg)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
rtl8169shutdown(Ether *edev)
|
||||||
|
{
|
||||||
|
Ctlr *ctlr = edev->ctlr;
|
||||||
|
|
||||||
|
rtl8169halt(ctlr);
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
vetmacv(Ctlr *ctlr, uint *macv)
|
vetmacv(Ctlr *ctlr, uint *macv)
|
||||||
{
|
{
|
||||||
|
@ -1103,11 +1129,14 @@ rtl8169pci(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(p->mem[0].size == 0 || (p->mem[0].bar & 1) == 0)
|
||||||
|
continue;
|
||||||
port = p->mem[0].bar & ~3;
|
port = p->mem[0].bar & ~3;
|
||||||
if(ioalloc(port, p->mem[0].size, 0, "rtl8169") < 0){
|
if(ioalloc(port, p->mem[0].size, 0, "rtl8169") < 0){
|
||||||
print("rtl8169: port %#ux in use\n", port);
|
print("rtl8169: port %#ux in use\n", port);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctlr = malloc(sizeof(Ctlr));
|
ctlr = malloc(sizeof(Ctlr));
|
||||||
if(ctlr == nil){
|
if(ctlr == nil){
|
||||||
print("rtl8169: can't allocate memory\n");
|
print("rtl8169: can't allocate memory\n");
|
||||||
|
@ -1121,31 +1150,19 @@ rtl8169pci(void)
|
||||||
|
|
||||||
pcienable(p);
|
pcienable(p);
|
||||||
if(vetmacv(ctlr, &macv) == -1){
|
if(vetmacv(ctlr, &macv) == -1){
|
||||||
|
print("rtl8169: %T: unknown mac %.4ux %.8ux\n", p->tbdf, p->did, macv);
|
||||||
pcidisable(p);
|
pcidisable(p);
|
||||||
iofree(port);
|
iofree(port);
|
||||||
free(ctlr);
|
free(ctlr);
|
||||||
print("rtl8169: unknown mac %.4ux %.8ux\n", p->did, macv);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(rtl8169reset(ctlr)){
|
|
||||||
pcidisable(p);
|
|
||||||
iofree(port);
|
|
||||||
free(ctlr);
|
|
||||||
print("rtl8169: reset failed\n");
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
rtl8169halt(ctlr);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Extract the chip hardware version,
|
* Extract the chip hardware version,
|
||||||
* needed to configure each properly.
|
* needed to configure each properly.
|
||||||
*/
|
*/
|
||||||
ctlr->macv = macv;
|
ctlr->macv = macv;
|
||||||
|
|
||||||
rtl8169mii(ctlr);
|
|
||||||
|
|
||||||
pcisetbme(p);
|
|
||||||
|
|
||||||
if(rtl8169ctlrhead != nil)
|
if(rtl8169ctlrhead != nil)
|
||||||
rtl8169ctlrtail->next = ctlr;
|
rtl8169ctlrtail->next = ctlr;
|
||||||
else
|
else
|
||||||
|
@ -1208,6 +1225,7 @@ rtl8169pnp(Ether* edev)
|
||||||
edev->attach = rtl8169attach;
|
edev->attach = rtl8169attach;
|
||||||
edev->transmit = rtl8169transmit;
|
edev->transmit = rtl8169transmit;
|
||||||
edev->ifstat = rtl8169ifstat;
|
edev->ifstat = rtl8169ifstat;
|
||||||
|
edev->shutdown = rtl8169shutdown;
|
||||||
|
|
||||||
edev->arg = edev;
|
edev->arg = edev;
|
||||||
edev->promiscuous = rtl8169promiscuous;
|
edev->promiscuous = rtl8169promiscuous;
|
||||||
|
@ -1215,8 +1233,6 @@ rtl8169pnp(Ether* edev)
|
||||||
|
|
||||||
rtl8169link(edev);
|
rtl8169link(edev);
|
||||||
|
|
||||||
intrenable(edev->irq, rtl8169interrupt, edev, edev->tbdf, edev->name);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -48,15 +48,19 @@ enum {
|
||||||
typedef struct Vctl {
|
typedef struct Vctl {
|
||||||
Vctl* next; /* handlers on this vector */
|
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 isintr; /* interrupt or fault/trap */
|
||||||
int irq;
|
|
||||||
int tbdf;
|
|
||||||
int (*isr)(int); /* get isr bit for this irq */
|
int (*isr)(int); /* get isr bit for this irq */
|
||||||
int (*eoi)(int); /* eoi */
|
int (*eoi)(int); /* eoi */
|
||||||
|
|
||||||
void (*f)(Ureg*, void*); /* handler to call */
|
void (*disable)(Vctl*);
|
||||||
void* a; /* argument to call it with */
|
int irq;
|
||||||
|
int tbdf;
|
||||||
|
|
||||||
|
char name[KNAMELEN]; /* of driver */
|
||||||
} Vctl;
|
} Vctl;
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
|
|
|
@ -469,6 +469,15 @@ htmsienable(Pcidev *pdev)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
msiintrdisable(Vctl *v)
|
||||||
|
{
|
||||||
|
Pcidev *pci;
|
||||||
|
|
||||||
|
if((pci = pcimatchtbdf(v->tbdf)) != nil)
|
||||||
|
pcimsidisable(pci);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
msiintrenable(Vctl *v)
|
msiintrenable(Vctl *v)
|
||||||
{
|
{
|
||||||
|
@ -493,6 +502,7 @@ msiintrenable(Vctl *v)
|
||||||
cpu = mpintrcpu();
|
cpu = mpintrcpu();
|
||||||
if(pcimsienable(pci, 0xFEE00000ULL | (cpu << 12), vno | (1<<14)) < 0)
|
if(pcimsienable(pci, 0xFEE00000ULL | (cpu << 12), vno | (1<<14)) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
v->disable = msiintrdisable;
|
||||||
v->isr = lapicisr;
|
v->isr = lapicisr;
|
||||||
v->eoi = lapiceoi;
|
v->eoi = lapiceoi;
|
||||||
return vno;
|
return vno;
|
||||||
|
|
|
@ -89,8 +89,7 @@ intrdisable(int irq, void (*f)(Ureg *, void *), void *a, int tbdf, char *name)
|
||||||
irq = 9;
|
irq = 9;
|
||||||
if(arch->intrvecno == nil || (tbdf != BUSUNKNOWN && (irq == 0xff || irq == 0))){
|
if(arch->intrvecno == nil || (tbdf != BUSUNKNOWN && (irq == 0xff || irq == 0))){
|
||||||
/*
|
/*
|
||||||
* on APIC machine, irq is pretty meaningless
|
* on APIC machine, irq is pretty meaningless.
|
||||||
* and disabling a the vector is not implemented.
|
|
||||||
* however, we still want to remove the matching
|
* however, we still want to remove the matching
|
||||||
* Vctl entry to prevent calling Vctl.f() with a
|
* Vctl entry to prevent calling Vctl.f() with a
|
||||||
* stale Vctl.a pointer.
|
* stale Vctl.a pointer.
|
||||||
|
@ -109,6 +108,8 @@ intrdisable(int irq, void (*f)(Ureg *, void *), void *a, int tbdf, char *name)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(v != nil){
|
if(v != nil){
|
||||||
|
if(v->disable != nil)
|
||||||
|
(*v->disable)(v);
|
||||||
*pv = v->next;
|
*pv = v->next;
|
||||||
xfree(v);
|
xfree(v);
|
||||||
|
|
||||||
|
|
|
@ -111,6 +111,8 @@ intrdisable(int irq, void (*f)(Ureg *, void *), void *a, int tbdf, char *name)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(v != nil){
|
if(v != nil){
|
||||||
|
if(v->disable != nil)
|
||||||
|
(*v->disable)(v);
|
||||||
*pv = v->next;
|
*pv = v->next;
|
||||||
xfree(v);
|
xfree(v);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue