Documentation/driver-api/usb/dwc3.rst GitHub 원문 ↗

Linux 6.18.37 · Driver API

Synopsys DWC3 USB Controller

Synopsys DesignWare Core SuperSpeed USB 3.0 컨트롤러의 기능과 제한, 버그 보고 절차, DebugFS·Trace Events 인터페이스를 설명하는 한국어 전문 번역입니다.

Source pathDocumentation/driver-api/usb/dwc3.rst
Source versionLinux v6.18.37
TranslationDUJINLABS 전문 번역 + 해설

요약·해설과 원문, 전문 번역을 서로 분리했습니다. API 이름, symbol, source path는 원문 표기를 사용합니다.

1. 요약·해설

원문의 핵심 논리와 kernel programming 관점의 보충 설명입니다. 아래의 전문 번역과는 별도로 작성했습니다.

요약·해설

dwc3.rst:1-711

DWC3 드라이버는 peripheral·host·dual-role·hub 구성을 지원하며 Gadget API, endpoint TRB ring, DebugFS snapshot, FTRACE 기반 event를 통해 전송과 controller 상태를 관리·진단합니다.

문서 구성
원문 줄핵심 내용
1-74소개, 기능, 드라이버 설계
75-112OUT 크기와 TRB ring 제한
113-168버그 보고 자료 수집
169-236디버깅과 DebugFS
237-266endpoint별 상태
267-532TRB ring 덤프
533-583MMIO·IRQ·Control trace
584-683request·command·TRB·endpoint 수명주기
684-711kernel-doc와 참조

2. 영어 원문 전체

번역 기준이 된 Linux v6.18.37 원문입니다. 줄 번호는 이 버전의 파일 좌표입니다.

