Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 202081
b: refs/heads/master
c: b30ece5
h: refs/heads/master
i:
  202079: c01cb2c
v: v3
  • Loading branch information
Laurent Pinchart authored and Mauro Carvalho Chehab committed Aug 2, 2010
1 parent a877b8b commit 2cdcb76
Show file tree
Hide file tree
Showing 4 changed files with 39 additions and 20 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 1b4e21c4f62eae6bdcb3e7bfdfc52171a24f3689
refs/heads/master: b30ece53946ad2b79304ee5cfdb18b361dc3a3fc
51 changes: 33 additions & 18 deletions trunk/drivers/media/video/uvc/uvc_ctrl.c
Original file line number Diff line number Diff line change
Expand Up @@ -643,7 +643,7 @@ static struct uvc_control_mapping uvc_ctrl_mappings[] = {

static inline __u8 *uvc_ctrl_data(struct uvc_control *ctrl, int id)
{
return ctrl->data + id * ctrl->info->size;
return ctrl->uvc_data + id * ctrl->info->size;
}

static inline int uvc_test_bit(const __u8 *data, int bit)
Expand Down Expand Up @@ -1293,13 +1293,15 @@ int uvc_ctrl_resume_device(struct uvc_device *dev)
* Control and mapping handling
*/

static void uvc_ctrl_add_ctrl(struct uvc_device *dev,
static int uvc_ctrl_add_ctrl(struct uvc_device *dev,
struct uvc_control_info *info)
{
struct uvc_entity *entity;
struct uvc_control *ctrl = NULL;
int ret, found = 0;
int ret = 0, found = 0;
unsigned int i;
u8 *uvc_info;
u8 *uvc_data;

list_for_each_entry(entity, &dev->entities, list) {
if (!uvc_entity_match_guid(entity, info->entity))
Expand All @@ -1318,56 +1320,69 @@ static void uvc_ctrl_add_ctrl(struct uvc_device *dev,
}

if (!found)
return;
return 0;

uvc_data = kmalloc(info->size * UVC_CTRL_DATA_LAST + 1, GFP_KERNEL);
if (uvc_data == NULL)
return -ENOMEM;

uvc_info = uvc_data + info->size * UVC_CTRL_DATA_LAST;

if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT) {
/* Check if the device control information and length match
* the user supplied information.
*/
__le16 size;
__u8 _info;

ret = uvc_query_ctrl(dev, UVC_GET_LEN, ctrl->entity->id,
dev->intfnum, info->selector, (__u8 *)&size, 2);
dev->intfnum, info->selector, uvc_data, 2);
if (ret < 0) {
uvc_trace(UVC_TRACE_CONTROL,
"GET_LEN failed on control %pUl/%u (%d).\n",
info->entity, info->selector, ret);
return;
goto done;
}

if (info->size != le16_to_cpu(size)) {
if (info->size != le16_to_cpu(*(__le16 *)uvc_data)) {
uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u size "
"doesn't match user supplied value.\n",
info->entity, info->selector);
return;
ret = -EINVAL;
goto done;
}

ret = uvc_query_ctrl(dev, UVC_GET_INFO, ctrl->entity->id,
dev->intfnum, info->selector, &_info, 1);
dev->intfnum, info->selector, uvc_info, 1);
if (ret < 0) {
uvc_trace(UVC_TRACE_CONTROL,
"GET_INFO failed on control %pUl/%u (%d).\n",
info->entity, info->selector, ret);
return;
goto done;
}

if (((info->flags & UVC_CONTROL_GET_CUR) &&
!(_info & UVC_CONTROL_CAP_GET)) ||
!(*uvc_info & UVC_CONTROL_CAP_GET)) ||
((info->flags & UVC_CONTROL_SET_CUR) &&
!(_info & UVC_CONTROL_CAP_SET))) {
!(*uvc_info & UVC_CONTROL_CAP_SET))) {
uvc_trace(UVC_TRACE_CONTROL, "Control %pUl/%u flags "
"don't match supported operations.\n",
info->entity, info->selector);
return;
ret = -EINVAL;
goto done;
}
}

ctrl->info = info;
ctrl->data = kmalloc(ctrl->info->size * UVC_CTRL_DATA_LAST, GFP_KERNEL);
ctrl->uvc_data = uvc_data;
ctrl->uvc_info = uvc_info;

uvc_trace(UVC_TRACE_CONTROL, "Added control %pUl/%u to device %s "
"entity %u\n", ctrl->info->entity, ctrl->info->selector,
dev->udev->devpath, entity->id);

done:
if (ret < 0)
kfree(uvc_data);

return ret;
}

/*
Expand Down Expand Up @@ -1600,7 +1615,7 @@ void uvc_ctrl_cleanup_device(struct uvc_device *dev)

list_for_each_entry(entity, &dev->entities, list) {
for (i = 0; i < entity->ncontrols; ++i)
kfree(entity->controls[i].data);
kfree(entity->controls[i].uvc_data);

kfree(entity->controls);
}
Expand Down
3 changes: 3 additions & 0 deletions trunk/drivers/media/video/uvc/uvc_v4l2.c
Original file line number Diff line number Diff line change
Expand Up @@ -1028,6 +1028,9 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
if (!capable(CAP_SYS_ADMIN))
return -EPERM;

if (xinfo->size == 0)
return -EINVAL;

info = kzalloc(sizeof *info, GFP_KERNEL);
if (info == NULL)
return -ENOMEM;
Expand Down
3 changes: 2 additions & 1 deletion trunk/drivers/media/video/uvc/uvcvideo.h
Original file line number Diff line number Diff line change
Expand Up @@ -262,7 +262,8 @@ struct uvc_control {
modified : 1,
cached : 1;

__u8 *data;
__u8 *uvc_data;
__u8 *uvc_info;
};

struct uvc_format_desc {
Expand Down

0 comments on commit 2cdcb76

Please sign in to comment.