|  | =============================================================== | 
|  | Synopsys DesignWare Core SuperSpeed USB 3.0 Controller | 
|  | =============================================================== | 
|  |  | 
|  | :Author: Felipe Balbi <felipe.balbi@linux.intel.com> | 
|  | :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: felipe.balbi@linux.intel.com | 
|  | .. _linux-usb: linux-usb@vger.kernel.org |