From 18613dc6d9f2f33c333440fecab4c584281305ee Mon Sep 17 00:00:00 2001 From: "Denis V. Lunev" Date: Tue, 2 Oct 2018 16:55:38 +0300 Subject: 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 CC: "Dr. David Alan Gilbert" CC: Eric Blake CC: Markus Armbruster Message-Id: <20181002135538.12113-1-den@openvz.org> Reported-by: Markus Armbruster Reviewed-by: Eric Blake Reviewed-by: Dr. David Alan Gilbert Reviewed-by: Markus Armbruster Signed-off-by: Dr. David Alan Gilbert --- hw/pci/pci.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'hw/pci') diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 51d0dec..b937f0d 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; -- cgit v1.1