Hello everyone,

I am trying to stream with 2 webcams simultaneously so I tried your patch.
The thing is I am not that good with Linux so.... didn't work. Here what I
did:

**I downloaded your source from:
http://linuxtv.org/hg/~pinchartl/uvcvideo/


**I copied/pasted the content of this mail and the second one started from:

diff -r 88ef3b9f5071 -r 012e480c8e6a linux/drivers/media/video/uvc/uvc_ctrl.c

till the end to files that I named patchOne.diff and patchTwo.diff

**Then, in a terminal, I went to:
uvcvideo-bff77ec33116/linux/drivers/media/video/uvc

**I did:
patch <patchOne.diff

It did not changed the content of the original files and I got:
patching file uvc_driver.c
Hunk #1 FAILED at 551.
Hunk #2 FAILED at 752.
Hunk #3 FAILED at 1167.
Hunk #5 FAILED at 1494.
Hunk #6 FAILED at 1515.
Hunk #7 FAILED at 1530.
Hunk #8 FAILED at 1568.
Hunk #9 FAILED at 1602.
Hunk #10 FAILED at 1643.
Hunk #11 FAILED at 1697.
Hunk #12 FAILED at 1706.
Hunk #13 FAILED at 1735.
12 out of 13 hunks FAILED -- saving rejects to file uvc_driver.c.rej
patching file uvc_isight.c
Hunk #1 FAILED at 99.
Hunk #2 FAILED at 120.
etc...

Can anyone tell me what I am doing wrong?
Regards,


LESCOP Cédric




