summaryrefslogtreecommitdiff
path: root/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c
diff options
context:
space:
mode:
authorljin6 <ljin6@6f19259b-4bc3-4df7-8a09-765794883524>2006-07-18 04:13:40 +0000
committerljin6 <ljin6@6f19259b-4bc3-4df7-8a09-765794883524>2006-07-18 04:13:40 +0000
commit562d28495df348923812281161e64bc9514e15e6 (patch)
tree121f4f3c37c23b23a4dabe21cf4fc46c78a0c5b3 /EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c
parent4b9fc76f7bba0d847d36cb2070a2d3305ae87acc (diff)
downloadedk2-platforms-562d28495df348923812281161e64bc9514e15e6.tar.xz
Add DevicePathUtilities DevicePathToText DevciePathFromText USB2HostController protocols
git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@1037 6f19259b-4bc3-4df7-8a09-765794883524
Diffstat (limited to 'EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c')
-rw-r--r--EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c421
1 files changed, 421 insertions, 0 deletions
diff --git a/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c
new file mode 100644
index 0000000000..2b54c76832
--- /dev/null
+++ b/EdkModulePkg/Universal/DevicePath/Dxe/DevicePathUtilities.c
@@ -0,0 +1,421 @@
+/*++
+
+Copyright (c) 2006, Intel Corporation
+All rights reserved. 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.
+
+Module Name:
+
+ DevicePathUtilities.c
+
+Abstract:
+
+ Implementation file for Device Path Utilities Protocol
+
+--*/
+
+#include <protocol/DevicePathUtilities.h>
+#include <protocol/DevicePath.h>
+#include "DevicePath.h"
+
+UINTN
+GetDevicePathSize (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+ Routine Description:
+ Returns the size of the device path, in bytes.
+
+ Arguments:
+ DevicePath - Points to the start of the EFI device path.
+
+ Returns:
+ Size - Size of the specified device path, in bytes, including the end-of-path tag.
+
+--*/
+{
+ CONST EFI_DEVICE_PATH_PROTOCOL *Start;
+
+ if (DevicePath == NULL) {
+ return 0;
+ }
+
+ //
+ // Search for the end of the device path structure
+ //
+ Start = (EFI_DEVICE_PATH_PROTOCOL *) 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) + sizeof (EFI_DEVICE_PATH_PROTOCOL);
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+DuplicateDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+ Routine Description:
+ Create a duplicate of the specified path.
+
+ Arguments:
+ DevicePath - Points to the source EFI device path.
+
+ Returns:
+ Pointer - A pointer to the duplicate device path.
+ NULL - Insufficient memory.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ UINTN Size;
+
+ if (DevicePath == NULL) {
+ return NULL;
+ }
+
+ //
+ // Compute the size
+ //
+ Size = GetDevicePathSize (DevicePath);
+ if (Size == 0) {
+ return NULL;
+ }
+
+ //
+ // Allocate space for duplicate device path
+ //
+ NewDevicePath = AllocateCopyPool (Size, (VOID *) DevicePath);
+
+ return NewDevicePath;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePath (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *Src1,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *Src2
+ )
+/*++
+
+ Routine Description:
+ Create a new path by appending the second device path to the first.
+
+ Arguments:
+ Src1 - Points to the first device path. If NULL, then it is ignored.
+ Src2 - Points to the second device path. If NULL, then it is ignored.
+
+ Returns:
+ Pointer - A pointer to the newly created device path.
+ NULL - Memory could not be allocated
+ or either DevicePath or DeviceNode is NULL.
+
+--*/
+{
+ UINTN Size;
+ UINTN Size1;
+ UINTN Size2;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ EFI_DEVICE_PATH_PROTOCOL *SecondDevicePath;
+
+ //
+ // If there's only 1 path, just duplicate it
+ //
+ if (Src1 == NULL) {
+ ASSERT (!IsDevicePathUnpacked (Src2));
+ return DuplicateDevicePath (Src2);
+ }
+
+ if (Src2 == NULL) {
+ ASSERT (!IsDevicePathUnpacked (Src1));
+ return DuplicateDevicePath (Src1);
+ }
+
+ //
+ // Allocate space for the combined device path. It only has one end node of
+ // length EFI_DEVICE_PATH_PROTOCOL
+ //
+ Size1 = GetDevicePathSize (Src1);
+ Size2 = GetDevicePathSize (Src2);
+ Size = Size1 + Size2 - sizeof (EFI_DEVICE_PATH_PROTOCOL);
+
+ NewDevicePath = AllocateCopyPool (Size, (VOID *) Src1);
+
+ if (NewDevicePath != NULL) {
+ //
+ // Over write Src1 EndNode and do the copy
+ //
+ SecondDevicePath = (EFI_DEVICE_PATH_PROTOCOL *) ((CHAR8 *) NewDevicePath + (Size1 - sizeof (EFI_DEVICE_PATH_PROTOCOL)));
+ CopyMem (SecondDevicePath, (VOID *) Src2, Size2);
+ }
+
+ return NewDevicePath;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDeviceNode (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DeviceNode
+ )
+/*++
+
+ Routine Description:
+ Creates a new path by appending the device node to the device path.
+
+ Arguments:
+ DevicePath - Points to the device path.
+ DeviceNode - Points to the device node.
+
+ Returns:
+ Pointer - A pointer to the allocated device node.
+ NULL - Memory could not be allocated
+ or either DevicePath or DeviceNode is NULL.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *Temp;
+ EFI_DEVICE_PATH_PROTOCOL *NextNode;
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
+ UINTN NodeLength;
+
+ if ((DevicePath == NULL) || (DeviceNode == NULL)) {
+ return NULL;
+ }
+
+ //
+ // Build a Node that has a terminator on it
+ //
+ NodeLength = DevicePathNodeLength (DeviceNode);
+
+ Temp = AllocateCopyPool (NodeLength + sizeof (EFI_DEVICE_PATH_PROTOCOL), (VOID *) DeviceNode);
+ if (Temp == NULL) {
+ return NULL;
+ }
+
+ //
+ // Add and end device path node to convert Node to device path
+ //
+ NextNode = NextDevicePathNode (Temp);
+ SetDevicePathEndNode (NextNode);
+
+ //
+ // Append device paths
+ //
+ NewDevicePath = AppendDevicePath (DevicePath, Temp);
+ gBS->FreePool (Temp);
+ return NewDevicePath;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+AppendDevicePathInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath,
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathInstance
+ )
+/*++
+
+ Routine Description:
+ Creates a new path by appending the specified device path instance to the specified device path.
+
+ Arguments:
+ DevicePath - Points to the device path. If NULL, then ignored.
+ DevicePathInstance - Points to the device path instance.
+
+ Returns:
+ Pointer - A pointer to the newly created device path
+ NULL - Memory could not be allocated or DevicePathInstance is NULL.
+
+--*/
+{
+ UINT8 *Ptr;
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+ UINTN SrcSize;
+ UINTN InstanceSize;
+
+ if (DevicePathInstance == NULL) {
+ return NULL;
+ }
+
+ if (DevicePath == NULL) {
+ return DuplicateDevicePath (DevicePathInstance);
+ }
+
+ SrcSize = GetDevicePathSize (DevicePath);
+ InstanceSize = GetDevicePathSize (DevicePathInstance);
+
+ Ptr = AllocateCopyPool (SrcSize + InstanceSize, (VOID *) DevicePath);
+ if (Ptr != NULL) {
+
+ DevPath = (EFI_DEVICE_PATH_PROTOCOL *) (Ptr + (SrcSize - sizeof (EFI_DEVICE_PATH_PROTOCOL)));
+ //
+ // Convert the End to an End Instance, since we are
+ // appending another instacne after this one its a good
+ // idea.
+ //
+ DevPath->SubType = END_INSTANCE_DEVICE_PATH_SUBTYPE;
+
+ DevPath = NextDevicePathNode (DevPath);
+ CopyMem (DevPath, (VOID *) DevicePathInstance, InstanceSize);
+ }
+
+ return (EFI_DEVICE_PATH_PROTOCOL *) Ptr;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+GetNextDevicePathInstance (
+ IN OUT EFI_DEVICE_PATH_PROTOCOL **DevicePathInstance,
+ OUT UINTN *DevicePathInstanceSize
+ )
+/*++
+
+ Routine Description:
+ Creates a copy of the current device path instance and returns a pointer to the next device path instance.
+
+ Arguments:
+ DevicePathInstance - 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.
+ DevicePathInstanceSize - On output, this holds the size of the device path instance,
+ in bytes or zero, if DevicePathInstance is zero.
+
+ Returns:
+ Pointer - A pointer to the copy of the current device path instance.
+ NULL - DevicePathInstace was NULL on entry or there was insufficient memory.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *DevPath;
+ EFI_DEVICE_PATH_PROTOCOL *ReturnValue;
+ UINT8 Temp;
+
+ if (*DevicePathInstance == NULL) {
+ if (DevicePathInstanceSize != NULL) {
+ *DevicePathInstanceSize = 0;
+ }
+
+ return NULL;
+ }
+
+ //
+ // Find the end of the device path instance
+ //
+ DevPath = *DevicePathInstance;
+ while (!IsDevicePathEndType (DevPath)) {
+ DevPath = NextDevicePathNode (DevPath);
+ }
+
+ //
+ // Compute the size of the device path instance
+ //
+ if (DevicePathInstanceSize != NULL) {
+ *DevicePathInstanceSize = ((UINTN) DevPath - (UINTN) (*DevicePathInstance)) + 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 (*DevicePathInstance);
+ 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) {
+ *DevicePathInstance = NULL;
+ } else {
+ *DevicePathInstance = NextDevicePathNode (DevPath);
+ }
+
+ return ReturnValue;
+}
+
+BOOLEAN
+IsDevicePathMultiInstance (
+ IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath
+ )
+/*++
+
+ Routine Description:
+ Returns whether a device path is multi-instance.
+
+ Arguments:
+ DevicePath - Points to the device path. If NULL, then ignored.
+
+ Returns:
+ TRUE - The device path has more than one instance
+ FALSE - The device path is empty or contains only a single instance.
+
+--*/
+{
+ CONST EFI_DEVICE_PATH_PROTOCOL *Node;
+
+ if (DevicePath == NULL) {
+ return FALSE;
+ }
+
+ Node = DevicePath;
+ while (!IsDevicePathEnd (Node)) {
+ if (EfiIsDevicePathEndInstance (Node)) {
+ return TRUE;
+ }
+
+ Node = NextDevicePathNode (Node);
+ }
+
+ return FALSE;
+}
+
+EFI_DEVICE_PATH_PROTOCOL *
+CreateDeviceNode (
+ IN UINT8 NodeType,
+ IN UINT8 NodeSubType,
+ IN UINT16 NodeLength
+ )
+/*++
+
+ Routine Description:
+ Creates a device node
+
+ Arguments:
+ NodeType - NodeType is the device node type (EFI_DEVICE_PATH.Type) for
+ the new device node.
+ NodeSubType - NodeSubType is the device node sub-type
+ EFI_DEVICE_PATH.SubType) for the new device node.
+ NodeLength - NodeLength is the length of the device node
+ (EFI_DEVICE_PATH.Length) for the new device node.
+
+ Returns:
+ Pointer - A pointer to the newly created device node.
+ NULL - NodeLength is less than
+ the size of the header or there was insufficient memory.
+
+--*/
+{
+ EFI_DEVICE_PATH_PROTOCOL *Node;
+
+ if (NodeLength < sizeof (EFI_DEVICE_PATH_PROTOCOL)) {
+ return NULL;
+ }
+
+ Node = (EFI_DEVICE_PATH_PROTOCOL *) AllocateZeroPool ((UINTN) NodeLength);
+ if (Node != NULL) {
+ Node->Type = NodeType;
+ Node->SubType = NodeSubType;
+ SetDevicePathNodeLength (Node, NodeLength);
+ }
+
+ return Node;
+}