/** @file\r
+ The Ehci controller driver.\r
\r
-Copyright (c) 2006 - 2007, Intel Corporation\r
-All rights reserved. This program and the accompanying materials\r
-are licensed and made available under the terms and conditions of the BSD License\r
-which accompanies this distribution. The full text of the license may be found at\r
-http://opensource.org/licenses/bsd-license.php\r
+ EhciDxe driver is responsible for managing the behavior of EHCI controller.\r
+ It implements the interfaces of monitoring the status of all ports and transferring\r
+ Control, Bulk, Interrupt and Isochronous requests to Usb2.0 device.\r
\r
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+ Note that EhciDxe driver is enhanced to guarantee that the EHCI controller get attached\r
+ to the EHCI controller before a UHCI or OHCI driver attaches to the companion UHCI or\r
+ OHCI controller. This way avoids the control transfer on a shared port between EHCI\r
+ and companion host controller when UHCI or OHCI gets attached earlier than EHCI and a\r
+ USB 2.0 device inserts.\r
\r
-Module Name:\r
-\r
- Ehci.c\r
-\r
-Abstract:\r
-\r
-\r
-Revision History\r
+Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
-\r
#include "Ehci.h"\r
\r
//\r
// to the UEFI protocol's port state (change).\r
//\r
USB_PORT_STATE_MAP mUsbPortStateMap[] = {\r
- {PORTSC_CONN, USB_PORT_STAT_CONNECTION},\r
- {PORTSC_ENABLED, USB_PORT_STAT_ENABLE},\r
- {PORTSC_SUSPEND, USB_PORT_STAT_SUSPEND},\r
- {PORTSC_OVERCUR, USB_PORT_STAT_OVERCURRENT},\r
- {PORTSC_RESET, USB_PORT_STAT_RESET},\r
- {PORTSC_POWER, USB_PORT_STAT_POWER},\r
- {PORTSC_OWNER, USB_PORT_STAT_OWNER}\r
+ { PORTSC_CONN, USB_PORT_STAT_CONNECTION },\r
+ { PORTSC_ENABLED, USB_PORT_STAT_ENABLE },\r
+ { PORTSC_SUSPEND, USB_PORT_STAT_SUSPEND },\r
+ { PORTSC_OVERCUR, USB_PORT_STAT_OVERCURRENT },\r
+ { PORTSC_RESET, USB_PORT_STAT_RESET },\r
+ { PORTSC_POWER, USB_PORT_STAT_POWER },\r
+ { PORTSC_OWNER, USB_PORT_STAT_OWNER }\r
};\r
\r
USB_PORT_STATE_MAP mUsbPortChangeMap[] = {\r
- {PORTSC_CONN_CHANGE, USB_PORT_STAT_C_CONNECTION},\r
- {PORTSC_ENABLE_CHANGE, USB_PORT_STAT_C_ENABLE},\r
- {PORTSC_OVERCUR_CHANGE, USB_PORT_STAT_C_OVERCURRENT}\r
+ { PORTSC_CONN_CHANGE, USB_PORT_STAT_C_CONNECTION },\r
+ { PORTSC_ENABLE_CHANGE, USB_PORT_STAT_C_ENABLE },\r
+ { PORTSC_OVERCUR_CHANGE, USB_PORT_STAT_C_OVERCURRENT }\r
};\r
\r
+EFI_DRIVER_BINDING_PROTOCOL\r
+ gEhciDriverBinding = {\r
+ EhcDriverBindingSupported,\r
+ EhcDriverBindingStart,\r
+ EhcDriverBindingStop,\r
+ 0x30,\r
+ NULL,\r
+ NULL\r
+};\r
\r
/**\r
- Retrieves the capablility of root hub ports.\r
+ Retrieves the capability of root hub ports.\r
\r
- @param This This EFI_USB_HC_PROTOCOL instance.\r
- @param MaxSpeed Max speed supported by the controller\r
- @param PortNumber Number of the root hub ports.\r
- @param Is64BitCapable Whether the controller supports 64-bit memory\r
- addressing.\r
+ @param This This EFI_USB_HC_PROTOCOL instance.\r
+ @param MaxSpeed Max speed supported by the controller.\r
+ @param PortNumber Number of the root hub ports.\r
+ @param Is64BitCapable Whether the controller supports 64-bit memory\r
+ addressing.\r
\r
- @return EFI_SUCCESS : host controller capability were retrieved successfully.\r
- @return EFI_INVALID_PARAMETER : Either of the three capability pointer is NULL\r
+ @retval EFI_SUCCESS Host controller capability were retrieved successfully.\r
+ @retval EFI_INVALID_PARAMETER Either of the three capability pointer is NULL.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
EhcGetCapability (\r
OUT UINT8 *Is64BitCapable\r
)\r
{\r
- USB2_HC_DEV *Ehc;\r
- EFI_TPL OldTpl;\r
+ USB2_HC_DEV *Ehc;\r
+ EFI_TPL OldTpl;\r
\r
if ((MaxSpeed == NULL) || (PortNumber == NULL) || (Is64BitCapable == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- OldTpl = gBS->RaiseTPL (EHC_TPL);\r
- Ehc = EHC_FROM_THIS (This);\r
+ OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+ Ehc = EHC_FROM_THIS (This);\r
\r
*MaxSpeed = EFI_USB_SPEED_HIGH;\r
- *PortNumber = (UINT8) (Ehc->HcStructParams & HCSP_NPORTS);\r
- *Is64BitCapable = (UINT8) (Ehc->HcCapParams & HCCP_64BIT);\r
+ *PortNumber = (UINT8)(Ehc->HcStructParams & HCSP_NPORTS);\r
+ *Is64BitCapable = (UINT8)Ehc->Support64BitDma;\r
\r
- DEBUG ((EFI_D_INFO, "EhcGetCapability: %d ports, 64 bit %d\n", *PortNumber, *Is64BitCapable));\r
+ DEBUG ((DEBUG_INFO, "EhcGetCapability: %d ports, 64 bit %d\n", *PortNumber, *Is64BitCapable));\r
\r
gBS->RestoreTPL (OldTpl);\r
return EFI_SUCCESS;\r
}\r
\r
-\r
/**\r
Provides software reset for the USB host controller.\r
\r
- @param This This EFI_USB2_HC_PROTOCOL instance.\r
- @param Attributes A bit mask of the reset operation to perform.\r
+ @param This This EFI_USB2_HC_PROTOCOL instance.\r
+ @param Attributes A bit mask of the reset operation to perform.\r
\r
- @return EFI_SUCCESS : The reset operation succeeded.\r
- @return EFI_INVALID_PARAMETER : Attributes is not valid.\r
- @return EFI_UNSUPPOURTED : The type of reset specified by Attributes is\r
- @return not currently supported by the host controller.\r
- @return EFI_DEVICE_ERROR : Host controller isn't halted to reset.\r
+ @retval EFI_SUCCESS The reset operation succeeded.\r
+ @retval EFI_INVALID_PARAMETER Attributes is not valid.\r
+ @retval EFI_UNSUPPOURTED The type of reset specified by Attributes is\r
+ not currently supported by the host controller.\r
+ @retval EFI_DEVICE_ERROR Host controller isn't halted to reset.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
EhcReset (\r
- IN EFI_USB2_HC_PROTOCOL *This,\r
- IN UINT16 Attributes\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT16 Attributes\r
)\r
{\r
- USB2_HC_DEV *Ehc;\r
- EFI_TPL OldTpl;\r
- EFI_STATUS Status;\r
+ USB2_HC_DEV *Ehc;\r
+ EFI_TPL OldTpl;\r
+ EFI_STATUS Status;\r
\r
- OldTpl = gBS->RaiseTPL (EHC_TPL);\r
- Ehc = EHC_FROM_THIS (This);\r
+ Ehc = EHC_FROM_THIS (This);\r
\r
- switch (Attributes) {\r
- case EFI_USB_HC_RESET_GLOBAL:\r
- //\r
- // Flow through, same behavior as Host Controller Reset\r
- //\r
- case EFI_USB_HC_RESET_HOST_CONTROLLER:\r
+ if (Ehc->DevicePath != NULL) {\r
//\r
- // Host Controller must be Halt when Reset it\r
+ // Report Status Code to indicate reset happens\r
//\r
- if (!EhcIsHalt (Ehc)) {\r
- Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ (EFI_IO_BUS_USB | EFI_IOB_PC_RESET),\r
+ Ehc->DevicePath\r
+ );\r
+ }\r
\r
- if (EFI_ERROR (Status)) {\r
- Status = EFI_DEVICE_ERROR;\r
- goto ON_EXIT;\r
- }\r
- }\r
+ OldTpl = gBS->RaiseTPL (EHC_TPL);\r
\r
+ switch (Attributes) {\r
+ case EFI_USB_HC_RESET_GLOBAL:\r
//\r
- // Clean up the asynchronous transfers, currently only\r
- // interrupt supports asynchronous operation.\r
+ // Flow through, same behavior as Host Controller Reset\r
//\r
- EhciDelAllAsyncIntTransfers (Ehc);\r
- EhcAckAllInterrupt (Ehc);\r
- EhcFreeSched (Ehc);\r
+ case EFI_USB_HC_RESET_HOST_CONTROLLER:\r
+ //\r
+ // Host Controller must be Halt when Reset it\r
+ //\r
+ if (EhcIsDebugPortInUse (Ehc, NULL)) {\r
+ Status = EFI_SUCCESS;\r
+ goto ON_EXIT;\r
+ }\r
\r
- Status = EhcResetHC (Ehc, EHC_RESET_TIMEOUT);\r
+ if (!EhcIsHalt (Ehc)) {\r
+ Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
\r
- if (EFI_ERROR (Status)) {\r
- goto ON_EXIT;\r
- }\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ goto ON_EXIT;\r
+ }\r
+ }\r
\r
- Status = EhcInitHC (Ehc);\r
- break;\r
+ //\r
+ // Clean up the asynchronous transfers, currently only\r
+ // interrupt supports asynchronous operation.\r
+ //\r
+ EhciDelAllAsyncIntTransfers (Ehc);\r
+ EhcAckAllInterrupt (Ehc);\r
+ EhcFreeSched (Ehc);\r
\r
- case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG:\r
- case EFI_USB_HC_RESET_HOST_WITH_DEBUG:\r
- Status = EFI_UNSUPPORTED;\r
- break;\r
+ Status = EhcResetHC (Ehc, EHC_RESET_TIMEOUT);\r
\r
- default:\r
- Status = EFI_INVALID_PARAMETER;\r
+ if (EFI_ERROR (Status)) {\r
+ goto ON_EXIT;\r
+ }\r
+\r
+ Status = EhcInitHC (Ehc);\r
+ break;\r
+\r
+ case EFI_USB_HC_RESET_GLOBAL_WITH_DEBUG:\r
+ case EFI_USB_HC_RESET_HOST_WITH_DEBUG:\r
+ Status = EFI_UNSUPPORTED;\r
+ break;\r
+\r
+ default:\r
+ Status = EFI_INVALID_PARAMETER;\r
}\r
\r
ON_EXIT:\r
- DEBUG ((EFI_D_INFO, "EhcReset: exit status %r\n", Status));\r
+ DEBUG ((DEBUG_INFO, "EhcReset: exit status %r\n", Status));\r
gBS->RestoreTPL (OldTpl);\r
return Status;\r
}\r
\r
-\r
/**\r
Retrieve the current state of the USB host controller.\r
\r
- @param This This EFI_USB2_HC_PROTOCOL instance.\r
- @param State Variable to return the current host controller\r
- state.\r
+ @param This This EFI_USB2_HC_PROTOCOL instance.\r
+ @param State Variable to return the current host controller\r
+ state.\r
\r
- @return EFI_SUCCESS : Host controller state was returned in State.\r
- @return EFI_INVALID_PARAMETER : State is NULL.\r
- @return EFI_DEVICE_ERROR : An error was encountered while attempting to\r
- @return retrieve the host controller's current state.\r
+ @retval EFI_SUCCESS Host controller state was returned in State.\r
+ @retval EFI_INVALID_PARAMETER State is NULL.\r
+ @retval EFI_DEVICE_ERROR An error was encountered while attempting to\r
+ retrieve the host controller's current state.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
EhcGetState (\r
- IN CONST EFI_USB2_HC_PROTOCOL *This,\r
- OUT EFI_USB_HC_STATE *State\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ OUT EFI_USB_HC_STATE *State\r
)\r
{\r
- EFI_TPL OldTpl;\r
- USB2_HC_DEV *Ehc;\r
+ EFI_TPL OldTpl;\r
+ USB2_HC_DEV *Ehc;\r
\r
if (State == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- OldTpl = gBS->RaiseTPL (EHC_TPL);\r
- Ehc = EHC_FROM_THIS (This);\r
+ OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+ Ehc = EHC_FROM_THIS (This);\r
\r
if (EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) {\r
*State = EfiUsbHcStateHalt;\r
\r
gBS->RestoreTPL (OldTpl);\r
\r
- DEBUG ((EFI_D_INFO, "EhcGetState: current state %d\n", *State));\r
+ DEBUG ((DEBUG_INFO, "EhcGetState: current state %d\n", *State));\r
return EFI_SUCCESS;\r
}\r
\r
-\r
/**\r
Sets the USB host controller to a specific state.\r
\r
- @param This This EFI_USB2_HC_PROTOCOL instance.\r
- @param State The state of the host controller that will be set.\r
+ @param This This EFI_USB2_HC_PROTOCOL instance.\r
+ @param State The state of the host controller that will be set.\r
\r
- @return EFI_SUCCESS : The USB host controller was successfully placed\r
- @return in the state specified by State.\r
- @return EFI_INVALID_PARAMETER : State is invalid.\r
- @return EFI_DEVICE_ERROR : Failed to set the state due to device error.\r
+ @retval EFI_SUCCESS The USB host controller was successfully placed\r
+ in the state specified by State.\r
+ @retval EFI_INVALID_PARAMETER State is invalid.\r
+ @retval EFI_DEVICE_ERROR Failed to set the state due to device error.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
EhcSetState (\r
- IN EFI_USB2_HC_PROTOCOL *This,\r
- IN EFI_USB_HC_STATE State\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN EFI_USB_HC_STATE State\r
)\r
{\r
- USB2_HC_DEV *Ehc;\r
- EFI_TPL OldTpl;\r
- EFI_STATUS Status;\r
- EFI_USB_HC_STATE CurState;\r
+ USB2_HC_DEV *Ehc;\r
+ EFI_TPL OldTpl;\r
+ EFI_STATUS Status;\r
+ EFI_USB_HC_STATE CurState;\r
\r
Status = EhcGetState (This, &CurState);\r
\r
return EFI_SUCCESS;\r
}\r
\r
- OldTpl = gBS->RaiseTPL (EHC_TPL);\r
- Ehc = EHC_FROM_THIS (This);\r
+ OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+ Ehc = EHC_FROM_THIS (This);\r
\r
switch (State) {\r
- case EfiUsbHcStateHalt:\r
- Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
- break;\r
-\r
- case EfiUsbHcStateOperational:\r
- if (EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_SYS_ERROR)) {\r
- Status = EFI_DEVICE_ERROR;\r
+ case EfiUsbHcStateHalt:\r
+ Status = EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
break;\r
- }\r
\r
- //\r
- // Software must not write a one to this field unless the host controller\r
- // is in the Halted state. Doing so will yield undefined results.\r
- // refers to Spec[EHCI1.0-2.3.1]\r
- //\r
- if (!EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) {\r
- Status = EFI_DEVICE_ERROR;\r
- break;\r
- }\r
+ case EfiUsbHcStateOperational:\r
+ if (EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_SYS_ERROR)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ break;\r
+ }\r
\r
- Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT);\r
- break;\r
+ //\r
+ // Software must not write a one to this field unless the host controller\r
+ // is in the Halted state. Doing so will yield undefined results.\r
+ // refers to Spec[EHCI1.0-2.3.1]\r
+ //\r
+ if (!EHC_REG_BIT_IS_SET (Ehc, EHC_USBSTS_OFFSET, USBSTS_HALT)) {\r
+ Status = EFI_DEVICE_ERROR;\r
+ break;\r
+ }\r
\r
- case EfiUsbHcStateSuspend:\r
- Status = EFI_UNSUPPORTED;\r
- break;\r
+ Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT);\r
+ break;\r
\r
- default:\r
- Status = EFI_INVALID_PARAMETER;\r
+ case EfiUsbHcStateSuspend:\r
+ Status = EFI_UNSUPPORTED;\r
+ break;\r
+\r
+ default:\r
+ Status = EFI_INVALID_PARAMETER;\r
}\r
\r
- DEBUG ((EFI_D_INFO, "EhcSetState: exit status %r\n", Status));\r
+ DEBUG ((DEBUG_INFO, "EhcSetState: exit status %r\n", Status));\r
gBS->RestoreTPL (OldTpl);\r
return Status;\r
}\r
\r
-\r
/**\r
Retrieves the current status of a USB root hub port.\r
\r
- @param This This EFI_USB2_HC_PROTOCOL instance.\r
- @param PortNumber The root hub port to retrieve the state from. This\r
- value is zero-based.\r
- @param PortStatus Variable to receive the port state\r
+ @param This This EFI_USB2_HC_PROTOCOL instance.\r
+ @param PortNumber The root hub port to retrieve the state from.\r
+ This value is zero-based.\r
+ @param PortStatus Variable to receive the port state.\r
\r
- @return EFI_SUCCESS : The status of the USB root hub port specified\r
- @return by PortNumber was returned in PortStatus.\r
- @return EFI_INVALID_PARAMETER : PortNumber is invalid.\r
- @return EFI_DEVICE_ERROR : Can't read register\r
+ @retval EFI_SUCCESS The status of the USB root hub port specified.\r
+ by PortNumber was returned in PortStatus.\r
+ @retval EFI_INVALID_PARAMETER PortNumber is invalid.\r
+ @retval EFI_DEVICE_ERROR Can't read register.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
EhcGetRootHubPortStatus (\r
- IN CONST EFI_USB2_HC_PROTOCOL *This,\r
- IN CONST UINT8 PortNumber,\r
- OUT EFI_USB_PORT_STATUS *PortStatus\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 PortNumber,\r
+ OUT EFI_USB_PORT_STATUS *PortStatus\r
)\r
{\r
- USB2_HC_DEV *Ehc;\r
- EFI_TPL OldTpl;\r
- UINT32 Offset;\r
- UINT32 State;\r
- UINT32 TotalPort;\r
- UINTN Index;\r
- UINTN MapSize;\r
- EFI_STATUS Status;\r
+ USB2_HC_DEV *Ehc;\r
+ EFI_TPL OldTpl;\r
+ UINT32 Offset;\r
+ UINT32 State;\r
+ UINT32 TotalPort;\r
+ UINTN Index;\r
+ UINTN MapSize;\r
+ EFI_STATUS Status;\r
\r
if (PortStatus == NULL) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+ OldTpl = gBS->RaiseTPL (EHC_TPL);\r
\r
- Ehc = EHC_FROM_THIS (This);\r
- Status = EFI_SUCCESS;\r
+ Ehc = EHC_FROM_THIS (This);\r
+ Status = EFI_SUCCESS;\r
\r
TotalPort = (Ehc->HcStructParams & HCSP_NPORTS);\r
\r
goto ON_EXIT;\r
}\r
\r
- Offset = (UINT32) (EHC_PORT_STAT_OFFSET + (4 * PortNumber));\r
- PortStatus->PortStatus = 0;\r
- PortStatus->PortChangeStatus = 0;\r
+ Offset = (UINT32)(EHC_PORT_STAT_OFFSET + (4 * PortNumber));\r
+ PortStatus->PortStatus = 0;\r
+ PortStatus->PortChangeStatus = 0;\r
+\r
+ if (EhcIsDebugPortInUse (Ehc, &PortNumber)) {\r
+ goto ON_EXIT;\r
+ }\r
\r
- State = EhcReadOpReg (Ehc, Offset);\r
+ State = EhcReadOpReg (Ehc, Offset);\r
\r
//\r
// Identify device speed. If in K state, it is low speed.\r
//\r
if (EHC_BIT_IS_SET (State, PORTSC_LINESTATE_K)) {\r
PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;\r
-\r
} else if (EHC_BIT_IS_SET (State, PORTSC_ENABLED)) {\r
PortStatus->PortStatus |= USB_PORT_STAT_HIGH_SPEED;\r
}\r
\r
for (Index = 0; Index < MapSize; Index++) {\r
if (EHC_BIT_IS_SET (State, mUsbPortStateMap[Index].HwState)) {\r
- PortStatus->PortStatus = (UINT16) (PortStatus->PortStatus | mUsbPortStateMap[Index].UefiState);\r
+ PortStatus->PortStatus = (UINT16)(PortStatus->PortStatus | mUsbPortStateMap[Index].UefiState);\r
}\r
}\r
\r
\r
for (Index = 0; Index < MapSize; Index++) {\r
if (EHC_BIT_IS_SET (State, mUsbPortChangeMap[Index].HwState)) {\r
- PortStatus->PortChangeStatus = (UINT16) (PortStatus->PortChangeStatus | mUsbPortChangeMap[Index].UefiState);\r
+ PortStatus->PortChangeStatus = (UINT16)(PortStatus->PortChangeStatus | mUsbPortChangeMap[Index].UefiState);\r
}\r
}\r
\r
return Status;\r
}\r
\r
-\r
/**\r
Sets a feature for the specified root hub port.\r
\r
- @param This This EFI_USB2_HC_PROTOCOL instance.\r
- @param PortNumber Root hub port to set.\r
- @param PortFeature Feature to set\r
+ @param This This EFI_USB2_HC_PROTOCOL instance.\r
+ @param PortNumber Root hub port to set.\r
+ @param PortFeature Feature to set.\r
\r
- @return EFI_SUCCESS : The feature specified by PortFeature was set\r
- @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.\r
- @return EFI_DEVICE_ERROR : Can't read register\r
+ @retval EFI_SUCCESS The feature specified by PortFeature was set.\r
+ @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.\r
+ @retval EFI_DEVICE_ERROR Can't read register.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
EhcSetRootHubPortFeature (\r
IN EFI_USB_PORT_FEATURE PortFeature\r
)\r
{\r
- USB2_HC_DEV *Ehc;\r
- EFI_TPL OldTpl;\r
- UINT32 Offset;\r
- UINT32 State;\r
- UINT32 TotalPort;\r
- EFI_STATUS Status;\r
-\r
- OldTpl = gBS->RaiseTPL (EHC_TPL);\r
- Ehc = EHC_FROM_THIS (This);\r
- Status = EFI_SUCCESS;\r
+ USB2_HC_DEV *Ehc;\r
+ EFI_TPL OldTpl;\r
+ UINT32 Offset;\r
+ UINT32 State;\r
+ UINT32 TotalPort;\r
+ EFI_STATUS Status;\r
+\r
+ OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+ Ehc = EHC_FROM_THIS (This);\r
+ Status = EFI_SUCCESS;\r
\r
TotalPort = (Ehc->HcStructParams & HCSP_NPORTS);\r
\r
goto ON_EXIT;\r
}\r
\r
- Offset = (UINT32) (EHC_PORT_STAT_OFFSET + (4 * PortNumber));\r
- State = EhcReadOpReg (Ehc, Offset);\r
+ Offset = (UINT32)(EHC_PORT_STAT_OFFSET + (4 * PortNumber));\r
+ State = EhcReadOpReg (Ehc, Offset);\r
\r
//\r
// Mask off the port status change bits, these bits are\r
State &= ~PORTSC_CHANGE_MASK;\r
\r
switch (PortFeature) {\r
- case EfiUsbPortEnable:\r
- //\r
- // Sofeware can't set this bit, Port can only be enable by\r
- // EHCI as a part of the reset and enable\r
- //\r
- State |= PORTSC_ENABLED;\r
- EhcWriteOpReg (Ehc, Offset, State);\r
- break;\r
-\r
- case EfiUsbPortSuspend:\r
- State |= PORTSC_SUSPEND;\r
- EhcWriteOpReg (Ehc, Offset, State);\r
- break;\r
+ case EfiUsbPortEnable:\r
+ //\r
+ // Sofeware can't set this bit, Port can only be enable by\r
+ // EHCI as a part of the reset and enable\r
+ //\r
+ State |= PORTSC_ENABLED;\r
+ EhcWriteOpReg (Ehc, Offset, State);\r
+ break;\r
\r
- case EfiUsbPortReset:\r
- //\r
- // Make sure Host Controller not halt before reset it\r
- //\r
- if (EhcIsHalt (Ehc)) {\r
- Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT);\r
+ case EfiUsbPortSuspend:\r
+ State |= PORTSC_SUSPEND;\r
+ EhcWriteOpReg (Ehc, Offset, State);\r
+ break;\r
\r
- if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_INFO, "EhcSetRootHubPortFeature :failed to start HC - %r\n", Status));\r
- break;\r
+ case EfiUsbPortReset:\r
+ //\r
+ // Make sure Host Controller not halt before reset it\r
+ //\r
+ if (EhcIsHalt (Ehc)) {\r
+ Status = EhcRunHC (Ehc, EHC_GENERIC_TIMEOUT);\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ DEBUG ((DEBUG_INFO, "EhcSetRootHubPortFeature :failed to start HC - %r\n", Status));\r
+ break;\r
+ }\r
}\r
- }\r
\r
- //\r
- // Set one to PortReset bit must also set zero to PortEnable bit\r
- //\r
- State |= PORTSC_RESET;\r
- State &= ~PORTSC_ENABLED;\r
- EhcWriteOpReg (Ehc, Offset, State);\r
- break;\r
+ //\r
+ // Set one to PortReset bit must also set zero to PortEnable bit\r
+ //\r
+ State |= PORTSC_RESET;\r
+ State &= ~PORTSC_ENABLED;\r
+ EhcWriteOpReg (Ehc, Offset, State);\r
+ break;\r
\r
- case EfiUsbPortPower:\r
- //\r
- // Not supported, ignore the operation\r
- //\r
- Status = EFI_SUCCESS;\r
- break;\r
+ case EfiUsbPortPower:\r
+ //\r
+ // Set port power bit when PPC is 1\r
+ //\r
+ if ((Ehc->HcCapParams & HCSP_PPC) == HCSP_PPC) {\r
+ State |= PORTSC_POWER;\r
+ EhcWriteOpReg (Ehc, Offset, State);\r
+ }\r
+\r
+ break;\r
\r
- case EfiUsbPortOwner:\r
- State |= PORTSC_OWNER;\r
- EhcWriteOpReg (Ehc, Offset, State);\r
- break;\r
+ case EfiUsbPortOwner:\r
+ State |= PORTSC_OWNER;\r
+ EhcWriteOpReg (Ehc, Offset, State);\r
+ break;\r
\r
- default:\r
- Status = EFI_INVALID_PARAMETER;\r
+ default:\r
+ Status = EFI_INVALID_PARAMETER;\r
}\r
\r
ON_EXIT:\r
- DEBUG ((EFI_D_INFO, "EhcSetRootHubPortFeature: exit status %r\n", Status));\r
+ DEBUG ((DEBUG_INFO, "EhcSetRootHubPortFeature: exit status %r\n", Status));\r
\r
gBS->RestoreTPL (OldTpl);\r
return Status;\r
}\r
\r
-\r
/**\r
Clears a feature for the specified root hub port.\r
\r
- @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
- @param PortNumber Specifies the root hub port whose feature is\r
- requested to be cleared.\r
- @param PortFeature Indicates the feature selector associated with the\r
- feature clear request.\r
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ @param PortNumber Specifies the root hub port whose feature is\r
+ requested to be cleared.\r
+ @param PortFeature Indicates the feature selector associated with the\r
+ feature clear request.\r
\r
- @return EFI_SUCCESS : The feature specified by PortFeature was cleared\r
- @return for the USB root hub port specified by PortNumber.\r
- @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.\r
- @return EFI_DEVICE_ERROR : Can't read register\r
+ @retval EFI_SUCCESS The feature specified by PortFeature was cleared\r
+ for the USB root hub port specified by PortNumber.\r
+ @retval EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.\r
+ @retval EFI_DEVICE_ERROR Can't read register.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
EhcClearRootHubPortFeature (\r
IN EFI_USB_PORT_FEATURE PortFeature\r
)\r
{\r
- USB2_HC_DEV *Ehc;\r
- EFI_TPL OldTpl;\r
- UINT32 Offset;\r
- UINT32 State;\r
- UINT32 TotalPort;\r
- EFI_STATUS Status;\r
-\r
- OldTpl = gBS->RaiseTPL (EHC_TPL);\r
- Ehc = EHC_FROM_THIS (This);\r
- Status = EFI_SUCCESS;\r
+ USB2_HC_DEV *Ehc;\r
+ EFI_TPL OldTpl;\r
+ UINT32 Offset;\r
+ UINT32 State;\r
+ UINT32 TotalPort;\r
+ EFI_STATUS Status;\r
+\r
+ OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+ Ehc = EHC_FROM_THIS (This);\r
+ Status = EFI_SUCCESS;\r
\r
TotalPort = (Ehc->HcStructParams & HCSP_NPORTS);\r
\r
goto ON_EXIT;\r
}\r
\r
- Offset = EHC_PORT_STAT_OFFSET + (4 * PortNumber);\r
- State = EhcReadOpReg (Ehc, Offset);\r
+ Offset = EHC_PORT_STAT_OFFSET + (4 * PortNumber);\r
+ State = EhcReadOpReg (Ehc, Offset);\r
State &= ~PORTSC_CHANGE_MASK;\r
\r
switch (PortFeature) {\r
- case EfiUsbPortEnable:\r
- //\r
- // Clear PORT_ENABLE feature means disable port.\r
- //\r
- State &= ~PORTSC_ENABLED;\r
- EhcWriteOpReg (Ehc, Offset, State);\r
- break;\r
+ case EfiUsbPortEnable:\r
+ //\r
+ // Clear PORT_ENABLE feature means disable port.\r
+ //\r
+ State &= ~PORTSC_ENABLED;\r
+ EhcWriteOpReg (Ehc, Offset, State);\r
+ break;\r
\r
- case EfiUsbPortSuspend:\r
- //\r
- // A write of zero to this bit is ignored by the host\r
- // controller. The host controller will unconditionally\r
- // set this bit to a zero when:\r
- // 1. software sets the Forct Port Resume bit to a zero from a one.\r
- // 2. software sets the Port Reset bit to a one frome a zero.\r
- //\r
- State &= ~PORSTSC_RESUME;\r
- EhcWriteOpReg (Ehc, Offset, State);\r
- break;\r
+ case EfiUsbPortSuspend:\r
+ //\r
+ // A write of zero to this bit is ignored by the host\r
+ // controller. The host controller will unconditionally\r
+ // set this bit to a zero when:\r
+ // 1. software sets the Forct Port Resume bit to a zero from a one.\r
+ // 2. software sets the Port Reset bit to a one frome a zero.\r
+ //\r
+ State &= ~PORSTSC_RESUME;\r
+ EhcWriteOpReg (Ehc, Offset, State);\r
+ break;\r
\r
- case EfiUsbPortReset:\r
- //\r
- // Clear PORT_RESET means clear the reset signal.\r
- //\r
- State &= ~PORTSC_RESET;\r
- EhcWriteOpReg (Ehc, Offset, State);\r
- break;\r
+ case EfiUsbPortReset:\r
+ //\r
+ // Clear PORT_RESET means clear the reset signal.\r
+ //\r
+ State &= ~PORTSC_RESET;\r
+ EhcWriteOpReg (Ehc, Offset, State);\r
+ break;\r
\r
- case EfiUsbPortOwner:\r
- //\r
- // Clear port owner means this port owned by EHC\r
- //\r
- State &= ~PORTSC_OWNER;\r
- EhcWriteOpReg (Ehc, Offset, State);\r
- break;\r
+ case EfiUsbPortOwner:\r
+ //\r
+ // Clear port owner means this port owned by EHC\r
+ //\r
+ State &= ~PORTSC_OWNER;\r
+ EhcWriteOpReg (Ehc, Offset, State);\r
+ break;\r
\r
- case EfiUsbPortConnectChange:\r
- //\r
- // Clear connect status change\r
- //\r
- State |= PORTSC_CONN_CHANGE;\r
- EhcWriteOpReg (Ehc, Offset, State);\r
- break;\r
+ case EfiUsbPortConnectChange:\r
+ //\r
+ // Clear connect status change\r
+ //\r
+ State |= PORTSC_CONN_CHANGE;\r
+ EhcWriteOpReg (Ehc, Offset, State);\r
+ break;\r
\r
- case EfiUsbPortEnableChange:\r
- //\r
- // Clear enable status change\r
- //\r
- State |= PORTSC_ENABLE_CHANGE;\r
- EhcWriteOpReg (Ehc, Offset, State);\r
- break;\r
+ case EfiUsbPortEnableChange:\r
+ //\r
+ // Clear enable status change\r
+ //\r
+ State |= PORTSC_ENABLE_CHANGE;\r
+ EhcWriteOpReg (Ehc, Offset, State);\r
+ break;\r
\r
- case EfiUsbPortOverCurrentChange:\r
- //\r
- // Clear PortOverCurrent change\r
- //\r
- State |= PORTSC_OVERCUR_CHANGE;\r
- EhcWriteOpReg (Ehc, Offset, State);\r
- break;\r
+ case EfiUsbPortOverCurrentChange:\r
+ //\r
+ // Clear PortOverCurrent change\r
+ //\r
+ State |= PORTSC_OVERCUR_CHANGE;\r
+ EhcWriteOpReg (Ehc, Offset, State);\r
+ break;\r
\r
- case EfiUsbPortPower:\r
- case EfiUsbPortSuspendChange:\r
- case EfiUsbPortResetChange:\r
- //\r
- // Not supported or not related operation\r
- //\r
- break;\r
+ case EfiUsbPortPower:\r
+ //\r
+ // Clear port power bit when PPC is 1\r
+ //\r
+ if ((Ehc->HcCapParams & HCSP_PPC) == HCSP_PPC) {\r
+ State &= ~PORTSC_POWER;\r
+ EhcWriteOpReg (Ehc, Offset, State);\r
+ }\r
\r
- default:\r
- Status = EFI_INVALID_PARAMETER;\r
- break;\r
+ break;\r
+ case EfiUsbPortSuspendChange:\r
+ case EfiUsbPortResetChange:\r
+ //\r
+ // Not supported or not related operation\r
+ //\r
+ break;\r
+\r
+ default:\r
+ Status = EFI_INVALID_PARAMETER;\r
+ break;\r
}\r
\r
ON_EXIT:\r
- DEBUG ((EFI_D_INFO, "EhcClearRootHubPortFeature: exit status %r\n", Status));\r
+ DEBUG ((DEBUG_INFO, "EhcClearRootHubPortFeature: exit status %r\n", Status));\r
gBS->RestoreTPL (OldTpl);\r
return Status;\r
}\r
\r
-\r
/**\r
Submits control transfer to a target USB device.\r
\r
- @param This This EFI_USB2_HC_PROTOCOL instance.\r
- @param DeviceAddress The target device address\r
- @param DeviceSpeed Target device speed.\r
- @param MaximumPacketLength Maximum packet size the default control transfer\r
- endpoint is capable of sending or receiving.\r
- @param Request USB device request to send\r
- @param TransferDirection Specifies the data direction for the data stage\r
- @param Data Data buffer to be transmitted or received from USB\r
- device.\r
- @param DataLength The size (in bytes) of the data buffer\r
- @param TimeOut Indicates the maximum timeout, in millisecond,\r
- @param Translator Transaction translator to be used by this device.\r
- @param TransferResult Return the result of this control transfer.\r
-\r
- @return EFI_SUCCESS : Transfer was completed successfully.\r
- @return EFI_OUT_OF_RESOURCES : The transfer failed due to lack of resources.\r
- @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
- @return EFI_TIMEOUT : Transfer failed due to timeout.\r
- @return EFI_DEVICE_ERROR : Transfer failed due to host controller or device error.\r
+ @param This This EFI_USB2_HC_PROTOCOL instance.\r
+ @param DeviceAddress The target device address.\r
+ @param DeviceSpeed Target device speed.\r
+ @param MaximumPacketLength Maximum packet size the default control transfer\r
+ endpoint is capable of sending or receiving.\r
+ @param Request USB device request to send.\r
+ @param TransferDirection Specifies the data direction for the data stage\r
+ @param Data Data buffer to be transmitted or received from USB\r
+ device.\r
+ @param DataLength The size (in bytes) of the data buffer.\r
+ @param TimeOut Indicates the maximum timeout, in millisecond.\r
+ @param Translator Transaction translator to be used by this device.\r
+ @param TransferResult Return the result of this control transfer.\r
+\r
+ @retval EFI_SUCCESS Transfer was completed successfully.\r
+ @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources.\r
+ @retval EFI_INVALID_PARAMETER Some parameters are invalid.\r
+ @retval EFI_TIMEOUT Transfer failed due to timeout.\r
+ @retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
EhcControlTransfer (\r
OUT UINT32 *TransferResult\r
)\r
{\r
- USB2_HC_DEV *Ehc;\r
- URB *Urb;\r
- EFI_TPL OldTpl;\r
- UINT8 Endpoint;\r
- EFI_STATUS Status;\r
+ USB2_HC_DEV *Ehc;\r
+ URB *Urb;\r
+ EFI_TPL OldTpl;\r
+ UINT8 Endpoint;\r
+ EFI_STATUS Status;\r
\r
//\r
// Validate parameters\r
\r
if ((TransferDirection != EfiUsbDataIn) &&\r
(TransferDirection != EfiUsbDataOut) &&\r
- (TransferDirection != EfiUsbNoData)) {\r
+ (TransferDirection != EfiUsbNoData))\r
+ {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
if ((TransferDirection == EfiUsbNoData) &&\r
- ((Data != NULL) || (*DataLength != 0))) {\r
+ ((Data != NULL) || (*DataLength != 0)))\r
+ {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
if ((TransferDirection != EfiUsbNoData) &&\r
- ((Data == NULL) || (*DataLength == 0))) {\r
+ ((Data == NULL) || (*DataLength == 0)))\r
+ {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
if ((MaximumPacketLength != 8) && (MaximumPacketLength != 16) &&\r
- (MaximumPacketLength != 32) && (MaximumPacketLength != 64)) {\r
+ (MaximumPacketLength != 32) && (MaximumPacketLength != 64))\r
+ {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- OldTpl = gBS->RaiseTPL (EHC_TPL);\r
- Ehc = EHC_FROM_THIS (This);\r
+ OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+ Ehc = EHC_FROM_THIS (This);\r
\r
Status = EFI_DEVICE_ERROR;\r
*TransferResult = EFI_USB_ERR_SYSTEM;\r
\r
if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) {\r
- DEBUG ((EFI_D_ERROR, "EhcControlTransfer: HC halted at entrance\n"));\r
+ DEBUG ((DEBUG_ERROR, "EhcControlTransfer: HC halted at entrance\n"));\r
\r
EhcAckAllInterrupt (Ehc);\r
goto ON_EXIT;\r
// endpoint is bidirectional. EhcCreateUrb expects this\r
// combination of Ep addr and its direction.\r
//\r
- Endpoint = (UINT8) (0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0));\r
- Urb = EhcCreateUrb (\r
- Ehc,\r
- DeviceAddress,\r
- Endpoint,\r
- DeviceSpeed,\r
- 0,\r
- MaximumPacketLength,\r
- Translator,\r
- EHC_CTRL_TRANSFER,\r
- Request,\r
- Data,\r
- *DataLength,\r
- NULL,\r
- NULL,\r
- 1\r
- );\r
+ Endpoint = (UINT8)(0 | ((TransferDirection == EfiUsbDataIn) ? 0x80 : 0));\r
+ Urb = EhcCreateUrb (\r
+ Ehc,\r
+ DeviceAddress,\r
+ Endpoint,\r
+ DeviceSpeed,\r
+ 0,\r
+ MaximumPacketLength,\r
+ Translator,\r
+ EHC_CTRL_TRANSFER,\r
+ Request,\r
+ Data,\r
+ *DataLength,\r
+ NULL,\r
+ NULL,\r
+ 1\r
+ );\r
\r
if (Urb == NULL) {\r
- DEBUG ((EFI_D_ERROR, "EhcControlTransfer: failed to create URB"));\r
+ DEBUG ((DEBUG_ERROR, "EhcControlTransfer: failed to create URB"));\r
\r
Status = EFI_OUT_OF_RESOURCES;\r
goto ON_EXIT;\r
gBS->RestoreTPL (OldTpl);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "EhcControlTransfer: error - %r, transfer - %x\n", Status, *TransferResult));\r
+ DEBUG ((DEBUG_ERROR, "EhcControlTransfer: error - %r, transfer - %x\n", Status, *TransferResult));\r
}\r
\r
return Status;\r
}\r
\r
-\r
/**\r
Submits bulk transfer to a bulk endpoint of a USB device.\r
\r
- @param This This EFI_USB2_HC_PROTOCOL instance.\r
- @param DeviceAddress Target device address\r
- @param EndPointAddress Endpoint number and its direction in bit 7. .\r
- @param DeviceSpeed Device speed, Low speed device doesn't support bulk\r
- transfer.\r
- @param MaximumPacketLength Maximum packet size the endpoint is capable of\r
- sending or receiving.\r
- @param DataBuffersNumber Number of data buffers prepared for the transfer.\r
- @param Data Array of pointers to the buffers of data to transmit\r
+ @param This This EFI_USB2_HC_PROTOCOL instance.\r
+ @param DeviceAddress Target device address.\r
+ @param EndPointAddress Endpoint number and its direction in bit 7.\r
+ @param DeviceSpeed Device speed, Low speed device doesn't support bulk\r
+ transfer.\r
+ @param MaximumPacketLength Maximum packet size the endpoint is capable of\r
+ sending or receiving.\r
+ @param DataBuffersNumber Number of data buffers prepared for the transfer.\r
+ @param Data Array of pointers to the buffers of data to transmit\r
from or receive into.\r
- @param DataLength The lenght of the data buffer\r
- @param DataToggle On input, the initial data toggle for the transfer;\r
- On output, it is updated to to next data toggle to\r
- use of the subsequent bulk\r
- transfer.\r
- @param Translator A pointr to the transaction translator data.\r
- @param TimeOut Indicates the maximum time, in millisecond, which\r
- the transfer is allowed to complete.\r
- @param TransferResult A pointer to the detailed result information of the\r
- bulk transfer.\r
-\r
- @return EFI_SUCCESS : The transfer was completed successfully.\r
- @return EFI_OUT_OF_RESOURCES : The transfer failed due to lack of resource.\r
- @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
- @return EFI_TIMEOUT : The transfer failed due to timeout.\r
- @return EFI_DEVICE_ERROR : The transfer failed due to host controller error.\r
+ @param DataLength The lenght of the data buffer.\r
+ @param DataToggle On input, the initial data toggle for the transfer;\r
+ On output, it is updated to to next data toggle to\r
+ use of the subsequent bulk transfer.\r
+ @param TimeOut Indicates the maximum time, in millisecond, which\r
+ the transfer is allowed to complete.\r
+ @param Translator A pointr to the transaction translator data.\r
+ @param TransferResult A pointer to the detailed result information of the\r
+ bulk transfer.\r
+\r
+ @retval EFI_SUCCESS The transfer was completed successfully.\r
+ @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource.\r
+ @retval EFI_INVALID_PARAMETER Some parameters are invalid.\r
+ @retval EFI_TIMEOUT The transfer failed due to timeout.\r
+ @retval EFI_DEVICE_ERROR The transfer failed due to host controller error.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
EhcBulkTransfer (\r
OUT UINT32 *TransferResult\r
)\r
{\r
- USB2_HC_DEV *Ehc;\r
- URB *Urb;\r
- EFI_TPL OldTpl;\r
- EFI_STATUS Status;\r
+ USB2_HC_DEV *Ehc;\r
+ URB *Urb;\r
+ EFI_TPL OldTpl;\r
+ EFI_STATUS Status;\r
+ UINTN DebugErrorLevel;\r
\r
//\r
// Validate the parameters\r
//\r
if ((DataLength == NULL) || (*DataLength == 0) ||\r
- (Data == NULL) || (Data[0] == NULL) || (TransferResult == NULL)) {\r
+ (Data == NULL) || (Data[0] == NULL) || (TransferResult == NULL))\r
+ {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
\r
if ((DeviceSpeed == EFI_USB_SPEED_LOW) ||\r
((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) ||\r
- ((EFI_USB_SPEED_HIGH == DeviceSpeed) && (MaximumPacketLength > 512))) {\r
+ ((EFI_USB_SPEED_HIGH == DeviceSpeed) && (MaximumPacketLength > 512)))\r
+ {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- OldTpl = gBS->RaiseTPL (EHC_TPL);\r
- Ehc = EHC_FROM_THIS (This);\r
+ OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+ Ehc = EHC_FROM_THIS (This);\r
\r
*TransferResult = EFI_USB_ERR_SYSTEM;\r
Status = EFI_DEVICE_ERROR;\r
\r
if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) {\r
- DEBUG ((EFI_D_ERROR, "EhcBulkTransfer: HC is halted\n"));\r
+ DEBUG ((DEBUG_ERROR, "EhcBulkTransfer: HC is halted\n"));\r
\r
EhcAckAllInterrupt (Ehc);\r
goto ON_EXIT;\r
);\r
\r
if (Urb == NULL) {\r
- DEBUG ((EFI_D_ERROR, "EhcBulkTransfer: failed to create URB\n"));\r
+ DEBUG ((DEBUG_ERROR, "EhcBulkTransfer: failed to create URB\n"));\r
\r
Status = EFI_OUT_OF_RESOURCES;\r
goto ON_EXIT;\r
gBS->RestoreTPL (OldTpl);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "EhcBulkTransfer: error - %r, transfer - %x\n", Status, *TransferResult));\r
+ if (Status == EFI_TIMEOUT) {\r
+ DebugErrorLevel = DEBUG_VERBOSE;\r
+ } else {\r
+ DebugErrorLevel = DEBUG_ERROR;\r
+ }\r
+\r
+ DEBUG ((DebugErrorLevel, "EhcBulkTransfer: error - %r, transfer - %x\n", Status, *TransferResult));\r
}\r
\r
return Status;\r
}\r
\r
-\r
/**\r
Submits an asynchronous interrupt transfer to an\r
interrupt endpoint of a USB device.\r
\r
- @param This This EFI_USB2_HC_PROTOCOL instance.\r
- @param DeviceAddress Target device address\r
- @param EndPointAddress Endpoint number and its direction encoded in bit 7\r
- @param DeviceSpeed Indicates device speed.\r
- @param MaximumPacketLength Maximum packet size the target endpoint is capable\r
- @param IsNewTransfer If TRUE, to submit an new asynchronous interrupt\r
- transfer If FALSE, to remove the specified\r
- asynchronous interrupt\r
- @param DataToggle On input, the initial data toggle to use; on output,\r
- it is updated to indicate the next data toggle\r
- @param PollingInterval The he interval, in milliseconds, that the transfer\r
- is polled.\r
- @param DataLength The length of data to receive at the rate specified\r
- by PollingInterval.\r
- @param Translator Transaction translator to use.\r
- @param CallBackFunction Function to call at the rate specified by\r
- PollingInterval\r
- @param Context Context to CallBackFunction.\r
-\r
- @return EFI_SUCCESS : The request has been successfully submitted or canceled.\r
- @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
- @return EFI_OUT_OF_RESOURCES : The request failed due to a lack of resources.\r
- @return EFI_DEVICE_ERROR : The transfer failed due to host controller error.\r
+ @param This This EFI_USB2_HC_PROTOCOL instance.\r
+ @param DeviceAddress Target device address.\r
+ @param EndPointAddress Endpoint number and its direction encoded in bit 7\r
+ @param DeviceSpeed Indicates device speed.\r
+ @param MaximumPacketLength Maximum packet size the target endpoint is capable\r
+ @param IsNewTransfer If TRUE, to submit an new asynchronous interrupt\r
+ transfer If FALSE, to remove the specified\r
+ asynchronous interrupt.\r
+ @param DataToggle On input, the initial data toggle to use; on output,\r
+ it is updated to indicate the next data toggle.\r
+ @param PollingInterval The he interval, in milliseconds, that the transfer\r
+ is polled.\r
+ @param DataLength The length of data to receive at the rate specified\r
+ by PollingInterval.\r
+ @param Translator Transaction translator to use.\r
+ @param CallBackFunction Function to call at the rate specified by\r
+ PollingInterval.\r
+ @param Context Context to CallBackFunction.\r
+\r
+ @retval EFI_SUCCESS The request has been successfully submitted or canceled.\r
+ @retval EFI_INVALID_PARAMETER Some parameters are invalid.\r
+ @retval EFI_OUT_OF_RESOURCES The request failed due to a lack of resources.\r
+ @retval EFI_DEVICE_ERROR The transfer failed due to host controller error.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
EhcAsyncInterruptTransfer (\r
- IN EFI_USB2_HC_PROTOCOL * This,\r
- IN UINT8 DeviceAddress,\r
- IN UINT8 EndPointAddress,\r
- IN UINT8 DeviceSpeed,\r
- IN UINTN MaximumPacketLength,\r
- IN BOOLEAN IsNewTransfer,\r
- IN OUT UINT8 *DataToggle,\r
- IN UINTN PollingInterval,\r
- IN UINTN DataLength,\r
- IN EFI_USB2_HC_TRANSACTION_TRANSLATOR * Translator,\r
- IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,\r
- IN VOID *Context OPTIONAL\r
+ IN EFI_USB2_HC_PROTOCOL *This,\r
+ IN UINT8 DeviceAddress,\r
+ IN UINT8 EndPointAddress,\r
+ IN UINT8 DeviceSpeed,\r
+ IN UINTN MaximumPacketLength,\r
+ IN BOOLEAN IsNewTransfer,\r
+ IN OUT UINT8 *DataToggle,\r
+ IN UINTN PollingInterval,\r
+ IN UINTN DataLength,\r
+ IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,\r
+ IN EFI_ASYNC_USB_TRANSFER_CALLBACK CallBackFunction,\r
+ IN VOID *Context OPTIONAL\r
)\r
{\r
- USB2_HC_DEV *Ehc;\r
- URB *Urb;\r
- EFI_TPL OldTpl;\r
- EFI_STATUS Status;\r
- UINT8 *Data;\r
+ USB2_HC_DEV *Ehc;\r
+ URB *Urb;\r
+ EFI_TPL OldTpl;\r
+ EFI_STATUS Status;\r
\r
//\r
// Validate parameters\r
}\r
}\r
\r
- OldTpl = gBS->RaiseTPL (EHC_TPL);\r
- Ehc = EHC_FROM_THIS (This);\r
+ OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+ Ehc = EHC_FROM_THIS (This);\r
\r
//\r
// Delete Async interrupt transfer request. DataToggle will return\r
if (!IsNewTransfer) {\r
Status = EhciDelAsyncIntTransfer (Ehc, DeviceAddress, EndPointAddress, DataToggle);\r
\r
- DEBUG ((EFI_D_INFO, "EhcAsyncInterruptTransfer: remove old transfer - %r\n", Status));\r
+ DEBUG ((DEBUG_INFO, "EhcAsyncInterruptTransfer: remove old transfer - %r\n", Status));\r
goto ON_EXIT;\r
}\r
\r
Status = EFI_SUCCESS;\r
\r
if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) {\r
- DEBUG ((EFI_D_ERROR, "EhcAsyncInterruptTransfer: HC is halt\n"));\r
+ DEBUG ((DEBUG_ERROR, "EhcAsyncInterruptTransfer: HC is halt\n"));\r
EhcAckAllInterrupt (Ehc);\r
\r
Status = EFI_DEVICE_ERROR;\r
\r
EhcAckAllInterrupt (Ehc);\r
\r
- Data = AllocatePool (DataLength);\r
-\r
- if (Data == NULL) {\r
- DEBUG ((EFI_D_ERROR, "EhcAsyncInterruptTransfer: failed to allocate buffer\n"));\r
-\r
- Status = EFI_OUT_OF_RESOURCES;\r
- goto ON_EXIT;\r
- }\r
-\r
- Urb = EhcCreateUrb (\r
+ Urb = EhciInsertAsyncIntTransfer (\r
Ehc,\r
DeviceAddress,\r
EndPointAddress,\r
*DataToggle,\r
MaximumPacketLength,\r
Translator,\r
- EHC_INT_TRANSFER_ASYNC,\r
- NULL,\r
- Data,\r
DataLength,\r
CallBackFunction,\r
Context,\r
);\r
\r
if (Urb == NULL) {\r
- DEBUG ((EFI_D_ERROR, "EhcAsyncInterruptTransfer: failed to create URB\n"));\r
-\r
- gBS->FreePool (Data);\r
Status = EFI_OUT_OF_RESOURCES;\r
goto ON_EXIT;\r
}\r
\r
- //\r
- // New asynchronous transfer must inserted to the head.\r
- // Check the comments in EhcMoniteAsyncRequests\r
- //\r
- EhcLinkQhToPeriod (Ehc, Urb->Qh);\r
- InsertHeadList (&Ehc->AsyncIntTransfers, &Urb->UrbList);\r
-\r
ON_EXIT:\r
Ehc->PciIo->Flush (Ehc->PciIo);\r
gBS->RestoreTPL (OldTpl);\r
return Status;\r
}\r
\r
-\r
/**\r
Submits synchronous interrupt transfer to an interrupt endpoint\r
of a USB device.\r
\r
- @param This This EFI_USB2_HC_PROTOCOL instance.\r
- @param DeviceAddress Target device address\r
- @param EndPointAddress Endpoint number and its direction encoded in bit 7\r
- @param DeviceSpeed Indicates device speed.\r
- @param MaximumPacketLength Maximum packet size the target endpoint is capable\r
- of sending or receiving.\r
- @param Data Buffer of data that will be transmitted to USB\r
- device or received from USB device.\r
- @param DataLength On input, the size, in bytes, of the data buffer; On\r
- output, the number of bytes transferred.\r
- @param DataToggle On input, the initial data toggle to use; on output,\r
- it is updated to indicate the next data toggle\r
- @param TimeOut Maximum time, in second, to complete\r
- @param Translator Transaction translator to use.\r
- @param TransferResult Variable to receive the transfer result\r
-\r
- @return EFI_SUCCESS : The transfer was completed successfully.\r
- @return EFI_OUT_OF_RESOURCES : The transfer failed due to lack of resource.\r
- @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
- @return EFI_TIMEOUT : The transfer failed due to timeout.\r
- @return EFI_DEVICE_ERROR : The failed due to host controller or device error\r
+ @param This This EFI_USB2_HC_PROTOCOL instance.\r
+ @param DeviceAddress Target device address.\r
+ @param EndPointAddress Endpoint number and its direction encoded in bit 7\r
+ @param DeviceSpeed Indicates device speed.\r
+ @param MaximumPacketLength Maximum packet size the target endpoint is capable\r
+ of sending or receiving.\r
+ @param Data Buffer of data that will be transmitted to USB\r
+ device or received from USB device.\r
+ @param DataLength On input, the size, in bytes, of the data buffer; On\r
+ output, the number of bytes transferred.\r
+ @param DataToggle On input, the initial data toggle to use; on output,\r
+ it is updated to indicate the next data toggle.\r
+ @param TimeOut Maximum time, in second, to complete.\r
+ @param Translator Transaction translator to use.\r
+ @param TransferResult Variable to receive the transfer result.\r
+\r
+ @return EFI_SUCCESS The transfer was completed successfully.\r
+ @return EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource.\r
+ @return EFI_INVALID_PARAMETER Some parameters are invalid.\r
+ @return EFI_TIMEOUT The transfer failed due to timeout.\r
+ @return EFI_DEVICE_ERROR The failed due to host controller or device error\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
EhcSyncInterruptTransfer (\r
OUT UINT32 *TransferResult\r
)\r
{\r
- USB2_HC_DEV *Ehc;\r
- EFI_TPL OldTpl;\r
- URB *Urb;\r
- EFI_STATUS Status;\r
+ USB2_HC_DEV *Ehc;\r
+ EFI_TPL OldTpl;\r
+ URB *Urb;\r
+ EFI_STATUS Status;\r
\r
//\r
// Validates parameters\r
//\r
if ((DataLength == NULL) || (*DataLength == 0) ||\r
- (Data == NULL) || (TransferResult == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (!EHCI_IS_DATAIN (EndPointAddress)) {\r
+ (Data == NULL) || (TransferResult == NULL))\r
+ {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
\r
if (((DeviceSpeed == EFI_USB_SPEED_LOW) && (MaximumPacketLength != 8)) ||\r
((DeviceSpeed == EFI_USB_SPEED_FULL) && (MaximumPacketLength > 64)) ||\r
- ((DeviceSpeed == EFI_USB_SPEED_HIGH) && (MaximumPacketLength > 3072))) {\r
+ ((DeviceSpeed == EFI_USB_SPEED_HIGH) && (MaximumPacketLength > 3072)))\r
+ {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- OldTpl = gBS->RaiseTPL (EHC_TPL);\r
- Ehc = EHC_FROM_THIS (This);\r
+ OldTpl = gBS->RaiseTPL (EHC_TPL);\r
+ Ehc = EHC_FROM_THIS (This);\r
\r
*TransferResult = EFI_USB_ERR_SYSTEM;\r
Status = EFI_DEVICE_ERROR;\r
\r
if (EhcIsHalt (Ehc) || EhcIsSysError (Ehc)) {\r
- DEBUG ((EFI_D_ERROR, "EhcSyncInterruptTransfer: HC is halt\n"));\r
+ DEBUG ((DEBUG_ERROR, "EhcSyncInterruptTransfer: HC is halt\n"));\r
\r
EhcAckAllInterrupt (Ehc);\r
goto ON_EXIT;\r
);\r
\r
if (Urb == NULL) {\r
- DEBUG ((EFI_D_ERROR, "EhcSyncInterruptTransfer: failed to create URB\n"));\r
+ DEBUG ((DEBUG_ERROR, "EhcSyncInterruptTransfer: failed to create URB\n"));\r
\r
Status = EFI_OUT_OF_RESOURCES;\r
goto ON_EXIT;\r
Status = EFI_SUCCESS;\r
}\r
\r
+ EhcFreeUrb (Ehc, Urb);\r
ON_EXIT:\r
Ehc->PciIo->Flush (Ehc->PciIo);\r
gBS->RestoreTPL (OldTpl);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "EhcSyncInterruptTransfer: error - %r, transfer - %x\n", Status, *TransferResult));\r
+ DEBUG ((DEBUG_ERROR, "EhcSyncInterruptTransfer: error - %r, transfer - %x\n", Status, *TransferResult));\r
}\r
\r
return Status;\r
}\r
\r
-\r
/**\r
Submits isochronous transfer to a target USB device.\r
\r
@param This This EFI_USB2_HC_PROTOCOL instance.\r
- @param DeviceAddress Target device address\r
- @param EndPointAddress End point address with its direction\r
+ @param DeviceAddress Target device address.\r
+ @param EndPointAddress End point address with its direction.\r
@param DeviceSpeed Device speed, Low speed device doesn't support this\r
type.\r
@param MaximumPacketLength Maximum packet size that the endpoint is capable of\r
@param Data Array of pointers to the buffers of data that will\r
be transmitted to USB device or received from USB\r
device.\r
- @param DataLength The size, in bytes, of the data buffer\r
+ @param DataLength The size, in bytes, of the data buffer.\r
@param Translator Transaction translator to use.\r
- @param TransferResult Variable to receive the transfer result\r
+ @param TransferResult Variable to receive the transfer result.\r
\r
- @return EFI_UNSUPPORTED : Isochronous transfer is unsupported.\r
+ @return EFI_UNSUPPORTED Isochronous transfer is unsupported.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
EhcIsochronousTransfer (\r
return EFI_UNSUPPORTED;\r
}\r
\r
-\r
/**\r
Submits Async isochronous transfer to a target USB device.\r
\r
@param This This EFI_USB2_HC_PROTOCOL instance.\r
- @param DeviceAddress Target device address\r
- @param EndPointAddress End point address with its direction\r
+ @param DeviceAddress Target device address.\r
+ @param EndPointAddress End point address with its direction.\r
@param DeviceSpeed Device speed, Low speed device doesn't support this\r
type.\r
@param MaximumPacketLength Maximum packet size that the endpoint is capable of\r
@param Data Array of pointers to the buffers of data that will\r
be transmitted to USB device or received from USB\r
device.\r
- @param DataLength The size, in bytes, of the data buffer\r
+ @param DataLength The size, in bytes, of the data buffer.\r
@param Translator Transaction translator to use.\r
- @param IsochronousCallBack Function to be called when the transfer complete\r
+ @param IsochronousCallBack Function to be called when the transfer complete.\r
@param Context Context passed to the call back function as\r
- parameter\r
+ parameter.\r
\r
- @return EFI_UNSUPPORTED : Isochronous transfer isn't supported\r
+ @return EFI_UNSUPPORTED Isochronous transfer isn't supported.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
EhcAsyncIsochronousTransfer (\r
return EFI_UNSUPPORTED;\r
}\r
\r
-EFI_STATUS\r
-EFIAPI\r
-EhcDriverEntryPoint (\r
- IN EFI_HANDLE ImageHandle,\r
- IN EFI_SYSTEM_TABLE *SystemTable\r
- )\r
-/*++\r
-\r
-Routine Description:\r
-\r
+/**\r
Entry point for EFI drivers.\r
\r
-Arguments:\r
-\r
- ImageHandle - EFI_HANDLE\r
- SystemTable - EFI_SYSTEM_TABLE\r
+ @param ImageHandle EFI_HANDLE.\r
+ @param SystemTable EFI_SYSTEM_TABLE.\r
\r
-Returns:\r
+ @return EFI_SUCCESS Success.\r
+ EFI_DEVICE_ERROR Fail.\r
\r
- EFI_SUCCESS Success\r
- EFI_DEVICE_ERROR Fail\r
-\r
---*/\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+EhcDriverEntryPoint (\r
+ IN EFI_HANDLE ImageHandle,\r
+ IN EFI_SYSTEM_TABLE *SystemTable\r
+ )\r
{\r
return EfiLibInstallDriverBindingComponentName2 (\r
ImageHandle,\r
);\r
}\r
\r
-\r
/**\r
Test to see if this driver supports ControllerHandle. Any\r
ControllerHandle that has Usb2HcProtocol installed will\r
be supported.\r
\r
@param This Protocol instance pointer.\r
- @param Controlle Handle of device to test\r
- @param RemainingDevicePath Not used\r
+ @param Controller Handle of device to test.\r
+ @param RemainingDevicePath Not used.\r
\r
- @return EFI_SUCCESS : This driver supports this device.\r
- @return EFI_UNSUPPORTED : This driver does not support this device.\r
+ @return EFI_SUCCESS This driver supports this device.\r
+ @return EFI_UNSUPPORTED This driver does not support this device.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
EhcDriverBindingSupported (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
)\r
{\r
- EFI_STATUS Status;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- USB_CLASSC UsbClassCReg;\r
+ EFI_STATUS Status;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ USB_CLASSC UsbClassCReg;\r
\r
//\r
// Test whether there is PCI IO Protocol attached on the controller handle.\r
Status = gBS->OpenProtocol (\r
Controller,\r
&gEfiPciIoProtocolGuid,\r
- (VOID **) &PciIo,\r
+ (VOID **)&PciIo,\r
This->DriverBindingHandle,\r
Controller,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
Status = PciIo->Pci.Read (\r
PciIo,\r
EfiPciIoWidthUint8,\r
- EHC_PCI_CLASSC,\r
+ PCI_CLASSCODE_OFFSET,\r
sizeof (USB_CLASSC) / sizeof (UINT8),\r
&UsbClassCReg\r
);\r
//\r
// Test whether the controller belongs to Ehci type\r
//\r
- if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||\r
- (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||\r
- (UsbClassCReg.PI != EHC_PCI_CLASSC_PI)) {\r
-\r
+ if ( (UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) || (UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB)\r
+ || ((UsbClassCReg.ProgInterface != PCI_IF_EHCI) && (UsbClassCReg.ProgInterface != PCI_IF_UHCI) && (UsbClassCReg.ProgInterface != PCI_IF_OHCI)))\r
+ {\r
Status = EFI_UNSUPPORTED;\r
}\r
\r
return Status;\r
}\r
\r
+/**\r
+ Get the usb debug port related information.\r
+\r
+ @param Ehc The EHCI device.\r
+\r
+ @retval RETURN_SUCCESS Get debug port number, bar and offset successfully.\r
+ @retval Others The usb host controller does not supported usb debug port capability.\r
+\r
+**/\r
+EFI_STATUS\r
+EhcGetUsbDebugPortInfo (\r
+ IN USB2_HC_DEV *Ehc\r
+ )\r
+{\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ UINT16 PciStatus;\r
+ UINT8 CapabilityPtr;\r
+ UINT8 CapabilityId;\r
+ UINT16 DebugPort;\r
+ EFI_STATUS Status;\r
+\r
+ ASSERT (Ehc->PciIo != NULL);\r
+ PciIo = Ehc->PciIo;\r
+\r
+ //\r
+ // Detect if the EHCI host controller support Capaility Pointer.\r
+ //\r
+ Status = PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ PCI_PRIMARY_STATUS_OFFSET,\r
+ sizeof (UINT16),\r
+ &PciStatus\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if ((PciStatus & EFI_PCI_STATUS_CAPABILITY) == 0) {\r
+ //\r
+ // The Pci Device Doesn't Support Capability Pointer.\r
+ //\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Get Pointer To Capability List\r
+ //\r
+ Status = PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ PCI_CAPBILITY_POINTER_OFFSET,\r
+ 1,\r
+ &CapabilityPtr\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ //\r
+ // Find Capability ID 0xA, Which Is For Debug Port\r
+ //\r
+ while (CapabilityPtr != 0) {\r
+ Status = PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ CapabilityPtr,\r
+ 1,\r
+ &CapabilityId\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ if (CapabilityId == EHC_DEBUG_PORT_CAP_ID) {\r
+ break;\r
+ }\r
+\r
+ Status = PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ CapabilityPtr + 1,\r
+ 1,\r
+ &CapabilityPtr\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+ }\r
+\r
+ //\r
+ // No Debug Port Capability Found\r
+ //\r
+ if (CapabilityPtr == 0) {\r
+ return EFI_UNSUPPORTED;\r
+ }\r
+\r
+ //\r
+ // Get The Base Address Of Debug Port Register In Debug Port Capability Register\r
+ //\r
+ Status = PciIo->Pci.Read (\r
+ Ehc->PciIo,\r
+ EfiPciIoWidthUint8,\r
+ CapabilityPtr + 2,\r
+ sizeof (UINT16),\r
+ &DebugPort\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ Ehc->DebugPortOffset = DebugPort & 0x1FFF;\r
+ Ehc->DebugPortBarNum = (UINT8)((DebugPort >> 13) - 1);\r
+ Ehc->DebugPortNum = (UINT8)((Ehc->HcStructParams & 0x00F00000) >> 20);\r
+\r
+ return EFI_SUCCESS;\r
+}\r
\r
/**\r
- Create and initialize a USB2_HC_DEV\r
+ Create and initialize a USB2_HC_DEV.\r
\r
- @param PciIo The PciIo on this device\r
- @param OriginalPciAttributes Original PCI attributes\r
+ @param PciIo The PciIo on this device.\r
+ @param DevicePath The device path of host controller.\r
+ @param OriginalPciAttributes Original PCI attributes.\r
\r
- @return The allocated and initialized USB2_HC_DEV structure\r
- @return if created, otherwise NULL.\r
+ @return The allocated and initialized USB2_HC_DEV structure if created,\r
+ otherwise NULL.\r
\r
**/\r
-STATIC\r
USB2_HC_DEV *\r
EhcCreateUsb2Hc (\r
- IN EFI_PCI_IO_PROTOCOL *PciIo,\r
- IN UINT64 OriginalPciAttributes\r
+ IN EFI_PCI_IO_PROTOCOL *PciIo,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *DevicePath,\r
+ IN UINT64 OriginalPciAttributes\r
)\r
{\r
- USB2_HC_DEV *Ehc;\r
- EFI_STATUS Status;\r
+ USB2_HC_DEV *Ehc;\r
+ EFI_STATUS Status;\r
\r
Ehc = AllocateZeroPool (sizeof (USB2_HC_DEV));\r
\r
//\r
// Init EFI_USB2_HC_PROTOCOL interface and private data structure\r
//\r
- Ehc->Signature = USB2_HC_DEV_SIGNATURE;\r
-\r
- Ehc->Usb2Hc.GetCapability = EhcGetCapability;\r
- Ehc->Usb2Hc.Reset = EhcReset;\r
- Ehc->Usb2Hc.GetState = EhcGetState;\r
- Ehc->Usb2Hc.SetState = EhcSetState;\r
- Ehc->Usb2Hc.ControlTransfer = EhcControlTransfer;\r
- Ehc->Usb2Hc.BulkTransfer = EhcBulkTransfer;\r
- Ehc->Usb2Hc.AsyncInterruptTransfer = EhcAsyncInterruptTransfer;\r
- Ehc->Usb2Hc.SyncInterruptTransfer = EhcSyncInterruptTransfer;\r
- Ehc->Usb2Hc.IsochronousTransfer = EhcIsochronousTransfer;\r
- Ehc->Usb2Hc.AsyncIsochronousTransfer = EhcAsyncIsochronousTransfer;\r
- Ehc->Usb2Hc.GetRootHubPortStatus = EhcGetRootHubPortStatus;\r
- Ehc->Usb2Hc.SetRootHubPortFeature = EhcSetRootHubPortFeature;\r
- Ehc->Usb2Hc.ClearRootHubPortFeature = EhcClearRootHubPortFeature;\r
- Ehc->Usb2Hc.MajorRevision = 0x1;\r
- Ehc->Usb2Hc.MinorRevision = 0x1;\r
+ Ehc->Signature = USB2_HC_DEV_SIGNATURE;\r
+\r
+ Ehc->Usb2Hc.GetCapability = EhcGetCapability;\r
+ Ehc->Usb2Hc.Reset = EhcReset;\r
+ Ehc->Usb2Hc.GetState = EhcGetState;\r
+ Ehc->Usb2Hc.SetState = EhcSetState;\r
+ Ehc->Usb2Hc.ControlTransfer = EhcControlTransfer;\r
+ Ehc->Usb2Hc.BulkTransfer = EhcBulkTransfer;\r
+ Ehc->Usb2Hc.AsyncInterruptTransfer = EhcAsyncInterruptTransfer;\r
+ Ehc->Usb2Hc.SyncInterruptTransfer = EhcSyncInterruptTransfer;\r
+ Ehc->Usb2Hc.IsochronousTransfer = EhcIsochronousTransfer;\r
+ Ehc->Usb2Hc.AsyncIsochronousTransfer = EhcAsyncIsochronousTransfer;\r
+ Ehc->Usb2Hc.GetRootHubPortStatus = EhcGetRootHubPortStatus;\r
+ Ehc->Usb2Hc.SetRootHubPortFeature = EhcSetRootHubPortFeature;\r
+ Ehc->Usb2Hc.ClearRootHubPortFeature = EhcClearRootHubPortFeature;\r
+ Ehc->Usb2Hc.MajorRevision = 0x2;\r
+ Ehc->Usb2Hc.MinorRevision = 0x0;\r
\r
Ehc->PciIo = PciIo;\r
+ Ehc->DevicePath = DevicePath;\r
Ehc->OriginalPciAttributes = OriginalPciAttributes;\r
\r
InitializeListHead (&Ehc->AsyncIntTransfers);\r
Ehc->HcCapParams = EhcReadCapRegister (Ehc, EHC_HCCPARAMS_OFFSET);\r
Ehc->CapLen = EhcReadCapRegister (Ehc, EHC_CAPLENGTH_OFFSET) & 0x0FF;\r
\r
- DEBUG ((EFI_D_INFO, "EhcCreateUsb2Hc: capability length %d\n", Ehc->CapLen));\r
+ DEBUG ((DEBUG_INFO, "EhcCreateUsb2Hc: capability length %d\n", Ehc->CapLen));\r
+\r
+ //\r
+ // EHCI Controllers with a CapLen of 0 are ignored.\r
+ //\r
+ if (Ehc->CapLen == 0) {\r
+ gBS->FreePool (Ehc);\r
+ return NULL;\r
+ }\r
+\r
+ EhcGetUsbDebugPortInfo (Ehc);\r
\r
//\r
// Create AsyncRequest Polling Timer\r
//\r
Status = gBS->CreateEvent (\r
EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
- EhcMoniteAsyncRequests,\r
+ TPL_NOTIFY,\r
+ EhcMonitorAsyncRequests,\r
Ehc,\r
&Ehc->PollTimer\r
);\r
return Ehc;\r
}\r
\r
+/**\r
+ One notified function to stop the Host Controller when gBS->ExitBootServices() called.\r
+\r
+ @param Event Pointer to this event\r
+ @param Context Event handler private data\r
+\r
+**/\r
+VOID\r
+EFIAPI\r
+EhcExitBootService (\r
+ EFI_EVENT Event,\r
+ VOID *Context\r
+ )\r
+\r
+{\r
+ USB2_HC_DEV *Ehc;\r
+\r
+ Ehc = (USB2_HC_DEV *)Context;\r
+\r
+ //\r
+ // Reset the Host Controller\r
+ //\r
+ EhcResetHC (Ehc, EHC_RESET_TIMEOUT);\r
+}\r
\r
/**\r
- Starting the Usb EHCI Driver\r
+ Starting the Usb EHCI Driver.\r
\r
@param This Protocol instance pointer.\r
- @param Controller Handle of device to test\r
- @param RemainingDevicePath Not used\r
+ @param Controller Handle of device to test.\r
+ @param RemainingDevicePath Not used.\r
\r
- @return EFI_SUCCESS : supports this device.\r
- @return EFI_UNSUPPORTED : do not support this device.\r
- @return EFI_DEVICE_ERROR : cannot be started due to device Error\r
- @return EFI_OUT_OF_RESOURCES : cannot allocate resources\r
+ @return EFI_SUCCESS supports this device.\r
+ @return EFI_UNSUPPORTED do not support this device.\r
+ @return EFI_DEVICE_ERROR cannot be started due to device Error.\r
+ @return EFI_OUT_OF_RESOURCES cannot allocate resources.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
EhcDriverBindingStart (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
)\r
{\r
- EFI_STATUS Status;\r
- USB2_HC_DEV *Ehc;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- UINT64 Supports;\r
- UINT64 OriginalPciAttributes;\r
- BOOLEAN PciAttributesSaved;\r
+ EFI_STATUS Status;\r
+ USB2_HC_DEV *Ehc;\r
+ EFI_PCI_IO_PROTOCOL *PciIo;\r
+ EFI_PCI_IO_PROTOCOL *Instance;\r
+ UINT64 Supports;\r
+ UINT64 OriginalPciAttributes;\r
+ BOOLEAN PciAttributesSaved;\r
+ USB_CLASSC UsbClassCReg;\r
+ EFI_HANDLE *HandleBuffer;\r
+ UINTN NumberOfHandles;\r
+ UINTN Index;\r
+ UINTN CompanionSegmentNumber;\r
+ UINTN CompanionBusNumber;\r
+ UINTN CompanionDeviceNumber;\r
+ UINTN CompanionFunctionNumber;\r
+ UINTN EhciSegmentNumber;\r
+ UINTN EhciBusNumber;\r
+ UINTN EhciDeviceNumber;\r
+ UINTN EhciFunctionNumber;\r
+ EFI_DEVICE_PATH_PROTOCOL *HcDevicePath;\r
\r
//\r
// Open the PciIo Protocol, then enable the USB host controller\r
Status = gBS->OpenProtocol (\r
Controller,\r
&gEfiPciIoProtocolGuid,\r
- (VOID **) &PciIo,\r
+ (VOID **)&PciIo,\r
This->DriverBindingHandle,\r
Controller,\r
EFI_OPEN_PROTOCOL_BY_DRIVER\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to open PCI_IO\n"));\r
- return EFI_DEVICE_ERROR;\r
+ return Status;\r
}\r
\r
+ //\r
+ // Open Device Path Protocol for on USB host controller\r
+ //\r
+ HcDevicePath = NULL;\r
+ Status = gBS->OpenProtocol (\r
+ Controller,\r
+ &gEfiDevicePathProtocolGuid,\r
+ (VOID **)&HcDevicePath,\r
+ This->DriverBindingHandle,\r
+ Controller,\r
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+ );\r
+\r
PciAttributesSaved = FALSE;\r
//\r
// Save original PCI attributes\r
if (EFI_ERROR (Status)) {\r
goto CLOSE_PCIIO;\r
}\r
+\r
PciAttributesSaved = TRUE;\r
\r
Status = PciIo->Attributes (\r
&Supports\r
);\r
if (!EFI_ERROR (Status)) {\r
- Supports &= EFI_PCI_DEVICE_ENABLE;\r
- Status = PciIo->Attributes (\r
- PciIo,\r
- EfiPciIoAttributeOperationEnable,\r
- Supports,\r
- NULL\r
- );\r
+ Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;\r
+ Status = PciIo->Attributes (\r
+ PciIo,\r
+ EfiPciIoAttributeOperationEnable,\r
+ Supports,\r
+ NULL\r
+ );\r
}\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to enable controller\n"));\r
+ DEBUG ((DEBUG_ERROR, "EhcDriverBindingStart: failed to enable controller\n"));\r
+ goto CLOSE_PCIIO;\r
+ }\r
+\r
+ //\r
+ // Get the Pci device class code.\r
+ //\r
+ Status = PciIo->Pci.Read (\r
+ PciIo,\r
+ EfiPciIoWidthUint8,\r
+ PCI_CLASSCODE_OFFSET,\r
+ sizeof (USB_CLASSC) / sizeof (UINT8),\r
+ &UsbClassCReg\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_UNSUPPORTED;\r
+ goto CLOSE_PCIIO;\r
+ }\r
+\r
+ //\r
+ // Determine if the device is UHCI or OHCI host controller or not. If yes, then find out the\r
+ // companion usb ehci host controller and force EHCI driver get attached to it before\r
+ // UHCI or OHCI driver attaches to UHCI or OHCI host controller.\r
+ //\r
+ if (((UsbClassCReg.ProgInterface == PCI_IF_UHCI) || (UsbClassCReg.ProgInterface == PCI_IF_OHCI)) &&\r
+ (UsbClassCReg.BaseCode == PCI_CLASS_SERIAL) &&\r
+ (UsbClassCReg.SubClassCode == PCI_CLASS_SERIAL_USB))\r
+ {\r
+ Status = PciIo->GetLocation (\r
+ PciIo,\r
+ &CompanionSegmentNumber,\r
+ &CompanionBusNumber,\r
+ &CompanionDeviceNumber,\r
+ &CompanionFunctionNumber\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto CLOSE_PCIIO;\r
+ }\r
+\r
+ Status = gBS->LocateHandleBuffer (\r
+ ByProtocol,\r
+ &gEfiPciIoProtocolGuid,\r
+ NULL,\r
+ &NumberOfHandles,\r
+ &HandleBuffer\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto CLOSE_PCIIO;\r
+ }\r
+\r
+ for (Index = 0; Index < NumberOfHandles; Index++) {\r
+ //\r
+ // Get the device path on this handle\r
+ //\r
+ Status = gBS->HandleProtocol (\r
+ HandleBuffer[Index],\r
+ &gEfiPciIoProtocolGuid,\r
+ (VOID **)&Instance\r
+ );\r
+ ASSERT_EFI_ERROR (Status);\r
+\r
+ Status = Instance->Pci.Read (\r
+ Instance,\r
+ EfiPciIoWidthUint8,\r
+ PCI_CLASSCODE_OFFSET,\r
+ sizeof (USB_CLASSC) / sizeof (UINT8),\r
+ &UsbClassCReg\r
+ );\r
+\r
+ if (EFI_ERROR (Status)) {\r
+ Status = EFI_UNSUPPORTED;\r
+ goto CLOSE_PCIIO;\r
+ }\r
+\r
+ if ((UsbClassCReg.ProgInterface == PCI_IF_EHCI) &&\r
+ (UsbClassCReg.BaseCode == PCI_CLASS_SERIAL) &&\r
+ (UsbClassCReg.SubClassCode == PCI_CLASS_SERIAL_USB))\r
+ {\r
+ Status = Instance->GetLocation (\r
+ Instance,\r
+ &EhciSegmentNumber,\r
+ &EhciBusNumber,\r
+ &EhciDeviceNumber,\r
+ &EhciFunctionNumber\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto CLOSE_PCIIO;\r
+ }\r
+\r
+ //\r
+ // Currently, the judgment on the companion usb host controller is through the\r
+ // same bus number, which may vary on different platform.\r
+ //\r
+ if (EhciBusNumber == CompanionBusNumber) {\r
+ gBS->CloseProtocol (\r
+ Controller,\r
+ &gEfiPciIoProtocolGuid,\r
+ This->DriverBindingHandle,\r
+ Controller\r
+ );\r
+ EhcDriverBindingStart (This, HandleBuffer[Index], NULL);\r
+ }\r
+ }\r
+ }\r
+\r
+ Status = EFI_NOT_FOUND;\r
goto CLOSE_PCIIO;\r
}\r
\r
//\r
// Create then install USB2_HC_PROTOCOL\r
//\r
- Ehc = EhcCreateUsb2Hc (PciIo, OriginalPciAttributes);\r
+ Ehc = EhcCreateUsb2Hc (PciIo, HcDevicePath, OriginalPciAttributes);\r
\r
if (Ehc == NULL) {\r
- DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to create USB2_HC\n"));\r
+ DEBUG ((DEBUG_ERROR, "EhcDriverBindingStart: failed to create USB2_HC\n"));\r
\r
Status = EFI_OUT_OF_RESOURCES;\r
goto CLOSE_PCIIO;\r
}\r
\r
+ //\r
+ // Enable 64-bit DMA support in the PCI layer if this controller\r
+ // supports it.\r
+ //\r
+ if (EHC_BIT_IS_SET (Ehc->HcCapParams, HCCP_64BIT)) {\r
+ Status = PciIo->Attributes (\r
+ PciIo,\r
+ EfiPciIoAttributeOperationEnable,\r
+ EFI_PCI_IO_ATTRIBUTE_DUAL_ADDRESS_CYCLE,\r
+ NULL\r
+ );\r
+ if (!EFI_ERROR (Status)) {\r
+ Ehc->Support64BitDma = TRUE;\r
+ } else {\r
+ DEBUG ((\r
+ DEBUG_WARN,\r
+ "%a: failed to enable 64-bit DMA on 64-bit capable controller @ %p (%r)\n",\r
+ __FUNCTION__,\r
+ Controller,\r
+ Status\r
+ ));\r
+ }\r
+ }\r
+\r
Status = gBS->InstallProtocolInterface (\r
&Controller,\r
&gEfiUsb2HcProtocolGuid,\r
);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to install USB2_HC Protocol\n"));\r
+ DEBUG ((DEBUG_ERROR, "EhcDriverBindingStart: failed to install USB2_HC Protocol\n"));\r
goto FREE_POOL;\r
}\r
\r
//\r
- // Robustnesss improvement such as for UoL\r
+ // Robustnesss improvement such as for Duet platform\r
// Default is not required.\r
//\r
if (FeaturePcdGet (PcdTurnOffUsbLegacySupport)) {\r
EhcClearLegacySupport (Ehc);\r
}\r
- EhcResetHC (Ehc, EHC_RESET_TIMEOUT);\r
+\r
+ if (!EhcIsDebugPortInUse (Ehc, NULL)) {\r
+ EhcResetHC (Ehc, EHC_RESET_TIMEOUT);\r
+ }\r
\r
Status = EhcInitHC (Ehc);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to init host controller\n"));\r
+ DEBUG ((DEBUG_ERROR, "EhcDriverBindingStart: failed to init host controller\n"));\r
goto UNINSTALL_USBHC;\r
}\r
\r
Status = gBS->SetTimer (Ehc->PollTimer, TimerPeriodic, EHC_ASYNC_POLL_INTERVAL);\r
\r
if (EFI_ERROR (Status)) {\r
- DEBUG ((EFI_D_ERROR, "EhcDriverBindingStart: failed to start async interrupt monitor\n"));\r
+ DEBUG ((DEBUG_ERROR, "EhcDriverBindingStart: failed to start async interrupt monitor\n"));\r
\r
EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
goto UNINSTALL_USBHC;\r
}\r
\r
+ //\r
+ // Create event to stop the HC when exit boot service.\r
+ //\r
+ Status = gBS->CreateEventEx (\r
+ EVT_NOTIFY_SIGNAL,\r
+ TPL_NOTIFY,\r
+ EhcExitBootService,\r
+ Ehc,\r
+ &gEfiEventExitBootServicesGuid,\r
+ &Ehc->ExitBootServiceEvent\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto UNINSTALL_USBHC;\r
+ }\r
+\r
//\r
// Install the component name protocol, don't fail the start\r
// because of something for display.\r
FALSE\r
);\r
\r
-\r
- DEBUG ((EFI_D_INFO, "EhcDriverBindingStart: EHCI started for controller @ %x\n", Controller));\r
+ DEBUG ((DEBUG_INFO, "EhcDriverBindingStart: EHCI started for controller @ %p\n", Controller));\r
return EFI_SUCCESS;\r
\r
UNINSTALL_USBHC:\r
gBS->FreePool (Ehc);\r
\r
CLOSE_PCIIO:\r
- if (PciAttributesSaved == TRUE) {\r
+ if (PciAttributesSaved) {\r
//\r
// Restore original PCI attributes\r
//\r
PciIo->Attributes (\r
- PciIo,\r
- EfiPciIoAttributeOperationSet,\r
- OriginalPciAttributes,\r
- NULL\r
- );\r
+ PciIo,\r
+ EfiPciIoAttributeOperationSet,\r
+ OriginalPciAttributes,\r
+ NULL\r
+ );\r
}\r
\r
gBS->CloseProtocol (\r
return Status;\r
}\r
\r
-\r
/**\r
- Stop this driver on ControllerHandle. Support stoping any child handles\r
+ Stop this driver on ControllerHandle. Support stopping any child handles\r
created by this driver.\r
\r
@param This Protocol instance pointer.\r
- @param Controller Handle of device to stop driver on\r
- @param NumberOfChildren Number of Children in the ChildHandleBuffer\r
+ @param Controller Handle of device to stop driver on.\r
+ @param NumberOfChildren Number of Children in the ChildHandleBuffer.\r
@param ChildHandleBuffer List of handles for the children we need to stop.\r
\r
- @return EFI_SUCCESS Success\r
- @return EFI_DEVICE_ERROR Fail\r
+ @return EFI_SUCCESS Success.\r
+ @return EFI_DEVICE_ERROR Fail.\r
\r
**/\r
EFI_STATUS\r
EFIAPI\r
EhcDriverBindingStop (\r
- IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
- IN EFI_HANDLE Controller,\r
- IN UINTN NumberOfChildren,\r
- IN EFI_HANDLE *ChildHandleBuffer\r
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,\r
+ IN EFI_HANDLE Controller,\r
+ IN UINTN NumberOfChildren,\r
+ IN EFI_HANDLE *ChildHandleBuffer\r
)\r
{\r
EFI_STATUS Status;\r
Status = gBS->OpenProtocol (\r
Controller,\r
&gEfiUsb2HcProtocolGuid,\r
- (VOID **) &Usb2Hc,\r
+ (VOID **)&Usb2Hc,\r
This->DriverBindingHandle,\r
Controller,\r
EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
Ehc = EHC_FROM_THIS (Usb2Hc);\r
PciIo = Ehc->PciIo;\r
\r
- //\r
- // Stop AsyncRequest Polling timer then stop the EHCI driver\r
- // and uninstall the EHCI protocl.\r
- //\r
- gBS->SetTimer (Ehc->PollTimer, TimerCancel, EHC_ASYNC_POLL_INTERVAL);\r
- EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
-\r
Status = gBS->UninstallProtocolInterface (\r
Controller,\r
&gEfiUsb2HcProtocolGuid,\r
return Status;\r
}\r
\r
+ //\r
+ // Stop AsyncRequest Polling timer then stop the EHCI driver\r
+ // and uninstall the EHCI protocl.\r
+ //\r
+ gBS->SetTimer (Ehc->PollTimer, TimerCancel, EHC_ASYNC_POLL_INTERVAL);\r
+ EhcHaltHC (Ehc, EHC_GENERIC_TIMEOUT);\r
+\r
if (Ehc->PollTimer != NULL) {\r
gBS->CloseEvent (Ehc->PollTimer);\r
}\r
\r
+ if (Ehc->ExitBootServiceEvent != NULL) {\r
+ gBS->CloseEvent (Ehc->ExitBootServiceEvent);\r
+ }\r
+\r
EhcFreeSched (Ehc);\r
\r
- if (Ehc->ControllerNameTable) {\r
+ if (Ehc->ControllerNameTable != NULL) {\r
FreeUnicodeStringTable (Ehc->ControllerNameTable);\r
}\r
\r
+ //\r
+ // Disable routing of all ports to EHCI controller, so all ports are\r
+ // routed back to the UHCI or OHCI controller.\r
+ //\r
+ EhcClearOpRegBit (Ehc, EHC_CONFIG_FLAG_OFFSET, CONFIGFLAG_ROUTE_EHC);\r
+\r
//\r
// Restore original PCI attributes\r
//\r
PciIo->Attributes (\r
- PciIo,\r
- EfiPciIoAttributeOperationSet,\r
- Ehc->OriginalPciAttributes,\r
- NULL\r
- );\r
+ PciIo,\r
+ EfiPciIoAttributeOperationSet,\r
+ Ehc->OriginalPciAttributes,\r
+ NULL\r
+ );\r
\r
gBS->CloseProtocol (\r
Controller,\r
\r
return EFI_SUCCESS;\r
}\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL\r
-gEhciDriverBinding = {\r
- EhcDriverBindingSupported,\r
- EhcDriverBindingStart,\r
- EhcDriverBindingStop,\r
- 0x10,\r
- NULL,\r
- NULL\r
-};\r