aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2019-04-02 08:18:24 +0100
committerPeter Maydell <peter.maydell@linaro.org>2019-04-02 08:18:24 +0100
commitd61d1a1fb2f1db6c54651844a28389c523f3f8c7 (patch)
treeb2d1e8d86a7e4a7f7303872f39c605509d9602e6
parent47175951a691a8a2d483f0cbc7f31b4e3814bffa (diff)
parentbe1092afa07794e5247eb504095fb5f2ae421ec6 (diff)
Merge remote-tracking branch 'remotes/kraxel/tags/fixes-20190402-pull-request' into staging
fixes for 4.0 (audio, usb), # gpg: Signature made Tue 02 Apr 2019 07:46:22 BST # gpg: using RSA key 4CB6D8EED3E87138 # gpg: Good signature from "Gerd Hoffmann (work) <kraxel@redhat.com>" [full] # gpg: aka "Gerd Hoffmann <gerd@kraxel.org>" [full] # gpg: aka "Gerd Hoffmann (private) <kraxel@gmail.com>" [full] # Primary key fingerprint: A032 8CFF B93A 17A7 9901 FE7D 4CB6 D8EE D3E8 7138 * remotes/kraxel/tags/fixes-20190402-pull-request: audio: fix audio timer rate conversion bug usb-mtp: remove usb_mtp_object_free_one usb-mtp: fix return status of delete hw/usb/bus.c: Handle "no speed matched" case in usb_mask_to_str() Revert "audio: fix pc speaker init" Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
-rw-r--r--audio/audio.c2
-rw-r--r--audio/audio_legacy.c6
-rw-r--r--hw/audio/pcspk.c36
-rw-r--r--hw/usb/bus.c4
-rw-r--r--hw/usb/dev-mtp.c76
5 files changed, 68 insertions, 56 deletions
diff --git a/audio/audio.c b/audio/audio.c
index 5fd9a58a80..2040762fef 100644
--- a/audio/audio.c
+++ b/audio/audio.c
@@ -1471,7 +1471,7 @@ static int audio_init(Audiodev *dev)
if (dev->timer_period <= 0) {
s->period_ticks = 1;
} else {
- s->period_ticks = NANOSECONDS_PER_SECOND / dev->timer_period;
+ s->period_ticks = dev->timer_period * SCALE_US;
}
e = qemu_add_vm_change_state_handler (audio_vm_change_state_handler, s);
diff --git a/audio/audio_legacy.c b/audio/audio_legacy.c
index 6d140119d9..2fd58cb8ef 100644
--- a/audio/audio_legacy.c
+++ b/audio/audio_legacy.c
@@ -26,6 +26,7 @@
#include "audio_int.h"
#include "qemu-common.h"
#include "qemu/cutils.h"
+#include "qemu/timer.h"
#include "qapi/error.h"
#include "qapi/qapi-visit-audio.h"
#include "qapi/visitor-impl.h"
@@ -338,8 +339,13 @@ static AudiodevListEntry *legacy_opt(const char *drvname)
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) {
case AUDIODEV_DRIVER_ALSA:
diff --git a/hw/audio/pcspk.c b/hw/audio/pcspk.c
index fdbb4b6e99..9c7fd74aeb 100644
--- a/hw/audio/pcspk.c
+++ b/hw/audio/pcspk.c
@@ -57,6 +57,7 @@ typedef struct {
} PCSpkState;
static const char *s_spk = "pcspk";
+static PCSpkState *pcspk_state;
static inline void generate_samples(PCSpkState *s)
{
@@ -110,6 +111,22 @@ static void pcspk_callback(void *opaque, int free)
}
}
+static int pcspk_audio_init(ISABus *bus)
+{
+ PCSpkState *s = pcspk_state;
+ struct audsettings as = {PCSPK_SAMPLE_RATE, 1, AUDIO_FORMAT_U8, 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");
+ return -1;
+ }
+
+ return 0;
+}
+
static uint64_t pcspk_io_read(void *opaque, hwaddr addr,
unsigned size)
{
@@ -162,20 +179,12 @@ static void pcspk_initfn(Object *obj)
static void pcspk_realizefn(DeviceState *dev, Error **errp)
{
- struct audsettings as = {PCSPK_SAMPLE_RATE, 1, AUDIO_FORMAT_U8, 0};
ISADevice *isadev = ISA_DEVICE(dev);
PCSpkState *s = PC_SPEAKER(dev);
isa_register_ioport(isadev, &s->ioport, s->iobase);
- 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) {
- error_setg(errp, "Initializing audio voice failed");
- AUD_remove_card(&s->card);
- return;
- }
+ pcspk_state = s;
}
static bool migrate_needed(void *opaque)
@@ -212,6 +221,9 @@ static void pcspk_class_initfn(ObjectClass *klass, void *data)
set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->vmsd = &vmstate_spk;
dc->props = pcspk_properties;
+ /* Reason: realize sets global pcspk_state */
+ /* Reason: pit object link */
+ dc->user_creatable = false;
}
static const TypeInfo pcspk_info = {
@@ -222,12 +234,6 @@ static const TypeInfo pcspk_info = {
.class_init = pcspk_class_initfn,
};
-static int pcspk_audio_init(ISABus *bus)
-{
- isa_create_simple(bus, TYPE_PC_SPEAKER);
- return 0;
-}
-
static void pcspk_register(void)
{
type_register_static(&pcspk_info);
diff --git a/hw/usb/bus.c b/hw/usb/bus.c
index 6fffab7bfa..9a74dc9560 100644
--- a/hw/usb/bus.c
+++ b/hw/usb/bus.c
@@ -500,6 +500,10 @@ static void usb_mask_to_str(char *dest, size_t size,
speeds[i].name);
}
}
+
+ if (pos == 0) {
+ snprintf(dest, size, "unknown");
+ }
}
void usb_check_attach(USBDevice *dev, Error **errp)
diff --git a/hw/usb/dev-mtp.c b/hw/usb/dev-mtp.c
index 06e376bcd2..4dc1317e2e 100644
--- a/hw/usb/dev-mtp.c
+++ b/hw/usb/dev-mtp.c
@@ -1135,28 +1135,25 @@ static MTPData *usb_mtp_get_object_prop_value(MTPState *s, MTPControl *c,
return d;
}
-/* Return correct return code for a delete event */
+/*
+ * Return values when object @o is deleted.
+ * If at least one of the deletions succeeded,
+ * DELETE_SUCCESS is set and if at least one
+ * of the deletions failed, DELETE_FAILURE is
+ * set. Both bits being set (DELETE_PARTIAL)
+ * signifies a RES_PARTIAL_DELETE being sent
+ * back to the initiator.
+ */
enum {
- ALL_DELETE,
- PARTIAL_DELETE,
- READ_ONLY,
+ DELETE_SUCCESS = (1 << 0),
+ DELETE_FAILURE = (1 << 1),
+ DELETE_PARTIAL = (DELETE_FAILURE | DELETE_SUCCESS),
};
-/* Assumes that children, if any, have been already freed */
-static void usb_mtp_object_free_one(MTPState *s, MTPObject *o)
-{
- assert(o->nchildren == 0);
- QTAILQ_REMOVE(&s->objects, o, next);
- g_free(o->name);
- g_free(o->path);
- g_free(o);
-}
-
static int usb_mtp_deletefn(MTPState *s, MTPObject *o, uint32_t trans)
{
MTPObject *iter, *iter2;
- bool partial_delete = false;
- bool success = false;
+ int ret = 0;
/*
* TODO: Add support for Protection Status
@@ -1165,34 +1162,28 @@ static int usb_mtp_deletefn(MTPState *s, MTPObject *o, uint32_t trans)
QLIST_FOREACH(iter, &o->children, list) {
if (iter->format == FMT_ASSOCIATION) {
QLIST_FOREACH(iter2, &iter->children, list) {
- usb_mtp_deletefn(s, iter2, trans);
+ ret |= usb_mtp_deletefn(s, iter2, trans);
}
}
}
if (o->format == FMT_UNDEFINED_OBJECT) {
if (remove(o->path)) {
- partial_delete = true;
+ ret |= DELETE_FAILURE;
} else {
- usb_mtp_object_free_one(s, o);
- success = true;
+ usb_mtp_object_free(s, o);
+ ret |= DELETE_SUCCESS;
}
} else if (o->format == FMT_ASSOCIATION) {
if (rmdir(o->path)) {
- partial_delete = true;
+ ret |= DELETE_FAILURE;
} else {
- usb_mtp_object_free_one(s, o);
- success = true;
+ usb_mtp_object_free(s, o);
+ ret |= DELETE_SUCCESS;
}
}
- if (success && partial_delete) {
- return PARTIAL_DELETE;
- }
- if (!success && partial_delete) {
- return READ_ONLY;
- }
- return ALL_DELETE;
+ return ret;
}
static void usb_mtp_object_delete(MTPState *s, uint32_t handle,
@@ -1226,19 +1217,24 @@ static void usb_mtp_object_delete(MTPState *s, uint32_t handle,
}
ret = usb_mtp_deletefn(s, o, trans);
- if (ret == PARTIAL_DELETE) {
- usb_mtp_queue_result(s, RES_PARTIAL_DELETE,
- trans, 0, 0, 0, 0);
- return;
- } else if (ret == READ_ONLY) {
- usb_mtp_queue_result(s, RES_STORE_READ_ONLY, trans,
- 0, 0, 0, 0);
- return;
- } else {
+ switch (ret) {
+ case DELETE_SUCCESS:
usb_mtp_queue_result(s, RES_OK, trans,
0, 0, 0, 0);
- return;
+ break;
+ case DELETE_FAILURE:
+ usb_mtp_queue_result(s, RES_PARTIAL_DELETE,
+ trans, 0, 0, 0, 0);
+ break;
+ case DELETE_PARTIAL:
+ usb_mtp_queue_result(s, RES_PARTIAL_DELETE,
+ trans, 0, 0, 0, 0);
+ break;
+ default:
+ g_assert_not_reached();
}
+
+ return;
}
static void usb_mtp_command(MTPState *s, MTPControl *c)