]> git.proxmox.com Git - mirror_edk2.git/blame - 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
562d2849 1/*++\r
2\r
4d1fe68e 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
562d2849 11\r
12Module Name:\r
13\r
14 Ehchlp.c\r
4d1fe68e 15\r
16Abstract:\r
17\r
562d2849 18\r
19Revision History\r
20--*/\r
21\r
22#include "Ehci.h"\r
23\r
24\r
74c56167 25VOID\r
26HostReset (\r
27 IN USB2_HC_DEV *HcDev\r
28 )\r
29{\r
30 UINT32 Value;\r
31 UINT32 TimeOut;\r
4d1fe68e 32\r
74c56167 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
562d2849 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
4d1fe68e 105\r
562d2849 106Arguments:\r
107\r
4d1fe68e 108 HcDev - USB2_HC_DEV\r
562d2849 109 CapabiltiyRegAddr - Ehc Capability register address\r
110 Data - A pointer to data read from register\r
4d1fe68e 111\r
562d2849 112Returns:\r
113\r
114 EFI_SUCCESS Success\r
115 EFI_DEVICE_ERROR Fail\r
4d1fe68e 116\r
562d2849 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
4d1fe68e 140\r
562d2849 141Arguments:\r
142\r
4d1fe68e 143 HcDev - USB2_HC_DEV\r
562d2849 144 OperationalRegAddr - Ehc Operation register address\r
145 Data - A pointer to data read from register\r
4d1fe68e 146\r
562d2849 147Returns:\r
148\r
149 EFI_SUCCESS Success\r
150 EFI_DEVICE_ERROR Fail\r
4d1fe68e 151\r
562d2849 152--*/\r
153{\r
37279806 154 ASSERT (HcDev->UsbCapabilityLen);\r
562d2849 155 return HcDev->PciIo->Mem.Read (\r
156 HcDev->PciIo,\r
157 EfiPciIoWidthUint32,\r
158 USB_BAR_INDEX,\r
37279806 159 (UINT64) (OperationalRegAddr + HcDev->UsbCapabilityLen),\r
562d2849 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
4d1fe68e 176\r
562d2849 177Arguments:\r
178\r
4d1fe68e 179 HcDev - USB2_HC_DEV\r
562d2849 180 OperationalRegAddr - Ehc Operation register address\r
181 Data - 32bit write to register\r
4d1fe68e 182\r
562d2849 183Returns:\r
184\r
185 EFI_SUCCESS Success\r
186 EFI_DEVICE_ERROR Fail\r
4d1fe68e 187\r
562d2849 188--*/\r
189{\r
37279806 190 ASSERT (HcDev->UsbCapabilityLen);\r
562d2849 191 return HcDev->PciIo->Mem.Write (\r
192 HcDev->PciIo,\r
193 EfiPciIoWidthUint32,\r
194 USB_BAR_INDEX,\r
37279806 195 (UINT64) (OperationalRegAddr + HcDev->UsbCapabilityLen),\r
562d2849 196 1,\r
197 &Data\r
198 );\r
199}\r
200\r
4d1fe68e 201\r
202\r
74c56167 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
4d1fe68e 244 &Value\r
74c56167 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
4d1fe68e 254 &Value\r
74c56167 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
4d1fe68e 264 &Value\r
74c56167 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
4d1fe68e 275 &Value\r
74c56167 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
4d1fe68e 287 &Value\r
74c56167 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
4d1fe68e 296 }\r
297\r
74c56167 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
4d1fe68e 305 &Value\r
74c56167 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
4d1fe68e 315 &Value\r
74c56167 316 );\r
317\r
318 DEBUG((gEHCDebugLevel, "EECP[4] = 0x%x\n", Value));\r
319\r
320\r
321}\r
322\r
562d2849 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
4d1fe68e 332\r
562d2849 333Arguments:\r
334\r
4d1fe68e 335 HcDev - USB2_HC_DEV\r
336\r
562d2849 337Returns:\r
338\r
339 EFI_SUCCESS Success\r
340 EFI_DEVICE_ERROR Fail\r
4d1fe68e 341\r
562d2849 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
37279806 352 &(HcDev->UsbCapabilityLen)\r
562d2849 353 );\r
37279806 354 HcDev->UsbCapabilityLen = (UINT8) HcDev->UsbCapabilityLen;\r
562d2849 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
4d1fe68e 369\r
562d2849 370Arguments:\r
371\r
4d1fe68e 372 HcDev - USB2_HC_DEV\r
562d2849 373 Length - the required length of frame list\r
4d1fe68e 374\r
562d2849 375Returns:\r
376\r
377 EFI_SUCCESS Success\r
378 EFI_INVALID_PARAMETER Invalid parameter\r
379 EFI_DEVICE_ERROR Fail\r
4d1fe68e 380\r
562d2849 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
4d1fe68e 433\r
562d2849 434Arguments:\r
435\r
4d1fe68e 436 HcDev - USB2_HC_DEV\r
562d2849 437 FrameBuffer - base address of first entry of frame list\r
4d1fe68e 438\r
562d2849 439Returns:\r
4d1fe68e 440\r
562d2849 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
4d1fe68e 479\r
562d2849 480Arguments:\r
481\r
4d1fe68e 482 HcDev - USB2_HC_DEV\r
562d2849 483 QhPtr - A pointer to first Qh in the Async schedule\r
4d1fe68e 484\r
562d2849 485Returns:\r
486\r
487 EFI_SUCCESS Success\r
488 EFI_DEVICE_ERROR Fail\r
4d1fe68e 489\r
562d2849 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
4d1fe68e 517\r
562d2849 518Arguments:\r
519\r
4d1fe68e 520 HcDev - USB2_HC_DEV\r
521\r
562d2849 522Returns:\r
523\r
524 EFI_SUCCESS Success\r
525 EFI_DEVICE_ERROR Fail\r
4d1fe68e 526\r
562d2849 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
4d1fe68e 555\r
562d2849 556Arguments:\r
557\r
4d1fe68e 558 HcDev - USB2_HC_DEV\r
559\r
562d2849 560Returns:\r
561\r
562 EFI_SUCCESS Success\r
563 EFI_DEVICE_ERROR Fail\r
4d1fe68e 564\r
562d2849 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
4d1fe68e 606\r
562d2849 607Arguments:\r
608\r
4d1fe68e 609 HcDev - USB2_HC_DEV\r
610\r
562d2849 611Returns:\r
612\r
613 EFI_SUCCESS Success\r
614 EFI_DEVICE_ERROR Fail\r
4d1fe68e 615\r
562d2849 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
4d1fe68e 657\r
562d2849 658Arguments:\r
659\r
4d1fe68e 660 HcDev - USB2_HC_DEV\r
661\r
562d2849 662Returns:\r
663\r
664 EFI_SUCCESS Success\r
665 EFI_DEVICE_ERROR Fail\r
4d1fe68e 666\r
562d2849 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
4d1fe68e 689\r
562d2849 690Arguments:\r
691\r
4d1fe68e 692 HcDev - USB2_HC_DEV\r
693\r
562d2849 694Returns:\r
695\r
696 EFI_SUCCESS Success\r
697 EFI_DEVICE_ERROR Fail\r
4d1fe68e 698\r
562d2849 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
4d1fe68e 740\r
562d2849 741Arguments:\r
742\r
4d1fe68e 743 HcDev - USB2_HC_DEV\r
744\r
562d2849 745Returns:\r
746\r
747 EFI_SUCCESS Success\r
748 EFI_DEVICE_ERROR Fail\r
4d1fe68e 749\r
562d2849 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
4d1fe68e 789\r
562d2849 790Arguments:\r
791\r
4d1fe68e 792 HcDev - USB2_HC_DEV\r
793\r
562d2849 794Returns:\r
795\r
796 EFI_SUCCESS Success\r
797 EFI_DEVICE_ERROR Fail\r
4d1fe68e 798\r
562d2849 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
4d1fe68e 840\r
562d2849 841Arguments:\r
842\r
4d1fe68e 843 HcDev - USB2_HC_DEV\r
844\r
562d2849 845Returns:\r
846\r
847 EFI_SUCCESS Success\r
848 EFI_DEVICE_ERROR Fail\r
4d1fe68e 849\r
562d2849 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
4d1fe68e 889\r
562d2849 890Arguments:\r
891\r
4d1fe68e 892 HcDev - USB2_HC_DEV\r
893\r
562d2849 894Returns:\r
895\r
896 EFI_SUCCESS Success\r
897 EFI_DEVICE_ERROR Fail\r
4d1fe68e 898\r
562d2849 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
4d1fe68e 940\r
562d2849 941Arguments:\r
942\r
4d1fe68e 943 HcDev - USB2_HC_DEV\r
944\r
562d2849 945Returns:\r
946\r
947 EFI_SUCCESS Success\r
948 EFI_DEVICE_ERROR Fail\r
4d1fe68e 949\r
562d2849 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
4d1fe68e 991\r
562d2849 992Arguments:\r
993\r
4d1fe68e 994 HcDev - USB2_HC_DEV\r
995\r
562d2849 996Returns:\r
997\r
998 TRUE Programmable\r
999 FALSE Unprogrammable\r
4d1fe68e 1000\r
562d2849 1001--*/\r
1002{\r
1003 BOOLEAN Value;\r
1004 UINT32 HcCapParamsAddr;\r
1005 UINT32 HcCapParamsReg;\r
1006\r
1007 HcCapParamsAddr = HCCPARAMS;\r
1008\r
37279806 1009 ReadEhcCapabiltiyReg(\r
562d2849 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
4d1fe68e 1033\r
562d2849 1034Arguments:\r
1035\r
4d1fe68e 1036 HcDev - USB2_HC_DEV\r
1037\r
562d2849 1038Returns:\r
1039\r
1040 TRUE Enabled\r
1041 FALSE Disabled\r
4d1fe68e 1042\r
562d2849 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
4d1fe68e 1075\r
562d2849 1076Arguments:\r
1077\r
4d1fe68e 1078 HcDev - USB2_HC_DEV\r
1079\r
562d2849 1080Returns:\r
1081\r
1082 TRUE Enabled\r
1083 FALSE Disabled\r
4d1fe68e 1084\r
562d2849 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
4d1fe68e 1118\r
562d2849 1119Arguments:\r
1120\r
4d1fe68e 1121 HcDev - USB2_HC_DEV\r
1122\r
562d2849 1123Returns:\r
1124\r
1125 TRUE Enabled\r
1126 FALSE Disabled\r
4d1fe68e 1127\r
562d2849 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
1cc8ee78 1141 return ((BOOLEAN) ((PortStatusControlReg & PORTSC_PED) ? TRUE : FALSE));\r
562d2849 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
4d1fe68e 1153\r
562d2849 1154Arguments:\r
1155\r
4d1fe68e 1156 HcDev - USB2_HC_DEV\r
1157\r
562d2849 1158Returns:\r
1159\r
1160 TRUE Reseted\r
1161 FALSE Unreseted\r
4d1fe68e 1162\r
562d2849 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
4d1fe68e 1195\r
562d2849 1196Arguments:\r
1197\r
4d1fe68e 1198 HcDev - USB2_HC_DEV\r
1199\r
562d2849 1200Returns:\r
1201\r
1202 TRUE Halted\r
1203 FALSE Not halted\r
4d1fe68e 1204\r
562d2849 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
4d1fe68e 1237\r
562d2849 1238Arguments:\r
1239\r
4d1fe68e 1240 HcDev - USB2_HC_DEV\r
1241\r
562d2849 1242Returns:\r
1243\r
1244 TRUE System error\r
1245 FALSE No system error\r
4d1fe68e 1246\r
562d2849 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
4d1fe68e 1273 IN UINT8 PortNum\r
562d2849 1274 )\r
1275/*++\r
1276\r
1277Routine Description:\r
1278\r
1279 Whether high speed device attached\r
4d1fe68e 1280\r
562d2849 1281Arguments:\r
1282\r
4d1fe68e 1283 HcDev - USB2_HC_DEV\r
1284\r
562d2849 1285Returns:\r
1286\r
1287 TRUE High speed\r
1288 FALSE Full speed\r
4d1fe68e 1289\r
562d2849 1290--*/\r
1291{\r
1292 USB2_HC_DEV *HcDev;\r
1293 UINT32 PortStatusControlAddr;\r
1294 UINT32 PortStatusControlReg;\r
4d1fe68e 1295\r
562d2849 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
1cc8ee78 1352 return ((BOOLEAN) (IsEhcPortEnabled (HcDev, PortNum) ? TRUE : FALSE));\r
562d2849 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
4d1fe68e 1365\r
562d2849 1366Arguments:\r
1367\r
4d1fe68e 1368 HcDev - USB2_HC_DEV\r
562d2849 1369 Timeout - timeout threshold\r
4d1fe68e 1370\r
562d2849 1371Returns:\r
1372\r
1373 EFI_SUCCESS Success\r
1374 EFI_TIMEOUT Timeout\r
4d1fe68e 1375\r
562d2849 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
4d1fe68e 1411\r
562d2849 1412Arguments:\r
1413\r
4d1fe68e 1414 HcDev - USB2_HC_DEV\r
562d2849 1415 Timeout - timeout threshold\r
4d1fe68e 1416\r
562d2849 1417Returns:\r
1418\r
1419 EFI_SUCCESS Success\r
1420 EFI_TIMEOUT Timeout\r
4d1fe68e 1421\r
562d2849 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
4d1fe68e 1457\r
562d2849 1458Arguments:\r
1459\r
4d1fe68e 1460 HcDev - USB2_HC_DEV\r
562d2849 1461 Timeout - timeout threshold\r
4d1fe68e 1462\r
562d2849 1463Returns:\r
1464\r
1465 EFI_SUCCESS Success\r
1466 EFI_TIMEOUT Timeout\r
4d1fe68e 1467\r
562d2849 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
4d1fe68e 1503\r
562d2849 1504Arguments:\r
1505\r
4d1fe68e 1506 HcDev - USB2_HC_DEV\r
562d2849 1507 Timeout - timeout threshold\r
4d1fe68e 1508\r
562d2849 1509Returns:\r
1510\r
1511 EFI_SUCCESS Success\r
1512 EFI_TIMEOUT Timeout\r
4d1fe68e 1513\r
562d2849 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
4d1fe68e 1549\r
562d2849 1550Arguments:\r
1551\r
4d1fe68e 1552 HcDev - USB2_HC_DEV\r
562d2849 1553 Timeout - timeout threshold\r
4d1fe68e 1554\r
562d2849 1555Returns:\r
1556\r
1557 EFI_SUCCESS Success\r
1558 EFI_TIMEOUT Timeout\r
4d1fe68e 1559\r
562d2849 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
4d1fe68e 1595\r
562d2849 1596Arguments:\r
1597\r
4d1fe68e 1598 HcDev - USB2_HC_DEV\r
562d2849 1599 Timeout - timeout threshold\r
4d1fe68e 1600\r
562d2849 1601Returns:\r
1602\r
1603 EFI_SUCCESS Success\r
1604 EFI_TIMEOUT Timeout\r
4d1fe68e 1605\r
562d2849 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
4d1fe68e 1641\r
562d2849 1642Arguments:\r
1643\r
4d1fe68e 1644 HcDev - USB2_HC_DEV\r
562d2849 1645 Timeout - timeout threshold\r
4d1fe68e 1646\r
562d2849 1647Returns:\r
1648\r
1649 EFI_SUCCESS Success\r
1650 EFI_TIMEOUT Timeout\r
4d1fe68e 1651\r
562d2849 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
4d1fe68e 1690 HcDev - USB2_HC_DEV\r
562d2849 1691 Timeout - timeout threshold\r
1692\r
1693Returns:\r
1694\r
1695 EFI_SUCCESS Success\r
1696 EFI_TIMEOUT Timeout\r
4d1fe68e 1697\r
562d2849 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
4d1fe68e 1707\r
562d2849 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