Commit d3c5e707 authored by Andy Walls's avatar Andy Walls Committed by Mauro Carvalho Chehab

V4L/DVB (8773): cx18: Fix cx18_find_handle() and add error checking

cx18: Fix cx18_find_handle() and add error checking.  cx18_find_handle() did
not find a good task handle and would use the invalid task handle under common
conditions.  Added a define for the invalid task handle and added error checking
as well.
Signed-off-by: default avatarAndy Walls <awalls@radix.net>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent b04bce47
...@@ -236,6 +236,8 @@ struct cx18_dvb { ...@@ -236,6 +236,8 @@ struct cx18_dvb {
struct cx18; /* forward reference */ struct cx18; /* forward reference */
struct cx18_scb; /* forward reference */ struct cx18_scb; /* forward reference */
#define CX18_INVALID_TASK_HANDLE 0xffffffff
struct cx18_stream { struct cx18_stream {
/* These first four fields are always set, even if the stream /* These first four fields are always set, even if the stream
is not actually created. */ is not actually created. */
......
...@@ -132,6 +132,7 @@ static void cx18_dualwatch(struct cx18 *cx) ...@@ -132,6 +132,7 @@ static void cx18_dualwatch(struct cx18 *cx)
u16 new_stereo_mode; u16 new_stereo_mode;
const u16 stereo_mask = 0x0300; const u16 stereo_mask = 0x0300;
const u16 dual = 0x0200; const u16 dual = 0x0200;
u32 h;
new_stereo_mode = cx->params.audio_properties & stereo_mask; new_stereo_mode = cx->params.audio_properties & stereo_mask;
memset(&vt, 0, sizeof(vt)); memset(&vt, 0, sizeof(vt));
...@@ -143,13 +144,21 @@ static void cx18_dualwatch(struct cx18 *cx) ...@@ -143,13 +144,21 @@ static void cx18_dualwatch(struct cx18 *cx)
if (new_stereo_mode == cx->dualwatch_stereo_mode) if (new_stereo_mode == cx->dualwatch_stereo_mode)
return; return;
new_bitmap = new_stereo_mode | (cx->params.audio_properties & ~stereo_mask); new_bitmap = new_stereo_mode
| (cx->params.audio_properties & ~stereo_mask);
CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x. new audio_bitmask=0x%ux\n", CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x. "
cx->dualwatch_stereo_mode, new_stereo_mode, new_bitmap); "new audio_bitmask=0x%ux\n",
cx->dualwatch_stereo_mode, new_stereo_mode, new_bitmap);
if (cx18_vapi(cx, CX18_CPU_SET_AUDIO_PARAMETERS, 2, h = cx18_find_handle(cx);
cx18_find_handle(cx), new_bitmap) == 0) { if (h == CX18_INVALID_TASK_HANDLE) {
CX18_DEBUG_INFO("dualwatch: can't find valid task handle\n");
return;
}
if (cx18_vapi(cx,
CX18_CPU_SET_AUDIO_PARAMETERS, 2, h, new_bitmap) == 0) {
cx->dualwatch_stereo_mode = new_stereo_mode; cx->dualwatch_stereo_mode = new_stereo_mode;
return; return;
} }
...@@ -695,20 +704,28 @@ int cx18_v4l2_open(struct inode *inode, struct file *filp) ...@@ -695,20 +704,28 @@ int cx18_v4l2_open(struct inode *inode, struct file *filp)
void cx18_mute(struct cx18 *cx) void cx18_mute(struct cx18 *cx)
{ {
if (atomic_read(&cx->ana_capturing)) u32 h;
cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, if (atomic_read(&cx->ana_capturing)) {
cx18_find_handle(cx), 1); h = cx18_find_handle(cx);
if (h != CX18_INVALID_TASK_HANDLE)
cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 1);
else
CX18_ERR("Can't find valid task handle for mute\n");
}
CX18_DEBUG_INFO("Mute\n"); CX18_DEBUG_INFO("Mute\n");
} }
void cx18_unmute(struct cx18 *cx) void cx18_unmute(struct cx18 *cx)
{ {
u32 h;
if (atomic_read(&cx->ana_capturing)) { if (atomic_read(&cx->ana_capturing)) {
cx18_msleep_timeout(100, 0); h = cx18_find_handle(cx);
cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, if (h != CX18_INVALID_TASK_HANDLE) {
cx18_find_handle(cx), 12); cx18_msleep_timeout(100, 0);
cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, h, 12);
cx18_find_handle(cx), 0); cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 0);
} else
CX18_ERR("Can't find valid task handle for unmute\n");
} }
CX18_DEBUG_INFO("Unmute\n"); CX18_DEBUG_INFO("Unmute\n");
} }
...@@ -622,6 +622,7 @@ static int cx18_encoder_cmd(struct file *file, void *fh, ...@@ -622,6 +622,7 @@ static int cx18_encoder_cmd(struct file *file, void *fh,
{ {
struct cx18_open_id *id = fh; struct cx18_open_id *id = fh;
struct cx18 *cx = id->cx; struct cx18 *cx = id->cx;
u32 h;
switch (enc->cmd) { switch (enc->cmd) {
case V4L2_ENC_CMD_START: case V4L2_ENC_CMD_START:
...@@ -643,8 +644,14 @@ static int cx18_encoder_cmd(struct file *file, void *fh, ...@@ -643,8 +644,14 @@ static int cx18_encoder_cmd(struct file *file, void *fh,
return -EPERM; return -EPERM;
if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
return 0; return 0;
h = cx18_find_handle(cx);
if (h == CX18_INVALID_TASK_HANDLE) {
CX18_ERR("Can't find valid task handle for "
"V4L2_ENC_CMD_PAUSE\n");
return -EBADFD;
}
cx18_mute(cx); cx18_mute(cx);
cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, cx18_find_handle(cx)); cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, h);
break; break;
case V4L2_ENC_CMD_RESUME: case V4L2_ENC_CMD_RESUME:
...@@ -654,7 +661,13 @@ static int cx18_encoder_cmd(struct file *file, void *fh, ...@@ -654,7 +661,13 @@ static int cx18_encoder_cmd(struct file *file, void *fh,
return -EPERM; return -EPERM;
if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags))
return 0; return 0;
cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, cx18_find_handle(cx)); h = cx18_find_handle(cx);
if (h == CX18_INVALID_TASK_HANDLE) {
CX18_ERR("Can't find valid task handle for "
"V4L2_ENC_CMD_RESUME\n");
return -EBADFD;
}
cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, h);
cx18_unmute(cx); cx18_unmute(cx);
break; break;
......
...@@ -119,7 +119,7 @@ static void cx18_stream_init(struct cx18 *cx, int type) ...@@ -119,7 +119,7 @@ static void cx18_stream_init(struct cx18 *cx, int type)
s->cx = cx; s->cx = cx;
s->type = type; s->type = type;
s->name = cx18_stream_info[type].name; s->name = cx18_stream_info[type].name;
s->handle = 0xffffffff; s->handle = CX18_INVALID_TASK_HANDLE;
s->dma = cx18_stream_info[type].dma; s->dma = cx18_stream_info[type].dma;
s->buf_size = cx->stream_buf_size[type]; s->buf_size = cx->stream_buf_size[type];
...@@ -548,7 +548,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end) ...@@ -548,7 +548,7 @@ int cx18_stop_v4l2_encode_stream(struct cx18_stream *s, int gop_end)
clear_bit(CX18_F_S_STREAMING, &s->s_flags); clear_bit(CX18_F_S_STREAMING, &s->s_flags);
cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle);
s->handle = 0xffffffff; s->handle = CX18_INVALID_TASK_HANDLE;
if (atomic_read(&cx->tot_capturing) > 0) if (atomic_read(&cx->tot_capturing) > 0)
return 0; return 0;
...@@ -567,8 +567,8 @@ u32 cx18_find_handle(struct cx18 *cx) ...@@ -567,8 +567,8 @@ u32 cx18_find_handle(struct cx18 *cx)
for (i = 0; i < CX18_MAX_STREAMS; i++) { for (i = 0; i < CX18_MAX_STREAMS; i++) {
struct cx18_stream *s = &cx->streams[i]; struct cx18_stream *s = &cx->streams[i];
if (s->v4l2dev && s->handle) if (s->v4l2dev && (s->handle != CX18_INVALID_TASK_HANDLE))
return s->handle; return s->handle;
} }
return 0; return CX18_INVALID_TASK_HANDLE;
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment