summaryrefslogtreecommitdiffstats
path: root/src/hardware
diff options
context:
space:
mode:
authorPeter Schiffer <pschiffe@redhat.com>2014-01-24 16:10:21 +0100
committerPeter Schiffer <pschiffe@redhat.com>2014-01-24 16:43:39 +0100
commitaf361ba550ba552ef90cba01fe24fa4f72131c76 (patch)
treeadaa8f897dd4fb12df49322e9da6f8cf5d78c72e /src/hardware
parent84f8972201a2362f966690e855453276ca7adc75 (diff)
downloadopenlmi-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.c9
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;
}
}