static void cfgset8(uintptr_t p, uint8_t v, void* r) { Reg *ro = r; Pcidev d; d.tbdf = ro->tbdf; pcicfgw8(&d, p, v); }
static void wpipci(void) { Pcidev *pdev; pdev = nil; while(pdev = pcimatch(pdev, 0x8086, 0)){ Ctlr *ctlr; void *mem; switch(pdev->did){ default: continue; case 0x4227: break; } /* Clear device-specific "PCI retry timeout" register (41h). */ 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"); continue; } ctlr->port = pdev->mem[0].bar & ~0x0F; mem = vmap(pdev->mem[0].bar & ~0x0F, pdev->mem[0].size); if(mem == nil) { print("wpi: can't map %8.8luX\n", pdev->mem[0].bar); free(ctlr); continue; } ctlr->nic = mem; ctlr->pdev = pdev; if(wpihead != nil) wpitail->link = ctlr; else wpihead = ctlr; wpitail = ctlr; } }
static void i82563pci(void) { int port, type, cls; Pcidev *p; Ctlr *ctlr; static int first = 1; if (first) first = 0; else return; p = nil; while(p = pcimatch(p, 0x8086, 0)){ if(p->ccrb != 0x02 || p->ccru != 0) continue; //print("i82563pci: did %4.4#x\n", p->did); switch(p->did){ case 0x1096: case 0x10ba: type = i82563; break; case 0x1049: /* mm */ case 0x104a: /* dm */ case 0x104d: /* v */ case 0x10bd: /* dm */ type = i82566; break; case 0x10cd: /* lf */ type = i82567; break; case 0x10a4: case 0x105e: type = i82571; break; case 0x10b9: /* sic, 82572 */ type = i82572; break; case 0x108b: /* e */ case 0x108c: /* e (iamt) */ case 0x109a: /* l */ type = i82573; break; case 0x10a7: /* 82575eb */ type = i82575; break; default: continue; } port = upamalloc(p->mem[0].bar & ~0x0F, p->mem[0].size, 0); if(port == 0){ print("%s: can't map %d @ 0x%8.8lux\n", tname[type], p->mem[0].size, p->mem[0].bar); continue; } if(p->pcr & MemWrInv){ cls = pcicfgr8(p, PciCLS) * 4; if(cls != CACHELINESZ) pcicfgw8(p, PciCLS, CACHELINESZ/4); } cls = pcicfgr8(p, PciCLS); switch(cls){ default: print("%s: unexpected CLS - %d bytes\n", tname[type], cls*sizeof(long)); break; case 0x00: case 0xFF: /* alphapc 164lx returns 0 */ print("%s: unusable PciCLS: %d, using %d longs\n", tname[type], cls, CACHELINESZ/sizeof(long)); cls = CACHELINESZ/sizeof(long); pcicfgw8(p, PciCLS, cls); break; case 0x08: case 0x10: break; } ctlr = malloc(sizeof(Ctlr)); ctlr->port = port; ctlr->pcidev = p; ctlr->cls = cls*4; ctlr->type = type; ctlr->nic = KADDR(ctlr->port); if(i82563reset(ctlr)){ free(ctlr); continue; } pcisetbme(p); if(ctlrhead != nil) ctlrtail->next = ctlr; else ctlrhead = ctlr; ctlrtail = ctlr; } }