diff -r 3d85f589531a sys/src/9/pc/ether8169.c --- a/sys/src/9/pc/ether8169.c Sat Nov 21 16:26:46 2020 +0100 +++ b/sys/src/9/pc/ether8169.c Sat Nov 21 19:28:42 2020 +0100 @@ -615,6 +615,8 @@ rtl8169halt(Ctlr* ctlr) { csr8w(ctlr, Cr, 0); + + ctlr->imr = 0; csr16w(ctlr, Imr, 0); csr16w(ctlr, Isr, ~0); } @@ -782,53 +784,52 @@ } } +static void rtl8169interrupt(Ureg*, void* arg); + static void rtl8169attach(Ether* edev) { - int timeo; Ctlr *ctlr; ctlr = edev->ctlr; qlock(&ctlr->alock); - if(!ctlr->init){ - 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(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); + if(ctlr->init){ + qunlock(&ctlr->alock); + return; + } + if(waserror()){ + 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(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; + error(Enomem); + } + ctlr->init = 1; + pcisetbme(ctlr->pcidev); + intrenable(edev->irq, rtl8169interrupt, edev, edev->tbdf, edev->name); - /* rtl8169reseter() does qunlock(&ctlr->alock) when complete */ - qlock(&ctlr->alock); - } - qunlock(&ctlr->alock); + kproc("rtl8169", rtl8169reseter, edev); - /* - * Wait for link to be ready. - */ - for(timeo = 0; timeo < 35; timeo++){ - if(miistatus(ctlr->mii) == 0) - break; - delay(100); /* print fewer miistatus messages */ - } + /* reseter unlocks ctlr->alock */ + poperror(); } static void @@ -990,7 +991,6 @@ static void rtl8169restart(Ctlr *ctlr) { - ctlr->imr = 0; rtl8169halt(ctlr); wakeup(&ctlr->reset); } @@ -1037,6 +1037,14 @@ } } +static void +rtl8169shutdown(Ether *edev) +{ + Ctlr *ctlr = edev->ctlr; + + rtl8169halt(ctlr); +} + int vetmacv(Ctlr *ctlr, uint *macv) { @@ -1144,8 +1152,6 @@ rtl8169mii(ctlr); - pcisetbme(p); - if(rtl8169ctlrhead != nil) rtl8169ctlrtail->next = ctlr; else @@ -1208,6 +1214,7 @@ edev->attach = rtl8169attach; edev->transmit = rtl8169transmit; edev->ifstat = rtl8169ifstat; + edev->shutdown = rtl8169shutdown; edev->arg = edev; edev->promiscuous = rtl8169promiscuous; @@ -1215,8 +1222,6 @@ rtl8169link(edev); - intrenable(edev->irq, rtl8169interrupt, edev, edev->tbdf, edev->name); - return 0; }