pc drivers: use pcienable() to handle device power up and missing initialization

This commit is contained in:
cinap_lenrek 2018-10-07 22:28:21 +02:00
parent 4d7c195804
commit 9fec0e7360
32 changed files with 123 additions and 107 deletions

View file

@ -1852,6 +1852,7 @@ hdareset(Audio *adev)
return -1;
Found:
pcienable(p);
adev->ctlr = ctlr;
ctlr->adev = adev;
@ -1890,9 +1891,6 @@ Found:
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 @@ Found:
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);

View file

@ -544,9 +544,10 @@ reset(Ether* ether)
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);

View file

@ -681,7 +681,7 @@ rtl8139match(Ether* edev, int id)
{
Pcidev *p;
Ctlr *ctlr;
int i, port;
int port;
/*
* Any adapter matches if no edev->port is supplied,
@ -701,20 +701,10 @@ rtl8139match(Ether* edev, int id)
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;
}

View file

@ -1118,25 +1118,17 @@ rtl8169pci(void)
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);
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");

View file

@ -1290,11 +1290,6 @@ gc82543pci(void)
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 @@ gc82543pnp(Ether* edev)
}
if(ctlr == nil)
return -1;
pcienable(ctlr->pcidev);
gc82543reset(ctlr);
edev->ctlr = ctlr;
edev->port = ctlr->port;
@ -1347,6 +1345,7 @@ gc82543pnp(Ether* edev)
}
}
gc82543init(edev);
pcisetbme(ctlr->pcidev);
/*
* Linkage to the generic ethernet driver.

View file

@ -930,7 +930,7 @@ i82557pci(void)
{
Pcidev *p;
Ctlr *ctlr;
int i, nop, port;
int nop, port;
p = nil;
nop = 0;
@ -956,17 +956,6 @@ i82557pci(void)
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 @@ i82557pci(void)
else
ctlrhead = ctlr;
ctlrtail = ctlr;
pcisetbme(p);
}
}
@ -1075,6 +1062,9 @@ reset(Ether* ether)
if(ctlr == nil)
return -1;
pcienable(ctlr->pcidev);
pcisetbme(ctlr->pcidev);
/*
* Initialise the Ctlr structure.
* Perform a software reset after which should ensure busmastering

View file

@ -2053,11 +2053,13 @@ setup(Ctlr *ctlr)
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;
}

View file

@ -897,6 +897,7 @@ scan(void)
free(c);
continue;
}
pcienable(p);
c->p = p;
c->io = io;
c->reg = (u32int*)mem;

View file

@ -1098,13 +1098,6 @@ scanpci83815(void)
free(ctlr);
continue;
}
if(softreset(ctlr, 0) == -1){
free(ctlr);
continue;
}
srom(ctlr);
if(ctlrhead != nil)
ctlrtail->next = ctlr;
else
@ -1148,6 +1141,10 @@ reset(Ether* ether)
if(ctlr == nil)
return -1;
pcienable(ctlr->pcidev);
softreset(ctlr, 0);
srom(ctlr);
ether->ctlr = ctlr;
ether->port = ctlr->port;
ether->irq = ctlr->pcidev->intl;

View file

@ -791,8 +791,6 @@ bcmpci(void)
break;
}
pcisetbme(pdev);
pcisetpms(pdev, 0);
ctlr = malloc(sizeof(Ctlr));
if(ctlr == nil) {
print("bcm: unable to alloc Ctlr\n");
@ -867,7 +865,10 @@ again:
if(ctlr == nil)
return -1;
pcienable(ctlr->pdev);
pcisetbme(ctlr->pdev);
edev->ctlr = ctlr;
edev->port = ctlr->port;
edev->irq = ctlr->pdev->intl;

View file

@ -1170,6 +1170,7 @@ dp83820pci(void)
}
ctlr->port = p->mem[1].bar & ~0x0F;
ctlr->pcidev = p;
pcienable(p);
ctlr->id = (p->did<<16)|p->vid;
ctlr->nic = mem;

View file

@ -1481,6 +1481,7 @@ tcm59Xpci(void)
print("tcm59Xpci: port 0x%uX in use\n", port);
continue;
}
pcienable(p);
irq = p->intl;
txrxreset(port);

View file

@ -1178,6 +1178,8 @@ ga620pci(void)
}
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 @@ ga620pci(void)
free(ctlr);
continue;
}
pcisetbme(p);
if(ctlrhead != nil)
ctlrtail->next = ctlr;

View file

@ -1966,6 +1966,7 @@ igbepci(void)
}
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;

View file

@ -821,6 +821,23 @@ iwlinit(Ether *edev)
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 @@ iwlpci(void)
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,14 +2496,6 @@ iwlpci(void)
}
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;
@ -2542,11 +2538,14 @@ again:
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;

View file

@ -1571,6 +1571,7 @@ m10gpci(void)
continue;
}
c->pcidev = p;
pcienable(p);
c->id = p->did<<16 | p->vid;
c->boot = pcicap(p, PciCapVND);
// kickthebaby(p, c);

View file

@ -3489,9 +3489,6 @@ rt2860pci(void)
break;
}
pcisetbme(pdev);
pcisetpms(pdev, 0);
ctlr = malloc(sizeof(Ctlr));
if(ctlr == nil){
print("rt2860: unable to alloc Ctlr\n");
@ -3535,6 +3532,9 @@ again:
if(ctlr == nil)
return -1;
pcienable(ctlr->pdev);
pcisetbme(ctlr->pdev);
edev->ctlr = ctlr;
edev->port = ctlr->port;
edev->irq = ctlr->pdev->intl;

View file

@ -930,9 +930,6 @@ vgbepci(void)
continue;
}
pcisetbme(pdev);
pcisetpms(pdev, 0);
port = pdev->mem[0].bar;
size = pdev->mem[0].size;
@ -1126,6 +1123,9 @@ vgbepnp(Ether* edev)
if(ctlr == nil)
return -1;
pcienable(ctlr->pdev);
pcisetbme(ctlr->pdev);
vgbereset(ctlr);

View file

@ -976,6 +976,7 @@ vt6102pci(void)
}
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;

View file

@ -1140,6 +1140,7 @@ vt6105Mpci(void)
}
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;

View file

@ -134,7 +134,6 @@ wavelanpciscan(void)
else
ctlrhead = ctlr;
ctlrtail = ctlr;
pcisetbme(p);
}
}
@ -158,7 +157,9 @@ wavelanpcireset(Ether *ether)
return -1;
ctlr->active = 1;
ilock(ctlr);
pcienable(ctlr->pcidev);
ether->irq = ctlr->pcidev->intl;
ether->tbdf = ctlr->pcidev->tbdf;
@ -189,6 +190,7 @@ wavelanpcireset(Ether *ether)
*p = ' ';
w_option(ctlr, ether->opt[i], strlen(ether->opt[i]));
}
pcisetbme(ctlr->pcidev);
iunlock(ctlr);
return 0;
}

View file

@ -1793,9 +1793,6 @@ wpipci(void)
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 @@ again:
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;

View file

@ -2129,6 +2129,8 @@ setup(Ctlr *c)
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){

View file

@ -234,6 +234,13 @@ pmmcinit(void)
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 @@ pmmcinit(void)
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;
}

View file

@ -2175,12 +2175,14 @@ iapnp(void)
s->ctlr = c;
c->sdev = s;
pcienable(p);
ahcihandoff((Ahba*)c->mmio);
if(p->vid == 0x8086)
iasetupahci(c);
nunit = ahciconf(c);
if(nunit < 1){
vunmap(c->mmio, p->mem[Abar].size);
pcidisable(p);
continue;
}
c->ndrive = s->nunit = nunit;

View file

@ -566,6 +566,7 @@ nvmepnpctlrs(void)
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 @@ nvmepnpctlrs(void)
Bad:
if(ctlr->reg != nil)
vunmap(ctlr->reg, p->mem[0].size);
pcidisable(p);
free(ctlr);
continue;
}

View file

@ -795,6 +795,8 @@ axpalloc(int ctlrno, Pcidev* pcidev)
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.

View file

@ -35,6 +35,7 @@ uartpci(int ctlrno, Pcidev* p, int barno, int n, int freq, char* name,
return nil;
}
pcienable(p);
uart = head;
for(i = 0; i < n; i++){
ctlr = i8250alloc(io + i*iosize, p->intl, p->tbdf);

View file

@ -186,12 +186,16 @@ scanpci(void)
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 @@ reset(Hci *hp)
return -1;
p = ctlr->pcidev;
pcienable(p);
hp->aux = ctlr;
hp->port = ctlr->base;
hp->irq = p->intl;
@ -263,8 +269,11 @@ reset(Hci *hp)
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.

View file

@ -2405,12 +2405,14 @@ scanpci(void)
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 @@ reset(Hci *hp)
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;
@ -2591,6 +2597,8 @@ reset(Hci *hp)
ohcireset(ctlr);
ohcimeminit(ctlr);
pcisetbme(p);
/*
* Linkage to the generic HCI driver.
*/

View file

@ -2319,6 +2319,8 @@ reset(Hci *hp)
return -1;
p = ctlr->pcidev;
pcienable(p);
hp->aux = ctlr;
hp->port = ctlr->port;
hp->irq = p->intl;
@ -2328,6 +2330,8 @@ reset(Hci *hp)
uhcireset(ctlr);
uhcimeminit(ctlr);
pcisetbme(p);
/*
* Linkage to the generic HCI driver.
*/

View file

@ -412,7 +412,7 @@ shutdown(Hci *hp)
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 @@ init(Hci *hp)
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 @@ init(Hci *hp)
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()){