]> bbs.cooldavid.org Git - net-next-2.6.git/commitdiff
V4L/DVB (13506): uvcvideo: Factorize common field in uvc_entity structure
authorLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Wed, 25 Nov 2009 15:00:30 +0000 (12:00 -0300)
committerMauro Carvalho Chehab <mchehab@redhat.com>
Sat, 5 Dec 2009 20:42:13 +0000 (18:42 -0200)
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>
drivers/media/video/uvc/uvc_driver.c
drivers/media/video/uvc/uvc_v4l2.c
drivers/media/video/uvc/uvcvideo.h

index e7ce898ad7065fea7c1a6cdbfec480c071dabdc1..c31bc50113bca9bb144bda087338da030644ff3e 100644 (file)
@@ -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;
@@ -785,6 +765,28 @@ error:
        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)
@@ -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)
@@ -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;
@@ -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,
@@ -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,
@@ -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];
@@ -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)
@@ -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;
@@ -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) {
@@ -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);
@@ -1358,17 +1344,14 @@ 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;
                }
 
@@ -1376,8 +1359,8 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
                        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 "
@@ -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;
        }
 
index 9e1f2c208ed8e09ee598df53694780e12d7db37c..23239a4adefe092d0ed1a2e026499215613595d5 100644 (file)
@@ -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;
@@ -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,
index 9e6948fb3e61821016a51c841b83dde55919be52..7ec9a04ced5055f0dde006788aa1437be7f6dedd 100644 (file)
@@ -293,11 +293,9 @@ struct uvc_entity {
                } media;
 
                struct {
-                       __u8  bSourceID;
                } output;
 
                struct {
-                       __u8  bSourceID;
                        __u16 wMaxMultiplier;
                        __u8  bControlSize;
                        __u8  *bmControls;
@@ -305,21 +303,20 @@ struct uvc_entity {
                } 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;
 };