/** @file\r
\r
-Copyright (c) 2004 - 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
-\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
-\r
-Module Name:\r
-\r
- Uhci.c\r
-\r
-Abstract:\r
-\r
The UHCI driver model and HC protocol routines.\r
\r
-Revision History\r
-\r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
+SPDX-License-Identifier: BSD-2-Clause-Patent\r
\r
**/\r
\r
#include "Uhci.h"\r
\r
+\r
+EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding = {\r
+ UhciDriverBindingSupported,\r
+ UhciDriverBindingStart,\r
+ UhciDriverBindingStop,\r
+ 0x20,\r
+ NULL,\r
+ NULL\r
+};\r
+\r
/**\r
Provides software reset for the USB host controller according to UEFI 2.0 spec.\r
\r
- @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
- @param Attributes A bit mask of the reset operation to perform. See\r
- below for a list of the supported bit mask values.\r
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ @param Attributes A bit mask of the reset operation to perform. See\r
+ below for a list of the supported bit mask values.\r
\r
- @return EFI_SUCCESS : The reset operation succeeded.\r
- @return EFI_INVALID_PARAMETER : Attributes is not valid.\r
- @return EFI_UNSUPPORTED : This type of reset is not currently supported\r
- @return EFI_DEVICE_ERROR : Other errors\r
+ @return EFI_SUCCESS The reset operation succeeded.\r
+ @return EFI_INVALID_PARAMETER Attributes is not valid.\r
+ @return EFI_UNSUPPORTED This type of reset is not currently supported.\r
+ @return EFI_DEVICE_ERROR Other errors.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
Uhci2Reset (\r
return EFI_UNSUPPORTED;\r
}\r
\r
- Uhc = UHC_FROM_USB2_HC_PROTO (This);\r
+ Uhc = UHC_FROM_USB2_HC_PROTO (This);\r
+\r
+ if (Uhc->DevicePath != NULL) {\r
+ //\r
+ // Report Status Code to indicate reset happens\r
+ //\r
+ REPORT_STATUS_CODE_WITH_DEVICE_PATH (\r
+ EFI_PROGRESS_CODE,\r
+ (EFI_IO_BUS_USB | EFI_IOB_PC_RESET),\r
+ Uhc->DevicePath\r
+ );\r
+ }\r
\r
OldTpl = gBS->RaiseTPL (UHCI_TPL);\r
\r
/**\r
Retrieves current state of the USB host controller according to UEFI 2.0 spec.\r
\r
- @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
- @param State Variable to receive current device state\r
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ @param State Variable to receive current device state.\r
\r
- @return EFI_SUCCESS : The state is returned\r
- @return EFI_INVALID_PARAMETER : State is not valid.\r
- @return EFI_DEVICE_ERROR : Other errors2006\r
+ @return EFI_SUCCESS The state is returned.\r
+ @return EFI_INVALID_PARAMETER State is not valid.\r
+ @return EFI_DEVICE_ERROR Other errors.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
Uhci2GetState (\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
USB_HC_DEV *Uhc;\r
UsbCmd = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET);\r
UsbSts = UhciReadReg (Uhc->PciIo, USBSTS_OFFSET);\r
\r
- if (UsbCmd & USBCMD_EGSM) {\r
+ if ((UsbCmd & USBCMD_EGSM) !=0 ) {\r
*State = EfiUsbHcStateSuspend;\r
\r
} else if ((UsbSts & USBSTS_HCH) != 0) {\r
/**\r
Sets the USB host controller to a specific state according to UEFI 2.0 spec.\r
\r
- @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
- @param State Indicates the state of the host controller that will\r
- be set.\r
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ @param State Indicates the state of the host controller that will\r
+ be set.\r
\r
- @return EFI_SUCCESS : Host controller was successfully placed in the state\r
- @return EFI_INVALID_PARAMETER : State is invalid.\r
- @return EFI_DEVICE_ERROR : Failed to set the state\r
+ @return EFI_SUCCESS Host controller was successfully placed in the state.\r
+ @return EFI_INVALID_PARAMETER State is invalid.\r
+ @return EFI_DEVICE_ERROR Failed to set the state.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
Uhci2SetState (\r
/**\r
Retrieves capabilities of USB host controller according to UEFI 2.0 spec.\r
\r
- @param This A pointer to the EFI_USB2_HC_PROTOCOL instance\r
- @param MaxSpeed A pointer to the max speed USB host controller\r
- supports.\r
- @param PortNumber A pointer to the number of root hub ports.\r
- @param Is64BitCapable A pointer to an integer to show whether USB host\r
- controller supports 64-bit memory addressing.\r
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ @param MaxSpeed A pointer to the max speed USB host controller\r
+ supports.\r
+ @param PortNumber A pointer to the number of root hub ports.\r
+ @param Is64BitCapable A pointer to an integer to show whether USB host\r
+ controller supports 64-bit memory addressing.\r
\r
- @return EFI_SUCCESS : capabilities were retrieved successfully.\r
- @return EFI_INVALID_PARAMETER : MaxSpeed or PortNumber or Is64BitCapable is NULL.\r
- @return EFI_DEVICE_ERROR : An error was encountered\r
+ @return EFI_SUCCESS capabilities were retrieved successfully.\r
+ @return EFI_INVALID_PARAMETER MaxSpeed or PortNumber or Is64BitCapable is NULL.\r
+ @return EFI_DEVICE_ERROR An error was encountered.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
Uhci2GetCapability (\r
// returns 0 in this bit if port number is invalid. Also, if\r
// PciIo IoRead returns error, 0xFFFF is returned to caller.\r
//\r
- if (((PortSC & 0x80) != 0) && (PortSC != 0xFFFF)) {\r
- (*PortNumber)++;\r
+ if (((PortSC & 0x80) == 0) || (PortSC == 0xFFFF)) {\r
+ break;\r
}\r
+ (*PortNumber)++;\r
}\r
\r
Uhc->RootPorts = *PortNumber;\r
\r
- DEBUG ((EFI_D_INFO, "Uhci2GetCapability: %d ports\n", Uhc->RootPorts));\r
+ DEBUG ((EFI_D_INFO, "Uhci2GetCapability: %d ports\n", (UINT32)Uhc->RootPorts));\r
return EFI_SUCCESS;\r
}\r
\r
/**\r
Retrieves the current status of a USB root hub port according to UEFI 2.0 spec.\r
\r
- @param This A pointer to the EFI_USB2_HC_PROTOCOL.\r
- @param PortNumber The port to get status\r
- @param PortStatus A pointer to the current port status bits and port\r
- status change bits.\r
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL.\r
+ @param PortNumber The port to get status.\r
+ @param PortStatus A pointer to the current port status bits and port\r
+ status change bits.\r
\r
- @return EFI_SUCCESS : status of the USB root hub port was returned in PortStatus.\r
- @return EFI_INVALID_PARAMETER : PortNumber is invalid.\r
- @return EFI_DEVICE_ERROR : Can't read register\r
+ @return EFI_SUCCESS status of the USB root hub port was returned in PortStatus.\r
+ @return EFI_INVALID_PARAMETER PortNumber is invalid.\r
+ @return EFI_DEVICE_ERROR Can't read register.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
Uhci2GetRootHubPortStatus (\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
USB_HC_DEV *Uhc;\r
\r
PortSC = UhciReadReg (Uhc->PciIo, Offset);\r
\r
- if (PortSC & USBPORTSC_CCS) {\r
+ if ((PortSC & USBPORTSC_CCS) != 0) {\r
PortStatus->PortStatus |= USB_PORT_STAT_CONNECTION;\r
}\r
\r
- if (PortSC & USBPORTSC_PED) {\r
+ if ((PortSC & USBPORTSC_PED) != 0) {\r
PortStatus->PortStatus |= USB_PORT_STAT_ENABLE;\r
}\r
\r
- if (PortSC & USBPORTSC_SUSP) {\r
+ if ((PortSC & USBPORTSC_SUSP) != 0) {\r
DEBUG ((EFI_D_INFO, "Uhci2GetRootHubPortStatus: port %d is suspended\n", PortNumber));\r
PortStatus->PortStatus |= USB_PORT_STAT_SUSPEND;\r
}\r
\r
- if (PortSC & USBPORTSC_PR) {\r
+ if ((PortSC & USBPORTSC_PR) != 0) {\r
PortStatus->PortStatus |= USB_PORT_STAT_RESET;\r
}\r
\r
- if (PortSC & USBPORTSC_LSDA) {\r
+ if ((PortSC & USBPORTSC_LSDA) != 0) {\r
PortStatus->PortStatus |= USB_PORT_STAT_LOW_SPEED;\r
}\r
\r
//\r
PortStatus->PortStatus |= USB_PORT_STAT_OWNER;\r
\r
- if (PortSC & USBPORTSC_CSC) {\r
+ if ((PortSC & USBPORTSC_CSC) != 0) {\r
PortStatus->PortChangeStatus |= USB_PORT_STAT_C_CONNECTION;\r
}\r
\r
- if (PortSC & USBPORTSC_PEDC) {\r
+ if ((PortSC & USBPORTSC_PEDC) != 0) {\r
PortStatus->PortChangeStatus |= USB_PORT_STAT_C_ENABLE;\r
}\r
\r
/**\r
Sets a feature for the specified root hub port according to UEFI 2.0 spec.\r
\r
- @param This A pointer to the EFI_USB2_HC_PROTOCOL.\r
- @param PortNumber Specifies the root hub port whose feature is\r
- requested to be set.\r
- @param PortFeature Indicates the feature selector associated with the\r
- feature set request.\r
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL.\r
+ @param PortNumber Specifies the root hub port whose feature is\r
+ requested to be set.\r
+ @param PortFeature Indicates the feature selector associated with the\r
+ feature set request.\r
\r
- @return EFI_SUCCESS : PortFeature was set for the root port\r
- @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.\r
- @return EFI_DEVICE_ERROR : Can't read register\r
+ @return EFI_SUCCESS PortFeature was set for the root port.\r
+ @return EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.\r
+ @return EFI_DEVICE_ERROR Can't read register.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
Uhci2SetRootHubPortFeature (\r
switch (PortFeature) {\r
case EfiUsbPortSuspend:\r
Command = UhciReadReg (Uhc->PciIo, USBCMD_OFFSET);\r
- if (!(Command & USBCMD_EGSM)) {\r
+ if ((Command & USBCMD_EGSM) == 0) {\r
//\r
// if global suspend is not active, can set port suspend\r
//\r
/**\r
Clears a feature for the specified root hub port according to Uefi 2.0 spec.\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 : PortFeature was cleared for the USB root hub port\r
- @return EFI_INVALID_PARAMETER : PortNumber is invalid or PortFeature is invalid.\r
- @return EFI_DEVICE_ERROR : Can't read register\r
+ @return EFI_SUCCESS PortFeature was cleared for the USB root hub port.\r
+ @return EFI_INVALID_PARAMETER PortNumber is invalid or PortFeature is invalid.\r
+ @return EFI_DEVICE_ERROR Can't read register.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
Uhci2ClearRootHubPortFeature (\r
\r
\r
/**\r
- Submits control transfer to a target USB device accroding to UEFI 2.0 spec..\r
-\r
- This : A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
- DeviceAddress : Target device address\r
- DeviceSpeed : Device speed\r
- MaximumPacketLength : Maximum packet size of the target endpoint\r
- Request : USB device request to send\r
- TransferDirection : Data direction of the Data stage in control transfer\r
- Data : Data to transmit/receive in data stage\r
- DataLength : Length of the data\r
- TimeOut : Maximum time, in microseconds, for transfer to complete.\r
- TransferResult : Variable to receive the transfer result\r
-\r
- @return EFI_SUCCESS : The control transfer was completed successfully.\r
- @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource.\r
- @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
- @return EFI_TIMEOUT : Failed due to timeout.\r
- @return EFI_DEVICE_ERROR : Failed due to host controller or device error.\r
+ Submits control transfer to a target USB device according to UEFI 2.0 spec.\r
+\r
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ @param DeviceAddress Target device address.\r
+ @param DeviceSpeed Device speed.\r
+ @param MaximumPacketLength Maximum packet size of the target endpoint.\r
+ @param Request USB device request to send.\r
+ @param TransferDirection Data direction of the Data stage in control transfer.\r
+ @param Data Data to transmit/receive in data stage.\r
+ @param DataLength Length of the data.\r
+ @param TimeOut Maximum time, in microseconds, for transfer to complete.\r
+ @param Translator Transaction translator to be used by this device.\r
+ @param TransferResult Variable to receive the transfer result.\r
+\r
+ @return EFI_SUCCESS The control transfer was completed successfully.\r
+ @return EFI_OUT_OF_RESOURCES Failed due to lack of resource.\r
+ @return EFI_INVALID_PARAMETER Some parameters are invalid.\r
+ @return EFI_TIMEOUT Failed due to timeout.\r
+ @return EFI_DEVICE_ERROR Failed due to host controller or device error.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
Uhci2ControlTransfer (\r
UINT8 *DataPhy;\r
VOID *DataMap;\r
BOOLEAN IsSlowDevice;\r
+ UINTN TransferDataLength;\r
\r
Uhc = UHC_FROM_USB2_HC_PROTO (This);\r
TDs = NULL;\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if ((TransferDirection != EfiUsbNoData) && (DataLength == NULL)) {\r
+ if ((TransferDirection != EfiUsbNoData) && (Data == NULL || DataLength == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
+ if (TransferDirection == EfiUsbNoData) {\r
+ TransferDataLength = 0;\r
+ } else {\r
+ TransferDataLength = *DataLength;\r
+ }\r
+\r
*TransferResult = EFI_USB_ERR_SYSTEM;\r
Status = EFI_DEVICE_ERROR;\r
\r
Uhc,\r
DeviceAddress,\r
PktId,\r
+ (UINT8*)Request,\r
RequestPhy,\r
+ (UINT8*)Data,\r
DataPhy,\r
- *DataLength,\r
+ TransferDataLength,\r
(UINT8) MaximumPacketLength,\r
IsSlowDevice\r
);\r
// the TD to corrosponding queue head, then check\r
// the execution result\r
//\r
- UhciLinkTdToQh (Uhc->CtrlQh, TDs);\r
+ UhciLinkTdToQh (Uhc, Uhc->CtrlQh, TDs);\r
Status = UhciExecuteTransfer (Uhc, Uhc->CtrlQh, TDs, TimeOut, IsSlowDevice, &QhResult);\r
UhciUnlinkTdFromQh (Uhc->CtrlQh, TDs);\r
\r
}\r
\r
\r
-\r
/**\r
- Submits bulk transfer to a bulk endpoint of a USB device\r
-\r
- This : A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
- DeviceAddress : Target device address\r
- EndPointAddress : Endpoint number and direction\r
- DeviceSpeed : Device speed\r
- MaximumPacketLength : Maximum packet size of the target endpoint\r
- DataBuffersNumber : Number of data buffers prepared for the transfer.\r
- Data : Array of pointers to the buffers of data\r
- DataLength : On input, size of the data buffer, On output,\r
- actually transferred data size.\r
- DataToggle : On input, data toggle to use; On output, next data toggle\r
- Translator : A pointr to the transaction translator data.\r
- TimeOut : Maximum time out, in microseconds\r
- TransferResult : Variable to receive transfer result\r
-\r
- @return EFI_SUCCESS : The bulk transfer was completed successfully.\r
- @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource.\r
- @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
- @return EFI_TIMEOUT : Failed due to timeout.\r
- @return EFI_DEVICE_ERROR : Failed due to host controller or device error.\r
+ Submits bulk transfer to a bulk endpoint of a USB device.\r
+\r
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ @param DeviceAddress Target device address.\r
+ @param EndPointAddress Endpoint number and direction.\r
+ @param DeviceSpeed Device speed.\r
+ @param MaximumPacketLength Maximum packet size of the target endpoint.\r
+ @param DataBuffersNumber Number of data buffers prepared for the transfer.\r
+ @param Data Array of pointers to the buffers of data.\r
+ @param DataLength On input, size of the data buffer, On output,\r
+ actually transferred data size.\r
+ @param DataToggle On input, data toggle to use; On output, next data toggle.\r
+ @param TimeOut Maximum time out, in microseconds.\r
+ @param Translator A pointr to the transaction translator data.\r
+ @param TransferResult Variable to receive transfer result.\r
+\r
+ @return EFI_SUCCESS The bulk transfer was completed successfully.\r
+ @return EFI_OUT_OF_RESOURCES Failed due to lack of resource.\r
+ @return EFI_INVALID_PARAMETER Some parameters are invalid.\r
+ @return EFI_TIMEOUT Failed due to timeout.\r
+ @return EFI_DEVICE_ERROR Failed due to host controller or device error.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
Uhci2BulkTransfer (\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if ((DataLength == NULL) || (Data == NULL) || (TransferResult == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (*DataLength == 0) {\r
+ if ((DataLength == NULL) || (*DataLength == 0) || (Data == NULL) || (TransferResult == NULL)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
// Map the source data buffer for bus master access,\r
// then create a list of TDs\r
//\r
- if (EndPointAddress & 0x80) {\r
+ if ((EndPointAddress & 0x80) != 0) {\r
Direction = EfiUsbDataIn;\r
} else {\r
Direction = EfiUsbDataOut;\r
DeviceAddress,\r
EndPointAddress,\r
PktId,\r
+ (UINT8 *)*Data,\r
DataPhy,\r
*DataLength,\r
DataToggle,\r
//\r
BulkQh = Uhc->BulkQh;\r
\r
- UhciLinkTdToQh (BulkQh, TDs);\r
+ UhciLinkTdToQh (Uhc, BulkQh, TDs);\r
Status = UhciExecuteTransfer (Uhc, BulkQh, TDs, TimeOut, FALSE, &QhResult);\r
UhciUnlinkTdFromQh (BulkQh, TDs);\r
\r
Submits an asynchronous interrupt transfer to an\r
interrupt endpoint of a USB device according to UEFI 2.0 spec.\r
\r
- This : A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
- DeviceAddress : Target device address\r
- EndPointAddress : Endpoint number and direction\r
- DeviceSpeed : Device speed\r
- MaximumPacketLength : Maximum packet size of the target endpoint\r
- IsNewTransfer : If TRUE, submit a new transfer, if FALSE cancel old transfer\r
- DataToggle : On input, data toggle to use; On output, next data toggle\r
- PollingInterval : Interrupt poll rate in milliseconds\r
- DataLength : On input, size of the data buffer, On output,\r
- actually transferred data size.\r
- Translator : A pointr to the transaction translator data.\r
- CallBackFunction : Function to call periodically\r
- Context : User context\r
-\r
- @return EFI_SUCCESS : Transfer was submitted\r
- @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
- @return EFI_OUT_OF_RESOURCES : Failed due to a lack of resources.\r
- @return EFI_DEVICE_ERROR : Can't read register\r
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ @param DeviceAddress Target device address.\r
+ @param EndPointAddress Endpoint number and direction.\r
+ @param DeviceSpeed Device speed.\r
+ @param MaximumPacketLength Maximum packet size of the target endpoint.\r
+ @param IsNewTransfer If TRUE, submit a new transfer, if FALSE cancel old transfer.\r
+ @param DataToggle On input, data toggle to use; On output, next data toggle.\r
+ @param PollingInterval Interrupt poll rate in milliseconds.\r
+ @param DataLength On input, size of the data buffer, On output,\r
+ actually transferred data size.\r
+ @param Translator A pointr to the transaction translator data.\r
+ @param CallBackFunction Function to call periodically.\r
+ @param Context User context.\r
+\r
+ @return EFI_SUCCESS Transfer was submitted.\r
+ @return EFI_INVALID_PARAMETER Some parameters are invalid.\r
+ @return EFI_OUT_OF_RESOURCES Failed due to a lack of resources.\r
+ @return EFI_DEVICE_ERROR Can't read register.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
Uhci2AsyncInterruptTransfer (\r
EFI_STATUS Status;\r
UINT8 *DataPtr;\r
UINT8 *DataPhy;\r
- VOID *DataMap;\r
UINT8 PktId;\r
\r
Uhc = UHC_FROM_USB2_HC_PROTO (This);\r
IntTds = NULL;\r
DataPtr = NULL;\r
DataPhy = NULL;\r
- DataMap = NULL;\r
\r
IsSlowDevice = (BOOLEAN) ((EFI_USB_SPEED_LOW == DeviceSpeed) ? TRUE : FALSE);\r
\r
return EFI_DEVICE_ERROR;\r
}\r
\r
+ if ((EndPointAddress & 0x80) == 0) {\r
+ PktId = OUTPUT_PACKET_ID;\r
+ } else {\r
+ PktId = INPUT_PACKET_ID;\r
+ }\r
+\r
//\r
// Allocate and map source data buffer for bus master access.\r
//\r
- DataPtr = AllocatePool (DataLength);\r
+ DataPtr = UsbHcAllocateMem (Uhc->MemPool, DataLength);\r
\r
if (DataPtr == NULL) {\r
return EFI_OUT_OF_RESOURCES;\r
}\r
\r
- OldTpl = gBS->RaiseTPL (UHCI_TPL);\r
+ DataPhy = (UINT8 *) (UINTN) UsbHcGetPciAddressForHostMem (Uhc->MemPool, DataPtr, DataLength);\r
\r
- //\r
- // Map the user data then create a queue head and\r
- // list of TD for it.\r
- //\r
- Status = UhciMapUserData (\r
- Uhc,\r
- EfiUsbDataIn,\r
- DataPtr,\r
- &DataLength,\r
- &PktId,\r
- &DataPhy,\r
- &DataMap\r
- );\r
-\r
- if (EFI_ERROR (Status)) {\r
- goto FREE_DATA;\r
- }\r
+ OldTpl = gBS->RaiseTPL (UHCI_TPL);\r
\r
Qh = UhciCreateQh (Uhc, PollingInterval);\r
\r
if (Qh == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
- goto UNMAP_DATA;\r
+ goto FREE_DATA;\r
}\r
\r
IntTds = UhciCreateBulkOrIntTds (\r
DeviceAddress,\r
EndPointAddress,\r
PktId,\r
+ DataPtr,\r
DataPhy,\r
DataLength,\r
DataToggle,\r
goto DESTORY_QH;\r
}\r
\r
- UhciLinkTdToQh (Qh, IntTds);\r
+ UhciLinkTdToQh (Uhc, Qh, IntTds);\r
\r
//\r
// Save QH-TD structures to async Interrupt transfer list,\r
EndPointAddress,\r
DataLength,\r
PollingInterval,\r
- DataMap,\r
DataPtr,\r
CallBackFunction,\r
Context,\r
goto DESTORY_QH;\r
}\r
\r
- UhciLinkQhToFrameList (Uhc->FrameBase, Qh);\r
+ UhciLinkQhToFrameList (Uhc, Qh);\r
\r
gBS->RestoreTPL (OldTpl);\r
return EFI_SUCCESS;\r
DESTORY_QH:\r
UsbHcFreeMem (Uhc->MemPool, Qh, sizeof (UHCI_QH_SW));\r
\r
-UNMAP_DATA:\r
- Uhc->PciIo->Unmap (Uhc->PciIo, DataMap);\r
-\r
FREE_DATA:\r
- gBS->FreePool (DataPtr);\r
+ UsbHcFreeMem (Uhc->MemPool, DataPtr, DataLength);\r
Uhc->PciIo->Flush (Uhc->PciIo);\r
\r
gBS->RestoreTPL (OldTpl);\r
Submits synchronous interrupt transfer to an interrupt endpoint\r
of a USB device according to UEFI 2.0 spec.\r
\r
- This : A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
- DeviceAddress : Target device address\r
- EndPointAddress : Endpoint number and direction\r
- DeviceSpeed : Device speed\r
- MaximumPacketLength : Maximum packet size of the target endpoint\r
- DataBuffersNumber : Number of data buffers prepared for the transfer.\r
- Data : Array of pointers to the buffers of data\r
- DataLength : On input, size of the data buffer, On output,\r
- actually transferred data size.\r
- DataToggle : On input, data toggle to use; On output, next data toggle\r
- TimeOut : Maximum time out, in microseconds\r
- Translator : A pointr to the transaction translator data.\r
- TransferResult : Variable to receive transfer result\r
-\r
- @return EFI_SUCCESS : The transfer was completed successfully.\r
- @return EFI_OUT_OF_RESOURCES : Failed due to lack of resource.\r
- @return EFI_INVALID_PARAMETER : Some parameters are invalid.\r
- @return EFI_TIMEOUT : Failed due to timeout.\r
- @return EFI_DEVICE_ERROR : Failed due to host controller or device error.\r
+\r
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ @param DeviceAddress Target device address.\r
+ @param EndPointAddress Endpoint number and direction.\r
+ @param DeviceSpeed Device speed.\r
+ @param MaximumPacketLength Maximum packet size of the target endpoint.\r
+ @param Data Array of pointers to the buffers of data.\r
+ @param DataLength On input, size of the data buffer, On output,\r
+ actually transferred data size.\r
+ @param DataToggle On input, data toggle to use; On output, next data toggle.\r
+ @param TimeOut Maximum time out, in microseconds.\r
+ @param Translator A pointr to the transaction translator data.\r
+ @param TransferResult Variable to receive transfer result.\r
+\r
+ @return EFI_SUCCESS The transfer was completed successfully.\r
+ @return EFI_OUT_OF_RESOURCES Failed due to lack of resource.\r
+ @return EFI_INVALID_PARAMETER Some parameters are invalid.\r
+ @return EFI_TIMEOUT Failed due to timeout.\r
+ @return EFI_DEVICE_ERROR Failed due to host controller or device error.\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
Uhci2SyncInterruptTransfer (\r
return EFI_INVALID_PARAMETER;\r
}\r
\r
- if ((EndPointAddress & 0x80) == 0) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
if ((*DataToggle != 1) && (*DataToggle != 0)) {\r
return EFI_INVALID_PARAMETER;\r
}\r
DeviceAddress,\r
EndPointAddress,\r
PktId,\r
+ (UINT8 *)Data,\r
DataPhy,\r
*DataLength,\r
DataToggle,\r
}\r
\r
\r
- UhciLinkTdToQh (Uhc->SyncIntQh, TDs);\r
+ UhciLinkTdToQh (Uhc, Uhc->SyncIntQh, TDs);\r
\r
Status = UhciExecuteTransfer (Uhc, Uhc->SyncIntQh, TDs, TimeOut, IsSlowDevice, &QhResult);\r
\r
/**\r
Submits isochronous transfer to a target USB device according to UEFI 2.0 spec.\r
\r
- This : A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
- DeviceAddress : Target device address\r
- EndPointAddress : Endpoint number and direction\r
- DeviceSpeed : Device speed\r
- MaximumPacketLength : Maximum packet size of the target endpoint\r
- DataBuffersNumber : Number of data buffers prepared for the transfer.\r
- Data : Array of pointers to the buffers of data\r
- DataLength : On input, size of the data buffer, On output,\r
- actually transferred data size.\r
- Translator : A pointr to the transaction translator data.\r
- TransferResult : Variable to receive transfer result\r
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ @param DeviceAddress Target device address.\r
+ @param EndPointAddress Endpoint number and direction.\r
+ @param DeviceSpeed Device speed.\r
+ @param MaximumPacketLength Maximum packet size of the target endpoint.\r
+ @param DataBuffersNumber Number of data buffers prepared for the transfer.\r
+ @param Data Array of pointers to the buffers of data.\r
+ @param DataLength On input, size of the data buffer, On output,\r
+ actually transferred data size.\r
+ @param Translator A pointr to the transaction translator data.\r
+ @param TransferResult Variable to receive transfer result.\r
\r
@return EFI_UNSUPPORTED\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
Uhci2IsochronousTransfer (\r
/**\r
Submits Async isochronous transfer to a target USB device according to UEFI 2.0 spec.\r
\r
- This : A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
- DeviceAddress : Target device address\r
- EndPointAddress : Endpoint number and direction\r
- DeviceSpeed : Device speed\r
- MaximumPacketLength : Maximum packet size of the target endpoint\r
- DataBuffersNumber : Number of data buffers prepared for the transfer.\r
- Data : Array of pointers to the buffers of data\r
- Translator : A pointr to the transaction translator data.\r
- IsochronousCallBack : Function to call when the transfer complete\r
- Context : Pass to the call back function as parameter\r
+ @param This A pointer to the EFI_USB2_HC_PROTOCOL instance.\r
+ @param DeviceAddress Target device address.\r
+ @param EndPointAddress Endpoint number and direction.\r
+ @param DeviceSpeed Device speed.\r
+ @param MaximumPacketLength Maximum packet size of the target endpoint.\r
+ @param DataBuffersNumber Number of data buffers prepared for the transfer.\r
+ @param Data Array of pointers to the buffers of data.\r
+ @param DataLength On input, size of the data buffer, On output,\r
+ actually transferred data size.\r
+ @param Translator A pointr to the transaction translator data.\r
+ @param IsochronousCallBack Function to call when the transfer complete.\r
+ @param Context Pass to the call back function as parameter.\r
\r
@return EFI_UNSUPPORTED\r
\r
**/\r
-STATIC\r
EFI_STATUS\r
EFIAPI\r
Uhci2AsyncIsochronousTransfer (\r
return EFI_UNSUPPORTED;\r
}\r
\r
+/**\r
+ Entry point for EFI drivers.\r
+\r
+ @param ImageHandle EFI_HANDLE.\r
+ @param SystemTable EFI_SYSTEM_TABLE.\r
+\r
+ @retval EFI_SUCCESS Driver is successfully loaded.\r
+ @return Others Failed.\r
+\r
+**/\r
EFI_STATUS\r
EFIAPI\r
UhciDriverEntryPoint (\r
IN EFI_HANDLE ImageHandle,\r
IN EFI_SYSTEM_TABLE *SystemTable\r
)\r
-/*++\r
-\r
- Routine Description:\r
-\r
- Entry point for EFI drivers.\r
-\r
- Arguments:\r
-\r
- ImageHandle - EFI_HANDLE\r
- SystemTable - EFI_SYSTEM_TABLE\r
-\r
- Returns:\r
-\r
- EFI_SUCCESS : Driver is successfully loaded\r
- Others : Failed\r
-\r
---*/\r
{\r
return EfiLibInstallDriverBindingComponentName2 (\r
ImageHandle,\r
ControllerHandle that has UsbHcProtocol installed will be supported.\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 : 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
Status = PciIo->Pci.Read (\r
PciIo,\r
EfiPciIoWidthUint8,\r
- CLASSC_OFFSET,\r
+ PCI_CLASSCODE_OFFSET,\r
sizeof (USB_CLASSC) / sizeof (UINT8),\r
&UsbClassCReg\r
);\r
//\r
if ((UsbClassCReg.BaseCode != PCI_CLASS_SERIAL) ||\r
(UsbClassCReg.SubClassCode != PCI_CLASS_SERIAL_USB) ||\r
- (UsbClassCReg.PI != PCI_CLASSC_PI_UHCI)\r
+ (UsbClassCReg.ProgInterface != PCI_IF_UHCI)\r
) {\r
\r
Status = EFI_UNSUPPORTED;\r
\r
\r
/**\r
- Allocate and initialize the empty UHCI device\r
+ Allocate and initialize the empty UHCI device.\r
\r
- @param PciIo The PCIIO to use\r
+ @param PciIo The PCIIO to use.\r
+ @param DevicePath The device path of host controller.\r
+ @param OriginalPciAttributes The original PCI attributes.\r
\r
- @return Allocated UHCI device\r
+ @return Allocated UHCI device. If err, return NULL.\r
\r
**/\r
-STATIC\r
USB_HC_DEV *\r
UhciAllocateDev (\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
USB_HC_DEV *Uhc;\r
Uhc->Usb2Hc.MinorRevision = 0x1;\r
\r
Uhc->PciIo = PciIo;\r
+ Uhc->DevicePath = DevicePath;\r
Uhc->OriginalPciAttributes = OriginalPciAttributes;\r
Uhc->MemPool = UsbHcInitMemPool (PciIo, TRUE, 0);\r
\r
\r
Status = gBS->CreateEvent (\r
EVT_TIMER | EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
+ TPL_NOTIFY,\r
UhciMonitorAsyncReqList,\r
Uhc,\r
&Uhc->AsyncIntMonitor\r
return Uhc;\r
\r
ON_ERROR:\r
- gBS->FreePool (Uhc);\r
+ FreePool (Uhc);\r
return NULL;\r
}\r
\r
\r
/**\r
- Free the UHCI device and release its associated resources\r
+ Free the UHCI device and release its associated resources.\r
\r
- @param Uhc The UHCI device to release\r
-\r
- @return None\r
+ @param Uhc The UHCI device to release.\r
\r
**/\r
-STATIC\r
VOID\r
UhciFreeDev (\r
IN USB_HC_DEV *Uhc\r
gBS->CloseEvent (Uhc->AsyncIntMonitor);\r
}\r
\r
+ if (Uhc->ExitBootServiceEvent != NULL) {\r
+ gBS->CloseEvent (Uhc->ExitBootServiceEvent);\r
+ }\r
+\r
if (Uhc->MemPool != NULL) {\r
UsbHcFreeMemPool (Uhc->MemPool);\r
}\r
\r
- if (Uhc->CtrlNameTable) {\r
+ if (Uhc->CtrlNameTable != NULL) {\r
FreeUnicodeStringTable (Uhc->CtrlNameTable);\r
}\r
\r
- gBS->FreePool (Uhc);\r
+ FreePool (Uhc);\r
}\r
\r
\r
/**\r
- Uninstall all Uhci Interface\r
+ Uninstall all Uhci Interface.\r
\r
- @param Controller Controller handle\r
+ @param Controller Controller handle.\r
@param This Protocol instance pointer.\r
\r
- @return VOID\r
-\r
**/\r
-STATIC\r
VOID\r
UhciCleanDevUp (\r
IN EFI_HANDLE Controller,\r
)\r
{\r
USB_HC_DEV *Uhc;\r
+ EFI_STATUS Status;\r
\r
//\r
// Uninstall the USB_HC and USB_HC2 protocol, then disable the controller\r
//\r
Uhc = UHC_FROM_USB2_HC_PROTO (This);\r
- UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);\r
\r
- gBS->UninstallProtocolInterface (\r
- Controller,\r
- &gEfiUsb2HcProtocolGuid,\r
- &Uhc->Usb2Hc\r
- );\r
\r
+ Status = gBS->UninstallProtocolInterface (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ &Uhc->Usb2Hc\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return ;\r
+ }\r
+\r
+ UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);\r
UhciFreeAllAsyncReq (Uhc);\r
UhciDestoryFrameList (Uhc);\r
\r
UhciFreeDev (Uhc);\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
+UhcExitBootService (\r
+ EFI_EVENT Event,\r
+ VOID *Context\r
+ )\r
+{\r
+ USB_HC_DEV *Uhc;\r
+\r
+ Uhc = (USB_HC_DEV *) Context;\r
+\r
+ //\r
+ // Stop the Host Controller\r
+ //\r
+ UhciStopHc (Uhc, UHC_GENERIC_TIMEOUT);\r
+\r
+ //\r
+ // Reset the Host Controller\r
+ //\r
+ UhciSetRegBit (Uhc->PciIo, USBCMD_OFFSET, USBCMD_HCRESET);\r
+ gBS->Stall (UHC_ROOT_PORT_RECOVERY_STALL);\r
+}\r
\r
/**\r
- Starting the Usb UHCI Driver\r
+ Starting the Usb UHCI 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
@retval EFI_SUCCESS This driver supports this device.\r
@retval EFI_UNSUPPORTED This driver does not support this device.\r
- @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error\r
- EFI_OUT_OF_RESOURCES- Failed due to resource\r
- shortage\r
+ @retval EFI_DEVICE_ERROR This driver cannot be started due to device Error.\r
+ EFI_OUT_OF_RESOURCES- Failed due to resource shortage.\r
\r
**/\r
EFI_STATUS\r
UINT64 Supports;\r
UINT64 OriginalPciAttributes;\r
BOOLEAN PciAttributesSaved;\r
+ EFI_DEVICE_PATH_PROTOCOL *HcDevicePath;\r
\r
//\r
// Open PCIIO, then enable the EHC device and turn off emulation\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
// Robustnesss improvement such as for UoL\r
// Default is not required.\r
//\r
- // UhciTurnOffUsbEmulation (PciIo);\r
+ if (FeaturePcdGet (PcdTurnOffUsbLegacySupport)) {\r
+ UhciTurnOffUsbEmulation (PciIo);\r
+ }\r
\r
Status = PciIo->Attributes (\r
PciIo,\r
&Supports\r
);\r
if (!EFI_ERROR (Status)) {\r
- Supports &= EFI_PCI_DEVICE_ENABLE;\r
+ Supports &= (UINT64)EFI_PCI_DEVICE_ENABLE;\r
Status = PciIo->Attributes (\r
PciIo,\r
EfiPciIoAttributeOperationEnable,\r
goto CLOSE_PCIIO;\r
}\r
\r
- Uhc = UhciAllocateDev (PciIo, OriginalPciAttributes);\r
+ Uhc = UhciAllocateDev (PciIo, HcDevicePath, OriginalPciAttributes);\r
\r
if (Uhc == NULL) {\r
Status = EFI_OUT_OF_RESOURCES;\r
goto FREE_UHC;\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
+ UhcExitBootService,\r
+ Uhc,\r
+ &gEfiEventExitBootServicesGuid,\r
+ &Uhc->ExitBootServiceEvent\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ goto UNINSTALL_USBHC;\r
+ }\r
+\r
//\r
// Install the component name protocol\r
//\r
\r
return EFI_SUCCESS;\r
\r
+UNINSTALL_USBHC:\r
+ gBS->UninstallMultipleProtocolInterfaces (\r
+ Controller,\r
+ &gEfiUsb2HcProtocolGuid,\r
+ &Uhc->Usb2Hc,\r
+ NULL\r
+ );\r
+\r
FREE_UHC:\r
UhciFreeDev (Uhc);\r
\r
CLOSE_PCIIO:\r
- if (PciAttributesSaved == TRUE) {\r
+ if (PciAttributesSaved) {\r
//\r
// Restore original PCI attributes\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\r
return EFI_SUCCESS;\r
}\r
\r
-EFI_DRIVER_BINDING_PROTOCOL gUhciDriverBinding = {\r
- UhciDriverBindingSupported,\r
- UhciDriverBindingStart,\r
- UhciDriverBindingStop,\r
- 0x20,\r
- NULL,\r
- NULL\r
-};\r