usb: xhci: Add debug capability support in xhci
Subsystems (3)
v2 cover usb: xhci: Add debug capability support in xhci
Hi,
This series is for xHCI debug capability (spec section 7.6.8) support in the xHCI driver.
xHCI compatible USB host controllers(i.e. super-speed USB3 controllers) can be implemented with the Debug Capability(DbC). It presents a debug device which is fully compliant with the USB framework and provides the equivalent of a very high performance full-duplex serial link. The debug capability operation model and registers interface are defined in 7.6.8 of the xHCI specification, revision 1.1.
The DbC debug device shares a root port with the xHCI host. By default, the debug capability is disabled and the root port is assigned to xHCI. When the DbC is enabled, the root port will be assigned to the DbC debug device, and the xHCI sees nothing on this port. This implementation uses a sysfs node named <dbc> under the xHCI device to manage the enabling and disabling of the debug capability.
When the debug capability is enabled, it will present a debug device through the debug port. This debug device is fully compliant with the USB3 framework, and it can be enumerated by a debug host on the other end of the USB link. As soon as the debug device is configured, a TTY serial device named /dev/ttyGSn will be created.
One use of this link is running a login service on the debug target. Hence it can be remote accessed by a debug host. Another use case can probably be found in servers. It provides a peer-to-peer USB link between two host-only machines. This provides a reasonable out-of-band communication method between two servers.
Best regards,
Lu Baolu
---
Change log:v1->v2:
- Add a new patch to move u_serial.c from drivers/usb/gadget/function to drivers/usb/common/ and move u_serial.h to include/linux/usb/.
Lu Baolu (4):
usb: xhci: Make some static functions global
usb: common: Move u_serial from gadget/function to usb/common
usb: xhci: Add DbC support in xHCI driver
usb: doc: Update document for USB3 debug port usage
.../ABI/testing/sysfs-bus-pci-drivers-xhci_hcd | 25 + Documentation/driver-api/usb/usb3-debug-port.rst | 68 + drivers/usb/Kconfig | 3 + drivers/usb/Makefile | 3 +- drivers/usb/common/Makefile | 1 + drivers/usb/common/u_serial.c | 1604 +++++++++++++++++++ drivers/usb/gadget/Kconfig | 3 - drivers/usb/gadget/function/Makefile | 1 - drivers/usb/gadget/function/f_acm.c | 4 +- drivers/usb/gadget/function/f_obex.c | 4 +- drivers/usb/gadget/function/f_serial.c | 3 +- drivers/usb/gadget/function/u_serial.c | 1606 -------------------- drivers/usb/gadget/function/u_serial.h | 71 - drivers/usb/gadget/legacy/acm_ms.c | 3 +- drivers/usb/gadget/legacy/cdc2.c | 2 +- drivers/usb/gadget/legacy/dbgp.c | 3 +- drivers/usb/gadget/legacy/multi.c | 2 +- drivers/usb/gadget/legacy/nokia.c | 2 +- drivers/usb/gadget/legacy/serial.c | 3 +- drivers/usb/host/Kconfig | 9 + drivers/usb/host/Makefile | 5 + drivers/usb/host/xhci-dbgcap.c | 1100 ++++++++++++++ drivers/usb/host/xhci-dbgcap.h | 194 +++ drivers/usb/host/xhci-mem.c | 94 +- drivers/usb/host/xhci-ring.c | 4 +- drivers/usb/host/xhci-trace.h | 65 + drivers/usb/host/xhci.c | 10 + drivers/usb/host/xhci.h | 17 +- include/linux/usb/gadget.h | 52 + include/linux/usb/u_serial.h | 71 + 30 files changed, 3290 insertions(+), 1742 deletions(-) create mode 100644 Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd create mode 100644 drivers/usb/common/u_serial.c delete mode 100644 drivers/usb/gadget/function/u_serial.c delete mode 100644 drivers/usb/gadget/function/u_serial.h create mode 100644 drivers/usb/host/xhci-dbgcap.c create mode 100644 drivers/usb/host/xhci-dbgcap.h create mode 100644 include/linux/usb/u_serial.h
Signature · 1 line
2.7.4
PATCH v2 1/4 usb: xhci: Make some static functions global
This patch makes some static functions global to avoid duplications in different files. These functions can be used in the implementation of xHCI debug capability. There is no functional change.
--- drivers/usb/host/xhci-mem.c | 94 ++++++++++++++++++++++++++------------------ drivers/usb/host/xhci-ring.c | 4 +- drivers/usb/host/xhci.h | 16 +++++++- 3 files changed, 72 insertions(+), 42 deletions(-)
drivers/usb/host/xhci-mem.c +55 -39
@@ -368,7 +368,7 @@ static int xhci_alloc_segments_for_ring(struct xhci_hcd *xhci,* Set the end flag and the cycle toggle bit on the last segment. * See section 4.9.1 and figures 15 and 16. */ -static struct xhci_ring *xhci_ring_alloc (struct xhci_hcd *xhci, +struct xhci_ring *xhci_ring_alloc (struct xhci_hcd *xhci,unsigned int num_segs,unsigned int cycle_state,enum xhci_ring_type type,unsigned int max_packet,gfp_t flags) {
@@ -467,7 +467,7 @@ int xhci_ring_expansion(struct xhci_hcd *xhci, struct xhci_ring *ring,#define CTX_SIZE (_hcc) (HCC_64BYTE_CONTEXT(_hcc) ? 64 : 32) -static struct xhci_container_ctx *xhci_alloc_container_ctx (struct xhci_hcd *xhci, +struct xhci_container_ctx *xhci_alloc_container_ctx (struct xhci_hcd *xhci,int type,gfp_t flags) {struct xhci_container_ctx *ctx;
@@ -492,7 +492,7 @@ static struct xhci_container_ctx *xhci_alloc_container_ctx(struct xhci_hcd *xhcireturn ctx; } -static void xhci_free_container_ctx (struct xhci_hcd *xhci, +void xhci_free_container_ctx (struct xhci_hcd *xhci,struct xhci_container_ctx *ctx) {if (!ctx)
@@ -1762,21 +1762,61 @@ void xhci_free_command(struct xhci_hcd *xhci,kfree (command); } +int xhci_alloc_erst (struct xhci_hcd *xhci, +struct xhci_ring *evt_ring, +struct xhci_erst *erst, +gfp_t flags) +{ +size_t size; +unsigned int val; +struct xhci_segment *seg; +struct xhci_erst_entry *entry; + + size =sizeof (struct xhci_erst_entry ) * evt_ring->num_segs; + erst->entries =dma_alloc_coherent (xhci_to_hcd (xhci)->self.sysdev, + size, + &erst->erst_dma_addr, + flags); +if (!erst->entries) +return -ENOMEM ; + +memset (erst->entries,0 , size); + erst->num_entries = evt_ring->num_segs; + + seg = evt_ring->first_seg; +for (val =0 ; val < evt_ring->num_segs; val++) { + entry = &erst->entries[val]; + entry->seg_addr =cpu_to_le64 (seg->dma); + entry->seg_size =cpu_to_le32 (TRBS_PER_SEGMENT ); + entry->rsvd =0 ; + seg = seg->next; + } + +return 0 ; +} + +void xhci_free_erst (struct xhci_hcd *xhci,struct xhci_erst *erst) +{ +size_t size; +struct device *dev =xhci_to_hcd (xhci)->self.sysdev; + + size =sizeof (struct xhci_erst_entry ) * (erst->num_entries); +if (erst->entries) +dma_free_coherent (dev, size, + erst->entries, + erst->erst_dma_addr); + erst->entries =NULL ; +} +void xhci_mem_cleanup (struct xhci_hcd *xhci) {struct device *dev =xhci_to_hcd (xhci)->self.sysdev; -int size;int i, j, num_ports;cancel_delayed_work_sync (&xhci->cmd_timer); -/* Free the Event Ring Segment Table and the actual Event Ring */ - size =sizeof (struct xhci_erst_entry )*(xhci->erst.num_entries); -if (xhci->erst.entries) -dma_free_coherent (dev, size, - xhci->erst.entries, xhci->erst.erst_dma_addr); - xhci->erst.entries =NULL ; -xhci_dbg_trace (xhci, trace_xhci_dbg_init,"Freed ERST" ); +xhci_free_erst (xhci, &xhci->erst); +if (xhci->event_ring)xhci_ring_free (xhci, xhci->event_ring); xhci->event_ring =NULL ;
@@ -2313,9 +2353,8 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)struct device *dev =xhci_to_hcd (xhci)->self.sysdev;unsigned int val, val2;u64 val_64; -struct xhci_segment *seg; -u32 page_size, temp; -int i; +u32 page_size, temp; +int i, ret;INIT_LIST_HEAD (&xhci->cmd_list);
@@ -2454,32 +2493,9 @@ int xhci_mem_init(struct xhci_hcd *xhci, gfp_t flags)if (xhci_check_trb_in_td_math (xhci) <0 ) goto fail; - xhci->erst.entries =dma_alloc_coherent (dev, -sizeof (struct xhci_erst_entry ) *ERST_NUM_SEGS , &dma, - flags); -if (!xhci->erst.entries) + ret =xhci_alloc_erst (xhci, xhci->event_ring, &xhci->erst, flags); +if (ret) goto fail; -xhci_dbg_trace (xhci, trace_xhci_dbg_init, -"// Allocated event ring segment table at 0x%llx" , - (unsigned long long )dma); - -memset (xhci->erst.entries,0 ,sizeof (struct xhci_erst_entry )*ERST_NUM_SEGS ); - xhci->erst.num_entries =ERST_NUM_SEGS ; - xhci->erst.erst_dma_addr = dma; -xhci_dbg_trace (xhci, trace_xhci_dbg_init, -"Set ERST to 0; private num segs = %i, virt addr = %p, dma addr = 0x%llx" , - xhci->erst.num_entries, - xhci->erst.entries, - (unsigned long long )xhci->erst.erst_dma_addr); - -/* set ring base address and size for each segment table entry */ -for (val =0 , seg = xhci->event_ring->first_seg; val <ERST_NUM_SEGS ; val++) { -struct xhci_erst_entry *entry = &xhci->erst.entries[val]; - entry->seg_addr =cpu_to_le64 (seg->dma); - entry->seg_size =cpu_to_le32 (TRBS_PER_SEGMENT ); - entry->rsvd =0 ; - seg = seg->next; - }/* set ERST count with the number of entries in the segment table */ val =readl (&xhci->ir_set->erst_size);
drivers/usb/host/xhci-ring.c +2 -2
@@ -165,7 +165,7 @@ static void next_trb(struct xhci_hcd *xhci,* See Cycle bit rules. SW is the consumer for the event ring only. * Don't make a ring full of link TRBs. That would be dumb and this would loop. */ -static void inc_deq (struct xhci_hcd *xhci,struct xhci_ring *ring) +void inc_deq (struct xhci_hcd *xhci,struct xhci_ring *ring) {/* event ring doesn't have link trbs, check for last trb */ if (ring->type ==TYPE_EVENT ) {
@@ -2961,7 +2961,7 @@ static int prepare_transfer(struct xhci_hcd *xhci,return 0 ; } -static unsigned int count_trbs (u64 addr,u64 len) +unsigned int count_trbs (u64 addr,u64 len) {unsigned int num_trbs;
drivers/usb/host/xhci.h +15 -1
@@ -1959,9 +1959,17 @@ void xhci_slot_copy(struct xhci_hcd *xhci,int xhci_endpoint_init (struct xhci_hcd *xhci,struct xhci_virt_device *virt_dev,struct usb_device *udev,struct usb_host_endpoint *ep,gfp_t mem_flags); +struct xhci_ring *xhci_ring_alloc (struct xhci_hcd *xhci, +unsigned int num_segs,unsigned int cycle_state, +enum xhci_ring_type type,unsigned int max_packet,gfp_t flags);void xhci_ring_free (struct xhci_hcd *xhci,struct xhci_ring *ring);int xhci_ring_expansion (struct xhci_hcd *xhci,struct xhci_ring *ring, -unsigned int num_trbs,gfp_t flags); +unsigned int num_trbs,gfp_t flags); +int xhci_alloc_erst (struct xhci_hcd *xhci, +struct xhci_ring *evt_ring, +struct xhci_erst *erst, +gfp_t flags); +void xhci_free_erst (struct xhci_hcd *xhci,struct xhci_erst *erst);void xhci_free_endpoint_ring (struct xhci_hcd *xhci,struct xhci_virt_device *virt_dev,unsigned int ep_index);
@@ -1991,6 +1999,10 @@ struct xhci_command *xhci_alloc_command(struct xhci_hcd *xhci,void xhci_urb_free_priv (struct urb_priv *urb_priv);void xhci_free_command (struct xhci_hcd *xhci,struct xhci_command *command); +struct xhci_container_ctx *xhci_alloc_container_ctx (struct xhci_hcd *xhci, +int type,gfp_t flags); +void xhci_free_container_ctx (struct xhci_hcd *xhci, +struct xhci_container_ctx *ctx);/* xHCI host controller glue */ typedef void (*xhci_get_quirks_t )(struct device *,struct xhci_hcd *);
@@ -2065,6 +2077,8 @@ void xhci_handle_command_timeout(struct work_struct *work);void xhci_ring_ep_doorbell (struct xhci_hcd *xhci,unsigned int slot_id,unsigned int ep_index,unsigned int stream_id);void xhci_cleanup_command_queue (struct xhci_hcd *xhci); +void inc_deq (struct xhci_hcd *xhci,struct xhci_ring *ring); +unsigned int count_trbs (u64 addr,u64 len);/* xHCI roothub code */ void xhci_set_link_state(struct xhci_hcd *xhci, __le32 __iomem **port_array,
Signature · 1 line
2.7.4
PATCH v2 2/4 usb: common: Move u_serial from gadget/function to usb/common
In reply to Lu BaoluThe component u_serial provides a glue layer between TTY layer and a USB gadget device needed to provide a basic serial port functionality. Currently, u_serial sits under gadget/function and depends on CONFIG_USB_GADGET to be compiled and used.
Most of the serial gadget devices are based on a UDC (USB device controller) and implemented by making use of the Linux gadget frameworks. But we are facing other implementions as well. One example can be found with xHCI debug capability. The xHCI debug capability implements a serial gadget with hardware and firmware, and provides an interface similar with xHCI host for submitting and reaping the transfer requests.
In order to make better use of u_serial when implementing xHCI debug capability in xHCI driver, this patch moves u_serial.c from gadget/function to usb/common, and moves u_serial.h from gadget/function to include/linux/usb.
--- drivers/usb/Kconfig | 3 + drivers/usb/Makefile | 3 +- drivers/usb/common/Makefile | 1 + drivers/usb/common/u_serial.c | 1604 +++++++++++++++++++++++++++++++ drivers/usb/gadget/Kconfig | 3 - drivers/usb/gadget/function/Makefile | 1 - drivers/usb/gadget/function/f_acm.c | 4 +- drivers/usb/gadget/function/f_obex.c | 4 +- drivers/usb/gadget/function/f_serial.c | 3 +- drivers/usb/gadget/function/u_serial.c | 1606 -------------------------------- drivers/usb/gadget/function/u_serial.h | 71 -- drivers/usb/gadget/legacy/acm_ms.c | 3 +- drivers/usb/gadget/legacy/cdc2.c | 2 +- drivers/usb/gadget/legacy/dbgp.c | 3 +- drivers/usb/gadget/legacy/multi.c | 2 +- drivers/usb/gadget/legacy/nokia.c | 2 +- drivers/usb/gadget/legacy/serial.c | 3 +- include/linux/usb/u_serial.h | 71 ++ 18 files changed, 1689 insertions(+), 1700 deletions(-) create mode 100644 drivers/usb/common/u_serial.c delete mode 100644 drivers/usb/gadget/function/u_serial.c delete mode 100644 drivers/usb/gadget/function/u_serial.h create mode 100644 include/linux/usb/u_serial.h
drivers/usb/Kconfig +3 -0
@@ -35,6 +35,9 @@ config USB_COMMON config USB_ARCH_HAS_HCD def_bool y +config USB_U_SERIAL + tristate + config USB tristate "Support for Host-side USB" depends on USB_ARCH_HAS_HCD
drivers/usb/Makefile +1 -2
@@ -5,6 +5,7 @@ # Object files in subdirectories obj-$(CONFIG_USB) += core/ +obj-$(CONFIG_USB_COMMON) += common/ obj-$(CONFIG_USB_SUPPORT) += phy/ obj-$(CONFIG_USB_DWC3) += dwc3/
@@ -59,8 +60,6 @@ obj-$(CONFIG_USB_CHIPIDEA) += chipidea/ obj-$(CONFIG_USB_RENESAS_USBHS) += renesas_usbhs/ obj-$(CONFIG_USB_GADGET) += gadget/ -obj-$(CONFIG_USB_COMMON) += common/ - obj-$(CONFIG_USBIP_CORE) += usbip/ obj-$(CONFIG_TYPEC) += typec/
drivers/usb/common/Makefile +1 -0
@@ -8,3 +8,4 @@ usb-common-$(CONFIG_USB_LED_TRIG) += led.o obj-$(CONFIG_USB_OTG_FSM) += usb-otg-fsm.o obj-$(CONFIG_USB_ULPI_BUS) += ulpi.o +obj-$(CONFIG_USB_U_SERIAL) += u_serial.o
drivers/usb/common/u_serial.c new file +1604 -0
1,604 lines not on this page · raw message
drivers/usb/gadget/Kconfig +0 -3
@@ -152,9 +152,6 @@ config USB_F_ACM config USB_F_SS_LB tristate -config USB_U_SERIAL - tristate - config USB_U_ETHER tristate
drivers/usb/gadget/function/Makefile +0 -1
@@ -10,7 +10,6 @@ usb_f_acm-y := f_acm.o obj-$(CONFIG_USB_F_ACM) += usb_f_acm.o usb_f_ss_lb-y := f_loopback.o f_sourcesink.o obj-$(CONFIG_USB_F_SS_LB) += usb_f_ss_lb.o -obj-$(CONFIG_USB_U_SERIAL) += u_serial.o usb_f_serial-y := f_serial.o obj-$(CONFIG_USB_F_SERIAL) += usb_f_serial.o usb_f_obex-y := f_obex.o
drivers/usb/gadget/function/f_acm.c +1 -3
@@ -19,9 +19,7 @@#include <linux/module.h> #include <linux/device.h> #include <linux/err.h> - -#include "u_serial.h" - +#include <linux/usb/u_serial.h> /* * This CDC ACM function support just wraps control functions and
drivers/usb/gadget/function/f_obex.c +1 -3
@@ -18,9 +18,7 @@#include <linux/kernel.h> #include <linux/device.h> #include <linux/module.h> - -#include "u_serial.h" - +#include <linux/usb/u_serial.h> /* * This CDC OBEX function support just packages a TTY-ish byte stream.
drivers/usb/gadget/function/f_serial.c +1 -2
@@ -14,8 +14,7 @@#include <linux/kernel.h> #include <linux/module.h> #include <linux/device.h> - -#include "u_serial.h" +#include <linux/usb/u_serial.h> /*
drivers/usb/gadget/function/u_serial.c deleted +0 -1606
1,323 lines not on this page · raw message
drivers/usb/gadget/function/u_serial.h deleted +0 -71
71 lines not on this page · raw message
include/linux/usb/u_serial.h new file +71 -0
71 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.7.4
Part of the diff is not shown here. View the raw message.
Felipe Balbi
NAKRe: [PATCH v2 2/4] usb: common: Move u_serial from gadget/function to usb/common
Hi,
Quoted 13 lines · Lu Baolu
The component
u_serialprovides a glue layer between TTY layer and a USB gadget device needed to provide a basic serial port functionality. Currently,u_serialsits under gadget/function and depends onCONFIG_USB_GADGETto be compiled and used.Most of the serial gadget devices are based on a UDC (USB device controller) and implemented by making use of the Linux gadget frameworks. But we are facing other implementions as well. One example can be found with xHCI debug capability. The xHCI debug capability implements a serial gadget with hardware and firmware, and provides an interface similar with xHCI host for submitting and reaping the transfer requests.
Quoted 6 lines
In order to make better use of
u_serialwhen implementing xHCI debug capability in xHCI driver, this patch movesu_serial.cfrom gadget/function to usb/common, and movesu_serial.hfrom gadget/function toinclude/linux/usb.Signed-off-by Lu Baolu <[email protected]>
NAK, u_serial uses the gadget API. It's definitely not COMMON.
Signature · 1 line
balbi
Re: [PATCH v2 2/4] usb: common: Move u_serial from gadget/function to usb/common
Hi,
Quoted 16 lines · Felipe Balbi
Hi,
Quoted 13 lines · Lu Baolu
The component
u_serialprovides a glue layer between TTY layer and a USB gadget device needed to provide a basic serial port functionality. Currently,u_serialsits under gadget/function and depends onCONFIG_USB_GADGETto be compiled and used.Most of the serial gadget devices are based on a UDC (USB device controller) and implemented by making use of the Linux gadget frameworks. But we are facing other implementions as well. One example can be found with xHCI debug capability. The xHCI debug capability implements a serial gadget with hardware and firmware, and provides an interface similar with xHCI host for submitting and reaping the transfer requests.
Quoted 8 lines
Quoted 6 lines
In order to make better use of
u_serialwhen implementing xHCI debug capability in xHCI driver, this patch movesu_serial.cfrom gadget/function to usb/common, and movesu_serial.hfrom gadget/function toinclude/linux/usb.Signed-off-by Lu Baolu <[email protected]>NAK,
u_serialuses the gadget API. It's definitely not COMMON.
Okay. It seems that I can't use u_serial anyway. I will implement a new tty glue for my case.
Best regards,
Lu Baolu
Re: [PATCH v2 2/4] usb: common: Move u_serial from gadget/function to usb/common
Hi,
Quoted 19 lines · Lu Baolu
Quoted 19 lines
Quoted 18 lines · Lu Baolu
The component
u_serialprovides a glue layer between TTY layer and a USB gadget device needed to provide a basic serial port functionality. Currently,u_serialsits under gadget/function and depends onCONFIG_USB_GADGETto be compiled and used.Most of the serial gadget devices are based on a UDC (USB device controller) and implemented by making use of the Linux gadget frameworks. But we are facing other implementions as well. One example can be found with xHCI debug capability. The xHCI debug capability implements a serial gadget with hardware and firmware, and provides an interface similar with xHCI host for submitting and reaping the transfer requests.
In order to make better use of
u_serialwhen implementing xHCI debug capability in xHCI driver, this patch movesu_serial.cfrom gadget/function to usb/common, and movesu_serial.hfrom gadget/function toinclude/linux/usb.
Quoted 6 lines
Quoted 3 lines
Quoted 1 line
Signed-off-by Lu Baolu <[email protected]>NAK,
u_serialuses the gadget API. It's definitely not COMMON.Okay. It seems that I can't use
u_serialanyway. I will implement a new tty glue for my case.
have you looked at drivers/usb/serial/?
Signature · 1 line
balbi
Re: [PATCH v2 2/4] usb: common: Move u_serial from gadget/function to usb/common
Hi,
Quoted 22 lines · Felipe Balbi
Hi,
Quoted 19 lines · Lu Baolu
Quoted 19 lines
Quoted 18 lines · Lu Baolu
The component
u_serialprovides a glue layer between TTY layer and a USB gadget device needed to provide a basic serial port functionality. Currently,u_serialsits under gadget/function and depends onCONFIG_USB_GADGETto be compiled and used.Most of the serial gadget devices are based on a UDC (USB device controller) and implemented by making use of the Linux gadget frameworks. But we are facing other implementions as well. One example can be found with xHCI debug capability. The xHCI debug capability implements a serial gadget with hardware and firmware, and provides an interface similar with xHCI host for submitting and reaping the transfer requests.
In order to make better use of
u_serialwhen implementing xHCI debug capability in xHCI driver, this patch movesu_serial.cfrom gadget/function to usb/common, and movesu_serial.hfrom gadget/function toinclude/linux/usb.
Quoted 7 lines
Quoted 5 lines
Quoted 3 lines
Quoted 1 line
Signed-off-by Lu Baolu <[email protected]>NAK,
u_serialuses the gadget API. It's definitely not COMMON.Okay. It seems that I can't use
u_serialanyway. I will implement a new tty glue for my case.have you looked at
drivers/usb/serial/?
Yes, I've checked that. I think usb-serial framework is too complex for this case. XHCI debug capability is a simple gadget attached to xHCI host.
Best regards,
Lu Baolu
PATCH v2 3/4 usb: xhci: Add DbC support in xHCI driver
In reply to Lu BaoluxHCI compatible USB host controllers(i.e. super-speed USB3 controllers) can be implemented with the Debug Capability(DbC). It presents a debug device which is fully compliant with the USB framework and provides the equivalent of a very high performance full-duplex serial link. The debug capability operation model and registers interface are defined in 7.6.8 of the xHCI specification, revision 1.1.
The DbC debug device shares a root port with the xHCI host. By default, the debug capability is disabled and the root port is assigned to xHCI. When the DbC is enabled, the root port will be assigned to the DbC debug device, and the xHCI sees nothing on this port. This implementation uses a sysfs node named <dbc> under the xHCI device to manage the enabling and disabling of the debug capability.
When the debug capability is enabled, it will present a debug device through the debug port. This debug device is fully compliant with the USB3 framework, and it can be enumerated by a debug host on the other end of the USB link. As soon as the debug device is configured, a TTY serial device named /dev/ttyGSn will be created.
One use of this link is running a login service on the debug target. Hence it can be remote accessed by a debug host. Another use case can probably be found in servers. It provides a peer-to-peer USB link between two host-only machines. This provides a reasonable out-of-band communication method between two servers.
--- .../ABI/testing/sysfs-bus-pci-drivers-xhci_hcd | 25 + drivers/usb/host/Kconfig | 9 + drivers/usb/host/Makefile | 5 + drivers/usb/host/xhci-dbgcap.c | 1100 ++++++++++++++++++++ drivers/usb/host/xhci-dbgcap.h | 194 ++++ drivers/usb/host/xhci-trace.h | 65 ++ drivers/usb/host/xhci.c | 10 + drivers/usb/host/xhci.h | 1 + include/linux/usb/gadget.h | 52 + 9 files changed, 1461 insertions(+) create mode 100644 Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd create mode 100644 drivers/usb/host/xhci-dbgcap.c create mode 100644 drivers/usb/host/xhci-dbgcap.h
Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd new file +25 -0
@@ -0,0 +1,25 @@ +What: /sys/bus/pci/drivers/xhci_hcd/.../dbc +Date: June 2017 +Contact: Lu Baolu <[email protected]> +Description: + xHCI compatible USB host controllers (i.e. super-speed + USB3 controllers) are often implemented with the Debug + Capability (DbC). It can present a debug device which + is fully compliant with the USB framework and provides + the equivalent of a very high performance full-duplex + serial link for debug purpose. + + The DbC debug device shares a root port with xHCI host. + When the DbC is enabled, the root port will be assigned + to the Debug Capability. Otherwise, it will be assigned + to xHCI. + + Writing "enable" to this attribute will enable the DbC + functionality and the shared root port will be assigned + to the DbC device. Writing "disable" to this attribute + will disable the DbC functionality and the shared root + port will roll back to the xHCI. + + Reading this attribute gives the state of the DbC. It + can be one of the following states: disabled, enabled, + initialized, connected, configured and stalled.
drivers/usb/host/Kconfig +9 -0
@@ -27,6 +27,15 @@ config USB_XHCI_HCD module will be called xhci-hcd. if USB_XHCI_HCD +config USB_XHCI_DBGCAP + bool "xHCI support for debug capability" + depends on TTY + select USB_U_SERIAL + ---help--- + Say 'Y' to enable the support for the xHCI debug capability. Make + sure that your xHCI host supports the extended debug capability and + you want a TTY serial device based on the xHCI debug capability + before enabling this option. If unsure, say 'N'. config USB_XHCI_PCI tristate
drivers/usb/host/Makefile +5 -0
@@ -13,6 +13,11 @@ 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 + +ifneq ($(CONFIG_USB_XHCI_DBGCAP), ) + xhci-hcd-y += xhci-dbgcap.o +endif + ifneq ($(CONFIG_USB_XHCI_MTK), ) xhci-hcd-y += xhci-mtk-sch.o endif
drivers/usb/host/xhci-dbgcap.c new file +1100 -0
1,100 lines not on this page · raw message
drivers/usb/host/xhci-dbgcap.h new file +194 -0
194 lines not on this page · raw message
drivers/usb/host/xhci-trace.h +65 -0
83 lines not on this page · raw message
drivers/usb/host/xhci.c +10 -0
@@ -32,6 +32,7 @@#include "xhci.h" #include "xhci-trace.h" #include "xhci-mtk.h" +#include "xhci-dbgcap.h" #define DRIVER_AUTHOR "Sarah Sharp"#define DRIVER_DESC "'eXtensible' Host Controller (xHC) Driver"
@@ -632,6 +633,9 @@ int xhci_run(struct usb_hcd *hcd) }xhci_dbg_trace (xhci, trace_xhci_dbg_init,"Finished xhci_run for USB2 roothub" ); + +dbc_create_sysfs_file (xhci); +return 0 ; }EXPORT_SYMBOL_GPL (xhci_run);
@@ -660,6 +664,8 @@ static void xhci_stop(struct usb_hcd *hcd)return ; } +dbc_remove_sysfs_file (xhci); +spin_lock_irq (&xhci->lock); xhci->xhc_state |=XHCI_STATE_HALTED ; xhci->cmd_ring_state =CMD_RING_STATE_STOPPED ;
@@ -876,6 +882,8 @@ int xhci_suspend(struct xhci_hcd *xhci, bool do_wakeup) xhci->shared_hcd->state != HC_STATE_SUSPENDED)return -EINVAL ; +xhci_dbc_suspend (xhci); +/* Clear root port wake on bits if wakeup not allowed. */ if (!do_wakeup)xhci_disable_port_wake_on_bits (xhci);
@@ -1071,6 +1079,8 @@ int xhci_resume(struct xhci_hcd *xhci, bool hibernated)spin_unlock_irq (&xhci->lock); +xhci_dbc_resume (xhci); + done:if (retval ==0 ) {/* Resume root hubs only when have pending events. */
drivers/usb/host/xhci.h +1 -0
@@ -1850,6 +1850,7 @@ struct xhci_hcd {/* Compliance Mode Timer Triggered every 2 seconds */ #define COMP_MODE_RCVRY_MSECS 2000 +void *dbc;/* platform-specific data -- must come last */ unsigned long priv[0 ]__aligned(sizeof(s64)) ; };
include/linux/usb/gadget.h +52 -0
58 lines not on this page · raw message
Signature · 1 line
2.7.4
PATCH v2 4/4 usb: doc: Update document for USB3 debug port usage
In reply to Lu BaoluUpdate Documentation/driver-api/usb/usb3-debug-port.rst. This update includes the guide for using xHCI debug capability based TTY serial link.
--- Documentation/driver-api/usb/usb3-debug-port.rst | 68 ++++++++++++++++++++++++ 1 file changed, 68 insertions(+)
Documentation/driver-api/usb/usb3-debug-port.rst +68 -0
@@ -98,3 +98,71 @@ you to check the sanity of the setup. cat /dev/ttyUSB0 done ===== end of bash scripts =============== + +Serial TTY +========== + +DbC has also been designed for a serial TTY device at runtime. +One use of this is running a login service on the debug target. +Hence it can be remote accessed by the debug host. Another use +can probably be found in servers. It provides a peer-to-peer USB +link between two host-only machines. This provides a reasonable +out-of-band communication method between two servers. + +In order to use this, you need to make sure your kernel has been +configured to support USB_XHCI_DBGCAP. A sysfs attribute under +the xHCI device node is used to enable or disable DbC. By default, +DbC is disabled:: + + root@target:/sys/bus/pci/devices/0000:00:14.0# cat dbc + disabled + +Enable DbC with the following command:: + + root@target:/sys/bus/pci/devices/0000:00:14.0# echo enable > dbc + +You can check the DbC state at anytime:: + + root@target:/sys/bus/pci/devices/0000:00:14.0# cat dbc + enabled + +Connect the debug target to the debug host with a USB 3.0 super- +speed A-to-A debugging cable. You can see the /dev/ttyGSn created +on the debug target. You will see below kernel message lines:: + + root@target: tail -f /var/log/kern.log + [ 182.730103] xhci_hcd 0000:00:14.0: DbC connected + [ 191.169420] xhci_hcd 0000:00:14.0: DbC configured + [ 191.169597] xhci_hcd 0000:00:14.0: DbC now attached to /dev/ttyGS0 + +Accordingly, the DbC state has been brought up to:: + + root@host:/sys/bus/pci/devices/0000:00:14.0# cat dbc + configured + +On the debug host, you will see the debug device has been enumerated. +You will see below kernel message lines:: + + root@host: tail -f /var/log/kern.log + [ 79.454780] usb 2-2.1: new SuperSpeed USB device number 3 using xhci_hcd + [ 79.475003] usb 2-2.1: LPM exit latency is zeroed, disabling LPM. + [ 79.475389] usb 2-2.1: New USB device found, idVendor=1d6b, idProduct=0004 + [ 79.475390] usb 2-2.1: New USB device strings: Mfr=1, Product=2, SerialNumber=3 + [ 79.475391] usb 2-2.1: Product: Remote GDB + [ 79.475392] usb 2-2.1: Manufacturer: Linux + [ 79.475393] usb 2-2.1: SerialNumber: 0001 + [ 79.660368] usb_debug 2-2.1:1.0: xhci_dbc converter detected + [ 79.660439] usb 2-2.1: xhci_dbc converter now attached to ttyUSB0 + +You can simply verify whether it works by:: + + # On target side + root@target: echo "Hello world" > /dev/ttyGS0 + + # On host side + root@host: cat /dev/ttyUSB0 + Hello world + + # vice versa + +You have a workable serial link over USB now.
Signature · 1 line
2.7.4