EHCI driver need enable routine and disable Legacy USB
[people/mcb30/edk2.git] / edk2 / EdkModulePkg / Bus / Pci / Ehci / Dxe / EhciReg.c
1 /*++\r
2 \r
3 Copyright (c) 2006, Intel Corporation                                                     \r
4 All rights reserved. This program and the accompanying materials                          \r
5 are licensed and made available under the terms and conditions of the BSD License         \r
6 which accompanies this distribution.  The full text of the license may be found at        \r
7 http://opensource.org/licenses/bsd-license.php                                            \r
8                                                                                           \r
9 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
10 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
11 \r
12 Module Name:\r
13 \r
14     Ehchlp.c\r
15     \r
16 Abstract: \r
17     \r
18 \r
19 Revision History\r
20 --*/\r
21 \r
22 #include "Ehci.h"\r
23 \r
24 \r
25 VOID\r
26 HostReset (\r
27   IN USB2_HC_DEV    *HcDev\r
28   )\r
29 {\r
30   UINT32  Value;\r
31   UINT32  TimeOut;\r
32  \r
33   ReadEhcOperationalReg (\r
34     HcDev,\r
35     USBCMD,\r
36     &Value\r
37     );\r
38 \r
39   Value = Value & (~USBCMD_RS);\r
40   WriteEhcOperationalReg (\r
41     HcDev,\r
42     USBCMD,\r
43     Value\r
44     );\r
45 \r
46   TimeOut = 40;\r
47   while (TimeOut --) {\r
48     gBS->Stall (500);\r
49     ReadEhcOperationalReg (\r
50       HcDev,\r
51       USBSTS,\r
52       &Value\r
53       );\r
54     if ((Value & USBSTS_HCH) != 0) {\r
55       break;\r
56     }\r
57   }\r
58 \r
59   if (TimeOut == 0) {\r
60     DEBUG((gEHCErrorLevel, "TimeOut for clearing Run/Stop bit\n"));\r
61   }\r
62 \r
63   ReadEhcOperationalReg (\r
64     HcDev,\r
65     USBCMD,\r
66     &Value\r
67     );\r
68   Value = Value | USBCMD_HCRESET;\r
69   WriteEhcOperationalReg (\r
70     HcDev,\r
71     USBCMD,\r
72     Value\r
73     );\r
74 \r
75   TimeOut = 40;\r
76   while (TimeOut --) {\r
77     gBS->Stall (500);\r
78     ReadEhcOperationalReg (\r
79       HcDev,\r
80       USBCMD,\r
81       &Value\r
82       );\r
83     if ((Value & USBCMD_HCRESET) == 0) {\r
84       break;\r
85     }\r
86   }\r
87 \r
88   if (TimeOut == 0) {\r
89     DEBUG((gEHCErrorLevel, "TimeOut for Host Reset\n"));\r
90   }\r
91 \r
92 }\r
93 \r
94 EFI_STATUS\r
95 ReadEhcCapabiltiyReg (\r
96   IN USB2_HC_DEV             *HcDev,\r
97   IN UINT32                  CapabiltiyRegAddr,\r
98   IN OUT UINT32              *Data\r
99   )\r
100 /*++\r
101 \r
102 Routine Description:\r
103 \r
104   Read  Ehc Capabitlity register\r
105   \r
106 Arguments:\r
107 \r
108   HcDev              - USB2_HC_DEV \r
109   CapabiltiyRegAddr  - Ehc Capability register address\r
110   Data               - A pointer to data read from register\r
111   \r
112 Returns:\r
113 \r
114   EFI_SUCCESS        Success\r
115   EFI_DEVICE_ERROR   Fail\r
116     \r
117 --*/\r
118 {\r
119   return HcDev->PciIo->Mem.Read (\r
120                              HcDev->PciIo,\r
121                              EfiPciIoWidthUint32,\r
122                              USB_BAR_INDEX,\r
123                              (UINT64) CapabiltiyRegAddr,\r
124                              1,\r
125                              Data\r
126                              );\r
127 }\r
128 \r
129 EFI_STATUS\r
130 ReadEhcOperationalReg (\r
131   IN USB2_HC_DEV             *HcDev,\r
132   IN UINT32                  OperationalRegAddr,\r
133   IN OUT UINT32              *Data\r
134   )\r
135 /*++\r
136 \r
137 Routine Description:\r
138 \r
139   Read  Ehc Operation register\r
140   \r
141 Arguments:\r
142 \r
143   HcDev                - USB2_HC_DEV \r
144   OperationalRegAddr   - Ehc Operation register address\r
145   Data                 - A pointer to data read from register\r
146   \r
147 Returns:\r
148 \r
149   EFI_SUCCESS        Success\r
150   EFI_DEVICE_ERROR   Fail\r
151     \r
152 --*/\r
153 {\r
154   ASSERT (mUsbCapabilityLen);\r
155   return HcDev->PciIo->Mem.Read (\r
156                              HcDev->PciIo,\r
157                              EfiPciIoWidthUint32,\r
158                              USB_BAR_INDEX,\r
159                              (UINT64) (OperationalRegAddr + mUsbCapabilityLen),\r
160                              1,\r
161                              Data\r
162                              );\r
163 }\r
164 \r
165 EFI_STATUS\r
166 WriteEhcOperationalReg (\r
167   IN USB2_HC_DEV             *HcDev,\r
168   IN UINT32                  OperationalRegAddr,\r
169   IN UINT32                  Data\r
170   )\r
171 /*++\r
172 \r
173 Routine Description:\r
174 \r
175   Write  Ehc Operation register\r
176   \r
177 Arguments:\r
178 \r
179   HcDev                - USB2_HC_DEV \r
180   OperationalRegAddr   - Ehc Operation register address\r
181   Data                 - 32bit write to register\r
182   \r
183 Returns:\r
184 \r
185   EFI_SUCCESS        Success\r
186   EFI_DEVICE_ERROR   Fail\r
187   \r
188 --*/\r
189 {\r
190   ASSERT (mUsbCapabilityLen);\r
191   return HcDev->PciIo->Mem.Write (\r
192                              HcDev->PciIo,\r
193                              EfiPciIoWidthUint32,\r
194                              USB_BAR_INDEX,\r
195                              (UINT64) (OperationalRegAddr + mUsbCapabilityLen),\r
196                              1,\r
197                              &Data\r
198                              );\r
199 }\r
200 \r
201 VOID\r
202 ClearLegacySupport (\r
203   IN USB2_HC_DEV     *HcDev\r
204   )\r
205 /*++\r
206 \r
207 Routine Description:\r
208 \r
209   Stop the legacy USB SMI\r
210 \r
211 Arguments:\r
212 \r
213   HcDev - USB2_HC_DEV\r
214 \r
215 Returns:\r
216 \r
217   EFI_SUCCESS       Success\r
218   EFI_DEVICE_ERROR  Fail\r
219 \r
220 --*/\r
221 {\r
222   UINT32  EECP;\r
223   UINT32  Value;\r
224   UINT32  TimeOut;\r
225 \r
226   ReadEhcCapabiltiyReg (\r
227     HcDev,\r
228     HCCPARAMS,\r
229     &EECP\r
230     );\r
231 \r
232   EECP = (EECP >> 8) & 0xFF;\r
233 \r
234   DEBUG ((gEHCDebugLevel, "EHCI: EECPBase = 0x%x\n", EECP));\r
235 \r
236 \r
237   HcDev->PciIo->Pci.Read (\r
238                      HcDev->PciIo,\r
239                      EfiPciIoWidthUint32,\r
240                      EECP,\r
241                      1,\r
242                      &Value \r
243                      );\r
244 \r
245   DEBUG((gEHCDebugLevel, "EECP[0] = 0x%x\n", Value));\r
246 \r
247   HcDev->PciIo->Pci.Read (\r
248                      HcDev->PciIo,\r
249                      EfiPciIoWidthUint32,\r
250                      EECP + 0x4,\r
251                      1,\r
252                      &Value \r
253                      );\r
254 \r
255   DEBUG((gEHCDebugLevel, "EECP[4] = 0x%x\n", Value));\r
256 \r
257   HcDev->PciIo->Pci.Read (\r
258                      HcDev->PciIo,\r
259                      EfiPciIoWidthUint32,\r
260                      EECP,\r
261                      1,\r
262                      &Value \r
263                      );\r
264 \r
265   Value = Value | (0x1 << 24);\r
266   DEBUG((gEHCErrorLevel, "Value Written = 0x%x\n", Value));\r
267 \r
268   HcDev->PciIo->Pci.Write (\r
269                      HcDev->PciIo,\r
270                      EfiPciIoWidthUint32,\r
271                      EECP,\r
272                      1,\r
273                      &Value \r
274                      );\r
275 \r
276  TimeOut = 40;\r
277  while (TimeOut --) {\r
278    gBS->Stall (500);\r
279 \r
280    HcDev->PciIo->Pci.Read (\r
281                       HcDev->PciIo,\r
282                       EfiPciIoWidthUint32,\r
283                       EECP,\r
284                       1,\r
285                       &Value \r
286                       );\r
287   if ((Value & 0x01010000) == 0x01000000) {\r
288     break;\r
289   }\r
290  }\r
291 \r
292   if (TimeOut == 0) {\r
293     DEBUG((gEHCErrorLevel, "Timeout for getting HC OS Owned Semaphore\n" ));\r
294   } \r
295   \r
296   DEBUG((gEHCErrorLevel, "After Release Value\n" ));\r
297 \r
298   HcDev->PciIo->Pci.Read (\r
299                      HcDev->PciIo,\r
300                      EfiPciIoWidthUint32,\r
301                      EECP,\r
302                      1,\r
303                      &Value \r
304                      );\r
305 \r
306   DEBUG((gEHCDebugLevel, "EECP[0] = 0x%x\n", Value));\r
307 \r
308   HcDev->PciIo->Pci.Read (\r
309                      HcDev->PciIo,\r
310                      EfiPciIoWidthUint32,\r
311                      EECP + 0x4,\r
312                      1,\r
313                      &Value \r
314                      );\r
315 \r
316   DEBUG((gEHCDebugLevel, "EECP[4] = 0x%x\n", Value));\r
317 \r
318 \r
319 }\r
320 \r
321 EFI_STATUS\r
322 GetCapabilityLen (\r
323   IN USB2_HC_DEV     *HcDev\r
324   )\r
325 /*++\r
326 \r
327 Routine Description:\r
328 \r
329   Get the length of capability register\r
330   \r
331 Arguments:\r
332 \r
333   HcDev - USB2_HC_DEV \r
334   \r
335 Returns:\r
336 \r
337   EFI_SUCCESS       Success\r
338   EFI_DEVICE_ERROR  Fail\r
339     \r
340 --*/\r
341 {\r
342   EFI_STATUS  Status;\r
343   UINT32      CapabilityLenAddr;\r
344 \r
345   CapabilityLenAddr = CAPLENGTH;\r
346 \r
347   Status = ReadEhcCapabiltiyReg (\r
348              HcDev,\r
349              CapabilityLenAddr,\r
350              &mUsbCapabilityLen\r
351              );\r
352   mUsbCapabilityLen = (UINT8) mUsbCapabilityLen;\r
353 \r
354   return Status;\r
355 }\r
356 \r
357 EFI_STATUS\r
358 SetFrameListLen (\r
359   IN USB2_HC_DEV     *HcDev,\r
360   IN UINTN           Length\r
361   )\r
362 /*++\r
363 \r
364 Routine Description:\r
365 \r
366   Set the length of Frame List\r
367   \r
368 Arguments:\r
369 \r
370   HcDev    - USB2_HC_DEV \r
371   Length   - the required length of frame list\r
372   \r
373 Returns:\r
374 \r
375   EFI_SUCCESS            Success\r
376   EFI_INVALID_PARAMETER  Invalid parameter\r
377   EFI_DEVICE_ERROR       Fail\r
378   \r
379 --*/\r
380 {\r
381   EFI_STATUS  Status;\r
382   UINT32      UsbCommandAddr;\r
383   UINT32      UsbCommandReg;\r
384 \r
385   UsbCommandAddr = USBCMD;\r
386 \r
387   if (256 != Length && 512 != Length) {\r
388     Status = EFI_INVALID_PARAMETER;\r
389     goto exit;\r
390   }\r
391 \r
392   Status = ReadEhcOperationalReg (\r
393              HcDev,\r
394              UsbCommandAddr,\r
395              &UsbCommandReg\r
396              );\r
397   if (EFI_ERROR (Status)) {\r
398     Status = EFI_DEVICE_ERROR;\r
399     goto exit;\r
400   }\r
401 \r
402   if (256 == Length) {\r
403     UsbCommandReg |= USBCMD_FLS_256;\r
404   } else {\r
405     UsbCommandReg |= USBCMD_FLS_512;\r
406   }\r
407 \r
408   Status = WriteEhcOperationalReg (\r
409              HcDev,\r
410              UsbCommandAddr,\r
411              UsbCommandReg\r
412              );\r
413   if (EFI_ERROR (Status)) {\r
414     Status = EFI_DEVICE_ERROR;\r
415   }\r
416 \r
417 exit:\r
418   return Status;\r
419 }\r
420 \r
421 EFI_STATUS\r
422 SetFrameListBaseAddr (\r
423   IN USB2_HC_DEV     *HcDev,\r
424   IN UINT32          FrameBuffer\r
425   )\r
426 /*++\r
427 \r
428 Routine Description:\r
429 \r
430   Set base address of frame list first entry\r
431   \r
432 Arguments:\r
433 \r
434   HcDev        - USB2_HC_DEV \r
435   FrameBuffer  - base address of first entry of frame list\r
436   \r
437 Returns:\r
438   \r
439 --*/\r
440 {\r
441   EFI_STATUS  Status;\r
442   UINT32      PeriodicListBaseAddr;\r
443   UINT32      PeriodicListBaseReg;\r
444 \r
445   Status                = EFI_SUCCESS;\r
446   PeriodicListBaseAddr  = PERIODICLISTBASE;\r
447   PeriodicListBaseReg   = FrameBuffer & 0xfffff000;\r
448 \r
449   if (IsEhcHalted (HcDev)) {\r
450 \r
451     Status = WriteEhcOperationalReg (\r
452                HcDev,\r
453                PeriodicListBaseAddr,\r
454                PeriodicListBaseReg\r
455                );\r
456     if (EFI_ERROR (Status)) {\r
457       Status = EFI_DEVICE_ERROR;\r
458       goto exit;\r
459     }\r
460 \r
461   }\r
462 \r
463 exit:\r
464   return Status;\r
465 }\r
466 \r
467 EFI_STATUS\r
468 SetAsyncListAddr (\r
469   IN USB2_HC_DEV        *HcDev,\r
470   IN EHCI_QH_ENTITY     *QhPtr\r
471   )\r
472 /*++\r
473 \r
474 Routine Description:\r
475 \r
476   Set address of first Async schedule Qh\r
477   \r
478 Arguments:\r
479 \r
480   HcDev   - USB2_HC_DEV \r
481   QhPtr   - A pointer to first Qh in the Async schedule\r
482   \r
483 Returns:\r
484 \r
485   EFI_SUCCESS       Success\r
486   EFI_DEVICE_ERROR  Fail\r
487     \r
488 --*/\r
489 {\r
490   EFI_STATUS  Status;\r
491   UINT32      AsyncListAddr;\r
492   UINT32      AsyncListReg;\r
493 \r
494   AsyncListAddr = ASYNCLISTADDR;\r
495   AsyncListReg  = (UINT32) GET_0B_TO_31B (&(QhPtr->Qh));\r
496 \r
497   Status = WriteEhcOperationalReg (\r
498              HcDev,\r
499              AsyncListAddr,\r
500              AsyncListReg\r
501              );\r
502 \r
503   return Status;\r
504 }\r
505 \r
506 EFI_STATUS\r
507 SetCtrlDataStructSeg (\r
508   IN USB2_HC_DEV     *HcDev\r
509   )\r
510 /*++\r
511 \r
512 Routine Description:\r
513 \r
514   Set register of control and data structure segment\r
515   \r
516 Arguments:\r
517 \r
518   HcDev  - USB2_HC_DEV \r
519   \r
520 Returns:\r
521 \r
522   EFI_SUCCESS       Success\r
523   EFI_DEVICE_ERROR  Fail\r
524   \r
525 \r
526 --*/\r
527 {\r
528   EFI_STATUS  Status;\r
529   UINT32      CtrlDsSegmentAddr;\r
530   UINT32      CtrlDsSegmentReg;\r
531 \r
532   CtrlDsSegmentAddr = CTRLDSSGMENT;\r
533   CtrlDsSegmentReg  = HcDev->High32BitAddr;\r
534 \r
535   Status = WriteEhcOperationalReg (\r
536              HcDev,\r
537              CtrlDsSegmentAddr,\r
538              CtrlDsSegmentReg\r
539              );\r
540 \r
541   return Status;\r
542 }\r
543 \r
544 EFI_STATUS\r
545 SetPortRoutingEhc (\r
546   IN USB2_HC_DEV     *HcDev\r
547   )\r
548 /*++\r
549 \r
550 Routine Description:\r
551 \r
552   Set Ehc port routing bit\r
553   \r
554 Arguments:\r
555 \r
556   HcDev - USB2_HC_DEV \r
557   \r
558 Returns:\r
559 \r
560   EFI_SUCCESS       Success\r
561   EFI_DEVICE_ERROR  Fail\r
562     \r
563 --*/\r
564 {\r
565   EFI_STATUS  Status;\r
566   UINT32      ConfigFlagAddr;\r
567   UINT32      ConfigFlagReg;\r
568 \r
569   ConfigFlagAddr = CONFIGFLAG;\r
570 \r
571   Status = ReadEhcOperationalReg (\r
572              HcDev,\r
573              ConfigFlagAddr,\r
574              &ConfigFlagReg\r
575              );\r
576   if (EFI_ERROR (Status)) {\r
577     Status = EFI_DEVICE_ERROR;\r
578     goto exit;\r
579   }\r
580 \r
581   ConfigFlagReg |= CONFIGFLAG_CF;\r
582   Status = WriteEhcOperationalReg (\r
583              HcDev,\r
584              ConfigFlagAddr,\r
585              ConfigFlagReg\r
586              );\r
587   if (EFI_ERROR (Status)) {\r
588     Status = EFI_DEVICE_ERROR;\r
589   }\r
590 \r
591 exit:\r
592   return Status;\r
593 }\r
594 \r
595 EFI_STATUS\r
596 SetEhcDoorbell (\r
597   IN  USB2_HC_DEV     *HcDev\r
598   )\r
599 /*++\r
600 \r
601 Routine Description:\r
602 \r
603   Set Ehc door bell bit\r
604   \r
605 Arguments:\r
606 \r
607   HcDev - USB2_HC_DEV \r
608   \r
609 Returns:\r
610 \r
611   EFI_SUCCESS       Success\r
612   EFI_DEVICE_ERROR  Fail\r
613      \r
614 --*/\r
615 {\r
616   EFI_STATUS  Status;\r
617   UINT32      UsbCommandAddr;\r
618   UINT32      UsbCommandReg;\r
619 \r
620   UsbCommandAddr = USBCMD;\r
621 \r
622   Status = ReadEhcOperationalReg (\r
623              HcDev,\r
624              UsbCommandAddr,\r
625              &UsbCommandReg\r
626              );\r
627   if (EFI_ERROR (Status)) {\r
628     Status = EFI_DEVICE_ERROR;\r
629     goto exit;\r
630   }\r
631 \r
632   UsbCommandReg |= USBCMD_IAAD;\r
633   Status = WriteEhcOperationalReg (\r
634              HcDev,\r
635              UsbCommandAddr,\r
636              UsbCommandReg\r
637              );\r
638   if (EFI_ERROR (Status)) {\r
639     Status = EFI_DEVICE_ERROR;\r
640   }\r
641 \r
642 exit:\r
643   return Status;\r
644 }\r
645 \r
646 EFI_STATUS\r
647 ClearEhcAllStatus (\r
648   IN  USB2_HC_DEV     *HcDev\r
649   )\r
650 /*++\r
651 \r
652 Routine Description:\r
653 \r
654   Clear Ehc all status bits\r
655   \r
656 Arguments:\r
657 \r
658   HcDev - USB2_HC_DEV \r
659   \r
660 Returns:\r
661 \r
662   EFI_SUCCESS       Success\r
663   EFI_DEVICE_ERROR  Fail\r
664      \r
665 --*/\r
666 {\r
667   UINT32  UsbStatusAddr;\r
668 \r
669   UsbStatusAddr = USBSTS;\r
670 \r
671   return WriteEhcOperationalReg (\r
672            HcDev,\r
673            UsbStatusAddr,\r
674            0x003F\r
675            );\r
676 }\r
677 \r
678 EFI_STATUS\r
679 EnablePeriodicSchedule (\r
680   IN  USB2_HC_DEV     *HcDev\r
681   )\r
682 /*++\r
683 \r
684 Routine Description:\r
685 \r
686   Enable periodic schedule\r
687   \r
688 Arguments:\r
689 \r
690   HcDev - USB2_HC_DEV \r
691   \r
692 Returns:\r
693 \r
694   EFI_SUCCESS       Success\r
695   EFI_DEVICE_ERROR  Fail\r
696    \r
697 --*/\r
698 {\r
699   EFI_STATUS  Status;\r
700   UINT32      UsbCommandAddr;\r
701   UINT32      UsbCommandReg;\r
702 \r
703   UsbCommandAddr = USBCMD;\r
704 \r
705   Status = ReadEhcOperationalReg (\r
706              HcDev,\r
707              UsbCommandAddr,\r
708              &UsbCommandReg\r
709              );\r
710   if (EFI_ERROR (Status)) {\r
711     Status = EFI_DEVICE_ERROR;\r
712     goto exit;\r
713   }\r
714 \r
715   UsbCommandReg |= USBCMD_PSE;\r
716   Status = WriteEhcOperationalReg (\r
717              HcDev,\r
718              UsbCommandAddr,\r
719              UsbCommandReg\r
720              );\r
721   if (EFI_ERROR (Status)) {\r
722     Status = EFI_DEVICE_ERROR;\r
723   }\r
724 \r
725 exit:\r
726   return Status;\r
727 }\r
728 \r
729 EFI_STATUS\r
730 DisablePeriodicSchedule (\r
731   IN  USB2_HC_DEV     *HcDev\r
732   )\r
733 /*++\r
734 \r
735 Routine Description:\r
736 \r
737   Disable periodic schedule\r
738   \r
739 Arguments:\r
740 \r
741   HcDev - USB2_HC_DEV \r
742   \r
743 Returns:\r
744 \r
745   EFI_SUCCESS       Success\r
746   EFI_DEVICE_ERROR  Fail\r
747    \r
748 --*/\r
749 {\r
750   EFI_STATUS  Status;\r
751   UINT32      UsbCommandAddr;\r
752   UINT32      UsbCommandReg;\r
753 \r
754   UsbCommandAddr = USBCMD;\r
755 \r
756   Status = ReadEhcOperationalReg (\r
757              HcDev,\r
758              UsbCommandAddr,\r
759              &UsbCommandReg\r
760              );\r
761   if (EFI_ERROR (Status)) {\r
762     return EFI_DEVICE_ERROR;\r
763   }\r
764 \r
765   UsbCommandReg &= ~USBCMD_PSE;\r
766   Status = WriteEhcOperationalReg (\r
767              HcDev,\r
768              UsbCommandAddr,\r
769              UsbCommandReg\r
770              );\r
771   if (EFI_ERROR (Status)) {\r
772     return EFI_DEVICE_ERROR;\r
773   }\r
774 \r
775   return Status;\r
776 }\r
777 \r
778 EFI_STATUS\r
779 EnableAsynchronousSchedule (\r
780   IN  USB2_HC_DEV     *HcDev\r
781   )\r
782 /*++\r
783 \r
784 Routine Description:\r
785 \r
786   Enable asynchrounous schedule\r
787   \r
788 Arguments:\r
789 \r
790   HcDev - USB2_HC_DEV \r
791   \r
792 Returns:\r
793 \r
794   EFI_SUCCESS       Success\r
795   EFI_DEVICE_ERROR  Fail\r
796     \r
797 --*/\r
798 {\r
799   EFI_STATUS  Status;\r
800   UINT32      UsbCommandAddr;\r
801   UINT32      UsbCommandReg;\r
802 \r
803   UsbCommandAddr = USBCMD;\r
804 \r
805   Status = ReadEhcOperationalReg (\r
806              HcDev,\r
807              UsbCommandAddr,\r
808              &UsbCommandReg\r
809              );\r
810   if (EFI_ERROR (Status)) {\r
811     Status = EFI_DEVICE_ERROR;\r
812     goto exit;\r
813   }\r
814 \r
815   UsbCommandReg |= USBCMD_ASE;\r
816   Status = WriteEhcOperationalReg (\r
817              HcDev,\r
818              UsbCommandAddr,\r
819              UsbCommandReg\r
820              );\r
821   if (EFI_ERROR (Status)) {\r
822     Status = EFI_DEVICE_ERROR;\r
823   }\r
824 \r
825 exit:\r
826   return Status;\r
827 }\r
828 \r
829 EFI_STATUS\r
830 DisableAsynchronousSchedule (\r
831   IN  USB2_HC_DEV     *HcDev\r
832   )\r
833 /*++\r
834 \r
835 Routine Description:\r
836 \r
837   Disable asynchrounous schedule\r
838   \r
839 Arguments:\r
840 \r
841   HcDev - USB2_HC_DEV \r
842   \r
843 Returns:\r
844 \r
845   EFI_SUCCESS       Success\r
846   EFI_DEVICE_ERROR  Fail\r
847    \r
848 --*/\r
849 {\r
850   EFI_STATUS  Status;\r
851   UINT32      UsbCommandAddr;\r
852   UINT32      UsbCommandReg;\r
853 \r
854   UsbCommandAddr = USBCMD;\r
855 \r
856   Status = ReadEhcOperationalReg (\r
857              HcDev,\r
858              UsbCommandAddr,\r
859              &UsbCommandReg\r
860              );\r
861   if (EFI_ERROR (Status)) {\r
862     return EFI_DEVICE_ERROR;\r
863   }\r
864 \r
865   UsbCommandReg &= ~USBCMD_ASE;\r
866   Status = WriteEhcOperationalReg (\r
867              HcDev,\r
868              UsbCommandAddr,\r
869              UsbCommandReg\r
870              );\r
871   if (EFI_ERROR (Status)) {\r
872     return EFI_DEVICE_ERROR;\r
873   }\r
874 \r
875   return Status;\r
876 }\r
877 \r
878 EFI_STATUS\r
879 ResetEhc (\r
880   IN  USB2_HC_DEV     *HcDev\r
881   )\r
882 /*++\r
883 \r
884 Routine Description:\r
885 \r
886   Reset Ehc\r
887   \r
888 Arguments:\r
889 \r
890   HcDev - USB2_HC_DEV \r
891   \r
892 Returns:\r
893 \r
894   EFI_SUCCESS       Success\r
895   EFI_DEVICE_ERROR  Fail\r
896    \r
897 --*/\r
898 {\r
899   EFI_STATUS  Status;\r
900   UINT32      UsbCommandAddr;\r
901   UINT32      UsbCommandReg;\r
902 \r
903   UsbCommandAddr = USBCMD;\r
904 \r
905   Status = ReadEhcOperationalReg (\r
906              HcDev,\r
907              UsbCommandAddr,\r
908              &UsbCommandReg\r
909              );\r
910   if (EFI_ERROR (Status)) {\r
911     Status = EFI_DEVICE_ERROR;\r
912     goto exit;\r
913   }\r
914 \r
915   UsbCommandReg |= USBCMD_HCRESET;\r
916   Status = WriteEhcOperationalReg (\r
917              HcDev,\r
918              UsbCommandAddr,\r
919              UsbCommandReg\r
920              );\r
921   if (EFI_ERROR (Status)) {\r
922     Status = EFI_DEVICE_ERROR;\r
923   }\r
924 \r
925 exit:\r
926   return Status;\r
927 }\r
928 \r
929 EFI_STATUS\r
930 StartScheduleExecution (\r
931   IN  USB2_HC_DEV     *HcDev\r
932   )\r
933 /*++\r
934 \r
935 Routine Description:\r
936 \r
937   Start Ehc schedule execution\r
938   \r
939 Arguments:\r
940 \r
941   HcDev - USB2_HC_DEV \r
942   \r
943 Returns:\r
944 \r
945   EFI_SUCCESS       Success\r
946   EFI_DEVICE_ERROR  Fail\r
947    \r
948 --*/\r
949 {\r
950   EFI_STATUS  Status;\r
951   UINT32      UsbCommandAddr;\r
952   UINT32      UsbCommandReg;\r
953 \r
954   UsbCommandAddr = USBCMD;\r
955 \r
956   Status = ReadEhcOperationalReg (\r
957              HcDev,\r
958              UsbCommandAddr,\r
959              &UsbCommandReg\r
960              );\r
961   if (EFI_ERROR (Status)) {\r
962     Status = EFI_DEVICE_ERROR;\r
963     goto exit;\r
964   }\r
965 \r
966   UsbCommandReg |= USBCMD_RS;\r
967   Status = WriteEhcOperationalReg (\r
968              HcDev,\r
969              UsbCommandAddr,\r
970              UsbCommandReg\r
971              );\r
972   if (EFI_ERROR (Status)) {\r
973     Status = EFI_DEVICE_ERROR;\r
974   }\r
975 \r
976 exit:\r
977   return Status;\r
978 }\r
979 \r
980 BOOLEAN\r
981 IsFrameListProgrammable (\r
982   IN  USB2_HC_DEV     *HcDev\r
983   )\r
984 /*++\r
985 \r
986 Routine Description:\r
987 \r
988   Whether frame list is programmable\r
989   \r
990 Arguments:\r
991 \r
992   HcDev - USB2_HC_DEV \r
993   \r
994 Returns:\r
995 \r
996   TRUE   Programmable\r
997   FALSE  Unprogrammable\r
998   \r
999 --*/\r
1000 {\r
1001   BOOLEAN Value;\r
1002   UINT32  HcCapParamsAddr;\r
1003   UINT32  HcCapParamsReg;\r
1004 \r
1005   HcCapParamsAddr = HCCPARAMS;\r
1006 \r
1007   ReadEhcOperationalReg (\r
1008     HcDev,\r
1009     HcCapParamsAddr,\r
1010     &HcCapParamsReg\r
1011     );\r
1012 \r
1013   if (HcCapParamsReg & HCCP_PFLF) {\r
1014     Value = TRUE;\r
1015   } else {\r
1016     Value = FALSE;\r
1017   }\r
1018 \r
1019   return Value;\r
1020 }\r
1021 \r
1022 BOOLEAN\r
1023 IsPeriodicScheduleEnabled (\r
1024   IN  USB2_HC_DEV     *HcDev\r
1025   )\r
1026 /*++\r
1027 \r
1028 Routine Description:\r
1029 \r
1030   Whether periodic schedule is enabled\r
1031   \r
1032 Arguments:\r
1033 \r
1034   HcDev - USB2_HC_DEV \r
1035   \r
1036 Returns:\r
1037 \r
1038   TRUE    Enabled\r
1039   FALSE   Disabled\r
1040   \r
1041 --*/\r
1042 {\r
1043   BOOLEAN Value;\r
1044   UINT32  UsbStatusAddr;\r
1045   UINT32  UsbStatusReg;\r
1046 \r
1047   UsbStatusAddr = USBSTS;\r
1048 \r
1049   ReadEhcOperationalReg (\r
1050     HcDev,\r
1051     UsbStatusAddr,\r
1052     &UsbStatusReg\r
1053     );\r
1054 \r
1055   if (UsbStatusReg & USBSTS_PSS) {\r
1056     Value = TRUE;\r
1057   } else {\r
1058     Value = FALSE;\r
1059   }\r
1060 \r
1061   return Value;\r
1062 }\r
1063 \r
1064 BOOLEAN\r
1065 IsAsyncScheduleEnabled (\r
1066   IN  USB2_HC_DEV     *HcDev\r
1067   )\r
1068 /*++\r
1069 \r
1070 Routine Description:\r
1071 \r
1072   Whether asynchronous schedule is enabled\r
1073   \r
1074 Arguments:\r
1075 \r
1076   HcDev - USB2_HC_DEV \r
1077   \r
1078 Returns:\r
1079 \r
1080   TRUE   Enabled\r
1081   FALSE  Disabled\r
1082   \r
1083 --*/\r
1084 {\r
1085   BOOLEAN Value;\r
1086   UINT32  UsbStatusAddr;\r
1087   UINT32  UsbStatusReg;\r
1088 \r
1089   UsbStatusAddr = USBSTS;\r
1090 \r
1091   ReadEhcOperationalReg (\r
1092     HcDev,\r
1093     UsbStatusAddr,\r
1094     &UsbStatusReg\r
1095     );\r
1096 \r
1097   if (UsbStatusReg & USBSTS_ASS) {\r
1098     Value = TRUE;\r
1099   } else {\r
1100     Value = FALSE;\r
1101   }\r
1102 \r
1103   return Value;\r
1104 }\r
1105 \r
1106 BOOLEAN\r
1107 IsEhcPortEnabled (\r
1108   IN  USB2_HC_DEV     *HcDev,\r
1109   IN  UINT8           PortNum\r
1110   )\r
1111 /*++\r
1112 \r
1113 Routine Description:\r
1114 \r
1115   Whether port is enabled\r
1116   \r
1117 Arguments:\r
1118 \r
1119   HcDev - USB2_HC_DEV \r
1120   \r
1121 Returns:\r
1122 \r
1123   TRUE   Enabled\r
1124   FALSE  Disabled\r
1125   \r
1126 --*/\r
1127 {\r
1128   UINT32  PortStatusControlAddr;\r
1129   UINT32  PortStatusControlReg;\r
1130 \r
1131   PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNum));\r
1132 \r
1133   ReadEhcOperationalReg (\r
1134     HcDev,\r
1135     PortStatusControlAddr,\r
1136     &PortStatusControlReg\r
1137     );\r
1138 \r
1139   return ((PortStatusControlReg & PORTSC_PED) ? TRUE : FALSE);\r
1140 }\r
1141 \r
1142 BOOLEAN\r
1143 IsEhcReseted (\r
1144   IN  USB2_HC_DEV     *HcDev\r
1145   )\r
1146 /*++\r
1147 \r
1148 Routine Description:\r
1149 \r
1150   Whether Ehc is reseted\r
1151   \r
1152 Arguments:\r
1153 \r
1154   HcDev - USB2_HC_DEV \r
1155   \r
1156 Returns:\r
1157 \r
1158   TRUE   Reseted\r
1159   FALSE  Unreseted\r
1160   \r
1161 --*/\r
1162 {\r
1163   BOOLEAN Value;\r
1164   UINT32  UsbCommandAddr;\r
1165   UINT32  UsbCommandReg;\r
1166 \r
1167   UsbCommandAddr = USBCMD;\r
1168 \r
1169   ReadEhcOperationalReg (\r
1170     HcDev,\r
1171     UsbCommandAddr,\r
1172     &UsbCommandReg\r
1173     );\r
1174 \r
1175   if (UsbCommandReg & USBCMD_HCRESET) {\r
1176     Value = FALSE;\r
1177   } else {\r
1178     Value = TRUE;\r
1179   }\r
1180 \r
1181   return Value;\r
1182 }\r
1183 \r
1184 BOOLEAN\r
1185 IsEhcHalted (\r
1186   IN  USB2_HC_DEV     *HcDev\r
1187   )\r
1188 /*++\r
1189 \r
1190 Routine Description:\r
1191 \r
1192   Whether Ehc is halted\r
1193   \r
1194 Arguments:\r
1195 \r
1196   HcDev - USB2_HC_DEV \r
1197   \r
1198 Returns:\r
1199 \r
1200   TRUE   Halted\r
1201   FALSE  Not halted\r
1202   \r
1203 --*/\r
1204 {\r
1205   BOOLEAN Value;\r
1206   UINT32  UsbStatusAddr;\r
1207   UINT32  UsbStatusReg;\r
1208 \r
1209   UsbStatusAddr = USBSTS;\r
1210 \r
1211   ReadEhcOperationalReg (\r
1212     HcDev,\r
1213     UsbStatusAddr,\r
1214     &UsbStatusReg\r
1215     );\r
1216 \r
1217   if (UsbStatusReg & USBSTS_HCH) {\r
1218     Value = TRUE;\r
1219   } else {\r
1220     Value = FALSE;\r
1221   }\r
1222 \r
1223   return Value;\r
1224 }\r
1225 \r
1226 BOOLEAN\r
1227 IsEhcSysError (\r
1228   IN  USB2_HC_DEV     *HcDev\r
1229   )\r
1230 /*++\r
1231 \r
1232 Routine Description:\r
1233 \r
1234   Whether Ehc is system error\r
1235   \r
1236 Arguments:\r
1237 \r
1238   HcDev - USB2_HC_DEV \r
1239   \r
1240 Returns:\r
1241 \r
1242   TRUE   System error\r
1243   FALSE  No system error\r
1244   \r
1245 --*/\r
1246 {\r
1247   BOOLEAN Value;\r
1248   UINT32  UsbStatusAddr;\r
1249   UINT32  UsbStatusReg;\r
1250 \r
1251   UsbStatusAddr = USBSTS;\r
1252 \r
1253   ReadEhcOperationalReg (\r
1254     HcDev,\r
1255     UsbStatusAddr,\r
1256     &UsbStatusReg\r
1257     );\r
1258 \r
1259   if (UsbStatusReg & USBSTS_HSE) {\r
1260     Value = TRUE;\r
1261   } else {\r
1262     Value = FALSE;\r
1263   }\r
1264 \r
1265   return Value;\r
1266 }\r
1267 \r
1268 BOOLEAN\r
1269 IsHighSpeedDevice (\r
1270   IN EFI_USB2_HC_PROTOCOL *This,\r
1271   IN UINT8                PortNum \r
1272   )\r
1273 /*++\r
1274 \r
1275 Routine Description:\r
1276 \r
1277   Whether high speed device attached\r
1278   \r
1279 Arguments:\r
1280 \r
1281   HcDev - USB2_HC_DEV \r
1282   \r
1283 Returns:\r
1284 \r
1285   TRUE   High speed\r
1286   FALSE  Full speed\r
1287   \r
1288 --*/\r
1289 {\r
1290   USB2_HC_DEV          *HcDev;\r
1291   UINT32               PortStatusControlAddr;\r
1292   UINT32               PortStatusControlReg;\r
1293   \r
1294   HcDev = USB2_HC_DEV_FROM_THIS (This);\r
1295   PortStatusControlAddr = (UINT32) (PORTSC + (4 * PortNum));\r
1296 \r
1297   //\r
1298   // Set port reset bit\r
1299   //\r
1300   ReadEhcOperationalReg (\r
1301     HcDev,\r
1302     PortStatusControlAddr,\r
1303     &PortStatusControlReg\r
1304     );\r
1305   //\r
1306   // Make sure Host Controller not halt before reset it\r
1307   //\r
1308   if (IsEhcHalted (HcDev)) {\r
1309     StartScheduleExecution (HcDev);\r
1310     WaitForEhcNotHalt (HcDev, EHCI_GENERIC_TIMEOUT);\r
1311   }\r
1312   PortStatusControlReg &= 0xffffffd5;\r
1313   PortStatusControlReg |= PORTSC_PR;\r
1314   //\r
1315   // Set one to PortReset bit must also set zero to PortEnable bit\r
1316   //\r
1317   PortStatusControlReg &= ~PORTSC_PED;\r
1318   WriteEhcOperationalReg (\r
1319     HcDev,\r
1320     PortStatusControlAddr,\r
1321     PortStatusControlReg\r
1322     );\r
1323 \r
1324   //\r
1325   // Set Port reset recovery time\r
1326   //\r
1327   gBS->Stall (EHCI_SET_PORT_RESET_RECOVERY_TIME);\r
1328 \r
1329   //\r
1330   // Clear port reset bit\r
1331   //\r
1332   ReadEhcOperationalReg (\r
1333     HcDev,\r
1334     PortStatusControlAddr,\r
1335     &PortStatusControlReg\r
1336     );\r
1337   PortStatusControlReg &= 0xffffffd5;\r
1338   PortStatusControlReg &= ~PORTSC_PR;\r
1339   WriteEhcOperationalReg (\r
1340     HcDev,\r
1341     PortStatusControlAddr,\r
1342     PortStatusControlReg\r
1343     );\r
1344 \r
1345   //\r
1346   // Clear port reset recovery time\r
1347   //\r
1348   gBS->Stall (EHCI_CLEAR_PORT_RESET_RECOVERY_TIME);\r
1349 \r
1350   return (IsEhcPortEnabled (HcDev, PortNum) ? TRUE : FALSE);\r
1351 }\r
1352 \r
1353 EFI_STATUS\r
1354 WaitForEhcReset (\r
1355   IN USB2_HC_DEV             *HcDev,\r
1356   IN UINTN                   Timeout\r
1357   )\r
1358 /*++\r
1359 \r
1360 Routine Description:\r
1361 \r
1362   wait for Ehc reset or timeout\r
1363   \r
1364 Arguments:\r
1365 \r
1366   HcDev   - USB2_HC_DEV \r
1367   Timeout - timeout threshold\r
1368   \r
1369 Returns:\r
1370 \r
1371   EFI_SUCCESS    Success\r
1372   EFI_TIMEOUT    Timeout\r
1373   \r
1374 --*/\r
1375 {\r
1376   EFI_STATUS  Status;\r
1377   UINTN       Delay;\r
1378 \r
1379   //\r
1380   // Timeout is in US unit\r
1381   //\r
1382   Delay = (Timeout / 50) + 1;\r
1383   do {\r
1384 \r
1385     if (IsEhcReseted (HcDev)) {\r
1386       Status = EFI_SUCCESS;\r
1387       goto exit;\r
1388     }\r
1389     gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
1390 \r
1391   } while (Delay--);\r
1392 \r
1393   Status = EFI_TIMEOUT;\r
1394 \r
1395 exit:\r
1396   return Status;\r
1397 }\r
1398 \r
1399 EFI_STATUS\r
1400 WaitForEhcHalt (\r
1401   IN USB2_HC_DEV             *HcDev,\r
1402   IN UINTN                   Timeout\r
1403   )\r
1404 /*++\r
1405 \r
1406 Routine Description:\r
1407 \r
1408   wait for Ehc halt or timeout\r
1409   \r
1410 Arguments:\r
1411 \r
1412   HcDev   - USB2_HC_DEV \r
1413   Timeout - timeout threshold\r
1414   \r
1415 Returns:\r
1416 \r
1417   EFI_SUCCESS    Success\r
1418   EFI_TIMEOUT    Timeout\r
1419   \r
1420 --*/\r
1421 {\r
1422   EFI_STATUS  Status;\r
1423   UINTN       Delay;\r
1424 \r
1425   //\r
1426   // Timeout is in US unit\r
1427   //\r
1428   Delay = (Timeout / 50) + 1;\r
1429   do {\r
1430 \r
1431     if (IsEhcHalted (HcDev)) {\r
1432       Status = EFI_SUCCESS;\r
1433       goto exit;\r
1434     }\r
1435     gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
1436 \r
1437   } while (Delay--);\r
1438 \r
1439   Status = EFI_TIMEOUT;\r
1440 \r
1441 exit:\r
1442   return Status;\r
1443 }\r
1444 \r
1445 EFI_STATUS\r
1446 WaitForEhcNotHalt (\r
1447   IN USB2_HC_DEV             *HcDev,\r
1448   IN UINTN                   Timeout\r
1449   )\r
1450 /*++\r
1451 \r
1452 Routine Description:\r
1453 \r
1454   wait for Ehc not halt or timeout\r
1455   \r
1456 Arguments:\r
1457 \r
1458   HcDev   - USB2_HC_DEV \r
1459   Timeout - timeout threshold\r
1460   \r
1461 Returns:\r
1462 \r
1463   EFI_SUCCESS    Success\r
1464   EFI_TIMEOUT    Timeout\r
1465   \r
1466 --*/\r
1467 {\r
1468   EFI_STATUS  Status;\r
1469   UINTN       Delay;\r
1470 \r
1471   //\r
1472   // Timeout is in US unit\r
1473   //\r
1474   Delay = (Timeout / 50) + 1;\r
1475   do {\r
1476 \r
1477     if (!IsEhcHalted (HcDev)) {\r
1478       Status = EFI_SUCCESS;\r
1479       goto exit;\r
1480     }\r
1481     gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
1482 \r
1483   } while (Delay--);\r
1484 \r
1485   Status = EFI_TIMEOUT;\r
1486 \r
1487 exit:\r
1488   return Status;\r
1489 }\r
1490 \r
1491 EFI_STATUS\r
1492 WaitForAsyncScheduleEnable (\r
1493   IN  USB2_HC_DEV            *HcDev,\r
1494   IN UINTN                   Timeout\r
1495   )\r
1496 /*++\r
1497 \r
1498 Routine Description:\r
1499 \r
1500   Wait for Ehc asynchronous schedule enable or timeout\r
1501   \r
1502 Arguments:\r
1503 \r
1504   HcDev   - USB2_HC_DEV \r
1505   Timeout - timeout threshold\r
1506   \r
1507 Returns:\r
1508 \r
1509   EFI_SUCCESS    Success\r
1510   EFI_TIMEOUT    Timeout\r
1511   \r
1512 --*/\r
1513 {\r
1514   EFI_STATUS  Status;\r
1515   UINTN       Delay;\r
1516 \r
1517   //\r
1518   // Timeout is in US unit\r
1519   //\r
1520   Delay = (Timeout / 50) + 1;\r
1521   do {\r
1522 \r
1523     if (IsAsyncScheduleEnabled (HcDev)) {\r
1524       Status = EFI_SUCCESS;\r
1525       goto exit;\r
1526     }\r
1527     gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
1528 \r
1529   } while (Delay--);\r
1530 \r
1531   Status = EFI_TIMEOUT;\r
1532 \r
1533 exit:\r
1534   return Status;\r
1535 }\r
1536 \r
1537 EFI_STATUS\r
1538 WaitForAsyncScheduleDisable (\r
1539   IN USB2_HC_DEV             *HcDev,\r
1540   IN UINTN                   Timeout\r
1541   )\r
1542 /*++\r
1543 \r
1544 Routine Description:\r
1545 \r
1546   Wait for Ehc asynchronous schedule disable or timeout\r
1547   \r
1548 Arguments:\r
1549 \r
1550   HcDev   - USB2_HC_DEV \r
1551   Timeout - timeout threshold\r
1552   \r
1553 Returns:\r
1554 \r
1555   EFI_SUCCESS    Success\r
1556   EFI_TIMEOUT    Timeout\r
1557   \r
1558 --*/\r
1559 {\r
1560   EFI_STATUS  Status;\r
1561   UINTN       Delay;\r
1562 \r
1563   //\r
1564   // Timeout is in US unit\r
1565   //\r
1566   Delay = (Timeout / 50) + 1;\r
1567   do {\r
1568 \r
1569     if (!IsAsyncScheduleEnabled (HcDev)) {\r
1570       Status = EFI_SUCCESS;\r
1571       goto exit;\r
1572     }\r
1573     gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
1574 \r
1575   } while (Delay--);\r
1576 \r
1577   Status = EFI_TIMEOUT;\r
1578 \r
1579 exit:\r
1580   return Status;\r
1581 }\r
1582 \r
1583 EFI_STATUS\r
1584 WaitForPeriodicScheduleEnable (\r
1585   IN USB2_HC_DEV             *HcDev,\r
1586   IN UINTN                   Timeout\r
1587   )\r
1588 /*++\r
1589 \r
1590 Routine Description:\r
1591 \r
1592   Wait for Ehc periodic schedule enable or timeout\r
1593   \r
1594 Arguments:\r
1595 \r
1596   HcDev   - USB2_HC_DEV \r
1597   Timeout - timeout threshold\r
1598   \r
1599 Returns:\r
1600 \r
1601   EFI_SUCCESS    Success\r
1602   EFI_TIMEOUT    Timeout\r
1603   \r
1604 --*/\r
1605 {\r
1606   EFI_STATUS  Status;\r
1607   UINTN       Delay;\r
1608 \r
1609   //\r
1610   // Timeout is in US unit\r
1611   //\r
1612   Delay = (Timeout / 50) + 1;\r
1613   do {\r
1614 \r
1615     if (IsPeriodicScheduleEnabled (HcDev)) {\r
1616       Status = EFI_SUCCESS;\r
1617       goto exit;\r
1618     }\r
1619     gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
1620 \r
1621   } while (Delay--);\r
1622 \r
1623   Status = EFI_TIMEOUT;\r
1624 \r
1625 exit:\r
1626   return Status;\r
1627 }\r
1628 \r
1629 EFI_STATUS\r
1630 WaitForPeriodicScheduleDisable (\r
1631   IN USB2_HC_DEV             *HcDev,\r
1632   IN UINTN                   Timeout\r
1633   )\r
1634 /*++\r
1635 \r
1636 Routine Description:\r
1637 \r
1638   Wait for periodic schedule disable or timeout\r
1639   \r
1640 Arguments:\r
1641 \r
1642   HcDev   - USB2_HC_DEV \r
1643   Timeout - timeout threshold\r
1644   \r
1645 Returns:\r
1646 \r
1647   EFI_SUCCESS    Success\r
1648   EFI_TIMEOUT    Timeout\r
1649   \r
1650 --*/\r
1651 {\r
1652   EFI_STATUS  Status;\r
1653   UINTN       Delay;\r
1654 \r
1655   //\r
1656   // Timeout is in US unit\r
1657   //\r
1658   Delay = (Timeout / 50) + 1;\r
1659   do {\r
1660 \r
1661     if (!IsPeriodicScheduleEnabled (HcDev)) {\r
1662       Status = EFI_SUCCESS;\r
1663       goto exit;\r
1664     }\r
1665     gBS->Stall (EHCI_GENERIC_RECOVERY_TIME);\r
1666 \r
1667   } while (Delay--);\r
1668 \r
1669   Status = EFI_TIMEOUT;\r
1670 \r
1671 exit:\r
1672   return Status;\r
1673 }\r
1674 \r
1675 EFI_STATUS\r
1676 WaitForEhcDoorbell (\r
1677   IN USB2_HC_DEV             *HcDev,\r
1678   IN UINTN                   Timeout\r
1679   )\r
1680 /*++\r
1681 \r
1682 Routine Description:\r
1683 \r
1684   Wait for periodic schedule disable or timeout\r
1685 \r
1686 Arguments:\r
1687 \r
1688   HcDev   - USB2_HC_DEV \r
1689   Timeout - timeout threshold\r
1690 \r
1691 Returns:\r
1692 \r
1693   EFI_SUCCESS    Success\r
1694   EFI_TIMEOUT    Timeout\r
1695   \r
1696 --*/\r
1697 {\r
1698   EFI_STATUS  Status;\r
1699   UINT32      UsbCommandAddr;\r
1700   UINT32      UsbCommandReg;\r
1701   UINTN       Delay;\r
1702 \r
1703   UsbCommandAddr  = USBCMD;\r
1704   Delay           = (Timeout / 50) + 1;\r
1705   \r
1706   do {\r
1707     Status = ReadEhcOperationalReg (\r
1708                HcDev,\r
1709                UsbCommandAddr,\r
1710                &UsbCommandReg\r
1711                );\r
1712     if (EFI_ERROR (Status)) {\r
1713       Status = EFI_DEVICE_ERROR;\r
1714       goto exit;\r
1715     }\r
1716     if (!(UsbCommandReg & USBCMD_IAAD)) {\r
1717       break;\r
1718     }\r
1719         \r
1720   } while (--Delay);\r
1721 \r
1722   if (0 == Delay) {\r
1723     Status = EFI_TIMEOUT;\r
1724   }\r
1725 \r
1726 exit:\r
1727   return Status;\r
1728 }\r