diff options
author | Brad Smith <brad@cvs.openbsd.org> | 2005-06-29 03:18:50 +0000 |
---|---|---|
committer | Brad Smith <brad@cvs.openbsd.org> | 2005-06-29 03:18:50 +0000 |
commit | 20872ae2cefa31a862e9e2b8f35faa8dfb1dad74 (patch) | |
tree | af4a4de5b9b80d775c2a78d1c9dde38d9d23ac00 | |
parent | 0103040bf0da84a19e991a5491f084eddc07d2aa (diff) |
rev 1.47
Make pci_get_capability() work correctly on both header type 0 and type 2
devices; both have different Capability List Pointer registers.
From NetBSD
-rw-r--r-- | sys/dev/pci/pci.c | 17 |
1 files changed, 15 insertions, 2 deletions
diff --git a/sys/dev/pci/pci.c b/sys/dev/pci/pci.c index 8d6e4b9e587..f9c66ff318d 100644 --- a/sys/dev/pci/pci.c +++ b/sys/dev/pci/pci.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pci.c,v 1.37 2005/05/02 11:30:25 grange Exp $ */ +/* $OpenBSD: pci.c,v 1.38 2005/06/29 03:18:49 brad Exp $ */ /* $NetBSD: pci.c,v 1.31 1997/06/06 23:48:04 thorpej Exp $ */ /* @@ -423,7 +423,20 @@ pci_get_capability(pc, tag, capid, offset, value) if (!(reg & PCI_STATUS_CAPLIST_SUPPORT)) return (0); - ofs = PCI_CAPLIST_PTR(pci_conf_read(pc, tag, PCI_CAPLISTPTR_REG)); + /* Determine the Capability List Pointer register to start with. */ + reg = pci_conf_read(pc, tag, PCI_BHLC_REG); + switch (PCI_HDRTYPE_TYPE(reg)) { + case 0: /* standard device header */ + ofs = PCI_CAPLISTPTR_REG; + break; + case 2: /* PCI-CardBus Bridge header */ + ofs = PCI_CARDBUS_CAPLISTPTR_REG; + break; + default: + return (0); + } + + ofs = PCI_CAPLIST_PTR(pci_conf_read(pc, tag, ofs)); while (ofs != 0) { #ifdef DIAGNOSTIC if ((ofs & 3) || (ofs < 0x40)) |