Synopsys DesignWare Core SuperSpeed USB 3.0 控制器¶
- 作者:
Felipe Balbi <felipe.balbi@linux.intel.com>
- 日期:
2017 年 4 月
簡介¶
_Synopsys DesignWare Core SuperSpeed USB 3.0 控制器_(以下簡稱 _DWC3_)是一款符合 USB SuperSpeed 標準的控制器,可以配置為以下 4 種方式之一
僅限外設配置
僅限主機配置
雙重角色配置
集線器配置
Linux 目前支援此控制器的多個版本。 在所有可能性中,您的 SoC 中的版本已被支援。 在撰寫本文時,已知的經過測試的版本範圍從 2.02a 到 3.10a。 根據經驗,高於 2.02a 的任何版本都應能可靠地工作。
目前,我們有很多已知的此驅動程式的使用者。 按字母順序排列
Cavium
英特爾公司
高通
瑞芯微
ST
三星
德州儀器
賽靈思
功能概述¶
有關 DWC3 版本的支援的功能的詳細資訊,請諮詢您的 IP 團隊和/或 _Synopsys DesignWare Core SuperSpeed USB 3.0 控制器資料手冊_。 以下是撰寫本文時驅動程式支援的功能列表
這些功能已透過許多樹內小工具驅動程式進行了測試。 我們已經驗證了 ConfigFS [4] 和舊版小工具驅動程式。
驅動程式設計¶
DWC3 驅動程式位於 _drivers/usb/dwc3/_ 目錄中。 與此驅動程式相關的所有檔案都在這一個目錄中。 這使得新手可以輕鬆閱讀程式碼並瞭解其行為方式。
由於 DWC3 的配置靈活性,驅動程式在某些地方有點複雜,但應該很容易理解。
驅動程式的最大部分是指小工具 API。
已知限制¶
與其他任何硬體一樣,DWC3 也有其自身的侷限性。 為了避免不斷地詢問此類問題,我們決定在此處記錄它們,並擁有一個可以指向使用者的單一位置。
OUT 傳輸大小要求¶
根據 Synopsys 資料手冊,所有 OUT 傳輸 TRB [1] 必須將其 _size_ 欄位設定為整數,該整數可被端點的 _wMaxPacketSize_ 整除。 這意味著,_例如_,為了接收大容量儲存 _CBW_ [5],req->length 必須設定為可被 _wMaxPacketSize_ 整除的值(在 SuperSpeed 上為 1024,在 HighSpeed 上為 512,等等),或者 DWC3 驅動程式必須新增一個連結的 TRB,指向剩餘長度的拋棄型緩衝區。 沒有這個,OUT 傳輸將不會啟動。
請注意,截至撰寫本文時,這不會成為問題,因為 DWC3 完全能夠為剩餘長度附加一個連結的 TRB,並從小工具驅動程式中完全隱藏此細節。 仍然值得一提,因為這似乎是關於 DWC3 和 _無法正常傳輸_ 的查詢的最大來源。
TRB 環大小限制¶
我們目前對每個端點有 256 個 TRB [1] 的硬性限制,最後一個 TRB 是一個連結 TRB [2],指回第一個。 此限制是任意的,但它的好處是總計正好 4096 位元組,或 1 頁。
DWC3 驅動程式將盡最大努力處理超過 255 個請求,並且在大多數情況下,它應該正常工作。 但是,這並不是經常進行的。 如果您遇到任何問題,請參閱下面的報告錯誤部分。
報告錯誤¶
每當您遇到 DWC3 問題時,首先也是最重要的,您應該確保
您正在執行來自 Linus’ tree 的最新標籤
您可以在沒有任何對 DWC3 的樹外更改的情況下重現該錯誤
您已檢查過它不是主機上的故障
在驗證所有這些之後,以下是如何捕獲足夠的資訊以便我們為您提供任何幫助。
所需資訊¶
DWC3 專門依賴於跟蹤事件進行除錯。 一切都暴露在那裡,一些額外的位暴露給 DebugFS [3]。
為了捕獲 DWC3 的跟蹤事件,您應該在將 USB 電纜插入主機之前執行以下命令
# 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
完成此操作後,您可以連線 USB 電纜並重現該問題。 重現故障後,請複製檔案 trace 和 regdump,如下所示
# cp /t/trace /root/trace.txt
# cat /d/*dwc3*/regdump > /root/regdump.txt
確保將 trace.txt 和 regdump.txt 壓縮到 tarball 中,並透過電子郵件傳送給 我,並在抄送中包含 linux-usb。 如果您想格外確保我會幫助您,請按以下格式編寫您的主題行
[BUG REPORT] usb: dwc3: Bug while doing XYZ
在電子郵件正文中,請務必詳細說明您正在做什麼,您正在使用哪個小工具驅動程式,如何重現該問題,您正在使用哪個 SoC,哪個作業系統(及其版本)正在主機上執行。
有了所有這些資訊,我們應該能夠了解發生了什麼併為您提供幫助。
除錯¶
首先也是最重要的免責宣告
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.
消除了這一點,讓我們繼續。
如果您願意除錯自己的問題,您應該得到熱烈的掌聲 :-)
無論如何,除了跟蹤事件對於找出 DWC3 的問題非常有幫助之外,這裡沒有什麼可說的。 此外,在這種情況下,訪問 Synopsys 資料手冊將非常有價值。
USB Sniffer 有時會有所幫助,但並非完全必需,無需檢視電線即可理解很多內容。
如果您需要任何幫助,請隨時透過電子郵件傳送給 我,並在抄送中包含 linux-usb。
DebugFS¶
DebugFS 非常適合收集有關 DWC3 和/或任何端點正在發生的事情的快照。
在 DWC3 的 DebugFS 目錄中,您將找到以下檔案和目錄
ep[0..15]{in,out}/ link_state regdump testmode
link_state¶
讀取時,link_state 將打印出 U0、U1、U2、U3、SS.Disabled、RX.Detect、SS.Inactive、Polling、Recovery、Hot Reset、Compliance、Loopback、Reset、Resume 或 UNKNOWN link state 之一。
也可以寫入此檔案以強制連結到上面的狀態之一。
regdump¶
檔名是不言自明的。 讀取時,regdump 將打印出 DWC3 的暫存器轉儲。 請注意,可以 grep 此檔案以查詢您想要的資訊。
testmode¶
讀取時,testmode 將打印出指定的 USB 2.0 測試模式(test_j、test_k、test_se0_nak、test_packet、test_force_enable)之一的名稱,或者在當前未執行任何測試時列印字串 no test。
為了啟動這些測試模式中的任何一種,可以將相同的字串寫入檔案中,DWC3 將進入請求的測試模式。
ep[0..15]{in,out}¶
對於每個端點,我們都遵循命名約定 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
透過訪問 Synopsys 資料手冊,您可以解碼其中的資訊。
transfer_type¶
讀取時,transfer_type 將打印出 control、bulk、interrupt 或 isochronous 之一,具體取決於端點描述符的內容。 如果尚未啟用端點,它將列印 --。
trb_ring¶
讀取時,trb_ring 將打印出有關環上所有 TRB 的詳細資訊。 它還將告訴您我們的入隊和出隊指標位於環中的位置
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
跟蹤事件¶
DWC3 還提供了幾個跟蹤事件,這些事件可幫助我們收集有關驅動程式在執行時行為的資訊。
為了使用這些事件,您必須在核心配置中啟用 CONFIG_FTRACE。
有關如何啟用 DWC3 事件的詳細資訊,請參閱報告錯誤部分。
以下小節將詳細介紹每個事件類和 DWC3 定義的每個事件。
MMIO¶
在尋找錯誤時,檢視每個 MMIO 訪問有時很有用。 因此,DWC3 提供了兩個跟蹤事件(一個用於 dwc3_readl(),一個用於 dwc3_writel())。 TP_printk 如下
TP_printk("addr %p value %08x", __entry->base + __entry->offset,
__entry->value)
中斷事件¶
每個 IRQ 事件都可以記錄並解碼為人類可讀的字串。 因為每個事件都不同,所以我們沒有給出除使用的 TP_printk 格式之外的示例
TP_printk("event (%08x): %s", __entry->event,
dwc3_decode_event(__entry->event, __entry->ep0state))
控制請求¶
每個 USB 控制請求都可以記錄到跟蹤緩衝區中。 輸出格式為
TP_printk("%s", dwc3_decode_ctrl(__entry->bRequestType,
__entry->bRequest, __entry->wValue,
__entry->wIndex, __entry->wLength)
)
請注意,標準控制請求將被解碼為帶有其各自引數的人類可讀的字串。 類和供應商請求將以十六進位制格式打印出 8 個位元組的序列。
struct usb_request 的生命週期¶
可以在跟蹤緩衝區上跟蹤 struct usb_request 的整個生命週期。 我們為每個分配、釋放、排隊、出隊和歸還都準備了一個事件。 輸出格式為
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
)
通用命令¶
我們可以記錄和解碼每個帶有其完成程式碼的通用命令。 格式為
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)
)
端點命令¶
端點命令也可以與完成程式碼一起記錄。 格式為
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)
)
TRB 的生命週期¶
TRB 的生命週期很簡單。 我們要麼準備一個 TRB,要麼完成它。 透過這兩個事件,我們可以看到 TRB 如何隨時間變化。 格式為
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))
)
端點的生命週期¶
端點的生命週期概括為啟用和停用操作,兩者都可以跟蹤。 格式為
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 ? '<' : '>'
)
結構、方法和定義¶
-
struct dwc3_event_buffer¶
軟體事件緩衝區表示
定義:
struct dwc3_event_buffer {
void *buf;
void *cache;
unsigned int length;
unsigned int lpos;
unsigned int count;
unsigned int flags;
#define DWC3_EVENT_PENDING BIT(0);
dma_addr_t dma;
struct dwc3 *dwc;
};
成員
buf_THE_ 緩衝區
cache執行緒化中斷中使用的緩衝區快取
length此緩衝區的大小
lpos事件偏移量
count上次讀取事件計數暫存器的快取
flags與此事件緩衝區相關的標誌
dmadma_addr_t
dwc指向 DWC 控制器的指標
-
struct dwc3_ep¶
裝置側端點表示
定義:
struct dwc3_ep {
struct usb_ep endpoint;
struct delayed_work nostream_work;
struct list_head cancelled_list;
struct list_head pending_list;
struct list_head started_list;
void __iomem *regs;
struct dwc3_trb *trb_pool;
dma_addr_t trb_pool_dma;
struct dwc3 *dwc;
u32 saved_state;
unsigned int flags;
#define DWC3_EP_ENABLED BIT(0);
#define DWC3_EP_STALL BIT(1);
#define DWC3_EP_WEDGE BIT(2);
#define DWC3_EP_TRANSFER_STARTED BIT(3);
#define DWC3_EP_END_TRANSFER_PENDING BIT(4);
#define DWC3_EP_PENDING_REQUEST BIT(5);
#define DWC3_EP_DELAY_START BIT(6);
#define DWC3_EP_WAIT_TRANSFER_COMPLETE BIT(7);
#define DWC3_EP_IGNORE_NEXT_NOSTREAM BIT(8);
#define DWC3_EP_FORCE_RESTART_STREAM BIT(9);
#define DWC3_EP_STREAM_PRIMED BIT(10);
#define DWC3_EP_PENDING_CLEAR_STALL BIT(11);
#define DWC3_EP_TXFIFO_RESIZED BIT(12);
#define DWC3_EP_DELAY_STOP BIT(13);
#define DWC3_EP_RESOURCE_ALLOCATED BIT(14);
#define DWC3_EP0_DIR_IN BIT(31);
u8 trb_enqueue;
u8 trb_dequeue;
u8 number;
u8 type;
u8 resource_index;
u32 frame_number;
u32 interval;
char name[20];
unsigned direction:1;
unsigned stream_capable:1;
u8 combo_num;
int start_cmd_status;
};
成員
endpointusb 端點
nostream_work用於處理批次 NoStream 的工作
cancelled_list此端點已取消的請求的列表
pending_list此端點的掛起請求的列表
started_list此端點上已啟動的請求的列表
regs指向第一個端點暫存器的指標
trb_pool事務緩衝區陣列
trb_pool_dmatrb_pool 的 DMA 地址
dwc指向 DWC 控制器的指標
saved_state休眠期間儲存的 ep 狀態
flags端點標誌(楔入、停止...)
trb_enqueueTRB 陣列中的入隊“指標”
trb_dequeueTRB 陣列中的出隊“指標”
number端點號 (1 - 15)
type設定為 bmAttributes & USB_ENDPOINT_XFERTYPE_MASK
resource_index資源傳輸索引
frame_number設定為我們希望此傳輸開始的幀號 (ISOC)
interval啟動 ISOC 傳輸的間隔
name人類可讀的名稱,例如 ep1out-bulk
direction對於 TX 為真,對於 RX 為假
stream_capable啟用流時為真
combo_num幀號的測試組合 BIT[15:14],用於測試同步啟動傳輸命令故障解決方法
start_cmd_statuscombo_num = ‘b00 測試 START TRANSFER 命令的狀態
-
struct dwc3_trb¶
傳輸請求塊(硬體格式)
定義:
struct dwc3_trb {
u32 bpl;
u32 bph;
u32 size;
u32 ctrl;
};
成員
bplDW0-3
bphDW4-7
sizeDW8-B
ctrlDWC-F
-
struct dwc3_hwparams¶
HWPARAMS 暫存器的副本
定義:
struct dwc3_hwparams {
u32 hwparams0;
u32 hwparams1;
u32 hwparams2;
u32 hwparams3;
u32 hwparams4;
u32 hwparams5;
u32 hwparams6;
u32 hwparams7;
u32 hwparams8;
u32 hwparams9;
};
成員
hwparams0GHWPARAMS0
hwparams1GHWPARAMS1
hwparams2GHWPARAMS2
hwparams3GHWPARAMS3
hwparams4GHWPARAMS4
hwparams5GHWPARAMS5
hwparams6GHWPARAMS6
hwparams7GHWPARAMS7
hwparams8GHWPARAMS8
hwparams9GHWPARAMS9
-
struct dwc3_request¶
傳輸請求的表示
定義:
struct dwc3_request {
struct usb_request request;
struct list_head list;
struct dwc3_ep *dep;
struct scatterlist *start_sg;
unsigned int num_pending_sgs;
unsigned int remaining;
unsigned int status;
#define DWC3_REQUEST_STATUS_QUEUED 0;
#define DWC3_REQUEST_STATUS_STARTED 1;
#define DWC3_REQUEST_STATUS_DISCONNECTED 2;
#define DWC3_REQUEST_STATUS_DEQUEUED 3;
#define DWC3_REQUEST_STATUS_STALLED 4;
#define DWC3_REQUEST_STATUS_COMPLETED 5;
#define DWC3_REQUEST_STATUS_UNKNOWN -1;
u8 epnum;
struct dwc3_trb *trb;
dma_addr_t trb_dma;
unsigned int num_trbs;
unsigned int direction:1;
unsigned int mapped:1;
};
成員
request要傳輸的
struct usb_requestlist用於請求排隊的 list_head
dep擁有此請求的
struct dwc3_epstart_sg指向接下來應排隊的 sg 的指標
num_pending_sgs待處理 sg 的計數器
remaining剩餘資料量
status內部 dwc3 請求狀態跟蹤
epnum此請求引用的端點號
trb指向
struct dwc3_trb的指標trb_dmatrb 的 DMA 地址
num_trbs此請求使用的 TRB 數量
directionIN 或 OUT 方向標誌
mapped請求已被 dma 對映時為 true
-
struct dwc3¶
我們控制器的表示
定義:
struct dwc3 {
struct work_struct drd_work;
struct dwc3_trb *ep0_trb;
void *bounce;
u8 *setup_buf;
dma_addr_t ep0_trb_addr;
dma_addr_t bounce_addr;
struct dwc3_request ep0_usb_req;
struct completion ep0_in_setup;
spinlock_t lock;
struct mutex mutex;
struct device *dev;
struct device *sysdev;
struct platform_device *xhci;
struct resource xhci_resources[DWC3_XHCI_RESOURCES_NUM];
struct dwc3_event_buffer *ev_buf;
struct dwc3_ep *eps[DWC3_ENDPOINTS_NUM];
struct usb_gadget *gadget;
struct usb_gadget_driver *gadget_driver;
struct clk *bus_clk;
struct clk *ref_clk;
struct clk *susp_clk;
struct clk *utmi_clk;
struct clk *pipe_clk;
struct reset_control *reset;
struct usb_phy *usb2_phy;
struct usb_phy *usb3_phy;
struct phy *usb2_generic_phy[DWC3_USB2_MAX_PORTS];
struct phy *usb3_generic_phy[DWC3_USB3_MAX_PORTS];
u8 num_usb2_ports;
u8 num_usb3_ports;
bool phys_ready;
struct ulpi *ulpi;
bool ulpi_ready;
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;
struct usb_role_switch *role_sw;
enum usb_dr_mode role_switch_default_mode;
struct power_supply *usb_psy;
u32 fladj;
u32 ref_clk_per;
u32 irq_gadget;
u32 otg_irq;
u32 current_otg_role;
u32 desired_otg_role;
bool otg_restart_host;
u32 u1u2;
u32 maximum_speed;
u32 gadget_max_speed;
enum usb_ssp_rate max_ssp_rate;
enum usb_ssp_rate gadget_ssp_rate;
u32 ip;
#define DWC3_IP 0x5533;
#define DWC31_IP 0x3331;
#define DWC32_IP 0x3332;
u32 revision;
#define DWC3_REVISION_ANY 0x0;
#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_320A 0x5533320a;
#define DWC3_REVISION_330A 0x5533330a;
#define DWC31_REVISION_ANY 0x0;
#define DWC31_REVISION_110A 0x3131302a;
#define DWC31_REVISION_120A 0x3132302a;
#define DWC31_REVISION_160A 0x3136302a;
#define DWC31_REVISION_170A 0x3137302a;
#define DWC31_REVISION_180A 0x3138302a;
#define DWC31_REVISION_190A 0x3139302a;
#define DWC31_REVISION_200A 0x3230302a;
#define DWC32_REVISION_ANY 0x0;
#define DWC32_REVISION_100A 0x3130302a;
u32 version_type;
#define DWC31_VERSIONTYPE_ANY 0x0;
#define DWC31_VERSIONTYPE_EA01 0x65613031;
#define DWC31_VERSIONTYPE_EA02 0x65613032;
#define DWC31_VERSIONTYPE_EA03 0x65613033;
#define DWC31_VERSIONTYPE_EA04 0x65613034;
#define DWC31_VERSIONTYPE_EA05 0x65613035;
#define DWC31_VERSIONTYPE_EA06 0x65613036;
enum dwc3_ep0_next ep0_next_event;
enum dwc3_ep0_state ep0state;
enum dwc3_link_state link_state;
u16 u2sel;
u16 u2pel;
u8 u1sel;
u8 u1pel;
u8 speed;
u8 num_eps;
struct dwc3_hwparams hwparams;
struct debugfs_regset32 *regset;
u32 dbg_lsp_select;
u8 test_mode;
u8 test_mode_nr;
u8 lpm_nyet_threshold;
u8 hird_threshold;
u8 rx_thr_num_pkt;
u8 rx_max_burst;
u8 tx_thr_num_pkt;
u8 tx_max_burst;
u8 rx_thr_num_pkt_prd;
u8 rx_max_burst_prd;
u8 tx_thr_num_pkt_prd;
u8 tx_max_burst_prd;
u8 tx_fifo_resize_max_num;
u8 clear_stall_protocol;
u16 num_hc_interrupters;
const char *hsphy_interface;
unsigned connected:1;
unsigned softconnect:1;
unsigned delayed_status:1;
unsigned ep0_bounced:1;
unsigned ep0_expect_in: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 do_fifo_resize:1;
unsigned pullups_connected:1;
unsigned setup_packet_pending:1;
unsigned three_stage_setup:1;
unsigned dis_start_transfer_quirk:1;
unsigned usb3_lpm_capable:1;
unsigned usb2_lpm_disable:1;
unsigned usb2_gadget_lpm_disable: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_u1_entry_quirk:1;
unsigned dis_u2_entry_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 resume_hs_terminations:1;
unsigned ulpi_ext_vbus_drv:1;
unsigned parkmode_disable_ss_quirk:1;
unsigned parkmode_disable_hs_quirk:1;
unsigned gfladj_refclk_lpm_sel:1;
unsigned tx_de_emphasis_quirk:1;
unsigned tx_de_emphasis:2;
unsigned dis_metastability_quirk:1;
unsigned dis_split_quirk:1;
unsigned async_callbacks:1;
unsigned sys_wakeup:1;
unsigned wakeup_configured:1;
unsigned suspended:1;
unsigned susphy_state:1;
u16 imod_interval;
int max_cfg_eps;
int last_fifo_depth;
int num_ep_resized;
struct dentry *debug_root;
u32 gsbuscfg0_reqinfo;
u32 wakeup_pending_funcs;
};
成員
drd_work用於角色切換的工作佇列
ep0_trb用於 ctrl_req 的 trb
bouncebounce 緩衝區的地址
setup_buf在處理 STD USB 請求時使用
ep0_trb_addrep0_trb 的 dma 地址
bounce_addrbounce 的 dma 地址
ep0_usb_req處理 STD USB 請求時使用的虛擬請求
ep0_in_setup一個控制傳輸已完成並進入設定階段
lock用於同步
mutex用於模式切換
dev指向我們的
struct device的指標sysdev指向支援 DMA 的裝置的指標
xhci指向我們的 xHCI 子裝置的指標
xhci_resources我們的 xhci 子裝置的結構資源
ev_bufeps端點陣列
gadget外圍控制器的裝置端表示
gadget_driver指向 gadget 驅動程式的指標
bus_clk用於訪問暫存器的時鐘
ref_clk參考時鐘
susp_clk當 SS phy 處於低功耗 (S3) 狀態時使用的時鐘
utmi_clk用於 USB2 PHY 通訊的時鐘
pipe_clk用於 USB3 PHY 通訊的時鐘
reset重置控制
usb2_phy指向 USB2 PHY 的指標
usb3_phy指向 USB3 PHY 的指標
usb2_generic_phy指向 USB2 PHY 陣列的指標
usb3_generic_phy指向 USB3 PHY 陣列的指標
num_usb2_portsUSB2 埠的數量
num_usb3_portsUSB3 埠的數量
phys_ready指示 PHY 已準備就緒的標誌
ulpi指向 ulpi 介面的指標
ulpi_ready指示 ULPI 已初始化的標誌
regs我們暫存器的基本地址
regs_size地址空間大小
dr_mode請求的操作模式
current_dr_role處於雙角色模式時的當前操作角色
desired_dr_role處於雙角色模式時所需的操作角色
edevextcon 控制代碼
edev_nbextcon 通知器
hsphy_modeUTMI phy 模式,以下之一: - USBPHY_INTERFACE_MODE_UTMI - USBPHY_INTERFACE_MODE_UTMIW
role_swusb_role_switch 控制代碼
role_switch_default_mode當 usb 角色為 USB_ROLE_NONE 時,控制器的預設操作模式。
usb_psy指向電源介面的指標。
fladj幀長度調整
ref_clk_per參考時鐘週期配置
irq_gadget外圍控制器的 IRQ 號
otg_irqOTG IRQ 的 IRQ 號
current_otg_role使用 OTG 塊時的當前操作角色
desired_otg_role使用 OTG 塊時所需的操作角色
otg_restart_hostOTG 控制器需要重新啟動主機的標誌
u1u2僅用於修訂版 <1.83a 以進行解決方法
maximum_speed請求的最大速度(主要用於測試目的)
gadget_max_speed請求的最大 gadget 速度
max_ssp_rateSuperSpeed Plus 最大信令速率和通道數
gadget_ssp_rateGadget 驅動程式支援的最大 SuperSpeed Plus 信令速率和通道數。
ip控制器的 ID
revisionIP 控制器的版本
version_typeVERSIONTYPE 暫存器內容,修訂版的子版本
ep0_next_event儲存下一個預期事件
ep0state端點零的狀態
link_state鏈路狀態
u2sel來自 Set SEL 請求的引數。
u2pel來自 Set SEL 請求的引數。
u1sel來自 Set SEL 請求的引數。
u1pel來自 Set SEL 請求的引數。
speed裝置速度(super、high、full、low)
num_eps端點數
hwparamshwparams 暫存器的副本
regset指向 regdump 檔案的 debugfs 指標
dbg_lsp_select當前除錯 lsp 多路複用器暫存器選擇
test_mode當我們進入 USB 測試模式時為 true
test_mode_nr測試功能選擇器
lpm_nyet_thresholdLPM NYET 響應閾值
hird_thresholdHIRD 閾值
rx_thr_num_pktUSB 接收資料包計數
rx_max_burst最大 USB 接收突發大小
tx_thr_num_pktUSB 傳輸資料包計數
tx_max_burst最大 USB 傳輸突發大小
rx_thr_num_pkt_prd週期性 ESS 接收資料包計數
rx_max_burst_prd最大週期性 ESS 接收突發大小
tx_thr_num_pkt_prd週期性 ESS 傳輸資料包計數
tx_max_burst_prd最大週期性 ESS 傳輸突發大小
tx_fifo_resize_max_numtxfifo 大小調整期間分配的最大 fifo 數量
clear_stall_protocol需要延遲狀態階段的端點號
num_hc_interrupters主機控制器中斷器的數量
hsphy_interface“utmi” 或 “ulpi”
connected當我們連線到主機時為 true,否則為 false
softconnect呼叫 gadget connect 時為 true,執行 disconnect 時為 false
delayed_status當 gadget 驅動程式請求延遲狀態時為 true
ep0_bounced當我們使用 bounce 緩衝區時為 true
ep0_expect_in當我們期望 DATA IN 傳輸時為 true
sysdev_is_parent當 dwc3 裝置具有父驅動程式時為 true
has_lpm_erratum當核心配置了 LPM 勘誤時為 true。請注意,軟體現在無法在執行時檢測到這一點。
is_utmi_l1_suspend核心斷言輸出訊號 0 - utmi_sleep_n 1 - utmi_l1_suspend_n
is_fpga當我們使用 FPGA 板時為 true
pending_events當我們有待處理的 IRQ 要處理時為 true
do_fifo_resize當為 dwc3 端點啟用 txfifo 大小調整時為 true
pullups_connected設定 Run/Stop 位時為 true
setup_packet_pending當 FIFO 中存在 Setup 資料包時為 true。解決方法
three_stage_setup如果我們執行三階段設定,則設定
dis_start_transfer_quirk如果 DWC_usb31 版本 1.70a-ea06 及更低版本不需要 start_transfer 失敗 SW 解決方法,則設定
usb3_lpm_capable如果硬體支援鏈路電源管理,則設定
usb2_lpm_disable設定為停用主機的 usb2 lpm
usb2_gadget_lpm_disable設定為停用 gadget 的 usb2 lpm
disable_scramble_quirk如果啟用停用加擾怪癖,則設定
u2exit_lfps_quirk如果啟用 u2exit lfps 怪癖,則設定
u2ss_inp3_quirk如果啟用 P3 OK for U2/SS Inactive 怪癖,則設定
req_p1p2p3_quirk如果啟用請求 p1p2p3 怪癖,則設定
del_p1p2p3_quirk如果啟用延遲 p1p2p3 怪癖,則設定
del_phy_power_chg_quirk如果啟用延遲 phy 電源更改怪癖,則設定
lfps_filter_quirk如果啟用 LFPS 過濾器怪癖,則設定
rx_detect_poll_quirk如果啟用 rx_detect 以輪詢 lfps 怪癖,則設定
dis_u3_susphy_quirk如果停用 usb3 掛起 phy,則設定
dis_u2_susphy_quirk如果停用 usb2 掛起 phy,則設定
dis_enblslpm_quirk如果清除 GUSB2PHYCFG 中的 enblslpm,停用到 PHY 的掛起訊號,則設定。
dis_u1_entry_quirk如果需要停用鏈路進入 U1 狀態,則設定。
dis_u2_entry_quirk如果需要停用鏈路進入 U2 狀態,則設定。
dis_rxdet_inp3_quirk如果停用 P3 中的 Rx.Detect,則設定
dis_u2_freeclk_exists_quirk如果清除 GUSB2PHYCFG 中的 u2_freeclk_exists,指定 USB2 PHY 不提供自由執行的 PHY 時鐘,則設定。
dis_del_phy_power_chg_quirk如果停用延遲 phy 電源更改怪癖,則設定。
dis_tx_ipgap_linecheck_quirk如果停用 HS 傳輸期間的 u2mac 線路狀態檢查,則設定。
resume_hs_terminations如果啟用在從掛起恢復後修復不正確的 crc 生成的怪癖,則設定。
ulpi_ext_vbus_drv設定為配置 upli 晶片以使用外部電源驅動 CPEN 引腳 VBUS。
parkmode_disable_ss_quirk如果我們需要停用 park 模式下的所有 SuperSpeed 例項,則設定。
parkmode_disable_hs_quirk如果我們需要停用 park 模式下的所有 HishSpeed 例項,則設定。
gfladj_refclk_lpm_sel如果我們需要啟用基於 ref_clk 執行的 SOF/ITP 計數器,則設定
tx_de_emphasis_quirk如果啟用 Tx 去加重怪癖,則設定
tx_de_emphasisTx 去加重值 0 - -6dB 去加重 1 - -3.5dB 去加重 2 - 無去加重 3 - 保留
dis_metastability_quirk設定為停用亞穩態怪癖。
dis_split_quirk設定為停用拆分邊界。
async_callbacks如果設定,指示將使用非同步回撥。
sys_wakeup如果裝置可以執行系統喚醒,則設定。
wakeup_configured如果裝置配置為遠端喚醒,則設定。
suspended設定為跟蹤由於 U3/L2 導致的掛起事件。
susphy_statePM 掛起之前 DWC3_GUSB2PHYCFG_SUSPHY + DWC3_GUSB3PIPECTL_SUSPHY 的狀態。
imod_interval以 250ns 增量設定中斷調節間隔,或設定為 0 以停用。
max_cfg_eps所有 USB 配置中使用的當前最大 IN 端點數。
last_fifo_depth用於確定下一個 fifo ram 起始地址的最後一個 fifo 深度。
num_ep_resized攜帶當前已調整其 tx fifo 大小的端點數。
debug_root此裝置的根 debugfs 目錄,用於放置其檔案。
gsbuscfg0_reqinfo儲存從 glue 驅動程式傳遞的 GSBUSCFG0.DATRDREQINFO、DESRDREQINFO、DATWRREQINFO 和 DESWRREQINFO 值。
wakeup_pending_funcs指示是否任何介面已請求以點陣圖格式進行函式喚醒,其中位位置表示 interface_id。
-
struct dwc3_event_depevt¶
裝置端點事件
定義:
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_STATUS_MISSED_ISOC BIT(3) ;
#define DEPEVT_STREAMEVT_FOUND 1;
#define DEPEVT_STREAMEVT_NOTFOUND 2;
#define DEPEVT_STREAM_PRIME 0xfffe;
#define DEPEVT_STREAM_NOSTREAM 0x0;
#define DEPEVT_STATUS_CONTROL_DATA 1;
#define DEPEVT_STATUS_CONTROL_STATUS 2;
#define DEPEVT_STATUS_CONTROL_PHASE(n) ((n) & 3);
#define DEPEVT_TRANSFER_NO_RESOURCE 1;
#define DEPEVT_TRANSFER_BUS_EXPIRY 2;
u32 parameters:16;
#define DEPEVT_PARAMETER_CMD(n) (((n) & (0xf << 8)) >> 8);
};
成員
one_bit指示這是一個端點事件(未使用)
endpoint_number端點號
endpoint_event我們擁有的事件: 0x00 - 保留 0x01 - XferComplete 0x02 - XferInProgress 0x03 - XferNotReady 0x04 - RxTxFifoEvt (IN->Underrun, OUT->Overrun) 0x05 - 保留 0x06 - StreamEvt 0x07 - EPCmdCmplt
reserved11_10保留,請勿使用。
status指示事件的狀態。有關更多資訊,請參閱資料手冊。
parameters當前事件的引數。有關更多資訊,請參閱資料手冊。
-
struct dwc3_event_devt¶
裝置事件
定義:
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;
};
成員
one_bit指示這是一個非端點事件(未使用)
device_event指示這是一個裝置事件。應讀取為 0x00
type指示裝置事件的型別。0 - DisconnEvt 1 - USBRst 2 - ConnectDone 3 - ULStChng 4 - WkUpEvt 5 - 保留 6 - Suspend (修訂版 2.10a 及更早版本上的 EOPF) 7 - SOF 8 - 保留 9 - ErrticErr 10 - CmdCmplt 11 - EvntOverflow 12 - VndrDevTstRcved
reserved15_12保留,未使用
event_info有關此事件的資訊
reserved31_25保留,未使用
-
struct dwc3_event_gevt¶
其他核心事件
定義:
struct dwc3_event_gevt {
u32 one_bit:1;
u32 device_event:7;
u32 phy_port_number:4;
u32 reserved31_12:20;
};
成員
one_bit指示這是一個非端點事件(未使用)
device_event指示它是 (0x03) Carkit 或 (0x04) I2C 事件。
phy_port_number不言自明
reserved31_12保留,未使用。
-
union dwc3_event¶
事件緩衝區內容的表示
定義:
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;
};
成員
raw原始 32 位事件
type事件的型別
depevt裝置端點事件
devt裝置事件
gevt全域性事件
-
struct dwc3_gadget_ep_cmd_params¶
端點命令引數的表示
定義:
struct dwc3_gadget_ep_cmd_params {
u32 param2;
u32 param1;
u32 param0;
};
成員
param2第三個引數
param1第二個引數
param0第一個引數
引數
struct dwc3 *dwc指向上下文結構的指標
描述
以位為單位返回 MDWIDTH 配置值。
-
struct dwc3_request *next_request(struct list_head *list)¶
獲取給定列表中的下一個請求
引數
struct list_head *list要操作的請求列表
描述
呼叫者應注意鎖定。此函式返回 NULL 或 **list** 上的第一個可用請求。
-
void dwc3_gadget_move_started_request(struct dwc3_request *req)¶
將 **req** 移動到 started_list
引數
struct dwc3_request *req要移動的請求
描述
呼叫者應注意鎖定。此函式會將 **req** 從其當前列表移動到端點的 started_list。
-
void dwc3_gadget_move_cancelled_request(struct dwc3_request *req, unsigned int reason)¶
將 **req** 移動到 cancelled_list
引數
struct dwc3_request *req要移動的請求
unsigned int reasondwc3 請求的取消原因
描述
呼叫者應注意鎖定。此函式會將 **req** 從其當前列表移動到端點的 cancelled_list。
引數
struct dwc3_ep *depdwc3 端點
描述
呼叫者應注意鎖定。 返回給定端點的傳輸資源索引。
引數
struct dwc3 *dwc指向上下文結構的指標
u32 value要寫入 DCTL 的值
描述
在對 DCTL 進行讀取-修改-寫入時使用此函式。它不會發送鏈路狀態更改請求。
引數
struct dwc3 *dwc指向上下文結構的指標
int mode要設定的模式(J、K SE0 NAK、強制啟用)
描述
呼叫者應注意鎖定。 如果傳遞了錯誤的測試選擇器,此函式將返回 0 表示成功,否則返回 -EINVAL。
引數
struct dwc3 *dwc指向上下文結構的指標
描述
呼叫者應注意鎖定。 此函式將在成功時返回鏈路狀態(>= 0)或 -ETIMEDOUT。
引數
struct dwc3 *dwc指向上下文結構的指標
enum dwc3_link_state state要將鏈路置於的狀態
描述
呼叫者應注意鎖定。 此函式將在成功時返回 0 或 -ETIMEDOUT。
-
void dwc3_ep_inc_trb(u8 *index)¶
遞增 trb 索引。
引數
u8 *index指向要遞增的 TRB 索引的指標。
描述
索引永遠不應指向鏈路 TRB。遞增後,如果它指向鏈路 TRB,則環繞到開頭。鏈路 TRB 始終位於最後一個 TRB 條目中。
引數
struct dwc3_ep *dep我們要遞增其入隊指標的端點
引數
struct dwc3_ep *dep我們要遞增其入隊指標的端點
-
void dwc3_gadget_giveback(struct dwc3_ep *dep, struct dwc3_request *req, int status)¶
呼叫
struct usb_request的 ->complete 回撥
引數
struct dwc3_ep *dep請求所屬的端點
struct dwc3_request *req我們要返回的請求
int status請求的完成程式碼
描述
必須在持有控制器的鎖並停用中斷的情況下呼叫。此函式將取消對映 **req** 並呼叫其 ->complete() 回撥以通知上層它已完成。
引數
struct dwc3 *dwc指向控制器上下文的指標
unsigned int cmd要發出的命令
u32 param命令引數
描述
呼叫者應注意鎖定。 將帶有給定 **param** 的 **cmd** 傳送到 **dwc** 並等待其完成。
-
int dwc3_send_gadget_ep_cmd(struct dwc3_ep *dep, unsigned int cmd, struct dwc3_gadget_ep_cmd_params *params)¶
發出端點命令
引數
struct dwc3_ep *dep命令將要發出的端點
unsigned int cmd要發出的命令
struct dwc3_gadget_ep_cmd_params *params命令的引數
描述
呼叫者應處理鎖定。 此函式將帶有給定 **params** 的 **cmd** 傳送到 **dep** 並等待其完成。
根據程式設計指南,如果鏈路狀態為 L1/L2/U3,則傳送“啟動傳輸”命令可能無法完成。 程式設計指南建議透過在傳送命令之前執行遠端喚醒來將鏈路狀態恢復為 ON/U0。 但是,當用戶/函式未透過喚醒操作傳送喚醒請求時,請勿啟動遠端喚醒。 在允許時傳送命令。
對於 L2 或 U3 鏈路狀態,裝置處於 USB 掛起狀態。 傳送“啟動傳輸”命令時,應注意確保在 USB 恢復後完成該操作。
註釋
對於 L1 鏈路狀態,發出命令需要清除 GUSB2PHYCFG.SUSPENDUSB2,這會開啟完成給定命令所需的訊號(通常在 50us 內)。 這應在驅動程式設定的命令超時內發生。 無需其他步驟。
引數
struct dwc3 *dwc指向 DWC3 上下文的指標
unsigned int resource_indexDEPSTARTCFG.XferRscIdx 值(必須為 0 或 2)
描述
設定 resource_index=0 以重置所有端點的資源分配。 作為開機/軟重置初始化的一部分執行此操作。
設定 resource_index=2 以僅重置非控制端點的資源。 在收到 SET_CONFIGURATION 請求或休眠恢復時執行此操作。
引數
struct dwc3 *dwc指向 DWC3 上下文的指標
int mult計算 fifo_size 時要使用的乘數
描述
根據以下公式計算大小值
DWC3 修訂版 280A 及更早版本:fifo_size = mult * (max_packet / mdwidth) + 1;
DWC3 修訂版 290A 及更高版本:fifo_size = mult * ((max_packet + mdwidth)/mdwidth + 1) + 1
最大資料包大小設定為 1024,因為 txfifo 要求主要適用於超高速 USB 用例。 但是,對於其他情況(即高速 USB),安全起見可以高估 fifo 分配。
引數
struct dwc3 *dwc指向 DWC3 上下文的指標
引數
struct dwc3 *dwc指向 DWC3 上下文的指標
描述
迭代所有端點暫存器並清除之前的 txfifo 分配。
引數
struct dwc3_ep *dep要初始化的端點
unsigned int actionINIT、MODIFY 或 RESTORE 之一
描述
呼叫者應注意鎖定。 執行所有必要的命令來初始化硬體端點,以便小工具驅動程式可以使用它。
引數
struct dwc3_ep *dep要停用的端點
描述
此函式撤消 __dwc3_gadget_ep_enable 所做的工作,並刪除當前由硬體處理的請求和尚未排程的請求。
呼叫者應注意鎖定。
引數
struct dwc3_ep *dep帶有 TRB 環的端點
u8 index環中當前 TRB 的索引
描述
返回索引所指向的 TRB 之前的 TRB。如果索引為 0,我們將向後環繞,跳過連結 TRB,然後返回它之前的 TRB。
-
void dwc3_prepare_one_trb(struct dwc3_ep *dep, struct dwc3_request *req, unsigned int trb_length, unsigned int chain, unsigned int node, bool use_bounce_buffer, bool must_interrupt)¶
從一個請求設定一個 TRB
引數
struct dwc3_ep *dep為此請求準備的端點
struct dwc3_request *reqdwc3_request 指標
unsigned int trb_lengthTRB 的緩衝區大小
unsigned int chain此 TRB 是否應連結到下一個?
unsigned int node僅適用於同步端點。第一個 TRB 需要不同的型別。
bool use_bounce_buffer設定為使用反彈緩衝區
bool must_interrupt設定為在 TRB 完成時中斷
-
int dwc3_prepare_last_sg(struct dwc3_ep *dep, struct dwc3_request *req, unsigned int entry_length, unsigned int node)¶
為最後一個 SG 條目準備 TRB
引數
struct dwc3_ep *dep請求所屬的端點
struct dwc3_request *req要準備的請求
unsigned int entry_length最後一個 SG 條目大小
unsigned int node指示這是否不是第一個條目(僅適用於 isoc)
描述
返回準備好的 TRB 的數量。
引數
struct dwc3_ep *depisoc 端點
bool force在命令中設定 forcerm 位
bool interrupt在結束傳輸命令後,命令完成中斷
描述
設定 force 時,將設定 ForceRM 位。在這種情況下,控制器不會在命令完成時更新 TRB 進度。它也不會清除 TRB 中的 HWO 位。在這種情況下,該命令也不會立即完成。
引數
struct dwc3_ep *depisoc 端點
描述
此函式測試來自 XferNotReady 事件報告的 16 位微幀號的 BIT[15:14] 的正確組合,以用於啟動 isoc 傳輸的未來幀號。
在 DWC_usb31 1.70a-ea06 及更早版本中,對於高速和全速同步 IN,XferNotReady 事件報告的 16 位微幀號的 BIT[15:14] 無效。驅動程式使用此號碼來安排同步傳輸,並將其傳遞給 START TRANSFER 命令。因為此號碼無效,所以命令可能會失敗。如果 BIT[15:14] 與內部 16 位微幀匹配,則 START TRANSFER 命令將透過,傳輸將在計劃的時間開始;如果相差 1,該命令仍將透過,但傳輸將在 2 秒後開始。對於所有其他情況,START TRANSFER 命令將因匯流排過期而失敗。
為了解決這個問題,我們可以透過傳送具有不同 BIT[15:14] 值的 START TRANSFER 命令來測試 BIT[15:14] 的正確組合:'b00、'b01、'b10 和 'b11。每個組合相隔 2^14 uframe(或 2 秒)。4 秒後的結果將是匯流排過期狀態。因此,在 BIT[15:14] 的 4 種可能組合中,將有 2 個成功的和 2 個失敗的 START COMMAND 狀態。2 個成功的命令狀態之一將導致延遲 2 秒的啟動。較小的 BIT[15:14] 值是正確的組合。
由於只有 4 個結果並且結果是有序的,我們可以簡單地測試 2 個具有 BIT[15:14] 組合 'b00 和 'b01 的 START TRANSFER 命令,以推斷出較小的成功組合。
假設 test0 = 組合 'b00 的測試狀態,test1 = BIT[15:14] 的 'b01 的測試狀態。正確的組合如下
如果 test0 失敗且 test1 透過,則 BIT[15:14] 為 'b01;如果 test0 失敗且 test1 失敗,則 BIT[15:14] 為 'b10;如果 test0 透過且 test1 失敗,則 BIT[15:14] 為 'b11;如果 test0 透過且 test1 透過,則 BIT[15:14] 為 'b00
Synopsys STAR 9001202023:同步 IN 端點的微幀號錯誤。
引數
struct dwc3 *dwc指向上下文結構的指標
描述
以下內容看起來很複雜,但實際上非常簡單。為了計算我們可以在 OUT 傳輸上一次突發的資料包數量,我們將使用 RxFIFO 大小。
要計算 RxFIFO 大小,我們需要兩個數字:MDWIDTH = 內部記憶體匯流排的大小(以位為單位)RAM2_DEPTH = 內部 RAM2 的深度(以 MDWIDTH 為單位)(RxFIFO 位於此處)
有了這兩個數字,公式很簡單
RxFIFO Size = (RAM2_DEPTH * MDWIDTH / 8) - 24 - 16;
24 位元組用於 3x SETUP 資料包,16 位元組是時鐘域交叉容差
給定 RxFIFO Size,NUMP = RxFIFOSize / 1024;
-
int dwc3_gadget_check_config(struct usb_gadget *g)¶
確保 dwc3 可以支援 USB 配置
引數
struct usb_gadget *g指向 USB gadget 的指標
描述
用於記錄 USB 複合裝置中使用的最大端點數。(跨所有配置)這將用於在調整各個端點的內部儲存器大小以計算 TXFIFO 大小時。它將有助於確保調整大小邏輯至少為一個最大資料包保留足夠的空間。
引數
struct dwc3 *dwc指向我們的控制器上下文結構的指標
描述
成功返回 0,否則返回負 errno。
引數
struct dwc3 *dwc指向上下文結構的指標
引數
struct dwc3 *dwc指向上下文結構的指標
-
void dwc3_ref_clk_period(struct dwc3 *dwc)¶
參考時鐘週期配置 預設參考時鐘週期取決於硬體配置。對於參考時鐘與預設值不同的系統,這將在 DWC3_GUCTL 暫存器中設定時鐘週期。
引數
struct dwc3 *dwc指向我們的控制器上下文結構的指標
-
void dwc3_free_one_event_buffer(struct dwc3 *dwc, struct dwc3_event_buffer *evt)¶
釋放一個事件緩衝區
引數
struct dwc3 *dwc指向我們的控制器上下文結構的指標
struct dwc3_event_buffer *evt指向要釋放的事件緩衝區的指標
-
struct dwc3_event_buffer *dwc3_alloc_one_event_buffer(struct dwc3 *dwc, unsigned int length)¶
分配一個事件緩衝區結構
引數
struct dwc3 *dwc指向我們的控制器上下文結構的指標
unsigned int length事件緩衝區的大小
描述
成功時返回指向已分配事件緩衝區結構的指標,否則返回 ERR_PTR(errno)。
引數
struct dwc3 *dwc指向我們的控制器上下文結構的指標
引數
struct dwc3 *dwc指向我們的控制器上下文結構的指標
unsigned int length事件緩衝區的大小
描述
成功返回 0,否則返回負 errno。在錯誤情況下,dwc 可能包含一些已分配但未全部請求的緩衝區。
引數
struct dwc3 *dwc指向我們的控制器上下文結構的指標
描述
成功返回 0,否則返回負 errno。
引數
struct dwc3 *dwc指向我們的控制器上下文結構的指標
描述
成功返回 0。USB PHY 介面已配置但未初始化。PHY 介面和 PHY 與核心一起在 dwc3_core_init 中初始化。
引數
struct dwc3 *dwc指向我們的控制器上下文結構的指標
描述
成功返回 0,否則返回負 errno。