diff options
author | Michael Zoran <mzoran@crowfest.net> | 2017-01-28 21:39:45 -0800 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-01-31 10:47:00 +0100 |
commit | 0cec463e391e05b807a5114e9f0635e4980b805e (patch) | |
tree | 849108b90589f627f3c6e40f166baad3c16f287f /drivers/staging/bcm2835-audio/bcm2835-vchiq.c | |
parent | 9c4f728693f7384144bb13dcd65dd8f6997e29e8 (diff) | |
download | op-kernel-dev-0cec463e391e05b807a5114e9f0635e4980b805e.zip op-kernel-dev-0cec463e391e05b807a5114e9f0635e4980b805e.tar.gz |
staging: bcm2835-audio: Simplify callback structure for write data
The device sends data to the audio devices by sending a message with
the data through VC04_SERVICES/VCHIQ. This message contains a
callback pointer that is always filled in with the same function.
This is prone to corruption issues.
Instead fill the callback fields with a fixed cookie value to perforam
some validation on the message response and call the handler function
directly instead of through the callback pointer.
Signed-off-by: Michael Zoran <mzoran@crowfest.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/staging/bcm2835-audio/bcm2835-vchiq.c')
-rw-r--r-- | drivers/staging/bcm2835-audio/bcm2835-vchiq.c | 35 |
1 files changed, 16 insertions, 19 deletions
diff --git a/drivers/staging/bcm2835-audio/bcm2835-vchiq.c b/drivers/staging/bcm2835-audio/bcm2835-vchiq.c index af70c27..e8fd9c7 100644 --- a/drivers/staging/bcm2835-audio/bcm2835-vchiq.c +++ b/drivers/staging/bcm2835-audio/bcm2835-vchiq.c @@ -100,6 +100,11 @@ bcm2835_vchi_msg_queue(VCHI_SERVICE_HANDLE_T handle, size); } +static const u32 BCM2835_AUDIO_WRITE_COOKIE1 = ('B' << 24 | 'C' << 16 || + 'M' << 8 | 'A'); +static const u32 BCM2835_AUDIO_WRITE_COOKIE2 = ('D' << 24 | 'A' << 16 || + 'T' << 8 | 'A'); + struct bcm2835_audio_work { struct work_struct my_work; struct bcm2835_alsa_stream *alsa_stream; @@ -248,21 +253,18 @@ static void audio_vchi_callback(void *param, complete(&instance->msg_avail_comp); } else if (m.type == VC_AUDIO_MSG_TYPE_COMPLETE) { struct bcm2835_alsa_stream *alsa_stream = instance->alsa_stream; -#if defined(CONFIG_64BIT) - irq_handler_t callback = - (irq_handler_t) (((unsigned long) m.u.complete.callbackl) | - ((unsigned long) m.u.complete.callbackh << 32)); -#else - irq_handler_t callback = (irq_handler_t) m.u.complete.callback; -#endif LOG_DBG(" .. instance=%p, m.type=VC_AUDIO_MSG_TYPE_COMPLETE, complete=%d\n", instance, m.u.complete.count); - if (alsa_stream && callback) { - atomic_add(m.u.complete.count, &alsa_stream->retrieved); - callback(0, alsa_stream); + if (m.u.complete.cookie1 != BCM2835_AUDIO_WRITE_COOKIE1 || + m.u.complete.cookie2 != BCM2835_AUDIO_WRITE_COOKIE2) + LOG_ERR(" .. response is corrupt\n"); + else if (alsa_stream) { + atomic_add(m.u.complete.count, + &alsa_stream->retrieved); + bcm2835_playback_fifo(alsa_stream); } else { - LOG_ERR(" .. unexpected alsa_stream=%p, callback=%p\n", - alsa_stream, callback); + LOG_ERR(" .. unexpected alsa_stream=%p\n", + alsa_stream); } } else { LOG_ERR(" .. unexpected m.type=%d\n", m.type); @@ -815,13 +817,8 @@ int bcm2835_audio_write_worker(struct bcm2835_alsa_stream *alsa_stream, m.u.write.count = count; // old version uses bulk, new version uses control m.u.write.max_packet = instance->peer_version < 2 || force_bulk ? 0 : 4000; -#if defined(CONFIG_64BIT) - m.u.write.callbackl = (u32) (((unsigned long) alsa_stream->fifo_irq_handler)&0xFFFFFFFF); - m.u.write.callbackh = (u32) ((((unsigned long) alsa_stream->fifo_irq_handler) >> 32)&0xFFFFFFFF); -#else - m.u.write.callback = alsa_stream->fifo_irq_handler; - m.u.write.cookie = alsa_stream; -#endif + m.u.write.cookie1 = BCM2835_AUDIO_WRITE_COOKIE1; + m.u.write.cookie2 = BCM2835_AUDIO_WRITE_COOKIE2; m.u.write.silence = src == NULL; /* Send the message to the videocore */ |