Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/kraxel/tags/fixes-20190402-pull…
Browse files Browse the repository at this point in the history
…-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>
  • Loading branch information
pm215 committed Apr 2, 2019
2 parents 4717595 + be1092a commit d61d1a1
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 56 deletions.
2 changes: 1 addition & 1 deletion audio/audio.c
Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions audio/audio_legacy.c
Expand Up @@ -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"
Expand Down Expand Up @@ -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:
Expand Down
36 changes: 21 additions & 15 deletions hw/audio/pcspk.c
Expand Up @@ -57,6 +57,7 @@ typedef struct {
} PCSpkState;

static const char *s_spk = "pcspk";
static PCSpkState *pcspk_state;

static inline void generate_samples(PCSpkState *s)
{
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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 = {
Expand All @@ -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);
Expand Down
4 changes: 4 additions & 0 deletions hw/usb/bus.c
Expand Up @@ -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)
Expand Down
76 changes: 36 additions & 40 deletions hw/usb/dev-mtp.c
Expand Up @@ -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
Expand All @@ -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,
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit d61d1a1

Please sign in to comment.