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