Skip to content

Commit

Permalink
V4L/DVB (13506): uvcvideo: Factorize common field in uvc_entity struc…
Browse files Browse the repository at this point in the history
…ture

The bNrInPins and baSourceID fields are common among all entities (some
of use bSourceID but this is conceptually the same). Move those two
fields out of entity type-specific unions into the uvc_entity structure
top level.

Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
  • Loading branch information
Laurent Pinchart authored and Mauro Carvalho Chehab committed Dec 5, 2009
1 parent 4057ac6 commit 8ca5a63
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 77 deletions.
119 changes: 51 additions & 68 deletions drivers/media/video/uvc/uvc_driver.c
Original file line number Diff line number Diff line change
Expand Up @@ -249,29 +249,9 @@ static struct uvc_entity *uvc_entity_by_reference(struct uvc_device *dev,
entity = list_entry(&dev->entities, struct uvc_entity, list);

list_for_each_entry_continue(entity, &dev->entities, list) {
switch (UVC_ENTITY_TYPE(entity)) {
case UVC_TT_STREAMING:
if (entity->output.bSourceID == id)
return entity;
break;

case UVC_VC_PROCESSING_UNIT:
if (entity->processing.bSourceID == id)
for (i = 0; i < entity->bNrInPins; ++i)
if (entity->baSourceID[i] == id)
return entity;
break;

case UVC_VC_SELECTOR_UNIT:
for (i = 0; i < entity->selector.bNrInPins; ++i)
if (entity->selector.baSourceID[i] == id)
return entity;
break;

case UVC_VC_EXTENSION_UNIT:
for (i = 0; i < entity->extension.bNrInPins; ++i)
if (entity->extension.baSourceID[i] == id)
return entity;
break;
}
}

return NULL;
Expand Down Expand Up @@ -785,6 +765,28 @@ static int uvc_parse_streaming(struct uvc_device *dev,
return ret;
}

static struct uvc_entity *uvc_alloc_entity(u16 type, u8 id,
unsigned int num_pads, unsigned int extra_size)
{
struct uvc_entity *entity;
unsigned int num_inputs;
unsigned int size;

num_inputs = (type & UVC_TERM_OUTPUT) ? num_pads : num_pads - 1;
size = sizeof(*entity) + extra_size + num_inputs;
entity = kzalloc(size, GFP_KERNEL);
if (entity == NULL)
return NULL;

entity->id = id;
entity->type = type;

entity->bNrInPins = num_inputs;
entity->baSourceID = ((__u8 *)entity) + sizeof(*entity) + extra_size;

return entity;
}

/* Parse vendor-specific extensions. */
static int uvc_parse_vendor_control(struct uvc_device *dev,
const unsigned char *buffer, int buflen)
Expand Down Expand Up @@ -836,21 +838,18 @@ static int uvc_parse_vendor_control(struct uvc_device *dev,
break;
}

unit = kzalloc(sizeof *unit + p + 2*n, GFP_KERNEL);
unit = uvc_alloc_entity(UVC_VC_EXTENSION_UNIT, buffer[3],
p + 1, 2*n);
if (unit == NULL)
return -ENOMEM;

unit->id = buffer[3];
unit->type = UVC_VC_EXTENSION_UNIT;
memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
unit->extension.bNumControls = buffer[20];
unit->extension.bNrInPins = buffer[21];
unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
memcpy(unit->extension.baSourceID, &buffer[22], p);
memcpy(unit->baSourceID, &buffer[22], p);
unit->extension.bControlSize = buffer[22+p];
unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p;
unit->extension.bmControlsType = (__u8 *)unit + sizeof *unit
+ p + n;
unit->extension.bmControls = (__u8 *)unit + sizeof(*unit);
unit->extension.bmControlsType = (__u8 *)unit + sizeof(*unit)
+ n;
memcpy(unit->extension.bmControls, &buffer[23+p], 2*n);

if (buffer[24+p+2*n] != 0)
Expand Down Expand Up @@ -947,13 +946,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
return -EINVAL;
}

