712 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
			
		
		
	
	
			712 lines
		
	
	
		
			27 KiB
		
	
	
	
		
			ReStructuredText
		
	
	
	
	
	
| ===============================================================
 | |
| 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
 | |
| likelihood, 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
 |