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

Commit 97548ed4 authored by Laurent Pinchart's avatar Laurent Pinchart Committed by Mauro Carvalho Chehab
Browse files

[media] media: Links setup



Create the following ioctl and implement it at the media device level to
setup links.

- MEDIA_IOC_SETUP_LINK: Modify the properties of a given link

The only property that can currently be modified is the ENABLED link
flag to enable/disable a link. Links marked with the IMMUTABLE link flag
can not be enabled or disabled.

Enabling or disabling a link has effects on entities' use count. Those
changes are automatically propagated through the graph.

Signed-off-by: default avatarLaurent Pinchart <laurent.pinchart@ideasonboard.com>
Signed-off-by: default avatarStanimir Varbanov <svarbanov@mm-sol.com>
Signed-off-by: default avatarSakari Ailus <sakari.ailus@iki.fi>
Acked-by: default avatarHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: default avatarMauro Carvalho Chehab <mchehab@redhat.com>
parent 1651333b
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -94,6 +94,7 @@
<!ENTITY MEDIA-IOC-DEVICE-INFO "<link linkend='media-ioc-device-info'><constant>MEDIA_IOC_DEVICE_INFO</constant></link>">
<!ENTITY MEDIA-IOC-ENUM-ENTITIES "<link linkend='media-ioc-enum-entities'><constant>MEDIA_IOC_ENUM_ENTITIES</constant></link>">
<!ENTITY MEDIA-IOC-ENUM-LINKS "<link linkend='media-ioc-enum-links'><constant>MEDIA_IOC_ENUM_LINKS</constant></link>">
<!ENTITY MEDIA-IOC-SETUP-LINK "<link linkend='media-ioc-setup-link'><constant>MEDIA_IOC_SETUP_LINK</constant></link>">

<!-- Types -->
<!ENTITY v4l2-std-id "<link linkend='v4l2-std-id'>v4l2_std_id</link>">
@@ -348,6 +349,7 @@
<!ENTITY sub-media-ioc-device-info SYSTEM "v4l/media-ioc-device-info.xml">
<!ENTITY sub-media-ioc-enum-entities SYSTEM "v4l/media-ioc-enum-entities.xml">
<!ENTITY sub-media-ioc-enum-links SYSTEM "v4l/media-ioc-enum-links.xml">
<!ENTITY sub-media-ioc-setup-link SYSTEM "v4l/media-ioc-setup-link.xml">

<!-- Function Reference -->
<!ENTITY close SYSTEM "v4l/func-close.xml">
+1 −0
Original line number Diff line number Diff line
@@ -85,4 +85,5 @@
  &sub-media-ioc-device-info;
  &sub-media-ioc-enum-entities;
  &sub-media-ioc-enum-links;
  &sub-media-ioc-setup-link;
</appendix>
+90 −0
Original line number Diff line number Diff line
<refentry id="media-ioc-setup-link">
  <refmeta>
    <refentrytitle>ioctl MEDIA_IOC_SETUP_LINK</refentrytitle>
    &manvol;
  </refmeta>

  <refnamediv>
    <refname>MEDIA_IOC_SETUP_LINK</refname>
    <refpurpose>Modify the properties of a link</refpurpose>
  </refnamediv>

  <refsynopsisdiv>
    <funcsynopsis>
      <funcprototype>
	<funcdef>int <function>ioctl</function></funcdef>
	<paramdef>int <parameter>fd</parameter></paramdef>
	<paramdef>int <parameter>request</parameter></paramdef>
	<paramdef>struct media_link_desc *<parameter>argp</parameter></paramdef>
      </funcprototype>
    </funcsynopsis>
  </refsynopsisdiv>

  <refsect1>
    <title>Arguments</title>

    <variablelist>
      <varlistentry>
	<term><parameter>fd</parameter></term>
	<listitem>
	  <para>File descriptor returned by
	  <link linkend='media-func-open'><function>open()</function></link>.</para>
	</listitem>
      </varlistentry>
      <varlistentry>
	<term><parameter>request</parameter></term>
	<listitem>
	  <para>MEDIA_IOC_ENUM_LINKS</para>
	</listitem>
      </varlistentry>
      <varlistentry>
	<term><parameter>argp</parameter></term>
	<listitem>
	  <para></para>
	</listitem>
      </varlistentry>
    </variablelist>
  </refsect1>

  <refsect1>
    <title>Description</title>

    <para>To change link properties applications fill a &media-link-desc; with
    link identification information (source and sink pad) and the new requested
    link flags. They then call the MEDIA_IOC_SETUP_LINK ioctl with a pointer to
    that structure.</para>
    <para>The only configurable property is the <constant>ENABLED</constant>
    link flag to enable/disable a link. Links marked with the
    <constant>IMMUTABLE</constant> link flag can not be enabled or disabled.
    </para>
    <para>Link configuration has no side effect on other links. If an enabled
    link at the sink pad prevents the link from being enabled, the driver
    returns with an &EBUSY;.</para>
    <para>If the specified link can't be found the driver returns with an
    &EINVAL;.</para>
  </refsect1>

  <refsect1>
    &return-value;

    <variablelist>
      <varlistentry>
	<term><errorcode>EBUSY</errorcode></term>
	<listitem>
	  <para>The link properties can't be changed because the link is
	  currently busy. This can be caused, for instance, by an active media
	  stream (audio or video) on the link. The ioctl shouldn't be retried if
	  no other action is performed before to fix the problem.</para>
	</listitem>
      </varlistentry>
      <varlistentry>
	<term><errorcode>EINVAL</errorcode></term>
	<listitem>
	  <para>The &media-link-desc; references a non-existing link, or the
	  link is immutable and an attempt to modify its configuration was made.
	  </para>
	</listitem>
      </varlistentry>
    </variablelist>
  </refsect1>
