Import Usb/UsbBusDxe and Usb/UsbMassStorageDxe into MdeModulePkg.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3193 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
vanjeff
2007-07-11 08:47:37 +00:00
parent f183b4f349
commit e237e7ae9f
25 changed files with 10355 additions and 0 deletions

View File

@ -0,0 +1,164 @@
/** @file
Copyright (c) 2004 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
ComponentName.c
Abstract:
**/
//
// The package level header files this module uses
//
#include <PiDxe.h>
//
// The Library classes this module consumes
//
#include <Library/UefiLib.h>
//
// EFI Component Name Functions
//
EFI_STATUS
EFIAPI
UsbBusComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
);
EFI_STATUS
EFIAPI
UsbBusComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle, OPTIONAL
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
);
//
// EFI Component Name Protocol
//
EFI_COMPONENT_NAME_PROTOCOL mUsbBusComponentName = {
UsbBusComponentNameGetDriverName,
UsbBusComponentNameGetControllerName,
"eng"
};
STATIC EFI_UNICODE_STRING_TABLE mUsbBusDriverNameTable[] = {
{ "eng", L"Usb Bus Driver" },
{ NULL , NULL }
};
EFI_STATUS
EFIAPI
UsbBusComponentNameGetDriverName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN CHAR8 *Language,
OUT CHAR16 **DriverName
)
/*++
Routine Description:
Retrieves a Unicode string that is the user readable name of the EFI Driver.
Arguments:
This - A pointer to the EFI_COMPONENT_NAME2_PROTOCOL instance.
Language - A pointer to a three character ISO 639-2 language identifier.
This is the language of the driver name that that the caller
is requesting, and it must match one of the languages specified
in SupportedLanguages. The number of languages supported by a
driver is up to the driver writer.
DriverName - A pointer to the Unicode string to return. This Unicode string
is the name of the driver specified by This in the language
specified by Language.
Returns:
EFI_SUCCESS - The Unicode string for the Driver specified by This
and the language specified by Language was returned
in DriverName.
EFI_INVALID_PARAMETER - Language is NULL.
EFI_INVALID_PARAMETER - DriverName is NULL.
EFI_UNSUPPORTED - The driver specified by This does not support the
language specified by Language.
--*/
{
return LookupUnicodeString (
Language,
mUsbBusComponentName.SupportedLanguages,
mUsbBusDriverNameTable,
DriverName
);
}
EFI_STATUS
EFIAPI
UsbBusComponentNameGetControllerName (
IN EFI_COMPONENT_NAME_PROTOCOL *This,
IN EFI_HANDLE ControllerHandle,
IN EFI_HANDLE ChildHandle, OPTIONAL
IN CHAR8 *Language,
OUT CHAR16 **ControllerName
)
/*++
Routine Description:
Retrieves a Unicode string that is the user readable name of the controller
that is being managed by an EFI Driver.
Arguments:
This - A pointer to the EFI_COMPONENT_NAME2_PROTOCOL instance.
ControllerHandle - The handle of a controller that the driver specified by
This is managing. This handle specifies the controller
whose name is to be returned.
ChildHandle - The handle of the child controller to retrieve the name
of. This is an optional parameter that may be NULL. It
will be NULL for device drivers. It will also be NULL
for a bus drivers that wish to retrieve the name of the
bus controller. It will not be NULL for a bus driver
that wishes to retrieve the name of a child controller.
Language - A pointer to a three character ISO 639-2 language
identifier. This is the language of the controller name
that that the caller is requesting, and it must match one
of the languages specified in SupportedLanguages. The
number of languages supported by a driver is up to the
driver writer.
ControllerName - A pointer to the Unicode string to return. This Unicode
string is the name of the controller specified by
ControllerHandle and ChildHandle in the language specified
by Language from the point of view of the driver specified
by This.
Returns:
EFI_SUCCESS - The Unicode string for the user readable name in the
language specified by Language for the driver
specified by This was returned in DriverName.
EFI_INVALID_PARAMETER - ControllerHandle is not a valid EFI_HANDLE.
EFI_INVALID_PARAMETER - ChildHandle is not NULL and it is not a valid EFI_HANDLE.
EFI_INVALID_PARAMETER - Language is NULL.
EFI_INVALID_PARAMETER - ControllerName is NULL.
EFI_UNSUPPORTED - The driver specified by This is not currently managing
the controller specified by ControllerHandle and
ChildHandle.
EFI_UNSUPPORTED - The driver specified by This does not support the
language specified by Language.
--*/
{
return EFI_UNSUPPORTED;
}

View File

@ -0,0 +1,99 @@
#/** @file
# Component name for module UsbBus
#
# Copyright (c) 2006, Intel Corporation. All right reserved.
#
# All rights reserved. This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
# http://opensource.org/licenses/bsd-license.php
#
# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#
#
#**/
################################################################################
#
# Defines Section - statements that will be processed to create a Makefile.
#
################################################################################
[Defines]
INF_VERSION = 0x00010005
BASE_NAME = UsbBusDxe
FILE_GUID = 240612B7-A063-11d4-9A3A-0090273FC14D
MODULE_TYPE = DXE_DRIVER
VERSION_STRING = 1.0
EDK_RELEASE_VERSION = 0x00020000
EFI_SPECIFICATION_VERSION = 0x00020000
ENTRY_POINT = UsbBusDriverEntryPoint
#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 IPF EBC
#
################################################################################
#
# Sources Section - list of files that are required for the build to succeed.
#
################################################################################
[Sources.common]
UsbDesc.c
UsbEnumer.c
UsbEnumer.h
usbbus.c
UsbHub.c
ComponentName.c
UsbUtility.h
UsbHub.h
UsbUtility.c
UsbDesc.h
usbbus.h
################################################################################
#
# Package Dependency Section - list of Package files that are required for
# this module.
#
################################################################################
[Packages]
MdePkg/MdePkg.dec
MdeModulePkg/MdeModulePkg.dec
################################################################################
#
# Library Class Section - list of Library Classes that are required for
# this module.
#
################################################################################
[LibraryClasses]
MemoryAllocationLib
DevicePathLib
UefiLib
UefiBootServicesTableLib
UefiDriverEntryPoint
BaseMemoryLib
DebugLib
################################################################################
#
# Protocol C Name Section - list of Protocol and Protocol Notify C Names
# that this module uses or produces.
#
################################################################################
[Protocols]
gEfiUsbIoProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiDevicePathProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiUsb2HcProtocolGuid # PROTOCOL ALWAYS_CONSUMED
gEfiUsbHcProtocolGuid # PROTOCOL ALWAYS_CONSUMED

View File

@ -0,0 +1,85 @@
<ModuleSurfaceArea xmlns="http://www.TianoCore.org/2006/Edk2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<MsaHeader>
<ModuleName>UsbBusDxe</ModuleName>
<ModuleType>DXE_DRIVER</ModuleType>
<GuidValue>240612B7-A063-11d4-9A3A-0090273FC14D</GuidValue>
<Version>1.0</Version>
<Abstract>Component name for module UsbBus</Abstract>
<Description>FIX ME!</Description>
<Copyright>Copyright (c) 2006, Intel Corporation. All right reserved.</Copyright>
<License>All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.</License>
<Specification>FRAMEWORK_BUILD_PACKAGING_SPECIFICATION 0x00000052</Specification>
</MsaHeader>
<ModuleDefinitions>
<SupportedArchitectures>IA32 X64 IPF EBC</SupportedArchitectures>
<BinaryModule>false</BinaryModule>
<OutputFileBasename>UsbBusDxe</OutputFileBasename>
</ModuleDefinitions>
<LibraryClassDefinitions>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>DebugLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>BaseMemoryLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UefiDriverEntryPoint</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UefiBootServicesTableLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>UefiLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>DevicePathLib</Keyword>
</LibraryClass>
<LibraryClass Usage="ALWAYS_CONSUMED">
<Keyword>MemoryAllocationLib</Keyword>
</LibraryClass>
</LibraryClassDefinitions>
<SourceFiles>
<Filename>usbbus.h</Filename>
<Filename>UsbDesc.h</Filename>
<Filename>UsbUtility.c</Filename>
<Filename>UsbHub.h</Filename>
<Filename>UsbUtility.h</Filename>
<Filename>ComponentName.c</Filename>
<Filename>UsbHub.c</Filename>
<Filename>usbbus.c</Filename>
<Filename>UsbEnumer.h</Filename>
<Filename>UsbEnumer.c</Filename>
<Filename>UsbDesc.c</Filename>
</SourceFiles>
<PackageDependencies>
<Package PackageGuid="5e0e9358-46b6-4ae2-8218-4ab8b9bbdcec"/>
<Package PackageGuid="68169ab0-d41b-4009-9060-292c253ac43d"/>
</PackageDependencies>
<Protocols>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiUsbHcProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiUsb2HcProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiDevicePathProtocolGuid</ProtocolCName>
</Protocol>
<Protocol Usage="ALWAYS_CONSUMED">
<ProtocolCName>gEfiUsbIoProtocolGuid</ProtocolCName>
</Protocol>
</Protocols>
<Externs>
<Specification>EFI_SPECIFICATION_VERSION 0x00020000</Specification>
<Specification>EDK_RELEASE_VERSION 0x00020000</Specification>
<Extern>
<ModuleEntryPoint>UsbBusDriverEntryPoint</ModuleEntryPoint>
</Extern>
</Externs>
</ModuleSurfaceArea>

View File

