From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756547AbdEROj2 (ORCPT ); Thu, 18 May 2017 10:39:28 -0400 Received: from mga03.intel.com ([134.134.136.65]:10812 "EHLO mga03.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756490AbdEROjY (ORCPT ); Thu, 18 May 2017 10:39:24 -0400 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.38,359,1491289200"; d="scan'208";a="1132137586" 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 10/24] thunderbolt: Read vendor and device name from DROM Date: Thu, 18 May 2017 17:39:00 +0300 Message-Id: <20170518143914.60902-11-mika.westerberg@linux.intel.com> X-Mailer: git-send-email 2.11.0 In-Reply-To: <20170518143914.60902-1-mika.westerberg@linux.intel.com> References: <20170518143914.60902-1-mika.westerberg@linux.intel.com> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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 --- Documentation/ABI/testing/sysfs-bus-thunderbolt | 14 ++++++++++++++ drivers/thunderbolt/eeprom.c | 23 ++++++++++++++++++++++- drivers/thunderbolt/switch.c | 22 ++++++++++++++++++++++ drivers/thunderbolt/tb.h | 4 ++++ 4 files changed, 62 insertions(+), 1 deletion(-) diff --git a/Documentation/ABI/testing/sysfs-bus-thunderbolt b/Documentation/ABI/testing/sysfs-bus-thunderbolt index a3dac3becd1e..2f352c787431 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 e2c1f8a45522..f688fb255042 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; @@ -304,6 +309,15 @@ static void tb_drom_parse_port_entry(struct tb_port *port, &port->sw->ports[entry->dual_link_port_nr]; } +static void tb_drom_parse_generic_entry(struct tb_switch *sw, + struct tb_drom_entry_generic *entry) +{ + if (entry->header.index == 1) + sw->vendor_name = kstrdup((char *)entry->data, GFP_KERNEL); + else if (entry->header.index == 2) + sw->device_name = kstrdup((char *)entry->data, GFP_KERNEL); +} + static int tb_drom_parse_entry(struct tb_switch *sw, struct tb_drom_entry_header *header) { @@ -311,8 +325,15 @@ static int tb_drom_parse_entry(struct tb_switch *sw, int res; enum tb_port_type type; - if (header->type != TB_DROM_ENTRY_PORT) + switch (header->type) { + case TB_DROM_ENTRY_PORT: + break; + case TB_DROM_ENTRY_GENERIC: + tb_drom_parse_generic_entry(sw, + (struct tb_drom_entry_generic *)header); + default: return 0; + } port = &sw->ports[header->index]; port->disabled = header->port_disabled; diff --git a/drivers/thunderbolt/switch.c b/drivers/thunderbolt/switch.c index 4a961d174cad..b06de0efbdfc 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, }; @@ -350,6 +370,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 350c3f21924e..5e66dce53c65 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