Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > linux.kernel > #1693493 > unrolled thread
| Started by | Lu Baolu <baolu.lu@linux.intel.com> |
|---|---|
| First post | 2017-07-21 11:00 +0200 |
| Last post | 2017-07-24 06:00 +0200 |
| Articles | 4 — 2 participants |
Back to article view | Back to linux.kernel
[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
| From | Lu Baolu <baolu.lu@linux.intel.com> |
|---|---|
| Date | 2017-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]
| From | Lu Baolu <baolu.lu@linux.intel.com> |
|---|---|
| Date | 2017-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]
| From | Felipe Balbi <felipe.balbi@linux.intel.com> |
|---|---|
| Date | 2017-07-21 12:40 +0200 |
| Subject | Re: [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]
| From | Lu Baolu <baolu.lu@linux.intel.com> |
|---|---|
| Date | 2017-07-24 06:00 +0200 |
| Subject | Re: [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