diff options
author | Peter Schiffer <pschiffe@redhat.com> | 2014-01-24 16:10:21 +0100 |
---|---|---|
committer | Peter Schiffer <pschiffe@redhat.com> | 2014-01-24 16:43:39 +0100 |
commit | af361ba550ba552ef90cba01fe24fa4f72131c76 (patch) | |
tree | adaa8f897dd4fb12df49322e9da6f8cf5d78c72e /src/hardware | |
parent | 84f8972201a2362f966690e855453276ca7adc75 (diff) | |
download | openlmi-providers-af361ba550ba552ef90cba01fe24fa4f72131c76.tar.gz openlmi-providers-af361ba550ba552ef90cba01fe24fa4f72131c76.tar.xz openlmi-providers-af361ba550ba552ef90cba01fe24fa4f72131c76.zip |
Hardware: detect subsystem id and vendor for PCI Bridges
PCI Bridges have subsystem id and vendor stored in capabilities, not in header.
Diffstat (limited to 'src/hardware')
-rw-r--r-- | src/hardware/PCIDev.c | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/src/hardware/PCIDev.c b/src/hardware/PCIDev.c index ead54a9..83f2cf2 100644 --- a/src/hardware/PCIDev.c +++ b/src/hardware/PCIDev.c @@ -61,16 +61,21 @@ void cleanup_pci_access(struct pci_access **acc) void get_subid(struct pci_dev *d, u16 *subvp, u16 *subdp) { + *subvp = *subdp = 0xffff; u8 htype = pci_read_byte(d, PCI_HEADER_TYPE) & 0x7f; if (htype == PCI_HEADER_TYPE_NORMAL) { *subvp = pci_read_word(d, PCI_SUBSYSTEM_VENDOR_ID); *subdp = pci_read_word(d, PCI_SUBSYSTEM_ID); + } else if (htype == PCI_HEADER_TYPE_BRIDGE) { + struct pci_cap *cap = pci_find_cap(d, PCI_CAP_ID_SSVID, PCI_CAP_NORMAL); + if (cap) { + *subvp = pci_read_word(d, cap->addr + PCI_SSVID_VENDOR); + *subdp = pci_read_word(d, cap->addr + PCI_SSVID_DEVICE); + } } else if (htype == PCI_HEADER_TYPE_CARDBUS) { *subvp = pci_read_word(d, PCI_CB_SUBSYSTEM_VENDOR_ID); *subdp = pci_read_word(d, PCI_CB_SUBSYSTEM_ID); - } else { - *subvp = *subdp = 0xffff; } } |