@ -0,0 +1,991 @@
/** @file
Copyright (c) 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
UsbDesc.c
Abstract:
Manage Usb Descriptor List
Revision History
**/
#include "UsbBus.h"
/**
Free the interface setting descriptor
@param Setting The descriptor to free
@return None
**/
STATIC
VOID
UsbFreeInterfaceDesc (
IN USB_INTERFACE_SETTING *Setting
)
{
USB_ENDPOINT_DESC *Ep;
UINTN Index;
if (Setting->Endpoints != NULL) {
//
// Each interface setting may have several endpoints, free them first.
//
for (Index = 0; Index < Setting->Desc.NumEndpoints; Index++) {
Ep = Setting->Endpoints[Index];
if (Ep != NULL) {
gBS->FreePool (Ep);
}
}
gBS->FreePool (Setting->Endpoints);
}
gBS->FreePool (Setting);
}
/**
Free a configuration descriptor with its interface
descriptors. It may be initialized partially
@param Config The configuration descriptor to free
@return None
**/
STATIC
VOID
UsbFreeConfigDesc (
IN USB_CONFIG_DESC *Config
)
{
USB_INTERFACE_DESC *Interface;
UINTN Index;
UINTN SetIndex;
if (Config->Interfaces != NULL) {
//
// A configuration may have several interfaces, free the interface
//
for (Index = 0; Index < Config->Desc.NumInterfaces; Index++) {
Interface = Config->Interfaces[Index];
if (Interface == NULL) {
continue;
}
//
// Each interface may have several settings, free the settings
//
for (SetIndex = 0; SetIndex < Interface->NumOfSetting; SetIndex++) {
if (Interface->Settings[SetIndex] != NULL) {
UsbFreeInterfaceDesc (Interface->Settings[SetIndex]);
}
}
gBS->FreePool (Interface);
}
gBS->FreePool (Config->Interfaces);
}
gBS->FreePool (Config);
}
/**
Free a device descriptor with its configurations
@param DevDesc The device descriptor
@return None
**/
VOID
UsbFreeDevDesc (
IN USB_DEVICE_DESC *DevDesc
)
{
UINTN Index;
if (DevDesc->Configs != NULL) {
for (Index = 0; Index < DevDesc->Desc.NumConfigurations; Index++) {
if (DevDesc->Configs[Index] != NULL) {
UsbFreeConfigDesc (DevDesc->Configs[Index]);
}
}
gBS->FreePool (DevDesc->Configs);
}
gBS->FreePool (DevDesc);
}
/**
Create a descriptor
@param DescBuf The buffer of raw descriptor
@param Len The lenght of the raw descriptor buffer
@param Type The type of descriptor to create
@param Consumed Number of bytes consumed
@return Created descriptor or NULL
**/
STATIC
VOID *
UsbCreateDesc (
IN UINT8 *DescBuf,
IN INTN Len,
IN UINT8 Type,
OUT INTN *Consumed
)
{
USB_DESC_HEAD *Head;
INTN DescLen;
INTN CtrlLen;
INTN Offset;
VOID *Desc;
DescLen = 0;
CtrlLen = 0;
*Consumed = 0;
switch (Type) {
case USB_DESC_TYPE_DEVICE:
DescLen = sizeof (EFI_USB_DEVICE_DESCRIPTOR);
CtrlLen = sizeof (USB_DEVICE_DESC);
break;
case USB_DESC_TYPE_CONFIG:
DescLen = sizeof (EFI_USB_CONFIG_DESCRIPTOR);
CtrlLen = sizeof (USB_CONFIG_DESC);
break;
case USB_DESC_TYPE_INTERFACE:
DescLen = sizeof (EFI_USB_INTERFACE_DESCRIPTOR);
CtrlLen = sizeof (USB_INTERFACE_SETTING);
break;
case USB_DESC_TYPE_ENDPOINT:
DescLen = sizeof (EFI_USB_ENDPOINT_DESCRIPTOR);
CtrlLen = sizeof (USB_ENDPOINT_DESC);
break;
}
//
// All the descriptor has a common LTV (Length, Type, Value)
// format. Skip the descriptor that isn't of this Type
//
Offset = 0;
Head = (USB_DESC_HEAD*)DescBuf;
while ((Offset < Len) && (Head->Type != Type)) {
Offset += Head->Len;
Head = (USB_DESC_HEAD*)(DescBuf + Offset);
}
if ((Len <= Offset) || (Len < Offset + DescLen) ||
(Head->Type != Type) || (Head->Len != DescLen)) {
USB_ERROR (("UsbCreateDesc: met mal-format descriptor\n"));
return NULL;
}
Desc = AllocateZeroPool (CtrlLen);
if (Desc == NULL) {
return NULL;
}
CopyMem (Desc, Head, DescLen);
*Consumed = Offset + Head->Len;
return Desc;
}
/**
Parse an interface desciptor and its endpoints
@param DescBuf The buffer of raw descriptor
@param Len The lenght of the raw descriptor buffer
@param Consumed The number of raw descriptor consumed
@return The create interface setting or NULL if failed
**/
STATIC
USB_INTERFACE_SETTING *
UsbParseInterfaceDesc (
IN UINT8 *DescBuf,
IN INTN Len,
OUT INTN *Consumed
)
{
USB_INTERFACE_SETTING *Setting;
USB_ENDPOINT_DESC *Ep;
UINTN Index;
UINTN NumEp;
INTN Used;
INTN Offset;
*Consumed = 0;
Setting = UsbCreateDesc (DescBuf, Len, USB_DESC_TYPE_INTERFACE, &Used);
if (Setting == NULL) {
USB_ERROR (("UsbParseInterfaceDesc: failed to create interface descriptor\n"));
return NULL;
}
Offset = Used;
//
// Create an arry to hold the interface's endpoints
//
NumEp = Setting->Desc.NumEndpoints;
USB_DEBUG (("UsbParseInterfaceDesc: interface %d(setting %d) has %d endpoints\n",
Setting->Desc.InterfaceNumber, Setting->Desc.AlternateSetting, NumEp));
if (NumEp == 0) {
goto ON_EXIT;
}
Setting->Endpoints = AllocateZeroPool (sizeof (USB_ENDPOINT_DESC *) * NumEp);
if (Setting->Endpoints == NULL) {
goto ON_ERROR;
}
//
// Create the endpoints for this interface
//
for (Index = 0; Index < NumEp; Index++) {
Ep = UsbCreateDesc (DescBuf + Offset, Len - Offset, USB_DESC_TYPE_ENDPOINT, &Used);
if (Ep == NULL) {
USB_ERROR (("UsbParseInterfaceDesc: failed to create endpoint(index %d)\n", Index));
goto ON_ERROR;
}
Setting->Endpoints[Index] = Ep;
Offset += Used;
}
ON_EXIT:
*Consumed = Offset;
return Setting;
ON_ERROR:
UsbFreeInterfaceDesc (Setting);
return NULL;
}
/**
Parse the configuration descriptor and its interfaces.
@param DescBuf The buffer of raw descriptor
@param Len The lenght of the raw descriptor buffer
@return The created configuration descriptor
**/
STATIC
USB_CONFIG_DESC *
UsbParseConfigDesc (
IN UINT8 *DescBuf,
IN INTN Len
)
{
USB_CONFIG_DESC *Config;
USB_INTERFACE_SETTING *Setting;
USB_INTERFACE_DESC *Interface;
UINTN Index;
UINTN NumIf;
INTN Consumed;
ASSERT (DescBuf != NULL);
Config = UsbCreateDesc (DescBuf, Len, USB_DESC_TYPE_CONFIG, &Consumed);
if (Config == NULL) {
return NULL;
}
//
// Initialize an array of setting for the configuration's interfaces.
//
NumIf = Config->Desc.NumInterfaces;
Config->Interfaces = AllocateZeroPool (sizeof (USB_INTERFACE_DESC *) * NumIf);
if (Config->Interfaces == NULL) {
goto ON_ERROR;
}
USB_DEBUG (("UsbParseConfigDesc: config %d has %d interfaces\n",
Config->Desc.ConfigurationValue, NumIf));
for (Index = 0; Index < NumIf; Index++) {
Interface = AllocateZeroPool (sizeof (USB_INTERFACE_DESC));
if (Interface == NULL) {
goto ON_ERROR;
}
Config->Interfaces[Index] = Interface;
}
//
// If a configuration has several interfaces, these interfaces are
// numbered from zero to n. If a interface has several settings,
// these settings are also number from zero to m. The interface
// setting must be organized as |interface 0, setting 0|interface 0
// setting 1|interface 1, setting 0|interface 2, setting 0|. Check
// USB2.0 spec, page 267.
//
DescBuf += Consumed;
Len -= Consumed;
while (Len > 0) {
Setting = UsbParseInterfaceDesc (DescBuf, Len, &Consumed);
if ((Setting == NULL)) {
USB_ERROR (("UsbParseConfigDesc: failed to parse interface setting\n"));
goto ON_ERROR;
} else if (Setting->Desc.InterfaceNumber >= NumIf) {
USB_ERROR (("UsbParseConfigDesc: mal-formated interface descriptor\n"));
UsbFreeInterfaceDesc (Setting);
goto ON_ERROR;
}
//
// Insert the descriptor to the corresponding set.
//
Interface = Config->Interfaces[Setting->Desc.InterfaceNumber];
if (Interface->NumOfSetting >= USB_MAX_INTERFACE_SETTING) {
goto ON_ERROR;
}
Interface->Settings[Interface->NumOfSetting] = Setting;
Interface->NumOfSetting++;
DescBuf += Consumed;
Len -= Consumed;
}
return Config;
ON_ERROR:
UsbFreeConfigDesc (Config);
return NULL;
}
/**
USB standard control transfer support routine. This
function is used by USB device. It is possible that
the device's interfaces are still waiting to be
enumerated.
@param UsbDev The usb device
@param Direction The direction of data transfer
@param Type Standard / class specific / vendor specific
@param Target The receiving target
@param Request Which request
@param Value The wValue parameter of the request
@param Index The wIndex parameter of the request
@param Buf The buffer to receive data into / transmit from
@param Length The length of the buffer
@retval EFI_SUCCESS The control request is executed
@retval EFI_DEVICE_ERROR Failed to execute the control transfer
**/
EFI_STATUS
UsbCtrlRequest (
IN USB_DEVICE *UsbDev,
IN EFI_USB_DATA_DIRECTION Direction,
IN UINTN Type,
IN UINTN Target,
IN UINTN Request,
IN UINT16 Value,
IN UINT16 Index,
IN OUT VOID *Buf,
IN UINTN Length
)
{
EFI_USB_DEVICE_REQUEST DevReq;
EFI_STATUS Status;
UINT32 Result;
UINTN Len;
ASSERT ((UsbDev != NULL) && (UsbDev->Bus != NULL));
DevReq.RequestType = USB_REQUEST_TYPE (Direction, Type, Target);
DevReq.Request = (UINT8) Request;
DevReq.Value = Value;
DevReq.Index = Index;
DevReq.Length = (UINT16) Length;
Len = Length;
Status = UsbHcControlTransfer (
UsbDev->Bus,
UsbDev->Address,
UsbDev->Speed,
UsbDev->MaxPacket0,
&DevReq,
Direction,
Buf,
&Len,
50 * USB_STALL_1_MS,
&UsbDev->Translator,
&Result
);
return Status;
}
/**
Get the standard descriptors.
@param UsbDev The USB device to read descriptor from
@param DescType The type of descriptor to read
@param DescIndex The index of descriptor to read
@param LangId Language ID, only used to get string, otherwise set
it to 0
@param Buf The buffer to hold the descriptor read
@param Length The length of the buffer
@retval EFI_SUCCESS The descriptor is read OK
@retval Others Failed to retrieve the descriptor
**/
STATIC
EFI_STATUS
UsbCtrlGetDesc (
IN USB_DEVICE *UsbDev,
IN UINTN DescType,
IN UINTN DescIndex,
IN UINT16 LangId,
OUT VOID *Buf,
IN UINTN Length
)
{
EFI_STATUS Status;
Status = UsbCtrlRequest (
UsbDev,
EfiUsbDataIn,
USB_REQ_TYPE_STANDARD,
USB_TARGET_DEVICE,
USB_REQ_GET_DESCRIPTOR,
(UINT16) ((DescType << 8) | DescIndex),
LangId,
Buf,
Length
);
return Status;
}
/**
Return the max packet size for endpoint zero. This function
is the first function called to get descriptors during bus
enumeration.
@param UsbDev The usb device
@retval EFI_SUCCESS The max packet size of endpoint zero is retrieved
@retval EFI_DEVICE_ERROR Failed to retrieve it
**/
EFI_STATUS
UsbGetMaxPacketSize0 (
IN USB_DEVICE *UsbDev
)
{
EFI_USB_DEVICE_DESCRIPTOR DevDesc;
EFI_STATUS Status;
UINTN Index;
//
// Get the first 8 bytes of the device descriptor which contains
// max packet size for endpoint 0, which is at least 8.
//
UsbDev->MaxPacket0 = 8;
for (Index = 0; Index < 3; Index++) {
Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_DEVICE, 0, 0, &DevDesc, 8);
if (!EFI_ERROR (Status)) {
UsbDev->MaxPacket0 = DevDesc.MaxPacketSize0;
return EFI_SUCCESS;
}
gBS->Stall (100 * USB_STALL_1_MS);
}
return EFI_DEVICE_ERROR;
}
/**
Get the device descriptor for the device.
@param UsbDev The Usb device to retrieve descriptor from
@retval EFI_SUCCESS The device descriptor is returned
@retval EFI_OUT_OF_RESOURCES Failed to allocate memory
**/
STATIC
EFI_STATUS
UsbGetDevDesc (
IN USB_DEVICE *UsbDev
)
{
USB_DEVICE_DESC *DevDesc;
EFI_STATUS Status;
DevDesc = AllocateZeroPool (sizeof (USB_DEVICE_DESC));
if (DevDesc == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Status = UsbCtrlGetDesc (
UsbDev,
USB_DESC_TYPE_DEVICE,
0,
0,
DevDesc,
sizeof (EFI_USB_DEVICE_DESCRIPTOR)
);
if (EFI_ERROR (Status)) {
gBS->FreePool (DevDesc);
} else {
UsbDev->DevDesc = DevDesc;
}
return Status;
}
/**
Retrieve the indexed string for the language. It requires two
steps to get a string, first to get the string's length. Then
the string itself.
@param UsbDev The usb device
@param Index The index the string to retrieve
@param LangId Language ID
@return The created string descriptor or NULL
**/
EFI_USB_STRING_DESCRIPTOR *
UsbGetOneString (
IN USB_DEVICE *UsbDev,
IN UINT8 Index,
IN UINT16 LangId
)
{
EFI_USB_STRING_DESCRIPTOR Desc;
EFI_STATUS Status;
UINT8 *Buf;
//
// First get two bytes which contains the string length.
//
Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_STRING, Index, LangId, &Desc, 2);
if (EFI_ERROR (Status)) {
return NULL;
}
Buf = AllocateZeroPool (Desc.Length);
if (Buf == NULL) {
return NULL;
}
Status = UsbCtrlGetDesc (
UsbDev,
USB_DESC_TYPE_STRING,
Index,
LangId,
Buf,
Desc.Length
);
if (EFI_ERROR (Status)) {
gBS->FreePool (Buf);
return NULL;
}
return (EFI_USB_STRING_DESCRIPTOR *) Buf;
}
/**
Build the language ID table for string descriptors
@param UsbDev The Usb device
@retval EFI_UNSUPPORTED This device doesn't support string table
**/
STATIC
EFI_STATUS
UsbBuildLangTable (
IN USB_DEVICE *UsbDev
)
{
EFI_USB_STRING_DESCRIPTOR *Desc;
EFI_STATUS Status;
UINTN Index;
UINTN Max;
UINT16 *Point;
//
// The string of language ID zero returns the supported languages
//
Desc = UsbGetOneString (UsbDev, 0, 0);
if (Desc == NULL) {
return EFI_UNSUPPORTED;
}
if (Desc->Length < 4) {
Status = EFI_UNSUPPORTED;
goto ON_EXIT;
}
Status = EFI_SUCCESS;
Max = (Desc->Length - 2) / 2;
Max = (Max < USB_MAX_LANG_ID ? Max : USB_MAX_LANG_ID);
Point = Desc->String;
for (Index = 0; Index < Max; Index++) {
UsbDev->LangId[Index] = *Point;
Point++;
}
UsbDev->TotalLangId = (UINT16)Max;
ON_EXIT:
gBS->FreePool (Desc);
return Status;
}
/**
Retrieve the indexed configure for the device. USB device
returns the configuration togetther with the interfaces for
this configuration. Configuration descriptor is also of
variable length
@param UsbDev The Usb interface
@param Index The index of the configuration
@return The created configuration descriptor
**/
STATIC
EFI_USB_CONFIG_DESCRIPTOR *
UsbGetOneConfig (
IN USB_DEVICE *UsbDev,
IN UINT8 Index
)
{
EFI_USB_CONFIG_DESCRIPTOR Desc;
EFI_STATUS Status;
VOID *Buf;
//
// First get four bytes which contains the total length
// for this configuration.
//
Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_CONFIG, Index, 0, &Desc, 8);
if (EFI_ERROR (Status)) {
USB_ERROR (("UsbGetOneConfig: failed to get descript length(%d) %r\n",
Status, Desc.TotalLength));
return NULL;
}
USB_DEBUG (("UsbGetOneConfig: total length is %d\n", Desc.TotalLength));
Buf = AllocateZeroPool (Desc.TotalLength);
if (Buf == NULL) {
return NULL;
}
Status = UsbCtrlGetDesc (UsbDev, USB_DESC_TYPE_CONFIG, Index, 0, Buf, Desc.TotalLength);
if (EFI_ERROR (Status)) {
USB_ERROR (("UsbGetOneConfig: failed to get full descript %r\n", Status));
gBS->FreePool (Buf);
return NULL;
}
return Buf;
}
/**
Build the whole array of descriptors. This function must
be called after UsbGetMaxPacketSize0 returns the max packet
size correctly for endpoint 0.
@param UsbDev The Usb device
@retval EFI_SUCCESS The descriptor table is build
@retval EFI_OUT_OF_RESOURCES Failed to allocate resource for the descriptor
**/
EFI_STATUS
UsbBuildDescTable (
IN USB_DEVICE *UsbDev
)
{
EFI_USB_CONFIG_DESCRIPTOR *Config;
USB_DEVICE_DESC *DevDesc;
USB_CONFIG_DESC *ConfigDesc;
UINT8 NumConfig;
EFI_STATUS Status;
UINT8 Index;
//
// Get the device descriptor, then allocate the configure
// descriptor pointer array to hold configurations.
//
Status = UsbGetDevDesc (UsbDev);
if (EFI_ERROR (Status)) {
USB_ERROR (("UsbBuildDescTable: failed to get device descriptor - %r\n", Status));
return Status;
}
DevDesc = UsbDev->DevDesc;
NumConfig = DevDesc->Desc.NumConfigurations;
DevDesc->Configs = AllocateZeroPool (NumConfig * sizeof (USB_CONFIG_DESC *));
if (DevDesc->Configs == NULL) {
return EFI_OUT_OF_RESOURCES;
}
USB_DEBUG (("UsbBuildDescTable: device has %d configures\n", NumConfig));
//
// Read each configurations, then parse them
//
for (Index = 0; Index < NumConfig; Index++) {
Config = UsbGetOneConfig (UsbDev, Index);
if (Config == NULL) {
USB_ERROR (("UsbBuildDescTable: failed to get configure (index %d)\n", Index));
//
// If we can get the default descriptor, it is likely that the
// device is still operational.
//
if (Index == 0) {
return EFI_DEVICE_ERROR;
}
break;
}
ConfigDesc = UsbParseConfigDesc ((UINT8 *) Config, Config->TotalLength);
gBS->FreePool (Config);
if (ConfigDesc == NULL) {
USB_ERROR (("UsbBuildDescTable: failed to parse configure (index %d)\n", Index));
//
// If we can get the default descriptor, it is likely that the
// device is still operational.
//
if (Index == 0) {
return EFI_DEVICE_ERROR;
}
break;
}
DevDesc->Configs[Index] = ConfigDesc;
}
//
// Don't return error even this function failed because
// it is possible for the device to not support strings.
//
Status = UsbBuildLangTable (UsbDev);
if (EFI_ERROR (Status)) {
USB_DEBUG (("UsbBuildDescTable: get language ID table %r\n", Status));
}
return EFI_SUCCESS;
}
/**
Set the device's address.
@param UsbDev The device to set address to
@param Address The address to set
@retval EFI_SUCCESS The device is set to the address
@retval Others Failed to set the device address
**/
EFI_STATUS
UsbSetAddress (
IN USB_DEVICE *UsbDev,
IN UINT8 Address
)
{
EFI_STATUS Status;
Status = UsbCtrlRequest (
UsbDev,
EfiUsbNoData,
USB_REQ_TYPE_STANDARD,
USB_TARGET_DEVICE,
USB_REQ_SET_ADDRESS,
Address,
0,
NULL,
0
);
return Status;
}
/**
Set the device's configuration. This function changes
the device's internal state. UsbSelectConfig changes
the Usb bus's internal state.
@param UsbDev The USB device to set configure to
@param ConfigIndex The configure index to set
@retval EFI_SUCCESS The device is configured now
@retval Others Failed to set the device configure
**/
EFI_STATUS
UsbSetConfig (
IN USB_DEVICE *UsbDev,
IN UINT8 ConfigIndex
)
{
EFI_STATUS Status;
Status = UsbCtrlRequest (
UsbDev,
EfiUsbNoData,
USB_REQ_TYPE_STANDARD,
USB_TARGET_DEVICE,
USB_REQ_SET_CONFIG,
ConfigIndex,
0,
NULL,
0
);
return Status;
}
/**
Usb UsbIo interface to clear the feature. This is should
only be used by HUB which is considered a device driver
on top of the UsbIo interface.
@param UsbIo The UsbIo interface
@param Target The target of the transfer: endpoint/device
@param Feature The feature to clear
@param Index The wIndex parameter
@retval EFI_SUCCESS The device feature is cleared
@retval Others Failed to clear the feature
**/
EFI_STATUS
UsbIoClearFeature (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN UINTN Target,
IN UINT16 Feature,
IN UINT16 Index
)
{
EFI_USB_DEVICE_REQUEST DevReq;
UINT32 UsbResult;
EFI_STATUS Status;
DevReq.RequestType = USB_REQUEST_TYPE (EfiUsbNoData, USB_REQ_TYPE_STANDARD, Target);
DevReq.Request = USB_REQ_CLEAR_FEATURE;
DevReq.Value = Feature;
DevReq.Index = Index;
DevReq.Length = 0;
Status = UsbIo->UsbControlTransfer (
UsbIo,
&DevReq,
EfiUsbNoData,
10 * USB_STALL_1_MS,
NULL,
0,
&UsbResult
);
return Status;
}

