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:
jljusten
2011-06-27 23:30:55 +00:00
parent 366f81a016
commit 4b1bf81c20
36 changed files with 15879 additions and 0 deletions

View File

@@ -0,0 +1,401 @@
/** @file
BOT Transportation implementation.
Copyright (c) 2006, 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 "UsbBotPeim.h"
#include "BotPeim.h"
#include "PeiUsbLib.h"
/**
Reset the given usb device.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDev The instance to PEI_BOT_DEVICE.
@retval EFI_INVALID_PARAMETER Can not get usb io ppi.
@retval EFI_SUCCESS Failed to reset the given usb device.
**/
EFI_STATUS
BotRecoveryReset (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDev
)
{
EFI_USB_DEVICE_REQUEST DevReq;
UINT32 Timeout;
PEI_USB_IO_PPI *UsbIoPpi;
UINT8 EndpointAddr;
EFI_STATUS Status;
UsbIoPpi = PeiBotDev->UsbIoPpi;
if (UsbIoPpi == NULL) {
return EFI_INVALID_PARAMETER;
}
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
DevReq.RequestType = 0x21;
DevReq.Request = 0xFF;
DevReq.Value = 0;
DevReq.Index = 0;
DevReq.Length = 0;
Timeout = 3000;
Status = UsbIoPpi->UsbControlTransfer (
PeiServices,
UsbIoPpi,
&DevReq,
EfiUsbNoData,
Timeout,
NULL,
0
);
//
// clear bulk in endpoint stall feature
//
EndpointAddr = (PeiBotDev->BulkInEndpoint)->EndpointAddress;
PeiUsbClearEndpointHalt (PeiServices, UsbIoPpi, EndpointAddr);
//
// clear bulk out endpoint stall feature
//
EndpointAddr = (PeiBotDev->BulkOutEndpoint)->EndpointAddress;
PeiUsbClearEndpointHalt (PeiServices, UsbIoPpi, EndpointAddr);
return Status;
}
/**
Send the command to the device using Bulk-Out endpoint.
This function sends the command to the device using Bulk-Out endpoint.
BOT transfer is composed of three phases: Command, Data, and Status.
This is the Command phase.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDev The instance to PEI_BOT_DEVICE.
@param Command The command to transfer to device.
@param CommandSize The length of the command.
@param DataTransferLength The expected length of the data.
@param Direction The direction of the data.
@param Timeout Indicates the maximum time, in millisecond, which the
transfer is allowed to complete.
@retval EFI_DEVICE_ERROR Successful to send the command to device.
@retval EFI_SUCCESS Failed to send the command to device.
**/
EFI_STATUS
BotCommandPhase (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDev,
IN VOID *Command,
IN UINT8 CommandSize,
IN UINT32 DataTransferLength,
IN EFI_USB_DATA_DIRECTION Direction,
IN UINT16 Timeout
)
{
CBW Cbw;
EFI_STATUS Status;
PEI_USB_IO_PPI *UsbIoPpi;
UINTN DataSize;
UsbIoPpi = PeiBotDev->UsbIoPpi;
ZeroMem (&Cbw, sizeof (CBW));
//
// Fill the command block, detailed see BOT spec
//
Cbw.Signature = CBWSIG;
Cbw.Tag = 0x01;
Cbw.DataTransferLength = DataTransferLength;
Cbw.Flags = (UINT8) ((Direction == EfiUsbDataIn) ? 0x80 : 0);
Cbw.Lun = 0;
Cbw.CmdLen = CommandSize;
CopyMem (Cbw.CmdBlock, Command, CommandSize);
DataSize = sizeof (CBW);
Status = UsbIoPpi->UsbBulkTransfer (
PeiServices,
UsbIoPpi,
(PeiBotDev->BulkOutEndpoint)->EndpointAddress,
(UINT8 *) &Cbw,
&DataSize,
Timeout
);
if (EFI_ERROR (Status)) {
//
// Command phase fail, we need to recovery reset this device
//
BotRecoveryReset (PeiServices, PeiBotDev);
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
/**
Transfer the data between the device and host.
This function transfers the data between the device and host.
BOT transfer is composed of three phases: Command, Data, and Status.
This is the Data phase.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDev The instance to PEI_BOT_DEVICE.
@param DataSize The length of the data.
@param DataBuffer The pointer to the data.
@param Direction The direction of the data.
@param Timeout Indicates the maximum time, in millisecond, which the
transfer is allowed to complete.
@retval EFI_DEVICE_ERROR Successful to send the data to device.
@retval EFI_SUCCESS Failed to send the data to device.
**/
EFI_STATUS
BotDataPhase (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDev,
IN UINT32 *DataSize,
IN OUT VOID *DataBuffer,
IN EFI_USB_DATA_DIRECTION Direction,
IN UINT16 Timeout
)
{
EFI_STATUS Status;
PEI_USB_IO_PPI *UsbIoPpi;
UINT8 EndpointAddr;
UINTN Remain;
UINTN Increment;
UINT32 MaxPacketLen;
UINT8 *BufferPtr;
UINTN TransferredSize;
UsbIoPpi = PeiBotDev->UsbIoPpi;
Remain = *DataSize;
BufferPtr = (UINT8 *) DataBuffer;
TransferredSize = 0;
//
// retrieve the the max packet length of the given endpoint
//
if (Direction == EfiUsbDataIn) {
MaxPacketLen = (PeiBotDev->BulkInEndpoint)->MaxPacketSize;
EndpointAddr = (PeiBotDev->BulkInEndpoint)->EndpointAddress;
} else {
MaxPacketLen = (PeiBotDev->BulkOutEndpoint)->MaxPacketSize;
EndpointAddr = (PeiBotDev->BulkOutEndpoint)->EndpointAddress;
}
while (Remain > 0) {
//
// Using 15 packets to avoid Bitstuff error
//
if (Remain > 16 * MaxPacketLen) {
Increment = 16 * MaxPacketLen;
} else {
Increment = Remain;
}
Status = UsbIoPpi->UsbBulkTransfer (
PeiServices,
UsbIoPpi,
EndpointAddr,
BufferPtr,
&Increment,
Timeout
);
TransferredSize += Increment;
if (EFI_ERROR (Status)) {
PeiUsbClearEndpointHalt (PeiServices, UsbIoPpi, EndpointAddr);
return Status;
}
BufferPtr += Increment;
Remain -= Increment;
}
*DataSize = (UINT32) TransferredSize;
return EFI_SUCCESS;
}
/**
Get the command execution status from device.
This function gets the command execution status from device.
BOT transfer is composed of three phases: Command, Data, and Status.
This is the Status phase.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDev The instance to PEI_BOT_DEVICE.
@param TransferStatus The status of the transaction.
@param Timeout Indicates the maximum time, in millisecond, which the
transfer is allowed to complete.
@retval EFI_DEVICE_ERROR Successful to get the status of device.
@retval EFI_SUCCESS Failed to get the status of device.
**/
EFI_STATUS
BotStatusPhase (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDev,
OUT UINT8 *TransferStatus,
IN UINT16 Timeout
)
{
CSW Csw;
EFI_STATUS Status;
PEI_USB_IO_PPI *UsbIoPpi;
UINT8 EndpointAddr;
UINTN DataSize;
UsbIoPpi = PeiBotDev->UsbIoPpi;
ZeroMem (&Csw, sizeof (CSW));
EndpointAddr = (PeiBotDev->BulkInEndpoint)->EndpointAddress;
DataSize = sizeof (CSW);
//
// Get the status field from bulk transfer
//
Status = UsbIoPpi->UsbBulkTransfer (
PeiServices,
UsbIoPpi,
EndpointAddr,
&Csw,
&DataSize,
Timeout
);
if (EFI_ERROR (Status)) {
return Status;
}
if (Csw.Signature == CSWSIG) {
*TransferStatus = Csw.Status;
} else {
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
/**
Send ATAPI command using BOT protocol.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDev The instance to PEI_BOT_DEVICE.
@param Command The command to be sent to ATAPI device.
@param CommandSize The length of the data to be sent.
@param DataBuffer The pointer to the data.
@param BufferLength The length of the data.
@param Direction The direction of the data.
@param TimeOutInMilliSeconds Indicates the maximum time, in millisecond, which the
transfer is allowed to complete.
@retval EFI_DEVICE_ERROR Successful to get the status of device.
@retval EFI_SUCCESS Failed to get the status of device.
**/
EFI_STATUS
PeiAtapiCommand (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDev,
IN VOID *Command,
IN UINT8 CommandSize,
IN VOID *DataBuffer,
IN UINT32 BufferLength,
IN EFI_USB_DATA_DIRECTION Direction,
IN UINT16 TimeOutInMilliSeconds
)
{
EFI_STATUS Status;
EFI_STATUS BotDataStatus;
UINT8 TransferStatus;
UINT32 BufferSize;
BotDataStatus = EFI_SUCCESS;
//
// First send ATAPI command through Bot
//
Status = BotCommandPhase (
PeiServices,
PeiBotDev,
Command,
CommandSize,
BufferLength,
Direction,
TimeOutInMilliSeconds
);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
//
// Send/Get Data if there is a Data Stage
//
switch (Direction) {
case EfiUsbDataIn:
case EfiUsbDataOut:
BufferSize = BufferLength;
BotDataStatus = BotDataPhase (
PeiServices,
PeiBotDev,
&BufferSize,
DataBuffer,
Direction,
TimeOutInMilliSeconds
);
break;
case EfiUsbNoData:
break;
}
//
// Status Phase
//
Status = BotStatusPhase (
PeiServices,
PeiBotDev,
&TransferStatus,
TimeOutInMilliSeconds
);
if (EFI_ERROR (Status)) {
BotRecoveryReset (PeiServices, PeiBotDev);
return EFI_DEVICE_ERROR;
}
if (TransferStatus == 0x01) {
return EFI_DEVICE_ERROR;
}
return BotDataStatus;
}

View File

@@ -0,0 +1,224 @@
/** @file
BOT Transportation implementation.
Copyright (c) 2006, 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.
**/
#ifndef _PEI_BOT_PEIM_H_
#define _PEI_BOT_PEIM_H_
#include <PiPei.h>
#include <Ppi/UsbIo.h>
#include <Ppi/UsbHostController.h>
#include <Ppi/BlockIo.h>
//#include <Library/DebugLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/PeiServicesLib.h>
#include <Library/BaseMemoryLib.h>
#include <IndustryStandard/Atapi.h>
#pragma pack(1)
//
// Bulk Only device protocol
//
typedef struct {
UINT32 Signature;
UINT32 Tag;
UINT32 DataTransferLength;
UINT8 Flags;
UINT8 Lun;
UINT8 CmdLen;
UINT8 CmdBlock[16];
} CBW;
typedef struct {
UINT32 Signature;
UINT32 Tag;
UINT32 DataResidue;
UINT8 Status;
} CSW;
#pragma pack()
//
// Status code, see Usb Bot device spec
//
#define CSWSIG 0x53425355
#define CBWSIG 0x43425355
/**
Sends out ATAPI Inquiry Packet Command to the specified device. This command will
return INQUIRY data of the device.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.
@retval EFI_SUCCESS Inquiry command completes successfully.
@retval EFI_DEVICE_ERROR Inquiry command failed.
**/
EFI_STATUS
PeiUsbInquiry (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDevice
);
/**
Sends out ATAPI Test Unit Ready Packet Command to the specified device
to find out whether device is accessible.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.
@retval EFI_SUCCESS TestUnit command executed successfully.
@retval EFI_DEVICE_ERROR Device cannot be executed TestUnit command successfully.
**/
EFI_STATUS
PeiUsbTestUnitReady (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDevice
);
/**
Sends out ATAPI Request Sense Packet Command to the specified device.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.
@param SenseCounts Length of sense buffer.
@param SenseKeyBuffer Pointer to sense buffer.
@retval EFI_SUCCESS Command executed successfully.
@retval EFI_DEVICE_ERROR Some device errors happen.
**/
EFI_STATUS
PeiUsbRequestSense (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDevice,
OUT UINTN *SenseCounts,
IN UINT8 *SenseKeyBuffer
);
/**
Sends out ATAPI Read Capacity Packet Command to the specified device.
This command will return the information regarding the capacity of the
media in the device.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.
@retval EFI_SUCCESS Command executed successfully.
@retval EFI_DEVICE_ERROR Some device errors happen.
**/
EFI_STATUS
PeiUsbReadCapacity (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDevice
);
/**
Sends out ATAPI Read Format Capacity Data Command to the specified device.
This command will return the information regarding the capacity of the
media in the device.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.
@retval EFI_SUCCESS Command executed successfully.
@retval EFI_DEVICE_ERROR Some device errors happen.
**/
EFI_STATUS
PeiUsbReadFormattedCapacity (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDevice
);
/**
Execute Read(10) ATAPI command on a specific SCSI target.
Executes the ATAPI Read(10) command on the ATAPI target specified by PeiBotDevice.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.
@param Buffer The pointer to data buffer.
@param Lba The start logic block address of reading.
@param NumberOfBlocks The block number of reading.
@retval EFI_SUCCESS Command executed successfully.
@retval EFI_DEVICE_ERROR Some device errors happen.
**/
EFI_STATUS
PeiUsbRead10 (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDevice,
IN VOID *Buffer,
IN EFI_PEI_LBA Lba,
IN UINTN NumberOfBlocks
);
/**
Check if there is media according to sense data.
@param SenseData Pointer to sense data.
@param SenseCounts Count of sense data.
@retval TRUE No media
@retval FALSE Media exists
**/
BOOLEAN
IsNoMedia (
IN ATAPI_REQUEST_SENSE_DATA *SenseData,
IN UINTN SenseCounts
);
/**
Check if there is media error according to sense data.
@param SenseData Pointer to sense data.
@param SenseCounts Count of sense data.
@retval TRUE Media error
@retval FALSE No media error
**/
BOOLEAN
IsMediaError (
IN ATAPI_REQUEST_SENSE_DATA *SenseData,
IN UINTN SenseCounts
);
/**
Check if media is changed according to sense data.
@param SenseData Pointer to sense data.
@param SenseCounts Count of sense data.
@retval TRUE There is media change event.
@retval FALSE media is NOT changed.
**/
BOOLEAN
IsMediaChange (
IN ATAPI_REQUEST_SENSE_DATA *SenseData,
IN UINTN SenseCounts
);
#endif

View File

@@ -0,0 +1,630 @@
/** @file
Pei USB ATATPI command implementations.
Copyright (c) 1999 - 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 "UsbBotPeim.h"
#include "BotPeim.h"
#define MAXSENSEKEY 5
/**
Sends out ATAPI Inquiry Packet Command to the specified device. This command will
return INQUIRY data of the device.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.
@retval EFI_SUCCESS Inquiry command completes successfully.
@retval EFI_DEVICE_ERROR Inquiry command failed.
**/
EFI_STATUS
PeiUsbInquiry (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDevice
)
{
ATAPI_PACKET_COMMAND Packet;
EFI_STATUS Status;
ATAPI_INQUIRY_DATA Idata;
//
// fill command packet
//
ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
ZeroMem (&Idata, sizeof (ATAPI_INQUIRY_DATA));
Packet.Inquiry.opcode = ATA_CMD_INQUIRY;
Packet.Inquiry.page_code = 0;
Packet.Inquiry.allocation_length = 36;
//
// Send scsi INQUIRY command packet.
// According to SCSI Primary Commands-2 spec, host only needs to
// retrieve the first 36 bytes for standard INQUIRY data.
//
Status = PeiAtapiCommand (
PeiServices,
PeiBotDevice,
&Packet,
(UINT8) sizeof (ATAPI_PACKET_COMMAND),
&Idata,
36,
EfiUsbDataIn,
2000
);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
if ((Idata.peripheral_type & 0x1f) == 0x05) {
PeiBotDevice->DeviceType = USBCDROM;
PeiBotDevice->Media.BlockSize = 0x800;
} else {
PeiBotDevice->DeviceType = USBFLOPPY;
PeiBotDevice->Media.BlockSize = 0x200;
}
return EFI_SUCCESS;
}
/**
Sends out ATAPI Test Unit Ready Packet Command to the specified device
to find out whether device is accessible.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.
@retval EFI_SUCCESS TestUnit command executed successfully.
@retval EFI_DEVICE_ERROR Device cannot be executed TestUnit command successfully.
**/
EFI_STATUS
PeiUsbTestUnitReady (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDevice
)
{
ATAPI_PACKET_COMMAND Packet;
EFI_STATUS Status;
//
// fill command packet
//
ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
Packet.TestUnitReady.opcode = ATA_CMD_TEST_UNIT_READY;
//
// send command packet
//
Status = PeiAtapiCommand (
PeiServices,
PeiBotDevice,
&Packet,
(UINT8) sizeof (ATAPI_PACKET_COMMAND),
NULL,
0,
EfiUsbNoData,
2000
);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
return EFI_SUCCESS;
}
/**
Sends out ATAPI Request Sense Packet Command to the specified device.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.
@param SenseCounts Length of sense buffer.
@param SenseKeyBuffer Pointer to sense buffer.
@retval EFI_SUCCESS Command executed successfully.
@retval EFI_DEVICE_ERROR Some device errors happen.
**/
EFI_STATUS
PeiUsbRequestSense (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDevice,
OUT UINTN *SenseCounts,
IN UINT8 *SenseKeyBuffer
)
{
EFI_STATUS Status;
ATAPI_PACKET_COMMAND Packet;
UINT8 *Ptr;
BOOLEAN SenseReq;
ATAPI_REQUEST_SENSE_DATA *Sense;
*SenseCounts = 0;
//
// fill command packet for Request Sense Packet Command
//
ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
Packet.RequestSence.opcode = ATA_CMD_REQUEST_SENSE;
Packet.RequestSence.allocation_length = (UINT8) sizeof (ATAPI_REQUEST_SENSE_DATA);
Ptr = SenseKeyBuffer;
SenseReq = TRUE;
//
// request sense data from device continuously
// until no sense data exists in the device.
//
while (SenseReq) {
Sense = (ATAPI_REQUEST_SENSE_DATA *) Ptr;
//
// send out Request Sense Packet Command and get one Sense
// data form device.
//
Status = PeiAtapiCommand (
PeiServices,
PeiBotDevice,
&Packet,
(UINT8) sizeof (ATAPI_PACKET_COMMAND),
(VOID *) Ptr,
sizeof (ATAPI_REQUEST_SENSE_DATA),
EfiUsbDataIn,
2000
);
//
// failed to get Sense data
//
if (EFI_ERROR (Status)) {
if (*SenseCounts == 0) {
return EFI_DEVICE_ERROR;
} else {
return EFI_SUCCESS;
}
}
if (Sense->sense_key != ATA_SK_NO_SENSE) {
Ptr += sizeof (ATAPI_REQUEST_SENSE_DATA);
//
// Ptr is byte based pointer
//
(*SenseCounts)++;
if (*SenseCounts == MAXSENSEKEY) {
break;
}
} else {
//
// when no sense key, skip out the loop
//
SenseReq = FALSE;
}
}
return EFI_SUCCESS;
}
/**
Sends out ATAPI Read Capacity Packet Command to the specified device.
This command will return the information regarding the capacity of the
media in the device.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.
@retval EFI_SUCCESS Command executed successfully.
@retval EFI_DEVICE_ERROR Some device errors happen.
**/
EFI_STATUS
PeiUsbReadCapacity (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDevice
)
{
EFI_STATUS Status;
ATAPI_PACKET_COMMAND Packet;
ATAPI_READ_CAPACITY_DATA Data;
ZeroMem (&Data, sizeof (ATAPI_READ_CAPACITY_DATA));
ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
Packet.Inquiry.opcode = ATA_CMD_READ_CAPACITY;
//
// send command packet
//
Status = PeiAtapiCommand (
PeiServices,
PeiBotDevice,
&Packet,
(UINT8) sizeof (ATAPI_PACKET_COMMAND),
(VOID *) &Data,
sizeof (ATAPI_READ_CAPACITY_DATA),
EfiUsbDataIn,
2000
);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
PeiBotDevice->Media.LastBlock = (Data.LastLba3 << 24) | (Data.LastLba2 << 16) | (Data.LastLba1 << 8) | Data.LastLba0;
PeiBotDevice->Media.MediaPresent = TRUE;
return EFI_SUCCESS;
}
/**
Sends out ATAPI Read Format Capacity Data Command to the specified device.
This command will return the information regarding the capacity of the
media in the device.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.
@retval EFI_SUCCESS Command executed successfully.
@retval EFI_DEVICE_ERROR Some device errors happen.
**/
EFI_STATUS
PeiUsbReadFormattedCapacity (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDevice
)
{
EFI_STATUS Status;
ATAPI_PACKET_COMMAND Packet;
ATAPI_READ_FORMAT_CAPACITY_DATA FormatData;
ZeroMem (&FormatData, sizeof (ATAPI_READ_FORMAT_CAPACITY_DATA));
ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
Packet.ReadFormatCapacity.opcode = ATA_CMD_READ_FORMAT_CAPACITY;
Packet.ReadFormatCapacity.allocation_length_lo = 12;
//
// send command packet
//
Status = PeiAtapiCommand (
PeiServices,
PeiBotDevice,
&Packet,
(UINT8) sizeof (ATAPI_PACKET_COMMAND),
(VOID *) &FormatData,
sizeof (ATAPI_READ_FORMAT_CAPACITY_DATA),
EfiUsbDataIn,
2000
);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
if (FormatData.DesCode == 3) {
//
// Media is not present
//
PeiBotDevice->Media.MediaPresent = FALSE;
PeiBotDevice->Media.LastBlock = 0;
} else {
PeiBotDevice->Media.LastBlock = (FormatData.LastLba3 << 24) | (FormatData.LastLba2 << 16) | (FormatData.LastLba1 << 8) | FormatData.LastLba0;
PeiBotDevice->Media.LastBlock--;
PeiBotDevice->Media.MediaPresent = TRUE;
}
return EFI_SUCCESS;
}
/**
Execute Read(10) ATAPI command on a specific SCSI target.
Executes the ATAPI Read(10) command on the ATAPI target specified by PeiBotDevice.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDevice The pointer to PEI_BOT_DEVICE instance.
@param Buffer The pointer to data buffer.
@param Lba The start logic block address of reading.
@param NumberOfBlocks The block number of reading.
@retval EFI_SUCCESS Command executed successfully.
@retval EFI_DEVICE_ERROR Some device errors happen.
**/
EFI_STATUS
PeiUsbRead10 (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDevice,
IN VOID *Buffer,
IN EFI_PEI_LBA Lba,
IN UINTN NumberOfBlocks
)
{
ATAPI_PACKET_COMMAND Packet;
ATAPI_READ10_CMD *Read10Packet;
UINT16 MaxBlock;
UINT16 BlocksRemaining;
UINT16 SectorCount;
UINT32 Lba32;
UINT32 BlockSize;
UINT32 ByteCount;
VOID *PtrBuffer;
EFI_STATUS Status;
UINT16 TimeOut;
//
// prepare command packet for the Inquiry Packet Command.
//
ZeroMem (&Packet, sizeof (ATAPI_PACKET_COMMAND));
Read10Packet = &Packet.Read10;
Lba32 = (UINT32) Lba;
PtrBuffer = Buffer;
BlockSize = (UINT32) PeiBotDevice->Media.BlockSize;
MaxBlock = (UINT16) (65535 / BlockSize);
BlocksRemaining = (UINT16) NumberOfBlocks;
Status = EFI_SUCCESS;
while (BlocksRemaining > 0) {
if (BlocksRemaining <= MaxBlock) {
SectorCount = BlocksRemaining;
} else {
SectorCount = MaxBlock;
}
//
// fill the Packet data structure
//
Read10Packet->opcode = ATA_CMD_READ_10;
//
// Lba0 ~ Lba3 specify the start logical block address of the data transfer.
// Lba0 is MSB, Lba3 is LSB
//
Read10Packet->Lba3 = (UINT8) (Lba32 & 0xff);
Read10Packet->Lba2 = (UINT8) (Lba32 >> 8);
Read10Packet->Lba1 = (UINT8) (Lba32 >> 16);
Read10Packet->Lba0 = (UINT8) (Lba32 >> 24);
//
// TranLen0 ~ TranLen1 specify the transfer length in block unit.
// TranLen0 is MSB, TranLen is LSB
//
Read10Packet->TranLen1 = (UINT8) (SectorCount & 0xff);
Read10Packet->TranLen0 = (UINT8) (SectorCount >> 8);
ByteCount = SectorCount * BlockSize;
TimeOut = (UINT16) (SectorCount * 2000);
//
// send command packet
//
Status = PeiAtapiCommand (
PeiServices,
PeiBotDevice,
&Packet,
(UINT8) sizeof (ATAPI_PACKET_COMMAND),
(VOID *) PtrBuffer,
ByteCount,
EfiUsbDataIn,
TimeOut
);
if (Status != EFI_SUCCESS) {
return Status;
}
Lba32 += SectorCount;
PtrBuffer = (UINT8 *) PtrBuffer + SectorCount * BlockSize;
BlocksRemaining = (UINT16) (BlocksRemaining - SectorCount);
}
return Status;
}
/**
Check if there is media according to sense data.
@param SenseData Pointer to sense data.
@param SenseCounts Count of sense data.
@retval TRUE No media
@retval FALSE Media exists
**/
BOOLEAN
IsNoMedia (
IN ATAPI_REQUEST_SENSE_DATA *SenseData,
IN UINTN SenseCounts
)
{
ATAPI_REQUEST_SENSE_DATA *SensePtr;
UINTN Index;
BOOLEAN NoMedia;
NoMedia = FALSE;
SensePtr = SenseData;
for (Index = 0; Index < SenseCounts; Index++) {
switch (SensePtr->sense_key) {
case ATA_SK_NOT_READY:
switch (SensePtr->addnl_sense_code) {
//
// if no media, fill IdeDev parameter with specific info.
//
case ATA_ASC_NO_MEDIA:
NoMedia = TRUE;
break;
default:
break;
}
break;
default:
break;
}
SensePtr++;
}
return NoMedia;
}
/**
Check if there is media error according to sense data.
@param SenseData Pointer to sense data.
@param SenseCounts Count of sense data.
@retval TRUE Media error
@retval FALSE No media error
**/
BOOLEAN
IsMediaError (
IN ATAPI_REQUEST_SENSE_DATA *SenseData,
IN UINTN SenseCounts
)
{
ATAPI_REQUEST_SENSE_DATA *SensePtr;
UINTN Index;
BOOLEAN Error;
SensePtr = SenseData;
Error = FALSE;
for (Index = 0; Index < SenseCounts; Index++) {
switch (SensePtr->sense_key) {
//
// Medium error case
//
case ATA_SK_MEDIUM_ERROR:
switch (SensePtr->addnl_sense_code) {
case ATA_ASC_MEDIA_ERR1:
//
// fall through
//
case ATA_ASC_MEDIA_ERR2:
//
// fall through
//
case ATA_ASC_MEDIA_ERR3:
//
// fall through
//
case ATA_ASC_MEDIA_ERR4:
Error = TRUE;
break;
default:
break;
}
break;
//
// Medium upside-down case
//
case ATA_SK_NOT_READY:
switch (SensePtr->addnl_sense_code) {
case ATA_ASC_MEDIA_UPSIDE_DOWN:
Error = TRUE;
break;
default:
break;
}
break;
default:
break;
}
SensePtr++;
}
return Error;
}
/**
Check if media is changed according to sense data.
@param SenseData Pointer to sense data.
@param SenseCounts Count of sense data.
@retval TRUE There is media change event.
@retval FALSE media is NOT changed.
**/
BOOLEAN
IsMediaChange (
IN ATAPI_REQUEST_SENSE_DATA *SenseData,
IN UINTN SenseCounts
)
{
ATAPI_REQUEST_SENSE_DATA *SensePtr;
UINTN Index;
BOOLEAN MediaChange;
MediaChange = FALSE;
SensePtr = SenseData;
for (Index = 0; Index < SenseCounts; Index++) {
//
// catch media change sense key and addition sense data
//
switch (SensePtr->sense_key) {
case ATA_SK_UNIT_ATTENTION:
switch (SensePtr->addnl_sense_code) {
case ATA_ASC_MEDIA_CHANGE:
MediaChange = TRUE;
break;
default:
break;
}
break;
default:
break;
}
SensePtr++;
}
return MediaChange;
}

View File

@@ -0,0 +1,331 @@
/** @file
Common Libarary for PEI USB.
Copyright (c) 2006, 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"
/**
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.
**/
BOOLEAN
IsPortLowSpeedDeviceAttached (
IN UINT16 PortStatus
)
{
//
// return the bit 9 value of PortStatus
//
if ((PortStatus & USB_PORT_STAT_LOW_SPEED) != 0) {
return TRUE;
} else {
return FALSE;
}
}
/**
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;
}
}

View File

@@ -0,0 +1,248 @@
/** @file
Common Libarary for PEI USB.
Copyright (c) 1999 - 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.
**/
#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.
**/
BOOLEAN
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

View File

@@ -0,0 +1,65 @@
## @file
# Component description file for UsbBotPei module.
#
# Usb mass storage device Peim driver to support recovery from USB device.
# 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.
#
##
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = UsbBotPei
FILE_GUID = 8401A046-6F70-4505-8471-7015B40355E3
MODULE_TYPE = PEIM
VERSION_STRING = 1.0
ENTRY_POINT = PeimInitializeUsbBot
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
[Sources]
PeiUsbLib.c
PeiAtapi.c
BotPeim.c
UsbBotPeim.c
UsbPeim.h
UsbBotPeim.h
PeiUsbLib.h
BotPeim.h
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
BaseMemoryLib
PeiServicesLib
PeimEntryPoint
DebugLib
PcdLib
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdUsbTransferTimeoutValue
[Ppis]
gEfiPeiVirtualBlockIoPpiGuid # PPI ALWAYS_PRODUCED
gPeiUsbIoPpiGuid # PPI ALWAYS_CONSUMED
[Depex]
gEfiPeiMemoryDiscoveredPpiGuid AND gPeiUsbIoPpiGuid AND gEfiPeiBootInRecoveryModePpiGuid

View File

@@ -0,0 +1,720 @@
/** @file
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 "UsbBotPeim.h"
#include "BotPeim.h"
//
// Global function
//
EFI_PEI_NOTIFY_DESCRIPTOR mNotifyList = {
EFI_PEI_PPI_DESCRIPTOR_NOTIFY_DISPATCH | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
&gPeiUsbIoPpiGuid,
NotifyOnUsbIoPpi
};
EFI_PEI_RECOVERY_BLOCK_IO_PPI mRecoveryBlkIoPpi = {
BotGetNumberOfBlockDevices,
BotGetMediaInfo,
BotReadBlocks
};
EFI_PEI_PPI_DESCRIPTOR mPpiList = {
EFI_PEI_PPI_DESCRIPTOR_PPI | EFI_PEI_PPI_DESCRIPTOR_TERMINATE_LIST,
&gEfiPeiVirtualBlockIoPpiGuid,
NULL
};
/**
Detect whether the removable media is present and whether it has changed.
@param[in] PeiServices General-purpose services that are available to every
PEIM.
@param[in] PeiBotDev Indicates the PEI_BOT_DEVICE instance.
@retval EFI_SUCCESS The media status is successfully checked.
@retval Other Failed to detect media.
**/
EFI_STATUS
PeiBotDetectMedia (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDev
);
/**
Initializes the Usb Bot.
@param FileHandle Handle of the file being invoked.
@param PeiServices Describes the list of possible PEI Services.
@retval EFI_SUCCESS Usb bot driver is successfully initialized.
@retval EFI_OUT_OF_RESOURCES Can't initialize the driver.
**/
EFI_STATUS
EFIAPI
PeimInitializeUsbBot (
IN EFI_PEI_FILE_HANDLE FileHandle,
IN CONST EFI_PEI_SERVICES **PeiServices
)
{
EFI_STATUS Status;
UINTN UsbIoPpiInstance;
EFI_PEI_PPI_DESCRIPTOR *TempPpiDescriptor;
PEI_USB_IO_PPI *UsbIoPpi;
//
// Shadow this PEIM to run from memory
//
if (!EFI_ERROR (PeiServicesRegisterForShadow (FileHandle))) {
return EFI_SUCCESS;
}
//
// locate all usb io PPIs
//
for (UsbIoPpiInstance = 0; UsbIoPpiInstance < PEI_FAT_MAX_USB_IO_PPI; UsbIoPpiInstance++) {
Status = PeiServicesLocatePpi (
&gPeiUsbIoPpiGuid,
UsbIoPpiInstance,
&TempPpiDescriptor,
(VOID **) &UsbIoPpi
);
if (EFI_ERROR (Status)) {
break;
}
}
//
// Register a notify function
//
return PeiServicesNotifyPpi (&mNotifyList);
}
/**
UsbIo installation notification function.
This function finds out all the current USB IO PPIs in the system and add them
into private data.
@param PeiServices Indirect reference to the PEI Services Table.
@param NotifyDesc Address of the notification descriptor data structure.
@param InvokePpi Address of the PPI that was invoked.
@retval EFI_SUCCESS The function completes successfully.
**/
EFI_STATUS
EFIAPI
NotifyOnUsbIoPpi (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
IN VOID *InvokePpi
)
{
PEI_USB_IO_PPI *UsbIoPpi;
UsbIoPpi = (PEI_USB_IO_PPI *) InvokePpi;
InitUsbBot (PeiServices, UsbIoPpi);
return EFI_SUCCESS;
}
/**
Initialize the usb bot device.
@param[in] PeiServices General-purpose services that are available to every
PEIM.
@param[in] UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
@retval EFI_SUCCESS The usb bot device is initialized successfully.
@retval Other Failed to initialize media.
**/
EFI_STATUS
InitUsbBot (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_USB_IO_PPI *UsbIoPpi
)
{
PEI_BOT_DEVICE *PeiBotDevice;
EFI_STATUS Status;
EFI_USB_INTERFACE_DESCRIPTOR *InterfaceDesc;
UINTN MemPages;
EFI_PHYSICAL_ADDRESS AllocateAddress;
EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDesc;
UINT8 Index;
//
// Check its interface
//
Status = UsbIoPpi->UsbGetInterfaceDescriptor (
PeiServices,
UsbIoPpi,
&InterfaceDesc
);
if (EFI_ERROR (Status)) {
return Status;
}
//
// Check if it is the BOT device we support
//
if ((InterfaceDesc->InterfaceClass != 0x08) || (InterfaceDesc->InterfaceProtocol != 0x50)) {
return EFI_NOT_FOUND;
}
MemPages = sizeof (PEI_BOT_DEVICE) / EFI_PAGE_SIZE + 1;
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
MemPages,
&AllocateAddress
);
if (EFI_ERROR (Status)) {
return Status;
}
PeiBotDevice = (PEI_BOT_DEVICE *) ((UINTN) AllocateAddress);
PeiBotDevice->Signature = PEI_BOT_DEVICE_SIGNATURE;
PeiBotDevice->UsbIoPpi = UsbIoPpi;
PeiBotDevice->AllocateAddress = (UINTN) AllocateAddress;
PeiBotDevice->BotInterface = InterfaceDesc;
//
// Default value
//
PeiBotDevice->Media.DeviceType = UsbMassStorage;
PeiBotDevice->Media.BlockSize = 0x200;
//
// Check its Bulk-in/Bulk-out endpoint
//
for (Index = 0; Index < 2; Index++) {
Status = UsbIoPpi->UsbGetEndpointDescriptor (
PeiServices,
UsbIoPpi,
Index,
&EndpointDesc
);
if (EFI_ERROR (Status)) {
return Status;
}
if ((EndpointDesc->EndpointAddress & 0x80) != 0) {
PeiBotDevice->BulkInEndpoint = EndpointDesc;
} else {
PeiBotDevice->BulkOutEndpoint = EndpointDesc;
}
}
CopyMem (
&(PeiBotDevice->BlkIoPpi),
&mRecoveryBlkIoPpi,
sizeof (EFI_PEI_RECOVERY_BLOCK_IO_PPI)
);
CopyMem (
&(PeiBotDevice->BlkIoPpiList),
&mPpiList,
sizeof (EFI_PEI_PPI_DESCRIPTOR)
);
PeiBotDevice->BlkIoPpiList.Ppi = &PeiBotDevice->BlkIoPpi;
Status = PeiUsbInquiry (PeiServices, PeiBotDevice);
if (EFI_ERROR (Status)) {
return Status;
}
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
1,
&AllocateAddress
);
if (EFI_ERROR (Status)) {
return Status;
}
PeiBotDevice->SensePtr = (ATAPI_REQUEST_SENSE_DATA *) ((UINTN) AllocateAddress);
Status = PeiServicesInstallPpi (&PeiBotDevice->BlkIoPpiList);
if (EFI_ERROR (Status)) {
return Status;
}
return EFI_SUCCESS;
}
/**
Gets the count of block I/O devices that one specific block driver detects.
This function is used for getting the count of block I/O devices that one
specific block driver detects. To the PEI ATAPI driver, it returns the number
of all the detected ATAPI devices it detects during the enumeration process.
To the PEI legacy floppy driver, it returns the number of all the legacy
devices it finds during its enumeration process. If no device is detected,
then the function will return zero.
@param[in] PeiServices General-purpose services that are available
to every PEIM.
@param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI
instance.
@param[out] NumberBlockDevices The number of block I/O devices discovered.
@retval EFI_SUCCESS Operation performed successfully.
**/
EFI_STATUS
EFIAPI
BotGetNumberOfBlockDevices (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
OUT UINTN *NumberBlockDevices
)
{
//
// For Usb devices, this value should be always 1
//
*NumberBlockDevices = 1;
return EFI_SUCCESS;
}
/**
Gets a block device's media information.
This function will provide the caller with the specified block device's media
information. If the media changes, calling this function will update the media
information accordingly.
@param[in] PeiServices General-purpose services that are available to every
PEIM
@param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.
@param[in] DeviceIndex Specifies the block device to which the function wants
to talk. Because the driver that implements Block I/O
PPIs will manage multiple block devices, the PPIs that
want to talk to a single device must specify the
device index that was assigned during the enumeration
process. This index is a number from one to
NumberBlockDevices.
@param[out] MediaInfo The media information of the specified block media.
The caller is responsible for the ownership of this
data structure.
@retval EFI_SUCCESS Media information about the specified block device
was obtained successfully.
@retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware
error.
**/
EFI_STATUS
EFIAPI
BotGetMediaInfo (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
IN UINTN DeviceIndex,
OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo
)
{
PEI_BOT_DEVICE *PeiBotDev;
EFI_STATUS Status;
PeiBotDev = PEI_BOT_DEVICE_FROM_THIS (This);
//
// First test unit ready
//
PeiUsbTestUnitReady (
PeiServices,
PeiBotDev
);
Status = PeiBotDetectMedia (
PeiServices,
PeiBotDev
);
if (EFI_ERROR (Status)) {
return EFI_DEVICE_ERROR;
}
CopyMem (
MediaInfo,
&(PeiBotDev->Media),
sizeof (EFI_PEI_BLOCK_IO_MEDIA)
);
return EFI_SUCCESS;
}
/**
Reads the requested number of blocks from the specified block device.
The function reads the requested number of blocks from the device. All the
blocks are read, or an error is returned. If there is no media in the device,
the function returns EFI_NO_MEDIA.
@param[in] PeiServices General-purpose services that are available to
every PEIM.
@param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.
@param[in] DeviceIndex Specifies the block device to which the function wants
to talk. Because the driver that implements Block I/O
PPIs will manage multiple block devices, the PPIs that
want to talk to a single device must specify the device
index that was assigned during the enumeration process.
This index is a number from one to NumberBlockDevices.
@param[in] StartLBA The starting logical block address (LBA) to read from
on the device
@param[in] BufferSize The size of the Buffer in bytes. This number must be
a multiple of the intrinsic block size of the device.
@param[out] Buffer A pointer to the destination buffer for the data.
The caller is responsible for the ownership of the
buffer.
@retval EFI_SUCCESS The data was read correctly from the device.
@retval EFI_DEVICE_ERROR The device reported an error while attempting
to perform the read operation.
@retval EFI_INVALID_PARAMETER The read request contains LBAs that are not
valid, or the buffer is not properly aligned.
@retval EFI_NO_MEDIA There is no media in the device.
@retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of
the intrinsic block size of the device.
**/
EFI_STATUS
EFIAPI
BotReadBlocks (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
IN UINTN DeviceIndex,
IN EFI_PEI_LBA StartLBA,
IN UINTN BufferSize,
OUT VOID *Buffer
)
{
PEI_BOT_DEVICE *PeiBotDev;
EFI_STATUS Status;
UINTN BlockSize;
UINTN NumberOfBlocks;
Status = EFI_SUCCESS;
PeiBotDev = PEI_BOT_DEVICE_FROM_THIS (This);
//
// Check parameters
//
if (Buffer == NULL) {
return EFI_INVALID_PARAMETER;
}
if (BufferSize == 0) {
return EFI_SUCCESS;
}
if (!PeiBotDev->Media.MediaPresent) {
return EFI_NO_MEDIA;
}
BlockSize = PeiBotDev->Media.BlockSize;
if (BufferSize % BlockSize != 0) {
Status = EFI_BAD_BUFFER_SIZE;
}
if (StartLBA > PeiBotDev->Media.LastBlock) {
Status = EFI_INVALID_PARAMETER;
}
NumberOfBlocks = BufferSize / (PeiBotDev->Media.BlockSize);
if (Status == EFI_SUCCESS) {
Status = PeiUsbTestUnitReady (
PeiServices,
PeiBotDev
);
if (Status == EFI_SUCCESS) {
Status = PeiUsbRead10 (
PeiServices,
PeiBotDev,
Buffer,
StartLBA,
1
);
}
} else {
//
// To generate sense data for DetectMedia use.
//
PeiUsbTestUnitReady (
PeiServices,
PeiBotDev
);
}
if (EFI_ERROR (Status)) {
//
// if any error encountered, detect what happened to the media and
// update the media info accordingly.
//
Status = PeiBotDetectMedia (
PeiServices,
PeiBotDev
);
if (Status != EFI_SUCCESS) {
return EFI_DEVICE_ERROR;
}
NumberOfBlocks = BufferSize / PeiBotDev->Media.BlockSize;
if (!(PeiBotDev->Media.MediaPresent)) {
return EFI_NO_MEDIA;
}
if (BufferSize % (PeiBotDev->Media.BlockSize) != 0) {
return EFI_BAD_BUFFER_SIZE;
}
if (StartLBA > PeiBotDev->Media.LastBlock) {
return EFI_INVALID_PARAMETER;
}
if ((StartLBA + NumberOfBlocks - 1) > PeiBotDev->Media.LastBlock) {
return EFI_INVALID_PARAMETER;
}
Status = PeiUsbRead10 (
PeiServices,
PeiBotDev,
Buffer,
StartLBA,
NumberOfBlocks
);
switch (Status) {
case EFI_SUCCESS:
return EFI_SUCCESS;
default:
return EFI_DEVICE_ERROR;
}
} else {
StartLBA += 1;
NumberOfBlocks -= 1;
Buffer = (UINT8 *) Buffer + PeiBotDev->Media.BlockSize;
if (NumberOfBlocks == 0) {
return EFI_SUCCESS;
}
Status = PeiUsbRead10 (
PeiServices,
PeiBotDev,
Buffer,
StartLBA,
NumberOfBlocks
);
switch (Status) {
case EFI_SUCCESS:
return EFI_SUCCESS;
default:
return EFI_DEVICE_ERROR;
}
}
}
/**
Detect whether the removable media is present and whether it has changed.
@param[in] PeiServices General-purpose services that are available to every
PEIM.
@param[in] PeiBotDev Indicates the PEI_BOT_DEVICE instance.
@retval EFI_SUCCESS The media status is successfully checked.
@retval Other Failed to detect media.
**/
EFI_STATUS
PeiBotDetectMedia (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDev
)
{
EFI_STATUS Status;
EFI_STATUS FloppyStatus;
UINTN SenseCounts;
BOOLEAN NeedReadCapacity;
EFI_PHYSICAL_ADDRESS AllocateAddress;
ATAPI_REQUEST_SENSE_DATA *SensePtr;
UINTN Retry;
//
// if there is no media present,or media not changed,
// the request sense command will detect faster than read capacity command.
// read capacity command can be bypassed, thus improve performance.
//
SenseCounts = 0;
NeedReadCapacity = TRUE;
Status = PeiServicesAllocatePages (
EfiBootServicesCode,
1,
&AllocateAddress
);
if (EFI_ERROR (Status)) {
return Status;
}
SensePtr = PeiBotDev->SensePtr;
ZeroMem (SensePtr, EFI_PAGE_SIZE);
Status = PeiUsbRequestSense (
PeiServices,
PeiBotDev,
&SenseCounts,
(UINT8 *) SensePtr
);
if (Status == EFI_SUCCESS) {
//
// No Media
//
if (IsNoMedia (SensePtr, SenseCounts)) {
NeedReadCapacity = FALSE;
PeiBotDev->Media.MediaPresent = FALSE;
PeiBotDev->Media.LastBlock = 0;
} else {
//
// Media Changed
//
if (IsMediaChange (SensePtr, SenseCounts)) {
PeiBotDev->Media.MediaPresent = TRUE;
}
//
// Media Error
//
if (IsMediaError (SensePtr, SenseCounts)) {
//
// if media error encountered, make it look like no media present.
//
PeiBotDev->Media.MediaPresent = FALSE;
PeiBotDev->Media.LastBlock = 0;
}
}
}
if (NeedReadCapacity) {
//
// Retry at most 4 times to detect media info
//
for (Retry = 0; Retry < 4; Retry++) {
switch (PeiBotDev->DeviceType) {
case USBCDROM:
Status = PeiUsbReadCapacity (
PeiServices,
PeiBotDev
);
break;
case USBFLOPPY2:
Status = PeiUsbReadFormattedCapacity (
PeiServices,
PeiBotDev
);
if (EFI_ERROR(Status)||
!PeiBotDev->Media.MediaPresent) {
//
// retry the ReadCapacity command
//
PeiBotDev->DeviceType = USBFLOPPY;
Status = EFI_DEVICE_ERROR;
}
break;
case USBFLOPPY:
Status = PeiUsbReadCapacity (
PeiServices,
PeiBotDev
);
//
// retry the ReadFormatCapacity command
//
PeiBotDev->DeviceType = USBFLOPPY2;
break;
default:
return EFI_INVALID_PARAMETER;
}
SenseCounts = 0;
ZeroMem (SensePtr, EFI_PAGE_SIZE);
if (Status == EFI_SUCCESS) {
break;
}
FloppyStatus = PeiUsbRequestSense (
PeiServices,
PeiBotDev,
&SenseCounts,
(UINT8 *) SensePtr
);
//
// If Request Sense data failed,retry.
//
if (EFI_ERROR (FloppyStatus)) {
continue;
}
//
// No Media
//
if (IsNoMedia (SensePtr, SenseCounts)) {
PeiBotDev->Media.MediaPresent = FALSE;
PeiBotDev->Media.LastBlock = 0;
break;
}
if (IsMediaError (SensePtr, SenseCounts)) {
//
// if media error encountered, make it look like no media present.
//
PeiBotDev->Media.MediaPresent = FALSE;
PeiBotDev->Media.LastBlock = 0;
break;
}
}
//
// ENDFOR
//
// tell whether the readcapacity process is successful or not
// ("Status" variable record the latest status returned
// by ReadCapacity )
//
if (Status != EFI_SUCCESS) {
return EFI_DEVICE_ERROR;
}
}
return EFI_SUCCESS;
}

View File

@@ -0,0 +1,233 @@
/** @file
Usb BOT Peim definition.
Copyright (c) 2006, 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.
**/
#ifndef _PEI_USB_BOT_PEIM_H_
#define _PEI_USB_BOT_PEIM_H_
#include <PiPei.h>
#include <Ppi/UsbIo.h>
#include <Ppi/UsbHostController.h>
#include <Ppi/BlockIo.h>
#include <Library/DebugLib.h>
#include <IndustryStandard/Usb.h>
#include <IndustryStandard/Atapi.h>
#define PEI_FAT_MAX_USB_IO_PPI 127
/**
Gets the count of block I/O devices that one specific block driver detects.
This function is used for getting the count of block I/O devices that one
specific block driver detects. To the PEI ATAPI driver, it returns the number
of all the detected ATAPI devices it detects during the enumeration process.
To the PEI legacy floppy driver, it returns the number of all the legacy
devices it finds during its enumeration process. If no device is detected,
then the function will return zero.
@param[in] PeiServices General-purpose services that are available
to every PEIM.
@param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI
instance.
@param[out] NumberBlockDevices The number of block I/O devices discovered.
@retval EFI_SUCCESS Operation performed successfully.
**/
EFI_STATUS
EFIAPI
BotGetNumberOfBlockDevices (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
OUT UINTN *NumberBlockDevices
);
/**
Gets a block device's media information.
This function will provide the caller with the specified block device's media
information. If the media changes, calling this function will update the media
information accordingly.
@param[in] PeiServices General-purpose services that are available to every
PEIM
@param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.
@param[in] DeviceIndex Specifies the block device to which the function wants
to talk. Because the driver that implements Block I/O
PPIs will manage multiple block devices, the PPIs that
want to talk to a single device must specify the
device index that was assigned during the enumeration
process. This index is a number from one to
NumberBlockDevices.
@param[out] MediaInfo The media information of the specified block media.
The caller is responsible for the ownership of this
data structure.
@retval EFI_SUCCESS Media information about the specified block device
was obtained successfully.
@retval EFI_DEVICE_ERROR Cannot get the media information due to a hardware
error.
**/
EFI_STATUS
EFIAPI
BotGetMediaInfo (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
IN UINTN DeviceIndex,
OUT EFI_PEI_BLOCK_IO_MEDIA *MediaInfo
);
/**
Reads the requested number of blocks from the specified block device.
The function reads the requested number of blocks from the device. All the
blocks are read, or an error is returned. If there is no media in the device,
the function returns EFI_NO_MEDIA.
@param[in] PeiServices General-purpose services that are available to
every PEIM.
@param[in] This Indicates the EFI_PEI_RECOVERY_BLOCK_IO_PPI instance.
@param[in] DeviceIndex Specifies the block device to which the function wants
to talk. Because the driver that implements Block I/O
PPIs will manage multiple block devices, the PPIs that
want to talk to a single device must specify the device
index that was assigned during the enumeration process.
This index is a number from one to NumberBlockDevices.
@param[in] StartLBA The starting logical block address (LBA) to read from
on the device
@param[in] BufferSize The size of the Buffer in bytes. This number must be
a multiple of the intrinsic block size of the device.
@param[out] Buffer A pointer to the destination buffer for the data.
The caller is responsible for the ownership of the
buffer.
@retval EFI_SUCCESS The data was read correctly from the device.
@retval EFI_DEVICE_ERROR The device reported an error while attempting
to perform the read operation.
@retval EFI_INVALID_PARAMETER The read request contains LBAs that are not
valid, or the buffer is not properly aligned.
@retval EFI_NO_MEDIA There is no media in the device.
@retval EFI_BAD_BUFFER_SIZE The BufferSize parameter is not a multiple of
the intrinsic block size of the device.
**/
EFI_STATUS
EFIAPI
BotReadBlocks (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_RECOVERY_BLOCK_IO_PPI *This,
IN UINTN DeviceIndex,
IN EFI_PEI_LBA StartLBA,
IN UINTN BufferSize,
OUT VOID *Buffer
);
/**
UsbIo installation notification function.
This function finds out all the current USB IO PPIs in the system and add them
into private data.
@param PeiServices Indirect reference to the PEI Services Table.
@param NotifyDesc Address of the notification descriptor data structure.
@param InvokePpi Address of the PPI that was invoked.
@retval EFI_SUCCESS The function completes successfully.
**/
EFI_STATUS
EFIAPI
NotifyOnUsbIoPpi (
IN EFI_PEI_SERVICES **PeiServices,
IN EFI_PEI_NOTIFY_DESCRIPTOR *NotifyDesc,
IN VOID *InvokePpi
);
/**
Initialize the usb bot device.
@param[in] PeiServices General-purpose services that are available to every
PEIM.
@param[in] UsbIoPpi Indicates the PEI_USB_IO_PPI instance.
@retval EFI_SUCCESS The usb bot device is initialized successfully.
@retval Other Failed to initialize media.
**/
EFI_STATUS
InitUsbBot (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_USB_IO_PPI *UsbIoPpi
);
#define USBCDROM 1 // let the device type value equal to USBCDROM, which is defined by PI spec.
// Therefore the CdExpressPei module can do recovery on UsbCdrom.
#define USBFLOPPY 2 // for those that use ReadCapacity(0x25) command to retrieve media capacity
#define USBFLOPPY2 3 // for those that use ReadFormatCapacity(0x23) command to retrieve media capacity
//
// Bot device structure
//
#define PEI_BOT_DEVICE_SIGNATURE SIGNATURE_32 ('U', 'B', 'O', 'T')
typedef struct {
UINTN Signature;
EFI_PEI_RECOVERY_BLOCK_IO_PPI BlkIoPpi;
EFI_PEI_PPI_DESCRIPTOR BlkIoPpiList;
EFI_PEI_BLOCK_IO_MEDIA Media;
PEI_USB_IO_PPI *UsbIoPpi;
EFI_USB_INTERFACE_DESCRIPTOR *BotInterface;
EFI_USB_ENDPOINT_DESCRIPTOR *BulkInEndpoint;
EFI_USB_ENDPOINT_DESCRIPTOR *BulkOutEndpoint;
UINTN AllocateAddress;
UINTN DeviceType;
ATAPI_REQUEST_SENSE_DATA *SensePtr;
} PEI_BOT_DEVICE;
#define PEI_BOT_DEVICE_FROM_THIS(a) CR (a, PEI_BOT_DEVICE, BlkIoPpi, PEI_BOT_DEVICE_SIGNATURE)
/**
Send ATAPI command using BOT protocol.
@param PeiServices The pointer of EFI_PEI_SERVICES.
@param PeiBotDev The instance to PEI_BOT_DEVICE.
@param Command The command to be sent to ATAPI device.
@param CommandSize The length of the data to be sent.
@param DataBuffer The pointer to the data.
@param BufferLength The length of the data.
@param Direction The direction of the data.
@param TimeOutInMilliSeconds Indicates the maximum time, in millisecond, which the
transfer is allowed to complete.
@retval EFI_DEVICE_ERROR Successful to get the status of device.
@retval EFI_SUCCESS Failed to get the status of device.
**/
EFI_STATUS
PeiAtapiCommand (
IN EFI_PEI_SERVICES **PeiServices,
IN PEI_BOT_DEVICE *PeiBotDev,
IN VOID *Command,
IN UINT8 CommandSize,
IN VOID *DataBuffer,
IN UINT32 BufferLength,
IN EFI_USB_DATA_DIRECTION Direction,
IN UINT16 TimeOutInMilliSeconds
);
#endif

View File

@@ -0,0 +1,179 @@
/** @file
Usb Peim definition.
Copyright (c) 2006, 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.
**/
#ifndef _PEI_USB_PEIM_H_
#define _PEI_USB_PEIM_H_
#include <PiPei.h>
#include <Ppi/UsbIo.h>
#include <Ppi/UsbHostController.h>
#include <Ppi/BlockIo.h>
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/PcdLib.h>
#include <IndustryStandard/Usb.h>
#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;
UINT8 ConfigurationData[1024];
EFI_USB_CONFIG_DESCRIPTOR *ConfigDesc;
EFI_USB_INTERFACE_DESCRIPTOR *InterfaceDesc;
EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDesc[MAX_ENDPOINT];
} 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
);
#endif

View File

@@ -0,0 +1,537 @@
/** @file
Usb Hub Request Support In PEI Phase
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 "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;
}

View File

@@ -0,0 +1,279 @@
/** @file
Constants definitions for Usb Hub Peim
Copyright (c) 2006, 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.
**/
#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

View File

@@ -0,0 +1,333 @@
/** @file
Common Libarary for PEI USB
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"
/**
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;
}
}

View File

@@ -0,0 +1,250 @@
/** @file
Common Libarary for PEI USB
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.
**/
#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

View File

@@ -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.<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.
#
##
[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

View 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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,203 @@
/** @file
Usb Peim definition.
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.
**/
#ifndef _PEI_USB_PEIM_H_
#define _PEI_USB_PEIM_H_
#include <PiPei.h>
#include <Ppi/UsbHostController.h>
#include <Ppi/Usb2HostController.h>
#include <Ppi/UsbIo.h>
#include <Library/DebugLib.h>
#include <Library/PeimEntryPoint.h>
#include <Library/PeiServicesLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/TimerLib.h>
#include <Library/PcdLib.h>
#include <IndustryStandard/Usb.h>
#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