aboutsummaryrefslogtreecommitdiff
path: root/hw/pci/pci.c
diff options
context:
space:
mode:
authorDenis V. Lunev <den@openvz.org>2018-10-02 16:55:38 +0300
committerDr. David Alan Gilbert <dgilbert@redhat.com>2018-10-11 19:58:26 +0100
commit18613dc6d9f2f33c333440fecab4c584281305ee (patch)
tree0d20da3fa631c76f95e0b0a690c683368ef33384 /hw/pci/pci.c
parent5ce43896e1679e706db1562d0e2d86ad428ed1e6 (diff)
qmp, hmp: make subsystem/system-vendor identities optional
According to PCI specification, subsystem id and subsystem vendor id are present only in type 0 and type 2 headers (at different offsets), but not in type 1 headers. Thus we should make this data optional in struct PciDeviceId and skip reporting them via HMP if the information is not available. Additional (wrong information) about PCI bridges (Type1 devices) has been added in 5383a705 and fortunately not released. This patch fixes that problem. The problem was spotted by Markus. Signed-off-by: Denis V. Lunev <den@openvz.org> CC: "Dr. David Alan Gilbert" <dgilbert@redhat.com> CC: Eric Blake <eblake@redhat.com> CC: Markus Armbruster <armbru@redhat.com> Message-Id: <20181002135538.12113-1-den@openvz.org> Reported-by: Markus Armbruster <armbru@redhat.com> Reviewed-by: Eric Blake <eblake@redhat.com> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Diffstat (limited to 'hw/pci/pci.c')
-rw-r--r--hw/pci/pci.c13
1 files changed, 10 insertions, 3 deletions
diff --git a/hw/pci/pci.c b/hw/pci/pci.c
index 51d0dec466..b937f0dc0a 100644
--- a/hw/pci/pci.c
+++ b/hw/pci/pci.c
@@ -1737,9 +1737,6 @@ static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus,
info->id = g_new0(PciDeviceId, 1);
info->id->vendor = pci_get_word(dev->config + PCI_VENDOR_ID);
info->id->device = pci_get_word(dev->config + PCI_DEVICE_ID);
- info->id->subsystem = pci_get_word(dev->config + PCI_SUBSYSTEM_ID);
- info->id->subsystem_vendor =
- pci_get_word(dev->config + PCI_SUBSYSTEM_VENDOR_ID);
info->regions = qmp_query_pci_regions(dev);
info->qdev_id = g_strdup(dev->qdev.id ? dev->qdev.id : "");
@@ -1752,6 +1749,16 @@ static PciDeviceInfo *qmp_query_pci_device(PCIDevice *dev, PCIBus *bus,
if (type == PCI_HEADER_TYPE_BRIDGE) {
info->has_pci_bridge = true;
info->pci_bridge = qmp_query_pci_bridge(dev, bus, bus_num);
+ } else if (type == PCI_HEADER_TYPE_NORMAL) {
+ info->id->has_subsystem = info->id->has_subsystem_vendor = true;
+ info->id->subsystem = pci_get_word(dev->config + PCI_SUBSYSTEM_ID);
+ info->id->subsystem_vendor =
+ pci_get_word(dev->config + PCI_SUBSYSTEM_VENDOR_ID);
+ } else if (type == PCI_HEADER_TYPE_CARDBUS) {
+ info->id->has_subsystem = info->id->has_subsystem_vendor = true;
+ info->id->subsystem = pci_get_word(dev->config + PCI_CB_SUBSYSTEM_ID);
+ info->id->subsystem_vendor =
+ pci_get_word(dev->config + PCI_CB_SUBSYSTEM_VENDOR_ID);
}
return info;