From 4b1bf81c20d5523554a83f6604df7930396f7c21 Mon Sep 17 00:00:00 2001 From: jljusten Date: Mon, 27 Jun 2011 23:30:55 +0000 Subject: MdeModulePkg: Add PEI USB drivers and related PPIs Signed-off-by: jljusten Reviewed-by: mdkinney Reviewed-by: geekboy15a git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@11901 6f19259b-4bc3-4df7-8a09-765794883524 --- MdeModulePkg/Bus/Usb/UsbBusPei/HubPeim.c | 537 +++++++++++++ MdeModulePkg/Bus/Usb/UsbBusPei/HubPeim.h | 279 +++++++ MdeModulePkg/Bus/Usb/UsbBusPei/PeiUsbLib.c | 333 ++++++++ MdeModulePkg/Bus/Usb/UsbBusPei/PeiUsbLib.h | 250 +++++++ MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf | 66 ++ MdeModulePkg/Bus/Usb/UsbBusPei/UsbIoPeim.c | 325 ++++++++ MdeModulePkg/Bus/Usb/UsbBusPei/UsbPeim.c | 1041 ++++++++++++++++++++++++++ MdeModulePkg/Bus/Usb/UsbBusPei/UsbPeim.h | 203 +++++ 8 files changed, 3034 insertions(+) create mode 100644 MdeModulePkg/Bus/Usb/UsbBusPei/HubPeim.c create mode 100644 MdeModulePkg/Bus/Usb/UsbBusPei/HubPeim.h create mode 100644 MdeModulePkg/Bus/Usb/UsbBusPei/PeiUsbLib.c create mode 100644 MdeModulePkg/Bus/Usb/UsbBusPei/PeiUsbLib.h create mode 100644 MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf create mode 100644 MdeModulePkg/Bus/Usb/UsbBusPei/UsbIoPeim.c create mode 100644 MdeModulePkg/Bus/Usb/UsbBusPei/UsbPeim.c create mode 100644 MdeModulePkg/Bus/Usb/UsbBusPei/UsbPeim.h (limited to 'MdeModulePkg/Bus/Usb/UsbBusPei') diff --git a/MdeModulePkg/Bus/Usb/UsbBusPei/HubPeim.c b/MdeModulePkg/Bus/Usb/UsbBusPei/HubPeim.c new file mode 100644 index 0000000..5b7ebfa --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbBusPei/HubPeim.c @@ -0,0 +1,537 @@ +/** @file +Usb Hub Request Support In PEI Phase + +Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ +This program and the accompanying materials +are licensed and made available under the terms and conditions +of the BSD License which accompanies this distribution. The +full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "UsbPeim.h" +#include "HubPeim.h" +#include "PeiUsbLib.h" + +/** + Get a given hub port status. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param Port Usb hub port number (starting from 1). + @param PortStatus Current Hub port status and change status. + + @retval EFI_SUCCESS Port status is obtained successfully. + @retval EFI_DEVICE_ERROR Cannot get the port status due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiHubGetPortStatus ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 Port, + OUT UINT32 *PortStatus + ) +{ + EFI_USB_DEVICE_REQUEST DeviceRequest; + + ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST)); + + // + // Fill Device request packet + // + DeviceRequest.RequestType = USB_HUB_GET_PORT_STATUS_REQ_TYPE; + DeviceRequest.Request = USB_HUB_GET_PORT_STATUS; + DeviceRequest.Index = Port; + DeviceRequest.Length = (UINT16) sizeof (UINT32); + + + return UsbIoPpi->UsbControlTransfer ( + PeiServices, + UsbIoPpi, + &DeviceRequest, + EfiUsbDataIn, + PcdGet32 (PcdUsbTransferTimeoutValue), + PortStatus, + sizeof (UINT32) + ); + +} + +/** + Set specified feature to a given hub port. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param Port Usb hub port number (starting from 1). + @param Value New feature value. + + @retval EFI_SUCCESS Port feature is set successfully. + @retval EFI_DEVICE_ERROR Cannot set the port feature due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiHubSetPortFeature ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 Port, + IN UINT8 Value + ) +{ + EFI_USB_DEVICE_REQUEST DeviceRequest; + + ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST)); + + // + // Fill Device request packet + // + DeviceRequest.RequestType = USB_HUB_SET_PORT_FEATURE_REQ_TYPE; + DeviceRequest.Request = USB_HUB_SET_PORT_FEATURE; + DeviceRequest.Value = Value; + DeviceRequest.Index = Port; + + return UsbIoPpi->UsbControlTransfer ( + PeiServices, + UsbIoPpi, + &DeviceRequest, + EfiUsbNoData, + PcdGet32 (PcdUsbTransferTimeoutValue), + NULL, + 0 + ); +} + +/** + Clear specified feature on a given hub port. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param Port Usb hub port number (starting from 1). + @param Value Feature value that will be cleared from the hub port. + + @retval EFI_SUCCESS Port feature is cleared successfully. + @retval EFI_DEVICE_ERROR Cannot clear the port feature due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiHubClearPortFeature ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 Port, + IN UINT8 Value + ) +{ + EFI_USB_DEVICE_REQUEST DeviceRequest; + + ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST)); + + // + // Fill Device request packet + // + DeviceRequest.RequestType = USB_HUB_CLEAR_FEATURE_PORT_REQ_TYPE; + DeviceRequest.Request = USB_HUB_CLEAR_FEATURE_PORT; + DeviceRequest.Value = Value; + DeviceRequest.Index = Port; + + return UsbIoPpi->UsbControlTransfer ( + PeiServices, + UsbIoPpi, + &DeviceRequest, + EfiUsbNoData, + PcdGet32 (PcdUsbTransferTimeoutValue), + NULL, + 0 + ); +} + +/** + Get a given hub status. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param HubStatus Current Hub status and change status. + + @retval EFI_SUCCESS Hub status is obtained successfully. + @retval EFI_DEVICE_ERROR Cannot get the hub status due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiHubGetHubStatus ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + OUT UINT32 *HubStatus + ) +{ + EFI_USB_DEVICE_REQUEST DeviceRequest; + + ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST)); + + // + // Fill Device request packet + // + DeviceRequest.RequestType = USB_HUB_GET_HUB_STATUS_REQ_TYPE; + DeviceRequest.Request = USB_HUB_GET_HUB_STATUS; + DeviceRequest.Length = (UINT16) sizeof (UINT32); + + return UsbIoPpi->UsbControlTransfer ( + PeiServices, + UsbIoPpi, + &DeviceRequest, + EfiUsbDataIn, + PcdGet32 (PcdUsbTransferTimeoutValue), + HubStatus, + sizeof (UINT32) + ); +} + +/** + Set specified feature to a given hub. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param Value New feature value. + + @retval EFI_SUCCESS Port feature is set successfully. + @retval EFI_DEVICE_ERROR Cannot set the port feature due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiHubSetHubFeature ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 Value + ) +{ + EFI_USB_DEVICE_REQUEST DeviceRequest; + + ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST)); + + // + // Fill Device request packet + // + DeviceRequest.RequestType = USB_HUB_SET_HUB_FEATURE_REQ_TYPE; + DeviceRequest.Request = USB_HUB_SET_HUB_FEATURE; + DeviceRequest.Value = Value; + + return UsbIoPpi->UsbControlTransfer ( + PeiServices, + UsbIoPpi, + &DeviceRequest, + EfiUsbNoData, + PcdGet32 (PcdUsbTransferTimeoutValue), + NULL, + 0 + ); +} + +/** + Clear specified feature on a given hub. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param Value Feature value that will be cleared from the hub port. + + @retval EFI_SUCCESS Hub feature is cleared successfully. + @retval EFI_DEVICE_ERROR Cannot clear the hub feature due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiHubClearHubFeature ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 Value + ) +{ + EFI_USB_DEVICE_REQUEST DeviceRequest; + + ZeroMem (&DeviceRequest, sizeof (EFI_USB_DEVICE_REQUEST)); + + // + // Fill Device request packet + // + DeviceRequest.RequestType = USB_HUB_CLEAR_FEATURE_REQ_TYPE; + DeviceRequest.Request = USB_HUB_CLEAR_FEATURE; + DeviceRequest.Value = Value; + + return UsbIoPpi->UsbControlTransfer ( + PeiServices, + UsbIoPpi, + &DeviceRequest, + EfiUsbNoData, + PcdGet32 (PcdUsbTransferTimeoutValue), + NULL, + 0 + ); +} + +/** + Get a given hub descriptor. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param DescriptorSize The length of Hub Descriptor buffer. + @param HubDescriptor Caller allocated buffer to store the hub descriptor if + successfully returned. + + @retval EFI_SUCCESS Hub descriptor is obtained successfully. + @retval EFI_DEVICE_ERROR Cannot get the hub descriptor due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiGetHubDescriptor ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINTN DescriptorSize, + OUT EFI_USB_HUB_DESCRIPTOR *HubDescriptor + ) +{ + EFI_USB_DEVICE_REQUEST DevReq; + ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); + + // + // Fill Device request packet + // + DevReq.RequestType = USB_RT_HUB | 0x80; + DevReq.Request = USB_HUB_GET_DESCRIPTOR; + DevReq.Value = USB_DT_HUB << 8; + DevReq.Length = (UINT16)DescriptorSize; + + return UsbIoPpi->UsbControlTransfer ( + PeiServices, + UsbIoPpi, + &DevReq, + EfiUsbDataIn, + PcdGet32 (PcdUsbTransferTimeoutValue), + HubDescriptor, + (UINT16)DescriptorSize + ); +} + +/** + Configure a given hub. + + @param PeiServices General-purpose services that are available to every PEIM. + @param PeiUsbDevice Indicating the hub controller device that will be configured + + @retval EFI_SUCCESS Hub configuration is done successfully. + @retval EFI_DEVICE_ERROR Cannot configure the hub due to a hardware error. + +**/ +EFI_STATUS +PeiDoHubConfig ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_DEVICE *PeiUsbDevice + ) +{ + EFI_USB_HUB_DESCRIPTOR HubDescriptor; + EFI_STATUS Status; + EFI_USB_HUB_STATUS HubStatus; + UINTN Index; + UINT32 PortStatus; + PEI_USB_IO_PPI *UsbIoPpi; + + ZeroMem (&HubDescriptor, sizeof (HubDescriptor)); + UsbIoPpi = &PeiUsbDevice->UsbIoPpi; + + // + // First get the hub descriptor length + // + Status = PeiGetHubDescriptor ( + PeiServices, + UsbIoPpi, + 2, + &HubDescriptor + ); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + // + // First get the whole descriptor, then + // get the number of hub ports + // + Status = PeiGetHubDescriptor ( + PeiServices, + UsbIoPpi, + HubDescriptor.Length, + &HubDescriptor + ); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + + PeiUsbDevice->DownStreamPortNo = HubDescriptor.NbrPorts; + + Status = PeiHubGetHubStatus ( + PeiServices, + UsbIoPpi, + (UINT32 *) &HubStatus + ); + + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } + // + // Get all hub ports status + // + for (Index = 0; Index < PeiUsbDevice->DownStreamPortNo; Index++) { + + Status = PeiHubGetPortStatus ( + PeiServices, + UsbIoPpi, + (UINT8) (Index + 1), + &PortStatus + ); + if (EFI_ERROR (Status)) { + continue; + } + } + // + // Power all the hub ports + // + for (Index = 0; Index < PeiUsbDevice->DownStreamPortNo; Index++) { + Status = PeiHubSetPortFeature ( + PeiServices, + UsbIoPpi, + (UINT8) (Index + 1), + EfiUsbPortPower + ); + if (EFI_ERROR (Status)) { + continue; + } + } + // + // Clear Hub Status Change + // + Status = PeiHubGetHubStatus ( + PeiServices, + UsbIoPpi, + (UINT32 *) &HubStatus + ); + if (EFI_ERROR (Status)) { + return EFI_DEVICE_ERROR; + } else { + // + // Hub power supply change happens + // + if ((HubStatus.HubChangeStatus & HUB_CHANGE_LOCAL_POWER) != 0) { + PeiHubClearHubFeature ( + PeiServices, + UsbIoPpi, + C_HUB_LOCAL_POWER + ); + } + // + // Hub change overcurrent happens + // + if ((HubStatus.HubChangeStatus & HUB_CHANGE_OVERCURRENT) != 0) { + PeiHubClearHubFeature ( + PeiServices, + UsbIoPpi, + C_HUB_OVER_CURRENT + ); + } + } + + return EFI_SUCCESS; +} + +/** + Send reset signal over the given root hub port. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param PortNum Usb hub port number (starting from 1). + +**/ +VOID +PeiResetHubPort ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 PortNum + ) +{ + UINT8 Try; + EFI_USB_PORT_STATUS HubPortStatus; + + + MicroSecondDelay (100 * 1000); + + // + // reset root port + // + PeiHubSetPortFeature ( + PeiServices, + UsbIoPpi, + PortNum, + EfiUsbPortReset + ); + + Try = 10; + do { + PeiHubGetPortStatus ( + PeiServices, + UsbIoPpi, + PortNum, + (UINT32 *) &HubPortStatus + ); + + MicroSecondDelay (2 * 1000); + Try -= 1; + } while ((HubPortStatus.PortChangeStatus & USB_PORT_STAT_C_RESET) == 0 && Try > 0); + + // + // clear reset root port + // + PeiHubClearPortFeature ( + PeiServices, + UsbIoPpi, + PortNum, + EfiUsbPortReset + ); + + MicroSecondDelay (1 * 1000); + + PeiHubClearPortFeature ( + PeiServices, + UsbIoPpi, + PortNum, + EfiUsbPortConnectChange + ); + + // + // Set port enable + // + PeiHubSetPortFeature ( + PeiServices, + UsbIoPpi, + PortNum, + EfiUsbPortEnable + ); + + // + // Clear any change status + // + + PeiHubClearPortFeature ( + PeiServices, + UsbIoPpi, + PortNum, + EfiUsbPortEnableChange + ); + + MicroSecondDelay (10 * 1000); + + return; +} diff --git a/MdeModulePkg/Bus/Usb/UsbBusPei/HubPeim.h b/MdeModulePkg/Bus/Usb/UsbBusPei/HubPeim.h new file mode 100644 index 0000000..273a26c --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbBusPei/HubPeim.h @@ -0,0 +1,279 @@ +/** @file +Constants definitions for Usb Hub Peim + +Copyright (c) 2006, Intel Corporation. All rights reserved.
+ +This program and the accompanying materials +are licensed and made available under the terms and conditions +of the BSD License which accompanies this distribution. The +full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _PEI_HUB_PEIM_H_ +#define _PEI_HUB_PEIM_H_ + + +// +// Hub feature numbers +// +#define C_HUB_LOCAL_POWER 0 +#define C_HUB_OVER_CURRENT 1 + +// +// Hub class code & sub class code +// +#define CLASS_CODE_HUB 0x09 +#define SUB_CLASS_CODE_HUB 0 + +// +// Hub Status & Hub Change bit masks +// +#define HUB_STATUS_LOCAL_POWER 0x0001 +#define HUB_STATUS_OVERCURRENT 0x0002 + +#define HUB_CHANGE_LOCAL_POWER 0x0001 +#define HUB_CHANGE_OVERCURRENT 0x0002 + +// +// Hub Characteristics +// +#define HUB_CHAR_LPSM 0x0003 +#define HUB_CHAR_COMPOUND 0x0004 +#define HUB_CHAR_OCPM 0x0018 + +// +// Standard hub request and request type +// By [Spec-USB20/Chapter-11.24] +// +#define USB_HUB_CLEAR_FEATURE 0x01 +#define USB_HUB_CLEAR_FEATURE_REQ_TYPE 0x20 + +#define USB_HUB_CLEAR_FEATURE_PORT 0x01 +#define USB_HUB_CLEAR_FEATURE_PORT_REQ_TYPE 0x23 + +#define USB_HUB_GET_BUS_STATE 0x02 +#define USB_HUB_GET_BUS_STATE_REQ_TYPE 0xA3 + +#define USB_HUB_GET_DESCRIPTOR 0x06 +#define USB_HUB_GET_DESCRIPTOR_REQ_TYPE 0xA0 + +#define USB_HUB_GET_HUB_STATUS 0x00 +#define USB_HUB_GET_HUB_STATUS_REQ_TYPE 0xA0 + +#define USB_HUB_GET_PORT_STATUS 0x00 +#define USB_HUB_GET_PORT_STATUS_REQ_TYPE 0xA3 + +#define USB_HUB_SET_DESCRIPTOR 0x07 +#define USB_HUB_SET_DESCRIPTOR_REQ_TYPE 0x20 + +#define USB_HUB_SET_HUB_FEATURE 0x03 +#define USB_HUB_SET_HUB_FEATURE_REQ_TYPE 0x20 + +#define USB_HUB_SET_PORT_FEATURE 0x03 +#define USB_HUB_SET_PORT_FEATURE_REQ_TYPE 0x23 + +#define USB_RT_HUB (USB_TYPE_CLASS | USB_RECIP_DEVICE) +#define USB_RT_PORT (USB_TYPE_CLASS | USB_RECIP_OTHER) + +#define MAXBYTES 8 +#pragma pack(1) +// +// Hub descriptor, the last two fields are of variable lenght. +// +typedef struct { + UINT8 Length; + UINT8 DescriptorType; + UINT8 NbrPorts; + UINT8 HubCharacteristics[2]; + UINT8 PwrOn2PwrGood; + UINT8 HubContrCurrent; + UINT8 Filler[MAXBYTES]; +} EFI_USB_HUB_DESCRIPTOR; + +typedef struct { + UINT16 HubStatus; + UINT16 HubChangeStatus; +} EFI_USB_HUB_STATUS; + +#pragma pack() +/** + Get a given hub port status. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param Port Usb hub port number (starting from 1). + @param PortStatus Current Hub port status and change status. + + @retval EFI_SUCCESS Port status is obtained successfully. + @retval EFI_DEVICE_ERROR Cannot get the port status due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiHubGetPortStatus ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 Port, + OUT UINT32 *PortStatus + ); + +/** + Set specified feature to a given hub port. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param Port Usb hub port number (starting from 1). + @param Value New feature value. + + @retval EFI_SUCCESS Port feature is set successfully. + @retval EFI_DEVICE_ERROR Cannot set the port feature due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiHubSetPortFeature ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 Port, + IN UINT8 Value + ); + +/** + Set specified feature to a given hub. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param Value New feature value. + + @retval EFI_SUCCESS Port feature is set successfully. + @retval EFI_DEVICE_ERROR Cannot set the port feature due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiHubSetHubFeature ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 Value + ); + +/** + Get a given hub status. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param HubStatus Current Hub status and change status. + + @retval EFI_SUCCESS Hub status is obtained successfully. + @retval EFI_DEVICE_ERROR Cannot get the hub status due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiHubGetHubStatus ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + OUT UINT32 *HubStatus + ); + +/** + Clear specified feature on a given hub port. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param Port Usb hub port number (starting from 1). + @param Value Feature value that will be cleared from the hub port. + + @retval EFI_SUCCESS Port feature is cleared successfully. + @retval EFI_DEVICE_ERROR Cannot clear the port feature due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiHubClearPortFeature ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 Port, + IN UINT8 Value + ); + +/** + Clear specified feature on a given hub. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param Value Feature value that will be cleared from the hub port. + + @retval EFI_SUCCESS Hub feature is cleared successfully. + @retval EFI_DEVICE_ERROR Cannot clear the hub feature due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiHubClearHubFeature ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 Value + ); + +/** + Get a given hub descriptor. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param DescriptorSize The length of Hub Descriptor buffer. + @param HubDescriptor Caller allocated buffer to store the hub descriptor if + successfully returned. + + @retval EFI_SUCCESS Hub descriptor is obtained successfully. + @retval EFI_DEVICE_ERROR Cannot get the hub descriptor due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiGetHubDescriptor ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINTN DescriptorSize, + OUT EFI_USB_HUB_DESCRIPTOR *HubDescriptor + ); + +/** + Configure a given hub. + + @param PeiServices General-purpose services that are available to every PEIM. + @param PeiUsbDevice Indicating the hub controller device that will be configured + + @retval EFI_SUCCESS Hub configuration is done successfully. + @retval EFI_DEVICE_ERROR Cannot configure the hub due to a hardware error. + +**/ +EFI_STATUS +PeiDoHubConfig ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_DEVICE *PeiUsbDevice + ); + +/** + Send reset signal over the given root hub port. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param PortNum Usb hub port number (starting from 1). + +**/ +VOID +PeiResetHubPort ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 PortNum + ); + +#endif + + diff --git a/MdeModulePkg/Bus/Usb/UsbBusPei/PeiUsbLib.c b/MdeModulePkg/Bus/Usb/UsbBusPei/PeiUsbLib.c new file mode 100644 index 0000000..2ac8d7b --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbBusPei/PeiUsbLib.c @@ -0,0 +1,333 @@ +/** @file +Common Libarary for PEI USB + +Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ +This program and the accompanying materials +are licensed and made available under the terms and conditions +of the BSD License which accompanies this distribution. The +full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "UsbPeim.h" +#include "PeiUsbLib.h" + +/** + Get a given usb descriptor. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param Value Request Value. + @param Index Request Index. + @param DescriptorLength Request descriptor Length. + @param Descriptor Request descriptor. + + + @retval EFI_SUCCESS Usb descriptor is obtained successfully. + @retval EFI_DEVICE_ERROR Cannot get the usb descriptor due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiUsbGetDescriptor ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT16 Value, + IN UINT16 Index, + IN UINT16 DescriptorLength, + OUT VOID *Descriptor + ) +{ + EFI_USB_DEVICE_REQUEST DevReq; + + ASSERT (UsbIoPpi != NULL); + + DevReq.RequestType = USB_DEV_GET_DESCRIPTOR_REQ_TYPE; + DevReq.Request = USB_DEV_GET_DESCRIPTOR; + DevReq.Value = Value; + DevReq.Index = Index; + DevReq.Length = DescriptorLength; + + return UsbIoPpi->UsbControlTransfer ( + PeiServices, + UsbIoPpi, + &DevReq, + EfiUsbDataIn, + PcdGet32 (PcdUsbTransferTimeoutValue), + Descriptor, + DescriptorLength + ); +} + +/** + Set a usb device with a specified address. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param AddressValue The address to assign. + + @retval EFI_SUCCESS Usb device address is set successfully. + @retval EFI_DEVICE_ERROR Cannot set the usb address due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiUsbSetDeviceAddress ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT16 AddressValue + ) +{ + EFI_USB_DEVICE_REQUEST DevReq; + + ASSERT (UsbIoPpi != NULL); + + DevReq.RequestType = USB_DEV_SET_ADDRESS_REQ_TYPE; + DevReq.Request = USB_DEV_SET_ADDRESS; + DevReq.Value = AddressValue; + DevReq.Index = 0; + DevReq.Length = 0; + + return UsbIoPpi->UsbControlTransfer ( + PeiServices, + UsbIoPpi, + &DevReq, + EfiUsbNoData, + PcdGet32 (PcdUsbTransferTimeoutValue), + NULL, + 0 + ); +} + +/** + Clear a given usb feature. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param Recipient The recipient of ClearFeature Request, should be one of Device/Interface/Endpoint. + @param Value Request Value. + @param Target Request Index. + + @retval EFI_SUCCESS Usb feature is cleared successfully. + @retval EFI_DEVICE_ERROR Cannot clear the usb feature due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiUsbClearDeviceFeature ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN EFI_USB_RECIPIENT Recipient, + IN UINT16 Value, + IN UINT16 Target + ) +{ + EFI_USB_DEVICE_REQUEST DevReq; + + ASSERT (UsbIoPpi != NULL); + + switch (Recipient) { + case EfiUsbDevice: + DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_D; + break; + + case EfiUsbInterface: + DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_I; + break; + + case EfiUsbEndpoint: + DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_E; + break; + } + + DevReq.Request = USB_DEV_CLEAR_FEATURE; + DevReq.Value = Value; + DevReq.Index = Target; + DevReq.Length = 0; + + return UsbIoPpi->UsbControlTransfer ( + PeiServices, + UsbIoPpi, + &DevReq, + EfiUsbNoData, + PcdGet32 (PcdUsbTransferTimeoutValue), + NULL, + 0 + ); +} + +/** + Configure a usb device to Configuration 1. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + + @retval EFI_SUCCESS Usb device is set to use Configuration 1 successfully. + @retval EFI_DEVICE_ERROR Cannot set the usb device due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiUsbSetConfiguration ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi + ) +{ + EFI_USB_DEVICE_REQUEST DevReq; + ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST)); + + DevReq.RequestType = USB_DEV_SET_CONFIGURATION_REQ_TYPE; + DevReq.Request = USB_DEV_SET_CONFIGURATION; + DevReq.Value = 1; + + return UsbIoPpi->UsbControlTransfer ( + PeiServices, + UsbIoPpi, + &DevReq, + EfiUsbNoData, + PcdGet32 (PcdUsbTransferTimeoutValue), + NULL, + 0 + ); +} + +/** + Clear Endpoint Halt. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param EndpointAddress The endpoint address. + + @retval EFI_SUCCESS Endpoint halt is cleared successfully. + @retval EFI_DEVICE_ERROR Cannot clear the endpoint halt status due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiUsbClearEndpointHalt ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 EndpointAddress + ) +{ + EFI_STATUS Status; + PEI_USB_DEVICE *PeiUsbDev; + EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor; + UINT8 EndpointIndex; + + EndpointIndex = 0; + PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (UsbIoPpi); + + while (EndpointIndex < MAX_ENDPOINT) { + Status = UsbIoPpi->UsbGetEndpointDescriptor (PeiServices, UsbIoPpi, EndpointIndex, &EndpointDescriptor); + if (EFI_ERROR (Status)) { + return EFI_INVALID_PARAMETER; + } + + if (EndpointDescriptor->EndpointAddress == EndpointAddress) { + break; + } + + EndpointIndex++; + } + + if (EndpointIndex == MAX_ENDPOINT) { + return EFI_INVALID_PARAMETER; + } + + Status = PeiUsbClearDeviceFeature ( + PeiServices, + UsbIoPpi, + EfiUsbEndpoint, + EfiUsbEndpointHalt, + EndpointAddress + ); + + // + // set data toggle to zero. + // + if ((PeiUsbDev->DataToggle & (1 << EndpointIndex)) != 0) { + PeiUsbDev->DataToggle = (UINT8) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex)); + } + + return Status; +} + +/** + Judge if the port is connected with a usb device or not. + + @param PortStatus The usb port status gotten. + + @retval TRUE A usb device is connected with the port. + @retval FALSE No usb device is connected with the port. + +**/ +BOOLEAN +IsPortConnect ( + IN UINT16 PortStatus + ) +{ + // + // return the bit 0 value of PortStatus + // + if ((PortStatus & USB_PORT_STAT_CONNECTION) != 0) { + return TRUE; + } else { + return FALSE; + } +} + +/** + Judge if the port is connected with a low-speed usb device or not. + + @param PortStatus The usb port status gotten. + + @retval TRUE A low-speed usb device is connected with the port. + @retval FALSE No low-speed usb device is connected with the port. + +**/ +UINTN +IsPortLowSpeedDeviceAttached ( + IN UINT16 PortStatus + ) +{ + // + // return the bit 9 value of PortStatus + // + if ((PortStatus & USB_PORT_STAT_LOW_SPEED) != 0) { + return EFI_USB_SPEED_LOW; + } else if ((PortStatus & USB_PORT_STAT_HIGH_SPEED) != 0){ + return EFI_USB_SPEED_HIGH; + } else { + return EFI_USB_SPEED_FULL; + } +} + +/** + Judge if the port is in "connection change" status or not. + + @param PortChangeStatus The usb port change status gotten. + + @retval TRUE The port is in "connection change" status. + @retval FALSE The port is NOT in "connection change" status. + +**/ +BOOLEAN +IsPortConnectChange ( + IN UINT16 PortChangeStatus + ) +{ + // + // return the bit 0 value of PortChangeStatus + // + if ((PortChangeStatus & USB_PORT_STAT_C_CONNECTION) != 0) { + return TRUE; + } else { + return FALSE; + } +} diff --git a/MdeModulePkg/Bus/Usb/UsbBusPei/PeiUsbLib.h b/MdeModulePkg/Bus/Usb/UsbBusPei/PeiUsbLib.h new file mode 100644 index 0000000..dd4ce1b --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbBusPei/PeiUsbLib.h @@ -0,0 +1,250 @@ +/** @file +Common Libarary for PEI USB + +Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ +This program and the accompanying materials +are licensed and made available under the terms and conditions +of the BSD License which accompanies this distribution. The +full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _PEI_USB_LIB_H_ +#define _PEI_USB_LIB_H_ + + +// +// Standard device request and request type +// By [Spec-USB20/Chapter-9.4] +// +#define USB_DEV_GET_STATUS 0x00 +#define USB_DEV_GET_STATUS_REQ_TYPE_D 0x80 // Receiver : Device +#define USB_DEV_GET_STATUS_REQ_TYPE_I 0x81 // Receiver : Interface +#define USB_DEV_GET_STATUS_REQ_TYPE_E 0x82 // Receiver : Endpoint + +#define USB_DEV_CLEAR_FEATURE 0x01 +#define USB_DEV_CLEAR_FEATURE_REQ_TYPE_D 0x00 // Receiver : Device +#define USB_DEV_CLEAR_FEATURE_REQ_TYPE_I 0x01 // Receiver : Interface +#define USB_DEV_CLEAR_FEATURE_REQ_TYPE_E 0x02 // Receiver : Endpoint + +#define USB_DEV_SET_FEATURE 0x03 +#define USB_DEV_SET_FEATURE_REQ_TYPE_D 0x00 // Receiver : Device +#define USB_DEV_SET_FEATURE_REQ_TYPE_I 0x01 // Receiver : Interface +#define USB_DEV_SET_FEATURE_REQ_TYPE_E 0x02 // Receiver : Endpoint + +#define USB_DEV_SET_ADDRESS 0x05 +#define USB_DEV_SET_ADDRESS_REQ_TYPE 0x00 + +#define USB_DEV_GET_DESCRIPTOR 0x06 +#define USB_DEV_GET_DESCRIPTOR_REQ_TYPE 0x80 + +#define USB_DEV_SET_DESCRIPTOR 0x07 +#define USB_DEV_SET_DESCRIPTOR_REQ_TYPE 0x00 + +#define USB_DEV_GET_CONFIGURATION 0x08 +#define USB_DEV_GET_CONFIGURATION_REQ_TYPE 0x80 + +#define USB_DEV_SET_CONFIGURATION 0x09 +#define USB_DEV_SET_CONFIGURATION_REQ_TYPE 0x00 + +#define USB_DEV_GET_INTERFACE 0x0A +#define USB_DEV_GET_INTERFACE_REQ_TYPE 0x81 + +#define USB_DEV_SET_INTERFACE 0x0B +#define USB_DEV_SET_INTERFACE_REQ_TYPE 0x01 + +#define USB_DEV_SYNCH_FRAME 0x0C +#define USB_DEV_SYNCH_FRAME_REQ_TYPE 0x82 + +// +// USB Descriptor types +// +#define USB_DT_DEVICE 0x01 +#define USB_DT_CONFIG 0x02 +#define USB_DT_STRING 0x03 +#define USB_DT_INTERFACE 0x04 +#define USB_DT_ENDPOINT 0x05 +#define USB_DT_HUB 0x29 +#define USB_DT_HID 0x21 + +// +// USB request type +// +#define USB_TYPE_STANDARD (0x00 << 5) +#define USB_TYPE_CLASS (0x01 << 5) +#define USB_TYPE_VENDOR (0x02 << 5) +#define USB_TYPE_RESERVED (0x03 << 5) + +// +// USB request targer device +// +#define USB_RECIP_DEVICE 0x00 +#define USB_RECIP_INTERFACE 0x01 +#define USB_RECIP_ENDPOINT 0x02 +#define USB_RECIP_OTHER 0x03 + +typedef enum { + EfiUsbEndpointHalt, + EfiUsbDeviceRemoteWakeup +} EFI_USB_STANDARD_FEATURE_SELECTOR; + +// +// Usb Data recipient type +// +typedef enum { + EfiUsbDevice, + EfiUsbInterface, + EfiUsbEndpoint +} EFI_USB_RECIPIENT; + +/** + Get a given usb descriptor. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param Value Request Value. + @param Index Request Index. + @param DescriptorLength Request descriptor Length. + @param Descriptor Request descriptor. + + + @retval EFI_SUCCESS Usb descriptor is obtained successfully. + @retval EFI_DEVICE_ERROR Cannot get the usb descriptor due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiUsbGetDescriptor ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT16 Value, + IN UINT16 Index, + IN UINT16 DescriptorLength, + OUT VOID *Descriptor + ); + +/** + Set a usb device with a specified address. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param AddressValue The address to assign. + + @retval EFI_SUCCESS Usb device address is set successfully. + @retval EFI_DEVICE_ERROR Cannot set the usb address due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiUsbSetDeviceAddress ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT16 AddressValue + ); + +/** + Clear a given usb feature. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param Recipient The recipient of ClearFeature Request, should be one of Device/Interface/Endpoint. + @param Value Request Value. + @param Target Request Index. + + @retval EFI_SUCCESS Usb feature is cleared successfully. + @retval EFI_DEVICE_ERROR Cannot clear the usb feature due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiUsbClearDeviceFeature ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN EFI_USB_RECIPIENT Recipient, + IN UINT16 Value, + IN UINT16 Target + ); + +/** + Configure a usb device to Configuration 1. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + + @retval EFI_SUCCESS Usb device is set to use Configuration 1 successfully. + @retval EFI_DEVICE_ERROR Cannot set the usb device due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiUsbSetConfiguration ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi + ); + +/** + Clear Endpoint Halt. + + @param PeiServices General-purpose services that are available to every PEIM. + @param UsbIoPpi Indicates the PEI_USB_IO_PPI instance. + @param EndpointAddress The endpoint address. + + @retval EFI_SUCCESS Endpoint halt is cleared successfully. + @retval EFI_DEVICE_ERROR Cannot clear the endpoint halt status due to a hardware error. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiUsbClearEndpointHalt ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *UsbIoPpi, + IN UINT8 EndpointAddress + ); + +/** + Judge if the port is connected with a usb device or not. + + @param PortStatus The usb port status gotten. + + @retval TRUE A usb device is connected with the port. + @retval FALSE No usb device is connected with the port. + +**/ +BOOLEAN +IsPortConnect ( + IN UINT16 PortStatus + ); + +/** + Judge if the port is connected with a low-speed usb device or not. + + @param PortStatus The usb port status gotten. + + @retval TRUE A low-speed usb device is connected with the port. + @retval FALSE No low-speed usb device is connected with the port. + +**/ +UINTN +IsPortLowSpeedDeviceAttached ( + IN UINT16 PortStatus + ); + +/** + Judge if the port is in "connection change" status or not. + + @param PortChangeStatus The usb port change status gotten. + + @retval TRUE The port is in "connection change" status. + @retval FALSE The port is NOT in "connection change" status. + +**/ +BOOLEAN +IsPortConnectChange ( + IN UINT16 PortChangeStatus + ); +#endif diff --git a/MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf b/MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf new file mode 100644 index 0000000..e4a2cb4 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbBusPei/UsbBusPei.inf @@ -0,0 +1,66 @@ +## @file +# Component description file for UsbPeim module. +# +# Usb Bus Peim driver to support recovery from usb device. +# Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+# +# This program and the accompanying materials +# are licensed and made available under the terms and conditions +# of the BSD License which accompanies this distribution. The +# full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = UsbBusPei + FILE_GUID = 8401A045-6F70-4505-8471-7015B40355E3 + MODULE_TYPE = PEIM + VERSION_STRING = 1.0 + + ENTRY_POINT = PeimInitializeUsb + +# +# The following information is for reference only and not required by the build tools. +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources] + PeiUsbLib.c + HubPeim.c + UsbIoPeim.c + UsbPeim.c + UsbPeim.h + PeiUsbLib.h + HubPeim.h + + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + TimerLib + BaseMemoryLib + PeiServicesLib + PeimEntryPoint + DebugLib + PcdLib + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdUsbTransferTimeoutValue + +[Ppis] + gPeiUsbIoPpiGuid # PPI ALWAYS_PRODUCED + gPeiUsbHostControllerPpiGuid # PPI ALWAYS_CONSUMED + gPeiUsb2HostControllerPpiGuid # PPI ALWAYS_CONSUMED + + +[Depex] + gEfiPeiMemoryDiscoveredPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid AND gPeiUsb2HostControllerPpiGuid OR gPeiUsbHostControllerPpiGuid + diff --git a/MdeModulePkg/Bus/Usb/UsbBusPei/UsbIoPeim.c b/MdeModulePkg/Bus/Usb/UsbBusPei/UsbIoPeim.c new file mode 100644 index 0000000..897b228 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbBusPei/UsbIoPeim.c @@ -0,0 +1,325 @@ +/** @file +The module is used to implement Usb Io PPI interfaces. + +Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ +This program and the accompanying materials +are licensed and made available under the terms and conditions +of the BSD License which accompanies this distribution. The +full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "UsbPeim.h" +#include "PeiUsbLib.h" + +/** + Submits control transfer to a target USB device. + + @param PeiServices The pointer of EFI_PEI_SERVICES. + @param This The pointer of PEI_USB_IO_PPI. + @param Request USB device request to send. + @param Direction Specifies the data direction for the data stage. + @param Timeout Indicates the maximum timeout, in millisecond. + @param Data Data buffer to be transmitted or received from USB device. + @param DataLength The size (in bytes) of the data buffer. + + @retval EFI_SUCCESS Transfer was completed successfully. + @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources. + @retval EFI_INVALID_PARAMETER Some parameters are invalid. + @retval EFI_TIMEOUT Transfer failed due to timeout. + @retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error. + +**/ +EFI_STATUS +EFIAPI +PeiUsbControlTransfer ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *This, + IN EFI_USB_DEVICE_REQUEST *Request, + IN EFI_USB_DATA_DIRECTION Direction, + IN UINT32 Timeout, + IN OUT VOID *Data, OPTIONAL + IN UINTN DataLength OPTIONAL + ) +{ + EFI_STATUS Status; + PEI_USB_DEVICE *PeiUsbDev; + UINT32 TransferResult; + + PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This); + + if (PeiUsbDev->Usb2HcPpi != NULL) { + Status = PeiUsbDev->Usb2HcPpi->ControlTransfer ( + PeiServices, + PeiUsbDev->Usb2HcPpi, + PeiUsbDev->DeviceAddress, + PeiUsbDev->DeviceSpeed, + PeiUsbDev->MaxPacketSize0, + Request, + Direction, + Data, + &DataLength, + Timeout, + &(PeiUsbDev->Translator), + &TransferResult + ); + } else { + Status = PeiUsbDev->UsbHcPpi->ControlTransfer ( + PeiServices, + PeiUsbDev->UsbHcPpi, + PeiUsbDev->DeviceAddress, + PeiUsbDev->DeviceSpeed, + PeiUsbDev->MaxPacketSize0, + Request, + Direction, + Data, + &DataLength, + Timeout, + &TransferResult + ); + } + return Status; +} + +/** + Submits bulk transfer to a bulk endpoint of a USB device. + + @param PeiServices The pointer of EFI_PEI_SERVICES. + @param This The pointer of PEI_USB_IO_PPI. + @param DeviceEndpoint Endpoint number and its direction in bit 7. + @param Data A pointer to the buffer of data to transmit + from or receive into. + @param DataLength The lenght of the data buffer. + @param Timeout Indicates the maximum time, in millisecond, which the + transfer is allowed to complete. + + @retval EFI_SUCCESS The transfer was completed successfully. + @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource. + @retval EFI_INVALID_PARAMETER Parameters are invalid. + @retval EFI_TIMEOUT The transfer failed due to timeout. + @retval EFI_DEVICE_ERROR The transfer failed due to host controller error. + +**/ +EFI_STATUS +EFIAPI +PeiUsbBulkTransfer ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *This, + IN UINT8 DeviceEndpoint, + IN OUT VOID *Data, + IN OUT UINTN *DataLength, + IN UINTN Timeout + ) +{ + EFI_STATUS Status; + PEI_USB_DEVICE *PeiUsbDev; + UINT32 TransferResult; + UINTN MaxPacketLength; + UINT8 DataToggle; + UINT8 OldToggle; + EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor; + UINT8 EndpointIndex; + VOID *Data2[EFI_USB_MAX_BULK_BUFFER_NUM]; + + PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This); + + EndpointDescriptor = NULL; + EndpointIndex = 0; + Data2[0] = Data; + Data2[1] = NULL; + + while (EndpointIndex < MAX_ENDPOINT) { + Status = PeiUsbGetEndpointDescriptor (PeiServices, This, EndpointIndex, &EndpointDescriptor); + if (EFI_ERROR (Status)) { + return EFI_INVALID_PARAMETER; + } + + if (EndpointDescriptor->EndpointAddress == DeviceEndpoint) { + break; + } + + EndpointIndex++; + } + + if (EndpointIndex == MAX_ENDPOINT) { + return EFI_INVALID_PARAMETER; + } + + MaxPacketLength = PeiUsbDev->EndpointDesc[EndpointIndex]->MaxPacketSize; + if ((PeiUsbDev->DataToggle & (1 << EndpointIndex)) != 0) { + DataToggle = 1; + } else { + DataToggle = 0; + } + + OldToggle = DataToggle; + + if (PeiUsbDev->Usb2HcPpi != NULL) { + Status = PeiUsbDev->Usb2HcPpi->BulkTransfer ( + PeiServices, + PeiUsbDev->Usb2HcPpi, + PeiUsbDev->DeviceAddress, + DeviceEndpoint, + PeiUsbDev->DeviceSpeed, + MaxPacketLength, + Data2, + DataLength, + &DataToggle, + Timeout, + &(PeiUsbDev->Translator), + &TransferResult + ); + } else { + Status = PeiUsbDev->UsbHcPpi->BulkTransfer ( + PeiServices, + PeiUsbDev->UsbHcPpi, + PeiUsbDev->DeviceAddress, + DeviceEndpoint, + (UINT8) MaxPacketLength, + Data, + DataLength, + &DataToggle, + Timeout, + &TransferResult + ); + } + + if (OldToggle != DataToggle) { + PeiUsbDev->DataToggle = (UINT8) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex)); + } + + return Status; +} + +/** + Get the usb interface descriptor. + + @param PeiServices General-purpose services that are available to every PEIM. + @param This Indicates the PEI_USB_IO_PPI instance. + @param InterfaceDescriptor Request interface descriptor. + + + @retval EFI_SUCCESS Usb interface descriptor is obtained successfully. + +**/ +EFI_STATUS +EFIAPI +PeiUsbGetInterfaceDescriptor ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *This, + OUT EFI_USB_INTERFACE_DESCRIPTOR **InterfaceDescriptor + ) +{ + PEI_USB_DEVICE *PeiUsbDev; + PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This); + *InterfaceDescriptor = PeiUsbDev->InterfaceDesc; + return EFI_SUCCESS; +} + +/** + Get the usb endpoint descriptor. + + @param PeiServices General-purpose services that are available to every PEIM. + @param This Indicates the PEI_USB_IO_PPI instance. + @param EndpointIndex The valid index of the specified endpoint. + @param EndpointDescriptor Request endpoint descriptor. + + @retval EFI_SUCCESS Usb endpoint descriptor is obtained successfully. + @retval EFI_NOT_FOUND Usb endpoint descriptor is NOT found. + +**/ +EFI_STATUS +EFIAPI +PeiUsbGetEndpointDescriptor ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *This, + IN UINT8 EndpointIndex, + OUT EFI_USB_ENDPOINT_DESCRIPTOR **EndpointDescriptor + ) +{ + PEI_USB_DEVICE *PeiUsbDev; + + PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This); + + ASSERT (EndpointDescriptor != NULL); + + // + // The valid range of EndpointIndex is 0..15 + // If EndpointIndex is lesser than 15 but larger than the number of interfaces, + // a EFI_NOT_FOUND should be returned + // + ASSERT (EndpointIndex <= 15); + + if (EndpointIndex >= PeiUsbDev->InterfaceDesc->NumEndpoints) { + return EFI_NOT_FOUND; + } + + *EndpointDescriptor = PeiUsbDev->EndpointDesc[EndpointIndex]; + + return EFI_SUCCESS; +} + +/** + Reset the port and re-configure the usb device. + + @param PeiServices General-purpose services that are available to every PEIM. + @param This Indicates the PEI_USB_IO_PPI instance. + + @retval EFI_SUCCESS Usb device is reset and configured successfully. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +EFIAPI +PeiUsbPortReset ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *This + ) +{ + PEI_USB_DEVICE *PeiUsbDev; + EFI_STATUS Status; + UINT8 Address; + + PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This); + + ResetRootPort ( + PeiServices, + PeiUsbDev->UsbHcPpi, + PeiUsbDev->Usb2HcPpi, + PeiUsbDev->DeviceAddress, + 0 + ); + + // + // Set address + // + Address = PeiUsbDev->DeviceAddress; + PeiUsbDev->DeviceAddress = 0; + + Status = PeiUsbSetDeviceAddress ( + PeiServices, + This, + Address + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + PeiUsbDev->DeviceAddress = Address; + + // + // Set default configuration + // + Status = PeiUsbSetConfiguration ( + PeiServices, + This + ); + + return Status; +} diff --git a/MdeModulePkg/Bus/Usb/UsbBusPei/UsbPeim.c b/MdeModulePkg/Bus/Usb/UsbBusPei/UsbPeim.c new file mode 100644 index 0000000..4a5d8e8 --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbBusPei/UsbPeim.c @@ -0,0 +1,1041 @@ +/** @file +The module to produce Usb Bus PPI. + +Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ +This program and the accompanying materials +are licensed and made available under the terms and conditions +of the BSD License which accompanies this distribution. The +full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include "UsbPeim.h" +#include "HubPeim.h" +#include "PeiUsbLib.h" + +// +// UsbIo PPI interface function +// +PEI_USB_IO_PPI mUsbIoPpi = { + PeiUsbControlTransfer, + PeiUsbBulkTransfer, + PeiUsbGetInterfaceDescriptor, + PeiUsbGetEndpointDescriptor, + PeiUsbPortReset +}; + +EFI_PEI_PPI_DESCRIPTOR mUsbIoPpiList = { + (EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST), + &gPeiUsbIoPpiGuid, + NULL +}; + +/** + The enumeration routine to detect device change. + + @param PeiServices Describes the list of possible PEI Services. + @param UsbHcPpi The pointer of PEI_USB_HOST_CONTROLLER_PPI instance. + @param Usb2HcPpi The pointer of PEI_USB2_HOST_CONTROLLER_PPI instance. + + @retval EFI_SUCCESS The usb is enumerated successfully. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiUsbEnumeration ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi, + IN PEI_USB2_HOST_CONTROLLER_PPI *Usb2HcPpi + ); + +/** + Configure new detected usb device. + + @param PeiServices Describes the list of possible PEI Services. + @param PeiUsbDevice The pointer of PEI_USB_DEVICE instance. + @param Port The port to be configured. + @param DeviceAddress The device address to be configured. + + @retval EFI_SUCCESS The new detected usb device is configured successfully. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiConfigureUsbDevice ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_DEVICE *PeiUsbDevice, + IN UINT8 Port, + IN OUT UINT8 *DeviceAddress + ); + +/** + Get all configurations from a detected usb device. + + @param PeiServices Describes the list of possible PEI Services. + @param PeiUsbDevice The pointer of PEI_USB_DEVICE instance. + + @retval EFI_SUCCESS The new detected usb device is configured successfully. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiUsbGetAllConfiguration ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_DEVICE *PeiUsbDevice + ); + +/** + Get the start position of next wanted descriptor. + + @param Buffer Buffer containing data to parse. + @param Length Buffer length. + @param DescType Descriptor type. + @param DescLength Descriptor length. + @param ParsedBytes Bytes has been parsed. + + @retval EFI_SUCCESS Get wanted descriptor successfully. + @retval EFI_DEVICE_ERROR Error occurred. + +**/ +EFI_STATUS +GetExpectedDescriptor ( + IN UINT8 *Buffer, + IN UINTN Length, + IN UINT8 DescType, + IN UINT8 DescLength, + OUT UINTN *ParsedBytes + ); + +/** + The entrypoint of the module, it will enumerate all HCs. + + @param FileHandle Handle of the file being invoked. + @param PeiServices Describes the list of possible PEI Services. + + @retval EFI_SUCCESS Usb initialization is done successfully. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. + @retval EFI_UNSUPPORTED Can't find required PPI. + +**/ +EFI_STATUS +EFIAPI +PeimInitializeUsb ( + IN EFI_PEI_FILE_HANDLE FileHandle, + IN CONST EFI_PEI_SERVICES **PeiServices + ) +{ + EFI_STATUS Status; + UINTN Index; + PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi; + PEI_USB2_HOST_CONTROLLER_PPI *Usb2HcPpi; + + if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) { + return EFI_SUCCESS; + } + + // + // gPeiUsbHostControllerPpiGuid and gPeiUsb2HostControllerPpiGuid should not + // be produced at the same time + // + Index = 0; + while (TRUE) { + // + // Get UsbHcPpi at first. + // + Status = PeiServicesLocatePpi ( + &gPeiUsbHostControllerPpiGuid, + Index, + NULL, + (VOID **) &UsbHcPpi + ); + if (EFI_ERROR (Status)) { + // + // No more host controller, break out + // + break; + } + PeiUsbEnumeration ((EFI_PEI_SERVICES **) PeiServices, UsbHcPpi, NULL); + Index++; + } + + if (Index == 0) { + // + // Then try to get Usb2HcPpi. + // + while (TRUE) { + Status = PeiServicesLocatePpi ( + &gPeiUsb2HostControllerPpiGuid, + Index, + NULL, + (VOID **) &Usb2HcPpi + ); + if (EFI_ERROR (Status)) { + // + // No more host controller, break out + // + break; + } + PeiUsbEnumeration ((EFI_PEI_SERVICES **) PeiServices, NULL, Usb2HcPpi); + Index++; + } + } + + if (Index == 0) { + return EFI_UNSUPPORTED; + } + + return EFI_SUCCESS; +} + +/** + The Hub Enumeration just scans the hub ports one time. It also + doesn't support hot-plug. + + @param PeiServices Describes the list of possible PEI Services. + @param PeiUsbDevice The pointer of PEI_USB_DEVICE instance. + @param CurrentAddress The DeviceAddress of usb device. + + @retval EFI_SUCCESS The usb hub is enumerated successfully. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiHubEnumeration ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_DEVICE *PeiUsbDevice, + IN UINT8 *CurrentAddress + ) +{ + UINTN Index; + EFI_STATUS Status; + PEI_USB_IO_PPI *UsbIoPpi; + EFI_USB_PORT_STATUS PortStatus; + UINTN MemPages; + EFI_PHYSICAL_ADDRESS AllocateAddress; + PEI_USB_DEVICE *NewPeiUsbDevice; + + + UsbIoPpi = &PeiUsbDevice->UsbIoPpi; + + for (Index = 0; Index < PeiUsbDevice->DownStreamPortNo; Index++) { + + Status = PeiHubGetPortStatus ( + PeiServices, + UsbIoPpi, + (UINT8) (Index + 1), + (UINT32 *) &PortStatus + ); + + if (EFI_ERROR (Status)) { + continue; + } + + if (IsPortConnectChange (PortStatus.PortChangeStatus)) { + PeiHubClearPortFeature ( + PeiServices, + UsbIoPpi, + (UINT8) (Index + 1), + EfiUsbPortConnectChange + ); + + MicroSecondDelay (100 * 1000); + + if (IsPortConnect (PortStatus.PortStatus)) { + + PeiHubGetPortStatus ( + PeiServices, + UsbIoPpi, + (UINT8) (Index + 1), + (UINT32 *) &PortStatus + ); + + // + // Begin to deal with the new device + // + MemPages = sizeof (PEI_USB_DEVICE) / EFI_PAGE_SIZE + 1; + Status = PeiServicesAllocatePages ( + EfiBootServicesCode, + MemPages, + &AllocateAddress + ); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + + NewPeiUsbDevice = (PEI_USB_DEVICE *) ((UINTN) AllocateAddress); + ZeroMem (NewPeiUsbDevice, sizeof (PEI_USB_DEVICE)); + + NewPeiUsbDevice->Signature = PEI_USB_DEVICE_SIGNATURE; + NewPeiUsbDevice->DeviceAddress = 0; + NewPeiUsbDevice->MaxPacketSize0 = 8; + NewPeiUsbDevice->DataToggle = 0; + CopyMem ( + &(NewPeiUsbDevice->UsbIoPpi), + &mUsbIoPpi, + sizeof (PEI_USB_IO_PPI) + ); + CopyMem ( + &(NewPeiUsbDevice->UsbIoPpiList), + &mUsbIoPpiList, + sizeof (EFI_PEI_PPI_DESCRIPTOR) + ); + NewPeiUsbDevice->UsbIoPpiList.Ppi = &NewPeiUsbDevice->UsbIoPpi; + NewPeiUsbDevice->AllocateAddress = (UINTN) AllocateAddress; + NewPeiUsbDevice->UsbHcPpi = PeiUsbDevice->UsbHcPpi; + NewPeiUsbDevice->Usb2HcPpi = PeiUsbDevice->Usb2HcPpi; + NewPeiUsbDevice->IsHub = 0x0; + NewPeiUsbDevice->DownStreamPortNo = 0x0; + + PeiResetHubPort (PeiServices, UsbIoPpi, (UINT8)(Index + 1)); + + PeiHubGetPortStatus ( + PeiServices, + UsbIoPpi, + (UINT8) (Index + 1), + (UINT32 *) &PortStatus + ); + + NewPeiUsbDevice->DeviceSpeed = (UINT8)IsPortLowSpeedDeviceAttached (PortStatus.PortStatus); + + if(NewPeiUsbDevice->DeviceSpeed != EFI_USB_SPEED_HIGH) { + if (PeiUsbDevice->DeviceSpeed == EFI_USB_SPEED_HIGH) { + NewPeiUsbDevice->Translator.TranslatorPortNumber = (UINT8)Index; + NewPeiUsbDevice->Translator.TranslatorHubAddress = *CurrentAddress; + } else { + CopyMem(&(NewPeiUsbDevice->Translator), &(PeiUsbDevice->Translator), sizeof(EFI_USB2_HC_TRANSACTION_TRANSLATOR)); + } + } + + // + // Configure that Usb Device + // + Status = PeiConfigureUsbDevice ( + PeiServices, + NewPeiUsbDevice, + (UINT8) (Index + 1), + CurrentAddress + ); + + if (EFI_ERROR (Status)) { + continue; + } + + Status = PeiServicesInstallPpi (&NewPeiUsbDevice->UsbIoPpiList); + + if (NewPeiUsbDevice->InterfaceDesc->InterfaceClass == 0x09) { + NewPeiUsbDevice->IsHub = 0x1; + + Status = PeiDoHubConfig (PeiServices, NewPeiUsbDevice); + if (EFI_ERROR (Status)) { + return Status; + } + + PeiHubEnumeration (PeiServices, NewPeiUsbDevice, CurrentAddress); + } + } + + } + } + + + return EFI_SUCCESS; +} + +/** + The enumeration routine to detect device change. + + @param PeiServices Describes the list of possible PEI Services. + @param UsbHcPpi The pointer of PEI_USB_HOST_CONTROLLER_PPI instance. + @param Usb2HcPpi The pointer of PEI_USB2_HOST_CONTROLLER_PPI instance. + + @retval EFI_SUCCESS The usb is enumerated successfully. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiUsbEnumeration ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi, + IN PEI_USB2_HOST_CONTROLLER_PPI *Usb2HcPpi + ) +{ + UINT8 NumOfRootPort; + EFI_STATUS Status; + UINT8 Index; + EFI_USB_PORT_STATUS PortStatus; + PEI_USB_DEVICE *PeiUsbDevice; + UINTN MemPages; + EFI_PHYSICAL_ADDRESS AllocateAddress; + UINT8 CurrentAddress; + + + CurrentAddress = 0; + if (Usb2HcPpi != NULL){ + Usb2HcPpi->GetRootHubPortNumber ( + PeiServices, + Usb2HcPpi, + (UINT8 *) &NumOfRootPort + ); + } else { + UsbHcPpi->GetRootHubPortNumber ( + PeiServices, + UsbHcPpi, + (UINT8 *) &NumOfRootPort + ); + } + + for (Index = 0; Index < NumOfRootPort; Index++) { + // + // First get root port status to detect changes happen + // + if (Usb2HcPpi != NULL) { + Usb2HcPpi->GetRootHubPortStatus ( + PeiServices, + Usb2HcPpi, + (UINT8) Index, + &PortStatus + ); + } else { + UsbHcPpi->GetRootHubPortStatus ( + PeiServices, + UsbHcPpi, + (UINT8) Index, + &PortStatus + ); + } + DEBUG ((EFI_D_INFO, "USB Status --- ConnectChange[%04x] Status[%04x]\n", PortStatus.PortChangeStatus, PortStatus.PortStatus)); + if (IsPortConnectChange (PortStatus.PortChangeStatus)) { + // + // Changes happen, first clear this change status + // + if (Usb2HcPpi != NULL) { + Usb2HcPpi->ClearRootHubPortFeature ( + PeiServices, + Usb2HcPpi, + (UINT8) Index, + EfiUsbPortConnectChange + ); + } else { + UsbHcPpi->ClearRootHubPortFeature ( + PeiServices, + UsbHcPpi, + (UINT8) Index, + EfiUsbPortConnectChange + ); + } + MicroSecondDelay (100 * 1000); + + if (IsPortConnect (PortStatus.PortStatus)) { + if (Usb2HcPpi != NULL) { + Usb2HcPpi->GetRootHubPortStatus ( + PeiServices, + Usb2HcPpi, + (UINT8) Index, + &PortStatus + ); + } else { + UsbHcPpi->GetRootHubPortStatus ( + PeiServices, + UsbHcPpi, + (UINT8) Index, + &PortStatus + ); + } + + // + // Connect change happen + // + MemPages = sizeof (PEI_USB_DEVICE) / EFI_PAGE_SIZE + 1; + Status = PeiServicesAllocatePages ( + EfiBootServicesCode, + MemPages, + &AllocateAddress + ); + if (EFI_ERROR (Status)) { + return EFI_OUT_OF_RESOURCES; + } + + PeiUsbDevice = (PEI_USB_DEVICE *) ((UINTN) AllocateAddress); + ZeroMem (PeiUsbDevice, sizeof (PEI_USB_DEVICE)); + + PeiUsbDevice->Signature = PEI_USB_DEVICE_SIGNATURE; + PeiUsbDevice->DeviceAddress = 0; + PeiUsbDevice->MaxPacketSize0 = 8; + PeiUsbDevice->DataToggle = 0; + CopyMem ( + &(PeiUsbDevice->UsbIoPpi), + &mUsbIoPpi, + sizeof (PEI_USB_IO_PPI) + ); + CopyMem ( + &(PeiUsbDevice->UsbIoPpiList), + &mUsbIoPpiList, + sizeof (EFI_PEI_PPI_DESCRIPTOR) + ); + PeiUsbDevice->UsbIoPpiList.Ppi = &PeiUsbDevice->UsbIoPpi; + PeiUsbDevice->AllocateAddress = (UINTN) AllocateAddress; + PeiUsbDevice->UsbHcPpi = UsbHcPpi; + PeiUsbDevice->Usb2HcPpi = Usb2HcPpi; + PeiUsbDevice->IsHub = 0x0; + PeiUsbDevice->DownStreamPortNo = 0x0; + + ResetRootPort ( + PeiServices, + PeiUsbDevice->UsbHcPpi, + PeiUsbDevice->Usb2HcPpi, + Index, + 0 + ); + + if (Usb2HcPpi != NULL) { + Usb2HcPpi->GetRootHubPortStatus ( + PeiServices, + Usb2HcPpi, + (UINT8) Index, + &PortStatus + ); + } else { + UsbHcPpi->GetRootHubPortStatus ( + PeiServices, + UsbHcPpi, + (UINT8) Index, + &PortStatus + ); + } + + PeiUsbDevice->DeviceSpeed = (UINT8)IsPortLowSpeedDeviceAttached (PortStatus.PortStatus); + DEBUG ((EFI_D_INFO, "Device Speed =%d\n", PeiUsbDevice->DeviceSpeed)); + + // + // Configure that Usb Device + // + Status = PeiConfigureUsbDevice ( + PeiServices, + PeiUsbDevice, + Index, + &CurrentAddress + ); + + if (EFI_ERROR (Status)) { + continue; + } + DEBUG ((EFI_D_INFO, "PeiConfigureUsbDevice Success\n")); + + Status = PeiServicesInstallPpi (&PeiUsbDevice->UsbIoPpiList); + + if (PeiUsbDevice->InterfaceDesc->InterfaceClass == 0x09) { + PeiUsbDevice->IsHub = 0x1; + + Status = PeiDoHubConfig (PeiServices, PeiUsbDevice); + if (EFI_ERROR (Status)) { + return Status; + } + + PeiHubEnumeration (PeiServices, PeiUsbDevice, &CurrentAddress); + } + } else { + // + // Disconnect change happen, currently we don't support + // + } + } + } + + return EFI_SUCCESS; +} + +/** + Configure new detected usb device. + + @param PeiServices Describes the list of possible PEI Services. + @param PeiUsbDevice The pointer of PEI_USB_DEVICE instance. + @param Port The port to be configured. + @param DeviceAddress The device address to be configured. + + @retval EFI_SUCCESS The new detected usb device is configured successfully. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiConfigureUsbDevice ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_DEVICE *PeiUsbDevice, + IN UINT8 Port, + IN OUT UINT8 *DeviceAddress + ) +{ + EFI_USB_DEVICE_DESCRIPTOR DeviceDescriptor; + EFI_STATUS Status; + PEI_USB_IO_PPI *UsbIoPpi; + UINT8 Retry; + + UsbIoPpi = &PeiUsbDevice->UsbIoPpi; + Status = EFI_SUCCESS; + ZeroMem (&DeviceDescriptor, sizeof (EFI_USB_DEVICE_DESCRIPTOR)); + // + // Get USB device descriptor + // + + for (Retry = 0; Retry < 3; Retry ++) { + + PeiUsbDevice->MaxPacketSize0 = 8; + + Status = PeiUsbGetDescriptor ( + PeiServices, + UsbIoPpi, + (USB_DT_DEVICE << 8), + 0, + 8, + &DeviceDescriptor + ); + + if (!EFI_ERROR (Status)) { + DEBUG ((EFI_D_INFO, "PeiUsbGet Device Descriptor the %d time Sucess\n", Retry)); + break; + } + } + + if (Retry == 3) { + DEBUG ((EFI_D_ERROR, "PeiUsbGet Device Descriptor fail\n", Retry)); + return Status; + } + + PeiUsbDevice->MaxPacketSize0 = DeviceDescriptor.MaxPacketSize0; + + (*DeviceAddress) ++; + + Status = PeiUsbSetDeviceAddress ( + PeiServices, + UsbIoPpi, + *DeviceAddress + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "PeiUsbSetDeviceAddress Failed\n")); + return Status; + } + + PeiUsbDevice->DeviceAddress = *DeviceAddress; + + // + // Get whole USB device descriptor + // + Status = PeiUsbGetDescriptor ( + PeiServices, + UsbIoPpi, + (USB_DT_DEVICE << 8), + 0, + (UINT16) sizeof (EFI_USB_DEVICE_DESCRIPTOR), + &DeviceDescriptor + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "PeiUsbGetDescriptor First Failed\n")); + return Status; + } + // + // Get its default configuration and its first interface + // + Status = PeiUsbGetAllConfiguration ( + PeiServices, + PeiUsbDevice + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + Status = PeiUsbSetConfiguration ( + PeiServices, + UsbIoPpi + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + return EFI_SUCCESS; +} + +/** + Get all configurations from a detected usb device. + + @param PeiServices Describes the list of possible PEI Services. + @param PeiUsbDevice The pointer of PEI_USB_DEVICE instance. + + @retval EFI_SUCCESS The new detected usb device is configured successfully. + @retval EFI_OUT_OF_RESOURCES Can't allocate memory resource. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +PeiUsbGetAllConfiguration ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_DEVICE *PeiUsbDevice + ) +{ + EFI_STATUS Status; + EFI_USB_CONFIG_DESCRIPTOR *ConfigDesc; + PEI_USB_IO_PPI *UsbIoPpi; + UINT16 ConfigDescLength; + UINT8 *Ptr; + UINTN SkipBytes; + UINTN LengthLeft; + UINTN Index; + UINTN NumOfEndpoint; + + UsbIoPpi = &PeiUsbDevice->UsbIoPpi; + + // + // First get its 4-byte configuration descriptor + // + Status = PeiUsbGetDescriptor ( + PeiServices, + UsbIoPpi, + (USB_DT_CONFIG << 8), // Value + 0, // Index + 4, // Length + PeiUsbDevice->ConfigurationData + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "PeiUsbGet Config Descriptor First Failed\n")); + return Status; + } + + ConfigDesc = (EFI_USB_CONFIG_DESCRIPTOR *) PeiUsbDevice->ConfigurationData; + ConfigDescLength = ConfigDesc->TotalLength; + + // + // Then we get the total descriptors for this configuration + // + Status = PeiUsbGetDescriptor ( + PeiServices, + UsbIoPpi, + (USB_DT_CONFIG << 8), + 0, + ConfigDescLength, + PeiUsbDevice->ConfigurationData + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "PeiUsbGet Config Descriptor all Failed\n")); + return Status; + } + // + // Parse this configuration descriptor + // First get the current config descriptor; + // + Status = GetExpectedDescriptor ( + PeiUsbDevice->ConfigurationData, + ConfigDescLength, + USB_DT_CONFIG, + (UINT8) sizeof (EFI_USB_CONFIG_DESCRIPTOR), + &SkipBytes + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + Ptr = PeiUsbDevice->ConfigurationData + SkipBytes; + PeiUsbDevice->ConfigDesc = (EFI_USB_CONFIG_DESCRIPTOR *) Ptr; + + Ptr += sizeof (EFI_USB_CONFIG_DESCRIPTOR); + LengthLeft = ConfigDescLength - SkipBytes - sizeof (EFI_USB_CONFIG_DESCRIPTOR); + + // + // Get the first interface descriptor + // + Status = GetExpectedDescriptor ( + Ptr, + LengthLeft, + USB_DT_INTERFACE, + (UINT8) sizeof (EFI_USB_INTERFACE_DESCRIPTOR), + &SkipBytes + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + Ptr += SkipBytes; + PeiUsbDevice->InterfaceDesc = (EFI_USB_INTERFACE_DESCRIPTOR *) Ptr; + + Ptr += sizeof (EFI_USB_INTERFACE_DESCRIPTOR); + LengthLeft -= SkipBytes; + LengthLeft -= sizeof (EFI_USB_INTERFACE_DESCRIPTOR); + + // + // Parse all the endpoint descriptor within this interface + // + NumOfEndpoint = PeiUsbDevice->InterfaceDesc->NumEndpoints; + ASSERT (NumOfEndpoint <= MAX_ENDPOINT); + + for (Index = 0; Index < NumOfEndpoint; Index++) { + // + // Get the endpoint descriptor + // + Status = GetExpectedDescriptor ( + Ptr, + LengthLeft, + USB_DT_ENDPOINT, + (UINT8) sizeof (EFI_USB_ENDPOINT_DESCRIPTOR), + &SkipBytes + ); + + if (EFI_ERROR (Status)) { + return Status; + } + + Ptr += SkipBytes; + PeiUsbDevice->EndpointDesc[Index] = (EFI_USB_ENDPOINT_DESCRIPTOR *) Ptr; + + Ptr += sizeof (EFI_USB_ENDPOINT_DESCRIPTOR); + LengthLeft -= SkipBytes; + LengthLeft -= sizeof (EFI_USB_ENDPOINT_DESCRIPTOR); + } + + return EFI_SUCCESS; +} + +/** + Get the start position of next wanted descriptor. + + @param Buffer Buffer containing data to parse. + @param Length Buffer length. + @param DescType Descriptor type. + @param DescLength Descriptor length. + @param ParsedBytes Bytes has been parsed. + + @retval EFI_SUCCESS Get wanted descriptor successfully. + @retval EFI_DEVICE_ERROR Error occurred. + +**/ +EFI_STATUS +GetExpectedDescriptor ( + IN UINT8 *Buffer, + IN UINTN Length, + IN UINT8 DescType, + IN UINT8 DescLength, + OUT UINTN *ParsedBytes + ) +{ + UINT16 DescriptorHeader; + UINT8 Len; + UINT8 *Ptr; + UINTN Parsed; + + Parsed = 0; + Ptr = Buffer; + + while (TRUE) { + // + // Buffer length should not less than Desc length + // + if (Length < DescLength) { + return EFI_DEVICE_ERROR; + } + + DescriptorHeader = (UINT16) (*Ptr + ((*(Ptr + 1)) << 8)); + + Len = Buffer[0]; + + // + // Check to see if it is a start of expected descriptor + // + if (DescriptorHeader == ((DescType << 8) | DescLength)) { + break; + } + + if ((UINT8) (DescriptorHeader >> 8) == DescType) { + if (Len > DescLength) { + return EFI_DEVICE_ERROR; + } + } + // + // Descriptor length should be at least 2 + // and should not exceed the buffer length + // + if (Len < 2) { + return EFI_DEVICE_ERROR; + } + + if (Len > Length) { + return EFI_DEVICE_ERROR; + } + // + // Skip this mismatch descriptor + // + Length -= Len; + Ptr += Len; + Parsed += Len; + } + + *ParsedBytes = Parsed; + + return EFI_SUCCESS; +} + +/** + Send reset signal over the given root hub port. + + @param PeiServices Describes the list of possible PEI Services. + @param UsbHcPpi The pointer of PEI_USB_HOST_CONTROLLER_PPI instance. + @param Usb2HcPpi The pointer of PEI_USB2_HOST_CONTROLLER_PPI instance. + @param PortNum The port to be reset. + @param RetryIndex The retry times. + +**/ +VOID +ResetRootPort ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi, + IN PEI_USB2_HOST_CONTROLLER_PPI *Usb2HcPpi, + IN UINT8 PortNum, + IN UINT8 RetryIndex + ) +{ + EFI_STATUS Status; + + + if (Usb2HcPpi != NULL) { + MicroSecondDelay (200 * 1000); + + // + // reset root port + // + Status = Usb2HcPpi->SetRootHubPortFeature ( + PeiServices, + Usb2HcPpi, + PortNum, + EfiUsbPortReset + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "SetRootHubPortFeature EfiUsbPortReset Failed\n")); + return; + } + + MicroSecondDelay (200 * 1000); + + // + // clear reset root port + // + Status = Usb2HcPpi->ClearRootHubPortFeature ( + PeiServices, + Usb2HcPpi, + PortNum, + EfiUsbPortReset + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ClearRootHubPortFeature EfiUsbPortReset Failed\n")); + return; + } + + MicroSecondDelay (1 * 1000); + + Usb2HcPpi->ClearRootHubPortFeature ( + PeiServices, + Usb2HcPpi, + PortNum, + EfiUsbPortConnectChange + ); + + // + // Set port enable + // + Usb2HcPpi->SetRootHubPortFeature( + PeiServices, + Usb2HcPpi, + PortNum, + EfiUsbPortEnable + ); + + Usb2HcPpi->ClearRootHubPortFeature ( + PeiServices, + Usb2HcPpi, + PortNum, + EfiUsbPortEnableChange + ); + + MicroSecondDelay ((RetryIndex + 1) * 50 * 1000); + } else { + MicroSecondDelay (200 * 1000); + + // + // reset root port + // + Status = UsbHcPpi->SetRootHubPortFeature ( + PeiServices, + UsbHcPpi, + PortNum, + EfiUsbPortReset + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "SetRootHubPortFeature EfiUsbPortReset Failed\n")); + return; + } + + MicroSecondDelay (200 * 1000); + + // + // clear reset root port + // + Status = UsbHcPpi->ClearRootHubPortFeature ( + PeiServices, + UsbHcPpi, + PortNum, + EfiUsbPortReset + ); + + if (EFI_ERROR (Status)) { + DEBUG ((EFI_D_ERROR, "ClearRootHubPortFeature EfiUsbPortReset Failed\n")); + return; + } + + MicroSecondDelay (1 * 1000); + + UsbHcPpi->ClearRootHubPortFeature ( + PeiServices, + UsbHcPpi, + PortNum, + EfiUsbPortConnectChange + ); + + // + // Set port enable + // + UsbHcPpi->SetRootHubPortFeature( + PeiServices, + UsbHcPpi, + PortNum, + EfiUsbPortEnable + ); + + UsbHcPpi->ClearRootHubPortFeature ( + PeiServices, + UsbHcPpi, + PortNum, + EfiUsbPortEnableChange + ); + + MicroSecondDelay ((RetryIndex + 1) * 50 * 1000); + } + return; +} + + diff --git a/MdeModulePkg/Bus/Usb/UsbBusPei/UsbPeim.h b/MdeModulePkg/Bus/Usb/UsbBusPei/UsbPeim.h new file mode 100644 index 0000000..c9e75ba --- /dev/null +++ b/MdeModulePkg/Bus/Usb/UsbBusPei/UsbPeim.h @@ -0,0 +1,203 @@ +/** @file +Usb Peim definition. + +Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ +This program and the accompanying materials +are licensed and made available under the terms and conditions +of the BSD License which accompanies this distribution. The +full text of the license may be found at +http://opensource.org/licenses/bsd-license.php + +THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _PEI_USB_PEIM_H_ +#define _PEI_USB_PEIM_H_ + + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include + +#define MAX_ROOT_PORT 2 +#define MAX_ENDPOINT 16 + +#define USB_SLOW_SPEED_DEVICE 0x01 +#define USB_FULL_SPEED_DEVICE 0x02 + +#define PEI_USB_DEVICE_SIGNATURE SIGNATURE_32 ('U', 's', 'b', 'D') +typedef struct { + UINTN Signature; + PEI_USB_IO_PPI UsbIoPpi; + EFI_PEI_PPI_DESCRIPTOR UsbIoPpiList; + UINT8 DeviceAddress; + UINT8 MaxPacketSize0; + UINT8 DeviceSpeed; + UINT8 DataToggle; + UINT8 IsHub; + UINT8 DownStreamPortNo; + UINT8 Reserved[2]; // Padding for IPF + UINTN AllocateAddress; + PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi; + PEI_USB2_HOST_CONTROLLER_PPI *Usb2HcPpi; + UINT8 ConfigurationData[1024]; + EFI_USB_CONFIG_DESCRIPTOR *ConfigDesc; + EFI_USB_INTERFACE_DESCRIPTOR *InterfaceDesc; + EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDesc[MAX_ENDPOINT]; + EFI_USB2_HC_TRANSACTION_TRANSLATOR Translator; +} PEI_USB_DEVICE; + +#define PEI_USB_DEVICE_FROM_THIS(a) CR (a, PEI_USB_DEVICE, UsbIoPpi, PEI_USB_DEVICE_SIGNATURE) + + +/** + Submits control transfer to a target USB device. + + @param PeiServices The pointer of EFI_PEI_SERVICES. + @param This The pointer of PEI_USB_IO_PPI. + @param Request USB device request to send. + @param Direction Specifies the data direction for the data stage. + @param Timeout Indicates the maximum timeout, in millisecond. + @param Data Data buffer to be transmitted or received from USB device. + @param DataLength The size (in bytes) of the data buffer. + + @retval EFI_SUCCESS Transfer was completed successfully. + @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources. + @retval EFI_INVALID_PARAMETER Some parameters are invalid. + @retval EFI_TIMEOUT Transfer failed due to timeout. + @retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error. + +**/ +EFI_STATUS +EFIAPI +PeiUsbControlTransfer ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *This, + IN EFI_USB_DEVICE_REQUEST *Request, + IN EFI_USB_DATA_DIRECTION Direction, + IN UINT32 Timeout, + IN OUT VOID *Data, OPTIONAL + IN UINTN DataLength OPTIONAL + ); + +/** + Submits bulk transfer to a bulk endpoint of a USB device. + + @param PeiServices The pointer of EFI_PEI_SERVICES. + @param This The pointer of PEI_USB_IO_PPI. + @param DeviceEndpoint Endpoint number and its direction in bit 7. + @param Data A pointer to the buffer of data to transmit + from or receive into. + @param DataLength The lenght of the data buffer. + @param Timeout Indicates the maximum time, in millisecond, which the + transfer is allowed to complete. + + @retval EFI_SUCCESS The transfer was completed successfully. + @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource. + @retval EFI_INVALID_PARAMETER Parameters are invalid. + @retval EFI_TIMEOUT The transfer failed due to timeout. + @retval EFI_DEVICE_ERROR The transfer failed due to host controller error. + +**/ +EFI_STATUS +EFIAPI +PeiUsbBulkTransfer ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *This, + IN UINT8 DeviceEndpoint, + IN OUT VOID *Data, + IN OUT UINTN *DataLength, + IN UINTN Timeout + ); + +/** + Get the usb interface descriptor. + + @param PeiServices General-purpose services that are available to every PEIM. + @param This Indicates the PEI_USB_IO_PPI instance. + @param InterfaceDescriptor Request interface descriptor. + + + @retval EFI_SUCCESS Usb interface descriptor is obtained successfully. + +**/ +EFI_STATUS +EFIAPI +PeiUsbGetInterfaceDescriptor ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *This, + OUT EFI_USB_INTERFACE_DESCRIPTOR **InterfaceDescriptor + ); + +/** + Get the usb endpoint descriptor. + + @param PeiServices General-purpose services that are available to every PEIM. + @param This Indicates the PEI_USB_IO_PPI instance. + @param EndpointIndex The valid index of the specified endpoint. + @param EndpointDescriptor Request endpoint descriptor. + + @retval EFI_SUCCESS Usb endpoint descriptor is obtained successfully. + @retval EFI_NOT_FOUND Usb endpoint descriptor is NOT found. + +**/ +EFI_STATUS +EFIAPI +PeiUsbGetEndpointDescriptor ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *This, + IN UINT8 EndpointIndex, + OUT EFI_USB_ENDPOINT_DESCRIPTOR **EndpointDescriptor + ); + +/** + Reset the port and re-configure the usb device. + + @param PeiServices General-purpose services that are available to every PEIM. + @param This Indicates the PEI_USB_IO_PPI instance. + + @retval EFI_SUCCESS Usb device is reset and configured successfully. + @retval Others Other failure occurs. + +**/ +EFI_STATUS +EFIAPI +PeiUsbPortReset ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_IO_PPI *This + ); + +/** + Send reset signal over the given root hub port. + + @param PeiServices Describes the list of possible PEI Services. + @param UsbHcPpi The pointer of PEI_USB_HOST_CONTROLLER_PPI instance. + @param Usb2HcPpi The pointer of PEI_USB2_HOST_CONTROLLER_PPI instance. + @param PortNum The port to be reset. + @param RetryIndex The retry times. + +**/ +VOID +ResetRootPort ( + IN EFI_PEI_SERVICES **PeiServices, + IN PEI_USB_HOST_CONTROLLER_PPI *UsbHcPpi, + IN PEI_USB2_HOST_CONTROLLER_PPI *Usb2HcPpi, + IN UINT8 PortNum, + IN UINT8 RetryIndex + ); + +#endif -- cgit v1.1