Commit 071c8bb8 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab

[media] uvcvideo: Embed uvc_control_info inside struct uvc_control

Now that control information structures are not shared between control
instances, embed a uvc_control_info instance inside the uvc_control
structure instead of storing a pointer.
Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 8fb91b33
...@@ -643,7 +643,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = { ...@@ -643,7 +643,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {
static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id) static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id)
{ {
return ctrl->uvc_data + id * ctrl->info->size; return ctrl->uvc_data + id * ctrl->info.size;
} }
static inline int uvc_test_bit(const __u8 *data, int bit) static inline int uvc_test_bit(const __u8 *data, int bit)
...@@ -766,10 +766,10 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id, ...@@ -766,10 +766,10 @@ static void __uvc_find_control(struct uvc_entity *entity, __u32 v4l2_id,
for (i = 0; i < entity->ncontrols; ++i) { for (i = 0; i < entity->ncontrols; ++i) {
ctrl = &entity->controls[i]; ctrl = &entity->controls[i];
if (ctrl->info == NULL) if (!ctrl->initialized)
continue; continue;
list_for_each_entry(map, &ctrl->info->mappings, list) { list_for_each_entry(map, &ctrl->info.mappings, list) {
if ((map->id == v4l2_id) && !next) { if ((map->id == v4l2_id) && !next) {
*control = ctrl; *control = ctrl;
*mapping = map; *mapping = map;
...@@ -816,36 +816,36 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain, ...@@ -816,36 +816,36 @@ static int uvc_ctrl_populate_cache(struct uvc_video_chain *chain,
{ {
int ret; int ret;
if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { if (ctrl->info.flags & UVC_CONTROL_GET_DEF) {
ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id, ret = uvc_query_ctrl(chain->dev, UVC_GET_DEF, ctrl->entity->id,
chain->dev->intfnum, ctrl->info->selector, chain->dev->intfnum, ctrl->info.selector,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF), uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF),
ctrl->info->size); ctrl->info.size);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { if (ctrl->info.flags & UVC_CONTROL_GET_MIN) {
ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id, ret = uvc_query_ctrl(chain->dev, UVC_GET_MIN, ctrl->entity->id,
chain->dev->intfnum, ctrl->info->selector, chain->dev->intfnum, ctrl->info.selector,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN), uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN),
ctrl->info->size); ctrl->info.size);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { if (ctrl->info.flags & UVC_CONTROL_GET_MAX) {
ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id, ret = uvc_query_ctrl(chain->dev, UVC_GET_MAX, ctrl->entity->id,
chain->dev->intfnum, ctrl->info->selector, chain->dev->intfnum, ctrl->info.selector,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX), uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX),
ctrl->info->size); ctrl->info.size);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
if (ctrl->info->flags & UVC_CONTROL_GET_RES) { if (ctrl->info.flags & UVC_CONTROL_GET_RES) {
ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id, ret = uvc_query_ctrl(chain->dev, UVC_GET_RES, ctrl->entity->id,
chain->dev->intfnum, ctrl->info->selector, chain->dev->intfnum, ctrl->info.selector,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES), uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES),
ctrl->info->size); ctrl->info.size);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
...@@ -873,9 +873,9 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, ...@@ -873,9 +873,9 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name); strlcpy(v4l2_ctrl->name, mapping->name, sizeof v4l2_ctrl->name);
v4l2_ctrl->flags = 0; v4l2_ctrl->flags = 0;
if (!(ctrl->info->flags & UVC_CONTROL_GET_CUR)) if (!(ctrl->info.flags & UVC_CONTROL_GET_CUR))
v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY; v4l2_ctrl->flags |= V4L2_CTRL_FLAG_WRITE_ONLY;
if (!(ctrl->info->flags & UVC_CONTROL_SET_CUR)) if (!(ctrl->info.flags & UVC_CONTROL_SET_CUR))
v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY; v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
if (!ctrl->cached) { if (!ctrl->cached) {
...@@ -884,7 +884,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, ...@@ -884,7 +884,7 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
return ret; return ret;
} }
if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { if (ctrl->info.flags & UVC_CONTROL_GET_DEF) {
v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF, v4l2_ctrl->default_value = mapping->get(mapping, UVC_GET_DEF,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF)); uvc_ctrl_data(ctrl, UVC_CTRL_DATA_DEF));
} }
...@@ -921,15 +921,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain, ...@@ -921,15 +921,15 @@ int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
break; break;
} }
if (ctrl->info->flags & UVC_CONTROL_GET_MIN) if (ctrl->info.flags & UVC_CONTROL_GET_MIN)
v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN, v4l2_ctrl->minimum = mapping->get(mapping, UVC_GET_MIN,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN)); uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MIN));
if (ctrl->info->flags & UVC_CONTROL_GET_MAX) if (ctrl->info.flags & UVC_CONTROL_GET_MAX)
v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX, v4l2_ctrl->maximum = mapping->get(mapping, UVC_GET_MAX,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX)); uvc_ctrl_data(ctrl, UVC_CTRL_DATA_MAX));
if (ctrl->info->flags & UVC_CONTROL_GET_RES) if (ctrl->info.flags & UVC_CONTROL_GET_RES)
v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES, v4l2_ctrl->step = mapping->get(mapping, UVC_GET_RES,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES)); uvc_ctrl_data(ctrl, UVC_CTRL_DATA_RES));
...@@ -978,14 +978,14 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, ...@@ -978,14 +978,14 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
for (i = 0; i < entity->ncontrols; ++i) { for (i = 0; i < entity->ncontrols; ++i) {
ctrl = &entity->controls[i]; ctrl = &entity->controls[i];
if (ctrl->info == NULL) if (!ctrl->initialized)
continue; continue;
/* Reset the loaded flag for auto-update controls that were /* Reset the loaded flag for auto-update controls that were
* marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent * marked as loaded in uvc_ctrl_get/uvc_ctrl_set to prevent
* uvc_ctrl_get from using the cached value. * uvc_ctrl_get from using the cached value.
*/ */
if (ctrl->info->flags & UVC_CONTROL_AUTO_UPDATE) if (ctrl->info.flags & UVC_CONTROL_AUTO_UPDATE)
ctrl->loaded = 0; ctrl->loaded = 0;
if (!ctrl->dirty) if (!ctrl->dirty)
...@@ -993,16 +993,16 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev, ...@@ -993,16 +993,16 @@ static int uvc_ctrl_commit_entity(struct uvc_device *dev,
if (!rollback) if (!rollback)
ret = uvc_query_ctrl(dev, UVC_SET_CUR, ctrl->entity->id, ret = uvc_query_ctrl(dev, UVC_SET_CUR, ctrl->entity->id,
dev->intfnum, ctrl->info->selector, dev->intfnum, ctrl->info.selector,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
ctrl->info->size); ctrl->info.size);
else else
ret = 0; ret = 0;
if (rollback || ret < 0) if (rollback || ret < 0)
memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
ctrl->info->size); ctrl->info.size);
ctrl->dirty = 0; ctrl->dirty = 0;
...@@ -1040,14 +1040,14 @@ int uvc_ctrl_get(struct uvc_video_chain *chain, ...@@ -1040,14 +1040,14 @@ int uvc_ctrl_get(struct uvc_video_chain *chain,
int ret; int ret;
ctrl = uvc_find_control(chain, xctrl->id, &mapping); ctrl = uvc_find_control(chain, xctrl->id, &mapping);
if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) if (ctrl == NULL || (ctrl->info.flags & UVC_CONTROL_GET_CUR) == 0)
return -EINVAL; return -EINVAL;
if (!ctrl->loaded) { if (!ctrl->loaded) {
ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id, ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ctrl->entity->id,
chain->dev->intfnum, ctrl->info->selector, chain->dev->intfnum, ctrl->info.selector,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
ctrl->info->size); ctrl->info.size);
if (ret < 0) if (ret < 0)
return ret; return ret;
...@@ -1082,7 +1082,7 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, ...@@ -1082,7 +1082,7 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
int ret; int ret;
ctrl = uvc_find_control(chain, xctrl->id, &mapping); ctrl = uvc_find_control(chain, xctrl->id, &mapping);
if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0) if (ctrl == NULL || (ctrl->info.flags & UVC_CONTROL_SET_CUR) == 0)
return -EINVAL; return -EINVAL;
/* Clamp out of range values. */ /* Clamp out of range values. */
...@@ -1128,16 +1128,16 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, ...@@ -1128,16 +1128,16 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
* needs to be loaded from the device to perform the read-modify-write * needs to be loaded from the device to perform the read-modify-write
* operation. * operation.
*/ */
if (!ctrl->loaded && (ctrl->info->size * 8) != mapping->size) { if (!ctrl->loaded && (ctrl->info.size * 8) != mapping->size) {
if ((ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) { if ((ctrl->info.flags & UVC_CONTROL_GET_CUR) == 0) {
memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
0, ctrl->info->size); 0, ctrl->info.size);
} else { } else {
ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR, ret = uvc_query_ctrl(chain->dev, UVC_GET_CUR,
ctrl->entity->id, chain->dev->intfnum, ctrl->entity->id, chain->dev->intfnum,
ctrl->info->selector, ctrl->info.selector,
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
ctrl->info->size); ctrl->info.size);
if (ret < 0) if (ret < 0)
return ret; return ret;
} }
...@@ -1149,7 +1149,7 @@ int uvc_ctrl_set(struct uvc_video_chain *chain, ...@@ -1149,7 +1149,7 @@ int uvc_ctrl_set(struct uvc_video_chain *chain,
if (!ctrl->dirty) { if (!ctrl->dirty) {
memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP),
uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
ctrl->info->size); ctrl->info.size);
} }
mapping->set(mapping, value, mapping->set(mapping, value,
...@@ -1189,10 +1189,10 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain, ...@@ -1189,10 +1189,10 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
/* Find the control. */ /* Find the control. */
for (i = 0; i < entity->ncontrols; ++i) { for (i = 0; i < entity->ncontrols; ++i) {
ctrl = &entity->controls[i]; ctrl = &entity->controls[i];
if (ctrl->info == NULL) if (!ctrl->initialized)
continue; continue;
if (ctrl->info->selector == xctrl->selector) { if (ctrl->info.selector == xctrl->selector) {
found = 1; found = 1;
break; break;
} }
...@@ -1205,11 +1205,11 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain, ...@@ -1205,11 +1205,11 @@ int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
} }
/* Validate control data size. */ /* Validate control data size. */
if (ctrl->info->size != xctrl->size) if (ctrl->info.size != xctrl->size)
return -EINVAL; return -EINVAL;
if ((set && !(ctrl->info->flags & UVC_CONTROL_SET_CUR)) || if ((set && !(ctrl->info.flags & UVC_CONTROL_SET_CUR)) ||
(!set && !(ctrl->info->flags & UVC_CONTROL_GET_CUR))) (!set && !(ctrl->info.flags & UVC_CONTROL_GET_CUR)))
return -EINVAL; return -EINVAL;
if (mutex_lock_interruptible(&chain->ctrl_mutex)) if (mutex_lock_interruptible(&chain->ctrl_mutex))
...@@ -1272,13 +1272,13 @@ int uvc_ctrl_resume_device(struct uvc_device *dev) ...@@ -1272,13 +1272,13 @@ int uvc_ctrl_resume_device(struct uvc_device *dev)
for (i = 0; i < entity->ncontrols; ++i) { for (i = 0; i < entity->ncontrols; ++i) {
ctrl = &entity->controls[i]; ctrl = &entity->controls[i];
if (ctrl->info == NULL || !ctrl->modified || if (!ctrl->initialized || !ctrl->modified ||
(ctrl->info->flags & UVC_CONTROL_RESTORE) == 0) (ctrl->info.flags & UVC_CONTROL_RESTORE) == 0)
continue; continue;
printk(KERN_INFO "restoring control %pUl/%u/%u\n", printk(KERN_INFO "restoring control %pUl/%u/%u\n",
ctrl->info->entity, ctrl->info->index, ctrl->info.entity, ctrl->info.index,
ctrl->info->selector); ctrl->info.selector);
ctrl->dirty = 1; ctrl->dirty = 1;
} }
...@@ -1361,31 +1361,26 @@ static int uvc_ctrl_add_info(struct uvc_device *dev, struct uvc_control *ctrl, ...@@ -1361,31 +1361,26 @@ static int uvc_ctrl_add_info(struct uvc_device *dev, struct uvc_control *ctrl,
{ {
int ret = 0; int ret = 0;
/* Clone the control info struct for this device's instance */ memcpy(&ctrl->info, info, sizeof(*info));
ctrl->info = kmemdup(info, sizeof(*info), GFP_KERNEL); INIT_LIST_HEAD(&ctrl->info.mappings);
if (ctrl->info == NULL) {
ret = -ENOMEM;
goto done;
}
INIT_LIST_HEAD(&ctrl->info->mappings);
/* Allocate an array to save control values (cur, def, max, etc.) */ /* Allocate an array to save control values (cur, def, max, etc.) */
ctrl->uvc_data = kzalloc(ctrl->info->size * UVC_CTRL_DATA_LAST + 1, ctrl->uvc_data = kzalloc(ctrl->info.size * UVC_CTRL_DATA_LAST + 1,
GFP_KERNEL); GFP_KERNEL);
if (ctrl->uvc_data == NULL) { if (ctrl->uvc_data == NULL) {
ret = -ENOMEM; ret = -ENOMEM;
goto done; goto done;
} }
ctrl->initialized = 1;
uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s " uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s "
"entity %u\n", ctrl->info->entity, ctrl->info->selector, "entity %u\n", ctrl->info.entity, ctrl->info.selector,
dev->udev->devpath, ctrl->entity->id); dev->udev->devpath, ctrl->entity->id);
done: done:
if (ret < 0) { if (ret < 0)
kfree(ctrl->uvc_data); kfree(ctrl->uvc_data);
kfree(ctrl->info);
}
return ret; return ret;
} }
...@@ -1418,11 +1413,11 @@ static int __uvc_ctrl_add_mapping(struct uvc_device *dev, ...@@ -1418,11 +1413,11 @@ static int __uvc_ctrl_add_mapping(struct uvc_device *dev,
if (map->set == NULL) if (map->set == NULL)
map->set = uvc_set_le_value; map->set = uvc_set_le_value;
map->ctrl = ctrl->info; map->ctrl = &ctrl->info;
list_add_tail(&map->list, &ctrl->info->mappings); list_add_tail(&map->list, &ctrl->info.mappings);
uvc_trace(UVC_TRACE_CONTROL, uvc_trace(UVC_TRACE_CONTROL,
"Adding mapping '%s' to control %pUl/%u.\n", "Adding mapping '%s' to control %pUl/%u.\n",
map->name, ctrl->info->entity, ctrl->info->selector); map->name, ctrl->info.entity, ctrl->info.selector);
return 0; return 0;
} }
...@@ -1453,8 +1448,8 @@ int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, ...@@ -1453,8 +1448,8 @@ int uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
for (i = 0; i < entity->ncontrols; ++i) { for (i = 0; i < entity->ncontrols; ++i) {
ctrl = &entity->controls[i]; ctrl = &entity->controls[i];
if (ctrl->info != NULL && if (ctrl->initialized &&
ctrl->info->selector == mapping->selector) { ctrl->info.selector == mapping->selector) {
found = 1; found = 1;
break; break;
} }
...@@ -1469,7 +1464,7 @@ int uvc_ctrl_add_mapping(struct uvc_video_chain *chain, ...@@ -1469,7 +1464,7 @@ int uvc_ctrl_add_mapping(struct uvc_video_chain *chain,
if (mutex_lock_interruptible(&chain->ctrl_mutex)) if (mutex_lock_interruptible(&chain->ctrl_mutex))
return -ERESTARTSYS; return -ERESTARTSYS;
list_for_each_entry(map, &ctrl->info->mappings, list) { list_for_each_entry(map, &ctrl->info.mappings, list) {
if (mapping->id == map->id) { if (mapping->id == map->id) {
uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', " uvc_trace(UVC_TRACE_CONTROL, "Can't add mapping '%s', "
"control id 0x%08x already exists.\n", "control id 0x%08x already exists.\n",
...@@ -1601,12 +1596,12 @@ static void uvc_ctrl_init_ctrl(struct uvc_device *dev, struct uvc_control *ctrl) ...@@ -1601,12 +1596,12 @@ static void uvc_ctrl_init_ctrl(struct uvc_device *dev, struct uvc_control *ctrl)
} }
} }
if (ctrl->info == NULL) if (!ctrl->initialized)
return; return;
for (; mapping < mend; ++mapping) { for (; mapping < mend; ++mapping) {
if (uvc_entity_match_guid(ctrl->entity, mapping->entity) && if (uvc_entity_match_guid(ctrl->entity, mapping->entity) &&
ctrl->info->selector == mapping->selector) ctrl->info.selector == mapping->selector)
__uvc_ctrl_add_mapping(dev, ctrl, mapping); __uvc_ctrl_add_mapping(dev, ctrl, mapping);
} }
} }
...@@ -1676,7 +1671,7 @@ static void uvc_ctrl_cleanup_mappings(struct uvc_device *dev, ...@@ -1676,7 +1671,7 @@ static void uvc_ctrl_cleanup_mappings(struct uvc_device *dev,
{ {
struct uvc_control_mapping *mapping, *nm; struct uvc_control_mapping *mapping, *nm;
list_for_each_entry_safe(mapping, nm, &ctrl->info->mappings, list) { list_for_each_entry_safe(mapping, nm, &ctrl->info.mappings, list) {
list_del(&mapping->list); list_del(&mapping->list);
kfree(mapping->menu_info); kfree(mapping->menu_info);
kfree(mapping); kfree(mapping);
...@@ -1693,12 +1688,11 @@ void uvc_ctrl_cleanup_device(struct uvc_device *dev) ...@@ -1693,12 +1688,11 @@ void uvc_ctrl_cleanup_device(struct uvc_device *dev)
for (i = 0; i < entity->ncontrols; ++i) { for (i = 0; i < entity->ncontrols; ++i) {
struct uvc_control *ctrl = &entity->controls[i]; struct uvc_control *ctrl = &entity->controls[i];
if (ctrl->info == NULL) if (!ctrl->initialized)
continue; continue;
uvc_ctrl_cleanup_mappings(dev, ctrl); uvc_ctrl_cleanup_mappings(dev, ctrl);
kfree(ctrl->uvc_data); kfree(ctrl->uvc_data);
kfree(ctrl->info);
} }
kfree(entity->controls); kfree(entity->controls);
......
...@@ -236,14 +236,15 @@ struct uvc_control_mapping { ...@@ -236,14 +236,15 @@ struct uvc_control_mapping {
struct uvc_control { struct uvc_control {
struct uvc_entity *entity; struct uvc_entity *entity;
struct uvc_control_info *info; struct uvc_control_info info;
__u8 index; /* Used to match the uvc_control entry with a __u8 index; /* Used to match the uvc_control entry with a
uvc_control_info. */ uvc_control_info. */
__u8 dirty : 1, __u8 dirty:1,
loaded : 1, loaded:1,
modified : 1, modified:1,
cached : 1; cached:1,
initialized:1;
__u8 *uvc_data; __u8 *uvc_data;
}; };
......
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