summaryrefslogtreecommitdiff
path: root/linux/drivers/media/video/uvc/uvc_ctrl.c
diff options
context:
space:
mode:
authorMauro Carvalho Chehab <mchehab@redhat.com>2008-09-27 23:54:02 +0000
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-09-27 23:54:02 +0000
commitcfd49e1a2492fe52c02e75c2e2a82eceb3385ff8 (patch)
treef10cef33c899a2446441eb53939f9dc0fd8c308c /linux/drivers/media/video/uvc/uvc_ctrl.c
parent3f7c87cad1eaa1b5274ee30258cd5862c3adfb98 (diff)
downloadmediapointer-dvb-s2-cfd49e1a2492fe52c02e75c2e2a82eceb3385ff8.tar.gz
mediapointer-dvb-s2-cfd49e1a2492fe52c02e75c2e2a82eceb3385ff8.tar.bz2
uvcvideo: Fix control cache access when setting composite auto-update controls
From: Laurent Pinchart <laurent.pinchart@skynet.be> 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 'linux/drivers/media/video/uvc/uvc_ctrl.c')
-rw-r--r--linux/drivers/media/video/uvc/uvc_ctrl.c21
1 files changed, 13 insertions, 8 deletions
diff --git a/linux/drivers/media/video/uvc/uvc_ctrl.c b/linux/drivers/media/video/uvc/uvc_ctrl.c
index 6da37cdda..b66c95ffd 100644
--- a/linux/drivers/media/video/uvc/uvc_ctrl.c
+++ b/linux/drivers/media/video/uvc/uvc_ctrl.c
@@ -837,7 +837,17 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
for (i = 0; i < entity->ncontrols; ++i) {
ctrl = &entity->controls[i];
- if (ctrl->info == NULL || !ctrl->dirty)
+ if (ctrl->info == NULL)
+ continue;
+
+ /* Reset the loaded flag for auto-update controls that were
+ * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent
+ * uvc_ctrl_get from using the cached value.
+ */
+ if (ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE)
+ ctrl->loaded = 0;
+
+ if (!ctrl->dirty)
continue;
if (!rollback)
@@ -853,9 +863,6 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
ctrl->info->size);
- if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0)
- ctrl->loaded = 0;
-
ctrl->dirty = 0;
if (ret < 0)
@@ -913,8 +920,7 @@ int uvc_ctrl_get(struct uvc_video_device *video,
if (ret < 0)
return ret;
- if ((ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE) == 0)
- ctrl->loaded = 1;
+ ctrl->loaded = 1;
}
xctrl->value = uvc_get_le_value(
@@ -965,8 +971,7 @@ int uvc_ctrl_set(struct uvc_video_device *video,
return ret;
}
- if ((ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE) == 0)
- ctrl->loaded = 1;
+ ctrl->loaded = 1;
}
if (!ctrl->dirty) {