mirror of https://github.com/Qortal/Brooklyn
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
711 lines
27 KiB
711 lines
27 KiB
=============================================================== |
|
Synopsys DesignWare Core SuperSpeed USB 3.0 Controller |
|
=============================================================== |
|
|
|
:Author: Felipe Balbi <[email protected]> |
|
:Date: April 2017 |
|
|
|
Introduction |
|
============ |
|
|
|
The *Synopsys DesignWare Core SuperSpeed USB 3.0 Controller* |
|
(hereinafter referred to as *DWC3*) is a USB SuperSpeed compliant |
|
controller which can be configured in one of 4 ways: |
|
|
|
1. Peripheral-only configuration |
|
2. Host-only configuration |
|
3. Dual-Role configuration |
|
4. Hub configuration |
|
|
|
Linux currently supports several versions of this controller. In all |
|
likelyhood, the version in your SoC is already supported. At the time |
|
of this writing, known tested versions range from 2.02a to 3.10a. As a |
|
rule of thumb, anything above 2.02a should work reliably well. |
|
|
|
Currently, we have many known users for this driver. In alphabetical |
|
order: |
|
|
|
1. Cavium |
|
2. Intel Corporation |
|
3. Qualcomm |
|
4. Rockchip |
|
5. ST |
|
6. Samsung |
|
7. Texas Instruments |
|
8. Xilinx |
|
|
|
Summary of Features |
|
====================== |
|
|
|
For details about features supported by your version of DWC3, consult |
|
your IP team and/or *Synopsys DesignWare Core SuperSpeed USB 3.0 |
|
Controller Databook*. Following is a list of features supported by the |
|
driver at the time of this writing: |
|
|
|
1. Up to 16 bidirectional endpoints (including the control |
|
pipe - ep0) |
|
2. Flexible endpoint configuration |
|
3. Simultaneous IN and OUT transfer support |
|
4. Scatter-list support |
|
5. Up to 256 TRBs [#trb]_ per endpoint |
|
6. Support for all transfer types (*Control*, *Bulk*, |
|
*Interrupt*, and *Isochronous*) |
|
7. SuperSpeed Bulk Streams |
|
8. Link Power Management |
|
9. Trace Events for debugging |
|
10. DebugFS [#debugfs]_ interface |
|
|
|
These features have all been exercised with many of the **in-tree** |
|
gadget drivers. We have verified both *ConfigFS* [#configfs]_ and |
|
legacy gadget drivers. |
|
|
|
Driver Design |
|
============== |
|
|
|
The DWC3 driver sits on the *drivers/usb/dwc3/* directory. All files |
|
related to this driver are in this one directory. This makes it easy |
|
for new-comers to read the code and understand how it behaves. |
|
|
|
Because of DWC3's configuration flexibility, the driver is a little |
|
complex in some places but it should be rather straightforward to |
|
understand. |
|
|
|
The biggest part of the driver refers to the Gadget API. |
|
|
|
Known Limitations |
|
=================== |
|
|
|
Like any other HW, DWC3 has its own set of limitations. To avoid |
|
constant questions about such problems, we decided to document them |
|
here and have a single location to where we could point users. |
|
|
|
OUT Transfer Size Requirements |
|
--------------------------------- |
|
|
|
According to Synopsys Databook, all OUT transfer TRBs [#trb]_ must |
|
have their *size* field set to a value which is integer divisible by |
|
the endpoint's *wMaxPacketSize*. This means that *e.g.* in order to |
|
receive a Mass Storage *CBW* [#cbw]_, req->length must either be set |
|
to a value that's divisible by *wMaxPacketSize* (1024 on SuperSpeed, |
|
512 on HighSpeed, etc), or DWC3 driver must add a Chained TRB pointing |
|
to a throw-away buffer for the remaining length. Without this, OUT |
|
transfers will **NOT** start. |
|
|
|
Note that as of this writing, this won't be a problem because DWC3 is |
|
fully capable of appending a chained TRB for the remaining length and |
|
completely hide this detail from the gadget driver. It's still worth |
|
mentioning because this seems to be the largest source of queries |
|
about DWC3 and *non-working transfers*. |
|
|
|
TRB Ring Size Limitation |
|
------------------------- |
|
|
|
We, currently, have a hard limit of 256 TRBs [#trb]_ per endpoint, |
|
with the last TRB being a Link TRB [#link_trb]_ pointing back to the |
|
first. This limit is arbitrary but it has the benefit of adding up to |
|
exactly 4096 bytes, or 1 Page. |
|
|
|
DWC3 driver will try its best to cope with more than 255 requests and, |
|
for the most part, it should work normally. However this is not |
|
something that has been exercised very frequently. If you experience |
|
any problems, see section **Reporting Bugs** below. |
|
|
|
Reporting Bugs |
|
================ |
|
|
|
Whenever you encounter a problem with DWC3, first and foremost you |
|
should make sure that: |
|
|
|
1. You're running latest tag from `Linus' tree`_ |
|
2. You can reproduce the error without any out-of-tree changes |
|
to DWC3 |
|
3. You have checked that it's not a fault on the host machine |
|
|
|
After all these are verified, then here's how to capture enough |
|
information so we can be of any help to you. |
|
|
|
Required Information |
|
--------------------- |
|
|
|
DWC3 relies exclusively on Trace Events for debugging. Everything is |
|
exposed there, with some extra bits being exposed to DebugFS |
|
[#debugfs]_. |
|
|
|
In order to capture DWC3's Trace Events you should run the following |
|
commands **before** plugging the USB cable to a host machine: |
|
|
|
.. code-block:: sh |
|
|
|
# mkdir -p /d |
|
# mkdir -p /t |
|
# mount -t debugfs none /d |
|
# mount -t tracefs none /t |
|
# echo 81920 > /t/buffer_size_kb |
|
# echo 1 > /t/events/dwc3/enable |
|
|
|
After this is done, you can connect your USB cable and reproduce the |
|
problem. As soon as the fault is reproduced, make a copy of files |
|
``trace`` and ``regdump``, like so: |
|
|
|
.. code-block:: sh |
|
|
|
# cp /t/trace /root/trace.txt |
|
# cat /d/*dwc3*/regdump > /root/regdump.txt |
|
|
|
Make sure to compress ``trace.txt`` and ``regdump.txt`` in a tarball |
|
and email it to `me`_ with `linux-usb`_ in Cc. If you want to be extra |
|
sure that I'll help you, write your subject line in the following |
|
format: |
|
|
|
**[BUG REPORT] usb: dwc3: Bug while doing XYZ** |
|
|
|
On the email body, make sure to detail what you doing, which gadget |
|
driver you were using, how to reproduce the problem, what SoC you're |
|
using, which OS (and its version) was running on the Host machine. |
|
|
|
With all this information, we should be able to understand what's |
|
going on and be helpful to you. |
|
|
|
Debugging |
|
=========== |
|
|
|
First and foremost a disclaimer:: |
|
|
|
DISCLAIMER: The information available on DebugFS and/or TraceFS can |
|
change at any time at any Major Linux Kernel Release. If writing |
|
scripts, do **NOT** assume information to be available in the |
|
current format. |
|
|
|
With that out of the way, let's carry on. |
|
|
|
If you're willing to debug your own problem, you deserve a round of |
|
applause :-) |
|
|
|
Anyway, there isn't much to say here other than Trace Events will be |
|
really helpful in figuring out issues with DWC3. Also, access to |
|
Synopsys Databook will be **really** valuable in this case. |
|
|
|
A USB Sniffer can be helpful at times but it's not entirely required, |
|
there's a lot that can be understood without looking at the wire. |
|
|
|
Feel free to email `me`_ and Cc `linux-usb`_ if you need any help. |
|
|
|
``DebugFS`` |
|
------------- |
|
|
|
``DebugFS`` is very good for gathering snapshots of what's going on |
|
with DWC3 and/or any endpoint. |
|
|
|
On DWC3's ``DebugFS`` directory, you will find the following files and |
|
directories: |
|
|
|
``ep[0..15]{in,out}/`` |
|
``link_state`` |
|
``regdump`` |
|
``testmode`` |
|
|
|
``link_state`` |
|
`````````````` |
|
|
|
When read, ``link_state`` will print out one of ``U0``, ``U1``, |
|
``U2``, ``U3``, ``SS.Disabled``, ``RX.Detect``, ``SS.Inactive``, |
|
``Polling``, ``Recovery``, ``Hot Reset``, ``Compliance``, |
|
``Loopback``, ``Reset``, ``Resume`` or ``UNKNOWN link state``. |
|
|
|
This file can also be written to in order to force link to one of the |
|
states above. |
|
|
|
``regdump`` |
|
````````````` |
|
|
|
File name is self-explanatory. When read, ``regdump`` will print out a |
|
register dump of DWC3. Note that this file can be grepped to find the |
|
information you want. |
|
|
|
``testmode`` |
|
`````````````` |
|
|
|
When read, ``testmode`` will print out a name of one of the specified |
|
USB 2.0 Testmodes (``test_j``, ``test_k``, ``test_se0_nak``, |
|
``test_packet``, ``test_force_enable``) or the string ``no test`` in |
|
case no tests are currently being executed. |
|
|
|
In order to start any of these test modes, the same strings can be |
|
written to the file and DWC3 will enter the requested test mode. |
|
|
|
|
|
``ep[0..15]{in,out}`` |
|
`````````````````````` |
|
|
|
For each endpoint we expose one directory following the naming |
|
convention ``ep$num$dir`` *(ep0in, ep0out, ep1in, ...)*. Inside each |
|
of these directories you will find the following files: |
|
|
|
``descriptor_fetch_queue`` |
|
``event_queue`` |
|
``rx_fifo_queue`` |
|
``rx_info_queue`` |
|
``rx_request_queue`` |
|
``transfer_type`` |
|
``trb_ring`` |
|
``tx_fifo_queue`` |
|
``tx_request_queue`` |
|
|
|
With access to Synopsys Databook, you can decode the information on |
|
them. |
|
|
|
``transfer_type`` |
|
~~~~~~~~~~~~~~~~~~ |
|
|
|
When read, ``transfer_type`` will print out one of ``control``, |
|
``bulk``, ``interrupt`` or ``isochronous`` depending on what the |
|
endpoint descriptor says. If the endpoint hasn't been enabled yet, it |
|
will print ``--``. |
|
|
|
``trb_ring`` |
|
~~~~~~~~~~~~~ |
|
|
|
When read, ``trb_ring`` will print out details about all TRBs on the |
|
ring. It will also tell you where our enqueue and dequeue pointers are |
|
located in the ring: |
|
|
|
.. code-block:: sh |
|
|
|
buffer_addr,size,type,ioc,isp_imi,csp,chn,lst,hwo |
|
000000002c754000,481,normal,1,0,1,0,0,0 |
|
000000002c75c000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c788000,481,normal,1,0,1,0,0,0 |
|
000000002c78c000,481,normal,1,0,1,0,0,0 |
|
000000002c754000,481,normal,1,0,1,0,0,0 |
|
000000002c75c000,481,normal,1,0,1,0,0,0 |
|
000000002c784000,481,normal,1,0,1,0,0,0 |
|
000000002c788000,481,normal,1,0,1,0,0,0 |
|
000000002c78c000,481,normal,1,0,1,0,0,0 |
|
000000002c790000,481,normal,1,0,1,0,0,0 |
|
000000002c758000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c788000,481,normal,1,0,1,0,0,0 |
|
000000002c790000,481,normal,1,0,1,0,0,0 |
|
000000002c758000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c784000,481,normal,1,0,1,0,0,0 |
|
000000002c788000,481,normal,1,0,1,0,0,0 |
|
000000002c78c000,481,normal,1,0,1,0,0,0 |
|
000000002c754000,481,normal,1,0,1,0,0,0 |
|
000000002c758000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c784000,481,normal,1,0,1,0,0,0 |
|
000000002c78c000,481,normal,1,0,1,0,0,0 |
|
000000002c790000,481,normal,1,0,1,0,0,0 |
|
000000002c758000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c788000,481,normal,1,0,1,0,0,0 |
|
000000002c790000,481,normal,1,0,1,0,0,0 |
|
000000002c758000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c788000,481,normal,1,0,1,0,0,0 |
|
000000002c790000,481,normal,1,0,1,0,0,0 |
|
000000002c758000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c788000,481,normal,1,0,1,0,0,0 |
|
000000002c790000,481,normal,1,0,1,0,0,0 |
|
000000002c758000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c788000,481,normal,1,0,1,0,0,0 |
|
000000002c790000,481,normal,1,0,1,0,0,0 |
|
000000002c758000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c788000,481,normal,1,0,1,0,0,0 |
|
000000002c790000,481,normal,1,0,1,0,0,0 |
|
000000002c758000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c788000,481,normal,1,0,1,0,0,0 |
|
000000002c790000,481,normal,1,0,1,0,0,0 |
|
000000002c758000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c788000,481,normal,1,0,1,0,0,0 |
|
000000002c790000,481,normal,1,0,1,0,0,0 |
|
000000002c758000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c78c000,481,normal,1,0,1,0,0,0 |
|
000000002c784000,481,normal,1,0,1,0,0,0 |
|
000000002c788000,481,normal,1,0,1,0,0,0 |
|
000000002c78c000,481,normal,1,0,1,0,0,0 |
|
000000002c754000,481,normal,1,0,1,0,0,0 |
|
000000002c758000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c788000,481,normal,1,0,1,0,0,0 |
|
000000002c790000,481,normal,1,0,1,0,0,0 |
|
000000002c758000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c758000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c78c000,481,normal,1,0,1,0,0,0 |
|
000000002c75c000,481,normal,1,0,1,0,0,0 |
|
000000002c78c000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c754000,481,normal,1,0,1,0,0,0 |
|
000000002c788000,481,normal,1,0,1,0,0,0 |
|
000000002c754000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c788000,481,normal,1,0,1,0,0,0 |
|
000000002c78c000,481,normal,1,0,1,0,0,0 |
|
000000002c790000,481,normal,1,0,1,0,0,0 |
|
000000002c754000,481,normal,1,0,1,0,0,0 |
|
000000002c758000,481,normal,1,0,1,0,0,0 |
|
000000002c75c000,481,normal,1,0,1,0,0,0 |
|
000000002c780000,481,normal,1,0,1,0,0,0 |
|
000000002c784000,481,normal,1,0,1,0,0,0 |
|
000000002c788000,481,normal,1,0,1,0,0,0 |
|
000000002c78c000,481,normal,1,0,1,0,0,0 |
|
000000002c790000,481,normal,1,0,1,0,0,0 |
|
000000002c754000,481,normal,1,0,1,0,0,0 |
|
000000002c758000,481,normal,1,0,1,0,0,0 |
|
000000002c75c000,512,normal,1,0,1,0,0,1 D |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 E |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
0000000000000000,0,UNKNOWN,0,0,0,0,0,0 |
|
00000000381ab000,0,link,0,0,0,0,0,1 |
|
|
|
|
|
Trace Events |
|
------------- |
|
|
|
DWC3 also provides several trace events which help us gathering |
|
information about the behavior of the driver during runtime. |
|
|
|
In order to use these events, you must enable ``CONFIG_FTRACE`` in |
|
your kernel config. |
|
|
|
For details about how enable DWC3 events, see section **Reporting |
|
Bugs**. |
|
|
|
The following subsections will give details about each Event Class and |
|
each Event defined by DWC3. |
|
|
|
MMIO |
|
``````` |
|
|
|
It is sometimes useful to look at every MMIO access when looking for |
|
bugs. Because of that, DWC3 offers two Trace Events (one for |
|
dwc3_readl() and one for dwc3_writel()). ``TP_printk`` follows:: |
|
|
|
TP_printk("addr %p value %08x", __entry->base + __entry->offset, |
|
__entry->value) |
|
|
|
Interrupt Events |
|
```````````````` |
|
|
|
Every IRQ event can be logged and decoded into a human readable |
|
string. Because every event will be different, we don't give an |
|
example other than the ``TP_printk`` format used:: |
|
|
|
TP_printk("event (%08x): %s", __entry->event, |
|
dwc3_decode_event(__entry->event, __entry->ep0state)) |
|
|
|
Control Request |
|
````````````````` |
|
|
|
Every USB Control Request can be logged to the trace buffer. The |
|
output format is:: |
|
|
|
TP_printk("%s", dwc3_decode_ctrl(__entry->bRequestType, |
|
__entry->bRequest, __entry->wValue, |
|
__entry->wIndex, __entry->wLength) |
|
) |
|
|
|
Note that Standard Control Requests will be decoded into |
|
human-readable strings with their respective arguments. Class and |
|
Vendor requests will be printed out a sequence of 8 bytes in hex |
|
format. |
|
|
|
Lifetime of a ``struct usb_request`` |
|
``````````````````````````````````````` |
|
|
|
The entire lifetime of a ``struct usb_request`` can be tracked on the |
|
trace buffer. We have one event for each of allocation, free, |
|
queueing, dequeueing, and giveback. Output format is:: |
|
|
|
TP_printk("%s: req %p length %u/%u %s%s%s ==> %d", |
|
__get_str(name), __entry->req, __entry->actual, __entry->length, |
|
__entry->zero ? "Z" : "z", |
|
__entry->short_not_ok ? "S" : "s", |
|
__entry->no_interrupt ? "i" : "I", |
|
__entry->status |
|
) |
|
|
|
Generic Commands |
|
```````````````````` |
|
|
|
We can log and decode every Generic Command with its completion |
|
code. Format is:: |
|
|
|
TP_printk("cmd '%s' [%x] param %08x --> status: %s", |
|
dwc3_gadget_generic_cmd_string(__entry->cmd), |
|
__entry->cmd, __entry->param, |
|
dwc3_gadget_generic_cmd_status_string(__entry->status) |
|
) |
|
|
|
Endpoint Commands |
|
```````````````````` |
|
|
|
Endpoints commands can also be logged together with completion |
|
code. Format is:: |
|
|
|
TP_printk("%s: cmd '%s' [%d] params %08x %08x %08x --> status: %s", |
|
__get_str(name), dwc3_gadget_ep_cmd_string(__entry->cmd), |
|
__entry->cmd, __entry->param0, |
|
__entry->param1, __entry->param2, |
|
dwc3_ep_cmd_status_string(__entry->cmd_status) |
|
) |
|
|
|
Lifetime of a ``TRB`` |
|
`````````````````````` |
|
|
|
A ``TRB`` Lifetime is simple. We are either preparing a ``TRB`` or |
|
completing it. With these two events, we can see how a ``TRB`` changes |
|
over time. Format is:: |
|
|
|
TP_printk("%s: %d/%d trb %p buf %08x%08x size %s%d ctrl %08x (%c%c%c%c:%c%c:%s)", |
|
__get_str(name), __entry->queued, __entry->allocated, |
|
__entry->trb, __entry->bph, __entry->bpl, |
|
({char *s; |
|
int pcm = ((__entry->size >> 24) & 3) + 1; |
|
switch (__entry->type) { |
|
case USB_ENDPOINT_XFER_INT: |
|
case USB_ENDPOINT_XFER_ISOC: |
|
switch (pcm) { |
|
case 1: |
|
s = "1x "; |
|
break; |
|
case 2: |
|
s = "2x "; |
|
break; |
|
case 3: |
|
s = "3x "; |
|
break; |
|
} |
|
default: |
|
s = ""; |
|
} s; }), |
|
DWC3_TRB_SIZE_LENGTH(__entry->size), __entry->ctrl, |
|
__entry->ctrl & DWC3_TRB_CTRL_HWO ? 'H' : 'h', |
|
__entry->ctrl & DWC3_TRB_CTRL_LST ? 'L' : 'l', |
|
__entry->ctrl & DWC3_TRB_CTRL_CHN ? 'C' : 'c', |
|
__entry->ctrl & DWC3_TRB_CTRL_CSP ? 'S' : 's', |
|
__entry->ctrl & DWC3_TRB_CTRL_ISP_IMI ? 'S' : 's', |
|
__entry->ctrl & DWC3_TRB_CTRL_IOC ? 'C' : 'c', |
|
dwc3_trb_type_string(DWC3_TRBCTL_TYPE(__entry->ctrl)) |
|
) |
|
|
|
Lifetime of an Endpoint |
|
``````````````````````` |
|
|
|
And endpoint's lifetime is summarized with enable and disable |
|
operations, both of which can be traced. Format is:: |
|
|
|
TP_printk("%s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c%c:%c:%c", |
|
__get_str(name), __entry->maxpacket, |
|
__entry->maxpacket_limit, __entry->max_streams, |
|
__entry->maxburst, __entry->trb_enqueue, |
|
__entry->trb_dequeue, |
|
__entry->flags & DWC3_EP_ENABLED ? 'E' : 'e', |
|
__entry->flags & DWC3_EP_STALL ? 'S' : 's', |
|
__entry->flags & DWC3_EP_WEDGE ? 'W' : 'w', |
|
__entry->flags & DWC3_EP_TRANSFER_STARTED ? 'B' : 'b', |
|
__entry->flags & DWC3_EP_PENDING_REQUEST ? 'P' : 'p', |
|
__entry->flags & DWC3_EP_END_TRANSFER_PENDING ? 'E' : 'e', |
|
__entry->direction ? '<' : '>' |
|
) |
|
|
|
|
|
Structures, Methods and Definitions |
|
==================================== |
|
|
|
.. kernel-doc:: drivers/usb/dwc3/core.h |
|
:doc: main data structures |
|
:internal: |
|
|
|
.. kernel-doc:: drivers/usb/dwc3/gadget.h |
|
:doc: gadget-only helpers |
|
:internal: |
|
|
|
.. kernel-doc:: drivers/usb/dwc3/gadget.c |
|
:doc: gadget-side implementation |
|
:internal: |
|
|
|
.. kernel-doc:: drivers/usb/dwc3/core.c |
|
:doc: core driver (probe, PM, etc) |
|
:internal: |
|
|
|
.. [#trb] Transfer Request Block |
|
.. [#link_trb] Transfer Request Block pointing to another Transfer |
|
Request Block. |
|
.. [#debugfs] The Debug File System |
|
.. [#configfs] The Config File System |
|
.. [#cbw] Command Block Wrapper |
|
.. _Linus' tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/ |
|
.. _me: [email protected] |
|
.. _linux-usb: [email protected]
|
|
|