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