forked from luck/tmp_suning_uos_patched
V4L/DVB (13505): uvcvideo: Refactor chain scan
Don't handle the first output terminal in a chain in a special way. Use uvc_scan_chain_entity() like for all other entities, making the chain scan code more generic. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
This commit is contained in:
parent
fd3e921739
commit
4057ac6ca9
@ -1265,13 +1265,12 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
|
||||
break;
|
||||
|
||||
case UVC_TT_STREAMING:
|
||||
if (uvc_trace_param & UVC_TRACE_PROBE)
|
||||
printk(" <- IT %d\n", entity->id);
|
||||
|
||||
if (!UVC_ENTITY_IS_ITERM(entity)) {
|
||||
uvc_trace(UVC_TRACE_DESCR, "Unsupported input "
|
||||
"terminal %u.\n", entity->id);
|
||||
return -1;
|
||||
if (UVC_ENTITY_IS_ITERM(entity)) {
|
||||
if (uvc_trace_param & UVC_TRACE_PROBE)
|
||||
printk(" <- IT %d\n", entity->id);
|
||||
} else {
|
||||
if (uvc_trace_param & UVC_TRACE_PROBE)
|
||||
printk(" OT %d", entity->id);
|
||||
}
|
||||
|
||||
break;
|
||||
@ -1351,10 +1350,11 @@ static int uvc_scan_chain_forward(struct uvc_video_chain *chain,
|
||||
}
|
||||
|
||||
static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
|
||||
struct uvc_entity *entity)
|
||||
struct uvc_entity **_entity)
|
||||
{
|
||||
struct uvc_entity *entity = *_entity;
|
||||
struct uvc_entity *term;
|
||||
int id = -1, i;
|
||||
int id = -EINVAL, i;
|
||||
|
||||
switch (UVC_ENTITY_TYPE(entity)) {
|
||||
case UVC_VC_EXTENSION_UNIT:
|
||||
@ -1398,34 +1398,49 @@ static int uvc_scan_chain_backward(struct uvc_video_chain *chain,
|
||||
|
||||
id = 0;
|
||||
break;
|
||||
|
||||
case UVC_ITT_VENDOR_SPECIFIC:
|
||||
case UVC_ITT_CAMERA:
|
||||
case UVC_ITT_MEDIA_TRANSPORT_INPUT:
|
||||
case UVC_OTT_VENDOR_SPECIFIC:
|
||||
case UVC_OTT_DISPLAY:
|
||||
case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
|
||||
case UVC_TT_STREAMING:
|
||||
id = UVC_ENTITY_IS_OTERM(entity) ? entity->output.bSourceID : 0;
|
||||
break;
|
||||
}
|
||||
|
||||
return id;
|
||||
if (id <= 0) {
|
||||
*_entity = NULL;
|
||||
return 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 -EINVAL;
|
||||
}
|
||||
|
||||
*_entity = entity;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int uvc_scan_chain(struct uvc_video_chain *chain,
|
||||
struct uvc_entity *oterm)
|
||||
struct uvc_entity *term)
|
||||
{
|
||||
struct uvc_entity *entity, *prev;
|
||||
int id;
|
||||
|
||||
entity = oterm;
|
||||
list_add_tail(&entity->chain, &chain->entities);
|
||||
uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain: OT %d", entity->id);
|
||||
uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain:");
|
||||
|
||||
id = entity->output.bSourceID;
|
||||
while (id != 0) {
|
||||
prev = entity;
|
||||
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 -EINVAL;
|
||||
}
|
||||
entity = term;
|
||||
prev = NULL;
|
||||
|
||||
while (entity != NULL) {
|
||||
/* Entity must not be part of an existing chain */
|
||||
if (entity->chain.next || entity->chain.prev) {
|
||||
uvc_trace(UVC_TRACE_DESCR, "Found reference to "
|
||||
"entity %d already in chain.\n", id);
|
||||
"entity %d already in chain.\n", entity->id);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
@ -1437,14 +1452,10 @@ static int uvc_scan_chain(struct uvc_video_chain *chain,
|
||||
if (uvc_scan_chain_forward(chain, entity, prev) < 0)
|
||||
return -EINVAL;
|
||||
|
||||
/* Stop when a terminal is found. */
|
||||
if (UVC_ENTITY_IS_TERM(entity))
|
||||
break;
|
||||
|
||||
/* Backward scan */
|
||||
id = uvc_scan_chain_backward(chain, entity);
|
||||
if (id < 0)
|
||||
return id;
|
||||
prev = entity;
|
||||
if (uvc_scan_chain_backward(chain, &entity) < 0)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user