summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrad Smith <brad@cvs.openbsd.org>2005-06-29 03:18:50 +0000
committerBrad Smith <brad@cvs.openbsd.org>2005-06-29 03:18:50 +0000
commit20872ae2cefa31a862e9e2b8f35faa8dfb1dad74 (patch)
treeaf4a4de5b9b80d775c2a78d1c9dde38d9d23ac00
parent0103040bf0da84a19e991a5491f084eddc07d2aa (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.c17
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))