summaryrefslogtreecommitdiff
path: root/Core/MdePkg/Library/UefiUsbLib/UsbDxeLib.c
diff options
context:
space:
mode:
Diffstat (limited to 'Core/MdePkg/Library/UefiUsbLib/UsbDxeLib.c')
-rw-r--r--Core/MdePkg/Library/UefiUsbLib/UsbDxeLib.c672
1 files changed, 672 insertions, 0 deletions
diff --git a/Core/MdePkg/Library/UefiUsbLib/UsbDxeLib.c b/Core/MdePkg/Library/UefiUsbLib/UsbDxeLib.c
new file mode 100644
index 0000000000..b22a8294a4
--- /dev/null
+++ b/Core/MdePkg/Library/UefiUsbLib/UsbDxeLib.c
@@ -0,0 +1,672 @@
+/** @file
+
+ The library provides the USB Standard Device Requests defined
+ in Usb specification 9.4 section.
+
+ Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials are
+ licensed and made available under the terms and conditions of
+ the BSD License which accompanies this distribution. The full
+ text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "UefiUsbLibInternal.h"
+
+
+/**
+ Get the descriptor of the specified USB device.
+
+ Submit a USB get descriptor request for the USB device specified by UsbIo, Value,
+ and Index, and return the descriptor in the buffer specified by Descriptor.
+ The status of the transfer is returned in Status.
+ If UsbIo is NULL, then ASSERT().
+ If Descriptor is NULL, then ASSERT().
+ If Status is NULL, then ASSERT().
+
+ @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
+ @param Value The device request value.
+ @param Index The device request index.
+ @param DescriptorLength The size, in bytes, of Descriptor.
+ @param Descriptor A pointer to the descriptor buffer to get.
+ @param Status A pointer to the status of the transfer.
+
+ @retval EFI_SUCCESS The request executed successfully.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed because the
+ buffer specified by DescriptorLength and Descriptor
+ is not large enough to hold the result of the request.
+ @retval EFI_TIMEOUT A timeout occurred executing the request.
+ @retval EFI_DEVICE_ERROR The request failed due to a device error. The transfer
+ status is returned in Status.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbGetDescriptor (
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN UINT16 Value,
+ IN UINT16 Index,
+ IN UINT16 DescriptorLength,
+ OUT VOID *Descriptor,
+ OUT UINT32 *Status
+ )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+
+ ASSERT (UsbIo != NULL);
+ ASSERT (Descriptor != NULL);
+ ASSERT (Status != NULL);
+
+ ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
+
+ DevReq.RequestType = USB_DEV_GET_DESCRIPTOR_REQ_TYPE;
+ DevReq.Request = USB_REQ_GET_DESCRIPTOR;
+ DevReq.Value = Value;
+ DevReq.Index = Index;
+ DevReq.Length = DescriptorLength;
+
+ return UsbIo->UsbControlTransfer (
+ UsbIo,
+ &DevReq,
+ EfiUsbDataIn,
+ PcdGet32 (PcdUsbTransferTimeoutValue),
+ Descriptor,
+ DescriptorLength,
+ Status
+ );
+}
+
+
+/**
+ Set the descriptor of the specified USB device.
+
+ Submit a USB set descriptor request for the USB device specified by UsbIo,
+ Value, and Index, and set the descriptor using the buffer specified by DesriptorLength
+ and Descriptor. The status of the transfer is returned in Status.
+ If UsbIo is NULL, then ASSERT().
+ If Descriptor is NULL, then ASSERT().
+ If Status is NULL, then ASSERT().
+
+ @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
+ @param Value The device request value.
+ @param Index The device request index.
+ @param DescriptorLength The size, in bytes, of Descriptor.
+ @param Descriptor A pointer to the descriptor buffer to set.
+ @param Status A pointer to the status of the transfer.
+
+ @retval EFI_SUCCESS The request executed successfully.
+ @retval EFI_TIMEOUT A timeout occurred executing the request.
+ @retval EFI_DEVICE_ERROR The request failed due to a device error.
+ The transfer status is returned in Status.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSetDescriptor (
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN UINT16 Value,
+ IN UINT16 Index,
+ IN UINT16 DescriptorLength,
+ IN VOID *Descriptor,
+ OUT UINT32 *Status
+ )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+
+ ASSERT (UsbIo != NULL);
+ ASSERT (Descriptor != NULL);
+ ASSERT (Status != NULL);
+
+ ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
+
+ DevReq.RequestType = USB_DEV_SET_DESCRIPTOR_REQ_TYPE;
+ DevReq.Request = USB_REQ_SET_DESCRIPTOR;
+ DevReq.Value = Value;
+ DevReq.Index = Index;
+ DevReq.Length = DescriptorLength;
+
+ return UsbIo->UsbControlTransfer (
+ UsbIo,
+ &DevReq,
+ EfiUsbDataOut,
+ PcdGet32 (PcdUsbTransferTimeoutValue),
+ Descriptor,
+ DescriptorLength,
+ Status
+ );
+}
+
+
+/**
+ Get the interface setting of the specified USB device.
+
+ Submit a USB get interface request for the USB device specified by UsbIo,
+ and Interface, and place the result in the buffer specified by AlternateSetting.
+ The status of the transfer is returned in Status.
+ If UsbIo is NULL, then ASSERT().
+ If AlternateSetting is NULL, then ASSERT().
+ If Status is NULL, then ASSERT().
+
+ @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
+ @param Interface The interface index value.
+ @param AlternateSetting A pointer to the alternate setting to be retrieved.
+ @param Status A pointer to the status of the transfer.
+
+ @retval EFI_SUCCESS The request executed successfully.
+ @retval EFI_TIMEOUT A timeout occurred executing the request.
+ @retval EFI_DEVICE_ERROR The request failed due to a device error.
+ The transfer status is returned in Status.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbGetInterface (
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN UINT16 Interface,
+ OUT UINT16 *AlternateSetting,
+ OUT UINT32 *Status
+ )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+
+ ASSERT (UsbIo != NULL);
+ ASSERT (AlternateSetting != NULL);
+ ASSERT (Status != NULL);
+
+ *AlternateSetting = 0;
+
+ ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
+
+ DevReq.RequestType = USB_DEV_GET_INTERFACE_REQ_TYPE;
+ DevReq.Request = USB_REQ_GET_INTERFACE;
+ DevReq.Index = Interface;
+ DevReq.Length = 1;
+
+ return UsbIo->UsbControlTransfer (
+ UsbIo,
+ &DevReq,
+ EfiUsbDataIn,
+ PcdGet32 (PcdUsbTransferTimeoutValue),
+ AlternateSetting,
+ 1,
+ Status
+ );
+}
+
+
+/**
+ Set the interface setting of the specified USB device.
+
+ Submit a USB set interface request for the USB device specified by UsbIo, and
+ Interface, and set the alternate setting to the value specified by AlternateSetting.
+ The status of the transfer is returned in Status.
+ If UsbIo is NULL, then ASSERT().
+ If Status is NULL, then ASSERT().
+
+ @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
+ @param Interface The interface index value.
+ @param AlternateSetting The alternate setting to be set.
+ @param Status A pointer to the status of the transfer.
+
+ @retval EFI_SUCCESS The request executed successfully.
+ @retval EFI_TIMEOUT A timeout occurred executing the request.
+ @retval EFI_SUCCESS The request failed due to a device error.
+ The transfer status is returned in Status.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSetInterface (
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN UINT16 Interface,
+ IN UINT16 AlternateSetting,
+ OUT UINT32 *Status
+ )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+
+ ASSERT (UsbIo != NULL);
+ ASSERT (Status != NULL);
+
+ ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
+
+ DevReq.RequestType = USB_DEV_SET_INTERFACE_REQ_TYPE;
+ DevReq.Request = USB_REQ_SET_INTERFACE;
+ DevReq.Value = AlternateSetting;
+ DevReq.Index = Interface;
+
+ return UsbIo->UsbControlTransfer (
+ UsbIo,
+ &DevReq,
+ EfiUsbNoData,
+ PcdGet32 (PcdUsbTransferTimeoutValue),
+ NULL,
+ 0,
+ Status
+ );
+}
+
+
+/**
+ Get the device configuration.
+
+ Submit a USB get configuration request for the USB device specified by UsbIo
+ and place the result in the buffer specified by ConfigurationValue. The status
+ of the transfer is returned in Status.
+ If UsbIo is NULL, then ASSERT().
+ If ConfigurationValue is NULL, then ASSERT().
+ If Status is NULL, then ASSERT().
+
+ @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
+ @param ConfigurationValue A pointer to the device configuration to be retrieved.
+ @param Status A pointer to the status of the transfer.
+
+ @retval EFI_SUCCESS The request executed successfully.
+ @retval EFI_TIMEOUT A timeout occurred executing the request.
+ @retval EFI_DEVICE_ERROR The request failed due to a device error.
+ The transfer status is returned in Status.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbGetConfiguration (
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ OUT UINT16 *ConfigurationValue,
+ OUT UINT32 *Status
+ )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+
+ ASSERT (UsbIo != NULL);
+ ASSERT (ConfigurationValue != NULL);
+ ASSERT (Status != NULL);
+
+ *ConfigurationValue = 0;
+
+ ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
+
+ DevReq.RequestType = USB_DEV_GET_CONFIGURATION_REQ_TYPE;
+ DevReq.Request = USB_REQ_GET_CONFIG;
+ DevReq.Length = 1;
+
+ return UsbIo->UsbControlTransfer (
+ UsbIo,
+ &DevReq,
+ EfiUsbDataIn,
+ PcdGet32 (PcdUsbTransferTimeoutValue),
+ ConfigurationValue,
+ 1,
+ Status
+ );
+}
+
+
+/**
+ Set the device configuration.
+
+ Submit a USB set configuration request for the USB device specified by UsbIo
+ and set the device configuration to the value specified by ConfigurationValue.
+ The status of the transfer is returned in Status.
+ If UsbIo is NULL, then ASSERT().
+ If Status is NULL, then ASSERT().
+
+ @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
+ @param ConfigurationValue The device configuration value to be set.
+ @param Status A pointer to the status of the transfer.
+
+ @retval EFI_SUCCESS The request executed successfully.
+ @retval EFI_TIMEOUT A timeout occurred executing the request.
+ @retval EFI_DEVICE_ERROR The request failed due to a device error.
+ The transfer status is returned in Status.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSetConfiguration (
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN UINT16 ConfigurationValue,
+ OUT UINT32 *Status
+ )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+
+ ASSERT (UsbIo != NULL);
+ ASSERT (Status != NULL);
+
+ ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
+
+ DevReq.RequestType = USB_DEV_SET_CONFIGURATION_REQ_TYPE;
+ DevReq.Request = USB_REQ_SET_CONFIG;
+ DevReq.Value = ConfigurationValue;
+
+ return UsbIo->UsbControlTransfer (
+ UsbIo,
+ &DevReq,
+ EfiUsbNoData,
+ PcdGet32 (PcdUsbTransferTimeoutValue),
+ NULL,
+ 0,
+ Status
+ );
+}
+
+
+/**
+ Set the specified feature of the specified device.
+
+ Submit a USB set device feature request for the USB device specified by UsbIo,
+ Recipient, and Target to the value specified by Value. The status of the
+ transfer is returned in Status.
+ If UsbIo is NULL, then ASSERT().
+ If Status is NULL, then ASSERT().
+
+ @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
+ @param Recipient The USB data recipient type (i.e. Device, Interface, Endpoint).
+ Type USB_TYPES_DEFINITION is defined in the MDE Package Industry
+ Standard include file Usb.h.
+ @param Value The value of the feature to be set.
+ @param Target The index of the device to be set.
+ @param Status A pointer to the status of the transfer.
+
+ @retval EFI_SUCCESS The request executed successfully.
+ @retval EFI_TIMEOUT A timeout occurred executing the request.
+ @retval EFI_DEVICE_ERROR The request failed due to a device error.
+ The transfer status is returned in Status.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbSetFeature (
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN USB_TYPES_DEFINITION Recipient,
+ IN UINT16 Value,
+ IN UINT16 Target,
+ OUT UINT32 *Status
+ )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+
+ ASSERT (UsbIo != NULL);
+ ASSERT (Status != NULL);
+
+ ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
+
+ switch (Recipient) {
+
+ case USB_TARGET_DEVICE:
+ DevReq.RequestType = USB_DEV_SET_FEATURE_REQ_TYPE_D;
+ break;
+
+ case USB_TARGET_INTERFACE:
+ DevReq.RequestType = USB_DEV_SET_FEATURE_REQ_TYPE_I;
+ break;
+
+ case USB_TARGET_ENDPOINT:
+ DevReq.RequestType = USB_DEV_SET_FEATURE_REQ_TYPE_E;
+ break;
+
+ default:
+ break;
+ }
+ //
+ // Fill device request, see USB1.1 spec
+ //
+ DevReq.Request = USB_REQ_SET_FEATURE;
+ DevReq.Value = Value;
+ DevReq.Index = Target;
+
+
+ return UsbIo->UsbControlTransfer (
+ UsbIo,
+ &DevReq,
+ EfiUsbNoData,
+ PcdGet32 (PcdUsbTransferTimeoutValue),
+ NULL,
+ 0,
+ Status
+ );
+}
+
+
+/**
+ Clear the specified feature of the specified device.
+
+ Submit a USB clear device feature request for the USB device specified by UsbIo,
+ Recipient, and Target to the value specified by Value. The status of the transfer
+ is returned in Status.
+ If UsbIo is NULL, then ASSERT().
+ If Status is NULL, then ASSERT().
+
+ @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
+ @param Recipient The USB data recipient type (i.e. Device, Interface, Endpoint).
+ Type USB_TYPES_DEFINITION is defined in the MDE Package Industry Standard
+ include file Usb.h.
+ @param Value The value of the feature to be cleared.
+ @param Target The index of the device to be cleared.
+ @param Status A pointer to the status of the transfer.
+
+ @retval EFI_SUCCESS The request executed successfully.
+ @retval EFI_TIMEOUT A timeout occurred executing the request.
+ @retval EFI_DEVICE_ERROR The request failed due to a device error.
+ The transfer status is returned in Status.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbClearFeature (
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN USB_TYPES_DEFINITION Recipient,
+ IN UINT16 Value,
+ IN UINT16 Target,
+ OUT UINT32 *Status
+ )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+
+ ASSERT (UsbIo != NULL);
+ ASSERT (Status != NULL);
+
+
+ ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
+
+ switch (Recipient) {
+
+ case USB_TARGET_DEVICE:
+ DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_D;
+ break;
+
+ case USB_TARGET_INTERFACE:
+ DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_I;
+ break;
+
+ case USB_TARGET_ENDPOINT:
+ DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_E;
+ break;
+
+ default:
+ break;
+ }
+ //
+ // Fill device request, see USB1.1 spec
+ //
+ DevReq.Request = USB_REQ_CLEAR_FEATURE;
+ DevReq.Value = Value;
+ DevReq.Index = Target;
+
+
+ return UsbIo->UsbControlTransfer (
+ UsbIo,
+ &DevReq,
+ EfiUsbNoData,
+ PcdGet32 (PcdUsbTransferTimeoutValue),
+ NULL,
+ 0,
+ Status
+ );
+}
+
+
+/**
+ Get the status of the specified device.
+
+ Submit a USB device get status request for the USB device specified by UsbIo,
+ Recipient, and Target and place the result in the buffer specified by DeviceStatus.
+ The status of the transfer is returned in Status.
+ If UsbIo is NULL, then ASSERT().
+ If DeviceStatus is NULL, then ASSERT().
+ If Status is NULL, then ASSERT().
+
+ @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
+ @param Recipient The USB data recipient type (i.e. Device, Interface, Endpoint).
+ Type USB_TYPES_DEFINITION is defined in the MDE Package Industry Standard
+ include file Usb.h.
+ @param Target The index of the device to be get the status of.
+ @param DeviceStatus A pointer to the device status to be retrieved.
+ @param Status A pointer to the status of the transfer.
+
+ @retval EFI_SUCCESS The request executed successfully.
+ @retval EFI_TIMEOUT A timeout occurred executing the request.
+ @retval EFI_DEVICE_ERROR The request failed due to a device error.
+ The transfer status is returned in Status.
+
+**/
+EFI_STATUS
+EFIAPI
+UsbGetStatus (
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN USB_TYPES_DEFINITION Recipient,
+ IN UINT16 Target,
+ OUT UINT16 *DeviceStatus,
+ OUT UINT32 *Status
+ )
+{
+ EFI_USB_DEVICE_REQUEST DevReq;
+
+ ASSERT (UsbIo != NULL);
+ ASSERT (DeviceStatus != NULL);
+ ASSERT (Status != NULL);
+
+ ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
+
+ switch (Recipient) {
+
+ case USB_TARGET_DEVICE:
+ DevReq.RequestType = USB_DEV_GET_STATUS_REQ_TYPE_D;
+ break;
+
+ case USB_TARGET_INTERFACE:
+ DevReq.RequestType = USB_DEV_GET_STATUS_REQ_TYPE_I;
+ break;
+
+ case USB_TARGET_ENDPOINT:
+ DevReq.RequestType = USB_DEV_GET_STATUS_REQ_TYPE_E;
+ break;
+
+ default:
+ break;
+ }
+ //
+ // Fill device request, see USB1.1 spec
+ //
+ DevReq.Request = USB_REQ_GET_STATUS;
+ DevReq.Value = 0;
+ DevReq.Index = Target;
+ DevReq.Length = 2;
+
+ return UsbIo->UsbControlTransfer (
+ UsbIo,
+ &DevReq,
+ EfiUsbDataIn,
+ PcdGet32 (PcdUsbTransferTimeoutValue),
+ DeviceStatus,
+ 2,
+ Status
+ );
+}
+
+
+/**
+ Clear halt feature of the specified usb endpoint.
+
+ Retrieve the USB endpoint descriptor specified by UsbIo and EndPoint.
+ If the USB endpoint descriptor can not be retrieved, then return EFI_NOT_FOUND.
+ If the endpoint descriptor is found, then clear the halt feature of this USB endpoint.
+ The status of the transfer is returned in Status.
+ If UsbIo is NULL, then ASSERT().
+ If Status is NULL, then ASSERT().
+
+ @param UsbIo A pointer to the USB I/O Protocol instance for the specific USB target.
+ @param Endpoint The endpoint address.
+ @param Status A pointer to the status of the transfer.
+
+ @retval EFI_SUCCESS The request executed successfully.
+ @retval EFI_TIMEOUT A timeout occurred executing the request.
+ @retval EFI_DEVICE_ERROR The request failed due to a device error.
+ The transfer status is returned in Status.
+ @retval EFI_NOT_FOUND The specified USB endpoint descriptor can not be found
+
+**/
+EFI_STATUS
+EFIAPI
+UsbClearEndpointHalt (
+ IN EFI_USB_IO_PROTOCOL *UsbIo,
+ IN UINT8 Endpoint,
+ OUT UINT32 *Status
+ )
+{
+ EFI_STATUS Result;
+ EFI_USB_ENDPOINT_DESCRIPTOR EndpointDescriptor;
+ EFI_USB_INTERFACE_DESCRIPTOR InterfaceDescriptor;
+ UINT8 Index;
+
+ ASSERT (UsbIo != NULL);
+ ASSERT (Status != NULL);
+
+ 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 == Endpoint) {
+ break;
+ }
+ }
+
+ if (Index == InterfaceDescriptor.NumEndpoints) {
+ //
+ // No such endpoint
+ //
+ return EFI_NOT_FOUND;
+ }
+
+ Result = UsbClearFeature (
+ UsbIo,
+ USB_TARGET_ENDPOINT,
+ USB_FEATURE_ENDPOINT_HALT,
+ EndpointDescriptor.EndpointAddress,
+ Status
+ );
+
+ return Result;
+}