[PATCH 6/6] can: peak_usb: add sysfs interface to internal device user value

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



This patch adds under /sys/class/net/canX a new group named "peak_usb"
which contains a "dev_num" entry accessible for reading (display in
decimal of the numerical value stored in non-volatile memory of the USB
device) and also for writing (modification by the user of this value).

Signed-off-by: Stephane Grosjean <s.grosjean@xxxxxxxxxxxxxxx>
---
 drivers/net/can/usb/peak_usb/pcan_usb_core.c | 76 ++++++++++++++++++++
 1 file changed, 76 insertions(+)

diff --git a/drivers/net/can/usb/peak_usb/pcan_usb_core.c b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
index ad9f435fc57e..08d1db988d81 100644
--- a/drivers/net/can/usb/peak_usb/pcan_usb_core.c
+++ b/drivers/net/can/usb/peak_usb/pcan_usb_core.c
@@ -53,6 +53,17 @@ static const struct usb_device_id peak_usb_table[] = {
 
 MODULE_DEVICE_TABLE(usb, peak_usb_table);
 
+/* sysfs shortcuts */
+#define PEAK_USB_DEVICE_ATTR_RW(_name) \
+	struct device_attribute peak_usb_attr_##_name = \
+		__ATTR(_name, 0644, \
+		       peak_usb_##_name##_show, peak_usb_##_name##_store)
+
+#define PEAK_USB_DEVICE_ATTR_RO(_name) \
+	struct device_attribute peak_usb_attr_##_name = \
+		__ATTR(_name, 0444, \
+		       peak_usb_##_name##_show, NULL)
+
 /*
  * dump memory
  */
@@ -784,6 +795,61 @@ static const struct net_device_ops peak_usb_netdev_ops = {
 	.ndo_change_mtu = can_change_mtu,
 };
 
+static inline struct peak_usb_device *to_peak_usb_device(struct device *dev)
+{
+	return netdev_priv(to_net_dev(dev));
+}
+
+static ssize_t peak_usb_dev_num_show(struct device *dev,
+				     struct device_attribute *attr, char *buf)
+{
+	struct peak_usb_device *pdev = to_peak_usb_device(dev);
+
+	if (!pdev->adapter->dev_get_user_devid)
+		return -EOPNOTSUPP;
+
+	pdev->adapter->dev_get_user_devid(pdev, &pdev->device_number);
+
+	return snprintf(buf, PAGE_SIZE, "%u\n", pdev->device_number);
+}
+
+static ssize_t peak_usb_dev_num_store(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf, size_t count)
+{
+	struct peak_usb_device *pdev = to_peak_usb_device(dev);
+	unsigned long devid;
+	int err;
+
+	if (!pdev->adapter->dev_set_user_devid)
+		return -EOPNOTSUPP;
+
+	err = kstrtoul(buf, 0, &devid);
+	if (err)
+		return err;
+
+	err = pdev->adapter->dev_set_user_devid(pdev, devid);
+	if (err)
+		return err;
+
+	/* on success, update cached value */
+	pdev->device_number = devid;
+
+	return count;
+}
+
+static PEAK_USB_DEVICE_ATTR_RW(dev_num);
+
+static const struct attribute *const peak_usb_net_attrs[] = {
+	&peak_usb_attr_dev_num.attr,
+	NULL,
+};
+
+static const struct attribute_group peak_usb_net_attrs_group = {
+	.name = PCAN_USB_DRIVER_NAME,
+	.attrs = (struct attribute **)peak_usb_net_attrs,
+};
+
 /*
  * create one device which is attached to CAN controller #ctrl_idx of the
  * usb adapter.
@@ -886,6 +952,12 @@ static int peak_usb_create_dev(const struct peak_usb_adapter *peak_usb_adapter,
 	if (dev->adapter->dev_get_user_devid)
 		dev->adapter->dev_get_user_devid(dev, &dev->device_number);
 
+	/* add our own attrs to /sys/class/net/canX node */
+	err = sysfs_create_group(&netdev->dev.kobj, &peak_usb_net_attrs_group);
+	if (err)
+		netdev_warn(netdev,
+			    "can't add sysfs features (err %d)\n", err);
+
 	netdev_info(netdev, "attached to %s channel %u (device %u)\n",
 			peak_usb_adapter->name, ctrl_idx, dev->device_number);
 
@@ -925,6 +997,9 @@ static void peak_usb_disconnect(struct usb_interface *intf)
 		dev->state &= ~PCAN_USB_STATE_CONNECTED;
 		strlcpy(name, netdev->name, IFNAMSIZ);
 
+		sysfs_remove_group(&netdev->dev.kobj,
+				   &peak_usb_net_attrs_group);
+
 		unregister_candev(netdev);
 
 		kfree(dev->cmd_buf);
@@ -958,6 +1033,7 @@ static int peak_usb_probe(struct usb_interface *intf,
 			return err;
 	}
 
+	/* create one CAN device for each CAN controller */
 	for (i = 0; i < peak_usb_adapter->ctrl_count; i++) {
 		err = peak_usb_create_dev(peak_usb_adapter, intf, i);
 		if (err) {
-- 
2.25.1




[Index of Archives]     [Automotive Discussions]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux]     [Linux OMAP]     [Linux MIPS]     [eCos]     [Asterisk Internet PBX]     [Linux API]     [CAN Bus]

  Powered by Linux