aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Hajnoczi <stefanha@redhat.com>2023-10-03 07:43:43 -0400
committerStefan Hajnoczi <stefanha@redhat.com>2023-10-03 07:43:44 -0400
commitda1034094d375afe9e3d8ec8980550ea0f06f7e0 (patch)
treec7afeecefd68813c3636ae0ab8f9d40683175e11
parent50d0bfd0ed78209f003e8f7b9ac25edaa0399157 (diff)
parent9f8cf356723702272af124e621e4c0e9805c8e22 (diff)
Merge tag 'for-upstream' of https://gitlab.com/bonzini/qemu into staging
* fix from optionrom build * fix for KVM on Apple M2 * introduce machine property "audiodev" * ui/vnc: Require audiodev= to enable audio * audio: remove QEMU_AUDIO_* and -audio-help support * audio: forbid using default audiodev backend with -audiodev and -nodefaults * remove compatibility code for old machine types * make-release: do not ship dtc sources * build system cleanups # -----BEGIN PGP SIGNATURE----- # # iQFIBAABCAAyFiEE8TM4V0tmI4mGbHaCv/vSX3jHroMFAmUb0QgUHHBib256aW5p # QHJlZGhhdC5jb20ACgkQv/vSX3jHroOpnAf9EFXfGkXpqQ5Q8ZbVlVc5GQKofMHW # OZwamTBlp/c07+QcQiMxwLhIW0iyDhrfdCjoFSUaTA8O10FM1YrFv4SkUryYb9B3 # bmoTl4NeLvmkxpC47GEeaaBfjyM0G/9Ip9Zsuqx3u+gSzwTbkEstA2u7gcsN0tL9 # VlhMSiV82uHhRC/DJYLxr+8bRYSIm1AeuI8K/O1yags85Kztf3UiQUhePIKLznMH # BdORjD+i46xM1dE8ifpdsunm462cDWz/faAnIH0YVKBlshnQHXKTO+GDA/Fbfl51 # wFfupZXo93wwgawS7elAUzI+gwaKCPRHA8NDcukeO91hTzk6i14y04u5SQ== # =nv64 # -----END PGP SIGNATURE----- # gpg: Signature made Tue 03 Oct 2023 04:30:00 EDT # gpg: using RSA key F13338574B662389866C7682BFFBD25F78C7AE83 # gpg: issuer "pbonzini@redhat.com" # gpg: Good signature from "Paolo Bonzini <bonzini@gnu.org>" [full] # gpg: aka "Paolo Bonzini <pbonzini@redhat.com>" [full] # Primary key fingerprint: 46F5 9FBD 57D6 12E7 BFD4 E2F7 7E15 100C CD36 69B1 # Subkey fingerprint: F133 3857 4B66 2389 866C 7682 BFFB D25F 78C7 AE83 * tag 'for-upstream' of https://gitlab.com/bonzini/qemu: (24 commits) audio: forbid default audiodev backend with -nodefaults audio: propagate Error * out of audio_init vt82c686 machines: Support machine-default audiodev with fallback hw/ppc: Support machine-default audiodev with fallback hw/arm: Support machine-default audiodev with fallback Introduce machine property "audiodev" audio: remove QEMU_AUDIO_* and -audio-help support audio: simplify flow in audio_init audio: commonize voice initialization audio: return Error ** from audio_state_by_name audio: allow returning an error from the driver init audio: Require AudioState in AUD_add_capture ui/vnc: Require audiodev= to enable audio crypto: only include tls-cipher-suites in emulators scsi-disk: ensure that FORMAT UNIT commands are terminated esp: restrict non-DMA transfer length to that of available data esp: use correct type for esp_dma_enable() in sysbus_esp_gpio_demux() Makefile: build plugins before running TCG tests meson: clean up static_library keyword arguments make-release: do not ship dtc sources ... Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
-rw-r--r--accel/kvm/kvm-all.c32
-rw-r--r--audio/alsaaudio.c3
-rw-r--r--audio/audio-hmp-cmds.c6
-rw-r--r--audio/audio.c244
-rw-r--r--audio/audio.h7
-rw-r--r--audio/audio_int.h7
-rw-r--r--audio/audio_legacy.c591
-rw-r--r--audio/audio_template.h9
-rw-r--r--audio/coreaudio.m3
-rw-r--r--audio/dbusaudio.c3
-rw-r--r--audio/dsoundaudio.c3
-rw-r--r--audio/jackaudio.c3
-rw-r--r--audio/meson.build1
-rw-r--r--audio/noaudio.c3
-rw-r--r--audio/ossaudio.c12
-rw-r--r--audio/paaudio.c8
-rw-r--r--audio/pwaudio.c17
-rw-r--r--audio/sdlaudio.c6
-rw-r--r--audio/sndioaudio.c3
-rw-r--r--audio/spiceaudio.c5
-rw-r--r--audio/wavaudio.c3
-rw-r--r--crypto/meson.build3
-rw-r--r--docs/about/deprecated.rst16
-rw-r--r--docs/about/removed-features.rst12
-rw-r--r--gdbstub/meson.build4
-rw-r--r--hw/arm/integratorcp.c11
-rw-r--r--hw/arm/musicpal.c11
-rw-r--r--hw/arm/nseries.c4
-rw-r--r--hw/arm/omap2.c7
-rw-r--r--hw/arm/palm.c2
-rw-r--r--hw/arm/realview.c12
-rw-r--r--hw/arm/spitz.c17
-rw-r--r--hw/arm/versatilepb.c8
-rw-r--r--hw/arm/vexpress.c5
-rw-r--r--hw/arm/xlnx-zcu102.c6
-rw-r--r--hw/arm/z2.c15
-rw-r--r--hw/audio/ac97.c6
-rw-r--r--hw/audio/adlib.c6
-rw-r--r--hw/audio/cs4231a.c6
-rw-r--r--hw/audio/es1370.c5
-rw-r--r--hw/audio/gus.c6
-rw-r--r--hw/audio/hda-codec.c5
-rw-r--r--hw/audio/lm4549.c8
-rw-r--r--hw/audio/pcspk.c4
-rw-r--r--hw/audio/sb16.c6
-rw-r--r--hw/audio/via-ac97.c6
-rw-r--r--hw/audio/wm8750.c5
-rw-r--r--hw/core/machine.c33
-rw-r--r--hw/core/qdev-properties-system.c16
-rw-r--r--hw/display/xlnx_dp.c6
-rw-r--r--hw/input/tsc210x.c7
-rw-r--r--hw/mips/fuloong2e.c15
-rw-r--r--hw/net/e1000.c81
-rw-r--r--hw/nvram/meson.build6
-rw-r--r--hw/pci-host/i440fx.c8
-rw-r--r--hw/pci-host/q35.c7
-rw-r--r--hw/ppc/pegasos2.c12
-rw-r--r--hw/ppc/prep.c7
-rw-r--r--hw/scsi/esp.c5
-rw-r--r--hw/scsi/scsi-disk.c4
-rw-r--r--hw/usb/dev-audio.c5
-rw-r--r--include/hw/boards.h9
-rw-r--r--include/hw/pci-host/q35.h1
-rw-r--r--meson.build14
-rw-r--r--pc-bios/optionrom/Makefile2
-rw-r--r--qemu-options.hx10
-rwxr-xr-xscripts/archive-source.sh2
-rwxr-xr-xscripts/make-release2
-rw-r--r--softmmu/vl.c8
-rw-r--r--tcg/meson.build4
-rw-r--r--tests/Makefile.include2
-rw-r--r--tests/meson.build5
-rw-r--r--tests/plugin/meson.build18
-rw-r--r--ui/dbus.c3
-rw-r--r--ui/vnc.c14
-rw-r--r--ui/vnc.h2
76 files changed, 515 insertions, 958 deletions
diff --git a/accel/kvm/kvm-all.c b/accel/kvm/kvm-all.c
index ff1578bb32..72e1d1141c 100644
--- a/accel/kvm/kvm-all.c
+++ b/accel/kvm/kvm-all.c
@@ -2851,7 +2851,13 @@ bool kvm_cpu_check_are_resettable(void)
static void do_kvm_cpu_synchronize_state(CPUState *cpu, run_on_cpu_data arg)
{
if (!cpu->vcpu_dirty) {
- kvm_arch_get_registers(cpu);
+ int ret = kvm_arch_get_registers(cpu);
+ if (ret) {
+ error_report("Failed to get registers: %s", strerror(-ret));
+ cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
+ vm_stop(RUN_STATE_INTERNAL_ERROR);
+ }
+
cpu->vcpu_dirty = true;
}
}
@@ -2865,7 +2871,13 @@ void kvm_cpu_synchronize_state(CPUState *cpu)
static void do_kvm_cpu_synchronize_post_reset(CPUState *cpu, run_on_cpu_data arg)
{
- kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE);
+ int ret = kvm_arch_put_registers(cpu, KVM_PUT_RESET_STATE);
+ if (ret) {
+ error_report("Failed to put registers after reset: %s", strerror(-ret));
+ cpu_dump_state(cpu, stderr, CPU_DUMP_CODE);
+ vm_stop(RUN_STATE_INTERNAL_ERROR);
+ }
+
cpu->vcpu_dirty = false;
}
@@ -2876,7 +2888,12 @@ void kvm_cpu_synchronize_post_reset(CPUState *cpu)
static void do_kvm_cpu_synchronize_post_init(CPUState *cpu, run_on_cpu_data arg)
{
- kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE);
+ int ret = kvm_arch_put_registers(cpu, KVM_PUT_FULL_STATE);
+ if (ret) {
+ error_report("Failed to put registers after init: %s", strerror(-ret));
+ exit(1);
+ }
+
cpu->vcpu_dirty = false;
}
@@ -2969,7 +2986,14 @@ int kvm_cpu_exec(CPUState *cpu)
MemTxAttrs attrs;
if (cpu->vcpu_dirty) {
- kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE);
+ ret = kvm_arch_put_registers(cpu, KVM_PUT_RUNTIME_STATE);
+ if (ret) {
+ error_report("Failed to put registers after init: %s",
+ strerror(-ret));
+ ret = -1;
+ break;
+ }
+
cpu->vcpu_dirty = false;
}
diff --git a/audio/alsaaudio.c b/audio/alsaaudio.c
index 057571dd1e..cacae1ea59 100644
--- a/audio/alsaaudio.c
+++ b/audio/alsaaudio.c
@@ -904,7 +904,7 @@ static void alsa_init_per_direction(AudiodevAlsaPerDirectionOptions *apdo)
}
}
-static void *alsa_audio_init(Audiodev *dev)
+static void *alsa_audio_init(Audiodev *dev, Error **errp)
{
AudiodevAlsaOptions *aopts;
assert(dev->driver == AUDIODEV_DRIVER_ALSA);
@@ -960,7 +960,6 @@ static struct audio_driver alsa_audio_driver = {
.init = alsa_audio_init,
.fini = alsa_audio_fini,
.pcm_ops = &alsa_pcm_ops,
- .can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof (ALSAVoiceOut),
diff --git a/audio/audio-hmp-cmds.c b/audio/audio-hmp-cmds.c
index 1237ce9e75..c9608b715b 100644
--- a/audio/audio-hmp-cmds.c
+++ b/audio/audio-hmp-cmds.c
@@ -26,6 +26,7 @@
#include "audio/audio.h"
#include "monitor/hmp.h"
#include "monitor/monitor.h"
+#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
static QLIST_HEAD (capture_list_head, CaptureState) capture_head;
@@ -65,10 +66,11 @@ void hmp_wavcapture(Monitor *mon, const QDict *qdict)
int nchannels = qdict_get_try_int(qdict, "nchannels", 2);
const char *audiodev = qdict_get_str(qdict, "audiodev");
CaptureState *s;
- AudioState *as = audio_state_by_name(audiodev);
+ Error *local_err = NULL;
+ AudioState *as = audio_state_by_name(audiodev, &local_err);
if (!as) {
- monitor_printf(mon, "Audiodev '%s' not found\n", audiodev);
+ error_report_err(local_err);
return;
}
diff --git a/audio/audio.c b/audio/audio.c
index 2f47965711..730bf2498d 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -32,7 +32,9 @@
#include "qapi/qobject-input-visitor.h"
#include "qapi/qapi-visit-audio.h"
#include "qapi/qapi-commands-audio.h"
+#include "qapi/qmp/qdict.h"
#include "qemu/cutils.h"
+#include "qemu/error-report.h"
#include "qemu/log.h"
#include "qemu/module.h"
#include "qemu/help_option.h"
@@ -61,19 +63,22 @@ const char *audio_prio_list[] = {
"spice",
CONFIG_AUDIO_DRIVERS
"none",
- "wav",
NULL
};
static QLIST_HEAD(, audio_driver) audio_drivers;
-static AudiodevListHead audiodevs = QSIMPLEQ_HEAD_INITIALIZER(audiodevs);
+static AudiodevListHead audiodevs =
+ QSIMPLEQ_HEAD_INITIALIZER(audiodevs);
+static AudiodevListHead default_audiodevs =
+ QSIMPLEQ_HEAD_INITIALIZER(default_audiodevs);
+
void audio_driver_register(audio_driver *drv)
{
QLIST_INSERT_HEAD(&audio_drivers, drv, next);
}
-audio_driver *audio_driver_lookup(const char *name)
+static audio_driver *audio_driver_lookup(const char *name)
{
struct audio_driver *d;
Error *local_err = NULL;
@@ -111,8 +116,6 @@ const struct mixeng_volume nominal_volume = {
#endif
};
-static bool legacy_config = true;
-
int audio_bug (const char *funcname, int cond)
{
if (cond) {
@@ -1553,9 +1556,11 @@ size_t audio_generic_read(HWVoiceIn *hw, void *buf, size_t size)
}
static int audio_driver_init(AudioState *s, struct audio_driver *drv,
- bool msg, Audiodev *dev)
+ Audiodev *dev, Error **errp)
{
- s->drv_opaque = drv->init(dev);
+ Error *local_err = NULL;
+
+ s->drv_opaque = drv->init(dev, &local_err);
if (s->drv_opaque) {
if (!drv->pcm_ops->get_buffer_in) {
@@ -1567,13 +1572,15 @@ static int audio_driver_init(AudioState *s, struct audio_driver *drv,
drv->pcm_ops->put_buffer_out = audio_generic_put_buffer_out;
}
- audio_init_nb_voices_out(s, drv);
- audio_init_nb_voices_in(s, drv);
+ audio_init_nb_voices_out(s, drv, 1);
+ audio_init_nb_voices_in(s, drv, 0);
s->drv = drv;
return 0;
} else {
- if (msg) {
- dolog("Could not init `%s' audio driver\n", drv->name);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ } else {
+ error_setg(errp, "Could not init `%s' audio driver", drv->name);
}
return -1;
}
@@ -1681,17 +1688,45 @@ static const VMStateDescription vmstate_audio = {
static void audio_validate_opts(Audiodev *dev, Error **errp);
-static AudiodevListEntry *audiodev_find(
- AudiodevListHead *head, const char *drvname)
+static void audio_create_default_audiodevs(void)
{
- AudiodevListEntry *e;
- QSIMPLEQ_FOREACH(e, head, next) {
- if (strcmp(AudiodevDriver_str(e->dev->driver), drvname) == 0) {
- return e;
- }
+ const char *drvname = getenv("QEMU_AUDIO_DRV");
+
+ if (!defaults_enabled()) {
+ return;
}
- return NULL;
+ /* QEMU_AUDIO_DRV=none is used by libqtest. */
+ if (drvname && !g_str_equal(drvname, "none")) {
+ error_report("Please use -audiodev instead of QEMU_AUDIO_*");
+ exit(1);
+ }
+
+ for (int i = 0; audio_prio_list[i]; i++) {
+ if (drvname && !g_str_equal(drvname, audio_prio_list[i])) {
+ continue;
+ }
+
+ if (audio_driver_lookup(audio_prio_list[i])) {
+ QDict *dict = qdict_new();
+ Audiodev *dev = NULL;
+ AudiodevListEntry *e;
+ Visitor *v;
+
+ qdict_put_str(dict, "driver", audio_prio_list[i]);
+ qdict_put_str(dict, "id", "#default");
+
+ v = qobject_input_visitor_new_keyval(QOBJECT(dict));
+ qobject_unref(dict);
+ visit_type_Audiodev(v, NULL, &dev, &error_fatal);
+ visit_free(v);
+
+ audio_validate_opts(dev, &error_abort);
+ e = g_new0(AudiodevListEntry, 1);
+ e->dev = dev;
+ QSIMPLEQ_INSERT_TAIL(&default_audiodevs, e, next);
+ }
+ }
}
/*
@@ -1700,62 +1735,16 @@ static AudiodevListEntry *audiodev_find(
* if dev == NULL => legacy implicit initialization, return the already created
* state or create a new one
*/
-static AudioState *audio_init(Audiodev *dev, const char *name)
+static AudioState *audio_init(Audiodev *dev, Error **errp)
{
static bool atexit_registered;
- size_t i;
int done = 0;
- const char *drvname = NULL;
+ const char *drvname;
VMChangeStateEntry *vmse;
AudioState *s;
struct audio_driver *driver;
- /* silence gcc warning about uninitialized variable */
- AudiodevListHead head = QSIMPLEQ_HEAD_INITIALIZER(head);
-
- if (using_spice) {
- /*
- * When using spice allow the spice audio driver being picked
- * as default.
- *
- * Temporary hack. Using audio devices without explicit
- * audiodev= property is already deprecated. Same goes for
- * the -soundhw switch. Once this support gets finally
- * removed we can also drop the concept of a default audio
- * backend and this can go away.
- */
- driver = audio_driver_lookup("spice");
- if (driver) {
- driver->can_be_default = 1;
- }
- }
-
- if (dev) {
- /* -audiodev option */
- legacy_config = false;
- drvname = AudiodevDriver_str(dev->driver);
- } else if (!QTAILQ_EMPTY(&audio_states)) {
- if (!legacy_config) {
- dolog("Device %s: audiodev default parameter is deprecated, please "
- "specify audiodev=%s\n", name,
- QTAILQ_FIRST(&audio_states)->dev->id);
- }
- return QTAILQ_FIRST(&audio_states);
- } else {
- /* legacy implicit initialization */
- head = audio_handle_legacy_opts();
- /*
- * In case of legacy initialization, all Audiodevs in the list will have
- * the same configuration (except the driver), so it doesn't matter which
- * one we chose. We need an Audiodev to set up AudioState before we can
- * init a driver. Also note that dev at this point is still in the
- * list.
- */
- dev = QSIMPLEQ_FIRST(&head)->dev;
- audio_validate_opts(dev, &error_abort);
- }
s = g_new0(AudioState, 1);
- s->dev = dev;
QLIST_INIT (&s->hw_head_out);
QLIST_INIT (&s->hw_head_in);
@@ -1767,56 +1756,35 @@ static AudioState *audio_init(Audiodev *dev, const char *name)
s->ts = timer_new_ns(QEMU_CLOCK_VIRTUAL, audio_timer, s);
- s->nb_hw_voices_out = audio_get_pdo_out(dev)->voices;
- s->nb_hw_voices_in = audio_get_pdo_in(dev)->voices;
-
- if (s->nb_hw_voices_out < 1) {
- dolog ("Bogus number of playback voices %d, setting to 1\n",
- s->nb_hw_voices_out);
- s->nb_hw_voices_out = 1;
- }
-
- if (s->nb_hw_voices_in < 0) {
- dolog ("Bogus number of capture voices %d, setting to 0\n",
- s->nb_hw_voices_in);
- s->nb_hw_voices_in = 0;
- }
-
- if (drvname) {
+ if (dev) {
+ /* -audiodev option */
+ s->dev = dev;
+ drvname = AudiodevDriver_str(dev->driver);
driver = audio_driver_lookup(drvname);
if (driver) {
- done = !audio_driver_init(s, driver, true, dev);
+ done = !audio_driver_init(s, driver, dev, errp);
} else {
- dolog ("Unknown audio driver `%s'\n", drvname);
+ error_setg(errp, "Unknown audio driver `%s'\n", drvname);
}
if (!done) {
- free_audio_state(s);
- return NULL;
+ goto out;
}
} else {
- for (i = 0; audio_prio_list[i]; i++) {
- AudiodevListEntry *e = audiodev_find(&head, audio_prio_list[i]);
- driver = audio_driver_lookup(audio_prio_list[i]);
-
- if (e && driver) {
- s->dev = dev = e->dev;
- audio_validate_opts(dev, &error_abort);
- done = !audio_driver_init(s, driver, false, dev);
- if (done) {
- e->dev = NULL;
- break;
- }
+ for (;;) {
+ AudiodevListEntry *e = QSIMPLEQ_FIRST(&default_audiodevs);
+ if (!e) {
+ error_setg(errp, "no default audio driver available");
+ goto out;
+ }
+ s->dev = dev = e->dev;
+ drvname = AudiodevDriver_str(dev->driver);
+ driver = audio_driver_lookup(drvname);
+ if (!audio_driver_init(s, driver, dev, NULL)) {
+ break;
}
+ QSIMPLEQ_REMOVE_HEAD(&default_audiodevs, next);
}
}
- audio_free_audiodev_list(&head);
-
- if (!done) {
- driver = audio_driver_lookup("none");
- done = !audio_driver_init(s, driver, false, dev);
- assert(done);
- dolog("warning: Using timer based audio emulation\n");
- }
if (dev->timer_period <= 0) {
s->period_ticks = 1;
@@ -1834,27 +1802,50 @@ static AudioState *audio_init(Audiodev *dev, const char *name)
QLIST_INIT (&s->card_head);
vmstate_register (NULL, 0, &vmstate_audio, s);
return s;
-}
-void audio_free_audiodev_list(AudiodevListHead *head)
-{
- AudiodevListEntry *e;
- while ((e = QSIMPLEQ_FIRST(head))) {
- QSIMPLEQ_REMOVE_HEAD(head, next);
- qapi_free_Audiodev(e->dev);
- g_free(e);
- }
+out:
+ free_audio_state(s);
+ return NULL;
}
-void AUD_register_card (const char *name, QEMUSoundCard *card)
+bool AUD_register_card (const char *name, QEMUSoundCard *card, Error **errp)
{
if (!card->state) {
- card->state = audio_init(NULL, name);
+ if (!QTAILQ_EMPTY(&audio_states)) {
+ /*
+ * FIXME: once it is possible to create an arbitrary
+ * default device via -audio DRIVER,OPT=VALUE (no "model"),
+ * replace this special case with the default AudioState*,
+ * storing it in a separate global. For now, keep the
+ * warning to encourage moving off magic use of the first
+ * -audiodev.
+ */
+ if (QSIMPLEQ_EMPTY(&default_audiodevs)) {
+ dolog("Device %s: audiodev default parameter is deprecated, please "
+ "specify audiodev=%s\n", name,
+ QTAILQ_FIRST(&audio_states)->dev->id);
+ }
+ card->state = QTAILQ_FIRST(&audio_states);
+ } else {
+ if (QSIMPLEQ_EMPTY(&default_audiodevs)) {
+ audio_create_default_audiodevs();
+ }
+ card->state = audio_init(NULL, errp);
+ if (!card->state) {
+ if (!QSIMPLEQ_EMPTY(&audiodevs)) {
+ error_append_hint(errp, "Perhaps you wanted to set audiodev=%s?",
+ QSIMPLEQ_FIRST(&audiodevs)->dev->id);
+ }
+ return false;
+ }
+ }
}
card->name = g_strdup (name);
memset (&card->entries, 0, sizeof (card->entries));
QLIST_INSERT_HEAD(&card->state->card_head, card, entries);
+
+ return true;
}
void AUD_remove_card (QEMUSoundCard *card)
@@ -1876,10 +1867,8 @@ CaptureVoiceOut *AUD_add_capture(
struct capture_callback *cb;
if (!s) {
- if (!legacy_config) {
- dolog("Capturing without setting an audiodev is deprecated\n");
- }
- s = audio_init(NULL, NULL);
+ error_report("Capturing without setting an audiodev is not supported");
+ abort();
}
if (!audio_get_pdo_out(s->dev)->mixing_engine) {
@@ -2183,17 +2172,13 @@ void audio_define(Audiodev *dev)
QSIMPLEQ_INSERT_TAIL(&audiodevs, e, next);
}
-bool audio_init_audiodevs(void)
+void audio_init_audiodevs(void)
{
AudiodevListEntry *e;
QSIMPLEQ_FOREACH(e, &audiodevs, next) {
- if (!audio_init(e->dev, NULL)) {
- return false;
- }
+ audio_init(e->dev, &error_fatal);
}
-
- return true;
}
audsettings audiodev_to_audsettings(AudiodevPerDirectionOptions *pdo)
@@ -2255,7 +2240,7 @@ int audio_buffer_bytes(AudiodevPerDirectionOptions *pdo,
audioformat_bytes_per_sample(as->fmt);
}
-AudioState *audio_state_by_name(const char *name)
+AudioState *audio_state_by_name(const char *name, Error **errp)
{
AudioState *s;
QTAILQ_FOREACH(s, &audio_states, list) {
@@ -2264,6 +2249,7 @@ AudioState *audio_state_by_name(const char *name)
return s;
}
}
+ error_setg(errp, "audiodev '%s' not found", name);
return NULL;
}
diff --git a/audio/audio.h b/audio/audio.h
index 01bdc567fb..80f3f92124 100644
--- a/audio/audio.h
+++ b/audio/audio.h
@@ -94,7 +94,7 @@ typedef struct QEMUAudioTimeStamp {
void AUD_vlog (const char *cap, const char *fmt, va_list ap) G_GNUC_PRINTF(2, 0);
void AUD_log (const char *cap, const char *fmt, ...) G_GNUC_PRINTF(2, 3);
-void AUD_register_card (const char *name, QEMUSoundCard *card);
+bool AUD_register_card (const char *name, QEMUSoundCard *card, Error **errp);
void AUD_remove_card (QEMUSoundCard *card);
CaptureVoiceOut *AUD_add_capture(
AudioState *s,
@@ -170,11 +170,10 @@ void audio_sample_from_uint64(void *samples, int pos,
void audio_define(Audiodev *audio);
void audio_parse_option(const char *opt);
-bool audio_init_audiodevs(void);
+void audio_init_audiodevs(void);
void audio_help(void);
-void audio_legacy_help(void);
-AudioState *audio_state_by_name(const char *name);
+AudioState *audio_state_by_name(const char *name, Error **errp);
const char *audio_get_id(QEMUSoundCard *card);
#define DEFINE_AUDIO_PROPERTIES(_s, _f) \
diff --git a/audio/audio_int.h b/audio/audio_int.h
index e57ff50155..2d079d00a2 100644
--- a/audio/audio_int.h
+++ b/audio/audio_int.h
@@ -140,13 +140,12 @@ typedef struct audio_driver audio_driver;
struct audio_driver {
const char *name;
const char *descr;
- void *(*init) (Audiodev *);
+ void *(*init) (Audiodev *, Error **);
void (*fini) (void *);
#ifdef CONFIG_GIO
void (*set_dbus_server) (AudioState *s, GDBusObjectManagerServer *manager, bool p2p);
#endif
struct audio_pcm_ops *pcm_ops;
- int can_be_default;
int max_voices_out;
int max_voices_in;
size_t voice_size_out;
@@ -243,7 +242,6 @@ extern const struct mixeng_volume nominal_volume;
extern const char *audio_prio_list[];
void audio_driver_register(audio_driver *drv);
-audio_driver *audio_driver_lookup(const char *name);
void audio_pcm_init_info (struct audio_pcm_info *info, struct audsettings *as);
void audio_pcm_info_clear_buf (struct audio_pcm_info *info, void *buf, int len);
@@ -297,9 +295,6 @@ typedef struct AudiodevListEntry {
} AudiodevListEntry;
typedef QSIMPLEQ_HEAD(, AudiodevListEntry) AudiodevListHead;
-AudiodevListHead audio_handle_legacy_opts(void);
-
-void audio_free_audiodev_list(AudiodevListHead *head);
void audio_create_pdos(Audiodev *dev);
AudiodevPerDirectionOptions *audio_get_pdo_in(Audiodev *dev);
diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c
deleted file mode 100644
index dc72ba55e9..0000000000
--- a/audio/audio_legacy.c
+++ /dev/null
@@ -1,591 +0,0 @@
-/*
- * QEMU Audio subsystem: legacy configuration handling
- *
- * Copyright (c) 2015-2019 Zoltán Kővágó <DirtY.iCE.hu@gmail.com>
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-#include "qemu/osdep.h"
-#include "audio.h"
-#include "audio_int.h"
-#include "qemu/cutils.h"
-#include "qemu/timer.h"
-#include "qapi/error.h"
-#include "qapi/qapi-visit-audio.h"
-#include "qapi/visitor-impl.h"
-
-#define AUDIO_CAP "audio-legacy"
-#include "audio_int.h"
-
-static uint32_t toui32(const char *str)
-{
- uint64_t ret;
- if (parse_uint_full(str, 10, &ret) || ret > UINT32_MAX) {
- dolog("Invalid integer value `%s'\n", str);
- exit(1);
- }
- return ret;
-}
-
-/* helper functions to convert env variables */
-static void get_bool(const char *env, bool *dst, bool *has_dst)
-{
- const char *val = getenv(env);
- if (val) {
- *dst = toui32(val) != 0;
- *has_dst = true;
- }
-}
-
-static void get_int(const char *env, uint32_t *dst, bool *has_dst)
-{
- const char *val = getenv(env);
- if (val) {
- *dst = toui32(val);
- *has_dst = true;
- }
-}
-
-static void get_str(const char *env, char **dst)
-{
- const char *val = getenv(env);
- if (val) {
- g_free(*dst);
- *dst = g_strdup(val);
- }
-}
-
-static void get_fmt(const char *env, AudioFormat *dst, bool *has_dst)
-{
- const char *val = getenv(env);
- if (val) {
- size_t i;
- for (i = 0; AudioFormat_lookup.size; ++i) {
- if (strcasecmp(val, AudioFormat_lookup.array[i]) == 0) {
- *dst = i;
- *has_dst = true;
- return;
- }
- }
-
- dolog("Invalid audio format `%s'\n", val);
- exit(1);
- }
-}
-
-
-#if defined(CONFIG_AUDIO_ALSA) || defined(CONFIG_AUDIO_DSOUND)
-static void get_millis_to_usecs(const char *env, uint32_t *dst, bool *has_dst)
-{
- const char *val = getenv(env);
- if (val) {
- *dst = toui32(val) * 1000;
- *has_dst = true;
- }
-}
-#endif
-
-#if defined(CONFIG_AUDIO_ALSA) || defined(CONFIG_AUDIO_COREAUDIO) || \
- defined(CONFIG_AUDIO_PA) || defined(CONFIG_AUDIO_SDL) || \
- defined(CONFIG_AUDIO_DSOUND) || defined(CONFIG_AUDIO_OSS)
-static uint32_t frames_to_usecs(uint32_t frames,
- AudiodevPerDirectionOptions *pdo)
-{
- uint32_t freq = pdo->has_frequency ? pdo->frequency : 44100;
- return (frames * 1000000 + freq / 2) / freq;
-}
-#endif
-
-#ifdef CONFIG_AUDIO_COREAUDIO
-static void get_frames_to_usecs(const char *env, uint32_t *dst, bool *has_dst,
- AudiodevPerDirectionOptions *pdo)
-{
- const char *val = getenv(env);
- if (val) {
- *dst = frames_to_usecs(toui32(val), pdo);
- *has_dst = true;
- }
-}
-#endif
-
-#if defined(CONFIG_AUDIO_PA) || defined(CONFIG_AUDIO_SDL) || \
- defined(CONFIG_AUDIO_DSOUND) || defined(CONFIG_AUDIO_OSS)
-static uint32_t samples_to_usecs(uint32_t samples,
- AudiodevPerDirectionOptions *pdo)
-{
- uint32_t channels = pdo->has_channels ? pdo->channels : 2;
- return frames_to_usecs(samples / channels, pdo);
-}
-#endif
-
-#if defined(CONFIG_AUDIO_PA) || defined(CONFIG_AUDIO_SDL)
-static void get_samples_to_usecs(const char *env, uint32_t *dst, bool *has_dst,
- AudiodevPerDirectionOptions *pdo)
-{
- const char *val = getenv(env);
- if (val) {
- *dst = samples_to_usecs(toui32(val), pdo);
- *has_dst = true;
- }
-}
-#endif
-
-#if defined(CONFIG_AUDIO_DSOUND) || defined(CONFIG_AUDIO_OSS)
-static uint32_t bytes_to_usecs(uint32_t bytes, AudiodevPerDirectionOptions *pdo)
-{
- AudioFormat fmt = pdo->has_format ? pdo->format : AUDIO_FORMAT_S16;
- uint32_t bytes_per_sample = audioformat_bytes_per_sample(fmt);
- return samples_to_usecs(bytes / bytes_per_sample, pdo);
-}
-
-static void get_bytes_to_usecs(const char *env, uint32_t *dst, bool *has_dst,
- AudiodevPerDirectionOptions *pdo)
-{
- const char *val = getenv(env);
- if (val) {
- *dst = bytes_to_usecs(toui32(val), pdo);
- *has_dst = true;
- }
-}
-#endif
-
-/* backend specific functions */
-
-#ifdef CONFIG_AUDIO_ALSA
-/* ALSA */
-static void handle_alsa_per_direction(
- AudiodevAlsaPerDirectionOptions *apdo, const char *prefix)
-{
- char buf[64];
- size_t len = strlen(prefix);
- bool size_in_usecs = false;
- bool dummy;
-
- memcpy(buf, prefix, len);
- strcpy(buf + len, "TRY_POLL");
- get_bool(buf, &apdo->try_poll, &apdo->has_try_poll);
-
- strcpy(buf + len, "DEV");
- get_str(buf, &apdo->dev);
-
- strcpy(buf + len, "SIZE_IN_USEC");
- get_bool(buf, &size_in_usecs, &dummy);
-
- strcpy(buf + len, "PERIOD_SIZE");
- get_int(buf, &apdo->period_length, &apdo->has_period_length);
- if (apdo->has_period_length && !size_in_usecs) {
- apdo->period_length = frames_to_usecs(
- apdo->period_length,
- qapi_AudiodevAlsaPerDirectionOptions_base(apdo));
- }
-
- strcpy(buf + len, "BUFFER_SIZE");
- get_int(buf, &apdo->buffer_length, &apdo->has_buffer_length);
- if (apdo->has_buffer_length && !size_in_usecs) {
- apdo->buffer_length = frames_to_usecs(
- apdo->buffer_length,
- qapi_AudiodevAlsaPerDirectionOptions_base(apdo));
- }
-}
-
-static void handle_alsa(Audiodev *dev)
-{
- AudiodevAlsaOptions *aopt = &dev->u.alsa;
- handle_alsa_per_direction(aopt->in, "QEMU_ALSA_ADC_");
- handle_alsa_per_direction(aopt->out, "QEMU_ALSA_DAC_");
-
- get_millis_to_usecs("QEMU_ALSA_THRESHOLD",
- &aopt->threshold, &aopt->has_threshold);
-}
-#endif
-
-#ifdef CONFIG_AUDIO_COREAUDIO
-/* coreaudio */
-static void handle_coreaudio(Audiodev *dev)
-{
- get_frames_to_usecs(
- "QEMU_COREAUDIO_BUFFER_SIZE",
- &dev->u.coreaudio.out->buffer_length,
- &dev->u.coreaudio.out->has_buffer_length,
- qapi_AudiodevCoreaudioPerDirectionOptions_base(dev->u.coreaudio.out));
- get_int("QEMU_COREAUDIO_BUFFER_COUNT",
- &dev->u.coreaudio.out->buffer_count,
- &dev->u.coreaudio.out->has_buffer_count);
-}
-#endif
-
-#ifdef CONFIG_AUDIO_DSOUND
-/* dsound */
-static void handle_dsound(Audiodev *dev)
-{
- get_millis_to_usecs("QEMU_DSOUND_LATENCY_MILLIS",
- &dev->u.dsound.latency, &dev->u.dsound.has_latency);
- get_bytes_to_usecs("QEMU_DSOUND_BUFSIZE_OUT",
- &dev->u.dsound.out->buffer_length,
- &dev->u.dsound.out->has_buffer_length,
- dev->u.dsound.out);
- get_bytes_to_usecs("QEMU_DSOUND_BUFSIZE_IN",
- &dev->u.dsound.in->buffer_length,
- &dev->u.dsound.in->has_buffer_length,
- dev->u.dsound.in);
-}
-#endif
-
-#ifdef CONFIG_AUDIO_OSS
-/* OSS */
-static void handle_oss_per_direction(
- AudiodevOssPerDirectionOptions *opdo, const char *try_poll_env,
- const char *dev_env)
-{
- get_bool(try_poll_env, &opdo->try_poll, &opdo->has_try_poll);
- get_str(dev_env, &opdo->dev);
-
- get_bytes_to_usecs("QEMU_OSS_FRAGSIZE",
- &opdo->buffer_length, &opdo->has_buffer_length,
- qapi_AudiodevOssPerDirectionOptions_base(opdo));
- get_int("QEMU_OSS_NFRAGS", &opdo->buffer_count,
- &opdo->has_buffer_count);
-}
-
-static void handle_oss(Audiodev *dev)
-{
- AudiodevOssOptions *oopt = &dev->u.oss;
- handle_oss_per_direction(oopt->in, "QEMU_AUDIO_ADC_TRY_POLL",
- "QEMU_OSS_ADC_DEV");
- handle_oss_per_direction(oopt->out, "QEMU_AUDIO_DAC_TRY_POLL",
- "QEMU_OSS_DAC_DEV");
-
- get_bool("QEMU_OSS_MMAP", &oopt->try_mmap, &oopt->has_try_mmap);
- get_bool("QEMU_OSS_EXCLUSIVE", &oopt->exclusive, &oopt->has_exclusive);
- get_int("QEMU_OSS_POLICY", &oopt->dsp_policy, &oopt->has_dsp_policy);
-}
-#endif
-
-#ifdef CONFIG_AUDIO_PA
-/* pulseaudio */
-static void handle_pa_per_direction(
- AudiodevPaPerDirectionOptions *ppdo, const char *env)
-{
- get_str(env, &ppdo->name);
-}
-
-static void handle_pa(Audiodev *dev)
-{
- handle_pa_per_direction(dev->u.pa.in, "QEMU_PA_SOURCE");
- handle_pa_per_direction(dev->u.pa.out, "QEMU_PA_SINK");
-
- get_samples_to_usecs(
- "QEMU_PA_SAMPLES", &dev->u.pa.in->buffer_length,
- &dev->u.pa.in->has_buffer_length,
- qapi_AudiodevPaPerDirectionOptions_base(dev->u.pa.in));
- get_samples_to_usecs(
- "QEMU_PA_SAMPLES", &dev->u.pa.out->buffer_length,
- &dev->u.pa.out->has_buffer_length,
- qapi_AudiodevPaPerDirectionOptions_base(dev->u.pa.out));
-
- get_str("QEMU_PA_SERVER", &dev->u.pa.server);
-}
-#endif
-
-#ifdef CONFIG_AUDIO_SDL
-/* SDL */
-static void handle_sdl(Audiodev *dev)
-{
- /* SDL is output only */
- get_samples_to_usecs("QEMU_SDL_SAMPLES", &dev->u.sdl.out->buffer_length,
- &dev->u.sdl.out->has_buffer_length,
- qapi_AudiodevSdlPerDirectionOptions_base(dev->u.sdl.out));
-}
-#endif
-
-/* wav */
-static void handle_wav(Audiodev *dev)
-{
- get_int("QEMU_WAV_FREQUENCY",
- &dev->u.wav.out->frequency, &dev->u.wav.out->has_frequency);
- get_fmt("QEMU_WAV_FORMAT", &dev->u.wav.out->format,
- &dev->u.wav.out->has_format);
- get_int("QEMU_WAV_DAC_FIXED_CHANNELS",
- &dev->u.wav.out->channels, &dev->u.wav.out->has_channels);
- get_str("QEMU_WAV_PATH", &dev->u.wav.path);
-}
-
-/* general */
-static void handle_per_direction(
- AudiodevPerDirectionOptions *pdo, const char *prefix)
-{
- char buf[64];
- size_t len = strlen(prefix);
-
- memcpy(buf, prefix, len);
- strcpy(buf + len, "FIXED_SETTINGS");
- get_bool(buf, &pdo->fixed_settings, &pdo->has_fixed_settings);
-
- strcpy(buf + len, "FIXED_FREQ");
- get_int(buf, &pdo->frequency, &pdo->has_frequency);
-
- strcpy(buf + len, "FIXED_FMT");
- get_fmt(buf, &pdo->format, &pdo->has_format);
-
- strcpy(buf + len, "FIXED_CHANNELS");
- get_int(buf, &pdo->channels, &pdo->has_channels);
-
- strcpy(buf + len, "VOICES");
- get_int(buf, &pdo->voices, &pdo->has_voices);
-}
-
-static AudiodevListEntry *legacy_opt(const char *drvname)
-{
- AudiodevListEntry *e = g_new0(AudiodevListEntry, 1);
- e->dev = g_new0(Audiodev, 1);
- e->dev->id = g_strdup(drvname);
- e->dev->driver = qapi_enum_parse(
- &AudiodevDriver_lookup, drvname, -1, &error_abort);
-
- audio_create_pdos(e->dev);
-
- handle_per_direction(audio_get_pdo_in(e->dev), "QEMU_AUDIO_ADC_");
- handle_per_direction(audio_get_pdo_out(e->dev), "QEMU_AUDIO_DAC_");
-
- /* Original description: Timer period in HZ (0 - use lowest possible) */
- get_int("QEMU_AUDIO_TIMER_PERIOD",
- &e->dev->timer_period, &e->dev->has_timer_period);
- if (e->dev->has_timer_period && e->dev->timer_period) {
- e->dev->timer_period = NANOSECONDS_PER_SECOND / 1000 /
- e->dev->timer_period;
- }
-
- switch (e->dev->driver) {
-#ifdef CONFIG_AUDIO_ALSA
- case AUDIODEV_DRIVER_ALSA:
- handle_alsa(e->dev);
- break;
-#endif
-
-#ifdef CONFIG_AUDIO_COREAUDIO
- case AUDIODEV_DRIVER_COREAUDIO:
- handle_coreaudio(e->dev);
- break;
-#endif
-
-#ifdef CONFIG_AUDIO_DSOUND
- case AUDIODEV_DRIVER_DSOUND:
- handle_dsound(e->dev);
- break;
-#endif
-
-#ifdef CONFIG_AUDIO_OSS
- case AUDIODEV_DRIVER_OSS:
- handle_oss(e->dev);
- break;
-#endif
-
-#ifdef CONFIG_AUDIO_PA
- case AUDIODEV_DRIVER_PA:
- handle_pa(e->dev);
- break;
-#endif
-
-#ifdef CONFIG_AUDIO_SDL
- case AUDIODEV_DRIVER_SDL:
- handle_sdl(e->dev);
- break;
-#endif
-
- case AUDIODEV_DRIVER_WAV:
- handle_wav(e->dev);
- break;
-
- default:
- break;
- }
-
- return e;
-}
-
-AudiodevListHead audio_handle_legacy_opts(void)
-{
- const char *drvname = getenv("QEMU_AUDIO_DRV");
- AudiodevListHead head = QSIMPLEQ_HEAD_INITIALIZER(head);
-
- if (drvname) {
- AudiodevListEntry *e;
- audio_driver *driver = audio_driver_lookup(drvname);
- if (!driver) {
- dolog("Unknown audio driver `%s'\n", drvname);
- exit(1);
- }
- e = legacy_opt(drvname);
- QSIMPLEQ_INSERT_TAIL(&head, e, next);
- } else {
- for (int i = 0; audio_prio_list[i]; i++) {
- audio_driver *driver = audio_driver_lookup(audio_prio_list[i]);
- if (driver && driver->can_be_default) {
- AudiodevListEntry *e = legacy_opt(driver->name);
- QSIMPLEQ_INSERT_TAIL(&head, e, next);
- }
- }
- if (QSIMPLEQ_EMPTY(&head)) {
- dolog("Internal error: no default audio driver available\n");
- exit(1);
- }
- }
-
- return head;
-}
-
-/* visitor to print -audiodev option */
-typedef struct {
- Visitor visitor;
-
- bool comma;
- GList *path;
-} LegacyPrintVisitor;
-
-static bool lv_start_struct(Visitor *v, const char *name, void **obj,
- size_t size, Error **errp)
-{
- LegacyPrintVisitor *lv = (LegacyPrintVisitor *) v;
- lv->path = g_list_append(lv->path, g_strdup(name));
- return true;
-}
-
-static void lv_end_struct(Visitor *v, void **obj)
-{
- LegacyPrintVisitor *lv = (LegacyPrintVisitor *) v;
- lv->path = g_list_delete_link(lv->path, g_list_last(lv->path));
-}
-
-static void lv_print_key(Visitor *v, const char *name)
-{
- GList *e;
- LegacyPrintVisitor *lv = (LegacyPrintVisitor *) v;
- if (lv->comma) {
- putchar(',');
- } else {
- lv->comma = true;
- }
-
- for (e = lv->path; e; e = e->next) {
- if (e->data) {
- printf("%s.", (const char *) e->data);
- }
- }
-
- printf("%s=", name);
-}
-
-static bool lv_type_int64(Visitor *v, const char *name, int64_t *obj,
- Error **errp)
-{
- lv_print_key(v, name);
- printf("%" PRIi64, *obj);
- return true;
-}
-
-static bool lv_type_uint64(Visitor *v, const char *name, uint64_t *obj,
- Error **errp)
-{
- lv_print_key(v, name);
- printf("%" PRIu64, *obj);
- return true;
-}
-
-static bool lv_type_bool(Visitor *v, const char *name, bool *obj, Error **errp)
-{
- lv_print_key(v, name);
- printf("%s", *obj ? "on" : "off");
- return true;
-}
-
-static bool lv_type_str(Visitor *v, const char *name, char **obj, Error **errp)
-{
- const char *str = *obj;
- lv_print_key(v, name);
-
- while (*str) {
- if (*str == ',') {
- putchar(',');
- }
- putchar(*str++);
- }
- return true;
-}
-
-static void lv_complete(Visitor *v, void *opaque)
-{
- LegacyPrintVisitor *lv = (LegacyPrintVisitor *) v;
- assert(lv->path == NULL);
-}
-
-static void lv_free(Visitor *v)
-{
- LegacyPrintVisitor *lv = (LegacyPrintVisitor *) v;
-
- g_list_free_full(lv->path, g_free);
- g_free(lv);
-}
-
-static Visitor *legacy_visitor_new(void)
-{
- LegacyPrintVisitor *lv = g_new0(LegacyPrintVisitor, 1);
-
- lv->visitor.start_struct = lv_start_struct;
- lv->visitor.end_struct = lv_end_struct;
- /* lists not supported */
- lv->visitor.type_int64 = lv_type_int64;
- lv->visitor.type_uint64 = lv_type_uint64;
- lv->visitor.type_bool = lv_type_bool;
- lv->visitor.type_str = lv_type_str;
-
- lv->visitor.type = VISITOR_OUTPUT;
- lv->visitor.complete = lv_complete;
- lv->visitor.free = lv_free;
-
- return &lv->visitor;
-}
-
-void audio_legacy_help(void)
-{
- AudiodevListHead head;
- AudiodevListEntry *e;
-
- printf("Environment variable based configuration deprecated.\n");
- printf("Please use the new -audiodev option.\n");
-
- head = audio_handle_legacy_opts();
- printf("\nEquivalent -audiodev to your current environment variables:\n");
- if (!getenv("QEMU_AUDIO_DRV")) {
- printf("(Since you didn't specify QEMU_AUDIO_DRV, I'll list all "
- "possibilities)\n");
- }
-
- QSIMPLEQ_FOREACH(e, &head, next) {
- Visitor *v;
- Audiodev *dev = e->dev;
- printf("-audiodev ");
-
- v = legacy_visitor_new();
- visit_type_Audiodev(v, NULL, &dev, &error_abort);
- visit_free(v);
-
- printf("\n");
- }
- audio_free_audiodev_list(&head);
-}
diff --git a/audio/audio_template.h b/audio/audio_template.h
index dc0c74aa74..7ccfec0116 100644
--- a/audio/audio_template.h
+++ b/audio/audio_template.h
@@ -37,11 +37,12 @@
#endif
static void glue(audio_init_nb_voices_, TYPE)(AudioState *s,
- struct audio_driver *drv)
+ struct audio_driver *drv, int min_voices)
{
int max_voices = glue (drv->max_voices_, TYPE);
size_t voice_size = glue(drv->voice_size_, TYPE);
+ glue (s->nb_hw_voices_, TYPE) = glue(audio_get_pdo_, TYPE)(s->dev)->voices;
if (glue (s->nb_hw_voices_, TYPE) > max_voices) {
if (!max_voices) {
#ifdef DAC
@@ -56,6 +57,12 @@ static void glue(audio_init_nb_voices_, TYPE)(AudioState *s,
glue (s->nb_hw_voices_, TYPE) = max_voices;
}
+ if (glue (s->nb_hw_voices_, TYPE) < min_voices) {
+ dolog ("Bogus number of " NAME " voices %d, setting to %d\n",
+ glue (s->nb_hw_voices_, TYPE),
+ min_voices);
+ }
+
if (audio_bug(__func__, !voice_size && max_voices)) {
dolog ("drv=`%s' voice_size=0 max_voices=%d\n",
drv->name, max_voices);
diff --git a/audio/coreaudio.m b/audio/coreaudio.m
index 4695291621..8cd129a27d 100644
--- a/audio/coreaudio.m
+++ b/audio/coreaudio.m
@@ -644,7 +644,7 @@ static void coreaudio_enable_out(HWVoiceOut *hw, bool enable)
update_device_playback_state(core);
}
-static void *coreaudio_audio_init(Audiodev *dev)
+static void *coreaudio_audio_init(Audiodev *dev, Error **errp)
{
return dev;
}
@@ -673,7 +673,6 @@ static struct audio_driver coreaudio_audio_driver = {
.init = coreaudio_audio_init,
.fini = coreaudio_audio_fini,
.pcm_ops = &coreaudio_pcm_ops,
- .can_be_default = 1,
.max_voices_out = 1,
.max_voices_in = 0,
.voice_size_out = sizeof (coreaudioVoiceOut),
diff --git a/audio/dbusaudio.c b/audio/dbusaudio.c
index 7a11fbfb42..60fcf643ec 100644
--- a/audio/dbusaudio.c
+++ b/audio/dbusaudio.c
@@ -395,7 +395,7 @@ dbus_enable_in(HWVoiceIn *hw, bool enable)
}
static void *
-dbus_audio_init(Audiodev *dev)
+dbus_audio_init(Audiodev *dev, Error **errp)
{
DBusAudio *da = g_new0(DBusAudio, 1);
@@ -676,7 +676,6 @@ static struct audio_driver dbus_audio_driver = {
.fini = dbus_audio_fini,
.set_dbus_server = dbus_audio_set_server,
.pcm_ops = &dbus_pcm_ops,
- .can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof(DBusVoiceOut),
diff --git a/audio/dsoundaudio.c b/audio/dsoundaudio.c
index 3fb67ec3ee..f3bb48d007 100644
--- a/audio/dsoundaudio.c
+++ b/audio/dsoundaudio.c
@@ -619,7 +619,7 @@ static void dsound_audio_fini (void *opaque)
g_free(s);
}
-static void *dsound_audio_init(Audiodev *dev)
+static void *dsound_audio_init(Audiodev *dev, Error **errp)
{
int err;
HRESULT hr;
@@ -721,7 +721,6 @@ static struct audio_driver dsound_audio_driver = {
.init = dsound_audio_init,
.fini = dsound_audio_fini,
.pcm_ops = &dsound_pcm_ops,
- .can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = 1,
.voice_size_out = sizeof (DSoundVoiceOut),
diff --git a/audio/jackaudio.c b/audio/jackaudio.c
index e1eaa3477d..974a3caad3 100644
--- a/audio/jackaudio.c
+++ b/audio/jackaudio.c
@@ -645,7 +645,7 @@ static int qjack_thread_creator(jack_native_thread_t *thread,
}
#endif
-static void *qjack_init(Audiodev *dev)
+static void *qjack_init(Audiodev *dev, Error **errp)
{
assert(dev->driver == AUDIODEV_DRIVER_JACK);
return dev;
@@ -676,7 +676,6 @@ static struct audio_driver jack_driver = {
.init = qjack_init,
.fini = qjack_fini,
.pcm_ops = &jack_pcm_ops,
- .can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof(QJackOut),
diff --git a/audio/meson.build b/audio/meson.build
index df4d968c0f..c8f658611f 100644
--- a/audio/meson.build
+++ b/audio/meson.build
@@ -1,7 +1,6 @@
system_ss.add([spice_headers, files('audio.c')])
system_ss.add(files(
'audio-hmp-cmds.c',
- 'audio_legacy.c',
'mixeng.c',
'noaudio.c',
'wavaudio.c',
diff --git a/audio/noaudio.c b/audio/noaudio.c
index 4fdee5adec..1b60d8518a 100644
--- a/audio/noaudio.c
+++ b/audio/noaudio.c
@@ -104,7 +104,7 @@ static void no_enable_in(HWVoiceIn *hw, bool enable)
}
}
-static void *no_audio_init(Audiodev *dev)
+static void *no_audio_init(Audiodev *dev, Error **errp)
{
return &no_audio_init;
}
@@ -135,7 +135,6 @@ static struct audio_driver no_audio_driver = {
.init = no_audio_init,
.fini = no_audio_fini,
.pcm_ops = &no_pcm_ops,
- .can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof (NoVoiceOut),
diff --git a/audio/ossaudio.c b/audio/ossaudio.c
index e8d732b612..3f31852371 100644
--- a/audio/ossaudio.c
+++ b/audio/ossaudio.c
@@ -28,6 +28,7 @@
#include "qemu/main-loop.h"
#include "qemu/module.h"
#include "qemu/host-utils.h"
+#include "qapi/error.h"
#include "audio.h"
#include "trace.h"
@@ -736,7 +737,7 @@ static void oss_init_per_direction(AudiodevOssPerDirectionOptions *opdo)
}
}
-static void *oss_audio_init(Audiodev *dev)
+static void *oss_audio_init(Audiodev *dev, Error **errp)
{
AudiodevOssOptions *oopts;
assert(dev->driver == AUDIODEV_DRIVER_OSS);
@@ -745,8 +746,12 @@ static void *oss_audio_init(Audiodev *dev)
oss_init_per_direction(oopts->in);
oss_init_per_direction(oopts->out);
- if (access(oopts->in->dev ?: "/dev/dsp", R_OK | W_OK) < 0 ||
- access(oopts->out->dev ?: "/dev/dsp", R_OK | W_OK) < 0) {
+ if (access(oopts->in->dev ?: "/dev/dsp", R_OK | W_OK) < 0) {
+ error_setg_errno(errp, errno, "%s not accessible", oopts->in->dev ?: "/dev/dsp");
+ return NULL;
+ }
+ if (access(oopts->out->dev ?: "/dev/dsp", R_OK | W_OK) < 0) {
+ error_setg_errno(errp, errno, "%s not accessible", oopts->out->dev ?: "/dev/dsp");
return NULL;
}
return dev;
@@ -779,7 +784,6 @@ static struct audio_driver oss_audio_driver = {
.init = oss_audio_init,
.fini = oss_audio_fini,
.pcm_ops = &oss_pcm_ops,
- .can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof (OSSVoiceOut),
diff --git a/audio/paaudio.c b/audio/paaudio.c
index 529b39daac..f3193b08c3 100644
--- a/audio/paaudio.c
+++ b/audio/paaudio.c
@@ -3,7 +3,7 @@
#include "qemu/osdep.h"
#include "qemu/module.h"
#include "audio.h"
-#include "qapi/opts-visitor.h"
+#include "qapi/error.h"
#include <pulse/pulseaudio.h>
@@ -818,7 +818,7 @@ fail:
return NULL;
}
-static void *qpa_audio_init(Audiodev *dev)
+static void *qpa_audio_init(Audiodev *dev, Error **errp)
{
paaudio *g;
AudiodevPaOptions *popts = &dev->u.pa;
@@ -834,10 +834,12 @@ static void *qpa_audio_init(Audiodev *dev)
runtime = getenv("XDG_RUNTIME_DIR");
if (!runtime) {
+ error_setg(errp, "XDG_RUNTIME_DIR not set");
return NULL;
}
snprintf(pidfile, sizeof(pidfile), "%s/pulse/pid", runtime);
if (stat(pidfile, &st) != 0) {
+ error_setg_errno(errp, errno, "could not stat pidfile %s", pidfile);
return NULL;
}
}
@@ -867,6 +869,7 @@ static void *qpa_audio_init(Audiodev *dev)
}
if (!g->conn) {
g_free(g);
+ error_setg(errp, "could not connect to PulseAudio server");
return NULL;
}
@@ -928,7 +931,6 @@ static struct audio_driver pa_audio_driver = {
.init = qpa_audio_init,
.fini = qpa_audio_fini,
.pcm_ops = &qpa_pcm_ops,
- .can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof (PAVoiceOut),
diff --git a/audio/pwaudio.c b/audio/pwaudio.c
index b6a38738ee..3ce5f6507b 100644
--- a/audio/pwaudio.c
+++ b/audio/pwaudio.c
@@ -13,6 +13,7 @@
#include "audio.h"
#include <errno.h>
#include "qemu/error-report.h"
+#include "qapi/error.h"
#include <spa/param/audio/format-utils.h>
#include <spa/utils/ringbuffer.h>
#include <spa/utils/result.h>
@@ -736,7 +737,7 @@ static const struct pw_core_events core_events = {
};
static void *
-qpw_audio_init(Audiodev *dev)
+qpw_audio_init(Audiodev *dev, Error **errp)
{
g_autofree pwaudio *pw = g_new0(pwaudio, 1);
@@ -748,19 +749,19 @@ qpw_audio_init(Audiodev *dev)
pw->dev = dev;
pw->thread_loop = pw_thread_loop_new("PipeWire thread loop", NULL);
if (pw->thread_loop == NULL) {
- error_report("Could not create PipeWire loop: %s", g_strerror(errno));
+ error_setg_errno(errp, errno, "Could not create PipeWire loop");
goto fail;
}
pw->context =
pw_context_new(pw_thread_loop_get_loop(pw->thread_loop), NULL, 0);
if (pw->context == NULL) {
- error_report("Could not create PipeWire context: %s", g_strerror(errno));
+ error_setg_errno(errp, errno, "Could not create PipeWire context");
goto fail;
}
if (pw_thread_loop_start(pw->thread_loop) < 0) {
- error_report("Could not start PipeWire loop: %s", g_strerror(errno));
+ error_setg_errno(errp, errno, "Could not start PipeWire loop");
goto fail;
}
@@ -769,13 +770,13 @@ qpw_audio_init(Audiodev *dev)
pw->core = pw_context_connect(pw->context, NULL, 0);
if (pw->core == NULL) {
pw_thread_loop_unlock(pw->thread_loop);
- goto fail;
+ goto fail_error;
}
if (pw_core_add_listener(pw->core, &pw->core_listener,
&core_events, pw) < 0) {
pw_thread_loop_unlock(pw->thread_loop);
- goto fail;
+ goto fail_error;
}
if (wait_resync(pw) < 0) {
pw_thread_loop_unlock(pw->thread_loop);
@@ -785,8 +786,9 @@ qpw_audio_init(Audiodev *dev)
return g_steal_pointer(&pw);
+fail_error:
+ error_setg(errp, "Failed to initialize PW context");
fail:
- AUD_log(AUDIO_CAP, "Failed to initialize PW context");
if (pw->thread_loop) {
pw_thread_loop_stop(pw->thread_loop);
}
@@ -841,7 +843,6 @@ static struct audio_driver pw_audio_driver = {
.init = qpw_audio_init,
.fini = qpw_audio_fini,
.pcm_ops = &qpw_pcm_ops,
- .can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof(PWVoiceOut),
diff --git a/audio/sdlaudio.c b/audio/sdlaudio.c
index 68a237b76b..641357e5ee 100644
--- a/audio/sdlaudio.c
+++ b/audio/sdlaudio.c
@@ -26,6 +26,7 @@
#include <SDL.h>
#include <SDL_thread.h>
#include "qemu/module.h"
+#include "qapi/error.h"
#include "audio.h"
#ifndef _WIN32
@@ -449,10 +450,10 @@ static void sdl_enable_in(HWVoiceIn *hw, bool enable)
SDL_PauseAudioDevice(sdl->devid, !enable);
}
-static void *sdl_audio_init(Audiodev *dev)
+static void *sdl_audio_init(Audiodev *dev, Error **errp)
{
if (SDL_InitSubSystem (SDL_INIT_AUDIO)) {
- sdl_logerr ("SDL failed to initialize audio subsystem\n");
+ error_setg(errp, "SDL failed to initialize audio subsystem");
return NULL;
}
@@ -493,7 +494,6 @@ static struct audio_driver sdl_audio_driver = {
.init = sdl_audio_init,
.fini = sdl_audio_fini,
.pcm_ops = &sdl_pcm_ops,
- .can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof(SDLVoiceOut),
diff --git a/audio/sndioaudio.c b/audio/sndioaudio.c
index 3fde01fdbd..8eb35e1e53 100644
--- a/audio/sndioaudio.c
+++ b/audio/sndioaudio.c
@@ -518,7 +518,7 @@ static void sndio_fini_in(HWVoiceIn *hw)
sndio_fini(self);
}
-static void *sndio_audio_init(Audiodev *dev)
+static void *sndio_audio_init(Audiodev *dev, Error **errp)
{
assert(dev->driver == AUDIODEV_DRIVER_SNDIO);
return dev;
@@ -550,7 +550,6 @@ static struct audio_driver sndio_audio_driver = {
.init = sndio_audio_init,
.fini = sndio_audio_fini,
.pcm_ops = &sndio_pcm_ops,
- .can_be_default = 1,
.max_voices_out = INT_MAX,
.max_voices_in = INT_MAX,
.voice_size_out = sizeof(SndioVoice),
diff --git a/audio/spiceaudio.c b/audio/spiceaudio.c
index d17ef1a25e..7f02f7285c 100644
--- a/audio/spiceaudio.c
+++ b/audio/spiceaudio.c
@@ -22,6 +22,7 @@
#include "qemu/module.h"
#include "qemu/error-report.h"
#include "qemu/timer.h"
+#include "qapi/error.h"
#include "ui/qemu-spice.h"
#define AUDIO_CAP "spice"
@@ -71,11 +72,13 @@ static const SpiceRecordInterface record_sif = {
.base.minor_version = SPICE_INTERFACE_RECORD_MINOR,
};
-static void *spice_audio_init(Audiodev *dev)
+static void *spice_audio_init(Audiodev *dev, Error **errp)
{
if (!using_spice) {
+ error_setg(errp, "Cannot use spice audio without -spice");
return NULL;
}
+
return &spice_audio_init;
}
diff --git a/audio/wavaudio.c b/audio/wavaudio.c
index 6445a2cb90..ea20fed0cc 100644
--- a/audio/wavaudio.c
+++ b/audio/wavaudio.c
@@ -182,7 +182,7 @@ static void wav_enable_out(HWVoiceOut *hw, bool enable)
}
}
-static void *wav_audio_init(Audiodev *dev)
+static void *wav_audio_init(Audiodev *dev, Error **errp)
{
assert(dev->driver == AUDIODEV_DRIVER_WAV);
return dev;
@@ -208,7 +208,6 @@ static struct audio_driver wav_audio_driver = {
.init = wav_audio_init,
.fini = wav_audio_fini,
.pcm_ops = &wav_pcm_ops,
- .can_be_default = 0,
.max_voices_out = 1,
.max_voices_in = 0,
.voice_size_out = sizeof (WAVVoiceOut),
diff --git a/crypto/meson.build b/crypto/meson.build
index 9ac1a89802..c46f9c22a7 100644
--- a/crypto/meson.build
+++ b/crypto/meson.build
@@ -46,7 +46,8 @@ endif
if have_afalg
crypto_ss.add(if_true: files('afalg.c', 'cipher-afalg.c', 'hash-afalg.c'))
endif
-crypto_ss.add(when: gnutls, if_true: files('tls-cipher-suites.c'))
+
+system_ss.add(when: gnutls, if_true: files('tls-cipher-suites.c'))
util_ss.add(files(
'aes.c',
diff --git a/docs/about/deprecated.rst b/docs/about/deprecated.rst
index 8f3fef97bd..2f51cf770a 100644
--- a/docs/about/deprecated.rst
+++ b/docs/about/deprecated.rst
@@ -37,21 +37,11 @@ coverage.
System emulator command line arguments
--------------------------------------
-``QEMU_AUDIO_`` environment variables and ``-audio-help`` (since 4.0)
-'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
-
-The ``-audiodev`` argument is now the preferred way to specify audio
-backend settings instead of environment variables. To ease migration to
-the new format, the ``-audiodev-help`` option can be used to convert
-the current values of the environment variables to ``-audiodev`` options.
-
-Creating sound card devices and vnc without ``audiodev=`` property (since 4.2)
-''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+Creating sound card devices without ``audiodev=`` property (since 4.2)
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
When not using the deprecated legacy audio config, each sound card
-should specify an ``audiodev=`` property. Additionally, when using
-vnc, you should specify an ``audiodev=`` property if you plan to
-transmit audio through the VNC protocol.
+should specify an ``audiodev=`` property.
Short-form boolean options (since 6.0)
''''''''''''''''''''''''''''''''''''''
diff --git a/docs/about/removed-features.rst b/docs/about/removed-features.rst
index 97ec47f1d2..e83ed087f6 100644
--- a/docs/about/removed-features.rst
+++ b/docs/about/removed-features.rst
@@ -436,6 +436,18 @@ the process listing. This was replaced by the new ``password-secret``
option which lets the password be securely provided on the command
line using a ``secret`` object instance.
+``QEMU_AUDIO_`` environment variables and ``-audio-help`` (removed in 8.2)
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+The ``-audiodev`` and ``-audio`` command line options are now the only
+way to specify audio backend settings.
+
+Creating vnc without ``audiodev=`` property (removed in 8.2)
+''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
+
+When using vnc, you should specify an ``audiodev=`` property if
+you plan to transmit audio through the VNC protocol.
+
QEMU Machine Protocol (QMP) commands
------------------------------------
diff --git a/gdbstub/meson.build b/gdbstub/meson.build
index 9500b9dc4e..a5a1f4e433 100644
--- a/gdbstub/meson.build
+++ b/gdbstub/meson.build
@@ -21,12 +21,12 @@ libgdb_user = static_library('gdb_user',
gdb_user_ss.sources() + genh,
name_suffix: 'fa',
c_args: '-DCONFIG_USER_ONLY',
- build_by_default: have_user)
+ build_by_default: false)
libgdb_softmmu = static_library('gdb_softmmu',
gdb_system_ss.sources() + genh,
name_suffix: 'fa',
- build_by_default: have_system)
+ build_by_default: false)
gdb_user = declare_dependency(link_whole: libgdb_user)
user_ss.add(gdb_user)
diff --git a/hw/arm/integratorcp.c b/hw/arm/integratorcp.c
index b109ece3ae..d176e9af7e 100644
--- a/hw/arm/integratorcp.c
+++ b/hw/arm/integratorcp.c
@@ -27,6 +27,7 @@
#include "hw/irq.h"
#include "hw/sd/sd.h"
#include "qom/object.h"
+#include "audio/audio.h"
#define TYPE_INTEGRATOR_CM "integrator_core"
OBJECT_DECLARE_SIMPLE_TYPE(IntegratorCMState, INTEGRATOR_CM)
@@ -660,7 +661,13 @@ static void integratorcp_init(MachineState *machine)
&error_fatal);
}
- sysbus_create_varargs("pl041", 0x1d000000, pic[25], NULL);
+ dev = qdev_new("pl041");
+ if (machine->audiodev) {
+ qdev_prop_set_string(dev, "audiodev", machine->audiodev);
+ }
+ sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
+ sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, 0x1d000000);
+ sysbus_connect_irq(SYS_BUS_DEVICE(dev), 0, pic[25]);
if (nd_table[0].used)
smc91c111_init(&nd_table[0], 0xc8000000, pic[27]);
@@ -678,6 +685,8 @@ static void integratorcp_machine_init(MachineClass *mc)
mc->ignore_memory_transaction_failures = true;
mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm926");
mc->default_ram_id = "integrator.ram";
+
+ machine_add_audiodev_property(mc);
}
DEFINE_MACHINE("integratorcp", integratorcp_machine_init)
diff --git a/hw/arm/musicpal.c b/hw/arm/musicpal.c
index dc4e43e0ee..9703bfb97f 100644
--- a/hw/arm/musicpal.c
+++ b/hw/arm/musicpal.c
@@ -37,9 +37,9 @@
#include "qemu/cutils.h"
#include "qom/object.h"
#include "hw/net/mv88w8618_eth.h"
+#include "audio/audio.h"
#include "qemu/error-report.h"
-
#define MP_MISC_BASE 0x80002000
#define MP_MISC_SIZE 0x00001000
@@ -1326,7 +1326,12 @@ static void musicpal_init(MachineState *machine)
qdev_connect_gpio_out(key_dev, i, qdev_get_gpio_in(dev, i + 15));
}
- wm8750_dev = i2c_slave_create_simple(i2c, TYPE_WM8750, MP_WM_ADDR);
+ wm8750_dev = i2c_slave_new(TYPE_WM8750, MP_WM_ADDR);
+ if (machine->audiodev) {
+ qdev_prop_set_string(DEVICE(wm8750_dev), "audiodev", machine->audiodev);
+ }
+ i2c_slave_realize_and_unref(wm8750_dev, i2c, &error_abort);
+
dev = qdev_new(TYPE_MV88W8618_AUDIO);
s = SYS_BUS_DEVICE(dev);
object_property_set_link(OBJECT(dev), "wm8750", OBJECT(wm8750_dev),
@@ -1347,6 +1352,8 @@ static void musicpal_machine_init(MachineClass *mc)
mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm926");
mc->default_ram_size = MP_RAM_DEFAULT_SIZE;
mc->default_ram_id = "musicpal.ram";
+
+ machine_add_audiodev_property(mc);
}
DEFINE_MACHINE("musicpal", musicpal_machine_init)
diff --git a/hw/arm/nseries.c b/hw/arm/nseries.c
index 9e49e9e177..35aff46b4b 100644
--- a/hw/arm/nseries.c
+++ b/hw/arm/nseries.c
@@ -1432,6 +1432,8 @@ static void n800_class_init(ObjectClass *oc, void *data)
/* Actually two chips of 0x4000000 bytes each */
mc->default_ram_size = 0x08000000;
mc->default_ram_id = "omap2.dram";
+
+ machine_add_audiodev_property(mc);
}
static const TypeInfo n800_type = {
@@ -1452,6 +1454,8 @@ static void n810_class_init(ObjectClass *oc, void *data)
/* Actually two chips of 0x4000000 bytes each */
mc->default_ram_size = 0x08000000;
mc->default_ram_id = "omap2.dram";
+
+ machine_add_audiodev_property(mc);
}
static const TypeInfo n810_type = {
diff --git a/hw/arm/omap2.c b/hw/arm/omap2.c
index d5a2ae7af6..f170728e7e 100644
--- a/hw/arm/omap2.c
+++ b/hw/arm/omap2.c
@@ -37,6 +37,7 @@
#include "hw/block/flash.h"
#include "hw/arm/soc_dma.h"
#include "hw/sysbus.h"
+#include "hw/boards.h"
#include "audio/audio.h"
/* Enhanced Audio Controller (CODEC only) */
@@ -609,7 +610,11 @@ static struct omap_eac_s *omap_eac_init(struct omap_target_agent_s *ta,
s->codec.txdrq = *drq;
omap_eac_reset(s);
- AUD_register_card("OMAP EAC", &s->codec.card);
+ if (current_machine->audiodev) {
+ s->codec.card.name = g_strdup(current_machine->audiodev);
+ s->codec.card.state = audio_state_by_name(s->codec.card.name, &error_fatal);
+ }
+ AUD_register_card("OMAP EAC", &s->codec.card, &error_fatal);
memory_region_init_io(&s->iomem, NULL, &omap_eac_ops, s, "omap.eac",
omap_l4_region_size(ta, 0));
diff --git a/hw/arm/palm.c b/hw/arm/palm.c
index 17c11ac4ce..b86f2c331b 100644
--- a/hw/arm/palm.c
+++ b/hw/arm/palm.c
@@ -310,6 +310,8 @@ static void palmte_machine_init(MachineClass *mc)
mc->default_cpu_type = ARM_CPU_TYPE_NAME("ti925t");
mc->default_ram_size = 0x02000000;
mc->default_ram_id = "omap1.dram";
+
+ machine_add_audiodev_property(mc);
}
DEFINE_MACHINE("cheetah", palmte_machine_init)
diff --git a/hw/arm/realview.c b/hw/arm/realview.c
index a5aa2f046a..8f89526596 100644
--- a/hw/arm/realview.c
+++ b/hw/arm/realview.c
@@ -29,6 +29,7 @@
#include "hw/irq.h"
#include "hw/i2c/arm_sbcon_i2c.h"
#include "hw/sd/sd.h"
+#include "audio/audio.h"
#define SMP_BOOT_ADDR 0xe0000000
#define SMP_BOOTREG_ADDR 0x10000030
@@ -207,6 +208,9 @@ static void realview_init(MachineState *machine,
pl041 = qdev_new("pl041");
qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512);
+ if (machine->audiodev) {
+ qdev_prop_set_string(pl041, "audiodev", machine->audiodev);
+ }
sysbus_realize_and_unref(SYS_BUS_DEVICE(pl041), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(pl041), 0, 0x10004000);
sysbus_connect_irq(SYS_BUS_DEVICE(pl041), 0, pic[19]);
@@ -412,6 +416,8 @@ static void realview_eb_class_init(ObjectClass *oc, void *data)
mc->block_default_type = IF_SCSI;
mc->ignore_memory_transaction_failures = true;
mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm926");
+
+ machine_add_audiodev_property(mc);
}
static const TypeInfo realview_eb_type = {
@@ -430,6 +436,8 @@ static void realview_eb_mpcore_class_init(ObjectClass *oc, void *data)
mc->max_cpus = 4;
mc->ignore_memory_transaction_failures = true;
mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm11mpcore");
+
+ machine_add_audiodev_property(mc);
}
static const TypeInfo realview_eb_mpcore_type = {
@@ -446,6 +454,8 @@ static void realview_pb_a8_class_init(ObjectClass *oc, void *data)
mc->init = realview_pb_a8_init;
mc->ignore_memory_transaction_failures = true;
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a8");
+
+ machine_add_audiodev_property(mc);
}
static const TypeInfo realview_pb_a8_type = {
@@ -463,6 +473,8 @@ static void realview_pbx_a9_class_init(ObjectClass *oc, void *data)
mc->max_cpus = 4;
mc->ignore_memory_transaction_failures = true;
mc->default_cpu_type = ARM_CPU_TYPE_NAME("cortex-a9");
+
+ machine_add_audiodev_property(mc);
}
static const TypeInfo realview_pbx_a9_type = {
diff --git a/hw/arm/spitz.c b/hw/arm/spitz.c
index f732fe0acf..cc268c6ac0 100644
--- a/hw/arm/spitz.c
+++ b/hw/arm/spitz.c
@@ -35,6 +35,7 @@
#include "exec/address-spaces.h"
#include "cpu.h"
#include "qom/object.h"
+#include "audio/audio.h"
enum spitz_model_e { spitz, akita, borzoi, terrier };
@@ -774,15 +775,19 @@ static void spitz_wm8750_addr(void *opaque, int line, int level)
i2c_slave_set_address(wm, SPITZ_WM_ADDRL);
}
-static void spitz_i2c_setup(PXA2xxState *cpu)
+static void spitz_i2c_setup(MachineState *machine, PXA2xxState *cpu)
{
/* Attach the CPU on one end of our I2C bus. */
I2CBus *bus = pxa2xx_i2c_bus(cpu->i2c[0]);
- DeviceState *wm;
-
/* Attach a WM8750 to the bus */
- wm = DEVICE(i2c_slave_create_simple(bus, TYPE_WM8750, 0));
+ I2CSlave *i2c_dev = i2c_slave_new(TYPE_WM8750, 0);
+ DeviceState *wm = DEVICE(i2c_dev);
+
+ if (machine->audiodev) {
+ qdev_prop_set_string(wm, "audiodev", machine->audiodev);
+ }
+ i2c_slave_realize_and_unref(i2c_dev, bus, &error_abort);
spitz_wm8750_addr(wm, 0, 0);
qdev_connect_gpio_out(cpu->gpio, SPITZ_GPIO_WM,
@@ -1013,7 +1018,7 @@ static void spitz_common_init(MachineState *machine)
spitz_gpio_setup(mpu, (model == akita) ? 1 : 2);
- spitz_i2c_setup(mpu);
+ spitz_i2c_setup(machine, mpu);
if (model == akita)
spitz_akita_i2c_setup(mpu);
@@ -1037,6 +1042,8 @@ static void spitz_common_class_init(ObjectClass *oc, void *data)
mc->block_default_type = IF_IDE;
mc->ignore_memory_transaction_failures = true;
mc->init = spitz_common_init;
+
+ machine_add_audiodev_property(mc);
}
static const TypeInfo spitz_common_info = {
diff --git a/hw/arm/versatilepb.c b/hw/arm/versatilepb.c
index 05b9462a5b..2f22dc890f 100644
--- a/hw/arm/versatilepb.c
+++ b/hw/arm/versatilepb.c
@@ -26,6 +26,7 @@
#include "hw/char/pl011.h"
#include "hw/sd/sd.h"
#include "qom/object.h"
+#include "audio/audio.h"
#define VERSATILE_FLASH_ADDR 0x34000000
#define VERSATILE_FLASH_SIZE (64 * 1024 * 1024)
@@ -343,6 +344,9 @@ static void versatile_init(MachineState *machine, int board_id)
/* Add PL041 AACI Interface to the LM4549 codec */
pl041 = qdev_new("pl041");
qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512);
+ if (machine->audiodev) {
+ qdev_prop_set_string(pl041, "audiodev", machine->audiodev);
+ }
sysbus_realize_and_unref(SYS_BUS_DEVICE(pl041), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(pl041), 0, 0x10004000);
sysbus_connect_irq(SYS_BUS_DEVICE(pl041), 0, sic[24]);
@@ -416,6 +420,8 @@ static void versatilepb_class_init(ObjectClass *oc, void *data)
mc->ignore_memory_transaction_failures = true;
mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm926");
mc->default_ram_id = "versatile.ram";
+
+ machine_add_audiodev_property(mc);
}
static const TypeInfo versatilepb_type = {
@@ -434,6 +440,8 @@ static void versatileab_class_init(ObjectClass *oc, void *data)
mc->ignore_memory_transaction_failures = true;
mc->default_cpu_type = ARM_CPU_TYPE_NAME("arm926");
mc->default_ram_id = "versatile.ram";
+
+ machine_add_audiodev_property(mc);
}
static const TypeInfo versatileab_type = {
diff --git a/hw/arm/vexpress.c b/hw/arm/vexpress.c
index 56abadd9b8..8ff37f52ca 100644
--- a/hw/arm/vexpress.c
+++ b/hw/arm/vexpress.c
@@ -44,6 +44,7 @@
#include "hw/i2c/arm_sbcon_i2c.h"
#include "hw/sd/sd.h"
#include "qom/object.h"
+#include "audio/audio.h"
#define VEXPRESS_BOARD_ID 0x8e0
#define VEXPRESS_FLASH_SIZE (64 * 1024 * 1024)
@@ -613,6 +614,9 @@ static void vexpress_common_init(MachineState *machine)
pl041 = qdev_new("pl041");
qdev_prop_set_uint32(pl041, "nc_fifo_depth", 512);
+ if (machine->audiodev) {
+ qdev_prop_set_string(pl041, "audiodev", machine->audiodev);
+ }
sysbus_realize_and_unref(SYS_BUS_DEVICE(pl041), &error_fatal);
sysbus_mmio_map(SYS_BUS_DEVICE(pl041), 0, map[VE_PL041]);
sysbus_connect_irq(SYS_BUS_DEVICE(pl041), 0, pic[11]);
@@ -776,6 +780,7 @@ static void vexpress_class_init(ObjectClass *oc, void *data)
mc->ignore_memory_transaction_failures = true;
mc->default_ram_id = "vexpress.highmem";
+ machine_add_audiodev_property(mc);
object_class_property_add_bool(oc, "secure", vexpress_get_secure,
vexpress_set_secure);
object_class_property_set_description(oc, "secure",
diff --git a/hw/arm/xlnx-zcu102.c b/hw/arm/xlnx-zcu102.c
index 21483f75fd..c5a07cfe19 100644
--- a/hw/arm/xlnx-zcu102.c
+++ b/hw/arm/xlnx-zcu102.c
@@ -24,6 +24,7 @@
#include "sysemu/device_tree.h"
#include "qom/object.h"
#include "net/can_emu.h"
+#include "audio/audio.h"
struct XlnxZCU102 {
MachineState parent_obj;
@@ -143,6 +144,10 @@ static void xlnx_zcu102_init(MachineState *machine)
object_initialize_child(OBJECT(machine), "soc", &s->soc, TYPE_XLNX_ZYNQMP);
+ if (machine->audiodev) {
+ qdev_prop_set_string(DEVICE(&s->soc.dp), "audiodev", machine->audiodev);
+ }
+
object_property_set_link(OBJECT(&s->soc), "ddr-ram", OBJECT(machine->ram),
&error_abort);
object_property_set_bool(OBJECT(&s->soc), "secure", s->secure,
@@ -275,6 +280,7 @@ static void xlnx_zcu102_machine_class_init(ObjectClass *oc, void *data)
mc->default_cpus = XLNX_ZYNQMP_NUM_APU_CPUS;
mc->default_ram_id = "ddr-ram";
+ machine_add_audiodev_property(mc);
object_class_property_add_bool(oc, "secure", zcu102_get_secure,
zcu102_set_secure);
object_class_property_set_description(oc, "secure",
diff --git a/hw/arm/z2.c b/hw/arm/z2.c
index dc25304290..d9a08fa67b 100644
--- a/hw/arm/z2.c
+++ b/hw/arm/z2.c
@@ -27,6 +27,7 @@
#include "exec/address-spaces.h"
#include "cpu.h"
#include "qom/object.h"
+#include "qapi/error.h"
#ifdef DEBUG_Z2
#define DPRINTF(fmt, ...) \
@@ -307,6 +308,7 @@ static void z2_init(MachineState *machine)
void *z2_lcd;
I2CBus *bus;
DeviceState *wm;
+ I2CSlave *i2c_dev;
/* Setup CPU & memory */
mpu = pxa270_init(z2_binfo.ram_size, machine->cpu_type);
@@ -328,8 +330,17 @@ static void z2_init(MachineState *machine)
type_register_static(&aer915_info);
z2_lcd = ssi_create_peripheral(mpu->ssp[1], TYPE_ZIPIT_LCD);
bus = pxa2xx_i2c_bus(mpu->i2c[0]);
+
i2c_slave_create_simple(bus, TYPE_AER915, 0x55);
- wm = DEVICE(i2c_slave_create_simple(bus, TYPE_WM8750, 0x1b));
+
+ i2c_dev = i2c_slave_new(TYPE_WM8750, 0x1b);
+ wm = DEVICE(i2c_dev);
+
+ if (machine->audiodev) {
+ qdev_prop_set_string(wm, "audiodev", machine->audiodev);
+ }
+ i2c_slave_realize_and_unref(i2c_dev, bus, &error_abort);
+
mpu->i2s->opaque = wm;
mpu->i2s->codec_out = wm8750_dac_dat;
mpu->i2s->codec_in = wm8750_adc_dat;
@@ -348,6 +359,8 @@ static void z2_machine_init(MachineClass *mc)
mc->init = z2_init;
mc->ignore_memory_transaction_failures = true;
mc->default_cpu_type = ARM_CPU_TYPE_NAME("pxa270-c5");
+
+ machine_add_audiodev_property(mc);
}
DEFINE_MACHINE("z2", z2_machine_init)
diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c
index c2a5ce062a..6a7a2dc80c 100644
--- a/hw/audio/ac97.c
+++ b/hw/audio/ac97.c
@@ -1273,6 +1273,10 @@ static void ac97_realize(PCIDevice *dev, Error **errp)
AC97LinkState *s = AC97(dev);
uint8_t *c = s->dev.config;
+ if (!AUD_register_card ("ac97", &s->card, errp)) {
+ return;
+ }
+
/* TODO: no need to override */
c[PCI_COMMAND] = 0x00; /* pcicmd pci command rw, ro */
c[PCI_COMMAND + 1] = 0x00;
@@ -1306,7 +1310,7 @@ static void ac97_realize(PCIDevice *dev, Error **errp)
"ac97-nabm", 256);
pci_register_bar(&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nam);
pci_register_bar(&s->dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->io_nabm);
- AUD_register_card("ac97", &s->card);
+
ac97_on_reset(DEVICE(s));
}
diff --git a/hw/audio/adlib.c b/hw/audio/adlib.c
index 5f979b1487..bd73806d83 100644
--- a/hw/audio/adlib.c
+++ b/hw/audio/adlib.c
@@ -255,6 +255,10 @@ static void adlib_realizefn (DeviceState *dev, Error **errp)
AdlibState *s = ADLIB(dev);
struct audsettings as;
+ if (!AUD_register_card ("adlib", &s->card, errp)) {
+ return;
+ }
+
s->opl = OPLCreate (3579545, s->freq);
if (!s->opl) {
error_setg (errp, "OPLCreate %d failed", s->freq);
@@ -270,8 +274,6 @@ static void adlib_realizefn (DeviceState *dev, Error **errp)
as.fmt = AUDIO_FORMAT_S16;
as.endianness = AUDIO_HOST_ENDIANNESS;
- AUD_register_card ("adlib", &s->card);
-
s->voice = AUD_open_out (
&s->card,
s->voice,
diff --git a/hw/audio/cs4231a.c b/hw/audio/cs4231a.c
index 5c6d643732..3aa105748d 100644
--- a/hw/audio/cs4231a.c
+++ b/hw/audio/cs4231a.c
@@ -678,13 +678,15 @@ static void cs4231a_realizefn (DeviceState *dev, Error **errp)
return;
}
+ if (!AUD_register_card ("cs4231a", &s->card, errp)) {
+ return;
+ }
+
s->pic = isa_bus_get_irq(bus, s->irq);
k = ISADMA_GET_CLASS(s->isa_dma);
k->register_channel(s->isa_dma, s->dma, cs_dma_read, s);
isa_register_ioport (d, &s->ioports, s->port);
-
- AUD_register_card ("cs4231a", &s->card);
}
static Property cs4231a_properties[] = {
diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c
index 4f738a0ad8..90f73d4c23 100644
--- a/hw/audio/es1370.c
+++ b/hw/audio/es1370.c
@@ -853,6 +853,10 @@ static void es1370_realize(PCIDevice *dev, Error **errp)
ES1370State *s = ES1370(dev);
uint8_t *c = s->dev.config;
+ if (!AUD_register_card ("es1370", &s->card, errp)) {
+ return;
+ }
+
c[PCI_STATUS + 1] = PCI_STATUS_DEVSEL_SLOW >> 8;
#if 0
@@ -868,7 +872,6 @@ static void es1370_realize(PCIDevice *dev, Error **errp)
memory_region_init_io (&s->io, OBJECT(s), &es1370_io_ops, s, "es1370", 256);
pci_register_bar (&s->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io);
- AUD_register_card ("es1370", &s->card);
es1370_reset (s);
}
diff --git a/hw/audio/gus.c b/hw/audio/gus.c
index 787345ce54..6c2b586ca7 100644
--- a/hw/audio/gus.c
+++ b/hw/audio/gus.c
@@ -241,14 +241,16 @@ static void gus_realizefn (DeviceState *dev, Error **errp)
IsaDmaClass *k;
struct audsettings as;
+ if (!AUD_register_card ("gus", &s->card, errp)) {
+ return;
+ }
+
s->isa_dma = isa_bus_get_dma(bus, s->emu.gusdma);
if (!s->isa_dma) {
error_setg(errp, "ISA controller does not support DMA");
return;
}
- AUD_register_card ("gus", &s->card);
-
as.freq = s->freq;
as.nchannels = 2;
as.fmt = AUDIO_FORMAT_S16;
diff --git a/hw/audio/hda-codec.c b/hw/audio/hda-codec.c
index a26048cf15..b9ad1f4c39 100644
--- a/hw/audio/hda-codec.c
+++ b/hw/audio/hda-codec.c
@@ -685,11 +685,14 @@ static void hda_audio_init(HDACodecDevice *hda,
const desc_param *param;
uint32_t i, type;
+ if (!AUD_register_card("hda", &a->card, errp)) {
+ return;
+ }
+
a->desc = desc;
a->name = object_get_typename(OBJECT(a));
dprint(a, 1, "%s: cad %d\n", __func__, a->hda.cad);
- AUD_register_card("hda", &a->card);
for (i = 0; i < a->desc->nnodes; i++) {
node = a->desc->nodes + i;
param = hda_codec_find_param(node, AC_PAR_AUDIO_WIDGET_CAP);
diff --git a/hw/audio/lm4549.c b/hw/audio/lm4549.c
index 418041bc9c..e7bfcc4b9f 100644
--- a/hw/audio/lm4549.c
+++ b/hw/audio/lm4549.c
@@ -281,6 +281,11 @@ void lm4549_init(lm4549_state *s, lm4549_callback data_req_cb, void* opaque,
{
struct audsettings as;
+ /* Register an audio card */
+ if (!AUD_register_card("lm4549", &s->card, errp)) {
+ return;
+ }
+
/* Store the callback and opaque pointer */
s->data_req_cb = data_req_cb;
s->opaque = opaque;
@@ -288,9 +293,6 @@ void lm4549_init(lm4549_state *s, lm4549_callback data_req_cb, void* opaque,
/* Init the registers */
lm4549_reset(s);
- /* Register an audio card */
- AUD_register_card("lm4549", &s->card);
-
/* Open a default voice */
as.freq = 48000;
as.nchannels = 2;
diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c
index daf92a4ce1..fe7f07ced2 100644
--- a/hw/audio/pcspk.c
+++ b/hw/audio/pcspk.c
@@ -123,8 +123,6 @@ static int pcspk_audio_init(PCSpkState *s)
return 0;
}
- AUD_register_card(s_spk, &s->card);
-
s->voice = AUD_open_out(&s->card, s->voice, s_spk, s, pcspk_callback, &as);
if (!s->voice) {
AUD_log(s_spk, "Could not open voice\n");
@@ -191,7 +189,7 @@ static void pcspk_realizefn(DeviceState *dev, Error **errp)
isa_register_ioport(isadev, &s->ioport, s->iobase);
- if (s->card.state) {
+ if (s->card.state && AUD_register_card(s_spk, &s->card, errp)) {
pcspk_audio_init(s);
}
diff --git a/hw/audio/sb16.c b/hw/audio/sb16.c
index 535ccccdc9..18f6d252db 100644
--- a/hw/audio/sb16.c
+++ b/hw/audio/sb16.c
@@ -1402,6 +1402,10 @@ static void sb16_realizefn (DeviceState *dev, Error **errp)
SB16State *s = SB16 (dev);
IsaDmaClass *k;
+ if (!AUD_register_card ("sb16", &s->card, errp)) {
+ return;
+ }
+
s->isa_hdma = isa_bus_get_dma(bus, s->hdma);
s->isa_dma = isa_bus_get_dma(bus, s->dma);
if (!s->isa_dma || !s->isa_hdma) {
@@ -1434,8 +1438,6 @@ static void sb16_realizefn (DeviceState *dev, Error **errp)
k->register_channel(s->isa_dma, s->dma, SB_read_DMA, s);
s->can_write = 1;
-
- AUD_register_card ("sb16", &s->card);
}
static Property sb16_properties[] = {
diff --git a/hw/audio/via-ac97.c b/hw/audio/via-ac97.c
index 676254b7a4..30095a4c7a 100644
--- a/hw/audio/via-ac97.c
+++ b/hw/audio/via-ac97.c
@@ -426,6 +426,10 @@ static void via_ac97_realize(PCIDevice *pci_dev, Error **errp)
ViaAC97State *s = VIA_AC97(pci_dev);
Object *o = OBJECT(s);
+ if (!AUD_register_card ("via-ac97", &s->card, errp)) {
+ return;
+ }
+
/*
* Command register Bus Master bit is documented to be fixed at 0 but it's
* needed for PCI DMA to work in QEMU. The pegasos2 firmware writes 0 here
@@ -445,8 +449,6 @@ static void via_ac97_realize(PCIDevice *pci_dev, Error **errp)
pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->fm);
memory_region_init_io(&s->midi, o, &midi_ops, s, "via-ac97.midi", 4);
pci_register_bar(pci_dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &s->midi);
-
- AUD_register_card ("via-ac97", &s->card);
}
static void via_ac97_exit(PCIDevice *dev)
diff --git a/hw/audio/wm8750.c b/hw/audio/wm8750.c
index b5722b37c3..57954a6314 100644
--- a/hw/audio/wm8750.c
+++ b/hw/audio/wm8750.c
@@ -624,7 +624,10 @@ static void wm8750_realize(DeviceState *dev, Error **errp)
{
WM8750State *s = WM8750(dev);
- AUD_register_card(CODEC, &s->card);
+ if (!AUD_register_card(CODEC, &s->card, errp)) {
+ return;
+ }
+
wm8750_reset(I2C_SLAVE(s));
}
diff --git a/hw/core/machine.c b/hw/core/machine.c
index a232ae0bcd..b135d12b40 100644
--- a/hw/core/machine.c
+++ b/hw/core/machine.c
@@ -39,6 +39,7 @@
#include "hw/virtio/virtio.h"
#include "hw/virtio/virtio-pci.h"
#include "hw/virtio/virtio-net.h"
+#include "audio/audio.h"
GlobalProperty hw_compat_8_1[] = {};
const size_t hw_compat_8_1_len = G_N_ELEMENTS(hw_compat_8_1);
@@ -686,6 +687,26 @@ bool device_type_is_dynamic_sysbus(MachineClass *mc, const char *type)
return allowed;
}
+static char *machine_get_audiodev(Object *obj, Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+
+ return g_strdup(ms->audiodev);
+}
+
+static void machine_set_audiodev(Object *obj, const char *value,
+ Error **errp)
+{
+ MachineState *ms = MACHINE(obj);
+
+ if (!audio_state_by_name(value, errp)) {
+ return;
+ }
+
+ g_free(ms->audiodev);
+ ms->audiodev = g_strdup(value);
+}
+
HotpluggableCPUList *machine_query_hotpluggable_cpus(MachineState *machine)
{
int i;
@@ -931,6 +952,17 @@ out_free:
qapi_free_BootConfiguration(config);
}
+void machine_add_audiodev_property(MachineClass *mc)
+{
+ ObjectClass *oc = OBJECT_CLASS(mc);
+
+ object_class_property_add_str(oc, "audiodev",
+ machine_get_audiodev,
+ machine_set_audiodev);
+ object_class_property_set_description(oc, "audiodev",
+ "Audiodev to use for default machine devices");
+}
+
static void machine_class_init(ObjectClass *oc, void *data)
{
MachineClass *mc = MACHINE_CLASS(oc);
@@ -1134,6 +1166,7 @@ static void machine_finalize(Object *obj)
g_free(ms->device_memory);
g_free(ms->nvdimms_state);
g_free(ms->numa_state);
+ g_free(ms->audiodev);
}
bool machine_usb(MachineState *machine)
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 41b7e682c7..688340610e 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -480,24 +480,16 @@ static void set_audiodev(Object *obj, Visitor *v, const char* name,
Property *prop = opaque;
QEMUSoundCard *card = object_field_prop_ptr(obj, prop);
AudioState *state;
- int err = 0;
- char *str;
+ g_autofree char *str = NULL;
if (!visit_type_str(v, name, &str, errp)) {
return;
}
- state = audio_state_by_name(str);
-
- if (!state) {
- err = -ENOENT;
- goto out;
+ state = audio_state_by_name(str, errp);
+ if (state) {
+ card->state = state;
}
- card->state = state;
-
-out:
- error_set_from_qdev_prop_error(errp, err, obj, name, str);
- g_free(str);
}
const PropertyInfo qdev_prop_audiodev = {
diff --git a/hw/display/xlnx_dp.c b/hw/display/xlnx_dp.c
index 341e91e886..eee8f33a58 100644
--- a/hw/display/xlnx_dp.c
+++ b/hw/display/xlnx_dp.c
@@ -1302,6 +1302,10 @@ static void xlnx_dp_realize(DeviceState *dev, Error **errp)
DisplaySurface *surface;
struct audsettings as;
+ if (!AUD_register_card("xlnx_dp.audio", &s->aud_card, errp)) {
+ return;
+ }
+
aux_bus_realize(s->aux_bus);
qdev_realize(DEVICE(s->dpcd), BUS(s->aux_bus), &error_fatal);
@@ -1320,8 +1324,6 @@ static void xlnx_dp_realize(DeviceState *dev, Error **errp)
as.fmt = AUDIO_FORMAT_S16;
as.endianness = 0;
- AUD_register_card("xlnx_dp.audio", &s->aud_card);
-
s->amixer_output_stream = AUD_open_out(&s->aud_card,
s->amixer_output_stream,
"xlnx_dp.audio.out",
diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c
index f568759e05..950506fb38 100644
--- a/hw/input/tsc210x.c
+++ b/hw/input/tsc210x.c
@@ -27,6 +27,7 @@
#include "sysemu/reset.h"
#include "ui/console.h"
#include "hw/arm/omap.h" /* For I2SCodec */
+#include "hw/boards.h" /* for current_machine */
#include "hw/input/tsc2xxx.h"
#include "hw/irq.h"
#include "migration/vmstate.h"
@@ -1097,7 +1098,11 @@ static void tsc210x_init(TSC210xState *s,
qemu_add_mouse_event_handler(tsc210x_touchscreen_event, s, 1, name);
- AUD_register_card(s->name, &s->card);
+ if (current_machine->audiodev) {
+ s->card.name = g_strdup(current_machine->audiodev);
+ s->card.state = audio_state_by_name(s->card.name, &error_fatal);
+ }
+ AUD_register_card(s->name, &s->card, &error_fatal);
qemu_register_reset((void *) tsc210x_reset, s);
vmstate_register(NULL, 0, vmsd, s);
diff --git a/hw/mips/fuloong2e.c b/hw/mips/fuloong2e.c
index c827f615f3..c6109633fe 100644
--- a/hw/mips/fuloong2e.c
+++ b/hw/mips/fuloong2e.c
@@ -295,9 +295,17 @@ static void mips_fuloong2e_init(MachineState *machine)
pci_bus = bonito_init((qemu_irq *)&(env->irq[2]));
/* South bridge -> IP5 */
- pci_dev = pci_create_simple_multifunction(pci_bus,
- PCI_DEVFN(FULOONG2E_VIA_SLOT, 0),
- TYPE_VT82C686B_ISA);
+ pci_dev = pci_new_multifunction(PCI_DEVFN(FULOONG2E_VIA_SLOT, 0),
+ TYPE_VT82C686B_ISA);
+
+ /* Set properties on individual devices before realizing the south bridge */
+ if (machine->audiodev) {
+ dev = DEVICE(object_resolve_path_component(OBJECT(pci_dev), "ac97"));
+ qdev_prop_set_string(dev, "audiodev", machine->audiodev);
+ }
+
+ pci_realize_and_unref(pci_dev, pci_bus, &error_abort);
+
object_property_add_alias(OBJECT(machine), "rtc-time",
object_resolve_path_component(OBJECT(pci_dev),
"rtc"),
@@ -337,6 +345,7 @@ static void mips_fuloong2e_machine_init(MachineClass *mc)
mc->default_ram_size = 256 * MiB;
mc->default_ram_id = "fuloong2e.ram";
mc->minimum_page_bits = 14;
+ machine_add_audiodev_property(mc);
}
DEFINE_MACHINE("fuloong2e", mips_fuloong2e_machine_init)
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
index 093c2d4531..548bcabcbb 100644
--- a/hw/net/e1000.c
+++ b/hw/net/e1000.c
@@ -127,13 +127,9 @@ struct E1000State_st {
QEMUTimer *flush_queue_timer;
/* Compatibility flags for migration to/from qemu 1.3.0 and older */
-#define E1000_FLAG_AUTONEG_BIT 0
-#define E1000_FLAG_MIT_BIT 1
#define E1000_FLAG_MAC_BIT 2
#define E1000_FLAG_TSO_BIT 3
#define E1000_FLAG_VET_BIT 4
-#define E1000_FLAG_AUTONEG (1 << E1000_FLAG_AUTONEG_BIT)
-#define E1000_FLAG_MIT (1 << E1000_FLAG_MIT_BIT)
#define E1000_FLAG_MAC (1 << E1000_FLAG_MAC_BIT)
#define E1000_FLAG_TSO (1 << E1000_FLAG_TSO_BIT)
#define E1000_FLAG_VET (1 << E1000_FLAG_VET_BIT)
@@ -180,7 +176,7 @@ e1000_autoneg_done(E1000State *s)
static bool
have_autoneg(E1000State *s)
{
- return chkflag(AUTONEG) && (s->phy_reg[MII_BMCR] & MII_BMCR_AUTOEN);
+ return (s->phy_reg[MII_BMCR] & MII_BMCR_AUTOEN);
}
static void
@@ -308,35 +304,34 @@ set_interrupt_cause(E1000State *s, int index, uint32_t val)
if (s->mit_timer_on) {
return;
}
- if (chkflag(MIT)) {
- /* Compute the next mitigation delay according to pending
- * interrupts and the current values of RADV (provided
- * RDTR!=0), TADV and ITR.
- * Then rearm the timer.
- */
- mit_delay = 0;
- if (s->mit_ide &&
- (pending_ints & (E1000_ICR_TXQE | E1000_ICR_TXDW))) {
- mit_update_delay(&mit_delay, s->mac_reg[TADV] * 4);
- }
- if (s->mac_reg[RDTR] && (pending_ints & E1000_ICS_RXT0)) {
- mit_update_delay(&mit_delay, s->mac_reg[RADV] * 4);
- }
- mit_update_delay(&mit_delay, s->mac_reg[ITR]);
-
- /*
- * According to e1000 SPEC, the Ethernet controller guarantees
- * a maximum observable interrupt rate of 7813 interrupts/sec.
- * Thus if mit_delay < 500 then the delay should be set to the
- * minimum delay possible which is 500.
- */
- mit_delay = (mit_delay < 500) ? 500 : mit_delay;
-
- s->mit_timer_on = 1;
- timer_mod(s->mit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
- mit_delay * 256);
- s->mit_ide = 0;
+
+ /* Compute the next mitigation delay according to pending
+ * interrupts and the current values of RADV (provided
+ * RDTR!=0), TADV and ITR.
+ * Then rearm the timer.
+ */
+ mit_delay = 0;
+ if (s->mit_ide &&
+ (pending_ints & (E1000_ICR_TXQE | E1000_ICR_TXDW))) {
+ mit_update_delay(&mit_delay, s->mac_reg[TADV] * 4);
}
+ if (s->mac_reg[RDTR] && (pending_ints & E1000_ICS_RXT0)) {
+ mit_update_delay(&mit_delay, s->mac_reg[RADV] * 4);
+ }
+ mit_update_delay(&mit_delay, s->mac_reg[ITR]);
+
+ /*
+ * According to e1000 SPEC, the Ethernet controller guarantees
+ * a maximum observable interrupt rate of 7813 interrupts/sec.
+ * Thus if mit_delay < 500 then the delay should be set to the
+ * minimum delay possible which is 500.
+ */
+ mit_delay = (mit_delay < 500) ? 500 : mit_delay;
+
+ s->mit_timer_on = 1;
+ timer_mod(s->mit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
+ mit_delay * 256);
+ s->mit_ide = 0;
}
s->mit_irq_level = (pending_ints != 0);
@@ -1223,9 +1218,6 @@ enum { MAC_ACCESS_PARTIAL = 1, MAC_ACCESS_FLAG_NEEDED = 2 };
* n - flag needed
* p - partially implenented */
static const uint8_t mac_reg_access[0x8000] = {
- [RDTR] = markflag(MIT), [TADV] = markflag(MIT),
- [RADV] = markflag(MIT), [ITR] = markflag(MIT),
-
[IPAV] = markflag(MAC), [WUC] = markflag(MAC),
[IP6AT] = markflag(MAC), [IP4AT] = markflag(MAC),
[FFVT] = markflag(MAC), [WUPM] = markflag(MAC),
@@ -1394,11 +1386,6 @@ static int e1000_post_load(void *opaque, int version_id)
E1000State *s = opaque;
NetClientState *nc = qemu_get_queue(s->nic);
- if (!chkflag(MIT)) {
- s->mac_reg[ITR] = s->mac_reg[RDTR] = s->mac_reg[RADV] =
- s->mac_reg[TADV] = 0;
- s->mit_irq_level = false;
- }
s->mit_ide = 0;
s->mit_timer_on = true;
timer_mod(s->mit_timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 1);
@@ -1432,13 +1419,6 @@ static int e1000_tx_tso_post_load(void *opaque, int version_id)
return 0;
}
-static bool e1000_mit_state_needed(void *opaque)
-{
- E1000State *s = opaque;
-
- return chkflag(MIT);
-}
-
static bool e1000_full_mac_needed(void *opaque)
{
E1000State *s = opaque;
@@ -1457,7 +1437,6 @@ static const VMStateDescription vmstate_e1000_mit_state = {
.name = "e1000/mit_state",
.version_id = 1,
.minimum_version_id = 1,
- .needed = e1000_mit_state_needed,
.fields = (VMStateField[]) {
VMSTATE_UINT32(mac_reg[RDTR], E1000State),
VMSTATE_UINT32(mac_reg[RADV], E1000State),
@@ -1699,10 +1678,6 @@ static void pci_e1000_realize(PCIDevice *pci_dev, Error **errp)
static Property e1000_properties[] = {
DEFINE_NIC_PROPERTIES(E1000State, conf),
- DEFINE_PROP_BIT("autonegotiation", E1000State,
- compat_flags, E1000_FLAG_AUTONEG_BIT, true),
- DEFINE_PROP_BIT("mitigation", E1000State,
- compat_flags, E1000_FLAG_MIT_BIT, true),
DEFINE_PROP_BIT("extra_mac_registers", E1000State,
compat_flags, E1000_FLAG_MAC_BIT, true),
DEFINE_PROP_BIT("migrate_tso_props", E1000State,
diff --git a/hw/nvram/meson.build b/hw/nvram/meson.build
index 988dff6f8e..75e415b1a0 100644
--- a/hw/nvram/meson.build
+++ b/hw/nvram/meson.build
@@ -1,8 +1,4 @@
-if have_system or have_tools
- # QOM interfaces must be available anytime QOM is used.
- qom_ss.add(files('fw_cfg-interface.c'))
-endif
-
+system_ss.add(files('fw_cfg-interface.c'))
system_ss.add(files('fw_cfg.c'))
system_ss.add(when: 'CONFIG_CHRP_NVRAM', if_true: files('chrp_nvram.c'))
system_ss.add(when: 'CONFIG_DS1225Y', if_true: files('ds1225y.c'))
diff --git a/hw/pci-host/i440fx.c b/hw/pci-host/i440fx.c
index 62d6287681..653cc3f149 100644
--- a/hw/pci-host/i440fx.c
+++ b/hw/pci-host/i440fx.c
@@ -56,7 +56,6 @@ struct I440FXState {
uint64_t above_4g_mem_size;
uint64_t pci_hole64_size;
bool pci_hole64_fix;
- uint32_t short_root_bus;
char *pci_type;
};
@@ -351,19 +350,12 @@ static const TypeInfo i440fx_info = {
static const char *i440fx_pcihost_root_bus_path(PCIHostState *host_bridge,
PCIBus *rootbus)
{
- I440FXState *s = I440FX_PCI_HOST_BRIDGE(host_bridge);
-
- /* For backwards compat with old device paths */
- if (s->short_root_bus) {
- return "0000";
- }
return "0000:00";
}
static Property i440fx_props[] = {
DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, I440FXState,
pci_hole64_size, I440FX_PCI_HOST_HOLE64_SIZE_DEFAULT),
- DEFINE_PROP_UINT32("short_root_bus", I440FXState, short_root_bus, 0),
DEFINE_PROP_SIZE(PCI_HOST_BELOW_4G_MEM_SIZE, I440FXState,
below_4g_mem_size, 0),
DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MEM_SIZE, I440FXState,
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 91c46df9ae..08534bc7cc 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -73,12 +73,6 @@ static void q35_host_realize(DeviceState *dev, Error **errp)
static const char *q35_host_root_bus_path(PCIHostState *host_bridge,
PCIBus *rootbus)
{
- Q35PCIHost *s = Q35_HOST_DEVICE(host_bridge);
-
- /* For backwards compat with old device paths */
- if (s->mch.short_root_bus) {
- return "0000";
- }
return "0000:00";
}
@@ -181,7 +175,6 @@ static Property q35_host_props[] = {
MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT),
DEFINE_PROP_SIZE(PCI_HOST_PROP_PCI_HOLE64_SIZE, Q35PCIHost,
mch.pci_hole64_size, Q35_PCI_HOST_HOLE64_SIZE_DEFAULT),
- DEFINE_PROP_UINT32("short_root_bus", Q35PCIHost, mch.short_root_bus, 0),
DEFINE_PROP_SIZE(PCI_HOST_BELOW_4G_MEM_SIZE, Q35PCIHost,
mch.below_4g_mem_size, 0),
DEFINE_PROP_SIZE(PCI_HOST_ABOVE_4G_MEM_SIZE, Q35PCIHost,
diff --git a/hw/ppc/pegasos2.c b/hw/ppc/pegasos2.c
index bd397cf2b5..3203a4a728 100644
--- a/hw/ppc/pegasos2.c
+++ b/hw/ppc/pegasos2.c
@@ -180,8 +180,15 @@ static void pegasos2_init(MachineState *machine)
pci_bus_irqs(pci_bus, pegasos2_pci_irq, pm, PCI_NUM_PINS);
/* VIA VT8231 South Bridge (multifunction PCI device) */
- via = OBJECT(pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0),
- TYPE_VT8231_ISA));
+ via = OBJECT(pci_new_multifunction(PCI_DEVFN(12, 0), TYPE_VT8231_ISA));
+
+ /* Set properties on individual devices before realizing the south bridge */
+ if (machine->audiodev) {
+ dev = PCI_DEVICE(object_resolve_path_component(via, "ac97"));
+ qdev_prop_set_string(DEVICE(dev), "audiodev", machine->audiodev);
+ }
+
+ pci_realize_and_unref(PCI_DEVICE(via), pci_bus, &error_abort);
for (i = 0; i < PCI_NUM_PINS; i++) {
pm->via_pirq[i] = qdev_get_gpio_in_named(DEVICE(via), "pirq", i);
}
@@ -556,6 +563,7 @@ static void pegasos2_machine_class_init(ObjectClass *oc, void *data)
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("7457_v1.2");
mc->default_ram_id = "pegasos2.ram";
mc->default_ram_size = 512 * MiB;
+ machine_add_audiodev_property(mc);
vhc->cpu_in_nested = pegasos2_cpu_in_nested;
vhc->hypercall = pegasos2_hypercall;
diff --git a/hw/ppc/prep.c b/hw/ppc/prep.c
index f6fd35fcb9..137276bcb9 100644
--- a/hw/ppc/prep.c
+++ b/hw/ppc/prep.c
@@ -45,6 +45,7 @@
#include "trace.h"
#include "elf.h"
#include "qemu/units.h"
+#include "audio/audio.h"
/* SMP is not enabled, for now */
#define MAX_CPUS 1
@@ -310,6 +311,10 @@ static void ibm_40p_init(MachineState *machine)
dev = DEVICE(isa_dev);
qdev_prop_set_uint32(dev, "iobase", 0x830);
qdev_prop_set_uint32(dev, "irq", 10);
+
+ if (machine->audiodev) {
+ qdev_prop_set_string(dev, "audiodev", machine->audiodev);
+ }
isa_realize_and_unref(isa_dev, isa_bus, &error_fatal);
isa_dev = isa_new("pc87312");
@@ -426,6 +431,8 @@ static void ibm_40p_machine_init(MachineClass *mc)
mc->default_cpu_type = POWERPC_CPU_TYPE_NAME("604");
mc->default_display = "std";
mc->default_nic = "pcnet";
+
+ machine_add_audiodev_property(mc);
}
DEFINE_MACHINE("40p", ibm_40p_machine_init)
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index e52188d022..9b11d8c573 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -759,7 +759,8 @@ static void esp_do_nodma(ESPState *s)
}
if (to_device) {
- len = MIN(fifo8_num_used(&s->fifo), ESP_FIFO_SZ);
+ len = MIN(s->async_len, ESP_FIFO_SZ);
+ len = MIN(len, fifo8_num_used(&s->fifo));
esp_fifo_pop_buf(&s->fifo, s->async_buf, len);
s->async_buf += len;
s->async_len -= len;
@@ -1395,7 +1396,7 @@ static void sysbus_esp_gpio_demux(void *opaque, int irq, int level)
parent_esp_reset(s, irq, level);
break;
case 1:
- esp_dma_enable(opaque, irq, level);
+ esp_dma_enable(s, irq, level);
break;
}
}
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 477ee2bcd4..6691f5edb8 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -1959,6 +1959,10 @@ static void scsi_disk_emulate_write_data(SCSIRequest *req)
scsi_disk_emulate_write_same(r, r->iov.iov_base);
break;
+ case FORMAT_UNIT:
+ scsi_req_complete(&r->req, GOOD);
+ break;
+
default:
abort();
}
diff --git a/hw/usb/dev-audio.c b/hw/usb/dev-audio.c
index 8748c1ba04..d5ac1f8962 100644
--- a/hw/usb/dev-audio.c
+++ b/hw/usb/dev-audio.c
@@ -944,12 +944,15 @@ static void usb_audio_realize(USBDevice *dev, Error **errp)
USBAudioState *s = USB_AUDIO(dev);
int i;
+ if (!AUD_register_card(TYPE_USB_AUDIO, &s->card, errp)) {
+ return;
+ }
+
dev->usb_desc = s->multi ? &desc_audio_multi : &desc_audio;
usb_desc_create_serial(dev);
usb_desc_init(dev);
s->dev.opaque = s;
- AUD_register_card(TYPE_USB_AUDIO, &s->card);
s->out.altset = ALTSET_OFF;
s->out.vol.mute = false;
diff --git a/include/hw/boards.h b/include/hw/boards.h
index 6c67af196a..55a64a13fd 100644
--- a/include/hw/boards.h
+++ b/include/hw/boards.h
@@ -24,6 +24,7 @@ OBJECT_DECLARE_TYPE(MachineState, MachineClass, MACHINE)
extern MachineState *current_machine;
+void machine_add_audiodev_property(MachineClass *mc);
void machine_run_board_init(MachineState *machine, const char *mem_path, Error **errp);
bool machine_usb(MachineState *machine);
int machine_phandle_start(MachineState *machine);
@@ -358,6 +359,14 @@ struct MachineState {
MemoryRegion *ram;
DeviceMemoryState *device_memory;
+ /*
+ * Included in MachineState for simplicity, but not supported
+ * unless machine_add_audiodev_property is called. Boards
+ * that have embedded audio devices can call it from the
+ * machine init function and forward the property to the device.
+ */
+ char *audiodev;
+
ram_addr_t ram_size;
ram_addr_t maxram_size;
uint64_t ram_slots;
diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
index 1d98bbfe0d..bafcbe6752 100644
--- a/include/hw/pci-host/q35.h
+++ b/include/hw/pci-host/q35.h
@@ -54,7 +54,6 @@ struct MCHPCIState {
uint64_t below_4g_mem_size;
uint64_t above_4g_mem_size;
uint64_t pci_hole64_size;
- uint32_t short_root_bus;
uint16_t ext_tseg_mbytes;
};
diff --git a/meson.build b/meson.build
index 5139db2ff7..21a1bc03f8 100644
--- a/meson.build
+++ b/meson.build
@@ -3070,6 +3070,9 @@ if fdt_required.length() > 0 or fdt_opt == 'enabled'
endif
if fdt_opt in ['enabled', 'auto', 'system']
+ if get_option('wrap_mode') == 'nodownload'
+ fdt_opt = 'system'
+ endif
fdt = cc.find_library('fdt', required: fdt_opt == 'system')
if fdt.found() and cc.links('''
#include <libfdt.h>
@@ -3177,7 +3180,6 @@ foreach d : hx_headers
input: files(d[0]),
output: d[1],
capture: true,
- build_by_default: true, # to be removed when added to a target
command: [hxtool, '-h', '@INPUT0@'])
endforeach
genh += hxdep
@@ -3363,12 +3365,15 @@ endif
qom_ss = qom_ss.apply(config_targetos, strict: false)
libqom = static_library('qom', qom_ss.sources() + genh,
dependencies: [qom_ss.dependencies()],
- name_suffix: 'fa')
+ name_suffix: 'fa',
+ build_by_default: false)
qom = declare_dependency(link_whole: libqom)
event_loop_base = files('event-loop-base.c')
-event_loop_base = static_library('event-loop-base', sources: event_loop_base + genh,
- build_by_default: true)
+event_loop_base = static_library('event-loop-base',
+ sources: event_loop_base + genh,
+ name_suffix: 'fa',
+ build_by_default: false)
event_loop_base = declare_dependency(link_whole: event_loop_base,
dependencies: [qom])
@@ -3377,6 +3382,7 @@ stub_ss = stub_ss.apply(config_all, strict: false)
util_ss.add_all(trace_ss)
util_ss = util_ss.apply(config_all, strict: false)
libqemuutil = static_library('qemuutil',
+ build_by_default: false,
sources: util_ss.sources() + stub_ss.sources() + genh,
dependencies: [util_ss.dependencies(), libm, threads, glib, socket, malloc, pixman])
qemuutil = declare_dependency(link_with: libqemuutil,
diff --git a/pc-bios/optionrom/Makefile b/pc-bios/optionrom/Makefile
index b1fff0ba6c..30d07026c7 100644
--- a/pc-bios/optionrom/Makefile
+++ b/pc-bios/optionrom/Makefile
@@ -36,7 +36,7 @@ config-cc.mak: Makefile
$(call cc-option,-Wno-array-bounds)) 3> config-cc.mak
-include config-cc.mak
-override LDFLAGS = -nostdlib -Wl,-T,$(SRC_DIR)/flat.lds
+override LDFLAGS = -nostdlib -Wl,--build-id=none,-T,$(SRC_DIR)/flat.lds
pvh.img: pvh.o pvh_main.o
diff --git a/qemu-options.hx b/qemu-options.hx
index bcd77255cb..9ce8a5b957 100644
--- a/qemu-options.hx
+++ b/qemu-options.hx
@@ -727,16 +727,6 @@ SRST
ERST
-HXCOMM Deprecated by -audiodev
-DEF("audio-help", 0, QEMU_OPTION_audio_help,
- "-audio-help show -audiodev equivalent of the currently specified audio settings\n",
- QEMU_ARCH_ALL)
-SRST
-``-audio-help``
- Will show the -audiodev equivalent of the currently specified
- (deprecated) environment variables.
-ERST
-
DEF("audio", HAS_ARG, QEMU_OPTION_audio,
"-audio [driver=]driver,model=value[,prop[=value][,...]]\n"
" specifies the audio backend and device to use;\n"
diff --git a/scripts/archive-source.sh b/scripts/archive-source.sh
index 4899630491..65af8063e4 100755
--- a/scripts/archive-source.sh
+++ b/scripts/archive-source.sh
@@ -26,7 +26,7 @@ sub_file="${sub_tdir}/submodule.tar"
# independent of what the developer currently has initialized
# in their checkout, because the build environment is completely
# different to the host OS.
-subprojects="dtc keycodemapdb libvfio-user berkeley-softfloat-3 berkeley-testfloat-3"
+subprojects="keycodemapdb libvfio-user berkeley-softfloat-3 berkeley-testfloat-3"
sub_deinit=""
function cleanup() {
diff --git a/scripts/make-release b/scripts/make-release
index c5db87b3f9..9c570b87f4 100755
--- a/scripts/make-release
+++ b/scripts/make-release
@@ -17,7 +17,7 @@ if [ $# -ne 2 ]; then
fi
# Only include wraps that are invoked with subproject()
-SUBPROJECTS="dtc libvfio-user keycodemapdb berkeley-softfloat-3 berkeley-testfloat-3"
+SUBPROJECTS="libvfio-user keycodemapdb berkeley-softfloat-3 berkeley-testfloat-3"
src="$1"
version="$2"
diff --git a/softmmu/vl.c b/softmmu/vl.c
index 59a472a0b1..98e071e63b 100644
--- a/softmmu/vl.c
+++ b/softmmu/vl.c
@@ -1962,9 +1962,7 @@ static void qemu_create_early_backends(void)
* setting machine properties, so they can be referred to.
*/
configure_blockdev(&bdo_queue, machine_class, snapshot);
- if (!audio_init_audiodevs()) {
- exit(1);
- }
+ audio_init_audiodevs();
}
@@ -2926,10 +2924,6 @@ void qemu_init(int argc, char **argv)
}
break;
#endif
- case QEMU_OPTION_audio_help:
- audio_legacy_help();
- exit (0);
- break;
case QEMU_OPTION_audiodev:
audio_parse_option(optarg);
break;
diff --git a/tcg/meson.build b/tcg/meson.build
index 0014dca7d4..4be4a616ca 100644
--- a/tcg/meson.build
+++ b/tcg/meson.build
@@ -28,7 +28,7 @@ libtcg_user = static_library('tcg_user',
tcg_ss.sources() + genh,
name_suffix: 'fa',
c_args: '-DCONFIG_USER_ONLY',
- build_by_default: have_user)
+ build_by_default: false)
tcg_user = declare_dependency(link_with: libtcg_user,
dependencies: tcg_ss.dependencies())
@@ -38,7 +38,7 @@ libtcg_softmmu = static_library('tcg_softmmu',
tcg_ss.sources() + genh,
name_suffix: 'fa',
c_args: '-DCONFIG_SOFTMMU',
- build_by_default: have_system)
+ build_by_default: false)
tcg_softmmu = declare_dependency(link_with: libtcg_softmmu,
dependencies: tcg_ss.dependencies())
diff --git a/tests/Makefile.include b/tests/Makefile.include
index 3898742659..dab1989a07 100644
--- a/tests/Makefile.include
+++ b/tests/Makefile.include
@@ -73,7 +73,7 @@ $(TCG_TESTS_TARGETS:%=distclean-tcg-tests-%): distclean-tcg-tests-%:
build-tcg: $(BUILD_TCG_TARGET_RULES)
.PHONY: check-tcg
-.ninja-goals.check-tcg = all
+.ninja-goals.check-tcg = all test-plugins
check-tcg: $(RUN_TCG_TARGET_RULES)
.PHONY: clean-tcg
diff --git a/tests/meson.build b/tests/meson.build
index debaa4505e..9996a293fb 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -80,10 +80,7 @@ if 'CONFIG_TCG' in config_all
subdir('fp')
endif
-if get_option('plugins')
- subdir('plugin')
-endif
-
+subdir('plugin')
subdir('unit')
subdir('qapi-schema')
subdir('qtest')
diff --git a/tests/plugin/meson.build b/tests/plugin/meson.build
index 2bbfc4b19e..322cafcdf6 100644
--- a/tests/plugin/meson.build
+++ b/tests/plugin/meson.build
@@ -1,7 +1,13 @@
t = []
-foreach i : ['bb', 'empty', 'insn', 'mem', 'syscall']
- t += shared_module(i, files(i + '.c'),
- include_directories: '../../include/qemu',
- dependencies: glib)
-endforeach
-alias_target('test-plugins', t)
+if get_option('plugins')
+ foreach i : ['bb', 'empty', 'insn', 'mem', 'syscall']
+ t += shared_module(i, files(i + '.c'),
+ include_directories: '../../include/qemu',
+ dependencies: glib)
+ endforeach
+endif
+if t.length() > 0
+ alias_target('test-plugins', t)
+else
+ run_target('test-plugins', command: find_program('true'))
+endif
diff --git a/ui/dbus.c b/ui/dbus.c
index 32f1bbe81a..866467ad2e 100644
--- a/ui/dbus.c
+++ b/ui/dbus.c
@@ -220,9 +220,8 @@ dbus_display_complete(UserCreatable *uc, Error **errp)
}
if (dd->audiodev && *dd->audiodev) {
- AudioState *audio_state = audio_state_by_name(dd->audiodev);
+ AudioState *audio_state = audio_state_by_name(dd->audiodev, errp);
if (!audio_state) {
- error_setg(errp, "Audiodev '%s' not found", dd->audiodev);
return;
}
if (!g_str_equal(audio_state->drv->name, "dbus")) {
diff --git a/ui/vnc.c b/ui/vnc.c
index 523eb1f5b0..acbb88c4ca 100644
--- a/ui/vnc.c
+++ b/ui/vnc.c
@@ -2195,7 +2195,10 @@ static void set_encodings(VncState *vs, int32_t *encodings, size_t n_encodings)
send_ext_key_event_ack(vs);
break;
case VNC_ENCODING_AUDIO:
- send_ext_audio_ack(vs);
+ if (vs->vd->audio_state) {
+ vs->features |= VNC_FEATURE_AUDIO_MASK;
+ send_ext_audio_ack(vs);
+ }
break;
case VNC_ENCODING_WMVi:
vs->features |= VNC_FEATURE_WMVI_MASK;
@@ -2502,6 +2505,12 @@ static int protocol_client_msg(VncState *vs, uint8_t *data, size_t len)
read_u32(data, 4), read_u32(data, 8));
break;
case VNC_MSG_CLIENT_QEMU_AUDIO:
+ if (!vnc_has_feature(vs, VNC_FEATURE_AUDIO)) {
+ error_report("Audio message %d with audio disabled", read_u8(data, 2));
+ vnc_client_error(vs);
+ break;
+ }
+
if (len == 2)
return 4;
@@ -4172,9 +4181,8 @@ void vnc_display_open(const char *id, Error **errp)
audiodev = qemu_opt_get(opts, "audiodev");
if (audiodev) {
- vd->audio_state = audio_state_by_name(audiodev);
+ vd->audio_state = audio_state_by_name(audiodev, errp);
if (!vd->audio_state) {
- error_setg(errp, "Audiodev '%s' not found", audiodev);
goto fail;
}
}
diff --git a/ui/vnc.h b/ui/vnc.h
index 757fa83044..96d19dce19 100644
--- a/ui/vnc.h
+++ b/ui/vnc.h
@@ -464,6 +464,7 @@ enum VncFeatures {
VNC_FEATURE_LED_STATE,
VNC_FEATURE_XVP,
VNC_FEATURE_CLIPBOARD_EXT,
+ VNC_FEATURE_AUDIO,
};
#define VNC_FEATURE_RESIZE_MASK (1 << VNC_FEATURE_RESIZE)
@@ -481,6 +482,7 @@ enum VncFeatures {
#define VNC_FEATURE_LED_STATE_MASK (1 << VNC_FEATURE_LED_STATE)
#define VNC_FEATURE_XVP_MASK (1 << VNC_FEATURE_XVP)
#define VNC_FEATURE_CLIPBOARD_EXT_MASK (1 << VNC_FEATURE_CLIPBOARD_EXT)
+#define VNC_FEATURE_AUDIO_MASK (1 << VNC_FEATURE_AUDIO)
/* Client -> Server message IDs */