]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Bus/Usb/UsbBusPei/PeiUsbLib.c
MdeModulePkg: Add PEI USB drivers and related PPIs
[mirror_edk2.git] / MdeModulePkg / Bus / Usb / UsbBusPei / PeiUsbLib.c
diff --git a/MdeModulePkg/Bus/Usb/UsbBusPei/PeiUsbLib.c b/MdeModulePkg/Bus/Usb/UsbBusPei/PeiUsbLib.c
new file mode 100644 (file)
index 0000000..2ac8d7b
--- /dev/null
@@ -0,0 +1,333 @@
+/** @file\r
+Common Libarary for PEI USB\r
+\r
+Copyright (c) 2006 - 2010, 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
+of the BSD License which accompanies this distribution.  The\r
+full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "UsbPeim.h"\r
+#include "PeiUsbLib.h"\r
+\r
+/**\r
+  Get a given usb descriptor.\r
+\r
+  @param  PeiServices        General-purpose services that are available to every PEIM.\r
+  @param  UsbIoPpi           Indicates the PEI_USB_IO_PPI instance.\r
+  @param  Value              Request Value.\r
+  @param  Index              Request Index.\r
+  @param  DescriptorLength   Request descriptor Length.\r
+  @param  Descriptor         Request descriptor.\r
+\r
+\r
+  @retval EFI_SUCCESS       Usb descriptor is obtained successfully.\r
+  @retval EFI_DEVICE_ERROR  Cannot get the usb descriptor due to a hardware error.\r
+  @retval Others            Other failure occurs.\r
+\r
+**/\r
+EFI_STATUS\r
+PeiUsbGetDescriptor (\r
+  IN  EFI_PEI_SERVICES         **PeiServices,\r
+  IN  PEI_USB_IO_PPI           *UsbIoPpi,\r
+  IN  UINT16                   Value,\r
+  IN  UINT16                   Index,\r
+  IN  UINT16                   DescriptorLength,\r
+  OUT VOID                     *Descriptor\r
+  )\r
+{\r
+  EFI_USB_DEVICE_REQUEST  DevReq;\r
+\r
+  ASSERT (UsbIoPpi != NULL);\r
+\r
+  DevReq.RequestType  = USB_DEV_GET_DESCRIPTOR_REQ_TYPE;\r
+  DevReq.Request      = USB_DEV_GET_DESCRIPTOR;\r
+  DevReq.Value        = Value;\r
+  DevReq.Index        = Index;\r
+  DevReq.Length       = DescriptorLength;\r
+\r
+  return UsbIoPpi->UsbControlTransfer (\r
+                     PeiServices,\r
+                     UsbIoPpi,\r
+                     &DevReq,\r
+                     EfiUsbDataIn,\r
+                     PcdGet32 (PcdUsbTransferTimeoutValue),\r
+                     Descriptor,\r
+                     DescriptorLength\r
+                     );\r
+}\r
+\r
+/**\r
+  Set a usb device with a specified address.\r
+\r
+  @param  PeiServices        General-purpose services that are available to every PEIM.\r
+  @param  UsbIoPpi           Indicates the PEI_USB_IO_PPI instance.\r
+  @param  AddressValue       The address to assign.\r
+\r
+  @retval EFI_SUCCESS       Usb device address is set successfully.\r
+  @retval EFI_DEVICE_ERROR  Cannot set the usb address due to a hardware error.\r
+  @retval Others            Other failure occurs.\r
+\r
+**/\r
+EFI_STATUS\r
+PeiUsbSetDeviceAddress (\r
+  IN EFI_PEI_SERVICES         **PeiServices,\r
+  IN PEI_USB_IO_PPI           *UsbIoPpi,\r
+  IN UINT16                   AddressValue\r
+  )\r
+{\r
+  EFI_USB_DEVICE_REQUEST  DevReq;\r
+\r
+  ASSERT (UsbIoPpi != NULL);\r
+\r
+  DevReq.RequestType  = USB_DEV_SET_ADDRESS_REQ_TYPE;\r
+  DevReq.Request      = USB_DEV_SET_ADDRESS;\r
+  DevReq.Value        = AddressValue;\r
+  DevReq.Index        = 0;\r
+  DevReq.Length       = 0;\r
+\r
+  return UsbIoPpi->UsbControlTransfer (\r
+                     PeiServices,\r
+                     UsbIoPpi,\r
+                     &DevReq,\r
+                     EfiUsbNoData,\r
+                     PcdGet32 (PcdUsbTransferTimeoutValue),\r
+                     NULL,\r
+                     0\r
+                     );\r
+}\r
+\r
+/**\r
+  Clear a given usb feature.\r
+\r
+  @param  PeiServices       General-purpose services that are available to every PEIM.\r
+  @param  UsbIoPpi          Indicates the PEI_USB_IO_PPI instance.\r
+  @param  Recipient         The recipient of ClearFeature Request, should be one of Device/Interface/Endpoint.\r
+  @param  Value             Request Value.\r
+  @param  Target            Request Index.\r
+\r
+  @retval EFI_SUCCESS       Usb feature is cleared successfully.\r
+  @retval EFI_DEVICE_ERROR  Cannot clear the usb feature due to a hardware error.\r
+  @retval Others            Other failure occurs.\r
+\r
+**/\r
+EFI_STATUS\r
+PeiUsbClearDeviceFeature (\r
+  IN EFI_PEI_SERVICES         **PeiServices,\r
+  IN PEI_USB_IO_PPI           *UsbIoPpi,\r
+  IN EFI_USB_RECIPIENT        Recipient,\r
+  IN UINT16                   Value,\r
+  IN UINT16                   Target\r
+  )\r
+{\r
+  EFI_USB_DEVICE_REQUEST  DevReq;\r
+\r
+  ASSERT (UsbIoPpi != NULL);\r
+\r
+  switch (Recipient) {\r
+  case EfiUsbDevice:\r
+    DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_D;\r
+    break;\r
+\r
+  case EfiUsbInterface:\r
+    DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_I;\r
+    break;\r
+\r
+  case EfiUsbEndpoint:\r
+    DevReq.RequestType = USB_DEV_CLEAR_FEATURE_REQ_TYPE_E;\r
+    break;\r
+  }\r
+\r
+  DevReq.Request      = USB_DEV_CLEAR_FEATURE;\r
+  DevReq.Value        = Value;\r
+  DevReq.Index        = Target;\r
+  DevReq.Length       = 0;\r
+\r
+  return UsbIoPpi->UsbControlTransfer (\r
+                     PeiServices,\r
+                     UsbIoPpi,\r
+                     &DevReq,\r
+                     EfiUsbNoData,\r
+                     PcdGet32 (PcdUsbTransferTimeoutValue),\r
+                     NULL,\r
+                     0\r
+                     );\r
+}\r
+\r
+/**\r
+  Configure a usb device to Configuration 1.\r
+\r
+  @param  PeiServices        General-purpose services that are available to every PEIM.\r
+  @param  UsbIoPpi           Indicates the PEI_USB_IO_PPI instance.\r
+\r
+  @retval EFI_SUCCESS       Usb device is set to use Configuration 1 successfully.\r
+  @retval EFI_DEVICE_ERROR  Cannot set the usb device due to a hardware error.\r
+  @retval Others            Other failure occurs.\r
+\r
+**/\r
+EFI_STATUS\r
+PeiUsbSetConfiguration (\r
+  IN EFI_PEI_SERVICES         **PeiServices,\r
+  IN PEI_USB_IO_PPI           *UsbIoPpi\r
+  )\r
+{\r
+  EFI_USB_DEVICE_REQUEST  DevReq;\r
+  ZeroMem (&DevReq, sizeof (EFI_USB_DEVICE_REQUEST));\r
+\r
+  DevReq.RequestType  = USB_DEV_SET_CONFIGURATION_REQ_TYPE;\r
+  DevReq.Request      = USB_DEV_SET_CONFIGURATION;\r
+  DevReq.Value        = 1;\r
+\r
+  return UsbIoPpi->UsbControlTransfer (\r
+                     PeiServices,\r
+                     UsbIoPpi,\r
+                     &DevReq,\r
+                     EfiUsbNoData,\r
+                     PcdGet32 (PcdUsbTransferTimeoutValue),\r
+                     NULL,\r
+                     0\r
+                     );\r
+}\r
+\r
+/**\r
+  Clear Endpoint Halt.\r
+\r
+  @param  PeiServices       General-purpose services that are available to every PEIM.\r
+  @param  UsbIoPpi          Indicates the PEI_USB_IO_PPI instance.\r
+  @param  EndpointAddress   The endpoint address.\r
+\r
+  @retval EFI_SUCCESS       Endpoint halt is cleared successfully.\r
+  @retval EFI_DEVICE_ERROR  Cannot clear the endpoint halt status due to a hardware error.\r
+  @retval Others            Other failure occurs.\r
+\r
+**/\r
+EFI_STATUS\r
+PeiUsbClearEndpointHalt (\r
+  IN EFI_PEI_SERVICES         **PeiServices,\r
+  IN PEI_USB_IO_PPI           *UsbIoPpi,\r
+  IN UINT8                    EndpointAddress\r
+  )\r
+{\r
+  EFI_STATUS                  Status;\r
+  PEI_USB_DEVICE              *PeiUsbDev;\r
+  EFI_USB_ENDPOINT_DESCRIPTOR *EndpointDescriptor;\r
+  UINT8                       EndpointIndex;\r
+\r
+  EndpointIndex = 0;\r
+  PeiUsbDev     = PEI_USB_DEVICE_FROM_THIS (UsbIoPpi);\r
+\r
+  while (EndpointIndex < MAX_ENDPOINT) {\r
+    Status = UsbIoPpi->UsbGetEndpointDescriptor (PeiServices, UsbIoPpi, EndpointIndex, &EndpointDescriptor);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+\r
+    if (EndpointDescriptor->EndpointAddress == EndpointAddress) {\r
+      break;\r
+    }\r
+\r
+    EndpointIndex++;\r
+  }\r
+\r
+  if (EndpointIndex == MAX_ENDPOINT) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  Status = PeiUsbClearDeviceFeature (\r
+            PeiServices,\r
+            UsbIoPpi,\r
+            EfiUsbEndpoint,\r
+            EfiUsbEndpointHalt,\r
+            EndpointAddress\r
+            );\r
+\r
+  //\r
+  // set data toggle to zero.\r
+  //\r
+  if ((PeiUsbDev->DataToggle & (1 << EndpointIndex)) != 0) {\r
+    PeiUsbDev->DataToggle = (UINT8) (PeiUsbDev->DataToggle ^ (1 << EndpointIndex));\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Judge if the port is connected with a usb device or not.\r
+\r
+  @param  PortStatus  The usb port status gotten.\r
+\r
+  @retval TRUE        A usb device is connected with the port.\r
+  @retval FALSE       No usb device is connected with the port.\r
+\r
+**/\r
+BOOLEAN\r
+IsPortConnect (\r
+  IN UINT16  PortStatus\r
+  )\r
+{\r
+  //\r
+  // return the bit 0 value of PortStatus\r
+  //\r
+  if ((PortStatus & USB_PORT_STAT_CONNECTION) != 0) {\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r
+\r
+/**\r
+  Judge if the port is connected with a low-speed usb device or not.\r
+\r
+  @param  PortStatus  The usb port status gotten.\r
+\r
+  @retval TRUE        A low-speed usb device is connected with the port.\r
+  @retval FALSE       No low-speed usb device is connected with the port.\r
+\r
+**/\r
+UINTN\r
+IsPortLowSpeedDeviceAttached (\r
+  IN UINT16  PortStatus\r
+  )\r
+{\r
+  //\r
+  // return the bit 9 value of PortStatus\r
+  //\r
+  if ((PortStatus & USB_PORT_STAT_LOW_SPEED) != 0) {\r
+    return EFI_USB_SPEED_LOW;\r
+  } else if ((PortStatus & USB_PORT_STAT_HIGH_SPEED) != 0){\r
+    return EFI_USB_SPEED_HIGH;\r
+  } else {\r
+    return EFI_USB_SPEED_FULL;\r
+  }\r
+}\r
+\r
+/**\r
+  Judge if the port is in "connection change" status or not.\r
+\r
+  @param  PortChangeStatus  The usb port change status gotten.\r
+\r
+  @retval TRUE              The port is in "connection change" status.\r
+  @retval FALSE             The port is NOT in "connection change" status.\r
+\r
+**/\r
+BOOLEAN\r
+IsPortConnectChange (\r
+  IN UINT16  PortChangeStatus\r
+  )\r
+{\r
+  //\r
+  // return the bit 0 value of PortChangeStatus\r
+  //\r
+  if ((PortChangeStatus & USB_PORT_STAT_C_CONNECTION) != 0) {\r
+    return TRUE;\r
+  } else {\r
+    return FALSE;\r
+  }\r
+}\r