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