]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/EhciDxe/EhciDebug.c
Fixed potential issues to release resources when error occurs.
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / EhciDxe / EhciDebug.c
CommitLineData
913cb9dc 1/** @file\r
2\r
3Copyright (c) 2007, Intel Corporation\r
4All rights reserved. This program and the accompanying materials\r
5are licensed and made available under the terms and conditions of the BSD License\r
6which accompanies this distribution. The full text of the license may be found at\r
7http://opensource.org/licenses/bsd-license.php\r
8\r
9THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
10WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
11\r
12Module Name:\r
13\r
14 EhciDebug.c\r
15\r
16Abstract:\r
17 This file provides the information dump support for EHCI when in debug mode.\r
18You can dynamically adjust the debug level by changing variable mEhcDebugLevel\r
19and mEhcErrorLevel.\r
20\r
21Revision History\r
22\r
23**/\r
24\r
25\r
26#include "Ehci.h"\r
27\r
28#ifdef EFI_DEBUG\r
29UINTN mEhcDebugMask = USB_DEBUG_FORCE_OUTPUT;\r
30\r
31\r
32/**\r
33 EHCI's debug output function. It determines whether\r
34 to output by the mask and level\r
35\r
36 @param Level The output level\r
37 @param Format The format parameters to the print\r
38 @param ... The variable length parameters after format\r
39\r
40 @return None\r
41\r
42**/\r
43VOID\r
44EhciDebugPrint (\r
45 IN UINTN Level,\r
46 IN CHAR8 *Format,\r
47 ...\r
48 )\r
49{\r
50\r
51 VA_LIST Marker;\r
52\r
53 VA_START (Marker, Format);\r
54\r
55 if (Level & mEhcDebugMask) {\r
56 if (mEhcDebugMask & USB_DEBUG_FORCE_OUTPUT) {\r
57 DebugVPrint (DEBUG_ERROR, Format, Marker);\r
58 } else {\r
59 DebugVPrint (DEBUG_INFO, Format, Marker);\r
60 }\r
61 }\r
62\r
63 VA_END (Marker);\r
64}\r
65\r
66\r
67/**\r
68 EHCI's debug output function. It determines whether\r
69 to output by the mask and level\r
70\r
71 @param Format The format parameters to the print\r
72 @param ... The variable length parameters after format\r
73\r
74 @return None\r
75\r
76**/\r
77VOID\r
78EhcDebug (\r
79 IN CHAR8 *Format,\r
80 ...\r
81 )\r
82{\r
83 VA_LIST Marker;\r
84\r
85 VA_START (Marker, Format);\r
86 DebugVPrint (DEBUG_INFO, Format, Marker);\r
87 VA_END (Marker);\r
88}\r
89\r
90\r
91/**\r
92 EHCI's error output function. It determines whether\r
93 to output by the mask and level\r
94\r
95 @param Format The format parameters to the print\r
96 @param ... The variable length parameters after format\r
97\r
98 @return None\r
99\r
100**/\r
101VOID\r
102EhcError (\r
103 IN CHAR8 *Format,\r
104 ...\r
105 )\r
106{\r
107\r
108 VA_LIST Marker;\r
109\r
110 VA_START (Marker, Format);\r
111 DebugVPrint (DEBUG_ERROR, Format, Marker);\r
112 VA_END (Marker);\r
113}\r
114\r
115\r
116/**\r
117 Dump the status byte in QTD/QH to a more friendly\r
118 format\r
119\r
120 @param State The state in the QTD/QH\r
121 @param Level The output level\r
122\r
123 @return None\r
124\r
125**/\r
126STATIC\r
127VOID\r
128EhcDumpStatus (\r
129 IN UINT32 State,\r
130 IN UINTN Level\r
131 )\r
132{\r
133 if (EHC_BIT_IS_SET (State, QTD_STAT_DO_PING)) {\r
134 EhciDebugPrint (Level, " Do_Ping");\r
135 } else {\r
136 EhciDebugPrint (Level, " Do_Out");\r
137 }\r
138\r
139 if (EHC_BIT_IS_SET (State, QTD_STAT_DO_CS)) {\r
140 EhciDebugPrint (Level, " Do_CS");\r
141 } else {\r
142 EhciDebugPrint (Level, " Do_SS");\r
143 }\r
144\r
145 if (EHC_BIT_IS_SET (State, QTD_STAT_TRANS_ERR)) {\r
146 EhciDebugPrint (Level, " Transfer_Error");\r
147 }\r
148\r
149 if (EHC_BIT_IS_SET (State, QTD_STAT_BABBLE_ERR)) {\r
150 EhciDebugPrint (Level, " Babble_Error");\r
151 }\r
152\r
153 if (EHC_BIT_IS_SET (State, QTD_STAT_BUFF_ERR)) {\r
154 EhciDebugPrint (Level, " Buffer_Error");\r
155 }\r
156\r
157 if (EHC_BIT_IS_SET (State, QTD_STAT_HALTED)) {\r
158 EhciDebugPrint (Level, " Halted");\r
159 }\r
160\r
161 if (EHC_BIT_IS_SET (State, QTD_STAT_ACTIVE)) {\r
162 EhciDebugPrint (Level, " Active");\r
163 }\r
164\r
165 EhciDebugPrint (Level, "\n");\r
166}\r
167\r
168\r
169/**\r
170 Dump the fields of a QTD\r
171\r
172 @param Qtd The QTD to dump\r
173 @param Msg The message to print before the dump\r
174\r
175 @return None\r
176\r
177**/\r
178VOID\r
179EhcDumpQtd (\r
180 IN EHC_QTD *Qtd,\r
181 IN UINT8 *Msg\r
182 )\r
183{\r
184 QTD_HW *QtdHw;\r
185 UINTN Index;\r
186 UINTN Level;\r
187\r
188 Level = EHC_DEBUG_QTD;\r
189\r
190 if (Msg != NULL) {\r
191 EhciDebugPrint (Level, Msg);\r
192 }\r
193\r
194 EhciDebugPrint (Level, "Queue TD @ 0x%x, data length %d\n", Qtd, Qtd->DataLen);\r
195\r
196 QtdHw = &Qtd->QtdHw;\r
197\r
198 EhciDebugPrint (Level, "Next QTD : %x\n", QtdHw->NextQtd);\r
199 EhciDebugPrint (Level, "AltNext QTD : %x\n", QtdHw->AltNext);\r
200 EhciDebugPrint (Level, "Status : %x\n", QtdHw->Status);\r
201 EhcDumpStatus (QtdHw->Status, Level);\r
202\r
203 if (QtdHw->Pid == QTD_PID_SETUP) {\r
204 EhciDebugPrint (Level, "PID : Setup\n");\r
205\r
206 } else if (QtdHw->Pid == QTD_PID_INPUT) {\r
207 EhciDebugPrint (Level, "PID : IN\n");\r
208\r
209 } else if (QtdHw->Pid == QTD_PID_OUTPUT) {\r
210 EhciDebugPrint (Level, "PID : OUT\n");\r
211\r
212 }\r
213\r
214 EhciDebugPrint (Level, "Error Count : %d\n", QtdHw->ErrCnt);\r
215 EhciDebugPrint (Level, "Current Page : %d\n", QtdHw->CurPage);\r
216 EhciDebugPrint (Level, "IOC : %d\n", QtdHw->IOC);\r
217 EhciDebugPrint (Level, "Total Bytes : %d\n", QtdHw->TotalBytes);\r
218 EhciDebugPrint (Level, "Data Toggle : %d\n", QtdHw->DataToggle);\r
219\r
220 for (Index = 0; Index < 5; Index++) {\r
221 EhciDebugPrint (Level, "Page[%d] : 0x%x\n", Index, QtdHw->Page[Index]);\r
222 }\r
223}\r
224\r
225\r
226/**\r
227 Dump the queue head\r
228\r
229 @param Qh The queue head to dump\r
230 @param Msg The message to print before the dump\r
231 @param DumpBuf Whether to dump the memory buffer of the associated QTD\r
232\r
233 @return None\r
234\r
235**/\r
236VOID\r
237EhcDumpQh (\r
238 IN EHC_QH *Qh,\r
239 IN UINT8 *Msg,\r
240 IN BOOLEAN DumpBuf\r
241 )\r
242{\r
243 EHC_QTD *Qtd;\r
244 QH_HW *QhHw;\r
245 LIST_ENTRY *Entry;\r
246 UINTN Index;\r
247 UINTN Level;\r
248\r
249 Level = EHC_DEBUG_QH;\r
250\r
251 if (Msg != NULL) {\r
252 EhciDebugPrint (Level, Msg);\r
253 }\r
254\r
255 EhciDebugPrint (Level, "Queue head @ 0x%x, interval %d, next qh %x\n",\r
256 Qh, Qh->Interval, Qh->NextQh);\r
257\r
258 QhHw = &Qh->QhHw;\r
259\r
260 EhciDebugPrint (Level, "Hoziontal link: %x\n", QhHw->HorizonLink);\r
261 EhciDebugPrint (Level, "Device address: %d\n", QhHw->DeviceAddr);\r
262 EhciDebugPrint (Level, "Inactive : %d\n", QhHw->Inactive);\r
263 EhciDebugPrint (Level, "EP number : %d\n", QhHw->EpNum);\r
264 EhciDebugPrint (Level, "EP speed : %d\n", QhHw->EpSpeed);\r
265 EhciDebugPrint (Level, "DT control : %d\n", QhHw->DtCtrl);\r
266 EhciDebugPrint (Level, "Reclaim head : %d\n", QhHw->ReclaimHead);\r
267 EhciDebugPrint (Level, "Max packet len: %d\n", QhHw->MaxPacketLen);\r
268 EhciDebugPrint (Level, "Ctrl EP : %d\n", QhHw->CtrlEp);\r
269 EhciDebugPrint (Level, "Nak reload : %d\n", QhHw->NakReload);\r
270\r
271 EhciDebugPrint (Level, "SMask : %x\n", QhHw->SMask);\r
272 EhciDebugPrint (Level, "CMask : %x\n", QhHw->CMask);\r
273 EhciDebugPrint (Level, "Hub address : %d\n", QhHw->HubAddr);\r
274 EhciDebugPrint (Level, "Hub port : %d\n", QhHw->PortNum);\r
275 EhciDebugPrint (Level, "Multiplier : %d\n", QhHw->Multiplier);\r
276\r
277 EhciDebugPrint (Level, "Cur QTD : %x\n", QhHw->CurQtd);\r
278\r
279 EhciDebugPrint (Level, "Next QTD : %x\n", QhHw->NextQtd);\r
280 EhciDebugPrint (Level, "AltNext QTD : %x\n", QhHw->AltQtd);\r
281 EhciDebugPrint (Level, "Status : %x\n", QhHw->Status);\r
282 EhcDumpStatus (QhHw->Status, Level);\r
283\r
284 if (QhHw->Pid == QTD_PID_SETUP) {\r
285 EhciDebugPrint (Level, "PID : Setup\n");\r
286\r
287 } else if (QhHw->Pid == QTD_PID_INPUT) {\r
288 EhciDebugPrint (Level, "PID : IN\n");\r
289\r
290 } else if (QhHw->Pid == QTD_PID_OUTPUT) {\r
291 EhciDebugPrint (Level, "PID : OUT\n");\r
292 }\r
293\r
294 EhciDebugPrint (Level, "Error Count : %d\n", QhHw->ErrCnt);\r
295 EhciDebugPrint (Level, "Current Page : %d\n", QhHw->CurPage);\r
296 EhciDebugPrint (Level, "IOC : %d\n", QhHw->IOC);\r
297 EhciDebugPrint (Level, "Total Bytes : %d\n", QhHw->TotalBytes);\r
298 EhciDebugPrint (Level, "Data Toggle : %d\n", QhHw->DataToggle);\r
299\r
300 for (Index = 0; Index < 5; Index++) {\r
301 EhciDebugPrint (Level, "Page[%d] : 0x%x\n", Index, QhHw->Page[Index]);\r
302 }\r
303\r
304 EhciDebugPrint (Level, "\n");\r
305\r
306 EFI_LIST_FOR_EACH (Entry, &Qh->Qtds) {\r
307 Qtd = EFI_LIST_CONTAINER (Entry, EHC_QTD, QtdList);\r
308 EhcDumpQtd (Qtd, NULL);\r
309\r
310 if (DumpBuf && (Qtd->DataLen != 0)) {\r
311 EhcDumpBuf (Qtd->Data, Qtd->DataLen);\r
312 }\r
313 }\r
314}\r
315\r
316\r
317/**\r
318 Dump the buffer in the form of hex\r
319\r
320 @param Buf The buffer to dump\r
321 @param Len The length of buffer\r
322\r
323 @return None\r
324\r
325**/\r
326VOID\r
327EhcDumpBuf (\r
328 IN UINT8 *Buf,\r
329 IN UINTN Len\r
330 )\r
331{\r
332 UINTN Index;\r
333\r
334 for (Index = 0; Index < Len; Index++) {\r
335 if (Index % 16 == 0) {\r
336 EhciDebugPrint (EHC_DEBUG_BUF, "\n");\r
337 }\r
338\r
339 EhciDebugPrint (EHC_DEBUG_BUF, "%02x ", Buf[Index]);\r
340 }\r
341\r
342 EhciDebugPrint (EHC_DEBUG_BUF, "\n");\r
343}\r
344\r
345#endif\r