From patchwork Fri Jul 15 11:01:05 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 9231691 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 07EFB6075D for ; Fri, 15 Jul 2016 11:01:11 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id ECC3727D5D for ; Fri, 15 Jul 2016 11:01:10 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id E07F628324; Fri, 15 Jul 2016 11:01:10 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 3DE5627D5D for ; Fri, 15 Jul 2016 11:01:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S932537AbcGOLBI (ORCPT ); Fri, 15 Jul 2016 07:01:08 -0400 Received: from mx1.redhat.com ([209.132.183.28]:32857 "EHLO mx1.redhat.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S932505AbcGOLBH convert rfc822-to-8bit (ORCPT ); Fri, 15 Jul 2016 07:01:07 -0400 Received: from int-mx09.intmail.prod.int.phx2.redhat.com (int-mx09.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id B9650C05AA49 for ; Fri, 15 Jul 2016 11:01:06 +0000 (UTC) Received: from warthog.procyon.org.uk (ovpn-116-151.phx2.redhat.com [10.3.116.151]) by int-mx09.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id u6FB15Sm012003; Fri, 15 Jul 2016 07:01:05 -0400 Organization: Red Hat UK Ltd. Registered Address: Red Hat UK Ltd, Amberley Place, 107-111 Peascod Street, Windsor, Berkshire, SI4 1TE, United Kingdom. Registered in England and Wales under Company Registration No. 3798903 From: David Howells To: linux-media@vger.kernel.org cc: dhowells@redhat.com Subject: Trying to pass the port number to udev for a multiport DVB card MIME-Version: 1.0 Content-ID: <22947.1468580465.1@warthog.procyon.org.uk> Date: Fri, 15 Jul 2016 12:01:05 +0100 Message-ID: <22948.1468580465@warthog.procyon.org.uk> X-Scanned-By: MIMEDefang 2.68 on 10.5.11.22 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.32]); Fri, 15 Jul 2016 11:01:06 +0000 (UTC) Sender: linux-media-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-media@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Hi, Can someone give me a hand with unpicking the tangle of spaghetti that's the DVB core? Attached is a patch that can pass various attributes, including, theoretically, the port number of the separate ports of a multiport card, such as the DVBSky S952 and T982 cards, so that udev can create persistent names. However, the port number I've added to the dvb_adapter struct is always seen as zero in the attribute function I've written. Putting in some printks shows that the dvb_adapter struct seen in the attribute struct has a *different* address to the one seen in dvb_register() in cx23885-dvb.c. Does anyone know what's going on? I should also add that the MAC address *does* go through, though I can't see where it's copied. David --- commit c100b0ddc9436152e770a80eedfdd90644c1ee3d Author: David Howells Date: Wed Jul 13 23:05:34 2016 +0100 dvb: Save port number and provide sysfs attributes to pass values to udev 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 -- To unsubscribe from this list: send the line "unsubscribe linux-media" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/media/dvb-core/dvbdev.c b/drivers/media/dvb-core/dvbdev.c index 75a3f4b57fd4..638719483167 100644 --- a/drivers/media/dvb-core/dvbdev.c +++ b/drivers/media/dvb-core/dvbdev.c @@ -901,6 +901,51 @@ out: 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); @@ -941,6 +986,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 4aff7bd3dea8..cf4d5fc501e0 100644 --- a/drivers/media/dvb-core/dvbdev.h +++ b/drivers/media/dvb-core/dvbdev.h @@ -65,6 +65,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 @@ -85,6 +86,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 f041b6931ba8..a4260fa8eec7 100644 --- a/drivers/media/pci/cx23885/cx23885-dvb.c +++ b/drivers/media/pci/cx23885/cx23885-dvb.c @@ -1209,6 +1209,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: