From 8b4cfe0bb7a4117087e2431d668ab79faabe3faa Mon Sep 17 00:00:00 2001 From: Felipe Balbi Date: Wed, 19 Apr 2017 15:02:20 +0300 Subject: usb: dwc3: add ReST documentation Document a few details about DWC3 in order to help people report bugs and debug DWC3. Signed-off-by: Felipe Balbi --- Documentation/driver-api/usb/dwc3.rst | 712 +++++++++++++++++++++++++++++++++ Documentation/driver-api/usb/index.rst | 1 + 2 files changed, 713 insertions(+) create mode 100644 Documentation/driver-api/usb/dwc3.rst (limited to 'Documentation') diff --git a/Documentation/driver-api/usb/dwc3.rst b/Documentation/driver-api/usb/dwc3.rst new file mode 100644 index 000000000000..c3dc84a50ce5 --- /dev/null +++ b/Documentation/driver-api/usb/dwc3.rst @@ -0,0 +1,712 @@ +=============================================================== +Synopsys DesignWare Core SuperSpeed USB 3.0 Controller +=============================================================== + +:Author: Felipe Balbi +: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_BUSY ? 'B' : 'b', + __entry->flags & DWC3_EP_PENDING_REQUEST ? 'P' : 'p', + __entry->flags & DWC3_EP_MISSED_ISOC ? 'M' : 'm', + __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 diff --git a/Documentation/driver-api/usb/index.rst b/Documentation/driver-api/usb/index.rst index 1bf64edc8c8a..3d357a83046b 100644 --- a/Documentation/driver-api/usb/index.rst +++ b/Documentation/driver-api/usb/index.rst @@ -16,6 +16,7 @@ Linux USB API persist error-codes writing_usb_driver + dwc3 writing_musb_glue_layer .. only:: subproject and html -- cgit v1.2.3