mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-02-23 20:02:21 +00:00
qemu: sound: Support intel 'ich6' model
In QEMU, the card itself is a PCI device, but it requires a codec (either -device hda-output or -device hda-duplex) to actually output sound. Specifying <sound model='ich6'/> gives us -device intel-hda -device hda-duplex I think it's important that a simple <sound model='ich6'/> sets up a useful codec, to have consistent behavior with all other sound cards. This is basically Dan's proposal of <sound model='ich6'> <codec type='output' slot='0'/> <codec type='duplex' slot='3'/> </sound> without the codec bits implemented. The important thing is to keep a consistent API here, we don't want some <sound> devs require tweaking codecs but not others. Steps I see to accomplishing this: - every <sound> device has a <codec type='default'/> (unless codecs are manually specified) - <codec type='none'/> is required to specify 'no codecs' - new audio settings like mic=on|off could then be exposed in <sound> or <codec> in a consistent manner for all sound models v2: Use model='ich6' v3: Use feature detection, from eblake Set codec id, bus, and cad values v4: intel-hda isn't supported if -device isn't available v5: Comment spelling fixes
This commit is contained in:
parent
4a267912bf
commit
6cabc0b0d0
@ -1880,8 +1880,9 @@ qemu-kvm -net nic,model=? /dev/null
|
|||||||
The <code>sound</code> element has one mandatory attribute,
|
The <code>sound</code> element has one mandatory attribute,
|
||||||
<code>model</code>, which specifies what real sound device is emulated.
|
<code>model</code>, which specifies what real sound device is emulated.
|
||||||
Valid values are specific to the underlying hypervisor, though typical
|
Valid values are specific to the underlying hypervisor, though typical
|
||||||
choices are 'es1370', 'sb16', and 'ac97'
|
choices are 'es1370', 'sb16', 'ac97', and 'ich6'
|
||||||
(<span class="since">'ac97' only since 0.6.0</span>)
|
(<span class="since">
|
||||||
|
'ac97' only since 0.6.0, 'ich6' only since 0.8.8</span>)
|
||||||
</dd>
|
</dd>
|
||||||
</dl>
|
</dl>
|
||||||
|
|
||||||
|
@ -1530,6 +1530,7 @@
|
|||||||
<value>es1370</value>
|
<value>es1370</value>
|
||||||
<value>pcspk</value>
|
<value>pcspk</value>
|
||||||
<value>ac97</value>
|
<value>ac97</value>
|
||||||
|
<value>ich6</value>
|
||||||
</choice>
|
</choice>
|
||||||
</attribute>
|
</attribute>
|
||||||
<optional>
|
<optional>
|
||||||
|
@ -231,7 +231,8 @@ VIR_ENUM_IMPL(virDomainSoundModel, VIR_DOMAIN_SOUND_MODEL_LAST,
|
|||||||
"sb16",
|
"sb16",
|
||||||
"es1370",
|
"es1370",
|
||||||
"pcspk",
|
"pcspk",
|
||||||
"ac97")
|
"ac97",
|
||||||
|
"ich6")
|
||||||
|
|
||||||
VIR_ENUM_IMPL(virDomainMemballoonModel, VIR_DOMAIN_MEMBALLOON_MODEL_LAST,
|
VIR_ENUM_IMPL(virDomainMemballoonModel, VIR_DOMAIN_MEMBALLOON_MODEL_LAST,
|
||||||
"virtio",
|
"virtio",
|
||||||
|
@ -480,6 +480,7 @@ enum virDomainSoundModel {
|
|||||||
VIR_DOMAIN_SOUND_MODEL_ES1370,
|
VIR_DOMAIN_SOUND_MODEL_ES1370,
|
||||||
VIR_DOMAIN_SOUND_MODEL_PCSPK,
|
VIR_DOMAIN_SOUND_MODEL_PCSPK,
|
||||||
VIR_DOMAIN_SOUND_MODEL_AC97,
|
VIR_DOMAIN_SOUND_MODEL_AC97,
|
||||||
|
VIR_DOMAIN_SOUND_MODEL_ICH6,
|
||||||
|
|
||||||
VIR_DOMAIN_SOUND_MODEL_LAST
|
VIR_DOMAIN_SOUND_MODEL_LAST
|
||||||
};
|
};
|
||||||
|
@ -1079,6 +1079,11 @@ cleanup:
|
|||||||
int
|
int
|
||||||
qemuCapsParseDeviceStr(const char *str, unsigned long long *flags)
|
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"))
|
if (strstr(str, "pci-assign.configfd"))
|
||||||
*flags |= QEMUD_CMD_FLAG_PCI_CONFIGFD;
|
*flags |= QEMUD_CMD_FLAG_PCI_CONFIGFD;
|
||||||
if (strstr(str, "virtio-blk-pci.bootindex"))
|
if (strstr(str, "virtio-blk-pci.bootindex"))
|
||||||
|
@ -84,6 +84,7 @@ enum qemuCapsFlags {
|
|||||||
QEMUD_CMD_FLAG_VGA_NONE = (1LL << 47), /* The 'none' arg for '-vga' */
|
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_MIGRATE_QEMU_FD = (1LL << 48), /* -incoming fd:n */
|
||||||
QEMUD_CMD_FLAG_BOOTINDEX = (1LL << 49), /* -device bootindex property */
|
QEMUD_CMD_FLAG_BOOTINDEX = (1LL << 49), /* -device bootindex property */
|
||||||
|
QEMUD_CMD_FLAG_HDA_DUPLEX = (1LL << 50), /* -device hda-duplex */
|
||||||
};
|
};
|
||||||
|
|
||||||
virCapsPtr qemuCapsInit(virCapsPtr old_caps);
|
virCapsPtr qemuCapsInit(virCapsPtr old_caps);
|
||||||
|
@ -1774,11 +1774,13 @@ qemuBuildSoundDevStr(virDomainSoundDefPtr sound)
|
|||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Hack for 2 wierdly unusal devices name in QEMU */
|
/* Hack for weirdly unusual devices name in QEMU */
|
||||||
if (STREQ(model, "es1370"))
|
if (STREQ(model, "es1370"))
|
||||||
model = "ES1370";
|
model = "ES1370";
|
||||||
else if (STREQ(model, "ac97"))
|
else if (STREQ(model, "ac97"))
|
||||||
model = "AC97";
|
model = "AC97";
|
||||||
|
else if (STREQ(model, "ich6"))
|
||||||
|
model = "intel-hda";
|
||||||
|
|
||||||
virBufferVSprintf(&buf, "%s", model);
|
virBufferVSprintf(&buf, "%s", model);
|
||||||
virBufferVSprintf(&buf, ",id=%s", sound->info.alias);
|
virBufferVSprintf(&buf, ",id=%s", sound->info.alias);
|
||||||
@ -1797,6 +1799,29 @@ error:
|
|||||||
return NULL;
|
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 *
|
static char *
|
||||||
qemuBuildVideoDevStr(virDomainVideoDefPtr video)
|
qemuBuildVideoDevStr(virDomainVideoDefPtr video)
|
||||||
@ -3817,11 +3842,29 @@ qemuBuildCommandLine(virConnectPtr conn,
|
|||||||
virCommandAddArgList(cmd, "-soundhw", "pcspk", NULL);
|
virCommandAddArgList(cmd, "-soundhw", "pcspk", NULL);
|
||||||
} else {
|
} else {
|
||||||
virCommandAddArg(cmd, "-device");
|
virCommandAddArg(cmd, "-device");
|
||||||
|
|
||||||
if (!(str = qemuBuildSoundDevStr(sound)))
|
if (!(str = qemuBuildSoundDevStr(sound)))
|
||||||
goto error;
|
goto error;
|
||||||
|
|
||||||
virCommandAddArg(cmd, str);
|
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);
|
VIR_FREE(str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3840,6 +3883,13 @@ qemuBuildCommandLine(virConnectPtr conn,
|
|||||||
"%s", _("invalid sound model"));
|
"%s", _("invalid sound model"));
|
||||||
goto error;
|
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);
|
strncat(modstr, model, size);
|
||||||
size -= strlen(model);
|
size -= strlen(model);
|
||||||
if (i < (def->nsounds - 1))
|
if (i < (def->nsounds - 1))
|
||||||
@ -5675,6 +5725,8 @@ virDomainDefPtr qemuParseCommandLine(virCapsPtr caps,
|
|||||||
type = VIR_DOMAIN_SOUND_MODEL_ES1370;
|
type = VIR_DOMAIN_SOUND_MODEL_ES1370;
|
||||||
} else if (STRPREFIX(start, "ac97")) {
|
} else if (STRPREFIX(start, "ac97")) {
|
||||||
type = VIR_DOMAIN_SOUND_MODEL_AC97;
|
type = VIR_DOMAIN_SOUND_MODEL_AC97;
|
||||||
|
} else if (STRPREFIX(start, "hda")) {
|
||||||
|
type = VIR_DOMAIN_SOUND_MODEL_ICH6;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type != -1) {
|
if (type != -1) {
|
||||||
|
@ -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
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
<sound model='es1370'/>
|
<sound model='es1370'/>
|
||||||
<sound model='sb16'/>
|
<sound model='sb16'/>
|
||||||
<sound model='ac97'/>
|
<sound model='ac97'/>
|
||||||
|
<sound model='ich6'/>
|
||||||
<memballoon model='virtio'/>
|
<memballoon model='virtio'/>
|
||||||
</devices>
|
</devices>
|
||||||
</domain>
|
</domain>
|
||||||
|
@ -418,7 +418,7 @@ mymain(int argc, char **argv)
|
|||||||
QEMUD_CMD_FLAG_NODEFCONFIG, false);
|
QEMUD_CMD_FLAG_NODEFCONFIG, false);
|
||||||
DO_TEST("sound", 0, false);
|
DO_TEST("sound", 0, false);
|
||||||
DO_TEST("sound-device", QEMUD_CMD_FLAG_DEVICE |
|
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 |
|
DO_TEST("fs9p", QEMUD_CMD_FLAG_DEVICE |
|
||||||
QEMUD_CMD_FLAG_NODEFCONFIG | QEMUD_CMD_FLAG_FSDEV, false);
|
QEMUD_CMD_FLAG_NODEFCONFIG | QEMUD_CMD_FLAG_FSDEV, false);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user