term = kzalloc(sizeof *term + n + p, GFP_KERNEL);
term = uvc_alloc_entity(type | UVC_TERM_INPUT, buffer[3],
1, n + p);
if (term == NULL)
return -ENOMEM;

term->id = buffer[3];
term->type = type | UVC_TERM_INPUT;

if (UVC_ENTITY_TYPE(term) == UVC_ITT_CAMERA) {
term->camera.bControlSize = n;
term->camera.bmControls = (__u8 *)term + sizeof *term;
Expand Down Expand Up @@ -1008,13 +1005,12 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
return 0;
}

term = kzalloc(sizeof *term, GFP_KERNEL);
term = uvc_alloc_entity(type | UVC_TERM_OUTPUT, buffer[3],
1, 0);
if (term == NULL)
return -ENOMEM;

term->id = buffer[3];
term->type = type | UVC_TERM_OUTPUT;
term->output.bSourceID = buffer[7];
memcpy(term->baSourceID, &buffer[7], 1);

if (buffer[8] != 0)
usb_string(udev, buffer[8], term->name,
Expand All @@ -1035,15 +1031,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
return -EINVAL;
}

unit = kzalloc(sizeof *unit + p, GFP_KERNEL);
unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, 0);
if (unit == NULL)
return -ENOMEM;

unit->id = buffer[3];
unit->type = buffer[2];
unit->selector.bNrInPins = buffer[4];
unit->selector.baSourceID = (__u8 *)unit + sizeof *unit;
memcpy(unit->selector.baSourceID, &buffer[5], p);
memcpy(unit->baSourceID, &buffer[5], p);

if (buffer[5+p] != 0)
usb_string(udev, buffer[5+p], unit->name,
Expand All @@ -1065,13 +1057,11 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
return -EINVAL;
}

unit = kzalloc(sizeof *unit + n, GFP_KERNEL);
unit = uvc_alloc_entity(buffer[2], buffer[3], 2, n);
if (unit == NULL)
return -ENOMEM;

unit->id = buffer[3];
unit->type = buffer[2];
unit->processing.bSourceID = buffer[4];
memcpy(unit->baSourceID, &buffer[4], 1);
unit->processing.wMaxMultiplier =
get_unaligned_le16(&buffer[5]);
unit->processing.bControlSize = buffer[7];
Expand Down Expand Up @@ -1100,19 +1090,15 @@ static int uvc_parse_standard_control(struct uvc_device *dev,
return -EINVAL;
}

unit = kzalloc(sizeof *unit + p + n, GFP_KERNEL);
unit = uvc_alloc_entity(buffer[2], buffer[3], p + 1, n);
if (unit == NULL)
return -ENOMEM;

unit->id = buffer[3];
unit->type = buffer[2];
memcpy(unit->extension.guidExtensionCode, &buffer[4], 16);
unit->extension.bNumControls = buffer[20];
unit->extension.bNrInPins = buffer[21];
unit->extension.baSourceID = (__u8 *)unit + sizeof *unit;
memcpy(unit->extension.baSourceID, &buffer[22], p);
memcpy(unit->baSourceID, &buffer[22], p);
unit->extension.bControlSize = buffer[22+p];
unit->extension.bmControls = (__u8 *)unit + sizeof *unit + p;
unit->extension.bmControls = (__u8 *)unit + sizeof *unit;
memcpy(unit->extension.bmControls, &buffer[23+p], n);

if (buffer[23+p+n] != 0)
Expand Down Expand Up @@ -1218,7 +1204,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
if (uvc_trace_param & UVC_TRACE_PROBE)
printk(" <- XU %d", entity->id);

