| =============================================================== | |
| 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 |