원문 전체 펼치기
1 ===============================================================
2 Synopsys DesignWare Core SuperSpeed USB 3.0 Controller
3 ===============================================================
4
5 :Author: Felipe Balbi <[email protected]>
6 :Date: April 2017
7
8 Introduction
9 ============
10
11 The *Synopsys DesignWare Core SuperSpeed USB 3.0 Controller*
12 (hereinafter referred to as *DWC3*) is a USB SuperSpeed compliant
13 controller which can be configured in one of 4 ways:
14
15 1. Peripheral-only configuration
16 2. Host-only configuration
17 3. Dual-Role configuration
18 4. Hub configuration
19
20 Linux currently supports several versions of this controller. In all
21 likelihood, the version in your SoC is already supported. At the time
22 of this writing, known tested versions range from 2.02a to 3.10a. As a
23 rule of thumb, anything above 2.02a should work reliably well.
24
25 Currently, we have many known users for this driver. In alphabetical
26 order:
27
28 1. Cavium
29 2. Intel Corporation
30 3. Qualcomm
31 4. Rockchip
32 5. ST
33 6. Samsung
34 7. Texas Instruments
35 8. Xilinx
36
37 Summary of Features
38 ======================
39
40 For details about features supported by your version of DWC3, consult
41 your IP team and/or *Synopsys DesignWare Core SuperSpeed USB 3.0
42 Controller Databook*. Following is a list of features supported by the
43 driver at the time of this writing:
44
45 1. Up to 16 bidirectional endpoints (including the control
46 pipe - ep0)
47 2. Flexible endpoint configuration
48 3. Simultaneous IN and OUT transfer support
49 4. Scatter-list support
50 5. Up to 256 TRBs [#trb]_ per endpoint
51 6. Support for all transfer types (*Control*, *Bulk*,
52 *Interrupt*, and *Isochronous*)
53 7. SuperSpeed Bulk Streams
54 8. Link Power Management
55 9. Trace Events for debugging
56 10. DebugFS [#debugfs]_ interface
57
58 These features have all been exercised with many of the **in-tree**
59 gadget drivers. We have verified both *ConfigFS* [#configfs]_ and
60 legacy gadget drivers.
61
62 Driver Design
63 ==============
64
65 The DWC3 driver sits on the *drivers/usb/dwc3/* directory. All files
66 related to this driver are in this one directory. This makes it easy
67 for new-comers to read the code and understand how it behaves.
68
69 Because of DWC3's configuration flexibility, the driver is a little
70 complex in some places but it should be rather straightforward to
71 understand.
72
73 The biggest part of the driver refers to the Gadget API.
74
75 Known Limitations
76 ===================
77
78 Like any other HW, DWC3 has its own set of limitations. To avoid
79 constant questions about such problems, we decided to document them
80 here and have a single location to where we could point users.
81
82 OUT Transfer Size Requirements
83 ---------------------------------
84
85 According to Synopsys Databook, all OUT transfer TRBs [#trb]_ must
86 have their *size* field set to a value which is integer divisible by
87 the endpoint's *wMaxPacketSize*. This means that *e.g.* in order to
88 receive a Mass Storage *CBW* [#cbw]_, req->length must either be set
89 to a value that's divisible by *wMaxPacketSize* (1024 on SuperSpeed,
90 512 on HighSpeed, etc), or DWC3 driver must add a Chained TRB pointing
91 to a throw-away buffer for the remaining length. Without this, OUT
92 transfers will **NOT** start.
93
94 Note that as of this writing, this won't be a problem because DWC3 is
95 fully capable of appending a chained TRB for the remaining length and
96 completely hide this detail from the gadget driver. It's still worth
97 mentioning because this seems to be the largest source of queries
98 about DWC3 and *non-working transfers*.
99
100 TRB Ring Size Limitation
101 -------------------------
102
103 We, currently, have a hard limit of 256 TRBs [#trb]_ per endpoint,
104 with the last TRB being a Link TRB [#link_trb]_ pointing back to the
105 first. This limit is arbitrary but it has the benefit of adding up to
106 exactly 4096 bytes, or 1 Page.
107
108 DWC3 driver will try its best to cope with more than 255 requests and,
109 for the most part, it should work normally. However this is not
110 something that has been exercised very frequently. If you experience
111 any problems, see section **Reporting Bugs** below.
112
113 Reporting Bugs
114 ================
115
116 Whenever you encounter a problem with DWC3, first and foremost you
117 should make sure that:
118
119 1. You're running latest tag from `Linus' tree`_
120 2. You can reproduce the error without any out-of-tree changes
121 to DWC3
122 3. You have checked that it's not a fault on the host machine
123
124 After all these are verified, then here's how to capture enough
125 information so we can be of any help to you.
126
127 Required Information
128 ---------------------
129
130 DWC3 relies exclusively on Trace Events for debugging. Everything is
131 exposed there, with some extra bits being exposed to DebugFS
132 [#debugfs]_.
133
134 In order to capture DWC3's Trace Events you should run the following
135 commands **before** plugging the USB cable to a host machine:
136
137 .. code-block:: sh
138
139 # mkdir -p /d
140 # mkdir -p /t
141 # mount -t debugfs none /d
142 # mount -t tracefs none /t
143 # echo 81920 > /t/buffer_size_kb
144 # echo 1 > /t/events/dwc3/enable
145
146 After this is done, you can connect your USB cable and reproduce the
147 problem. As soon as the fault is reproduced, make a copy of files
148 ``trace`` and ``regdump``, like so:
149
150 .. code-block:: sh
151
152 # cp /t/trace /root/trace.txt
153 # cat /d/*dwc3*/regdump > /root/regdump.txt
154
155 Make sure to compress ``trace.txt`` and ``regdump.txt`` in a tarball
156 and email it to `me`_ with `linux-usb`_ in Cc. If you want to be extra
157 sure that I'll help you, write your subject line in the following
158 format:
159
160 **[BUG REPORT] usb: dwc3: Bug while doing XYZ**
161
162 On the email body, make sure to detail what you doing, which gadget
163 driver you were using, how to reproduce the problem, what SoC you're
164 using, which OS (and its version) was running on the Host machine.
165
166 With all this information, we should be able to understand what's
167 going on and be helpful to you.
168
169 Debugging
170 ===========
171
172 First and foremost a disclaimer::
173
174 DISCLAIMER: The information available on DebugFS and/or TraceFS can
175 change at any time at any Major Linux Kernel Release. If writing
176 scripts, do **NOT** assume information to be available in the
177 current format.
178
179 With that out of the way, let's carry on.
180
181 If you're willing to debug your own problem, you deserve a round of
182 applause :-)
183
184 Anyway, there isn't much to say here other than Trace Events will be
185 really helpful in figuring out issues with DWC3. Also, access to
186 Synopsys Databook will be **really** valuable in this case.
187
188 A USB Sniffer can be helpful at times but it's not entirely required,
189 there's a lot that can be understood without looking at the wire.
190
191 Feel free to email `me`_ and Cc `linux-usb`_ if you need any help.
192
193 ``DebugFS``
194 -------------
195
196 ``DebugFS`` is very good for gathering snapshots of what's going on
197 with DWC3 and/or any endpoint.
198
199 On DWC3's ``DebugFS`` directory, you will find the following files and
200 directories:
201
202 ``ep[0..15]{in,out}/``
203 ``link_state``
204 ``regdump``
205 ``testmode``
206
207 ``link_state``
208 ``````````````
209
210 When read, ``link_state`` will print out one of ``U0``, ``U1``,
211 ``U2``, ``U3``, ``SS.Disabled``, ``RX.Detect``, ``SS.Inactive``,
212 ``Polling``, ``Recovery``, ``Hot Reset``, ``Compliance``,
213 ``Loopback``, ``Reset``, ``Resume`` or ``UNKNOWN link state``.
214
215 This file can also be written to in order to force link to one of the
216 states above.
217
218 ``regdump``
219 `````````````
220
221 File name is self-explanatory. When read, ``regdump`` will print out a
222 register dump of DWC3. Note that this file can be grepped to find the
223 information you want.
224
225 ``testmode``
226 ``````````````
227
228 When read, ``testmode`` will print out a name of one of the specified
229 USB 2.0 Testmodes (``test_j``, ``test_k``, ``test_se0_nak``,
230 ``test_packet``, ``test_force_enable``) or the string ``no test`` in
231 case no tests are currently being executed.
232
233 In order to start any of these test modes, the same strings can be
234 written to the file and DWC3 will enter the requested test mode.
235
236
237 ``ep[0..15]{in,out}``
238 ``````````````````````
239
240 For each endpoint we expose one directory following the naming
241 convention ``ep$num$dir`` *(ep0in, ep0out, ep1in, ...)*. Inside each
242 of these directories you will find the following files:
243
244 ``descriptor_fetch_queue``
245 ``event_queue``
246 ``rx_fifo_queue``
247 ``rx_info_queue``
248 ``rx_request_queue``
249 ``transfer_type``
250 ``trb_ring``
251 ``tx_fifo_queue``
252 ``tx_request_queue``
253
254 With access to Synopsys Databook, you can decode the information on
255 them.
256
257 ``transfer_type``
258 ~~~~~~~~~~~~~~~~~~
259
260 When read, ``transfer_type`` will print out one of ``control``,
261 ``bulk``, ``interrupt`` or ``isochronous`` depending on what the
262 endpoint descriptor says. If the endpoint hasn't been enabled yet, it
263 will print ``--``.
264
265 ``trb_ring``
266 ~~~~~~~~~~~~~
267
268 When read, ``trb_ring`` will print out details about all TRBs on the
269 ring. It will also tell you where our enqueue and dequeue pointers are
270 located in the ring:
271
272 .. code-block:: sh
273
274 buffer_addr,size,type,ioc,isp_imi,csp,chn,lst,hwo
275 000000002c754000,481,normal,1,0,1,0,0,0
276 000000002c75c000,481,normal,1,0,1,0,0,0
277 000000002c780000,481,normal,1,0,1,0,0,0
278 000000002c788000,481,normal,1,0,1,0,0,0
279 000000002c78c000,481,normal,1,0,1,0,0,0
280 000000002c754000,481,normal,1,0,1,0,0,0
281 000000002c75c000,481,normal,1,0,1,0,0,0
282 000000002c784000,481,normal,1,0,1,0,0,0
283 000000002c788000,481,normal,1,0,1,0,0,0
284 000000002c78c000,481,normal,1,0,1,0,0,0
285 000000002c790000,481,normal,1,0,1,0,0,0
286 000000002c758000,481,normal,1,0,1,0,0,0
287 000000002c780000,481,normal,1,0,1,0,0,0
288 000000002c788000,481,normal,1,0,1,0,0,0
289 000000002c790000,481,normal,1,0,1,0,0,0
290 000000002c758000,481,normal,1,0,1,0,0,0
291 000000002c780000,481,normal,1,0,1,0,0,0
292 000000002c784000,481,normal,1,0,1,0,0,0
293 000000002c788000,481,normal,1,0,1,0,0,0
294 000000002c78c000,481,normal,1,0,1,0,0,0
295 000000002c754000,481,normal,1,0,1,0,0,0
296 000000002c758000,481,normal,1,0,1,0,0,0
297 000000002c780000,481,normal,1,0,1,0,0,0
298 000000002c784000,481,normal,1,0,1,0,0,0
299 000000002c78c000,481,normal,1,0,1,0,0,0
300 000000002c790000,481,normal,1,0,1,0,0,0
301 000000002c758000,481,normal,1,0,1,0,0,0
302 000000002c780000,481,normal,1,0,1,0,0,0
303 000000002c788000,481,normal,1,0,1,0,0,0
304 000000002c790000,481,normal,1,0,1,0,0,0
305 000000002c758000,481,normal,1,0,1,0,0,0
306 000000002c780000,481,normal,1,0,1,0,0,0
307 000000002c788000,481,normal,1,0,1,0,0,0
308 000000002c790000,481,normal,1,0,1,0,0,0
309 000000002c758000,481,normal,1,0,1,0,0,0
310 000000002c780000,481,normal,1,0,1,0,0,0
311 000000002c788000,481,normal,1,0,1,0,0,0
312 000000002c790000,481,normal,1,0,1,0,0,0
313 000000002c758000,481,normal,1,0,1,0,0,0
314 000000002c780000,481,normal,1,0,1,0,0,0
315 000000002c788000,481,normal,1,0,1,0,0,0
316 000000002c790000,481,normal,1,0,1,0,0,0
317 000000002c758000,481,normal,1,0,1,0,0,0
318 000000002c780000,481,normal,1,0,1,0,0,0
319 000000002c788000,481,normal,1,0,1,0,0,0
320 000000002c790000,481,normal,1,0,1,0,0,0
321 000000002c758000,481,normal,1,0,1,0,0,0
322 000000002c780000,481,normal,1,0,1,0,0,0
323 000000002c788000,481,normal,1,0,1,0,0,0
324 000000002c790000,481,normal,1,0,1,0,0,0
325 000000002c758000,481,normal,1,0,1,0,0,0
326 000000002c780000,481,normal,1,0,1,0,0,0
327 000000002c788000,481,normal,1,0,1,0,0,0
328 000000002c790000,481,normal,1,0,1,0,0,0
329 000000002c758000,481,normal,1,0,1,0,0,0
330 000000002c780000,481,normal,1,0,1,0,0,0
331 000000002c78c000,481,normal,1,0,1,0,0,0
332 000000002c784000,481,normal,1,0,1,0,0,0
333 000000002c788000,481,normal,1,0,1,0,0,0
334 000000002c78c000,481,normal,1,0,1,0,0,0
335 000000002c754000,481,normal,1,0,1,0,0,0
336 000000002c758000,481,normal,1,0,1,0,0,0
337 000000002c780000,481,normal,1,0,1,0,0,0
338 000000002c788000,481,normal,1,0,1,0,0,0
339 000000002c790000,481,normal,1,0,1,0,0,0
340 000000002c758000,481,normal,1,0,1,0,0,0
341 000000002c780000,481,normal,1,0,1,0,0,0
342 000000002c758000,481,normal,1,0,1,0,0,0
343 000000002c780000,481,normal,1,0,1,0,0,0
344 000000002c78c000,481,normal,1,0,1,0,0,0
345 000000002c75c000,481,normal,1,0,1,0,0,0
346 000000002c78c000,481,normal,1,0,1,0,0,0
347 000000002c780000,481,normal,1,0,1,0,0,0
348 000000002c754000,481,normal,1,0,1,0,0,0
349 000000002c788000,481,normal,1,0,1,0,0,0
350 000000002c754000,481,normal,1,0,1,0,0,0
351 000000002c780000,481,normal,1,0,1,0,0,0
352 000000002c788000,481,normal,1,0,1,0,0,0
353 000000002c78c000,481,normal,1,0,1,0,0,0
354 000000002c790000,481,normal,1,0,1,0,0,0
355 000000002c754000,481,normal,1,0,1,0,0,0
356 000000002c758000,481,normal,1,0,1,0,0,0
357 000000002c75c000,481,normal,1,0,1,0,0,0
358 000000002c780000,481,normal,1,0,1,0,0,0
359 000000002c784000,481,normal,1,0,1,0,0,0
360 000000002c788000,481,normal,1,0,1,0,0,0
361 000000002c78c000,481,normal,1,0,1,0,0,0
362 000000002c790000,481,normal,1,0,1,0,0,0
363 000000002c754000,481,normal,1,0,1,0,0,0
364 000000002c758000,481,normal,1,0,1,0,0,0
365 000000002c75c000,512,normal,1,0,1,0,0,1 D
366 0000000000000000,0,UNKNOWN,0,0,0,0,0,0 E
367 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
368 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
369 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
370 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
371 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
372 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
373 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
374 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
375 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
376 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
377 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
378 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
379 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
380 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
381 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
382 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
383 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
384 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
385 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
386 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
387 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
388 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
389 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
390 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
391 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
392 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
393 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
394 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
395 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
396 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
397 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
398 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
399 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
400 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
401 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
402 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
403 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
404 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
405 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
406 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
407 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
408 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
409 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
410 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
411 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
412 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
413 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
414 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
415 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
416 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
417 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
418 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
419 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
420 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
421 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
422 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
423 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
424 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
425 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
426 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
427 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
428 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
429 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
430 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
431 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
432 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
433 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
434 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
435 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
436 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
437 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
438 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
439 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
440 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
441 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
442 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
443 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
444 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
445 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
446 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
447 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
448 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
449 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
450 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
451 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
452 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
453 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
454 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
455 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
456 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
457 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
458 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
459 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
460 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
461 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
462 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
463 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
464 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
465 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
466 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
467 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
468 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
469 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
470 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
471 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
472 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
473 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
474 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
475 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
476 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
477 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
478 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
479 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
480 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
481 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
482 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
483 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
484 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
485 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
486 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
487 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
488 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
489 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
490 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
491 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
492 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
493 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
494 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
495 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
496 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
497 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
498 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
499 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
500 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
501 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
502 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
503 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
504 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
505 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
506 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
507 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
508 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
509 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
510 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
511 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
512 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
513 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
514 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
515 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
516 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
517 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
518 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
519 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
520 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
521 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
522 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
523 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
524 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
525 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
526 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
527 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
528 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
529 0000000000000000,0,UNKNOWN,0,0,0,0,0,0
530 00000000381ab000,0,link,0,0,0,0,0,1
531
532
533 Trace Events
534 -------------
535
536 DWC3 also provides several trace events which help us gathering
537 information about the behavior of the driver during runtime.
538
539 In order to use these events, you must enable ``CONFIG_FTRACE`` in
540 your kernel config.
541
542 For details about how enable DWC3 events, see section **Reporting
543 Bugs**.
544
545 The following subsections will give details about each Event Class and
546 each Event defined by DWC3.
547
548 MMIO
549 ```````
550
551 It is sometimes useful to look at every MMIO access when looking for
552 bugs. Because of that, DWC3 offers two Trace Events (one for
553 dwc3_readl() and one for dwc3_writel()). ``TP_printk`` follows::
554
555 TP_printk("addr %p value %08x", __entry->base + __entry->offset,
556 __entry->value)
557
558 Interrupt Events
559 ````````````````
560
561 Every IRQ event can be logged and decoded into a human readable
562 string. Because every event will be different, we don't give an
563 example other than the ``TP_printk`` format used::
564
565 TP_printk("event (%08x): %s", __entry->event,
566 dwc3_decode_event(__entry->event, __entry->ep0state))
567
568 Control Request
569 `````````````````
570
571 Every USB Control Request can be logged to the trace buffer. The
572 output format is::
573
574 TP_printk("%s", dwc3_decode_ctrl(__entry->bRequestType,
575 __entry->bRequest, __entry->wValue,
576 __entry->wIndex, __entry->wLength)
577 )
578
579 Note that Standard Control Requests will be decoded into
580 human-readable strings with their respective arguments. Class and
581 Vendor requests will be printed out a sequence of 8 bytes in hex
582 format.
583
584 Lifetime of a ``struct usb_request``
585 ```````````````````````````````````````
586
587 The entire lifetime of a ``struct usb_request`` can be tracked on the
588 trace buffer. We have one event for each of allocation, free,
589 queueing, dequeueing, and giveback. Output format is::
590
591 TP_printk("%s: req %p length %u/%u %s%s%s ==> %d",
592 __get_str(name), __entry->req, __entry->actual, __entry->length,
593 __entry->zero ? "Z" : "z",
594 __entry->short_not_ok ? "S" : "s",
595 __entry->no_interrupt ? "i" : "I",
596 __entry->status
597 )
598
599 Generic Commands
600 ````````````````````
601
602 We can log and decode every Generic Command with its completion
603 code. Format is::
604
605 TP_printk("cmd '%s' [%x] param %08x --> status: %s",
606 dwc3_gadget_generic_cmd_string(__entry->cmd),
607 __entry->cmd, __entry->param,
608 dwc3_gadget_generic_cmd_status_string(__entry->status)
609 )
610
611 Endpoint Commands
612 ````````````````````
613
614 Endpoints commands can also be logged together with completion
615 code. Format is::
616
617 TP_printk("%s: cmd '%s' [%d] params %08x %08x %08x --> status: %s",
618 __get_str(name), dwc3_gadget_ep_cmd_string(__entry->cmd),
619 __entry->cmd, __entry->param0,
620 __entry->param1, __entry->param2,
621 dwc3_ep_cmd_status_string(__entry->cmd_status)
622 )
623
624 Lifetime of a ``TRB``
625 ``````````````````````
626
627 A ``TRB`` Lifetime is simple. We are either preparing a ``TRB`` or
628 completing it. With these two events, we can see how a ``TRB`` changes
629 over time. Format is::
630
631 TP_printk("%s: %d/%d trb %p buf %08x%08x size %s%d ctrl %08x (%c%c%c%c:%c%c:%s)",
632 __get_str(name), __entry->queued, __entry->allocated,
633 __entry->trb, __entry->bph, __entry->bpl,
634 ({char *s;
635 int pcm = ((__entry->size >> 24) & 3) + 1;
636 switch (__entry->type) {
637 case USB_ENDPOINT_XFER_INT:
638 case USB_ENDPOINT_XFER_ISOC:
639 switch (pcm) {
640 case 1:
641 s = "1x ";
642 break;
643 case 2:
644 s = "2x ";
645 break;
646 case 3:
647 s = "3x ";
648 break;
649 }
650 default:
651 s = "";
652 } s; }),
653 DWC3_TRB_SIZE_LENGTH(__entry->size), __entry->ctrl,
654 __entry->ctrl & DWC3_TRB_CTRL_HWO ? 'H' : 'h',
655 __entry->ctrl & DWC3_TRB_CTRL_LST ? 'L' : 'l',
656 __entry->ctrl & DWC3_TRB_CTRL_CHN ? 'C' : 'c',
657 __entry->ctrl & DWC3_TRB_CTRL_CSP ? 'S' : 's',
658 __entry->ctrl & DWC3_TRB_CTRL_ISP_IMI ? 'S' : 's',
659 __entry->ctrl & DWC3_TRB_CTRL_IOC ? 'C' : 'c',
660 dwc3_trb_type_string(DWC3_TRBCTL_TYPE(__entry->ctrl))
661 )
662
663 Lifetime of an Endpoint
664 ```````````````````````
665
666 And endpoint's lifetime is summarized with enable and disable
667 operations, both of which can be traced. Format is::
668
669 TP_printk("%s: mps %d/%d streams %d burst %d ring %d/%d flags %c:%c%c%c%c%c:%c:%c",
670 __get_str(name), __entry->maxpacket,
671 __entry->maxpacket_limit, __entry->max_streams,
672 __entry->maxburst, __entry->trb_enqueue,
673 __entry->trb_dequeue,
674 __entry->flags & DWC3_EP_ENABLED ? 'E' : 'e',
675 __entry->flags & DWC3_EP_STALL ? 'S' : 's',
676 __entry->flags & DWC3_EP_WEDGE ? 'W' : 'w',
677 __entry->flags & DWC3_EP_TRANSFER_STARTED ? 'B' : 'b',
678 __entry->flags & DWC3_EP_PENDING_REQUEST ? 'P' : 'p',
679 __entry->flags & DWC3_EP_END_TRANSFER_PENDING ? 'E' : 'e',
680 __entry->direction ? '<' : '>'
681 )
682
683
684 Structures, Methods and Definitions
685 ====================================
686
687 .. kernel-doc:: drivers/usb/dwc3/core.h
688 :doc: main data structures
689 :internal:
690
691 .. kernel-doc:: drivers/usb/dwc3/gadget.h
692 :doc: gadget-only helpers
693 :internal:
694
695 .. kernel-doc:: drivers/usb/dwc3/gadget.c
696 :doc: gadget-side implementation
697 :internal:
698
699 .. kernel-doc:: drivers/usb/dwc3/core.c
700 :doc: core driver (probe, PM, etc)
701 :internal:
702
703 .. [#trb] Transfer Request Block
704 .. [#link_trb] Transfer Request Block pointing to another Transfer
705 Request Block.
706 .. [#debugfs] The Debug File System
707 .. [#configfs] The Config File System
708 .. [#cbw] Command Block Wrapper
709 .. _Linus' tree: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/
711 .. _linux-usb: [email protected]
712

3. 한국어 전문 번역

영어 원문의 문단 순서와 의미를 유지한 전체 번역입니다. 코드, 함수명, symbol과 URL은 원문 표기를 유지합니다.

DWC3 소개, 기능, 드라이버 설계

1-74

*Synopsys DesignWare Core SuperSpeed USB 3.0 Controller*(이하 *DWC3*)는 USB SuperSpeed 규격을 따르는 컨트롤러이며 peripheral 전용, host 전용, dual-role, hub의 네 가지 형태로 구성할 수 있습니다.

Linux는 이 컨트롤러의 여러 버전을 지원합니다. 작성 당시 검증된 범위는 2.02a부터 3.10a까지이며, 일반적으로 2.02a보다 새 버전은 안정적으로 동작할 것으로 기대됩니다. 알려진 사용자는 Cavium, Intel Corporation, Qualcomm, Rockchip, ST, Samsung, Texas Instruments, Xilinx입니다.

개별 DWC3 버전이 제공하는 기능은 IP 팀 또는 *Synopsys DesignWare Core SuperSpeed USB 3.0 Controller Databook*에서 확인해야 합니다. 드라이버는 제어 파이프 `ep0`을 포함한 최대 16개 양방향 endpoint, 유연한 endpoint 구성, 동시 IN/OUT 전송, scatter-list, endpoint당 최대 256개 TRB, 모든 전송 유형, SuperSpeed Bulk Streams, Link Power Management, Trace Events, DebugFS를 지원합니다.

이 기능들은 여러 in-tree gadget driver에서 검증되었으며 *ConfigFS*와 기존 gadget driver 모두 시험되었습니다.

DWC3 드라이버 관련 파일은 모두 `drivers/usb/dwc3/`에 모여 있습니다. 구성 유연성 때문에 일부는 복잡하지만 전체 흐름은 비교적 직접적이며, 가장 큰 부분은 Gadget API 구현입니다.

DWC3 구성과 핵심 기능
영역지원 내용
구성 모드Peripheral-only, Host-only, Dual-Role, Hub
endpoint제어 파이프를 포함해 최대 16개 양방향 endpoint
전송Control, Bulk, Interrupt, Isochronous, 동시 IN/OUT, scatter-list
고급 기능최대 256 TRB, Bulk Streams, LPM, Trace Events, DebugFS
소스 위치`drivers/usb/dwc3/`

===============================================================
Synopsys DesignWare Core SuperSpeed USB 3.0 Controller
===============================================================

:Author: Felipe Balbi <[email protected]>
: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.

알려진 제한 사항

75-112

DWC3에도 하드웨어 고유의 제한이 있으며, 반복되는 문제를 한곳에서 설명하기 위해 이 절에 정리합니다.

Synopsys Databook에 따르면 모든 OUT 전송 TRB의 `size` 필드는 endpoint의 `wMaxPacketSize`로 나누어떨어져야 합니다. 예를 들어 Mass Storage `CBW`를 받으려면 `req->length`를 `wMaxPacketSize`의 배수로 설정하거나, 남는 길이를 버릴 buffer를 가리키는 chained TRB를 DWC3 드라이버가 추가해야 합니다. 그렇지 않으면 OUT 전송은 시작되지 않습니다.

현재 드라이버는 남은 길이에 대한 chained TRB를 자동으로 붙여 이 세부 사항을 gadget driver에서 숨길 수 있습니다. 다만 DWC3에서 전송이 동작하지 않는다는 문의의 가장 흔한 원인이므로 이 제약을 알아둘 필요가 있습니다.

endpoint마다 TRB는 256개로 제한되며 마지막 항목은 첫 항목을 가리키는 Link TRB입니다. 이 값은 임의로 정한 제한이지만 전체가 정확히 4096바이트, 즉 한 페이지가 되는 장점이 있습니다.

드라이버는 255개를 넘는 request도 가능한 한 처리하며 대개 정상 동작합니다. 그러나 충분히 자주 검증된 경로는 아니므로 문제가 생기면 아래의 **Reporting Bugs** 절을 따라야 합니다.

OUT 전송 길이 처리
`req->length` 확인`wMaxPacketSize`의 정수 배수인지 검사
나머지 존재버릴 buffer를 가리키는 chained TRB 추가
TRB ring마지막 Link TRB를 포함해 endpoint당 256개
문제 발생**Reporting Bugs** 절의 자료 수집 절차 수행

OUT TRB 크기가 packet 경계에 맞지 않을 때 드라이버가 보완하는 흐름입니다.

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.

버그 보고에 필요한 정보

113-168

DWC3 문제를 보고하기 전에 `Linus' tree`의 최신 tag를 사용 중인지, DWC3에 대한 out-of-tree 변경 없이 재현되는지, host machine의 결함이 아닌지 먼저 확인합니다.

DWC3 디버깅은 Trace Events에 전적으로 의존하며 일부 추가 정보는 DebugFS에 노출됩니다. USB cable을 host에 연결하기 전에 debugfs와 tracefs를 mount하고 trace buffer를 81920 KiB로 설정한 뒤 DWC3 event를 활성화합니다.

문제를 재현한 직후 `/t/trace`를 `/root/trace.txt`로 복사하고 각 DWC3 DebugFS 디렉터리의 `regdump`를 `/root/regdump.txt`에 모읍니다. 두 파일을 tarball로 압축하여 저자에게 보내고 `linux-usb`를 Cc에 넣습니다.

메일 제목은 **[BUG REPORT] usb: dwc3: Bug while doing XYZ** 형식을 사용합니다. 본문에는 수행한 작업, 사용한 gadget driver, 재현 절차, SoC, host에서 실행한 OS와 버전을 자세히 적어야 합니다.

DWC3 버그 보고 체크리스트
단계필수 내용
사전 확인최신 Linus tree, out-of-tree 변경 제거, host 결함 배제
trace 준비debugfs·tracefs mount, `buffer_size_kb=81920`, `events/dwc3/enable=1`
재현 직후`trace.txt`와 `regdump.txt` 확보
메일지정 제목, gadget driver·재현 절차·SoC·host OS 기재, `linux-usb` Cc

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.

디버깅과 DebugFS 최상위 파일

169-236

DebugFS와 TraceFS에 보이는 정보는 Linux kernel의 major release에서 언제든 바뀔 수 있습니다. 스크립트를 작성할 때 현재 형식이 유지된다고 가정해서는 안 됩니다.

DWC3 문제 분석에는 Trace Events가 특히 유용하고 Synopsys Databook 접근 권한도 큰 도움이 됩니다. USB sniffer가 유용할 때도 있지만 필수는 아니며 wire를 직접 보지 않고도 많은 상태를 이해할 수 있습니다.

DWC3의 DebugFS 디렉터리에는 endpoint별 `ep[0..15]{in,out}/` 디렉터리와 `link_state`, `regdump`, `testmode` 파일이 있습니다.

`link_state`를 읽으면 `U0`, `U1`, `U2`, `U3`, `SS.Disabled`, `RX.Detect`, `SS.Inactive`, `Polling`, `Recovery`, `Hot Reset`, `Compliance`, `Loopback`, `Reset`, `Resume` 또는 `UNKNOWN link state`가 출력됩니다. 같은 상태 이름을 써서 link를 해당 상태로 강제할 수도 있습니다.

`regdump`는 DWC3 register dump를 출력하며 필요한 정보를 grep으로 찾을 수 있습니다. `testmode`는 현재 USB 2.0 test mode 이름 또는 `no test`를 출력합니다. `test_j`, `test_k`, `test_se0_nak`, `test_packet`, `test_force_enable` 중 하나를 파일에 쓰면 해당 test mode를 시작합니다.

DWC3 DebugFS 최상위 항목
항목읽기·쓰기 동작
`link_state`현재 SuperSpeed link state 조회, 상태 이름을 써서 강제 전환
`regdump`DWC3 register 전체 dump 출력
`testmode`USB 2.0 test mode 조회 및 시작
`ep[0..15]{in,out}/`endpoint별 queue, transfer type, TRB ring 상태

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.

Endpoint별 DebugFS 정보

237-266

각 endpoint에는 `ep$num$dir` 규칙을 따르는 디렉터리가 하나씩 노출됩니다. 예는 `ep0in`, `ep0out`, `ep1in`이며, 내부에는 `descriptor_fetch_queue`, `event_queue`, `rx_fifo_queue`, `rx_info_queue`, `rx_request_queue`, `transfer_type`, `trb_ring`, `tx_fifo_queue`, `tx_request_queue`가 있습니다.

이 queue 파일들의 정보는 Synopsys Databook을 함께 보면 decode할 수 있습니다.

`transfer_type`은 endpoint descriptor에 따라 `control`, `bulk`, `interrupt`, `isochronous` 중 하나를 출력합니다. endpoint가 아직 enable되지 않았다면 `--`를 출력합니다.

Endpoint DebugFS 디렉터리
분류파일
수신 queue`rx_fifo_queue`, `rx_info_queue`, `rx_request_queue`
송신 queue`tx_fifo_queue`, `tx_request_queue`
이벤트·descriptor`event_queue`, `descriptor_fetch_queue`
전송 상태`transfer_type`, `trb_ring`

``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``
~~~~~~~~~~~~~

TRB ring 덤프 해석

267-532

`trb_ring`을 읽으면 ring에 있는 모든 TRB의 세부 정보와 enqueue·dequeue pointer의 위치가 출력됩니다.

출력 열은 `buffer_addr`, `size`, `type`, `ioc`, `isp_imi`, `csp`, `chn`, `lst`, `hwo` 순서입니다. 예시의 `D`와 `E` 표시는 각각 dequeue와 enqueue 위치를 나타내며, 마지막 `link` TRB는 ring의 시작으로 연결합니다.

`trb_ring` 주요 열
의미
`buffer_addr`, `size`전송 buffer 주소와 길이
`type`normal, link 등 TRB 유형
`ioc`, `isp_imi`, `csp`완료 interrupt·short packet 관련 제어 bit
`chn`, `lst`, `hwo`chain·last·hardware ownership bit
`D`, `E`dequeue와 enqueue pointer 위치


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, MMIO, IRQ, Control Request

533-583

DWC3는 runtime 중 드라이버 동작을 수집할 수 있도록 여러 trace event를 제공합니다. 사용하려면 kernel configuration에서 `CONFIG_FTRACE`를 enable해야 하며, event 활성화 방법은 **Reporting Bugs** 절을 따릅니다.

MMIO 문제를 조사할 때 모든 접근을 보는 것이 유용할 수 있습니다. DWC3는 `dwc3_readl()`과 `dwc3_writel()` 각각에 대한 trace event를 제공하며 주소와 32비트 값을 기록합니다.

모든 IRQ event는 기록된 뒤 사람이 읽을 수 있는 문자열로 decode할 수 있습니다. event 값과 `ep0state`를 `dwc3_decode_event()`에 넘기는 `TP_printk` 형식을 사용합니다.

모든 USB Control Request도 trace buffer에 기록할 수 있습니다. Standard Control Request는 각 argument와 함께 읽기 쉬운 문자열로 decode되고, Class 및 Vendor request는 8바이트의 16진수열로 출력됩니다.

DWC3 trace event 분류
`CONFIG_FTRACE`kernel trace 기능 활성화
MMIO`dwc3_readl()`·`dwc3_writel()` 주소와 값
Interruptevent와 `ep0state`를 문자열로 decode
Control Request표준 요청은 의미 해석, class·vendor 요청은 8바이트 hex

runtime 문제를 관찰하는 기본 trace 경로입니다.

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.

Request, command, TRB, endpoint 수명주기 이벤트

584-683

`struct usb_request`의 전체 수명주기를 trace buffer에서 추적할 수 있습니다. allocation, free, queueing, dequeueing, giveback마다 event가 있으며 request pointer, 실제·요청 길이, zero·short_not_ok·no_interrupt flag와 status를 출력합니다.

모든 Generic Command는 completion code와 함께 기록하고 decode할 수 있습니다. command 문자열, command 값, parameter, status 문자열이 출력됩니다.

Endpoint command도 completion code와 함께 기록합니다. endpoint 이름, command 문자열과 값, 세 parameter, command status를 출력합니다.

TRB 수명주기는 준비와 완료의 두 event로 표현됩니다. 이를 통해 queue·allocation 수, TRB와 buffer 주소, size, control flag, TRB type이 시간에 따라 어떻게 바뀌는지 볼 수 있습니다. Interrupt와 Isochronous endpoint에서는 PCM 값에 따라 `1x`, `2x`, `3x`도 표시됩니다.

Endpoint 수명주기는 enable과 disable operation으로 요약됩니다. trace에는 max packet 값과 제한, stream 수, burst, TRB enqueue·dequeue 위치, enabled·stall·wedge·transfer started·pending request·end transfer pending flag 및 방향이 기록됩니다.

DWC3 수명주기 trace
대상관찰 event와 핵심 필드
`struct usb_request`alloc/free/queue/dequeue/giveback, 길이·flag·status
Generic Commandcommand·parameter·completion status
Endpoint Commandendpoint·세 parameter·command status
TRBprepare/complete, buffer·size·control·type
Endpointenable/disable, packet·stream·ring 위치·상태 flag

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 ? '<' : '>'
  )

구조체, 메서드, 정의와 참고 링크

684-711

구조체와 내부 구현 문서는 kernel-doc 지시문으로 소스에서 직접 가져옵니다. `drivers/usb/dwc3/core.h`는 main data structures, `drivers/usb/dwc3/gadget.h`는 gadget-only helpers를 설명합니다.

`drivers/usb/dwc3/gadget.c`에서는 gadget-side implementation을, `drivers/usb/dwc3/core.c`에서는 probe와 power management 등을 포함한 core driver를 문서화합니다. 네 지시문 모두 `:internal:` 항목을 포함합니다.

각주에서 TRB는 Transfer Request Block, Link TRB는 다른 Transfer Request Block을 가리키는 TRB, DebugFS는 Debug File System, ConfigFS는 Config File System, CBW는 Command Block Wrapper로 정의됩니다.

참조 링크는 `Linus' tree`의 kernel.org Git 저장소, 저자 Felipe Balbi의 이메일, `[email protected]` mailing list를 가리킵니다.

DWC3 kernel-doc 원천
소스 경로문서 범위
`drivers/usb/dwc3/core.h`main data structures
`drivers/usb/dwc3/gadget.h`gadget-only helpers
`drivers/usb/dwc3/gadget.c`gadget-side implementation
`drivers/usb/dwc3/core.c`core driver, probe, PM 등

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: [email protected]
.. _linux-usb: [email protected]