if (entity->extension.bNrInPins != 1) {
if (entity->bNrInPins != 1) {
uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has more "
"than 1 input pin.\n", entity->id);
return -1;
Expand All @@ -1244,7 +1230,7 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
printk(" <- SU %d", entity->id);

/* Single-input selector units are ignored. */
if (entity->selector.bNrInPins == 1)
if (entity->bNrInPins == 1)
break;

if (chain->selector != NULL) {
Expand Down Expand Up @@ -1305,7 +1291,7 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,

switch (UVC_ENTITY_TYPE(forward)) {
case UVC_VC_EXTENSION_UNIT:
if (forward->extension.bNrInPins != 1) {
if (forward->bNrInPins != 1) {
uvc_trace(UVC_TRACE_DESCR, "Extension unit %d "
"has more than 1 input pin.\n",
entity->id);
Expand Down Expand Up @@ -1358,26 +1344,23 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain,

switch (UVC_ENTITY_TYPE(entity)) {
case UVC_VC_EXTENSION_UNIT:
id = entity->extension.baSourceID[0];
break;

case UVC_VC_PROCESSING_UNIT:
id = entity->processing.bSourceID;
id = entity->baSourceID[0];
break;

case UVC_VC_SELECTOR_UNIT:
/* Single-input selector units are ignored. */
if (entity->selector.bNrInPins == 1) {
id = entity->selector.baSourceID[0];
if (entity->bNrInPins == 1) {
id = entity->baSourceID[0];
break;
}

if (uvc_trace_param & UVC_TRACE_PROBE)
printk(" <- IT");

chain->selector = entity;
for (i = 0; i < entity->selector.bNrInPins; ++i) {
id = entity->selector.baSourceID[i];
for (i = 0; i < entity->bNrInPins; ++i) {
id = entity->baSourceID[i];
term = uvc_entity_by_id(chain->dev, id);
if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) {
uvc_trace(UVC_TRACE_DESCR, "Selector unit %d "
Expand Down Expand Up @@ -1406,7 +1389,7 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
case UVC_OTT_DISPLAY:
case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
case UVC_TT_STREAMING:
id = UVC_ENTITY_IS_OTERM(entity) ? entity->output.bSourceID : 0;
id = UVC_ENTITY_IS_OTERM(entity) ? entity->baSourceID[0] : 0;
break;
}

Expand Down
6 changes: 3 additions & 3 deletions drivers/media/video/uvc/uvc_v4l2.c
Original file line number Diff line number Diff line change
Expand Up @@ -625,8 +625,8 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
break;
}
pin = iterm->id;
} else if (pin < selector->selector.bNrInPins) {
pin = selector->selector.baSourceID[index];
} else if (pin < selector->bNrInPins) {
pin = selector->baSourceID[index];
list_for_each_entry(iterm, &chain->entities, chain) {
if (!UVC_ENTITY_IS_ITERM(iterm))
continue;
Expand Down Expand Up @@ -680,7 +680,7 @@ static long uvc_v4l2_do_ioctl(struct file *file, unsigned int cmd, void *arg)
break;
}

if (input == 0 || input > chain->selector->selector.bNrInPins)
if (input == 0 || input > chain->selector->bNrInPins)
return -EINVAL;

return uvc_query_ctrl(chain->dev, UVC_SET_CUR,
Expand Down
9 changes: 3 additions & 6 deletions drivers/media/video/uvc/uvcvideo.h
Original file line number Diff line number Diff line change
Expand Up @@ -293,33 +293,30 @@ struct uvc_entity {
} media;

struct {
__u8 bSourceID;
} output;

struct {
__u8 bSourceID;
__u16 wMaxMultiplier;
__u8 bControlSize;
__u8 *bmControls;
__u8 bmVideoStandards;
} processing;

struct {
__u8 bNrInPins;
__u8 *baSourceID;
} selector;

struct {
__u8 guidExtensionCode[16];
__u8 bNumControls;
__u8 bNrInPins;
__u8 *baSourceID;
__u8 bControlSize;
__u8 *bmControls;
__u8 *bmControlsType;
} extension;
};

__u8 bNrInPins;
__u8 *baSourceID;

unsigned int ncontrols;
struct uvc_control *controls;
};
Expand Down

0 comments on commit 8ca5a63

Please sign in to comment.