cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

uvc_entity.c (3967B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 *      uvc_entity.c  --  USB Video Class driver
      4 *
      5 *      Copyright (C) 2005-2011
      6 *          Laurent Pinchart (laurent.pinchart@ideasonboard.com)
      7 */
      8
      9#include <linux/kernel.h>
     10#include <linux/list.h>
     11#include <linux/videodev2.h>
     12
     13#include <media/v4l2-common.h>
     14
     15#include "uvcvideo.h"
     16
     17static int uvc_mc_create_links(struct uvc_video_chain *chain,
     18				    struct uvc_entity *entity)
     19{
     20	const u32 flags = MEDIA_LNK_FL_ENABLED | MEDIA_LNK_FL_IMMUTABLE;
     21	struct media_entity *sink;
     22	unsigned int i;
     23	int ret;
     24
     25	sink = (UVC_ENTITY_TYPE(entity) == UVC_TT_STREAMING)
     26	     ? (entity->vdev ? &entity->vdev->entity : NULL)
     27	     : &entity->subdev.entity;
     28	if (sink == NULL)
     29		return 0;
     30
     31	for (i = 0; i < entity->num_pads; ++i) {
     32		struct media_entity *source;
     33		struct uvc_entity *remote;
     34		u8 remote_pad;
     35
     36		if (!(entity->pads[i].flags & MEDIA_PAD_FL_SINK))
     37			continue;
     38
     39		remote = uvc_entity_by_id(chain->dev, entity->baSourceID[i]);
     40		if (remote == NULL)
     41			return -EINVAL;
     42
     43		source = (UVC_ENTITY_TYPE(remote) == UVC_TT_STREAMING)
     44		       ? (remote->vdev ? &remote->vdev->entity : NULL)
     45		       : &remote->subdev.entity;
     46		if (source == NULL)
     47			continue;
     48
     49		remote_pad = remote->num_pads - 1;
     50		ret = media_create_pad_link(source, remote_pad,
     51					       sink, i, flags);
     52		if (ret < 0)
     53			return ret;
     54	}
     55
     56	return 0;
     57}
     58
     59static const struct v4l2_subdev_ops uvc_subdev_ops = {
     60};
     61
     62void uvc_mc_cleanup_entity(struct uvc_entity *entity)
     63{
     64	if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING)
     65		media_entity_cleanup(&entity->subdev.entity);
     66	else if (entity->vdev != NULL)
     67		media_entity_cleanup(&entity->vdev->entity);
     68}
     69
     70static int uvc_mc_init_entity(struct uvc_video_chain *chain,
     71			      struct uvc_entity *entity)
     72{
     73	int ret;
     74
     75	if (UVC_ENTITY_TYPE(entity) != UVC_TT_STREAMING) {
     76		u32 function;
     77
     78		v4l2_subdev_init(&entity->subdev, &uvc_subdev_ops);
     79		strscpy(entity->subdev.name, entity->name,
     80			sizeof(entity->subdev.name));
     81
     82		switch (UVC_ENTITY_TYPE(entity)) {
     83		case UVC_VC_SELECTOR_UNIT:
     84			function = MEDIA_ENT_F_VID_MUX;
     85			break;
     86		case UVC_VC_PROCESSING_UNIT:
     87		case UVC_VC_EXTENSION_UNIT:
     88			/* For lack of a better option. */
     89			function = MEDIA_ENT_F_PROC_VIDEO_PIXEL_FORMATTER;
     90			break;
     91		case UVC_COMPOSITE_CONNECTOR:
     92		case UVC_COMPONENT_CONNECTOR:
     93			function = MEDIA_ENT_F_CONN_COMPOSITE;
     94			break;
     95		case UVC_SVIDEO_CONNECTOR:
     96			function = MEDIA_ENT_F_CONN_SVIDEO;
     97			break;
     98		case UVC_ITT_CAMERA:
     99			function = MEDIA_ENT_F_CAM_SENSOR;
    100			break;
    101		case UVC_TT_VENDOR_SPECIFIC:
    102		case UVC_ITT_VENDOR_SPECIFIC:
    103		case UVC_ITT_MEDIA_TRANSPORT_INPUT:
    104		case UVC_OTT_VENDOR_SPECIFIC:
    105		case UVC_OTT_DISPLAY:
    106		case UVC_OTT_MEDIA_TRANSPORT_OUTPUT:
    107		case UVC_EXTERNAL_VENDOR_SPECIFIC:
    108		case UVC_EXT_GPIO_UNIT:
    109		default:
    110			function = MEDIA_ENT_F_V4L2_SUBDEV_UNKNOWN;
    111			break;
    112		}
    113
    114		entity->subdev.entity.function = function;
    115
    116		ret = media_entity_pads_init(&entity->subdev.entity,
    117					entity->num_pads, entity->pads);
    118
    119		if (ret < 0)
    120			return ret;
    121
    122		ret = v4l2_device_register_subdev(&chain->dev->vdev,
    123						  &entity->subdev);
    124	} else if (entity->vdev != NULL) {
    125		ret = media_entity_pads_init(&entity->vdev->entity,
    126					entity->num_pads, entity->pads);
    127		if (entity->flags & UVC_ENTITY_FLAG_DEFAULT)
    128			entity->vdev->entity.flags |= MEDIA_ENT_FL_DEFAULT;
    129	} else
    130		ret = 0;
    131
    132	return ret;
    133}
    134
    135int uvc_mc_register_entities(struct uvc_video_chain *chain)
    136{
    137	struct uvc_entity *entity;
    138	int ret;
    139
    140	list_for_each_entry(entity, &chain->entities, chain) {
    141		ret = uvc_mc_init_entity(chain, entity);
    142		if (ret < 0) {
    143			dev_info(&chain->dev->udev->dev,
    144				 "Failed to initialize entity for entity %u\n",
    145				 entity->id);
    146			return ret;
    147		}
    148	}
    149
    150	list_for_each_entry(entity, &chain->entities, chain) {
    151		ret = uvc_mc_create_links(chain, entity);
    152		if (ret < 0) {
    153			dev_info(&chain->dev->udev->dev,
    154				 "Failed to create links for entity %u\n",
    155				 entity->id);
    156			return ret;
    157		}
    158	}
    159
    160	return 0;
    161}