summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvanjeff <vanjeff>2013-09-10 07:35:11 +0000
committervanjeff <vanjeff@6f19259b-4bc3-4df7-8a09-765794883524>2013-09-10 07:35:11 +0000
commit369fb82c2b0ae6f56a00894b169febca6d479fc3 (patch)
treed49cd7a25fe8ddc1ac6dd1d15d4ce4a6bfe9f258
parent75633aae00289e3516c8a0707f09d2562ae13aed (diff)
downloadedk2-369fb82c2b0ae6f56a00894b169febca6d479fc3.zip
edk2-369fb82c2b0ae6f56a00894b169febca6d479fc3.tar.gz
edk2-369fb82c2b0ae6f56a00894b169febca6d479fc3.tar.bz2
Sync patches r14496, r14497, r14504, r14548, r14549, r14550 and r14554 from main trunk.
1. Fixed the issue that BitFieldWrite32, BitFieldAnd32, BitFieldOr32, BitFieldAndThenOr32 with StartBit==0 and EndBit== 31 will hang in debug tip. 2. Add 4 APIs to DevicePathLib: ConvertDeviceNodeToText, ConvertDevicePathToText, ConvertTextToDeviceNode and ConvertTextToDevicePath. Add a new instance of DevicePathLib which tries to locate the protocol and if it's not found, it uses the internal functions. 3. Add I2C related definition in PI 1.3 spec. Add I2C bus DXE driver and I2C host DXE driver following PI 1.3 spec. 4. MdePkg/IndustryStandard: Update Atapi.h to comply with latest ATA8-ACS spec (d2015r7). git-svn-id: https://svn.code.sf.net/p/edk2/code/branches/UDK2010.SR1@14642 6f19259b-4bc3-4df7-8a09-765794883524
-rw-r--r--MdeModulePkg/Bus/I2c/I2cDxe/I2cBus.c1468
-rw-r--r--MdeModulePkg/Bus/I2c/I2cDxe/I2cBusDxe.inf54
-rw-r--r--MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.c75
-rw-r--r--MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.h1097
-rw-r--r--MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.inf56
-rw-r--r--MdeModulePkg/Bus/I2c/I2cDxe/I2cHost.c1169
-rw-r--r--MdeModulePkg/Bus/I2c/I2cDxe/I2cHostDxe.inf53
-rw-r--r--MdeModulePkg/MdeModulePkg.dsc3
-rw-r--r--MdeModulePkg/Universal/DevicePathDxe/DevicePath.c44
-rw-r--r--MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf23
-rw-r--r--MdeModulePkg/Universal/DevicePathDxe/DevicePathUtilities.c234
-rw-r--r--MdePkg/Include/IndustryStandard/Atapi.h58
-rw-r--r--MdePkg/Include/Library/DevicePathLib.h82
-rw-r--r--MdePkg/Include/Pi/PiI2c.h307
-rw-r--r--MdePkg/Include/Ppi/I2cMaster.h108
-rw-r--r--MdePkg/Include/Protocol/I2cBusConfigurationManagement.h171
-rw-r--r--MdePkg/Include/Protocol/I2cEnumerate.h110
-rw-r--r--MdePkg/Include/Protocol/I2cHost.h160
-rw-r--r--MdePkg/Include/Protocol/I2cIo.h175
-rw-r--r--MdePkg/Include/Protocol/I2cMaster.h192
-rw-r--r--MdePkg/Library/BaseLib/BitField.c28
-rw-r--r--MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c (renamed from MdeModulePkg/Universal/DevicePathDxe/DevicePathFromText.c)438
-rw-r--r--MdePkg/Library/UefiDevicePathLib/DevicePathToText.c (renamed from MdeModulePkg/Universal/DevicePathDxe/DevicePathToText.c)697
-rw-r--r--MdePkg/Library/UefiDevicePathLib/DevicePathUtilities.c882
-rw-r--r--MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c683
-rw-r--r--MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.h (renamed from MdeModulePkg/Universal/DevicePathDxe/DevicePath.h)406
-rw-r--r--MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf18
-rw-r--r--MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.c484
-rw-r--r--MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.inf73
-rw-r--r--MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c177
-rw-r--r--MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf4
-rw-r--r--MdePkg/MdePkg.dec26
-rw-r--r--MdePkg/MdePkg.dsc3
33 files changed, 7730 insertions, 1828 deletions
diff --git a/MdeModulePkg/Bus/I2c/I2cDxe/I2cBus.c b/MdeModulePkg/Bus/I2c/I2cDxe/I2cBus.c
new file mode 100644
index 0000000..3da1474
--- /dev/null
+++ b/MdeModulePkg/Bus/I2c/I2cDxe/I2cBus.c
@@ -0,0 +1,1468 @@
+/** @file
+ This file implements I2C IO Protocol which enables the user to manipulate a single
+ I2C device independent of the host controller and I2C design.
+
+ Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "I2cDxe.h"
+
+//
+// EFI_DRIVER_BINDING_PROTOCOL instance
+//
+EFI_DRIVER_BINDING_PROTOCOL gI2cBusDriverBinding = {
+ I2cBusDriverSupported,
+ I2cBusDriverStart,
+ I2cBusDriverStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+//
+// Template for I2C Bus Child Device.
+//
+I2C_DEVICE_CONTEXT gI2cDeviceContextTemplate = {
+ I2C_DEVICE_SIGNATURE,
+ NULL,
+ { // I2cIo Protocol
+ I2cBusQueueRequest, // QueueRequest
+ NULL, // DeviceGuid
+ 0, // DeviceIndex
+ 0, // HardwareRevision
+ NULL // I2cControllerCapabilities
+ },
+ NULL, // DevicePath
+ NULL, // I2cDevice
+ NULL, // I2cBusContext
+};
+
+//
+// Template for controller device path node.
+//
+CONTROLLER_DEVICE_PATH gControllerDevicePathTemplate = {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_CONTROLLER_DP,
+ {
+ (UINT8) (sizeof (CONTROLLER_DEVICE_PATH)),
+ (UINT8) ((sizeof (CONTROLLER_DEVICE_PATH)) >> 8)
+ }
+ },
+ 0
+};
+
+//
+// Template for vendor device path node.
+//
+VENDOR_DEVICE_PATH gVendorDevicePathTemplate = {
+ {
+ HARDWARE_DEVICE_PATH,
+ HW_VENDOR_DP,
+ {
+ (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
+ (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
+ }
+ },
+ { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }}
+};
+
+//
+// Driver name table
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mI2cBusDriverNameTable[] = {
+ { "eng;en", (CHAR16 *) L"I2C Bus Driver" },
+ { NULL , NULL }
+};
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gI2cBusComponentName = {
+ (EFI_COMPONENT_NAME_GET_DRIVER_NAME) I2cBusComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME_GET_CONTROLLER_NAME) I2cBusComponentNameGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gI2cBusComponentName2 = {
+ I2cBusComponentNameGetDriverName,
+ I2cBusComponentNameGetControllerName,
+ "en"
+};
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cBusComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mI2cBusDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This != &gI2cBusComponentName2)
+ );
+}
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cBusComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Check if the child of I2C controller has been created.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] Controller I2C controller handle.
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
+ @param[in] RemainingHasControllerNode Indicate if RemainingDevicePath contains CONTROLLER_DEVICE_PATH.
+ @param[in] RemainingControllerNumber Controller number in CONTROLLER_DEVICE_PATH.
+
+ @retval EFI_SUCCESS The child of I2C controller is not created.
+ @retval Others The child of I2C controller has been created or other errors happen.
+
+**/
+EFI_STATUS
+CheckRemainingDevicePath (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath,
+ IN BOOLEAN RemainingHasControllerNode,
+ IN UINT32 RemainingControllerNumber
+ )
+{
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *SystemDevicePath;
+ EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfoBuffer;
+ UINTN EntryCount;
+ UINTN Index;
+ BOOLEAN SystemHasControllerNode;
+ UINT32 SystemControllerNumber;
+
+ SystemHasControllerNode = FALSE;
+ SystemControllerNumber = 0;
+
+ Status = gBS->OpenProtocolInformation (
+ Controller,
+ &gEfiI2cHostProtocolGuid,
+ &OpenInfoBuffer,
+ &EntryCount
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ for (Index = 0; Index < EntryCount; Index++) {
+ if ((OpenInfoBuffer[Index].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) != 0) {
+ Status = gBS->OpenProtocol (
+ OpenInfoBuffer[Index].ControllerHandle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &SystemDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ //
+ // Find vendor device path node and compare
+ //
+ while (!IsDevicePathEnd (SystemDevicePath)) {
+ if ((DevicePathType (SystemDevicePath) == HARDWARE_DEVICE_PATH) &&
+ (DevicePathSubType (SystemDevicePath) == HW_VENDOR_DP)) {
+ //
+ // Check if vendor device path is same between system device path and remaining device path
+ //
+ if (CompareMem (SystemDevicePath, RemainingDevicePath, sizeof (VENDOR_DEVICE_PATH)) == 0) {
+ //
+ // Get controller node appended after vendor node
+ //
+ SystemDevicePath = NextDevicePathNode (SystemDevicePath);
+ if ((DevicePathType (SystemDevicePath) == HARDWARE_DEVICE_PATH) &&
+ (DevicePathSubType (SystemDevicePath) == HW_CONTROLLER_DP)) {
+ SystemHasControllerNode = TRUE;
+ SystemControllerNumber = ((CONTROLLER_DEVICE_PATH *) SystemDevicePath)->ControllerNumber;
+ } else {
+ SystemHasControllerNode = FALSE;
+ SystemControllerNumber = 0;
+ }
+ if (((SystemHasControllerNode) && (!RemainingHasControllerNode) && (SystemControllerNumber == 0)) ||
+ ((!SystemHasControllerNode) && (RemainingHasControllerNode) && (RemainingControllerNumber == 0)) ||
+ ((SystemHasControllerNode) && (RemainingHasControllerNode) && (SystemControllerNumber == RemainingControllerNumber)) ||
+ ((!SystemHasControllerNode) && (!RemainingHasControllerNode))) {
+ DEBUG ((EFI_D_ERROR, "This I2C device has been already started.\n"));
+ Status = EFI_UNSUPPORTED;
+ break;
+ }
+ }
+ }
+ SystemDevicePath = NextDevicePathNode (SystemDevicePath);
+ }
+ if (EFI_ERROR (Status)) {
+ break;
+ }
+ }
+ }
+ }
+ FreePool (OpenInfoBuffer);
+ return Status;
+}
+
+/**
+ Tests to see if this driver supports a given controller. If a child device is provided,
+ it further tests to see if this driver supports creating a handle for the specified child device.
+
+ This function checks to see if the driver specified by This supports the device specified by
+ ControllerHandle. Drivers will typically use the device path attached to
+ ControllerHandle and/or the services from the bus I/O abstraction attached to
+ ControllerHandle to determine if the driver supports ControllerHandle. This function
+ may be called many times during platform initialization. In order to reduce boot times, the tests
+ performed by this function must be very small, and take as little time as possible to execute. This
+ function must not change the state of any hardware devices, and this function must be aware that the
+ device specified by ControllerHandle may already be managed by the same driver or a
+ different driver. This function must match its calls to AllocatePages() with FreePages(),
+ AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
+ Since ControllerHandle may have been previously started by the same driver, if a protocol is
+ already in the opened state, then it must not be closed with CloseProtocol(). This is required
+ to guarantee the state of ControllerHandle is not modified by this function.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle The handle of the controller to test. This handle
+ must support a protocol interface that supplies
+ an I/O abstraction to the driver.
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
+ parameter is ignored by device drivers, and is optional for bus
+ drivers. For bus drivers, if this parameter is not NULL, then
+ the bus driver must determine if the bus controller specified
+ by ControllerHandle and the child controller specified
+ by RemainingDevicePath are both supported by this
+ bus driver.
+
+ @retval EFI_SUCCESS The device specified by ControllerHandle and
+ RemainingDevicePath is supported by the driver specified by This.
+ @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
+ RemainingDevicePath is already being managed by the driver
+ specified by This.
+ @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
+ RemainingDevicePath is already being managed by a different
+ driver or an application that requires exclusive access.
+ Currently not implemented.
+ @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
+ RemainingDevicePath is not supported by the driver specified by This.
+**/
+EFI_STATUS
+EFIAPI
+I2cBusDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_I2C_ENUMERATE_PROTOCOL *I2cEnumerate;
+ EFI_I2C_HOST_PROTOCOL *I2cHost;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
+ BOOLEAN RemainingHasControllerNode;
+ UINT32 RemainingControllerNumber;
+
+ RemainingHasControllerNode = FALSE;
+ RemainingControllerNumber = 0;
+
+ //
+ // Determine if the I2c Enumerate Protocol is available
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiI2cEnumerateProtocolGuid,
+ (VOID **) &I2cEnumerate,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
+ return Status;
+ }
+
+ if (!EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiI2cEnumerateProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ }
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ParentDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if ((EFI_ERROR (Status)) && (Status != EFI_ALREADY_STARTED)) {
+ return Status;
+ }
+
+ if (!EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ }
+
+ if ((RemainingDevicePath != NULL) && !IsDevicePathEnd (RemainingDevicePath)) {
+ //
+ // Check if the first node of RemainingDevicePath is a hardware vendor device path
+ //
+ if ((DevicePathType (RemainingDevicePath) != HARDWARE_DEVICE_PATH) ||
+ (DevicePathSubType (RemainingDevicePath) != HW_VENDOR_DP)) {
+ return EFI_UNSUPPORTED;
+ }
+ //
+ // Check if the second node of RemainingDevicePath is a controller node
+ //
+ DevPathNode = NextDevicePathNode (RemainingDevicePath);
+ if (!IsDevicePathEnd (DevPathNode)) {
+ if ((DevicePathType (DevPathNode) != HARDWARE_DEVICE_PATH) ||
+ (DevicePathSubType (DevPathNode) != HW_CONTROLLER_DP)) {
+ return EFI_UNSUPPORTED;
+ } else {
+ RemainingHasControllerNode = TRUE;
+ RemainingControllerNumber = ((CONTROLLER_DEVICE_PATH *) DevPathNode)->ControllerNumber;
+ }
+ }
+ }
+
+ //
+ // Determine if the I2C Host Protocol is available
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiI2cHostProtocolGuid,
+ (VOID **) &I2cHost,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+
+ if (!EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiI2cHostProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ }
+
+
+ if (Status == EFI_ALREADY_STARTED) {
+ if ((RemainingDevicePath == NULL) ||
+ ((RemainingDevicePath != NULL) && IsDevicePathEnd (RemainingDevicePath))) {
+ //
+ // If RemainingDevicePath is NULL or is the End of Device Path Node, return EFI_SUCCESS.
+ //
+ Status = EFI_SUCCESS;
+ } else {
+ //
+ // Test if the child with the RemainingDevicePath has already been created.
+ //
+ Status = CheckRemainingDevicePath (
+ This,
+ Controller,
+ RemainingDevicePath,
+ RemainingHasControllerNode,
+ RemainingControllerNumber
+ );
+ }
+ }
+
+ return Status;
+}
+
+/**
+ Starts a device controller or a bus controller.
+
+ The Start() function is designed to be invoked from the EFI boot service ConnectController().
+ As a result, much of the error checking on the parameters to Start() has been moved into this
+ common boot service. It is legal to call Start() from other locations,
+ but the following calling restrictions must be followed or the system behavior will not be deterministic.
+ 1. ControllerHandle must be a valid EFI_HANDLE.
+ 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
+ EFI_DEVICE_PATH_PROTOCOL.
+ 3. Prior to calling Start(), the Supported() function for the driver specified by This must
+ have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle The handle of the controller to start. This handle
+ must support a protocol interface that supplies
+ an I/O abstraction to the driver.
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
+ parameter is ignored by device drivers, and is optional for bus
+ drivers. For a bus driver, if this parameter is NULL, then handles
+ for all the children of Controller are created by this driver.
+ If this parameter is not NULL and the first Device Path Node is
+ not the End of Device Path Node, then only the handle for the
+ child device specified by the first Device Path Node of
+ RemainingDevicePath is created by this driver.
+ If the first Device Path Node of RemainingDevicePath is
+ the End of Device Path Node, no child handle is created by this
+ driver.
+
+ @retval EFI_SUCCESS The device was started.
+ @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval Others The driver failded to start the device.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cBusDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_I2C_ENUMERATE_PROTOCOL *I2cEnumerate;
+ EFI_I2C_HOST_PROTOCOL *I2cHost;
+ I2C_BUS_CONTEXT *I2cBusContext;
+ EFI_STATUS Status;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+
+ I2cBusContext = NULL;
+ ParentDevicePath = NULL;
+ I2cEnumerate = NULL;
+ I2cHost = NULL;
+
+ //
+ // Determine if the I2C controller is available
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiI2cHostProtocolGuid,
+ (VOID**)&I2cHost,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
+ DEBUG ((EFI_D_ERROR, "I2cBus: open I2C host error, Status = %r\n", Status));
+ return Status;
+ }
+
+ if (Status == EFI_ALREADY_STARTED) {
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiCallerIdGuid,
+ (VOID **) &I2cBusContext,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "I2cBus: open private protocol error, Status = %r.\n", Status));
+ return Status;
+ }
+ }
+
+ //
+ // Get the I2C bus enumeration API
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiI2cEnumerateProtocolGuid,
+ (VOID**)&I2cEnumerate,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
+ DEBUG ((EFI_D_ERROR, "I2cBus: open I2C enumerate error, Status = %r\n", Status));
+ goto Error;
+ }
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ (VOID **) &ParentDevicePath,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status) && (Status != EFI_ALREADY_STARTED)) {
+ DEBUG ((EFI_D_ERROR, "I2cBus: open device path error, Status = %r\n", Status));
+ goto Error;
+ }
+
+ if ((RemainingDevicePath != NULL) && IsDevicePathEnd (RemainingDevicePath)) {
+ //
+ // If RemainingDevicePath is the End of Device Path Node,
+ // don't create any child device and return EFI_SUCESS
+ //
+ return EFI_SUCCESS;
+ }
+
+ //
+ // Allocate the buffer for I2C_BUS_CONTEXT if it is not allocated before.
+ //
+ if (I2cBusContext == NULL) {
+ //
+ // Allocate the I2C context structure for the current I2C controller
+ //
+ I2cBusContext = AllocateZeroPool (sizeof (I2C_BUS_CONTEXT));
+ if (I2cBusContext == NULL) {
+ DEBUG ((EFI_D_ERROR, "I2cBus: there is no enough memory to allocate.\n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Error;
+ }
+
+ /*
+ +----------------+
+ .->| I2C_BUS_CONTEXT|<----- This file Protocol (gEfiCallerIdGuid) installed on I2C Controller handle
+ | +----------------+
+ |
+ | +----------------------------+
+ | | I2C_DEVICE_CONTEXT |
+ `--| |
+ | |
+ | I2C IO Protocol Structure | <----- I2C IO Protocol
+ | |
+ +----------------------------+
+
+ */
+ I2cBusContext->I2cHost = I2cHost;
+ I2cBusContext->I2cEnumerate = I2cEnumerate;
+ //
+ // Parent controller used to create children
+ //
+ I2cBusContext->Controller = Controller;
+ //
+ // Parent controller device path used to create children device path
+ //
+ I2cBusContext->ParentDevicePath = ParentDevicePath;
+
+ I2cBusContext->DriverBindingHandle = This->DriverBindingHandle;
+
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Controller,
+ &gEfiCallerIdGuid,
+ I2cBusContext,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "I2cBus: install private protocol error, Status = %r.\n", Status));
+ goto Error;
+ }
+ }
+
+ //
+ // Start the driver
+ //
+ Status = RegisterI2cDevice (I2cBusContext, Controller, RemainingDevicePath);
+
+ return Status;
+
+Error:
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "I2cBus: Start() function failed, Status = %r\n", Status));
+ if (ParentDevicePath != NULL) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ }
+
+ if (I2cHost != NULL) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiI2cHostProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ }
+
+ if (I2cEnumerate != NULL) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiI2cEnumerateProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ }
+
+ if (I2cBusContext != NULL) {
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ &Controller,
+ gEfiCallerIdGuid,
+ I2cBusContext,
+ NULL
+ );
+ FreePool (I2cBusContext);
+ }
+ }
+
+ //
+ // Return the operation status.
+ //
+ return Status;
+}
+
+
+/**
+ Stops a device controller or a bus controller.
+
+ The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
+ As a result, much of the error checking on the parameters to Stop() has been moved
+ into this common boot service. It is legal to call Stop() from other locations,
+ but the following calling restrictions must be followed or the system behavior will not be deterministic.
+ 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
+ same driver's Start() function.
+ 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
+ EFI_HANDLE. In addition, all of these handles must have been created in this driver's
+ Start() function, and the Start() function must have called OpenProtocol() on
+ ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle A handle to the device being stopped. The handle must
+ support a bus specific I/O protocol for the driver
+ to use to stop the device.
+ @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
+ if NumberOfChildren is 0.
+
+ @retval EFI_SUCCESS The device was stopped.
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cBusDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ I2C_BUS_CONTEXT *I2cBusContext;
+ EFI_STATUS Status;
+ BOOLEAN AllChildrenStopped;
+ UINTN Index;
+
+ if (NumberOfChildren == 0) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiDevicePathProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiI2cHostProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiI2cEnumerateProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiCallerIdGuid,
+ (VOID **) &I2cBusContext,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (!EFI_ERROR (Status)) {
+ gBS->UninstallMultipleProtocolInterfaces (
+ Controller,
+ &gEfiCallerIdGuid,
+ I2cBusContext,
+ NULL
+ );
+ //
+ // No more child now, free bus context data.
+ //
+ FreePool (I2cBusContext);
+ }
+ return Status;
+ }
+
+ AllChildrenStopped = TRUE;
+
+ for (Index = 0; Index < NumberOfChildren; Index++) {
+
+ Status = UnRegisterI2cDevice (This, Controller, ChildHandleBuffer[Index]);
+ if (EFI_ERROR (Status)) {
+ AllChildrenStopped = FALSE;
+ }
+ }
+
+ if (!AllChildrenStopped) {
+ return EFI_DEVICE_ERROR;
+ }
+ return EFI_SUCCESS;
+}
+
+/**
+ Enumerate the I2C bus
+
+ This routine walks the platform specific data describing the
+ I2C bus to create the I2C devices where driver GUIDs were
+ specified.
+
+ @param[in] I2cBusContext Address of an I2C_BUS_CONTEXT structure
+ @param[in] Controller Handle to the controller
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
+
+ @retval EFI_SUCCESS The bus is successfully configured
+
+**/
+EFI_STATUS
+RegisterI2cDevice (
+ IN I2C_BUS_CONTEXT *I2cBusContext,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ I2C_DEVICE_CONTEXT *I2cDeviceContext;
+ EFI_STATUS Status;
+ CONST EFI_I2C_DEVICE *Device;
+ CONST EFI_I2C_DEVICE *TempDevice;
+ UINT32 RemainingPathDeviceIndex;
+ EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
+ BOOLEAN BuildControllerNode;
+ UINTN Count;
+
+ Status = EFI_SUCCESS;
+ BuildControllerNode = TRUE;
+
+ //
+ // Default DeviceIndex
+ //
+ RemainingPathDeviceIndex = 0;
+
+ //
+ // Determine the controller number in Controller Node Device Path when RemainingDevicePath is not NULL.
+ //
+ if (RemainingDevicePath != NULL) {
+ //
+ // Check if there is a controller node appended after vendor node
+ //
+ DevPathNode = NextDevicePathNode (RemainingDevicePath);
+ if ((DevicePathType (DevPathNode) == HARDWARE_DEVICE_PATH) &&
+ (DevicePathSubType(DevPathNode) == HW_CONTROLLER_DP)) {
+ //
+ // RemainingDevicePath != NULL and RemainingDevicePath contains Controller Node,
+ // add Controller Node to Device Path on child handle.
+ //
+ RemainingPathDeviceIndex = ((CONTROLLER_DEVICE_PATH *) DevPathNode)->ControllerNumber;
+ } else {
+ //
+ // RemainingDevicePath != NULL and RemainingDevicePath does not contain Controller Node,
+ // do not add controller node to Device Path on child handle.
+ //
+ BuildControllerNode = FALSE;
+ }
+ }
+
+ //
+ // Walk the list of I2C devices on this bus
+ //
+ Device = NULL;
+ while (TRUE) {
+ //
+ // Get the next I2C device
+ //
+ Status = I2cBusContext->I2cEnumerate->Enumerate (I2cBusContext->I2cEnumerate, &Device);
+ if (EFI_ERROR (Status) || Device == NULL) {
+ if (RemainingDevicePath != NULL) {
+ Status = EFI_NOT_FOUND;
+ } else {
+ Status = EFI_SUCCESS;
+ }
+ break;
+ }
+
+ //
+ // Determine if the device info is valid
+ //
+ if ((Device->DeviceGuid == NULL) || (Device->SlaveAddressCount == 0) || (Device->SlaveAddressArray == NULL)) {
+ DEBUG ((EFI_D_ERROR, "Invalid EFI_I2C_DEVICE reported by I2c Enumerate protocol.\n"));
+ continue;
+ }
+
+ if (RemainingDevicePath == NULL) {
+ if (Device->DeviceIndex == 0) {
+ //
+ // Determine if the controller node is necessary when controller number is zero in I2C device
+ //
+ TempDevice = NULL;
+ Count = 0;
+ while (TRUE) {
+ //
+ // Get the next I2C device
+ //
+ Status = I2cBusContext->I2cEnumerate->Enumerate (I2cBusContext->I2cEnumerate, &TempDevice);
+ if (EFI_ERROR (Status) || TempDevice == NULL) {
+ Status = EFI_SUCCESS;
+ break;
+ }
+ if (CompareGuid (Device->DeviceGuid, TempDevice->DeviceGuid)) {
+ Count++;
+ }
+ }
+ if (Count == 1) {
+ //
+ // RemainingDevicePath == NULL and only DeviceIndex 0 is present on the I2C bus,
+ // do not add Controller Node to Device Path on child handle.
+ //
+ BuildControllerNode = FALSE;
+ }
+ }
+ } else {
+ //
+ // Find I2C device reported in Remaining Device Path
+ //
+ if ((!CompareGuid (&((VENDOR_DEVICE_PATH *)RemainingDevicePath)->Guid, Device->DeviceGuid)) ||
+ (RemainingPathDeviceIndex != Device->DeviceIndex)) {
+ continue;
+ }
+ }
+
+ //
+ // Build the device context for current I2C device.
+ //
+ I2cDeviceContext = NULL;
+ I2cDeviceContext = AllocateCopyPool (sizeof (I2C_DEVICE_CONTEXT), &gI2cDeviceContextTemplate);
+ ASSERT (I2cDeviceContext != NULL);
+ if (I2cDeviceContext == NULL) {
+ continue;
+ }
+
+ //
+ // Initialize the specific device context
+ //
+ I2cDeviceContext->I2cBusContext = I2cBusContext;
+ I2cDeviceContext->I2cDevice = Device;
+ I2cDeviceContext->I2cIo.DeviceGuid = Device->DeviceGuid;
+ I2cDeviceContext->I2cIo.DeviceIndex = Device->DeviceIndex;
+ I2cDeviceContext->I2cIo.HardwareRevision = Device->HardwareRevision;
+ I2cDeviceContext->I2cIo.I2cControllerCapabilities = I2cBusContext->I2cHost->I2cControllerCapabilities;
+
+ //
+ // Build the device path
+ //
+ Status = I2cBusDevicePathAppend (I2cDeviceContext, BuildControllerNode);
+ ASSERT_EFI_ERROR (Status);
+ if (EFI_ERROR (Status)) {
+ continue;
+ }
+
+ //
+ // Install the protocol
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &I2cDeviceContext->Handle,
+ &gEfiI2cIoProtocolGuid,
+ &I2cDeviceContext->I2cIo,
+ &gEfiDevicePathProtocolGuid,
+ I2cDeviceContext->DevicePath,
+ NULL );
+ if (EFI_ERROR (Status)) {
+ //
+ // Free resources for this I2C device
+ //
+ ReleaseI2cDeviceContext (I2cDeviceContext);
+ continue;
+ }
+
+ //
+ // Create the child handle
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiI2cHostProtocolGuid,
+ (VOID **) &I2cBusContext->I2cHost,
+ I2cBusContext->DriverBindingHandle,
+ I2cDeviceContext->Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ if (EFI_ERROR (Status)) {
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ I2cDeviceContext->Handle,
+ &gEfiDevicePathProtocolGuid,
+ I2cDeviceContext->DevicePath,
+ &gEfiI2cIoProtocolGuid,
+ &I2cDeviceContext->I2cIo,
+ NULL
+ );
+ //
+ // Free resources for this I2C device
+ //
+ ReleaseI2cDeviceContext (I2cDeviceContext);
+ continue;
+ }
+
+ if (RemainingDevicePath != NULL) {
+ //
+ // Child has been created successfully
+ //
+ break;
+ }
+ }
+
+ return Status;
+}
+
+
+/**
+ Queue an I2C transaction for execution on the I2C device.
+
+ This routine must be called at or below TPL_NOTIFY. For synchronous
+ requests this routine must be called at or below TPL_CALLBACK.
+
+ This routine queues an I2C transaction to the I2C controller for
+ execution on the I2C bus.
+
+ When Event is NULL, QueueRequest() operates synchronously and returns
+ the I2C completion status as its return value.
+
+ When Event is not NULL, QueueRequest() synchronously returns EFI_SUCCESS
+ indicating that the asynchronous I2C transaction was queued. The values
+ above are returned in the buffer pointed to by I2cStatus upon the
+ completion of the I2C transaction when I2cStatus is not NULL.
+
+ The upper layer driver writer provides the following to the platform
+ vendor:
+
+ 1. Vendor specific GUID for the I2C part
+ 2. Guidance on proper construction of the slave address array when the
+ I2C device uses more than one slave address. The I2C bus protocol
+ uses the SlaveAddressIndex to perform relative to physical address
+ translation to access the blocks of hardware within the I2C device.
+
+ @param[in] This Pointer to an EFI_I2C_IO_PROTOCOL structure.
+ @param[in] SlaveAddressIndex Index value into an array of slave addresses
+ for the I2C device. The values in the array
+ are specified by the board designer, with the
+ third party I2C device driver writer providing
+ the slave address order.
+
+ For devices that have a single slave address,
+ this value must be zero. If the I2C device
+ uses more than one slave address then the
+ third party (upper level) I2C driver writer
+ needs to specify the order of entries in the
+ slave address array.
+
+ \ref ThirdPartyI2cDrivers "Third Party I2C
+ Drivers" section in I2cMaster.h.
+ @param[in] Event Event to signal for asynchronous transactions,
+ NULL for synchronous transactions
+ @param[in] RequestPacket Pointer to an EFI_I2C_REQUEST_PACKET structure
+ describing the I2C transaction
+ @param[out] I2cStatus Optional buffer to receive the I2C transaction
+ completion status
+
+ @retval EFI_SUCCESS The asynchronous transaction was successfully
+ queued when Event is not NULL.
+ @retval EFI_SUCCESS The transaction completed successfully when
+ Event is NULL.
+ @retval EFI_ABORTED The request did not complete because the driver
+ binding Stop() routine was called.
+ @retval EFI_BAD_BUFFER_SIZE The RequestPacket->LengthInBytes value is too
+ large.
+ @retval EFI_DEVICE_ERROR There was an I2C error (NACK) during the
+ transaction.
+ @retval EFI_INVALID_PARAMETER RequestPacket is NULL
+ @retval EFI_NOT_FOUND Reserved bit set in the SlaveAddress parameter
+ @retval EFI_NO_MAPPING The EFI_I2C_HOST_PROTOCOL could not set the
+ bus configuration required to access this I2C
+ device.
+ @retval EFI_NO_RESPONSE The I2C device is not responding to the slave
+ address selected by SlaveAddressIndex.
+ EFI_DEVICE_ERROR will be returned if the
+ controller cannot distinguish when the NACK
+ occurred.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory for I2C transaction
+ @retval EFI_UNSUPPORTED The controller does not support the requested
+ transaction.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cBusQueueRequest (
+ IN CONST EFI_I2C_IO_PROTOCOL *This,
+ IN UINTN SlaveAddressIndex,
+ IN EFI_EVENT Event OPTIONAL,
+ IN EFI_I2C_REQUEST_PACKET *RequestPacket,
+ OUT EFI_STATUS *I2cStatus OPTIONAL
+ )
+{
+ CONST EFI_I2C_DEVICE *I2cDevice;
+ I2C_BUS_CONTEXT *I2cBusContext;
+ CONST EFI_I2C_HOST_PROTOCOL *I2cHost;
+ I2C_DEVICE_CONTEXT *I2cDeviceContext;
+ EFI_STATUS Status;
+
+ if (RequestPacket == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Validate the I2C slave index
+ //
+ I2cDeviceContext = I2C_DEVICE_CONTEXT_FROM_PROTOCOL (This);
+ I2cDevice = I2cDeviceContext->I2cDevice;
+ if ( SlaveAddressIndex >= I2cDevice->SlaveAddressCount ) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Locate the I2c Host Protocol to queue request
+ //
+ I2cBusContext = I2cDeviceContext->I2cBusContext;
+ I2cHost = I2cBusContext->I2cHost;
+
+ //
+ // Start the I2C operation
+ //
+ Status = I2cHost->QueueRequest (
+ I2cHost,
+ I2cDevice->I2cBusConfiguration,
+ I2cDevice->SlaveAddressArray [SlaveAddressIndex],
+ Event,
+ RequestPacket,
+ I2cStatus
+ );
+
+ return Status;
+}
+
+/**
+ Release all the resources allocated for the I2C device.
+
+ This function releases all the resources allocated for the I2C device.
+
+ @param I2cDeviceContext The I2C child device involved for the operation.
+
+**/
+VOID
+ReleaseI2cDeviceContext (
+ IN I2C_DEVICE_CONTEXT *I2cDeviceContext
+ )
+{
+ if (I2cDeviceContext == NULL) {
+ return;
+ }
+
+ if (I2cDeviceContext->DevicePath != NULL) {
+ FreePool (I2cDeviceContext->DevicePath);
+ }
+
+ FreePool (I2cDeviceContext);
+}
+
+/**
+ Unregister an I2C device.
+
+ This function removes the protocols installed on the controller handle and
+ frees the resources allocated for the I2C device.
+
+ @param This The pointer to EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param Controller The controller handle of the I2C device.
+ @param Handle The child handle.
+
+ @retval EFI_SUCCESS The I2C device is successfully unregistered.
+ @return Others Some error occurs when unregistering the I2C device.
+
+**/
+EFI_STATUS
+UnRegisterI2cDevice (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_HANDLE Handle
+ )
+{
+ EFI_STATUS Status;
+ I2C_DEVICE_CONTEXT *I2cDeviceContext;
+ EFI_I2C_IO_PROTOCOL *I2cIo;
+ EFI_I2C_HOST_PROTOCOL *I2cHost;
+
+ I2cIo = NULL;
+
+ Status = gBS->OpenProtocol (
+ Handle,
+ &gEfiI2cIoProtocolGuid,
+ (VOID **) &I2cIo,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Get I2c device context data.
+ //
+ I2cDeviceContext = I2C_DEVICE_CONTEXT_FROM_PROTOCOL (I2cIo);
+
+ //
+ // Close the child handle
+ //
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiI2cHostProtocolGuid,
+ This->DriverBindingHandle,
+ Handle
+ );
+
+ //
+ // The I2C Bus driver installs the I2C Io and Device Path Protocol in the DriverBindingStart().
+ // Here should uninstall them.
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ I2cDeviceContext->DevicePath,
+ &gEfiI2cIoProtocolGuid,
+ &I2cDeviceContext->I2cIo,
+ NULL
+ );
+
+ if (EFI_ERROR (Status)) {
+ //
+ // Keep parent and child relationship
+ //
+ gBS->OpenProtocol (
+ Controller,
+ &gEfiI2cHostProtocolGuid,
+ (VOID **) &I2cHost,
+ This->DriverBindingHandle,
+ Handle,
+ EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
+ );
+ return Status;
+ }
+
+ //
+ // Free resources for this I2C device
+ //
+ ReleaseI2cDeviceContext (I2cDeviceContext);
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Create a path for the I2C device
+
+ Append the I2C slave path to the I2C master controller path.
+
+ @param[in] I2cDeviceContext Address of an I2C_DEVICE_CONTEXT structure.
+ @param[in] BuildControllerNode Flag to build controller node in device path.
+
+ @retval EFI_SUCCESS The I2C device path is built successfully.
+ @return Others It is failed to built device path.
+
+**/
+EFI_STATUS
+I2cBusDevicePathAppend (
+ IN I2C_DEVICE_CONTEXT *I2cDeviceContext,
+ IN BOOLEAN BuildControllerNode
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *PreviousDevicePath;
+
+ PreviousDevicePath = NULL;
+
+ //
+ // Build vendor device path
+ //
+ CopyMem (&gVendorDevicePathTemplate.Guid, I2cDeviceContext->I2cDevice->DeviceGuid, sizeof (EFI_GUID));
+ I2cDeviceContext->DevicePath = AppendDevicePathNode (
+ I2cDeviceContext->I2cBusContext->ParentDevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &gVendorDevicePathTemplate
+ );
+ ASSERT (I2cDeviceContext->DevicePath != NULL);
+ if (I2cDeviceContext->DevicePath == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ if ((BuildControllerNode) && (I2cDeviceContext->DevicePath != NULL)) {
+ //
+ // Build the final I2C device path with controller node
+ //
+ PreviousDevicePath = I2cDeviceContext->DevicePath;
+ gControllerDevicePathTemplate.ControllerNumber = I2cDeviceContext->I2cDevice->DeviceIndex;
+ I2cDeviceContext->DevicePath = AppendDevicePathNode (
+ I2cDeviceContext->DevicePath,
+ (EFI_DEVICE_PATH_PROTOCOL *) &gControllerDevicePathTemplate
+ );
+ gBS->FreePool (PreviousDevicePath);
+ ASSERT (I2cDeviceContext->DevicePath != NULL);
+ if (I2cDeviceContext->DevicePath == NULL) {
+ return EFI_OUT_OF_RESOURCES;
+ }
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ The user entry point for the I2C bus module. The user code starts with
+ this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeI2cBus(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Install driver model protocol(s).
+ //
+ Status = EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &gI2cBusDriverBinding,
+ NULL,
+ &gI2cBusComponentName,
+ &gI2cBusComponentName2
+ );
+ ASSERT_EFI_ERROR (Status);
+
+
+ return Status;
+}
+
+/**
+ This is the unload handle for I2C bus module.
+
+ Disconnect the driver specified by ImageHandle from all the devices in the handle database.
+ Uninstall all the protocols installed in the driver entry point.
+
+ @param[in] ImageHandle The drivers' driver image.
+
+ @retval EFI_SUCCESS The image is unloaded.
+ @retval Others Failed to unload the image.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cBusUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *DeviceHandleBuffer;
+ UINTN DeviceHandleCount;
+ UINTN Index;
+
+ //
+ // Get the list of all I2C Controller handles in the handle database.
+ // If there is an error getting the list, then the unload
+ // operation fails.
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiI2cHostProtocolGuid,
+ NULL,
+ &DeviceHandleCount,
+ &DeviceHandleBuffer
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Disconnect the driver specified by Driver BindingHandle from all
+ // the devices in the handle database.
+ //
+ for (Index = 0; Index < DeviceHandleCount; Index++) {
+ Status = gBS->DisconnectController (
+ DeviceHandleBuffer[Index],
+ gI2cBusDriverBinding.DriverBindingHandle,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ }
+
+ //
+ // Uninstall all the protocols installed in the driver entry point
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ gI2cBusDriverBinding.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid,
+ &gI2cBusDriverBinding,
+ &gEfiComponentNameProtocolGuid,
+ &gI2cBusComponentName,
+ &gEfiComponentName2ProtocolGuid,
+ &gI2cBusComponentName2,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+Done:
+ //
+ // Free the buffer containing the list of handles from the handle database
+ //
+ if (DeviceHandleBuffer != NULL) {
+ gBS->FreePool (DeviceHandleBuffer);
+ }
+
+ return Status;
+}
diff --git a/MdeModulePkg/Bus/I2c/I2cDxe/I2cBusDxe.inf b/MdeModulePkg/Bus/I2c/I2cDxe/I2cBusDxe.inf
new file mode 100644
index 0000000..12b42ab
--- /dev/null
+++ b/MdeModulePkg/Bus/I2c/I2cDxe/I2cBusDxe.inf
@@ -0,0 +1,54 @@
+## @file
+# This driver enumerates I2C devices on I2C bus and produce I2C
+# IO Protocol on I2C devices.
+#
+# Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = I2cBusDxe
+ FILE_GUID = 0C34B372-2622-4A13-A46E-BFD0DEB48BFF
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeI2cBus
+ UNLOAD_IMAGE = I2cBusUnload
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources.common]
+ I2cDxe.h
+ I2cBus.c
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[Protocols]
+ gEfiI2cIoProtocolGuid ## BY_START
+ gEfiI2cHostProtocolGuid ## BY_START
+ gEfiI2cMasterProtocolGuid ## TO_START
+ gEfiI2cEnumerateProtocolGuid ## TO_START
+ gEfiI2cBusConfigurationManagementProtocolGuid ## TO_START
+ gEfiI2cHostProtocolGuid ## TO_START
diff --git a/MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.c b/MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.c
new file mode 100644
index 0000000..fb985f9
--- /dev/null
+++ b/MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.c
@@ -0,0 +1,75 @@
+/** @file
+ This file implements the entrypoint and unload function for I2C DXE module.
+
+ Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "I2cDxe.h"
+
+/**
+ The user Entry Point for I2C module. The user code starts with this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeI2c(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Install driver model protocol(s).
+ //
+ Status = InitializeI2cHost ( ImageHandle, SystemTable );
+ if ( !EFI_ERROR ( Status ))
+ {
+ Status = InitializeI2cBus ( ImageHandle, SystemTable );
+ }
+ return Status;
+}
+
+/**
+ This is the unload handle for I2C module.
+
+ Disconnect the driver specified by ImageHandle from all the devices in the handle database.
+ Uninstall all the protocols installed in the driver entry point.
+
+ @param[in] ImageHandle The drivers' driver image.
+
+ @retval EFI_SUCCESS The image is unloaded.
+ @retval Others Failed to unload the image.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Disconnect the drivers
+ //
+ Status = I2cBusUnload ( ImageHandle );
+ if ( !EFI_ERROR ( Status )) {
+ Status = I2cHostUnload ( ImageHandle );
+ }
+ return Status;
+}
diff --git a/MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.h b/MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.h
new file mode 100644
index 0000000..1490d42
--- /dev/null
+++ b/MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.h
@@ -0,0 +1,1097 @@
+/** @file
+ Private data structures for the I2C DXE driver.
+
+ This file defines common data structures, macro definitions and some module
+ internal function header files.
+
+ Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#ifndef __I2C_DXE_H__
+#define __I2C_DXE_H__
+
+#include <Uefi.h>
+#include <Library/BaseMemoryLib.h>
+#include <Library/DebugLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/MemoryAllocationLib.h>
+#include <Library/TimerLib.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiLib.h>
+
+#include <Protocol/DriverBinding.h>
+#include <Protocol/I2cEnumerate.h>
+#include <Protocol/I2cHost.h>
+#include <Protocol/I2cIo.h>
+#include <Protocol/I2cMaster.h>
+#include <Protocol/I2cBusConfigurationManagement.h>
+#include <Protocol/LoadedImage.h>
+
+#define I2C_DEVICE_SIGNATURE SIGNATURE_32 ('I', '2', 'C', 'D')
+#define I2C_HOST_SIGNATURE SIGNATURE_32 ('I', '2', 'C', 'H')
+#define I2C_REQUEST_SIGNATURE SIGNATURE_32 ('I', '2', 'C', 'R')
+
+//
+// Synchronize access to the list of requests
+//
+#define TPL_I2C_SYNC TPL_NOTIFY
+
+//
+// I2C bus context
+//
+typedef struct {
+ EFI_I2C_ENUMERATE_PROTOCOL *I2cEnumerate;
+ EFI_I2C_HOST_PROTOCOL *I2cHost;
+ EFI_HANDLE Controller;
+ EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
+ EFI_HANDLE DriverBindingHandle;
+} I2C_BUS_CONTEXT;
+
+//
+// I2C device context
+//
+typedef struct {
+ //
+ // Structure identification
+ //
+ UINT32 Signature;
+
+ //
+ // I2c device handle
+ //
+ EFI_HANDLE Handle;
+
+ //
+ // Upper level API to support the I2C device I/O
+ //
+ EFI_I2C_IO_PROTOCOL I2cIo;
+
+ //
+ // Device path for this device
+ //
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ //
+ // Platform specific data for this device
+ //
+ CONST EFI_I2C_DEVICE *I2cDevice;
+
+ //
+ // Context for the common I/O support including the
+ // lower level API to the host controller.
+ //
+ I2C_BUS_CONTEXT *I2cBusContext;
+} I2C_DEVICE_CONTEXT;
+
+#define I2C_DEVICE_CONTEXT_FROM_PROTOCOL(a) CR (a, I2C_DEVICE_CONTEXT, I2cIo, I2C_DEVICE_SIGNATURE)
+
+//
+// I2C Request
+//
+typedef struct {
+ //
+ // Signature
+ //
+ UINT32 Signature;
+
+ //
+ // Next request in the pending request list
+ //
+ LIST_ENTRY Link;
+
+ //
+ // I2C bus configuration for the operation
+ //
+ UINTN I2cBusConfiguration;
+
+ //
+ // I2C slave address for the operation
+ //
+ UINTN SlaveAddress;
+
+ //
+ // Event to set for asynchronous operations, NULL for
+ // synchronous operations
+ //
+ EFI_EVENT Event;
+
+ //
+ // I2C operation description
+ //
+ EFI_I2C_REQUEST_PACKET *RequestPacket;
+
+ //
+ // Optional buffer to receive the I2C operation completion status
+ //
+ EFI_STATUS *Status;
+} I2C_REQUEST;
+
+#define I2C_REQUEST_FROM_ENTRY(a) CR (a, I2C_REQUEST, Link, I2C_REQUEST_SIGNATURE);
+
+//
+// I2C host context
+//
+typedef struct {
+ //
+ // Structure identification
+ //
+ UINTN Signature;
+
+ //
+ // Current I2C bus configuration
+ //
+ UINTN I2cBusConfiguration;
+
+ //
+ // I2C bus configuration management event
+ //
+ EFI_EVENT I2cBusConfigurationEvent;
+
+ //
+ // I2C operation completion event
+ //
+ EFI_EVENT I2cEvent;
+
+ //
+ // I2C operation and I2C bus configuration management status
+ //
+ EFI_STATUS Status;
+
+ //
+ // I2C bus configuration management operation pending
+ //
+ BOOLEAN I2cBusConfigurationManagementPending;
+
+ //
+ // I2C request list maintained by I2C Host
+ //
+ LIST_ENTRY RequestList;
+
+ //
+ // Upper level API
+ //
+ EFI_I2C_HOST_PROTOCOL I2cHost;
+
+ //
+ // I2C bus configuration management protocol
+ //
+ EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL *I2cBusConfigurationManagement;
+
+ //
+ // Lower level API for I2C master (controller)
+ //
+ EFI_I2C_MASTER_PROTOCOL *I2cMaster;
+} I2C_HOST_CONTEXT;
+
+#define I2C_HOST_CONTEXT_FROM_PROTOCOL(a) CR (a, I2C_HOST_CONTEXT, I2cHost, I2C_HOST_SIGNATURE)
+
+//
+// Global Variables
+//
+extern EFI_COMPONENT_NAME_PROTOCOL gI2cBusComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gI2cBusComponentName2;
+extern EFI_DRIVER_BINDING_PROTOCOL gI2cBusDriverBinding;
+
+extern EFI_COMPONENT_NAME_PROTOCOL gI2cHostComponentName;
+extern EFI_COMPONENT_NAME2_PROTOCOL gI2cHostComponentName2;
+extern EFI_DRIVER_BINDING_PROTOCOL gI2cHostDriverBinding;
+
+/**
+ Start the I2C driver
+
+ This routine allocates the necessary resources for the driver.
+
+ This routine is called by I2cBusDriverStart to complete the driver
+ initialization.
+
+ @param[in] I2cBus Address of an I2C_BUS_CONTEXT structure
+ @param[in] Controller Handle to the controller
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path.
+
+ @retval EFI_SUCCESS Driver API properly initialized
+
+**/
+EFI_STATUS
+RegisterI2cDevice (
+ IN I2C_BUS_CONTEXT *I2cBus,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Unregister an I2C device.
+
+ This function removes the protocols installed on the controller handle and
+ frees the resources allocated for the I2C device.
+
+ @param This The pointer to EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param Controller The controller handle of the I2C device.
+ @param Handle The child handle.
+
+ @retval EFI_SUCCESS The I2C device is successfully unregistered.
+ @return Others Some error occurs when unregistering the I2C device.
+
+**/
+EFI_STATUS
+UnRegisterI2cDevice (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_HANDLE Handle
+ );
+
+/**
+ Create a path for the I2C device
+
+ Append the I2C slave path to the I2C master controller path.
+
+ @param[in] I2cDeviceContext Address of an I2C_DEVICE_CONTEXT structure.
+ @param[in] BuildControllerNode Flag to build controller node in device path.
+
+ @retval EFI_SUCCESS The I2C device path is built successfully.
+ @return Others It is failed to built device path.
+
+**/
+EFI_STATUS
+I2cBusDevicePathAppend (
+ IN I2C_DEVICE_CONTEXT *I2cDeviceContext,
+ IN BOOLEAN BuildControllerNode
+ );
+
+/**
+ Queue an I2C transaction for execution on the I2C device.
+
+ This routine must be called at or below TPL_NOTIFY. For synchronous
+ requests this routine must be called at or below TPL_CALLBACK.
+
+ This routine queues an I2C transaction to the I2C controller for
+ execution on the I2C bus.
+
+ When Event is NULL, QueueRequest() operates synchronously and returns
+ the I2C completion status as its return value.
+
+ When Event is not NULL, QueueRequest() synchronously returns EFI_SUCCESS
+ indicating that the asynchronous I2C transaction was queued. The values
+ above are returned in the buffer pointed to by I2cStatus upon the
+ completion of the I2C transaction when I2cStatus is not NULL.
+
+ The upper layer driver writer provides the following to the platform
+ vendor:
+
+ 1. Vendor specific GUID for the I2C part
+ 2. Guidance on proper construction of the slave address array when the
+ I2C device uses more than one slave address. The I2C bus protocol
+ uses the SlaveAddressIndex to perform relative to physical address
+ translation to access the blocks of hardware within the I2C device.
+
+ @param[in] This Pointer to an EFI_I2C_IO_PROTOCOL structure.
+ @param[in] SlaveAddressIndex Index value into an array of slave addresses
+ for the I2C device. The values in the array
+ are specified by the board designer, with the
+ third party I2C device driver writer providing
+ the slave address order.
+
+ For devices that have a single slave address,
+ this value must be zero. If the I2C device
+ uses more than one slave address then the
+ third party (upper level) I2C driver writer
+ needs to specify the order of entries in the
+ slave address array.
+
+ \ref ThirdPartyI2cDrivers "Third Party I2C
+ Drivers" section in I2cMaster.h.
+ @param[in] Event Event to signal for asynchronous transactions,
+ NULL for synchronous transactions
+ @param[in] RequestPacket Pointer to an EFI_I2C_REQUEST_PACKET structure
+ describing the I2C transaction
+ @param[out] I2cStatus Optional buffer to receive the I2C transaction
+ completion status
+
+ @retval EFI_SUCCESS The asynchronous transaction was successfully
+ queued when Event is not NULL.
+ @retval EFI_SUCCESS The transaction completed successfully when
+ Event is NULL.
+ @retval EFI_ABORTED The request did not complete because the driver
+ binding Stop() routine was called.
+ @retval EFI_BAD_BUFFER_SIZE The RequestPacket->LengthInBytes value is too
+ large.
+ @retval EFI_DEVICE_ERROR There was an I2C error (NACK) during the
+ transaction.
+ @retval EFI_INVALID_PARAMETER RequestPacket is NULL
+ @retval EFI_NOT_FOUND Reserved bit set in the SlaveAddress parameter
+ @retval EFI_NO_MAPPING The EFI_I2C_HOST_PROTOCOL could not set the
+ bus configuration required to access this I2C
+ device.
+ @retval EFI_NO_RESPONSE The I2C device is not responding to the slave
+ address selected by SlaveAddressIndex.
+ EFI_DEVICE_ERROR will be returned if the
+ controller cannot distinguish when the NACK
+ occurred.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory for I2C transaction
+ @retval EFI_UNSUPPORTED The controller does not support the requested
+ transaction.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cBusQueueRequest (
+ IN CONST EFI_I2C_IO_PROTOCOL *This,
+ IN UINTN SlaveAddressIndex,
+ IN EFI_EVENT Event OPTIONAL,
+ IN EFI_I2C_REQUEST_PACKET *RequestPacket,
+ OUT EFI_STATUS *I2cStatus OPTIONAL
+ );
+
+/**
+ Tests to see if this driver supports a given controller. If a child device is provided,
+ it further tests to see if this driver supports creating a handle for the specified child device.
+
+ This function checks to see if the driver specified by This supports the device specified by
+ ControllerHandle. Drivers will typically use the device path attached to
+ ControllerHandle and/or the services from the bus I/O abstraction attached to
+ ControllerHandle to determine if the driver supports ControllerHandle. This function
+ may be called many times during platform initialization. In order to reduce boot times, the tests
+ performed by this function must be very small, and take as little time as possible to execute. This
+ function must not change the state of any hardware devices, and this function must be aware that the
+ device specified by ControllerHandle may already be managed by the same driver or a
+ different driver. This function must match its calls to AllocatePages() with FreePages(),
+ AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
+ Since ControllerHandle may have been previously started by the same driver, if a protocol is
+ already in the opened state, then it must not be closed with CloseProtocol(). This is required
+ to guarantee the state of ControllerHandle is not modified by this function.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle The handle of the controller to test. This handle
+ must support a protocol interface that supplies
+ an I/O abstraction to the driver.
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
+ parameter is ignored by device drivers, and is optional for bus
+ drivers. For bus drivers, if this parameter is not NULL, then
+ the bus driver must determine if the bus controller specified
+ by ControllerHandle and the child controller specified
+ by RemainingDevicePath are both supported by this
+ bus driver.
+
+ @retval EFI_SUCCESS The device specified by ControllerHandle and
+ RemainingDevicePath is supported by the driver specified by This.
+ @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
+ RemainingDevicePath is already being managed by the driver
+ specified by This.
+ @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
+ RemainingDevicePath is already being managed by a different
+ driver or an application that requires exclusive access.
+ Currently not implemented.
+ @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
+ RemainingDevicePath is not supported by the driver specified by This.
+**/
+EFI_STATUS
+EFIAPI
+I2cBusDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Starts a device controller or a bus controller.
+
+ The Start() function is designed to be invoked from the EFI boot service ConnectController().
+ As a result, much of the error checking on the parameters to Start() has been moved into this
+ common boot service. It is legal to call Start() from other locations,
+ but the following calling restrictions must be followed or the system behavior will not be deterministic.
+ 1. ControllerHandle must be a valid EFI_HANDLE.
+ 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
+ EFI_DEVICE_PATH_PROTOCOL.
+ 3. Prior to calling Start(), the Supported() function for the driver specified by This must
+ have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle The handle of the controller to start. This handle
+ must support a protocol interface that supplies
+ an I/O abstraction to the driver.
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
+ parameter is ignored by device drivers, and is optional for bus
+ drivers. For a bus driver, if this parameter is NULL, then handles
+ for all the children of Controller are created by this driver.
+ If this parameter is not NULL and the first Device Path Node is
+ not the End of Device Path Node, then only the handle for the
+ child device specified by the first Device Path Node of
+ RemainingDevicePath is created by this driver.
+ If the first Device Path Node of RemainingDevicePath is
+ the End of Device Path Node, no child handle is created by this
+ driver.
+
+ @retval EFI_SUCCESS The device was started.
+ @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval Others The driver failded to start the device.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cBusDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Stops a device controller or a bus controller.
+
+ The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
+ As a result, much of the error checking on the parameters to Stop() has been moved
+ into this common boot service. It is legal to call Stop() from other locations,
+ but the following calling restrictions must be followed or the system behavior will not be deterministic.
+ 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
+ same driver's Start() function.
+ 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
+ EFI_HANDLE. In addition, all of these handles must have been created in this driver's
+ Start() function, and the Start() function must have called OpenProtocol() on
+ ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle A handle to the device being stopped. The handle must
+ support a bus specific I/O protocol for the driver
+ to use to stop the device.
+ @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
+ if NumberOfChildren is 0.
+
+ @retval EFI_SUCCESS The device was stopped.
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cBusDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cBusComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cBusComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+/**
+ The user entry point for the I2C bus module. The user code starts with
+ this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeI2cBus(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ This is the unload handle for I2C bus module.
+
+ Disconnect the driver specified by ImageHandle from all the devices in the handle database.
+ Uninstall all the protocols installed in the driver entry point.
+
+ @param[in] ImageHandle The drivers' driver image.
+
+ @retval EFI_SUCCESS The image is unloaded.
+ @retval Others Failed to unload the image.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cBusUnload (
+ IN EFI_HANDLE ImageHandle
+ );
+
+/**
+ Release all the resources allocated for the I2C device.
+
+ This function releases all the resources allocated for the I2C device.
+
+ @param I2cDeviceContext The I2C child device involved for the operation.
+
+**/
+VOID
+ReleaseI2cDeviceContext (
+ IN I2C_DEVICE_CONTEXT *I2cDeviceContext
+ );
+
+/**
+ Complete the current request
+
+ @param[in] I2cHost Address of an I2C_HOST_CONTEXT structure.
+ @param[in] Status Status of the I<sub>2</sub>C operation.
+
+ @return This routine returns the input status value.
+
+**/
+EFI_STATUS
+I2cHostRequestComplete (
+ I2C_HOST_CONTEXT *I2cHost,
+ EFI_STATUS Status
+ );
+
+/**
+ Enable access to the I2C bus configuration
+
+ @param[in] I2cHostContext Address of an I2C_HOST_CONTEXT structure
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_ABORTED The request did not complete because the driver
+ was shutdown.
+ @retval EFI_BAD_BUFFER_SIZE The WriteBytes or ReadBytes buffer size is too large.
+ @retval EFI_DEVICE_ERROR There was an I2C error (NACK) during the operation.
+ This could indicate the slave device is not present.
+ @retval EFI_INVALID_PARAMETER RequestPacket is NULL
+ @retval EFI_NO_MAPPING Invalid I2cBusConfiguration value
+ @retval EFI_NO_RESPONSE The I2C device is not responding to the
+ slave address. EFI_DEVICE_ERROR may also be
+ returned if the controller can not distinguish
+ when the NACK occurred.
+ @retval EFI_NOT_FOUND I2C slave address exceeds maximum address
+ @retval EFI_NOT_READY I2C bus is busy or operation pending, wait for
+ the event and then read status.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory for I2C operation
+ @retval EFI_TIMEOUT The transaction did not complete within an internally
+ specified timeout period.
+
+**/
+EFI_STATUS
+I2cHostRequestEnable (
+ I2C_HOST_CONTEXT *I2cHost
+ );
+
+/**
+ Tests to see if this driver supports a given controller. If a child device is provided,
+ it further tests to see if this driver supports creating a handle for the specified child device.
+
+ This function checks to see if the driver specified by This supports the device specified by
+ ControllerHandle. Drivers will typically use the device path attached to
+ ControllerHandle and/or the services from the bus I/O abstraction attached to
+ ControllerHandle to determine if the driver supports ControllerHandle. This function
+ may be called many times during platform initialization. In order to reduce boot times, the tests
+ performed by this function must be very small, and take as little time as possible to execute. This
+ function must not change the state of any hardware devices, and this function must be aware that the
+ device specified by ControllerHandle may already be managed by the same driver or a
+ different driver. This function must match its calls to AllocatePages() with FreePages(),
+ AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
+ Since ControllerHandle may have been previously started by the same driver, if a protocol is
+ already in the opened state, then it must not be closed with CloseProtocol(). This is required
+ to guarantee the state of ControllerHandle is not modified by this function.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle The handle of the controller to test. This handle
+ must support a protocol interface that supplies
+ an I/O abstraction to the driver.
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
+ parameter is ignored by device drivers, and is optional for bus
+ drivers. For bus drivers, if this parameter is not NULL, then
+ the bus driver must determine if the bus controller specified
+ by ControllerHandle and the child controller specified
+ by RemainingDevicePath are both supported by this
+ bus driver.
+
+ @retval EFI_SUCCESS The device specified by ControllerHandle and
+ RemainingDevicePath is supported by the driver specified by This.
+ @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
+ RemainingDevicePath is already being managed by the driver
+ specified by This.
+ @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
+ RemainingDevicePath is already being managed by a different
+ driver or an application that requires exclusive access.
+ Currently not implemented.
+ @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
+ RemainingDevicePath is not supported by the driver specified by This.
+**/
+EFI_STATUS
+EFIAPI
+I2cHostDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Starts a device controller or a bus controller.
+
+ The Start() function is designed to be invoked from the EFI boot service ConnectController().
+ As a result, much of the error checking on the parameters to Start() has been moved into this
+ common boot service. It is legal to call Start() from other locations,
+ but the following calling restrictions must be followed, or the system behavior will not be deterministic.
+ 1. ControllerHandle must be a valid EFI_HANDLE.
+ 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
+ EFI_DEVICE_PATH_PROTOCOL.
+ 3. Prior to calling Start(), the Supported() function for the driver specified by This must
+ have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle The handle of the controller to start. This handle
+ must support a protocol interface that supplies
+ an I/O abstraction to the driver.
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
+ parameter is ignored by device drivers, and is optional for bus
+ drivers. For a bus driver, if this parameter is NULL, then handles
+ for all the children of Controller are created by this driver.
+ If this parameter is not NULL and the first Device Path Node is
+ not the End of Device Path Node, then only the handle for the
+ child device specified by the first Device Path Node of
+ RemainingDevicePath is created by this driver.
+ If the first Device Path Node of RemainingDevicePath is
+ the End of Device Path Node, no child handle is created by this
+ driver.
+
+ @retval EFI_SUCCESS The device was started.
+ @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval Others The driver failded to start the device.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cHostDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ );
+
+/**
+ Stops a device controller or a bus controller.
+
+ The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
+ As a result, much of the error checking on the parameters to Stop() has been moved
+ into this common boot service. It is legal to call Stop() from other locations,
+ but the following calling restrictions must be followed, or the system behavior will not be deterministic.
+ 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
+ same driver's Start() function.
+ 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
+ EFI_HANDLE. In addition, all of these handles must have been created in this driver's
+ Start() function, and the Start() function must have called OpenProtocol() on
+ ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle A handle to the device being stopped. The handle must
+ support a bus specific I/O protocol for the driver
+ to use to stop the device.
+ @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
+ if NumberOfChildren is 0.
+
+ @retval EFI_SUCCESS The device was stopped.
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cHostDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ );
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cHostComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ );
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cHostComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ );
+
+/**
+ Handle the bus available event
+
+ This routine is called at TPL_I2C_SYNC.
+
+ @param[in] Event Address of an EFI_EVENT handle
+ @param[in] Context Address of an I2C_HOST_CONTEXT structure
+
+**/
+VOID
+EFIAPI
+I2cHostRequestCompleteEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ Handle the I2C bus configuration available event
+
+ This routine is called at TPL_I2C_SYNC.
+
+ @param[in] Event Address of an EFI_EVENT handle
+ @param[in] Context Address of an I2C_HOST_CONTEXT structure
+
+**/
+VOID
+EFIAPI
+I2cHostI2cBusConfigurationAvailable (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ );
+
+/**
+ Queue an I2C operation for execution on the I2C controller.
+
+ This routine must be called at or below TPL_NOTIFY. For synchronous
+ requests this routine must be called at or below TPL_CALLBACK.
+
+ N.B. The typical consumers of this API are the I2C bus driver and
+ on rare occasions the I2C test application. Extreme care must be
+ taken by other consumers of this API to prevent confusing the
+ third party I2C drivers due to a state change at the I2C device
+ which the third party I2C drivers did not initiate. I2C platform
+ drivers may use this API within these guidelines.
+
+ This layer uses the concept of I2C bus configurations to describe
+ the I2C bus. An I2C bus configuration is defined as a unique
+ setting of the multiplexers and switches in the I2C bus which
+ enable access to one or more I2C devices. When using a switch
+ to divide a bus, due to speed differences, the I2C platform layer
+ would define an I2C bus configuration for the I2C devices on each
+ side of the switch. When using a multiplexer, the I2C platform
+ layer defines an I2C bus configuration for each of the selector
+ values required to control the multiplexer. See Figure 1 in the
+ <a href="http://www.nxp.com/documents/user_manual/UM10204.pdf">I<sup>2</sup>C
+ Specification</a> for a complex I2C bus configuration.
+
+ The I2C host driver processes all operations in FIFO order. Prior to
+ performing the operation, the I2C host driver calls the I2C platform
+ driver to reconfigure the switches and multiplexers in the I2C bus
+ enabling access to the specified I2C device. The I2C platform driver
+ also selects the maximum bus speed for the device. After the I2C bus
+ is configured, the I2C host driver calls the I2C port driver to
+ initialize the I2C controller and start the I2C operation.
+
+ @param[in] This Address of an EFI_I2C_HOST_PROTOCOL instance.
+ @param[in] I2cBusConfiguration I2C bus configuration to access the I2C
+ device.
+ @param[in] SlaveAddress Address of the device on the I2C bus.
+ @param[in] Event Event to set for asynchronous operations,
+ NULL for synchronous operations
+ @param[in] RequestPacket Address of an EFI_I2C_REQUEST_PACKET
+ structure describing the I2C operation
+ @param[out] I2cStatus Optional buffer to receive the I2C operation
+ completion status
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_ABORTED The request did not complete because the driver
+ was shutdown.
+ @retval EFI_BAD_BUFFER_SIZE The WriteBytes or ReadBytes buffer size is too large.
+ @retval EFI_DEVICE_ERROR There was an I2C error (NACK) during the operation.
+ This could indicate the slave device is not present.
+ @retval EFI_INVALID_PARAMETER RequestPacket is NULL
+ @retval EFI_INVALID_PARAMETER TPL is too high
+ @retval EFI_NO_MAPPING Invalid I2cBusConfiguration value
+ @retval EFI_NO_RESPONSE The I2C device is not responding to the
+ slave address. EFI_DEVICE_ERROR may also be
+ returned if the controller can not distinguish
+ when the NACK occurred.
+ @retval EFI_NOT_FOUND I2C slave address exceeds maximum address
+ @retval EFI_NOT_READY I2C bus is busy or operation pending, wait for
+ the event and then read status pointed to by
+ the request packet.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory for I2C operation
+ @retval EFI_TIMEOUT The transaction did not complete within an internally
+ specified timeout period.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cHostQueueRequest (
+ IN CONST EFI_I2C_HOST_PROTOCOL *This,
+ IN UINTN I2cBusConfiguration,
+ IN UINTN SlaveAddress,
+ IN EFI_EVENT Event OPTIONAL,
+ IN EFI_I2C_REQUEST_PACKET *RequestPacket,
+ OUT EFI_STATUS *I2cStatus OPTIONAL
+ );
+
+/**
+ The user Entry Point for I2C host module. The user code starts with this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeI2cHost(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ );
+
+/**
+ This is the unload handle for I2C host module.
+
+ Disconnect the driver specified by ImageHandle from all the devices in the handle database.
+ Uninstall all the protocols installed in the driver entry point.
+
+ @param[in] ImageHandle The drivers' driver image.
+
+ @retval EFI_SUCCESS The image is unloaded.
+ @retval Others Failed to unload the image.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cHostUnload (
+ IN EFI_HANDLE ImageHandle
+ );
+
+#endif // __I2C_DXE_H__
diff --git a/MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.inf b/MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.inf
new file mode 100644
index 0000000..8600531
--- /dev/null
+++ b/MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.inf
@@ -0,0 +1,56 @@
+## @file
+# This driver produce I2C Host Protocol on I2C controller handle, enumerate I2C
+# devices on I2C bus and produce I2C IO Protocol on I2C devices.
+#
+# Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = I2cDxe
+ FILE_GUID = ECA2AE9E-7594-4901-871C-449DA1A11660
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeI2c
+ UNLOAD_IMAGE = I2cUnload
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources.common]
+ I2cDxe.c
+ I2cDxe.h
+ I2cHost.c
+ I2cBus.c
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[Protocols]
+ gEfiI2cIoProtocolGuid ## BY_START
+ gEfiI2cHostProtocolGuid ## BY_START
+ gEfiI2cMasterProtocolGuid ## TO_START
+ gEfiI2cEnumerateProtocolGuid ## TO_START
+ gEfiI2cBusConfigurationManagementProtocolGuid ## TO_START
+ gEfiI2cHostProtocolGuid ## TO_START
diff --git a/MdeModulePkg/Bus/I2c/I2cDxe/I2cHost.c b/MdeModulePkg/Bus/I2c/I2cDxe/I2cHost.c
new file mode 100644
index 0000000..e153a4d
--- /dev/null
+++ b/MdeModulePkg/Bus/I2c/I2cDxe/I2cHost.c
@@ -0,0 +1,1169 @@
+/** @file
+ This file implements I2C Host Protocol which provides callers with the ability to
+ do I/O transactions to all of the devices on the I2C bus.
+
+ Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "I2cDxe.h"
+
+EFI_DRIVER_BINDING_PROTOCOL gI2cHostDriverBinding = {
+ I2cHostDriverSupported,
+ I2cHostDriverStart,
+ I2cHostDriverStop,
+ 0x10,
+ NULL,
+ NULL
+};
+
+//
+// Driver name table
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mI2cHostDriverNameTable[] = {
+ { "eng;en", L"I2c Host Driver" },
+ { NULL , NULL }
+};
+
+//
+// EFI Component Name Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gI2cHostComponentName = {
+ (EFI_COMPONENT_NAME_GET_DRIVER_NAME) I2cHostComponentNameGetDriverName,
+ (EFI_COMPONENT_NAME_GET_CONTROLLER_NAME) I2cHostComponentNameGetControllerName,
+ "eng"
+};
+
+//
+// EFI Component Name 2 Protocol
+//
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gI2cHostComponentName2 = {
+ I2cHostComponentNameGetDriverName,
+ I2cHostComponentNameGetControllerName,
+ "en"
+};
+
+/**
+ Retrieves a Unicode string that is the user readable name of the driver.
+
+ This function retrieves the user readable name of a driver in the form of a
+ Unicode string. If the driver specified by This has a user readable name in
+ the language specified by Language, then a pointer to the driver name is
+ returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
+ by This does not support the language specified by Language,
+ then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified
+ in RFC 4646 or ISO 639-2 language code format.
+
+ @param DriverName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ driver specified by This in the language
+ specified by Language.
+
+ @retval EFI_SUCCESS The Unicode string for the Driver specified by
+ This and the language specified by Language was
+ returned in DriverName.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER DriverName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cHostComponentNameGetDriverName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN CHAR8 *Language,
+ OUT CHAR16 **DriverName
+ )
+{
+ return LookupUnicodeString2 (
+ Language,
+ This->SupportedLanguages,
+ mI2cHostDriverNameTable,
+ DriverName,
+ (BOOLEAN)(This != &gI2cHostComponentName2)
+ );
+}
+
+/**
+ Retrieves a Unicode string that is the user readable name of the controller
+ that is being managed by a driver.
+
+ This function retrieves the user readable name of the controller specified by
+ ControllerHandle and ChildHandle in the form of a Unicode string. If the
+ driver specified by This has a user readable name in the language specified by
+ Language, then a pointer to the controller name is returned in ControllerName,
+ and EFI_SUCCESS is returned. If the driver specified by This is not currently
+ managing the controller specified by ControllerHandle and ChildHandle,
+ then EFI_UNSUPPORTED is returned. If the driver specified by This does not
+ support the language specified by Language, then EFI_UNSUPPORTED is returned.
+
+ @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
+ EFI_COMPONENT_NAME_PROTOCOL instance.
+
+ @param ControllerHandle[in] The handle of a controller that the driver
+ specified by This is managing. This handle
+ specifies the controller whose name is to be
+ returned.
+
+ @param ChildHandle[in] The handle of the child controller to retrieve
+ the name of. This is an optional parameter that
+ may be NULL. It will be NULL for device
+ drivers. It will also be NULL for a bus drivers
+ that wish to retrieve the name of the bus
+ controller. It will not be NULL for a bus
+ driver that wishes to retrieve the name of a
+ child controller.
+
+ @param Language[in] A pointer to a Null-terminated ASCII string
+ array indicating the language. This is the
+ language of the driver name that the caller is
+ requesting, and it must match one of the
+ languages specified in SupportedLanguages. The
+ number of languages supported by a driver is up
+ to the driver writer. Language is specified in
+ RFC 4646 or ISO 639-2 language code format.
+
+ @param ControllerName[out] A pointer to the Unicode string to return.
+ This Unicode string is the name of the
+ controller specified by ControllerHandle and
+ ChildHandle in the language specified by
+ Language from the point of view of the driver
+ specified by This.
+
+ @retval EFI_SUCCESS The Unicode string for the user readable name in
+ the language specified by Language for the
+ driver specified by This was returned in
+ DriverName.
+
+ @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
+
+ @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
+ EFI_HANDLE.
+
+ @retval EFI_INVALID_PARAMETER Language is NULL.
+
+ @retval EFI_INVALID_PARAMETER ControllerName is NULL.
+
+ @retval EFI_UNSUPPORTED The driver specified by This is not currently
+ managing the controller specified by
+ ControllerHandle and ChildHandle.
+
+ @retval EFI_UNSUPPORTED The driver specified by This does not support
+ the language specified by Language.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cHostComponentNameGetControllerName (
+ IN EFI_COMPONENT_NAME2_PROTOCOL *This,
+ IN EFI_HANDLE ControllerHandle,
+ IN EFI_HANDLE ChildHandle OPTIONAL,
+ IN CHAR8 *Language,
+ OUT CHAR16 **ControllerName
+ )
+{
+ return EFI_UNSUPPORTED;
+}
+
+/**
+ Tests to see if this driver supports a given controller. If a child device is provided,
+ it further tests to see if this driver supports creating a handle for the specified child device.
+
+ This function checks to see if the driver specified by This supports the device specified by
+ ControllerHandle. Drivers will typically use the device path attached to
+ ControllerHandle and/or the services from the bus I/O abstraction attached to
+ ControllerHandle to determine if the driver supports ControllerHandle. This function
+ may be called many times during platform initialization. In order to reduce boot times, the tests
+ performed by this function must be very small, and take as little time as possible to execute. This
+ function must not change the state of any hardware devices, and this function must be aware that the
+ device specified by ControllerHandle may already be managed by the same driver or a
+ different driver. This function must match its calls to AllocatePages() with FreePages(),
+ AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
+ Since ControllerHandle may have been previously started by the same driver, if a protocol is
+ already in the opened state, then it must not be closed with CloseProtocol(). This is required
+ to guarantee the state of ControllerHandle is not modified by this function.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle The handle of the controller to test. This handle
+ must support a protocol interface that supplies
+ an I/O abstraction to the driver.
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
+ parameter is ignored by device drivers, and is optional for bus
+ drivers. For bus drivers, if this parameter is not NULL, then
+ the bus driver must determine if the bus controller specified
+ by ControllerHandle and the child controller specified
+ by RemainingDevicePath are both supported by this
+ bus driver.
+
+ @retval EFI_SUCCESS The device specified by ControllerHandle and
+ RemainingDevicePath is supported by the driver specified by This.
+ @retval EFI_ALREADY_STARTED The device specified by ControllerHandle and
+ RemainingDevicePath is already being managed by the driver
+ specified by This.
+ @retval EFI_ACCESS_DENIED The device specified by ControllerHandle and
+ RemainingDevicePath is already being managed by a different
+ driver or an application that requires exclusive access.
+ Currently not implemented.
+ @retval EFI_UNSUPPORTED The device specified by ControllerHandle and
+ RemainingDevicePath is not supported by the driver specified by This.
+**/
+EFI_STATUS
+EFIAPI
+I2cHostDriverSupported (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_I2C_MASTER_PROTOCOL *I2cMaster;
+ EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL *I2cBusConfigurationManagement;
+ EFI_STATUS Status;
+
+ //
+ // Locate I2C Bus Configuration Management Protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiI2cBusConfigurationManagementProtocolGuid,
+ (VOID **)&I2cBusConfigurationManagement,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Close the protocol because we don't use it here
+ //
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiI2cBusConfigurationManagementProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ //
+ // Locate I2C Master Protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiI2cMasterProtocolGuid,
+ (VOID **)&I2cMaster,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ return EFI_SUCCESS;
+}
+
+/**
+ Starts a device controller or a bus controller.
+
+ The Start() function is designed to be invoked from the EFI boot service ConnectController().
+ As a result, much of the error checking on the parameters to Start() has been moved into this
+ common boot service. It is legal to call Start() from other locations,
+ but the following calling restrictions must be followed, or the system behavior will not be deterministic.
+ 1. ControllerHandle must be a valid EFI_HANDLE.
+ 2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
+ EFI_DEVICE_PATH_PROTOCOL.
+ 3. Prior to calling Start(), the Supported() function for the driver specified by This must
+ have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle The handle of the controller to start. This handle
+ must support a protocol interface that supplies
+ an I/O abstraction to the driver.
+ @param[in] RemainingDevicePath A pointer to the remaining portion of a device path. This
+ parameter is ignored by device drivers, and is optional for bus
+ drivers. For a bus driver, if this parameter is NULL, then handles
+ for all the children of Controller are created by this driver.
+ If this parameter is not NULL and the first Device Path Node is
+ not the End of Device Path Node, then only the handle for the
+ child device specified by the first Device Path Node of
+ RemainingDevicePath is created by this driver.
+ If the first Device Path Node of RemainingDevicePath is
+ the End of Device Path Node, no child handle is created by this
+ driver.
+
+ @retval EFI_SUCCESS The device was started.
+ @retval EFI_DEVICE_ERROR The device could not be started due to a device error.Currently not implemented.
+ @retval EFI_OUT_OF_RESOURCES The request could not be completed due to a lack of resources.
+ @retval Others The driver failded to start the device.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cHostDriverStart (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
+ )
+{
+ EFI_STATUS Status;
+ EFI_I2C_MASTER_PROTOCOL *I2cMaster;
+ EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL *I2cBusConfigurationManagement;
+ I2C_HOST_CONTEXT *I2cHostContext;
+
+ I2cMaster = NULL;
+ I2cHostContext = NULL;
+ I2cBusConfigurationManagement = NULL;
+
+ //
+ // Locate I2C Bus Configuration Management Protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiI2cBusConfigurationManagementProtocolGuid,
+ (VOID **)&I2cBusConfigurationManagement,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_BY_DRIVER
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "I2cHost: Open I2C bus configuration error, Status = %r\n", Status));
+ return Status;
+ }
+
+ //
+ // Locate I2C Master Protocol
+ //
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiI2cMasterProtocolGuid,
+ (VOID **)&I2cMaster,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "I2cHost: Open I2C master error, Status = %r\n", Status));
+ goto Exit;
+ }
+
+ //
+ // Allocate the I2C Host Context structure
+ //
+ I2cHostContext = AllocateZeroPool (sizeof (I2C_HOST_CONTEXT));
+ if (I2cHostContext == NULL) {
+ DEBUG ((EFI_D_ERROR, "I2cHost: there is no enough memory to allocate.\n"));
+ Status = EFI_OUT_OF_RESOURCES;
+ goto Exit;
+ }
+
+ //
+ // Initialize the context structure for the current I2C Controller
+ //
+ I2cHostContext->Signature = I2C_HOST_SIGNATURE;
+ I2cHostContext->I2cMaster = I2cMaster;
+ I2cHostContext->I2cBusConfigurationManagement = I2cBusConfigurationManagement;
+ I2cHostContext->I2cBusConfiguration = (UINTN) -1;
+ InitializeListHead(&I2cHostContext->RequestList);
+
+ //
+ // Reset the controller
+ //
+ Status = I2cMaster->Reset (I2cMaster);
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "I2cHost: I2C controller reset failed!\n"));
+ goto Exit;
+ }
+
+ //
+ // Create the I2C transaction complete event
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_I2C_SYNC,
+ I2cHostRequestCompleteEvent,
+ I2cHostContext,
+ &I2cHostContext->I2cEvent
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "I2cHost: create complete event error, Status = %r\n", Status));
+ goto Exit;
+ }
+
+ //
+ // Get the bus management event
+ //
+ Status = gBS->CreateEvent (
+ EVT_NOTIFY_SIGNAL,
+ TPL_I2C_SYNC,
+ I2cHostI2cBusConfigurationAvailable,
+ I2cHostContext,
+ &I2cHostContext->I2cBusConfigurationEvent
+ );
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "I2cHost: create bus available event error, Status = %r\n", Status));
+ goto Exit;
+ }
+
+ //
+ // Build the I2C host protocol for the current I2C controller
+ //
+ I2cHostContext->I2cHost.QueueRequest = I2cHostQueueRequest;
+ I2cHostContext->I2cHost.I2cControllerCapabilities = I2cMaster->I2cControllerCapabilities;
+
+ //
+ // Install the driver protocol
+ //
+ Status = gBS->InstallMultipleProtocolInterfaces (
+ &Controller,
+ &gEfiI2cHostProtocolGuid,
+ &I2cHostContext->I2cHost,
+ NULL
+ );
+Exit:
+ if (EFI_ERROR (Status)) {
+ DEBUG ((EFI_D_ERROR, "I2cHost: Start() function failed, Status = %r\n", Status));
+ if (I2cBusConfigurationManagement != NULL) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiI2cBusConfigurationManagementProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+ }
+
+ if ((I2cHostContext != NULL) && (I2cHostContext->I2cEvent != NULL)) {
+ gBS->CloseEvent (I2cHostContext->I2cEvent);
+ I2cHostContext->I2cEvent = NULL;
+ }
+
+ if ((I2cHostContext != NULL) && (I2cHostContext->I2cBusConfigurationEvent != NULL)) {
+ gBS->CloseEvent (I2cHostContext->I2cBusConfigurationEvent);
+ I2cHostContext->I2cBusConfigurationEvent = NULL;
+ }
+
+ //
+ // Release the context structure upon failure
+ //
+ if (I2cHostContext != NULL) {
+ FreePool (I2cHostContext);
+ }
+ }
+
+ //
+ // Return the operation status.
+ //
+ return Status;
+}
+
+/**
+ Stops a device controller or a bus controller.
+
+ The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
+ As a result, much of the error checking on the parameters to Stop() has been moved
+ into this common boot service. It is legal to call Stop() from other locations,
+ but the following calling restrictions must be followed, or the system behavior will not be deterministic.
+ 1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
+ same driver's Start() function.
+ 2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
+ EFI_HANDLE. In addition, all of these handles must have been created in this driver's
+ Start() function, and the Start() function must have called OpenProtocol() on
+ ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
+
+ @param[in] This A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
+ @param[in] ControllerHandle A handle to the device being stopped. The handle must
+ support a bus specific I/O protocol for the driver
+ to use to stop the device.
+ @param[in] NumberOfChildren The number of child device handles in ChildHandleBuffer.
+ @param[in] ChildHandleBuffer An array of child handles to be freed. May be NULL
+ if NumberOfChildren is 0.
+
+ @retval EFI_SUCCESS The device was stopped.
+ @retval EFI_DEVICE_ERROR The device could not be stopped due to a device error.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cHostDriverStop (
+ IN EFI_DRIVER_BINDING_PROTOCOL *This,
+ IN EFI_HANDLE Controller,
+ IN UINTN NumberOfChildren,
+ IN EFI_HANDLE *ChildHandleBuffer
+ )
+{
+ EFI_STATUS Status;
+ I2C_HOST_CONTEXT *I2cHostContext;
+ EFI_I2C_HOST_PROTOCOL *I2cHost;
+ EFI_TPL TplPrevious;
+
+ TplPrevious = EfiGetCurrentTpl ();
+ if (TplPrevious > TPL_I2C_SYNC) {
+ DEBUG ((EFI_D_ERROR, "I2cHost: TPL %d is too high in Stop.\n", TplPrevious));
+ return EFI_DEVICE_ERROR;
+ }
+
+ Status = gBS->OpenProtocol (
+ Controller,
+ &gEfiI2cHostProtocolGuid,
+ (VOID **) &I2cHost,
+ This->DriverBindingHandle,
+ Controller,
+ EFI_OPEN_PROTOCOL_GET_PROTOCOL
+ );
+
+ if (EFI_ERROR (Status)) {
+ return EFI_DEVICE_ERROR;
+ }
+
+ I2cHostContext = I2C_HOST_CONTEXT_FROM_PROTOCOL (I2cHost);
+
+ //
+ // Raise TPL for critical section
+ //
+ TplPrevious = gBS->RaiseTPL (TPL_I2C_SYNC);
+
+ //
+ // If there is pending request or pending bus configuration, do not stop
+ //
+ Status = EFI_DEVICE_ERROR;
+ if (( !I2cHostContext->I2cBusConfigurationManagementPending )
+ && IsListEmpty (&I2cHostContext->RequestList)) {
+
+ //
+ // Remove the I2C host protocol
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ Controller,
+ &gEfiI2cHostProtocolGuid,
+ I2cHost,
+ NULL
+ );
+ }
+
+ //
+ // Leave critical section
+ //
+ gBS->RestoreTPL (TplPrevious);
+ if (!EFI_ERROR (Status)) {
+ gBS->CloseProtocol (
+ Controller,
+ &gEfiI2cBusConfigurationManagementProtocolGuid,
+ This->DriverBindingHandle,
+ Controller
+ );
+
+ //
+ // Release I2c Host resources
+ //
+ if (I2cHostContext->I2cBusConfigurationEvent != NULL) {
+ gBS->CloseEvent (I2cHostContext->I2cBusConfigurationEvent);
+ I2cHostContext->I2cBusConfigurationEvent = NULL;
+ }
+
+ if (I2cHostContext->I2cEvent != NULL) {
+ gBS->CloseEvent (I2cHostContext->I2cEvent);
+ I2cHostContext->I2cEvent = NULL;
+ }
+
+ FreePool (I2cHostContext);
+ }
+
+ //
+ // Return the stop status
+ //
+ return Status;
+}
+
+/**
+ Handle the I2C bus configuration available event
+
+ This routine is called at TPL_I2C_SYNC.
+
+ @param[in] Event Address of an EFI_EVENT handle
+ @param[in] Context Address of an I2C_HOST_CONTEXT structure
+
+**/
+VOID
+EFIAPI
+I2cHostI2cBusConfigurationAvailable (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ I2C_HOST_CONTEXT *I2cHostContext;
+ EFI_I2C_MASTER_PROTOCOL *I2cMaster;
+ I2C_REQUEST *I2cRequest;
+ LIST_ENTRY *EntryHeader;
+ LIST_ENTRY *Entry;
+ EFI_STATUS Status;
+
+ //
+ // Mark this I2C bus configuration management operation as complete
+ //
+ I2cHostContext = (I2C_HOST_CONTEXT *)Context;
+ I2cMaster = I2cHostContext->I2cMaster;
+ ASSERT (I2cMaster != NULL);
+ //
+ // Clear flag to indicate I2C bus configuration is finished
+ //
+ I2cHostContext->I2cBusConfigurationManagementPending = FALSE;
+
+ //
+ // Validate the completion status
+ //
+ if (EFI_ERROR (I2cHostContext->Status)) {
+ //
+ // Setting I2C bus configuration failed before
+ //
+ I2cHostRequestComplete (I2cHostContext, I2cHostContext->Status);
+
+ //
+ // Unknown I2C bus configuration
+ // Force next operation to enable the I2C bus configuration
+ //
+ I2cHostContext->I2cBusConfiguration = (UINTN) -1;
+
+ //
+ // Do not continue current I2C request
+ //
+ return;
+ }
+
+ //
+ // Get the first request in the link with FIFO order
+ //
+ EntryHeader = &I2cHostContext->RequestList;
+ Entry = GetFirstNode (EntryHeader);
+ I2cRequest = I2C_REQUEST_FROM_ENTRY (Entry);
+
+ //
+ // Update the I2C bus configuration of the current I2C request
+ //
+ I2cHostContext->I2cBusConfiguration = I2cRequest->I2cBusConfiguration;
+
+ //
+ // Start an I2C operation on the host, the status is returned by I2cHostContext->Status
+ //
+ Status = I2cMaster->StartRequest (
+ I2cMaster,
+ I2cRequest->SlaveAddress,
+ I2cRequest->RequestPacket,
+ I2cHostContext->I2cEvent,
+ &I2cHostContext->Status
+ );
+}
+
+/**
+ Complete the current request
+
+ This routine is called at TPL_I2C_SYNC.
+
+ @param[in] I2cHostContext Address of an I2C_HOST_CONTEXT structure.
+ @param[in] Status Status of the I2C operation.
+
+ @return This routine returns the input status value.
+
+**/
+EFI_STATUS
+I2cHostRequestComplete (
+ I2C_HOST_CONTEXT *I2cHostContext,
+ EFI_STATUS Status
+ )
+{
+ I2C_REQUEST *I2cRequest;
+ LIST_ENTRY *EntryHeader;
+ LIST_ENTRY *Entry;
+
+ //
+ // Remove the current I2C request from the list
+ //
+ EntryHeader = &I2cHostContext->RequestList;
+ Entry = GetFirstNode (EntryHeader);
+ I2cRequest = I2C_REQUEST_FROM_ENTRY (Entry);
+
+ //
+ // Save the status for QueueRequest
+ //
+ if ( NULL != I2cRequest->Status ) {
+ *I2cRequest->Status = Status;
+ }
+
+ //
+ // Notify the user of the I2C request completion
+ //
+ if ( NULL != I2cRequest->Event ) {
+ gBS->SignalEvent (I2cRequest->Event);
+ }
+
+ //
+ // Done with this request, remove the current request from list
+ //
+ RemoveEntryList (&I2cRequest->Link);
+ FreePool (I2cRequest->RequestPacket);
+ FreePool (I2cRequest);
+
+ //
+ // If there is more I2C request, start next one
+ //
+ if(!IsListEmpty (EntryHeader)) {
+ I2cHostRequestEnable (I2cHostContext);
+ }
+
+ return Status;
+}
+
+/**
+ Handle the bus available event
+
+ This routine is called at TPL_I2C_SYNC.
+
+ @param[in] Event Address of an EFI_EVENT handle
+ @param[in] Context Address of an I2C_HOST_CONTEXT structure
+
+**/
+VOID
+EFIAPI
+I2cHostRequestCompleteEvent (
+ IN EFI_EVENT Event,
+ IN VOID *Context
+ )
+{
+ I2C_HOST_CONTEXT *I2cHostContext;
+
+ //
+ // Handle the completion event
+ //
+ I2cHostContext = (I2C_HOST_CONTEXT *)Context;
+ I2cHostRequestComplete (I2cHostContext, I2cHostContext->Status);
+}
+
+/**
+ Enable access to the I2C bus configuration
+
+ @param[in] I2cHostContext Address of an I2C_HOST_CONTEXT structure
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_ABORTED The request did not complete because the driver
+ was shutdown.
+ @retval EFI_BAD_BUFFER_SIZE The WriteBytes or ReadBytes buffer size is too large.
+ @retval EFI_DEVICE_ERROR There was an I2C error (NACK) during the operation.
+ This could indicate the slave device is not present.
+ @retval EFI_INVALID_PARAMETER RequestPacket is NULL
+ @retval EFI_NO_MAPPING Invalid I2cBusConfiguration value
+ @retval EFI_NO_RESPONSE The I2C device is not responding to the
+ slave address. EFI_DEVICE_ERROR may also be
+ returned if the controller can not distinguish
+ when the NACK occurred.
+ @retval EFI_NOT_FOUND I2C slave address exceeds maximum address
+ @retval EFI_NOT_READY I2C bus is busy or operation pending, wait for
+ the event and then read status.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory for I2C operation
+ @retval EFI_TIMEOUT The transaction did not complete within an internally
+ specified timeout period.
+
+**/
+EFI_STATUS
+I2cHostRequestEnable (
+ I2C_HOST_CONTEXT *I2cHostContext
+ )
+{
+ UINTN I2cBusConfiguration;
+ CONST EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL *I2cBusConfigurationManagement;
+ I2C_REQUEST *I2cRequest;
+ EFI_STATUS Status;
+ EFI_TPL TplPrevious;
+ LIST_ENTRY *EntryHeader;
+ LIST_ENTRY *Entry;
+
+ //
+ // Assume pending request
+ //
+ Status = EFI_NOT_READY;
+
+ I2cBusConfigurationManagement = I2cHostContext->I2cBusConfigurationManagement;
+
+ //
+ // Validate the I2c bus configuration
+ //
+ EntryHeader = &I2cHostContext->RequestList;
+ Entry = GetFirstNode (EntryHeader);
+ I2cRequest = I2C_REQUEST_FROM_ENTRY (Entry);
+
+ I2cBusConfiguration = I2cRequest->I2cBusConfiguration;
+
+ if (I2cHostContext->I2cBusConfiguration != I2cBusConfiguration ) {
+ //
+ // Set flag to indicate I2C bus configuration is in progress
+ //
+ I2cHostContext->I2cBusConfigurationManagementPending = TRUE;
+ //
+ // Update bus configuration for this device's requesting bus configuration
+ //
+ Status = I2cBusConfigurationManagement->EnableI2cBusConfiguration (
+ I2cBusConfigurationManagement,
+ I2cBusConfiguration,
+ I2cHostContext->I2cBusConfigurationEvent,
+ &I2cHostContext->Status
+ );
+ } else {
+ //
+ // I2C bus configuration is same, no need change configuration and start I2c transaction directly
+ //
+ TplPrevious = gBS->RaiseTPL ( TPL_I2C_SYNC );
+
+ //
+ // Same I2C bus configuration
+ //
+ I2cHostContext->Status = EFI_SUCCESS;
+ I2cHostI2cBusConfigurationAvailable (I2cHostContext->I2cBusConfigurationEvent, I2cHostContext);
+
+ //
+ // Release the thread synchronization
+ //
+ gBS->RestoreTPL ( TplPrevious );
+ }
+ return Status;
+}
+
+/**
+ Queue an I2C operation for execution on the I2C controller.
+
+ This routine must be called at or below TPL_NOTIFY. For synchronous
+ requests this routine must be called at or below TPL_CALLBACK.
+
+ N.B. The typical consumers of this API are the I2C bus driver and
+ on rare occasions the I2C test application. Extreme care must be
+ taken by other consumers of this API to prevent confusing the
+ third party I2C drivers due to a state change at the I2C device
+ which the third party I2C drivers did not initiate. I2C platform
+ drivers may use this API within these guidelines.
+
+ This layer uses the concept of I2C bus configurations to describe
+ the I2C bus. An I2C bus configuration is defined as a unique
+ setting of the multiplexers and switches in the I2C bus which
+ enable access to one or more I2C devices. When using a switch
+ to divide a bus, due to speed differences, the I2C platform layer
+ would define an I2C bus configuration for the I2C devices on each
+ side of the switch. When using a multiplexer, the I2C platform
+ layer defines an I2C bus configuration for each of the selector
+ values required to control the multiplexer. See Figure 1 in the
+ <a href="http://www.nxp.com/documents/user_manual/UM10204.pdf">I<sup>2</sup>C
+ Specification</a> for a complex I2C bus configuration.
+
+ The I2C host driver processes all operations in FIFO order. Prior to
+ performing the operation, the I2C host driver calls the I2C platform
+ driver to reconfigure the switches and multiplexers in the I2C bus
+ enabling access to the specified I2C device. The I2C platform driver
+ also selects the maximum bus speed for the device. After the I2C bus
+ is configured, the I2C host driver calls the I2C port driver to
+ initialize the I2C controller and start the I2C operation.
+
+ @param[in] This Address of an EFI_I2C_HOST_PROTOCOL instance.
+ @param[in] I2cBusConfiguration I2C bus configuration to access the I2C
+ device.
+ @param[in] SlaveAddress Address of the device on the I2C bus.
+ @param[in] Event Event to set for asynchronous operations,
+ NULL for synchronous operations
+ @param[in] RequestPacket Address of an EFI_I2C_REQUEST_PACKET
+ structure describing the I2C operation
+ @param[out] I2cStatus Optional buffer to receive the I2C operation
+ completion status
+
+ @retval EFI_SUCCESS The operation completed successfully.
+ @retval EFI_ABORTED The request did not complete because the driver
+ was shutdown.
+ @retval EFI_BAD_BUFFER_SIZE The WriteBytes or ReadBytes buffer size is too large.
+ @retval EFI_DEVICE_ERROR There was an I2C error (NACK) during the operation.
+ This could indicate the slave device is not present.
+ @retval EFI_INVALID_PARAMETER RequestPacket is NULL
+ @retval EFI_INVALID_PARAMETER TPL is too high
+ @retval EFI_NO_MAPPING Invalid I2cBusConfiguration value
+ @retval EFI_NO_RESPONSE The I2C device is not responding to the
+ slave address. EFI_DEVICE_ERROR may also be
+ returned if the controller can not distinguish
+ when the NACK occurred.
+ @retval EFI_NOT_FOUND I2C slave address exceeds maximum address
+ @retval EFI_NOT_READY I2C bus is busy or operation pending, wait for
+ the event and then read status pointed to by
+ the request packet.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory for I2C operation
+ @retval EFI_TIMEOUT The transaction did not complete within an internally
+ specified timeout period.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cHostQueueRequest (
+ IN CONST EFI_I2C_HOST_PROTOCOL *This,
+ IN UINTN I2cBusConfiguration,
+ IN UINTN SlaveAddress,
+ IN EFI_EVENT Event OPTIONAL,
+ IN EFI_I2C_REQUEST_PACKET *RequestPacket,
+ OUT EFI_STATUS *I2cStatus OPTIONAL
+ )
+{
+ EFI_STATUS Status;
+ EFI_EVENT SyncEvent;
+ EFI_TPL TplPrevious;
+ I2C_REQUEST *I2cRequest;
+ I2C_HOST_CONTEXT *I2cHostContext;
+ BOOLEAN FirstRequest;
+ UINTN RequestPacketSize;
+
+ SyncEvent = NULL;
+ FirstRequest = FALSE;
+ Status = EFI_SUCCESS;
+
+ if (RequestPacket == NULL) {
+ return EFI_INVALID_PARAMETER;
+ }
+
+ I2cHostContext = I2C_HOST_CONTEXT_FROM_PROTOCOL (This);
+
+ if (Event == NULL) {
+ //
+ // For synchronous transaction, register an event used to wait for finishing synchronous transaction
+ //
+ Status = gBS->CreateEvent (
+ 0,
+ TPL_I2C_SYNC,
+ NULL,
+ NULL,
+ &SyncEvent
+ );
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+ }
+
+ //
+ // TPL should be at or below TPL_NOTIFY.
+ // For synchronous requests this routine must be called at or below TPL_CALLBACK.
+ //
+ TplPrevious = EfiGetCurrentTpl ();
+ if ((TplPrevious > TPL_I2C_SYNC) || ((Event == NULL) && (TplPrevious > TPL_CALLBACK))) {
+ DEBUG ((EFI_D_ERROR, "ERROR - TPL %d is too high!\n", TplPrevious));
+ return EFI_INVALID_PARAMETER;
+ }
+
+ //
+ // Allocate the request structure
+ //
+ I2cRequest = AllocateZeroPool (sizeof (I2C_REQUEST));
+ if (I2cRequest == NULL) {
+ DEBUG ((EFI_D_ERROR, "WARNING - Failed to allocate I2C_REQUEST!\n"));
+ return EFI_OUT_OF_RESOURCES;
+ }
+
+ //
+ // Initialize the request
+ //
+ I2cRequest->Signature = I2C_REQUEST_SIGNATURE;
+ I2cRequest->I2cBusConfiguration = I2cBusConfiguration;
+ I2cRequest->SlaveAddress = SlaveAddress;
+ I2cRequest->Event = (Event == NULL) ? SyncEvent : Event;
+ I2cRequest->Status = I2cStatus;
+
+ //
+ // Copy request packet into private buffer, as RequestPacket may be freed during asynchronous transaction
+ //
+ RequestPacketSize = sizeof (UINTN) + RequestPacket->OperationCount * sizeof (EFI_I2C_OPERATION);
+ I2cRequest->RequestPacket = AllocateZeroPool (RequestPacketSize);
+ CopyMem (I2cRequest->RequestPacket, RequestPacket, RequestPacketSize);
+
+ //
+ // Synchronize with the other threads
+ //
+ gBS->RaiseTPL ( TPL_I2C_SYNC );
+
+ FirstRequest = IsListEmpty (&I2cHostContext->RequestList);
+
+ //
+ // Insert new I2C request in the list
+ //
+ InsertTailList (&I2cHostContext->RequestList, &I2cRequest->Link);
+
+ //
+ // Release the thread synchronization
+ //
+ gBS->RestoreTPL (TplPrevious);
+
+ if (FirstRequest) {
+ //
+ // Start the first I2C request, then the subsequent of I2C request will continue
+ //
+ Status = I2cHostRequestEnable (I2cHostContext);
+ }
+
+ if (Event != NULL) {
+ //
+ // For asynchronous, return EFI_SUCCESS indicating that the asynchronously I2C transaction was queued.
+ // No real I2C operation status in I2cStatus
+ //
+ return EFI_SUCCESS;
+ }
+
+ //
+ // For synchronous transaction, wait for the operation completion
+ //
+ do {
+ Status = gBS->CheckEvent (SyncEvent);
+ } while (Status == EFI_NOT_READY);
+
+ //
+ // Get the I2C operation status
+ //
+ Status = I2cHostContext->Status;
+
+ //
+ // Return the I2C operation status
+ //
+ if (I2cStatus != NULL) {
+ *I2cStatus = Status;
+ }
+
+ //
+ // Close the event if necessary
+ //
+ if (SyncEvent != NULL) {
+ gBS->CloseEvent (SyncEvent);
+ }
+
+ return Status;
+}
+
+/**
+ The user Entry Point for I2C host module. The user code starts with this function.
+
+ @param[in] ImageHandle The firmware allocated handle for the EFI image.
+ @param[in] SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The entry point is executed successfully.
+ @retval other Some error occurs when executing this entry point.
+
+**/
+EFI_STATUS
+EFIAPI
+InitializeI2cHost(
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ //
+ // Install driver model protocol(s).
+ //
+ Status = EfiLibInstallDriverBindingComponentName2 (
+ ImageHandle,
+ SystemTable,
+ &gI2cHostDriverBinding,
+ ImageHandle,
+ &gI2cHostComponentName,
+ &gI2cHostComponentName2
+ );
+ ASSERT_EFI_ERROR (Status);
+ return Status;
+}
+
+/**
+ This is the unload handle for I2C host module.
+
+ Disconnect the driver specified by ImageHandle from all the devices in the handle database.
+ Uninstall all the protocols installed in the driver entry point.
+
+ @param[in] ImageHandle The drivers' driver image.
+
+ @retval EFI_SUCCESS The image is unloaded.
+ @retval Others Failed to unload the image.
+
+**/
+EFI_STATUS
+EFIAPI
+I2cHostUnload (
+ IN EFI_HANDLE ImageHandle
+ )
+{
+ EFI_STATUS Status;
+ EFI_HANDLE *DeviceHandleBuffer;
+ UINTN DeviceHandleCount;
+ UINTN Index;
+
+ //
+ // Get the list of all I2C Controller handles in the handle database.
+ // If there is an error getting the list, then the unload
+ // operation fails.
+ //
+ Status = gBS->LocateHandleBuffer (
+ ByProtocol,
+ &gEfiI2cHostProtocolGuid,
+ NULL,
+ &DeviceHandleCount,
+ &DeviceHandleBuffer
+ );
+
+ if (EFI_ERROR (Status)) {
+ return Status;
+ }
+
+ //
+ // Disconnect the driver specified by ImageHandle from all
+ // the devices in the handle database.
+ //
+ for (Index = 0; Index < DeviceHandleCount; Index++) {
+ Status = gBS->DisconnectController (
+ DeviceHandleBuffer[Index],
+ ImageHandle,
+ NULL
+ );
+ if (EFI_ERROR (Status)) {
+ goto Done;
+ }
+ }
+
+ //
+ // Uninstall all the protocols installed in the driver entry point
+ //
+ Status = gBS->UninstallMultipleProtocolInterfaces (
+ gI2cHostDriverBinding.DriverBindingHandle,
+ &gEfiDriverBindingProtocolGuid,
+ &gI2cHostDriverBinding,
+ &gEfiComponentNameProtocolGuid,
+ &gI2cHostComponentName,
+ &gEfiComponentName2ProtocolGuid,
+ &gI2cHostComponentName2,
+ NULL
+ );
+ ASSERT_EFI_ERROR (Status);
+
+Done:
+ //
+ // Free the buffer containing the list of handles from the handle database
+ //
+ if (DeviceHandleBuffer != NULL) {
+ gBS->FreePool (DeviceHandleBuffer);
+ }
+
+ return Status;
+}
diff --git a/MdeModulePkg/Bus/I2c/I2cDxe/I2cHostDxe.inf b/MdeModulePkg/Bus/I2c/I2cDxe/I2cHostDxe.inf
new file mode 100644
index 0000000..ebd9fca
--- /dev/null
+++ b/MdeModulePkg/Bus/I2c/I2cDxe/I2cHostDxe.inf
@@ -0,0 +1,53 @@
+## @file
+# This driver produce I2C Host Protocol on I2C controller handle.
+#
+# Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = I2cHostDxe
+ FILE_GUID = CDEC3671-816E-43DC-A002-DCD645229338
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ ENTRY_POINT = InitializeI2cHost
+ UNLOAD_IMAGE = I2cHostUnload
+
+#
+# The following information is for reference only and not required by the build tools.
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources.common]
+ I2cDxe.h
+ I2cHost.c
+
+[LibraryClasses]
+ BaseMemoryLib
+ DebugLib
+ DevicePathLib
+ MemoryAllocationLib
+ UefiBootServicesTableLib
+ UefiDriverEntryPoint
+ UefiLib
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+[Protocols]
+ gEfiI2cIoProtocolGuid ## BY_START
+ gEfiI2cHostProtocolGuid ## BY_START
+ gEfiI2cMasterProtocolGuid ## TO_START
+ gEfiI2cEnumerateProtocolGuid ## TO_START
+ gEfiI2cBusConfigurationManagementProtocolGuid ## TO_START
+ gEfiI2cHostProtocolGuid ## TO_START
diff --git a/MdeModulePkg/MdeModulePkg.dsc b/MdeModulePkg/MdeModulePkg.dsc
index 7a00a5d..83fb6d1 100644
--- a/MdeModulePkg/MdeModulePkg.dsc
+++ b/MdeModulePkg/MdeModulePkg.dsc
@@ -210,6 +210,9 @@
MdeModulePkg/Bus/Usb/UsbMassStorageDxe/UsbMassStorageDxe.inf
MdeModulePkg/Bus/Usb/UsbMouseAbsolutePointerDxe/UsbMouseAbsolutePointerDxe.inf
MdeModulePkg/Bus/Usb/UsbMouseDxe/UsbMouseDxe.inf
+ MdeModulePkg/Bus/I2c/I2cDxe/I2cBusDxe.inf
+ MdeModulePkg/Bus/I2c/I2cDxe/I2cHostDxe.inf
+ MdeModulePkg/Bus/I2c/I2cDxe/I2cDxe.inf
MdeModulePkg/Core/Dxe/DxeMain.inf {
<LibraryClasses>
diff --git a/MdeModulePkg/Universal/DevicePathDxe/DevicePath.c b/MdeModulePkg/Universal/DevicePathDxe/DevicePath.c
index 716aa60..70f03bd 100644
--- a/MdeModulePkg/Universal/DevicePathDxe/DevicePath.c
+++ b/MdeModulePkg/Universal/DevicePathDxe/DevicePath.c
@@ -2,7 +2,7 @@
Device Path Driver to produce DevPathUtilities Protocol, DevPathFromText Protocol
and DevPathToText Protocol.
-Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -13,19 +13,24 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
-#include "DevicePath.h"
-
-EFI_HANDLE mDevicePathHandle = NULL;
+#include <Uefi.h>
+#include <Protocol/DevicePathUtilities.h>
+#include <Protocol/DevicePathToText.h>
+#include <Protocol/DevicePathFromText.h>
+#include <Library/UefiDriverEntryPoint.h>
+#include <Library/UefiBootServicesTableLib.h>
+#include <Library/DevicePathLib.h>
+#include <Library/PcdLib.h>
GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_DEVICE_PATH_UTILITIES_PROTOCOL mDevicePathUtilities = {
- GetDevicePathSizeProtocolInterface,
- DuplicateDevicePathProtocolInterface,
- AppendDevicePathProtocolInterface,
- AppendDeviceNodeProtocolInterface,
- AppendDevicePathInstanceProtocolInterface,
- GetNextDevicePathInstanceProtocolInterface,
- IsDevicePathMultiInstanceProtocolInterface,
- CreateDeviceNodeProtocolInterface
+ GetDevicePathSize,
+ DuplicateDevicePath,
+ AppendDevicePath,
+ AppendDevicePathNode,
+ AppendDevicePathInstance,
+ GetNextDevicePathInstance,
+ IsDevicePathMultiInstance,
+ CreateDeviceNode
};
GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_DEVICE_PATH_TO_TEXT_PROTOCOL mDevicePathToText = {
@@ -38,11 +43,6 @@ GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL mDevicePa
ConvertTextToDevicePath
};
-GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_GUID mEfiDevicePathMessagingUartFlowControlGuid = DEVICE_PATH_MESSAGING_UART_FLOW_CONTROL;
-GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_GUID mEfiDevicePathMessagingSASGuid = DEVICE_PATH_MESSAGING_SAS;
-
-
-
/**
The user Entry Point for DevicePath module.
@@ -64,12 +64,14 @@ DevicePathEntryPoint (
)
{
EFI_STATUS Status;
+ EFI_HANDLE Handle;
+ Handle = NULL;
Status = EFI_UNSUPPORTED;
if (FeaturePcdGet (PcdDevicePathSupportDevicePathToText)) {
if (FeaturePcdGet (PcdDevicePathSupportDevicePathFromText)) {
Status = gBS->InstallMultipleProtocolInterfaces (
- &mDevicePathHandle,
+ &Handle,
&gEfiDevicePathUtilitiesProtocolGuid, &mDevicePathUtilities,
&gEfiDevicePathToTextProtocolGuid, &mDevicePathToText,
&gEfiDevicePathFromTextProtocolGuid, &mDevicePathFromText,
@@ -77,7 +79,7 @@ DevicePathEntryPoint (
);
} else {
Status = gBS->InstallMultipleProtocolInterfaces (
- &mDevicePathHandle,
+ &Handle,
&gEfiDevicePathUtilitiesProtocolGuid, &mDevicePathUtilities,
&gEfiDevicePathToTextProtocolGuid, &mDevicePathToText,
NULL
@@ -86,14 +88,14 @@ DevicePathEntryPoint (
} else {
if (FeaturePcdGet (PcdDevicePathSupportDevicePathFromText)) {
Status = gBS->InstallMultipleProtocolInterfaces (
- &mDevicePathHandle,
+ &Handle,
&gEfiDevicePathUtilitiesProtocolGuid, &mDevicePathUtilities,
&gEfiDevicePathFromTextProtocolGuid, &mDevicePathFromText,
NULL
);
} else {
Status = gBS->InstallMultipleProtocolInterfaces (
- &mDevicePathHandle,
+ &Handle,
&gEfiDevicePathUtilitiesProtocolGuid, &mDevicePathUtilities,
NULL
);
diff --git a/MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf b/MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
index d315fe6..29017ba 100644
--- a/MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
+++ b/MdeModulePkg/Universal/DevicePathDxe/DevicePathDxe.inf
@@ -6,7 +6,7 @@
# PcdDevicePathSupportDevicePathToText & PcdDevicePathSupportDevicePathFromText
# respectively.
#
-# Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
# which accompanies this distribution. The full text of the license may be found at
@@ -32,40 +32,21 @@
#
[Sources]
- DevicePathUtilities.c
- DevicePathToText.c ||||gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathToText
- DevicePathFromText.c ||||gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathFromText
- DevicePath.h
DevicePath.c
[Packages]
- MdeModulePkg/MdeModulePkg.dec
MdePkg/MdePkg.dec
+ MdeModulePkg/MdeModulePkg.dec
[LibraryClasses]
- PcdLib
DevicePathLib
UefiBootServicesTableLib
- MemoryAllocationLib
- BaseMemoryLib
- BaseLib
UefiDriverEntryPoint
- PrintLib
- DebugLib
-
-[Guids]
- gEfiVTUTF8Guid | gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathFromText OR gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathToText ## SOMETIMES_CONSUMES ## GUID
- gEfiVT100Guid | gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathFromText OR gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathToText ## SOMETIMES_CONSUMES ## GUID
- gEfiVT100PlusGuid | gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathFromText OR gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathToText ## SOMETIMES_CONSUMES ## GUID
- gEfiPcAnsiGuid | gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathFromText OR gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathToText ## SOMETIMES_CONSUMES ## GUID
- gEfiUartDevicePathGuid | gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathFromText OR gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathToText ## SOMETIMES_CONSUMES ## GUID
- gEfiSasDevicePathGuid | gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathFromText OR gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathToText ## SOMETIMES_CONSUMES ## GUID
[Protocols]
gEfiDevicePathToTextProtocolGuid | gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathFromText ## PRODUCES
gEfiDevicePathFromTextProtocolGuid | gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathToText ## PRODUCES
gEfiDevicePathUtilitiesProtocolGuid ## PRODUCES
- gEfiDebugPortProtocolGuid | gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathFromText OR gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathToText ## SOMETIMES_CONSUMES ## GUID
[FeaturePcd]
gEfiMdeModulePkgTokenSpaceGuid.PcdDevicePathSupportDevicePathFromText
diff --git a/MdeModulePkg/Universal/DevicePathDxe/DevicePathUtilities.c b/MdeModulePkg/Universal/DevicePathDxe/DevicePathUtilities.c
deleted file mode 100644
index 78b2670..0000000
--- a/MdeModulePkg/Universal/DevicePathDxe/DevicePathUtilities.c
+++ /dev/null
@@ -1,234 +0,0 @@
-/** @file
- Implementation file for Device Path Utilities Protocol
-
-Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.<BR>
-This program and the accompanying materials
-are licensed and made available under the terms and conditions of the BSD License
-which accompanies this distribution. The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-#include "DevicePath.h"
-
-/**
- Returns the size of a device path in bytes.
-
- This function returns the size, in bytes, of the device path data structure specified by
- DevicePath including the end of device path node. If DevicePath is NULL, then 0 is returned.
-
- @param DevicePath A pointer to a device path data structure.
-
- @return The size of a device path in bytes.
-
-**/
-UINTN
-EFIAPI
-GetDevicePathSizeProtocolInterface (
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
- )
-{
- return GetDevicePathSize (DevicePath);
-}
-
-
-/**
- Creates a new device path by appending a second device path to a first device path.
-
- This function allocates space for a new copy of the device path specified by DevicePath. If
- DevicePath is NULL, then NULL is returned. If the memory is successfully allocated, then the
- contents of DevicePath are copied to the newly allocated buffer, and a pointer to that buffer
- is returned. Otherwise, NULL is returned.
-
- @param DevicePath A pointer to a device path data structure.
-
- @return A pointer to the duplicated device path.
-
-**/
-EFI_DEVICE_PATH_PROTOCOL *
-EFIAPI
-DuplicateDevicePathProtocolInterface (
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
- )
-{
- return DuplicateDevicePath (DevicePath);
-}
-
-/**
- Creates a new device path by appending a second device path to a first device path.
-
- This function creates a new device path by appending a copy of SecondDevicePath to a copy of
- FirstDevicePath in a newly allocated buffer. Only the end-of-device-path device node from
- SecondDevicePath is retained. The newly created device path is returned.
- If FirstDevicePath is NULL, then it is ignored, and a duplicate of SecondDevicePath is returned.
- If SecondDevicePath is NULL, then it is ignored, and a duplicate of FirstDevicePath is returned.
- If both FirstDevicePath and SecondDevicePath are NULL, then a copy of an end-of-device-path is
- returned.
- If there is not enough memory for the newly allocated buffer, then NULL is returned.
- The memory for the new device path is allocated from EFI boot services memory. It is the
- responsibility of the caller to free the memory allocated.
-
- @param FirstDevicePath A pointer to a device path data structure.
- @param SecondDevicePath A pointer to a device path data structure.
-
- @return A pointer to the new device path.
-
-**/
-EFI_DEVICE_PATH_PROTOCOL *
-EFIAPI
-AppendDevicePathProtocolInterface (
- IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath,
- IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath
- )
-{
- return AppendDevicePath (FirstDevicePath, SecondDevicePath);
-}
-
-/**
- Creates a new path by appending the device node to the device path.
-
- This function creates a new device path by appending a copy of the device node specified by
- DevicePathNode to a copy of the device path specified by DevicePath in an allocated buffer.
- The end-of-device-path device node is moved after the end of the appended device node.
- If DevicePathNode is NULL then a copy of DevicePath is returned.
- If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device path device
- node is returned.
- If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path device node
- is returned.
- If there is not enough memory to allocate space for the new device path, then NULL is returned.
- The memory is allocated from EFI boot services memory. It is the responsibility of the caller to
- free the memory allocated.
-
- @param DevicePath A pointer to a device path data structure.
- @param DevicePathNode A pointer to a single device path node.
-
- @return A pointer to the new device path.
-
-**/
-EFI_DEVICE_PATH_PROTOCOL *
-EFIAPI
-AppendDeviceNodeProtocolInterface (
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode
- )
-{
- return AppendDevicePathNode (DevicePath, DevicePathNode);
-}
-
-/**
- Creates a new device path by appending the specified device path instance to the specified device
- path.
-
- This function creates a new device path by appending a copy of the device path instance specified
- by DevicePathInstance to a copy of the device path specified by DevicePath in a allocated buffer.
- The end-of-device-path device node is moved after the end of the appended device path instance
- and a new end-of-device-path-instance node is inserted between.
- If DevicePath is NULL, then a copy if DevicePathInstance is returned.
- If DevicePathInstance is NULL, then NULL is returned.
- If there is not enough memory to allocate space for the new device path, then NULL is returned.
- The memory is allocated from EFI boot services memory. It is the responsibility of the caller to
- free the memory allocated.
-
- @param DevicePath A pointer to a device path data structure.
- @param DevicePathInstance A pointer to a device path instance.
-
- @return A pointer to the new device path.
-
-**/
-EFI_DEVICE_PATH_PROTOCOL *
-EFIAPI
-AppendDevicePathInstanceProtocolInterface (
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
- )
-{
- return AppendDevicePathInstance (DevicePath, DevicePathInstance);
-}
-
-/**
- Creates a copy of the current device path instance and returns a pointer to the next device path
- instance.
-
- This function creates a copy of the current device path instance. It also updates DevicePath to
- point to the next device path instance in the device path (or NULL if no more) and updates Size
- to hold the size of the device path instance copy.
- If DevicePath is NULL, then NULL is returned.
- If there is not enough memory to allocate space for the new device path, then NULL is returned.
- The memory is allocated from EFI boot services memory. It is the responsibility of the caller to
- free the memory allocated.
- If Size is NULL, then ASSERT().
-
- @param DevicePath On input, this holds the pointer to the current device path
- instance. On output, this holds the pointer to the next device
- path instance or NULL if there are no more device path
- instances in the device path pointer to a device path data
- structure.
- @param Size On output, this holds the size of the device path instance, in
- bytes or zero, if DevicePath is NULL.
-
- @return A pointer to the current device path instance.
-
-**/
-EFI_DEVICE_PATH_PROTOCOL *
-EFIAPI
-GetNextDevicePathInstanceProtocolInterface (
- IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
- OUT UINTN *Size
- )
-{
- return GetNextDevicePathInstance (DevicePath, Size);
-}
-
-/**
- Determines if a device path is single or multi-instance.
-
- This function returns TRUE if the device path specified by DevicePath is multi-instance.
- Otherwise, FALSE is returned. If DevicePath is NULL, then FALSE is returned.
-
- @param DevicePath A pointer to a device path data structure.
-
- @retval TRUE DevicePath is multi-instance.
- @retval FALSE DevicePath is not multi-instance or DevicePath is NULL.
-
-**/
-BOOLEAN
-EFIAPI
-IsDevicePathMultiInstanceProtocolInterface (
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
- )
-{
- return IsDevicePathMultiInstance (DevicePath);
-}
-
-/**
- Creates a copy of the current device path instance and returns a pointer to the next device path
- instance.
-
- This function creates a new device node in a newly allocated buffer of size NodeLength and
- initializes the device path node header with NodeType and NodeSubType. The new device path node
- is returned.
- If NodeLength is smaller than a device path header, then NULL is returned.
- If there is not enough memory to allocate space for the new device path, then NULL is returned.
- The memory is allocated from EFI boot services memory. It is the responsibility of the caller to
- free the memory allocated.
-
- @param NodeType The device node type for the new device node.
- @param NodeSubType The device node sub-type for the new device node.
- @param NodeLength The length of the new device node.
-
- @return The new device path.
-
-**/
-EFI_DEVICE_PATH_PROTOCOL *
-EFIAPI
-CreateDeviceNodeProtocolInterface (
- IN UINT8 NodeType,
- IN UINT8 NodeSubType,
- IN UINT16 NodeLength
- )
-{
- return CreateDeviceNode (NodeType, NodeSubType, NodeLength);
-}
diff --git a/MdePkg/Include/IndustryStandard/Atapi.h b/MdePkg/Include/IndustryStandard/Atapi.h
index 0deb22b..2fcbd3f 100644
--- a/MdePkg/Include/IndustryStandard/Atapi.h
+++ b/MdePkg/Include/IndustryStandard/Atapi.h
@@ -2,7 +2,7 @@
This file contains just some basic definitions that are needed by drivers
that dealing with ATA/ATAPI interface.
-Copyright (c) 2007 - 2010, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
@@ -102,7 +102,7 @@ typedef struct {
UINT16 obsolete_51_52[2];
UINT16 field_validity;
UINT16 obsolete_54_58[5];
- UINT16 multi_sector_setting;
+ UINT16 multi_sector_setting;
UINT16 user_addressable_sectors_lo;
UINT16 user_addressable_sectors_hi;
UINT16 obsolete_62;
@@ -112,9 +112,14 @@ typedef struct {
UINT16 rec_multi_word_dma_cycle_time;
UINT16 min_pio_cycle_time_without_flow_control;
UINT16 min_pio_cycle_time_with_flow_control;
- UINT16 reserved_69_74[6];
+ UINT16 additional_supported; ///< word 69
+ UINT16 reserved_70;
+ UINT16 reserved_71_74[4]; ///< Reserved for IDENTIFY PACKET DEVICE cmd.
UINT16 queue_depth;
- UINT16 reserved_76_79[4]; ///< Reserved for Serial ATA.
+ UINT16 serial_ata_capabilities;
+ UINT16 reserved_77; ///< Reserved for Serial ATA
+ UINT16 serial_ata_features_supported;
+ UINT16 serial_ata_features_enabled;
UINT16 major_version_no;
UINT16 minor_version_no;
UINT16 command_set_supported_82; ///< word 82
@@ -129,14 +134,14 @@ typedef struct {
UINT16 advanced_power_management_level;
UINT16 master_password_identifier;
UINT16 hardware_configuration_test_result;
- UINT16 acoustic_management_value;
+ UINT16 obsolete_94;
UINT16 stream_minimum_request_size;
UINT16 streaming_transfer_time_for_dma;
UINT16 streaming_access_latency_for_dma_and_pio;
UINT16 streaming_performance_granularity[2]; ///< word 98~99
UINT16 maximum_lba_for_48bit_addressing[4]; ///< word 100~103
UINT16 streaming_transfer_time_for_pio;
- UINT16 reserved_105;
+ UINT16 max_no_of_512byte_blocks_per_data_set_cmd;
UINT16 phy_logic_sector_support; ///< word 106
UINT16 interseek_delay_for_iso7779;
UINT16 world_wide_name[4]; ///< word 108~111
@@ -151,7 +156,11 @@ typedef struct {
UINT16 security_status; ///< word 128
UINT16 vendor_specific_129_159[31];
UINT16 cfa_power_mode; ///< word 160
- UINT16 reserved_for_compactflash_161_175[15];
+ UINT16 reserved_for_compactflash_161_167[7];
+ UINT16 device_nominal_form_factor;
+ UINT16 is_data_set_cmd_supported;
+ CHAR8 additional_product_identifier[8];
+ UINT16 reserved_174_175[2];
CHAR8 media_serial_number[60]; ///< word 176~205
UINT16 sct_command_transport; ///< word 206
UINT16 reserved_207_208[2];
@@ -161,14 +170,15 @@ typedef struct {
UINT16 nv_cache_capabilities;
UINT16 nv_cache_size_in_logical_block_lsw; ///< word 215
UINT16 nv_cache_size_in_logical_block_msw; ///< word 216
- UINT16 nv_cache_read_speed;
- UINT16 nv_cache_write_speed;
+ UINT16 nominal_media_rotation_rate;
+ UINT16 reserved_218;
UINT16 nv_cache_options; ///< word 219
UINT16 write_read_verify_mode; ///< word 220
UINT16 reserved_221;
UINT16 transport_major_revision_number;
UINT16 transport_minor_revision_number;
- UINT16 reserved_224_233[10];
+ UINT16 reserved_224_229[6];
+ UINT64 extended_no_of_addressable_sectors;
UINT16 min_number_per_download_microcode_mode3; ///< word 234
UINT16 max_number_per_download_microcode_mode3; ///< word 235
UINT16 reserved_236_254[19];
@@ -206,8 +216,11 @@ typedef struct {
UINT16 reserved_69_70[2];
UINT16 obsolete_71_72[2];
UINT16 reserved_73_74[2];
- UINT16 queue_depth;
- UINT16 reserved_76_79[4];
+ UINT16 obsolete_75;
+ UINT16 serial_ata_capabilities;
+ UINT16 reserved_77; ///< Reserved for Serial ATA
+ UINT16 serial_ata_features_supported;
+ UINT16 serial_ata_features_enabled;
UINT16 major_version_no; ///< word 80
UINT16 minor_version_no; ///< word 81
UINT16 cmd_set_support_82;
@@ -219,21 +232,26 @@ typedef struct {
UINT16 ultra_dma_select;
UINT16 time_required_for_sec_erase; ///< word 89
UINT16 time_required_for_enhanced_sec_erase; ///< word 90
- UINT16 reserved_91;
+ UINT16 advanced_power_management_level;
UINT16 master_pwd_revison_code;
UINT16 hardware_reset_result; ///< word 93
- UINT16 current_auto_acoustic_mgmt_value;
+ UINT16 obsolete_94;
UINT16 reserved_95_107[13];
UINT16 world_wide_name[4]; ///< word 108~111
UINT16 reserved_for_128bit_wwn_112_115[4];
- UINT16 reserved_116_124[9];
+ UINT16 reserved_116_118[3];
+ UINT16 command_and_feature_sets_supported; ///< word 119
+ UINT16 command_and_feature_sets_supported_enabled;
+ UINT16 reserved_121_124[4];
UINT16 atapi_byte_count_0_behavior; ///< word 125
- UINT16 obsolete_126;
- UINT16 removable_media_status_notification_support;
+ UINT16 obsolete_126_127[2];
UINT16 security_status;
- UINT16 reserved_129_160[32];
- UINT16 cfa_reserved_161_175[15];
- UINT16 reserved_176_254[79];
+ UINT16 reserved_129_159[31];
+ UINT16 cfa_reserved_160_175[16];
+ UINT16 reserved_176_221[46];
+ UINT16 transport_major_version;
+ UINT16 transport_minor_version;
+ UINT16 reserved_224_254[31];
UINT16 integrity_word;
} ATAPI_IDENTIFY_DATA;
diff --git a/MdePkg/Include/Library/DevicePathLib.h b/MdePkg/Include/Library/DevicePathLib.h
index 37acd45..78aac35 100644
--- a/MdePkg/Include/Library/DevicePathLib.h
+++ b/MdePkg/Include/Library/DevicePathLib.h
@@ -4,7 +4,7 @@
This library provides defines, macros, and functions to help create and parse
EFI_DEVICE_PATH_PROTOCOL structures.
-Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License that accompanies this distribution.
The full text of the license may be found at
@@ -483,4 +483,84 @@ FileDevicePath (
IN CONST CHAR16 *FileName
);
+/**
+ Converts a device path to its text representation.
+
+ @param DevicePath A Pointer to the device to be converted.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ @return A pointer to the allocated text representation of the device path or
+ NULL if DeviceNode is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+ConvertDevicePathToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ );
+
+/**
+ Converts a device node to its string representation.
+
+ @param DeviceNode A Pointer to the device node to be converted.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
+ is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+ConvertDeviceNodeToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ );
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+ insufficient memory or text unsupported.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+ConvertTextToDeviceNode (
+ IN CONST CHAR16 *TextDeviceNode
+ );
+
+/**
+ Convert text to the binary representation of a device path.
+
+ @param TextDevicePath TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+ there was insufficient memory.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+ConvertTextToDevicePath (
+ IN CONST CHAR16 *TextDevicePath
+ );
+
#endif
diff --git a/MdePkg/Include/Pi/PiI2c.h b/MdePkg/Include/Pi/PiI2c.h
new file mode 100644
index 0000000..d7e0e2d
--- /dev/null
+++ b/MdePkg/Include/Pi/PiI2c.h
@@ -0,0 +1,307 @@
+/** @file
+ Include file matches things in PI.
+
+Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+This program and the accompanying materials are licensed and made available under
+the terms and conditions of the BSD License that accompanies this distribution.
+The full text of the license may be found at
+http://opensource.org/licenses/bsd-license.php.
+
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Revision Reference:
+ PI Version 1.3
+
+**/
+
+#ifndef __PI_I2C_H__
+#define __PI_I2C_H__
+
+///
+/// A 10-bit slave address is or'ed with the following value enabling the
+/// I2C protocol stack to address the duplicated address space between 0
+// and 127 in 10-bit mode.
+///
+#define I2C_ADDRESSING_10_BIT 0x80000000
+
+///
+/// I2C controller capabilities
+///
+/// The EFI_I2C_CONTROLLER_CAPABILITIES specifies the capabilities of the
+/// I2C host controller. The StructureSizeInBytes enables variations of
+/// this structure to be identified if there is need to extend this
+/// structure in the future.
+///
+typedef struct {
+ ///
+ /// Length of this data structure in bytes
+ ///
+ UINT32 StructureSizeInBytes;
+
+ ///
+ /// The maximum number of bytes the I2C host controller is able to
+ /// receive from the I2C bus.
+ ///
+ UINT32 MaximumReceiveBytes;
+
+ ///
+ /// The maximum number of bytes the I2C host controller is able to send
+ /// on the I2C bus.
+ ///
+ UINT32 MaximumTransmitBytes;
+
+ ///
+ /// The maximum number of bytes in the I2C bus transaction.
+ ///
+ UINT32 MaximumTotalBytes;
+} EFI_I2C_CONTROLLER_CAPABILITIES;
+
+///
+/// I2C device description
+///
+/// The EFI_I2C_ENUMERATE_PROTOCOL uses the EFI_I2C_DEVICE to describe
+/// the platform specific details associated with an I2C device. This
+/// description is passed to the I2C bus driver during enumeration where
+/// it is made available to the third party I2C device driver via the
+/// EFI_I2C_IO_PROTOCOL.
+///
+typedef struct {
+ ///
+ /// Unique value assigned by the silicon manufacture or the third
+ /// party I2C driver writer for the I2C part. This value logically
+ /// combines both the manufacture name and the I2C part number into
+ /// a single value specified as a GUID.
+ ///
+ CONST EFI_GUID *DeviceGuid;
+
+ ///
+ /// Unique ID of the I2C part within the system
+ ///
+ UINT32 DeviceIndex;
+
+ ///
+ /// Hardware revision - ACPI _HRV value. See the Advanced
+ /// Configuration and Power Interface Specification, Revision 5.0
+ /// for the field format and the Plug and play support for I2C
+ /// web-page for restriction on values.
+ ///
+ /// http://www.acpi.info/spec.htm
+ /// http://msdn.microsoft.com/en-us/library/windows/hardware/jj131711(v=vs.85).aspx
+ ///
+ UINT32 HardwareRevision;
+
+ ///
+ /// I2C bus configuration for the I2C device
+ ///
+ UINT32 I2cBusConfiguration;
+
+ ///
+ /// Number of slave addresses for the I2C device.
+ ///
+ UINT32 SlaveAddressCount;
+
+ ///
+ /// Pointer to the array of slave addresses for the I2C device.
+ ///
+ CONST UINT32 *SlaveAddressArray;
+} EFI_I2C_DEVICE;
+
+///
+/// Define the I2C flags
+///
+/// I2C read operation when set
+#define I2C_FLAG_READ 0x00000001
+
+///
+/// Define the flags for SMBus operation
+///
+/// The following flags are also present in only the first I2C operation
+/// and are ignored when present in other operations. These flags
+/// describe a particular SMB transaction as shown in the following table.
+///
+
+/// SMBus operation
+#define I2C_FLAG_SMBUS_OPERATION 0x00010000
+
+/// SMBus block operation
+/// The flag I2C_FLAG_SMBUS_BLOCK causes the I2C master protocol to update
+/// the LengthInBytes field of the operation in the request packet with
+/// the actual number of bytes read or written. These values are only
+/// valid when the entire I2C transaction is successful.
+/// This flag also changes the LengthInBytes meaning to be: A maximum
+/// of LengthInBytes is to be read from the device. The first byte
+/// read contains the number of bytes remaining to be read, plus an
+/// optional PEC value.
+#define I2C_FLAG_SMBUS_BLOCK 0x00020000
+
+/// SMBus process call operation
+#define I2C_FLAG_SMBUS_PROCESS_CALL 0x00040000
+
+/// SMBus use packet error code (PEC)
+/// Note that the I2C master protocol may clear the I2C_FLAG_SMBUS_PEC bit
+/// to indicate that the PEC value was checked by the hardware and is
+/// not appended to the returned read data.
+///
+#define I2C_FLAG_SMBUS_PEC 0x00080000
+
+//----------------------------------------------------------------------
+///
+/// QuickRead: OperationCount=1,
+/// LengthInBytes=0, Flags=I2C_FLAG_READ
+/// QuickWrite: OperationCount=1,
+/// LengthInBytes=0, Flags=0
+///
+///
+/// ReceiveByte: OperationCount=1,
+/// LengthInBytes=1, Flags=I2C_FLAG_SMBUS_OPERATION
+/// | I2C_FLAG_READ
+/// ReceiveByte+PEC: OperationCount=1,
+/// LengthInBytes=2, Flags=I2C_FLAG_SMBUS_OPERATION
+/// | I2C_FLAG_READ
+/// | I2C_FLAG_SMBUS_PEC
+///
+///
+/// SendByte: OperationCount=1,
+/// LengthInBytes=1, Flags=I2C_FLAG_SMBUS_OPERATION
+/// SendByte+PEC: OperationCount=1,
+/// LengthInBytes=2, Flags=I2C_FLAG_SMBUS_OPERATION
+/// | I2C_FLAG_SMBUS_PEC
+///
+///
+/// ReadDataByte: OperationCount=2,
+/// LengthInBytes=1, Flags=I2C_FLAG_SMBUS_OPERATION
+/// LengthInBytes=1, Flags=I2C_FLAG_READ
+/// ReadDataByte+PEC: OperationCount=2,
+/// LengthInBytes=1, Flags=I2C_FLAG_SMBUS_OPERATION
+/// | I2C_FLAG_SMBUS_PEC
+/// LengthInBytes=2, Flags=I2C_FLAG_READ
+///
+///
+/// WriteDataByte: OperationCount=1,
+/// LengthInBytes=2, Flags=I2C_FLAG_SMBUS_OPERATION
+/// WriteDataByte+PEC: OperationCount=1,
+/// LengthInBytes=3, Flags=I2C_FLAG_SMBUS_OPERATION
+/// | I2C_FLAG_SMBUS_PEC
+///
+///
+/// ReadDataWord: OperationCount=2,
+/// LengthInBytes=1, Flags=I2C_FLAG_SMBUS_OPERATION
+/// LengthInBytes=2, Flags=I2C_FLAG_READ
+/// ReadDataWord+PEC: OperationCount=2,
+/// LengthInBytes=1, Flags=I2C_FLAG_SMBUS_OPERATION
+/// | I2C_FLAG_SMBUS_PEC
+/// LengthInBytes=3, Flags=I2C_FLAG_READ
+///
+///
+/// WriteDataWord: OperationCount=1,
+/// LengthInBytes=3, Flags=I2C_FLAG_SMBUS_OPERATION
+/// WriteDataWord+PEC: OperationCount=1,
+/// LengthInBytes=4, Flags=I2C_FLAG_SMBUS_OPERATION
+/// | I2C_FLAG_SMBUS_PEC
+///
+///
+/// ReadBlock: OperationCount=2,
+/// LengthInBytes=1, Flags=I2C_FLAG_SMBUS_OPERATION
+/// | I2C_FLAG_SMBUS_BLOCK
+/// LengthInBytes=33, Flags=I2C_FLAG_READ
+/// ReadBlock+PEC: OperationCount=2,
+/// LengthInBytes=1, Flags=I2C_FLAG_SMBUS_OPERATION
+/// | I2C_FLAG_SMBUS_BLOCK
+/// | I2C_FLAG_SMBUS_PEC
+/// LengthInBytes=34, Flags=I2C_FLAG_READ
+///
+///
+/// WriteBlock: OperationCount=1,
+/// LengthInBytes=N+2, Flags=I2C_FLAG_SMBUS_OPERATION
+/// | I2C_FLAG_SMBUS_BLOCK
+/// WriteBlock+PEC: OperationCount=1,
+/// LengthInBytes=N+3, Flags=I2C_FLAG_SMBUS_OPERATION
+/// | I2C_FLAG_SMBUS_BLOCK
+/// | I2C_FLAG_SMBUS_PEC
+///
+///
+/// ProcessCall: OperationCount=2,
+/// LengthInBytes=3, Flags=I2C_FLAG_SMBUS_OPERATION
+/// | I2C_FLAG_SMBUS_PROCESS_CALL
+/// LengthInBytes=2, Flags=I2C_FLAG_READ
+/// ProcessCall+PEC: OperationCount=2,
+/// LengthInBytes=3, Flags=I2C_FLAG_SMBUS_OPERATION
+/// | I2C_FLAG_SMBUS_PROCESS_CALL
+/// | I2C_FLAG_SMBUS_PEC
+/// LengthInBytes=3, Flags=I2C_FLAG_READ
+///
+///
+/// BlkProcessCall: OperationCount=2,
+/// LengthInBytes=N+2, Flags=I2C_FLAG_SMBUS_OPERATION
+/// | I2C_FLAG_SMBUS_PROCESS_CALL
+/// | I2C_FLAG_SMBUS_BLOCK
+/// LengthInBytes=33, Flags=I2C_FLAG_READ
+/// BlkProcessCall+PEC: OperationCount=2,
+/// LengthInBytes=N+2, Flags=I2C_FLAG_SMBUS_OPERATION
+/// | I2C_FLAG_SMBUS_PROCESS_CALL
+/// | I2C_FLAG_SMBUS_BLOCK
+/// | I2C_FLAG_SMBUS_PEC
+/// LengthInBytes=34, Flags=I2C_FLAG_READ
+///
+//----------------------------------------------------------------------
+
+///
+/// I2C device operation
+///
+/// The EFI_I2C_OPERATION describes a subset of an I2C transaction in which
+/// the I2C controller is either sending or receiving bytes from the bus.
+/// Some transactions will consist of a single operation while others will
+/// be two or more.
+///
+/// Note: Some I2C controllers do not support read or write ping (address
+/// only) operation and will return EFI_UNSUPPORTED status when these
+/// operations are requested.
+///
+/// Note: I2C controllers which do not support complex transactions requiring
+/// multiple repeated start bits return EFI_UNSUPPORTED without processing
+/// any of the transaction.
+///
+typedef struct {
+ ///
+ /// Flags to qualify the I2C operation.
+ ///
+ UINT32 Flags;
+
+ ///
+ /// Number of bytes to send to or receive from the I2C device. A ping
+ /// (address only byte/bytes) is indicated by setting the LengthInBytes
+ /// to zero.
+ ///
+ UINT32 LengthInBytes;
+
+ ///
+ /// Pointer to a buffer containing the data to send or to receive from
+ /// the I2C device. The Buffer must be at least LengthInBytes in size.
+ ///
+ UINT8 *Buffer;
+} EFI_I2C_OPERATION;
+
+///
+/// I2C device request
+///
+/// The EFI_I2C_REQUEST_PACKET describes a single I2C transaction. The
+/// transaction starts with a start bit followed by the first operation
+/// in the operation array. Subsequent operations are separated with
+/// repeated start bits and the last operation is followed by a stop bit
+/// which concludes the transaction. Each operation is described by one
+/// of the elements in the Operation array.
+///
+typedef struct {
+ ///
+ /// Number of elements in the operation array
+ ///
+ UINTN OperationCount;
+
+ ///
+ /// Description of the I2C operation
+ ///
+ EFI_I2C_OPERATION Operation [1];
+} EFI_I2C_REQUEST_PACKET;
+
+#endif // __PI_I2C_H__
diff --git a/MdePkg/Include/Ppi/I2cMaster.h b/MdePkg/Include/Ppi/I2cMaster.h
new file mode 100644
index 0000000..a46b055
--- /dev/null
+++ b/MdePkg/Include/Ppi/I2cMaster.h
@@ -0,0 +1,108 @@
+/** @file
+ This PPI manipulates the I2C host controller to perform transactions as a master
+ on the I2C bus using the current state of any switches or multiplexers in the I2C bus.
+
+ Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Revision Reference:
+ This PPI is introduced in PI Version 1.3.
+
+**/
+
+#ifndef __I2C_MASTER_PPI_H__
+#define __I2C_MASTER_PPI_H__
+
+#include <Pi/PiI2c.h>
+
+#define EFI_PEI_I2C_MASTER_PPI_GUID \
+ { 0xb3bfab9b, 0x9f9c, 0x4e8b, { 0xad, 0x37, 0x7f, 0x8c, 0x51, 0xfc, 0x62, 0x80 }}
+
+typedef struct _EFI_PEI_I2C_MASTER_PPI EFI_PEI_I2C_MASTER_PPI;
+
+/**
+ Set the frequency for the I2C clock line.
+
+ @param This Pointer to an EFI_PEI_I2C_MASTER_PPI structure.
+ @param BusClockHertz Pointer to the requested I2C bus clock frequency in Hertz.
+ Upon return this value contains the actual frequency
+ in use by the I2C controller.
+
+ @retval EFI_SUCCESS The bus frequency was set successfully.
+ @retval EFI_INVALID_PARAMETER BusClockHertz is NULL
+ @retval EFI_UNSUPPORTED The controller does not support this frequency.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_I2C_MASTER_PPI_SET_BUS_FREQUENCY) (
+ IN EFI_PEI_I2C_MASTER_PPI *This,
+ IN UINTN *BusClockHertz
+ );
+
+/**
+ Reset the I2C controller and configure it for use.
+
+ @param This Pointer to an EFI_PEI_I2C_MASTER_PPI structure.
+
+ @retval EFI_SUCCESS The reset completed successfully.
+ @retval EFI_DEVICE_ERROR The reset operation failed.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_I2C_MASTER_PPI_RESET) (
+ IN CONST EFI_PEI_I2C_MASTER_PPI *This
+ );
+
+/**
+ Start an I2C transaction on the host controller.
+
+ @param This Pointer to an EFI_PEI_I2C_MASTER_PPI structure.
+ @param SlaveAddress Address of the device on the I2C bus.
+ Set the I2C_ADDRESSING_10_BIT when using 10-bit addresses,
+ clear this bit for 7-bit addressing.
+ Bits 0-6 are used for 7-bit I2C slave addresses and
+ bits 0-9 are used for 10-bit I2C slave addresses.
+ @param RequestPacket Pointer to an EFI_I2C_REQUEST_PACKET structure describing the I2C transaction.
+
+ @retval EFI_SUCCESS The transaction completed successfully.
+ @retval EFI_BAD_BUFFER_SIZE The RequestPacket->LengthInBytes value is too large.
+ @retval EFI_DEVICE_ERROR There was an I2C error (NACK) during the transaction.
+ @retval EFI_INVALID_PARAMETER RequestPacket is NULL
+ @retval EFI_NO_RESPONSE The I2C device is not responding to the slave address.
+ EFI_DEVICE_ERROR will be returned if the controller cannot distinguish when the NACK occurred.
+ @retval EFI_NOT_FOUND Reserved bit set in the SlaveAddress parameter
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory for I2C transaction
+ @retval EFI_UNSUPPORTED The controller does not support the requested transaction.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_PEI_I2C_MASTER_PPI_START_REQUEST) (
+ IN CONST EFI_PEI_I2C_MASTER_PPI *This,
+ IN UINTN SlaveAddress,
+ IN EFI_I2C_REQUEST_PACKET *RequestPacket
+ );
+
+///
+/// This PPI manipulates the I2C host controller to perform transactions as a master on the I2C bus
+/// using the current state of any switches or multiplexers in the I2C bus.
+///
+struct _EFI_PEI_I2C_MASTER_PPI {
+ EFI_PEI_I2C_MASTER_PPI_SET_BUS_FREQUENCY SetBusFrequency;
+ EFI_PEI_I2C_MASTER_PPI_RESET Reset;
+ EFI_PEI_I2C_MASTER_PPI_START_REQUEST StartRequest;
+ CONST EFI_I2C_CONTROLLER_CAPABILITIES *I2cControllerCapabilities;
+ EFI_GUID Identifier;
+};
+
+extern EFI_GUID gEfiPeiI2cMasterPpiGuid;
+
+#endif
diff --git a/MdePkg/Include/Protocol/I2cBusConfigurationManagement.h b/MdePkg/Include/Protocol/I2cBusConfigurationManagement.h
new file mode 100644
index 0000000..68000cf
--- /dev/null
+++ b/MdePkg/Include/Protocol/I2cBusConfigurationManagement.h
@@ -0,0 +1,171 @@
+/** @file
+ I2C Bus Configuration Management Protocol as defined in the PI 1.3 specification.
+
+ The EFI I2C bus configuration management protocol provides platform specific
+ services that allow the I2C host protocol to reconfigure the switches and multiplexers
+ and set the clock frequency for the I2C bus. This protocol also enables the I2C host protocol
+ to reset an I2C device which may be locking up the I2C bus by holding the clock or data line low.
+
+ Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Revision Reference:
+ This protocol is from PI Version 1.3.
+
+**/
+
+#ifndef __I2C_BUS_CONFIGURATION_MANAGEMENT_H__
+#define __I2C_BUS_CONFIGURATION_MANAGEMENT_H__
+
+#define EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL_GUID \
+ { 0x55b71fb5, 0x17c6, 0x410e, { 0xb5, 0xbd, 0x5f, 0xa2, 0xe3, 0xd4, 0x46, 0x6b }}
+
+///
+/// I2C bus configuration management protocol
+///
+/// The EFI I2C bus configuration management protocol provides platform
+/// specific services that allow the I2C host protocol to reconfigure the
+/// switches and multiplexers and set the clock frequency for the I2C bus.
+/// This protocol also enables the I2C host protocol to reset an I2C device
+/// which may be locking up the I2C bus by holding the clock or data line
+/// low.
+///
+/// The I2C protocol stack uses the concept of an I2C bus configuration as
+/// a way to describe a particular state of the switches and multiplexers
+/// in the I2C bus.
+///
+/// A simple I2C bus does not have any multiplexers or switches is described
+/// to the I2C protocol stack with a single I2C bus configuration which
+/// specifies the I2C bus frequency.
+///
+/// An I2C bus with switches and multiplexers use an I2C bus configuration
+/// to describe each of the unique settings for the switches and multiplexers
+/// and the I2C bus frequency. However the I2C bus configuration management
+/// protocol only needs to define the I2C bus configurations that the software
+/// uses, which may be a subset of the total.
+///
+/// The I2C bus configuration description includes a list of I2C devices
+/// which may be accessed when this I2C bus configuration is enabled. I2C
+/// devices before a switch or multiplexer must be included in one I2C bus
+/// configuration while I2C devices after a switch or multiplexer are on
+/// another I2C bus configuration.
+///
+/// The I2C bus configuration management protocol is an optional protocol.
+/// When the I2C bus configuration protocol is not defined the I2C host
+/// protocol does not start and the I2C master protocol may be used for
+/// other purposes such as SMBus traffic. When the I2C bus configuration
+/// protocol is available, the I2C host protocol uses the I2C bus
+/// configuration protocol to call into the platform specific code to set
+/// the switches and multiplexers and set the maximum I2C bus frequency.
+///
+/// The platform designers determine the maximum I2C bus frequency by
+/// selecting a frequency which supports all of the I2C devices on the
+/// I2C bus for the setting of switches and multiplexers. The platform
+/// designers must validate this against the I2C device data sheets and
+/// any limits of the I2C controller or bus length.
+///
+/// During I2C device enumeration, the I2C bus driver retrieves the I2C
+/// bus configuration that must be used to perform I2C transactions to
+/// each I2C device. This I2C bus configuration value is passed into
+/// the I2C host protocol to identify the I2C bus configuration required
+/// to access a specific I2C device. The I2C host protocol calls
+/// EnableBusConfiguration() to set the switches and multiplexers in the
+/// I2C bus and the I2C clock frequency. The I2C host protocol may
+/// optimize calls to EnableBusConfiguration() by only making the call
+/// when the I2C bus configuration value changes between I2C requests.
+///
+/// When I2C transactions are required on the same I2C bus to change the
+/// state of multiplexers or switches, the I2C master protocol must be
+/// used to perform the necessary I2C transactions.
+///
+/// It is up to the platform specific code to choose the proper I2C bus
+/// configuration when ExitBootServices() is called. Some operating systems
+/// are not able to manage the I2C bus configurations and must use the I2C
+/// bus configuration that is established by the platform firmware before
+/// ExitBootServices() returns.
+///
+typedef struct _EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL;
+
+
+/**
+ Enable access to an I2C bus configuration.
+
+ This routine must be called at or below TPL_NOTIFY. For synchronous
+ requests this routine must be called at or below TPL_CALLBACK.
+
+ Reconfigure the switches and multiplexers in the I2C bus to enable
+ access to a specific I2C bus configuration. Also select the maximum
+ clock frequency for this I2C bus configuration.
+
+ This routine uses the I2C Master protocol to perform I2C transactions
+ on the local bus. This eliminates any recursion in the I2C stack for
+ configuration transactions on the same I2C bus. This works because the
+ local I2C bus is idle while the I2C bus configuration is being enabled.
+
+ If I2C transactions must be performed on other I2C busses, then the
+ EFI_I2C_HOST_PROTOCOL, the EFI_I2C_IO_PROTCOL, or a third party I2C
+ driver interface for a specific device must be used. This requirement
+ is because the I2C host protocol controls the flow of requests to the
+ I2C controller. Use the EFI_I2C_HOST_PROTOCOL when the I2C device is
+ not enumerated by the EFI_I2C_ENUMERATE_PROTOCOL. Use a protocol
+ produced by a third party driver when it is available or the
+ EFI_I2C_IO_PROTOCOL when the third party driver is not available but
+ the device is enumerated with the EFI_I2C_ENUMERATE_PROTOCOL.
+
+ When Event is NULL, EnableI2cBusConfiguration operates synchronously
+ and returns the I2C completion status as its return value.
+
+ @param[in] This Pointer to an EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL
+ structure.
+ @param[in] I2cBusConfiguration Index of an I2C bus configuration. All
+ values in the range of zero to N-1 are
+ valid where N is the total number of I2C
+ bus configurations for an I2C bus.
+ @param[in] Event Event to signal when the transaction is complete
+ @param[out] I2cStatus Buffer to receive the transaction status.
+
+ @return When Event is NULL, EnableI2cBusConfiguration operates synchrouously
+ and returns the I2C completion status as its return value. In this case it is
+ recommended to use NULL for I2cStatus. The values returned from
+ EnableI2cBusConfiguration are:
+
+ @retval EFI_SUCCESS The asynchronous bus configuration request
+ was successfully started when Event is not
+ NULL.
+ @retval EFI_SUCCESS The bus configuration request completed
+ successfully when Event is NULL.
+ @retval EFI_DEVICE_ERROR The bus configuration failed.
+ @retval EFI_NO_MAPPING Invalid I2cBusConfiguration value
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL_ENABLE_I2C_BUS_CONFIGURATION) (
+ IN CONST EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL *This,
+ IN UINTN I2cBusConfiguration,
+ IN EFI_EVENT Event OPTIONAL,
+ IN EFI_STATUS *I2cStatus OPTIONAL
+ );
+
+///
+/// I2C bus configuration management protocol
+///
+struct _EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL {
+ ///
+ /// Enable an I2C bus configuration for use.
+ ///
+ EFI_I2C_BUS_CONFIGURATION_MANAGEMENT_PROTOCOL_ENABLE_I2C_BUS_CONFIGURATION EnableI2cBusConfiguration;
+};
+
+///
+/// Reference to variable defined in the .DEC file
+///
+extern EFI_GUID gEfiI2cBusConfigurationManagementProtocolGuid;
+
+#endif // __I2C_BUS_CONFIGURATION_MANAGEMENT_H__
diff --git a/MdePkg/Include/Protocol/I2cEnumerate.h b/MdePkg/Include/Protocol/I2cEnumerate.h
new file mode 100644
index 0000000..45e6a26
--- /dev/null
+++ b/MdePkg/Include/Protocol/I2cEnumerate.h
@@ -0,0 +1,110 @@
+/** @file
+ I2C Device Enumerate Protocol as defined in the PI 1.3 specification.
+
+ This protocol supports the enumerations of device on the I2C bus.
+
+ Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Revision Reference:
+ This protocol is from PI Version 1.3.
+
+**/
+
+#ifndef __I2C_ENUMERATE_H__
+#define __I2C_ENUMERATE_H__
+
+#include <Pi/PiI2c.h>
+
+#define EFI_I2C_ENUMERATE_PROTOCOL_GUID { 0xda8cd7c4, 0x1c00, 0x49e2, { 0x80, 0x3e, 0x52, 0x14, 0xe7, 0x01, 0x89, 0x4c }}
+
+typedef struct _EFI_I2C_ENUMERATE_PROTOCOL EFI_I2C_ENUMERATE_PROTOCOL;
+
+/**
+ Enumerate the I2C devices
+
+ This function enables the caller to traverse the set of I2C devices
+ on an I2C bus.
+
+ @param[in] This The platform data for the next device on
+ the I2C bus was returned successfully.
+ @param[in, out] Device Pointer to a buffer containing an
+ EFI_I2C_DEVICE structure. Enumeration is
+ started by setting the initial EFI_I2C_DEVICE
+ structure pointer to NULL. The buffer
+ receives an EFI_I2C_DEVICE structure pointer
+ to the next I2C device.
+
+ @retval EFI_SUCCESS The platform data for the next device on
+ the I2C bus was returned successfully.
+ @retval EFI_INVALID_PARAMETER Device is NULL
+ @retval EFI_NO_MAPPING *Device does not point to a valid
+ EFI_I2C_DEVICE structure returned in a
+ previous call Enumerate().
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_ENUMERATE_PROTOCOL_ENUMERATE) (
+ IN CONST EFI_I2C_ENUMERATE_PROTOCOL *This,
+ IN OUT CONST EFI_I2C_DEVICE **Device
+ );
+
+/**
+ Get the requested I2C bus frequency for a specified bus configuration.
+
+ This function returns the requested I2C bus clock frequency for the
+ I2cBusConfiguration. This routine is provided for diagnostic purposes
+ and is meant to be called after calling Enumerate to get the
+ I2cBusConfiguration value.
+
+ @param[in] This Pointer to an EFI_I2C_ENUMERATE_PROTOCOL
+ structure.
+ @param[in] I2cBusConfiguration I2C bus configuration to access the I2C
+ device
+ @param[out] *BusClockHertz Pointer to a buffer to receive the I2C
+ bus clock frequency in Hertz
+
+ @retval EFI_SUCCESS The I2C bus frequency was returned
+ successfully.
+ @retval EFI_INVALID_PARAMETER BusClockHertz was NULL
+ @retval EFI_NO_MAPPING Invalid I2cBusConfiguration value
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_ENUMERATE_PROTOCOL_GET_BUS_FREQUENCY) (
+ IN CONST EFI_I2C_ENUMERATE_PROTOCOL *This,
+ IN UINTN I2cBusConfiguration,
+ OUT UINTN *BusClockHertz
+ );
+
+///
+/// I2C Enumerate protocol
+///
+struct _EFI_I2C_ENUMERATE_PROTOCOL {
+ ///
+ /// Traverse the set of I2C devices on an I2C bus. This routine
+ /// returns the next I2C device on an I2C bus.
+ ///
+ EFI_I2C_ENUMERATE_PROTOCOL_ENUMERATE Enumerate;
+
+ ///
+ /// Get the requested I2C bus frequency for a specified bus
+ /// configuration.
+ ///
+ EFI_I2C_ENUMERATE_PROTOCOL_GET_BUS_FREQUENCY GetBusFrequency;
+};
+
+///
+/// Reference to variable defined in the .DEC file
+///
+extern EFI_GUID gEfiI2cEnumerateProtocolGuid;
+
+#endif // __I2C_ENUMERATE_H__
diff --git a/MdePkg/Include/Protocol/I2cHost.h b/MdePkg/Include/Protocol/I2cHost.h
new file mode 100644
index 0000000..12e77a4
--- /dev/null
+++ b/MdePkg/Include/Protocol/I2cHost.h
@@ -0,0 +1,160 @@
+/** @file
+ I2C Host Protocol as defined in the PI 1.3 specification.
+
+ This protocol provides callers with the ability to do I/O transactions
+ to all of the devices on the I2C bus.
+
+ Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Revision Reference:
+ This protocol is from PI Version 1.3.
+
+**/
+
+#ifndef __I2C_HOST_H__
+#define __I2C_HOST_H__
+
+#include <Pi/PiI2c.h>
+
+#define EFI_I2C_HOST_PROTOCOL_GUID { 0xa5aab9e3, 0xc727, 0x48cd, { 0x8b, 0xbf, 0x42, 0x72, 0x33, 0x85, 0x49, 0x48 }}
+
+///
+/// I2C Host Protocol
+///
+/// The I2C bus driver uses the services of the EFI_I2C_HOST_PROTOCOL
+/// to produce an instance of the EFI_I2C_IO_PROTOCOL for each I2C
+/// device on an I2C bus.
+///
+/// The EFI_I2C_HOST_PROTOCOL exposes an asynchronous interface to
+/// callers to perform transactions to any device on the I2C bus.
+/// Internally, the I2C host protocol manages the flow of the I2C
+/// transactions to the host controller, keeping them in FIFO order.
+/// Prior to each transaction, the I2C host protocol ensures that the
+/// switches and multiplexers are properly configured. The I2C host
+/// protocol then starts the transaction on the host controller using
+/// the EFI_I2C_MASTER_PROTOCOL.
+///
+typedef struct _EFI_I2C_HOST_PROTOCOL EFI_I2C_HOST_PROTOCOL;
+
+
+/**
+ Queue an I2C transaction for execution on the I2C controller.
+
+ This routine must be called at or below TPL_NOTIFY. For
+ synchronous requests this routine must be called at or below
+ TPL_CALLBACK.
+
+ The I2C host protocol uses the concept of I2C bus configurations
+ to describe the I2C bus. An I2C bus configuration is defined as
+ a unique setting of the multiplexers and switches in the I2C bus
+ which enable access to one or more I2C devices. When using a
+ switch to divide a bus, due to bus frequency differences, the
+ I2C bus configuration management protocol defines an I2C bus
+ configuration for the I2C devices on each side of the switch.
+ When using a multiplexer, the I2C bus configuration management
+ defines an I2C bus configuration for each of the selector values
+ required to control the multiplexer. See Figure 1 in the I2C -bus
+ specification and user manual for a complex I2C bus configuration.
+
+ The I2C host protocol processes all transactions in FIFO order.
+ Prior to performing the transaction, the I2C host protocol calls
+ EnableI2cBusConfiguration to reconfigure the switches and
+ multiplexers in the I2C bus enabling access to the specified I2C
+ device. The EnableI2cBusConfiguration also selects the I2C bus
+ frequency for the I2C device. After the I2C bus is configured,
+ the I2C host protocol calls the I2C master protocol to start the
+ I2C transaction.
+
+ If the I2C host protocol has pending I2C transactions queued when
+ the driver binding Stop() routine is called then the I2C host
+ protocol completes all of the pending I2C transactions by returning
+ EFI_ABORTED status. This notifies the upper layers allowing them
+ to take corrective action or prepare to stop.
+
+ When Event is NULL, QueueRequest() operates synchronously and
+ returns the I2C completion status as its return value.
+
+ When Event is not NULL, QueueRequest() synchronously returns
+ EFI_SUCCESS indicating that the asynchronously I2C transaction was
+ queued. The values above are returned in the buffer pointed to by
+ I2cStatus upon the completion of the I2C transaction when I2cStatus
+ is not NULL.
+
+ @param[in] This Pointer to an EFI_I2C_HOST_PROTOCOL structure.
+ @param[in] I2cBusConfiguration I2C bus configuration to access the I2C
+ device
+ @param[in] SlaveAddress Address of the device on the I2C bus. Set
+ the I2C_ADDRESSING_10_BIT when using 10-bit
+ addresses, clear this bit for 7-bit addressing.
+ Bits 0-6 are used for 7-bit I2C slave addresses
+ and bits 0-9 are used for 10-bit I2C slave
+ addresses.
+ @param[in] Event Event to signal for asynchronous transactions,
+ NULL for synchronous transactions
+ @param[in] RequestPacket Pointer to an EFI_I2C_REQUEST_PACKET structure
+ describing the I2C transaction
+ @param[out] I2cStatus Optional buffer to receive the I2C transaction
+ completion status
+
+ @retval EFI_SUCCESS The asynchronous transaction was successfully
+ queued when Event is not NULL.
+ @retval EFI_SUCCESS The transaction completed successfully when
+ Event is NULL.
+ @retval EFI_ABORTED The request did not complete because the
+ driver binding Stop() routine was called.
+ @retval EFI_BAD_BUFFER_SIZE The RequestPacket->LengthInBytes value is
+ too large.
+ @retval EFI_DEVICE_ERROR There was an I2C error (NACK) during the
+ transaction.
+ @retval EFI_INVALID_PARAMETER RequestPacket is NULL
+ @retval EFI_NOT_FOUND Reserved bit set in the SlaveAddress parameter
+ @retval EFI_NO_MAPPING Invalid I2cBusConfiguration value
+ @retval EFI_NO_RESPONSE The I2C device is not responding to the slave
+ address. EFI_DEVICE_ERROR will be returned
+ if the controller cannot distinguish when the
+ NACK occurred.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory for I2C transaction
+ @retval EFI_UNSUPPORTED The controller does not support the requested
+ transaction.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_HOST_PROTOCOL_QUEUE_REQUEST) (
+ IN CONST EFI_I2C_HOST_PROTOCOL *This,
+ IN UINTN I2cBusConfiguration,
+ IN UINTN SlaveAddress,
+ IN EFI_EVENT Event OPTIONAL,
+ IN EFI_I2C_REQUEST_PACKET *RequestPacket,
+ OUT EFI_STATUS *I2cStatus OPTIONAL
+ );
+
+///
+/// I2C Host Protocol
+///
+struct _EFI_I2C_HOST_PROTOCOL {
+ ///
+ /// Queue an I2C transaction for execution on the I2C bus
+ ///
+ EFI_I2C_HOST_PROTOCOL_QUEUE_REQUEST QueueRequest;
+
+ ///
+ /// Pointer to an EFI_I2C_CONTROLLER_CAPABILITIES data structure
+ /// containing the capabilities of the I2C host controller.
+ ///
+ CONST EFI_I2C_CONTROLLER_CAPABILITIES *I2cControllerCapabilities;
+};
+
+///
+/// Reference to variable defined in the .DEC file
+///
+extern EFI_GUID gEfiI2cHostProtocolGuid;
+
+#endif // __I2C_HOST_H__
diff --git a/MdePkg/Include/Protocol/I2cIo.h b/MdePkg/Include/Protocol/I2cIo.h
new file mode 100644
index 0000000..3627d0d
--- /dev/null
+++ b/MdePkg/Include/Protocol/I2cIo.h
@@ -0,0 +1,175 @@
+/** @file
+ I2C I/O Protocol as defined in the PI 1.3 specification.
+
+ The EFI I2C I/O protocol enables the user to manipulate a single
+ I2C device independent of the host controller and I2C design.
+
+ Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Revision Reference:
+ This protocol is from PI Version 1.3.
+
+**/
+
+#ifndef __I2C_IO_H__
+#define __I2C_IO_H__
+
+#include <Pi/PiI2c.h>
+
+#define EFI_I2C_IO_PROTOCOL_GUID { 0xb60a3e6b, 0x18c4, 0x46e5, { 0xa2, 0x9a, 0xc9, 0xa1, 0x06, 0x65, 0xa2, 0x8e }}
+
+///
+/// I2C I/O protocol
+///
+/// The I2C IO protocol enables access to a specific device on the I2C
+/// bus.
+///
+/// Each I2C device is identified uniquely in the system by the tuple
+/// DeviceGuid:DeviceIndex. The DeviceGuid represents the manufacture
+/// and part number and is provided by the silicon vendor or the third
+/// party I2C device driver writer. The DeviceIndex identifies the part
+/// within the system by using a unique number and is created by the
+/// board designer or the writer of the EFI_I2C_ENUMERATE_PROTOCOL.
+///
+/// I2C slave addressing is abstracted to validate addresses and limit
+/// operation to the specified I2C device. The third party providing
+/// the I2C device support provides an ordered list of slave addresses
+/// for the I2C device required to implement the EFI_I2C_ENUMERATE_PROTOCOL.
+/// The order of the list must be preserved.
+///
+typedef struct _EFI_I2C_IO_PROTOCOL EFI_I2C_IO_PROTOCOL;
+
+
+/**
+ Queue an I2C transaction for execution on the I2C device.
+
+ This routine must be called at or below TPL_NOTIFY. For synchronous
+ requests this routine must be called at or below TPL_CALLBACK.
+
+ This routine queues an I2C transaction to the I2C controller for
+ execution on the I2C bus.
+
+ When Event is NULL, QueueRequest() operates synchronously and returns
+ the I2C completion status as its return value.
+
+ When Event is not NULL, QueueRequest() synchronously returns EFI_SUCCESS
+ indicating that the asynchronous I2C transaction was queued. The values
+ above are returned in the buffer pointed to by I2cStatus upon the
+ completion of the I2C transaction when I2cStatus is not NULL.
+
+ The upper layer driver writer provides the following to the platform
+ vendor:
+
+ 1. Vendor specific GUID for the I2C part
+ 2. Guidance on proper construction of the slave address array when the
+ I2C device uses more than one slave address. The I2C bus protocol
+ uses the SlaveAddressIndex to perform relative to physical address
+ translation to access the blocks of hardware within the I2C device.
+
+ @param[in] This Pointer to an EFI_I2C_IO_PROTOCOL structure.
+ @param[in] SlaveAddressIndex Index value into an array of slave addresses
+ for the I2C device. The values in the array
+ are specified by the board designer, with the
+ third party I2C device driver writer providing
+ the slave address order.
+
+ For devices that have a single slave address,
+ this value must be zero. If the I2C device
+ uses more than one slave address then the
+ third party (upper level) I2C driver writer
+ needs to specify the order of entries in the
+ slave address array.
+
+ \ref ThirdPartyI2cDrivers "Third Party I2C
+ Drivers" section in I2cMaster.h.
+ @param[in] Event Event to signal for asynchronous transactions,
+ NULL for synchronous transactions
+ @param[in] RequestPacket Pointer to an EFI_I2C_REQUEST_PACKET structure
+ describing the I2C transaction
+ @param[out] I2cStatus Optional buffer to receive the I2C transaction
+ completion status
+
+ @retval EFI_SUCCESS The asynchronous transaction was successfully
+ queued when Event is not NULL.
+ @retval EFI_SUCCESS The transaction completed successfully when
+ Event is NULL.
+ @retval EFI_ABORTED The request did not complete because the driver
+ binding Stop() routine was called.
+ @retval EFI_BAD_BUFFER_SIZE The RequestPacket->LengthInBytes value is too
+ large.
+ @retval EFI_DEVICE_ERROR There was an I2C error (NACK) during the
+ transaction.
+ @retval EFI_INVALID_PARAMETER RequestPacket is NULL
+ @retval EFI_NOT_FOUND Reserved bit set in the SlaveAddress parameter
+ @retval EFI_NO_MAPPING The EFI_I2C_HOST_PROTOCOL could not set the
+ bus configuration required to access this I2C
+ device.
+ @retval EFI_NO_RESPONSE The I2C device is not responding to the slave
+ address selected by SlaveAddressIndex.
+ EFI_DEVICE_ERROR will be returned if the
+ controller cannot distinguish when the NACK
+ occurred.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory for I2C transaction
+ @retval EFI_UNSUPPORTED The controller does not support the requested
+ transaction.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_IO_PROTOCOL_QUEUE_REQUEST) (
+ IN CONST EFI_I2C_IO_PROTOCOL *This,
+ IN UINTN SlaveAddressIndex,
+ IN EFI_EVENT Event OPTIONAL,
+ IN EFI_I2C_REQUEST_PACKET *RequestPacket,
+ OUT EFI_STATUS *I2cStatus OPTIONAL
+ );
+
+///
+/// I2C I/O protocol
+///
+struct _EFI_I2C_IO_PROTOCOL {
+ ///
+ /// Queue an I2C transaction for execution on the I2C device.
+ ///
+ EFI_I2C_IO_PROTOCOL_QUEUE_REQUEST QueueRequest;
+
+ ///
+ /// Unique value assigned by the silicon manufacture or the third
+ /// party I2C driver writer for the I2C part. This value logically
+ /// combines both the manufacture name and the I2C part number into
+ /// a single value specified as a GUID.
+ ///
+ CONST EFI_GUID *DeviceGuid;
+
+ ///
+ /// Unique ID of the I2C part within the system
+ ///
+ UINT32 DeviceIndex;
+
+ ///
+ /// Hardware revision - ACPI _HRV value. See the Advanced Configuration
+ /// and Power Interface Specification, Revision 5.0 for the field format
+ /// and the Plug and play support for I2C web-page for restriction on values.
+ ///
+ UINT32 HardwareRevision;
+
+ ///
+ /// Pointer to an EFI_I2C_CONTROLLER_CAPABILITIES data structure containing
+ /// the capabilities of the I2C host controller.
+ ///
+ CONST EFI_I2C_CONTROLLER_CAPABILITIES *I2cControllerCapabilities;
+};
+
+///
+/// Reference to variable defined in the .DEC file
+///
+extern EFI_GUID gEfiI2cIoProtocolGuid;
+
+#endif // __I2C_IO_H__
diff --git a/MdePkg/Include/Protocol/I2cMaster.h b/MdePkg/Include/Protocol/I2cMaster.h
new file mode 100644
index 0000000..2613734
--- /dev/null
+++ b/MdePkg/Include/Protocol/I2cMaster.h
@@ -0,0 +1,192 @@
+/** @file
+ I2C Master Protocol as defined in the PI 1.3 specification.
+
+ This protocol manipulates the I2C host controller to perform transactions as a master
+ on the I2C bus using the current state of any switches or multiplexers in the I2C bus.
+
+ Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+ @par Revision Reference:
+ This protocol is from PI Version 1.3.
+
+**/
+
+#ifndef __I2C_MASTER_H__
+#define __I2C_MASTER_H__
+
+#include <Pi/PiI2c.h>
+
+#define EFI_I2C_MASTER_PROTOCOL_GUID { 0xcd72881f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }}
+
+typedef struct _EFI_I2C_MASTER_PROTOCOL EFI_I2C_MASTER_PROTOCOL;
+
+/**
+ Set the frequency for the I2C clock line.
+
+ This routine must be called at or below TPL_NOTIFY.
+
+ The software and controller do a best case effort of using the specified
+ frequency for the I2C bus. If the frequency does not match exactly then
+ the I2C master protocol selects the next lower frequency to avoid
+ exceeding the operating conditions for any of the I2C devices on the bus.
+ For example if 400 KHz was specified and the controller's divide network
+ only supports 402 KHz or 398 KHz then the I2C master protocol selects 398
+ KHz. If there are not lower frequencies available, then return
+ EFI_UNSUPPORTED.
+
+ @param[in] This Pointer to an EFI_I2C_MASTER_PROTOCOL structure
+ @param[in] BusClockHertz Pointer to the requested I2C bus clock frequency
+ in Hertz. Upon return this value contains the
+ actual frequency in use by the I2C controller.
+
+ @retval EFI_SUCCESS The bus frequency was set successfully.
+ @retval EFI_ALREADY_STARTED The controller is busy with another transaction.
+ @retval EFI_INVALID_PARAMETER BusClockHertz is NULL
+ @retval EFI_UNSUPPORTED The controller does not support this frequency.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_MASTER_PROTOCOL_SET_BUS_FREQUENCY) (
+ IN CONST EFI_I2C_MASTER_PROTOCOL *This,
+ IN OUT UINTN *BusClockHertz
+ );
+
+/**
+ Reset the I2C controller and configure it for use
+
+ This routine must be called at or below TPL_NOTIFY.
+
+ The I2C controller is reset. The caller must call SetBusFrequench() after
+ calling Reset().
+
+ @param[in] This Pointer to an EFI_I2C_MASTER_PROTOCOL structure.
+
+ @retval EFI_SUCCESS The reset completed successfully.
+ @retval EFI_ALREADY_STARTED The controller is busy with another transaction.
+ @retval EFI_DEVICE_ERROR The reset operation failed.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_MASTER_PROTOCOL_RESET) (
+ IN CONST EFI_I2C_MASTER_PROTOCOL *This
+ );
+
+/**
+ Start an I2C transaction on the host controller.
+
+ This routine must be called at or below TPL_NOTIFY. For synchronous
+ requests this routine must be called at or below TPL_CALLBACK.
+
+ This function initiates an I2C transaction on the controller. To
+ enable proper error handling by the I2C protocol stack, the I2C
+ master protocol does not support queuing but instead only manages
+ one I2C transaction at a time. This API requires that the I2C bus
+ is in the correct configuration for the I2C transaction.
+
+ The transaction is performed by sending a start-bit and selecting the
+ I2C device with the specified I2C slave address and then performing
+ the specified I2C operations. When multiple operations are requested
+ they are separated with a repeated start bit and the slave address.
+ The transaction is terminated with a stop bit.
+
+ When Event is NULL, StartRequest operates synchronously and returns
+ the I2C completion status as its return value.
+
+ When Event is not NULL, StartRequest synchronously returns EFI_SUCCESS
+ indicating that the I2C transaction was started asynchronously. The
+ transaction status value is returned in the buffer pointed to by
+ I2cStatus upon the completion of the I2C transaction when I2cStatus
+ is not NULL. After the transaction status is returned the Event is
+ signaled.
+
+ Note: The typical consumer of this API is the I2C host protocol.
+ Extreme care must be taken by other consumers of this API to prevent
+ confusing the third party I2C drivers due to a state change at the
+ I2C device which the third party I2C drivers did not initiate. I2C
+ platform specific code may use this API within these guidelines.
+
+ @param[in] This Pointer to an EFI_I2C_MASTER_PROTOCOL structure.
+ @param[in] SlaveAddress Address of the device on the I2C bus. Set the
+ I2C_ADDRESSING_10_BIT when using 10-bit addresses,
+ clear this bit for 7-bit addressing. Bits 0-6
+ are used for 7-bit I2C slave addresses and bits
+ 0-9 are used for 10-bit I2C slave addresses.
+ @param[in] RequestPacket Pointer to an EFI_I2C_REQUEST_PACKET
+ structure describing the I2C transaction.
+ @param[in] Event Event to signal for asynchronous transactions,
+ NULL for asynchronous transactions
+ @param[out] I2cStatus Optional buffer to receive the I2C transaction
+ completion status
+
+ @retval EFI_SUCCESS The asynchronous transaction was successfully
+ started when Event is not NULL.
+ @retval EFI_SUCCESS The transaction completed successfully when
+ Event is NULL.
+ @retval EFI_ALREADY_STARTED The controller is busy with another transaction.
+ @retval EFI_BAD_BUFFER_SIZE The RequestPacket->LengthInBytes value is too
+ large.
+ @retval EFI_DEVICE_ERROR There was an I2C error (NACK) during the
+ transaction.
+ @retval EFI_INVALID_PARAMETER RequestPacket is NULL
+ @retval EFI_NOT_FOUND Reserved bit set in the SlaveAddress parameter
+ @retval EFI_NO_RESPONSE The I2C device is not responding to the slave
+ address. EFI_DEVICE_ERROR will be returned if
+ the controller cannot distinguish when the NACK
+ occurred.
+ @retval EFI_OUT_OF_RESOURCES Insufficient memory for I2C transaction
+ @retval EFI_UNSUPPORTED The controller does not support the requested
+ transaction.
+
+**/
+typedef
+EFI_STATUS
+(EFIAPI *EFI_I2C_MASTER_PROTOCOL_START_REQUEST) (
+ IN CONST EFI_I2C_MASTER_PROTOCOL *This,
+ IN UINTN SlaveAddress,
+ IN EFI_I2C_REQUEST_PACKET *RequestPacket,
+ IN EFI_EVENT Event OPTIONAL,
+ OUT EFI_STATUS *I2cStatus OPTIONAL
+ );
+
+///
+/// I2C master mode protocol
+///
+/// This protocol manipulates the I2C host controller to perform transactions as a
+/// master on the I2C bus using the current state of any switches or multiplexers
+/// in the I2C bus.
+///
+struct _EFI_I2C_MASTER_PROTOCOL {
+ ///
+ /// Set the clock frequency for the I2C bus.
+ ///
+ EFI_I2C_MASTER_PROTOCOL_SET_BUS_FREQUENCY SetBusFrequency;
+
+ ///
+ /// Reset the I2C host controller.
+ ///
+ EFI_I2C_MASTER_PROTOCOL_RESET Reset;
+
+ ///
+ /// Start an I2C transaction in master mode on the host controller.
+ ///
+ EFI_I2C_MASTER_PROTOCOL_START_REQUEST StartRequest;
+
+ ///
+ /// Pointer to an EFI_I2C_CONTROLLER_CAPABILITIES data structure containing
+ /// the capabilities of the I2C host controller.
+ ///
+ CONST EFI_I2C_CONTROLLER_CAPABILITIES *I2cControllerCapabilities;
+};
+
+extern EFI_GUID gEfiI2cMasterProtocolGuid;
+
+#endif // __I2C_MASTER_H__
diff --git a/MdePkg/Library/BaseLib/BitField.c b/MdePkg/Library/BaseLib/BitField.c
index eb5fcd9..eb9e276 100644
--- a/MdePkg/Library/BaseLib/BitField.c
+++ b/MdePkg/Library/BaseLib/BitField.c
@@ -1,7 +1,7 @@
/** @file
Bit field functions of BaseLib.
- Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -71,7 +71,10 @@ InternalBaseLibBitFieldOrUint (
//
// Higher bits in OrData those are not used must be zero.
//
- ASSERT ((OrData >> (EndBit - StartBit + 1)) == 0);
+ // EndBit - StartBit + 1 might be 32 while the result right shifting 32 on a 32bit integer is undefined,
+ // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.
+ //
+ ASSERT ((OrData >> (EndBit - StartBit)) == ((OrData >> (EndBit - StartBit)) & 1));
//
// ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]
@@ -110,7 +113,10 @@ InternalBaseLibBitFieldAndUint (
//
// Higher bits in AndData those are not used must be zero.
//
- ASSERT ((AndData >> (EndBit - StartBit + 1)) == 0);
+ // EndBit - StartBit + 1 might be 32 while the result right shifting 32 on a 32bit integer is undefined,
+ // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.
+ //
+ ASSERT ((AndData >> (EndBit - StartBit)) == ((AndData >> (EndBit - StartBit)) & 1));
//
// ~((UINTN)-2 << EndBit) is a mask in which bit[0] thru bit[EndBit]
@@ -802,7 +808,13 @@ BitFieldOr64 (
ASSERT (EndBit < 64);
ASSERT (StartBit <= EndBit);
- ASSERT (RShiftU64 (OrData, EndBit - StartBit + 1) == 0);
+ //
+ // Higher bits in OrData those are not used must be zero.
+ //
+ // EndBit - StartBit + 1 might be 64 while the result right shifting 64 on RShiftU64() API is invalid,
+ // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.
+ //
+ ASSERT (RShiftU64 (OrData, EndBit - StartBit) == (RShiftU64 (OrData, EndBit - StartBit) & 1));
Value1 = LShiftU64 (OrData, StartBit);
Value2 = LShiftU64 ((UINT64) - 2, EndBit);
@@ -848,7 +860,13 @@ BitFieldAnd64 (
ASSERT (EndBit < 64);
ASSERT (StartBit <= EndBit);
- ASSERT (RShiftU64 (AndData, EndBit - StartBit + 1) == 0);
+ //
+ // Higher bits in AndData those are not used must be zero.
+ //
+ // EndBit - StartBit + 1 might be 64 while the right shifting 64 on RShiftU64() API is invalid,
+ // So the logic is updated to right shift (EndBit - StartBit) bits and compare the last bit directly.
+ //
+ ASSERT (RShiftU64 (AndData, EndBit - StartBit) == (RShiftU64 (AndData, EndBit - StartBit) & 1));
Value1 = LShiftU64 (~AndData, StartBit);
Value2 = LShiftU64 ((UINT64)-2, EndBit);
diff --git a/MdeModulePkg/Universal/DevicePathDxe/DevicePathFromText.c b/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
index f96bea1..9120319 100644
--- a/MdeModulePkg/Universal/DevicePathDxe/DevicePathFromText.c
+++ b/MdePkg/Library/UefiDevicePathLib/DevicePathFromText.c
@@ -1,7 +1,7 @@
/** @file
DevicePathFromText protocol as defined in the UEFI 2.0 specification.
-Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -12,8 +12,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
-#include "DevicePath.h"
-
+#include "UefiDevicePathLib.h"
/**
@@ -25,7 +24,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
CHAR16 *
-StrDuplicate (
+UefiDevicePathLibStrDuplicate (
IN CONST CHAR16 *Src
)
{
@@ -58,7 +57,7 @@ GetParamByNodeName (
// Check whether the node name matchs
//
NodeNameLength = StrLen (NodeName);
- if (CompareMem (Str, NodeName, NodeNameLength * sizeof (CHAR16)) != 0) {
+ if (StrnCmp (Str, NodeName, NodeNameLength) != 0) {
return NULL;
}
@@ -255,176 +254,33 @@ GetNextDeviceNodeStr (
/**
- Skip the leading white space and '0x' or '0X' of a integer string
+ Return whether the integer string is a hex string.
@param Str The integer string
- @param IsHex TRUE: Hex string, FALSE: Decimal string
- @return The trimmed Hex string.
+ @retval TRUE Hex string
+ @retval FALSE Decimal string
**/
-CHAR16 *
-TrimHexStr (
- IN CHAR16 *Str,
- OUT BOOLEAN *IsHex
+BOOLEAN
+IsHexStr (
+ IN CHAR16 *Str
)
{
- *IsHex = FALSE;
-
//
// skip preceeding white space
//
- while ((*Str != 0) && *Str == ' ') {
- Str += 1;
+ while ((*Str != 0) && *Str == L' ') {
+ Str ++;
}
//
// skip preceeding zeros
//
- while ((*Str != 0) && *Str == '0') {
- Str += 1;
- }
- //
- // skip preceeding character 'x' or 'X'
- //
- if ((*Str != 0) && (*Str == 'x' || *Str == 'X')) {
- Str += 1;
- *IsHex = TRUE;
- }
-
- return Str;
-}
-
-/**
-
- Convert hex string to uint.
-
- @param Str The hex string
-
- @return A UINTN value represented by Str
-
-**/
-UINTN
-Xtoi (
- IN CHAR16 *Str
- )
-{
- return StrHexToUintn (Str);
-}
-
-/**
-
- Convert hex string to 64 bit data.
-
- @param Str The hex string
- @param Data A pointer to the UINT64 value represented by Str
-
-**/
-VOID
-Xtoi64 (
- IN CHAR16 *Str,
- OUT UINT64 *Data
- )
-{
- *Data = StrHexToUint64 (Str);
-}
-
-/**
-
- Convert decimal string to uint.
-
- @param Str The decimal string
-
- @return A UINTN value represented by Str
-
-**/
-UINTN
-Dtoi (
- IN CHAR16 *Str
- )
-{
- UINTN Rvalue;
- CHAR16 Char;
- UINTN High;
- UINTN Low;
-
- ASSERT (Str != NULL);
-
- High = (UINTN) -1 / 10;
- Low = (UINTN) -1 % 10;
- //
- // skip preceeding white space
- //
- while ((*Str != 0) && *Str == ' ') {
- Str += 1;
- }
- //
- // convert digits
- //
- Rvalue = 0;
- Char = *(Str++);
- while (Char != 0) {
- if (Char >= '0' && Char <= '9') {
- if ((Rvalue > High || Rvalue == High) && (Char - '0' > (INTN) Low)) {
- return (UINTN) -1;
- }
-
- Rvalue = (Rvalue * 10) + Char - '0';
- } else {
- break;
- }
-
- Char = *(Str++);
- }
-
- return Rvalue;
-}
-
-/**
-
- Convert decimal string to uint.
-
- @param Str The decimal string
- @param Data A pointer to the UINT64 value represented by Str
-
-**/
-VOID
-Dtoi64 (
- IN CHAR16 *Str,
- OUT UINT64 *Data
- )
-{
- UINT64 Rvalue;
- CHAR16 Char;
- UINT64 High;
- UINT64 Low;
-
- ASSERT (Str != NULL);
- ASSERT (Data != NULL);
-
- //
- // skip preceeding white space
- //
- while ((*Str != 0) && *Str == ' ') {
- Str += 1;
- }
- //
- // convert digits
- //
- Rvalue = 0;
- Char = *(Str++);
- while (Char != 0) {
- if (Char >= '0' && Char <= '9') {
- High = LShiftU64 (Rvalue, 3);
- Low = LShiftU64 (Rvalue, 1);
- Rvalue = High + Low + Char - '0';
- } else {
- break;
- }
-
- Char = *(Str++);
+ while ((*Str != 0) && *Str == L'0') {
+ Str ++;
}
-
- *Data = Rvalue;
+
+ return (BOOLEAN) (*Str == L'x' || *Str == L'X');
}
/**
@@ -441,14 +297,10 @@ Strtoi (
IN CHAR16 *Str
)
{
- BOOLEAN IsHex;
-
- Str = TrimHexStr (Str, &IsHex);
-
- if (IsHex) {
- return Xtoi (Str);
+ if (IsHexStr (Str)) {
+ return StrHexToUintn (Str);
} else {
- return Dtoi (Str);
+ return StrDecimalToUintn (Str);
}
}
@@ -466,14 +318,10 @@ Strtoi64 (
OUT UINT64 *Data
)
{
- BOOLEAN IsHex;
-
- Str = TrimHexStr (Str, &IsHex);
-
- if (IsHex) {
- Xtoi64 (Str, Data);
+ if (IsHexStr (Str)) {
+ *Data = StrHexToUint64 (Str);
} else {
- Dtoi64 (Str, Data);
+ *Data = StrDecimalToUint64 (Str);
}
}
@@ -631,7 +479,7 @@ StrToIPv4Addr (
UINTN Index;
for (Index = 0; Index < 4; Index++) {
- IPv4Addr->Addr[Index] = (UINT8) Dtoi (SplitStr (Str, L'.'));
+ IPv4Addr->Addr[Index] = (UINT8) StrDecimalToUintn (SplitStr (Str, L'.'));
}
}
@@ -652,7 +500,7 @@ StrToIPv6Addr (
UINT16 Data;
for (Index = 0; Index < 8; Index++) {
- Data = (UINT16) Xtoi (SplitStr (Str, L':'));
+ Data = (UINT16) StrHexToUintn (SplitStr (Str, L':'));
IPv6Addr->Addr[Index * 2] = (UINT8) (Data >> 8);
IPv6Addr->Addr[Index * 2 + 1] = (UINT8) (Data & 0xff);
}
@@ -874,22 +722,19 @@ DevPathFromTextCtrl (
Converts a string to EisaId.
@param Text The input string.
- @param EisaId A pointer to the output EisaId.
+ @return UINT32 EISA ID.
**/
-VOID
+UINT32
EisaIdFromText (
- IN CHAR16 *Text,
- OUT UINT32 *EisaId
+ IN CHAR16 *Text
)
{
- UINTN PnpId;
-
- PnpId = Xtoi (Text + 3);
- *EisaId = (((Text[0] - '@') & 0x1f) << 10) +
- (((Text[1] - '@') & 0x1f) << 5) +
- ((Text[2] - '@') & 0x1f) +
- (UINT32) (PnpId << 16);
+ return (((Text[0] - 'A' + 1) & 0x1f) << 10)
+ + (((Text[1] - 'A' + 1) & 0x1f) << 5)
+ + (((Text[2] - 'A' + 1) & 0x1f) << 0)
+ + (UINT32) (StrHexToUintn (&Text[3]) << 16)
+ ;
}
/**
@@ -917,7 +762,7 @@ DevPathFromTextAcpi (
(UINT16) sizeof (ACPI_HID_DEVICE_PATH)
);
- EisaIdFromText (HIDStr, &Acpi->HID);
+ Acpi->HID = EisaIdFromText (HIDStr);
Acpi->UID = (UINT32) Strtoi (UIDStr);
return (EFI_DEVICE_PATH_PROTOCOL *) Acpi;
@@ -1089,8 +934,8 @@ DevPathFromTextAcpiEx (
Length
);
- EisaIdFromText (HIDStr, &AcpiEx->HID);
- EisaIdFromText (CIDStr, &AcpiEx->CID);
+ AcpiEx->HID = EisaIdFromText (HIDStr);
+ AcpiEx->CID = EisaIdFromText (CIDStr);
AcpiEx->UID = (UINT32) Strtoi (UIDStr);
AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
@@ -1131,8 +976,8 @@ DevPathFromTextAcpiExp (
Length
);
- EisaIdFromText (HIDStr, &AcpiEx->HID);
- EisaIdFromText (CIDStr, &AcpiEx->CID);
+ AcpiEx->HID = EisaIdFromText (HIDStr);
+ AcpiEx->CID = EisaIdFromText (CIDStr);
AcpiEx->UID = 0;
AsciiStr = (CHAR8 *) ((UINT8 *)AcpiEx + sizeof (ACPI_EXTENDED_HID_DEVICE_PATH));
@@ -1357,7 +1202,7 @@ DevPathFromText1394 (
);
F1394DevPath->Reserved = 0;
- Xtoi64 (GuidStr, &F1394DevPath->Guid);
+ F1394DevPath->Guid = StrHexToUint64 (GuidStr);
return (EFI_DEVICE_PATH_PROTOCOL *) F1394DevPath;
}
@@ -2035,8 +1880,8 @@ DevPathFromTextUart (
(UINT16) sizeof (UART_DEVICE_PATH)
);
- Uart->BaudRate = (StrCmp (BaudStr, L"DEFAULT") == 0) ? 115200 : Dtoi (BaudStr);
- Uart->DataBits = (UINT8) ((StrCmp (DataBitsStr, L"DEFAULT") == 0) ? 8 : Dtoi (DataBitsStr));
+ Uart->BaudRate = (StrCmp (BaudStr, L"DEFAULT") == 0) ? 115200 : StrDecimalToUintn (BaudStr);
+ Uart->DataBits = (UINT8) ((StrCmp (DataBitsStr, L"DEFAULT") == 0) ? 8 : StrDecimalToUintn (DataBitsStr));
switch (*ParityStr) {
case L'D':
Uart->Parity = 0;
@@ -2681,7 +2526,7 @@ DevPathFromTextHD (
(UINT16) sizeof (HARDDRIVE_DEVICE_PATH)
);
- Hd->PartitionNumber = (UINT32) Dtoi (PartitionStr);
+ Hd->PartitionNumber = (UINT32) StrDecimalToUintn (PartitionStr);
ZeroMem (Hd->Signature, 16);
Hd->MBRType = (UINT8) 0;
@@ -2988,84 +2833,84 @@ DevPathFromTextSata (
MSG_SATA_DP,
(UINT16) sizeof (SATA_DEVICE_PATH)
);
- Sata->HBAPortNumber = (UINT16) Xtoi (Param1);
+ Sata->HBAPortNumber = (UINT16) StrHexToUintn (Param1);
if (Param3 != NULL) {
- Sata->PortMultiplierPortNumber = (UINT16) Xtoi (Param2);
+ Sata->PortMultiplierPortNumber = (UINT16) StrHexToUintn (Param2);
Param2 = Param3;
} else {
Sata->PortMultiplierPortNumber = SATA_HBA_DIRECT_CONNECT_FLAG;
}
- Sata->Lun = (UINT16) Xtoi (Param2);
+ Sata->Lun = (UINT16) StrHexToUintn (Param2);
return (EFI_DEVICE_PATH_PROTOCOL *) Sata;
}
-GLOBAL_REMOVE_IF_UNREFERENCED DEVICE_PATH_FROM_TEXT_TABLE DevPathFromTextTable[] = {
- {L"Pci", DevPathFromTextPci},
- {L"PcCard", DevPathFromTextPcCard},
- {L"MemoryMapped", DevPathFromTextMemoryMapped},
- {L"VenHw", DevPathFromTextVenHw},
- {L"Ctrl", DevPathFromTextCtrl},
- {L"Acpi", DevPathFromTextAcpi},
- {L"PciRoot", DevPathFromTextPciRoot},
- {L"PcieRoot", DevPathFromTextPcieRoot},
- {L"Floppy", DevPathFromTextFloppy},
- {L"Keyboard", DevPathFromTextKeyboard},
- {L"Serial", DevPathFromTextSerial},
- {L"ParallelPort", DevPathFromTextParallelPort},
- {L"AcpiEx", DevPathFromTextAcpiEx},
- {L"AcpiExp", DevPathFromTextAcpiExp},
- {L"AcpiAdr", DevPathFromTextAcpiAdr},
- {L"Ata", DevPathFromTextAta},
- {L"Scsi", DevPathFromTextScsi},
- {L"Fibre", DevPathFromTextFibre},
- {L"FibreEx", DevPathFromTextFibreEx},
- {L"I1394", DevPathFromText1394},
- {L"USB", DevPathFromTextUsb},
- {L"I2O", DevPathFromTextI2O},
- {L"Infiniband", DevPathFromTextInfiniband},
- {L"VenMsg", DevPathFromTextVenMsg},
- {L"VenPcAnsi", DevPathFromTextVenPcAnsi},
- {L"VenVt100", DevPathFromTextVenVt100},
- {L"VenVt100Plus", DevPathFromTextVenVt100Plus},
- {L"VenUtf8", DevPathFromTextVenUtf8},
- {L"UartFlowCtrl", DevPathFromTextUartFlowCtrl},
- {L"SAS", DevPathFromTextSAS},
- {L"SasEx", DevPathFromTextSasEx},
- {L"DebugPort", DevPathFromTextDebugPort},
- {L"MAC", DevPathFromTextMAC},
- {L"IPv4", DevPathFromTextIPv4},
- {L"IPv6", DevPathFromTextIPv6},
- {L"Uart", DevPathFromTextUart},
- {L"UsbClass", DevPathFromTextUsbClass},
- {L"UsbAudio", DevPathFromTextUsbAudio},
- {L"UsbCDCControl", DevPathFromTextUsbCDCControl},
- {L"UsbHID", DevPathFromTextUsbHID},
- {L"UsbImage", DevPathFromTextUsbImage},
- {L"UsbPrinter", DevPathFromTextUsbPrinter},
- {L"UsbMassStorage", DevPathFromTextUsbMassStorage},
- {L"UsbHub", DevPathFromTextUsbHub},
- {L"UsbCDCData", DevPathFromTextUsbCDCData},
- {L"UsbSmartCard", DevPathFromTextUsbSmartCard},
- {L"UsbVideo", DevPathFromTextUsbVideo},
- {L"UsbDiagnostic", DevPathFromTextUsbDiagnostic},
- {L"UsbWireless", DevPathFromTextUsbWireless},
- {L"UsbDeviceFirmwareUpdate", DevPathFromTextUsbDeviceFirmwareUpdate},
- {L"UsbIrdaBridge", DevPathFromTextUsbIrdaBridge},
- {L"UsbTestAndMeasurement", DevPathFromTextUsbTestAndMeasurement},
- {L"UsbWwid", DevPathFromTextUsbWwid},
- {L"Unit", DevPathFromTextUnit},
- {L"iSCSI", DevPathFromTextiSCSI},
- {L"Vlan", DevPathFromTextVlan},
- {L"HD", DevPathFromTextHD},
- {L"CDROM", DevPathFromTextCDROM},
- {L"VenMEDIA", DevPathFromTextVenMEDIA},
- {L"Media", DevPathFromTextMedia},
- {L"Fv", DevPathFromTextFv},
- {L"FvFile", DevPathFromTextFvFile},
- {L"Offset", DevPathFromTextRelativeOffsetRange},
- {L"BBS", DevPathFromTextBBS},
- {L"Sata", DevPathFromTextSata},
+GLOBAL_REMOVE_IF_UNREFERENCED DEVICE_PATH_FROM_TEXT_TABLE mUefiDevicePathLibDevPathFromTextTable[] = {
+ {L"Pci", DevPathFromTextPci },
+ {L"PcCard", DevPathFromTextPcCard },
+ {L"MemoryMapped", DevPathFromTextMemoryMapped },
+ {L"VenHw", DevPathFromTextVenHw },
+ {L"Ctrl", DevPathFromTextCtrl },
+ {L"Acpi", DevPathFromTextAcpi },
+ {L"PciRoot", DevPathFromTextPciRoot },
+ {L"PcieRoot", DevPathFromTextPcieRoot },
+ {L"Floppy", DevPathFromTextFloppy },
+ {L"Keyboard", DevPathFromTextKeyboard },
+ {L"Serial", DevPathFromTextSerial },
+ {L"ParallelPort", DevPathFromTextParallelPort },
+ {L"AcpiEx", DevPathFromTextAcpiEx },
+ {L"AcpiExp", DevPathFromTextAcpiExp },
+ {L"AcpiAdr", DevPathFromTextAcpiAdr },
+ {L"Ata", DevPathFromTextAta },
+ {L"Scsi", DevPathFromTextScsi },
+ {L"Fibre", DevPathFromTextFibre },
+ {L"FibreEx", DevPathFromTextFibreEx },
+ {L"I1394", DevPathFromText1394 },
+ {L"USB", DevPathFromTextUsb },
+ {L"I2O", DevPathFromTextI2O },
+ {L"Infiniband", DevPathFromTextInfiniband },
+ {L"VenMsg", DevPathFromTextVenMsg },
+ {L"VenPcAnsi", DevPathFromTextVenPcAnsi },
+ {L"VenVt100", DevPathFromTextVenVt100 },
+ {L"VenVt100Plus", DevPathFromTextVenVt100Plus },
+ {L"VenUtf8", DevPathFromTextVenUtf8 },
+ {L"UartFlowCtrl", DevPathFromTextUartFlowCtrl },
+ {L"SAS", DevPathFromTextSAS },
+ {L"SasEx", DevPathFromTextSasEx },
+ {L"DebugPort", DevPathFromTextDebugPort },
+ {L"MAC", DevPathFromTextMAC },
+ {L"IPv4", DevPathFromTextIPv4 },
+ {L"IPv6", DevPathFromTextIPv6 },
+ {L"Uart", DevPathFromTextUart },
+ {L"UsbClass", DevPathFromTextUsbClass },
+ {L"UsbAudio", DevPathFromTextUsbAudio },
+ {L"UsbCDCControl", DevPathFromTextUsbCDCControl },
+ {L"UsbHID", DevPathFromTextUsbHID },
+ {L"UsbImage", DevPathFromTextUsbImage },
+ {L"UsbPrinter", DevPathFromTextUsbPrinter },
+ {L"UsbMassStorage", DevPathFromTextUsbMassStorage },
+ {L"UsbHub", DevPathFromTextUsbHub },
+ {L"UsbCDCData", DevPathFromTextUsbCDCData },
+ {L"UsbSmartCard", DevPathFromTextUsbSmartCard },
+ {L"UsbVideo", DevPathFromTextUsbVideo },
+ {L"UsbDiagnostic", DevPathFromTextUsbDiagnostic },
+ {L"UsbWireless", DevPathFromTextUsbWireless },
+ {L"UsbDeviceFirmwareUpdate", DevPathFromTextUsbDeviceFirmwareUpdate },
+ {L"UsbIrdaBridge", DevPathFromTextUsbIrdaBridge },
+ {L"UsbTestAndMeasurement", DevPathFromTextUsbTestAndMeasurement },
+ {L"UsbWwid", DevPathFromTextUsbWwid },
+ {L"Unit", DevPathFromTextUnit },
+ {L"iSCSI", DevPathFromTextiSCSI },
+ {L"Vlan", DevPathFromTextVlan },
+ {L"HD", DevPathFromTextHD },
+ {L"CDROM", DevPathFromTextCDROM },
+ {L"VenMEDIA", DevPathFromTextVenMEDIA },
+ {L"Media", DevPathFromTextMedia },
+ {L"Fv", DevPathFromTextFv },
+ {L"FvFile", DevPathFromTextFvFile },
+ {L"Offset", DevPathFromTextRelativeOffsetRange },
+ {L"BBS", DevPathFromTextBBS },
+ {L"Sata", DevPathFromTextSata },
{NULL, NULL}
};
@@ -3082,11 +2927,11 @@ GLOBAL_REMOVE_IF_UNREFERENCED DEVICE_PATH_FROM_TEXT_TABLE DevPathFromTextTable[]
**/
EFI_DEVICE_PATH_PROTOCOL *
EFIAPI
-ConvertTextToDeviceNode (
+UefiDevicePathLibConvertTextToDeviceNode (
IN CONST CHAR16 *TextDeviceNode
)
{
- DUMP_NODE DumpNode;
+ DEVICE_PATH_FROM_TEXT FromText;
CHAR16 *ParamStr;
EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
CHAR16 *DeviceNodeStr;
@@ -3097,26 +2942,26 @@ ConvertTextToDeviceNode (
}
ParamStr = NULL;
- DumpNode = NULL;
- DeviceNodeStr = StrDuplicate (TextDeviceNode);
+ FromText = NULL;
+ DeviceNodeStr = UefiDevicePathLibStrDuplicate (TextDeviceNode);
ASSERT (DeviceNodeStr != NULL);
- for (Index = 0; DevPathFromTextTable[Index].Function != NULL; Index++) {
- ParamStr = GetParamByNodeName (DeviceNodeStr, DevPathFromTextTable[Index].DevicePathNodeText);
+ for (Index = 0; mUefiDevicePathLibDevPathFromTextTable[Index].Function != NULL; Index++) {
+ ParamStr = GetParamByNodeName (DeviceNodeStr, mUefiDevicePathLibDevPathFromTextTable[Index].DevicePathNodeText);
if (ParamStr != NULL) {
- DumpNode = DevPathFromTextTable[Index].Function;
+ FromText = mUefiDevicePathLibDevPathFromTextTable[Index].Function;
break;
}
}
- if (DumpNode == NULL) {
+ if (FromText == NULL) {
//
// A file path
//
- DumpNode = DevPathFromTextFilePath;
- DeviceNode = DumpNode (DeviceNodeStr);
+ FromText = DevPathFromTextFilePath;
+ DeviceNode = FromText (DeviceNodeStr);
} else {
- DeviceNode = DumpNode (ParamStr);
+ DeviceNode = FromText (ParamStr);
FreePool (ParamStr);
}
@@ -3139,19 +2984,16 @@ ConvertTextToDeviceNode (
**/
EFI_DEVICE_PATH_PROTOCOL *
EFIAPI
-ConvertTextToDevicePath (
+UefiDevicePathLibConvertTextToDevicePath (
IN CONST CHAR16 *TextDevicePath
)
{
- DUMP_NODE DumpNode;
- CHAR16 *ParamStr;
EFI_DEVICE_PATH_PROTOCOL *DeviceNode;
- UINTN Index;
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
CHAR16 *DevicePathStr;
CHAR16 *Str;
CHAR16 *DeviceNodeStr;
- UINT8 IsInstanceEnd;
+ BOOLEAN IsInstanceEnd;
EFI_DEVICE_PATH_PROTOCOL *DevicePath;
if ((TextDevicePath == NULL) || (IS_NULL (*TextDevicePath))) {
@@ -3162,43 +3004,23 @@ ConvertTextToDevicePath (
ASSERT (DevicePath != NULL);
SetDevicePathEndNode (DevicePath);
- ParamStr = NULL;
- DeviceNodeStr = NULL;
- DevicePathStr = StrDuplicate (TextDevicePath);
+ DevicePathStr = UefiDevicePathLibStrDuplicate (TextDevicePath);
- Str = DevicePathStr;
+ Str = DevicePathStr;
while ((DeviceNodeStr = GetNextDeviceNodeStr (&Str, &IsInstanceEnd)) != NULL) {
- DumpNode = NULL;
- for (Index = 0; DevPathFromTextTable[Index].Function != NULL; Index++) {
- ParamStr = GetParamByNodeName (DeviceNodeStr, DevPathFromTextTable[Index].DevicePathNodeText);
- if (ParamStr != NULL) {
- DumpNode = DevPathFromTextTable[Index].Function;
- break;
- }
- }
-
- if (DumpNode == NULL) {
- //
- // A file path
- //
- DumpNode = DevPathFromTextFilePath;
- DeviceNode = DumpNode (DeviceNodeStr);
- } else {
- DeviceNode = DumpNode (ParamStr);
- FreePool (ParamStr);
- }
+ DeviceNode = UefiDevicePathLibConvertTextToDeviceNode (DeviceNodeStr);
- NewDevicePath = AppendDeviceNodeProtocolInterface (DevicePath, DeviceNode);
+ NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode);
FreePool (DevicePath);
FreePool (DeviceNode);
DevicePath = NewDevicePath;
- if (IsInstanceEnd != 0) {
+ if (IsInstanceEnd) {
DeviceNode = (EFI_DEVICE_PATH_PROTOCOL *) AllocatePool (END_DEVICE_PATH_LENGTH);
ASSERT (DeviceNode != NULL);
- SET_DEVICE_PATH_INSTANCE_END_NODE (DeviceNode);
+ SetDevicePathEndNode (DeviceNode);
- NewDevicePath = AppendDeviceNodeProtocolInterface (DevicePath, DeviceNode);
+ NewDevicePath = AppendDevicePathNode (DevicePath, DeviceNode);
FreePool (DevicePath);
FreePool (DeviceNode);
DevicePath = NewDevicePath;
diff --git a/MdeModulePkg/Universal/DevicePathDxe/DevicePathToText.c b/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
index 3d9d7c7..81cf84e 100644
--- a/MdeModulePkg/Universal/DevicePathDxe/DevicePathToText.c
+++ b/MdePkg/Library/UefiDevicePathLib/DevicePathToText.c
@@ -1,7 +1,7 @@
/** @file
DevicePathToText protocol as defined in the UEFI 2.0 specification.
-Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -12,7 +12,7 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
-#include "DevicePath.h"
+#include "UefiDevicePathLib.h"
/**
Concatenates a formatted unicode string to allocated pool. The caller must
@@ -30,42 +30,31 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
CHAR16 *
EFIAPI
-CatPrint (
+UefiDevicePathLibCatPrint (
IN OUT POOL_PRINT *Str,
IN CHAR16 *Fmt,
...
)
{
- UINT16 *AppendStr;
- UINTN AppendCount;
+ UINTN Count;
VA_LIST Args;
- AppendStr = AllocateZeroPool (0x1000);
- ASSERT (AppendStr != NULL);
-
VA_START (Args, Fmt);
- AppendCount = UnicodeVSPrint (AppendStr, 0x1000, Fmt, Args);
- VA_END (Args);
+ Count = SPrintLength (Fmt, Args);
- if (Str->Length + AppendCount * sizeof (CHAR16) > Str->Capacity) {
- Str->Capacity = Str->Length + (AppendCount + 1) * sizeof (CHAR16) * 2;
+ if ((Str->Count + (Count + 1)) * sizeof (CHAR16) > Str->Capacity) {
+ Str->Capacity = (Str->Count + (Count + 1) * 2) * sizeof (CHAR16);
Str->Str = ReallocatePool (
- Str->Length,
+ Str->Count * sizeof (CHAR16),
Str->Capacity,
Str->Str
);
ASSERT (Str->Str != NULL);
}
-
- if (Str->Length == 0) {
- StrCpy (Str->Str, AppendStr);
- Str->Length = (AppendCount + 1) * sizeof (CHAR16);
- } else {
- StrCat (Str->Str, AppendStr);
- Str->Length += AppendCount * sizeof (CHAR16);
- }
-
- FreePool (AppendStr);
+ UnicodeVSPrint (&Str->Str[Str->Count], Str->Capacity - Str->Count * sizeof (CHAR16), Fmt, Args);
+ Str->Count += Count;
+
+ VA_END (Args);
return Str->Str;
}
@@ -93,7 +82,7 @@ DevPathToTextPci (
PCI_DEVICE_PATH *Pci;
Pci = DevPath;
- CatPrint (Str, L"Pci(0x%x,0x%x)", Pci->Device, Pci->Function);
+ UefiDevicePathLibCatPrint (Str, L"Pci(0x%x,0x%x)", Pci->Device, Pci->Function);
}
/**
@@ -120,7 +109,7 @@ DevPathToTextPccard (
PCCARD_DEVICE_PATH *Pccard;
Pccard = DevPath;
- CatPrint (Str, L"PcCard(0x%x)", Pccard->FunctionNumber);
+ UefiDevicePathLibCatPrint (Str, L"PcCard(0x%x)", Pccard->FunctionNumber);
}
/**
@@ -147,7 +136,7 @@ DevPathToTextMemMap (
MEMMAP_DEVICE_PATH *MemMap;
MemMap = DevPath;
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"MemoryMapped(0x%x,0x%lx,0x%lx)",
MemMap->MemoryType,
@@ -194,30 +183,30 @@ DevPathToTextVendor (
Type = L"Msg";
if (AllowShortcuts) {
if (CompareGuid (&Vendor->Guid, &gEfiPcAnsiGuid)) {
- CatPrint (Str, L"VenPcAnsi()");
+ UefiDevicePathLibCatPrint (Str, L"VenPcAnsi()");
return ;
} else if (CompareGuid (&Vendor->Guid, &gEfiVT100Guid)) {
- CatPrint (Str, L"VenVt100()");
+ UefiDevicePathLibCatPrint (Str, L"VenVt100()");
return ;
} else if (CompareGuid (&Vendor->Guid, &gEfiVT100PlusGuid)) {
- CatPrint (Str, L"VenVt100Plus()");
+ UefiDevicePathLibCatPrint (Str, L"VenVt100Plus()");
return ;
} else if (CompareGuid (&Vendor->Guid, &gEfiVTUTF8Guid)) {
- CatPrint (Str, L"VenUft8()");
+ UefiDevicePathLibCatPrint (Str, L"VenUft8()");
return ;
} else if (CompareGuid (&Vendor->Guid, &gEfiUartDevicePathGuid)) {
FlowControlMap = (((UART_FLOW_CONTROL_DEVICE_PATH *) Vendor)->FlowControlMap);
switch (FlowControlMap & 0x00000003) {
case 0:
- CatPrint (Str, L"UartFlowCtrl(%s)", L"None");
+ UefiDevicePathLibCatPrint (Str, L"UartFlowCtrl(%s)", L"None");
break;
case 1:
- CatPrint (Str, L"UartFlowCtrl(%s)", L"Hardware");
+ UefiDevicePathLibCatPrint (Str, L"UartFlowCtrl(%s)", L"Hardware");
break;
case 2:
- CatPrint (Str, L"UartFlowCtrl(%s)", L"XonXoff");
+ UefiDevicePathLibCatPrint (Str, L"UartFlowCtrl(%s)", L"XonXoff");
break;
default:
@@ -226,7 +215,7 @@ DevPathToTextVendor (
return ;
} else if (CompareGuid (&Vendor->Guid, &gEfiSasDevicePathGuid)) {
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"SAS(0x%lx,0x%lx,0x%x,",
((SAS_DEVICE_PATH *) Vendor)->SasAddress,
@@ -235,9 +224,9 @@ DevPathToTextVendor (
);
Info = (((SAS_DEVICE_PATH *) Vendor)->DeviceTopology);
if (((Info & 0x0f) == 0) && ((Info & BIT7) == 0)) {
- CatPrint (Str, L"NoTopology,0,0,0,");
+ UefiDevicePathLibCatPrint (Str, L"NoTopology,0,0,0,");
} else if (((Info & 0x0f) <= 2) && ((Info & BIT7) == 0)) {
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"%s,%s,%s,",
((Info & BIT4) != 0) ? L"SATA" : L"SAS",
@@ -245,21 +234,21 @@ DevPathToTextVendor (
((Info & BIT6) != 0) ? L"Expanded" : L"Direct"
);
if ((Info & 0x0f) == 1) {
- CatPrint (Str, L"0,");
+ UefiDevicePathLibCatPrint (Str, L"0,");
} else {
//
// Value 0x0 thru 0xFF -> Drive 1 thru Drive 256
//
- CatPrint (Str, L"0x%x,", ((Info >> 8) & 0xff) + 1);
+ UefiDevicePathLibCatPrint (Str, L"0x%x,", ((Info >> 8) & 0xff) + 1);
}
} else {
- CatPrint (Str, L"0x%x,0,0,0,", Info);
+ UefiDevicePathLibCatPrint (Str, L"0x%x,0,0,0,", Info);
}
- CatPrint (Str, L"0x%x)", ((SAS_DEVICE_PATH *) Vendor)->Reserved);
+ UefiDevicePathLibCatPrint (Str, L"0x%x)", ((SAS_DEVICE_PATH *) Vendor)->Reserved);
return ;
} else if (CompareGuid (&Vendor->Guid, &gEfiDebugPortProtocolGuid)) {
- CatPrint (Str, L"DebugPort()");
+ UefiDevicePathLibCatPrint (Str, L"DebugPort()");
return ;
}
}
@@ -275,15 +264,15 @@ DevPathToTextVendor (
}
DataLength = DevicePathNodeLength (&Vendor->Header) - sizeof (VENDOR_DEVICE_PATH);
- CatPrint (Str, L"Ven%s(%g", Type, &Vendor->Guid);
+ UefiDevicePathLibCatPrint (Str, L"Ven%s(%g", Type, &Vendor->Guid);
if (DataLength != 0) {
- CatPrint (Str, L",");
+ UefiDevicePathLibCatPrint (Str, L",");
for (Index = 0; Index < DataLength; Index++) {
- CatPrint (Str, L"%02x", ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);
+ UefiDevicePathLibCatPrint (Str, L"%02x", ((VENDOR_DEVICE_PATH_WITH_DATA *) Vendor)->VendorDefinedData[Index]);
}
}
- CatPrint (Str, L")");
+ UefiDevicePathLibCatPrint (Str, L")");
}
/**
@@ -310,7 +299,7 @@ DevPathToTextController (
CONTROLLER_DEVICE_PATH *Controller;
Controller = DevPath;
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"Ctrl(0x%x)",
Controller->ControllerNumber
@@ -344,70 +333,39 @@ DevPathToTextAcpi (
if ((Acpi->HID & PNP_EISA_ID_MASK) == PNP_EISA_ID_CONST) {
switch (EISA_ID_TO_NUM (Acpi->HID)) {
case 0x0a03:
- CatPrint (Str, L"PciRoot(0x%x)", Acpi->UID);
+ UefiDevicePathLibCatPrint (Str, L"PciRoot(0x%x)", Acpi->UID);
break;
case 0x0a08:
- CatPrint (Str, L"PcieRoot(0x%x)", Acpi->UID);
+ UefiDevicePathLibCatPrint (Str, L"PcieRoot(0x%x)", Acpi->UID);
break;
case 0x0604:
- CatPrint (Str, L"Floppy(0x%x)", Acpi->UID);
+ UefiDevicePathLibCatPrint (Str, L"Floppy(0x%x)", Acpi->UID);
break;
case 0x0301:
- CatPrint (Str, L"Keyboard(0x%x)", Acpi->UID);
+ UefiDevicePathLibCatPrint (Str, L"Keyboard(0x%x)", Acpi->UID);
break;
case 0x0501:
- CatPrint (Str, L"Serial(0x%x)", Acpi->UID);
+ UefiDevicePathLibCatPrint (Str, L"Serial(0x%x)", Acpi->UID);
break;
case 0x0401:
- CatPrint (Str, L"ParallelPort(0x%x)", Acpi->UID);
+ UefiDevicePathLibCatPrint (Str, L"ParallelPort(0x%x)", Acpi->UID);
break;
default:
- CatPrint (Str, L"Acpi(PNP%04x,0x%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);
+ UefiDevicePathLibCatPrint (Str, L"Acpi(PNP%04x,0x%x)", EISA_ID_TO_NUM (Acpi->HID), Acpi->UID);
break;
}
} else {
- CatPrint (Str, L"Acpi(0x%08x,0x%x)", Acpi->HID, Acpi->UID);
+ UefiDevicePathLibCatPrint (Str, L"Acpi(0x%08x,0x%x)", Acpi->HID, Acpi->UID);
}
}
/**
- Converts EISA identification to string.
-
- @param EisaId The input EISA identification.
- @param Text A pointer to the output string.
-
-**/
-VOID
-EisaIdToText (
- IN UINT32 EisaId,
- IN OUT CHAR16 *Text
- )
-{
- CHAR16 PnpIdStr[17];
-
- //
- //UnicodeSPrint ("%X", 0x0a03) => "0000000000000A03"
- //
- UnicodeSPrint (PnpIdStr, 17 * 2, L"%16X", EisaId >> 16);
-
- UnicodeSPrint (
- Text,
- sizeof (CHAR16) + sizeof (CHAR16) + sizeof (CHAR16) + sizeof (PnpIdStr),
- L"%c%c%c%s",
- '@' + ((EisaId >> 10) & 0x1f),
- '@' + ((EisaId >> 5) & 0x1f),
- '@' + ((EisaId >> 0) & 0x1f),
- PnpIdStr + (16 - 4)
- );
-}
-
-/**
Converts a ACPI extended HID device path structure to its string representative.
@param Str The string representative of input device.
@@ -440,14 +398,33 @@ DevPathToTextAcpiEx (
UIDStr = HIDStr + AsciiStrLen (HIDStr) + 1;
CIDStr = UIDStr + AsciiStrLen (UIDStr) + 1;
- EisaIdToText (AcpiEx->HID, HIDText);
- EisaIdToText (AcpiEx->CID, CIDText);
+ //
+ // Converts EISA identification to string.
+ //
+ UnicodeSPrint (
+ HIDText,
+ sizeof (HIDText),
+ L"%c%c%c%04X",
+ ((AcpiEx->HID >> 10) & 0x1f) + 'A' - 1,
+ ((AcpiEx->HID >> 5) & 0x1f) + 'A' - 1,
+ ((AcpiEx->HID >> 0) & 0x1f) + 'A' - 1,
+ (AcpiEx->HID >> 16) & 0xFFFF
+ );
+ UnicodeSPrint (
+ CIDText,
+ sizeof (CIDText),
+ L"%c%c%c%04X",
+ ((AcpiEx->CID >> 10) & 0x1f) + 'A' - 1,
+ ((AcpiEx->CID >> 5) & 0x1f) + 'A' - 1,
+ ((AcpiEx->CID >> 0) & 0x1f) + 'A' - 1,
+ (AcpiEx->CID >> 16) & 0xFFFF
+ );
if ((*HIDStr == '\0') && (*CIDStr == '\0') && (AcpiEx->UID == 0)) {
//
// use AcpiExp()
//
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"AcpiExp(%s,%s,%a)",
HIDText,
@@ -460,24 +437,24 @@ DevPathToTextAcpiEx (
// display only
//
if (AcpiEx->HID == 0) {
- CatPrint (Str, L"AcpiEx(%a,", HIDStr);
+ UefiDevicePathLibCatPrint (Str, L"AcpiEx(%a,", HIDStr);
} else {
- CatPrint (Str, L"AcpiEx(%s,", HIDText);
+ UefiDevicePathLibCatPrint (Str, L"AcpiEx(%s,", HIDText);
}
if (AcpiEx->UID == 0) {
- CatPrint (Str, L"%a,", UIDStr);
+ UefiDevicePathLibCatPrint (Str, L"%a,", UIDStr);
} else {
- CatPrint (Str, L"0x%x,", AcpiEx->UID);
+ UefiDevicePathLibCatPrint (Str, L"0x%x,", AcpiEx->UID);
}
if (AcpiEx->CID == 0) {
- CatPrint (Str, L"%a)", CIDStr);
+ UefiDevicePathLibCatPrint (Str, L"%a)", CIDStr);
} else {
- CatPrint (Str, L"%s)", CIDText);
+ UefiDevicePathLibCatPrint (Str, L"%s)", CIDText);
}
} else {
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"AcpiEx(%s,%s,0x%x,%a,%a,%a)",
HIDText,
@@ -521,11 +498,11 @@ DevPathToTextAcpiAdr (
Length = (UINT16) DevicePathNodeLength ((EFI_DEVICE_PATH_PROTOCOL *) AcpiAdr);
AdditionalAdrCount = (UINT16) ((Length - 8) / 4);
- CatPrint (Str, L"AcpiAdr(0x%x", AcpiAdr->ADR);
+ UefiDevicePathLibCatPrint (Str, L"AcpiAdr(0x%x", AcpiAdr->ADR);
for (Index = 0; Index < AdditionalAdrCount; Index++) {
- CatPrint (Str, L",0x%x", *(UINT32 *) ((UINT8 *) AcpiAdr + 8 + Index * 4));
+ UefiDevicePathLibCatPrint (Str, L",0x%x", *(UINT32 *) ((UINT8 *) AcpiAdr + 8 + Index * 4));
}
- CatPrint (Str, L")");
+ UefiDevicePathLibCatPrint (Str, L")");
}
/**
@@ -554,9 +531,9 @@ DevPathToTextAtapi (
Atapi = DevPath;
if (DisplayOnly) {
- CatPrint (Str, L"Ata(0x%x)", Atapi->Lun);
+ UefiDevicePathLibCatPrint (Str, L"Ata(0x%x)", Atapi->Lun);
} else {
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"Ata(%s,%s,0x%x)",
(Atapi->PrimarySecondary == 1) ? L"Secondary" : L"Primary",
@@ -590,7 +567,7 @@ DevPathToTextScsi (
SCSI_DEVICE_PATH *Scsi;
Scsi = DevPath;
- CatPrint (Str, L"Scsi(0x%x,0x%x)", Scsi->Pun, Scsi->Lun);
+ UefiDevicePathLibCatPrint (Str, L"Scsi(0x%x,0x%x)", Scsi->Pun, Scsi->Lun);
}
/**
@@ -617,7 +594,7 @@ DevPathToTextFibre (
FIBRECHANNEL_DEVICE_PATH *Fibre;
Fibre = DevPath;
- CatPrint (Str, L"Fibre(0x%lx,0x%lx)", Fibre->WWN, Fibre->Lun);
+ UefiDevicePathLibCatPrint (Str, L"Fibre(0x%lx,0x%lx)", Fibre->WWN, Fibre->Lun);
}
/**
@@ -645,15 +622,15 @@ DevPathToTextFibreEx (
UINTN Index;
FibreEx = DevPath;
- CatPrint (Str, L"FibreEx(0x");
+ UefiDevicePathLibCatPrint (Str, L"FibreEx(0x");
for (Index = 0; Index < sizeof (FibreEx->WWN) / sizeof (FibreEx->WWN[0]); Index++) {
- CatPrint (Str, L"%02x", FibreEx->WWN[Index]);
+ UefiDevicePathLibCatPrint (Str, L"%02x", FibreEx->WWN[Index]);
}
- CatPrint (Str, L",0x");
+ UefiDevicePathLibCatPrint (Str, L",0x");
for (Index = 0; Index < sizeof (FibreEx->Lun) / sizeof (FibreEx->Lun[0]); Index++) {
- CatPrint (Str, L"%02x", FibreEx->Lun[Index]);
+ UefiDevicePathLibCatPrint (Str, L"%02x", FibreEx->Lun[Index]);
}
- CatPrint (Str, L")");
+ UefiDevicePathLibCatPrint (Str, L")");
}
/**
@@ -681,21 +658,21 @@ DevPathToTextSasEx (
UINTN Index;
SasEx = DevPath;
- CatPrint (Str, L"SasEx(0x");
+ UefiDevicePathLibCatPrint (Str, L"SasEx(0x");
for (Index = 0; Index < sizeof (SasEx->SasAddress) / sizeof (SasEx->SasAddress[0]); Index++) {
- CatPrint (Str, L"%02x", SasEx->SasAddress[Index]);
+ UefiDevicePathLibCatPrint (Str, L"%02x", SasEx->SasAddress[Index]);
}
- CatPrint (Str, L",0x");
+ UefiDevicePathLibCatPrint (Str, L",0x");
for (Index = 0; Index < sizeof (SasEx->Lun) / sizeof (SasEx->Lun[0]); Index++) {
- CatPrint (Str, L"%02x", SasEx->Lun[Index]);
+ UefiDevicePathLibCatPrint (Str, L"%02x", SasEx->Lun[Index]);
}
- CatPrint (Str, L",0x%x,", SasEx->RelativeTargetPort);
+ UefiDevicePathLibCatPrint (Str, L",0x%x,", SasEx->RelativeTargetPort);
if (((SasEx->DeviceTopology & 0x0f) == 0) && ((SasEx->DeviceTopology & BIT7) == 0)) {
- CatPrint (Str, L"NoTopology,0,0,0");
+ UefiDevicePathLibCatPrint (Str, L"NoTopology,0,0,0");
} else if (((SasEx->DeviceTopology & 0x0f) <= 2) && ((SasEx->DeviceTopology & BIT7) == 0)) {
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"%s,%s,%s,",
((SasEx->DeviceTopology & BIT4) != 0) ? L"SATA" : L"SAS",
@@ -703,18 +680,18 @@ DevPathToTextSasEx (
((SasEx->DeviceTopology & BIT6) != 0) ? L"Expanded" : L"Direct"
);
if ((SasEx->DeviceTopology & 0x0f) == 1) {
- CatPrint (Str, L"0");
+ UefiDevicePathLibCatPrint (Str, L"0");
} else {
//
// Value 0x0 thru 0xFF -> Drive 1 thru Drive 256
//
- CatPrint (Str, L"0x%x", ((SasEx->DeviceTopology >> 8) & 0xff) + 1);
+ UefiDevicePathLibCatPrint (Str, L"0x%x", ((SasEx->DeviceTopology >> 8) & 0xff) + 1);
}
} else {
- CatPrint (Str, L"0x%x,0,0,0", SasEx->DeviceTopology);
+ UefiDevicePathLibCatPrint (Str, L"0x%x,0,0,0", SasEx->DeviceTopology);
}
- CatPrint (Str, L")");
+ UefiDevicePathLibCatPrint (Str, L")");
return ;
}
@@ -746,7 +723,7 @@ DevPathToText1394 (
//
// Guid has format of IEEE-EUI64
//
- CatPrint (Str, L"I1394(%016lx)", F1394DevPath->Guid);
+ UefiDevicePathLibCatPrint (Str, L"I1394(%016lx)", F1394DevPath->Guid);
}
/**
@@ -773,7 +750,7 @@ DevPathToTextUsb (
USB_DEVICE_PATH *Usb;
Usb = DevPath;
- CatPrint (Str, L"USB(0x%x,0x%x)", Usb->ParentPortNumber, Usb->InterfaceNumber);
+ UefiDevicePathLibCatPrint (Str, L"USB(0x%x,0x%x)", Usb->ParentPortNumber, Usb->InterfaceNumber);
}
/**
@@ -816,7 +793,7 @@ DevPathToTextUsbWWID (
SerialNumberStr = NewStr;
}
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"UsbWwid(0x%x,0x%x,0x%x,\"%s\")",
UsbWWId->VendorId,
@@ -850,7 +827,7 @@ DevPathToTextLogicalUnit (
DEVICE_LOGICAL_UNIT_DEVICE_PATH *LogicalUnit;
LogicalUnit = DevPath;
- CatPrint (Str, L"Unit(0x%x)", LogicalUnit->Lun);
+ UefiDevicePathLibCatPrint (Str, L"Unit(0x%x)", LogicalUnit->Lun);
}
/**
@@ -883,51 +860,51 @@ DevPathToTextUsbClass (
IsKnownSubClass = TRUE;
switch (UsbClass->DeviceClass) {
case USB_CLASS_AUDIO:
- CatPrint (Str, L"UsbAudio");
+ UefiDevicePathLibCatPrint (Str, L"UsbAudio");
break;
case USB_CLASS_CDCCONTROL:
- CatPrint (Str, L"UsbCDCControl");
+ UefiDevicePathLibCatPrint (Str, L"UsbCDCControl");
break;
case USB_CLASS_HID:
- CatPrint (Str, L"UsbHID");
+ UefiDevicePathLibCatPrint (Str, L"UsbHID");
break;
case USB_CLASS_IMAGE:
- CatPrint (Str, L"UsbImage");
+ UefiDevicePathLibCatPrint (Str, L"UsbImage");
break;
case USB_CLASS_PRINTER:
- CatPrint (Str, L"UsbPrinter");
+ UefiDevicePathLibCatPrint (Str, L"UsbPrinter");
break;
case USB_CLASS_MASS_STORAGE:
- CatPrint (Str, L"UsbMassStorage");
+ UefiDevicePathLibCatPrint (Str, L"UsbMassStorage");
break;
case USB_CLASS_HUB:
- CatPrint (Str, L"UsbHub");
+ UefiDevicePathLibCatPrint (Str, L"UsbHub");
break;
case USB_CLASS_CDCDATA:
- CatPrint (Str, L"UsbCDCData");
+ UefiDevicePathLibCatPrint (Str, L"UsbCDCData");
break;
case USB_CLASS_SMART_CARD:
- CatPrint (Str, L"UsbSmartCard");
+ UefiDevicePathLibCatPrint (Str, L"UsbSmartCard");
break;
case USB_CLASS_VIDEO:
- CatPrint (Str, L"UsbVideo");
+ UefiDevicePathLibCatPrint (Str, L"UsbVideo");
break;
case USB_CLASS_DIAGNOSTIC:
- CatPrint (Str, L"UsbDiagnostic");
+ UefiDevicePathLibCatPrint (Str, L"UsbDiagnostic");
break;
case USB_CLASS_WIRELESS:
- CatPrint (Str, L"UsbWireless");
+ UefiDevicePathLibCatPrint (Str, L"UsbWireless");
break;
default:
@@ -936,7 +913,7 @@ DevPathToTextUsbClass (
}
if (IsKnownSubClass) {
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"(0x%x,0x%x,0x%x,0x%x)",
UsbClass->VendorId,
@@ -949,7 +926,7 @@ DevPathToTextUsbClass (
if (UsbClass->DeviceClass == USB_CLASS_RESERVE) {
if (UsbClass->DeviceSubClass == USB_SUBCLASS_FW_UPDATE) {
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"UsbDeviceFirmwareUpdate(0x%x,0x%x,0x%x)",
UsbClass->VendorId,
@@ -958,7 +935,7 @@ DevPathToTextUsbClass (
);
return;
} else if (UsbClass->DeviceSubClass == USB_SUBCLASS_IRDA_BRIDGE) {
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"UsbIrdaBridge(0x%x,0x%x,0x%x)",
UsbClass->VendorId,
@@ -967,7 +944,7 @@ DevPathToTextUsbClass (
);
return;
} else if (UsbClass->DeviceSubClass == USB_SUBCLASS_TEST) {
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"UsbTestAndMeasurement(0x%x,0x%x,0x%x)",
UsbClass->VendorId,
@@ -978,7 +955,7 @@ DevPathToTextUsbClass (
}
}
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"UsbClass(0x%x,0x%x,0x%x,0x%x,0x%x)",
UsbClass->VendorId,
@@ -1014,14 +991,14 @@ DevPathToTextSata (
Sata = DevPath;
if ((Sata->PortMultiplierPortNumber & SATA_HBA_DIRECT_CONNECT_FLAG) != 0) {
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"Sata(0x%x,0x%x)",
Sata->HBAPortNumber,
Sata->Lun
);
} else {
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"Sata(0x%x,0x%x,0x%x)",
Sata->HBAPortNumber,
@@ -1055,7 +1032,7 @@ DevPathToTextI2O (
I2O_DEVICE_PATH *I2ODevPath;
I2ODevPath = DevPath;
- CatPrint (Str, L"I2O(0x%x)", I2ODevPath->Tid);
+ UefiDevicePathLibCatPrint (Str, L"I2O(0x%x)", I2ODevPath->Tid);
}
/**
@@ -1090,13 +1067,13 @@ DevPathToTextMacAddr (
HwAddressSize = 6;
}
- CatPrint (Str, L"MAC(");
+ UefiDevicePathLibCatPrint (Str, L"MAC(");
for (Index = 0; Index < HwAddressSize; Index++) {
- CatPrint (Str, L"%02x", MacDevPath->MacAddress.Addr[Index]);
+ UefiDevicePathLibCatPrint (Str, L"%02x", MacDevPath->MacAddress.Addr[Index]);
}
- CatPrint (Str, L",0x%x)", MacDevPath->IfType);
+ UefiDevicePathLibCatPrint (Str, L",0x%x)", MacDevPath->IfType);
}
/**
@@ -1113,15 +1090,55 @@ CatNetworkProtocol (
)
{
if (Protocol == RFC_1700_TCP_PROTOCOL) {
- CatPrint (Str, L"TCP");
+ UefiDevicePathLibCatPrint (Str, L"TCP");
} else if (Protocol == RFC_1700_UDP_PROTOCOL) {
- CatPrint (Str, L"UDP");
+ UefiDevicePathLibCatPrint (Str, L"UDP");
} else {
- CatPrint (Str, L"0x%x", Protocol);
+ UefiDevicePathLibCatPrint (Str, L"0x%x", Protocol);
}
}
/**
+ Converts IP v4 address to its text representation.
+
+ @param Str The string representative of input device.
+ @param Address The IP v4 address.
+**/
+VOID
+CatIPv4Address (
+ IN OUT POOL_PRINT *Str,
+ IN EFI_IPv4_ADDRESS *Address
+ )
+{
+ UefiDevicePathLibCatPrint (Str, L"%d.%d.%d.%d", Address->Addr[0], Address->Addr[1], Address->Addr[2], Address->Addr[3]);
+}
+
+/**
+ Converts IP v6 address to its text representation.
+
+ @param Str The string representative of input device.
+ @param Address The IP v6 address.
+**/
+VOID
+CatIPv6Address (
+ IN OUT POOL_PRINT *Str,
+ IN EFI_IPv6_ADDRESS *Address
+ )
+{
+ UefiDevicePathLibCatPrint (
+ Str, L"%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
+ Address->Addr[0], Address->Addr[1],
+ Address->Addr[2], Address->Addr[3],
+ Address->Addr[4], Address->Addr[5],
+ Address->Addr[6], Address->Addr[7],
+ Address->Addr[8], Address->Addr[9],
+ Address->Addr[10], Address->Addr[11],
+ Address->Addr[12], Address->Addr[13],
+ Address->Addr[14], Address->Addr[15]
+ );
+}
+
+/**
Converts a IPv4 device path structure to its string representative.
@param Str The string representative of input device.
@@ -1145,56 +1162,26 @@ DevPathToTextIPv4 (
IPv4_DEVICE_PATH *IPDevPath;
IPDevPath = DevPath;
+ UefiDevicePathLibCatPrint (Str, L"IPv4(");
+ CatIPv4Address (Str, &IPDevPath->RemoteIpAddress);
+
if (DisplayOnly) {
- CatPrint (
- Str,
- L"IPv4(%d.%d.%d.%d)",
- IPDevPath->RemoteIpAddress.Addr[0],
- IPDevPath->RemoteIpAddress.Addr[1],
- IPDevPath->RemoteIpAddress.Addr[2],
- IPDevPath->RemoteIpAddress.Addr[3]
- );
+ UefiDevicePathLibCatPrint (Str, L")");
return ;
}
- CatPrint (
- Str,
- L"IPv4(%d.%d.%d.%d,",
- IPDevPath->RemoteIpAddress.Addr[0],
- IPDevPath->RemoteIpAddress.Addr[1],
- IPDevPath->RemoteIpAddress.Addr[2],
- IPDevPath->RemoteIpAddress.Addr[3]
- );
+ UefiDevicePathLibCatPrint (Str, L",");
+ CatNetworkProtocol (Str, IPDevPath->Protocol);
- CatNetworkProtocol (
- Str,
- IPDevPath->Protocol
- );
-
- CatPrint (
- Str,
- L",%s,%d.%d.%d.%d",
- IPDevPath->StaticIpAddress ? L"Static" : L"DHCP",
- IPDevPath->LocalIpAddress.Addr[0],
- IPDevPath->LocalIpAddress.Addr[1],
- IPDevPath->LocalIpAddress.Addr[2],
- IPDevPath->LocalIpAddress.Addr[3]
- );
+ UefiDevicePathLibCatPrint (Str, L",%s,", IPDevPath->StaticIpAddress ? L"Static" : L"DHCP");
+ CatIPv4Address (Str, &IPDevPath->LocalIpAddress);
if (DevicePathNodeLength (IPDevPath) == sizeof (IPv4_DEVICE_PATH)) {
- CatPrint (
- Str,
- L",%d.%d.%d.%d,%d.%d.%d.%d",
- IPDevPath->GatewayIpAddress.Addr[0],
- IPDevPath->GatewayIpAddress.Addr[1],
- IPDevPath->GatewayIpAddress.Addr[2],
- IPDevPath->GatewayIpAddress.Addr[3],
- IPDevPath->SubnetMask.Addr[0],
- IPDevPath->SubnetMask.Addr[1],
- IPDevPath->SubnetMask.Addr[2],
- IPDevPath->SubnetMask.Addr[3]
- );
+ UefiDevicePathLibCatPrint (Str, L",");
+ CatIPv4Address (Str, &IPDevPath->GatewayIpAddress);
+ UefiDevicePathLibCatPrint (Str, L",");
+ CatIPv4Address (Str, &IPDevPath->SubnetMask);
}
- CatPrint (Str, L")");
+ UefiDevicePathLibCatPrint (Str, L")");
}
/**
@@ -1221,113 +1208,35 @@ DevPathToTextIPv6 (
IPv6_DEVICE_PATH *IPDevPath;
IPDevPath = DevPath;
+ UefiDevicePathLibCatPrint (Str, L"IPv6(");
+ CatIPv6Address (Str, &IPDevPath->RemoteIpAddress);
if (DisplayOnly) {
- CatPrint (
- Str,
- L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x)",
- IPDevPath->RemoteIpAddress.Addr[0],
- IPDevPath->RemoteIpAddress.Addr[1],
- IPDevPath->RemoteIpAddress.Addr[2],
- IPDevPath->RemoteIpAddress.Addr[3],
- IPDevPath->RemoteIpAddress.Addr[4],
- IPDevPath->RemoteIpAddress.Addr[5],
- IPDevPath->RemoteIpAddress.Addr[6],
- IPDevPath->RemoteIpAddress.Addr[7],
- IPDevPath->RemoteIpAddress.Addr[8],
- IPDevPath->RemoteIpAddress.Addr[9],
- IPDevPath->RemoteIpAddress.Addr[10],
- IPDevPath->RemoteIpAddress.Addr[11],
- IPDevPath->RemoteIpAddress.Addr[12],
- IPDevPath->RemoteIpAddress.Addr[13],
- IPDevPath->RemoteIpAddress.Addr[14],
- IPDevPath->RemoteIpAddress.Addr[15]
- );
+ UefiDevicePathLibCatPrint (Str, L")");
return ;
}
-
- CatPrint (
- Str,
- L"IPv6(%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x,",
- IPDevPath->RemoteIpAddress.Addr[0],
- IPDevPath->RemoteIpAddress.Addr[1],
- IPDevPath->RemoteIpAddress.Addr[2],
- IPDevPath->RemoteIpAddress.Addr[3],
- IPDevPath->RemoteIpAddress.Addr[4],
- IPDevPath->RemoteIpAddress.Addr[5],
- IPDevPath->RemoteIpAddress.Addr[6],
- IPDevPath->RemoteIpAddress.Addr[7],
- IPDevPath->RemoteIpAddress.Addr[8],
- IPDevPath->RemoteIpAddress.Addr[9],
- IPDevPath->RemoteIpAddress.Addr[10],
- IPDevPath->RemoteIpAddress.Addr[11],
- IPDevPath->RemoteIpAddress.Addr[12],
- IPDevPath->RemoteIpAddress.Addr[13],
- IPDevPath->RemoteIpAddress.Addr[14],
- IPDevPath->RemoteIpAddress.Addr[15]
- );
-
- CatNetworkProtocol (
- Str,
- IPDevPath->Protocol
- );
+
+ UefiDevicePathLibCatPrint (Str, L",");
+ CatNetworkProtocol (Str, IPDevPath->Protocol);
switch (IPDevPath->IpAddressOrigin) {
case 0:
- CatPrint (Str, L",Static");
+ UefiDevicePathLibCatPrint (Str, L",Static,");
break;
case 1:
- CatPrint (Str, L",StatelessAutoConfigure");
+ UefiDevicePathLibCatPrint (Str, L",StatelessAutoConfigure,");
break;
default:
- CatPrint (Str, L",StatefulAutoConfigure");
+ UefiDevicePathLibCatPrint (Str, L",StatefulAutoConfigure,");
break;
}
- CatPrint (
- Str,
- L",%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
- IPDevPath->LocalIpAddress.Addr[0],
- IPDevPath->LocalIpAddress.Addr[1],
- IPDevPath->LocalIpAddress.Addr[2],
- IPDevPath->LocalIpAddress.Addr[3],
- IPDevPath->LocalIpAddress.Addr[4],
- IPDevPath->LocalIpAddress.Addr[5],
- IPDevPath->LocalIpAddress.Addr[6],
- IPDevPath->LocalIpAddress.Addr[7],
- IPDevPath->LocalIpAddress.Addr[8],
- IPDevPath->LocalIpAddress.Addr[9],
- IPDevPath->LocalIpAddress.Addr[10],
- IPDevPath->LocalIpAddress.Addr[11],
- IPDevPath->LocalIpAddress.Addr[12],
- IPDevPath->LocalIpAddress.Addr[13],
- IPDevPath->LocalIpAddress.Addr[14],
- IPDevPath->LocalIpAddress.Addr[15]
- );
+ CatIPv6Address (Str, &IPDevPath->LocalIpAddress);
if (DevicePathNodeLength (IPDevPath) == sizeof (IPv6_DEVICE_PATH)) {
- CatPrint (
- Str,
- L",0x%x,%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
- IPDevPath->PrefixLength,
- IPDevPath->GatewayIpAddress.Addr[0],
- IPDevPath->GatewayIpAddress.Addr[1],
- IPDevPath->GatewayIpAddress.Addr[2],
- IPDevPath->GatewayIpAddress.Addr[3],
- IPDevPath->GatewayIpAddress.Addr[4],
- IPDevPath->GatewayIpAddress.Addr[5],
- IPDevPath->GatewayIpAddress.Addr[6],
- IPDevPath->GatewayIpAddress.Addr[7],
- IPDevPath->GatewayIpAddress.Addr[8],
- IPDevPath->GatewayIpAddress.Addr[9],
- IPDevPath->GatewayIpAddress.Addr[10],
- IPDevPath->GatewayIpAddress.Addr[11],
- IPDevPath->GatewayIpAddress.Addr[12],
- IPDevPath->GatewayIpAddress.Addr[13],
- IPDevPath->GatewayIpAddress.Addr[14],
- IPDevPath->GatewayIpAddress.Addr[15]
- );
+ UefiDevicePathLibCatPrint (Str, L",0x%x,", IPDevPath->PrefixLength);
+ CatIPv6Address (Str, &IPDevPath->GatewayIpAddress);
}
- CatPrint (Str, L")");
+ UefiDevicePathLibCatPrint (Str, L")");
}
/**
@@ -1354,7 +1263,7 @@ DevPathToTextInfiniBand (
INFINIBAND_DEVICE_PATH *InfiniBand;
InfiniBand = DevPath;
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"Infiniband(0x%x,%g,0x%lx,0x%lx,0x%lx)",
InfiniBand->ResourceFlags,
@@ -1421,38 +1330,38 @@ DevPathToTextUart (
}
if (Uart->BaudRate == 0) {
- CatPrint (Str, L"Uart(DEFAULT,");
+ UefiDevicePathLibCatPrint (Str, L"Uart(DEFAULT,");
} else {
- CatPrint (Str, L"Uart(%ld,", Uart->BaudRate);
+ UefiDevicePathLibCatPrint (Str, L"Uart(%ld,", Uart->BaudRate);
}
if (Uart->DataBits == 0) {
- CatPrint (Str, L"DEFAULT,");
+ UefiDevicePathLibCatPrint (Str, L"DEFAULT,");
} else {
- CatPrint (Str, L"%d,", Uart->DataBits);
+ UefiDevicePathLibCatPrint (Str, L"%d,", Uart->DataBits);
}
- CatPrint (Str, L"%c,", Parity);
+ UefiDevicePathLibCatPrint (Str, L"%c,", Parity);
switch (Uart->StopBits) {
case 0:
- CatPrint (Str, L"D)");
+ UefiDevicePathLibCatPrint (Str, L"D)");
break;
case 1:
- CatPrint (Str, L"1)");
+ UefiDevicePathLibCatPrint (Str, L"1)");
break;
case 2:
- CatPrint (Str, L"1.5)");
+ UefiDevicePathLibCatPrint (Str, L"1.5)");
break;
case 3:
- CatPrint (Str, L"2)");
+ UefiDevicePathLibCatPrint (Str, L"2)");
break;
default:
- CatPrint (Str, L"x)");
+ UefiDevicePathLibCatPrint (Str, L"x)");
break;
}
}
@@ -1482,7 +1391,7 @@ DevPathToTextiSCSI (
UINT16 Options;
ISCSIDevPath = DevPath;
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"iSCSI(%a,0x%x,0x%lx,",
ISCSIDevPath->TargetName,
@@ -1491,18 +1400,18 @@ DevPathToTextiSCSI (
);
Options = ISCSIDevPath->LoginOption;
- CatPrint (Str, L"%s,", (((Options >> 1) & 0x0001) != 0) ? L"CRC32C" : L"None");
- CatPrint (Str, L"%s,", (((Options >> 3) & 0x0001) != 0) ? L"CRC32C" : L"None");
+ UefiDevicePathLibCatPrint (Str, L"%s,", (((Options >> 1) & 0x0001) != 0) ? L"CRC32C" : L"None");
+ UefiDevicePathLibCatPrint (Str, L"%s,", (((Options >> 3) & 0x0001) != 0) ? L"CRC32C" : L"None");
if (((Options >> 11) & 0x0001) != 0) {
- CatPrint (Str, L"%s,", L"None");
+ UefiDevicePathLibCatPrint (Str, L"%s,", L"None");
} else if (((Options >> 12) & 0x0001) != 0) {
- CatPrint (Str, L"%s,", L"CHAP_UNI");
+ UefiDevicePathLibCatPrint (Str, L"%s,", L"CHAP_UNI");
} else {
- CatPrint (Str, L"%s,", L"CHAP_BI");
+ UefiDevicePathLibCatPrint (Str, L"%s,", L"CHAP_BI");
}
- CatPrint (Str, L"%s)", (ISCSIDevPath->NetworkProtocol == 0) ? L"TCP" : L"reserved");
+ UefiDevicePathLibCatPrint (Str, L"%s)", (ISCSIDevPath->NetworkProtocol == 0) ? L"TCP" : L"reserved");
}
/**
@@ -1529,7 +1438,7 @@ DevPathToTextVlan (
VLAN_DEVICE_PATH *Vlan;
Vlan = DevPath;
- CatPrint (Str, L"Vlan(%d)", Vlan->VlanId);
+ UefiDevicePathLibCatPrint (Str, L"Vlan(%d)", Vlan->VlanId);
}
/**
@@ -1558,7 +1467,7 @@ DevPathToTextHardDrive (
Hd = DevPath;
switch (Hd->SignatureType) {
case SIGNATURE_TYPE_MBR:
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"HD(%d,%s,0x%08x,",
Hd->PartitionNumber,
@@ -1568,7 +1477,7 @@ DevPathToTextHardDrive (
break;
case SIGNATURE_TYPE_GUID:
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"HD(%d,%s,%g,",
Hd->PartitionNumber,
@@ -1578,7 +1487,7 @@ DevPathToTextHardDrive (
break;
default:
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"HD(%d,%d,0,",
Hd->PartitionNumber,
@@ -1587,7 +1496,7 @@ DevPathToTextHardDrive (
break;
}
- CatPrint (Str, L"0x%lx,0x%lx)", Hd->PartitionStart, Hd->PartitionSize);
+ UefiDevicePathLibCatPrint (Str, L"0x%lx,0x%lx)", Hd->PartitionStart, Hd->PartitionSize);
}
/**
@@ -1615,11 +1524,11 @@ DevPathToTextCDROM (
Cd = DevPath;
if (DisplayOnly) {
- CatPrint (Str, L"CDROM(0x%x)", Cd->BootEntry);
+ UefiDevicePathLibCatPrint (Str, L"CDROM(0x%x)", Cd->BootEntry);
return ;
}
- CatPrint (Str, L"CDROM(0x%x,0x%lx,0x%lx)", Cd->BootEntry, Cd->PartitionStart, Cd->PartitionSize);
+ UefiDevicePathLibCatPrint (Str, L"CDROM(0x%x,0x%lx,0x%lx)", Cd->BootEntry, Cd->PartitionStart, Cd->PartitionSize);
}
/**
@@ -1646,7 +1555,7 @@ DevPathToTextFilePath (
FILEPATH_DEVICE_PATH *Fp;
Fp = DevPath;
- CatPrint (Str, L"%s", Fp->PathName);
+ UefiDevicePathLibCatPrint (Str, L"%s", Fp->PathName);
}
/**
@@ -1673,7 +1582,7 @@ DevPathToTextMediaProtocol (
MEDIA_PROTOCOL_DEVICE_PATH *MediaProt;
MediaProt = DevPath;
- CatPrint (Str, L"Media(%g)", &MediaProt->Protocol);
+ UefiDevicePathLibCatPrint (Str, L"Media(%g)", &MediaProt->Protocol);
}
/**
@@ -1700,7 +1609,7 @@ DevPathToTextFv (
MEDIA_FW_VOL_DEVICE_PATH *Fv;
Fv = DevPath;
- CatPrint (Str, L"Fv(%g)", &Fv->FvName);
+ UefiDevicePathLibCatPrint (Str, L"Fv(%g)", &Fv->FvName);
}
/**
@@ -1727,7 +1636,7 @@ DevPathToTextFvFile (
MEDIA_FW_VOL_FILEPATH_DEVICE_PATH *FvFile;
FvFile = DevPath;
- CatPrint (Str, L"FvFile(%g)", &FvFile->FvFileName);
+ UefiDevicePathLibCatPrint (Str, L"FvFile(%g)", &FvFile->FvFileName);
}
/**
@@ -1754,7 +1663,7 @@ DevPathRelativeOffsetRange (
MEDIA_RELATIVE_OFFSET_RANGE_DEVICE_PATH *Offset;
Offset = DevPath;
- CatPrint (
+ UefiDevicePathLibCatPrint (
Str,
L"Offset(0x%lx,0x%lx)",
Offset->StartingOffset,
@@ -1818,17 +1727,17 @@ DevPathToTextBBS (
}
if (Type != NULL) {
- CatPrint (Str, L"BBS(%s,%a", Type, Bbs->String);
+ UefiDevicePathLibCatPrint (Str, L"BBS(%s,%a", Type, Bbs->String);
} else {
- CatPrint (Str, L"BBS(0x%x,%a", Bbs->DeviceType, Bbs->String);
+ UefiDevicePathLibCatPrint (Str, L"BBS(0x%x,%a", Bbs->DeviceType, Bbs->String);
}
if (DisplayOnly) {
- CatPrint (Str, L")");
+ UefiDevicePathLibCatPrint (Str, L")");
return ;
}
- CatPrint (Str, L",0x%x)", Bbs->StatusFlag);
+ UefiDevicePathLibCatPrint (Str, L",0x%x)", Bbs->StatusFlag);
}
/**
@@ -1852,7 +1761,7 @@ DevPathToTextEndInstance (
IN BOOLEAN AllowShortcuts
)
{
- CatPrint (Str, L",");
+ UefiDevicePathLibCatPrint (Str, L",");
}
/**
@@ -1876,48 +1785,48 @@ DevPathToTextNodeUnknown (
IN BOOLEAN AllowShortcuts
)
{
- CatPrint (Str, L"?");
+ UefiDevicePathLibCatPrint (Str, L"?");
}
-GLOBAL_REMOVE_IF_UNREFERENCED const DEVICE_PATH_TO_TEXT_TABLE DevPathToTextTable[] = {
- {HARDWARE_DEVICE_PATH, HW_PCI_DP, DevPathToTextPci},
- {HARDWARE_DEVICE_PATH, HW_PCCARD_DP, DevPathToTextPccard},
- {HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, DevPathToTextMemMap},
- {HARDWARE_DEVICE_PATH, HW_VENDOR_DP, DevPathToTextVendor},
- {HARDWARE_DEVICE_PATH, HW_CONTROLLER_DP, DevPathToTextController},
- {ACPI_DEVICE_PATH, ACPI_DP, DevPathToTextAcpi},
- {ACPI_DEVICE_PATH, ACPI_EXTENDED_DP, DevPathToTextAcpiEx},
- {ACPI_DEVICE_PATH, ACPI_ADR_DP, DevPathToTextAcpiAdr},
- {MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, DevPathToTextAtapi},
- {MESSAGING_DEVICE_PATH, MSG_SCSI_DP, DevPathToTextScsi},
- {MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP, DevPathToTextFibre},
- {MESSAGING_DEVICE_PATH, MSG_FIBRECHANNELEX_DP, DevPathToTextFibreEx},
- {MESSAGING_DEVICE_PATH, MSG_SASEX_DP, DevPathToTextSasEx},
- {MESSAGING_DEVICE_PATH, MSG_1394_DP, DevPathToText1394},
- {MESSAGING_DEVICE_PATH, MSG_USB_DP, DevPathToTextUsb},
- {MESSAGING_DEVICE_PATH, MSG_USB_WWID_DP, DevPathToTextUsbWWID},
- {MESSAGING_DEVICE_PATH, MSG_DEVICE_LOGICAL_UNIT_DP, DevPathToTextLogicalUnit},
- {MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP, DevPathToTextUsbClass},
- {MESSAGING_DEVICE_PATH, MSG_SATA_DP, DevPathToTextSata},
- {MESSAGING_DEVICE_PATH, MSG_I2O_DP, DevPathToTextI2O},
- {MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, DevPathToTextMacAddr},
- {MESSAGING_DEVICE_PATH, MSG_IPv4_DP, DevPathToTextIPv4},
- {MESSAGING_DEVICE_PATH, MSG_IPv6_DP, DevPathToTextIPv6},
- {MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP, DevPathToTextInfiniBand},
- {MESSAGING_DEVICE_PATH, MSG_UART_DP, DevPathToTextUart},
- {MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, DevPathToTextVendor},
- {MESSAGING_DEVICE_PATH, MSG_ISCSI_DP, DevPathToTextiSCSI},
- {MESSAGING_DEVICE_PATH, MSG_VLAN_DP, DevPathToTextVlan},
- {MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, DevPathToTextHardDrive},
- {MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, DevPathToTextCDROM},
- {MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, DevPathToTextVendor},
- {MEDIA_DEVICE_PATH, MEDIA_PROTOCOL_DP, DevPathToTextMediaProtocol},
- {MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, DevPathToTextFilePath},
- {MEDIA_DEVICE_PATH, MEDIA_PIWG_FW_VOL_DP, DevPathToTextFv},
- {MEDIA_DEVICE_PATH, MEDIA_PIWG_FW_FILE_DP, DevPathToTextFvFile},
- {MEDIA_DEVICE_PATH, MEDIA_RELATIVE_OFFSET_RANGE_DP, DevPathRelativeOffsetRange},
- {BBS_DEVICE_PATH, BBS_BBS_DP, DevPathToTextBBS},
- {END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE, DevPathToTextEndInstance},
+GLOBAL_REMOVE_IF_UNREFERENCED const DEVICE_PATH_TO_TEXT_TABLE mUefiDevicePathLibDevPathToTextTable[] = {
+ {HARDWARE_DEVICE_PATH, HW_PCI_DP, DevPathToTextPci },
+ {HARDWARE_DEVICE_PATH, HW_PCCARD_DP, DevPathToTextPccard },
+ {HARDWARE_DEVICE_PATH, HW_MEMMAP_DP, DevPathToTextMemMap },
+ {HARDWARE_DEVICE_PATH, HW_VENDOR_DP, DevPathToTextVendor },
+ {HARDWARE_DEVICE_PATH, HW_CONTROLLER_DP, DevPathToTextController },
+ {ACPI_DEVICE_PATH, ACPI_DP, DevPathToTextAcpi },
+ {ACPI_DEVICE_PATH, ACPI_EXTENDED_DP, DevPathToTextAcpiEx },
+ {ACPI_DEVICE_PATH, ACPI_ADR_DP, DevPathToTextAcpiAdr },
+ {MESSAGING_DEVICE_PATH, MSG_ATAPI_DP, DevPathToTextAtapi },
+ {MESSAGING_DEVICE_PATH, MSG_SCSI_DP, DevPathToTextScsi },
+ {MESSAGING_DEVICE_PATH, MSG_FIBRECHANNEL_DP, DevPathToTextFibre },
+ {MESSAGING_DEVICE_PATH, MSG_FIBRECHANNELEX_DP, DevPathToTextFibreEx },
+ {MESSAGING_DEVICE_PATH, MSG_SASEX_DP, DevPathToTextSasEx },
+ {MESSAGING_DEVICE_PATH, MSG_1394_DP, DevPathToText1394 },
+ {MESSAGING_DEVICE_PATH, MSG_USB_DP, DevPathToTextUsb },
+ {MESSAGING_DEVICE_PATH, MSG_USB_WWID_DP, DevPathToTextUsbWWID },
+ {MESSAGING_DEVICE_PATH, MSG_DEVICE_LOGICAL_UNIT_DP, DevPathToTextLogicalUnit },
+ {MESSAGING_DEVICE_PATH, MSG_USB_CLASS_DP, DevPathToTextUsbClass },
+ {MESSAGING_DEVICE_PATH, MSG_SATA_DP, DevPathToTextSata },
+ {MESSAGING_DEVICE_PATH, MSG_I2O_DP, DevPathToTextI2O },
+ {MESSAGING_DEVICE_PATH, MSG_MAC_ADDR_DP, DevPathToTextMacAddr },
+ {MESSAGING_DEVICE_PATH, MSG_IPv4_DP, DevPathToTextIPv4 },
+ {MESSAGING_DEVICE_PATH, MSG_IPv6_DP, DevPathToTextIPv6 },
+ {MESSAGING_DEVICE_PATH, MSG_INFINIBAND_DP, DevPathToTextInfiniBand },
+ {MESSAGING_DEVICE_PATH, MSG_UART_DP, DevPathToTextUart },
+ {MESSAGING_DEVICE_PATH, MSG_VENDOR_DP, DevPathToTextVendor },
+ {MESSAGING_DEVICE_PATH, MSG_ISCSI_DP, DevPathToTextiSCSI },
+ {MESSAGING_DEVICE_PATH, MSG_VLAN_DP, DevPathToTextVlan },
+ {MEDIA_DEVICE_PATH, MEDIA_HARDDRIVE_DP, DevPathToTextHardDrive },
+ {MEDIA_DEVICE_PATH, MEDIA_CDROM_DP, DevPathToTextCDROM },
+ {MEDIA_DEVICE_PATH, MEDIA_VENDOR_DP, DevPathToTextVendor },
+ {MEDIA_DEVICE_PATH, MEDIA_PROTOCOL_DP, DevPathToTextMediaProtocol },
+ {MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, DevPathToTextFilePath },
+ {MEDIA_DEVICE_PATH, MEDIA_PIWG_FW_VOL_DP, DevPathToTextFv },
+ {MEDIA_DEVICE_PATH, MEDIA_PIWG_FW_FILE_DP, DevPathToTextFvFile },
+ {MEDIA_DEVICE_PATH, MEDIA_RELATIVE_OFFSET_RANGE_DP, DevPathRelativeOffsetRange },
+ {BBS_DEVICE_PATH, BBS_BBS_DP, DevPathToTextBBS },
+ {END_DEVICE_PATH_TYPE, END_INSTANCE_DEVICE_PATH_SUBTYPE, DevPathToTextEndInstance },
{0, 0, NULL}
};
@@ -1938,15 +1847,15 @@ GLOBAL_REMOVE_IF_UNREFERENCED const DEVICE_PATH_TO_TEXT_TABLE DevPathToTextTable
**/
CHAR16 *
EFIAPI
-ConvertDeviceNodeToText (
+UefiDevicePathLibConvertDeviceNodeToText (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
IN BOOLEAN DisplayOnly,
IN BOOLEAN AllowShortcuts
)
{
- POOL_PRINT Str;
- UINTN Index;
- VOID (*DumpNode)(POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);
+ POOL_PRINT Str;
+ UINTN Index;
+ DEVICE_PATH_TO_TEXT ToText;
if (DeviceNode == NULL) {
return NULL;
@@ -1956,27 +1865,22 @@ ConvertDeviceNodeToText (
//
// Process the device path node
+ // If not found, use a generic function
//
- DumpNode = NULL;
- for (Index = 0; DevPathToTextTable[Index].Function != NULL; Index++) {
- if (DevicePathType (DeviceNode) == DevPathToTextTable[Index].Type &&
- DevicePathSubType (DeviceNode) == DevPathToTextTable[Index].SubType
+ ToText = DevPathToTextNodeUnknown;
+ for (Index = 0; mUefiDevicePathLibDevPathToTextTable[Index].Function != NULL; Index++) {
+ if (DevicePathType (DeviceNode) == mUefiDevicePathLibDevPathToTextTable[Index].Type &&
+ DevicePathSubType (DeviceNode) == mUefiDevicePathLibDevPathToTextTable[Index].SubType
) {
- DumpNode = DevPathToTextTable[Index].Function;
+ ToText = mUefiDevicePathLibDevPathToTextTable[Index].Function;
break;
}
}
- //
- // If not found, use a generic function
- //
- if (DumpNode == NULL) {
- DumpNode = DevPathToTextNodeUnknown;
- }
//
// Print this node
//
- DumpNode (&Str, (VOID *) DeviceNode, DisplayOnly, AllowShortcuts);
+ ToText (&Str, (VOID *) DeviceNode, DisplayOnly, AllowShortcuts);
ASSERT (Str.Str != NULL);
return Str.Str;
@@ -1999,17 +1903,17 @@ ConvertDeviceNodeToText (
**/
CHAR16 *
EFIAPI
-ConvertDevicePathToText (
+UefiDevicePathLibConvertDevicePathToText (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
IN BOOLEAN DisplayOnly,
IN BOOLEAN AllowShortcuts
)
{
- POOL_PRINT Str;
- EFI_DEVICE_PATH_PROTOCOL *DevPathNode;
- EFI_DEVICE_PATH_PROTOCOL *AlignedDevPathNode;
- UINTN Index;
- VOID (*DumpNode) (POOL_PRINT *, VOID *, BOOLEAN, BOOLEAN);
+ POOL_PRINT Str;
+ EFI_DEVICE_PATH_PROTOCOL *Node;
+ EFI_DEVICE_PATH_PROTOCOL *AlignedNode;
+ UINTN Index;
+ DEVICE_PATH_TO_TEXT ToText;
if (DevicePath == NULL) {
return NULL;
@@ -2020,47 +1924,42 @@ ConvertDevicePathToText (
//
// Process each device path node
//
- DevPathNode = (EFI_DEVICE_PATH_PROTOCOL *) DevicePath;
- while (!IsDevicePathEnd (DevPathNode)) {
+ Node = (EFI_DEVICE_PATH_PROTOCOL *) DevicePath;
+ while (!IsDevicePathEnd (Node)) {
//
// Find the handler to dump this device path node
+ // If not found, use a generic function
//
- DumpNode = NULL;
- for (Index = 0; DevPathToTextTable[Index].Function != NULL; Index += 1) {
+ ToText = DevPathToTextNodeUnknown;
+ for (Index = 0; mUefiDevicePathLibDevPathToTextTable[Index].Function != NULL; Index += 1) {
- if (DevicePathType (DevPathNode) == DevPathToTextTable[Index].Type &&
- DevicePathSubType (DevPathNode) == DevPathToTextTable[Index].SubType
+ if (DevicePathType (Node) == mUefiDevicePathLibDevPathToTextTable[Index].Type &&
+ DevicePathSubType (Node) == mUefiDevicePathLibDevPathToTextTable[Index].SubType
) {
- DumpNode = DevPathToTextTable[Index].Function;
+ ToText = mUefiDevicePathLibDevPathToTextTable[Index].Function;
break;
}
}
//
- // If not found, use a generic function
- //
- if (!DumpNode) {
- DumpNode = DevPathToTextNodeUnknown;
- }
- //
// Put a path separator in if needed
//
- if ((Str.Length != 0) && (DumpNode != DevPathToTextEndInstance)) {
- if (*(Str.Str + Str.Length / sizeof (CHAR16) - 1) != L',') {
- CatPrint (&Str, L"/");
+ if ((Str.Count != 0) && (ToText != DevPathToTextEndInstance)) {
+ if (Str.Str[Str.Count] != L',') {
+ UefiDevicePathLibCatPrint (&Str, L"/");
}
}
- AlignedDevPathNode = AllocateCopyPool (DevicePathNodeLength (DevPathNode), DevPathNode);
+ AlignedNode = AllocateCopyPool (DevicePathNodeLength (Node), Node);
//
// Print this node of the device path
//
- DumpNode (&Str, AlignedDevPathNode, DisplayOnly, AllowShortcuts);
- FreePool (AlignedDevPathNode);
+ ToText (&Str, AlignedNode, DisplayOnly, AllowShortcuts);
+ FreePool (AlignedNode);
//
// Next device path node
//
- DevPathNode = NextDevicePathNode (DevPathNode);
+ Node = NextDevicePathNode (Node);
}
if (Str.Str == NULL) {
diff --git a/MdePkg/Library/UefiDevicePathLib/DevicePathUtilities.c b/MdePkg/Library/UefiDevicePathLib/DevicePathUtilities.c
new file mode 100644
index 0000000..b48bf02
--- /dev/null
+++ b/MdePkg/Library/UefiDevicePathLib/DevicePathUtilities.c
@@ -0,0 +1,882 @@
+/** @file
+ Device Path services. The thing to remember is device paths are built out of
+ nodes. The device path is terminated by an end node that is length
+ sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL)
+ all over this file.
+
+ The only place where multi-instance device paths are supported is in
+ environment varibles. Multi-instance device paths should never be placed
+ on a Handle.
+
+ Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+#include "UefiDevicePathLib.h"
+
+//
+// Template for an end-of-device path node.
+//
+GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_DEVICE_PATH_PROTOCOL mUefiDevicePathLibEndDevicePath = {
+ END_DEVICE_PATH_TYPE,
+ END_ENTIRE_DEVICE_PATH_SUBTYPE,
+ {
+ END_DEVICE_PATH_LENGTH,
+ 0
+ }
+};
+
+/**
+ Determine whether a given device path is valid.
+ If DevicePath is NULL, then ASSERT().
+
+ @param DevicePath A pointer to a device path data structure.
+ @param MaxSize The maximum size of the device path data structure.
+
+ @retval TRUE DevicePath is valid.
+ @retval FALSE The length of any node node in the DevicePath is less
+ than sizeof (EFI_DEVICE_PATH_PROTOCOL).
+ @retval FALSE If MaxSize is not zero, the size of the DevicePath
+ exceeds MaxSize.
+ @retval FALSE If PcdMaximumDevicePathNodeCount is not zero, the node
+ count of the DevicePath exceeds PcdMaximumDevicePathNodeCount.
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathValid (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN UINTN MaxSize
+ )
+{
+ UINTN Count;
+ UINTN Size;
+ UINTN NodeLength;
+
+ ASSERT (DevicePath != NULL);
+
+ for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {
+ NodeLength = DevicePathNodeLength (DevicePath);
+ if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+ return FALSE;
+ }
+
+ if (MaxSize > 0) {
+ Size += NodeLength;
+ if (Size + END_DEVICE_PATH_LENGTH > MaxSize) {
+ return FALSE;
+ }
+ }
+
+ if (PcdGet32 (PcdMaximumDevicePathNodeCount) > 0) {
+ Count++;
+ if (Count >= PcdGet32 (PcdMaximumDevicePathNodeCount)) {
+ return FALSE;
+ }
+ }
+ }
+
+ //
+ // Only return TRUE when the End Device Path node is valid.
+ //
+ return (BOOLEAN) (DevicePathNodeLength (DevicePath) == END_DEVICE_PATH_LENGTH);
+}
+
+/**
+ Returns the Type field of a device path node.
+
+ Returns the Type field of the device path node specified by Node.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @return The Type field of the device path node specified by Node.
+
+**/
+UINT8
+EFIAPI
+DevicePathType (
+ IN CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Type;
+}
+
+/**
+ Returns the SubType field of a device path node.
+
+ Returns the SubType field of the device path node specified by Node.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @return The SubType field of the device path node specified by Node.
+
+**/
+UINT8
+EFIAPI
+DevicePathSubType (
+ IN CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->SubType;
+}
+
+/**
+ Returns the 16-bit Length field of a device path node.
+
+ Returns the 16-bit Length field of the device path node specified by Node.
+ Node is not required to be aligned on a 16-bit boundary, so it is recommended
+ that a function such as ReadUnaligned16() be used to extract the contents of
+ the Length field.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @return The 16-bit Length field of the device path node specified by Node.
+
+**/
+UINTN
+EFIAPI
+DevicePathNodeLength (
+ IN CONST VOID *Node
+ )
+{
+ UINTN Length;
+
+ ASSERT (Node != NULL);
+ Length = ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]);
+ ASSERT (Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL));
+ return Length;
+}
+
+/**
+ Returns a pointer to the next node in a device path.
+
+ Returns a pointer to the device path node that follows the device path node
+ specified by Node.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @return a pointer to the device path node that follows the device path node
+ specified by Node.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+NextDevicePathNode (
+ IN CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)(Node) + DevicePathNodeLength(Node));
+}
+
+/**
+ Determines if a device path node is an end node of a device path.
+ This includes nodes that are the end of a device path instance and nodes that
+ are the end of an entire device path.
+
+ Determines if the device path node specified by Node is an end node of a device path.
+ This includes nodes that are the end of a device path instance and nodes that are the
+ end of an entire device path. If Node represents an end node of a device path,
+ then TRUE is returned. Otherwise, FALSE is returned.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @retval TRUE The device path node specified by Node is an end node of a
+ device path.
+ @retval FALSE The device path node specified by Node is not an end node of
+ a device path.
+
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathEndType (
+ IN CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return (BOOLEAN) (DevicePathType (Node) == END_DEVICE_PATH_TYPE);
+}
+
+/**
+ Determines if a device path node is an end node of an entire device path.
+
+ Determines if a device path node specified by Node is an end node of an entire
+ device path. If Node represents the end of an entire device path, then TRUE is
+ returned. Otherwise, FALSE is returned.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @retval TRUE The device path node specified by Node is the end of an entire
+ device path.
+ @retval FALSE The device path node specified by Node is not the end of an
+ entire device path.
+
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathEnd (
+ IN CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_ENTIRE_DEVICE_PATH_SUBTYPE);
+}
+
+/**
+ Determines if a device path node is an end node of a device path instance.
+
+ Determines if a device path node specified by Node is an end node of a device
+ path instance. If Node represents the end of a device path instance, then TRUE
+ is returned. Otherwise, FALSE is returned.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+ @retval TRUE The device path node specified by Node is the end of a device
+ path instance.
+ @retval FALSE The device path node specified by Node is not the end of a
+ device path instance.
+
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathEndInstance (
+ IN CONST VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_INSTANCE_DEVICE_PATH_SUBTYPE);
+}
+
+/**
+ Sets the length, in bytes, of a device path node.
+
+ Sets the length of the device path node specified by Node to the value specified
+ by NodeLength. NodeLength is returned. Node is not required to be aligned on
+ a 16-bit boundary, so it is recommended that a function such as WriteUnaligned16()
+ be used to set the contents of the Length field.
+
+ If Node is NULL, then ASSERT().
+ If NodeLength >= SIZE_64KB, then ASSERT().
+ If NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL), then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+ @param Length The length, in bytes, of the device path node.
+
+ @return Length
+
+**/
+UINT16
+EFIAPI
+SetDevicePathNodeLength (
+ IN OUT VOID *Node,
+ IN UINTN Length
+ )
+{
+ ASSERT (Node != NULL);
+ ASSERT ((Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL)) && (Length < SIZE_64KB));
+ return WriteUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0], (UINT16)(Length));
+}
+
+/**
+ Fills in all the fields of a device path node that is the end of an entire device path.
+
+ Fills in all the fields of a device path node specified by Node so Node represents
+ the end of an entire device path. The Type field of Node is set to
+ END_DEVICE_PATH_TYPE, the SubType field of Node is set to
+ END_ENTIRE_DEVICE_PATH_SUBTYPE, and the Length field of Node is set to
+ END_DEVICE_PATH_LENGTH. Node is not required to be aligned on a 16-bit boundary,
+ so it is recommended that a function such as WriteUnaligned16() be used to set
+ the contents of the Length field.
+
+ If Node is NULL, then ASSERT().
+
+ @param Node A pointer to a device path node data structure.
+
+**/
+VOID
+EFIAPI
+SetDevicePathEndNode (
+ OUT VOID *Node
+ )
+{
+ ASSERT (Node != NULL);
+ CopyMem (Node, &mUefiDevicePathLibEndDevicePath, sizeof (mUefiDevicePathLibEndDevicePath));
+}
+
+/**
+ Returns the size of a device path in bytes.
+
+ This function returns the size, in bytes, of the device path data structure
+ specified by DevicePath including the end of device path node.
+ If DevicePath is NULL or invalid, then 0 is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval 0 If DevicePath is NULL or invalid.
+ @retval Others The size of a device path in bytes.
+
+**/
+UINTN
+EFIAPI
+UefiDevicePathLibGetDevicePathSize (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ CONST EFI_DEVICE_PATH_PROTOCOL *Start;
+
+ if (DevicePath == NULL) {
+ return 0;
+ }
+
+ if (!IsDevicePathValid (DevicePath, 0)) {
+ return 0;
+ }
+
+ //
+ // Search for the end of the device path structure
+ //
+ Start = DevicePath;
+ while (!IsDevicePathEnd (DevicePath)) {
+ DevicePath = NextDevicePathNode (DevicePath);
+ }
+
+ //
+ // Compute the size and add back in the size of the end device path structure
+ //
+ return ((UINTN) DevicePath - (UINTN) Start) + DevicePathNodeLength (DevicePath);
+}
+
+/**
+ Creates a new copy of an existing device path.
+
+ This function allocates space for a new copy of the device path specified by DevicePath.
+ If DevicePath is NULL, then NULL is returned. If the memory is successfully
+ allocated, then the contents of DevicePath are copied to the newly allocated
+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval NULL DevicePath is NULL or invalid.
+ @retval Others A pointer to the duplicated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibDuplicateDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ UINTN Size;
+
+ //
+ // Compute the size
+ //
+ Size = GetDevicePathSize (DevicePath);
+ if (Size == 0) {
+ return NULL;
+ }
+
+ //
+ // Allocate space for duplicate device path
+ //
+
+ return AllocateCopyPool (Size, DevicePath);
+}
+
+/**
+ Creates a new device path by appending a second device path to a first device path.
+
+ This function creates a new device path by appending a copy of SecondDevicePath
+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path
+ device node from SecondDevicePath is retained. The newly created device path is
+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored,
+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
+ SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
+
+ If there is not enough memory for the newly allocated buffer, then NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param FirstDevicePath A pointer to a device path data structure.
+ @param SecondDevicePath A pointer to a device path data structure.
+
+ @retval NULL If there is not enough memory for the newly allocated buffer.
+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid.
+ @retval Others A pointer to the new device path if success.
+ Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibAppendDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
+ )
+{
+ UINTN Size;
+ UINTN Size1;
+ UINTN Size2;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath2;
+
+ //
+ // If there's only 1 path, just duplicate it.
+ //
+ if (FirstDevicePath == NULL) {
+ return DuplicateDevicePath ((SecondDevicePath != NULL) ? SecondDevicePath : &mUefiDevicePathLibEndDevicePath);
+ }
+
+ if (SecondDevicePath == NULL) {
+ return DuplicateDevicePath (FirstDevicePath);
+ }
+
+ if (!IsDevicePathValid (FirstDevicePath, 0) || !IsDevicePathValid (SecondDevicePath, 0)) {
+ return NULL;
+ }
+
+ //
+ // Allocate space for the combined device path. It only has one end node of
+ // length EFI_DEVICE_PATH_PROTOCOL.
+ //
+ Size1 = GetDevicePathSize (FirstDevicePath);
+ Size2 = GetDevicePathSize (SecondDevicePath);
+ Size = Size1 + Size2 - END_DEVICE_PATH_LENGTH;
+
+ NewDevicePath = AllocatePool (Size);
+
+ if (NewDevicePath != NULL) {
+ NewDevicePath = CopyMem (NewDevicePath, FirstDevicePath, Size1);
+ //
+ // Over write FirstDevicePath EndNode and do the copy
+ //
+ DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath +
+ (Size1 - END_DEVICE_PATH_LENGTH));
+ CopyMem (DevicePath2, SecondDevicePath, Size2);
+ }
+
+ return NewDevicePath;
+}
+
+/**
+ Creates a new path by appending the device node to the device path.
+
+ This function creates a new device path by appending a copy of the device node
+ specified by DevicePathNode to a copy of the device path specified by DevicePath
+ in an allocated buffer. The end-of-device-path device node is moved after the
+ end of the appended device node.
+ If DevicePathNode is NULL then a copy of DevicePath is returned.
+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
+ path device node is returned.
+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
+ device node is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathNode A pointer to a single device path node.
+
+ @retval NULL If there is not enough memory for the new device path.
+ @retval Others A pointer to the new device path if success.
+ A copy of DevicePathNode followed by an end-of-device-path node
+ if both FirstDevicePath and SecondDevicePath are NULL.
+ A copy of an end-of-device-path node if both FirstDevicePath
+ and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibAppendDevicePathNode (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *NextNode;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ UINTN NodeLength;
+
+ if (DevicePathNode == NULL) {
+ return DuplicateDevicePath ((DevicePath != NULL) ? DevicePath : &mUefiDevicePathLibEndDevicePath);
+ }
+ //
+ // Build a Node that has a terminator on it
+ //
+ NodeLength = DevicePathNodeLength (DevicePathNode);
+
+ TempDevicePath = AllocatePool (NodeLength + END_DEVICE_PATH_LENGTH);
+ if (TempDevicePath == NULL) {
+ return NULL;
+ }
+ TempDevicePath = CopyMem (TempDevicePath, DevicePathNode, NodeLength);
+ //
+ // Add and end device path node to convert Node to device path
+ //
+ NextNode = NextDevicePathNode (TempDevicePath);
+ SetDevicePathEndNode (NextNode);
+ //
+ // Append device paths
+ //
+ NewDevicePath = AppendDevicePath (DevicePath, TempDevicePath);
+
+ FreePool (TempDevicePath);
+
+ return NewDevicePath;
+}
+
+/**
+ Creates a new device path by appending the specified device path instance to the specified device
+ path.
+
+ This function creates a new device path by appending a copy of the device path
+ instance specified by DevicePathInstance to a copy of the device path specified
+ by DevicePath in a allocated buffer.
+ The end-of-device-path device node is moved after the end of the appended device
+ path instance and a new end-of-device-path-instance node is inserted between.
+ If DevicePath is NULL, then a copy if DevicePathInstance is returned.
+ If DevicePathInstance is NULL, then NULL is returned.
+ If DevicePath or DevicePathInstance is invalid, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathInstance A pointer to a device path instance.
+
+ @return A pointer to the new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibAppendDevicePathInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
+ UINTN SrcSize;
+ UINTN InstanceSize;
+
+ if (DevicePath == NULL) {
+ return DuplicateDevicePath (DevicePathInstance);
+ }
+
+ if (DevicePathInstance == NULL) {
+ return NULL;
+ }
+
+ if (!IsDevicePathValid (DevicePath, 0) || !IsDevicePathValid (DevicePathInstance, 0)) {
+ return NULL;
+ }
+
+ SrcSize = GetDevicePathSize (DevicePath);
+ InstanceSize = GetDevicePathSize (DevicePathInstance);
+
+ NewDevicePath = AllocatePool (SrcSize + InstanceSize);
+ if (NewDevicePath != NULL) {
+
+ TempDevicePath = CopyMem (NewDevicePath, DevicePath, SrcSize);;
+
+ while (!IsDevicePathEnd (TempDevicePath)) {
+ TempDevicePath = NextDevicePathNode (TempDevicePath);
+ }
+
+ TempDevicePath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
+ TempDevicePath = NextDevicePathNode (TempDevicePath);
+ CopyMem (TempDevicePath, DevicePathInstance, InstanceSize);
+ }
+
+ return NewDevicePath;
+}
+
+/**
+ Creates a copy of the current device path instance and returns a pointer to the next device path
+ instance.
+
+ This function creates a copy of the current device path instance. It also updates
+ DevicePath to point to the next device path instance in the device path (or NULL
+ if no more) and updates Size to hold the size of the device path instance copy.
+ If DevicePath is NULL, then NULL is returned.
+ If DevicePath points to a invalid device path, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+ If Size is NULL, then ASSERT().
+
+ @param DevicePath On input, this holds the pointer to the current
+ device path instance. On output, this holds
+ the pointer to the next device path instance
+ or NULL if there are no more device path
+ instances in the device path pointer to a
+ device path data structure.
+ @param Size On output, this holds the size of the device
+ path instance, in bytes or zero, if DevicePath
+ is NULL.
+
+ @return A pointer to the current device path instance.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibGetNextDevicePathInstance (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ OUT UINTN *Size
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+ EFI_DEVICE_PATH_PROTOCOL *ReturnValue;
+ UINT8 Temp;
+
+ ASSERT (Size != NULL);
+
+ if (DevicePath == NULL || *DevicePath == NULL) {
+ *Size = 0;
+ return NULL;
+ }
+
+ if (!IsDevicePathValid (*DevicePath, 0)) {
+ return NULL;
+ }
+
+ //
+ // Find the end of the device path instance
+ //
+ DevPath = *DevicePath;
+ while (!IsDevicePathEndType (DevPath)) {
+ DevPath = NextDevicePathNode (DevPath);
+ }
+
+ //
+ // Compute the size of the device path instance
+ //
+ *Size = ((UINTN) DevPath - (UINTN) (*DevicePath)) + sizeof (EFI_DEVICE_PATH_PROTOCOL);
+
+ //
+ // Make a copy and return the device path instance
+ //
+ Temp = DevPath->SubType;
+ DevPath->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
+ ReturnValue = DuplicateDevicePath (*DevicePath);
+ DevPath->SubType = Temp;
+
+ //
+ // If DevPath is the end of an entire device path, then another instance
+ // does not follow, so *DevicePath is set to NULL.
+ //
+ if (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
+ *DevicePath = NULL;
+ } else {
+ *DevicePath = NextDevicePathNode (DevPath);
+ }
+
+ return ReturnValue;
+}
+
+/**
+ Creates a device node.
+
+ This function creates a new device node in a newly allocated buffer of size
+ NodeLength and initializes the device path node header with NodeType and NodeSubType.
+ The new device path node is returned.
+ If NodeLength is smaller than a device path header, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param NodeType The device node type for the new device node.
+ @param NodeSubType The device node sub-type for the new device node.
+ @param NodeLength The length of the new device node.
+
+ @return The new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+UefiDevicePathLibCreateDeviceNode (
+ IN UINT8 NodeType,
+ IN UINT8 NodeSubType,
+ IN UINT16 NodeLength
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+
+ if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+ //
+ // NodeLength is less than the size of the header.
+ //
+ return NULL;
+ }
+
+ DevicePath = AllocateZeroPool (NodeLength);
+ if (DevicePath != NULL) {
+ DevicePath->Type = NodeType;
+ DevicePath->SubType = NodeSubType;
+ SetDevicePathNodeLength (DevicePath, NodeLength);
+ }
+
+ return DevicePath;
+}
+
+/**
+ Determines if a device path is single or multi-instance.
+
+ This function returns TRUE if the device path specified by DevicePath is
+ multi-instance.
+ Otherwise, FALSE is returned.
+ If DevicePath is NULL or invalid, then FALSE is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval TRUE DevicePath is multi-instance.
+ @retval FALSE DevicePath is not multi-instance, or DevicePath
+ is NULL or invalid.
+
+**/
+BOOLEAN
+EFIAPI
+UefiDevicePathLibIsDevicePathMultiInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ CONST EFI_DEVICE_PATH_PROTOCOL *Node;
+
+ if (DevicePath == NULL) {
+ return FALSE;
+ }
+
+ if (!IsDevicePathValid (DevicePath, 0)) {
+ return FALSE;
+ }
+
+ Node = DevicePath;
+ while (!IsDevicePathEnd (Node)) {
+ if (IsDevicePathEndInstance (Node)) {
+ return TRUE;
+ }
+
+ Node = NextDevicePathNode (Node);
+ }
+
+ return FALSE;
+}
+
+
+/**
+ Retrieves the device path protocol from a handle.
+
+ This function returns the device path protocol from the handle specified by Handle.
+ If Handle is NULL or Handle does not contain a device path protocol, then NULL
+ is returned.
+
+ @param Handle The handle from which to retrieve the device
+ path protocol.
+
+ @return The device path protocol from the handle specified by Handle.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+DevicePathFromHandle (
+ IN EFI_HANDLE Handle
+ )
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_STATUS Status;
+
+ Status = gBS->HandleProtocol (
+ Handle,
+ &gEfiDevicePathProtocolGuid,
+ (VOID *) &DevicePath
+ );
+ if (EFI_ERROR (Status)) {
+ DevicePath = NULL;
+ }
+ return DevicePath;
+}
+
+/**
+ Allocates a device path for a file and appends it to an existing device path.
+
+ If Device is a valid device handle that contains a device path protocol, then a device path for
+ the file specified by FileName is allocated and appended to the device path associated with the
+ handle Device. The allocated device path is returned. If Device is NULL or Device is a handle
+ that does not support the device path protocol, then a device path containing a single device
+ path node for the file specified by FileName is allocated and returned.
+ The memory for the new device path is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ If FileName is NULL, then ASSERT().
+ If FileName is not aligned on a 16-bit boundary, then ASSERT().
+
+ @param Device A pointer to a device handle. This parameter
+ is optional and may be NULL.
+ @param FileName A pointer to a Null-terminated Unicode string.
+
+ @return The allocated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+FileDevicePath (
+ IN EFI_HANDLE Device, OPTIONAL
+ IN CONST CHAR16 *FileName
+ )
+{
+ UINTN Size;
+ FILEPATH_DEVICE_PATH *FilePath;
+ EFI_DEVICE_PATH_PROTOCOL *DevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *FileDevicePath;
+
+ DevicePath = NULL;
+
+ Size = StrSize (FileName);
+ FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH);
+ if (FileDevicePath != NULL) {
+ FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath;
+ FilePath->Header.Type = MEDIA_DEVICE_PATH;
+ FilePath->Header.SubType = MEDIA_FILEPATH_DP;
+ CopyMem (&FilePath->PathName, FileName, Size);
+ SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
+ SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));
+
+ if (Device != NULL) {
+ DevicePath = DevicePathFromHandle (Device);
+ }
+
+ DevicePath = AppendDevicePath (DevicePath, FileDevicePath);
+ FreePool (FileDevicePath);
+ }
+
+ return DevicePath;
+}
+
diff --git a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c
index a91a7a3..baad7bc 100644
--- a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c
+++ b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.c
@@ -8,7 +8,7 @@
environment varibles. Multi-instance device paths should never be placed
on a Handle.
- Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -20,319 +20,7 @@
**/
-#include <Uefi.h>
-
-#include <Library/DevicePathLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/BaseLib.h>
-#include <Library/PcdLib.h>
-
-//
-// Template for an end-of-device path node.
-//
-GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_DEVICE_PATH_PROTOCOL mUefiDevicePathLibEndDevicePath = {
- END_DEVICE_PATH_TYPE,
- END_ENTIRE_DEVICE_PATH_SUBTYPE,
- {
- END_DEVICE_PATH_LENGTH,
- 0
- }
-};
-
-/**
- Determine whether a given device path is valid.
- If DevicePath is NULL, then ASSERT().
-
- @param DevicePath A pointer to a device path data structure.
- @param MaxSize The maximum size of the device path data structure.
-
- @retval TRUE DevicePath is valid.
- @retval FALSE The length of any node node in the DevicePath is less
- than sizeof (EFI_DEVICE_PATH_PROTOCOL).
- @retval FALSE If MaxSize is not zero, the size of the DevicePath
- exceeds MaxSize.
- @retval FALSE If PcdMaximumDevicePathNodeCount is not zero, the node
- count of the DevicePath exceeds PcdMaximumDevicePathNodeCount.
-**/
-BOOLEAN
-EFIAPI
-IsDevicePathValid (
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
- IN UINTN MaxSize
- )
-{
- UINTN Count;
- UINTN Size;
- UINTN NodeLength;
-
- ASSERT (DevicePath != NULL);
-
- for (Count = 0, Size = 0; !IsDevicePathEnd (DevicePath); DevicePath = NextDevicePathNode (DevicePath)) {
- NodeLength = DevicePathNodeLength (DevicePath);
- if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
- return FALSE;
- }
-
- if (MaxSize > 0) {
- Size += NodeLength;
- if (Size + END_DEVICE_PATH_LENGTH > MaxSize) {
- return FALSE;
- }
- }
-
- if (PcdGet32 (PcdMaximumDevicePathNodeCount) > 0) {
- Count++;
- if (Count >= PcdGet32 (PcdMaximumDevicePathNodeCount)) {
- return FALSE;
- }
- }
- }
-
- //
- // Only return TRUE when the End Device Path node is valid.
- //
- return (BOOLEAN) (DevicePathNodeLength (DevicePath) == END_DEVICE_PATH_LENGTH);
-}
-
-/**
- Returns the Type field of a device path node.
-
- Returns the Type field of the device path node specified by Node.
-
- If Node is NULL, then ASSERT().
-
- @param Node A pointer to a device path node data structure.
-
- @return The Type field of the device path node specified by Node.
-
-**/
-UINT8
-EFIAPI
-DevicePathType (
- IN CONST VOID *Node
- )
-{
- ASSERT (Node != NULL);
- return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Type;
-}
-
-/**
- Returns the SubType field of a device path node.
-
- Returns the SubType field of the device path node specified by Node.
-
- If Node is NULL, then ASSERT().
-
- @param Node A pointer to a device path node data structure.
-
- @return The SubType field of the device path node specified by Node.
-
-**/
-UINT8
-EFIAPI
-DevicePathSubType (
- IN CONST VOID *Node
- )
-{
- ASSERT (Node != NULL);
- return ((EFI_DEVICE_PATH_PROTOCOL *)(Node))->SubType;
-}
-
-/**
- Returns the 16-bit Length field of a device path node.
-
- Returns the 16-bit Length field of the device path node specified by Node.
- Node is not required to be aligned on a 16-bit boundary, so it is recommended
- that a function such as ReadUnaligned16() be used to extract the contents of
- the Length field.
-
- If Node is NULL, then ASSERT().
-
- @param Node A pointer to a device path node data structure.
-
- @return The 16-bit Length field of the device path node specified by Node.
-
-**/
-UINTN
-EFIAPI
-DevicePathNodeLength (
- IN CONST VOID *Node
- )
-{
- UINTN Length;
-
- ASSERT (Node != NULL);
- Length = ReadUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0]);
- ASSERT (Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL));
- return Length;
-}
-
-/**
- Returns a pointer to the next node in a device path.
-
- Returns a pointer to the device path node that follows the device path node
- specified by Node.
-
- If Node is NULL, then ASSERT().
-
- @param Node A pointer to a device path node data structure.
-
- @return a pointer to the device path node that follows the device path node
- specified by Node.
-
-**/
-EFI_DEVICE_PATH_PROTOCOL *
-EFIAPI
-NextDevicePathNode (
- IN CONST VOID *Node
- )
-{
- ASSERT (Node != NULL);
- return (EFI_DEVICE_PATH_PROTOCOL *)((UINT8 *)(Node) + DevicePathNodeLength(Node));
-}
-
-/**
- Determines if a device path node is an end node of a device path.
- This includes nodes that are the end of a device path instance and nodes that
- are the end of an entire device path.
-
- Determines if the device path node specified by Node is an end node of a device path.
- This includes nodes that are the end of a device path instance and nodes that are the
- end of an entire device path. If Node represents an end node of a device path,
- then TRUE is returned. Otherwise, FALSE is returned.
-
- If Node is NULL, then ASSERT().
-
- @param Node A pointer to a device path node data structure.
-
- @retval TRUE The device path node specified by Node is an end node of a
- device path.
- @retval FALSE The device path node specified by Node is not an end node of
- a device path.
-
-**/
-BOOLEAN
-EFIAPI
-IsDevicePathEndType (
- IN CONST VOID *Node
- )
-{
- ASSERT (Node != NULL);
- return (BOOLEAN) (DevicePathType (Node) == END_DEVICE_PATH_TYPE);
-}
-
-/**
- Determines if a device path node is an end node of an entire device path.
-
- Determines if a device path node specified by Node is an end node of an entire
- device path. If Node represents the end of an entire device path, then TRUE is
- returned. Otherwise, FALSE is returned.
-
- If Node is NULL, then ASSERT().
-
- @param Node A pointer to a device path node data structure.
-
- @retval TRUE The device path node specified by Node is the end of an entire
- device path.
- @retval FALSE The device path node specified by Node is not the end of an
- entire device path.
-
-**/
-BOOLEAN
-EFIAPI
-IsDevicePathEnd (
- IN CONST VOID *Node
- )
-{
- ASSERT (Node != NULL);
- return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_ENTIRE_DEVICE_PATH_SUBTYPE);
-}
-
-/**
- Determines if a device path node is an end node of a device path instance.
-
- Determines if a device path node specified by Node is an end node of a device
- path instance. If Node represents the end of a device path instance, then TRUE
- is returned. Otherwise, FALSE is returned.
-
- If Node is NULL, then ASSERT().
-
- @param Node A pointer to a device path node data structure.
-
- @retval TRUE The device path node specified by Node is the end of a device
- path instance.
- @retval FALSE The device path node specified by Node is not the end of a
- device path instance.
-
-**/
-BOOLEAN
-EFIAPI
-IsDevicePathEndInstance (
- IN CONST VOID *Node
- )
-{
- ASSERT (Node != NULL);
- return (BOOLEAN) (IsDevicePathEndType (Node) && DevicePathSubType(Node) == END_INSTANCE_DEVICE_PATH_SUBTYPE);
-}
-
-/**
- Sets the length, in bytes, of a device path node.
-
- Sets the length of the device path node specified by Node to the value specified
- by NodeLength. NodeLength is returned. Node is not required to be aligned on
- a 16-bit boundary, so it is recommended that a function such as WriteUnaligned16()
- be used to set the contents of the Length field.
-
- If Node is NULL, then ASSERT().
- If NodeLength >= SIZE_64KB, then ASSERT().
- If NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL), then ASSERT().
-
- @param Node A pointer to a device path node data structure.
- @param Length The length, in bytes, of the device path node.
-
- @return Length
-
-**/
-UINT16
-EFIAPI
-SetDevicePathNodeLength (
- IN OUT VOID *Node,
- IN UINTN Length
- )
-{
- ASSERT (Node != NULL);
- ASSERT ((Length >= sizeof (EFI_DEVICE_PATH_PROTOCOL)) && (Length < SIZE_64KB));
- return WriteUnaligned16 ((UINT16 *)&((EFI_DEVICE_PATH_PROTOCOL *)(Node))->Length[0], (UINT16)(Length));
-}
-
-/**
- Fills in all the fields of a device path node that is the end of an entire device path.
-
- Fills in all the fields of a device path node specified by Node so Node represents
- the end of an entire device path. The Type field of Node is set to
- END_DEVICE_PATH_TYPE, the SubType field of Node is set to
- END_ENTIRE_DEVICE_PATH_SUBTYPE, and the Length field of Node is set to
- END_DEVICE_PATH_LENGTH. Node is not required to be aligned on a 16-bit boundary,
- so it is recommended that a function such as WriteUnaligned16() be used to set
- the contents of the Length field.
-
- If Node is NULL, then ASSERT().
-
- @param Node A pointer to a device path node data structure.
-
-**/
-VOID
-EFIAPI
-SetDevicePathEndNode (
- OUT VOID *Node
- )
-{
- ASSERT (Node != NULL);
- CopyMem (Node, &mUefiDevicePathLibEndDevicePath, sizeof (mUefiDevicePathLibEndDevicePath));
-}
+#include "UefiDevicePathLib.h"
/**
Returns the size of a device path in bytes.
@@ -353,28 +41,7 @@ GetDevicePathSize (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
- CONST EFI_DEVICE_PATH_PROTOCOL *Start;
-
- if (DevicePath == NULL) {
- return 0;
- }
-
- if (!IsDevicePathValid (DevicePath, 0)) {
- return 0;
- }
-
- //
- // Search for the end of the device path structure
- //
- Start = DevicePath;
- while (!IsDevicePathEnd (DevicePath)) {
- DevicePath = NextDevicePathNode (DevicePath);
- }
-
- //
- // Compute the size and add back in the size of the end device path structure
- //
- return ((UINTN) DevicePath - (UINTN) Start) + DevicePathNodeLength (DevicePath);
+ return UefiDevicePathLibGetDevicePathSize (DevicePath);
}
/**
@@ -399,21 +66,7 @@ DuplicateDevicePath (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
- UINTN Size;
-
- //
- // Compute the size
- //
- Size = GetDevicePathSize (DevicePath);
- if (Size == 0) {
- return NULL;
- }
-
- //
- // Allocate space for duplicate device path
- //
-
- return AllocateCopyPool (Size, DevicePath);
+ return UefiDevicePathLibDuplicateDevicePath (DevicePath);
}
/**
@@ -447,48 +100,7 @@ AppendDevicePath (
IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
)
{
- UINTN Size;
- UINTN Size1;
- UINTN Size2;
- EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath2;
-
- //
- // If there's only 1 path, just duplicate it.
- //
- if (FirstDevicePath == NULL) {
- return DuplicateDevicePath ((SecondDevicePath != NULL) ? SecondDevicePath : &mUefiDevicePathLibEndDevicePath);
- }
-
- if (SecondDevicePath == NULL) {
- return DuplicateDevicePath (FirstDevicePath);
- }
-
- if (!IsDevicePathValid (FirstDevicePath, 0) || !IsDevicePathValid (SecondDevicePath, 0)) {
- return NULL;
- }
-
- //
- // Allocate space for the combined device path. It only has one end node of
- // length EFI_DEVICE_PATH_PROTOCOL.
- //
- Size1 = GetDevicePathSize (FirstDevicePath);
- Size2 = GetDevicePathSize (SecondDevicePath);
- Size = Size1 + Size2 - END_DEVICE_PATH_LENGTH;
-
- NewDevicePath = AllocatePool (Size);
-
- if (NewDevicePath != NULL) {
- NewDevicePath = CopyMem (NewDevicePath, FirstDevicePath, Size1);
- //
- // Over write FirstDevicePath EndNode and do the copy
- //
- DevicePath2 = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath +
- (Size1 - END_DEVICE_PATH_LENGTH));
- CopyMem (DevicePath2, SecondDevicePath, Size2);
- }
-
- return NewDevicePath;
+ return UefiDevicePathLibAppendDevicePath (FirstDevicePath, SecondDevicePath);
}
/**
@@ -526,37 +138,7 @@ AppendDevicePathNode (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
)
{
- EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
- EFI_DEVICE_PATH_PROTOCOL *NextNode;
- EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
- UINTN NodeLength;
-
- if (DevicePathNode == NULL) {
- return DuplicateDevicePath ((DevicePath != NULL) ? DevicePath : &mUefiDevicePathLibEndDevicePath);
- }
- //
- // Build a Node that has a terminator on it
- //
- NodeLength = DevicePathNodeLength (DevicePathNode);
-
- TempDevicePath = AllocatePool (NodeLength + END_DEVICE_PATH_LENGTH);
- if (TempDevicePath == NULL) {
- return NULL;
- }
- TempDevicePath = CopyMem (TempDevicePath, DevicePathNode, NodeLength);
- //
- // Add and end device path node to convert Node to device path
- //
- NextNode = NextDevicePathNode (TempDevicePath);
- SetDevicePathEndNode (NextNode);
- //
- // Append device paths
- //
- NewDevicePath = AppendDevicePath (DevicePath, TempDevicePath);
-
- FreePool (TempDevicePath);
-
- return NewDevicePath;
+ return UefiDevicePathLibAppendDevicePathNode (DevicePath, DevicePathNode);
}
/**
@@ -589,41 +171,7 @@ AppendDevicePathInstance (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
)
{
- EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
- EFI_DEVICE_PATH_PROTOCOL *TempDevicePath;
- UINTN SrcSize;
- UINTN InstanceSize;
-
- if (DevicePath == NULL) {
- return DuplicateDevicePath (DevicePathInstance);
- }
-
- if (DevicePathInstance == NULL) {
- return NULL;
- }
-
- if (!IsDevicePathValid (DevicePath, 0) || !IsDevicePathValid (DevicePathInstance, 0)) {
- return NULL;
- }
-
- SrcSize = GetDevicePathSize (DevicePath);
- InstanceSize = GetDevicePathSize (DevicePathInstance);
-
- NewDevicePath = AllocatePool (SrcSize + InstanceSize);
- if (NewDevicePath != NULL) {
-
- TempDevicePath = CopyMem (NewDevicePath, DevicePath, SrcSize);;
-
- while (!IsDevicePathEnd (TempDevicePath)) {
- TempDevicePath = NextDevicePathNode (TempDevicePath);
- }
-
- TempDevicePath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
- TempDevicePath = NextDevicePathNode (TempDevicePath);
- CopyMem (TempDevicePath, DevicePathInstance, InstanceSize);
- }
-
- return NewDevicePath;
+ return UefiDevicePathLibAppendDevicePathInstance (DevicePath, DevicePathInstance);
}
/**
@@ -661,53 +209,7 @@ GetNextDevicePathInstance (
OUT UINTN *Size
)
{
- EFI_DEVICE_PATH_PROTOCOL *DevPath;
- EFI_DEVICE_PATH_PROTOCOL *ReturnValue;
- UINT8 Temp;
-
- ASSERT (Size != NULL);
-
- if (DevicePath == NULL || *DevicePath == NULL) {
- *Size = 0;
- return NULL;
- }
-
- if (!IsDevicePathValid (*DevicePath, 0)) {
- return NULL;
- }
-
- //
- // Find the end of the device path instance
- //
- DevPath = *DevicePath;
- while (!IsDevicePathEndType (DevPath)) {
- DevPath = NextDevicePathNode (DevPath);
- }
-
- //
- // Compute the size of the device path instance
- //
- *Size = ((UINTN) DevPath - (UINTN) (*DevicePath)) + sizeof (EFI_DEVICE_PATH_PROTOCOL);
-
- //
- // Make a copy and return the device path instance
- //
- Temp = DevPath->SubType;
- DevPath->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
- ReturnValue = DuplicateDevicePath (*DevicePath);
- DevPath->SubType = Temp;
-
- //
- // If DevPath is the end of an entire device path, then another instance
- // does not follow, so *DevicePath is set to NULL.
- //
- if (DevicePathSubType (DevPath) == END_ENTIRE_DEVICE_PATH_SUBTYPE) {
- *DevicePath = NULL;
- } else {
- *DevicePath = NextDevicePathNode (DevPath);
- }
-
- return ReturnValue;
+ return UefiDevicePathLibGetNextDevicePathInstance (DevicePath, Size);
}
/**
@@ -737,23 +239,7 @@ CreateDeviceNode (
IN UINT16 NodeLength
)
{
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
-
- if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
- //
- // NodeLength is less than the size of the header.
- //
- return NULL;
- }
-
- DevicePath = AllocateZeroPool (NodeLength);
- if (DevicePath != NULL) {
- DevicePath->Type = NodeType;
- DevicePath->SubType = NodeSubType;
- SetDevicePathNodeLength (DevicePath, NodeLength);
- }
-
- return DevicePath;
+ return UefiDevicePathLibCreateDeviceNode (NodeType, NodeSubType, NodeLength);
}
/**
@@ -777,115 +263,98 @@ IsDevicePathMultiInstance (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
- CONST EFI_DEVICE_PATH_PROTOCOL *Node;
-
- if (DevicePath == NULL) {
- return FALSE;
- }
+ return UefiDevicePathLibIsDevicePathMultiInstance (DevicePath);
+}
- if (!IsDevicePathValid (DevicePath, 0)) {
- return FALSE;
- }
+/**
+ Converts a device node to its string representation.
- Node = DevicePath;
- while (!IsDevicePathEnd (Node)) {
- if (IsDevicePathEndInstance (Node)) {
- return TRUE;
- }
+ @param DeviceNode A Pointer to the device node to be converted.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
- Node = NextDevicePathNode (Node);
- }
+ @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
+ is NULL or there was insufficient memory.
- return FALSE;
+**/
+CHAR16 *
+EFIAPI
+ConvertDeviceNodeToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ return UefiDevicePathLibConvertDeviceNodeToText (DeviceNode, DisplayOnly, AllowShortcuts);
}
+/**
+ Converts a device path to its text representation.
+
+ @param DevicePath A Pointer to the device to be converted.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ @return A pointer to the allocated text representation of the device path or
+ NULL if DeviceNode is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+ConvertDevicePathToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ return UefiDevicePathLibConvertDevicePathToText (DevicePath, DisplayOnly, AllowShortcuts);
+}
/**
- Retrieves the device path protocol from a handle.
+ Convert text to the binary representation of a device node.
- This function returns the device path protocol from the handle specified by Handle.
- If Handle is NULL or Handle does not contain a device path protocol, then NULL
- is returned.
-
- @param Handle The handle from which to retrieve the device
- path protocol.
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
- @return The device path protocol from the handle specified by Handle.
+ @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+ insufficient memory or text unsupported.
**/
EFI_DEVICE_PATH_PROTOCOL *
EFIAPI
-DevicePathFromHandle (
- IN EFI_HANDLE Handle
+ConvertTextToDeviceNode (
+ IN CONST CHAR16 *TextDeviceNode
)
{
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- EFI_STATUS Status;
-
- Status = gBS->HandleProtocol (
- Handle,
- &gEfiDevicePathProtocolGuid,
- (VOID *) &DevicePath
- );
- if (EFI_ERROR (Status)) {
- DevicePath = NULL;
- }
- return DevicePath;
+ return UefiDevicePathLibConvertTextToDeviceNode (TextDeviceNode);
}
/**
- Allocates a device path for a file and appends it to an existing device path.
-
- If Device is a valid device handle that contains a device path protocol, then a device path for
- the file specified by FileName is allocated and appended to the device path associated with the
- handle Device. The allocated device path is returned. If Device is NULL or Device is a handle
- that does not support the device path protocol, then a device path containing a single device
- path node for the file specified by FileName is allocated and returned.
- The memory for the new device path is allocated from EFI boot services memory. It is the responsibility
- of the caller to free the memory allocated.
-
- If FileName is NULL, then ASSERT().
- If FileName is not aligned on a 16-bit boundary, then ASSERT().
+ Convert text to the binary representation of a device path.
- @param Device A pointer to a device handle. This parameter
- is optional and may be NULL.
- @param FileName A pointer to a Null-terminated Unicode string.
- @return The allocated device path.
+ @param TextDevicePath TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+ there was insufficient memory.
**/
EFI_DEVICE_PATH_PROTOCOL *
EFIAPI
-FileDevicePath (
- IN EFI_HANDLE Device, OPTIONAL
- IN CONST CHAR16 *FileName
+ConvertTextToDevicePath (
+ IN CONST CHAR16 *TextDevicePath
)
{
- UINTN Size;
- FILEPATH_DEVICE_PATH *FilePath;
- EFI_DEVICE_PATH_PROTOCOL *DevicePath;
- EFI_DEVICE_PATH_PROTOCOL *FileDevicePath;
-
- DevicePath = NULL;
-
- Size = StrSize (FileName);
- FileDevicePath = AllocatePool (Size + SIZE_OF_FILEPATH_DEVICE_PATH + END_DEVICE_PATH_LENGTH);
- if (FileDevicePath != NULL) {
- FilePath = (FILEPATH_DEVICE_PATH *) FileDevicePath;
- FilePath->Header.Type = MEDIA_DEVICE_PATH;
- FilePath->Header.SubType = MEDIA_FILEPATH_DP;
- CopyMem (&FilePath->PathName, FileName, Size);
- SetDevicePathNodeLength (&FilePath->Header, Size + SIZE_OF_FILEPATH_DEVICE_PATH);
- SetDevicePathEndNode (NextDevicePathNode (&FilePath->Header));
-
- if (Device != NULL) {
- DevicePath = DevicePathFromHandle (Device);
- }
-
- DevicePath = AppendDevicePath (DevicePath, FileDevicePath);
- FreePool (FileDevicePath);
- }
-
- return DevicePath;
+ return UefiDevicePathLibConvertTextToDevicePath (TextDevicePath);
}
-
diff --git a/MdeModulePkg/Universal/DevicePathDxe/DevicePath.h b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.h
index 8beb68c..a7ed531 100644
--- a/MdeModulePkg/Universal/DevicePathDxe/DevicePath.h
+++ b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.h
@@ -1,7 +1,7 @@
/** @file
- Definition for Device Path Utilities driver
+ Definition for Device Path library.
-Copyright (c) 2006 - 2011, Intel Corporation. All rights reserved.<BR>
+Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -12,9 +12,8 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
**/
-#ifndef _DEVICE_PATH_DRIVER_H_
-#define _DEVICE_PATH_DRIVER_H_
-
+#ifndef _UEFI_DEVICE_PATH_LIB_H_
+#define _UEFI_DEVICE_PATH_LIB_H_
#include <Uefi.h>
#include <Protocol/DevicePathUtilities.h>
#include <Protocol/DebugPort.h>
@@ -23,7 +22,6 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#include <Guid/PcAnsi.h>
#include <Library/DebugLib.h>
#include <Library/PrintLib.h>
-#include <Library/UefiDriverEntryPoint.h>
#include <Library/BaseLib.h>
#include <Library/BaseMemoryLib.h>
#include <Library/MemoryAllocationLib.h>
@@ -40,46 +38,39 @@ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
#define IS_NULL(a) ((a) == L'\0')
-#define SET_DEVICE_PATH_INSTANCE_END_NODE(a) { \
- (a)->Type = END_DEVICE_PATH_TYPE; \
- (a)->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE; \
- (a)->Length[0] = (UINT8) sizeof (EFI_DEVICE_PATH_PROTOCOL); \
- (a)->Length[1] = 0; \
- }
-
//
// Private Data structure
//
typedef struct {
CHAR16 *Str;
- UINTN Length;
+ UINTN Count;
UINTN Capacity;
} POOL_PRINT;
typedef
EFI_DEVICE_PATH_PROTOCOL *
-(*DUMP_NODE) (
- IN CHAR16 *DeviceNodeStr
+(*DEVICE_PATH_FROM_TEXT) (
+ IN CHAR16 *Str
);
typedef
VOID
-(*DEVICE_PATH_TO_TEXT_FUNC) (
+(*DEVICE_PATH_TO_TEXT) (
IN OUT POOL_PRINT *Str,
- IN VOID *DevPath,
+ IN VOID *DevicePath,
IN BOOLEAN DisplayOnly,
IN BOOLEAN AllowShortcuts
);
typedef struct {
- UINT8 Type;
- UINT8 SubType;
- DEVICE_PATH_TO_TEXT_FUNC Function;
+ UINT8 Type;
+ UINT8 SubType;
+ DEVICE_PATH_TO_TEXT Function;
} DEVICE_PATH_TO_TEXT_TABLE;
typedef struct {
CHAR16 *DevicePathNodeText;
- DUMP_NODE Function;
+ DEVICE_PATH_FROM_TEXT Function;
} DEVICE_PATH_FROM_TEXT_TABLE;
typedef struct {
@@ -156,278 +147,305 @@ typedef struct {
#pragma pack()
/**
- Converts a device node to its string representation.
+ Returns the size of a device path in bytes.
- @param DeviceNode A Pointer to the device node to be converted.
- @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
- of the display node is used, where applicable. If DisplayOnly
- is FALSE, then the longer text representation of the display node
- is used.
- @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
- representation for a device node can be used, where applicable.
+ This function returns the size, in bytes, of the device path data structure
+ specified by DevicePath including the end of device path node.
+ If DevicePath is NULL or invalid, then 0 is returned.
- @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
- is NULL or there was insufficient memory.
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval 0 If DevicePath is NULL or invalid.
+ @retval Others The size of a device path in bytes.
**/
-CHAR16 *
+UINTN
EFIAPI
-ConvertDeviceNodeToText (
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
- IN BOOLEAN DisplayOnly,
- IN BOOLEAN AllowShortcuts
+UefiDevicePathLibGetDevicePathSize (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
);
/**
- Converts a device path to its text representation.
-
- @param DevicePath A Pointer to the device to be converted.
- @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
- of the display node is used, where applicable. If DisplayOnly
- is FALSE, then the longer text representation of the display node
- is used.
- @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
- representation for a device node can be used, where applicable.
-
- @return A pointer to the allocated text representation of the device path or
- NULL if DeviceNode is NULL or there was insufficient memory.
-
+ Creates a new copy of an existing device path.
+
+ This function allocates space for a new copy of the device path specified by DevicePath.
+ If DevicePath is NULL, then NULL is returned. If the memory is successfully
+ allocated, then the contents of DevicePath are copied to the newly allocated
+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval NULL DevicePath is NULL or invalid.
+ @retval Others A pointer to the duplicated device path.
+
**/
-CHAR16 *
+EFI_DEVICE_PATH_PROTOCOL *
EFIAPI
-ConvertDevicePathToText (
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
- IN BOOLEAN DisplayOnly,
- IN BOOLEAN AllowShortcuts
+UefiDevicePathLibDuplicateDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
);
/**
- Convert text to the binary representation of a device node.
+ Creates a new device path by appending a second device path to a first device path.
- @param TextDeviceNode TextDeviceNode points to the text representation of a device
- node. Conversion starts with the first character and continues
- until the first non-device node character.
+ This function creates a new device path by appending a copy of SecondDevicePath
+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path
+ device node from SecondDevicePath is retained. The newly created device path is
+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored,
+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
+ SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
+
+ If there is not enough memory for the newly allocated buffer, then NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
- @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
- insufficient memory or text unsupported.
+ @param FirstDevicePath A pointer to a device path data structure.
+ @param SecondDevicePath A pointer to a device path data structure.
+
+ @retval NULL If there is not enough memory for the newly allocated buffer.
+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid.
+ @retval Others A pointer to the new device path if success.
+ Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
**/
EFI_DEVICE_PATH_PROTOCOL *
EFIAPI
-ConvertTextToDeviceNode (
- IN CONST CHAR16 *TextDeviceNode
+UefiDevicePathLibAppendDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
);
/**
- Convert text to the binary representation of a device path.
+ Creates a new path by appending the device node to the device path.
+ This function creates a new device path by appending a copy of the device node
+ specified by DevicePathNode to a copy of the device path specified by DevicePath
+ in an allocated buffer. The end-of-device-path device node is moved after the
+ end of the appended device node.
+ If DevicePathNode is NULL then a copy of DevicePath is returned.
+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
+ path device node is returned.
+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
+ device node is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
- @param TextDevicePath TextDevicePath points to the text representation of a device
- path. Conversion starts with the first character and continues
- until the first non-device node character.
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathNode A pointer to a single device path node.
- @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
- there was insufficient memory.
+ @retval NULL If there is not enough memory for the new device path.
+ @retval Others A pointer to the new device path if success.
+ A copy of DevicePathNode followed by an end-of-device-path node
+ if both FirstDevicePath and SecondDevicePath are NULL.
+ A copy of an end-of-device-path node if both FirstDevicePath
+ and SecondDevicePath are NULL.
**/
EFI_DEVICE_PATH_PROTOCOL *
EFIAPI
-ConvertTextToDevicePath (
- IN CONST CHAR16 *TextDevicePath
+UefiDevicePathLibAppendDevicePathNode (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
);
/**
- Returns the size of a device path in bytes.
-
- This function returns the size, in bytes, of the device path data structure specified by
- DevicePath including the end of device path node. If DevicePath is NULL, then 0 is returned.
-
+ Creates a new device path by appending the specified device path instance to the specified device
+ path.
+
+ This function creates a new device path by appending a copy of the device path
+ instance specified by DevicePathInstance to a copy of the device path specified
+ by DevicePath in a allocated buffer.
+ The end-of-device-path device node is moved after the end of the appended device
+ path instance and a new end-of-device-path-instance node is inserted between.
+ If DevicePath is NULL, then a copy if DevicePathInstance is returned.
+ If DevicePathInstance is NULL, then NULL is returned.
+ If DevicePath or DevicePathInstance is invalid, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
@param DevicePath A pointer to a device path data structure.
+ @param DevicePathInstance A pointer to a device path instance.
- @return The size of a device path in bytes.
+ @return A pointer to the new device path.
**/
-UINTN
+EFI_DEVICE_PATH_PROTOCOL *
EFIAPI
-GetDevicePathSizeProtocolInterface (
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+UefiDevicePathLibAppendDevicePathInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
);
/**
- Creates a new device path by appending a second device path to a first device path.
-
- This function allocates space for a new copy of the device path specified by DevicePath. If
- DevicePath is NULL, then NULL is returned. If the memory is successfully allocated, then the
- contents of DevicePath are copied to the newly allocated buffer, and a pointer to that buffer
- is returned. Otherwise, NULL is returned.
+ Creates a copy of the current device path instance and returns a pointer to the next device path
+ instance.
- @param DevicePath A pointer to a device path data structure.
+ This function creates a copy of the current device path instance. It also updates
+ DevicePath to point to the next device path instance in the device path (or NULL
+ if no more) and updates Size to hold the size of the device path instance copy.
+ If DevicePath is NULL, then NULL is returned.
+ If DevicePath points to a invalid device path, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+ If Size is NULL, then ASSERT().
+
+ @param DevicePath On input, this holds the pointer to the current
+ device path instance. On output, this holds
+ the pointer to the next device path instance
+ or NULL if there are no more device path
+ instances in the device path pointer to a
+ device path data structure.
+ @param Size On output, this holds the size of the device
+ path instance, in bytes or zero, if DevicePath
+ is NULL.
- @return A pointer to the duplicated device path.
+ @return A pointer to the current device path instance.
**/
EFI_DEVICE_PATH_PROTOCOL *
EFIAPI
-DuplicateDevicePathProtocolInterface (
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+UefiDevicePathLibGetNextDevicePathInstance (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ OUT UINTN *Size
);
/**
- Creates a new device path by appending a second device path to a first device path.
+ Creates a device node.
- This function creates a new device path by appending a copy of SecondDevicePath to a copy of
- FirstDevicePath in a newly allocated buffer. Only the end-of-device-path device node from
- SecondDevicePath is retained. The newly created device path is returned.
- If FirstDevicePath is NULL, then it is ignored, and a duplicate of SecondDevicePath is returned.
- If SecondDevicePath is NULL, then it is ignored, and a duplicate of FirstDevicePath is returned.
- If both FirstDevicePath and SecondDevicePath are NULL, then a copy of an end-of-device-path is
- returned.
- If there is not enough memory for the newly allocated buffer, then NULL is returned.
- The memory for the new device path is allocated from EFI boot services memory. It is the
- responsibility of the caller to free the memory allocated.
+ This function creates a new device node in a newly allocated buffer of size
+ NodeLength and initializes the device path node header with NodeType and NodeSubType.
+ The new device path node is returned.
+ If NodeLength is smaller than a device path header, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
- @param FirstDevicePath A pointer to a device path data structure.
- @param SecondDevicePath A pointer to a device path data structure.
+ @param NodeType The device node type for the new device node.
+ @param NodeSubType The device node sub-type for the new device node.
+ @param NodeLength The length of the new device node.
- @return A pointer to the new device path.
+ @return The new device path.
**/
EFI_DEVICE_PATH_PROTOCOL *
EFIAPI
-AppendDevicePathProtocolInterface (
- IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath,
- IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath
+UefiDevicePathLibCreateDeviceNode (
+ IN UINT8 NodeType,
+ IN UINT8 NodeSubType,
+ IN UINT16 NodeLength
);
/**
- Creates a new path by appending the device node to the device path.
+ Determines if a device path is single or multi-instance.
- This function creates a new device path by appending a copy of the device node specified by
- DevicePathNode to a copy of the device path specified by DevicePath in an allocated buffer.
- The end-of-device-path device node is moved after the end of the appended device node.
- If DevicePathNode is NULL then a copy of DevicePath is returned.
- If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device path device
- node is returned.
- If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path device node
- is returned.
- If there is not enough memory to allocate space for the new device path, then NULL is returned.
- The memory is allocated from EFI boot services memory. It is the responsibility of the caller to
- free the memory allocated.
+ This function returns TRUE if the device path specified by DevicePath is
+ multi-instance.
+ Otherwise, FALSE is returned.
+ If DevicePath is NULL or invalid, then FALSE is returned.
@param DevicePath A pointer to a device path data structure.
- @param DevicePathNode A pointer to a single device path node.
- @return A pointer to the new device path.
+ @retval TRUE DevicePath is multi-instance.
+ @retval FALSE DevicePath is not multi-instance, or DevicePath
+ is NULL or invalid.
**/
-EFI_DEVICE_PATH_PROTOCOL *
+BOOLEAN
EFIAPI
-AppendDeviceNodeProtocolInterface (
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode
+UefiDevicePathLibIsDevicePathMultiInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
);
-/**
- Creates a new device path by appending the specified device path instance to the specified device
- path.
- This function creates a new device path by appending a copy of the device path instance specified
- by DevicePathInstance to a copy of the device path specified by DevicePath in a allocated buffer.
- The end-of-device-path device node is moved after the end of the appended device path instance
- and a new end-of-device-path-instance node is inserted between.
- If DevicePath is NULL, then a copy if DevicePathInstance is returned.
- If DevicePathInstance is NULL, then NULL is returned.
- If there is not enough memory to allocate space for the new device path, then NULL is returned.
- The memory is allocated from EFI boot services memory. It is the responsibility of the caller to
- free the memory allocated.
+/**
+ Converts a device path to its text representation.
- @param DevicePath A pointer to a device path data structure.
- @param DevicePathInstance A pointer to a device path instance.
+ @param DevicePath A Pointer to the device to be converted.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
- @return A pointer to the new device path.
+ @return A pointer to the allocated text representation of the device path or
+ NULL if DeviceNode is NULL or there was insufficient memory.
**/
-EFI_DEVICE_PATH_PROTOCOL *
+CHAR16 *
EFIAPI
-AppendDevicePathInstanceProtocolInterface (
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
+UefiDevicePathLibConvertDevicePathToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
);
/**
- Creates a copy of the current device path instance and returns a pointer to the next device path
- instance.
-
- This function creates a copy of the current device path instance. It also updates DevicePath to
- point to the next device path instance in the device path (or NULL if no more) and updates Size
- to hold the size of the device path instance copy.
- If DevicePath is NULL, then NULL is returned.
- If there is not enough memory to allocate space for the new device path, then NULL is returned.
- The memory is allocated from EFI boot services memory. It is the responsibility of the caller to
- free the memory allocated.
- If Size is NULL, then ASSERT().
+ Converts a device node to its string representation.
- @param DevicePath On input, this holds the pointer to the current device path
- instance. On output, this holds the pointer to the next device
- path instance or NULL if there are no more device path
- instances in the device path pointer to a device path data
- structure.
- @param Size On output, this holds the size of the device path instance, in
- bytes or zero, if DevicePath is NULL.
+ @param DeviceNode A Pointer to the device node to be converted.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
- @return A pointer to the current device path instance.
+ @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
+ is NULL or there was insufficient memory.
**/
-EFI_DEVICE_PATH_PROTOCOL *
+CHAR16 *
EFIAPI
-GetNextDevicePathInstanceProtocolInterface (
- IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
- OUT UINTN *Size
+UefiDevicePathLibConvertDeviceNodeToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
);
/**
- Determines if a device path is single or multi-instance.
-
- This function returns TRUE if the device path specified by DevicePath is multi-instance.
- Otherwise, FALSE is returned. If DevicePath is NULL, then FALSE is returned.
+ Convert text to the binary representation of a device node.
- @param DevicePath A pointer to a device path data structure.
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
- @retval TRUE DevicePath is multi-instance.
- @retval FALSE DevicePath is not multi-instance or DevicePath is NULL.
+ @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+ insufficient memory or text unsupported.
**/
-BOOLEAN
+EFI_DEVICE_PATH_PROTOCOL *
EFIAPI
-IsDevicePathMultiInstanceProtocolInterface (
- IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+UefiDevicePathLibConvertTextToDeviceNode (
+ IN CONST CHAR16 *TextDeviceNode
);
/**
- Creates a copy of the current device path instance and returns a pointer to the next device path
- instance.
+ Convert text to the binary representation of a device path.
- This function creates a new device node in a newly allocated buffer of size NodeLength and
- initializes the device path node header with NodeType and NodeSubType. The new device path node
- is returned.
- If NodeLength is smaller than a device path header, then NULL is returned.
- If there is not enough memory to allocate space for the new device path, then NULL is returned.
- The memory is allocated from EFI boot services memory. It is the responsibility of the caller to
- free the memory allocated.
- @param NodeType The device node type for the new device node.
- @param NodeSubType The device node sub-type for the new device node.
- @param NodeLength The length of the new device node.
+ @param TextDevicePath TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
- @return The new device path.
+ @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+ there was insufficient memory.
**/
EFI_DEVICE_PATH_PROTOCOL *
EFIAPI
-CreateDeviceNodeProtocolInterface (
- IN UINT8 NodeType,
- IN UINT8 NodeSubType,
- IN UINT16 NodeLength
+UefiDevicePathLibConvertTextToDevicePath (
+ IN CONST CHAR16 *TextDevicePath
);
#endif
diff --git a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
index 2ae151d..fc9b5c0 100644
--- a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+++ b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
@@ -3,7 +3,7 @@
#
# Device Path Library that layers on top of the Memory Allocation Library.
#
-# Copyright (c) 2007 - 2012, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
#
# This program and the accompanying materials
# are licensed and made available under the terms and conditions of the BSD License
@@ -29,8 +29,11 @@
#
[Sources]
+ DevicePathUtilities.c
+ DevicePathToText.c
+ DevicePathFromText.c
UefiDevicePathLib.c
-
+ UefiDevicePathLib.h
[Packages]
MdePkg/MdePkg.dec
@@ -38,14 +41,23 @@
[LibraryClasses]
BaseLib
- UefiBootServicesTableLib
MemoryAllocationLib
DebugLib
BaseMemoryLib
PcdLib
+ PrintLib
+
+[Guids]
+ gEfiVTUTF8Guid
+ gEfiVT100Guid
+ gEfiVT100PlusGuid
+ gEfiPcAnsiGuid
+ gEfiUartDevicePathGuid
+ gEfiSasDevicePathGuid
[Protocols]
gEfiDevicePathProtocolGuid ## CONSUMES
+ gEfiDebugPortProtocolGuid ## SOMETIMES_CONSUMES ## GUID
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdMaximumDevicePathNodeCount
diff --git a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.c b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.c
new file mode 100644
index 0000000..9580e39
--- /dev/null
+++ b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.c
@@ -0,0 +1,484 @@
+/** @file
+ Device Path services. The thing to remember is device paths are built out of
+ nodes. The device path is terminated by an end node that is length
+ sizeof(EFI_DEVICE_PATH_PROTOCOL). That would be why there is sizeof(EFI_DEVICE_PATH_PROTOCOL)
+ all over this file.
+
+ The only place where multi-instance device paths are supported is in
+ environment varibles. Multi-instance device paths should never be placed
+ on a Handle.
+
+ Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+ This program and the accompanying materials
+ are licensed and made available under the terms and conditions of the BSD License
+ which accompanies this distribution. The full text of the license may be found at
+ http://opensource.org/licenses/bsd-license.php.
+
+ THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+ WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+
+**/
+
+
+#include "UefiDevicePathLib.h"
+
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_UTILITIES_PROTOCOL *mDevicePathLibDevicePathUtilities = NULL;
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *mDevicePathLibDevicePathToText = NULL;
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mDevicePathLibDevicePathFromText = NULL;
+
+/**
+ The constructor function caches the pointer to DevicePathUtilites protocol,
+ DevicePathToText protocol and DevicePathFromText protocol.
+
+ The constructor function locates these three protocols from protocol database.
+ It will caches the pointer to local protocol instance if that operation fails
+ and it will always return EFI_SUCCESS.
+
+ @param ImageHandle The firmware allocated handle for the EFI image.
+ @param SystemTable A pointer to the EFI System Table.
+
+ @retval EFI_SUCCESS The constructor always returns EFI_SUCCESS.
+
+**/
+EFI_STATUS
+EFIAPI
+UefiDevicePathLibOptionalDevicePathProtocolConstructor (
+ IN EFI_HANDLE ImageHandle,
+ IN EFI_SYSTEM_TABLE *SystemTable
+ )
+{
+ EFI_STATUS Status;
+
+ Status = gBS->LocateProtocol (
+ &gEfiDevicePathUtilitiesProtocolGuid,
+ NULL,
+ (VOID**) &mDevicePathLibDevicePathUtilities
+ );
+ ASSERT_EFI_ERROR (Status);
+ ASSERT (mDevicePathLibDevicePathUtilities != NULL);
+ return Status;
+}
+
+/**
+ Returns the size of a device path in bytes.
+
+ This function returns the size, in bytes, of the device path data structure
+ specified by DevicePath including the end of device path node.
+ If DevicePath is NULL or invalid, then 0 is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval 0 If DevicePath is NULL or invalid.
+ @retval Others The size of a device path in bytes.
+
+**/
+UINTN
+EFIAPI
+GetDevicePathSize (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ if (mDevicePathLibDevicePathUtilities != NULL) {
+ return mDevicePathLibDevicePathUtilities->GetDevicePathSize (DevicePath);
+ } else {
+ return UefiDevicePathLibGetDevicePathSize (DevicePath);
+ }
+}
+
+/**
+ Creates a new copy of an existing device path.
+
+ This function allocates space for a new copy of the device path specified by DevicePath.
+ If DevicePath is NULL, then NULL is returned. If the memory is successfully
+ allocated, then the contents of DevicePath are copied to the newly allocated
+ buffer, and a pointer to that buffer is returned. Otherwise, NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval NULL DevicePath is NULL or invalid.
+ @retval Others A pointer to the duplicated device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+DuplicateDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ if (mDevicePathLibDevicePathUtilities != NULL) {
+ return mDevicePathLibDevicePathUtilities->DuplicateDevicePath (DevicePath);
+ } else {
+ return UefiDevicePathLibDuplicateDevicePath (DevicePath);
+ }
+}
+
+/**
+ Creates a new device path by appending a second device path to a first device path.
+
+ This function creates a new device path by appending a copy of SecondDevicePath
+ to a copy of FirstDevicePath in a newly allocated buffer. Only the end-of-device-path
+ device node from SecondDevicePath is retained. The newly created device path is
+ returned. If FirstDevicePath is NULL, then it is ignored, and a duplicate of
+ SecondDevicePath is returned. If SecondDevicePath is NULL, then it is ignored,
+ and a duplicate of FirstDevicePath is returned. If both FirstDevicePath and
+ SecondDevicePath are NULL, then a copy of an end-of-device-path is returned.
+
+ If there is not enough memory for the newly allocated buffer, then NULL is returned.
+ The memory for the new device path is allocated from EFI boot services memory.
+ It is the responsibility of the caller to free the memory allocated.
+
+ @param FirstDevicePath A pointer to a device path data structure.
+ @param SecondDevicePath A pointer to a device path data structure.
+
+ @retval NULL If there is not enough memory for the newly allocated buffer.
+ @retval NULL If FirstDevicePath or SecondDevicePath is invalid.
+ @retval Others A pointer to the new device path if success.
+ Or a copy an end-of-device-path if both FirstDevicePath and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+AppendDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *FirstDevicePath, OPTIONAL
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
+ )
+{
+ if (mDevicePathLibDevicePathUtilities != NULL) {
+ return mDevicePathLibDevicePathUtilities->AppendDevicePath (FirstDevicePath, SecondDevicePath);
+ } else {
+ return UefiDevicePathLibAppendDevicePath (FirstDevicePath, SecondDevicePath);
+ }
+}
+
+/**
+ Creates a new path by appending the device node to the device path.
+
+ This function creates a new device path by appending a copy of the device node
+ specified by DevicePathNode to a copy of the device path specified by DevicePath
+ in an allocated buffer. The end-of-device-path device node is moved after the
+ end of the appended device node.
+ If DevicePathNode is NULL then a copy of DevicePath is returned.
+ If DevicePath is NULL then a copy of DevicePathNode, followed by an end-of-device
+ path device node is returned.
+ If both DevicePathNode and DevicePath are NULL then a copy of an end-of-device-path
+ device node is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathNode A pointer to a single device path node.
+
+ @retval NULL If there is not enough memory for the new device path.
+ @retval Others A pointer to the new device path if success.
+ A copy of DevicePathNode followed by an end-of-device-path node
+ if both FirstDevicePath and SecondDevicePath are NULL.
+ A copy of an end-of-device-path node if both FirstDevicePath
+ and SecondDevicePath are NULL.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+AppendDevicePathNode (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
+ )
+{
+ if (mDevicePathLibDevicePathUtilities != NULL) {
+ return mDevicePathLibDevicePathUtilities->AppendDeviceNode (DevicePath, DevicePathNode);
+ } else {
+ return UefiDevicePathLibAppendDevicePathNode (DevicePath, DevicePathNode);
+ }
+}
+
+/**
+ Creates a new device path by appending the specified device path instance to the specified device
+ path.
+
+ This function creates a new device path by appending a copy of the device path
+ instance specified by DevicePathInstance to a copy of the device path specified
+ by DevicePath in a allocated buffer.
+ The end-of-device-path device node is moved after the end of the appended device
+ path instance and a new end-of-device-path-instance node is inserted between.
+ If DevicePath is NULL, then a copy if DevicePathInstance is returned.
+ If DevicePathInstance is NULL, then NULL is returned.
+ If DevicePath or DevicePathInstance is invalid, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param DevicePath A pointer to a device path data structure.
+ @param DevicePathInstance A pointer to a device path instance.
+
+ @return A pointer to the new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+AppendDevicePathInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath, OPTIONAL
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
+ )
+{
+ if (mDevicePathLibDevicePathUtilities != NULL) {
+ return mDevicePathLibDevicePathUtilities->AppendDevicePathInstance (DevicePath, DevicePathInstance);
+ } else {
+ return UefiDevicePathLibAppendDevicePathInstance (DevicePath, DevicePathInstance);
+ }
+}
+
+/**
+ Creates a copy of the current device path instance and returns a pointer to the next device path
+ instance.
+
+ This function creates a copy of the current device path instance. It also updates
+ DevicePath to point to the next device path instance in the device path (or NULL
+ if no more) and updates Size to hold the size of the device path instance copy.
+ If DevicePath is NULL, then NULL is returned.
+ If DevicePath points to a invalid device path, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+ If Size is NULL, then ASSERT().
+
+ @param DevicePath On input, this holds the pointer to the current
+ device path instance. On output, this holds
+ the pointer to the next device path instance
+ or NULL if there are no more device path
+ instances in the device path pointer to a
+ device path data structure.
+ @param Size On output, this holds the size of the device
+ path instance, in bytes or zero, if DevicePath
+ is NULL.
+
+ @return A pointer to the current device path instance.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+GetNextDevicePathInstance (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePath,
+ OUT UINTN *Size
+ )
+{
+ if (mDevicePathLibDevicePathUtilities != NULL) {
+ return mDevicePathLibDevicePathUtilities->GetNextDevicePathInstance (DevicePath, Size);
+ } else {
+ return UefiDevicePathLibGetNextDevicePathInstance (DevicePath, Size);
+ }
+}
+
+/**
+ Creates a device node.
+
+ This function creates a new device node in a newly allocated buffer of size
+ NodeLength and initializes the device path node header with NodeType and NodeSubType.
+ The new device path node is returned.
+ If NodeLength is smaller than a device path header, then NULL is returned.
+ If there is not enough memory to allocate space for the new device path, then
+ NULL is returned.
+ The memory is allocated from EFI boot services memory. It is the responsibility
+ of the caller to free the memory allocated.
+
+ @param NodeType The device node type for the new device node.
+ @param NodeSubType The device node sub-type for the new device node.
+ @param NodeLength The length of the new device node.
+
+ @return The new device path.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+CreateDeviceNode (
+ IN UINT8 NodeType,
+ IN UINT8 NodeSubType,
+ IN UINT16 NodeLength
+ )
+{
+ if (mDevicePathLibDevicePathUtilities != NULL) {
+ return mDevicePathLibDevicePathUtilities->CreateDeviceNode (NodeType, NodeSubType, NodeLength);
+ } else {
+ return UefiDevicePathLibCreateDeviceNode (NodeType, NodeSubType, NodeLength);
+ }
+}
+
+/**
+ Determines if a device path is single or multi-instance.
+
+ This function returns TRUE if the device path specified by DevicePath is
+ multi-instance.
+ Otherwise, FALSE is returned.
+ If DevicePath is NULL or invalid, then FALSE is returned.
+
+ @param DevicePath A pointer to a device path data structure.
+
+ @retval TRUE DevicePath is multi-instance.
+ @retval FALSE DevicePath is not multi-instance, or DevicePath
+ is NULL or invalid.
+
+**/
+BOOLEAN
+EFIAPI
+IsDevicePathMultiInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+{
+ if (mDevicePathLibDevicePathUtilities != NULL) {
+ return mDevicePathLibDevicePathUtilities->IsDevicePathMultiInstance (DevicePath);
+ } else {
+ return UefiDevicePathLibIsDevicePathMultiInstance (DevicePath);
+ }
+}
+
+/**
+ Locate and return the protocol instance identified by the ProtocolGuid.
+
+ @param ProtocolGuid The GUID of the protocol.
+
+ @return A pointer to the protocol instance or NULL when absent.
+**/
+VOID *
+UefiDevicePathLibLocateProtocol (
+ EFI_GUID *ProtocolGuid
+ )
+{
+ EFI_STATUS Status;
+ VOID *Protocol;
+ Status = gBS->LocateProtocol (
+ ProtocolGuid,
+ NULL,
+ (VOID**) &Protocol
+ );
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ } else {
+ return Protocol;
+ }
+}
+
+/**
+ Converts a device node to its string representation.
+
+ @param DeviceNode A Pointer to the device node to be converted.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
+ is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+ConvertDeviceNodeToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ if (mDevicePathLibDevicePathToText == NULL) {
+ mDevicePathLibDevicePathToText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathToTextProtocolGuid);
+ }
+ if (mDevicePathLibDevicePathToText != NULL) {
+ return mDevicePathLibDevicePathToText->ConvertDeviceNodeToText (DeviceNode, DisplayOnly, AllowShortcuts);
+ }
+
+ return UefiDevicePathLibConvertDeviceNodeToText (DeviceNode, DisplayOnly, AllowShortcuts);
+}
+
+/**
+ Converts a device path to its text representation.
+
+ @param DevicePath A Pointer to the device to be converted.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ @return A pointer to the allocated text representation of the device path or
+ NULL if DeviceNode is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+ConvertDevicePathToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ if (mDevicePathLibDevicePathToText == NULL) {
+ mDevicePathLibDevicePathToText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathToTextProtocolGuid);
+ }
+ if (mDevicePathLibDevicePathToText != NULL) {
+ return mDevicePathLibDevicePathToText->ConvertDevicePathToText (DevicePath, DisplayOnly, AllowShortcuts);
+ }
+
+ return UefiDevicePathLibConvertDevicePathToText (DevicePath, DisplayOnly, AllowShortcuts);
+}
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+ insufficient memory or text unsupported.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+ConvertTextToDeviceNode (
+ IN CONST CHAR16 *TextDeviceNode
+ )
+{
+ if (mDevicePathLibDevicePathFromText == NULL) {
+ mDevicePathLibDevicePathFromText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathFromTextProtocolGuid);
+ }
+ if (mDevicePathLibDevicePathFromText != NULL) {
+ return mDevicePathLibDevicePathFromText->ConvertTextToDeviceNode (TextDeviceNode);
+ }
+
+ return UefiDevicePathLibConvertTextToDeviceNode (TextDeviceNode);
+}
+
+/**
+ Convert text to the binary representation of a device path.
+
+
+ @param TextDevicePath TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+ there was insufficient memory.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+ConvertTextToDevicePath (
+ IN CONST CHAR16 *TextDevicePath
+ )
+{
+ if (mDevicePathLibDevicePathFromText == NULL) {
+ mDevicePathLibDevicePathFromText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathFromTextProtocolGuid);
+ }
+ if (mDevicePathLibDevicePathFromText != NULL) {
+ return mDevicePathLibDevicePathFromText->ConvertTextToDevicePath (TextDevicePath);
+ }
+
+ return UefiDevicePathLibConvertTextToDevicePath (TextDevicePath);
+}
+
diff --git a/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.inf b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.inf
new file mode 100644
index 0000000..34bc120
--- /dev/null
+++ b/MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.inf
@@ -0,0 +1,73 @@
+## @file
+# Instance of Device Path Library based on Device Path Protocol.
+#
+# Device Path Library that layers on top of the UEFI 2.0 Device Path Protocol.
+# If the DevicePathFromText/DevicePathToText protocol doesn't exist, the library
+# uses its internal conversion logic.
+#
+# Copyright (c) 2013, Intel Corporation. All rights reserved.<BR>
+#
+# This program and the accompanying materials
+# are licensed and made available under the terms and conditions of the BSD License
+# which accompanies this distribution. The full text of the license may be found at
+# http://opensource.org/licenses/bsd-license.php.
+# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
+# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
+#
+#
+##
+
+[Defines]
+ INF_VERSION = 0x00010005
+ BASE_NAME = UefiDevicePathLibOptionalDevicePathProtocol
+ FILE_GUID = 3E1C696D-FCF0-45a7-85A7-E86C2A1C1080
+ MODULE_TYPE = UEFI_DRIVER
+ VERSION_STRING = 1.0
+ LIBRARY_CLASS = DevicePathLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE
+
+ CONSTRUCTOR = UefiDevicePathLibOptionalDevicePathProtocolConstructor
+
+#
+# VALID_ARCHITECTURES = IA32 X64 IPF EBC
+#
+
+[Sources]
+ DevicePathUtilities.c
+ DevicePathToText.c
+ DevicePathFromText.c
+ UefiDevicePathLibOptionalDevicePathProtocol.c
+ UefiDevicePathLib.h
+
+[Packages]
+ MdePkg/MdePkg.dec
+
+
+[LibraryClasses]
+ BaseLib
+ UefiBootServicesTableLib
+ MemoryAllocationLib
+ DebugLib
+ BaseMemoryLib
+ PcdLib
+ PrintLib
+
+[Guids]
+ gEfiVTUTF8Guid
+ gEfiVT100Guid
+ gEfiVT100PlusGuid
+ gEfiPcAnsiGuid
+ gEfiUartDevicePathGuid
+ gEfiSasDevicePathGuid
+
+[Protocols]
+ gEfiDevicePathProtocolGuid ## CONSUMES
+ gEfiDevicePathUtilitiesProtocolGuid ## CONSUMES
+ gEfiDevicePathToTextProtocolGuid ## CONSUMES
+ gEfiDevicePathFromTextProtocolGuid ## CONSUMES
+ gEfiDebugPortProtocolGuid ## SOMETIMES_CONSUMES ## GUID
+
+[Pcd]
+ gEfiMdePkgTokenSpaceGuid.PcdMaximumDevicePathNodeCount
+
+[Depex.common.DXE_DRIVER, Depex.common.DXE_RUNTIME_DRIVER, Depex.common.DXE_SAL_DRIVER, Depex.common.DXE_SMM_DRIVER]
+ gEfiDevicePathUtilitiesProtocolGuid \ No newline at end of file
diff --git a/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c b/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c
index 1052988..b73bcce 100644
--- a/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c
+++ b/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLib.c
@@ -2,7 +2,7 @@
Library instance that implement UEFI Device Path Library class based on protocol
gEfiDevicePathUtilitiesProtocolGuid.
- Copyright (c) 2006 - 2012, Intel Corporation. All rights reserved.<BR>
+ Copyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution. The full text of the license may be found at
@@ -17,6 +17,8 @@
#include <Uefi.h>
#include <Protocol/DevicePathUtilities.h>
+#include <Protocol/DevicePathToText.h>
+#include <Protocol/DevicePathFromText.h>
#include <Library/DevicePathLib.h>
#include <Library/DebugLib.h>
@@ -26,7 +28,9 @@
#include <Library/UefiBootServicesTableLib.h>
#include <Library/PcdLib.h>
-EFI_DEVICE_PATH_UTILITIES_PROTOCOL *mDevicePathUtilities = NULL;
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_UTILITIES_PROTOCOL *mDevicePathLibDevicePathUtilities = NULL;
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *mDevicePathLibDevicePathToText = NULL;
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_DEVICE_PATH_FROM_TEXT_PROTOCOL *mDevicePathLibDevicePathFromText = NULL;
//
// Template for an end-of-device path node.
@@ -64,11 +68,10 @@ DevicePathLibConstructor (
Status = gBS->LocateProtocol (
&gEfiDevicePathUtilitiesProtocolGuid,
NULL,
- (VOID**) &mDevicePathUtilities
+ (VOID**) &mDevicePathLibDevicePathUtilities
);
ASSERT_EFI_ERROR (Status);
- ASSERT (mDevicePathUtilities != NULL);
-
+ ASSERT (mDevicePathLibDevicePathUtilities != NULL);
return Status;
}
@@ -382,7 +385,7 @@ GetDevicePathSize (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
- return mDevicePathUtilities->GetDevicePathSize (DevicePath);
+ return mDevicePathLibDevicePathUtilities->GetDevicePathSize (DevicePath);
}
/**
@@ -408,7 +411,7 @@ DuplicateDevicePath (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
- return mDevicePathUtilities->DuplicateDevicePath (DevicePath);
+ return mDevicePathLibDevicePathUtilities->DuplicateDevicePath (DevicePath);
}
/**
@@ -442,7 +445,7 @@ AppendDevicePath (
IN CONST EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath OPTIONAL
)
{
- return mDevicePathUtilities->AppendDevicePath (FirstDevicePath, SecondDevicePath);
+ return mDevicePathLibDevicePathUtilities->AppendDevicePath (FirstDevicePath, SecondDevicePath);
}
/**
@@ -480,7 +483,7 @@ AppendDevicePathNode (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL
)
{
- return mDevicePathUtilities->AppendDeviceNode (DevicePath, DevicePathNode);
+ return mDevicePathLibDevicePathUtilities->AppendDeviceNode (DevicePath, DevicePathNode);
}
/**
@@ -513,7 +516,7 @@ AppendDevicePathInstance (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance OPTIONAL
)
{
- return mDevicePathUtilities->AppendDevicePathInstance (DevicePath, DevicePathInstance);
+ return mDevicePathLibDevicePathUtilities->AppendDevicePathInstance (DevicePath, DevicePathInstance);
}
/**
@@ -551,7 +554,7 @@ GetNextDevicePathInstance (
)
{
ASSERT (Size != NULL);
- return mDevicePathUtilities->GetNextDevicePathInstance (DevicePath, Size);
+ return mDevicePathLibDevicePathUtilities->GetNextDevicePathInstance (DevicePath, Size);
}
/**
@@ -582,7 +585,7 @@ CreateDeviceNode (
IN UINT16 NodeLength
)
{
- return mDevicePathUtilities->CreateDeviceNode (NodeType, NodeSubType, NodeLength);
+ return mDevicePathLibDevicePathUtilities->CreateDeviceNode (NodeType, NodeSubType, NodeLength);
}
/**
@@ -606,7 +609,7 @@ IsDevicePathMultiInstance (
IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
)
{
- return mDevicePathUtilities->IsDevicePathMultiInstance (DevicePath);
+ return mDevicePathLibDevicePathUtilities->IsDevicePathMultiInstance (DevicePath);
}
/**
@@ -698,3 +701,151 @@ FileDevicePath (
return DevicePath;
}
+
+/**
+ Locate and return the protocol instance identified by the ProtocolGuid.
+
+ @param ProtocolGuid The GUID of the protocol.
+
+ @return A pointer to the protocol instance or NULL when absent.
+**/
+VOID *
+UefiDevicePathLibLocateProtocol (
+ EFI_GUID *ProtocolGuid
+ )
+{
+ EFI_STATUS Status;
+ VOID *Protocol;
+ Status = gBS->LocateProtocol (
+ ProtocolGuid,
+ NULL,
+ (VOID**) &Protocol
+ );
+ if (EFI_ERROR (Status)) {
+ return NULL;
+ } else {
+ return Protocol;
+ }
+}
+
+/**
+ Converts a device node to its string representation.
+
+ @param DeviceNode A Pointer to the device node to be converted.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ @return A pointer to the allocated text representation of the device node or NULL if DeviceNode
+ is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+ConvertDeviceNodeToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ if (mDevicePathLibDevicePathToText == NULL) {
+ mDevicePathLibDevicePathToText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathToTextProtocolGuid);
+ }
+ if (mDevicePathLibDevicePathToText != NULL) {
+ return mDevicePathLibDevicePathToText->ConvertDeviceNodeToText (DeviceNode, DisplayOnly, AllowShortcuts);
+ } else {
+ return NULL;
+ }
+}
+
+/**
+ Converts a device path to its text representation.
+
+ @param DevicePath A Pointer to the device to be converted.
+ @param DisplayOnly If DisplayOnly is TRUE, then the shorter text representation
+ of the display node is used, where applicable. If DisplayOnly
+ is FALSE, then the longer text representation of the display node
+ is used.
+ @param AllowShortcuts If AllowShortcuts is TRUE, then the shortcut forms of text
+ representation for a device node can be used, where applicable.
+
+ @return A pointer to the allocated text representation of the device path or
+ NULL if DeviceNode is NULL or there was insufficient memory.
+
+**/
+CHAR16 *
+EFIAPI
+ConvertDevicePathToText (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN BOOLEAN DisplayOnly,
+ IN BOOLEAN AllowShortcuts
+ )
+{
+ if (mDevicePathLibDevicePathToText == NULL) {
+ mDevicePathLibDevicePathToText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathToTextProtocolGuid);
+ }
+ if (mDevicePathLibDevicePathToText != NULL) {
+ return mDevicePathLibDevicePathToText->ConvertDevicePathToText (DevicePath, DisplayOnly, AllowShortcuts);
+ } else {
+ return NULL;
+ }
+}
+
+/**
+ Convert text to the binary representation of a device node.
+
+ @param TextDeviceNode TextDeviceNode points to the text representation of a device
+ node. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the EFI device node or NULL if TextDeviceNode is NULL or there was
+ insufficient memory or text unsupported.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+ConvertTextToDeviceNode (
+ IN CONST CHAR16 *TextDeviceNode
+ )
+{
+ if (mDevicePathLibDevicePathFromText == NULL) {
+ mDevicePathLibDevicePathFromText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathFromTextProtocolGuid);
+ }
+ if (mDevicePathLibDevicePathFromText != NULL) {
+ return mDevicePathLibDevicePathFromText->ConvertTextToDeviceNode (TextDeviceNode);
+ } else {
+ return NULL;
+ }
+}
+
+/**
+ Convert text to the binary representation of a device path.
+
+
+ @param TextDevicePath TextDevicePath points to the text representation of a device
+ path. Conversion starts with the first character and continues
+ until the first non-device node character.
+
+ @return A pointer to the allocated device path or NULL if TextDeviceNode is NULL or
+ there was insufficient memory.
+
+**/
+EFI_DEVICE_PATH_PROTOCOL *
+EFIAPI
+ConvertTextToDevicePath (
+ IN CONST CHAR16 *TextDevicePath
+ )
+{
+ if (mDevicePathLibDevicePathFromText == NULL) {
+ mDevicePathLibDevicePathFromText = UefiDevicePathLibLocateProtocol (&gEfiDevicePathFromTextProtocolGuid);
+ }
+ if (mDevicePathLibDevicePathFromText != NULL) {
+ return mDevicePathLibDevicePathFromText->ConvertTextToDevicePath (TextDevicePath);
+ } else {
+ return NULL;
+ }
+}
+
diff --git a/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf b/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
index 16b47e3..48ae8d0 100644
--- a/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
+++ b/MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
@@ -22,7 +22,7 @@
FILE_GUID = 050EB8C6-C12E-4b86-892B-40985E8B3137
MODULE_TYPE = UEFI_DRIVER
VERSION_STRING = 1.0
- LIBRARY_CLASS = DevicePathLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER
+ LIBRARY_CLASS = DevicePathLib|DXE_DRIVER DXE_RUNTIME_DRIVER DXE_SAL_DRIVER DXE_SMM_DRIVER UEFI_APPLICATION UEFI_DRIVER SMM_CORE
CONSTRUCTOR = DevicePathLibConstructor
@@ -49,6 +49,8 @@
[Protocols]
gEfiDevicePathProtocolGuid ## CONSUMES
gEfiDevicePathUtilitiesProtocolGuid ## CONSUMES
+ gEfiDevicePathToTextProtocolGuid ## CONSUMES
+ gEfiDevicePathFromTextProtocolGuid ## CONSUMES
[Pcd]
gEfiMdePkgTokenSpaceGuid.PcdMaximumDevicePathNodeCount
diff --git a/MdePkg/MdePkg.dec b/MdePkg/MdePkg.dec
index 3de6ff5..b0d4c9d 100644
--- a/MdePkg/MdePkg.dec
+++ b/MdePkg/MdePkg.dec
@@ -683,6 +683,13 @@
## Include/Ppi/PiPcd.h
gEfiPeiPcdPpiGuid = { 0x1f34d25, 0x4de2, 0x23ad, { 0x3f, 0xf3, 0x36, 0x35, 0x3f, 0xf3, 0x23, 0xf1 } }
+ #
+ # PPIs defined in PI 1.3.
+ #
+
+ ## Include/Ppi/I2cMaster.h
+ gEfiPeiI2cMasterPpiGuid = { 0xb3bfab9b, 0x9f9c, 0x4e8b, { 0xad, 0x37, 0x7f, 0x8c, 0x51, 0xfc, 0x62, 0x80 }}
+
[Protocols]
#
# Protocols defined in PI1.0.
@@ -906,6 +913,25 @@
gEfiSmmEndOfDxeProtocolGuid = { 0x24e70042, 0xd5c5, 0x4260, { 0x8c, 0x39, 0xa, 0xd3, 0xaa, 0x32, 0xe9, 0x3d }}
#
+ # Protocols defined in PI 1.3.
+ #
+
+ ## Include/Protocol/I2cMaster.h
+ gEfiI2cMasterProtocolGuid = { 0xcd72881f, 0x45b5, 0x4feb, { 0x98, 0xc8, 0x31, 0x3d, 0xa8, 0x11, 0x74, 0x62 }}
+
+ ## Include/Protocol/I2cIo.h
+ gEfiI2cIoProtocolGuid = { 0xb60a3e6b, 0x18c4, 0x46e5, { 0xa2, 0x9a, 0xc9, 0xa1, 0x06, 0x65, 0xa2, 0x8e }}
+
+ ## Include/Protocol/I2cEnumerate.h
+ gEfiI2cEnumerateProtocolGuid = { 0xda8cd7c4, 0x1c00, 0x49e2, { 0x80, 0x3e, 0x52, 0x14, 0xe7, 0x01, 0x89, 0x4c }}
+
+ ## Include/Protocol/I2cHost.h
+ gEfiI2cHostProtocolGuid = { 0xa5aab9e3, 0xc727, 0x48cd, { 0x8b, 0xbf, 0x42, 0x72, 0x33, 0x85, 0x49, 0x48 }}
+
+ ## Include/Protocol/I2cBusConfigurationManagement.h
+ gEfiI2cBusConfigurationManagementProtocolGuid = { 0x55b71fb5, 0x17c6, 0x410e, { 0xb5, 0xbd, 0x5f, 0xa2, 0xe3, 0xd4, 0x46, 0x6b }}
+
+ #
# Protocols defined in UEFI2.1/UEFI2.0/EFI1.1
#
diff --git a/MdePkg/MdePkg.dsc b/MdePkg/MdePkg.dsc
index 0fd6fcb..092a67d 100644
--- a/MdePkg/MdePkg.dsc
+++ b/MdePkg/MdePkg.dsc
@@ -1,7 +1,7 @@
## @file
# EFI/PI MdePkg Package
#
-# Copyright (c) 2007 - 2011, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2007 - 2013, Intel Corporation. All rights reserved.<BR>
# Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.<BR>
#
# This program and the accompanying materials
@@ -113,6 +113,7 @@
MdePkg/Library/UefiDebugLibConOut/UefiDebugLibConOut.inf
MdePkg/Library/UefiDebugLibStdErr/UefiDebugLibStdErr.inf
MdePkg/Library/UefiDevicePathLib/UefiDevicePathLib.inf
+ MdePkg/Library/UefiDevicePathLib/UefiDevicePathLibOptionalDevicePathProtocol.inf
MdePkg/Library/UefiDevicePathLibDevicePathProtocol/UefiDevicePathLibDevicePathProtocol.inf
MdePkg/Library/UefiDriverEntryPoint/UefiDriverEntryPoint.inf
MdePkg/Library/UefiLib/UefiLib.inf