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