On Thu, July 2, 2009 01:31, Laurent Pinchart wrote:
> Restructure the UVC descriptors parsing code to handle multiple streaming
>  interfaces. The driver now creates a uvc_video_chain instance for each
> chain detected in the UVC control interface descriptors, and tries to
> register one video device per streaming endpoint.
>
> Priority: normal
>
>
> Signed-off-by: Laurent Pinchart <[email protected]>
>
>
> diff -r 88ef3b9f5071 -r 012e480c8e6a
> linux/drivers/media/video/uvc/uvc_ctrl.c ---
> a/linux/drivers/media/video/uvc/uvc_ctrl.c    Sun Jun 28 13:37:50 2009 +0200
>  +++ b/linux/drivers/media/video/uvc/uvc_ctrl.c       Thu Jul 02 01:24:47 2009
> +0200
> @@ -731,7 +731,7 @@
> }
> }
>
>
> -struct uvc_control *uvc_find_control(struct uvc_video_device *video,
> +struct uvc_control *uvc_find_control(struct uvc_video_chain *chain,
> __u32 v4l2_id, struct uvc_control_mapping **mapping)
> {
> struct uvc_control *ctrl = NULL; @@ -744,17 +744,17 @@
> v4l2_id &= V4L2_CTRL_ID_MASK;
>
> /* Find the control. */
> -     __uvc_find_control(video->processing, v4l2_id, mapping, &ctrl, next);
> +     __uvc_find_control(chain->processing, v4l2_id, mapping, &ctrl, next);
> if (ctrl && !next) return ctrl;
>
> -     list_for_each_entry(entity, &video->iterms, chain) {
> +     list_for_each_entry(entity, &chain->iterms, chain) {
> __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
> if (ctrl && !next) return ctrl; }
>
>
> -     list_for_each_entry(entity, &video->extensions, chain) {
> +     list_for_each_entry(entity, &chain->extensions, chain) {
> __uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
> if (ctrl && !next) return ctrl; @@ -767,7 +767,7 @@
> return ctrl; }
>
>
> -int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
> +int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
> struct v4l2_queryctrl *v4l2_ctrl) {
> struct uvc_control *ctrl; @@ -777,7 +777,7 @@
> __u8 *data;
> int ret;
>
> -     ctrl = uvc_find_control(video, v4l2_ctrl->id, &mapping);
> +     ctrl = uvc_find_control(chain, v4l2_ctrl->id, &mapping);
> if (ctrl == NULL) return -EINVAL;
>
> @@ -795,9 +795,10 @@
> v4l2_ctrl->flags |= V4L2_CTRL_FLAG_READ_ONLY;
>
> if (ctrl->info->flags & UVC_CONTROL_GET_DEF) { -              if ((ret =
> uvc_query_ctrl(video->dev, GET_DEF, ctrl->entity->id, -
> video->dev->intfnum, ctrl->info->selector, -                          data, 
> ctrl->info->size)) <
> 0)
> +             ret = uvc_query_ctrl(chain->dev, GET_DEF, ctrl->entity->id,
> +                                  chain->dev->intfnum, ctrl->info->selector,
> +                                  data, ctrl->info->size);
> +             if (ret < 0)
> goto out; v4l2_ctrl->default_value = mapping->get(mapping, GET_DEF,
data); }
>  @@ -831,23 +832,26 @@
> }
>
>
> if (ctrl->info->flags & UVC_CONTROL_GET_MIN) { -              if ((ret =
> uvc_query_ctrl(video->dev, GET_MIN, ctrl->entity->id, -
> video->dev->intfnum, ctrl->info->selector, -                          data, 
> ctrl->info->size)) <
> 0)
> +             ret = uvc_query_ctrl(chain->dev, GET_MIN, ctrl->entity->id,
> +                                  chain->dev->intfnum, ctrl->info->selector,
> +                                  data, ctrl->info->size);
> +             if (ret < 0)
> goto out; v4l2_ctrl->minimum = mapping->get(mapping, GET_MIN, data); }
> if (ctrl->info->flags & UVC_CONTROL_GET_MAX) { -              if ((ret =
> uvc_query_ctrl(video->dev, GET_MAX, ctrl->entity->id, -
> video->dev->intfnum, ctrl->info->selector, -                          data, 
> ctrl->info->size)) <
> 0)
> +             ret = uvc_query_ctrl(chain->dev, GET_MAX, ctrl->entity->id,
> +                                  chain->dev->intfnum, ctrl->info->selector,
> +                                  data, ctrl->info->size);
> +             if (ret < 0)
> goto out; v4l2_ctrl->maximum = mapping->get(mapping, GET_MAX, data); }
> if (ctrl->info->flags & UVC_CONTROL_GET_RES) { -              if ((ret =
> uvc_query_ctrl(video->dev, GET_RES, ctrl->entity->id, -
> video->dev->intfnum, ctrl->info->selector, -                          data, 
> ctrl->info->size)) <
> 0)
> +             ret = uvc_query_ctrl(chain->dev, GET_RES, ctrl->entity->id,
> +                                  chain->dev->intfnum, ctrl->info->selector,
> +                                  data, ctrl->info->size);
> +             if (ret < 0)
> goto out; v4l2_ctrl->step = mapping->get(mapping, GET_RES, data); }
> @@ -883,9 +887,9 @@
> * (UVC_CTRL_DATA_BACKUP) for all dirty controls. Both functions release
> the * control lock.
> */
> -int uvc_ctrl_begin(struct uvc_video_device *video)
> +int uvc_ctrl_begin(struct uvc_video_chain *chain)
> {
> -     return mutex_lock_interruptible(&video->ctrl_mutex) ? -ERESTARTSYS : 0;
> +     return mutex_lock_interruptible(&chain->ctrl_mutex) ? -ERESTARTSYS : 0;
> }
>
>
> static int uvc_ctrl_commit_entity(struct uvc_device *dev, @@ -935,34
> +939,34 @@
> return 0; }
>
>
> -int __uvc_ctrl_commit(struct uvc_video_device *video, int rollback)
> +int __uvc_ctrl_commit(struct uvc_video_chain *chain, int rollback)
> {
> struct uvc_entity *entity; int ret = 0;
>
> /* Find the control. */
> -     ret = uvc_ctrl_commit_entity(video->dev, video->processing, rollback);
> +     ret = uvc_ctrl_commit_entity(chain->dev, chain->processing, rollback);
> if (ret < 0) goto done;
>
> -     list_for_each_entry(entity, &video->iterms, chain) {
> -             ret = uvc_ctrl_commit_entity(video->dev, entity, rollback);
> +     list_for_each_entry(entity, &chain->iterms, chain) {
> +             ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
> if (ret < 0) goto done; }
>
>
> -     list_for_each_entry(entity, &video->extensions, chain) {
> -             ret = uvc_ctrl_commit_entity(video->dev, entity, rollback);
> +     list_for_each_entry(entity, &chain->extensions, chain) {
> +             ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
> if (ret < 0) goto done; }
>
>
> done:
> -     mutex_unlock(&video->ctrl_mutex);
> +     mutex_unlock(&chain->ctrl_mutex);
> return ret; }
>
>
> -int uvc_ctrl_get(struct uvc_video_device *video,
> +int uvc_ctrl_get(struct uvc_video_chain *chain,
> struct v4l2_ext_control *xctrl) {
> struct uvc_control *ctrl; @@ -971,13 +975,13 @@
> unsigned int i; int ret;
>
> -     ctrl = uvc_find_control(video, xctrl->id, &mapping);
> +     ctrl = uvc_find_control(chain, xctrl->id, &mapping);
> if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_GET_CUR) == 0) return
> -EINVAL;
>
>
> if (!ctrl->loaded) { -                ret = uvc_query_ctrl(video->dev, 
> GET_CUR,
> ctrl->entity->id, -                           video->dev->intfnum, 
> ctrl->info->selector,
> +             ret = uvc_query_ctrl(chain->dev, GET_CUR, ctrl->entity->id,
> +                             chain->dev->intfnum, ctrl->info->selector,
> uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), ctrl->info->size); if (ret < 0)
> @@ -1002,7 +1006,7 @@
> return 0; }
>
>
> -int uvc_ctrl_set(struct uvc_video_device *video,
> +int uvc_ctrl_set(struct uvc_video_chain *chain,
> struct v4l2_ext_control *xctrl) {
> struct uvc_control *ctrl; @@ -1010,7 +1014,7 @@
> s32 value = xctrl->value; int ret;
>
> -     ctrl = uvc_find_control(video, xctrl->id, &mapping);
> +     ctrl = uvc_find_control(chain, xctrl->id, &mapping);
> if (ctrl == NULL || (ctrl->info->flags & UVC_CONTROL_SET_CUR) == 0) return
> -EINVAL;
>
>
> @@ -1025,8 +1029,8 @@
> memset(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT), 0, ctrl->info->size);
> } else {
> -                     ret = uvc_query_ctrl(video->dev, GET_CUR,
> -                             ctrl->entity->id, video->dev->intfnum,
> +                     ret = uvc_query_ctrl(chain->dev, GET_CUR,
> +                             ctrl->entity->id, chain->dev->intfnum,
> ctrl->info->selector, uvc_ctrl_data(ctrl, UVC_CTRL_DATA_CURRENT),
> ctrl->info->size); @@ -1055,7 +1059,7 @@
> * Dynamic controls
> */
>
>
> -int uvc_xu_ctrl_query(struct uvc_video_device *video,
> +int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
> struct uvc_xu_control *xctrl, int set) {
> struct uvc_entity *entity; @@ -1065,7 +1069,7 @@
> int ret;
>
> /* Find the extension unit. */
> -     list_for_each_entry(entity, &video->extensions, chain) {
> +     list_for_each_entry(entity, &chain->extensions, chain) {
> if (entity->id == xctrl->unit) break; }
> @@ -1104,7 +1108,7 @@
> (!set && !(ctrl->info->flags & UVC_CONTROL_GET_CUR)))
> return -EINVAL;
>
> -     if (mutex_lock_interruptible(&video->ctrl_mutex))
> +     if (mutex_lock_interruptible(&chain->ctrl_mutex))
> return -ERESTARTSYS;
>
> memcpy(uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), @@ -1117,8 +1121,8 @@
> goto out; }
>
>
> -     ret = uvc_query_ctrl(video->dev, set ? SET_CUR : GET_CUR, xctrl->unit,
> -                          video->dev->intfnum, xctrl->selector, data,
> +     ret = uvc_query_ctrl(chain->dev, set ? SET_CUR : GET_CUR, xctrl->unit,
> +                          chain->dev->intfnum, xctrl->selector, data,
> xctrl->size); if (ret < 0) goto out; @@ -1134,7 +1138,7 @@
> uvc_ctrl_data(ctrl, UVC_CTRL_DATA_BACKUP), xctrl->size);
>
> -     mutex_unlock(&video->ctrl_mutex);
> +     mutex_unlock(&chain->ctrl_mutex);
> return ret; }
>
>
> diff -r 88ef3b9f5071 -r 012e480c8e6a
> linux/drivers/media/video/uvc/uvc_driver.c ---
> a/linux/drivers/media/video/uvc/uvc_driver.c  Sun Jun 28 13:37:50 2009
> +0200
> +++ b/linux/drivers/media/video/uvc/uvc_driver.c      Thu Jul 02 01:24:47 2009
> +0200
> @@ -276,8 +276,20 @@
> return NULL; }
>
>
> +static struct uvc_streaming *uvc_stream_by_id(struct uvc_device *dev,
> int id) +{
> +     struct uvc_streaming *stream;
> +
> +     list_for_each_entry(stream, &dev->streams, list) {
> +             if (stream->header.bTerminalLink == id)
> +                     return stream;
> +     }
> +
> +     return NULL;
> +}
> +
> /*
> ------------------------------------------------------------------------
> - * Descriptors handling
> + * Descriptors parsing
> */
>
>
> static int uvc_parse_format(struct uvc_device *dev, @@ -1159,101 +1171,36
> @@
> }
>
>
> /*
> ------------------------------------------------------------------------
> - * USB probe and disconnect
> + * UVC device scan
> */
>
>
> /*
> - * Unregister the video devices.
> - */
> -static void uvc_unregister_video(struct uvc_device *dev)
> -{
> -     struct uvc_streaming *streaming;
> -
> -     list_for_each_entry(streaming, &dev->streams, list) {
> -             if (streaming->vdev == NULL)
> -                     continue;
> -
> -             if (streaming->vdev->minor == -1)
> -                     video_device_release(streaming->vdev);
> -             else
> -                     video_unregister_device(streaming->vdev);
> -             streaming->vdev = NULL;
> -     }
> -}
> -
> -static int uvc_register_video(struct uvc_device *dev,
> -             struct uvc_streaming *stream)
> -{
> -     struct video_device *vdev;
> -     struct uvc_entity *term;
> -     int ret;
> -
> -     if (uvc_trace_param & UVC_TRACE_PROBE) {
> -             uvc_printk(KERN_INFO, "Found a valid video chain (");
> -             list_for_each_entry(term, &dev->video.iterms, chain) {
> -                     printk("%d", term->id);
> -                     if (term->chain.next != &dev->video.iterms)
> -                             printk(",");
> -             }
> -             printk(" -> %d).\n", dev->video.oterm->id);
> -     }
> -
> -     /* Initialize the streaming interface with default streaming
> -      * parameters.
> -      */
> -     ret = uvc_video_init(stream);
> -     if (ret < 0) {
> -             uvc_printk(KERN_ERR, "Failed to initialize the device "
> -                     "(%d).\n", ret);
> -             return ret;
> -     }
> -
> -     /* Register the device with V4L. */
> -     vdev = video_device_alloc();
> -     if (vdev == NULL)
> -             return -1;
> -
> -     /* We already hold a reference to dev->udev. The video device will be
> -      * unregistered before the reference is released, so we don't need to
> -      * get another one.
> -      */
> -     vdev->parent = &dev->intf->dev;
> -     vdev->minor = -1;
> -     vdev->fops = &uvc_fops;
> -     vdev->release = video_device_release;
> -     strlcpy(vdev->name, dev->name, sizeof vdev->name);
> -
> -     /* Set the driver data before calling video_register_device, otherwise
> -      * uvc_v4l2_open might race us.
> -      */
> -     stream->vdev = vdev;
> -     video_set_drvdata(vdev, stream);
> -
> -     if (video_register_device(vdev, VFL_TYPE_GRABBER, -1) < 0) {
> -             stream->vdev = NULL;
> -             video_device_release(vdev);
> -             return -1;
> -     }
> -
> -     return 0;
> -}
> -
> -/*
> * Scan the UVC descriptors to locate a chain starting at an Output
> Terminal
> * and containing the following units:
> *
> - * - one Output Terminal (USB Streaming or Display)
> + * - one or more Output Terminals (USB Streaming or Display)
> * - zero or one Processing Unit
> - * - zero, one or mode single-input Selector Units
> + * - zero, one or more single-input Selector Units
> * - zero or one multiple-input Selector Units, provided all inputs are
> *   connected to input terminals
> * - zero, one or mode single-input Extension Units
> * - one or more Input Terminals (Camera, External or USB Streaming)
> *
> - * A side forward scan is made on each detected entity to check for
> additional - * extension units.
> + * The terminal and units must match on of the following structures:
> + *
> + * ITT_*(0) -> +---------+    +---------+    +---------+ ->
> TT_STREAMING(0)
> + * ...         | SU{0,1} | -> | PU{0,1} | -> | XU{0,n} |    ...
> + * ITT_*(n) -> +---------+    +---------+    +---------+ ->
> TT_STREAMING(n)
> + *
> + *                 +---------+    +---------+ -> OTT_*(0)
> + * TT_STREAMING -> | PU{0,1} | -> | XU{0,n} |    ...
> + *                 +---------+    +---------+ -> OTT_*(n)
> + *
> + * The Processing Unit and Extension Units can be in any order.
> Additional
> + * Extension Units connected to the main chain as single-unit branches
> are + * also supported. Single-input Selector Units are ignored.
> */
> -static int uvc_scan_chain_entity(struct uvc_video_device *video,
> +static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
> struct uvc_entity *entity) {
> switch (UVC_ENTITY_TYPE(entity)) { @@ -1267,20 +1214,20 @@
> return -1; }
>
>
> -             list_add_tail(&entity->chain, &video->extensions);
> +             list_add_tail(&entity->chain, &chain->extensions);
> break;
>
> case VC_PROCESSING_UNIT: if (uvc_trace_param & UVC_TRACE_PROBE) printk(" <-
> PU %d", entity->id);
>
>
> -             if (video->processing != NULL) {
> +             if (chain->processing != NULL) {
> uvc_trace(UVC_TRACE_DESCR, "Found multiple " "Processing Units in
> chain.\n"); return -1; }
>
>
> -             video->processing = entity;
> +             chain->processing = entity;
> break;
>
> case VC_SELECTOR_UNIT: @@ -1291,13 +1238,13 @@
> if (entity->selector.bNrInPins == 1) break;
>
> -             if (video->selector != NULL) {
> +             if (chain->selector != NULL) {
> uvc_trace(UVC_TRACE_DESCR, "Found multiple Selector " "Units in chain.\n");
>  return -1; }
>
>
> -             video->selector = entity;
> +             chain->selector = entity;
> break;
>
> case ITT_VENDOR_SPECIFIC: @@ -1306,7 +1253,7 @@
> if (uvc_trace_param & UVC_TRACE_PROBE) printk(" <- IT %d\n", entity->id);
>
> -             list_add_tail(&entity->chain, &video->iterms);
> +             list_add_tail(&entity->chain, &chain->iterms);
> break;
>
> case TT_STREAMING: @@ -1319,14 +1266,7 @@
> return -1; }
>
>
> -             if (video->sterm != NULL) {
> -                     uvc_trace(UVC_TRACE_DESCR, "Found multiple streaming "
> -                             "entities in chain.\n");
> -                     return -1;
> -             }
> -
> -             list_add_tail(&entity->chain, &video->iterms);
> -             video->sterm = entity;
> +             list_add_tail(&entity->chain, &chain->iterms);
> break;
>
> default:
> @@ -1338,7 +1278,7 @@
> return 0; }
>
>
> -static int uvc_scan_chain_forward(struct uvc_video_device *video,
> +static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
> struct uvc_entity *entity, struct uvc_entity *prev) {
> struct uvc_entity *forward; @@ -1349,28 +1289,51 @@
> found = 0;
>
> while (1) { -         forward = uvc_entity_by_reference(video->dev, 
> entity->id,
> +             forward = uvc_entity_by_reference(chain->dev, entity->id,
> forward); if (forward == NULL) break; -
> -             if (UVC_ENTITY_TYPE(forward) != VC_EXTENSION_UNIT ||
> -                 forward == prev)
> +             if (forward == prev)
> continue;
>
> -             if (forward->extension.bNrInPins != 1) {
> -                     uvc_trace(UVC_TRACE_DESCR, "Extension unit %d has "
> -                             "more than 1 input pin.\n", entity->id);
> -                     return -1;
> -             }
> +             switch (UVC_ENTITY_TYPE(forward)) {
> +             case VC_EXTENSION_UNIT:
> +                     if (forward->extension.bNrInPins != 1) {
> +                             uvc_trace(UVC_TRACE_DESCR, "Extension unit %d "
> +                                       "has more than 1 input pin.\n",
> +                                       entity->id);
> +                             return -EINVAL;
> +                     }
>
>
> -             list_add_tail(&forward->chain, &video->extensions);
> -             if (uvc_trace_param & UVC_TRACE_PROBE) {
> -                     if (!found)
> -                             printk(" (-> XU");
> +                     list_add_tail(&forward->chain, &chain->extensions);
> +                     if (uvc_trace_param & UVC_TRACE_PROBE) {
> +                             if (!found)
> +                                     printk(" (->");
>
>
> -                     printk(" %d", forward->id);
> -                     found = 1;
> +                             printk(" XU %d", forward->id);
> +                             found = 1;
> +                     }
> +                     break;
> +
> +             case OTT_VENDOR_SPECIFIC:
> +             case OTT_DISPLAY:
> +             case OTT_MEDIA_TRANSPORT_OUTPUT:
> +             case TT_STREAMING:
> +                     if (UVC_ENTITY_IS_ITERM(forward)) {
> +                             uvc_trace(UVC_TRACE_DESCR, "Unsupported input "
> +                                     "terminal %u.\n", forward->id);
> +                             return -EINVAL;
> +                     }
> +
> +                     list_add_tail(&forward->chain, &chain->oterms);
> +                     if (uvc_trace_param & UVC_TRACE_PROBE) {
> +                             if (!found)
> +                                     printk(" (->");
> +
> +                             printk(" OT %d", forward->id);
> +                             found = 1;
> +                     }
> +                     break;
> }
> }
> if (found) @@ -1379,7 +1342,7 @@
> return 0; }
>
>
> -static int uvc_scan_chain_backward(struct uvc_video_device *video,
> +static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
> struct uvc_entity *entity) {
> struct uvc_entity *term; @@ -1404,10 +1367,10 @@
> if (uvc_trace_param & UVC_TRACE_PROBE) printk(" <- IT");
>
> -             video->selector = entity;
> +             chain->selector = entity;
> for (i = 0; i < entity->selector.bNrInPins; ++i) { id =
> entity->selector.baSourceID[i]; -                     term = 
> uvc_entity_by_id(video->dev,
> id); +                        term = uvc_entity_by_id(chain->dev, id);
> if (term == NULL || !UVC_ENTITY_IS_ITERM(term)) {
> uvc_trace(UVC_TRACE_DESCR, "Selector unit %d " "input %d isn't connected
> to an " @@ -1418,8 +1381,8 @@
> if (uvc_trace_param & UVC_TRACE_PROBE) printk(" %d", term->id);
>
> -                     list_add_tail(&term->chain, &video->iterms);
> -                     uvc_scan_chain_forward(video, term, entity);
> +                     list_add_tail(&term->chain, &chain->iterms);
> +                     uvc_scan_chain_forward(chain, term, entity);
> }
>
>
> if (uvc_trace_param & UVC_TRACE_PROBE) @@ -1432,108 +1395,264 @@
> return id; }
>
>
> -static int uvc_scan_chain(struct uvc_video_device *video)
> +static int uvc_scan_chain(struct uvc_video_chain *chain,
> +                       struct uvc_entity *oterm)
> {
> struct uvc_entity *entity, *prev; int id;
>
> -     entity = video->oterm;
> +     entity = oterm;
> +     list_add_tail(&entity->chain, &chain->oterms);
> uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id);
>
> -     if (UVC_ENTITY_TYPE(entity) == TT_STREAMING)
> -             video->sterm = entity;
> -
> id = entity->output.bSourceID; while (id != 0) { prev = entity; -             
> entity =
> uvc_entity_by_id(video->dev, id); +           entity = 
> uvc_entity_by_id(chain->dev,
> id); if (entity == NULL) { uvc_trace(UVC_TRACE_DESCR, "Found reference to "
>  "unknown entity %d.\n", id);
> -                     return -1;
> +                     return -EINVAL;
> +             }
> +
> +             if (entity->chain.next || entity->chain.prev) {
> +                     uvc_trace(UVC_TRACE_DESCR, "Found reference to "
> +                             "entity %d already in chain.\n", id);
> +                     return -EINVAL;
> }
>
>
> /* Process entity */
> -             if (uvc_scan_chain_entity(video, entity) < 0)
> -                     return -1;
> +             if (uvc_scan_chain_entity(chain, entity) < 0)
> +                     return -EINVAL;
>
>
> /* Forward scan */
> -             if (uvc_scan_chain_forward(video, entity, prev) < 0)
> -                     return -1;
> +             if (uvc_scan_chain_forward(chain, entity, prev) < 0)
> +                     return -EINVAL;
>
>
> /* Stop when a terminal is found. */
> -             if (!UVC_ENTITY_IS_UNIT(entity))
> +             if (UVC_ENTITY_IS_TERM(entity))
> break;
>
> /* Backward scan */
> -             id = uvc_scan_chain_backward(video, entity);
> +             id = uvc_scan_chain_backward(chain, entity);
> if (id < 0) return id; }
>
>
> -     if (video->sterm == NULL) {
> -             uvc_trace(UVC_TRACE_DESCR, "No streaming entity found in "
> -                     "chain.\n");
> +     return 0;
> +}
> +
> +static unsigned int uvc_print_terms(struct list_head *terms, char
> *buffer)
> +{
> +     struct uvc_entity *term;
> +     unsigned int nterms = 0;
> +     char *p = buffer;
> +
> +     list_for_each_entry(term, terms, chain) {
> +             p += sprintf(p, "%u", term->id);
> +             if (term->chain.next != terms) {
> +                     p += sprintf(p, ",");
> +                     if (++nterms >= 4) {
> +                             p += sprintf(p, "...");
> +                             break;
> +                     }
> +             }
> +     }
> +
> +     return p - buffer;
> +}
> +
> +static const char *uvc_print_chain(struct uvc_video_chain *chain)
> +{
> +     static char buffer[43];
> +     char *p = buffer;
> +
> +     p += uvc_print_terms(&chain->iterms, p);
> +     p += sprintf(p, " -> ");
> +     uvc_print_terms(&chain->oterms, p);
> +
> +     return buffer;
> +}
> +
> +/*
> + * Scan the device for video chains and register video devices.
> + *
> + * Chains are scanned starting at their output terminals and walked
> backwards. + */
> +static int uvc_scan_device(struct uvc_device *dev)
> +{
> +     struct uvc_video_chain *chain;
> +     struct uvc_entity *term;
> +
> +     list_for_each_entry(term, &dev->entities, list) {
> +             if (!UVC_ENTITY_IS_OTERM(term))
> +                     continue;
> +
> +             /* If the terminal is already included in a chain, skip it.
> +              * This can happen for chains that have multiple output
> +              * terminals, where all output terminals beside the first one
> +              * will be inserted in the chain in forward scans.
> +              */
> +             if (term->chain.next || term->chain.prev)
> +                     continue;
> +
> +             chain = kzalloc(sizeof(*chain), GFP_KERNEL);
> +             if (chain == NULL)
> +                     return -ENOMEM;
> +
> +             INIT_LIST_HEAD(&chain->iterms);
> +             INIT_LIST_HEAD(&chain->oterms);
> +             INIT_LIST_HEAD(&chain->extensions);
> +             mutex_init(&chain->ctrl_mutex);
> +             chain->dev = dev;
> +
> +             if (uvc_scan_chain(chain, term) < 0) {
> +                     kfree(chain);
> +                     continue;
> +             }
> +
> +             uvc_trace(UVC_TRACE_PROBE, "Found a valid video chain (%s).\n",
> +                       uvc_print_chain(chain));
> +
> +             list_add_tail(&chain->list, &dev->chains);
> +     }
> +
> +     if (list_empty(&dev->chains)) {
> +             uvc_printk(KERN_INFO, "No valid video chain found.\n");
> return -1; }
>
>
> return 0; }
>
>
> +/*
> ------------------------------------------------------------------------
> + * Video device registration and unregistration
> + */
> +
> /*
> - * Scan the device for video chains and register video devices.
> - *
> - * The driver currently supports a single video device per control
> interface - * only. The terminal and units must match the following
> structure:
> - *
> - * ITT_* -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> TT_STREAMING
> - * TT_STREAMING -> VC_PROCESSING_UNIT -> VC_EXTENSION_UNIT{0,n} -> OTT_*
> - *
> - * The Extension Units, if present, must have a single input pin. The
> - * Processing Unit and Extension Units can be in any order. Additional
> - * Extension Units connected to the main chain as single-unit branches
> are - * also supported.
> + * Unregister the video devices.
> */
> -static int uvc_scan_device(struct uvc_device *dev)
> +static void uvc_unregister_video(struct uvc_device *dev)
> {
> -     struct uvc_entity *term;
> -     int found = 0;
> +     struct uvc_streaming *stream;
>
>
> -     /* Check if the control interface matches the structure we expect. */
> -     list_for_each_entry(term, &dev->entities, list) {
> -             struct uvc_streaming *stream;
> -
> -             if (!UVC_ENTITY_IS_TERM(term) || !UVC_ENTITY_IS_OTERM(term))
> +     list_for_each_entry(stream, &dev->streams, list) {
> +             if (stream->vdev == NULL)
> continue;
>
> -             memset(&dev->video, 0, sizeof dev->video);
> -             mutex_init(&dev->video.ctrl_mutex);
> -             INIT_LIST_HEAD(&dev->video.iterms);
> -             INIT_LIST_HEAD(&dev->video.extensions);
> -             dev->video.oterm = term;
> -             dev->video.dev = dev;
> -             if (uvc_scan_chain(&dev->video) < 0)
> -                     continue;
> +             if (stream->vdev->minor == -1)
> +                     video_device_release(stream->vdev);
> +             else
> +                     video_unregister_device(stream->vdev);
> +             stream->vdev = NULL;
> +     }
> +}
>
>
> -             list_for_each_entry(stream, &dev->streams, list) {
> -                     if (stream->header.bTerminalLink ==
> -                         dev->video.sterm->id) {
> -                             uvc_register_video(dev, stream);
> -                             found = 1;
> -                             break;
> -                     }
> -             }
> +static int uvc_register_video(struct uvc_device *dev,
> +             struct uvc_streaming *stream)
> +{
> +     struct video_device *vdev;
> +     int ret;
> +
> +     /* Initialize the streaming interface with default streaming
> +      * parameters.
> +      */
> +     ret = uvc_video_init(stream);
> +     if (ret < 0) {
> +             uvc_printk(KERN_ERR, "Failed to initialize the device "
> +                     "(%d).\n", ret);
> +             return ret;
> }
>
>
> -     if (!found) {
> -             uvc_printk(KERN_INFO, "No valid video chain found.\n");
> -             return -1;
> +     /* Register the device with V4L. */
> +     vdev = video_device_alloc();
> +     if (vdev == NULL) {
> +             uvc_printk(KERN_ERR, "Failed to allocate video device (%d).\n",
> +                        ret);
> +             return -ENOMEM;
> +     }
> +
> +     /* We already hold a reference to dev->udev. The video device will be
> +      * unregistered before the reference is released, so we don't need to
> +      * get another one.
> +      */
> +     vdev->parent = &dev->intf->dev;
> +     vdev->minor = -1;
> +     vdev->fops = &uvc_fops;
> +     vdev->release = video_device_release;
> +     strlcpy(vdev->name, dev->name, sizeof vdev->name);
> +
> +     /* Set the driver data before calling video_register_device, otherwise
> +      * uvc_v4l2_open might race us.
> +      */
> +     stream->vdev = vdev;
> +     video_set_drvdata(vdev, stream);
> +
> +     ret = video_register_device(vdev, VFL_TYPE_GRABBER, -1);
> +     if (ret < 0) {
> +             uvc_printk(KERN_ERR, "Failed to register video device (%d).\n",
> +                        ret);
> +             stream->vdev = NULL;
> +             video_device_release(vdev);
> +             return ret;
> }
>
>
> return 0; }
>
>
> /*
> + * Register all video devices in all chains.
> + */
> +static int uvc_register_terms(struct uvc_device *dev,
> +     struct uvc_video_chain *chain, struct list_head *terms)
> +{
> +     struct uvc_streaming *stream;
> +     struct uvc_entity *term;
> +     int ret;
> +
> +     list_for_each_entry(term, terms, chain) {
> +             if (UVC_ENTITY_TYPE(term) != TT_STREAMING)
> +                     continue;
> +
> +             stream = uvc_stream_by_id(dev, term->id);
> +             if (stream == NULL) {
> +                     uvc_printk(KERN_INFO, "No streaming interface found "
> +                                "for terminal %u.", term->id);
> +                     continue;
> +             }
> +
> +             stream->chain = chain;
> +             ret = uvc_register_video(dev, stream);
> +             if (ret < 0)
> +                     return ret;
> +     }
> +
> +     return 0;
> +}
> +
> +static int uvc_register_chains(struct uvc_device *dev)
> +{
> +     struct uvc_video_chain *chain;
> +     int ret;
> +
> +     list_for_each_entry(chain, &dev->chains, list) {
> +             ret = uvc_register_terms(dev, chain, &chain->iterms);
> +             if (ret < 0)
> +                     return ret;
> +
> +             ret = uvc_register_terms(dev, chain, &chain->oterms);
> +             if (ret < 0)
> +                     return ret;
> +     }
> +
> +     return 0;
> +}
> +
> +/*
> ------------------------------------------------------------------------
> + * USB probe, disconnect, suspend and resume
> + */
> +
> +/*
> * Delete the UVC device.
> *
> * Called by the kernel when the last reference to the uvc_device structure
>  @@ -1554,7 +1673,7 @@
> struct uvc_device *dev = container_of(kref, struct uvc_device, kref);
> struct list_head *p, *n;
>
> -     /* Unregister the video device. */
> +     /* Unregister the video devices. */
> uvc_unregister_video(dev); usb_put_intf(dev->intf); usb_put_dev(dev->udev);
> @@ -1562,6 +1681,12 @@
> uvc_status_cleanup(dev); uvc_ctrl_cleanup_device(dev);
>
> +     list_for_each_safe(p, n, &dev->chains) {
> +             struct uvc_video_chain *chain;
> +             chain = list_entry(p, struct uvc_video_chain, list);
> +             kfree(chain);
> +     }
> +
> list_for_each_safe(p, n, &dev->entities) { struct uvc_entity *entity;
entity
> = list_entry(p, struct uvc_entity, list);
> @@ -1602,6 +1727,7 @@
> return -ENOMEM;
>
> INIT_LIST_HEAD(&dev->entities);
> +     INIT_LIST_HEAD(&dev->chains);
> INIT_LIST_HEAD(&dev->streams);
> kref_init(&dev->kref); atomic_set(&dev->users, 0); @@ -1643,10 +1769,14 @@
> if (uvc_ctrl_init_device(dev) < 0) goto error;
>
> -     /* Scan the device for video chains and register video devices. */
> +     /* Scan the device for video chains. */
> if (uvc_scan_device(dev) < 0) goto error;
>
> +     /* Register video devices. */
> +     if (uvc_register_chains(dev) < 0)
> +             goto error;
> +
> /* Save our data pointer in the interface data. */
> usb_set_intfdata(intf, dev);
>
> diff -r 88ef3b9f5071 -r 012e480c8e6a
> linux/drivers/media/video/uvc/uvc_v4l2.c ---
> a/linux/drivers/media/video/uvc/uvc_v4l2.c    Sun Jun 28 13:37:50 2009 +0200
>  +++ b/linux/drivers/media/video/uvc/uvc_v4l2.c       Thu Jul 02 01:24:47 2009
> +0200
> @@ -40,7 +40,7 @@
> * table for the controls that can be mapped directly, and handle the
> others * manually.
> */
> -static int uvc_v4l2_query_menu(struct uvc_video_device *video,
> +static int uvc_v4l2_query_menu(struct uvc_video_chain *chain,
> struct v4l2_querymenu *query_menu) {
> struct uvc_menu_info *menu_info; @@ -49,7 +49,7 @@
> u32 index = query_menu->index; u32 id = query_menu->id;
>
> -     ctrl = uvc_find_control(video, query_menu->id, &mapping);
> +     ctrl = uvc_find_control(chain, query_menu->id, &mapping);
> if (ctrl == NULL || mapping->v4l2_type != V4L2_CTRL_TYPE_MENU) return
> -EINVAL;
>
>
> @@ -493,7 +493,7 @@
> }
> }
>
>
> -     handle->video = &stream->dev->video;
> +     handle->chain = stream->chain;
> handle->stream = stream; handle->state = UVC_HANDLE_PASSIVE;
> file->private_data = handle; @@ -542,7 +542,7 @@
> {
> struct video_device *vdev = video_devdata(file); struct uvc_fh *handle =
> (struct uvc_fh *)file->private_data;
> -     struct uvc_video_device *video = handle->video;
> +     struct uvc_video_chain *chain = handle->chain;
> struct uvc_streaming *stream = handle->stream; long ret = 0;
>
> @@ -569,7 +569,7 @@
>
>
> /* Get, Set & Query control */
> case VIDIOC_QUERYCTRL: -              return uvc_query_v4l2_ctrl(video, arg);
> +             return uvc_query_v4l2_ctrl(chain, arg);
>
>
> case VIDIOC_G_CTRL: {
> @@ -579,9 +579,9 @@
> memset(&xctrl, 0, sizeof xctrl); xctrl.id = ctrl->id;
>
> -             uvc_ctrl_begin(video);
> -             ret = uvc_ctrl_get(video, &xctrl);
> -             uvc_ctrl_rollback(video);
> +             uvc_ctrl_begin(chain);
> +             ret = uvc_ctrl_get(chain, &xctrl);
> +             uvc_ctrl_rollback(chain);
> if (ret >= 0) ctrl->value = xctrl.value; break; @@ -596,18 +596,18 @@
> xctrl.id = ctrl->id; xctrl.value = ctrl->value;
>
> -             uvc_ctrl_begin(video);
> -             ret = uvc_ctrl_set(video, &xctrl);
> +             uvc_ctrl_begin(chain);
> +             ret = uvc_ctrl_set(chain, &xctrl);
> if (ret < 0) { -                      uvc_ctrl_rollback(video);
> +                     uvc_ctrl_rollback(chain);
> return ret; }
> -             ret = uvc_ctrl_commit(video);
> +             ret = uvc_ctrl_commit(chain);
> break; }
>
>
> case VIDIOC_QUERYMENU: -              return uvc_v4l2_query_menu(video, arg);
> +             return uvc_v4l2_query_menu(chain, arg);
>
>
> case VIDIOC_G_EXT_CTRLS: {
> @@ -615,17 +615,17 @@
> struct v4l2_ext_control *ctrl = ctrls->controls; unsigned int i;
>
> -             uvc_ctrl_begin(video);
> +             uvc_ctrl_begin(chain);
> for (i = 0; i < ctrls->count; ++ctrl, ++i) { -                        ret = 
> uvc_ctrl_get(video,
> ctrl); +                      ret = uvc_ctrl_get(chain, ctrl);
> if (ret < 0) { -                              uvc_ctrl_rollback(video);
> +                             uvc_ctrl_rollback(chain);
> ctrls->error_idx = i; return ret; }
> }
> ctrls->error_idx = 0; -               ret = uvc_ctrl_rollback(video);
> +             ret = uvc_ctrl_rollback(chain);
> break; }
>
>
> @@ -636,14 +636,14 @@
> struct v4l2_ext_control *ctrl = ctrls->controls; unsigned int i;
>
> -             ret = uvc_ctrl_begin(video);
> +             ret = uvc_ctrl_begin(chain);
> if (ret < 0) return ret;
>
> for (i = 0; i < ctrls->count; ++ctrl, ++i) { -                        ret = 
> uvc_ctrl_set(video,
> ctrl); +                      ret = uvc_ctrl_set(chain, ctrl);
> if (ret < 0) { -                              uvc_ctrl_rollback(video);
> +                             uvc_ctrl_rollback(chain);
> ctrls->error_idx = i; return ret; }
> @@ -652,31 +652,31 @@
> ctrls->error_idx = 0;
>
> if (cmd == VIDIOC_S_EXT_CTRLS) -                      ret = 
> uvc_ctrl_commit(video);
> +                     ret = uvc_ctrl_commit(chain);
> else -                        ret = uvc_ctrl_rollback(video);
> +                     ret = uvc_ctrl_rollback(chain);
> break; }
>
>
> /* Get, Set & Enum input */
> case VIDIOC_ENUMINPUT: {
> -             const struct uvc_entity *selector = video->selector;
> +             const struct uvc_entity *selector = chain->selector;
> struct v4l2_input *input = arg; struct uvc_entity *iterm = NULL; u32
index =
> input->index; int pin = 0;
>
> if (selector == NULL || -                 (video->dev->quirks &
> UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
> +                 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
> if (index != 0) return -EINVAL; -                     iterm =
list_first_entry(&video->iterms,
>  +                    iterm = list_first_entry(&chain->iterms,
> struct uvc_entity, chain); pin = iterm->id; } else if (pin <
> selector->selector.bNrInPins) { pin =
> selector->selector.baSourceID[index]; -                       
> list_for_each_entry(iterm,
> video->iterms.next, chain) { +                        
> list_for_each_entry(iterm,
> chain->iterms.next, chain) { if (iterm->id == pin) break; }
> @@ -697,14 +697,14 @@
> {
> u8 input;
>
> -             if (video->selector == NULL ||
> -                 (video->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
> +             if (chain->selector == NULL ||
> +                 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
> *(int *)arg = 0;
> break; }
>
>
> -             ret = uvc_query_ctrl(video->dev, GET_CUR, video->selector->id,
> -                     video->dev->intfnum, SU_INPUT_SELECT_CONTROL,
> +             ret = uvc_query_ctrl(chain->dev, GET_CUR, chain->selector->id,
> +                     chain->dev->intfnum, SU_INPUT_SELECT_CONTROL,
> &input, 1);
> if (ret < 0) return ret; @@ -720,18 +720,18 @@
> if ((ret = uvc_acquire_privileges(handle)) < 0) return ret;
>
> -             if (video->selector == NULL ||
> -                 (video->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
> +             if (chain->selector == NULL ||
> +                 (chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
> if (input != 1) return -EINVAL; break; }
>
>
> -             if (input == 0 || input > video->selector->selector.bNrInPins)
> +             if (input == 0 || input > chain->selector->selector.bNrInPins)
> return -EINVAL;
>
> -             return uvc_query_ctrl(video->dev, SET_CUR, video->selector->id,
> -                     video->dev->intfnum, SU_INPUT_SELECT_CONTROL,
> +             return uvc_query_ctrl(chain->dev, SET_CUR, chain->selector->id,
> +                     chain->dev->intfnum, SU_INPUT_SELECT_CONTROL,
> &input, 1);
> }
>
>
> @@ -1064,10 +1064,10 @@
> }
>
>
> case UVCIOC_CTRL_GET: -               return uvc_xu_ctrl_query(video, arg, 0);
> +             return uvc_xu_ctrl_query(chain, arg, 0);
>
>
> case UVCIOC_CTRL_SET: -               return uvc_xu_ctrl_query(video, arg, 1);
> +             return uvc_xu_ctrl_query(chain, arg, 1);
>
>
> default:
> if ((ret = v4l_compat_translate_ioctl(file, cmd, arg, diff -r 88ef3b9f5071
> -r 012e480c8e6a linux/drivers/media/video/uvc/uvcvideo.h
> --- a/linux/drivers/media/video/uvc/uvcvideo.h        Sun Jun 28 13:37:50 2009
> +0200
> +++ b/linux/drivers/media/video/uvc/uvcvideo.h        Thu Jul 02 01:24:47 2009
> +0200
> @@ -224,9 +224,11 @@
> #define UVC_ENTITY_IS_UNIT(entity)    (((entity)->type & 0xff00) == 0)
> #define UVC_ENTITY_IS_TERM(entity)    (((entity)->type & 0xff00) != 0)
> #define UVC_ENTITY_IS_ITERM(entity) \
> -     (((entity)->type & 0x8000) == UVC_TERM_INPUT)
> +     (UVC_ENTITY_IS_TERM(entity) && \
> +     ((entity)->type & 0x8000) == UVC_TERM_INPUT)
> #define UVC_ENTITY_IS_OTERM(entity) \
> -     (((entity)->type & 0x8000) == UVC_TERM_OUTPUT)
> +     (UVC_ENTITY_IS_TERM(entity) && \
> +     ((entity)->type & 0x8000) == UVC_TERM_OUTPUT)
>
>
> #define UVC_STATUS_TYPE_CONTROL               1
> #define UVC_STATUS_TYPE_STREAMING     2
> @@ -560,10 +562,24 @@
> struct list_head irqqueue; };
>
>
> +struct uvc_video_chain {
> +     struct uvc_device *dev;
> +     struct list_head list;
> +
> +     struct list_head iterms;                /* Input terminals */
> +     struct list_head oterms;                /* Output terminals */
> +     struct uvc_entity *processing;          /* Processing unit */
> +     struct uvc_entity *selector;            /* Selector unit */
> +     struct list_head extensions;            /* Extension units */
> +
> +     struct mutex ctrl_mutex;
> +};
> +
> struct uvc_streaming { struct list_head list; struct uvc_device *dev;
struct
> video_device *vdev; + struct uvc_video_chain *chain;
> atomic_t active;
>
> struct usb_interface *intf; @@ -604,18 +620,6 @@
> __u8 last_fid;
> };
>
>
> -struct uvc_video_device {
> -     struct uvc_device *dev;
> -
> -     struct list_head iterms;                /* Input terminals */
> -     struct uvc_entity *oterm;               /* Output terminal */
> -     struct uvc_entity *sterm;               /* USB streaming terminal */
> -     struct uvc_entity *processing;
> -     struct uvc_entity *selector;
> -     struct list_head extensions;
> -     struct mutex ctrl_mutex;
> -};
> -
> enum uvc_device_state { UVC_DEV_DISCONNECTED = 1,
> };
> @@ -638,8 +642,7 @@
> __u32 clock_frequency;
>
>
> struct list_head entities; -
> -     struct uvc_video_device video;
> +     struct list_head chains;
>
>
> /* Video Streaming interfaces */
> struct list_head streams; @@ -658,7 +661,7 @@
> };
>
>
> struct uvc_fh { -     struct uvc_video_device *video;
> +     struct uvc_video_chain *chain;
> struct uvc_streaming *stream; enum uvc_handle_state state; };
> @@ -776,9 +779,9 @@
> extern int uvc_status_resume(struct uvc_device *dev);
>
> /* Controls */
> -extern struct uvc_control *uvc_find_control(struct uvc_video_device
> *video,
> +extern struct uvc_control *uvc_find_control(struct uvc_video_chain
> *chain,
> __u32 v4l2_id, struct uvc_control_mapping **mapping);
> -extern int uvc_query_v4l2_ctrl(struct uvc_video_device *video,
> +extern int uvc_query_v4l2_ctrl(struct uvc_video_chain *chain,
> struct v4l2_queryctrl *v4l2_ctrl);
>
> extern int uvc_ctrl_add_info(struct uvc_control_info *info); @@ -788,23
> +791,23 @@
> extern int uvc_ctrl_resume_device(struct uvc_device *dev); extern void
> uvc_ctrl_init(void);
>
> -extern int uvc_ctrl_begin(struct uvc_video_device *video);
> -extern int __uvc_ctrl_commit(struct uvc_video_device *video, int
> rollback); -static inline int uvc_ctrl_commit(struct uvc_video_device
> *video)
> +extern int uvc_ctrl_begin(struct uvc_video_chain *chain);
> +extern int __uvc_ctrl_commit(struct uvc_video_chain *chain, int
> rollback); +static inline int uvc_ctrl_commit(struct uvc_video_chain
> *chain)
> {
> -     return __uvc_ctrl_commit(video, 0);
> +     return __uvc_ctrl_commit(chain, 0);
> }
> -static inline int uvc_ctrl_rollback(struct uvc_video_device *video)
> +static inline int uvc_ctrl_rollback(struct uvc_video_chain *chain)
> {
> -     return __uvc_ctrl_commit(video, 1);
> +     return __uvc_ctrl_commit(chain, 1);
> }
>
>
> -extern int uvc_ctrl_get(struct uvc_video_device *video,
> +extern int uvc_ctrl_get(struct uvc_video_chain *chain,
> struct v4l2_ext_control *xctrl); -extern int uvc_ctrl_set(struct
> uvc_video_device *video, +extern int uvc_ctrl_set(struct uvc_video_chain
> *chain,
> struct v4l2_ext_control *xctrl);
>
> -extern int uvc_xu_ctrl_query(struct uvc_video_device *video,
> +extern int uvc_xu_ctrl_query(struct uvc_video_chain *chain,
> struct uvc_xu_control *ctrl, int set);
>
> /* Utility functions */
>
>
> _______________________________________________
> Linux-uvc-devel mailing list
> [email protected]
> https://lists.berlios.de/mailman/listinfo/linux-uvc-devel
>
>


_______________________________________________
Linux-uvc-devel mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/linux-uvc-devel

Reply via email to