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