ref: 9fec0e736081cd155afb6a413b7641b93faed519
parent: 4d7c195804991b9c762f9a859679282c7014bbbb
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Sun Oct 7 18:28:21 EDT 2018
pc drivers: use pcienable() to handle device power up and missing initialization
--- a/sys/src/9/pc/audiohda.c
+++ b/sys/src/9/pc/audiohda.c
@@ -1852,6 +1852,7 @@
return -1;
Found:
+ pcienable(p);
adev->ctlr = ctlr;
ctlr->adev = adev;
@@ -1890,9 +1891,6 @@
pcicfgw8(p, 0x44, pcicfgr8(p, 0x44) & 0xf8);
}
- pcisetbme(p);
- pcisetpms(p, 0);
-
ctlr->no = adev->ctlrno;
ctlr->size = p->mem[0].size;
ctlr->q = qopen(256, 0, 0, 0);
@@ -1924,6 +1922,7 @@
print("#A%d: input streamalloc failed\n", ctlr->no);
}
}
+ pcisetbme(p);
if(enumdev(ctlr) < 0){
print("#A%d: no audio codecs found\n", ctlr->no);
--- a/sys/src/9/pc/ether79c970.c
+++ b/sys/src/9/pc/ether79c970.c
@@ -544,9 +544,10 @@
ether->port = ctlr->port;
ether->irq = ctlr->pcidev->intl;
ether->tbdf = ctlr->pcidev->tbdf;
- pcisetbme(ctlr->pcidev);
ilock(ctlr);
ctlr->init = 1;
+ pcienable(ctlr->pcidev);
+ pcisetbme(ctlr->pcidev);
io32r(ctlr, Sreset);
io16r(ctlr, Sreset);
--- a/sys/src/9/pc/ether8139.c
+++ b/sys/src/9/pc/ether8139.c
@@ -681,7 +681,7 @@
{
Pcidev *p;
Ctlr *ctlr;
- int i, port;
+ int port;
/*
* Any adapter matches if no edev->port is supplied,
@@ -701,20 +701,10 @@
print("rtl8139: port %#ux in use\n", port);
continue;
}
-
- if(pcigetpms(p) > 0){
- pcisetpms(p, 0);
-
- for(i = 0; i < 6; i++)
- pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
- pcicfgw8(p, PciINTL, p->intl);
- pcicfgw8(p, PciLTR, p->ltr);
- pcicfgw8(p, PciCLS, p->cls);
- pcicfgw16(p, PciPCR, p->pcr);
- }
-
+ pcienable(p);
ctlr->port = port;
if(rtl8139reset(ctlr)) {
+ pcidisable(p);
iofree(port);
continue;
}
--- a/sys/src/9/pc/ether8169.c
+++ b/sys/src/9/pc/ether8169.c
@@ -1118,7 +1118,9 @@
ctlr->pciv = i;
ctlr->pcie = pcie;
+ pcienable(p);
if(vetmacv(ctlr, &macv) == -1){
+ pcidisable(p);
iofree(port);
free(ctlr);
print("rtl8169: unknown mac %.4ux %.8ux\n", p->did, macv);
@@ -1125,18 +1127,8 @@
continue;
}
- if(pcigetpms(p) > 0){
- pcisetpms(p, 0);
-
- for(i = 0; i < 6; i++)
- pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
- pcicfgw8(p, PciINTL, p->intl);
- pcicfgw8(p, PciLTR, p->ltr);
- pcicfgw8(p, PciCLS, p->cls);
- pcicfgw16(p, PciPCR, p->pcr);
- }
-
if(rtl8169reset(ctlr)){
+ pcidisable(p);
iofree(port);
free(ctlr);
print("rtl8169: reset failed\n");
--- a/sys/src/9/pc/ether82543gc.c
+++ b/sys/src/9/pc/ether82543gc.c
@@ -1290,11 +1290,6 @@
ctlr->id = (p->did<<16)|p->vid;
ctlr->nic = mem;
- if(gc82543reset(ctlr)){
- free(ctlr);
- continue;
- }
-
if(gc82543ctlrhead != nil)
gc82543ctlrtail->next = ctlr;
else
@@ -1327,6 +1322,9 @@
}
if(ctlr == nil)
return -1;
+
+ pcienable(ctlr->pcidev);
+ gc82543reset(ctlr);
edev->ctlr = ctlr;
edev->port = ctlr->port;
@@ -1347,6 +1345,7 @@
}
}
gc82543init(edev);
+ pcisetbme(ctlr->pcidev);
/*
* Linkage to the generic ethernet driver.
--- a/sys/src/9/pc/ether82557.c
+++ b/sys/src/9/pc/ether82557.c
@@ -930,7 +930,7 @@
{
Pcidev *p;
Ctlr *ctlr;
- int i, nop, port;
+ int nop, port;
p = nil;
nop = 0;
@@ -956,17 +956,6 @@
break;
}
- if(pcigetpms(p) > 0){
- pcisetpms(p, 0);
-
- for(i = 0; i < 6; i++)
- pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
- pcicfgw8(p, PciINTL, p->intl);
- pcicfgw8(p, PciLTR, p->ltr);
- pcicfgw8(p, PciCLS, p->cls);
- pcicfgw16(p, PciPCR, p->pcr);
- }
-
/*
* bar[0] is the memory-mapped register address (4KB),
* bar[1] is the I/O port register address (32 bytes) and
@@ -993,8 +982,6 @@
else
ctlrhead = ctlr;
ctlrtail = ctlr;
-
- pcisetbme(p);
}
}
@@ -1074,6 +1061,9 @@
}
if(ctlr == nil)
return -1;
+
+ pcienable(ctlr->pcidev);
+ pcisetbme(ctlr->pcidev);
/*
* Initialise the Ctlr structure.
--- a/sys/src/9/pc/ether82563.c
+++ b/sys/src/9/pc/ether82563.c
@@ -2053,11 +2053,13 @@
print("%s: can't map 0x%lux\n", cname(ctlr), ctlr->port);
return -1;
}
+ pcienable(p);
if(i82563reset(ctlr)){
+ pcidisable(p);
vunmap(ctlr->nic, p->mem[0].size);
return -1;
}
- pcisetbme(ctlr->pcidev);
+ pcisetbme(p);
return 0;
}
--- a/sys/src/9/pc/ether82598.c
+++ b/sys/src/9/pc/ether82598.c
@@ -897,6 +897,7 @@
free(c);
continue;
}
+ pcienable(p);
c->p = p;
c->io = io;
c->reg = (u32int*)mem;
--- a/sys/src/9/pc/ether83815.c
+++ b/sys/src/9/pc/ether83815.c
@@ -1098,13 +1098,6 @@
free(ctlr);
continue;
}
-
- if(softreset(ctlr, 0) == -1){
- free(ctlr);
- continue;
- }
- srom(ctlr);
-
if(ctlrhead != nil)
ctlrtail->next = ctlr;
else
@@ -1147,6 +1140,10 @@
}
if(ctlr == nil)
return -1;
+
+ pcienable(ctlr->pcidev);
+ softreset(ctlr, 0);
+ srom(ctlr);
ether->ctlr = ctlr;
ether->port = ctlr->port;
--- a/sys/src/9/pc/etherbcm.c
+++ b/sys/src/9/pc/etherbcm.c
@@ -791,8 +791,6 @@
break;
}
- pcisetbme(pdev);
- pcisetpms(pdev, 0);
ctlr = malloc(sizeof(Ctlr));
if(ctlr == nil) {
print("bcm: unable to alloc Ctlr\n");
@@ -867,7 +865,10 @@
if(ctlr == nil)
return -1;
-
+
+ pcienable(ctlr->pdev);
+ pcisetbme(ctlr->pdev);
+
edev->ctlr = ctlr;
edev->port = ctlr->port;
edev->irq = ctlr->pdev->intl;
--- a/sys/src/9/pc/etherdp83820.c
+++ b/sys/src/9/pc/etherdp83820.c
@@ -1170,6 +1170,7 @@
}
ctlr->port = p->mem[1].bar & ~0x0F;
ctlr->pcidev = p;
+ pcienable(p);
ctlr->id = (p->did<<16)|p->vid;
ctlr->nic = mem;
--- a/sys/src/9/pc/etherelnk3.c
+++ b/sys/src/9/pc/etherelnk3.c
@@ -1481,6 +1481,7 @@
print("tcm59Xpci: port 0x%uX in use\n", port);
continue;
}
+ pcienable(p);
irq = p->intl;
txrxreset(port);
--- a/sys/src/9/pc/etherga620.c
+++ b/sys/src/9/pc/etherga620.c
@@ -1178,6 +1178,8 @@
}
ctlr->port = p->mem[0].bar & ~0x0F;
ctlr->pcidev = p;
+ pcienable(p);
+
ctlr->id = p->did<<16 | p->vid;
ctlr->nic = mem;
@@ -1185,6 +1187,7 @@
free(ctlr);
continue;
}
+ pcisetbme(p);
if(ctlrhead != nil)
ctlrtail->next = ctlr;
--- a/sys/src/9/pc/etherigbe.c
+++ b/sys/src/9/pc/etherigbe.c
@@ -1966,6 +1966,7 @@
}
ctlr->port = p->mem[0].bar & ~0x0F;
ctlr->pcidev = p;
+ pcienable(p);
ctlr->id = (p->did<<16)|p->vid;
ctlr->cls = cls*4;
ctlr->nic = mem;
--- a/sys/src/9/pc/etheriwl.c
+++ b/sys/src/9/pc/etheriwl.c
@@ -821,6 +821,23 @@
uint u, caloff, regoff;
ctlr = edev->ctlr;
+
+ /* Clear device-specific "PCI retry timeout" register (41h). */
+ if(pcicfgr8(ctlr->pdev, 0x41) != 0)
+ pcicfgw8(ctlr->pdev, 0x41, 0);
+
+ /* Clear interrupt disable bit. Hardware bug workaround. */
+ if(ctlr->pdev->pcr & 0x400){
+ ctlr->pdev->pcr &= ~0x400;
+ pcicfgw16(ctlr->pdev, PciPCR, ctlr->pdev->pcr);
+ }
+
+ ctlr->type = (csr32r(ctlr, Rev) >> 4) & 0x1F;
+ if(fwname[ctlr->type] == nil){
+ print("iwl: unsupported controller type %d\n", ctlr->type);
+ return -1;
+ }
+
if((err = handover(ctlr)) != nil)
goto Err;
if((err = poweron(ctlr)) != nil)
@@ -2465,19 +2482,6 @@
break;
}
- /* Clear device-specific "PCI retry timeout" register (41h). */
- if(pcicfgr8(pdev, 0x41) != 0)
- pcicfgw8(pdev, 0x41, 0);
-
- /* Clear interrupt disable bit. Hardware bug workaround. */
- if(pdev->pcr & 0x400){
- pdev->pcr &= ~0x400;
- pcicfgw16(pdev, PciPCR, pdev->pcr);
- }
-
- pcisetbme(pdev);
- pcisetpms(pdev, 0);
-
ctlr = malloc(sizeof(Ctlr));
if(ctlr == nil) {
print("iwl: unable to alloc Ctlr\n");
@@ -2492,15 +2496,7 @@
}
ctlr->nic = mem;
ctlr->pdev = pdev;
- ctlr->type = (csr32r(ctlr, Rev) >> 4) & 0x1F;
- if(fwname[ctlr->type] == nil){
- print("iwl: unsupported controller type %d\n", ctlr->type);
- vunmap(mem, pdev->mem[0].size);
- free(ctlr);
- continue;
- }
-
if(iwlhead != nil)
iwltail->link = ctlr;
else
@@ -2542,11 +2538,14 @@
edev->multicast = iwlmulticast;
edev->mbps = 54;
+ pcienable(ctlr->pdev);
if(iwlinit(edev) < 0){
+ pcidisable(ctlr->pdev);
edev->ctlr = nil;
goto again;
}
+ pcisetbme(ctlr->pdev);
intrenable(edev->irq, iwlinterrupt, edev, edev->tbdf, edev->name);
return 0;
--- a/sys/src/9/pc/etherm10g.c
+++ b/sys/src/9/pc/etherm10g.c
@@ -1571,6 +1571,7 @@
continue;
}
c->pcidev = p;
+ pcienable(p);
c->id = p->did<<16 | p->vid;
c->boot = pcicap(p, PciCapVND);
// kickthebaby(p, c);
--- a/sys/src/9/pc/etherrt2860.c
+++ b/sys/src/9/pc/etherrt2860.c
@@ -3489,9 +3489,6 @@
break;
}
- pcisetbme(pdev);
- pcisetpms(pdev, 0);
-
ctlr = malloc(sizeof(Ctlr));
if(ctlr == nil){
print("rt2860: unable to alloc Ctlr\n");
@@ -3534,6 +3531,9 @@
if(ctlr == nil)
return -1;
+
+ pcienable(ctlr->pdev);
+ pcisetbme(ctlr->pdev);
edev->ctlr = ctlr;
edev->port = ctlr->port;
--- a/sys/src/9/pc/ethervgbe.c
+++ b/sys/src/9/pc/ethervgbe.c
@@ -930,9 +930,6 @@
continue;
}
- pcisetbme(pdev);
- pcisetpms(pdev, 0);
-
port = pdev->mem[0].bar;
size = pdev->mem[0].size;
@@ -1126,6 +1123,9 @@
if(ctlr == nil)
return -1;
+
+ pcienable(ctlr->pdev);
+ pcisetbme(ctlr->pdev);
vgbereset(ctlr);
--- a/sys/src/9/pc/ethervt6102.c
+++ b/sys/src/9/pc/ethervt6102.c
@@ -976,6 +976,7 @@
}
ctlr->port = port;
ctlr->pcidev = p;
+ pcienable(p);
ctlr->id = (p->did<<16)|p->vid;
if((cls = pcicfgr8(p, PciCLS)) == 0 || cls == 0xFF)
cls = 0x10;
--- a/sys/src/9/pc/ethervt6105m.c
+++ b/sys/src/9/pc/ethervt6105m.c
@@ -1140,6 +1140,7 @@
}
ctlr->port = port;
ctlr->pcidev = p;
+ pcienable(p);
ctlr->id = (p->did<<16)|p->vid;
if((cls = pcicfgr8(p, PciCLS)) == 0 || cls == 0xFF)
cls = 0x10;
--- a/sys/src/9/pc/etherwavelan.c
+++ b/sys/src/9/pc/etherwavelan.c
@@ -134,7 +134,6 @@
else
ctlrhead = ctlr;
ctlrtail = ctlr;
- pcisetbme(p);
}
}
@@ -158,7 +157,9 @@
return -1;
ctlr->active = 1;
+
ilock(ctlr);
+ pcienable(ctlr->pcidev);
ether->irq = ctlr->pcidev->intl;
ether->tbdf = ctlr->pcidev->tbdf;
@@ -189,6 +190,7 @@
*p = ' ';
w_option(ctlr, ether->opt[i], strlen(ether->opt[i]));
}
+ pcisetbme(ctlr->pcidev);
iunlock(ctlr);
return 0;
}
--- a/sys/src/9/pc/etherwpi.c
+++ b/sys/src/9/pc/etherwpi.c
@@ -1793,9 +1793,6 @@
if(pcicfgr8(pdev, 0x41) != 0)
pcicfgw8(pdev, 0x41, 0);
- pcisetbme(pdev);
- pcisetpms(pdev, 0);
-
ctlr = malloc(sizeof(Ctlr));
if(ctlr == nil) {
print("wpi: unable to alloc Ctlr\n");
@@ -1853,11 +1850,13 @@
edev->multicast = wpimulticast;
edev->mbps = 54;
+ pcienable(ctlr->pdev);
if(wpiinit(edev) < 0){
+ pcidisable(ctlr->pdev);
edev->ctlr = nil;
goto again;
}
-
+ pcisetbme(ctlr->pdev);
intrenable(edev->irq, wpiinterrupt, edev, edev->tbdf, edev->name);
return 0;
--- a/sys/src/9/pc/etheryuk.c
+++ b/sys/src/9/pc/etheryuk.c
@@ -2129,6 +2129,8 @@
Pcidev *p;
p = c->p;
+ pcienable(p);
+
c->io = p->mem[0].bar&~0xf;
mem = vmap(c->io, p->mem[0].size);
if(mem == nil){
--- a/sys/src/9/pc/pmmc.c
+++ b/sys/src/9/pc/pmmc.c
@@ -234,6 +234,13 @@
if(p == nil || p->mem[0].size < 256)
return -1;
+ pmmc->mmio = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
+ if(pmmc->mmio == nil)
+ return -1;
+
+ pmmc->pdev = p;
+ pcienable(p);
+
if(p->did == 0x1180 && p->vid == 0xe823){ /* Ricoh */
/* Enable SD2.0 mode. */
pcicfgw8(p, 0xf9, 0xfc);
@@ -249,10 +256,6 @@
pcicfgw8(p, 0xfc, 0x00);
}
- pmmc->mmio = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
- if(pmmc->mmio == nil)
- return -1;
- pmmc->pdev = p;
return 0;
}
--- a/sys/src/9/pc/sdiahci.c
+++ b/sys/src/9/pc/sdiahci.c
@@ -2175,6 +2175,7 @@
s->ctlr = c;
c->sdev = s;
+ pcienable(p);
ahcihandoff((Ahba*)c->mmio);
if(p->vid == 0x8086)
iasetupahci(c);
@@ -2181,6 +2182,7 @@
nunit = ahciconf(c);
if(nunit < 1){
vunmap(c->mmio, p->mem[Abar].size);
+ pcidisable(p);
continue;
}
c->ndrive = s->nunit = nunit;
--- a/sys/src/9/pc/sdnvme.c
+++ b/sys/src/9/pc/sdnvme.c
@@ -566,6 +566,7 @@
print("nvme: no memory for Ctlr\n");
break;
}
+ pcienable(p);
ctlr->pci = p;
ctlr->reg = vmap(p->mem[0].bar & ~0xF, p->mem[0].size);
if(ctlr->reg == nil){
@@ -573,6 +574,7 @@
Bad:
if(ctlr->reg != nil)
vunmap(ctlr->reg, p->mem[0].size);
+ pcidisable(p);
free(ctlr);
continue;
}
--- a/sys/src/9/pc/uartaxp.c
+++ b/sys/src/9/pc/uartaxp.c
@@ -795,6 +795,8 @@
ctlr->gcb = (Gcb*)(ctlr->mem+0x10000);
print("mem 0x%ux size %d: ", bar, pcidev->mem[2].size);
+ pcienable(pcidev);
+
/*
* Toggle the software reset and wait for
* the adapter local init status to indicate done.
--- a/sys/src/9/pc/uartpci.c
+++ b/sys/src/9/pc/uartpci.c
@@ -35,6 +35,7 @@
return nil;
}
+ pcienable(p);
uart = head;
for(i = 0; i < n; i++){
ctlr = i8250alloc(io + i*iosize, p->intl, p->tbdf);
--- a/sys/src/9/pc/usbehcipc.c
+++ b/sys/src/9/pc/usbehcipc.c
@@ -186,12 +186,16 @@
print("usbehci: no memory\n");
continue;
}
+
+ if((capio = vmap(io, p->mem[0].size)) == nil){
+ print("usbehci: cannot map mmio\n");
+ free(ctlr);
+ continue;
+ }
+
ctlr->pcidev = p;
ctlr->base = io;
- capio = ctlr->capio = vmap(io, p->mem[0].size);
- ctlr->opio = (Eopio*)((uintptr)capio + (capio->cap & 0xff));
- pcisetbme(p);
- pcisetpms(p, 0);
+ ctlr->capio = capio;
for(i = 0; i < Nhcis; i++)
if(ctlrs[i] == nil){
ctlrs[i] = ctlr;
@@ -248,6 +252,8 @@
return -1;
p = ctlr->pcidev;
+ pcienable(p);
+
hp->aux = ctlr;
hp->port = ctlr->base;
hp->irq = p->intl;
@@ -263,8 +269,11 @@
capio->parms & 0x40 ? "explicit" : "automatic",
capio->parms & 0x10 ? "" : "no ", hp->nports);
+ ctlr->opio = (Eopio*)((uintptr)capio + (capio->cap & 0xff));
ehcireset(ctlr);
ehcimeminit(ctlr);
+
+ pcisetbme(p);
/*
* Linkage to the generic HCI driver.
--- a/sys/src/9/pc/usbohci.c
+++ b/sys/src/9/pc/usbohci.c
@@ -2405,12 +2405,14 @@
print("ohci: no memory\n");
continue;
}
+ if((ctlr->ohci = vmap(io, p->mem[0].size)) == nil){
+ print("ohci: can't map ohci\n");
+ free(ctlr);
+ continue;
+ }
ctlr->pcidev = p;
ctlr->base = io;
- ctlr->ohci = vmap(io, p->mem[0].size);
dprint("scanpci: ctlr %#p, ohci %#p\n", ctlr, ctlr->ohci);
- pcisetbme(p);
- pcisetpms(p, 0);
for(i = 0; i < Nhcis; i++)
if(ctlrs[i] == nil){
ctlrs[i] = ctlr;
@@ -2577,11 +2579,15 @@
iunlock(&resetlck);
if(ctlrs[i] == nil || i == Nhcis)
return -1;
- if(ctlr->ohci->control == ~0)
- return -1;
-
p = ctlr->pcidev;
+ pcienable(p);
+
+ if(ctlr->ohci->control == ~0){
+ pcidisable(p);
+ return -1;
+ }
+
hp->aux = ctlr;
hp->port = ctlr->base;
hp->irq = p->intl;
@@ -2590,6 +2596,8 @@
ohcireset(ctlr);
ohcimeminit(ctlr);
+
+ pcisetbme(p);
/*
* Linkage to the generic HCI driver.
--- a/sys/src/9/pc/usbuhci.c
+++ b/sys/src/9/pc/usbuhci.c
@@ -2319,6 +2319,8 @@
return -1;
p = ctlr->pcidev;
+ pcienable(p);
+
hp->aux = ctlr;
hp->port = ctlr->port;
hp->irq = p->intl;
@@ -2327,6 +2329,8 @@
uhcireset(ctlr);
uhcimeminit(ctlr);
+
+ pcisetbme(p);
/*
* Linkage to the generic HCI driver.
--- a/sys/src/9/pc/usbxhci.c
+++ b/sys/src/9/pc/usbxhci.c
@@ -412,7 +412,7 @@
for(i=0; (ctlr->opr[USBSTS] & HCH) == 0 && i < 10; i++)
delay(10);
intrdisable(ctlr->pcidev->intl, hp->interrupt, hp, ctlr->pcidev->tbdf, hp->type);
- pciclrbme(ctlr->pcidev);
+ pcidisable(ctlr->pcidev);
}
static void
@@ -445,8 +445,11 @@
int i, j;
ctlr = hp->aux;
- if(ctlr->mmio[CAPLENGTH] == -1)
+ pcienable(ctlr->pcidev);
+ if(ctlr->mmio[CAPLENGTH] == -1){
+ pcidisable(ctlr->pcidev);
error("controller vanished");
+ }
ctlr->opr = &ctlr->mmio[(ctlr->mmio[CAPLENGTH]&0xFF)/4];
ctlr->dba = &ctlr->mmio[ctlr->mmio[DBOFF]/4];
@@ -463,7 +466,6 @@
tsleep(&up->sleep, return0, nil, 10);
pcisetbme(ctlr->pcidev);
- pcisetpms(ctlr->pcidev, 0);
intrenable(ctlr->pcidev->intl, hp->interrupt, hp, ctlr->pcidev->tbdf, hp->type);
if(waserror()){