shithub: riscv

Download patch

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()){