Skip to contentSkip to conversation

usb: xhci: Add debug capability support in xhci

PATCH Superseded Lu Baolu 2 participants 9 messages Aug 7, 2017 – Aug 9, 2017

Subsystems (3)

v2 of 3 Superseded Latest is v3 →

lore
Share & tools
lore

Lu Baolu

author
#0 lore raw

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
author
#1 lore raw

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
index 2a82c92..1ccb1c5 100644
@@ -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 *xhci
 	return 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
index cc368ad..a55e377 100644
@@ -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
index e3e9352..62bcdcd 100644
@@ -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
author
#2 lore raw

PATCH v2 2/4 usb: common: Move u_serial from gadget/function to usb/common

In reply to Lu Baolu

The 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
index 939a63b..c39aceb 100644
@@ -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
index 9650b35..a3274aa 100644
@@ -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
index 6bbb3ec..dff720b 100644
@@ -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
index 35cc641..304c9b4 100644
@@ -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
index 86e8252..57f5ed0 100644
@@ -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
index 5e3828d..5d00da1 100644
@@ -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
index d43e86c..6e7acd4 100644
@@ -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
index cb00ada..c589982 100644
@@ -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

drivers/usb/gadget/legacy/acm_ms.c +1 -2
index c39de65..5c63b95 100644

Lines of this file are not shown. View the raw message.

drivers/usb/gadget/legacy/cdc2.c +1 -1
index 51c0868..e06a88e 100644

Lines of this file are not shown. View the raw message.

drivers/usb/gadget/legacy/dbgp.c +1 -2
index 99ca3da..ed8b9d4 100644

Lines of this file are not shown. View the raw message.

drivers/usb/gadget/legacy/multi.c +1 -1
index a70a406..335eea9 100644

Lines of this file are not shown. View the raw message.

drivers/usb/gadget/legacy/nokia.c +1 -1
index b1e535f..135f075 100644

Lines of this file are not shown. View the raw message.

drivers/usb/gadget/legacy/serial.c +1 -2
index 9d89adc..1ca8d58 100644

Lines of this file are not shown. View the 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.

#3 lore raw

Re: [PATCH v2 2/4] usb: common: Move u_serial from gadget/function to usb/common

Hi,

Quoted 13 lines · Lu Baolu

The 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.

Quoted 6 lines

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.

NAK, u_serial uses the gadget API. It's definitely not COMMON.

Signature · 1 line
balbi
author
#4 lore raw

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_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.

Quoted 8 lines
Quoted 6 lines

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.

NAK, u_serial uses 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

#5 lore raw

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_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.

Quoted 6 lines
Quoted 3 lines
Quoted 1 line

NAK, u_serial uses 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.

have you looked at drivers/usb/serial/?

Signature · 1 line
balbi
author
#6 lore raw

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_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.

Quoted 7 lines
Quoted 5 lines
Quoted 3 lines
Quoted 1 line

NAK, u_serial uses 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.

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

author
#7 lore raw

PATCH v2 3/4 usb: xhci: Add DbC support in xHCI driver

In reply to Lu Baolu

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.

---
 .../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
new file mode 100644
index 0000000..0088aba
@@ -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
index fa5692d..968a196 100644
@@ -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
index cf2691f..4629d20 100644
@@ -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
index b2ff1ff..39a9a88 100644
@@ -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
index 62bcdcd..bae2538 100644
@@ -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
author
#8 lore raw

PATCH v2 4/4 usb: doc: Update document for USB3 debug port usage

In reply to Lu Baolu

Update 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
index feb1a36..e4bb02e 100644
@@ -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