View File

@ -0,0 +1,146 @@
/** @file
Copyright (c) 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
UsbDesc.h
Abstract:
Manage Usb Descriptor List
Revision History
**/
#ifndef _USB_DESCRIPTOR_H_
#define _USB_DESCRIPTOR_H_
enum {
USB_MAX_INTERFACE_SETTING = 8,
};
//
// The RequestType in EFI_USB_DEVICE_REQUEST is composed of
// three fields: One bit direction, 2 bit type, and 5 bit
// target.
//
#define USB_REQUEST_TYPE(Dir, Type, Target) \
((UINT8)((((Dir) == EfiUsbDataIn ? 0x01 : 0) << 7) | (Type) | (Target)))
//
// A common header for usb standard descriptor.
// Each stand descriptor has a length and type.
//
#pragma pack(1)
typedef struct {
UINT8 Len;
UINT8 Type;
} USB_DESC_HEAD;
#pragma pack()
//
// Each USB device has a device descriptor. Each device may
// have several configures. Each configure contains several
// interfaces. Each interface may have several settings. Each
// setting has several endpoints.
//
// EFI_USB_..._DESCRIPTOR must be the first member of the
// structure.
//
typedef struct {
EFI_USB_ENDPOINT_DESCRIPTOR Desc;
UINT8 Toggle;
} USB_ENDPOINT_DESC;
typedef struct {
EFI_USB_INTERFACE_DESCRIPTOR Desc;
USB_ENDPOINT_DESC **Endpoints;
} USB_INTERFACE_SETTING;
//
// An interface may have several settings. Use a
// fixed max number of settings to simplify code.
// It should sufice in most environments.
//
typedef struct {
USB_INTERFACE_SETTING* Settings[USB_MAX_INTERFACE_SETTING];
UINTN NumOfSetting;
UINT8 ActiveIndex; // Index of active setting
} USB_INTERFACE_DESC;
typedef struct {
EFI_USB_CONFIG_DESCRIPTOR Desc;
USB_INTERFACE_DESC **Interfaces;
} USB_CONFIG_DESC;
typedef struct {
EFI_USB_DEVICE_DESCRIPTOR Desc;
USB_CONFIG_DESC **Configs;
} USB_DEVICE_DESC;
EFI_STATUS
UsbCtrlRequest (
IN USB_DEVICE *UsbDev,
IN EFI_USB_DATA_DIRECTION Direction,
IN UINTN Type,
IN UINTN Target,
IN UINTN Request,
IN UINT16 Value,
IN UINT16 Index,
IN OUT VOID *Buf,
IN UINTN Length
);
EFI_STATUS
UsbGetMaxPacketSize0 (
IN USB_DEVICE *UsbDev
);
VOID
UsbFreeDevDesc (
IN USB_DEVICE_DESC *DevDesc
);
EFI_USB_STRING_DESCRIPTOR*
UsbGetOneString (
IN USB_DEVICE *UsbDev,
IN UINT8 StringIndex,
IN UINT16 LangId
);
EFI_STATUS
UsbBuildDescTable (
IN USB_DEVICE *UsbDev
);
EFI_STATUS
UsbSetAddress (
IN USB_DEVICE *UsbDev,
IN UINT8 Address
);
EFI_STATUS
UsbSetConfig (
IN USB_DEVICE *UsbDev,
IN UINT8 ConfigIndex
);
EFI_STATUS
UsbIoClearFeature (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN UINTN Target,
IN UINT16 Feature,
IN UINT16 Index
);
#endif

View File

