linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: David Howells <dhowells@redhat.com>
To: mchehab@kernel.org
Cc: dhowells@redhat.com, linux-kernel@vger.kernel.org,
	linux-media@vger.kernel.org
Subject: [PATCH] dvb: Save port number and provide sysfs attributes to pass values to udev
Date: Wed, 10 Jan 2018 14:50:35 +0000	[thread overview]
Message-ID: <151559583569.13545.12649741692530472663.stgit@warthog.procyon.org.uk> (raw)

Some devices, such as the DVBSky S952 and T982 cards, are dual port cards
that provide two cx23885 devices on the same PCI device, which means the
attributes available for writing udev rules are exactly the same, apart
from the adapter number.  Unfortunately, the adapter numbers are dependent
on the order in which things are initialised, so this can change over
different releases of the kernel.

The struct cx23885_tsport has a port number available, which is printed
during boot:

	[   10.951517] DVBSky T982 port 1 MAC address: 00:17:42:54:09:87
	...
	[   10.984875] DVBSky T982 port 2 MAC address: 00:17:42:54:09:88

To make it possible to distinguish these in udev, do the following steps:

 (1) Save the port number into struct dvb_adapter.

 (2) Provide sysfs attributes to export port number and also MAC address,
     adapter number and type.  There are other fields that could perhaps be
     exported also.

The new sysfs attributes can be seen from userspace as:

	[root@deneb ~]# ls /sys/class/dvb/dvb0.frontend0/
	dev  device  dvb_adapter  dvb_mac  dvb_port  dvb_type
	power  subsystem  uevent
	[root@deneb ~]# cat /sys/class/dvb/dvb0.frontend0/dvb_*
	0
	00:17:42:54:09:87
	0
	frontend

They can be used in udev rules:

	SUBSYSTEM=="dvb", ATTRS{vendor}=="0x14f1", ATTRS{device}=="0x8852", ATTRS{subsystem_device}=="0x0982", ATTR{dvb_mac}=="00:17:42:54:09:87", PROGRAM="/bin/sh -c 'K=%k; K=$${K#dvb}; printf dvb/adapter9820/%%s $${K#*.}'", SYMLINK+="%c"
	SUBSYSTEM=="dvb", ATTRS{vendor}=="0x14f1", ATTRS{device}=="0x8852", ATTRS{subsystem_device}=="0x0982", ATTR{dvb_mac}=="00:17:42:54:09:88", PROGRAM="/bin/sh -c 'K=%k; K=$${K#dvb}; printf dvb/adapter9821/%%s $${K#*.}'", SYMLINK+="%c"

where the match is made with ATTR{dvb_mac} or similar.  The rules above
make symlinks from /dev/dvb/adapter982/* to /dev/dvb/adapterXX/*.

Note that binding the dvb-net device to a network interface and changing it
there does not reflect back into the the dvb_adapter struct and doesn't
change the MAC address here.  This means that a system with two identical
cards in it may need to distinguish them by some other means than MAC
address.

Signed-off-by: David Howells <dhowells@redhat.com>
---

 drivers/media/dvb-core/dvbdev.c         |   46 +++++++++++++++++++++++++++++++
 drivers/media/dvb-core/dvbdev.h         |    2 +
 drivers/media/pci/cx23885/cx23885-dvb.c |    2 +
 3 files changed, 50 insertions(+)

diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c
index 060c60ddfcc3..b3aa5ae3d57f 100644
--- a/drivers/media/dvb-core/dvbdev.c
+++ b/drivers/media/dvb-core/dvbdev.c
@@ -941,6 +941,51 @@ int dvb_usercopy(struct file *file,
 	return err;
 }
 
+static ssize_t dvb_adapter_show(struct device *dev,
+				struct device_attribute *attr, char *buf)
+{
+	struct dvb_device *dvbdev = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", dvbdev->adapter->num);
+}
+static DEVICE_ATTR_RO(dvb_adapter);
+
+static ssize_t dvb_mac_show(struct device *dev,
+			    struct device_attribute *attr, char *buf)
+{
+	struct dvb_device *dvbdev = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%pM\n", dvbdev->adapter->proposed_mac);
+}
+static DEVICE_ATTR_RO(dvb_mac);
+
+static ssize_t dvb_port_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	struct dvb_device *dvbdev = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", dvbdev->adapter->port_num);
+}
+static DEVICE_ATTR_RO(dvb_port);
+
+static ssize_t dvb_type_show(struct device *dev,
+			     struct device_attribute *attr, char *buf)
+{
+	struct dvb_device *dvbdev = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%s\n", dnames[dvbdev->type]);
+}
+static DEVICE_ATTR_RO(dvb_type);
+
+static struct attribute *dvb_class_attrs[] = {
+	&dev_attr_dvb_adapter.attr,
+	&dev_attr_dvb_mac.attr,
+	&dev_attr_dvb_port.attr,
+	&dev_attr_dvb_type.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(dvb_class);
+
 static int dvb_uevent(struct device *dev, struct kobj_uevent_env *env)
 {
 	struct dvb_device *dvbdev = dev_get_drvdata(dev);
@@ -981,6 +1026,7 @@ static int __init init_dvbdev(void)
 		retval = PTR_ERR(dvb_class);
 		goto error;
 	}
+	dvb_class->dev_groups = dvb_class_groups,
 	dvb_class->dev_uevent = dvb_uevent;
 	dvb_class->devnode = dvb_devnode;
 	return 0;
diff --git a/drivers/media/dvb-core/dvbdev.h b/drivers/media/dvb-core/dvbdev.h
index bbc1c20c0529..1d5a170e279a 100644
--- a/drivers/media/dvb-core/dvbdev.h
+++ b/drivers/media/dvb-core/dvbdev.h
@@ -83,6 +83,7 @@ struct dvb_frontend;
  * @device_list:	List with the DVB devices
  * @name:		Name of the adapter
  * @proposed_mac:	proposed MAC address for the adapter
+ * @port_num:		Port number for multi-adapter devices
  * @priv:		private data
  * @device:		pointer to struct device
  * @module:		pointer to struct module
@@ -103,6 +104,7 @@ struct dvb_adapter {
 	struct list_head device_list;
 	const char *name;
 	u8 proposed_mac [6];
+	u8 port_num;
 	void* priv;
 
 	struct device *device;
diff --git a/drivers/media/pci/cx23885/cx23885-dvb.c b/drivers/media/pci/cx23885/cx23885-dvb.c
index e795ddeb7fe2..19c72c66d7e0 100644
--- a/drivers/media/pci/cx23885/cx23885-dvb.c
+++ b/drivers/media/pci/cx23885/cx23885-dvb.c
@@ -1217,6 +1217,8 @@ static int dvb_register(struct cx23885_tsport *port)
 	/* Sets the gate control callback to be used by i2c command calls */
 	port->gate_ctrl = cx23885_dvb_gate_ctrl;
 
+	port->frontends.adapter.port_num = port->nr;
+
 	/* init frontend */
 	switch (dev->board) {
 	case CX23885_BOARD_HAUPPAUGE_HVR1250:

             reply	other threads:[~2018-01-10 14:50 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-10 14:50 David Howells [this message]
2018-03-06 11:55 ` [PATCH] dvb: Save port number and provide sysfs attributes to pass values to udev Mauro Carvalho Chehab
2018-03-08 23:35 ` David Howells
2018-03-09  8:09   ` Mauro Carvalho Chehab

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=151559583569.13545.12649741692530472663.stgit@warthog.procyon.org.uk \
    --to=dhowells@redhat.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-media@vger.kernel.org \
    --cc=mchehab@kernel.org \
    /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).