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