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:
164
MdeModulePkg/Bus/Usb/UsbBusDxe/ComponentName.c
Normal file
164
MdeModulePkg/Bus/Usb/UsbBusDxe/ComponentName.c
Normal 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;
|
||||
}
|
99
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
Normal file
99
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.inf
Normal 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
|
||||
|
85
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.msa
Normal file
85
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbBusDxe.msa
Normal 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>
|
991
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
Normal file
991
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.c
Normal 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;
|
||||
}
|
146
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.h
Normal file
146
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbDesc.h
Normal 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
|
991
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
Normal file
991
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.c
Normal 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);
|
||||
}
|
||||
}
|
153
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.h
Normal file
153
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbEnumer.h
Normal 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
|
1334
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
Normal file
1334
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.c
Normal file
File diff suppressed because it is too large
Load Diff
140
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.h
Normal file
140
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbHub.h
Normal 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
|
||||
|
769
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbUtility.c
Normal file
769
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbUtility.c
Normal 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
|
220
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbUtility.h
Normal file
220
MdeModulePkg/Bus/Usb/UsbBusDxe/UsbUtility.h
Normal 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
|
1384
MdeModulePkg/Bus/Usb/UsbBusDxe/usbbus.c
Normal file
1384
MdeModulePkg/Bus/Usb/UsbBusDxe/usbbus.c
Normal file
File diff suppressed because it is too large
Load Diff
210
MdeModulePkg/Bus/Usb/UsbBusDxe/usbbus.h
Normal file
210
MdeModulePkg/Bus/Usb/UsbBusDxe/usbbus.h
Normal 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
|
Reference in New Issue
Block a user