usb: export firmware port location in sysfs
authorBjørn Mork <bjorn@mork.no>
Fri, 28 Sep 2018 13:40:31 +0000 (15:40 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Tue, 2 Oct 2018 19:05:30 +0000 (12:05 -0700)
The platform firmware "location" data is used to find port peer
relationships. But firmware is an unreliable source, and there are
real world examples of errors leading to missing or wrong peer
relationships.  Debugging this is currently hard.

Exporting the location attribute makes it easier to spot mismatches
between the firmware data and the real world.

Signed-off-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Documentation/ABI/testing/sysfs-bus-usb
drivers/usb/core/port.c

index c4a70f532ec39660a2d89fe192f31475cd6123c8..559baa5c418c25e3eddd639f6fb72577b1bfbeb1 100644 (file)
@@ -189,6 +189,16 @@ Description:
                The file will read "hotplug", "wired" and "not used" if the
                information is available, and "unknown" otherwise.
 
+What:          /sys/bus/usb/devices/.../(hub interface)/portX/location
+Date:          October 2018
+Contact:       Bjørn Mork <bjorn@mork.no>
+Description:
+               Some platforms provide usb port physical location through
+               firmware. This is used by the kernel to pair up logical ports
+               mapping to the same physical connector. The attribute exposes the
+               raw location value as a hex integer.
+
+
 What:          /sys/bus/usb/devices/.../(hub interface)/portX/quirks
 Date:          May 2018
 Contact:       Nicolas Boichat <drinkcat@chromium.org>
index 4a21431953953d5b52b467a107a04c5f8198cf19..1a06a4b5fbb14d592b6da8ed2cab8ebd123eb851 100644 (file)
@@ -16,6 +16,15 @@ static int usb_port_block_power_off;
 
 static const struct attribute_group *port_dev_group[];
 
+static ssize_t location_show(struct device *dev,
+                            struct device_attribute *attr, char *buf)
+{
+       struct usb_port *port_dev = to_usb_port(dev);
+
+       return sprintf(buf, "0x%08x\n", port_dev->location);
+}
+static DEVICE_ATTR_RO(location);
+
 static ssize_t connect_type_show(struct device *dev,
                                 struct device_attribute *attr, char *buf)
 {
@@ -140,6 +149,7 @@ static DEVICE_ATTR_RW(usb3_lpm_permit);
 
 static struct attribute *port_dev_attrs[] = {
        &dev_attr_connect_type.attr,
+       &dev_attr_location.attr,
        &dev_attr_quirks.attr,
        &dev_attr_over_current_count.attr,
        NULL,