--- /n/sources/plan9/sys/src/9/pc/fns.h Wed May 14 14:45:00 2014 +++ /sys/src/9/pc/fns.h Fri Feb 19 00:00:00 2016 @@ -121,6 +121,7 @@ ulong paddr(void*); ulong pcibarsize(Pcidev*, int); void pcibussize(Pcidev*, ulong*, ulong*); +int pcicap(Pcidev*, int); int pcicfgr8(Pcidev*, int); int pcicfgr16(Pcidev*, int); int pcicfgr32(Pcidev*, int); --- /n/sources/plan9/sys/src/9/pc/io.h Fri Apr 8 20:27:20 2011 +++ /sys/src/9/pc/io.h Fri Feb 19 00:00:00 2016 @@ -214,6 +214,23 @@ PciCBLMBAR = 0x44, /* legacy mode base address */ }; +/* capabilities */ +enum { + PciCapPMG = 0x01, /* power management */ + PciCapAGP = 0x02, + PciCapVPD = 0x03, /* vital product data */ + PciCapSID = 0x04, /* slot id */ + PciCapMSI = 0x05, + PciCapCHS = 0x06, /* compact pci hot swap */ + PciCapPCIX = 0x07, + PciCapHTC = 0x08, /* hypertransport irq conf */ + PciCapVND = 0x09, /* vendor specific information */ + PciCapPCIe = 0x10, + PciCapMSIX = 0x11, + PciCapSATA = 0x12, + PciCapHSW = 0x0c, /* hot swap */ +}; + typedef struct Pcisiz Pcisiz; struct Pcisiz { --- /n/sources/plan9/sys/src/9/pc/pci.c Mon Oct 21 21:57:15 2013 +++ /sys/src/9/pc/pci.c Fri Feb 19 00:00:00 2016 @@ -1402,50 +1402,36 @@ pcicfgw16(p, PciPCR, p->pcr); } -static int -pcigetpmrb(Pcidev* p) +int +pcicap(Pcidev* p, int cap) { - int ptr; - - if(p->pmrb != 0) - return p->pmrb; - p->pmrb = -1; + int i, c, off; - /* - * If there are no extended capabilities implemented, - * (bit 4 in the status register) assume there's no standard - * power management method. - * Find the capabilities pointer based on PCI header type. - */ - if(!(pcicfgr16(p, PciPSR) & 0x0010)) + /* status register bit 4 has capabilities */ + if((pcicfgr16(p, PciPSR) & 1<<4) == 0) return -1; - switch(pcicfgr8(p, PciHDT)){ + switch(pcicfgr8(p, PciHDT) & 0x7f){ default: return -1; case 0: /* all other */ case 1: /* PCI to PCI bridge */ - ptr = 0x34; + off = 0x34; break; case 2: /* CardBus bridge */ - ptr = 0x14; + off = 0x14; break; } - ptr = pcicfgr32(p, ptr); - - while(ptr != 0){ - /* - * Check for validity. - * Can't be in standard header and must be double - * word aligned. - */ - if(ptr < 0x40 || (ptr & ~0xFC)) - return -1; - if(pcicfgr8(p, ptr) == 0x01){ - p->pmrb = ptr; - return ptr; - } - - ptr = pcicfgr8(p, ptr+1); + for(i = 48; i--;){ + off = pcicfgr8(p, off); + if(off < 0x40 || (off & 3)) + break; + off &= ~3; + c = pcicfgr8(p, off); + if(c == 0xff) + break; + if(c == cap) + return off; + off++; } return -1; @@ -1456,7 +1442,7 @@ { int pmcsr, ptr; - if((ptr = pcigetpmrb(p)) == -1) + if((ptr = pcicap(p, PciCapPMG)) == -1) return -1; /* @@ -1478,7 +1464,7 @@ { int ostate, pmc, pmcsr, ptr; - if((ptr = pcigetpmrb(p)) == -1) + if((ptr = pcicap(p, PciCapPMG)) == -1) return -1; pmc = pcicfgr16(p, ptr+2); --- /n/sources/plan9/sys/src/9/pc/etherm10g.c Tue Mar 11 23:05:20 2014 +++ /sys/src/9/pc/etherm10g.c Fri Feb 19 00:00:00 2016 @@ -239,21 +239,6 @@ static Ctlr *ctlrs; enum { - PciCapPMG = 0x01, /* power management */ - PciCapAGP = 0x02, - PciCapVPD = 0x03, /* vital product data */ - PciCapSID = 0x04, /* slot id */ - PciCapMSI = 0x05, - PciCapCHS = 0x06, /* compact pci hot swap */ - PciCapPCIX = 0x07, - PciCapHTC = 0x08, /* hypertransport irq conf */ - PciCapVND = 0x09, /* vendor specific information */ - PciCapHSW = 0x0C, /* hot swap */ - PciCapPCIe = 0x10, - PciCapMSIX = 0x11, -}; - -enum { PcieAERC = 1, PcieVC, PcieSNC, @@ -269,31 +254,6 @@ PcieLCR = 12, PcieMRD = 0x7000, /* maximum read size */ }; - -static int -pcicap(Pcidev *p, int cap) -{ - int i, c, off; - - pcicapdbg("pcicap: %x:%d\n", p->vid, p->did); - off = 0x34; /* 0x14 for cardbus */ - for(i = 48; i--; ){ - pcicapdbg("\t" "loop %x\n", off); - off = pcicfgr8(p, off); - pcicapdbg("\t" "pcicfgr8 %x\n", off); - if(off < 0x40) - break; - off &= ~3; - c = pcicfgr8(p, off); - pcicapdbg("\t" "pcicfgr8 %x\n", c); - if(c == 0xff) - break; - if(c == cap) - return off; - off++; - } - return 0; -} /* * this function doesn't work because pcicgr32 doesn't have access