Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751914AbdFFMbJ (ORCPT ); Tue, 6 Jun 2017 08:31:09 -0400 Received: from mga06.intel.com ([134.134.136.31]:47993 "EHLO mga06.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751477AbdFFMZe (ORCPT ); Tue, 6 Jun 2017 08:25:34 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.39,306,1493708400"; d="scan'208";a="1157138564" From: Mika Westerberg To: Greg Kroah-Hartman Cc: Andreas Noever , Michael Jamet , Yehezkel Bernat , Lukas Wunner , Amir Levy , Andy Lutomirski , Mario.Limonciello@dell.com, Jared.Dominguez@dell.com, Andy Shevchenko , Mika Westerberg , linux-kernel@vger.kernel.org Subject: [PATCH v4 13/27] thunderbolt: Read vendor and device name from DROM Date: Tue, 6 Jun 2017 15:25:05 +0300 Message-Id: <20170606122519.35401-14-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170606122519.35401-1-mika.westerberg@linux.intel.com> References: <20170606122519.35401-1-mika.westerberg@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5974 Lines: 183 The device DROM contains name of the vendor and device among other things. Extract this information and expose it to the userspace via two new attributes. Signed-off-by: Mika Westerberg Reviewed-by: Yehezkel Bernat Reviewed-by: Michael Jamet Signed-off-by: Andreas Noever --- Documentation/ABI/testing/sysfs-bus-thunderbolt | 14 +++++++++++ drivers/thunderbolt/eeprom.c | 32 +++++++++++++++++++++++++ drivers/thunderbolt/switch.c | 22 +++++++++++++++++ drivers/thunderbolt/tb.h | 4 ++++ 4 files changed, 72 insertions(+) diff --git a/Documentation/ABI/testing/sysfs-bus-thunderbolt b/Documentation/ABI/testing/sysfs-bus-thunderbolt index 9f1bd0086938..29a516f53d2c 100644 --- a/Documentation/ABI/testing/sysfs-bus-thunderbolt +++ b/Documentation/ABI/testing/sysfs-bus-thunderbolt @@ -5,6 +5,13 @@ Contact: thunderbolt-software@lists.01.org Description: This attribute contains id of this device extracted from the device DROM. +What: /sys/bus/thunderbolt/devices/.../device_name +Date: Sep 2017 +KernelVersion: 4.13 +Contact: thunderbolt-software@lists.01.org +Description: This attribute contains name of this device extracted from + the device DROM. + What: /sys/bus/thunderbolt/devices/.../vendor Date: Sep 2017 KernelVersion: 4.13 @@ -12,6 +19,13 @@ Contact: thunderbolt-software@lists.01.org Description: This attribute contains vendor id of this device extracted from the device DROM. +What: /sys/bus/thunderbolt/devices/.../vendor_name +Date: Sep 2017 +KernelVersion: 4.13 +Contact: thunderbolt-software@lists.01.org +Description: This attribute contains vendor name of this device extracted + from the device DROM. + What: /sys/bus/thunderbolt/devices/.../unique_id Date: Sep 2017 KernelVersion: 4.13 diff --git a/drivers/thunderbolt/eeprom.c b/drivers/thunderbolt/eeprom.c index 5c7d80a109b1..d40a5f07fc4c 100644 --- a/drivers/thunderbolt/eeprom.c +++ b/drivers/thunderbolt/eeprom.c @@ -204,6 +204,11 @@ struct tb_drom_entry_header { enum tb_drom_entry_type type:1; } __packed; +struct tb_drom_entry_generic { + struct tb_drom_entry_header header; + u8 data[0]; +} __packed; + struct tb_drom_entry_port { /* BYTES 0-1 */ struct tb_drom_entry_header header; @@ -295,6 +300,32 @@ int tb_drom_read_uid_only(struct tb_switch *sw, u64 *uid) return 0; } +static int tb_drom_parse_entry_generic(struct tb_switch *sw, + struct tb_drom_entry_header *header) +{ + const struct tb_drom_entry_generic *entry = + (const struct tb_drom_entry_generic *)header; + + switch (header->index) { + case 1: + /* Length includes 2 bytes header so remove it before copy */ + sw->vendor_name = kstrndup(entry->data, + header->len - sizeof(*header), GFP_KERNEL); + if (!sw->vendor_name) + return -ENOMEM; + break; + + case 2: + sw->device_name = kstrndup(entry->data, + header->len - sizeof(*header), GFP_KERNEL); + if (!sw->device_name) + return -ENOMEM; + break; + } + + return 0; +} + static int tb_drom_parse_entry_port(struct tb_switch *sw, struct tb_drom_entry_header *header) { @@ -350,6 +381,7 @@ static int tb_drom_parse_entries(struct tb_switch *sw) switch (entry->type) { case TB_DROM_ENTRY_GENERIC: + res = tb_drom_parse_entry_generic(sw, entry); break; case TB_DROM_ENTRY_PORT: res = tb_drom_parse_entry_port(sw, entry); diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index 2390f08b94da..11f16a141686 100644 --- a/drivers/thunderbolt/switch.c +++ b/drivers/thunderbolt/switch.c @@ -319,6 +319,15 @@ static ssize_t device_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RO(device); +static ssize_t +device_name_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct tb_switch *sw = tb_to_switch(dev); + + return sprintf(buf, "%s\n", sw->device_name ? sw->device_name : ""); +} +static DEVICE_ATTR_RO(device_name); + static ssize_t vendor_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -328,6 +337,15 @@ static ssize_t vendor_show(struct device *dev, struct device_attribute *attr, } static DEVICE_ATTR_RO(vendor); +static ssize_t +vendor_name_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct tb_switch *sw = tb_to_switch(dev); + + return sprintf(buf, "%s\n", sw->vendor_name ? sw->vendor_name : ""); +} +static DEVICE_ATTR_RO(vendor_name); + static ssize_t unique_id_show(struct device *dev, struct device_attribute *attr, char *buf) { @@ -339,7 +357,9 @@ static DEVICE_ATTR_RO(unique_id); static struct attribute *switch_attrs[] = { &dev_attr_device.attr, + &dev_attr_device_name.attr, &dev_attr_vendor.attr, + &dev_attr_vendor_name.attr, &dev_attr_unique_id.attr, NULL, }; @@ -358,6 +378,8 @@ static void tb_switch_release(struct device *dev) struct tb_switch *sw = tb_to_switch(dev); kfree(sw->uuid); + kfree(sw->device_name); + kfree(sw->vendor_name); kfree(sw->ports); kfree(sw->drom); kfree(sw); diff --git a/drivers/thunderbolt/tb.h b/drivers/thunderbolt/tb.h index f7dfe733d71a..6d4910ef2eb9 100644 --- a/drivers/thunderbolt/tb.h +++ b/drivers/thunderbolt/tb.h @@ -23,6 +23,8 @@ * @uuid: UUID of the switch (or %NULL if not supported) * @vendor: Vendor ID of the switch * @device: Device ID of the switch + * @vendor_name: Name of the vendor (or %NULL if not known) + * @device_name: Name of the device (or %NULL if not known) * @cap_plug_events: Offset to the plug events capability (%0 if not found) * @is_unplugged: The switch is going away * @drom: DROM of the switch (%NULL if not found) @@ -36,6 +38,8 @@ struct tb_switch { uuid_be *uuid; u16 vendor; u16 device; + const char *vendor_name; + const char *device_name; int cap_plug_events; bool is_unplugged; u8 *drom; -- 2.11.0