@ -0,0 +1,991 @@
/** @file
Copyright (c) 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
UsbEnumer.c
Abstract:
Usb bus enumeration support
Revision History
**/
#include "UsbBus.h"
/**
Return the endpoint descriptor in this interface
@param UsbIf The interface to search in
@param EpAddr The address of the endpoint to return
@return The endpoint descriptor or NULL
**/
USB_ENDPOINT_DESC *
UsbGetEndpointDesc (
IN USB_INTERFACE *UsbIf,
IN UINT8 EpAddr
)
{
USB_ENDPOINT_DESC *EpDesc;
UINTN Index;
for (Index = 0; Index < UsbIf->IfSetting->Desc.NumEndpoints; Index++) {
EpDesc = UsbIf->IfSetting->Endpoints[Index];
if (EpDesc->Desc.EndpointAddress == EpAddr) {
return EpDesc;
}
}
return NULL;
}
/**
Free the resource used by USB interface
@param UsbIf The USB interface to free
@return None
**/
STATIC
VOID
UsbFreeInterface (
IN USB_INTERFACE *UsbIf
)
{
UsbCloseHostProtoByChild (UsbIf->Device->Bus, UsbIf->Handle);
gBS->UninstallMultipleProtocolInterfaces (
UsbIf->Handle,
&gEfiDevicePathProtocolGuid,
UsbIf->DevicePath,
&gEfiUsbIoProtocolGuid,
&UsbIf->UsbIo,
NULL
);
if (UsbIf->DevicePath != NULL) {
gBS->FreePool (UsbIf->DevicePath);
}
gBS->FreePool (UsbIf);
}
/**
Create an interface for the descriptor IfDesc. Each
device's configuration can have several interfaces.
@param Device The device has the interface descriptor
@param IfDesc The interface descriptor
@return The created USB interface for the descriptor, or NULL.
**/
STATIC
USB_INTERFACE *
UsbCreateInterface (
IN USB_DEVICE *Device,
IN USB_INTERFACE_DESC *IfDesc
)
{
USB_DEVICE_PATH UsbNode;
USB_INTERFACE *UsbIf;
USB_INTERFACE *HubIf;
EFI_STATUS Status;
UsbIf = AllocateZeroPool (sizeof (USB_INTERFACE));
if (UsbIf == NULL) {
return NULL;
}
UsbIf->Signature = USB_INTERFACE_SIGNATURE;
UsbIf->Device = Device;
UsbIf->IfDesc = IfDesc;
UsbIf->IfSetting = IfDesc->Settings[IfDesc->ActiveIndex];
UsbIf->UsbIo = mUsbIoProtocol;
//
// Install protocols for USBIO and device path
//
UsbNode.Header.Type = MESSAGING_DEVICE_PATH;
UsbNode.Header.SubType = MSG_USB_DP;
UsbNode.ParentPortNumber = Device->ParentPort;
UsbNode.InterfaceNumber = UsbIf->IfSetting->Desc.InterfaceNumber;
SetDevicePathNodeLength (&UsbNode.Header, sizeof (UsbNode));
HubIf = Device->ParentIf;
ASSERT (HubIf != NULL);
UsbIf->DevicePath = AppendDevicePathNode (HubIf->DevicePath, &UsbNode.Header);
if (UsbIf->DevicePath == NULL) {
USB_ERROR (("UsbCreateInterface: failed to create device path\n"));
Status = EFI_OUT_OF_RESOURCES;
goto ON_ERROR;
}
Status = gBS->InstallMultipleProtocolInterfaces (
&UsbIf->Handle,
&gEfiDevicePathProtocolGuid,
UsbIf->DevicePath,
&gEfiUsbIoProtocolGuid,
&UsbIf->UsbIo,
NULL
);
if (EFI_ERROR (Status)) {
USB_ERROR (("UsbCreateInterface: failed to install UsbIo - %r\n", Status));
goto ON_ERROR;
}
//
// Open USB Host Controller Protocol by Child
//
Status = UsbOpenHostProtoByChild (Device->Bus, UsbIf->Handle);
if (EFI_ERROR (Status)) {
gBS->UninstallMultipleProtocolInterfaces (
&UsbIf->Handle,
&gEfiDevicePathProtocolGuid,
UsbIf->DevicePath,
&gEfiUsbIoProtocolGuid,
&UsbIf->UsbIo,
NULL
);
USB_ERROR (("UsbCreateInterface: failed to open host for child - %r\n", Status));
goto ON_ERROR;
}
return UsbIf;
ON_ERROR:
if (UsbIf->DevicePath) {
gBS->FreePool (UsbIf->DevicePath);
}
gBS->FreePool (UsbIf);
return NULL;
}
/**
Free the resource used by this USB device
@param Device The USB device to free
@return None
**/
STATIC
VOID
UsbFreeDevice (
IN USB_DEVICE *Device
)
{
if (Device->DevDesc != NULL) {
UsbFreeDevDesc (Device->DevDesc);
}
gBS->FreePool (Device);
}
/**
Create a device which is on the parent's ParentPort port.
@param ParentIf The parent HUB interface
@param ParentPort The port on the HUB this device is connected to
@return Created USB device
**/
STATIC
USB_DEVICE *
UsbCreateDevice (
IN USB_INTERFACE *ParentIf,
IN UINT8 ParentPort
)
{
USB_DEVICE *Device;
ASSERT (ParentIf != NULL);
Device = AllocateZeroPool (sizeof (USB_DEVICE));
if (Device == NULL) {
return NULL;
}
Device->Bus = ParentIf->Device->Bus;
Device->MaxPacket0 = 8;
Device->ParentAddr = ParentIf->Device->Address;
Device->ParentIf = ParentIf;
Device->ParentPort = ParentPort;
return Device;
}
/**
Connect the USB interface with its driver. EFI USB bus will
create a USB interface for each seperate interface descriptor.
@param UsbIf The interface to connect driver to
@return EFI_SUCCESS : Interface is managed by some driver
@return Others : Failed to locate a driver for this interface
**/
STATIC
EFI_STATUS
UsbConnectDriver (
IN USB_INTERFACE *UsbIf
)
{
EFI_STATUS Status;
EFI_TPL OldTpl;
Status = EFI_SUCCESS;
//
// Hub is maintained by the USB bus driver. Otherwise try to
// connect drivers with this interface
//
if (UsbIsHubInterface (UsbIf)) {
USB_DEBUG (("UsbConnectDriver: found a hub device\n"));
Status = mUsbHubApi.Init (UsbIf);
} else {
//
// This function is called in both UsbIoControlTransfer and
// the timer callback in hub enumeration. So, at least it is
// called at TPL_CALLBACK. Some driver sitting on USB has
// twisted TPL used. It should be no problem for us to connect
// or disconnect at CALLBACK.
//
OldTpl = UsbGetCurrentTpl ();
USB_DEBUG (("UsbConnectDriver: TPL before connect is %d\n", OldTpl));
gBS->RestoreTPL (TPL_CALLBACK);
Status = gBS->ConnectController (UsbIf->Handle, NULL, NULL, TRUE);
UsbIf->IsManaged = (BOOLEAN)!EFI_ERROR (Status);
USB_DEBUG (("UsbConnectDriver: TPL after connect is %d\n", UsbGetCurrentTpl()));
ASSERT (UsbGetCurrentTpl () == TPL_CALLBACK);
gBS->RaiseTPL (OldTpl);
}
return Status;
}
/**
Select an alternate setting for the interface.
Each interface can have several mutually exclusive
settings. Only one setting is active. It will
also reset its endpoints' toggle to zero.
@param IfDesc The interface descriptor to set
@param Alternate The alternate setting number to locate
@retval EFI_NOT_FOUND There is no setting with this alternate index
@retval EFI_SUCCESS The interface is set to Alternate setting.
**/
EFI_STATUS
UsbSelectSetting (
IN USB_INTERFACE_DESC *IfDesc,
IN UINT8 Alternate
)
{
USB_INTERFACE_SETTING *Setting;
UINT8 Index;
//
// Locate the active alternate setting
//
Setting = NULL;
for (Index = 0; Index < IfDesc->NumOfSetting; Index++) {
Setting = IfDesc->Settings[Index];
if (Setting->Desc.AlternateSetting == Alternate) {
break;
}
}
if (Index == IfDesc->NumOfSetting) {
return EFI_NOT_FOUND;
}
IfDesc->ActiveIndex = Index;
USB_DEBUG (("UsbSelectSetting: setting %d selected for interface %d\n",
Alternate, Setting->Desc.InterfaceNumber));
//
// Reset the endpoint toggle to zero
//
for (Index = 0; Index < Setting->Desc.NumEndpoints; Index++) {
Setting->Endpoints[Index]->Toggle = 0;
}
return EFI_SUCCESS;
}
/**
Select a new configuration for the device. Each
device may support several configurations.
@param Device The device to select configuration
@param ConfigValue The index of the configuration ( != 0)
@retval EFI_NOT_FOUND There is no configuration with the index
@retval EFI_OUT_OF_RESOURCES Failed to allocate resource
@retval EFI_SUCCESS The configuration is selected.
**/
EFI_STATUS
UsbSelectConfig (
IN USB_DEVICE *Device,
IN UINT8 ConfigValue
)
{
USB_DEVICE_DESC *DevDesc;
USB_CONFIG_DESC *ConfigDesc;
USB_INTERFACE_DESC *IfDesc;
USB_INTERFACE *UsbIf;
EFI_STATUS Status;
UINT8 Index;
//
// Locate the active config, then set the device's pointer
//
DevDesc = Device->DevDesc;
ConfigDesc = NULL;
for (Index = 0; Index < DevDesc->Desc.NumConfigurations; Index++) {
ConfigDesc = DevDesc->Configs[Index];
if (ConfigDesc->Desc.ConfigurationValue == ConfigValue) {
break;
}
}
if (Index == DevDesc->Desc.NumConfigurations) {
return EFI_NOT_FOUND;
}
Device->ActiveConfig = ConfigDesc;
USB_DEBUG (("UsbSelectConfig: config %d selected for device %d\n",
ConfigValue, Device->Address));
//
// Create interfaces for each USB interface descriptor.
//
for (Index = 0; Index < ConfigDesc->Desc.NumInterfaces; Index++) {
//
// First select the default interface setting, and reset
// the endpoint toggles to zero for its endpoints.
//
IfDesc = ConfigDesc->Interfaces[Index];
UsbSelectSetting (IfDesc, IfDesc->Settings[0]->Desc.AlternateSetting);
//
// Create a USB_INTERFACE and install USB_IO and other protocols
//
UsbIf = UsbCreateInterface (Device, ConfigDesc->Interfaces[Index]);
if (UsbIf == NULL) {
return EFI_OUT_OF_RESOURCES;
}
Device->Interfaces[Index] = UsbIf;
//
// Connect the device to drivers, if it failed, ignore
// the error. Don't let the unsupported interfaces to block
// the supported interfaces.
//
Status = UsbConnectDriver (UsbIf);
if (EFI_ERROR (Status)) {
USB_ERROR (("UsbSelectConfig: failed to connect driver %r, ignored\n", Status));
}
}
Device->NumOfInterface = Index;
return EFI_SUCCESS;
}
/**
Disconnect the USB interface with its driver.
@param UsbIf The interface to disconnect driver from
@return None
**/
STATIC
VOID
UsbDisconnectDriver (
IN USB_INTERFACE *UsbIf
)
{
EFI_TPL OldTpl;
//
// Release the hub if it's a hub controller, otherwise
// disconnect the driver if it is managed by other drivers.
//
if (UsbIf->IsHub) {
UsbIf->HubApi->Release (UsbIf);
} else if (UsbIf->IsManaged) {
//
// This function is called in both UsbIoControlTransfer and
// the timer callback in hub enumeration. So, at least it is
// called at TPL_CALLBACK. Some driver sitting on USB has
// twisted TPL used. It should be no problem for us to connect
// or disconnect at CALLBACK.
//
OldTpl = UsbGetCurrentTpl ();
USB_DEBUG (("UsbDisconnectDriver: old TPL is %d\n", OldTpl));
gBS->RestoreTPL (TPL_CALLBACK);
gBS->DisconnectController (UsbIf->Handle, NULL, NULL);
UsbIf->IsManaged = FALSE;
USB_DEBUG (("UsbDisconnectDriver: TPL after disconnect is %d\n", UsbGetCurrentTpl()));
ASSERT (UsbGetCurrentTpl () == TPL_CALLBACK);
gBS->RaiseTPL (OldTpl);
}
}
/**
Remove the current device configuration
@param Device The USB device to remove configuration from
@return None
**/
VOID
UsbRemoveConfig (
IN USB_DEVICE *Device
)
{
USB_INTERFACE *UsbIf;
UINTN Index;
//
// Remove each interface of the device
//
for (Index = 0; Index < Device->NumOfInterface; Index++) {
UsbIf = Device->Interfaces[Index];
if (UsbIf == NULL) {
continue;
}
UsbDisconnectDriver (UsbIf);
UsbFreeInterface (UsbIf);
Device->Interfaces[Index] = NULL;
}
Device->ActiveConfig = NULL;
Device->NumOfInterface = 0;
}
/**
Remove the device and all its children from the bus.
@param Device The device to remove
@retval EFI_SUCCESS The device is removed
**/
EFI_STATUS
UsbRemoveDevice (
IN USB_DEVICE *Device
)
{
USB_BUS *Bus;
USB_DEVICE *Child;
EFI_STATUS Status;
UINT8 Index;
Bus = Device->Bus;
//
// Remove all the devices on its downstream ports. Search from devices[1].
// Devices[0] is the root hub.
//
for (Index = 1; Index < USB_MAX_DEVICES; Index++) {
Child = Bus->Devices[Index];
if ((Child == NULL) || (Child->ParentAddr != Device->Address)) {
continue;
}
Status = UsbRemoveDevice (Child);
if (EFI_ERROR (Status)) {
USB_ERROR (("UsbRemoveDevice: failed to remove child, ignore error\n"));
Bus->Devices[Index] = NULL;
}
}
UsbRemoveConfig (Device);
USB_DEBUG (("UsbRemoveDevice: device %d removed\n", Device->Address));
Bus->Devices[Device->Address] = NULL;
UsbFreeDevice (Device);
return EFI_SUCCESS;
}
/**
Find the child device on the hub's port
@param HubIf The hub interface
@param Port The port of the hub this child is connected to
@return The device on the hub's port, or NULL if there is none
**/
STATIC
USB_DEVICE *
UsbFindChild (
IN USB_INTERFACE *HubIf,
IN UINT8 Port
)
{
USB_DEVICE *Device;
USB_BUS *Bus;
UINTN Index;
Bus = HubIf->Device->Bus;
//
// Start checking from device 1, device 0 is the root hub
//
for (Index = 1; Index < USB_MAX_DEVICES; Index++) {
Device = Bus->Devices[Index];
if ((Device != NULL) && (Device->ParentAddr == HubIf->Device->Address) &&
(Device->ParentPort == Port)) {
return Device;
}
}
return NULL;
}
/**
Enumerate and configure the new device on the port of this HUB interface.
@param HubIf The HUB that has the device connected
@param Port The port index of the hub (started with zero)
@retval EFI_SUCCESS The device is enumerated (added or removed)
@retval EFI_OUT_OF_RESOURCES Failed to allocate resource for the device
@retval Others Failed to enumerate the device
**/
STATIC
EFI_STATUS
UsbEnumerateNewDev (
IN USB_INTERFACE *HubIf,
IN UINT8 Port
)
{
USB_BUS *Bus;
USB_HUB_API *HubApi;
USB_DEVICE *Child;
USB_DEVICE *Parent;
EFI_USB_PORT_STATUS PortState;
UINT8 Address;
UINT8 Config;
EFI_STATUS Status;
Address = USB_MAX_DEVICES;
Parent = HubIf->Device;
Bus = Parent->Bus;
HubApi = HubIf->HubApi;
//
// Wait at least 100 ms for the power on port to stable
//
gBS->Stall (100 * USB_STALL_1_MS);
//
// Hub resets the device for at least 10 milliseconds.
// Host learns device speed. If device is of low/full speed
// and the hub is a EHCI root hub, ResetPort will release
// the device to its companion UHCI and return an error.
//
Status = HubApi->ResetPort (HubIf, Port);
if (EFI_ERROR (Status)) {
USB_ERROR (("UsbEnumerateNewDev: failed to reset port %d - %r\n", Port, Status));
return Status;
}
USB_DEBUG (("UsbEnumerateNewDev: hub port %d is reset\n", Port));
Child = UsbCreateDevice (HubIf, Port);
if (Child == NULL) {
return EFI_OUT_OF_RESOURCES;
}
//
// OK, now identify the device speed. After reset, hub
// fully knows the actual device speed.
//
Status = HubApi->GetPortStatus (HubIf, Port, &PortState);
if (EFI_ERROR (Status)) {
USB_ERROR (("UsbEnumerateNewDev: failed to get speed of port %d\n", Port));
goto ON_ERROR;
}
if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_LOW_SPEED)) {
Child->Speed = EFI_USB_SPEED_LOW;
} else if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_HIGH_SPEED)) {
Child->Speed = EFI_USB_SPEED_HIGH;
} else {
Child->Speed = EFI_USB_SPEED_FULL;
}
USB_DEBUG (("UsbEnumerateNewDev: device is of %d speed\n", Child->Speed));
if (Child->Speed != EFI_USB_SPEED_HIGH) {
//
// If the child isn't a high speed device, it is necessary to
// set the transaction translator. This is quite simple:
// 1. if parent is of high speed, then parent is our translator
// 2. otherwise use parent's translator.
//
if (Parent->Speed == EFI_USB_SPEED_HIGH) {
Child->Translator.TranslatorHubAddress = Parent->Address;
Child->Translator.TranslatorPortNumber = Port;
} else {
Child->Translator = Parent->Translator;
}
USB_DEBUG (("UsbEnumerateNewDev: device uses translator (%d, %d)\n",
Child->Translator.TranslatorHubAddress,
Child->Translator.TranslatorPortNumber));
}
//
// After port is reset, hub establishes a signal path between
// the device and host (DEFALUT state). Device<63><65>s registers are
// reset, use default address 0 (host enumerates one device at
// a time) , and ready to respond to control transfer at EP 0.
//
//
// Host sends a Get_Descriptor request to learn the max packet
// size of default pipe (only part of the device<63><65>s descriptor).
//
Status = UsbGetMaxPacketSize0 (Child);
if (EFI_ERROR (Status)) {
USB_ERROR (("UsbEnumerateNewDev: failed to get max packet for EP 0 - %r\n", Status));
goto ON_ERROR;
}
USB_DEBUG (("UsbEnumerateNewDev: max packet size for EP 0 is %d\n", Child->MaxPacket0));
//
// Host assigns an address to the device. Device completes the
// status stage with default address, then switches to new address.
// ADDRESS state. Address zero is reserved for root hub.
//
for (Address = 1; Address < USB_MAX_DEVICES; Address++) {
if (Bus->Devices[Address] == NULL) {
break;
}
}
if (Address == USB_MAX_DEVICES) {
USB_ERROR (("UsbEnumerateNewDev: address pool is full for port %d\n", Port));
Status = EFI_ACCESS_DENIED;
goto ON_ERROR;
}
Bus->Devices[Address] = Child;
Status = UsbSetAddress (Child, Address);
Child->Address = Address;
if (EFI_ERROR (Status)) {
USB_ERROR (("UsbEnumerateNewDev: failed to set device address - %r\n", Status));
goto ON_ERROR;
}
//
// Wait 20ms for set address to complete
//
gBS->Stall (20 * USB_STALL_1_MS);
USB_DEBUG (("UsbEnumerateNewDev: device is now ADDRESSED at %d\n", Address));
//
// Host learns about the device<63><65>s abilities by requesting device's
// entire descriptions.
//
Status = UsbBuildDescTable (Child);
if (EFI_ERROR (Status)) {
USB_ERROR (("UsbEnumerateNewDev: failed to build descriptor table - %r\n", Status));
goto ON_ERROR;
}
//
// Select a default configuration: UEFI must set the configuration
// before the driver can connect to the device.
//
Config = Child->DevDesc->Configs[0]->Desc.ConfigurationValue;
Status = UsbSetConfig (Child, Config);
if (EFI_ERROR (Status)) {
USB_ERROR (("UsbEnumerateNewDev: failed to set configure %d - %r\n", Config, Status));
goto ON_ERROR;
}
USB_DEBUG (("UsbEnumerateNewDev: device %d is now in CONFIGED state\n", Address));
//
// Host assigns and loads a device driver.
//
Status = UsbSelectConfig (Child, Config);
if (EFI_ERROR (Status)) {
USB_ERROR (("UsbEnumerateNewDev: failed to create interfaces - %r\n", Status));
goto ON_ERROR;
}
return EFI_SUCCESS;
ON_ERROR:
if (Address != USB_MAX_DEVICES) {
Bus->Devices[Address] = NULL;
}
if (Child != NULL) {
UsbFreeDevice (Child);
}
return Status;
}
/**
Process the events on the port.
@param HubIf The HUB that has the device connected
@param Port The port index of the hub (started with zero)
@retval EFI_SUCCESS The device is enumerated (added or removed)
@retval EFI_OUT_OF_RESOURCES Failed to allocate resource for the device
@retval Others Failed to enumerate the device
**/
STATIC
EFI_STATUS
UsbEnumeratePort (
IN USB_INTERFACE *HubIf,
IN UINT8 Port
)
{
USB_HUB_API *HubApi;
USB_DEVICE *Child;
EFI_USB_PORT_STATUS PortState;
EFI_STATUS Status;
Child = NULL;
HubApi = HubIf->HubApi;
//
// Host learns of the new device by polling the hub for port changes.
//
Status = HubApi->GetPortStatus (HubIf, Port, &PortState);
if (EFI_ERROR (Status)) {
USB_ERROR (("UsbEnumeratePort: failed to get state of port %d\n", Port));
return Status;
}
if (PortState.PortChangeStatus == 0) {
return EFI_SUCCESS;
}
USB_DEBUG (("UsbEnumeratePort: port %d state - %x, change - %x\n",
Port, PortState.PortStatus, PortState.PortChangeStatus));
//
// This driver only process two kinds of events now: over current and
// connect/disconnect. Other three events are: ENABLE, SUSPEND, RESET.
// ENABLE/RESET is used to reset port. SUSPEND isn't supported.
//
Status = EFI_SUCCESS;
if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_OVERCURRENT)) {
//
// If overcurrent condition is cleared, enable the port again
//
if (!USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_OVERCURRENT)) {
HubApi->SetPortFeature (HubIf, Port, USB_HUB_PORT_POWER);
}
} else if (USB_BIT_IS_SET (PortState.PortChangeStatus, USB_PORT_STAT_C_CONNECTION)) {
//
// Device connected or disconnected. Either way, if there is
// already a device present in the bus, need to remove it.
//
Child = UsbFindChild (HubIf, Port);
if (Child != NULL) {
USB_DEBUG (("UsbEnumeratePort: device at port %d removed from system\n", Port));
UsbRemoveDevice (Child);
}
if (USB_BIT_IS_SET (PortState.PortStatus, USB_PORT_STAT_CONNECTION)) {
//
// Now, new device connected, enumerate and configure the device
//
USB_DEBUG (("UsbEnumeratePort: new device connected at port %d\n", Port));
Status = UsbEnumerateNewDev (HubIf, Port);
} else {
USB_DEBUG (("UsbEnumeratePort: device disconnected event on port %d\n", Port));
}
}
HubApi->ClearPortChange (HubIf, Port);
return Status;
}
/**
Enumerate all the changed hub ports
@param Event The event that is triggered
@param Context The context to the event
@return None
**/
VOID
UsbHubEnumeration (
IN EFI_EVENT Event,
IN VOID *Context
)
{
USB_INTERFACE *HubIf;
UINT8 Byte;
UINT8 Bit;
UINT8 Index;
ASSERT (Context);
HubIf = (USB_INTERFACE *) Context;
if (HubIf->ChangeMap == NULL) {
return ;
}
//
// HUB starts its port index with 1.
//
Byte = 0;
Bit = 1;
for (Index = 0; Index < HubIf->NumOfPort; Index++) {
if (USB_BIT_IS_SET (HubIf->ChangeMap[Byte], USB_BIT (Bit))) {
UsbEnumeratePort (HubIf, Index);
}
USB_NEXT_BIT (Byte, Bit);
}
UsbHubAckHubStatus (HubIf->Device);
gBS->FreePool (HubIf->ChangeMap);
HubIf->ChangeMap = NULL;
return ;
}
/**
Enumerate all the changed hub ports
@param Event The event that is triggered
@param Context The context to the event
@return None
**/
VOID
UsbRootHubEnumeration (
IN EFI_EVENT Event,
IN VOID *Context
)
{
USB_INTERFACE *RootHub;
UINT8 Index;
RootHub = (USB_INTERFACE *) Context;
for (Index = 0; Index < RootHub->NumOfPort; Index++) {
UsbEnumeratePort (RootHub, Index);
}
}

