Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1693493 > unrolled thread

[PATCH 0/3] usb: xhci: Add debug capability support in xhci

Started byLu Baolu <baolu.lu@linux.intel.com>
First post2017-07-21 11:00 +0200
Last post2017-07-24 06:00 +0200
Articles 4 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 0/3] usb: xhci: Add debug capability support in xhci Lu Baolu <baolu.lu@linux.intel.com> - 2017-07-21 11:00 +0200
    [PATCH 1/3] usb: xhci: Make some static functions global Lu Baolu <baolu.lu@linux.intel.com> - 2017-07-21 11:00 +0200
    Re: [PATCH 2/3] usb: xhci: Add DbC support in xHCI driver Felipe Balbi <felipe.balbi@linux.intel.com> - 2017-07-21 12:40 +0200
      Re: [PATCH 2/3] usb: xhci: Add DbC support in xHCI driver Lu Baolu <baolu.lu@linux.intel.com> - 2017-07-24 06:00 +0200

#1693493 — [PATCH 0/3] usb: xhci: Add debug capability support in xhci

FromLu Baolu <baolu.lu@linux.intel.com>
Date2017-07-21 11:00 +0200
Subject[PATCH 0/3] usb: xhci: Add debug capability support in xhci
Message-ID<u5BWV-2C2-17@gated-at.bofh.it>
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

Lu Baolu (3):
  usb: xhci: Make some static functions global
  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/host/Kconfig                           |   10 +
 drivers/usb/host/Makefile                          |    5 +
 drivers/usb/host/xhci-dbgcap.c                     | 1128 ++++++++++++++++++++
 drivers/usb/host/xhci-mem.c                        |   94 +-
 drivers/usb/host/xhci-ring.c                       |    4 +-
 drivers/usb/host/xhci-trace.h                      |   64 ++
 drivers/usb/host/xhci.c                            |    9 +
 drivers/usb/host/xhci.h                            |  205 +++-
 10 files changed, 1569 insertions(+), 43 deletions(-)
 create mode 100644 Documentation/ABI/testing/sysfs-bus-pci-drivers-xhci_hcd
 create mode 100644 drivers/usb/host/xhci-dbgcap.c

-- 
2.7.4

[toc] | [next] | [standalone]


#1693496 — [PATCH 1/3] usb: xhci: Make some static functions global

FromLu Baolu <baolu.lu@linux.intel.com>
Date2017-07-21 11:00 +0200
Subject[PATCH 1/3] usb: xhci: Make some static functions global
Message-ID<u5BWX-2C2-41@gated-at.bofh.it>
In reply to#1693493
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.

Signed-off-by: Lu Baolu <baolu.lu@linux.intel.com>
---
 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(-)

diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 2a82c92..1ccb1c5 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -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);
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index c50c902..6e73645 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -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) {
@@ -2958,7 +2958,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;
 
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 3c6da1f..b4a9b24 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1958,9 +1958,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);
@@ -1990,6 +1998,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 *);
@@ -2064,6 +2076,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,
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1693576 — Re: [PATCH 2/3] usb: xhci: Add DbC support in xHCI driver

FromFelipe Balbi <felipe.balbi@linux.intel.com>
Date2017-07-21 12:40 +0200
SubjectRe: [PATCH 2/3] usb: xhci: Add DbC support in xHCI driver
Message-ID<u5DvI-3Ew-19@gated-at.bofh.it>
In reply to#1693493

[Multipart message — attachments visible in raw view] — view raw

Hi,

Lu Baolu <baolu.lu@linux.intel.com> writes:
> +static void xhci_dbc_stop(struct xhci_hcd *xhci)
> +{
> +	struct xhci_dbc		*dbc = xhci->dbc;
> +
> +	WARN_ON(!dbc);
> +
> +	cancel_delayed_work_sync(&dbc->event_work);
> +
> +	if (dbc->gs_port_num != GSPORT_INVAL) {
> +		gserial_disconnect(&dbc->gs_port);
> +		gserial_free_line(dbc->gs_port_num);

why are you tying host stack to the gadget framework?

With this, you're forcing every single PC in the world to compile the
gadget framework, that's a bit much don't you think?

-- 
balbi

[toc] | [prev] | [next] | [standalone]


#1694432 — Re: [PATCH 2/3] usb: xhci: Add DbC support in xHCI driver

FromLu Baolu <baolu.lu@linux.intel.com>
Date2017-07-24 06:00 +0200
SubjectRe: [PATCH 2/3] usb: xhci: Add DbC support in xHCI driver
Message-ID<u6CHf-7X3-7@gated-at.bofh.it>
In reply to#1693576
Hi Felipe,

On 07/21/2017 06:31 PM, Felipe Balbi wrote:
> Hi,
>
> Lu Baolu <baolu.lu@linux.intel.com> writes:
>> +static void xhci_dbc_stop(struct xhci_hcd *xhci)
>> +{
>> +	struct xhci_dbc		*dbc = xhci->dbc;
>> +
>> +	WARN_ON(!dbc);
>> +
>> +	cancel_delayed_work_sync(&dbc->event_work);
>> +
>> +	if (dbc->gs_port_num != GSPORT_INVAL) {
>> +		gserial_disconnect(&dbc->gs_port);
>> +		gserial_free_line(dbc->gs_port_num);
> why are you tying host stack to the gadget framework?

XHCI debug capability is actually a debug device gadget.
The hardware and firmware do everything of gadget work
and leave the interface to xHCI for enabling/disabling and
queuing transfer requests.

u_serial.c provides a generic layer between a USB gadget
and the TTY layer. I used it to avoid duplicating code.

>
> With this, you're forcing every single PC in the world to compile the
> gadget framework, that's a bit much don't you think?
>

Yes, you are right. Is it acceptable if I move u_serial.c from
the current place to drivers/usb/common?

Best regards,
Lu Baolu

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web