/** @file\r
The module is used to implement Usb Io PPI interfaces.\r
\r
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved. <BR>\r
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved. <BR>\r
\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions\r
@param This The pointer of PEI_USB_IO_PPI.\r
@param Request USB device request to send.\r
@param Direction Specifies the data direction for the data stage.\r
- @param Timeout Indicates the maximum timeout, in millisecond.\r
+ @param Timeout Indicates the maximum timeout, in millisecond. If Timeout\r
+ is 0, then the caller must wait for the function to be\r
+ completed until EFI_SUCCESS or EFI_DEVICE_ERROR is returned.\r
@param Data Data buffer to be transmitted or received from USB device.\r
@param DataLength The size (in bytes) of the data buffer.\r
\r
EFI_STATUS Status;\r
PEI_USB_DEVICE *PeiUsbDev;\r
UINT32 TransferResult;\r
+ EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor;\r
+ UINT8 EndpointIndex;\r
\r
PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This);\r
\r
+ EndpointDescriptor = NULL;\r
+ EndpointIndex = 0;\r
+\r
+ if ((Request->Request == USB_REQ_CLEAR_FEATURE) &&\r
+ (Request->RequestType == USB_DEV_CLEAR_FEATURE_REQ_TYPE_E) &&\r
+ (Request->Value == USB_FEATURE_ENDPOINT_HALT)) {\r
+ //\r
+ // Request->Index is the Endpoint Address, use it to get the Endpoint Index.\r
+ //\r
+ while (EndpointIndex < MAX_ENDPOINT) {\r
+ Status = PeiUsbGetEndpointDescriptor (PeiServices, This, EndpointIndex, &EndpointDescriptor);\r
+ if (EFI_ERROR (Status)) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+\r
+ if (EndpointDescriptor->EndpointAddress == Request->Index) {\r
+ break;\r
+ }\r
+\r
+ EndpointIndex++;\r
+ }\r
+\r
+ if (EndpointIndex == MAX_ENDPOINT) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ }\r
+\r
if (PeiUsbDev->Usb2HcPpi != NULL) {\r
Status = PeiUsbDev->Usb2HcPpi->ControlTransfer (\r
PeiServices,\r
PeiUsbDev->UsbHcPpi,\r
PeiUsbDev->DeviceAddress,\r
PeiUsbDev->DeviceSpeed,\r
- PeiUsbDev->MaxPacketSize0,\r
+ (UINT8) PeiUsbDev->MaxPacketSize0,\r
Request,\r
Direction,\r
Data,\r
&TransferResult\r
);\r
}\r
+\r
+ //\r
+ // Reset the endpoint toggle when endpoint stall is cleared\r
+ //\r
+ if ((Request->Request == USB_REQ_CLEAR_FEATURE) &&\r
+ (Request->RequestType == USB_DEV_CLEAR_FEATURE_REQ_TYPE_E) &&\r
+ (Request->Value == USB_FEATURE_ENDPOINT_HALT)) {\r
+ if ((PeiUsbDev->DataToggle & (1 << EndpointIndex)) != 0) {\r
+ PeiUsbDev->DataToggle = (UINT16) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex));\r
+ }\r
+ }\r
+\r
+ DEBUG ((EFI_D_INFO, "PeiUsbControlTransfer: %r\n", Status));\r
return Status;\r
}\r
\r
from or receive into.\r
@param DataLength The lenght of the data buffer.\r
@param Timeout Indicates the maximum time, in millisecond, which the\r
- transfer is allowed to complete.\r
+ transfer is allowed to complete. If Timeout is 0, then\r
+ the caller must wait for the function to be completed\r
+ until EFI_SUCCESS or EFI_DEVICE_ERROR is returned.\r
\r
@retval EFI_SUCCESS The transfer was completed successfully.\r
@retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource.\r
}\r
\r
if (OldToggle != DataToggle) {\r
- PeiUsbDev->DataToggle = (UINT8) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex));\r
+ PeiUsbDev->DataToggle = (UINT16) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex));\r
}\r
\r
+ DEBUG ((EFI_D_INFO, "PeiUsbBulkTransfer: %r\n", Status));\r
return Status;\r
}\r
\r