https://bugzilla.tianocore.org/show_bug.cgi?id=1373 Replace BSD 2-Clause License with BSD+Patent License. This change is based on the following emails: https://lists.01.org/pipermail/edk2-devel/2019-February/036260.html https://lists.01.org/pipermail/edk2-devel/2018-October/030385.html RFCs with detailed process for the license change: V3: https://lists.01.org/pipermail/edk2-devel/2019-March/038116.html V2: https://lists.01.org/pipermail/edk2-devel/2019-March/037669.html V1: https://lists.01.org/pipermail/edk2-devel/2019-March/037500.html Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Michael D Kinney <michael.d.kinney@intel.com> Reviewed-by: Liming Gao <liming.gao@intel.com>
		
			
				
	
	
		
			666 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			666 lines
		
	
	
		
			21 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
| 
 | |
|   The library provides the USB Standard Device Requests defined
 | |
|   in Usb specification 9.4 section.
 | |
| 
 | |
|   Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
 | |
|   SPDX-License-Identifier: BSD-2-Clause-Patent
 | |
| 
 | |
| **/
 | |
| 
 | |
| #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 search 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;
 | |
| }
 |