1 /** @file
2 Common Library  for PEI USB.
3 
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>
5 
6 SPDX-License-Identifier: BSD-2-Clause-Patent
7 
8 **/
9 
10 #include "UsbPeim.h"
11 #include "PeiUsbLib.h"
12 
13 
14 /**
15   Clear a given usb feature.
16 
17   @param  PeiServices       General-purpose services that are available to every PEIM.
18   @param  UsbIoPpi          Indicates the PEI_USB_IO_PPI instance.
19   @param  Recipient         The recipient of ClearFeature Request, should be one of Device/Interface/Endpoint.
20   @param  Value             Request Value.
21   @param  Target            Request Index.
22 
23   @retval EFI_SUCCESS       Usb feature is cleared successfully.
24   @retval EFI_DEVICE_ERROR  Cannot clear the usb feature due to a hardware error.
25   @retval Others            Other failure occurs.
26 
27 **/
28 EFI_STATUS
PeiUsbClearDeviceFeature(IN EFI_PEI_SERVICES ** PeiServices,IN PEI_USB_IO_PPI * UsbIoPpi,IN EFI_USB_RECIPIENT Recipient,IN UINT16 Value,IN UINT16 Target)29 PeiUsbClearDeviceFeature (
30   IN EFI_PEI_SERVICES         **PeiServices,
31   IN PEI_USB_IO_PPI           *UsbIoPpi,
32   IN EFI_USB_RECIPIENT        Recipient,
33   IN UINT16                   Value,
34   IN UINT16                   Target
35   )
36 {
37   EFI_USB_DEVICE_REQUEST  DevReq;
38 
39   ASSERT (UsbIoPpi != NULL);
40 
41   switch (Recipient) {
42   case EfiUsbDevice:
43     DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_D;
44     break;
45 
46   case EfiUsbInterface:
47     DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_I;
48     break;
49 
50   case EfiUsbEndpoint:
51     DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_E;
52     break;
53   }
54 
55   DevReq.Request      = USB_DEV_CLEAR_FEATURE;
56   DevReq.Value        = Value;
57   DevReq.Index        = Target;
58   DevReq.Length       = 0;
59 
60   return UsbIoPpi->UsbControlTransfer (
61                      PeiServices,
62                      UsbIoPpi,
63                      &DevReq,
64                      EfiUsbNoData,
65                      PcdGet32 (PcdUsbTransferTimeoutValue),
66                      NULL,
67                      0
68                      );
69 }
70 
71 
72 /**
73   Clear Endpoint Halt.
74 
75   @param  PeiServices       General-purpose services that are available to every PEIM.
76   @param  UsbIoPpi          Indicates the PEI_USB_IO_PPI instance.
77   @param  EndpointAddress   The endpoint address.
78 
79   @retval EFI_SUCCESS       Endpoint halt is cleared successfully.
80   @retval EFI_DEVICE_ERROR  Cannot clear the endpoint halt status due to a hardware error.
81   @retval Others            Other failure occurs.
82 
83 **/
84 EFI_STATUS
PeiUsbClearEndpointHalt(IN EFI_PEI_SERVICES ** PeiServices,IN PEI_USB_IO_PPI * UsbIoPpi,IN UINT8 EndpointAddress)85 PeiUsbClearEndpointHalt (
86   IN EFI_PEI_SERVICES         **PeiServices,
87   IN PEI_USB_IO_PPI           *UsbIoPpi,
88   IN UINT8                    EndpointAddress
89   )
90 {
91   EFI_STATUS                    Status;
92   EFI_USB_INTERFACE_DESCRIPTOR  *InterfaceDesc;
93   EFI_USB_ENDPOINT_DESCRIPTOR   *EndpointDescriptor;
94   UINT8                         EndpointIndex;
95 
96 
97   //
98   // Check its interface
99   //
100   Status = UsbIoPpi->UsbGetInterfaceDescriptor (
101                       PeiServices,
102                       UsbIoPpi,
103                       &InterfaceDesc
104                       );
105   if (EFI_ERROR (Status)) {
106     return Status;
107   }
108   for (EndpointIndex = 0; EndpointIndex < InterfaceDesc->NumEndpoints; EndpointIndex++) {
109     Status = UsbIoPpi->UsbGetEndpointDescriptor (PeiServices, UsbIoPpi, EndpointIndex, &EndpointDescriptor);
110     if (EFI_ERROR (Status)) {
111       return EFI_INVALID_PARAMETER;
112     }
113 
114     if (EndpointDescriptor->EndpointAddress == EndpointAddress) {
115       break;
116     }
117   }
118 
119   if (EndpointIndex == InterfaceDesc->NumEndpoints) {
120     return EFI_INVALID_PARAMETER;
121   }
122 
123   Status = PeiUsbClearDeviceFeature (
124             PeiServices,
125             UsbIoPpi,
126             EfiUsbEndpoint,
127             EfiUsbEndpointHalt,
128             EndpointAddress
129             );
130 
131   return Status;
132 }
133 
134 
135