aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/uvc
diff options
context:
space:
mode:
authorLaurent Pinchart <laurent.pinchart@skynet.be>2008-09-27 19:54:02 -0400
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-10-12 07:37:08 -0400
commitb1accfa15533fdd40280aae3102e9599e63a7c10 (patch)
tree12cfcd4b6213c8ce47f11d3776caf7f40bab6ee6 /drivers/media/video/uvc
parent5e26d50f4e6b9c42bbfbaa452722797ece929cda (diff)
V4L/DVB (9036): uvcvideo: Fix control cache access when setting composite auto-update controls
Auto-update controls are never marked is loaded to prevent uvc_get_ctrl from loading the control value from the cache. When setting a composite (mapped to several V4L2 controls) auto-update UVC control, the driver updates the control cache value before processing each V4L2 control, overwriting the previously set V4L2 control. This fixes the problem by marking all controls as loaded in uvc_set_ctrl regardless of their type and resetting the loaded flag in uvc_commit_ctrl for auto-update controls. Signed-off-by: Laurent Pinchart <laurent.pinchart@skynet.be> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/uvc')
-rw-r--r--drivers/media/video/uvc/uvc_ctrl.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/drivers/media/video/uvc/uvc_ctrl.c b/drivers/media/video/uvc/uvc_ctrl.c
index 088437a5f60c..f16aafe9cf14 100644
--- a/drivers/media/video/uvc/uvc_ctrl.c
+++ b/drivers/media/video/uvc/uvc_ctrl.c
@@ -837,7 +837,17 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
837 837
838 for (i = 0; i < entity->ncontrols; ++i) { 838 for (i = 0; i < entity->ncontrols; ++i) {
839 ctrl = &entity->controls[i]; 839 ctrl = &entity->controls[i];
840 if (ctrl->info == NULL || !ctrl->dirty) 840 if (ctrl->info == NULL)
841 continue;
842
843 /* Reset the loaded flag for auto-update controls that were
844 * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent
845 * uvc_ctrl_get from using the cached value.
846 */
847 if (ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE)
848 ctrl->loaded = 0;
849
850 if (!ctrl->dirty)
841 continue; 851 continue;
842 852
843 if (!rollback) 853 if (!rollback)
@@ -853,9 +863,6 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
853 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), 863 uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
854 ctrl->info->size); 864 ctrl->info->size);
855 865
856 if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0)
857 ctrl->loaded = 0;
858
859 ctrl->dirty = 0; 866 ctrl->dirty = 0;
860 867
861 if (ret < 0) 868 if (ret < 0)
@@ -913,8 +920,7 @@ int uvc_ctrl_get(struct uvc_video_device *video,
913 if (ret < 0) 920 if (ret < 0)
914 return ret; 921 return ret;
915 922
916 if ((ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE) == 0) 923 ctrl->loaded = 1;
917 ctrl->loaded = 1;
918 } 924 }
919 925
920 xctrl->value = uvc_get_le_value( 926 xctrl->value = uvc_get_le_value(
@@ -965,8 +971,7 @@ int uvc_ctrl_set(struct uvc_video_device *video,
965 return ret; 971 return ret;
966 } 972 }
967 973
968 if ((ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE) == 0) 974 ctrl->loaded = 1;
969 ctrl->loaded = 1;
970 } 975 }
971 976
972 if (!ctrl->dirty) { 977 if (!ctrl->dirty) {