===================================================================
@@ -744,17 +744,7 @@ struct uvc_control *uvc_find_control(str
v4l2_id &= V4L2_CTRL_ID_MASK;
/* Find the control. */
- __uvc_find_control(chain->processing, v4l2_id, mapping, &ctrl, next);
- if (ctrl && !next)
- return ctrl;
-
- 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, &chain->extensions, chain) {
+ list_for_each_entry(entity, &chain->entities, chain) {
__uvc_find_control(entity, v4l2_id, mapping, &ctrl, next);
if (ctrl && !next)
return ctrl;
@@ -946,17 +936,7 @@ int __uvc_ctrl_commit(struct uvc_video_c
int ret = 0;
/* Find the control. */
- ret = uvc_ctrl_commit_entity(chain->dev, chain->processing, rollback);
- if (ret < 0)
- goto done;
-
- 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, &chain->extensions, chain) {
+ list_for_each_entry(entity, &chain->entities, chain) {
ret = uvc_ctrl_commit_entity(chain->dev, entity, rollback);
if (ret < 0)
goto done;
@@ -1070,8 +1050,9 @@ int uvc_xu_ctrl_query(struct uvc_video_c
int ret;
/* Find the extension unit. */
- list_for_each_entry(entity, &chain->extensions, chain) {
- if (entity->id == xctrl->unit)
+ list_for_each_entry(entity, &chain->entities, chain) {
+ if (UVC_ENTITY_TYPE(entity) == UVC_VC_EXTENSION_UNIT &&
+ entity->id == xctrl->unit)
break;
}
===================================================================
@@ -1215,7 +1215,6 @@ static int uvc_scan_chain_entity(struct
return -1;
}
- list_add_tail(&entity->chain, &chain->extensions);
break;
case UVC_VC_PROCESSING_UNIT:
@@ -1254,7 +1253,6 @@ static int uvc_scan_chain_entity(struct
if (uvc_trace_param & UVC_TRACE_PROBE)
printk(" <- IT %d\n", entity->id);
- list_add_tail(&entity->chain, &chain->iterms);
break;
case UVC_TT_STREAMING:
@@ -1267,7 +1265,6 @@ static int uvc_scan_chain_entity(struct
return -1;
}
- list_add_tail(&entity->chain, &chain->iterms);
break;
default:
@@ -1276,6 +1273,7 @@ static int uvc_scan_chain_entity(struct
return -1;
}
+ list_add_tail(&entity->chain, &chain->entities);
return 0;
}
@@ -1306,7 +1304,7 @@ static int uvc_scan_chain_forward(struct
return -EINVAL;
}
- list_add_tail(&forward->chain, &chain->extensions);
+ list_add_tail(&forward->chain, &chain->entities);
if (uvc_trace_param & UVC_TRACE_PROBE) {
if (!found)
printk(" (->");
@@ -1326,7 +1324,7 @@ static int uvc_scan_chain_forward(struct
return -EINVAL;
}
- list_add_tail(&forward->chain, &chain->oterms);
+ list_add_tail(&forward->chain, &chain->entities);
if (uvc_trace_param & UVC_TRACE_PROBE) {
if (!found)
printk(" (->");
@@ -1382,7 +1380,7 @@ static int uvc_scan_chain_backward(struc
if (uvc_trace_param & UVC_TRACE_PROBE)
printk(" %d", term->id);
- list_add_tail(&term->chain, &chain->iterms);
+ list_add_tail(&term->chain, &chain->entities);
uvc_scan_chain_forward(chain, term, entity);
}
@@ -1403,7 +1401,7 @@ static int uvc_scan_chain(struct uvc_vid
int id;
entity = oterm;
- list_add_tail(&entity->chain, &chain->oterms);
+ list_add_tail(&entity->chain, &chain->entities);
uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id);
id = entity->output.bSourceID;
@@ -1443,21 +1441,25 @@ static int uvc_scan_chain(struct uvc_vid
return 0;
}
-static unsigned int uvc_print_terms(struct list_head *terms, char *buffer)
+static unsigned int uvc_print_terms(struct list_head *terms, u16 dir,
+ 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) {
+ if (!UVC_ENTITY_IS_TERM(term) ||
+ UVC_TERM_DIRECTION(term) != dir)
+ continue;
+
+ if (nterms)
p += sprintf(p, ",");
- if (++nterms >= 4) {
- p += sprintf(p, "...");
- break;
- }
+ if (++nterms >= 4) {
+ p += sprintf(p, "...");
+ break;
}
+ p += sprintf(p, "%u", term->id);
}
return p - buffer;
@@ -1468,9 +1470,9 @@ static const char *uvc_print_chain(struc
static char buffer[43];
char *p = buffer;
- p += uvc_print_terms(&chain->iterms, p);
+ p += uvc_print_terms(&chain->entities, UVC_TERM_INPUT, p);
p += sprintf(p, " -> ");
- uvc_print_terms(&chain->oterms, p);
+ uvc_print_terms(&chain->entities, UVC_TERM_OUTPUT, p);
return buffer;
}
@@ -1501,9 +1503,7 @@ static int uvc_scan_device(struct uvc_de
if (chain == NULL)
return -ENOMEM;
- INIT_LIST_HEAD(&chain->iterms);
- INIT_LIST_HEAD(&chain->oterms);
- INIT_LIST_HEAD(&chain->extensions);
+ INIT_LIST_HEAD(&chain->entities);
mutex_init(&chain->ctrl_mutex);
chain->dev = dev;
@@ -1676,13 +1676,13 @@ static int uvc_register_video(struct uvc
* 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_video_chain *chain)
{
struct uvc_streaming *stream;
struct uvc_entity *term;
int ret;
- list_for_each_entry(term, terms, chain) {
+ list_for_each_entry(term, &chain->entities, chain) {
if (UVC_ENTITY_TYPE(term) != UVC_TT_STREAMING)
continue;
@@ -1708,11 +1708,7 @@ static int uvc_register_chains(struct uv
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);
+ ret = uvc_register_terms(dev, chain);
if (ret < 0)
return ret;
}
===================================================================
@@ -76,6 +76,7 @@ struct uvc_xu_control {
#define UVC_TERM_INPUT 0x0000
#define UVC_TERM_OUTPUT 0x8000
+#define UVC_TERM_DIRECTION(term) ((term)->type & 0x8000)
#define UVC_ENTITY_TYPE(entity) ((entity)->type & 0x7fff)
#define UVC_ENTITY_IS_UNIT(entity) (((entity)->type & 0xff00) == 0)
@@ -409,11 +410,9 @@ 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 list_head entities; /* All entities */
struct uvc_entity *processing; /* Processing unit */
struct uvc_entity *selector; /* Selector unit */
- struct list_head extensions; /* Extension units */
struct mutex ctrl_mutex;
};
===================================================================
@@ -628,12 +628,16 @@ static long uvc_v4l2_do_ioctl(struct fil
(chain->dev->quirks & UVC_QUIRK_IGNORE_SELECTOR_UNIT)) {
if (index != 0)
return -EINVAL;
- iterm = list_first_entry(&chain->iterms,
- struct uvc_entity, chain);
+ list_for_each_entry(iterm, &chain->entities, chain) {
+ if (UVC_ENTITY_IS_ITERM(iterm))
+ break;
+ }
pin = iterm->id;
} else if (pin < selector->selector.bNrInPins) {
pin = selector->selector.baSourceID[index];
- list_for_each_entry(iterm, chain->iterms.next, chain) {
+ list_for_each_entry(iterm, &chain->entities, chain) {
+ if (!UVC_ENTITY_IS_ITERM(iterm))
+ continue;
if (iterm->id == pin)
break;
}