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
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.
26 ReadEhcCapabiltiyReg (
27 IN USB2_HC_DEV
*HcDev
,
28 IN UINT32 CapabiltiyRegAddr
,
35 Read Ehc Capabitlity register
40 CapabiltiyRegAddr - Ehc Capability register address
41 Data - A pointer to data read from register
50 return HcDev
->PciIo
->Mem
.Read (
54 (UINT64
) CapabiltiyRegAddr
,
61 ReadEhcOperationalReg (
62 IN USB2_HC_DEV
*HcDev
,
63 IN UINT32 OperationalRegAddr
,
70 Read Ehc Operation register
75 OperationalRegAddr - Ehc Operation register address
76 Data - A pointer to data read from register
85 ASSERT (mUsbCapabilityLen
);
86 return HcDev
->PciIo
->Mem
.Read (
90 (UINT64
) (OperationalRegAddr
+ mUsbCapabilityLen
),
97 WriteEhcOperationalReg (
98 IN USB2_HC_DEV
*HcDev
,
99 IN UINT32 OperationalRegAddr
,
106 Write Ehc Operation register
111 OperationalRegAddr - Ehc Operation register address
112 Data - 32bit write to register
117 EFI_DEVICE_ERROR Fail
121 ASSERT (mUsbCapabilityLen
);
122 return HcDev
->PciIo
->Mem
.Write (
126 (UINT64
) (OperationalRegAddr
+ mUsbCapabilityLen
),
134 IN USB2_HC_DEV
*HcDev
140 Get the length of capability register
149 EFI_DEVICE_ERROR Fail
154 UINT32 CapabilityLenAddr
;
156 CapabilityLenAddr
= CAPLENGTH
;
158 Status
= ReadEhcCapabiltiyReg (
163 mUsbCapabilityLen
= (UINT8
) mUsbCapabilityLen
;
170 IN USB2_HC_DEV
*HcDev
,
177 Set the length of Frame List
182 Length - the required length of frame list
187 EFI_INVALID_PARAMETER Invalid parameter
188 EFI_DEVICE_ERROR Fail
193 UINT32 UsbCommandAddr
;
194 UINT32 UsbCommandReg
;
196 UsbCommandAddr
= USBCMD
;
198 if (256 != Length
&& 512 != Length
) {
199 Status
= EFI_INVALID_PARAMETER
;
203 Status
= ReadEhcOperationalReg (
208 if (EFI_ERROR (Status
)) {
209 Status
= EFI_DEVICE_ERROR
;
214 UsbCommandReg
|= USBCMD_FLS_256
;
216 UsbCommandReg
|= USBCMD_FLS_512
;
219 Status
= WriteEhcOperationalReg (
224 if (EFI_ERROR (Status
)) {
225 Status
= EFI_DEVICE_ERROR
;
233 SetFrameListBaseAddr (
234 IN USB2_HC_DEV
*HcDev
,
235 IN UINT32 FrameBuffer
241 Set base address of frame list first entry
246 FrameBuffer - base address of first entry of frame list
253 UINT32 PeriodicListBaseAddr
;
254 UINT32 PeriodicListBaseReg
;
256 Status
= EFI_SUCCESS
;
257 PeriodicListBaseAddr
= PERIODICLISTBASE
;
258 PeriodicListBaseReg
= FrameBuffer
& 0xfffff000;
260 if (IsEhcHalted (HcDev
)) {
262 Status
= WriteEhcOperationalReg (
264 PeriodicListBaseAddr
,
267 if (EFI_ERROR (Status
)) {
268 Status
= EFI_DEVICE_ERROR
;
280 IN USB2_HC_DEV
*HcDev
,
281 IN EHCI_QH_ENTITY
*QhPtr
287 Set address of first Async schedule Qh
292 QhPtr - A pointer to first Qh in the Async schedule
297 EFI_DEVICE_ERROR Fail
302 UINT32 AsyncListAddr
;
305 AsyncListAddr
= ASYNCLISTADDR
;
306 AsyncListReg
= (UINT32
) GET_0B_TO_31B (&(QhPtr
->Qh
));
308 Status
= WriteEhcOperationalReg (
318 SetCtrlDataStructSeg (
319 IN USB2_HC_DEV
*HcDev
325 Set register of control and data structure segment
334 EFI_DEVICE_ERROR Fail
340 UINT32 CtrlDsSegmentAddr
;
341 UINT32 CtrlDsSegmentReg
;
343 CtrlDsSegmentAddr
= CTRLDSSGMENT
;
344 CtrlDsSegmentReg
= HcDev
->High32BitAddr
;
346 Status
= WriteEhcOperationalReg (
357 IN USB2_HC_DEV
*HcDev
363 Set Ehc port routing bit
372 EFI_DEVICE_ERROR Fail
377 UINT32 ConfigFlagAddr
;
378 UINT32 ConfigFlagReg
;
380 ConfigFlagAddr
= CONFIGFLAG
;
382 Status
= ReadEhcOperationalReg (
387 if (EFI_ERROR (Status
)) {
388 Status
= EFI_DEVICE_ERROR
;
392 ConfigFlagReg
|= CONFIGFLAG_CF
;
393 Status
= WriteEhcOperationalReg (
398 if (EFI_ERROR (Status
)) {
399 Status
= EFI_DEVICE_ERROR
;
408 IN USB2_HC_DEV
*HcDev
414 Set Ehc door bell bit
423 EFI_DEVICE_ERROR Fail
428 UINT32 UsbCommandAddr
;
429 UINT32 UsbCommandReg
;
431 UsbCommandAddr
= USBCMD
;
433 Status
= ReadEhcOperationalReg (
438 if (EFI_ERROR (Status
)) {
439 Status
= EFI_DEVICE_ERROR
;
443 UsbCommandReg
|= USBCMD_IAAD
;
444 Status
= WriteEhcOperationalReg (
449 if (EFI_ERROR (Status
)) {
450 Status
= EFI_DEVICE_ERROR
;
459 IN USB2_HC_DEV
*HcDev
465 Clear Ehc all status bits
474 EFI_DEVICE_ERROR Fail
478 UINT32 UsbStatusAddr
;
480 UsbStatusAddr
= USBSTS
;
482 return WriteEhcOperationalReg (
490 EnablePeriodicSchedule (
491 IN USB2_HC_DEV
*HcDev
497 Enable periodic schedule
506 EFI_DEVICE_ERROR Fail
511 UINT32 UsbCommandAddr
;
512 UINT32 UsbCommandReg
;
514 UsbCommandAddr
= USBCMD
;
516 Status
= ReadEhcOperationalReg (
521 if (EFI_ERROR (Status
)) {
522 Status
= EFI_DEVICE_ERROR
;
526 UsbCommandReg
|= USBCMD_PSE
;
527 Status
= WriteEhcOperationalReg (
532 if (EFI_ERROR (Status
)) {
533 Status
= EFI_DEVICE_ERROR
;
541 DisablePeriodicSchedule (
542 IN USB2_HC_DEV
*HcDev
548 Disable periodic schedule
557 EFI_DEVICE_ERROR Fail
562 UINT32 UsbCommandAddr
;
563 UINT32 UsbCommandReg
;
565 UsbCommandAddr
= USBCMD
;
567 Status
= ReadEhcOperationalReg (
572 if (EFI_ERROR (Status
)) {
573 return EFI_DEVICE_ERROR
;
576 UsbCommandReg
&= ~USBCMD_PSE
;
577 Status
= WriteEhcOperationalReg (
582 if (EFI_ERROR (Status
)) {
583 return EFI_DEVICE_ERROR
;
590 EnableAsynchronousSchedule (
591 IN USB2_HC_DEV
*HcDev
597 Enable asynchrounous schedule
606 EFI_DEVICE_ERROR Fail
611 UINT32 UsbCommandAddr
;
612 UINT32 UsbCommandReg
;
614 UsbCommandAddr
= USBCMD
;
616 Status
= ReadEhcOperationalReg (
621 if (EFI_ERROR (Status
)) {
622 Status
= EFI_DEVICE_ERROR
;
626 UsbCommandReg
|= USBCMD_ASE
;
627 Status
= WriteEhcOperationalReg (
632 if (EFI_ERROR (Status
)) {
633 Status
= EFI_DEVICE_ERROR
;
641 DisableAsynchronousSchedule (
642 IN USB2_HC_DEV
*HcDev
648 Disable asynchrounous schedule
657 EFI_DEVICE_ERROR Fail
662 UINT32 UsbCommandAddr
;
663 UINT32 UsbCommandReg
;
665 UsbCommandAddr
= USBCMD
;
667 Status
= ReadEhcOperationalReg (
672 if (EFI_ERROR (Status
)) {
673 return EFI_DEVICE_ERROR
;
676 UsbCommandReg
&= ~USBCMD_ASE
;
677 Status
= WriteEhcOperationalReg (
682 if (EFI_ERROR (Status
)) {
683 return EFI_DEVICE_ERROR
;
691 IN USB2_HC_DEV
*HcDev
706 EFI_DEVICE_ERROR Fail
711 UINT32 UsbCommandAddr
;
712 UINT32 UsbCommandReg
;
714 UsbCommandAddr
= USBCMD
;
716 Status
= ReadEhcOperationalReg (
721 if (EFI_ERROR (Status
)) {
722 Status
= EFI_DEVICE_ERROR
;
726 UsbCommandReg
|= USBCMD_HCRESET
;
727 Status
= WriteEhcOperationalReg (
732 if (EFI_ERROR (Status
)) {
733 Status
= EFI_DEVICE_ERROR
;
741 StartScheduleExecution (
742 IN USB2_HC_DEV
*HcDev
748 Start Ehc schedule execution
757 EFI_DEVICE_ERROR Fail
762 UINT32 UsbCommandAddr
;
763 UINT32 UsbCommandReg
;
765 UsbCommandAddr
= USBCMD
;
767 Status
= ReadEhcOperationalReg (
772 if (EFI_ERROR (Status
)) {
773 Status
= EFI_DEVICE_ERROR
;
777 UsbCommandReg
|= USBCMD_RS
;
778 Status
= WriteEhcOperationalReg (
783 if (EFI_ERROR (Status
)) {
784 Status
= EFI_DEVICE_ERROR
;
792 IsFrameListProgrammable (
793 IN USB2_HC_DEV
*HcDev
799 Whether frame list is programmable
813 UINT32 HcCapParamsAddr
;
814 UINT32 HcCapParamsReg
;
816 HcCapParamsAddr
= HCCPARAMS
;
818 ReadEhcOperationalReg (
824 if (HcCapParamsReg
& HCCP_PFLF
) {
834 IsPeriodicScheduleEnabled (
835 IN USB2_HC_DEV
*HcDev
841 Whether periodic schedule is enabled
855 UINT32 UsbStatusAddr
;
858 UsbStatusAddr
= USBSTS
;
860 ReadEhcOperationalReg (
866 if (UsbStatusReg
& USBSTS_PSS
) {
876 IsAsyncScheduleEnabled (
877 IN USB2_HC_DEV
*HcDev
883 Whether asynchronous schedule is enabled
897 UINT32 UsbStatusAddr
;
900 UsbStatusAddr
= USBSTS
;
902 ReadEhcOperationalReg (
908 if (UsbStatusReg
& USBSTS_ASS
) {
919 IN USB2_HC_DEV
*HcDev
,
926 Whether port is enabled
939 UINT32 PortStatusControlAddr
;
940 UINT32 PortStatusControlReg
;
942 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNum
));
944 ReadEhcOperationalReg (
946 PortStatusControlAddr
,
947 &PortStatusControlReg
950 return ((PortStatusControlReg
& PORTSC_PED
) ? TRUE
: FALSE
);
955 IN USB2_HC_DEV
*HcDev
961 Whether Ehc is reseted
975 UINT32 UsbCommandAddr
;
976 UINT32 UsbCommandReg
;
978 UsbCommandAddr
= USBCMD
;
980 ReadEhcOperationalReg (
986 if (UsbCommandReg
& USBCMD_HCRESET
) {
997 IN USB2_HC_DEV
*HcDev
1001 Routine Description:
1003 Whether Ehc is halted
1017 UINT32 UsbStatusAddr
;
1018 UINT32 UsbStatusReg
;
1020 UsbStatusAddr
= USBSTS
;
1022 ReadEhcOperationalReg (
1028 if (UsbStatusReg
& USBSTS_HCH
) {
1039 IN USB2_HC_DEV
*HcDev
1043 Routine Description:
1045 Whether Ehc is system error
1054 FALSE No system error
1059 UINT32 UsbStatusAddr
;
1060 UINT32 UsbStatusReg
;
1062 UsbStatusAddr
= USBSTS
;
1064 ReadEhcOperationalReg (
1070 if (UsbStatusReg
& USBSTS_HSE
) {
1081 IN EFI_USB2_HC_PROTOCOL
*This
,
1086 Routine Description:
1088 Whether high speed device attached
1102 UINT32 PortStatusControlAddr
;
1103 UINT32 PortStatusControlReg
;
1105 HcDev
= USB2_HC_DEV_FROM_THIS (This
);
1106 PortStatusControlAddr
= (UINT32
) (PORTSC
+ (4 * PortNum
));
1109 // Set port reset bit
1111 ReadEhcOperationalReg (
1113 PortStatusControlAddr
,
1114 &PortStatusControlReg
1117 // Make sure Host Controller not halt before reset it
1119 if (IsEhcHalted (HcDev
)) {
1120 StartScheduleExecution (HcDev
);
1121 WaitForEhcNotHalt (HcDev
, EHCI_GENERIC_TIMEOUT
);
1123 PortStatusControlReg
&= 0xffffffd5;
1124 PortStatusControlReg
|= PORTSC_PR
;
1126 // Set one to PortReset bit must also set zero to PortEnable bit
1128 PortStatusControlReg
&= ~PORTSC_PED
;
1129 WriteEhcOperationalReg (
1131 PortStatusControlAddr
,
1132 PortStatusControlReg
1136 // Set Port reset recovery time
1138 gBS
->Stall (EHCI_SET_PORT_RESET_RECOVERY_TIME
);
1141 // Clear port reset bit
1143 ReadEhcOperationalReg (
1145 PortStatusControlAddr
,
1146 &PortStatusControlReg
1148 PortStatusControlReg
&= 0xffffffd5;
1149 PortStatusControlReg
&= ~PORTSC_PR
;
1150 WriteEhcOperationalReg (
1152 PortStatusControlAddr
,
1153 PortStatusControlReg
1157 // Clear port reset recovery time
1159 gBS
->Stall (EHCI_CLEAR_PORT_RESET_RECOVERY_TIME
);
1161 return (IsEhcPortEnabled (HcDev
, PortNum
) ? TRUE
: FALSE
);
1166 IN USB2_HC_DEV
*HcDev
,
1171 Routine Description:
1173 wait for Ehc reset or timeout
1178 Timeout - timeout threshold
1191 // Timeout is in US unit
1193 Delay
= (Timeout
/ 50) + 1;
1196 if (IsEhcReseted (HcDev
)) {
1197 Status
= EFI_SUCCESS
;
1200 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1204 Status
= EFI_TIMEOUT
;
1212 IN USB2_HC_DEV
*HcDev
,
1217 Routine Description:
1219 wait for Ehc halt or timeout
1224 Timeout - timeout threshold
1237 // Timeout is in US unit
1239 Delay
= (Timeout
/ 50) + 1;
1242 if (IsEhcHalted (HcDev
)) {
1243 Status
= EFI_SUCCESS
;
1246 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1250 Status
= EFI_TIMEOUT
;
1258 IN USB2_HC_DEV
*HcDev
,
1263 Routine Description:
1265 wait for Ehc not halt or timeout
1270 Timeout - timeout threshold
1283 // Timeout is in US unit
1285 Delay
= (Timeout
/ 50) + 1;
1288 if (!IsEhcHalted (HcDev
)) {
1289 Status
= EFI_SUCCESS
;
1292 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1296 Status
= EFI_TIMEOUT
;
1303 WaitForAsyncScheduleEnable (
1304 IN USB2_HC_DEV
*HcDev
,
1309 Routine Description:
1311 Wait for Ehc asynchronous schedule enable or timeout
1316 Timeout - timeout threshold
1329 // Timeout is in US unit
1331 Delay
= (Timeout
/ 50) + 1;
1334 if (IsAsyncScheduleEnabled (HcDev
)) {
1335 Status
= EFI_SUCCESS
;
1338 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1342 Status
= EFI_TIMEOUT
;
1349 WaitForAsyncScheduleDisable (
1350 IN USB2_HC_DEV
*HcDev
,
1355 Routine Description:
1357 Wait for Ehc asynchronous schedule disable or timeout
1362 Timeout - timeout threshold
1375 // Timeout is in US unit
1377 Delay
= (Timeout
/ 50) + 1;
1380 if (!IsAsyncScheduleEnabled (HcDev
)) {
1381 Status
= EFI_SUCCESS
;
1384 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1388 Status
= EFI_TIMEOUT
;
1395 WaitForPeriodicScheduleEnable (
1396 IN USB2_HC_DEV
*HcDev
,
1401 Routine Description:
1403 Wait for Ehc periodic schedule enable or timeout
1408 Timeout - timeout threshold
1421 // Timeout is in US unit
1423 Delay
= (Timeout
/ 50) + 1;
1426 if (IsPeriodicScheduleEnabled (HcDev
)) {
1427 Status
= EFI_SUCCESS
;
1430 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1434 Status
= EFI_TIMEOUT
;
1441 WaitForPeriodicScheduleDisable (
1442 IN USB2_HC_DEV
*HcDev
,
1447 Routine Description:
1449 Wait for periodic schedule disable or timeout
1454 Timeout - timeout threshold
1467 // Timeout is in US unit
1469 Delay
= (Timeout
/ 50) + 1;
1472 if (!IsPeriodicScheduleEnabled (HcDev
)) {
1473 Status
= EFI_SUCCESS
;
1476 gBS
->Stall (EHCI_GENERIC_RECOVERY_TIME
);
1480 Status
= EFI_TIMEOUT
;
1487 WaitForEhcDoorbell (
1488 IN USB2_HC_DEV
*HcDev
,
1493 Routine Description:
1495 Wait for periodic schedule disable or timeout
1500 Timeout - timeout threshold
1510 UINT32 UsbCommandAddr
;
1511 UINT32 UsbCommandReg
;
1514 UsbCommandAddr
= USBCMD
;
1515 Delay
= (Timeout
/ 50) + 1;
1518 Status
= ReadEhcOperationalReg (
1523 if (EFI_ERROR (Status
)) {
1524 Status
= EFI_DEVICE_ERROR
;
1527 if (!(UsbCommandReg
& USBCMD_IAAD
)) {
1534 Status
= EFI_TIMEOUT
;