|
@@ -0,0 +1,712 @@
|
|
|
+===============================================================
|
|
|
+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_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
|