Skip to content

Commit

Permalink
usbaudio: change playback counters to 64 bit
Browse files Browse the repository at this point in the history
With stereo playback, they need about 375 minutes of continuous audio
playback to overflow, which is usually not a problem (as stopping and
later resuming playback resets the counters).  But with 7.1 audio, they
only need about 95 minutes to overflow.

After the overflow, the buf->prod % USBAUDIO_PACKET_SIZE(channels)
assertion no longer holds true, which will result in overflowing the
buffer.  With 64 bit variables, it would take about 762000 years to
overflow.

Signed-off-by: Kővágó, Zoltán <DirtY.iCE.hu@gmail.com>
Message-id: ff866985ed369f1e18ea7c70da6a7fce8e241deb.1570996490.git.DirtY.iCE.hu@gmail.com
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
  • Loading branch information
DirtYiCE authored and kraxel committed Oct 18, 2019
1 parent 3e44607 commit 670777a
Showing 1 changed file with 8 additions and 6 deletions.
14 changes: 8 additions & 6 deletions hw/usb/dev-audio.c
Expand Up @@ -578,9 +578,9 @@ static const USBDesc desc_audio_multi = {

struct streambuf {
uint8_t *data;
uint32_t size;
uint32_t prod;
uint32_t cons;
size_t size;
uint64_t prod;
uint64_t cons;
};

static void streambuf_init(struct streambuf *buf, uint32_t size,
Expand All @@ -601,7 +601,7 @@ static void streambuf_fini(struct streambuf *buf)

static int streambuf_put(struct streambuf *buf, USBPacket *p, uint32_t channels)
{
uint32_t free = buf->size - (buf->prod - buf->cons);
int64_t free = buf->size - (buf->prod - buf->cons);

if (free < USBAUDIO_PACKET_SIZE(channels)) {
return 0;
Expand All @@ -610,6 +610,8 @@ static int streambuf_put(struct streambuf *buf, USBPacket *p, uint32_t channels)
return 0;
}

/* can happen if prod overflows */
assert(buf->prod % USBAUDIO_PACKET_SIZE(channels) == 0);
usb_packet_copy(p, buf->data + (buf->prod % buf->size),
USBAUDIO_PACKET_SIZE(channels));
buf->prod += USBAUDIO_PACKET_SIZE(channels);
Expand All @@ -618,10 +620,10 @@ static int streambuf_put(struct streambuf *buf, USBPacket *p, uint32_t channels)

static uint8_t *streambuf_get(struct streambuf *buf, size_t *len)
{
uint32_t used = buf->prod - buf->cons;
int64_t used = buf->prod - buf->cons;
uint8_t *data;

if (!used) {
if (used <= 0) {
*len = 0;
return NULL;
}
Expand Down

0 comments on commit 670777a

Please sign in to comment.