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
))
61 // Request->Index is the Endpoint Address, use it to get the Endpoint Index.
63 while (EndpointIndex
< MAX_ENDPOINT
) {
64 Status
= PeiUsbGetEndpointDescriptor (PeiServices
, This
, EndpointIndex
, &EndpointDescriptor
);
65 if (EFI_ERROR (Status
)) {
66 return EFI_INVALID_PARAMETER
;
69 if (EndpointDescriptor
->EndpointAddress
== Request
->Index
) {
76 if (EndpointIndex
== MAX_ENDPOINT
) {
77 return EFI_INVALID_PARAMETER
;
81 if (PeiUsbDev
->Usb2HcPpi
!= NULL
) {
82 Status
= PeiUsbDev
->Usb2HcPpi
->ControlTransfer (
85 PeiUsbDev
->DeviceAddress
,
86 PeiUsbDev
->DeviceSpeed
,
87 PeiUsbDev
->MaxPacketSize0
,
93 &(PeiUsbDev
->Translator
),
97 Status
= PeiUsbDev
->UsbHcPpi
->ControlTransfer (
100 PeiUsbDev
->DeviceAddress
,
101 PeiUsbDev
->DeviceSpeed
,
102 (UINT8
)PeiUsbDev
->MaxPacketSize0
,
113 // Reset the endpoint toggle when endpoint stall is cleared
115 if ((Request
->Request
== USB_REQ_CLEAR_FEATURE
) &&
116 (Request
->RequestType
== USB_DEV_CLEAR_FEATURE_REQ_TYPE_E
) &&
117 (Request
->Value
== USB_FEATURE_ENDPOINT_HALT
))
119 if ((PeiUsbDev
->DataToggle
& (1 << EndpointIndex
)) != 0) {
120 PeiUsbDev
->DataToggle
= (UINT16
)(PeiUsbDev
->DataToggle
^ (1 << EndpointIndex
));
124 DEBUG ((DEBUG_INFO
, "PeiUsbControlTransfer: %r\n", Status
));
129 Submits bulk transfer to a bulk endpoint of a USB device.
131 @param PeiServices The pointer of EFI_PEI_SERVICES.
132 @param This The pointer of PEI_USB_IO_PPI.
133 @param DeviceEndpoint Endpoint number and its direction in bit 7.
134 @param Data A pointer to the buffer of data to transmit
135 from or receive into.
136 @param DataLength The length of the data buffer.
137 @param Timeout Indicates the maximum time, in millisecond, which the
138 transfer is allowed to complete. If Timeout is 0, then
139 the caller must wait for the function to be completed
140 until EFI_SUCCESS or EFI_DEVICE_ERROR is returned.
142 @retval EFI_SUCCESS The transfer was completed successfully.
143 @retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource.
144 @retval EFI_INVALID_PARAMETER Parameters are invalid.
145 @retval EFI_TIMEOUT The transfer failed due to timeout.
146 @retval EFI_DEVICE_ERROR The transfer failed due to host controller error.
152 IN EFI_PEI_SERVICES
**PeiServices
,
153 IN PEI_USB_IO_PPI
*This
,
154 IN UINT8 DeviceEndpoint
,
156 IN OUT UINTN
*DataLength
,
161 PEI_USB_DEVICE
*PeiUsbDev
;
162 UINT32 TransferResult
;
163 UINTN MaxPacketLength
;
166 EFI_USB_ENDPOINT_DESCRIPTOR
*EndpointDescriptor
;
168 VOID
*Data2
[EFI_USB_MAX_BULK_BUFFER_NUM
];
170 PeiUsbDev
= PEI_USB_DEVICE_FROM_THIS (This
);
172 EndpointDescriptor
= NULL
;
177 while (EndpointIndex
< MAX_ENDPOINT
) {
178 Status
= PeiUsbGetEndpointDescriptor (PeiServices
, This
, EndpointIndex
, &EndpointDescriptor
);
179 if (EFI_ERROR (Status
)) {
180 return EFI_INVALID_PARAMETER
;
183 if (EndpointDescriptor
->EndpointAddress
== DeviceEndpoint
) {
190 if (EndpointIndex
== MAX_ENDPOINT
) {
191 return EFI_INVALID_PARAMETER
;
194 MaxPacketLength
= PeiUsbDev
->EndpointDesc
[EndpointIndex
]->MaxPacketSize
;
195 if ((PeiUsbDev
->DataToggle
& (1 << EndpointIndex
)) != 0) {
201 OldToggle
= DataToggle
;
203 if (PeiUsbDev
->Usb2HcPpi
!= NULL
) {
204 Status
= PeiUsbDev
->Usb2HcPpi
->BulkTransfer (
206 PeiUsbDev
->Usb2HcPpi
,
207 PeiUsbDev
->DeviceAddress
,
209 PeiUsbDev
->DeviceSpeed
,
215 &(PeiUsbDev
->Translator
),
219 Status
= PeiUsbDev
->UsbHcPpi
->BulkTransfer (
222 PeiUsbDev
->DeviceAddress
,
224 (UINT8
)MaxPacketLength
,
233 if (OldToggle
!= DataToggle
) {
234 PeiUsbDev
->DataToggle
= (UINT16
)(PeiUsbDev
->DataToggle
^ (1 << EndpointIndex
));
237 DEBUG ((DEBUG_INFO
, "PeiUsbBulkTransfer: %r\n", Status
));
242 Get the usb interface descriptor.
244 @param PeiServices General-purpose services that are available to every PEIM.
245 @param This Indicates the PEI_USB_IO_PPI instance.
246 @param InterfaceDescriptor Request interface descriptor.
249 @retval EFI_SUCCESS Usb interface descriptor is obtained successfully.
254 PeiUsbGetInterfaceDescriptor (
255 IN EFI_PEI_SERVICES
**PeiServices
,
256 IN PEI_USB_IO_PPI
*This
,
257 OUT EFI_USB_INTERFACE_DESCRIPTOR
**InterfaceDescriptor
260 PEI_USB_DEVICE
*PeiUsbDev
;
262 PeiUsbDev
= PEI_USB_DEVICE_FROM_THIS (This
);
263 *InterfaceDescriptor
= PeiUsbDev
->InterfaceDesc
;
268 Get the usb endpoint descriptor.
270 @param PeiServices General-purpose services that are available to every PEIM.
271 @param This Indicates the PEI_USB_IO_PPI instance.
272 @param EndpointIndex The valid index of the specified endpoint.
273 @param EndpointDescriptor Request endpoint descriptor.
275 @retval EFI_SUCCESS Usb endpoint descriptor is obtained successfully.
276 @retval EFI_NOT_FOUND Usb endpoint descriptor is NOT found.
281 PeiUsbGetEndpointDescriptor (
282 IN EFI_PEI_SERVICES
**PeiServices
,
283 IN PEI_USB_IO_PPI
*This
,
284 IN UINT8 EndpointIndex
,
285 OUT EFI_USB_ENDPOINT_DESCRIPTOR
**EndpointDescriptor
288 PEI_USB_DEVICE
*PeiUsbDev
;
290 PeiUsbDev
= PEI_USB_DEVICE_FROM_THIS (This
);
292 ASSERT (EndpointDescriptor
!= NULL
);
295 // The valid range of EndpointIndex is 0..15
296 // If EndpointIndex is lesser than 15 but larger than the number of interfaces,
297 // a EFI_NOT_FOUND should be returned
299 ASSERT (EndpointIndex
<= 15);
301 if (EndpointIndex
>= PeiUsbDev
->InterfaceDesc
->NumEndpoints
) {
302 return EFI_NOT_FOUND
;
305 *EndpointDescriptor
= PeiUsbDev
->EndpointDesc
[EndpointIndex
];
311 Reset the port and re-configure the usb device.
313 @param PeiServices General-purpose services that are available to every PEIM.
314 @param This Indicates the PEI_USB_IO_PPI instance.
316 @retval EFI_SUCCESS Usb device is reset and configured successfully.
317 @retval Others Other failure occurs.
323 IN EFI_PEI_SERVICES
**PeiServices
,
324 IN PEI_USB_IO_PPI
*This
327 PEI_USB_DEVICE
*PeiUsbDev
;
331 PeiUsbDev
= PEI_USB_DEVICE_FROM_THIS (This
);
336 PeiUsbDev
->Usb2HcPpi
,
337 PeiUsbDev
->DeviceAddress
,
344 Address
= PeiUsbDev
->DeviceAddress
;
345 PeiUsbDev
->DeviceAddress
= 0;
347 Status
= PeiUsbSetDeviceAddress (
353 if (EFI_ERROR (Status
)) {
357 PeiUsbDev
->DeviceAddress
= Address
;
360 // Set default configuration
362 Status
= PeiUsbSetConfiguration (