This patch adds a sysfs file for users to check 1) whether the debug capability is implemented by hardware; 2) if supported, which state does it stay at. With a host that supports debug port, a file named "debug_port_state" will be created under the device sysfs directory. Reading this file will show users the state (disabled, enabled or configured) of the debug port. With a host that does NOT support debug port, "debug_port_state" file won't be created. Signed-off-by: Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx> --- .../ABI/testing/sysfs-bus-pci-drivers-xhci_hcd | 23 ++++++++ drivers/usb/host/Makefile | 2 +- drivers/usb/host/xhci-ext-caps.h | 5 ++ drivers/usb/host/xhci-sysfs.c | 65 ++++++++++++++++++++++ drivers/usb/host/xhci.c | 4 ++ drivers/usb/host/xhci.h | 4 ++ 6 files changed, 102 insertions(+), 1 deletion(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd create mode 100644 drivers/usb/host/xhci-sysfs.c diff --git a/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd b/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd new file mode 100644 index 0000000..5d0a7d3 --- /dev/null +++ b/Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd @@ -0,0 +1,23 @@ +What: /sys/bus/pci/drivers/xhci_hcd/.../debug_port_state +Date: November 2015 +KernelVersion: 4.4.0 +Contact: Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx> +Description: + This file is designed for users to check the state of a + USB3 debug port. On a machine which supports USB3 debug + port, this file will be created. Reading this file will + show the state (disabled, enabled or configured) of the + debug port. On a machine that doesn't support USB3 debug + port, this file doesn't exist. + + The state of a debug port could be: + 1) disabled: The debug port is not enabled and the root + port has been switched to xHCI host as a normal + root port. + 2) enabled: The debug port is enabled. The debug port + has been assigned to debug capability. The debug + capability is able to handle the control requests + defined in USB3 spec. + 3) configured: The debug port has been enumerated by the + debug host as a debug device. The debug port is + in use now. diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index 65a06b4..aba2bf5 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -12,7 +12,7 @@ fhci-$(CONFIG_FHCI_DEBUG) += fhci-dbg.o xhci-hcd-y := xhci.o xhci-mem.o xhci-hcd-y += xhci-ring.o xhci-hub.o xhci-dbg.o -xhci-hcd-y += xhci-trace.o +xhci-hcd-y += xhci-trace.o xhci-sysfs.o ifneq ($(CONFIG_USB_XHCI_MTK), ) xhci-hcd-y += xhci-mtk-sch.o endif diff --git a/drivers/usb/host/xhci-ext-caps.h b/drivers/usb/host/xhci-ext-caps.h index 04ce6b1..c4b49c5 100644 --- a/drivers/usb/host/xhci-ext-caps.h +++ b/drivers/usb/host/xhci-ext-caps.h @@ -73,6 +73,11 @@ #define XHCI_HLC (1 << 19) #define XHCI_BLC (1 << 20) +/* Debug capability - section 7.6.8 */ +#define XHCI_DBC_DCCTRL 0x20 +#define XHCI_DBC_DCCTRL_DCR (1 << 0) +#define XHCI_DBC_DCCTRL_DCE (1 << 31) + /* command register values to disable interrupts and halt the HC */ /* start/stop HC execution - do not write unless HC is halted*/ #define XHCI_CMD_RUN (1 << 0) diff --git a/drivers/usb/host/xhci-sysfs.c b/drivers/usb/host/xhci-sysfs.c new file mode 100644 index 0000000..9feb727 --- /dev/null +++ b/drivers/usb/host/xhci-sysfs.c @@ -0,0 +1,65 @@ +/* + * sysfs interface for xHCI host controller driver + * + * Copyright (C) 2015 Intel Corp. + * + * Author: Lu Baolu <baolu.lu@xxxxxxxxxxxxxxx> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + */ +#include <linux/kernel.h> + +#include "xhci.h" + +#define GET_DBC_EXT_CAP_OFFSET(h) \ + xhci_find_next_ext_cap(&(h)->cap_regs->hc_capbase, \ + 0, XHCI_EXT_CAPS_DEBUG) + +static ssize_t debug_port_state_show(struct device *dev, + struct device_attribute *attr, char *buf) +{ + int count = 0, offset; + char *state; + void __iomem *dbc_base; + u32 dcctrl_reg; + struct xhci_hcd *xhci = hcd_to_xhci(dev_get_drvdata(dev)); + + offset = GET_DBC_EXT_CAP_OFFSET(xhci); + if (!offset) + return 0; + + dbc_base = (void __iomem *) xhci->cap_regs + offset; + dcctrl_reg = readl(dbc_base + XHCI_DBC_DCCTRL); + + if (!(dcctrl_reg & XHCI_DBC_DCCTRL_DCE)) + state = "disabled"; + else if (dcctrl_reg & XHCI_DBC_DCCTRL_DCR) + state = "configured"; + else + state = "enabled"; + + count = scnprintf(buf, PAGE_SIZE, "%s\n", state); + + return count; +} +static DEVICE_ATTR_RO(debug_port_state); + +int xhci_sysfs_create_files(struct xhci_hcd *xhci) +{ + struct device *dev = xhci_to_hcd(xhci)->self.controller; + + if (GET_DBC_EXT_CAP_OFFSET(xhci)) + return device_create_file(dev, &dev_attr_debug_port_state); + + return 0; +} + +void xhci_sysfs_remove_files(struct xhci_hcd *xhci) +{ + struct device *dev = xhci_to_hcd(xhci)->self.controller; + + if (GET_DBC_EXT_CAP_OFFSET(xhci)) + device_remove_file(dev, &dev_attr_debug_port_state); +} diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 26a44c0..450f8f5 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -666,6 +666,9 @@ int xhci_run(struct usb_hcd *hcd) } xhci_dbg_trace(xhci, trace_xhci_dbg_init, "Finished xhci_run for USB2 roothub"); + + xhci_sysfs_create_files(xhci); + return 0; } EXPORT_SYMBOL_GPL(xhci_run); @@ -699,6 +702,7 @@ void xhci_stop(struct usb_hcd *hcd) xhci_reset(xhci); spin_unlock_irq(&xhci->lock); + xhci_sysfs_remove_files(xhci); xhci_cleanup_msix(xhci); /* Deleting Compliance Mode Recovery Timer */ diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h index 9be7348..c2be2a0 100644 --- a/drivers/usb/host/xhci.h +++ b/drivers/usb/host/xhci.h @@ -1953,4 +1953,8 @@ struct xhci_input_control_ctx *xhci_get_input_control_ctx(struct xhci_container_ struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx); struct xhci_ep_ctx *xhci_get_ep_ctx(struct xhci_hcd *xhci, struct xhci_container_ctx *ctx, unsigned int ep_index); +/* xHCI sysfs interfaces */ +int xhci_sysfs_create_files(struct xhci_hcd *xhci); +void xhci_sysfs_remove_files(struct xhci_hcd *xhci); + #endif /* __LINUX_XHCI_HCD_H */ -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html