X-Git-Url: https://git.proxmox.com/?a=blobdiff_plain;ds=inline;f=MdeModulePkg%2FBus%2FUsb%2FUsbBusPei%2FUsbIoPeim.c;h=d13a7ee0a336fc9240f2e6b5982f070ee73c7821;hb=d987459f8e0b78831c95188b5b0d712ed6a54c88;hp=897b22896a2bc5d9a706df58ccfcc70697d354d4;hpb=4b1bf81c20d5523554a83f6604df7930396f7c21;p=mirror_edk2.git
diff --git a/MdeModulePkg/Bus/Usb/UsbBusPei/UsbIoPeim.c b/MdeModulePkg/Bus/Usb/UsbBusPei/UsbIoPeim.c
index 897b22896a..d13a7ee0a3 100644
--- a/MdeModulePkg/Bus/Usb/UsbBusPei/UsbIoPeim.c
+++ b/MdeModulePkg/Bus/Usb/UsbBusPei/UsbIoPeim.c
@@ -1,7 +1,7 @@
/** @file
The module is used to implement Usb Io PPI interfaces.
-Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2006 - 2014, Intel Corporation. All rights reserved.
This program and the accompanying materials
are licensed and made available under the terms and conditions
@@ -24,7 +24,9 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
@param This The pointer of PEI_USB_IO_PPI.
@param Request USB device request to send.
@param Direction Specifies the data direction for the data stage.
- @param Timeout Indicates the maximum timeout, in millisecond.
+ @param Timeout Indicates the maximum timeout, in millisecond. If Timeout
+ is 0, then the caller must wait for the function to be
+ completed until EFI_SUCCESS or EFI_DEVICE_ERROR is returned.
@param Data Data buffer to be transmitted or received from USB device.
@param DataLength The size (in bytes) of the data buffer.
@@ -50,9 +52,38 @@ PeiUsbControlTransfer (
EFI_STATUS Status;
PEI_USB_DEVICE *PeiUsbDev;
UINT32 TransferResult;
+ EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor;
+ UINT8 EndpointIndex;
PeiUsbDev = PEI_USB_DEVICE_FROM_THIS (This);
+ EndpointDescriptor = NULL;
+ EndpointIndex = 0;
+
+ if ((Request->Request == USB_REQ_CLEAR_FEATURE) &&
+ (Request->RequestType == USB_DEV_CLEAR_FEATURE_REQ_TYPE_E) &&
+ (Request->Value == USB_FEATURE_ENDPOINT_HALT)) {
+ //
+ // Request->Index is the Endpoint Address, use it to get the Endpoint Index.
+ //
+ while (EndpointIndex < MAX_ENDPOINT) {
+ Status = PeiUsbGetEndpointDescriptor (PeiServices, This, EndpointIndex, &EndpointDescriptor);
+ if (EFI_ERROR (Status)) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ if (EndpointDescriptor->EndpointAddress == Request->Index) {
+ break;
+ }
+
+ EndpointIndex++;
+ }
+
+ if (EndpointIndex == MAX_ENDPOINT) {
+ return EFI_INVALID_PARAMETER;
+ }
+ }
+
if (PeiUsbDev->Usb2HcPpi != NULL) {
Status = PeiUsbDev->Usb2HcPpi->ControlTransfer (
PeiServices,
@@ -74,7 +105,7 @@ PeiUsbControlTransfer (
PeiUsbDev->UsbHcPpi,
PeiUsbDev->DeviceAddress,
PeiUsbDev->DeviceSpeed,
- PeiUsbDev->MaxPacketSize0,
+ (UINT8) PeiUsbDev->MaxPacketSize0,
Request,
Direction,
Data,
@@ -83,6 +114,19 @@ PeiUsbControlTransfer (
&TransferResult
);
}
+
+ //
+ // Reset the endpoint toggle when endpoint stall is cleared
+ //
+ if ((Request->Request == USB_REQ_CLEAR_FEATURE) &&
+ (Request->RequestType == USB_DEV_CLEAR_FEATURE_REQ_TYPE_E) &&
+ (Request->Value == USB_FEATURE_ENDPOINT_HALT)) {
+ if ((PeiUsbDev->DataToggle & (1 << EndpointIndex)) != 0) {
+ PeiUsbDev->DataToggle = (UINT16) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex));
+ }
+ }
+
+ DEBUG ((EFI_D_INFO, "PeiUsbControlTransfer: %r\n", Status));
return Status;
}
@@ -96,7 +140,9 @@ PeiUsbControlTransfer (
from or receive into.
@param DataLength The lenght of the data buffer.
@param Timeout Indicates the maximum time, in millisecond, which the
- transfer is allowed to complete.
+ transfer is allowed to complete. If Timeout is 0, then
+ the caller must wait for the function to be completed
+ until EFI_SUCCESS or EFI_DEVICE_ERROR is returned.
@retval EFI_SUCCESS The transfer was completed successfully.
@retval EFI_OUT_OF_RESOURCES The transfer failed due to lack of resource.
@@ -190,9 +236,10 @@ PeiUsbBulkTransfer (
}
if (OldToggle != DataToggle) {
- PeiUsbDev->DataToggle = (UINT8) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex));
+ PeiUsbDev->DataToggle = (UINT16) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex));
}
+ DEBUG ((EFI_D_INFO, "PeiUsbBulkTransfer: %r\n", Status));
return Status;
}