changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: pc drivers: use pcienable() to handle device power up and missing initialization

changeset 6785: 9df9ef969856
parent 6784: c62a70191d57
child 6786: 2c3e7ea98e71
author: cinap_lenrek@felloff.net
date: Sun, 07 Oct 2018 22:28:21 +0200
files: sys/src/9/pc/audiohda.c sys/src/9/pc/ether79c970.c sys/src/9/pc/ether8139.c sys/src/9/pc/ether8169.c sys/src/9/pc/ether82543gc.c sys/src/9/pc/ether82557.c sys/src/9/pc/ether82563.c sys/src/9/pc/ether82598.c sys/src/9/pc/ether83815.c sys/src/9/pc/etherbcm.c sys/src/9/pc/etherdp83820.c sys/src/9/pc/etherelnk3.c sys/src/9/pc/etherga620.c sys/src/9/pc/etherigbe.c sys/src/9/pc/etheriwl.c sys/src/9/pc/etherm10g.c sys/src/9/pc/etherrt2860.c sys/src/9/pc/ethervgbe.c sys/src/9/pc/ethervt6102.c sys/src/9/pc/ethervt6105m.c sys/src/9/pc/etherwavelan.c sys/src/9/pc/etherwpi.c sys/src/9/pc/etheryuk.c sys/src/9/pc/pmmc.c sys/src/9/pc/sdiahci.c sys/src/9/pc/sdnvme.c sys/src/9/pc/uartaxp.c sys/src/9/pc/uartpci.c sys/src/9/pc/usbehcipc.c sys/src/9/pc/usbohci.c sys/src/9/pc/usbuhci.c sys/src/9/pc/usbxhci.c
description: pc drivers: use pcienable() to handle device power up and missing initialization
     1.1--- a/sys/src/9/pc/audiohda.c
     1.2+++ b/sys/src/9/pc/audiohda.c
     1.3@@ -1852,6 +1852,7 @@ hdareset(Audio *adev)
     1.4 	return -1;
     1.5 
     1.6 Found:
     1.7+	pcienable(p);
     1.8 	adev->ctlr = ctlr;
     1.9 	ctlr->adev = adev;
    1.10 
    1.11@@ -1890,9 +1891,6 @@ Found:
    1.12 		pcicfgw8(p, 0x44, pcicfgr8(p, 0x44) & 0xf8);
    1.13 	}
    1.14 
    1.15-	pcisetbme(p);
    1.16-	pcisetpms(p, 0);
    1.17-
    1.18 	ctlr->no = adev->ctlrno;
    1.19 	ctlr->size = p->mem[0].size;
    1.20 	ctlr->q = qopen(256, 0, 0, 0);
    1.21@@ -1924,6 +1922,7 @@ Found:
    1.22 				print("#A%d: input streamalloc failed\n", ctlr->no);
    1.23 		}
    1.24 	}
    1.25+	pcisetbme(p);
    1.26 
    1.27 	if(enumdev(ctlr) < 0){
    1.28 		print("#A%d: no audio codecs found\n", ctlr->no);
     2.1--- a/sys/src/9/pc/ether79c970.c
     2.2+++ b/sys/src/9/pc/ether79c970.c
     2.3@@ -544,9 +544,10 @@ reset(Ether* ether)
     2.4 	ether->port = ctlr->port;
     2.5 	ether->irq = ctlr->pcidev->intl;
     2.6 	ether->tbdf = ctlr->pcidev->tbdf;
     2.7-	pcisetbme(ctlr->pcidev);
     2.8 	ilock(ctlr);
     2.9 	ctlr->init = 1;
    2.10+	pcienable(ctlr->pcidev);
    2.11+	pcisetbme(ctlr->pcidev);
    2.12 
    2.13 	io32r(ctlr, Sreset);
    2.14 	io16r(ctlr, Sreset);
     3.1--- a/sys/src/9/pc/ether8139.c
     3.2+++ b/sys/src/9/pc/ether8139.c
     3.3@@ -681,7 +681,7 @@ rtl8139match(Ether* edev, int id)
     3.4 {
     3.5 	Pcidev *p;
     3.6 	Ctlr *ctlr;
     3.7-	int i, port;
     3.8+	int port;
     3.9 
    3.10 	/*
    3.11 	 * Any adapter matches if no edev->port is supplied,
    3.12@@ -701,20 +701,10 @@ rtl8139match(Ether* edev, int id)
    3.13 			print("rtl8139: port %#ux in use\n", port);
    3.14 			continue;
    3.15 		}
    3.16-
    3.17-		if(pcigetpms(p) > 0){
    3.18-			pcisetpms(p, 0);
    3.19-	
    3.20-			for(i = 0; i < 6; i++)
    3.21-				pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
    3.22-			pcicfgw8(p, PciINTL, p->intl);
    3.23-			pcicfgw8(p, PciLTR, p->ltr);
    3.24-			pcicfgw8(p, PciCLS, p->cls);
    3.25-			pcicfgw16(p, PciPCR, p->pcr);
    3.26-		}
    3.27-
    3.28+		pcienable(p);
    3.29 		ctlr->port = port;
    3.30 		if(rtl8139reset(ctlr)) {
    3.31+			pcidisable(p);
    3.32 			iofree(port);
    3.33 			continue;
    3.34 		}
     4.1--- a/sys/src/9/pc/ether8169.c
     4.2+++ b/sys/src/9/pc/ether8169.c
     4.3@@ -1118,25 +1118,17 @@ rtl8169pci(void)
     4.4 		ctlr->pciv = i;
     4.5 		ctlr->pcie = pcie;
     4.6 
     4.7+		pcienable(p);
     4.8 		if(vetmacv(ctlr, &macv) == -1){
     4.9+			pcidisable(p);
    4.10 			iofree(port);
    4.11 			free(ctlr);
    4.12 			print("rtl8169: unknown mac %.4ux %.8ux\n", p->did, macv);
    4.13 			continue;
    4.14 		}
    4.15 
    4.16-		if(pcigetpms(p) > 0){
    4.17-			pcisetpms(p, 0);
    4.18-
    4.19-			for(i = 0; i < 6; i++)
    4.20-				pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
    4.21-			pcicfgw8(p, PciINTL, p->intl);
    4.22-			pcicfgw8(p, PciLTR, p->ltr);
    4.23-			pcicfgw8(p, PciCLS, p->cls);
    4.24-			pcicfgw16(p, PciPCR, p->pcr);
    4.25-		}
    4.26-
    4.27 		if(rtl8169reset(ctlr)){
    4.28+			pcidisable(p);
    4.29 			iofree(port);
    4.30 			free(ctlr);
    4.31 			print("rtl8169: reset failed\n");
     5.1--- a/sys/src/9/pc/ether82543gc.c
     5.2+++ b/sys/src/9/pc/ether82543gc.c
     5.3@@ -1290,11 +1290,6 @@ gc82543pci(void)
     5.4 		ctlr->id = (p->did<<16)|p->vid;
     5.5 		ctlr->nic = mem;
     5.6 
     5.7-		if(gc82543reset(ctlr)){
     5.8-			free(ctlr);
     5.9-			continue;
    5.10-		}
    5.11-
    5.12 		if(gc82543ctlrhead != nil)
    5.13 			gc82543ctlrtail->next = ctlr;
    5.14 		else
    5.15@@ -1327,6 +1322,9 @@ gc82543pnp(Ether* edev)
    5.16 	}
    5.17 	if(ctlr == nil)
    5.18 		return -1;
    5.19+	
    5.20+	pcienable(ctlr->pcidev);
    5.21+	gc82543reset(ctlr);
    5.22 
    5.23 	edev->ctlr = ctlr;
    5.24 	edev->port = ctlr->port;
    5.25@@ -1347,6 +1345,7 @@ gc82543pnp(Ether* edev)
    5.26 		}
    5.27 	}
    5.28 	gc82543init(edev);
    5.29+	pcisetbme(ctlr->pcidev);
    5.30 
    5.31 	/*
    5.32 	 * Linkage to the generic ethernet driver.
     6.1--- a/sys/src/9/pc/ether82557.c
     6.2+++ b/sys/src/9/pc/ether82557.c
     6.3@@ -930,7 +930,7 @@ i82557pci(void)
     6.4 {
     6.5 	Pcidev *p;
     6.6 	Ctlr *ctlr;
     6.7-	int i, nop, port;
     6.8+	int nop, port;
     6.9 
    6.10 	p = nil;
    6.11 	nop = 0;
    6.12@@ -956,17 +956,6 @@ i82557pci(void)
    6.13 			break;
    6.14 		}
    6.15 
    6.16-		if(pcigetpms(p) > 0){
    6.17-			pcisetpms(p, 0);
    6.18-	
    6.19-			for(i = 0; i < 6; i++)
    6.20-				pcicfgw32(p, PciBAR0+i*4, p->mem[i].bar);
    6.21-			pcicfgw8(p, PciINTL, p->intl);
    6.22-			pcicfgw8(p, PciLTR, p->ltr);
    6.23-			pcicfgw8(p, PciCLS, p->cls);
    6.24-			pcicfgw16(p, PciPCR, p->pcr);
    6.25-		}
    6.26-
    6.27 		/*
    6.28 		 * bar[0] is the memory-mapped register address (4KB),
    6.29 		 * bar[1] is the I/O port register address (32 bytes) and
    6.30@@ -993,8 +982,6 @@ i82557pci(void)
    6.31 		else
    6.32 			ctlrhead = ctlr;
    6.33 		ctlrtail = ctlr;
    6.34-
    6.35-		pcisetbme(p);
    6.36 	}
    6.37 }
    6.38 
    6.39@@ -1075,6 +1062,9 @@ reset(Ether* ether)
    6.40 	if(ctlr == nil)
    6.41 		return -1;
    6.42 
    6.43+	pcienable(ctlr->pcidev);
    6.44+	pcisetbme(ctlr->pcidev);
    6.45+
    6.46 	/*
    6.47 	 * Initialise the Ctlr structure.
    6.48 	 * Perform a software reset after which should ensure busmastering
     7.1--- a/sys/src/9/pc/ether82563.c
     7.2+++ b/sys/src/9/pc/ether82563.c
     7.3@@ -2053,11 +2053,13 @@ setup(Ctlr *ctlr)
     7.4 		print("%s: can't map 0x%lux\n", cname(ctlr), ctlr->port);
     7.5 		return -1;
     7.6 	}
     7.7+	pcienable(p);
     7.8 	if(i82563reset(ctlr)){
     7.9+		pcidisable(p);
    7.10 		vunmap(ctlr->nic, p->mem[0].size);
    7.11 		return -1;
    7.12 	}
    7.13-	pcisetbme(ctlr->pcidev);
    7.14+	pcisetbme(p);
    7.15 	return 0;
    7.16 }
    7.17 
     8.1--- a/sys/src/9/pc/ether82598.c
     8.2+++ b/sys/src/9/pc/ether82598.c
     8.3@@ -897,6 +897,7 @@ scan(void)
     8.4 			free(c);
     8.5 			continue;
     8.6 		}
     8.7+		pcienable(p);
     8.8 		c->p = p;
     8.9 		c->io = io;
    8.10 		c->reg = (u32int*)mem;
     9.1--- a/sys/src/9/pc/ether83815.c
     9.2+++ b/sys/src/9/pc/ether83815.c
     9.3@@ -1098,13 +1098,6 @@ scanpci83815(void)
     9.4 			free(ctlr);
     9.5 			continue;
     9.6 		}
     9.7-
     9.8-		if(softreset(ctlr, 0) == -1){
     9.9-			free(ctlr);
    9.10-			continue;
    9.11-		}
    9.12-		srom(ctlr);
    9.13-
    9.14 		if(ctlrhead != nil)
    9.15 			ctlrtail->next = ctlr;
    9.16 		else
    9.17@@ -1148,6 +1141,10 @@ reset(Ether* ether)
    9.18 	if(ctlr == nil)
    9.19 		return -1;
    9.20 
    9.21+	pcienable(ctlr->pcidev);
    9.22+	softreset(ctlr, 0);
    9.23+	srom(ctlr);
    9.24+
    9.25 	ether->ctlr = ctlr;
    9.26 	ether->port = ctlr->port;
    9.27 	ether->irq = ctlr->pcidev->intl;
    10.1--- a/sys/src/9/pc/etherbcm.c
    10.2+++ b/sys/src/9/pc/etherbcm.c
    10.3@@ -791,8 +791,6 @@ bcmpci(void)
    10.4 			break;
    10.5 		}
    10.6 
    10.7-		pcisetbme(pdev);
    10.8-		pcisetpms(pdev, 0);
    10.9 		ctlr = malloc(sizeof(Ctlr));
   10.10 		if(ctlr == nil) {
   10.11 			print("bcm: unable to alloc Ctlr\n");
   10.12@@ -867,7 +865,10 @@ again:
   10.13 	
   10.14 	if(ctlr == nil)
   10.15 		return -1;
   10.16-	
   10.17+
   10.18+	pcienable(ctlr->pdev);
   10.19+	pcisetbme(ctlr->pdev);
   10.20+
   10.21 	edev->ctlr = ctlr;
   10.22 	edev->port = ctlr->port;
   10.23 	edev->irq = ctlr->pdev->intl;
    11.1--- a/sys/src/9/pc/etherdp83820.c
    11.2+++ b/sys/src/9/pc/etherdp83820.c
    11.3@@ -1170,6 +1170,7 @@ dp83820pci(void)
    11.4 		}
    11.5 		ctlr->port = p->mem[1].bar & ~0x0F;
    11.6 		ctlr->pcidev = p;
    11.7+		pcienable(p);
    11.8 		ctlr->id = (p->did<<16)|p->vid;
    11.9 
   11.10 		ctlr->nic = mem;
    12.1--- a/sys/src/9/pc/etherelnk3.c
    12.2+++ b/sys/src/9/pc/etherelnk3.c
    12.3@@ -1481,6 +1481,7 @@ tcm59Xpci(void)
    12.4 			print("tcm59Xpci: port 0x%uX in use\n", port);
    12.5 			continue;
    12.6 		}
    12.7+		pcienable(p);
    12.8 		irq = p->intl;
    12.9 
   12.10 		txrxreset(port);
    13.1--- a/sys/src/9/pc/etherga620.c
    13.2+++ b/sys/src/9/pc/etherga620.c
    13.3@@ -1178,6 +1178,8 @@ ga620pci(void)
    13.4 		}
    13.5 		ctlr->port = p->mem[0].bar & ~0x0F;
    13.6 		ctlr->pcidev = p;
    13.7+		pcienable(p);
    13.8+
    13.9 		ctlr->id = p->did<<16 | p->vid;
   13.10 
   13.11 		ctlr->nic = mem;
   13.12@@ -1185,6 +1187,7 @@ ga620pci(void)
   13.13 			free(ctlr);
   13.14 			continue;
   13.15 		}
   13.16+		pcisetbme(p);
   13.17 
   13.18 		if(ctlrhead != nil)
   13.19 			ctlrtail->next = ctlr;
    14.1--- a/sys/src/9/pc/etherigbe.c
    14.2+++ b/sys/src/9/pc/etherigbe.c
    14.3@@ -1966,6 +1966,7 @@ igbepci(void)
    14.4 		}
    14.5 		ctlr->port = p->mem[0].bar & ~0x0F;
    14.6 		ctlr->pcidev = p;
    14.7+		pcienable(p);
    14.8 		ctlr->id = (p->did<<16)|p->vid;
    14.9 		ctlr->cls = cls*4;
   14.10 		ctlr->nic = mem;
    15.1--- a/sys/src/9/pc/etheriwl.c
    15.2+++ b/sys/src/9/pc/etheriwl.c
    15.3@@ -821,6 +821,23 @@ iwlinit(Ether *edev)
    15.4 	uint u, caloff, regoff;
    15.5 
    15.6 	ctlr = edev->ctlr;
    15.7+
    15.8+	/* Clear device-specific "PCI retry timeout" register (41h). */
    15.9+	if(pcicfgr8(ctlr->pdev, 0x41) != 0)
   15.10+		pcicfgw8(ctlr->pdev, 0x41, 0);
   15.11+
   15.12+	/* Clear interrupt disable bit. Hardware bug workaround. */
   15.13+	if(ctlr->pdev->pcr & 0x400){
   15.14+		ctlr->pdev->pcr &= ~0x400;
   15.15+		pcicfgw16(ctlr->pdev, PciPCR, ctlr->pdev->pcr);
   15.16+	}
   15.17+
   15.18+	ctlr->type = (csr32r(ctlr, Rev) >> 4) & 0x1F;
   15.19+	if(fwname[ctlr->type] == nil){
   15.20+		print("iwl: unsupported controller type %d\n", ctlr->type);
   15.21+		return -1;
   15.22+	}
   15.23+
   15.24 	if((err = handover(ctlr)) != nil)
   15.25 		goto Err;
   15.26 	if((err = poweron(ctlr)) != nil)
   15.27@@ -2465,19 +2482,6 @@ iwlpci(void)
   15.28 			break;
   15.29 		}
   15.30 
   15.31-		/* Clear device-specific "PCI retry timeout" register (41h). */
   15.32-		if(pcicfgr8(pdev, 0x41) != 0)
   15.33-			pcicfgw8(pdev, 0x41, 0);
   15.34-
   15.35-		/* Clear interrupt disable bit. Hardware bug workaround. */
   15.36-		if(pdev->pcr & 0x400){
   15.37-			pdev->pcr &= ~0x400;
   15.38-			pcicfgw16(pdev, PciPCR, pdev->pcr);
   15.39-		}
   15.40-
   15.41-		pcisetbme(pdev);
   15.42-		pcisetpms(pdev, 0);
   15.43-
   15.44 		ctlr = malloc(sizeof(Ctlr));
   15.45 		if(ctlr == nil) {
   15.46 			print("iwl: unable to alloc Ctlr\n");
   15.47@@ -2492,14 +2496,6 @@ iwlpci(void)
   15.48 		}
   15.49 		ctlr->nic = mem;
   15.50 		ctlr->pdev = pdev;
   15.51-		ctlr->type = (csr32r(ctlr, Rev) >> 4) & 0x1F;
   15.52-
   15.53-		if(fwname[ctlr->type] == nil){
   15.54-			print("iwl: unsupported controller type %d\n", ctlr->type);
   15.55-			vunmap(mem, pdev->mem[0].size);
   15.56-			free(ctlr);
   15.57-			continue;
   15.58-		}
   15.59 
   15.60 		if(iwlhead != nil)
   15.61 			iwltail->link = ctlr;
   15.62@@ -2542,11 +2538,14 @@ again:
   15.63 	edev->multicast = iwlmulticast;
   15.64 	edev->mbps = 54;
   15.65 
   15.66+	pcienable(ctlr->pdev);
   15.67 	if(iwlinit(edev) < 0){
   15.68+		pcidisable(ctlr->pdev);
   15.69 		edev->ctlr = nil;
   15.70 		goto again;
   15.71 	}
   15.72 
   15.73+	pcisetbme(ctlr->pdev);
   15.74 	intrenable(edev->irq, iwlinterrupt, edev, edev->tbdf, edev->name);
   15.75 	
   15.76 	return 0;
    16.1--- a/sys/src/9/pc/etherm10g.c
    16.2+++ b/sys/src/9/pc/etherm10g.c
    16.3@@ -1571,6 +1571,7 @@ m10gpci(void)
    16.4 			continue;
    16.5 		}
    16.6 		c->pcidev = p;
    16.7+		pcienable(p);
    16.8 		c->id = p->did<<16 | p->vid;
    16.9 		c->boot = pcicap(p, PciCapVND);
   16.10 //		kickthebaby(p, c);
    17.1--- a/sys/src/9/pc/etherrt2860.c
    17.2+++ b/sys/src/9/pc/etherrt2860.c
    17.3@@ -3489,9 +3489,6 @@ rt2860pci(void)
    17.4 			break;
    17.5 		}
    17.6 
    17.7-		pcisetbme(pdev);
    17.8-		pcisetpms(pdev, 0);
    17.9-
   17.10 		ctlr = malloc(sizeof(Ctlr));
   17.11 		if(ctlr == nil){
   17.12 			print("rt2860: unable to alloc Ctlr\n");
   17.13@@ -3535,6 +3532,9 @@ again:
   17.14 	if(ctlr == nil)
   17.15 		return -1;
   17.16 
   17.17+	pcienable(ctlr->pdev);
   17.18+	pcisetbme(ctlr->pdev);
   17.19+
   17.20 	edev->ctlr = ctlr;
   17.21 	edev->port = ctlr->port;
   17.22 	edev->irq = ctlr->pdev->intl;
    18.1--- a/sys/src/9/pc/ethervgbe.c
    18.2+++ b/sys/src/9/pc/ethervgbe.c
    18.3@@ -930,9 +930,6 @@ vgbepci(void)
    18.4 			continue;
    18.5 		}
    18.6 
    18.7-		pcisetbme(pdev);
    18.8-		pcisetpms(pdev, 0);
    18.9-
   18.10 		port = pdev->mem[0].bar;
   18.11 		size = pdev->mem[0].size;
   18.12 
   18.13@@ -1126,6 +1123,9 @@ vgbepnp(Ether* edev)
   18.14 
   18.15 	if(ctlr == nil)
   18.16 		return -1;
   18.17+	
   18.18+	pcienable(ctlr->pdev);
   18.19+	pcisetbme(ctlr->pdev);
   18.20 
   18.21 	vgbereset(ctlr);
   18.22 
    19.1--- a/sys/src/9/pc/ethervt6102.c
    19.2+++ b/sys/src/9/pc/ethervt6102.c
    19.3@@ -976,6 +976,7 @@ vt6102pci(void)
    19.4 		}
    19.5 		ctlr->port = port;
    19.6 		ctlr->pcidev = p;
    19.7+		pcienable(p);
    19.8 		ctlr->id = (p->did<<16)|p->vid;
    19.9 		if((cls = pcicfgr8(p, PciCLS)) == 0 || cls == 0xFF)
   19.10 			cls = 0x10;
    20.1--- a/sys/src/9/pc/ethervt6105m.c
    20.2+++ b/sys/src/9/pc/ethervt6105m.c
    20.3@@ -1140,6 +1140,7 @@ vt6105Mpci(void)
    20.4 		}
    20.5 		ctlr->port = port;
    20.6 		ctlr->pcidev = p;
    20.7+		pcienable(p);
    20.8 		ctlr->id = (p->did<<16)|p->vid;
    20.9 		if((cls = pcicfgr8(p, PciCLS)) == 0 || cls == 0xFF)
   20.10 			cls = 0x10;
    21.1--- a/sys/src/9/pc/etherwavelan.c
    21.2+++ b/sys/src/9/pc/etherwavelan.c
    21.3@@ -134,7 +134,6 @@ wavelanpciscan(void)
    21.4 		else
    21.5 			ctlrhead = ctlr;
    21.6 		ctlrtail = ctlr;
    21.7-		pcisetbme(p);
    21.8 	}
    21.9 }
   21.10 
   21.11@@ -158,7 +157,9 @@ wavelanpcireset(Ether *ether)
   21.12 		return -1;
   21.13 
   21.14 	ctlr->active = 1;
   21.15+
   21.16 	ilock(ctlr);
   21.17+	pcienable(ctlr->pcidev);
   21.18 	ether->irq = ctlr->pcidev->intl;
   21.19 	ether->tbdf = ctlr->pcidev->tbdf;
   21.20 
   21.21@@ -189,6 +190,7 @@ wavelanpcireset(Ether *ether)
   21.22 			*p = ' ';
   21.23 		w_option(ctlr, ether->opt[i], strlen(ether->opt[i]));
   21.24 	}
   21.25+	pcisetbme(ctlr->pcidev);
   21.26 	iunlock(ctlr);
   21.27 	return 0;
   21.28 }
    22.1--- a/sys/src/9/pc/etherwpi.c
    22.2+++ b/sys/src/9/pc/etherwpi.c
    22.3@@ -1793,9 +1793,6 @@ wpipci(void)
    22.4 		if(pcicfgr8(pdev, 0x41) != 0)
    22.5 			pcicfgw8(pdev, 0x41, 0);
    22.6 
    22.7-		pcisetbme(pdev);
    22.8-		pcisetpms(pdev, 0);
    22.9-
   22.10 		ctlr = malloc(sizeof(Ctlr));
   22.11 		if(ctlr == nil) {
   22.12 			print("wpi: unable to alloc Ctlr\n");
   22.13@@ -1853,11 +1850,13 @@ again:
   22.14 	edev->multicast = wpimulticast;
   22.15 	edev->mbps = 54;
   22.16 
   22.17+	pcienable(ctlr->pdev);
   22.18 	if(wpiinit(edev) < 0){
   22.19+		pcidisable(ctlr->pdev);
   22.20 		edev->ctlr = nil;
   22.21 		goto again;
   22.22 	}
   22.23-
   22.24+	pcisetbme(ctlr->pdev);
   22.25 	intrenable(edev->irq, wpiinterrupt, edev, edev->tbdf, edev->name);
   22.26 
   22.27 	return 0;
    23.1--- a/sys/src/9/pc/etheryuk.c
    23.2+++ b/sys/src/9/pc/etheryuk.c
    23.3@@ -2129,6 +2129,8 @@ setup(Ctlr *c)
    23.4 	Pcidev *p;
    23.5 
    23.6 	p = c->p;
    23.7+	pcienable(p);
    23.8+
    23.9 	c->io = p->mem[0].bar&~0xf;
   23.10 	mem = vmap(c->io, p->mem[0].size);
   23.11 	if(mem == nil){
    24.1--- a/sys/src/9/pc/pmmc.c
    24.2+++ b/sys/src/9/pc/pmmc.c
    24.3@@ -234,6 +234,13 @@ pmmcinit(void)
    24.4 	if(p == nil || p->mem[0].size < 256)
    24.5 		return -1;
    24.6 
    24.7+	pmmc->mmio = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
    24.8+	if(pmmc->mmio == nil)
    24.9+		return -1;
   24.10+
   24.11+	pmmc->pdev = p;
   24.12+	pcienable(p);
   24.13+
   24.14 	if(p->did == 0x1180 && p->vid == 0xe823){	/* Ricoh */
   24.15 		/* Enable SD2.0 mode. */
   24.16 		pcicfgw8(p, 0xf9, 0xfc);
   24.17@@ -249,10 +256,6 @@ pmmcinit(void)
   24.18 		pcicfgw8(p, 0xfc, 0x00);
   24.19 	}
   24.20 
   24.21-	pmmc->mmio = vmap(p->mem[0].bar & ~0x0F, p->mem[0].size);
   24.22-	if(pmmc->mmio == nil)
   24.23-		return -1;
   24.24-	pmmc->pdev = p;
   24.25 	return 0;
   24.26 }
   24.27 
    25.1--- a/sys/src/9/pc/sdiahci.c
    25.2+++ b/sys/src/9/pc/sdiahci.c
    25.3@@ -2175,12 +2175,14 @@ iapnp(void)
    25.4 		s->ctlr = c;
    25.5 		c->sdev = s;
    25.6 
    25.7+		pcienable(p);
    25.8 		ahcihandoff((Ahba*)c->mmio);
    25.9 		if(p->vid == 0x8086)
   25.10 			iasetupahci(c);
   25.11 		nunit = ahciconf(c);
   25.12 		if(nunit < 1){
   25.13 			vunmap(c->mmio, p->mem[Abar].size);
   25.14+			pcidisable(p);
   25.15 			continue;
   25.16 		}
   25.17 		c->ndrive = s->nunit = nunit;
    26.1--- a/sys/src/9/pc/sdnvme.c
    26.2+++ b/sys/src/9/pc/sdnvme.c
    26.3@@ -566,6 +566,7 @@ nvmepnpctlrs(void)
    26.4 			print("nvme: no memory for Ctlr\n");
    26.5 			break;
    26.6 		}
    26.7+		pcienable(p);
    26.8 		ctlr->pci = p;
    26.9 		ctlr->reg = vmap(p->mem[0].bar & ~0xF, p->mem[0].size);
   26.10 		if(ctlr->reg == nil){
   26.11@@ -573,6 +574,7 @@ nvmepnpctlrs(void)
   26.12 		Bad:
   26.13 			if(ctlr->reg != nil)
   26.14 				vunmap(ctlr->reg, p->mem[0].size);
   26.15+			pcidisable(p);
   26.16 			free(ctlr);
   26.17 			continue;
   26.18 		}
    27.1--- a/sys/src/9/pc/uartaxp.c
    27.2+++ b/sys/src/9/pc/uartaxp.c
    27.3@@ -795,6 +795,8 @@ axpalloc(int ctlrno, Pcidev* pcidev)
    27.4 	ctlr->gcb = (Gcb*)(ctlr->mem+0x10000);
    27.5 	print("mem 0x%ux size %d: ", bar, pcidev->mem[2].size);
    27.6 
    27.7+	pcienable(pcidev);
    27.8+
    27.9 	/*
   27.10 	 * Toggle the software reset and wait for
   27.11 	 * the adapter local init status to indicate done.
    28.1--- a/sys/src/9/pc/uartpci.c
    28.2+++ b/sys/src/9/pc/uartpci.c
    28.3@@ -35,6 +35,7 @@ uartpci(int ctlrno, Pcidev* p, int barno
    28.4 		return nil;
    28.5 	}
    28.6 
    28.7+	pcienable(p);
    28.8 	uart = head;
    28.9 	for(i = 0; i < n; i++){
   28.10 		ctlr = i8250alloc(io + i*iosize, p->intl, p->tbdf);
    29.1--- a/sys/src/9/pc/usbehcipc.c
    29.2+++ b/sys/src/9/pc/usbehcipc.c
    29.3@@ -186,12 +186,16 @@ scanpci(void)
    29.4 			print("usbehci: no memory\n");
    29.5 			continue;
    29.6 		}
    29.7+
    29.8+		if((capio = vmap(io, p->mem[0].size)) == nil){
    29.9+			print("usbehci: cannot map mmio\n");
   29.10+			free(ctlr);
   29.11+			continue;
   29.12+		}
   29.13+
   29.14 		ctlr->pcidev = p;
   29.15 		ctlr->base = io;
   29.16-		capio = ctlr->capio = vmap(io, p->mem[0].size);
   29.17-		ctlr->opio = (Eopio*)((uintptr)capio + (capio->cap & 0xff));
   29.18-		pcisetbme(p);
   29.19-		pcisetpms(p, 0);
   29.20+		ctlr->capio = capio;
   29.21 		for(i = 0; i < Nhcis; i++)
   29.22 			if(ctlrs[i] == nil){
   29.23 				ctlrs[i] = ctlr;
   29.24@@ -248,6 +252,8 @@ reset(Hci *hp)
   29.25 		return -1;
   29.26 
   29.27 	p = ctlr->pcidev;
   29.28+	pcienable(p);
   29.29+
   29.30 	hp->aux = ctlr;
   29.31 	hp->port = ctlr->base;
   29.32 	hp->irq = p->intl;
   29.33@@ -263,8 +269,11 @@ reset(Hci *hp)
   29.34 		capio->parms & 0x40 ? "explicit" : "automatic",
   29.35 		capio->parms & 0x10 ? "" : "no ", hp->nports);
   29.36 
   29.37+	ctlr->opio = (Eopio*)((uintptr)capio + (capio->cap & 0xff));
   29.38 	ehcireset(ctlr);
   29.39 	ehcimeminit(ctlr);
   29.40+	
   29.41+	pcisetbme(p);
   29.42 
   29.43 	/*
   29.44 	 * Linkage to the generic HCI driver.
    30.1--- a/sys/src/9/pc/usbohci.c
    30.2+++ b/sys/src/9/pc/usbohci.c
    30.3@@ -2405,12 +2405,14 @@ scanpci(void)
    30.4 			print("ohci: no memory\n");
    30.5 			continue;
    30.6 		}
    30.7+		if((ctlr->ohci = vmap(io, p->mem[0].size)) == nil){
    30.8+			print("ohci: can't map ohci\n");
    30.9+			free(ctlr);
   30.10+			continue;
   30.11+		}
   30.12 		ctlr->pcidev = p;
   30.13 		ctlr->base = io;
   30.14-		ctlr->ohci = vmap(io, p->mem[0].size);
   30.15 		dprint("scanpci: ctlr %#p, ohci %#p\n", ctlr, ctlr->ohci);
   30.16-		pcisetbme(p);
   30.17-		pcisetpms(p, 0);
   30.18 		for(i = 0; i < Nhcis; i++)
   30.19 			if(ctlrs[i] == nil){
   30.20 				ctlrs[i] = ctlr;
   30.21@@ -2577,11 +2579,15 @@ reset(Hci *hp)
   30.22 	iunlock(&resetlck);
   30.23 	if(ctlrs[i] == nil || i == Nhcis)
   30.24 		return -1;
   30.25-	if(ctlr->ohci->control == ~0)
   30.26-		return -1;
   30.27-
   30.28 
   30.29 	p = ctlr->pcidev;
   30.30+	pcienable(p);
   30.31+
   30.32+	if(ctlr->ohci->control == ~0){
   30.33+		pcidisable(p);
   30.34+		return -1;
   30.35+	}
   30.36+
   30.37 	hp->aux = ctlr;
   30.38 	hp->port = ctlr->base;
   30.39 	hp->irq = p->intl;
   30.40@@ -2591,6 +2597,8 @@ reset(Hci *hp)
   30.41 	ohcireset(ctlr);
   30.42 	ohcimeminit(ctlr);
   30.43 
   30.44+	pcisetbme(p);
   30.45+
   30.46 	/*
   30.47 	 * Linkage to the generic HCI driver.
   30.48 	 */
    31.1--- a/sys/src/9/pc/usbuhci.c
    31.2+++ b/sys/src/9/pc/usbuhci.c
    31.3@@ -2319,6 +2319,8 @@ reset(Hci *hp)
    31.4 		return -1;
    31.5 
    31.6 	p = ctlr->pcidev;
    31.7+	pcienable(p);
    31.8+
    31.9 	hp->aux = ctlr;
   31.10 	hp->port = ctlr->port;
   31.11 	hp->irq = p->intl;
   31.12@@ -2328,6 +2330,8 @@ reset(Hci *hp)
   31.13 	uhcireset(ctlr);
   31.14 	uhcimeminit(ctlr);
   31.15 
   31.16+	pcisetbme(p);
   31.17+
   31.18 	/*
   31.19 	 * Linkage to the generic HCI driver.
   31.20 	 */
    32.1--- a/sys/src/9/pc/usbxhci.c
    32.2+++ b/sys/src/9/pc/usbxhci.c
    32.3@@ -412,7 +412,7 @@ shutdown(Hci *hp)
    32.4 	for(i=0; (ctlr->opr[USBSTS] & HCH) == 0 && i < 10; i++)
    32.5 		delay(10);
    32.6 	intrdisable(ctlr->pcidev->intl, hp->interrupt, hp, ctlr->pcidev->tbdf, hp->type);
    32.7-	pciclrbme(ctlr->pcidev);
    32.8+	pcidisable(ctlr->pcidev);
    32.9 }
   32.10 
   32.11 static void
   32.12@@ -445,8 +445,11 @@ init(Hci *hp)
   32.13 	int i, j;
   32.14 
   32.15 	ctlr = hp->aux;
   32.16-	if(ctlr->mmio[CAPLENGTH] == -1)
   32.17+	pcienable(ctlr->pcidev);
   32.18+	if(ctlr->mmio[CAPLENGTH] == -1){
   32.19+		pcidisable(ctlr->pcidev);
   32.20 		error("controller vanished");
   32.21+	}
   32.22 
   32.23 	ctlr->opr = &ctlr->mmio[(ctlr->mmio[CAPLENGTH]&0xFF)/4];
   32.24 	ctlr->dba = &ctlr->mmio[ctlr->mmio[DBOFF]/4];
   32.25@@ -463,7 +466,6 @@ init(Hci *hp)
   32.26 		tsleep(&up->sleep, return0, nil, 10);
   32.27 
   32.28 	pcisetbme(ctlr->pcidev);
   32.29-	pcisetpms(ctlr->pcidev, 0);
   32.30 	intrenable(ctlr->pcidev->intl, hp->interrupt, hp, ctlr->pcidev->tbdf, hp->type);
   32.31 
   32.32 	if(waserror()){