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
This commit is contained in:
325
MdeModulePkg/Bus/Usb/UsbBusPei/UsbIoPeim.c
Normal file
325
MdeModulePkg/Bus/Usb/UsbBusPei/UsbIoPeim.c
Normal file
@@ -0,0 +1,325 @@
|
||||
/** @file
|
||||
The module is used to implement Usb Io PPI interfaces.
|
||||
|
||||
Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved. <BR>
|
||||
|
||||
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;
|
||||
}
|
Reference in New Issue
Block a user