View File

@ -0,0 +1,153 @@
/** @file
Copyright (c) 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
UsbEnumer.h
Abstract:
USB bus enumeration interface
Revision History
**/
#ifndef _USB_ENUMERATION_H_
#define _USB_ENUMERATION_H_
//
// Advance the byte and bit to the next bit, adjust byte accordingly.
//
#define USB_NEXT_BIT(Byte, Bit) \
do { \
(Bit)++; \
if ((Bit) > 7) { \
(Byte)++; \
(Bit) = 0; \
} \
} while (0)
//
// Common interface used by usb bus enumeration process.
// This interface is defined to mask the difference between
// the root hub and normal hub. So, bus enumeration code
// can be shared by both root hub and normal hub
//
typedef
EFI_STATUS
(*USB_HUB_INIT) (
IN USB_INTERFACE *UsbIf
);
//
// Get the port status. This function is required to
// ACK the port change bits although it will return
// the port changes in PortState. Bus enumeration code
// doesn't need to ACK the port change bits.
//
typedef
EFI_STATUS
(*USB_HUB_GET_PORT_STATUS) (
IN USB_INTERFACE *UsbIf,
IN UINT8 Port,
OUT EFI_USB_PORT_STATUS *PortState
);
typedef
VOID
(*USB_HUB_CLEAR_PORT_CHANGE) (
IN USB_INTERFACE *HubIf,
IN UINT8 Port
);
typedef
EFI_STATUS
(*USB_HUB_SET_PORT_FEATURE) (
IN USB_INTERFACE *UsbIf,
IN UINT8 Port,
IN EFI_USB_PORT_FEATURE Feature
);
typedef
EFI_STATUS
(*USB_HUB_CLEAR_PORT_FEATURE) (
IN USB_INTERFACE *UsbIf,
IN UINT8 Port,
IN EFI_USB_PORT_FEATURE Feature
);
typedef
EFI_STATUS
(*USB_HUB_RESET_PORT) (
IN USB_INTERFACE *UsbIf,
IN UINT8 Port
);
typedef
EFI_STATUS
(*USB_HUB_RELEASE) (
IN USB_INTERFACE *UsbIf
);
typedef struct _USB_HUB_API{
USB_HUB_INIT Init;
USB_HUB_GET_PORT_STATUS GetPortStatus;
USB_HUB_CLEAR_PORT_CHANGE ClearPortChange;
USB_HUB_SET_PORT_FEATURE SetPortFeature;
USB_HUB_CLEAR_PORT_FEATURE ClearPortFeature;
USB_HUB_RESET_PORT ResetPort;
USB_HUB_RELEASE Release;
} USB_HUB_API;
USB_ENDPOINT_DESC*
UsbGetEndpointDesc (
IN USB_INTERFACE *UsbIf,
IN UINT8 EpAddr
);
EFI_STATUS
UsbSelectSetting (
IN USB_INTERFACE_DESC *IfDesc,
IN UINT8 Alternate
);
EFI_STATUS
UsbSelectConfig (
IN USB_DEVICE *Device,
IN UINT8 ConfigIndex
);
VOID
UsbRemoveConfig (
IN USB_DEVICE *Device
);
EFI_STATUS
UsbRemoveDevice (
IN USB_DEVICE *Device
);
VOID
UsbHubEnumeration (
IN EFI_EVENT Event,
IN VOID *Context
);
VOID
UsbRootHubEnumeration (
IN EFI_EVENT Event,
IN VOID *Context
);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,140 @@
/** @file
Copyright (c) 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
UsbHub.h
Abstract:
The definition for USB hub
Revision History
**/
#ifndef _USB_HUB_H_
#define _USB_HUB_H_
#define USB_ENDPOINT_ADDR(EpAddr) ((EpAddr) & 0x7F)
#define USB_ENDPOINT_TYPE(Desc) ((Desc)->Attributes & USB_ENDPOINT_TYPE_MASK)
enum {
USB_DESC_TYPE_HUB = 0x29,
//
// Hub class control transfer target
//
USB_HUB_TARGET_HUB = 0,
USB_HUB_TARGET_PORT = 3,
//
// HUB class specific contrl transfer request type
//
USB_HUB_REQ_GET_STATUS = 0,
USB_HUB_REQ_CLEAR_FEATURE = 1,
USB_HUB_REQ_SET_FEATURE = 3,
USB_HUB_REQ_GET_DESC = 6,
USB_HUB_REQ_SET_DESC = 7,
USB_HUB_REQ_CLEAR_TT = 8,
USB_HUB_REQ_RESET_TT = 9,
USB_HUB_REQ_GET_TT_STATE = 10,
USB_HUB_REQ_STOP_TT = 11,
//
// USB hub class feature selector
//
USB_HUB_C_HUB_LOCAL_POWER = 0,
USB_HUB_C_HUB_OVER_CURRENT = 1,
USB_HUB_PORT_CONNECTION = 0,
USB_HUB_PORT_ENABLE = 1,
USB_HUB_PORT_SUSPEND = 2,
USB_HUB_PORT_OVER_CURRENT = 3,
USB_HUB_PORT_RESET = 4,
USB_HUB_PORT_POWER = 8,
USB_HUB_PORT_LOW_SPEED = 9,
USB_HUB_C_PORT_CONNECT = 16,
USB_HUB_C_PORT_ENABLE = 17,
USB_HUB_C_PORT_SUSPEND = 18,
USB_HUB_C_PORT_OVER_CURRENT = 19,
USB_HUB_C_PORT_RESET = 20,
USB_HUB_PORT_TEST = 21,
USB_HUB_PORT_INDICATOR = 22,
//
// USB hub power control method. In gang power control
//
USB_HUB_GANG_POWER_CTRL = 0,
USB_HUB_PORT_POWER_CTRL = 0x01,
//
// USB hub status bits
//
USB_HUB_STAT_LOCAL_POWER = 0x01,
USB_HUB_STAT_OVER_CURRENT = 0x02,
USB_HUB_STAT_C_LOCAL_POWER = 0x01,
USB_HUB_STAT_C_OVER_CURRENT = 0x02,
USB_HUB_CLASS_CODE = 0x09,
USB_HUB_SUBCLASS_CODE = 0x00,
USB_HUB_LOOP = 50,
};
#pragma pack(1)
//
// Hub descriptor, the last two fields are of variable lenght.
//
typedef struct {
UINT8 Length;
UINT8 DescType;
UINT8 NumPorts;
UINT16 HubCharacter;
UINT8 PwrOn2PwrGood;
UINT8 HubContrCurrent;
UINT8 Filler[16];
} EFI_USB_HUB_DESCRIPTOR;
#pragma pack()
typedef struct {
UINT16 ChangedBit;
EFI_USB_PORT_FEATURE Feature;
} USB_CHANGE_FEATURE_MAP;
EFI_STATUS
UsbHubCtrlClearTTBuffer (
IN USB_DEVICE *UsbDev,
IN UINT8 Port,
IN UINT16 DevAddr,
IN UINT16 EpNum,
IN UINT16 EpType
);
BOOLEAN
UsbIsHubInterface (
IN USB_INTERFACE *UsbIf
);
EFI_STATUS
UsbHubAckHubStatus (
IN USB_DEVICE *UsbDev
);
extern USB_HUB_API mUsbHubApi;
extern USB_HUB_API mUsbRootHubApi;
#endif

