Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 4057ac6c authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab
Browse files

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: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent fd3e9217
Loading
Loading
Loading
Loading
+43 −32
Original line number Diff line number Diff line
@@ -1265,13 +1265,12 @@ static int uvc_scan_chain_entity(struct uvc_video_chain *chain,
		break;

	case UVC_TT_STREAMING:
		if (UVC_ENTITY_IS_ITERM(entity)) {
			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;
		} 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,24 +1398,23 @@ 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;
	}

	if (id <= 0) {
		*_entity = NULL;
		return id;
	}

static int uvc_scan_chain(struct uvc_video_chain *chain,
			  struct uvc_entity *oterm)
{
	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);

	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 "
@@ -1423,9 +1422,25 @@ static int uvc_scan_chain(struct uvc_video_chain *chain,
		return -EINVAL;
	}

	*_entity = entity;
	return 0;
}

static int uvc_scan_chain(struct uvc_video_chain *chain,
			  struct uvc_entity *term)
{
	struct uvc_entity *entity, *prev;

	uvc_trace(UVC_TRACE_PROBE, "Scanning UVC chain:");

	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;