</refentry>
+42 −0
Original line number Diff line number Diff line
@@ -259,6 +259,16 @@ When the graph traversal is complete the function will return NULL.
Graph traversal can be interrupted at any moment. No cleanup function call is
required and the graph structure can be freed normally.

Helper functions can be used to find a link between two given pads, or a pad
connected to another pad through an enabled link

	media_entity_find_link(struct media_pad *source,
			       struct media_pad *sink);

	media_entity_remote_source(struct media_pad *pad);

Refer to the kerneldoc documentation for more information.


Use count and power handling
----------------------------
@@ -271,3 +281,35 @@ track the number of users of every entity for power management needs.
The use_count field is owned by media drivers and must not be touched by entity
drivers. Access to the field must be protected by the media device graph_mutex
lock.


Links setup
-----------

Link properties can be modified at runtime by calling

	media_entity_setup_link(struct media_link *link, u32 flags);

The flags argument contains the requested new link flags.

The only configurable property is the ENABLED link flag to enable/disable a
link. Links marked with the IMMUTABLE link flag can not be enabled or disabled.

When a link is enabled or disabled, the media framework calls the
link_setup operation for the two entities at the source and sink of the link,
in that order. If the second link_setup call fails, another link_setup call is
made on the first entity to restore the original link flags.

Media device drivers can be notified of link setup operations by setting the
media_device::link_notify pointer to a callback function. If provided, the
notification callback will be called before enabling and after disabling
links.

Entity drivers must implement the link_setup operation if any of their links
is non-immutable. The operation must either configure the hardware or store
the configuration information to be applied later.

Link configuration must not have any side effect on other links. If an enabled
link at a sink pad prevents another link at the same pad from being disabled,
the link_setup operation must return -EBUSY and can't implicitly disable the
first enabled link.
+45 −0
Original line number Diff line number Diff line
@@ -172,6 +172,44 @@ static long media_device_enum_links(struct media_device *mdev,
	return 0;
}

static long media_device_setup_link(struct media_device *mdev,
				    struct media_link_desc __user *_ulink)
{
	struct media_link *link = NULL;
	struct media_link_desc ulink;
	struct media_entity *source;
	struct media_entity *sink;
	int ret;

	if (copy_from_user(&ulink, _ulink, sizeof(ulink)))
		return -EFAULT;

	/* Find the source and sink entities and link.
	 */
	source = find_entity(mdev, ulink.source.entity);
	sink = find_entity(mdev, ulink.sink.entity);

	if (source == NULL || sink == NULL)
		return -EINVAL;

	if (ulink.source.index >= source->num_pads ||
	    ulink.sink.index >= sink->num_pads)
		return -EINVAL;

	link = media_entity_find_link(&source->pads[ulink.source.index],
				      &sink->pads[ulink.sink.index]);
	if (link == NULL)
		return -EINVAL;

	/* Setup the link on both entities. */
	ret = __media_entity_setup_link(link, ulink.flags);

	if (copy_to_user(_ulink, &ulink, sizeof(ulink)))
		return -EFAULT;

	return ret;
}

static long media_device_ioctl(struct file *filp, unsigned int cmd,
			       unsigned long arg)
{
@@ -197,6 +235,13 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd,
		mutex_unlock(&dev->graph_mutex);
		break;

	case MEDIA_IOC_SETUP_LINK:
		mutex_lock(&dev->graph_mutex);
		ret = media_device_setup_link(dev,
				(struct media_link_desc __user *)arg);
		mutex_unlock(&dev->graph_mutex);
		break;

	default:
		ret = -ENOIOCTLCMD;
	}
Loading