aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2008-04-22 13:45:38 -0400
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-04-24 13:07:47 -0400
commitfdf256f3374d5060e3714651b45b8450b7dc4349 (patch)
tree3489f5c09d069a4ef4454882c6e3835bf1ddb722
parentbedbbf8be2f28c9f8a8cf1e2ead4fda8b5f47103 (diff)
V4L/DVB (7302): pvrusb2: Improve control validation for enumerations
When an enumeration control is changed, the pvrusb2 driver assumed that the enumeration values were continuous. That is no longer true; this change allows for properly input validation even when not all enumeration values are legal (which can happen with input selection based on what the hardware supports). Signed-off-by: Mike Isely <isely@pobox.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-ctrl.c19
1 files changed, 8 insertions, 11 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
index 5a3e8d21a38a..91a42f2473a7 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-ctrl.c
@@ -30,6 +30,9 @@ static int pvr2_ctrl_range_check(struct pvr2_ctrl *cptr,int val)
30{ 30{
31 if (cptr->info->check_value) { 31 if (cptr->info->check_value) {
32 if (!cptr->info->check_value(cptr,val)) return -ERANGE; 32 if (!cptr->info->check_value(cptr,val)) return -ERANGE;
33 } else if (cptr->info->type == pvr2_ctl_enum) {
34 if (val < 0) return -ERANGE;
35 if (val >= cptr->info->def.type_enum.count) return -ERANGE;
33 } else { 36 } else {
34 int lim; 37 int lim;
35 lim = cptr->info->def.type_int.min_value; 38 lim = cptr->info->def.type_int.min_value;
@@ -63,13 +66,10 @@ int pvr2_ctrl_set_mask_value(struct pvr2_ctrl *cptr,int mask,int val)
63 if (cptr->info->set_value) { 66 if (cptr->info->set_value) {
64 if (cptr->info->type == pvr2_ctl_bitmask) { 67 if (cptr->info->type == pvr2_ctl_bitmask) {
65 mask &= cptr->info->def.type_bitmask.valid_bits; 68 mask &= cptr->info->def.type_bitmask.valid_bits;
66 } else if (cptr->info->type == pvr2_ctl_int) { 69 } else if ((cptr->info->type == pvr2_ctl_int)||
70 (cptr->info->type == pvr2_ctl_enum)) {
67 ret = pvr2_ctrl_range_check(cptr,val); 71 ret = pvr2_ctrl_range_check(cptr,val);
68 if (ret < 0) break; 72 if (ret < 0) break;
69 } else if (cptr->info->type == pvr2_ctl_enum) {
70 if (val >= cptr->info->def.type_enum.count) {
71 break;
72 }
73 } else if (cptr->info->type != pvr2_ctl_bool) { 73 } else if (cptr->info->type != pvr2_ctl_bool) {
74 break; 74 break;
75 } 75 }
@@ -204,8 +204,7 @@ int pvr2_ctrl_get_valname(struct pvr2_ctrl *cptr,int val,
204 if (cptr->info->type == pvr2_ctl_enum) { 204 if (cptr->info->type == pvr2_ctl_enum) {
205 const char **names; 205 const char **names;
206 names = cptr->info->def.type_enum.value_names; 206 names = cptr->info->def.type_enum.value_names;
207 if ((val >= 0) && 207 if (pvr2_ctrl_range_check(cptr,val) == 0) {
208 (val < cptr->info->def.type_enum.count)) {
209 if (names[val]) { 208 if (names[val]) {
210 *blen = scnprintf( 209 *blen = scnprintf(
211 bptr,bmax,"%s", 210 bptr,bmax,"%s",
@@ -528,10 +527,8 @@ int pvr2_ctrl_sym_to_value(struct pvr2_ctrl *cptr,
528 ptr,len,valptr, 527 ptr,len,valptr,
529 cptr->info->def.type_enum.value_names, 528 cptr->info->def.type_enum.value_names,
530 cptr->info->def.type_enum.count); 529 cptr->info->def.type_enum.count);
531 if ((ret >= 0) && 530 if (ret >= 0) {
532 ((*valptr < 0) || 531 ret = pvr2_ctrl_range_check(cptr,*valptr);
533 (*valptr >= cptr->info->def.type_enum.count))) {
534 ret = -ERANGE;
535 } 532 }
536 if (maskptr) *maskptr = ~0; 533 if (maskptr) *maskptr = ~0;
537 } else if (cptr->info->type == pvr2_ctl_bitmask) { 534 } else if (cptr->info->type == pvr2_ctl_bitmask) {