diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in
index 859f3fdf50..e7f65ade53 100644
--- a/docs/formatdomain.html.in
+++ b/docs/formatdomain.html.in
@@ -1880,8 +1880,9 @@ qemu-kvm -net nic,model=? /dev/null
The sound
element has one mandatory attribute,
model
, which specifies what real sound device is emulated.
Valid values are specific to the underlying hypervisor, though typical
- choices are 'es1370', 'sb16', and 'ac97'
- ('ac97' only since 0.6.0)
+ choices are 'es1370', 'sb16', 'ac97', and 'ich6'
+ (
+ 'ac97' only since 0.6.0, 'ich6' only since 0.8.8)
diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng
index d4756e6e92..b2f8e0069a 100644
--- a/docs/schemas/domain.rng
+++ b/docs/schemas/domain.rng
@@ -1530,6 +1530,7 @@
es1370
pcspk
ac97
+ ich6
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 699fee750a..d5445a40a0 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -231,7 +231,8 @@ VIR_ENUM_IMPL(virDomainSoundModel, VIR_DOMAIN_SOUND_MODEL_LAST,
"sb16",
"es1370",
"pcspk",
- "ac97")
+ "ac97",
+ "ich6")
VIR_ENUM_IMPL(virDomainMemballoonModel, VIR_DOMAIN_MEMBALLOON_MODEL_LAST,
"virtio",
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 3b00ba0cd8..fc69627cfd 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -480,6 +480,7 @@ enum virDomainSoundModel {
VIR_DOMAIN_SOUND_MODEL_ES1370,
VIR_DOMAIN_SOUND_MODEL_PCSPK,
VIR_DOMAIN_SOUND_MODEL_AC97,
+ VIR_DOMAIN_SOUND_MODEL_ICH6,
VIR_DOMAIN_SOUND_MODEL_LAST
};
diff --git a/src/qemu/qemu_capabilities.c b/src/qemu/qemu_capabilities.c
index faf7d441f3..02865e41fe 100644
--- a/src/qemu/qemu_capabilities.c
+++ b/src/qemu/qemu_capabilities.c
@@ -1079,6 +1079,11 @@ cleanup:
int
qemuCapsParseDeviceStr(const char *str, unsigned long long *flags)
{
+ /* Which devices exist. */
+ if (strstr(str, "name \"hda-duplex\""))
+ *flags |= QEMUD_CMD_FLAG_HDA_DUPLEX;
+
+ /* Features of given devices. */
if (strstr(str, "pci-assign.configfd"))
*flags |= QEMUD_CMD_FLAG_PCI_CONFIGFD;
if (strstr(str, "virtio-blk-pci.bootindex"))
diff --git a/src/qemu/qemu_capabilities.h b/src/qemu/qemu_capabilities.h
index e9e2da0d42..9148d90851 100644
--- a/src/qemu/qemu_capabilities.h
+++ b/src/qemu/qemu_capabilities.h
@@ -84,6 +84,7 @@ enum qemuCapsFlags {
QEMUD_CMD_FLAG_VGA_NONE = (1LL << 47), /* The 'none' arg for '-vga' */
QEMUD_CMD_FLAG_MIGRATE_QEMU_FD = (1LL << 48), /* -incoming fd:n */
QEMUD_CMD_FLAG_BOOTINDEX = (1LL << 49), /* -device bootindex property */
+ QEMUD_CMD_FLAG_HDA_DUPLEX = (1LL << 50), /* -device hda-duplex */
};
virCapsPtr qemuCapsInit(virCapsPtr old_caps);
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
index c20f03120e..6dc586f916 100644
--- a/src/qemu/qemu_command.c
+++ b/src/qemu/qemu_command.c
@@ -1774,11 +1774,13 @@ qemuBuildSoundDevStr(virDomainSoundDefPtr sound)
goto error;
}
- /* Hack for 2 wierdly unusal devices name in QEMU */
+ /* Hack for weirdly unusual devices name in QEMU */
if (STREQ(model, "es1370"))
model = "ES1370";
else if (STREQ(model, "ac97"))
model = "AC97";
+ else if (STREQ(model, "ich6"))
+ model = "intel-hda";
virBufferVSprintf(&buf, "%s", model);
virBufferVSprintf(&buf, ",id=%s", sound->info.alias);
@@ -1797,6 +1799,29 @@ error:
return NULL;
}
+static char *
+qemuBuildSoundCodecStr(virDomainSoundDefPtr sound,
+ const char *codec)
+{
+ virBuffer buf = VIR_BUFFER_INITIALIZER;
+ int cad = 0;
+
+ virBufferVSprintf(&buf, "%s", codec);
+ virBufferVSprintf(&buf, ",id=%s-codec%d", sound->info.alias, cad);
+ virBufferVSprintf(&buf, ",bus=%s.0", sound->info.alias);
+ virBufferVSprintf(&buf, ",cad=%d", cad);
+
+ if (virBufferError(&buf)) {
+ virReportOOMError();
+ goto error;
+ }
+
+ return virBufferContentAndReset(&buf);
+
+error:
+ virBufferFreeAndReset(&buf);
+ return NULL;
+}
static char *
qemuBuildVideoDevStr(virDomainVideoDefPtr video)
@@ -3817,11 +3842,29 @@ qemuBuildCommandLine(virConnectPtr conn,
virCommandAddArgList(cmd, "-soundhw", "pcspk", NULL);
} else {
virCommandAddArg(cmd, "-device");
-
if (!(str = qemuBuildSoundDevStr(sound)))
goto error;
virCommandAddArg(cmd, str);
+
+ if (sound->model == VIR_DOMAIN_SOUND_MODEL_ICH6) {
+ char *codecstr = NULL;
+ if (!(qemuCmdFlags & QEMUD_CMD_FLAG_HDA_DUPLEX)) {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("this QEMU binary lacks hda support"));
+ goto error;
+ }
+
+ virCommandAddArg(cmd, "-device");
+ if (!(codecstr = qemuBuildSoundCodecStr(sound,
+ "hda-duplex"))) {
+ goto error;
+ }
+
+ virCommandAddArg(cmd, codecstr);
+ VIR_FREE(codecstr);
+ }
+
VIR_FREE(str);
}
}
@@ -3840,6 +3883,13 @@ qemuBuildCommandLine(virConnectPtr conn,
"%s", _("invalid sound model"));
goto error;
}
+
+ if (sound->model == VIR_DOMAIN_SOUND_MODEL_ICH6) {
+ qemuReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+ _("this QEMU binary lacks hda support"));
+ goto error;
+ }
+
strncat(modstr, model, size);
size -= strlen(model);
if (i < (def->nsounds - 1))
@@ -5675,6 +5725,8 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
type = VIR_DOMAIN_SOUND_MODEL_ES1370;
} else if (STRPREFIX(start, "ac97")) {
type = VIR_DOMAIN_SOUND_MODEL_AC97;
+ } else if (STRPREFIX(start, "hda")) {
+ type = VIR_DOMAIN_SOUND_MODEL_ICH6;
}
if (type != -1) {
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args
index 6b2e697236..4c5172fcf2 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args
+++ b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.args
@@ -1 +1 @@
-LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -soundhw pcspk -device ES1370,id=sound1,bus=pci.0,addr=0x2 -device sb16,id=sound2 -device AC97,id=sound3,bus=pci.0,addr=0x3 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x4
+LC_ALL=C PATH=/bin HOME=/home/test USER=test LOGNAME=test /usr/bin/qemu -S -M pc -m 214 -smp 1 -nographic -nodefconfig -nodefaults -monitor unix:/tmp/test-monitor,server,nowait -no-acpi -boot c -hda /dev/HostVG/QEMUGuest1 -usb -soundhw pcspk -device ES1370,id=sound1,bus=pci.0,addr=0x2 -device sb16,id=sound2 -device AC97,id=sound3,bus=pci.0,addr=0x3 -device intel-hda,id=sound4,bus=pci.0,addr=0x4 -device hda-duplex,id=sound4-codec0,bus=sound4.0,cad=0 -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
diff --git a/tests/qemuxml2argvdata/qemuxml2argv-sound-device.xml b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.xml
index c7253462b2..fbca4fe890 100644
--- a/tests/qemuxml2argvdata/qemuxml2argv-sound-device.xml
+++ b/tests/qemuxml2argvdata/qemuxml2argv-sound-device.xml
@@ -22,6 +22,7 @@
+
diff --git a/tests/qemuxml2argvtest.c b/tests/qemuxml2argvtest.c
index a7270ecc42..0c0693b7be 100644
--- a/tests/qemuxml2argvtest.c
+++ b/tests/qemuxml2argvtest.c
@@ -418,7 +418,7 @@ mymain(int argc, char **argv)
QEMUD_CMD_FLAG_NODEFCONFIG, false);
DO_TEST("sound", 0, false);
DO_TEST("sound-device", QEMUD_CMD_FLAG_DEVICE |
- QEMUD_CMD_FLAG_NODEFCONFIG, false);
+ QEMUD_CMD_FLAG_NODEFCONFIG | QEMUD_CMD_FLAG_HDA_DUPLEX, false);
DO_TEST("fs9p", QEMUD_CMD_FLAG_DEVICE |
QEMUD_CMD_FLAG_NODEFCONFIG | QEMUD_CMD_FLAG_FSDEV, false);