format command line of qemu to add pci-bridge
like this: -device pci-bridge.
and also add a qemu capability to check if
qemu support pci-bridge device
Signed-off-by: liguang <lig.fnst(a)cn.fujitsu.com>
---
src/qemu/qemu_capabilities.c | 6 ++-
src/qemu/qemu_capabilities.h | 1 +
src/qemu/qemu_command.c | 70 ++++++++++++++++++++++++++++-------------
3 files changed, 53 insertions(+), 24 deletions(-)
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index 29693c3..89ae2aa 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -200,9 +200,10 @@ VIR_ENUM_IMPL(qemuCaps, QEMU_CAPS_LAST,
"vmware-svga",
"device-video-primary",
"s390-sclp",
-
+
"usb-serial", /* 125 */
- "usb-net",
+ "usb-serial",
+ "pci-bridge"
);
@@ -1351,6 +1352,7 @@ struct qemuCapsStringFlags qemuCapsObjectTypes[] = {
{ "cirrus-vga", QEMU_CAPS_DEVICE_CIRRUS_VGA },
{ "vmware-svga", QEMU_CAPS_DEVICE_VMWARE_SVGA },
{ "usb-serial", QEMU_CAPS_DEVICE_USB_SERIAL},
+ { "pci-bridge", QEMU_CAPS_DEVICE_PCI_BRIDGE },
{ "usb-net", QEMU_CAPS_DEVICE_USB_NET},
};
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index 5279d07..c50bba8 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -165,6 +165,7 @@ enum qemuCapsFlags {
QEMU_CAPS_SCLP_S390 = 124, /* -device sclp* */
QEMU_CAPS_DEVICE_USB_SERIAL = 125, /* -device usb-serial */
QEMU_CAPS_DEVICE_USB_NET = 126, /* -device usb-net */
+ QEMU_CAPS_DEVICE_PCI_BRIDGE = 127, /* -device pci-bridge */
QEMU_CAPS_LAST, /* this must always be the last item */
};
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index f6273c1..57dcb2c 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -956,13 +956,6 @@ static char *qemuPCIAddressAsString(virDomainDeviceInfoPtr dev)
{
char *addr;
- if (dev->addr.pci.domain != 0 ||
- dev->addr.pci.bus != 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Only PCI domain 0 and bus 0 are available"));
- return NULL;
- }
-
if (virAsprintf(&addr, "%d:%d:%d.%d",
dev->addr.pci.domain,
dev->addr.pci.bus,
@@ -974,8 +967,24 @@ static char *qemuPCIAddressAsString(virDomainDeviceInfoPtr dev)
return addr;
}
+static int qemuPciBridgeSupport(virDomainDefPtr def)
+{
+ int i, c = 0;
+
+ for (i = 0; i < def->ncontrollers; i++) {
+ virDomainControllerDefPtr controller = def->controllers[i];
+
+ if (controller->type == VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE)
+ c++;
+ }
-static int qemuCollectPCIAddress(virDomainDefPtr def ATTRIBUTE_UNUSED,
+ if (c > 1)
+ return 0;
+ else
+ return -1;
+}
+
+static int qemuCollectPCIAddress(virDomainDefPtr def,
virDomainDeviceDefPtr device,
virDomainDeviceInfoPtr info,
void *opaque)
@@ -994,6 +1003,20 @@ static int qemuCollectPCIAddress(virDomainDefPtr def
ATTRIBUTE_UNUSED,
return 0;
}
+ if (info->addr.pci.domain != 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Only PCI device addresses with "
+ "domain=0 are supported"));
+ return -1;
+ }
+
+ if (info->addr.pci.bus != 0 && qemuPciBridgeSupport(def) < 0) {
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
+ _("Only PCI device addresses with bus=0 are"
+ " supported without pci-bridge support"));
+ return -1;
+ }
+
addr = qemuPCIAddressAsString(info);
if (!addr)
goto cleanup;
@@ -1002,7 +1025,8 @@ static int qemuCollectPCIAddress(virDomainDefPtr def
ATTRIBUTE_UNUSED,
if (info->addr.pci.function != 0) {
virReportError(VIR_ERR_XML_ERROR,
_("Attempted double use of PCI Address '%s'
"
- "(may need \"multifunction='on'\" for
device on function 0)"),
+ "(may need \"multifunction='on'\" for
"
+ "device on function 0)"),
addr);
} else {
virReportError(VIR_ERR_XML_ERROR,
@@ -1037,7 +1061,8 @@ static int qemuCollectPCIAddress(virDomainDefPtr def
ATTRIBUTE_UNUSED,
goto cleanup;
}
- VIR_DEBUG("Remembering PCI addr %s (multifunction=off for function
0)", addr);
+ VIR_DEBUG("Remembering PCI addr %s (multifunction=off"
+ " for function 0)", addr);
if (virHashAddEntry(addrs->used, addr, addr))
goto cleanup;
addr = NULL;
@@ -1753,16 +1778,6 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
qemuCapsPtr caps)
{
if (info->type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI) {
- if (info->addr.pci.domain != 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Only PCI device addresses with domain=0 are
supported"));
- return -1;
- }
- if (info->addr.pci.bus != 0) {
- virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
- _("Only PCI device addresses with bus=0 are
supported"));
- return -1;
- }
if (qemuCapsGet(caps, QEMU_CAPS_PCI_MULTIFUNCTION)) {
if (info->addr.pci.function > 7) {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
@@ -1777,6 +1792,7 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
"are supported with this QEMU binary"));
return -1;
}
+
if (info->addr.pci.multi == VIR_DEVICE_ADDRESS_PCI_MULTI_ON) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("'multifunction=on' is not supported with
"
@@ -1787,11 +1803,13 @@ qemuBuildDeviceAddressStr(virBufferPtr buf,
/* XXX
* When QEMU grows support for > 1 PCI bus, then pci.0 changes
- * to pci.1, pci.2, etc
+ * to pci.1, pci.2, etc, (e.g. when support pci-to-pci bridge)
* When QEMU grows support for > 1 PCI domain, then pci.0 change
* to pciNN.0 where NN is the domain number
*/
- if (qemuCapsGet(caps, QEMU_CAPS_PCI_MULTIBUS))
+ if (qemuCapsGet(caps, QEMU_CAPS_DEVICE_PCI_BRIDGE))
+ virBufferAsprintf(buf, ",bus=pci.%d", info->addr.pci.bus);
+ else if (qemuCapsGet(caps, QEMU_CAPS_PCI_MULTIBUS))
virBufferAsprintf(buf, ",bus=pci.0");
else
virBufferAsprintf(buf, ",bus=pci");
@@ -3072,6 +3090,12 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
int model;
switch (def->type) {
+ case VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE:
+ virBufferAsprintf(&buf, "pci-bridge,chassis_nr=%d",
def->idx+1);
+ virBufferAsprintf(&buf, ",id=pci.%d", def->idx);
+ if (def->idx == 0)
+ goto out;
+ break;
case VIR_DOMAIN_CONTROLLER_TYPE_SCSI:
model = def->model;
if ((qemuSetScsiControllerModel(domainDef, caps, &model)) < 0)
@@ -3145,6 +3169,7 @@ qemuBuildControllerDevStr(virDomainDefPtr domainDef,
if (qemuBuildDeviceAddressStr(&buf, &def->info, caps) < 0)
goto error;
+out:
if (virBufferError(&buf)) {
virReportOOMError();
goto error;
@@ -5080,6 +5105,7 @@ qemuBuildCommandLine(virConnectPtr conn,
/* We don't add an explicit IDE or FD controller because the
* provided PIIX4 device already includes one. It isn't possible to
* remove the PIIX4. */
+ VIR_DOMAIN_CONTROLLER_TYPE_PCIBRIDGE,
VIR_DOMAIN_CONTROLLER_TYPE_USB,
VIR_DOMAIN_CONTROLLER_TYPE_SCSI,
VIR_DOMAIN_CONTROLLER_TYPE_SATA,
--
1.7.2.5