View File

@ -0,0 +1,769 @@
/** @file
Copyright (c) 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
UsbUtility.c
Abstract:
Wrapper function for usb host controller interface
Revision History
**/
#include "UsbBus.h"
/**
Get the capability of the host controller
@param UsbBus The usb driver
@param MaxSpeed The maximum speed this host controller supports
@param NumOfPort The number of the root hub port
@param Is64BitCapable Whether this controller support 64 bit addressing
@retval EFI_SUCCESS The host controller capability is returned
@retval Others Failed to retrieve the host controller capability.
**/
EFI_STATUS
UsbHcGetCapability (
IN USB_BUS *UsbBus,
OUT UINT8 *MaxSpeed,
OUT UINT8 *NumOfPort,
OUT UINT8 *Is64BitCapable
)
{
EFI_STATUS Status;
if (UsbBus->Usb2Hc != NULL) {
Status = UsbBus->Usb2Hc->GetCapability (
UsbBus->Usb2Hc,
MaxSpeed,
NumOfPort,
Is64BitCapable
);
} else {
Status = UsbBus->UsbHc->GetRootHubPortNumber (UsbBus->UsbHc, NumOfPort);
*MaxSpeed = EFI_USB_SPEED_FULL;
*Is64BitCapable = (UINT8) FALSE;
}
return Status;
}
/**
Reset the host controller
@param UsbBus The usb bus driver
@param Attributes The reset type, only global reset is used by this driver
@return GC_TODO: add return values
**/
EFI_STATUS
UsbHcReset (
IN USB_BUS *UsbBus,
IN UINT16 Attributes
)
{
EFI_STATUS Status;
if (UsbBus->Usb2Hc != NULL) {
Status = UsbBus->Usb2Hc->Reset (UsbBus->Usb2Hc, Attributes);
} else {
Status = UsbBus->UsbHc->Reset (UsbBus->UsbHc, Attributes);
}
return Status;
}
/**
Get the current operation state of the host controller
@param UsbBus The USB bus driver
@param State The host controller operation state
@retval EFI_SUCCESS The operation state is returned in State
@retval Others Failed to get the host controller state
**/
EFI_STATUS
UsbHcGetState (
IN USB_BUS *UsbBus,
OUT EFI_USB_HC_STATE *State
)
{
EFI_STATUS Status;
if (UsbBus->Usb2Hc != NULL) {
Status = UsbBus->Usb2Hc->GetState (UsbBus->Usb2Hc, State);
} else {
Status = UsbBus->UsbHc->GetState (UsbBus->UsbHc, State);
}
return Status;
}
/**
Set the host controller operation state
@param UsbBus The USB bus driver
@param State The state to set
@retval EFI_SUCCESS The host controller is now working at State
@retval Others Failed to set operation state
**/
EFI_STATUS
UsbHcSetState (
IN USB_BUS *UsbBus,
IN EFI_USB_HC_STATE State
)
{
EFI_STATUS Status;
if (UsbBus->Usb2Hc != NULL) {
Status = UsbBus->Usb2Hc->SetState (UsbBus->Usb2Hc, State);
} else {
Status = UsbBus->UsbHc->SetState (UsbBus->UsbHc, State);
}
return Status;
}
/**
Get the root hub port state
@param UsbBus The USB bus driver
@param PortIndex The index of port
@param PortStatus The variable to save port state
@retval EFI_SUCCESS The root port state is returned in
@retval Others Failed to get the root hub port state
**/
EFI_STATUS
UsbHcGetRootHubPortStatus (
IN USB_BUS *UsbBus,
IN UINT8 PortIndex,
OUT EFI_USB_PORT_STATUS *PortStatus
)
{
EFI_STATUS Status;
if (UsbBus->Usb2Hc != NULL) {
Status = UsbBus->Usb2Hc->GetRootHubPortStatus (UsbBus->Usb2Hc, PortIndex, PortStatus);
} else {
Status = UsbBus->UsbHc->GetRootHubPortStatus (UsbBus->UsbHc, PortIndex, PortStatus);
}
return Status;
}
/**
Set the root hub port feature
@param UsbBus The USB bus driver
@param PortIndex The port index
@param Feature The port feature to set
@retval EFI_SUCCESS The port feature is set
@retval Others Failed to set port feature
**/
EFI_STATUS
UsbHcSetRootHubPortFeature (
IN USB_BUS *UsbBus,
IN UINT8 PortIndex,
IN EFI_USB_PORT_FEATURE Feature
)
{
EFI_STATUS Status;
if (UsbBus->Usb2Hc != NULL) {
Status = UsbBus->Usb2Hc->SetRootHubPortFeature (UsbBus->Usb2Hc, PortIndex, Feature);
} else {
Status = UsbBus->UsbHc->SetRootHubPortFeature (UsbBus->UsbHc, PortIndex, Feature);
}
return Status;
}
/**
Clear the root hub port feature
@param UsbBus The USB bus driver
@param PortIndex The port index
@param Feature The port feature to clear
@retval EFI_SUCCESS The port feature is clear
@retval Others Failed to clear port feature
**/
EFI_STATUS
UsbHcClearRootHubPortFeature (
IN USB_BUS *UsbBus,
IN UINT8 PortIndex,
IN EFI_USB_PORT_FEATURE Feature
)
{
EFI_STATUS Status;
if (UsbBus->Usb2Hc != NULL) {
Status = UsbBus->Usb2Hc->ClearRootHubPortFeature (UsbBus->Usb2Hc, PortIndex, Feature);
} else {
Status = UsbBus->UsbHc->ClearRootHubPortFeature (UsbBus->UsbHc, PortIndex, Feature);
}
return Status;
}
/**
Execute a control transfer to the device
@param UsbBus The USB bus driver
@param DevAddr The device address
@param DevSpeed The device speed
@param MaxPacket Maximum packet size of endpoint 0
@param Request The control transfer request
@param Direction The direction of data stage
@param Data The buffer holding data
@param DataLength The length of the data
@param TimeOut Timeout (in ms) to wait until timeout
@param Translator The transaction translator for low/full speed device
@param UsbResult The result of transfer
@retval EFI_SUCCESS The control transfer finished without error
@retval Others The control transfer failed, reason returned in UsbReslt
**/
EFI_STATUS
UsbHcControlTransfer (
IN USB_BUS *UsbBus,
IN UINT8 DevAddr,
IN UINT8 DevSpeed,
IN UINTN MaxPacket,
IN EFI_USB_DEVICE_REQUEST *Request,
IN EFI_USB_DATA_DIRECTION Direction,
IN OUT VOID *Data,
IN OUT UINTN *DataLength,
IN UINTN TimeOut,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *UsbResult
)
{
EFI_STATUS Status;
BOOLEAN IsSlowDevice;
if (UsbBus->Usb2Hc != NULL) {
Status = UsbBus->Usb2Hc->ControlTransfer (
UsbBus->Usb2Hc,
DevAddr,
DevSpeed,
MaxPacket,
Request,
Direction,
Data,
DataLength,
TimeOut,
Translator,
UsbResult
);
} else {
IsSlowDevice = (BOOLEAN)(EFI_USB_SPEED_LOW == DevSpeed);
Status = UsbBus->UsbHc->ControlTransfer (
UsbBus->UsbHc,
DevAddr,
IsSlowDevice,
(UINT8) MaxPacket,
Request,
Direction,
Data,
DataLength,
TimeOut,
UsbResult
);
}
return Status;
}
/**
Execute a bulk transfer to the device's endpoint
@param UsbBus The USB bus driver
@param DevAddr The target device address
@param EpAddr The target endpoint address, with direction encoded in
bit 7
@param DevSpeed The device's speed
@param MaxPacket The endpoint's max packet size
@param BufferNum The number of data buffer
@param Data Array of pointers to data buffer
@param DataLength The length of data buffer
@param DataToggle On input, the initial data toggle to use, also return
the next toggle on output.
@param TimeOut The time to wait until timeout
@param Translator The transaction translator for low/full speed device
@param UsbResult The result of USB execution
@retval EFI_SUCCESS The bulk transfer is finished without error
@retval Others Failed to execute bulk transfer, result in UsbResult
**/
EFI_STATUS
UsbHcBulkTransfer (
IN USB_BUS *UsbBus,
IN UINT8 DevAddr,
IN UINT8 EpAddr,
IN UINT8 DevSpeed,
IN UINTN MaxPacket,
IN UINT8 BufferNum,
IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
IN OUT UINTN *DataLength,
IN OUT UINT8 *DataToggle,
IN UINTN TimeOut,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *UsbResult
)
{
EFI_STATUS Status;
if (UsbBus->Usb2Hc != NULL) {
Status = UsbBus->Usb2Hc->BulkTransfer (
UsbBus->Usb2Hc,
DevAddr,
EpAddr,
DevSpeed,
MaxPacket,
BufferNum,
Data,
DataLength,
DataToggle,
TimeOut,
Translator,
UsbResult
);
} else {
Status = UsbBus->UsbHc->BulkTransfer (
UsbBus->UsbHc,
DevAddr,
EpAddr,
(UINT8) MaxPacket,
*Data,
DataLength,
DataToggle,
TimeOut,
UsbResult
);
}
return Status;
}
/**
Queue or cancel an asynchronous interrupt transfer
@param UsbBus The USB bus driver
@param DevAddr The target device address
@param EpAddr The target endpoint address, with direction encoded in
bit 7
@param DevSpeed The device's speed
@param MaxPacket The endpoint's max packet size
@param IsNewTransfer Whether this is a new request. If not, cancel the old
request
@param DataToggle Data toggle to use on input, next toggle on output
@param PollingInterval The interval to poll the interrupt transfer (in ms)
@param DataLength The length of periodical data receive
@param Translator The transaction translator for low/full speed device
@param Callback Function to call when data is received
@param Context The context to the callback
@retval EFI_SUCCESS The asynchronous transfer is queued
@retval Others Failed to queue the transfer
**/
EFI_STATUS
UsbHcAsyncInterruptTransfer (
IN USB_BUS *UsbBus,
IN UINT8 DevAddr,
IN UINT8 EpAddr,
IN UINT8 DevSpeed,
IN UINTN MaxPacket,
IN BOOLEAN IsNewTransfer,
IN OUT UINT8 *DataToggle,
IN UINTN PollingInterval,
IN UINTN DataLength,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,
IN VOID *Context OPTIONAL
)
{
EFI_STATUS Status;
BOOLEAN IsSlowDevice;
if (UsbBus->Usb2Hc != NULL) {
Status = UsbBus->Usb2Hc->AsyncInterruptTransfer (
UsbBus->Usb2Hc,
DevAddr,
EpAddr,
DevSpeed,
MaxPacket,
IsNewTransfer,
DataToggle,
PollingInterval,
DataLength,
Translator,
Callback,
Context
);
} else {
IsSlowDevice = (BOOLEAN)(EFI_USB_SPEED_LOW == DevSpeed);
Status = UsbBus->UsbHc->AsyncInterruptTransfer (
UsbBus->UsbHc,
DevAddr,
EpAddr,
IsSlowDevice,
(UINT8) MaxPacket,
IsNewTransfer,
DataToggle,
PollingInterval,
DataLength,
Callback,
Context
);
}
return Status;
}
/**
Execute a synchronous interrupt transfer to the target endpoint
@param UsbBus The USB bus driver
@param DevAddr The target device address
@param EpAddr The target endpoint address, with direction encoded in
bit 7
@param DevSpeed The device's speed
@param MaxPacket The endpoint's max packet size
@param Data Pointer to data buffer
@param DataLength The length of data buffer
@param DataToggle On input, the initial data toggle to use, also return
the next toggle on output.
@param TimeOut The time to wait until timeout
@param Translator The transaction translator for low/full speed device
@param UsbResult The result of USB execution
@retval EFI_SUCCESS The synchronous interrupt transfer is OK
@retval Others Failed to execute the synchronous interrupt transfer
**/
EFI_STATUS
UsbHcSyncInterruptTransfer (
IN USB_BUS *UsbBus,
IN UINT8 DevAddr,
IN UINT8 EpAddr,
IN UINT8 DevSpeed,
IN UINTN MaxPacket,
IN OUT VOID *Data,
IN OUT UINTN *DataLength,
IN OUT UINT8 *DataToggle,
IN UINTN TimeOut,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *UsbResult
)
{
EFI_STATUS Status;
BOOLEAN IsSlowDevice;
if (UsbBus->Usb2Hc != NULL) {
Status = UsbBus->Usb2Hc->SyncInterruptTransfer (
UsbBus->Usb2Hc,
DevAddr,
EpAddr,
DevSpeed,
MaxPacket,
Data,
DataLength,
DataToggle,
TimeOut,
Translator,
UsbResult
);
} else {
IsSlowDevice = (EFI_USB_SPEED_LOW == DevSpeed) ? TRUE : FALSE;
Status = UsbBus->UsbHc->SyncInterruptTransfer (
UsbBus->UsbHc,
DevAddr,
EpAddr,
IsSlowDevice,
(UINT8) MaxPacket,
Data,
DataLength,
DataToggle,
TimeOut,
UsbResult
);
}
return Status;
}
/**
Execute a synchronous Isochronous USB transfer
@param UsbBus The USB bus driver
@param DevAddr The target device address
@param EpAddr The target endpoint address, with direction encoded in
bit 7
@param DevSpeed The device's speed
@param MaxPacket The endpoint's max packet size
@param BufferNum The number of data buffer
@param Data Array of pointers to data buffer
@param DataLength The length of data buffer
@param Translator The transaction translator for low/full speed device
@param UsbResult The result of USB execution
@retval EFI_UNSUPPORTED The isochronous transfer isn't supported now
**/
EFI_STATUS
UsbHcIsochronousTransfer (
IN USB_BUS *UsbBus,
IN UINT8 DevAddr,
IN UINT8 EpAddr,
IN UINT8 DevSpeed,
IN UINTN MaxPacket,
IN UINT8 BufferNum,
IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
IN UINTN DataLength,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *UsbResult
)
{
return EFI_UNSUPPORTED;
}
/**
Queue an asynchronous isochronous transfer
@param UsbBus The USB bus driver
@param DevAddr The target device address
@param EpAddr The target endpoint address, with direction encoded in
bit 7
@param DevSpeed The device's speed
@param MaxPacket The endpoint's max packet size
@param BufferNum The number of data buffer
@param Data Array of pointers to data buffer
@param DataLength The length of data buffer
@param Translator The transaction translator for low/full speed device
@param Callback The function to call when data is transferred
@param Context The context to the callback function
@retval EFI_UNSUPPORTED The asynchronous isochronous transfer isn't supported
**/
EFI_STATUS
UsbHcAsyncIsochronousTransfer (
IN USB_BUS *UsbBus,
IN UINT8 DevAddr,
IN UINT8 EpAddr,
IN UINT8 DevSpeed,
IN UINTN MaxPacket,
IN UINT8 BufferNum,
IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
IN UINTN DataLength,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,
IN VOID *Context
)
{
return EFI_UNSUPPORTED;
}
/**
Open the USB host controller protocol BY_CHILD
@param Bus The USB bus driver
@param Child The child handle
@return The open protocol return
**/
EFI_STATUS
UsbOpenHostProtoByChild (
IN USB_BUS *Bus,
IN EFI_HANDLE Child
)
{
EFI_USB_HC_PROTOCOL *UsbHc;
EFI_USB2_HC_PROTOCOL *Usb2Hc;
EFI_STATUS Status;
if (Bus->Usb2Hc != NULL) {
Status = gBS->OpenProtocol (
Bus->HostHandle,
&gEfiUsb2HcProtocolGuid,
&Usb2Hc,
mUsbBusDriverBinding.DriverBindingHandle,
Child,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
} else {
Status = gBS->OpenProtocol (
Bus->HostHandle,
&gEfiUsbHcProtocolGuid,
&UsbHc,
mUsbBusDriverBinding.DriverBindingHandle,
Child,
EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
);
}
return Status;
}
/**
Close the USB host controller protocol BY_CHILD
@param Bus The USB bus driver
@param Child The child handle
@return None
**/
VOID
UsbCloseHostProtoByChild (
IN USB_BUS *Bus,
IN EFI_HANDLE Child
)
{
if (Bus->Usb2Hc != NULL) {
gBS->CloseProtocol (
Bus->HostHandle,
&gEfiUsb2HcProtocolGuid,
mUsbBusDriverBinding.DriverBindingHandle,
Child
);
} else {
gBS->CloseProtocol (
Bus->HostHandle,
&gEfiUsbHcProtocolGuid,
mUsbBusDriverBinding.DriverBindingHandle,
Child
);
}
}
/**
return the current TPL, copied from the EDKII glue lib.
VOID
@return Current TPL
**/
EFI_TPL
UsbGetCurrentTpl (
VOID
)
{
EFI_TPL Tpl;
Tpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);
gBS->RestoreTPL (Tpl);
return Tpl;
}
#ifdef EFI_DEBUG
VOID
UsbDebug (
IN CHAR8 *Format,
...
)
/*++
Routine Description:
USB's debug output function.
Arguments:
Format - The format parameters to the print
... - The variable length parameters after format
Returns:
None
--*/
{
VA_LIST Marker;
VA_START (Marker, Format);
DebugVPrint (DEBUG_INFO, Format, Marker);
VA_END (Marker);
}
/**
USB's error output function.
@param Format The format parameters to the print
@param ... The variable length parameters after format
@return None
**/
VOID
UsbError (
IN CHAR8 *Format,
...
)
{
VA_LIST Marker;
VA_START (Marker, Format);
DebugVPrint (DEBUG_ERROR, Format, Marker);
VA_END (Marker);
}
#endif

