Home | History | Annotate | Download | only in UefiUsbLib
      1 /** @file
      2 
      3   The library provides the USB Standard Device Requests defined
      4   in Usb specification 9.4 section.
      5 
      6   Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>
      7   This program and the accompanying materials are
      8   licensed and made available under the terms and conditions of
      9   the BSD License which accompanies this distribution.  The full
     10   text of the license may be found at
     11   http://opensource.org/licenses/bsd-license.php.
     12 
     13   THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     14   WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     15 
     16 **/
     17 
     18 #include "UefiUsbLibInternal.h"
     19 
     20 
     21 /**
     22   Get the descriptor of the specified USB device.
     23 
     24   Submit a USB get descriptor request for the USB device specified by UsbIo, Value,
     25   and Index, and return the descriptor in the buffer specified by Descriptor.
     26   The status of the transfer is returned in Status.
     27   If UsbIo is NULL, then ASSERT().
     28   If Descriptor is NULL, then ASSERT().
     29   If Status is NULL, then ASSERT().
     30 
     31   @param  UsbIo             A pointer to the USB I/O Protocol instance for the specific USB target.
     32   @param  Value             The device request value.
     33   @param  Index             The device request index.
     34   @param  DescriptorLength  The size, in bytes, of Descriptor.
     35   @param  Descriptor        A pointer to the descriptor buffer to get.
     36   @param  Status            A pointer to the status of the transfer.
     37 
     38   @retval EFI_SUCCESS           The request executed successfully.
     39   @retval EFI_OUT_OF_RESOURCES  The request could not be completed because the
     40                                 buffer specified by DescriptorLength and Descriptor
     41                                 is not large enough to hold the result of the request.
     42   @retval EFI_TIMEOUT           A timeout occurred executing the request.
     43   @retval EFI_DEVICE_ERROR      The request failed due to a device error. The transfer
     44                                 status is returned in Status.
     45 
     46 **/
     47 EFI_STATUS
     48 EFIAPI
     49 UsbGetDescriptor (
     50   IN  EFI_USB_IO_PROTOCOL     *UsbIo,
     51   IN  UINT16                  Value,
     52   IN  UINT16                  Index,
     53   IN  UINT16                  DescriptorLength,
     54   OUT VOID                    *Descriptor,
     55   OUT UINT32                  *Status
     56   )
     57 {
     58   EFI_USB_DEVICE_REQUEST  DevReq;
     59 
     60   ASSERT (UsbIo != NULL);
     61   ASSERT (Descriptor != NULL);
     62   ASSERT (Status != NULL);
     63 
     64   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
     65 
     66   DevReq.RequestType  = USB_DEV_GET_DESCRIPTOR_REQ_TYPE;
     67   DevReq.Request      = USB_REQ_GET_DESCRIPTOR;
     68   DevReq.Value        = Value;
     69   DevReq.Index        = Index;
     70   DevReq.Length       = DescriptorLength;
     71 
     72   return UsbIo->UsbControlTransfer (
     73                   UsbIo,
     74                   &DevReq,
     75                   EfiUsbDataIn,
     76                   PcdGet32 (PcdUsbTransferTimeoutValue),
     77                   Descriptor,
     78                   DescriptorLength,
     79                   Status
     80                   );
     81 }
     82 
     83 
     84 /**
     85   Set the descriptor of the specified USB device.
     86 
     87   Submit a USB set descriptor request for the USB device specified by UsbIo,
     88   Value, and Index, and set the descriptor using the buffer specified by DesriptorLength
     89   and Descriptor.  The status of the transfer is returned in Status.
     90   If UsbIo is NULL, then ASSERT().
     91   If Descriptor is NULL, then ASSERT().
     92   If Status is NULL, then ASSERT().
     93 
     94   @param  UsbIo             A pointer to the USB I/O Protocol instance for the specific USB target.
     95   @param  Value             The device request value.
     96   @param  Index             The device request index.
     97   @param  DescriptorLength  The size, in bytes, of Descriptor.
     98   @param  Descriptor        A pointer to the descriptor buffer to set.
     99   @param  Status            A pointer to the status of the transfer.
    100 
    101   @retval  EFI_SUCCESS       The request executed successfully.
    102   @retval  EFI_TIMEOUT       A timeout occurred executing the request.
    103   @retval  EFI_DEVICE_ERROR  The request failed due to a device error.
    104                              The transfer status is returned in Status.
    105 
    106 **/
    107 EFI_STATUS
    108 EFIAPI
    109 UsbSetDescriptor (
    110   IN  EFI_USB_IO_PROTOCOL     *UsbIo,
    111   IN  UINT16                  Value,
    112   IN  UINT16                  Index,
    113   IN  UINT16                  DescriptorLength,
    114   IN  VOID                    *Descriptor,
    115   OUT UINT32                  *Status
    116   )
    117 {
    118   EFI_USB_DEVICE_REQUEST  DevReq;
    119 
    120   ASSERT (UsbIo != NULL);
    121   ASSERT (Descriptor != NULL);
    122   ASSERT (Status != NULL);
    123 
    124   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
    125 
    126   DevReq.RequestType  = USB_DEV_SET_DESCRIPTOR_REQ_TYPE;
    127   DevReq.Request      = USB_REQ_SET_DESCRIPTOR;
    128   DevReq.Value        = Value;
    129   DevReq.Index        = Index;
    130   DevReq.Length       = DescriptorLength;
    131 
    132   return UsbIo->UsbControlTransfer (
    133                   UsbIo,
    134                   &DevReq,
    135                   EfiUsbDataOut,
    136                   PcdGet32 (PcdUsbTransferTimeoutValue),
    137                   Descriptor,
    138                   DescriptorLength,
    139                   Status
    140                   );
    141 }
    142 
    143 
    144 /**
    145   Get the interface setting of the specified USB device.
    146 
    147   Submit a USB get interface request for the USB device specified by UsbIo,
    148   and Interface, and place the result in the buffer specified by AlternateSetting.
    149   The status of the transfer is returned in Status.
    150   If UsbIo is NULL, then ASSERT().
    151   If AlternateSetting is NULL, then ASSERT().
    152   If Status is NULL, then ASSERT().
    153 
    154   @param  UsbIo             A pointer to the USB I/O Protocol instance for the specific USB target.
    155   @param  Interface         The interface index value.
    156   @param  AlternateSetting  A pointer to the alternate setting to be retrieved.
    157   @param  Status            A pointer to the status of the transfer.
    158 
    159   @retval EFI_SUCCESS       The request executed successfully.
    160   @retval EFI_TIMEOUT       A timeout occurred executing the request.
    161   @retval EFI_DEVICE_ERROR  The request failed due to a device error.
    162                             The transfer status is returned in Status.
    163 
    164 **/
    165 EFI_STATUS
    166 EFIAPI
    167 UsbGetInterface (
    168   IN  EFI_USB_IO_PROTOCOL     *UsbIo,
    169   IN  UINT16                  Interface,
    170   OUT UINT16                  *AlternateSetting,
    171   OUT UINT32                  *Status
    172   )
    173 {
    174   EFI_USB_DEVICE_REQUEST  DevReq;
    175 
    176   ASSERT (UsbIo != NULL);
    177   ASSERT (AlternateSetting != NULL);
    178   ASSERT (Status != NULL);
    179 
    180   *AlternateSetting = 0;
    181 
    182   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
    183 
    184   DevReq.RequestType  = USB_DEV_GET_INTERFACE_REQ_TYPE;
    185   DevReq.Request      = USB_REQ_GET_INTERFACE;
    186   DevReq.Index        = Interface;
    187   DevReq.Length       = 1;
    188 
    189   return UsbIo->UsbControlTransfer (
    190                   UsbIo,
    191                   &DevReq,
    192                   EfiUsbDataIn,
    193                   PcdGet32 (PcdUsbTransferTimeoutValue),
    194                   AlternateSetting,
    195                   1,
    196                   Status
    197                   );
    198 }
    199 
    200 
    201 /**
    202   Set the interface setting of the specified USB device.
    203 
    204   Submit a USB set interface request for the USB device specified by UsbIo, and
    205   Interface, and set the alternate setting to the value specified by AlternateSetting.
    206   The status of the transfer is returned in Status.
    207   If UsbIo is NULL, then ASSERT().
    208   If Status is NULL, then ASSERT().
    209 
    210   @param  UsbIo             A pointer to the USB I/O Protocol instance for the specific USB target.
    211   @param  Interface         The interface index value.
    212   @param  AlternateSetting  The alternate setting to be set.
    213   @param  Status            A pointer to the status of the transfer.
    214 
    215   @retval EFI_SUCCESS  The request executed successfully.
    216   @retval EFI_TIMEOUT  A timeout occurred executing the request.
    217   @retval EFI_SUCCESS  The request failed due to a device error.
    218                        The transfer status is returned in Status.
    219 
    220 **/
    221 EFI_STATUS
    222 EFIAPI
    223 UsbSetInterface (
    224   IN  EFI_USB_IO_PROTOCOL     *UsbIo,
    225   IN  UINT16                  Interface,
    226   IN  UINT16                  AlternateSetting,
    227   OUT UINT32                  *Status
    228   )
    229 {
    230   EFI_USB_DEVICE_REQUEST  DevReq;
    231 
    232   ASSERT (UsbIo != NULL);
    233   ASSERT (Status != NULL);
    234 
    235   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
    236 
    237   DevReq.RequestType  = USB_DEV_SET_INTERFACE_REQ_TYPE;
    238   DevReq.Request      = USB_REQ_SET_INTERFACE;
    239   DevReq.Value        = AlternateSetting;
    240   DevReq.Index        = Interface;
    241 
    242   return UsbIo->UsbControlTransfer (
    243                   UsbIo,
    244                   &DevReq,
    245                   EfiUsbNoData,
    246                   PcdGet32 (PcdUsbTransferTimeoutValue),
    247                   NULL,
    248                   0,
    249                   Status
    250                   );
    251 }
    252 
    253 
    254 /**
    255   Get the device configuration.
    256 
    257   Submit a USB get configuration request for the USB device specified by UsbIo
    258   and place the result in the buffer specified by ConfigurationValue. The status
    259   of the transfer is returned in Status.
    260   If UsbIo is NULL, then ASSERT().
    261   If ConfigurationValue is NULL, then ASSERT().
    262   If Status is NULL, then ASSERT().
    263 
    264   @param  UsbIo               A pointer to the USB I/O Protocol instance for the specific USB target.
    265   @param  ConfigurationValue  A pointer to the device configuration to be retrieved.
    266   @param  Status              A pointer to the status of the transfer.
    267 
    268   @retval EFI_SUCCESS        The request executed successfully.
    269   @retval EFI_TIMEOUT        A timeout occurred executing the request.
    270   @retval EFI_DEVICE_ERROR   The request failed due to a device error.
    271                              The transfer status is returned in Status.
    272 
    273 **/
    274 EFI_STATUS
    275 EFIAPI
    276 UsbGetConfiguration (
    277   IN  EFI_USB_IO_PROTOCOL     *UsbIo,
    278   OUT UINT16                  *ConfigurationValue,
    279   OUT UINT32                  *Status
    280   )
    281 {
    282   EFI_USB_DEVICE_REQUEST  DevReq;
    283 
    284   ASSERT (UsbIo != NULL);
    285   ASSERT (ConfigurationValue != NULL);
    286   ASSERT (Status != NULL);
    287 
    288   *ConfigurationValue = 0;
    289 
    290   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
    291 
    292   DevReq.RequestType  = USB_DEV_GET_CONFIGURATION_REQ_TYPE;
    293   DevReq.Request      = USB_REQ_GET_CONFIG;
    294   DevReq.Length       = 1;
    295 
    296   return UsbIo->UsbControlTransfer (
    297                   UsbIo,
    298                   &DevReq,
    299                   EfiUsbDataIn,
    300                   PcdGet32 (PcdUsbTransferTimeoutValue),
    301                   ConfigurationValue,
    302                   1,
    303                   Status
    304                   );
    305 }
    306 
    307 
    308 /**
    309   Set the device configuration.
    310 
    311   Submit a USB set configuration request for the USB device specified by UsbIo
    312   and set the device configuration to the value specified by ConfigurationValue.
    313   The status of the transfer is returned in Status.
    314   If UsbIo is NULL, then ASSERT().
    315   If Status is NULL, then ASSERT().
    316 
    317   @param  UsbIo               A pointer to the USB I/O Protocol instance for the specific USB target.
    318   @param  ConfigurationValue  The device configuration value to be set.
    319   @param  Status              A pointer to the status of the transfer.
    320 
    321   @retval EFI_SUCCESS       The request executed successfully.
    322   @retval EFI_TIMEOUT       A timeout occurred executing the request.
    323   @retval EFI_DEVICE_ERROR  The request failed due to a device error.
    324                             The transfer status is returned in Status.
    325 
    326 **/
    327 EFI_STATUS
    328 EFIAPI
    329 UsbSetConfiguration (
    330   IN  EFI_USB_IO_PROTOCOL     *UsbIo,
    331   IN  UINT16                  ConfigurationValue,
    332   OUT UINT32                  *Status
    333   )
    334 {
    335   EFI_USB_DEVICE_REQUEST  DevReq;
    336 
    337   ASSERT (UsbIo != NULL);
    338   ASSERT (Status != NULL);
    339 
    340   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
    341 
    342   DevReq.RequestType  = USB_DEV_SET_CONFIGURATION_REQ_TYPE;
    343   DevReq.Request      = USB_REQ_SET_CONFIG;
    344   DevReq.Value        = ConfigurationValue;
    345 
    346   return UsbIo->UsbControlTransfer (
    347                   UsbIo,
    348                   &DevReq,
    349                   EfiUsbNoData,
    350                   PcdGet32 (PcdUsbTransferTimeoutValue),
    351                   NULL,
    352                   0,
    353                   Status
    354                   );
    355 }
    356 
    357 
    358 /**
    359   Set the specified feature of the specified device.
    360 
    361   Submit a USB set device feature request for the USB device specified by UsbIo,
    362   Recipient, and Target to the value specified by Value.  The status of the
    363   transfer is returned in Status.
    364   If UsbIo is NULL, then ASSERT().
    365   If Status is NULL, then ASSERT().
    366 
    367   @param  UsbIo      A pointer to the USB I/O Protocol instance for the specific USB target.
    368   @param  Recipient  The USB data recipient type (i.e. Device, Interface, Endpoint).
    369                      Type USB_TYPES_DEFINITION is defined in the MDE Package Industry
    370                      Standard include file Usb.h.
    371   @param  Value      The value of the feature to be set.
    372   @param  Target     The index of the device to be set.
    373   @param  Status     A pointer to the status of the transfer.
    374 
    375   @retval EFI_SUCCESS       The request executed successfully.
    376   @retval EFI_TIMEOUT       A timeout occurred executing the request.
    377   @retval EFI_DEVICE_ERROR  The request failed due to a device error.
    378                             The transfer status is returned in Status.
    379 
    380 **/
    381 EFI_STATUS
    382 EFIAPI
    383 UsbSetFeature (
    384   IN  EFI_USB_IO_PROTOCOL     *UsbIo,
    385   IN  USB_TYPES_DEFINITION    Recipient,
    386   IN  UINT16                  Value,
    387   IN  UINT16                  Target,
    388   OUT UINT32                  *Status
    389   )
    390 {
    391   EFI_USB_DEVICE_REQUEST  DevReq;
    392 
    393   ASSERT (UsbIo != NULL);
    394   ASSERT (Status != NULL);
    395 
    396   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
    397 
    398   switch (Recipient) {
    399 
    400   case USB_TARGET_DEVICE:
    401     DevReq.RequestType = USB_DEV_SET_FEATURE_REQ_TYPE_D;
    402     break;
    403 
    404   case USB_TARGET_INTERFACE:
    405     DevReq.RequestType = USB_DEV_SET_FEATURE_REQ_TYPE_I;
    406     break;
    407 
    408   case USB_TARGET_ENDPOINT:
    409     DevReq.RequestType = USB_DEV_SET_FEATURE_REQ_TYPE_E;
    410     break;
    411 
    412   default:
    413     break;
    414   }
    415   //
    416   // Fill device request, see USB1.1 spec
    417   //
    418   DevReq.Request  = USB_REQ_SET_FEATURE;
    419   DevReq.Value    = Value;
    420   DevReq.Index    = Target;
    421 
    422 
    423   return UsbIo->UsbControlTransfer (
    424                   UsbIo,
    425                   &DevReq,
    426                   EfiUsbNoData,
    427                   PcdGet32 (PcdUsbTransferTimeoutValue),
    428                   NULL,
    429                   0,
    430                   Status
    431                   );
    432 }
    433 
    434 
    435 /**
    436   Clear the specified feature of the specified device.
    437 
    438   Submit a USB clear device feature request for the USB device specified by UsbIo,
    439   Recipient, and Target to the value specified by Value.  The status of the transfer
    440   is returned in Status.
    441   If UsbIo is NULL, then ASSERT().
    442   If Status is NULL, then ASSERT().
    443 
    444   @param  UsbIo      A pointer to the USB I/O Protocol instance for the specific USB target.
    445   @param  Recipient  The USB data recipient type (i.e. Device, Interface, Endpoint).
    446                      Type USB_TYPES_DEFINITION is defined in the MDE Package Industry Standard
    447                      include file Usb.h.
    448   @param  Value      The value of the feature to be cleared.
    449   @param  Target     The index of the device to be cleared.
    450   @param  Status     A pointer to the status of the transfer.
    451 
    452   @retval EFI_SUCCESS       The request executed successfully.
    453   @retval EFI_TIMEOUT       A timeout occurred executing the request.
    454   @retval EFI_DEVICE_ERROR  The request failed due to a device error.
    455                             The transfer status is returned in Status.
    456 
    457 **/
    458 EFI_STATUS
    459 EFIAPI
    460 UsbClearFeature (
    461   IN  EFI_USB_IO_PROTOCOL     *UsbIo,
    462   IN  USB_TYPES_DEFINITION    Recipient,
    463   IN  UINT16                  Value,
    464   IN  UINT16                  Target,
    465   OUT UINT32                  *Status
    466   )
    467 {
    468   EFI_USB_DEVICE_REQUEST  DevReq;
    469 
    470   ASSERT (UsbIo != NULL);
    471   ASSERT (Status != NULL);
    472 
    473 
    474   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
    475 
    476   switch (Recipient) {
    477 
    478   case USB_TARGET_DEVICE:
    479     DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_D;
    480     break;
    481 
    482   case USB_TARGET_INTERFACE:
    483     DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_I;
    484     break;
    485 
    486   case USB_TARGET_ENDPOINT:
    487     DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_E;
    488     break;
    489 
    490   default:
    491     break;
    492   }
    493   //
    494   // Fill device request, see USB1.1 spec
    495   //
    496   DevReq.Request  = USB_REQ_CLEAR_FEATURE;
    497   DevReq.Value    = Value;
    498   DevReq.Index    = Target;
    499 
    500 
    501   return UsbIo->UsbControlTransfer (
    502                   UsbIo,
    503                   &DevReq,
    504                   EfiUsbNoData,
    505                   PcdGet32 (PcdUsbTransferTimeoutValue),
    506                   NULL,
    507                   0,
    508                   Status
    509                   );
    510 }
    511 
    512 
    513 /**
    514   Get the status of the specified device.
    515 
    516   Submit a USB device get status request for the USB device specified by UsbIo,
    517   Recipient, and Target and place the result in the buffer specified by DeviceStatus.
    518   The status of the transfer is returned in Status.
    519   If UsbIo is NULL, then ASSERT().
    520   If DeviceStatus is NULL, then ASSERT().
    521   If Status is NULL, then ASSERT().
    522 
    523   @param  UsbIo         A pointer to the USB I/O Protocol instance for the specific USB target.
    524   @param  Recipient     The USB data recipient type (i.e. Device, Interface, Endpoint).
    525                         Type USB_TYPES_DEFINITION is defined in the MDE Package Industry Standard
    526                         include file Usb.h.
    527   @param  Target        The index of the device to be get the status of.
    528   @param  DeviceStatus  A pointer to the device status to be retrieved.
    529   @param  Status        A pointer to the status of the transfer.
    530 
    531   @retval EFI_SUCCESS       The request executed successfully.
    532   @retval EFI_TIMEOUT       A timeout occurred executing the request.
    533   @retval EFI_DEVICE_ERROR  The request failed due to a device error.
    534                             The transfer status is returned in Status.
    535 
    536 **/
    537 EFI_STATUS
    538 EFIAPI
    539 UsbGetStatus (
    540   IN  EFI_USB_IO_PROTOCOL     *UsbIo,
    541   IN  USB_TYPES_DEFINITION    Recipient,
    542   IN  UINT16                  Target,
    543   OUT UINT16                  *DeviceStatus,
    544   OUT UINT32                  *Status
    545   )
    546 {
    547   EFI_USB_DEVICE_REQUEST  DevReq;
    548 
    549   ASSERT (UsbIo != NULL);
    550   ASSERT (DeviceStatus != NULL);
    551   ASSERT (Status != NULL);
    552 
    553   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
    554 
    555   switch (Recipient) {
    556 
    557   case USB_TARGET_DEVICE:
    558     DevReq.RequestType = USB_DEV_GET_STATUS_REQ_TYPE_D;
    559     break;
    560 
    561   case USB_TARGET_INTERFACE:
    562     DevReq.RequestType = USB_DEV_GET_STATUS_REQ_TYPE_I;
    563     break;
    564 
    565   case USB_TARGET_ENDPOINT:
    566     DevReq.RequestType = USB_DEV_GET_STATUS_REQ_TYPE_E;
    567     break;
    568 
    569   default:
    570     break;
    571   }
    572   //
    573   // Fill device request, see USB1.1 spec
    574   //
    575   DevReq.Request  = USB_REQ_GET_STATUS;
    576   DevReq.Value    = 0;
    577   DevReq.Index    = Target;
    578   DevReq.Length   = 2;
    579 
    580   return UsbIo->UsbControlTransfer (
    581                   UsbIo,
    582                   &DevReq,
    583                   EfiUsbDataIn,
    584                   PcdGet32 (PcdUsbTransferTimeoutValue),
    585                   DeviceStatus,
    586                   2,
    587                   Status
    588                   );
    589 }
    590 
    591 
    592 /**
    593   Clear halt feature of the specified usb endpoint.
    594 
    595   Retrieve the USB endpoint descriptor specified by UsbIo and EndPoint.
    596   If the USB endpoint descriptor can not be retrieved, then return EFI_NOT_FOUND.
    597   If the endpoint descriptor is found, then clear the halt feature of this USB endpoint.
    598   The status of the transfer is returned in Status.
    599   If UsbIo is NULL, then ASSERT().
    600   If Status is NULL, then ASSERT().
    601 
    602   @param  UsbIo     A pointer to the USB I/O Protocol instance for the specific USB target.
    603   @param  Endpoint  The endpoint address.
    604   @param  Status    A pointer to the status of the transfer.
    605 
    606   @retval EFI_SUCCESS       The request executed successfully.
    607   @retval EFI_TIMEOUT       A timeout occurred executing the request.
    608   @retval EFI_DEVICE_ERROR  The request failed due to a device error.
    609                             The transfer status is returned in Status.
    610   @retval EFI_NOT_FOUND     The specified USB endpoint descriptor can not be found
    611 
    612 **/
    613 EFI_STATUS
    614 EFIAPI
    615 UsbClearEndpointHalt (
    616   IN  EFI_USB_IO_PROTOCOL     *UsbIo,
    617   IN  UINT8                   Endpoint,
    618   OUT UINT32                  *Status
    619   )
    620 {
    621   EFI_STATUS                    Result;
    622   EFI_USB_ENDPOINT_DESCRIPTOR   EndpointDescriptor;
    623   EFI_USB_INTERFACE_DESCRIPTOR  InterfaceDescriptor;
    624   UINT8                         Index;
    625 
    626   ASSERT (UsbIo != NULL);
    627   ASSERT (Status != NULL);
    628 
    629   ZeroMem (&EndpointDescriptor, sizeof (EFI_USB_ENDPOINT_DESCRIPTOR));
    630   //
    631   // First seach the endpoint descriptor for that endpoint addr
    632   //
    633   Result = UsbIo->UsbGetInterfaceDescriptor (
    634                     UsbIo,
    635                     &InterfaceDescriptor
    636                     );
    637   if (EFI_ERROR (Result)) {
    638     return Result;
    639   }
    640 
    641   for (Index = 0; Index < InterfaceDescriptor.NumEndpoints; Index++) {
    642     Result = UsbIo->UsbGetEndpointDescriptor (
    643                       UsbIo,
    644                       Index,
    645                       &EndpointDescriptor
    646                       );
    647     if (EFI_ERROR (Result)) {
    648       continue;
    649     }
    650 
    651     if (EndpointDescriptor.EndpointAddress == Endpoint) {
    652       break;
    653     }
    654   }
    655 
    656   if (Index == InterfaceDescriptor.NumEndpoints) {
    657     //
    658     // No such endpoint
    659     //
    660     return EFI_NOT_FOUND;
    661   }
    662 
    663   Result = UsbClearFeature (
    664             UsbIo,
    665             USB_TARGET_ENDPOINT,
    666             USB_FEATURE_ENDPOINT_HALT,
    667             EndpointDescriptor.EndpointAddress,
    668             Status
    669             );
    670 
    671   return Result;
    672 }
    673