From 1de6ee1757ea287e5098d58288ba6eabebe380a6 Mon Sep 17 00:00:00 2001
From: Andrei Borzenkov <arvidjaar@gmail.com>
Date: Thu, 7 May 2015 20:37:16 +0300
Subject: [PATCH 5/9] efidisk: move device path helpers in core for efinet

---
 grub-core/disk/efi/efidisk.c | 59 +++++++-------------------------------------
 grub-core/kern/efi/efi.c     | 41 ++++++++++++++++++++++++++++++
 include/grub/efi/efi.h       |  4 +++
 3 files changed, 54 insertions(+), 50 deletions(-)

Index: grub-2.00/grub-core/disk/efi/efidisk.c
===================================================================
--- grub-2.00.orig/grub-core/disk/efi/efidisk.c
+++ grub-2.00/grub-core/disk/efi/efidisk.c
@@ -43,47 +43,6 @@ static struct grub_efidisk_data *fd_devi
 static struct grub_efidisk_data *hd_devices;
 static struct grub_efidisk_data *cd_devices;
 
-/* Duplicate a device path.  */
-static grub_efi_device_path_t *
-duplicate_device_path (const grub_efi_device_path_t *dp)
-{
-  grub_efi_device_path_t *p;
-  grub_size_t total_size = 0;
-
-  for (p = (grub_efi_device_path_t *) dp;
-       ;
-       p = GRUB_EFI_NEXT_DEVICE_PATH (p))
-    {
-      total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
-      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
-	break;
-    }
-
-  p = grub_malloc (total_size);
-  if (! p)
-    return 0;
-
-  grub_memcpy (p, dp, total_size);
-  return p;
-}
-
-/* Return the device path node right before the end node.  */
-static grub_efi_device_path_t *
-find_last_device_path (const grub_efi_device_path_t *dp)
-{
-  grub_efi_device_path_t *next, *p;
-
-  if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
-    return 0;
-
-  for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p);
-       ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next);
-       p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next))
-    ;
-
-  return p;
-}
-
 static struct grub_efidisk_data *
 make_devices (void)
 {
@@ -110,7 +69,7 @@ make_devices (void)
       if (! dp)
 	continue;
 
-      ldp = find_last_device_path (dp);
+      ldp = grub_efi_find_last_device_path (dp);
       if (! ldp)
 	/* This is empty. Why?  */
 	continue;
@@ -150,11 +109,11 @@ find_parent_device (struct grub_efidisk_
   grub_efi_device_path_t *dp, *ldp;
   struct grub_efidisk_data *parent;
 
-  dp = duplicate_device_path (d->device_path);
+  dp = grub_efi_duplicate_device_path (d->device_path);
   if (! dp)
     return 0;
 
-  ldp = find_last_device_path (dp);
+  ldp = grub_efi_find_last_device_path (dp);
   ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
   ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
   ldp->length = sizeof (*ldp);
@@ -184,11 +143,11 @@ iterate_child_devices (struct grub_efidi
     {
       grub_efi_device_path_t *dp, *ldp;
 
-      dp = duplicate_device_path (p->device_path);
+      dp = grub_efi_duplicate_device_path (p->device_path);
       if (! dp)
 	return 0;
 
-      ldp = find_last_device_path (dp);
+      ldp = grub_efi_find_last_device_path (dp);
       ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
       ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
       ldp->length = sizeof (*ldp);
@@ -217,8 +176,8 @@ add_device (struct grub_efidisk_data **d
     {
       int ret;
 
-      ret = grub_efi_compare_device_paths (find_last_device_path ((*p)->device_path),
-					   find_last_device_path (d->device_path));
+      ret = grub_efi_compare_device_paths (grub_efi_find_last_device_path ((*p)->device_path),
+					   grub_efi_find_last_device_path (d->device_path));
       if (ret == 0)
 	ret = grub_efi_compare_device_paths ((*p)->device_path,
 					     d->device_path);
@@ -762,7 +721,7 @@ grub_efidisk_get_device_name (grub_efi_h
   if (! dp)
     return 0;
 
-  ldp = find_last_device_path (dp);
+  ldp = grub_efi_find_last_device_path (dp);
   if (! ldp)
     return 0;
 
@@ -794,11 +753,11 @@ grub_efidisk_get_device_name (grub_efi_h
 
       /* It is necessary to duplicate the device path so that GRUB
 	 can overwrite it.  */
-      dup_dp = duplicate_device_path (dp);
+      dup_dp = grub_efi_duplicate_device_path (dp);
       if (! dup_dp)
 	return 0;
 
-      dup_ldp = find_last_device_path (dup_dp);
+      dup_ldp = grub_efi_find_last_device_path (dup_dp);
       dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
       dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
       dup_ldp->length = sizeof (*dup_ldp);
@@ -842,11 +801,11 @@ grub_efidisk_get_device_name (grub_efi_h
 
       /* It is necessary to duplicate the device path so that GRUB
 	   can overwrite it.  */
-      dup_dp = duplicate_device_path (dp);
+      dup_dp = grub_efi_duplicate_device_path (dp);
       if (! dup_dp)
 	    return 0;
 
-      dup_ldp = find_last_device_path (dup_dp);
+      dup_ldp = grub_efi_find_last_device_path (dup_dp);
       dup_ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
       dup_ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
       dup_ldp->length = 4;
Index: grub-2.00/grub-core/kern/efi/efi.c
===================================================================
--- grub-2.00.orig/grub-core/kern/efi/efi.c
+++ grub-2.00/grub-core/kern/efi/efi.c
@@ -371,6 +371,47 @@ grub_efi_get_device_path (grub_efi_handl
 				 GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
 }
 
+/* Return the device path node right before the end node.  */
+grub_efi_device_path_t *
+grub_efi_find_last_device_path (const grub_efi_device_path_t *dp)
+{
+  grub_efi_device_path_t *next, *p;
+
+  if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
+    return 0;
+
+  for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p);
+       ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next);
+       p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next))
+    ;
+
+  return p;
+}
+
+/* Duplicate a device path.  */
+grub_efi_device_path_t *
+grub_efi_duplicate_device_path (const grub_efi_device_path_t *dp)
+{
+  grub_efi_device_path_t *p;
+  grub_size_t total_size = 0;
+
+  for (p = (grub_efi_device_path_t *) dp;
+       ;
+       p = GRUB_EFI_NEXT_DEVICE_PATH (p))
+    {
+      total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
+      if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
+	break;
+    }
+
+  p = grub_malloc (total_size);
+  if (! p)
+    return 0;
+
+  grub_memcpy (p, dp, total_size);
+  return p;
+}
+
 /* Print the chain of Device Path nodes. This is mainly for debugging. */
 void
 grub_efi_print_device_path (grub_efi_device_path_t *dp)
Index: grub-2.00/include/grub/efi/efi.h
===================================================================
--- grub-2.00.orig/include/grub/efi/efi.h
+++ grub-2.00/include/grub/efi/efi.h
@@ -56,6 +56,10 @@ void EXPORT_FUNC(grub_efi_print_device_p
 char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp);
 grub_efi_device_path_t *
 EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle);
+grub_efi_device_path_t *
+EXPORT_FUNC(grub_efi_find_last_device_path) (const grub_efi_device_path_t *dp);
+grub_efi_device_path_t *
+EXPORT_FUNC(grub_efi_duplicate_device_path) (const grub_efi_device_path_t *dp);
 grub_err_t EXPORT_FUNC (grub_efi_finish_boot_services) (grub_efi_uintn_t *outbuf_size, void *outbuf,
 							grub_efi_uintn_t *map_key,
 							grub_efi_uintn_t *efi_desc_size,