View File

@ -0,0 +1,220 @@
/** @file
Copyright (c) 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
UsbUtility.h
Abstract:
Manage Usb Port/Hc/Etc
Revision History
**/
#ifndef _USB_UTILITY_H
#define _USB_UTILITY_H
EFI_STATUS
UsbHcGetCapability (
IN USB_BUS *UsbBus,
OUT UINT8 *MaxSpeed,
OUT UINT8 *NumOfPort,
OUT UINT8 *Is64BitCapable
);
EFI_STATUS
UsbHcReset (
IN USB_BUS *UsbBus,
IN UINT16 Attributes
);
EFI_STATUS
UsbHcGetState (
IN USB_BUS *UsbBus,
OUT EFI_USB_HC_STATE *State
);
EFI_STATUS
UsbHcSetState (
IN USB_BUS *UsbBus,
IN EFI_USB_HC_STATE State
);
EFI_STATUS
UsbHcGetRootHubPortStatus (
IN USB_BUS *UsbBus,
IN UINT8 PortIndex,
OUT EFI_USB_PORT_STATUS *PortStatus
);
EFI_STATUS
UsbHcSetRootHubPortFeature (
IN USB_BUS *UsbBus,
IN UINT8 PortIndex,
IN EFI_USB_PORT_FEATURE Feature
);
EFI_STATUS
UsbHcClearRootHubPortFeature (
IN USB_BUS *UsbBus,
IN UINT8 PortIndex,
IN EFI_USB_PORT_FEATURE Feature
);
EFI_STATUS
UsbHcControlTransfer (
IN USB_BUS *UsbBus,
IN UINT8 DevAddr,
IN UINT8 DevSpeed,
IN UINTN MaxPacket,
IN EFI_USB_DEVICE_REQUEST *Request,
IN EFI_USB_DATA_DIRECTION Direction,
IN OUT VOID *Data,
IN OUT UINTN *DataLength,
IN UINTN TimeOut,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *UsbResult
);
EFI_STATUS
UsbHcBulkTransfer (
IN USB_BUS *UsbBus,
IN UINT8 DevAddr,
IN UINT8 EpAddr,
IN UINT8 DevSpeed,
IN UINTN MaxPacket,
IN UINT8 BufferNum,
IN OUT VOID *Data[EFI_USB_MAX_BULK_BUFFER_NUM],
IN OUT UINTN *DataLength,
IN OUT UINT8 *DataToggle,
IN UINTN TimeOut,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *UsbResult
);
EFI_STATUS
UsbHcAsyncInterruptTransfer (
IN USB_BUS *UsbBus,
IN UINT8 DevAddr,
IN UINT8 EpAddr,
IN UINT8 DevSpeed,
IN UINTN MaxPacket,
IN BOOLEAN IsNewTransfer,
IN OUT UINT8 *DataToggle,
IN UINTN PollingInterval,
IN UINTN DataLength,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,
IN VOID *Context OPTIONAL
);
EFI_STATUS
UsbHcSyncInterruptTransfer (
IN USB_BUS *UsbBus,
IN UINT8 DevAddr,
IN UINT8 EpAddr,
IN UINT8 DevSpeed,
IN UINTN MaxPacket,
IN OUT VOID *Data,
IN OUT UINTN *DataLength,
IN OUT UINT8 *DataToggle,
IN UINTN TimeOut,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *UsbResult
);
EFI_STATUS
UsbHcIsochronousTransfer (
IN USB_BUS *UsbBus,
IN UINT8 DevAddr,
IN UINT8 EpAddr,
IN UINT8 DevSpeed,
IN UINTN MaxPacket,
IN UINT8 BufferNum,
IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
IN UINTN DataLength,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
OUT UINT32 *UsbResult
);
EFI_STATUS
UsbHcAsyncIsochronousTransfer (
IN USB_BUS *UsbBus,
IN UINT8 DevAddr,
IN UINT8 EpAddr,
IN UINT8 DevSpeed,
IN UINTN MaxPacket,
IN UINT8 BufferNum,
IN OUT VOID *Data[EFI_USB_MAX_ISO_BUFFER_NUM],
IN UINTN DataLength,
IN EFI_USB2_HC_TRANSACTION_TRANSLATOR *Translator,
IN EFI_ASYNC_USB_TRANSFER_CALLBACK Callback,
IN VOID *Context
);
EFI_STATUS
UsbOpenHostProtoByChild (
IN USB_BUS *Bus,
IN EFI_HANDLE Child
);
VOID
UsbCloseHostProtoByChild (
IN USB_BUS *Bus,
IN EFI_HANDLE Child
);
EFI_TPL
UsbGetCurrentTpl (
VOID
);
//
// USB debug support routines
//
#ifdef EFI_DEBUG
#define USB_DEBUG(arg) UsbDebug arg
#define USB_ERROR(arg) UsbError arg
#else
#define USB_DEBUG(arg)
#define USB_ERROR(arg)
#endif
VOID
UsbDebug (
IN CHAR8 *Format,
...
);
VOID
UsbError (
IN CHAR8 *Format,
...
);
#endif

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,210 @@
/** @file
Copyright (c) 2004 - 2007, Intel Corporation
All rights reserved. This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
Module Name:
UsbBus.h
Abstract:
Usb Bus Driver Binding and Bus IO Protocol
Revision History
**/
#ifndef _EFI_USB_BUS_H_
#define _EFI_USB_BUS_H_
//
// The package level header files this module uses
//
#include <PiDxe.h>
//
// The protocols, PPI and GUID defintions for this module
//
#include <Protocol/Usb2HostController.h>
#include <Protocol/UsbHostController.h>
#include <Protocol/UsbIo.h>
#include <Protocol/DevicePath.h>
//
// The Library classes this module consumes
//
#include <Library/DebugLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/UefiLib.h>
#include <Library/DevicePathLib.h>
#include <Library/MemoryAllocationLib.h>
#include <IndustryStandard/Usb.h>
typedef struct _USB_DEVICE USB_DEVICE;
typedef struct _USB_INTERFACE USB_INTERFACE;
typedef struct _USB_BUS USB_BUS;
typedef struct _USB_HUB_API USB_HUB_API;
#include "UsbUtility.h"
#include "UsbDesc.h"
#include "UsbHub.h"
#include "UsbEnumer.h"
enum {
//
// Time definition
//
USB_STALL_1_MS = 1000,
TICKS_PER_MS = 10000U,
USB_ROOTHUB_POLL_INTERVAL = 1000 * TICKS_PER_MS,
USB_HUB_POLL_INTERVAL = 64,
//
// Maximum definition
//
USB_MAX_LANG_ID = 16,
USB_MAX_INTERFACE = 16,
USB_MAX_DEVICES = 128,
//
// Bus raises TPL to TPL_NOTIFY to serialize all its operations
// to protect shared data structures.
//
USB_BUS_TPL = TPL_NOTIFY,
USB_INTERFACE_SIGNATURE = EFI_SIGNATURE_32 ('U', 'S', 'B', 'I'),
USB_BUS_SIGNATURE = EFI_SIGNATURE_32 ('U', 'S', 'B', 'B'),
};
#define USB_BIT(a) ((UINTN)(1 << (a)))
#define USB_BIT_IS_SET(Data, Bit) ((BOOLEAN)(((Data) & (Bit)) == (Bit)))
#define EFI_USB_BUS_PROTOCOL_GUID \
{0x2B2F68CC, 0x0CD2, 0x44cf, 0x8E, 0x8B, 0xBB, 0xA2, 0x0B, 0x1B, 0x5B, 0x75}
#define USB_INTERFACE_FROM_USBIO(a) \
CR(a, USB_INTERFACE, UsbIo, USB_INTERFACE_SIGNATURE)
#define USB_BUS_FROM_THIS(a) \
CR(a, USB_BUS, BusId, USB_BUS_SIGNATURE)
//
// Used to locate USB_BUS
//
typedef struct _EFI_USB_BUS_PROTOCOL {
UINT64 Reserved;
} EFI_USB_BUS_PROTOCOL;
//
// Stands for the real USB device. Each device may
// has several seperately working interfaces.
//
typedef struct _USB_DEVICE {
USB_BUS *Bus;
//
// Configuration information
//
UINT8 Speed;
UINT8 Address;
UINT8 MaxPacket0;
//
// The device's descriptors and its configuration
//
USB_DEVICE_DESC *DevDesc;
USB_CONFIG_DESC *ActiveConfig;
UINT16 LangId [USB_MAX_LANG_ID];
UINT16 TotalLangId;
UINT8 NumOfInterface;
USB_INTERFACE *Interfaces [USB_MAX_INTERFACE];
//
// Parent child relationship
//
EFI_USB2_HC_TRANSACTION_TRANSLATOR Translator;
UINT8 ParentAddr;
USB_INTERFACE *ParentIf;
UINT8 ParentPort; // Start at 0
} USB_DEVICE;
//
// Stands for different functions of USB device
//
typedef struct _USB_INTERFACE {
UINTN Signature;
USB_DEVICE *Device;
USB_INTERFACE_DESC *IfDesc;
USB_INTERFACE_SETTING *IfSetting;
//
// Handles and protocols
//
EFI_HANDLE Handle;
EFI_USB_IO_PROTOCOL UsbIo;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
BOOLEAN IsManaged;
//
// Hub device special data
//
BOOLEAN IsHub;
USB_HUB_API *HubApi;
UINT8 NumOfPort;
EFI_EVENT HubNotify;
//
// Data used only by normal hub devices
//
USB_ENDPOINT_DESC *HubEp;
UINT8 *ChangeMap;
//
// Data used only by root hub to hand over device to
// companion UHCI driver if low/full speed devices are
// connected to EHCI.
//
UINT8 MaxSpeed;
} USB_INTERFACE;
//
// Stands for the current USB Bus
//
typedef struct _USB_BUS {
UINTN Signature;
EFI_USB_BUS_PROTOCOL BusId;
//
// Managed USB host controller
//
EFI_HANDLE HostHandle;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
EFI_USB2_HC_PROTOCOL *Usb2Hc;
EFI_USB_HC_PROTOCOL *UsbHc;
//
// An array of device that is on the bus. Devices[0] is
// for root hub. Device with address i is at Devices[i].
//
USB_DEVICE *Devices[USB_MAX_DEVICES];
} USB_BUS;
extern EFI_USB_IO_PROTOCOL mUsbIoProtocol;
extern EFI_DRIVER_BINDING_PROTOCOL mUsbBusDriverBinding;
extern EFI_COMPONENT_NAME_PROTOCOL mUsbBusComponentName;
#endif