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