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:
- Peripheral-only configuration
- Host-only configuration
- Dual-Role configuration
- 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:
- Cavium
- Intel Corporation
- Qualcomm
- Rockchip
- ST
- Samsung
- Texas Instruments
- 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:
- Up to 16 bidirectional endpoints (including the control pipe - ep0)
- Flexible endpoint configuration
- Simultaneous IN and OUT transfer support
- Scatter-list support
- Up to 256 TRBs [1] per endpoint
- Support for all transfer types (Control, Bulk, Interrupt, and Isochronous)
- SuperSpeed Bulk Streams
- Link Power Management
- Trace Events for debugging
- DebugFS [3] interface
These features have all been exercised with many of the in-tree gadget drivers. We have verified both ConfigFS [4] 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 [1] 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 [5], 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 [1] per endpoint, with the last TRB being a Link TRB [2] 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:
- You’re running latest tag from Linus’ tree
- You can reproduce the error without any out-of-tree changes to DWC3
- 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 [3].
In order to capture DWC3’s Trace Events you should run the following commands before plugging the USB cable to a host machine:
# 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:
# 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:
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¶
- 
struct dwc3_event_buffer¶
- Software event buffer representation 
Definition
struct dwc3_event_buffer {
  void * buf;
  void * cache;
  unsigned length;
  unsigned int lpos;
  unsigned int count;
  unsigned int flags;
#define DWC3_EVENT_PENDING    BIT(0
  dma_addr_t dma;
  struct dwc3 * dwc;
};
Members
- buf
- _THE_ buffer
- cache
- The buffer cache used in the threaded interrupt
- length
- size of this buffer
- lpos
- event offset
- count
- cache of last read event count register
- flags
- flags related to this event buffer
- dma
- dma_addr_t
- dwc
- pointer to DWC controller
- 
struct dwc3_ep¶
- device side endpoint representation 
Definition
struct dwc3_ep {
  struct usb_ep endpoint;
  struct list_head pending_list;
  struct list_head started_list;
  wait_queue_head_t wait_end_transfer;
  spinlock_t lock;
  void __iomem * regs;
  struct dwc3_trb * trb_pool;
  dma_addr_t trb_pool_dma;
  struct dwc3 * dwc;
  u32 saved_state;
  unsigned flags;
#define DWC3_EP_ENABLED               BIT(0
#define DWC3_EP_STALL         BIT(1
#define DWC3_EP_WEDGE         BIT(2
#define DWC3_EP_BUSY          BIT(4
#define DWC3_EP_PENDING_REQUEST       BIT(5
#define DWC3_EP_MISSED_ISOC   BIT(6
#define DWC3_EP_END_TRANSFER_PENDING  BIT(7
#define DWC3_EP_TRANSFER_STARTED BIT(8
#define DWC3_EP0_DIR_IN               BIT(31
  u8 trb_enqueue;
  u8 trb_dequeue;
  u8 number;
  u8 type;
  u8 resource_index;
  u32 allocated_requests;
  u32 queued_requests;
  u32 frame_number;
  u32 interval;
  char name;
  unsigned direction:1;
  unsigned stream_capable:1;
};
Members
- endpoint
- usb endpoint
- pending_list
- list of pending requests for this endpoint
- started_list
- list of started requests on this endpoint
- wait_end_transfer
- wait_queue_head_t for waiting on End Transfer complete
- lock
- spinlock for endpoint request queue traversal
- regs
- pointer to first endpoint register
- trb_pool
- array of transaction buffers
- trb_pool_dma
- dma address of trb_pool
- dwc
- pointer to DWC controller
- saved_state
- ep state saved during hibernation
- flags
- endpoint flags (wedged, stalled, ...)
- trb_enqueue
- enqueue ‘pointer’ into TRB array
- trb_dequeue
- dequeue ‘pointer’ into TRB array
- number
- endpoint number (1 - 15)
- type
- set to bmAttributes & USB_ENDPOINT_XFERTYPE_MASK
- resource_index
- Resource transfer index
- allocated_requests
- number of requests allocated
- queued_requests
- number of requests queued for transfer
- frame_number
- set to the frame number we want this transfer to start (ISOC)
- interval
- the interval on which the ISOC transfer is started
- name
- a human readable name e.g. ep1out-bulk
- direction
- true for TX, false for RX
- stream_capable
- true when streams are enabled
- 
struct dwc3_trb¶
- transfer request block (hw format) 
Definition
struct dwc3_trb {
  u32 bpl;
  u32 bph;
  u32 size;
  u32 ctrl;
};
Members
- bpl
- DW0-3
- bph
- DW4-7
- size
- DW8-B
- ctrl
- DWC-F
- 
struct dwc3_hwparams¶
- copy of HWPARAMS registers 
Definition
struct dwc3_hwparams {
  u32 hwparams0;
  u32 hwparams1;
  u32 hwparams2;
  u32 hwparams3;
  u32 hwparams4;
  u32 hwparams5;
  u32 hwparams6;
  u32 hwparams7;
  u32 hwparams8;
};
Members
- hwparams0
- GHWPARAMS0
- hwparams1
- GHWPARAMS1
- hwparams2
- GHWPARAMS2
- hwparams3
- GHWPARAMS3
- hwparams4
- GHWPARAMS4
- hwparams5
- GHWPARAMS5
- hwparams6
- GHWPARAMS6
- hwparams7
- GHWPARAMS7
- hwparams8
- GHWPARAMS8
- 
struct dwc3_request¶
- representation of a transfer request 
Definition
struct dwc3_request {
  struct usb_request request;
  struct list_head list;
  struct dwc3_ep * dep;
  struct scatterlist * sg;
  unsigned num_pending_sgs;
  unsigned remaining;
  u8 epnum;
  struct dwc3_trb * trb;
  dma_addr_t trb_dma;
  unsigned unaligned:1;
  unsigned direction:1;
  unsigned mapped:1;
  unsigned started:1;
  unsigned zero:1;
};
Members
- request
- struct usb_request to be transferred
- list
- a list_head used for request queueing
- dep
- struct dwc3_ep owning this request
- sg
- pointer to first incomplete sg
- num_pending_sgs
- counter to pending sgs
- remaining
- amount of data remaining
- epnum
- endpoint number to which this request refers
- trb
- pointer to struct dwc3_trb
- trb_dma
- DMA address of trb
- unaligned
- true for OUT endpoints with length not divisible by maxp
- direction
- IN or OUT direction flag
- mapped
- true when request has been dma-mapped
- started
- request is started
- zero
- wants a ZLP
- 
struct dwc3¶
- representation of our controller 
Definition
struct dwc3 {
  struct work_struct drd_work;
  struct dwc3_trb * ep0_trb;
  void * bounce;
  void * scratchbuf;
  u8 * setup_buf;
  dma_addr_t ep0_trb_addr;
  dma_addr_t bounce_addr;
  dma_addr_t scratch_addr;
  struct dwc3_request ep0_usb_req;
  struct completion ep0_in_setup;
  spinlock_t lock;
  struct device * dev;
  struct device * sysdev;
  struct platform_device * xhci;
  struct resource xhci_resources;
  struct dwc3_event_buffer * ev_buf;
  struct dwc3_ep * eps;
  struct usb_gadget gadget;
  struct usb_gadget_driver * gadget_driver;
  struct usb_phy * usb2_phy;
  struct usb_phy * usb3_phy;
  struct phy * usb2_generic_phy;
  struct phy * usb3_generic_phy;
  struct ulpi * ulpi;
  void __iomem * regs;
  size_t regs_size;
  enum usb_dr_mode dr_mode;
  u32 current_dr_role;
  u32 desired_dr_role;
  struct extcon_dev * edev;
  struct notifier_block edev_nb;
  enum usb_phy_interface hsphy_mode;
  u32 fladj;
  u32 irq_gadget;
  u32 nr_scratch;
  u32 u1u2;
  u32 maximum_speed;
  u32 revision;
#define DWC3_REVISION_173A    0x5533173a
#define DWC3_REVISION_175A    0x5533175a
#define DWC3_REVISION_180A    0x5533180a
#define DWC3_REVISION_183A    0x5533183a
#define DWC3_REVISION_185A    0x5533185a
#define DWC3_REVISION_187A    0x5533187a
#define DWC3_REVISION_188A    0x5533188a
#define DWC3_REVISION_190A    0x5533190a
#define DWC3_REVISION_194A    0x5533194a
#define DWC3_REVISION_200A    0x5533200a
#define DWC3_REVISION_202A    0x5533202a
#define DWC3_REVISION_210A    0x5533210a
#define DWC3_REVISION_220A    0x5533220a
#define DWC3_REVISION_230A    0x5533230a
#define DWC3_REVISION_240A    0x5533240a
#define DWC3_REVISION_250A    0x5533250a
#define DWC3_REVISION_260A    0x5533260a
#define DWC3_REVISION_270A    0x5533270a
#define DWC3_REVISION_280A    0x5533280a
#define DWC3_REVISION_290A    0x5533290a
#define DWC3_REVISION_300A    0x5533300a
#define DWC3_REVISION_310A    0x5533310a
#define DWC3_REVISION_IS_DWC31                0x80000000
#define DWC3_USB31_REVISION_110A      (0x3131302a | DWC3_REVISION_IS_DWC31
#define DWC3_USB31_REVISION_120A      (0x3132302a | DWC3_REVISION_IS_DWC31
  enum dwc3_ep0_next ep0_next_event;
  enum dwc3_ep0_state ep0state;
  enum dwc3_link_state link_state;
  u16 isoch_delay;
  u16 u2sel;
  u16 u2pel;
  u8 u1sel;
  u8 u1pel;
  u8 speed;
  u8 num_eps;
  struct dwc3_hwparams hwparams;
  struct dentry * root;
  struct debugfs_regset32 * regset;
  u8 test_mode;
  u8 test_mode_nr;
  u8 lpm_nyet_threshold;
  u8 hird_threshold;
  const char * hsphy_interface;
  unsigned connected:1;
  unsigned delayed_status:1;
  unsigned ep0_bounced:1;
  unsigned ep0_expect_in:1;
  unsigned has_hibernation:1;
  unsigned sysdev_is_parent:1;
  unsigned has_lpm_erratum:1;
  unsigned is_utmi_l1_suspend:1;
  unsigned is_fpga:1;
  unsigned pending_events:1;
  unsigned pullups_connected:1;
  unsigned setup_packet_pending:1;
  unsigned three_stage_setup:1;
  unsigned usb3_lpm_capable:1;
  unsigned disable_scramble_quirk:1;
  unsigned u2exit_lfps_quirk:1;
  unsigned u2ss_inp3_quirk:1;
  unsigned req_p1p2p3_quirk:1;
  unsigned del_p1p2p3_quirk:1;
  unsigned del_phy_power_chg_quirk:1;
  unsigned lfps_filter_quirk:1;
  unsigned rx_detect_poll_quirk:1;
  unsigned dis_u3_susphy_quirk:1;
  unsigned dis_u2_susphy_quirk:1;
  unsigned dis_enblslpm_quirk:1;
  unsigned dis_rxdet_inp3_quirk:1;
  unsigned dis_u2_freeclk_exists_quirk:1;
  unsigned dis_del_phy_power_chg_quirk:1;
  unsigned dis_tx_ipgap_linecheck_quirk:1;
  unsigned tx_de_emphasis_quirk:1;
  unsigned tx_de_emphasis:2;
  u16 imod_interval;
};
Members
- drd_work
- workqueue used for role swapping
- ep0_trb
- trb which is used for the ctrl_req
- bounce
- address of bounce buffer
- scratchbuf
- address of scratch buffer
- setup_buf
- used while precessing STD USB requests
- ep0_trb_addr
- dma address of ep0_trb
- bounce_addr
- dma address of bounce
- scratch_addr
- dma address of scratchbuf
- ep0_usb_req
- dummy req used while handling STD USB requests
- ep0_in_setup
- one control transfer is completed and enter setup phase
- lock
- for synchronizing
- dev
- pointer to our struct device
- sysdev
- pointer to the DMA-capable device
- xhci
- pointer to our xHCI child
- xhci_resources
- struct resources for our xhci child
- ev_buf
- struct dwc3_event_buffer pointer
- eps
- endpoint array
- gadget
- device side representation of the peripheral controller
- gadget_driver
- pointer to the gadget driver
- usb2_phy
- pointer to USB2 PHY
- usb3_phy
- pointer to USB3 PHY
- usb2_generic_phy
- pointer to USB2 PHY
- usb3_generic_phy
- pointer to USB3 PHY
- ulpi
- pointer to ulpi interface
- regs
- base address for our registers
- regs_size
- address space size
- dr_mode
- requested mode of operation
- current_dr_role
- current role of operation when in dual-role mode
- desired_dr_role
- desired role of operation when in dual-role mode
- edev
- extcon handle
- edev_nb
- extcon notifier
- hsphy_mode
- UTMI phy mode, one of following: - USBPHY_INTERFACE_MODE_UTMI - USBPHY_INTERFACE_MODE_UTMIW
- fladj
- frame length adjustment
- irq_gadget
- peripheral controller’s IRQ number
- nr_scratch
- number of scratch buffers
- u1u2
- only used on revisions <1.83a for workaround
- maximum_speed
- maximum speed requested (mainly for testing purposes)
- revision
- revision register contents
- ep0_next_event
- hold the next expected event
- ep0state
- state of endpoint zero
- link_state
- link state
- isoch_delay
- wValue from Set Isochronous Delay request;
- u2sel
- parameter from Set SEL request.
- u2pel
- parameter from Set SEL request.
- u1sel
- parameter from Set SEL request.
- u1pel
- parameter from Set SEL request.
- speed
- device speed (super, high, full, low)
- num_eps
- number of endpoints
- hwparams
- copy of hwparams registers
- root
- debugfs root folder pointer
- regset
- debugfs pointer to regdump file
- test_mode
- true when we’re entering a USB test mode
- test_mode_nr
- test feature selector
- lpm_nyet_threshold
- LPM NYET response threshold
- hird_threshold
- HIRD threshold
- hsphy_interface
- “utmi” or “ulpi”
- connected
- true when we’re connected to a host, false otherwise
- delayed_status
- true when gadget driver asks for delayed status
- ep0_bounced
- true when we used bounce buffer
- ep0_expect_in
- true when we expect a DATA IN transfer
- has_hibernation
- true when dwc3 was configured with Hibernation
- sysdev_is_parent
- true when dwc3 device has a parent driver
- has_lpm_erratum
- true when core was configured with LPM Erratum. Note that there’s now way for software to detect this in runtime.
- is_utmi_l1_suspend
- the core asserts output signal 0 - utmi_sleep_n 1 - utmi_l1_suspend_n
- is_fpga
- true when we are using the FPGA board
- pending_events
- true when we have pending IRQs to be handled
- pullups_connected
- true when Run/Stop bit is set
- setup_packet_pending
- true when there’s a Setup Packet in FIFO. Workaround
- three_stage_setup
- set if we perform a three phase setup
- usb3_lpm_capable
- set if hadrware supports Link Power Management
- disable_scramble_quirk
- set if we enable the disable scramble quirk
- u2exit_lfps_quirk
- set if we enable u2exit lfps quirk
- u2ss_inp3_quirk
- set if we enable P3 OK for U2/SS Inactive quirk
- req_p1p2p3_quirk
- set if we enable request p1p2p3 quirk
- del_p1p2p3_quirk
- set if we enable delay p1p2p3 quirk
- del_phy_power_chg_quirk
- set if we enable delay phy power change quirk
- lfps_filter_quirk
- set if we enable LFPS filter quirk
- rx_detect_poll_quirk
- set if we enable rx_detect to polling lfps quirk
- dis_u3_susphy_quirk
- set if we disable usb3 suspend phy
- dis_u2_susphy_quirk
- set if we disable usb2 suspend phy
- dis_enblslpm_quirk
- set if we clear enblslpm in GUSB2PHYCFG, disabling the suspend signal to the PHY.
- dis_rxdet_inp3_quirk
- set if we disable Rx.Detect in P3
- dis_u2_freeclk_exists_quirk
- set if we clear u2_freeclk_exists in GUSB2PHYCFG, specify that USB2 PHY doesn’t provide a free-running PHY clock.
- dis_del_phy_power_chg_quirk
- set if we disable delay phy power change quirk.
- dis_tx_ipgap_linecheck_quirk
- set if we disable u2mac linestate check during HS transmit.
- tx_de_emphasis_quirk
- set if we enable Tx de-emphasis quirk
- tx_de_emphasis
- Tx de-emphasis value 0 - -6dB de-emphasis 1 - -3.5dB de-emphasis 2 - No de-emphasis 3 - Reserved
- imod_interval
- set the interrupt moderation interval in 250ns increments or 0 to disable.
- 
struct dwc3_event_depevt¶
- Device Endpoint Events 
Definition
struct dwc3_event_depevt {
  u32 one_bit:1;
  u32 endpoint_number:5;
  u32 endpoint_event:4;
  u32 reserved11_10:2;
  u32 status:4;
#define DEPEVT_STATUS_TRANSFER_ACTIVE BIT(3
#define DEPEVT_STATUS_BUSERR  BIT(0
#define DEPEVT_STATUS_SHORT   BIT(1
#define DEPEVT_STATUS_IOC     BIT(2
#define DEPEVT_STATUS_LST     BIT(3
#define DEPEVT_STREAMEVT_FOUND                1
#define DEPEVT_STREAMEVT_NOTFOUND     2
#define DEPEVT_STATUS_CONTROL_DATA    1
#define DEPEVT_STATUS_CONTROL_STATUS  2
#define DEPEVT_STATUS_CONTROL_PHASE(n
#define DEPEVT_TRANSFER_NO_RESOURCE   1
#define DEPEVT_TRANSFER_BUS_EXPIRY    2
  u32 parameters:16;
#define DEPEVT_PARAMETER_CMD(n
};
Members
- one_bit
- indicates this is an endpoint event (not used)
- endpoint_number
- number of the endpoint
- endpoint_event
- The event we have: 0x00 - Reserved 0x01 - XferComplete 0x02 - XferInProgress 0x03 - XferNotReady 0x04 - RxTxFifoEvt (IN->Underrun, OUT->Overrun) 0x05 - Reserved 0x06 - StreamEvt 0x07 - EPCmdCmplt
- reserved11_10
- Reserved, don’t use.
- status
- Indicates the status of the event. Refer to databook for more information.
- parameters
- Parameters of the current event. Refer to databook for more information.
- 
struct dwc3_event_devt¶
- Device Events 
Definition
struct dwc3_event_devt {
  u32 one_bit:1;
  u32 device_event:7;
  u32 type:4;
  u32 reserved15_12:4;
  u32 event_info:9;
  u32 reserved31_25:7;
};
Members
- one_bit
- indicates this is a non-endpoint event (not used)
- device_event
- indicates it’s a device event. Should read as 0x00
- type
- indicates the type of device event. 0 - DisconnEvt 1 - USBRst 2 - ConnectDone 3 - ULStChng 4 - WkUpEvt 5 - Reserved 6 - EOPF 7 - SOF 8 - Reserved 9 - ErrticErr 10 - CmdCmplt 11 - EvntOverflow 12 - VndrDevTstRcved
- reserved15_12
- Reserved, not used
- event_info
- Information about this event
- reserved31_25
- Reserved, not used
- 
struct dwc3_event_gevt¶
- Other Core Events 
Definition
struct dwc3_event_gevt {
  u32 one_bit:1;
  u32 device_event:7;
  u32 phy_port_number:4;
  u32 reserved31_12:20;
};
Members
- one_bit
- indicates this is a non-endpoint event (not used)
- device_event
- indicates it’s (0x03) Carkit or (0x04) I2C event.
- phy_port_number
- self-explanatory
- reserved31_12
- Reserved, not used.
- 
union dwc3_event¶
- representation of Event Buffer contents 
Definition
union dwc3_event {
  u32 raw;
  struct dwc3_event_type type;
  struct dwc3_event_depevt depevt;
  struct dwc3_event_devt devt;
  struct dwc3_event_gevt gevt;
};
Members
- raw
- raw 32-bit event
- type
- the type of the event
- depevt
- Device Endpoint Event
- devt
- Device Event
- gevt
- Global Event
- 
struct dwc3_gadget_ep_cmd_params¶
- representation of endpoint command parameters 
Definition
struct dwc3_gadget_ep_cmd_params {
  u32 param2;
  u32 param1;
  u32 param0;
};
Members
- param2
- third parameter
- param1
- second parameter
- param0
- first parameter
- 
struct dwc3_request * next_request(struct list_head * list)¶
- gets the next request on the given list 
Parameters
- struct list_head * list
- the request list to operate on
Description
Caller should take care of locking. This function return NULL or the first
request available on list.
- 
void dwc3_gadget_move_started_request(struct dwc3_request * req)¶
- move req to the started_list 
Parameters
- struct dwc3_request * req
- the request to be moved
Description
Caller should take care of locking. This function will move req from its current list to the endpoint’s started_list.
Parameters
- struct dwc3_ep * dep
- dwc3 endpoint
Description
Caller should take care of locking. Returns the transfer resource index for a given endpoint.
Parameters
- struct dwc3 * dwc
- pointer to our context structure
- int mode
- the mode to set (J, K SE0 NAK, Force Enable)
Description
Caller should take care of locking. This function will return 0 on success or -EINVAL if wrong Test Selector is passed.
Parameters
- struct dwc3 * dwc
- pointer to our context structure
Description
Caller should take care of locking. This function will return the link state on success (>= 0) or -ETIMEDOUT.
- 
int dwc3_gadget_set_link_state(struct dwc3 * dwc, enum dwc3_link_state state)¶
- sets usb link to a particular state 
Parameters
- struct dwc3 * dwc
- pointer to our context structure
- enum dwc3_link_state state
- the state to put link into
Description
Caller should take care of locking. This function will return 0 on success or -ETIMEDOUT.
- 
void dwc3_ep_inc_trb(u8 * index)¶
- increment a trb index. 
Parameters
- u8 * index
- Pointer to the TRB index to increment.
Description
The index should never point to the link TRB. After incrementing, if it is point to the link TRB, wrap around to the beginning. The link TRB is always at the last TRB entry.
Parameters
- struct dwc3_ep * dep
- The endpoint whose enqueue pointer we’re incrementing
Parameters
- struct dwc3_ep * dep
- The endpoint whose enqueue pointer we’re incrementing
- 
void dwc3_gadget_giveback(struct dwc3_ep * dep, struct dwc3_request * req, int status)¶
- call struct usb_request’s ->complete callback 
Parameters
- struct dwc3_ep * dep
- The endpoint to whom the request belongs to
- struct dwc3_request * req
- The request we’re giving back
- int status
- completion code for the request
Description
Must be called with controller’s lock held and interrupts disabled. This function will unmap req and call its ->:c:func:complete() callback to notify upper layers that it has completed.
- 
int dwc3_send_gadget_generic_command(struct dwc3 * dwc, unsigned cmd, u32 param)¶
- issue a generic command for the controller 
Parameters
- struct dwc3 * dwc
- pointer to the controller context
- unsigned cmd
- the command to be issued
- u32 param
- command parameter
Description
Caller should take care of locking. Issue cmd with a given param to dwc and wait for its completion.
- 
int dwc3_send_gadget_ep_cmd(struct dwc3_ep * dep, unsigned cmd, struct dwc3_gadget_ep_cmd_params * params)¶
- issue an endpoint command 
Parameters
- struct dwc3_ep * dep
- the endpoint to which the command is going to be issued
- unsigned cmd
- the command to be issued
- struct dwc3_gadget_ep_cmd_params * params
- parameters to the command
Description
Caller should handle locking. This function will issue cmd with given params to dep and wait for its completion.
Parameters
- struct dwc3 * dwc
- pointer to our controller context structure
- struct dwc3_ep * dep
- endpoint that is being enabled
Description
Issue a DWC3_DEPCMD_DEPSTARTCFG command to dep. After the command’s
completion, it will set Transfer Resource for all available endpoints.
The assignment of transfer resources cannot perfectly follow the data book due to the fact that the controller driver does not have all knowledge of the configuration in advance. It is given this information piecemeal by the composite gadget framework after every SET_CONFIGURATION and SET_INTERFACE. Trying to follow the databook programming model in this scenario can cause errors. For two reasons:
1) The databook says to do DWC3_DEPCMD_DEPSTARTCFG for every
USB_REQ_SET_CONFIGURATION and USB_REQ_SET_INTERFACE (8.1.5). This is
incorrect in the scenario of multiple interfaces.
2) The databook does not mention doing more DWC3_DEPCMD_DEPXFERCFG for new
endpoint on alt setting (8.1.6).
The following simplified method is used instead:
All hardware endpoints can be assigned a transfer resource and this setting
will stay persistent until either a core reset or hibernation. So whenever we
do a DWC3_DEPCMD_DEPSTARTCFG``(0) we can go ahead and do
``DWC3_DEPCMD_DEPXFERCFG for every hardware endpoint as well. We are
guaranteed that there are as many transfer resources as endpoints.
This function is called for each endpoint when it is being enabled but is triggered only when called for EP0-out, which always happens first, and which should only happen in one of the above conditions.
- 
int __dwc3_gadget_ep_enable(struct dwc3_ep * dep, bool modify, bool restore)¶
- initializes a hw endpoint 
Parameters
- struct dwc3_ep * dep
- endpoint to be initialized
- bool modify
- if true, modify existing endpoint configuration
- bool restore
- if true, restore endpoint configuration from scratch buffer
Description
Caller should take care of locking. Execute all necessary commands to initialize a HW endpoint so it can be used by a gadget driver.
Parameters
- struct dwc3_ep * dep
- the endpoint to disable
Description
This function undoes what __dwc3_gadget_ep_enable did and also removes requests which are currently being processed by the hardware and those which are not yet scheduled.
Caller should take care of locking.
- 
void dwc3_prepare_one_trb(struct dwc3_ep * dep, struct dwc3_request * req, unsigned chain, unsigned node)¶
- setup one TRB from one request 
Parameters
- struct dwc3_ep * dep
- endpoint for which this request is prepared
- struct dwc3_request * req
- dwc3_request pointer
- unsigned chain
- should this TRB be chained to the next?
- unsigned node
- only for isochronous endpoints. First TRB needs different type.
- 
struct dwc3_trb * dwc3_ep_prev_trb(struct dwc3_ep * dep, u8 index)¶
- returns the previous TRB in the ring 
Parameters
- struct dwc3_ep * dep
- The endpoint with the TRB ring
- u8 index
- The index of the current TRB in the ring
Description
Returns the TRB prior to the one pointed to by the index. If the index is 0, we will wrap backwards, skip the link TRB, and return the one just before that.
Parameters
- struct dwc3 * dwc
- pointer to our context structure
Description
The following looks like complex but it’s actually very simple. In order to calculate the number of packets we can burst at once on OUT transfers, we’re gonna use RxFIFO size.
To calculate RxFIFO size we need two numbers: MDWIDTH = size, in bits, of the internal memory bus RAM2_DEPTH = depth, in MDWIDTH, of internal RAM2 (where RxFIFO sits)
Given these two numbers, the formula is simple:
RxFIFO Size = (RAM2_DEPTH * MDWIDTH / 8) - 24 - 16;
24 bytes is for 3x SETUP packets 16 bytes is a clock domain crossing tolerance
Given RxFIFO Size, NUMP = RxFIFOSize / 1024;
Parameters
- struct dwc3 * dwc
- pointer to our controller context structure
Description
Returns 0 on success otherwise negative errno.
- 
DWC3_DEFAULT_AUTOSUSPEND_DELAY()¶
- DesignWare USB3 DRD Controller Core file 
Parameters
Description
Copyright (C) 2010-2011 Texas Instruments Incorporated - http://www.ti.com
- Authors: Felipe Balbi <balbi**ti**.com>,
- Sebastian Andrzej Siewior <bigeasy**linutronix**.de>
Parameters
- struct dwc3 * dwc
- pointer to our context structure
Parameters
- struct dwc3 * dwc
- pointer to our context structure
- 
void dwc3_free_one_event_buffer(struct dwc3 * dwc, struct dwc3_event_buffer * evt)¶
- Frees one event buffer 
Parameters
- struct dwc3 * dwc
- Pointer to our controller context structure
- struct dwc3_event_buffer * evt
- Pointer to event buffer to be freed
- 
struct dwc3_event_buffer * dwc3_alloc_one_event_buffer(struct dwc3 * dwc, unsigned length)¶
- Allocates one event buffer structure 
Parameters
- struct dwc3 * dwc
- Pointer to our controller context structure
- unsigned length
- size of the event buffer
Description
Returns a pointer to the allocated event buffer structure on success otherwise ERR_PTR(errno).
Parameters
- struct dwc3 * dwc
- Pointer to our controller context structure
- 
int dwc3_alloc_event_buffers(struct dwc3 * dwc, unsigned length)¶
- Allocates num event buffers of size length 
Parameters
- struct dwc3 * dwc
- pointer to our controller context structure
- unsigned length
- size of event buffer
Description
Returns 0 on success otherwise negative errno. In the error case, dwc may contain some buffers allocated but not all which were requested.
Parameters
- struct dwc3 * dwc
- pointer to our controller context structure
Description
Returns 0 on success otherwise negative errno.
Parameters
- struct dwc3 * dwc
- Pointer to our controller context structure
Description
Returns 0 on success. The USB PHY interfaces are configured but not initialized. The PHY interfaces and the PHYs get initialized together with the core in dwc3_core_init.
Parameters
- struct dwc3 * dwc
- Pointer to our controller context structure
Description
Returns 0 on success otherwise negative errno.
| [1] | (1, 2, 3) Transfer Request Block | 
| [2] | Transfer Request Block pointing to another Transfer Request Block. | 
| [3] | (1, 2) The Debug File System | 
| [4] | The Config File System | 
| [5] | Command Block Wrapper |