linux-input.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Hans Verkuil <hverkuil@xs4all.nl>
To: Kamil Debski <k.debski@samsung.com>,
	dri-devel@lists.freedesktop.org, linux-media@vger.kernel.org
Cc: m.szyprowski@samsung.com, mchehab@osg.samsung.com,
	kyungmin.park@samsung.com, thomas@tommie-lie.de, sean@mess.org,
	dmitry.torokhov@gmail.com, linux-input@vger.kernel.org,
	linux-samsung-soc@vger.kernel.org, lars@opdenkamp.eu,
	Hans Verkuil <hansverk@cisco.com>
Subject: Re: [PATCH v6 06/11] cec: add HDMI CEC framework
Date: Wed, 13 May 2015 11:43:34 +0200	[thread overview]
Message-ID: <55531CC6.5020907@xs4all.nl> (raw)
In-Reply-To: <1430760785-1169-7-git-send-email-k.debski@samsung.com>

Typo and question:

On 05/04/15 19:32, Kamil Debski wrote:
> +static long cec_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
> +{
> +	struct cec_devnode *cecdev = cec_devnode_data(filp);
> +	struct cec_adapter *adap = to_cec_adapter(cecdev);
> +	void __user *parg = (void __user *)arg;
> +	int err;
> +
> +	if (!cec_devnode_is_registered(cecdev))
> +		return -EIO;
> +
> +	switch (cmd) {

snip

> +	case CEC_G_ADAP_STATE: {
> +		u32 state = adap->state != CEC_ADAP_STATE_DISABLED;
> +
> +		if (copy_to_user(parg, &state, sizeof(state)))
> +			return -EFAULT;
> +		break;
> +	}
> +
> +	case CEC_S_ADAP_STATE: {
> +		u32 state;
> +
> +		if (!(adap->capabilities & CEC_CAP_STATE))
> +			return -ENOTTY;
> +		if (copy_from_user(&state, parg, sizeof(state)))
> +			return -EFAULT;
> +		if (!state && adap->state == CEC_ADAP_STATE_DISABLED)
> +			return 0;
> +		if (state && adap->state != CEC_ADAP_STATE_DISABLED)
> +			return 0;
> +		cec_enable(adap, !!state);
> +		break;
> +	}
> +
> +	case CEC_G_ADAP_PHYS_ADDR:
> +		if (copy_to_user(parg, &adap->phys_addr,
> +						sizeof(adap->phys_addr)))
> +			return -EFAULT;

If the adapter requires that userspace sets up the phys addr, then what
should this return if no such address has been set up?

I see two options: either 0xffff (which should be used if the HDMI cable
is disconnected), or return an error (perhaps ENODATA).

I think 0xffff might be best. This will still allow the unregistered
logical address.

Note that the comment in uapi/linux/cec.h for G_ADAP_LOG_ADDRS says that it
will return an error if the physical address is not set. That's not true
as far as I can tell, and if we go for 0xffff as the default in a case like
that, then it isn't necessary either to return an error.

cec_create_adapter already initialized the physical address to 0xffff, so
that looks good. But it should be documented in cec-ioc-g-adap-phys-addr.xml.

> +		break;
> +
> +	case CEC_S_ADAP_PHYS_ADDR: {
> +		u16 phys_addr;
> +
> +		if (!(adap->capabilities & CEC_CAP_PHYS_ADDR))
> +			return -ENOTTY;
> +		if (copy_from_user(&phys_addr, parg, sizeof(phys_addr)))
> +			return -EFAULT;
> +		adap->phys_addr = phys_addr;
> +		break;
> +	}
> +
> +	case CEC_G_ADAP_LOG_ADDRS: {
> +		struct cec_log_addrs log_addrs;
> +
> +		log_addrs.cec_version = adap->version;
> +		log_addrs.num_log_addrs = adap->num_log_addrs;
> +		memcpy(log_addrs.primary_device_type, adap->prim_device,
> +							CEC_MAX_LOG_ADDRS);
> +		memcpy(log_addrs.log_addr_type, adap->log_addr_type,
> +							CEC_MAX_LOG_ADDRS);
> +		memcpy(log_addrs.log_addr, adap->log_addr,
> +							CEC_MAX_LOG_ADDRS);
> +
> +		if (copy_to_user(parg, &log_addrs, sizeof(log_addrs)))
> +			return -EFAULT;
> +		break;
> +	}
> +
> +	case CEC_S_ADAP_LOG_ADDRS: {
> +		struct cec_log_addrs log_addrs;
> +
> +		if (!(adap->capabilities & CEC_CAP_LOG_ADDRS))
> +			return -ENOTTY;
> +		if (copy_from_user(&log_addrs, parg, sizeof(log_addrs)))
> +			return -EFAULT;
> +		err = cec_claim_log_addrs(adap, &log_addrs,
> +					!(filp->f_flags & O_NONBLOCK));
> +		if (err)
> +			return err;
> +
> +		if (copy_to_user(parg, &log_addrs, sizeof(log_addrs)))
> +			return -EFAULT;
> +		break;
> +	}
> +
> +	case CEC_G_VENDOR_ID:
> +		if (copy_to_user(parg, &adap->vendor_id,
> +						sizeof(adap->vendor_id)))
> +			return -EFAULT;

I've been reading up on this. If I understand it correctly, then this is
optional (only if a device supports vendor commands does it have to implement
this).

So if the VENDOR capability is set, then userspace *may* change it. If it is
left undefined, then no vendor commands are allowed.

I think this should be redesigned:

One CEC_CAP_VENDOR_CMDS: if set, then vendor commands are allowed.
One CEC_CAP_VENDOR_ID: userspace may set the Vendor ID. No vendor commands are
allowed as long as no vendor ID was set.

So if VENDOR_CMDS is set and VENDOR_ID isn't, then that means that the driver
will have set the vendor ID and the application can retrieve it with G_VENDOR_ID.
If both are set, then userspace has to provide a vendor ID before vendor commands
will be allowed.

That leaves the problem of determining that no vendor ID was set. Unfortunately
the whole range of 0x000000-0xffffff is valid (and 0x000000 maps in fact to a
company (Xerox) according to the IEEE Registration Authority Committee website.

We can define a CEC_VENDOR_ID_INVALID 0xffffffff, that might be the easiest way
of doing this.

A related question: should userspace be allowed to change a valid physical
address or a valid vendor ID to something else once the logical addresses have
been claimed? Or should that result in -EBUSY? I'm leaning towards that.

Actually, the same question is true for S_LOG_ADDRS: that should be done only
once as well as long as the adapter is enabled.

BTW, the documentation does not mention the order in which S_PHYS_ADDR and
S_VENDOR_ID should be issued: should this be done before the adapter is
enabled or before the logical addresses are claimed?

> +		break;
> +
> +	case CEC_S_VENDOR_ID: {
> +		u32 vendor_id;
> +
> +		if (!(adap->capabilities & CEC_CAP_VENDOR_ID))
> +			return -ENOTTY;
> +		if (copy_from_user(&vendor_id, parg, sizeof(vendor_id)))
> +			return -EFAULT;
> +		/* Vendori ID is a 24 bit number, so check if the value is

Typo: Vendori -> Vendor


> +		 * within the correct range. */
> +		if ((vendor_id & 0xff000000) != 0)
> +			return -EINVAL;
> +		adap->vendor_id = vendor_id;
> +		break;
> +	}

Working on a compliance test is always a great way of finding all these
corner cases...

Regards,

	Hans

  parent reply	other threads:[~2015-05-13  9:43 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-05-04 17:32 [PATCH v6 00/11] Kamil Debski
2015-05-04 17:32 ` [PATCH v6 01/11] dts: exynos4*: add HDMI CEC pin definition to pinctrl Kamil Debski
2015-05-05  3:59   ` Krzysztof Kozłowski
2015-05-04 17:32 ` [PATCH v6 02/11] dts: exynos4: add node for the HDMI CEC device Kamil Debski
2015-05-05  3:59   ` Krzysztof Kozłowski
2015-05-04 17:32 ` [PATCH v6 03/11] dts: exynos4412-odroid*: enable " Kamil Debski
2015-05-05  4:00   ` Krzysztof Kozłowski
2015-05-04 17:32 ` [PATCH v6 04/11] HID: add HDMI CEC specific keycodes Kamil Debski
2015-05-08 11:00   ` Hans Verkuil
2015-05-04 17:32 ` [PATCH v6 05/11] rc: Add HDMI CEC protoctol handling Kamil Debski
2015-05-08 11:02   ` Hans Verkuil
2015-05-08 11:18     ` Hans Verkuil
2015-05-04 17:32 ` [PATCH v6 06/11] cec: add HDMI CEC framework Kamil Debski
2015-05-08 11:30   ` Hans Verkuil
2015-05-13  8:03   ` Hans Verkuil
2015-05-13  8:28   ` Hans Verkuil
2015-05-13  9:43   ` Hans Verkuil [this message]
2015-05-13 11:10   ` Sean Young
2015-05-19 11:03     ` Hans Verkuil
2015-05-04 17:33 ` [PATCH v6 07/11] DocBook/media: add CEC documentation Kamil Debski
2015-05-08 10:45   ` Hans Verkuil
2015-05-04 17:33 ` [PATCH v6 08/11] v4l2-subdev: add HDMI CEC ops Kamil Debski
2015-05-04 17:33 ` [PATCH v6 09/11] cec: adv7604: add cec support Kamil Debski
2015-05-04 17:33 ` [PATCH v6 10/11] cec: adv7511: " Kamil Debski
2015-05-04 17:33 ` [PATCH v6 11/11] cec: s5p-cec: Add s5p-cec driver Kamil Debski
2015-05-04 17:33 ` [PATCH v2] libgencec: Add userspace library for the generic CEC kernel interface Kamil Debski
2015-05-08 10:59   ` Hans Verkuil
2015-05-04 17:34 ` [PATCH v6 00/11] HDMI CEC framework Kamil Debski
2015-06-16  6:22 ` [PATCH v6 00/11] Hans Verkuil
2015-06-16  7:08   ` [PATCH v6 00/11] CEC update Hans Verkuil

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=55531CC6.5020907@xs4all.nl \
    --to=hverkuil@xs4all.nl \
    --cc=dmitry.torokhov@gmail.com \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=hansverk@cisco.com \
    --cc=k.debski@samsung.com \
    --cc=kyungmin.park@samsung.com \
    --cc=lars@opdenkamp.eu \
    --cc=linux-input@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=linux-samsung-soc@vger.kernel.org \
    --cc=m.szyprowski@samsung.com \
    --cc=mchehab@osg.samsung.com \
    --cc=sean@mess.org \
    --cc=thomas@tommie-lie.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).