radio-tavarua: Fix corner cases in dqbuf
- Sometimes user data getting corrupted and it is not available
at the kernel level
- Use the kernel buffer instead of user space buffer to copy
the data from fifo.
- Increase the STD_BUF_SIZE buffer size from 64 to 128 bytes
CRs-Fixed: 344443
Change-Id: Ibb8c60f18b72cbcd63c2f39eb49fbbadb7af5443
Signed-off-by: Venkateshwarlu Domakonda <Venkateshwarlu@codeaurora.org>
diff --git a/drivers/media/radio/radio-tavarua.c b/drivers/media/radio/radio-tavarua.c
index acf551e..61c07fb 100644
--- a/drivers/media/radio/radio-tavarua.c
+++ b/drivers/media/radio/radio-tavarua.c
@@ -3561,14 +3561,21 @@
{
struct tavarua_device *radio = video_get_drvdata(video_devdata(file));
- enum tavarua_buf_t buf_type = buffer->index;
- struct kfifo *data_fifo;
- unsigned char *buf = (unsigned char *)buffer->m.userptr;
- unsigned int len = buffer->length;
+ enum tavarua_buf_t buf_type = -1;
+ unsigned char buf_fifo[STD_BUF_SIZE] = {0};
+ struct kfifo *data_fifo = NULL;
+ unsigned char *buf = NULL;
+ unsigned int len = 0, retval = -1;
+
+ if ((radio == NULL) || (buffer == NULL)) {
+ FMDERR("radio/buffer is NULL\n");
+ return -ENXIO;
+ }
+ buf_type = buffer->index;
+ buf = (unsigned char *)buffer->m.userptr;
+ len = buffer->length;
FMDBG("%s: requesting buffer %d\n", __func__, buf_type);
- /* check if we can access the user buffer */
- if (!access_ok(VERIFY_WRITE, buf, len))
- return -EFAULT;
+
if ((buf_type < TAVARUA_BUF_MAX) && (buf_type >= 0)) {
data_fifo = &radio->data_buf[buf_type];
if (buf_type == TAVARUA_BUF_EVENTS) {
@@ -3581,10 +3588,20 @@
FMDERR("invalid buffer type\n");
return -EINVAL;
}
- buffer->bytesused = kfifo_out_locked(data_fifo, buf, len,
- &radio->buf_lock[buf_type]);
+ if (len <= STD_BUF_SIZE) {
+ buffer->bytesused = kfifo_out_locked(data_fifo, &buf_fifo[0],
+ len, &radio->buf_lock[buf_type]);
+ } else {
+ FMDERR("kfifo_out_locked can not use len more than 128\n");
+ return -EINVAL;
+ }
+ retval = copy_to_user(buf, &buf_fifo[0], buffer->bytesused);
+ if (retval > 0) {
+ FMDERR("Failed to copy %d bytes of data\n", retval);
+ return -EAGAIN;
+ }
- return 0;
+ return retval;
}
/*=============================================================================