commit 50d90e0985fdea1b66dcf6b7e823e666c674f888 Author: David du Colombier <0intro@gmail.com> Date: Sat Jan 15 23:19:28 2022 +0100 9k-jmk-pcicap diff --git a/sys/src/9k/386/etherm10g.c b/sys/src/9k/386/etherm10g.c index b6401282a..f8345eb38 100644 --- a/sys/src/9k/386/etherm10g.c +++ b/sys/src/9k/386/etherm10g.c @@ -239,21 +239,6 @@ typedef struct Ctlr { 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, @@ -271,31 +256,6 @@ enum { 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 * to the pcie extended configuration space. diff --git a/sys/src/9k/386/pci.c b/sys/src/9k/386/pci.c index ff7a1a62f..e9d0e5e0a 100644 --- a/sys/src/9k/386/pci.c +++ b/sys/src/9k/386/pci.c @@ -1258,50 +1258,36 @@ pciclrmwi(Pcidev* p) pcicfgw16(p, PciPCR, p->pcr); } -static int -pcigetpmrb(Pcidev* p) +int +pcicap(Pcidev* p, int cap) { - int ptr; + int i, c, off; - if(p->pmrb != 0) - return p->pmrb; - p->pmrb = -1; - - /* - * 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 = PciCP; + off = PciCP; 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; @@ -1312,7 +1298,7 @@ pcigetpms(Pcidev* p) { int pmcsr, ptr; - if((ptr = pcigetpmrb(p)) == -1) + if((ptr = pcicap(p, PciCapPMG)) == -1) return -1; /* @@ -1334,7 +1320,7 @@ pcisetpms(Pcidev* p, int state) { int ostate, pmc, pmcsr, ptr; - if((ptr = pcigetpmrb(p)) == -1) + if((ptr = pcicap(p, PciCapPMG)) == -1) return -1; pmc = pcicfgr16(p, ptr+2); diff --git a/sys/src/9k/k10/fns.h b/sys/src/9k/k10/fns.h index 7350becf5..54a26b779 100644 --- a/sys/src/9k/k10/fns.h +++ b/sys/src/9k/k10/fns.h @@ -95,6 +95,7 @@ void outsl(int, void*, int); void pause(void); int pciscan(int, Pcidev**); ulong pcibarsize(Pcidev*, int); +int pcicap(Pcidev*, int); int pcicfgr8(Pcidev*, int); int pcicfgr16(Pcidev*, int); int pcicfgr32(Pcidev*, int); diff --git a/sys/src/9k/k10/io.h b/sys/src/9k/k10/io.h index dbf9db8cc..99e409081 100644 --- a/sys/src/9k/k10/io.h +++ b/sys/src/9k/k10/io.h @@ -206,6 +206,23 @@ enum { /* type 2 pre-defined header */ 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 {