📄 usb.c
字号:
//
// Descriptor length should be at least 2
// and should not exceed the buffer length
//
if (Len < 2) {
return EFI_DEVICE_ERROR;
}
if(Len > Length) {
return EFI_DEVICE_ERROR;
}
//
// Skip this mismatch descriptor
//
Length -= Len;
ptr += Len;
Parsed += Len;
}
*ParsedBytes = Parsed;
return EFI_SUCCESS;
}
static
EFI_STATUS
ParseThisEndpoint (
IN ENDPOINT_DESC_LIST_ENTRY *EndpointEntry,
IN UINT8 *Buffer,
IN UINTN BufferLength,
OUT UINTN *ParsedBytes
)
/*++
Routine Description:
Get the start position of next wanted endpoint descriptor.
Parameters:
Return Value:
EFI_SUCCESS
EFI_DEVICE_ERROR
--*/
{
UINT8 *ptr;
EFI_STATUS Status;
UINTN SkipBytes;
//
// Skip some data for this interface
//
Status = GetExpectedDescriptor (
Buffer,
BufferLength,
USB_DT_ENDPOINT,
sizeof (EFI_USB_ENDPOINT_DESCRIPTOR),
&SkipBytes
);
if (EFI_ERROR (Status)) {
return Status;
}
ptr = Buffer + SkipBytes;
*ParsedBytes = SkipBytes;
EfiCopyMem (
&EndpointEntry->EndpointDescriptor,
ptr,
sizeof (EFI_USB_ENDPOINT_DESCRIPTOR)
);
*ParsedBytes += sizeof(EFI_USB_ENDPOINT_DESCRIPTOR);
return EFI_SUCCESS;
}
static
EFI_STATUS
ParseThisInterface(
IN INTERFACE_DESC_LIST_ENTRY *InterfaceEntry,
IN UINT8 *Buffer,
IN UINTN *BufferLen,
OUT UINTN *ParsedBytes
)
/*++
Routine Description:
Get the start position of next wanted interface descriptor.
Parameters:
Return Value:
EFI_SUCCESS
EFI_DEVICE_ERROR
--*/
{
UINT8 *ptr;
UINTN SkipBytes;
UINTN i;
UINTN Length;
UINTN Parsed;
ENDPOINT_DESC_LIST_ENTRY *EndpointEntry;
EFI_STATUS Status;
//
// Skip some data for this interface
//
Status = GetExpectedDescriptor (
Buffer,
*BufferLen,
USB_DT_INTERFACE,
sizeof(EFI_USB_INTERFACE_DESCRIPTOR),
&SkipBytes
);
if (EFI_ERROR (Status)) {
return Status;
}
ptr = Buffer + SkipBytes;
*ParsedBytes = SkipBytes;
//
// Copy the interface descriptor
//
EfiCopyMem (
&InterfaceEntry->InterfaceDescriptor,
ptr,
sizeof(EFI_USB_INTERFACE_DESCRIPTOR)
);
ptr = Buffer + sizeof(EFI_USB_INTERFACE_DESCRIPTOR);
*ParsedBytes += sizeof(EFI_USB_INTERFACE_DESCRIPTOR);
InitializeListHead (&InterfaceEntry->EndpointDescListHead);
Length = *BufferLen - SkipBytes - sizeof(EFI_USB_INTERFACE_DESCRIPTOR);
for(i = 0; i < (InterfaceEntry->InterfaceDescriptor).NumEndpoints; i++) {
EndpointEntry = NULL;
Status = gBS->AllocatePool(
EfiBootServicesData,
sizeof(ENDPOINT_DESC_LIST_ENTRY),
&EndpointEntry
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
EfiZeroMem(EndpointEntry, sizeof(ENDPOINT_DESC_LIST_ENTRY));
//
// Parses all the endpoint descriptors within this interface.
//
Status = ParseThisEndpoint(EndpointEntry, ptr, Length, &Parsed);
if (EFI_ERROR (Status)) {
gBS->FreePool(EndpointEntry);
return Status;
}
InsertTailList (
&InterfaceEntry->EndpointDescListHead,
&EndpointEntry->Link
);
Length -= Parsed;
ptr += Parsed;
*ParsedBytes += Parsed;
}
return EFI_SUCCESS;
}
static EFI_STATUS
ParseThisConfig(
IN CONFIG_DESC_LIST_ENTRY *ConfigDescEntry,
IN UINT8 *Buffer,
IN UINTN Length
)
/*++
Routine Description:
Parse the current configuration descriptior.
Parameters:
Return Value:
EFI_SUCCESS
EFI_DEVICE_ERROR
--*/
{
UINT8 *ptr;
UINT8 NumInterface;
UINTN i;
INTERFACE_DESC_LIST_ENTRY *InterfaceEntry;
UINTN SkipBytes;
UINTN Parsed;
EFI_STATUS Status;
UINTN LengthLeft;
//
// First skip the current config descriptor;
//
Status = GetExpectedDescriptor (
Buffer,
Length,
USB_DT_CONFIG,
sizeof(EFI_USB_CONFIG_DESCRIPTOR),
&SkipBytes
);
if (EFI_ERROR (Status)) {
return Status;
}
ptr = Buffer + SkipBytes;
EfiCopyMem (
&ConfigDescEntry->CongfigDescriptor,
ptr,
sizeof(EFI_USB_CONFIG_DESCRIPTOR)
);
NumInterface = ConfigDescEntry->CongfigDescriptor.NumInterfaces;
//
// Skip size of Configuration Descriptor
//
ptr += sizeof(EFI_USB_CONFIG_DESCRIPTOR);
LengthLeft = Length - SkipBytes - sizeof(EFI_USB_CONFIG_DESCRIPTOR);
for(i = 0; i < NumInterface; i++) {
//
// Parse all Interface
//
InterfaceEntry = NULL;
Status = gBS->AllocatePool(
EfiBootServicesData,
sizeof(INTERFACE_DESC_LIST_ENTRY),
&InterfaceEntry
);
if (EFI_ERROR (Status)) {
return EFI_OUT_OF_RESOURCES;
}
EfiZeroMem(InterfaceEntry, sizeof(INTERFACE_DESC_LIST_ENTRY));
Status = ParseThisInterface(InterfaceEntry, ptr, &LengthLeft, &Parsed);
if (EFI_ERROR (Status)) {
gBS->FreePool(InterfaceEntry);
return Status;
}
InsertTailList(
&ConfigDescEntry->InterfaceDescListHead,
&InterfaceEntry->Link
);
//
// Parsed for next interface
//
LengthLeft -= Parsed;
ptr += Parsed;
}
//
// Parse for additional alt setting;
//
return EFI_SUCCESS;
}
EFI_STATUS
UsbSetConfiguration (
IN USB_IO_DEVICE *Dev,
IN UINTN ConfigurationValue
)
/*++
Routine Description:
Set the device to a configuration value.
Parameters:
Dev - USB_IO_DEVICE to be set configuration
ConfigrationValue - The configuration value to be set to that device
Return Value:
EFI_SUCCESS
EFI_DEVICE_ERROR
--*/
{
EFI_LIST_ENTRY *NextEntry;
CONFIG_DESC_LIST_ENTRY *ConfigEntry;
UINT32 Status;
EFI_STATUS Result;
EFI_USB_IO_PROTOCOL *UsbIo;
UsbIo = &(Dev->UsbController[0]->UsbIo);
NextEntry = (Dev->ConfigDescListHead).ForwardLink;
while(NextEntry != &Dev->ConfigDescListHead) {
//
// Get one entry
//
ConfigEntry = (CONFIG_DESC_LIST_ENTRY *)NextEntry;
if ((ConfigEntry->CongfigDescriptor).ConfigurationValue
== ConfigurationValue) {
//
// Find one, set to the active configuration
//
Dev->ActiveConfig = ConfigEntry;
break;
}
NextEntry = NextEntry->ForwardLink;
}
//
// Next Entry should not be null
//
Result = UsbSetDeviceConfiguration(
UsbIo,
(UINT16)ConfigurationValue,
&Status
);
return Result;
}
EFI_STATUS
UsbSetDefaultConfiguration(
IN USB_IO_DEVICE *Dev
)
/*++
Routine Description:
Set the device to a default configuration value.
Parameters:
Dev - USB_IO_DEVICE to be set configuration
Return Value:
EFI_SUCCESS
EFI_DEVICE_ERROR
--*/
{
CONFIG_DESC_LIST_ENTRY *ConfigEntry;
UINT16 ConfigValue;
EFI_LIST_ENTRY *NextEntry;
if (IsListEmpty (&Dev->ConfigDescListHead)) {
return EFI_DEVICE_ERROR;
}
NextEntry = (Dev->ConfigDescListHead).ForwardLink;
ConfigEntry = (CONFIG_DESC_LIST_ENTRY*) NextEntry;
ConfigValue = (ConfigEntry->CongfigDescriptor).ConfigurationValue;
return UsbSetConfiguration(Dev, ConfigValue);
}
VOID
UsbDestroyAllConfiguration (
IN USB_IO_DEVICE *Dev
)
/*++
Routine Description:
Delete all configuration data when device is not used.
Parameter:
Dev - USB_IO_DEVICE to be set configuration
Return Value:
N/A
--*/
{
CONFIG_DESC_LIST_ENTRY *ConfigEntry;
INTERFACE_DESC_LIST_ENTRY *InterfaceEntry;
ENDPOINT_DESC_LIST_ENTRY *EndpointEntry;
EFI_LIST_ENTRY *NextEntry;
//
// Delete all configuration descriptor data
//
ConfigEntry = (CONFIG_DESC_LIST_ENTRY*)(Dev->ConfigDescListHead).ForwardLink;
while (ConfigEntry != (CONFIG_DESC_LIST_ENTRY *)&Dev->ConfigDescListHead) {
//
// Delete all its interface descriptors
//
InterfaceEntry = (INTERFACE_DESC_LIST_ENTRY *)ConfigEntry->InterfaceDescListHead.ForwardLink;
while (InterfaceEntry != (INTERFACE_DESC_LIST_ENTRY *)&ConfigEntry->InterfaceDescListHead) {
//
// Delete all its endpoint descriptors
//
EndpointEntry = (ENDPOINT_DESC_LIST_ENTRY *)InterfaceEntry->EndpointDescListHead.ForwardLink;
while (EndpointEntry != (ENDPOINT_DESC_LIST_ENTRY *)&InterfaceEntry->EndpointDescListHead) {
NextEntry = ((EFI_LIST_ENTRY *)EndpointEntry)->ForwardLink;
RemoveEntryList ((EFI_LIST_ENTRY *)EndpointEntry);
gBS->FreePool (EndpointEntry);
EndpointEntry = (ENDPOINT_DESC_LIST_ENTRY *)NextEntry;
}
NextEntry = ((EFI_LIST_ENTRY *)InterfaceEntry)->ForwardLink;
RemoveEntryList((EFI_LIST_ENTRY *)InterfaceEntry);
gBS->FreePool (InterfaceEntry);
InterfaceEntry = (INTERFACE_DESC_LIST_ENTRY *)NextEntry;
}
NextEntry = ((EFI_LIST_ENTRY *)ConfigEntry)->ForwardLink;
RemoveEntryList((EFI_LIST_ENTRY *)ConfigEntry);
gBS->FreePool (ConfigEntry);
ConfigEntry = (CONFIG_DESC_LIST_ENTRY *)NextEntry;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -