1 /** @file
2 Common Libarary for PEI USB
3 
4 Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved. <BR>
5 
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions
8 of the BSD License which accompanies this distribution.  The
9 full text of the license may be found at
10 http://opensource.org/licenses/bsd-license.php
11 
12 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
13 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
14 
15 **/
16 
17 #include "UsbPeim.h"
18 #include "PeiUsbLib.h"
19 
20 /**
21   Get a given usb descriptor.
22 
23   @param  PeiServices        General-purpose services that are available to every PEIM.
24   @param  UsbIoPpi           Indicates the PEI_USB_IO_PPI instance.
25   @param  Value              Request Value.
26   @param  Index              Request Index.
27   @param  DescriptorLength   Request descriptor Length.
28   @param  Descriptor         Request descriptor.
29 
30 
31   @retval EFI_SUCCESS       Usb descriptor is obtained successfully.
32   @retval EFI_DEVICE_ERROR  Cannot get the usb descriptor due to a hardware error.
33   @retval Others            Other failure occurs.
34 
35 **/
36 EFI_STATUS
PeiUsbGetDescriptor(IN EFI_PEI_SERVICES ** PeiServices,IN PEI_USB_IO_PPI * UsbIoPpi,IN UINT16 Value,IN UINT16 Index,IN UINT16 DescriptorLength,OUT VOID * Descriptor)37 PeiUsbGetDescriptor (
38   IN  EFI_PEI_SERVICES         **PeiServices,
39   IN  PEI_USB_IO_PPI           *UsbIoPpi,
40   IN  UINT16                   Value,
41   IN  UINT16                   Index,
42   IN  UINT16                   DescriptorLength,
43   OUT VOID                     *Descriptor
44   )
45 {
46   EFI_USB_DEVICE_REQUEST  DevReq;
47 
48   ASSERT (UsbIoPpi != NULL);
49 
50   DevReq.RequestType  = USB_DEV_GET_DESCRIPTOR_REQ_TYPE;
51   DevReq.Request      = USB_DEV_GET_DESCRIPTOR;
52   DevReq.Value        = Value;
53   DevReq.Index        = Index;
54   DevReq.Length       = DescriptorLength;
55 
56   return UsbIoPpi->UsbControlTransfer (
57                      PeiServices,
58                      UsbIoPpi,
59                      &DevReq,
60                      EfiUsbDataIn,
61                      PcdGet32 (PcdUsbTransferTimeoutValue),
62                      Descriptor,
63                      DescriptorLength
64                      );
65 }
66 
67 /**
68   Set a usb device with a specified address.
69 
70   @param  PeiServices        General-purpose services that are available to every PEIM.
71   @param  UsbIoPpi           Indicates the PEI_USB_IO_PPI instance.
72   @param  AddressValue       The address to assign.
73 
74   @retval EFI_SUCCESS       Usb device address is set successfully.
75   @retval EFI_DEVICE_ERROR  Cannot set the usb address due to a hardware error.
76   @retval Others            Other failure occurs.
77 
78 **/
79 EFI_STATUS
PeiUsbSetDeviceAddress(IN EFI_PEI_SERVICES ** PeiServices,IN PEI_USB_IO_PPI * UsbIoPpi,IN UINT16 AddressValue)80 PeiUsbSetDeviceAddress (
81   IN EFI_PEI_SERVICES         **PeiServices,
82   IN PEI_USB_IO_PPI           *UsbIoPpi,
83   IN UINT16                   AddressValue
84   )
85 {
86   EFI_USB_DEVICE_REQUEST  DevReq;
87 
88   ASSERT (UsbIoPpi != NULL);
89 
90   DevReq.RequestType  = USB_DEV_SET_ADDRESS_REQ_TYPE;
91   DevReq.Request      = USB_DEV_SET_ADDRESS;
92   DevReq.Value        = AddressValue;
93   DevReq.Index        = 0;
94   DevReq.Length       = 0;
95 
96   return UsbIoPpi->UsbControlTransfer (
97                      PeiServices,
98                      UsbIoPpi,
99                      &DevReq,
100                      EfiUsbNoData,
101                      PcdGet32 (PcdUsbTransferTimeoutValue),
102                      NULL,
103                      0
104                      );
105 }
106 
107 /**
108   Clear a given usb feature.
109 
110   @param  PeiServices       General-purpose services that are available to every PEIM.
111   @param  UsbIoPpi          Indicates the PEI_USB_IO_PPI instance.
112   @param  Recipient         The recipient of ClearFeature Request, should be one of Device/Interface/Endpoint.
113   @param  Value             Request Value.
114   @param  Target            Request Index.
115 
116   @retval EFI_SUCCESS       Usb feature is cleared successfully.
117   @retval EFI_DEVICE_ERROR  Cannot clear the usb feature due to a hardware error.
118   @retval Others            Other failure occurs.
119 
120 **/
121 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)122 PeiUsbClearDeviceFeature (
123   IN EFI_PEI_SERVICES         **PeiServices,
124   IN PEI_USB_IO_PPI           *UsbIoPpi,
125   IN EFI_USB_RECIPIENT        Recipient,
126   IN UINT16                   Value,
127   IN UINT16                   Target
128   )
129 {
130   EFI_USB_DEVICE_REQUEST  DevReq;
131 
132   ASSERT (UsbIoPpi != NULL);
133 
134   switch (Recipient) {
135   case EfiUsbDevice:
136     DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_D;
137     break;
138 
139   case EfiUsbInterface:
140     DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_I;
141     break;
142 
143   case EfiUsbEndpoint:
144     DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_E;
145     break;
146   }
147 
148   DevReq.Request      = USB_DEV_CLEAR_FEATURE;
149   DevReq.Value        = Value;
150   DevReq.Index        = Target;
151   DevReq.Length       = 0;
152 
153   return UsbIoPpi->UsbControlTransfer (
154                      PeiServices,
155                      UsbIoPpi,
156                      &DevReq,
157                      EfiUsbNoData,
158                      PcdGet32 (PcdUsbTransferTimeoutValue),
159                      NULL,
160                      0
161                      );
162 }
163 
164 /**
165   Configure a usb device to Configuration 1.
166 
167   @param  PeiServices        General-purpose services that are available to every PEIM.
168   @param  UsbIoPpi           Indicates the PEI_USB_IO_PPI instance.
169 
170   @retval EFI_SUCCESS       Usb device is set to use Configuration 1 successfully.
171   @retval EFI_DEVICE_ERROR  Cannot set the usb device due to a hardware error.
172   @retval Others            Other failure occurs.
173 
174 **/
175 EFI_STATUS
PeiUsbSetConfiguration(IN EFI_PEI_SERVICES ** PeiServices,IN PEI_USB_IO_PPI * UsbIoPpi)176 PeiUsbSetConfiguration (
177   IN EFI_PEI_SERVICES         **PeiServices,
178   IN PEI_USB_IO_PPI           *UsbIoPpi
179   )
180 {
181   EFI_USB_DEVICE_REQUEST  DevReq;
182   ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));
183 
184   DevReq.RequestType  = USB_DEV_SET_CONFIGURATION_REQ_TYPE;
185   DevReq.Request      = USB_DEV_SET_CONFIGURATION;
186   DevReq.Value        = 1;
187 
188   return UsbIoPpi->UsbControlTransfer (
189                      PeiServices,
190                      UsbIoPpi,
191                      &DevReq,
192                      EfiUsbNoData,
193                      PcdGet32 (PcdUsbTransferTimeoutValue),
194                      NULL,
195                      0
196                      );
197 }
198 
199 /**
200   Judge if the port is connected with a usb device or not.
201 
202   @param  PortStatus  The usb port status gotten.
203 
204   @retval TRUE        A usb device is connected with the port.
205   @retval FALSE       No usb device is connected with the port.
206 
207 **/
208 BOOLEAN
IsPortConnect(IN UINT16 PortStatus)209 IsPortConnect (
210   IN UINT16  PortStatus
211   )
212 {
213   //
214   // return the bit 0 value of PortStatus
215   //
216   if ((PortStatus & USB_PORT_STAT_CONNECTION) != 0) {
217     return TRUE;
218   } else {
219     return FALSE;
220   }
221 }
222 
223 /**
224   Get device speed according to port status.
225 
226   @param    PortStatus  The usb port status gotten.
227 
228   @return   Device speed value.
229 
230 **/
231 UINTN
PeiUsbGetDeviceSpeed(IN UINT16 PortStatus)232 PeiUsbGetDeviceSpeed (
233   IN UINT16 PortStatus
234   )
235 {
236   if ((PortStatus & USB_PORT_STAT_LOW_SPEED) != 0) {
237     return EFI_USB_SPEED_LOW;
238   } else if ((PortStatus & USB_PORT_STAT_HIGH_SPEED) != 0){
239     return EFI_USB_SPEED_HIGH;
240   } else if ((PortStatus & USB_PORT_STAT_SUPER_SPEED) != 0) {
241     return EFI_USB_SPEED_SUPER;
242   } else {
243     return EFI_USB_SPEED_FULL;
244   }
245 }
246 
247 /**
248   Judge if the port is in "connection change" status or not.
249 
250   @param  PortChangeStatus  The usb port change status gotten.
251 
252   @retval TRUE              The port is in "connection change" status.
253   @retval FALSE             The port is NOT in "connection change" status.
254 
255 **/
256 BOOLEAN
IsPortConnectChange(IN UINT16 PortChangeStatus)257 IsPortConnectChange (
258   IN UINT16  PortChangeStatus
259   )
260 {
261   //
262   // return the bit 0 value of PortChangeStatus
263   //
264   if ((PortChangeStatus & USB_PORT_STAT_C_CONNECTION) != 0) {
265     return TRUE;
266   } else {
267     return FALSE;
268   }
269 }
270