]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Bus/Pci/XhciDxe/XhciReg.c
SignedCapsulePkg: fix AARCH64 build
[mirror_edk2.git] / MdeModulePkg / Bus / Pci / XhciDxe / XhciReg.c
CommitLineData
92870c98 1/** @file\r
2\r
3 The XHCI register operation routines.\r
4\r
16f69227 5Copyright (c) 2011 - 2017, Intel Corporation. All rights reserved.<BR>\r
9d510e61 6SPDX-License-Identifier: BSD-2-Clause-Patent\r
92870c98 7\r
8**/\r
9\r
10#include "Xhci.h"\r
11\r
12/**\r
13 Read 1-byte width XHCI capability register.\r
14\r
a9292c13 15 @param Xhc The XHCI Instance.\r
92870c98 16 @param Offset The offset of the 1-byte width capability register.\r
17\r
18 @return The register content read.\r
19 @retval If err, return 0xFF.\r
20\r
21**/\r
22UINT8\r
23XhcReadCapReg8 (\r
a9292c13 24 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 25 IN UINT32 Offset\r
26 )\r
27{\r
28 UINT8 Data;\r
29 EFI_STATUS Status;\r
30\r
31 Status = Xhc->PciIo->Mem.Read (\r
32 Xhc->PciIo,\r
33 EfiPciIoWidthUint8,\r
34 XHC_BAR_INDEX,\r
35 (UINT64) Offset,\r
36 1,\r
37 &Data\r
38 );\r
39\r
40 if (EFI_ERROR (Status)) {\r
41 DEBUG ((EFI_D_ERROR, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status, Offset));\r
42 Data = 0xFF;\r
43 }\r
44\r
45 return Data;\r
46}\r
47\r
48/**\r
49 Read 4-bytes width XHCI capability register.\r
50\r
a9292c13 51 @param Xhc The XHCI Instance.\r
92870c98 52 @param Offset The offset of the 4-bytes width capability register.\r
53\r
54 @return The register content read.\r
55 @retval If err, return 0xFFFFFFFF.\r
56\r
57**/\r
58UINT32\r
59XhcReadCapReg (\r
a9292c13 60 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 61 IN UINT32 Offset\r
62 )\r
63{\r
64 UINT32 Data;\r
65 EFI_STATUS Status;\r
66\r
67 Status = Xhc->PciIo->Mem.Read (\r
68 Xhc->PciIo,\r
69 EfiPciIoWidthUint32,\r
70 XHC_BAR_INDEX,\r
71 (UINT64) Offset,\r
72 1,\r
73 &Data\r
74 );\r
75\r
76 if (EFI_ERROR (Status)) {\r
77 DEBUG ((EFI_D_ERROR, "XhcReadCapReg: Pci Io read error - %r at %d\n", Status, Offset));\r
78 Data = 0xFFFFFFFF;\r
79 }\r
80\r
81 return Data;\r
82}\r
83\r
84/**\r
85 Read 4-bytes width XHCI Operational register.\r
86\r
a9292c13 87 @param Xhc The XHCI Instance.\r
92870c98 88 @param Offset The offset of the 4-bytes width operational register.\r
89\r
90 @return The register content read.\r
91 @retval If err, return 0xFFFFFFFF.\r
92\r
93**/\r
94UINT32\r
95XhcReadOpReg (\r
a9292c13 96 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 97 IN UINT32 Offset\r
98 )\r
99{\r
100 UINT32 Data;\r
101 EFI_STATUS Status;\r
102\r
103 ASSERT (Xhc->CapLength != 0);\r
104\r
105 Status = Xhc->PciIo->Mem.Read (\r
106 Xhc->PciIo,\r
107 EfiPciIoWidthUint32,\r
108 XHC_BAR_INDEX,\r
16f69227 109 Xhc->CapLength + Offset,\r
92870c98 110 1,\r
111 &Data\r
112 );\r
113\r
114 if (EFI_ERROR (Status)) {\r
115 DEBUG ((EFI_D_ERROR, "XhcReadOpReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
116 Data = 0xFFFFFFFF;\r
117 }\r
118\r
119 return Data;\r
120}\r
121\r
122/**\r
123 Write the data to the 4-bytes width XHCI operational register.\r
124\r
a9292c13 125 @param Xhc The XHCI Instance.\r
92870c98 126 @param Offset The offset of the 4-bytes width operational register.\r
127 @param Data The data to write.\r
128\r
129**/\r
130VOID\r
131XhcWriteOpReg (\r
a9292c13 132 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 133 IN UINT32 Offset,\r
134 IN UINT32 Data\r
135 )\r
136{\r
137 EFI_STATUS Status;\r
138\r
139 ASSERT (Xhc->CapLength != 0);\r
140\r
141 Status = Xhc->PciIo->Mem.Write (\r
142 Xhc->PciIo,\r
143 EfiPciIoWidthUint32,\r
144 XHC_BAR_INDEX,\r
16f69227 145 Xhc->CapLength + Offset,\r
92870c98 146 1,\r
147 &Data\r
148 );\r
149\r
150 if (EFI_ERROR (Status)) {\r
151 DEBUG ((EFI_D_ERROR, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
152 }\r
153}\r
154\r
92870c98 155\r
92870c98 156\r
92870c98 157\r
92870c98 158\r
159/**\r
160 Write the data to the XHCI door bell register.\r
161\r
a9292c13 162 @param Xhc The XHCI Instance.\r
92870c98 163 @param Offset The offset of the door bell register.\r
164 @param Data The data to write.\r
165\r
166**/\r
167VOID\r
168XhcWriteDoorBellReg (\r
a9292c13 169 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 170 IN UINT32 Offset,\r
171 IN UINT32 Data\r
172 )\r
173{\r
174 EFI_STATUS Status;\r
175\r
176 ASSERT (Xhc->DBOff != 0);\r
177\r
178 Status = Xhc->PciIo->Mem.Write (\r
179 Xhc->PciIo,\r
180 EfiPciIoWidthUint32,\r
181 XHC_BAR_INDEX,\r
16f69227 182 Xhc->DBOff + Offset,\r
92870c98 183 1,\r
184 &Data\r
185 );\r
186\r
187 if (EFI_ERROR (Status)) {\r
188 DEBUG ((EFI_D_ERROR, "XhcWriteOpReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
189 }\r
190}\r
191\r
192/**\r
193 Read XHCI runtime register.\r
194\r
a9292c13 195 @param Xhc The XHCI Instance.\r
92870c98 196 @param Offset The offset of the runtime register.\r
197\r
198 @return The register content read\r
199\r
200**/\r
201UINT32\r
202XhcReadRuntimeReg (\r
a9292c13 203 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 204 IN UINT32 Offset\r
205 )\r
206{\r
207 UINT32 Data;\r
208 EFI_STATUS Status;\r
209\r
210 ASSERT (Xhc->RTSOff != 0);\r
211\r
212 Status = Xhc->PciIo->Mem.Read (\r
213 Xhc->PciIo,\r
214 EfiPciIoWidthUint32,\r
215 XHC_BAR_INDEX,\r
16f69227 216 Xhc->RTSOff + Offset,\r
92870c98 217 1,\r
218 &Data\r
219 );\r
220\r
221 if (EFI_ERROR (Status)) {\r
222 DEBUG ((EFI_D_ERROR, "XhcReadRuntimeReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
223 Data = 0xFFFFFFFF;\r
224 }\r
225\r
226 return Data;\r
227}\r
228\r
92870c98 229/**\r
230 Write the data to the XHCI runtime register.\r
231\r
a9292c13 232 @param Xhc The XHCI Instance.\r
92870c98 233 @param Offset The offset of the runtime register.\r
234 @param Data The data to write.\r
235\r
236**/\r
237VOID\r
238XhcWriteRuntimeReg (\r
a9292c13 239 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 240 IN UINT32 Offset,\r
241 IN UINT32 Data\r
242 )\r
243{\r
244 EFI_STATUS Status;\r
245\r
246 ASSERT (Xhc->RTSOff != 0);\r
247\r
248 Status = Xhc->PciIo->Mem.Write (\r
249 Xhc->PciIo,\r
250 EfiPciIoWidthUint32,\r
251 XHC_BAR_INDEX,\r
16f69227 252 Xhc->RTSOff + Offset,\r
92870c98 253 1,\r
254 &Data\r
255 );\r
256\r
257 if (EFI_ERROR (Status)) {\r
258 DEBUG ((EFI_D_ERROR, "XhcWriteRuntimeReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
259 }\r
260}\r
261\r
92870c98 262/**\r
263 Read XHCI extended capability register.\r
264\r
a9292c13 265 @param Xhc The XHCI Instance.\r
92870c98 266 @param Offset The offset of the extended capability register.\r
267\r
268 @return The register content read\r
269\r
270**/\r
271UINT32\r
272XhcReadExtCapReg (\r
a9292c13 273 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 274 IN UINT32 Offset\r
275 )\r
276{\r
277 UINT32 Data;\r
278 EFI_STATUS Status;\r
279\r
280 ASSERT (Xhc->ExtCapRegBase != 0);\r
281\r
282 Status = Xhc->PciIo->Mem.Read (\r
283 Xhc->PciIo,\r
284 EfiPciIoWidthUint32,\r
285 XHC_BAR_INDEX,\r
16f69227 286 Xhc->ExtCapRegBase + Offset,\r
92870c98 287 1,\r
288 &Data\r
289 );\r
290\r
291 if (EFI_ERROR (Status)) {\r
292 DEBUG ((EFI_D_ERROR, "XhcReadExtCapReg: Pci Io Read error - %r at %d\n", Status, Offset));\r
293 Data = 0xFFFFFFFF;\r
294 }\r
295\r
296 return Data;\r
297}\r
298\r
299/**\r
300 Write the data to the XHCI extended capability register.\r
301\r
a9292c13 302 @param Xhc The XHCI Instance.\r
92870c98 303 @param Offset The offset of the extended capability register.\r
304 @param Data The data to write.\r
305\r
306**/\r
307VOID\r
308XhcWriteExtCapReg (\r
a9292c13 309 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 310 IN UINT32 Offset,\r
311 IN UINT32 Data\r
312 )\r
313{\r
314 EFI_STATUS Status;\r
315\r
316 ASSERT (Xhc->ExtCapRegBase != 0);\r
317\r
318 Status = Xhc->PciIo->Mem.Write (\r
319 Xhc->PciIo,\r
320 EfiPciIoWidthUint32,\r
321 XHC_BAR_INDEX,\r
16f69227 322 Xhc->ExtCapRegBase + Offset,\r
92870c98 323 1,\r
324 &Data\r
325 );\r
326\r
327 if (EFI_ERROR (Status)) {\r
328 DEBUG ((EFI_D_ERROR, "XhcWriteExtCapReg: Pci Io Write error: %r at %d\n", Status, Offset));\r
329 }\r
330}\r
331\r
332\r
333/**\r
334 Set one bit of the runtime register while keeping other bits.\r
335\r
a9292c13 336 @param Xhc The XHCI Instance.\r
92870c98 337 @param Offset The offset of the runtime register.\r
338 @param Bit The bit mask of the register to set.\r
339\r
340**/\r
341VOID\r
342XhcSetRuntimeRegBit (\r
a9292c13 343 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 344 IN UINT32 Offset,\r
345 IN UINT32 Bit\r
346 )\r
347{\r
348 UINT32 Data;\r
349\r
350 Data = XhcReadRuntimeReg (Xhc, Offset);\r
351 Data |= Bit;\r
352 XhcWriteRuntimeReg (Xhc, Offset, Data);\r
353}\r
354\r
355/**\r
356 Clear one bit of the runtime register while keeping other bits.\r
357\r
a9292c13 358 @param Xhc The XHCI Instance.\r
92870c98 359 @param Offset The offset of the runtime register.\r
360 @param Bit The bit mask of the register to set.\r
361\r
362**/\r
363VOID\r
364XhcClearRuntimeRegBit (\r
a9292c13 365 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 366 IN UINT32 Offset,\r
367 IN UINT32 Bit\r
368 )\r
369{\r
370 UINT32 Data;\r
371\r
372 Data = XhcReadRuntimeReg (Xhc, Offset);\r
373 Data &= ~Bit;\r
374 XhcWriteRuntimeReg (Xhc, Offset, Data);\r
375}\r
376\r
377/**\r
378 Set one bit of the operational register while keeping other bits.\r
379\r
a9292c13 380 @param Xhc The XHCI Instance.\r
92870c98 381 @param Offset The offset of the operational register.\r
382 @param Bit The bit mask of the register to set.\r
383\r
384**/\r
385VOID\r
386XhcSetOpRegBit (\r
a9292c13 387 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 388 IN UINT32 Offset,\r
389 IN UINT32 Bit\r
390 )\r
391{\r
392 UINT32 Data;\r
393\r
394 Data = XhcReadOpReg (Xhc, Offset);\r
395 Data |= Bit;\r
396 XhcWriteOpReg (Xhc, Offset, Data);\r
397}\r
398\r
399\r
400/**\r
401 Clear one bit of the operational register while keeping other bits.\r
402\r
a9292c13 403 @param Xhc The XHCI Instance.\r
92870c98 404 @param Offset The offset of the operational register.\r
405 @param Bit The bit mask of the register to clear.\r
406\r
407**/\r
408VOID\r
409XhcClearOpRegBit (\r
a9292c13 410 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 411 IN UINT32 Offset,\r
412 IN UINT32 Bit\r
413 )\r
414{\r
415 UINT32 Data;\r
416\r
417 Data = XhcReadOpReg (Xhc, Offset);\r
418 Data &= ~Bit;\r
419 XhcWriteOpReg (Xhc, Offset, Data);\r
420}\r
421\r
422/**\r
423 Wait the operation register's bit as specified by Bit\r
424 to become set (or clear).\r
425\r
a9292c13 426 @param Xhc The XHCI Instance.\r
92870c98 427 @param Offset The offset of the operation register.\r
428 @param Bit The bit of the register to wait for.\r
429 @param WaitToSet Wait the bit to set or clear.\r
26cd2d6d 430 @param Timeout The time to wait before abort (in millisecond, ms).\r
92870c98 431\r
432 @retval EFI_SUCCESS The bit successfully changed by host controller.\r
433 @retval EFI_TIMEOUT The time out occurred.\r
434\r
435**/\r
436EFI_STATUS\r
437XhcWaitOpRegBit (\r
a9292c13 438 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 439 IN UINT32 Offset,\r
440 IN UINT32 Bit,\r
441 IN BOOLEAN WaitToSet,\r
442 IN UINT32 Timeout\r
443 )\r
444{\r
445 UINT32 Index;\r
26cd2d6d 446 UINT64 Loop;\r
92870c98 447\r
26cd2d6d 448 Loop = Timeout * XHC_1_MILLISECOND;\r
a9292c13 449\r
450 for (Index = 0; Index < Loop; Index++) {\r
92870c98 451 if (XHC_REG_BIT_IS_SET (Xhc, Offset, Bit) == WaitToSet) {\r
452 return EFI_SUCCESS;\r
453 }\r
454\r
26cd2d6d 455 gBS->Stall (XHC_1_MICROSECOND);\r
92870c98 456 }\r
457\r
458 return EFI_TIMEOUT;\r
459}\r
460\r
461/**\r
462 Set Bios Ownership\r
463\r
a9292c13 464 @param Xhc The XHCI Instance.\r
92870c98 465\r
466**/\r
467VOID\r
468XhcSetBiosOwnership (\r
a9292c13 469 IN USB_XHCI_INSTANCE *Xhc\r
92870c98 470 )\r
471{\r
472 UINT32 Buffer;\r
473\r
74b04490
SI
474 if (Xhc->UsbLegSupOffset == 0xFFFFFFFF) {\r
475 return;\r
476 }\r
477\r
92870c98 478 DEBUG ((EFI_D_INFO, "XhcSetBiosOwnership: called to set BIOS ownership\n"));\r
479\r
480 Buffer = XhcReadExtCapReg (Xhc, Xhc->UsbLegSupOffset);\r
481 Buffer = ((Buffer & (~USBLEGSP_OS_SEMAPHORE)) | USBLEGSP_BIOS_SEMAPHORE);\r
482 XhcWriteExtCapReg (Xhc, Xhc->UsbLegSupOffset, Buffer);\r
483}\r
484\r
485/**\r
486 Clear Bios Ownership\r
487\r
a9292c13 488 @param Xhc The XHCI Instance.\r
92870c98 489\r
490**/\r
491VOID\r
492XhcClearBiosOwnership (\r
a9292c13 493 IN USB_XHCI_INSTANCE *Xhc\r
92870c98 494 )\r
495{\r
496 UINT32 Buffer;\r
497\r
74b04490
SI
498 if (Xhc->UsbLegSupOffset == 0xFFFFFFFF) {\r
499 return;\r
500 }\r
501\r
92870c98 502 DEBUG ((EFI_D_INFO, "XhcClearBiosOwnership: called to clear BIOS ownership\n"));\r
503\r
504 Buffer = XhcReadExtCapReg (Xhc, Xhc->UsbLegSupOffset);\r
505 Buffer = ((Buffer & (~USBLEGSP_BIOS_SEMAPHORE)) | USBLEGSP_OS_SEMAPHORE);\r
506 XhcWriteExtCapReg (Xhc, Xhc->UsbLegSupOffset, Buffer);\r
507}\r
508\r
509/**\r
5bcb62a4 510 Calculate the offset of the XHCI capability.\r
92870c98 511\r
a9292c13 512 @param Xhc The XHCI Instance.\r
5bcb62a4 513 @param CapId The XHCI Capability ID.\r
92870c98 514\r
515 @return The offset of XHCI legacy support capability register.\r
516\r
517**/\r
518UINT32\r
5bcb62a4
EL
519XhcGetCapabilityAddr (\r
520 IN USB_XHCI_INSTANCE *Xhc,\r
521 IN UINT8 CapId\r
92870c98 522 )\r
523{\r
524 UINT32 ExtCapOffset;\r
525 UINT8 NextExtCapReg;\r
526 UINT32 Data;\r
527\r
528 ExtCapOffset = 0;\r
529\r
530 do {\r
531 //\r
532 // Check if the extended capability register's capability id is USB Legacy Support.\r
533 //\r
534 Data = XhcReadExtCapReg (Xhc, ExtCapOffset);\r
5bcb62a4 535 if ((Data & 0xFF) == CapId) {\r
92870c98 536 return ExtCapOffset;\r
537 }\r
538 //\r
539 // If not, then traverse all of the ext capability registers till finding out it.\r
540 //\r
ce9b5900 541 NextExtCapReg = (UINT8)((Data >> 8) & 0xFF);\r
92870c98 542 ExtCapOffset += (NextExtCapReg << 2);\r
543 } while (NextExtCapReg != 0);\r
544\r
74b04490 545 return 0xFFFFFFFF;\r
92870c98 546}\r
547\r
548/**\r
549 Whether the XHCI host controller is halted.\r
550\r
a9292c13 551 @param Xhc The XHCI Instance.\r
92870c98 552\r
553 @retval TRUE The controller is halted.\r
554 @retval FALSE It isn't halted.\r
555\r
556**/\r
557BOOLEAN\r
558XhcIsHalt (\r
a9292c13 559 IN USB_XHCI_INSTANCE *Xhc\r
92870c98 560 )\r
561{\r
562 return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT);\r
563}\r
564\r
565\r
566/**\r
567 Whether system error occurred.\r
568\r
a9292c13 569 @param Xhc The XHCI Instance.\r
92870c98 570\r
571 @retval TRUE System error happened.\r
572 @retval FALSE No system error.\r
573\r
574**/\r
575BOOLEAN\r
576XhcIsSysError (\r
a9292c13 577 IN USB_XHCI_INSTANCE *Xhc\r
92870c98 578 )\r
579{\r
580 return XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HSE);\r
581}\r
582\r
73dbd6af
SZ
583/**\r
584 Set USBCMD Host System Error Enable(HSEE) Bit if PCICMD SERR# Enable Bit is set.\r
585\r
586 The USBCMD HSEE Bit will be reset to default 0 by USBCMD Host Controller Reset(HCRST).\r
587 This function is to set USBCMD HSEE Bit if PCICMD SERR# Enable Bit is set.\r
588\r
589 @param Xhc The XHCI Instance.\r
590\r
591**/\r
592VOID\r
593XhcSetHsee (\r
594 IN USB_XHCI_INSTANCE *Xhc\r
595 )\r
596{\r
597 EFI_STATUS Status;\r
598 EFI_PCI_IO_PROTOCOL *PciIo;\r
599 UINT16 XhciCmd;\r
600\r
601 PciIo = Xhc->PciIo;\r
602 Status = PciIo->Pci.Read (\r
603 PciIo,\r
604 EfiPciIoWidthUint16,\r
605 PCI_COMMAND_OFFSET,\r
e5cd8090 606 sizeof (XhciCmd) / sizeof (UINT16),\r
73dbd6af
SZ
607 &XhciCmd\r
608 );\r
609 if (!EFI_ERROR (Status)) {\r
610 if ((XhciCmd & EFI_PCI_COMMAND_SERR) != 0) {\r
611 XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_HSEE);\r
612 }\r
613 }\r
614}\r
615\r
92870c98 616/**\r
617 Reset the XHCI host controller.\r
618\r
a9292c13 619 @param Xhc The XHCI Instance.\r
26cd2d6d 620 @param Timeout Time to wait before abort (in millisecond, ms).\r
92870c98 621\r
622 @retval EFI_SUCCESS The XHCI host controller is reset.\r
623 @return Others Failed to reset the XHCI before Timeout.\r
624\r
625**/\r
626EFI_STATUS\r
627XhcResetHC (\r
a9292c13 628 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 629 IN UINT32 Timeout\r
630 )\r
631{\r
632 EFI_STATUS Status;\r
633\r
5bcb62a4
EL
634 Status = EFI_SUCCESS;\r
635\r
92870c98 636 DEBUG ((EFI_D_INFO, "XhcResetHC!\n"));\r
637 //\r
638 // Host can only be reset when it is halt. If not so, halt it\r
639 //\r
640 if (!XHC_REG_BIT_IS_SET (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT)) {\r
641 Status = XhcHaltHC (Xhc, Timeout);\r
642\r
643 if (EFI_ERROR (Status)) {\r
644 return Status;\r
645 }\r
646 }\r
647\r
74b04490 648 if ((Xhc->DebugCapSupOffset == 0xFFFFFFFF) || ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset) & 0xFF) != XHC_CAP_USB_DEBUG) ||\r
5bcb62a4
EL
649 ((XhcReadExtCapReg (Xhc, Xhc->DebugCapSupOffset + XHC_DC_DCCTRL) & BIT0) == 0)) {\r
650 XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET);\r
dbe10619
FT
651 //\r
652 // Some XHCI host controllers require to have extra 1ms delay before accessing any MMIO register during reset.\r
653 // Otherwise there may have the timeout case happened.\r
654 // The below is a workaround to solve such problem.\r
655 //\r
656 gBS->Stall (XHC_1_MILLISECOND);\r
5bcb62a4 657 Status = XhcWaitOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RESET, FALSE, Timeout);\r
73dbd6af
SZ
658\r
659 if (!EFI_ERROR (Status)) {\r
660 //\r
661 // The USBCMD HSEE Bit will be reset to default 0 by USBCMD HCRST.\r
662 // Set USBCMD HSEE Bit if PCICMD SERR# Enable Bit is set.\r
663 //\r
664 XhcSetHsee (Xhc);\r
665 }\r
5bcb62a4
EL
666 }\r
667\r
92870c98 668 return Status;\r
669}\r
670\r
671\r
672/**\r
673 Halt the XHCI host controller.\r
674\r
a9292c13 675 @param Xhc The XHCI Instance.\r
26cd2d6d 676 @param Timeout Time to wait before abort (in millisecond, ms).\r
92870c98 677\r
678 @return EFI_SUCCESS The XHCI host controller is halt.\r
679 @return EFI_TIMEOUT Failed to halt the XHCI before Timeout.\r
680\r
681**/\r
682EFI_STATUS\r
683XhcHaltHC (\r
a9292c13 684 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 685 IN UINT32 Timeout\r
686 )\r
687{\r
688 EFI_STATUS Status;\r
689\r
690 XhcClearOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RUN);\r
691 Status = XhcWaitOpRegBit (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT, TRUE, Timeout);\r
692 return Status;\r
693}\r
694\r
695\r
696/**\r
697 Set the XHCI host controller to run.\r
698\r
a9292c13 699 @param Xhc The XHCI Instance.\r
26cd2d6d 700 @param Timeout Time to wait before abort (in millisecond, ms).\r
92870c98 701\r
702 @return EFI_SUCCESS The XHCI host controller is running.\r
703 @return EFI_TIMEOUT Failed to set the XHCI to run before Timeout.\r
704\r
705**/\r
706EFI_STATUS\r
707XhcRunHC (\r
a9292c13 708 IN USB_XHCI_INSTANCE *Xhc,\r
92870c98 709 IN UINT32 Timeout\r
710 )\r
711{\r
712 EFI_STATUS Status;\r
713\r
714 XhcSetOpRegBit (Xhc, XHC_USBCMD_OFFSET, XHC_USBCMD_RUN);\r
715 Status = XhcWaitOpRegBit (Xhc, XHC_USBSTS_OFFSET, XHC_USBSTS_HALT, FALSE, Timeout);\r
716 return Status;\r
717}\r
718\r