audk/EdkModulePkg/Library/EdkUsbLib/UsbDxeLib.c

700 lines
15 KiB
C

/*++
Copyright (c) 2006, 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:
UsbDxeLib.c
Abstract:
Common Dxe Libarary for USB
Revision History
--*/
//
// Get Device Descriptor
//
EFI_STATUS
UsbGetDescriptor (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN UINT16 Value,
IN UINT16 Index,
IN UINT16 DescriptorLength,
OUT VOID *Descriptor,
OUT UINT32 *Status
)
/*++
Routine Description:
Usb Get Descriptor
Arguments:
UsbIo - EFI_USB_IO_PROTOCOL
Value - Device Request Value
Index - Device Request Index
DescriptorLength - Descriptor Length
Descriptor - Descriptor buffer to contain result
Status - Transfer Status
Returns:
EFI_INVALID_PARAMETER - Parameter is error
EFI_SUCCESS - Success
EFI_TIMEOUT - Device has no response
--*/
{
EFI_USB_DEVICE_REQUEST DevReq;
if (UsbIo == NULL) {
return EFI_INVALID_PARAMETER;
}
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
DevReq.RequestType = USB_DEV_GET_DESCRIPTOR_REQ_TYPE;
DevReq.Request = USB_DEV_GET_DESCRIPTOR;
DevReq.Value = Value;
DevReq.Index = Index;
DevReq.Length = DescriptorLength;
return UsbIo->UsbControlTransfer (
UsbIo,
&DevReq,
EfiUsbDataIn,
TIMEOUT_VALUE,
Descriptor,
DescriptorLength,
Status
);
}
//
// Set Device Descriptor
//
EFI_STATUS
UsbSetDescriptor (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN UINT16 Value,
IN UINT16 Index,
IN UINT16 DescriptorLength,
IN VOID *Descriptor,
OUT UINT32 *Status
)
/*++
Routine Description:
Usb Set Descriptor
Arguments:
UsbIo - EFI_USB_IO_PROTOCOL
Value - Device Request Value
Index - Device Request Index
DescriptorLength - Descriptor Length
Descriptor - Descriptor buffer to set
Status - Transfer Status
Returns:
EFI_INVALID_PARAMETER - Parameter is error
EFI_SUCCESS - Success
EFI_TIMEOUT - Device has no response
--*/
{
EFI_USB_DEVICE_REQUEST DevReq;
if (UsbIo == NULL) {
return EFI_INVALID_PARAMETER;
}
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
DevReq.RequestType = USB_DEV_SET_DESCRIPTOR_REQ_TYPE;
DevReq.Request = USB_DEV_SET_DESCRIPTOR;
DevReq.Value = Value;
DevReq.Index = Index;
DevReq.Length = DescriptorLength;
return UsbIo->UsbControlTransfer (
UsbIo,
&DevReq,
EfiUsbDataOut,
TIMEOUT_VALUE,
Descriptor,
DescriptorLength,
Status
);
}
//
// Get device Interface
//
EFI_STATUS
UsbGetDeviceInterface (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN UINT16 Index,
OUT UINT8 *AltSetting,
OUT UINT32 *Status
)
/*++
Routine Description:
Usb Get Device Interface
Arguments:
UsbIo - EFI_USB_IO_PROTOCOL
Index - Interface index value
AltSetting - Alternate setting
Status - Trasnsfer status
Returns:
EFI_INVALID_PARAMETER - Parameter is error
EFI_SUCCESS - Success
EFI_TIMEOUT - Device has no response
--*/
{
EFI_USB_DEVICE_REQUEST DevReq;
if (UsbIo == NULL) {
return EFI_INVALID_PARAMETER;
}
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
DevReq.RequestType = USB_DEV_GET_INTERFACE_REQ_TYPE;
DevReq.Request = USB_DEV_GET_INTERFACE;
DevReq.Index = Index;
DevReq.Length = 1;
return UsbIo->UsbControlTransfer (
UsbIo,
&DevReq,
EfiUsbDataIn,
TIMEOUT_VALUE,
AltSetting,
1,
Status
);
}
//
// Set device interface
//
EFI_STATUS
UsbSetDeviceInterface (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN UINT16 InterfaceNo,
IN UINT16 AltSetting,
OUT UINT32 *Status
)
/*++
Routine Description:
Usb Set Device Interface
Arguments:
UsbIo - EFI_USB_IO_PROTOCOL
InterfaceNo - Interface Number
AltSetting - Alternate setting
Status - Trasnsfer status
Returns:
EFI_INVALID_PARAMETER - Parameter is error
EFI_SUCCESS - Success
EFI_TIMEOUT - Device has no response
--*/
{
EFI_USB_DEVICE_REQUEST DevReq;
if (UsbIo == NULL) {
return EFI_INVALID_PARAMETER;
}
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
DevReq.RequestType = USB_DEV_SET_INTERFACE_REQ_TYPE;
DevReq.Request = USB_DEV_SET_INTERFACE;
DevReq.Value = AltSetting;
DevReq.Index = InterfaceNo;
return UsbIo->UsbControlTransfer (
UsbIo,
&DevReq,
EfiUsbNoData,
TIMEOUT_VALUE,
NULL,
0,
Status
);
}
//
// Get device configuration
//
EFI_STATUS
UsbGetDeviceConfiguration (
IN EFI_USB_IO_PROTOCOL *UsbIo,
OUT UINT8 *ConfigValue,
OUT UINT32 *Status
)
/*++
Routine Description:
Usb Get Device Configuration
Arguments:
UsbIo - EFI_USB_IO_PROTOCOL
ConfigValue - Config Value
Status - Transfer Status
Returns:
EFI_INVALID_PARAMETER - Parameter is error
EFI_SUCCESS - Success
EFI_TIMEOUT - Device has no response
--*/
{
EFI_USB_DEVICE_REQUEST DevReq;
if (UsbIo == NULL) {
return EFI_INVALID_PARAMETER;
}
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
DevReq.RequestType = USB_DEV_GET_CONFIGURATION_REQ_TYPE;
DevReq.Request = USB_DEV_GET_CONFIGURATION;
DevReq.Length = 1;
return UsbIo->UsbControlTransfer (
UsbIo,
&DevReq,
EfiUsbDataIn,
TIMEOUT_VALUE,
ConfigValue,
1,
Status
);
}
//
// Set device configuration
//
EFI_STATUS
UsbSetDeviceConfiguration (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN UINT16 Value,
OUT UINT32 *Status
)
/*++
Routine Description:
Usb Set Device Configuration
Arguments:
UsbIo - EFI_USB_IO_PROTOCOL
Value - Configuration Value to set
Status - Transfer status
Returns:
EFI_INVALID_PARAMETER - Parameter is error
EFI_SUCCESS - Success
EFI_TIMEOUT - Device has no response
--*/
{
EFI_USB_DEVICE_REQUEST DevReq;
if (UsbIo == NULL) {
return EFI_INVALID_PARAMETER;
}
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
DevReq.RequestType = USB_DEV_SET_CONFIGURATION_REQ_TYPE;
DevReq.Request = USB_DEV_SET_CONFIGURATION;
DevReq.Value = Value;
return UsbIo->UsbControlTransfer (
UsbIo,
&DevReq,
EfiUsbNoData,
TIMEOUT_VALUE,
NULL,
0,
Status
);
}
//
// Set Device Feature
//
EFI_STATUS
UsbSetDeviceFeature (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN EFI_USB_RECIPIENT Recipient,
IN UINT16 Value,
IN UINT16 Target,
OUT UINT32 *Status
)
/*++
Routine Description:
Usb Set Device Feature
Arguments:
UsbIo - EFI_USB_IO_PROTOCOL
Recipient - Interface/Device/Endpoint
Value - Request value
Target - Request Index
Status - Transfer status
Returns:
EFI_INVALID_PARAMETER - Parameter is error
EFI_SUCCESS - Success
EFI_TIMEOUT - Device has no response
--*/
{
EFI_USB_DEVICE_REQUEST DevReq;
if (UsbIo == NULL) {
return EFI_INVALID_PARAMETER;
}
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
switch (Recipient) {
case EfiUsbDevice:
DevReq.RequestType = 0x00;
break;
case EfiUsbInterface:
DevReq.RequestType = 0x01;
break;
case EfiUsbEndpoint:
DevReq.RequestType = 0x02;
break;
}
//
// Fill device request, see USB1.1 spec
//
DevReq.Request = USB_DEV_SET_FEATURE;
DevReq.Value = Value;
DevReq.Index = Target;
return UsbIo->UsbControlTransfer (
UsbIo,
&DevReq,
EfiUsbNoData,
TIMEOUT_VALUE,
NULL,
0,
Status
);
}
//
// Clear Device Feature
//
EFI_STATUS
UsbClearDeviceFeature (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN EFI_USB_RECIPIENT Recipient,
IN UINT16 Value,
IN UINT16 Target,
OUT UINT32 *Status
)
/*++
Routine Description:
Usb Clear Device Feature
Arguments:
UsbIo - EFI_USB_IO_PROTOCOL
Recipient - Interface/Device/Endpoint
Value - Request value
Target - Request Index
Status - Transfer status
Returns:
EFI_INVALID_PARAMETER - Parameter is error
EFI_SUCCESS - Success
EFI_TIMEOUT - Device has no response
--*/
{
EFI_USB_DEVICE_REQUEST DevReq;
if (UsbIo == NULL) {
return EFI_INVALID_PARAMETER;
}
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
switch (Recipient) {
case EfiUsbDevice:
DevReq.RequestType = 0x00;
break;
case EfiUsbInterface:
DevReq.RequestType = 0x01;
break;
case EfiUsbEndpoint:
DevReq.RequestType = 0x02;
break;
}
//
// Fill device request, see USB1.1 spec
//
DevReq.Request = USB_DEV_CLEAR_FEATURE;
DevReq.Value = Value;
DevReq.Index = Target;
return UsbIo->UsbControlTransfer (
UsbIo,
&DevReq,
EfiUsbNoData,
TIMEOUT_VALUE,
NULL,
0,
Status
);
}
//
// Get Device Status
//
EFI_STATUS
UsbGetDeviceStatus (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN EFI_USB_RECIPIENT Recipient,
IN UINT16 Target,
OUT UINT16 *DevStatus,
OUT UINT32 *Status
)
/*++
Routine Description:
Usb Get Device Status
Arguments:
UsbIo - EFI_USB_IO_PROTOCOL
Recipient - Interface/Device/Endpoint
Target - Request index
DevStatus - Device status
Status - Transfer status
Returns:
EFI_INVALID_PARAMETER - Parameter is error
EFI_SUCCESS - Success
EFI_TIMEOUT - Device has no response
--*/
{
EFI_USB_DEVICE_REQUEST DevReq;
if (UsbIo == NULL) {
return EFI_INVALID_PARAMETER;
}
ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
switch (Recipient) {
case EfiUsbDevice:
DevReq.RequestType = 0x80;
break;
case EfiUsbInterface:
DevReq.RequestType = 0x81;
break;
case EfiUsbEndpoint:
DevReq.RequestType = 0x82;
break;
}
//
// Fill device request, see USB1.1 spec
//
DevReq.Request = USB_DEV_GET_STATUS;
DevReq.Value = 0;
DevReq.Index = Target;
DevReq.Length = 2;
return UsbIo->UsbControlTransfer (
UsbIo,
&DevReq,
EfiUsbDataIn,
TIMEOUT_VALUE,
DevStatus,
2,
Status
);
}
//
// Usb Get String
//
EFI_STATUS
UsbGetString (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN UINT16 LangID,
IN UINT8 Index,
IN VOID *Buf,
IN UINTN BufSize,
OUT UINT32 *Status
)
/*++
Routine Description:
Usb Get String
Arguments:
UsbIo - EFI_USB_IO_PROTOCOL
LangID - Language ID
Index - Request index
Buf - Buffer to store string
BufSize - Buffer size
Status - Transfer status
Returns:
EFI_INVALID_PARAMETER - Parameter is error
EFI_SUCCESS - Success
EFI_TIMEOUT - Device has no response
--*/
{
UINT16 Value;
if (UsbIo == NULL) {
return EFI_INVALID_PARAMETER;
}
//
// Fill value, see USB1.1 spec
//
Value = (UINT16) ((USB_DT_STRING << 8) | Index);
return UsbGetDescriptor (
UsbIo,
Value,
LangID,
(UINT16) BufSize,
Buf,
Status
);
}
EFI_STATUS
UsbClearEndpointHalt (
IN EFI_USB_IO_PROTOCOL *UsbIo,
IN UINT8 EndpointNo,
OUT UINT32 *Status
)
/*++
Routine Description:
Clear endpoint stall
Arguments:
UsbIo - EFI_USB_IO_PROTOCOL
EndpointNo - Endpoint Number
Status - Transfer Status
Returns:
EFI_NOT_FOUND - Can't find the Endpoint
EFI_DEVICE_ERROR - Hardware error
EFI_SUCCESS - Success
--*/
{
EFI_STATUS Result;
EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
UINT8 Index;
ZeroMem (&EndpointDescriptor, sizeof (EFI_USB_ENDPOINT_DESCRIPTOR));
//
// First seach the endpoint descriptor for that endpoint addr
//
Result = UsbIo->UsbGetInterfaceDescriptor (
UsbIo,
&InterfaceDescriptor
);
if (EFI_ERROR (Result)) {
return Result;
}
for (Index = 0; Index < InterfaceDescriptor.NumEndpoints; Index++) {
Result = UsbIo->UsbGetEndpointDescriptor (
UsbIo,
Index,
&EndpointDescriptor
);
if (EFI_ERROR (Result)) {
continue;
}
if (EndpointDescriptor.EndpointAddress == EndpointNo) {
break;
}
}
if (Index == InterfaceDescriptor.NumEndpoints) {
//
// No such endpoint
//
return EFI_NOT_FOUND;
}
Result = UsbClearDeviceFeature (
UsbIo,
EfiUsbEndpoint,
EfiUsbEndpointHalt,
EndpointDescriptor.EndpointAddress,
Status
);
return Result;
}