2 The module is used to implement Usb Io PPI interfaces.
4 Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved. <BR>
6 SPDX-License-Identifier: BSD-2-Clause-Patent
11 #include "PeiUsbLib.h"
14 Submits control transfer to a target USB device.
16 @param PeiServices The pointer of EFI_PEI_SERVICES.
17 @param This The pointer of PEI_USB_IO_PPI.
18 @param Request USB device request to send.
19 @param Direction Specifies the data direction for the data stage.
20 @param Timeout Indicates the maximum timeout, in millisecond. If Timeout
21 is 0, then the caller must wait for the function to be
22 completed until EFI_SUCCESS or EFI_DEVICE_ERROR is returned.
23 @param Data Data buffer to be transmitted or received from USB device.
24 @param DataLength The size (in bytes) of the data buffer.
26 @retval EFI_SUCCESS Transfer was completed successfully.
27 @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resources.
28 @retval EFI_INVALID_PARAMETER Some parameters are invalid.
29 @retval EFI_TIMEOUT Transfer failed due to timeout.
30 @retval EFI_DEVICE_ERROR Transfer failed due to host controller or device error.
35 PeiUsbControlTransfer (
36 IN EFI_PEI_SERVICES
**PeiServices
,
37 IN PEI_USB_IO_PPI
*This
,
38 IN EFI_USB_DEVICE_REQUEST
*Request
,
39 IN EFI_USB_DATA_DIRECTION Direction
,
41 IN OUT VOID
*Data
, OPTIONAL
42 IN UINTN DataLength OPTIONAL
46 PEI_USB_DEVICE
*PeiUsbDev
;
47 UINT32 TransferResult
;
48 EFI_USB_ENDPOINT_DESCRIPTOR
*EndpointDescriptor
;
51 PeiUsbDev
= PEI_USB_DEVICE_FROM_THIS (This
);
53 EndpointDescriptor
= NULL
;
56 if ((Request
->Request
== USB_REQ_CLEAR_FEATURE
) &&
57 (Request
->RequestType
== USB_DEV_CLEAR_FEATURE_REQ_TYPE_E
) &&
58 (Request
->Value
== USB_FEATURE_ENDPOINT_HALT
)) {
60 // Request->Index is the Endpoint Address, use it to get the Endpoint Index.
62 while (EndpointIndex
< MAX_ENDPOINT
) {
63 Status
= PeiUsbGetEndpointDescriptor (PeiServices
, This
, EndpointIndex
, &EndpointDescriptor
);
64 if (EFI_ERROR (Status
)) {
65 return EFI_INVALID_PARAMETER
;
68 if (EndpointDescriptor
->EndpointAddress
== Request
->Index
) {
75 if (EndpointIndex
== MAX_ENDPOINT
) {
76 return EFI_INVALID_PARAMETER
;
80 if (PeiUsbDev
->Usb2HcPpi
!= NULL
) {
81 Status
= PeiUsbDev
->Usb2HcPpi
->ControlTransfer (
84 PeiUsbDev
->DeviceAddress
,
85 PeiUsbDev
->DeviceSpeed
,
86 PeiUsbDev
->MaxPacketSize0
,
92 &(PeiUsbDev
->Translator
),
96 Status
= PeiUsbDev
->UsbHcPpi
->ControlTransfer (
99 PeiUsbDev
->DeviceAddress
,
100 PeiUsbDev
->DeviceSpeed
,
101 (UINT8
) PeiUsbDev
->MaxPacketSize0
,
112 // Reset the endpoint toggle when endpoint stall is cleared
114 if ((Request
->Request
== USB_REQ_CLEAR_FEATURE
) &&
115 (Request
->RequestType
== USB_DEV_CLEAR_FEATURE_REQ_TYPE_E
) &&
116 (Request
->Value
== USB_FEATURE_ENDPOINT_HALT
)) {
117 if ((PeiUsbDev
->DataToggle
& (1 << EndpointIndex
)) != 0) {
118 PeiUsbDev
->DataToggle
= (UINT16
) (PeiUsbDev
->DataToggle
^ (1 << EndpointIndex
));
122 DEBUG ((EFI_D_INFO
, "PeiUsbControlTransfer: %r\n", Status
));
127 Submits bulk transfer to a bulk endpoint of a USB device.
129 @param PeiServices The pointer of EFI_PEI_SERVICES.
130 @param This The pointer of PEI_USB_IO_PPI.
131 @param DeviceEndpoint Endpoint number and its direction in bit 7.
132 @param Data A pointer to the buffer of data to transmit
133 from or receive into.
134 @param DataLength The lenght of the data buffer.
135 @param Timeout Indicates the maximum time, in millisecond, which the
136 transfer is allowed to complete. If Timeout is 0, then
137 the caller must wait for the function to be completed
138 until EFI_SUCCESS or EFI_DEVICE_ERROR is returned.
140 @retval EFI_SUCCESS The transfer was completed successfully.
141 @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource.
142 @retval EFI_INVALID_PARAMETER Parameters are invalid.
143 @retval EFI_TIMEOUT The transfer failed due to timeout.
144 @retval EFI_DEVICE_ERROR The transfer failed due to host controller error.
150 IN EFI_PEI_SERVICES
**PeiServices
,
151 IN PEI_USB_IO_PPI
*This
,
152 IN UINT8 DeviceEndpoint
,
154 IN OUT UINTN
*DataLength
,
159 PEI_USB_DEVICE
*PeiUsbDev
;
160 UINT32 TransferResult
;
161 UINTN MaxPacketLength
;
164 EFI_USB_ENDPOINT_DESCRIPTOR
*EndpointDescriptor
;
166 VOID
*Data2
[EFI_USB_MAX_BULK_BUFFER_NUM
];
168 PeiUsbDev
= PEI_USB_DEVICE_FROM_THIS (This
);
170 EndpointDescriptor
= NULL
;
175 while (EndpointIndex
< MAX_ENDPOINT
) {
176 Status
= PeiUsbGetEndpointDescriptor (PeiServices
, This
, EndpointIndex
, &EndpointDescriptor
);
177 if (EFI_ERROR (Status
)) {
178 return EFI_INVALID_PARAMETER
;
181 if (EndpointDescriptor
->EndpointAddress
== DeviceEndpoint
) {
188 if (EndpointIndex
== MAX_ENDPOINT
) {
189 return EFI_INVALID_PARAMETER
;
192 MaxPacketLength
= PeiUsbDev
->EndpointDesc
[EndpointIndex
]->MaxPacketSize
;
193 if ((PeiUsbDev
->DataToggle
& (1 << EndpointIndex
)) != 0) {
199 OldToggle
= DataToggle
;
201 if (PeiUsbDev
->Usb2HcPpi
!= NULL
) {
202 Status
= PeiUsbDev
->Usb2HcPpi
->BulkTransfer (
204 PeiUsbDev
->Usb2HcPpi
,
205 PeiUsbDev
->DeviceAddress
,
207 PeiUsbDev
->DeviceSpeed
,
213 &(PeiUsbDev
->Translator
),
217 Status
= PeiUsbDev
->UsbHcPpi
->BulkTransfer (
220 PeiUsbDev
->DeviceAddress
,
222 (UINT8
) MaxPacketLength
,
231 if (OldToggle
!= DataToggle
) {
232 PeiUsbDev
->DataToggle
= (UINT16
) (PeiUsbDev
->DataToggle
^ (1 << EndpointIndex
));
235 DEBUG ((EFI_D_INFO
, "PeiUsbBulkTransfer: %r\n", Status
));
240 Get the usb interface descriptor.
242 @param PeiServices General-purpose services that are available to every PEIM.
243 @param This Indicates the PEI_USB_IO_PPI instance.
244 @param InterfaceDescriptor Request interface descriptor.
247 @retval EFI_SUCCESS Usb interface descriptor is obtained successfully.
252 PeiUsbGetInterfaceDescriptor (
253 IN EFI_PEI_SERVICES
**PeiServices
,
254 IN PEI_USB_IO_PPI
*This
,
255 OUT EFI_USB_INTERFACE_DESCRIPTOR
**InterfaceDescriptor
258 PEI_USB_DEVICE
*PeiUsbDev
;
259 PeiUsbDev
= PEI_USB_DEVICE_FROM_THIS (This
);
260 *InterfaceDescriptor
= PeiUsbDev
->InterfaceDesc
;
265 Get the usb endpoint descriptor.
267 @param PeiServices General-purpose services that are available to every PEIM.
268 @param This Indicates the PEI_USB_IO_PPI instance.
269 @param EndpointIndex The valid index of the specified endpoint.
270 @param EndpointDescriptor Request endpoint descriptor.
272 @retval EFI_SUCCESS Usb endpoint descriptor is obtained successfully.
273 @retval EFI_NOT_FOUND Usb endpoint descriptor is NOT found.
278 PeiUsbGetEndpointDescriptor (
279 IN EFI_PEI_SERVICES
**PeiServices
,
280 IN PEI_USB_IO_PPI
*This
,
281 IN UINT8 EndpointIndex
,
282 OUT EFI_USB_ENDPOINT_DESCRIPTOR
**EndpointDescriptor
285 PEI_USB_DEVICE
*PeiUsbDev
;
287 PeiUsbDev
= PEI_USB_DEVICE_FROM_THIS (This
);
289 ASSERT (EndpointDescriptor
!= NULL
);
292 // The valid range of EndpointIndex is 0..15
293 // If EndpointIndex is lesser than 15 but larger than the number of interfaces,
294 // a EFI_NOT_FOUND should be returned
296 ASSERT (EndpointIndex
<= 15);
298 if (EndpointIndex
>= PeiUsbDev
->InterfaceDesc
->NumEndpoints
) {
299 return EFI_NOT_FOUND
;
302 *EndpointDescriptor
= PeiUsbDev
->EndpointDesc
[EndpointIndex
];
308 Reset the port and re-configure the usb device.
310 @param PeiServices General-purpose services that are available to every PEIM.
311 @param This Indicates the PEI_USB_IO_PPI instance.
313 @retval EFI_SUCCESS Usb device is reset and configured successfully.
314 @retval Others Other failure occurs.
320 IN EFI_PEI_SERVICES
**PeiServices
,
321 IN PEI_USB_IO_PPI
*This
324 PEI_USB_DEVICE
*PeiUsbDev
;
328 PeiUsbDev
= PEI_USB_DEVICE_FROM_THIS (This
);
333 PeiUsbDev
->Usb2HcPpi
,
334 PeiUsbDev
->DeviceAddress
,
341 Address
= PeiUsbDev
->DeviceAddress
;
342 PeiUsbDev
->DeviceAddress
= 0;
344 Status
= PeiUsbSetDeviceAddress (
350 if (EFI_ERROR (Status
)) {
354 PeiUsbDev
->DeviceAddress
= Address
;
357 // Set default configuration
359 Status
= PeiUsbSetConfiguration (