aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/device/pci_device.c24
-rw-r--r--src/include/device/pci_def.h1
2 files changed, 23 insertions, 2 deletions
diff --git a/src/device/pci_device.c b/src/device/pci_device.c
index fbe9d9691b..5f908d2f68 100644
--- a/src/device/pci_device.c
+++ b/src/device/pci_device.c
@@ -734,11 +734,31 @@ void pci_bus_reset(struct bus *bus)
void pci_dev_set_subsystem(struct device *dev, unsigned int vendor,
unsigned int device)
{
+ uint8_t offset;
+
+ /* Header type */
+ switch (dev->hdr_type & 0x7f) {
+ case PCI_HEADER_TYPE_NORMAL:
+ offset = PCI_SUBSYSTEM_VENDOR_ID;
+ break;
+ case PCI_HEADER_TYPE_BRIDGE:
+ offset = pci_find_capability(dev, PCI_CAP_ID_SSVID);
+ if (!offset)
+ return;
+ offset += 4; /* Vendor ID at offset 4 */
+ break;
+ case PCI_HEADER_TYPE_CARDBUS:
+ offset = PCI_CB_SUBSYSTEM_VENDOR_ID;
+ break;
+ default:
+ return;
+ }
+
if (!vendor || !device) {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ pci_write_config32(dev, offset,
pci_read_config32(dev, PCI_VENDOR_ID));
} else {
- pci_write_config32(dev, PCI_SUBSYSTEM_VENDOR_ID,
+ pci_write_config32(dev, offset,
((device & 0xffff) << 16) | (vendor & 0xffff));
}
}
diff --git a/src/include/device/pci_def.h b/src/include/device/pci_def.h
index f9ce1a6382..bc5bc79e28 100644
--- a/src/include/device/pci_def.h
+++ b/src/include/device/pci_def.h
@@ -198,6 +198,7 @@
#define PCI_CAP_ID_HT 0x08 /* Hypertransport */
#define PCI_CAP_ID_EHCI_DEBUG 0x0A /* EHCI debug port */
#define PCI_CAP_ID_SHPC 0x0C /* PCI Standard Hot-Plug Controller */
+#define PCI_CAP_ID_SSVID 0x0D /* Bridge subsystem vendor/device ID */
#define PCI_CAP_ID_PCIE 0x10 /* PCI Express */
#define PCI_CAP_ID_MSIX 0x11 /* MSI-X */
#define PCI_CAP_LIST_NEXT 1 /* Next capability in the list */