diff options
author | Andy Walls <awalls@radix.net> | 2008-08-23 15:42:29 -0400 |
---|---|---|
committer | Mauro Carvalho Chehab <mchehab@redhat.com> | 2008-10-12 07:36:53 -0400 |
commit | d3c5e7075508a6874d1a53d0a409b0bbbe3a9fbe (patch) | |
tree | a9e6884ac71641938abc1866e5d81f607bd5f907 /drivers/media | |
parent | b04bce476c57ac844962462ee4c813c44fa942cf (diff) |
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: Andy Walls <awalls@radix.net>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media')
-rw-r--r-- | drivers/media/video/cx18/cx18-driver.h | 2 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-fileops.c | 43 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-ioctl.c | 17 | ||||
-rw-r--r-- | drivers/media/video/cx18/cx18-streams.c | 8 |
4 files changed, 51 insertions, 19 deletions
diff --git a/drivers/media/video/cx18/cx18-driver.h b/drivers/media/video/cx18/cx18-driver.h index 8812a5ec635f..26359897d147 100644 --- a/drivers/media/video/cx18/cx18-driver.h +++ b/drivers/media/video/cx18/cx18-driver.h | |||
@@ -236,6 +236,8 @@ struct cx18_dvb { | |||
236 | struct cx18; /* forward reference */ | 236 | struct cx18; /* forward reference */ |
237 | struct cx18_scb; /* forward reference */ | 237 | struct cx18_scb; /* forward reference */ |
238 | 238 | ||
239 | #define CX18_INVALID_TASK_HANDLE 0xffffffff | ||
240 | |||
239 | struct cx18_stream { | 241 | struct cx18_stream { |
240 | /* These first four fields are always set, even if the stream | 242 | /* These first four fields are always set, even if the stream |
241 | is not actually created. */ | 243 | is not actually created. */ |
diff --git a/drivers/media/video/cx18/cx18-fileops.c b/drivers/media/video/cx18/cx18-fileops.c index eb0144f95562..5f9089907544 100644 --- a/drivers/media/video/cx18/cx18-fileops.c +++ b/drivers/media/video/cx18/cx18-fileops.c | |||
@@ -132,6 +132,7 @@ static void cx18_dualwatch(struct cx18 *cx) | |||
132 | u16 new_stereo_mode; | 132 | u16 new_stereo_mode; |
133 | const u16 stereo_mask = 0x0300; | 133 | const u16 stereo_mask = 0x0300; |
134 | const u16 dual = 0x0200; | 134 | const u16 dual = 0x0200; |
135 | u32 h; | ||
135 | 136 | ||
136 | new_stereo_mode = cx->params.audio_properties & stereo_mask; | 137 | new_stereo_mode = cx->params.audio_properties & stereo_mask; |
137 | memset(&vt, 0, sizeof(vt)); | 138 | memset(&vt, 0, sizeof(vt)); |
@@ -143,13 +144,21 @@ static void cx18_dualwatch(struct cx18 *cx) | |||
143 | if (new_stereo_mode == cx->dualwatch_stereo_mode) | 144 | if (new_stereo_mode == cx->dualwatch_stereo_mode) |
144 | return; | 145 | return; |
145 | 146 | ||
146 | new_bitmap = new_stereo_mode | (cx->params.audio_properties & ~stereo_mask); | 147 | new_bitmap = new_stereo_mode |
148 | | (cx->params.audio_properties & ~stereo_mask); | ||
147 | 149 | ||
148 | CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x. new audio_bitmask=0x%ux\n", | 150 | CX18_DEBUG_INFO("dualwatch: change stereo flag from 0x%x to 0x%x. " |
149 | cx->dualwatch_stereo_mode, new_stereo_mode, new_bitmap); | 151 | "new audio_bitmask=0x%ux\n", |
152 | cx->dualwatch_stereo_mode, new_stereo_mode, new_bitmap); | ||
150 | 153 | ||
151 | if (cx18_vapi(cx, CX18_CPU_SET_AUDIO_PARAMETERS, 2, | 154 | h = cx18_find_handle(cx); |
152 | cx18_find_handle(cx), new_bitmap) == 0) { | 155 | if (h == CX18_INVALID_TASK_HANDLE) { |
156 | CX18_DEBUG_INFO("dualwatch: can't find valid task handle\n"); | ||
157 | return; | ||
158 | } | ||
159 | |||
160 | if (cx18_vapi(cx, | ||
161 | CX18_CPU_SET_AUDIO_PARAMETERS, 2, h, new_bitmap) == 0) { | ||
153 | cx->dualwatch_stereo_mode = new_stereo_mode; | 162 | cx->dualwatch_stereo_mode = new_stereo_mode; |
154 | return; | 163 | return; |
155 | } | 164 | } |
@@ -695,20 +704,28 @@ int cx18_v4l2_open(struct inode *inode, struct file *filp) | |||
695 | 704 | ||
696 | void cx18_mute(struct cx18 *cx) | 705 | void cx18_mute(struct cx18 *cx) |
697 | { | 706 | { |
698 | if (atomic_read(&cx->ana_capturing)) | 707 | u32 h; |
699 | cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, | 708 | if (atomic_read(&cx->ana_capturing)) { |
700 | cx18_find_handle(cx), 1); | 709 | h = cx18_find_handle(cx); |
710 | if (h != CX18_INVALID_TASK_HANDLE) | ||
711 | cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 1); | ||
712 | else | ||
713 | CX18_ERR("Can't find valid task handle for mute\n"); | ||
714 | } | ||
701 | CX18_DEBUG_INFO("Mute\n"); | 715 | CX18_DEBUG_INFO("Mute\n"); |
702 | } | 716 | } |
703 | 717 | ||
704 | void cx18_unmute(struct cx18 *cx) | 718 | void cx18_unmute(struct cx18 *cx) |
705 | { | 719 | { |
720 | u32 h; | ||
706 | if (atomic_read(&cx->ana_capturing)) { | 721 | if (atomic_read(&cx->ana_capturing)) { |
707 | cx18_msleep_timeout(100, 0); | 722 | h = cx18_find_handle(cx); |
708 | cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, | 723 | if (h != CX18_INVALID_TASK_HANDLE) { |
709 | cx18_find_handle(cx), 12); | 724 | cx18_msleep_timeout(100, 0); |
710 | cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, | 725 | cx18_vapi(cx, CX18_CPU_SET_MISC_PARAMETERS, 2, h, 12); |
711 | cx18_find_handle(cx), 0); | 726 | cx18_vapi(cx, CX18_CPU_SET_AUDIO_MUTE, 2, h, 0); |
727 | } else | ||
728 | CX18_ERR("Can't find valid task handle for unmute\n"); | ||
712 | } | 729 | } |
713 | CX18_DEBUG_INFO("Unmute\n"); | 730 | CX18_DEBUG_INFO("Unmute\n"); |
714 | } | 731 | } |
diff --git a/drivers/media/video/cx18/cx18-ioctl.c b/drivers/media/video/cx18/cx18-ioctl.c index 5325c7aacaf3..84507a39f2b8 100644 --- a/drivers/media/video/cx18/cx18-ioctl.c +++ b/drivers/media/video/cx18/cx18-ioctl.c | |||
@@ -622,6 +622,7 @@ static int cx18_encoder_cmd(struct file *file, void *fh, | |||
622 | { | 622 | { |
623 | struct cx18_open_id *id = fh; | 623 | struct cx18_open_id *id = fh; |
624 | struct cx18 *cx = id->cx; | 624 | struct cx18 *cx = id->cx; |
625 | u32 h; | ||
625 | 626 | ||
626 | switch (enc->cmd) { | 627 | switch (enc->cmd) { |
627 | case V4L2_ENC_CMD_START: | 628 | case V4L2_ENC_CMD_START: |
@@ -643,8 +644,14 @@ static int cx18_encoder_cmd(struct file *file, void *fh, | |||
643 | return -EPERM; | 644 | return -EPERM; |
644 | if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) | 645 | if (test_and_set_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) |
645 | return 0; | 646 | return 0; |
647 | h = cx18_find_handle(cx); | ||
648 | if (h == CX18_INVALID_TASK_HANDLE) { | ||
649 | CX18_ERR("Can't find valid task handle for " | ||
650 | "V4L2_ENC_CMD_PAUSE\n"); | ||
651 | return -EBADFD; | ||
652 | } | ||
646 | cx18_mute(cx); | 653 | cx18_mute(cx); |
647 | cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, cx18_find_handle(cx)); | 654 | cx18_vapi(cx, CX18_CPU_CAPTURE_PAUSE, 1, h); |
648 | break; | 655 | break; |
649 | 656 | ||
650 | case V4L2_ENC_CMD_RESUME: | 657 | case V4L2_ENC_CMD_RESUME: |
@@ -654,7 +661,13 @@ static int cx18_encoder_cmd(struct file *file, void *fh, | |||
654 | return -EPERM; | 661 | return -EPERM; |
655 | if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) | 662 | if (!test_and_clear_bit(CX18_F_I_ENC_PAUSED, &cx->i_flags)) |
656 | return 0; | 663 | return 0; |
657 | cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, cx18_find_handle(cx)); | 664 | h = cx18_find_handle(cx); |
665 | if (h == CX18_INVALID_TASK_HANDLE) { | ||
666 | CX18_ERR("Can't find valid task handle for " | ||
667 | "V4L2_ENC_CMD_RESUME\n"); | ||
668 | return -EBADFD; | ||
669 | } | ||
670 | cx18_vapi(cx, CX18_CPU_CAPTURE_RESUME, 1, h); | ||
658 | cx18_unmute(cx); | 671 | cx18_unmute(cx); |
659 | break; | 672 | break; |
660 | 673 | ||
diff --git a/drivers/media/video/cx18/cx18-streams.c b/drivers/media/video/cx18/cx18-streams.c index 45dc6f399ed4..53c5852bba37 100644 --- a/drivers/media/video/cx18/cx18-streams.c +++ b/drivers/media/video/cx18/cx18-streams.c | |||
@@ -119,7 +119,7 @@ static void cx18_stream_init(struct cx18 *cx, int type) | |||
119 | s->cx = cx; | 119 | s->cx = cx; |
120 | s->type = type; | 120 | s->type = type; |
121 | s->name = cx18_stream_info[type].name; | 121 | s->name = cx18_stream_info[type].name; |
122 | s->handle = 0xffffffff; | 122 | s->handle = CX18_INVALID_TASK_HANDLE; |
123 | 123 | ||
124 | s->dma = cx18_stream_info[type].dma; | 124 | s->dma = cx18_stream_info[type].dma; |
125 | s->buf_size = cx->stream_buf_size[type]; | 125 | 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 | clear_bit(CX18_F_S_STREAMING, &s->s_flags); | 548 | clear_bit(CX18_F_S_STREAMING, &s->s_flags); |
549 | 549 | ||
550 | cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); | 550 | cx18_vapi(cx, CX18_DESTROY_TASK, 1, s->handle); |
551 | s->handle = 0xffffffff; | 551 | s->handle = CX18_INVALID_TASK_HANDLE; |
552 | 552 | ||
553 | if (atomic_read(&cx->tot_capturing) > 0) | 553 | if (atomic_read(&cx->tot_capturing) > 0) |
554 | return 0; | 554 | return 0; |
@@ -567,8 +567,8 @@ u32 cx18_find_handle(struct cx18 *cx) | |||
567 | for (i = 0; i < CX18_MAX_STREAMS; i++) { | 567 | for (i = 0; i < CX18_MAX_STREAMS; i++) { |
568 | struct cx18_stream *s = &cx->streams[i]; | 568 | struct cx18_stream *s = &cx->streams[i]; |
569 | 569 | ||
570 | if (s->v4l2dev && s->handle) | 570 | if (s->v4l2dev && (s->handle != CX18_INVALID_TASK_HANDLE)) |
571 | return s->handle; | 571 | return s->handle; |
572 | } | 572 | } |
573 | return 0; | 573 | return CX18_INVALID_TASK_HANDLE; |
574 | } | 574 | } |