|
|
28f7f8 |
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
|
|
ecb9bb |
From: Andrei Borzenkov <arvidjaar@gmail.com>
|
|
|
ecb9bb |
Date: Thu, 7 May 2015 20:37:16 +0300
|
|
|
28f7f8 |
Subject: [PATCH] efidisk: move device path helpers in core for efinet
|
|
|
ecb9bb |
|
|
|
ecb9bb |
---
|
|
|
ecb9bb |
grub-core/disk/efi/efidisk.c | 61 ++++++++------------------------------------
|
|
|
ecb9bb |
grub-core/kern/efi/efi.c | 41 +++++++++++++++++++++++++++++
|
|
|
ecb9bb |
include/grub/efi/efi.h | 4 +++
|
|
|
ecb9bb |
3 files changed, 55 insertions(+), 51 deletions(-)
|
|
|
ecb9bb |
|
|
|
ecb9bb |
diff --git a/grub-core/disk/efi/efidisk.c b/grub-core/disk/efi/efidisk.c
|
|
|
28f7f8 |
index 3b12c349923..845c66fa9ab 100644
|
|
|
ecb9bb |
--- a/grub-core/disk/efi/efidisk.c
|
|
|
ecb9bb |
+++ b/grub-core/disk/efi/efidisk.c
|
|
|
ecb9bb |
@@ -43,47 +43,6 @@ static struct grub_efidisk_data *fd_devices;
|
|
|
ecb9bb |
static struct grub_efidisk_data *hd_devices;
|
|
|
ecb9bb |
static struct grub_efidisk_data *cd_devices;
|
|
|
ecb9bb |
|
|
|
ecb9bb |
-/* Duplicate a device path. */
|
|
|
ecb9bb |
-static grub_efi_device_path_t *
|
|
|
ecb9bb |
-duplicate_device_path (const grub_efi_device_path_t *dp)
|
|
|
ecb9bb |
-{
|
|
|
ecb9bb |
- grub_efi_device_path_t *p;
|
|
|
ecb9bb |
- grub_size_t total_size = 0;
|
|
|
ecb9bb |
-
|
|
|
ecb9bb |
- for (p = (grub_efi_device_path_t *) dp;
|
|
|
ecb9bb |
- ;
|
|
|
ecb9bb |
- p = GRUB_EFI_NEXT_DEVICE_PATH (p))
|
|
|
ecb9bb |
- {
|
|
|
ecb9bb |
- total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
|
|
|
ecb9bb |
- if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
|
|
|
ecb9bb |
- break;
|
|
|
ecb9bb |
- }
|
|
|
ecb9bb |
-
|
|
|
ecb9bb |
- p = grub_malloc (total_size);
|
|
|
ecb9bb |
- if (! p)
|
|
|
ecb9bb |
- return 0;
|
|
|
ecb9bb |
-
|
|
|
ecb9bb |
- grub_memcpy (p, dp, total_size);
|
|
|
ecb9bb |
- return p;
|
|
|
ecb9bb |
-}
|
|
|
ecb9bb |
-
|
|
|
ecb9bb |
-/* Return the device path node right before the end node. */
|
|
|
ecb9bb |
-static grub_efi_device_path_t *
|
|
|
ecb9bb |
-find_last_device_path (const grub_efi_device_path_t *dp)
|
|
|
ecb9bb |
-{
|
|
|
ecb9bb |
- grub_efi_device_path_t *next, *p;
|
|
|
ecb9bb |
-
|
|
|
ecb9bb |
- if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
|
|
|
ecb9bb |
- return 0;
|
|
|
ecb9bb |
-
|
|
|
ecb9bb |
- for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p);
|
|
|
ecb9bb |
- ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next);
|
|
|
ecb9bb |
- p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next))
|
|
|
ecb9bb |
- ;
|
|
|
ecb9bb |
-
|
|
|
ecb9bb |
- return p;
|
|
|
ecb9bb |
-}
|
|
|
ecb9bb |
-
|
|
|
ecb9bb |
static struct grub_efidisk_data *
|
|
|
ecb9bb |
make_devices (void)
|
|
|
ecb9bb |
{
|
|
|
ecb9bb |
@@ -110,7 +69,7 @@ make_devices (void)
|
|
|
ecb9bb |
if (! dp)
|
|
|
ecb9bb |
continue;
|
|
|
ecb9bb |
|
|
|
ecb9bb |
- ldp = find_last_device_path (dp);
|
|
|
ecb9bb |
+ ldp = grub_efi_find_last_device_path (dp);
|
|
|
ecb9bb |
if (! ldp)
|
|
|
ecb9bb |
/* This is empty. Why? */
|
|
|
ecb9bb |
continue;
|
|
|
ecb9bb |
@@ -150,11 +109,11 @@ find_parent_device (struct grub_efidisk_data *devices,
|
|
|
ecb9bb |
grub_efi_device_path_t *dp, *ldp;
|
|
|
ecb9bb |
struct grub_efidisk_data *parent;
|
|
|
ecb9bb |
|
|
|
ecb9bb |
- dp = duplicate_device_path (d->device_path);
|
|
|
ecb9bb |
+ dp = grub_efi_duplicate_device_path (d->device_path);
|
|
|
ecb9bb |
if (! dp)
|
|
|
ecb9bb |
return 0;
|
|
|
ecb9bb |
|
|
|
ecb9bb |
- ldp = find_last_device_path (dp);
|
|
|
ecb9bb |
+ ldp = grub_efi_find_last_device_path (dp);
|
|
|
ecb9bb |
ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
|
|
ecb9bb |
ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
|
|
ecb9bb |
ldp->length = sizeof (*ldp);
|
|
|
ecb9bb |
@@ -180,11 +139,11 @@ is_child (struct grub_efidisk_data *child,
|
|
|
ecb9bb |
grub_efi_device_path_t *dp, *ldp;
|
|
|
ecb9bb |
int ret;
|
|
|
ecb9bb |
|
|
|
ecb9bb |
- dp = duplicate_device_path (child->device_path);
|
|
|
ecb9bb |
+ dp = grub_efi_duplicate_device_path (child->device_path);
|
|
|
ecb9bb |
if (! dp)
|
|
|
ecb9bb |
return 0;
|
|
|
ecb9bb |
|
|
|
ecb9bb |
- ldp = find_last_device_path (dp);
|
|
|
ecb9bb |
+ ldp = grub_efi_find_last_device_path (dp);
|
|
|
ecb9bb |
ldp->type = GRUB_EFI_END_DEVICE_PATH_TYPE;
|
|
|
ecb9bb |
ldp->subtype = GRUB_EFI_END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
|
|
ecb9bb |
ldp->length = sizeof (*ldp);
|
|
|
ecb9bb |
@@ -207,8 +166,8 @@ add_device (struct grub_efidisk_data **devices, struct grub_efidisk_data *d)
|
|
|
ecb9bb |
{
|
|
|
ecb9bb |
int ret;
|
|
|
ecb9bb |
|
|
|
ecb9bb |
- ret = grub_efi_compare_device_paths (find_last_device_path ((*p)->device_path),
|
|
|
ecb9bb |
- find_last_device_path (d->device_path));
|
|
|
ecb9bb |
+ ret = grub_efi_compare_device_paths (grub_efi_find_last_device_path ((*p)->device_path),
|
|
|
ecb9bb |
+ grub_efi_find_last_device_path (d->device_path));
|
|
|
ecb9bb |
if (ret == 0)
|
|
|
ecb9bb |
ret = grub_efi_compare_device_paths ((*p)->device_path,
|
|
|
ecb9bb |
d->device_path);
|
|
|
ecb9bb |
@@ -795,7 +754,7 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
|
|
|
ecb9bb |
if (! dp)
|
|
|
ecb9bb |
return 0;
|
|
|
ecb9bb |
|
|
|
ecb9bb |
- ldp = find_last_device_path (dp);
|
|
|
ecb9bb |
+ ldp = grub_efi_find_last_device_path (dp);
|
|
|
ecb9bb |
if (! ldp)
|
|
|
ecb9bb |
return 0;
|
|
|
ecb9bb |
|
|
|
ecb9bb |
@@ -811,14 +770,14 @@ grub_efidisk_get_device_name (grub_efi_handle_t *handle)
|
|
|
ecb9bb |
|
|
|
ecb9bb |
/* It is necessary to duplicate the device path so that GRUB
|
|
|
ecb9bb |
can overwrite it. */
|
|
|
ecb9bb |
- dup_dp = duplicate_device_path (dp);
|
|
|
ecb9bb |
+ dup_dp = grub_efi_duplicate_device_path (dp);
|
|
|
ecb9bb |
if (! dup_dp)
|
|
|
ecb9bb |
return 0;
|
|
|
ecb9bb |
|
|
|
ecb9bb |
while (1)
|
|
|
ecb9bb |
{
|
|
|
ecb9bb |
grub_efi_device_path_t *dup_ldp;
|
|
|
ecb9bb |
- dup_ldp = find_last_device_path (dup_dp);
|
|
|
ecb9bb |
+ dup_ldp = grub_efi_find_last_device_path (dup_dp);
|
|
|
ecb9bb |
if (!(GRUB_EFI_DEVICE_PATH_TYPE (dup_ldp) == GRUB_EFI_MEDIA_DEVICE_PATH_TYPE
|
|
|
ecb9bb |
&& (GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_CDROM_DEVICE_PATH_SUBTYPE
|
|
|
ecb9bb |
|| GRUB_EFI_DEVICE_PATH_SUBTYPE (dup_ldp) == GRUB_EFI_HARD_DRIVE_DEVICE_PATH_SUBTYPE)))
|
|
|
ecb9bb |
diff --git a/grub-core/kern/efi/efi.c b/grub-core/kern/efi/efi.c
|
|
|
28f7f8 |
index d99a6fbdf0d..c80d85b677e 100644
|
|
|
ecb9bb |
--- a/grub-core/kern/efi/efi.c
|
|
|
ecb9bb |
+++ b/grub-core/kern/efi/efi.c
|
|
|
ecb9bb |
@@ -423,6 +423,47 @@ grub_efi_get_device_path (grub_efi_handle_t handle)
|
|
|
ecb9bb |
GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
|
|
ecb9bb |
}
|
|
|
ecb9bb |
|
|
|
ecb9bb |
+/* Return the device path node right before the end node. */
|
|
|
ecb9bb |
+grub_efi_device_path_t *
|
|
|
ecb9bb |
+grub_efi_find_last_device_path (const grub_efi_device_path_t *dp)
|
|
|
ecb9bb |
+{
|
|
|
ecb9bb |
+ grub_efi_device_path_t *next, *p;
|
|
|
ecb9bb |
+
|
|
|
ecb9bb |
+ if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (dp))
|
|
|
ecb9bb |
+ return 0;
|
|
|
ecb9bb |
+
|
|
|
ecb9bb |
+ for (p = (grub_efi_device_path_t *) dp, next = GRUB_EFI_NEXT_DEVICE_PATH (p);
|
|
|
ecb9bb |
+ ! GRUB_EFI_END_ENTIRE_DEVICE_PATH (next);
|
|
|
ecb9bb |
+ p = next, next = GRUB_EFI_NEXT_DEVICE_PATH (next))
|
|
|
ecb9bb |
+ ;
|
|
|
ecb9bb |
+
|
|
|
ecb9bb |
+ return p;
|
|
|
ecb9bb |
+}
|
|
|
ecb9bb |
+
|
|
|
ecb9bb |
+/* Duplicate a device path. */
|
|
|
ecb9bb |
+grub_efi_device_path_t *
|
|
|
ecb9bb |
+grub_efi_duplicate_device_path (const grub_efi_device_path_t *dp)
|
|
|
ecb9bb |
+{
|
|
|
ecb9bb |
+ grub_efi_device_path_t *p;
|
|
|
ecb9bb |
+ grub_size_t total_size = 0;
|
|
|
ecb9bb |
+
|
|
|
ecb9bb |
+ for (p = (grub_efi_device_path_t *) dp;
|
|
|
ecb9bb |
+ ;
|
|
|
ecb9bb |
+ p = GRUB_EFI_NEXT_DEVICE_PATH (p))
|
|
|
ecb9bb |
+ {
|
|
|
ecb9bb |
+ total_size += GRUB_EFI_DEVICE_PATH_LENGTH (p);
|
|
|
ecb9bb |
+ if (GRUB_EFI_END_ENTIRE_DEVICE_PATH (p))
|
|
|
ecb9bb |
+ break;
|
|
|
ecb9bb |
+ }
|
|
|
ecb9bb |
+
|
|
|
ecb9bb |
+ p = grub_malloc (total_size);
|
|
|
ecb9bb |
+ if (! p)
|
|
|
ecb9bb |
+ return 0;
|
|
|
ecb9bb |
+
|
|
|
ecb9bb |
+ grub_memcpy (p, dp, total_size);
|
|
|
ecb9bb |
+ return p;
|
|
|
ecb9bb |
+}
|
|
|
ecb9bb |
+
|
|
|
ecb9bb |
static void
|
|
|
ecb9bb |
dump_vendor_path (const char *type, grub_efi_vendor_device_path_t *vendor)
|
|
|
ecb9bb |
{
|
|
|
ecb9bb |
diff --git a/include/grub/efi/efi.h b/include/grub/efi/efi.h
|
|
|
28f7f8 |
index a000c383e81..22456327e13 100644
|
|
|
ecb9bb |
--- a/include/grub/efi/efi.h
|
|
|
ecb9bb |
+++ b/include/grub/efi/efi.h
|
|
|
ecb9bb |
@@ -56,6 +56,10 @@ void EXPORT_FUNC(grub_efi_print_device_path) (grub_efi_device_path_t *dp);
|
|
|
ecb9bb |
char *EXPORT_FUNC(grub_efi_get_filename) (grub_efi_device_path_t *dp);
|
|
|
ecb9bb |
grub_efi_device_path_t *
|
|
|
ecb9bb |
EXPORT_FUNC(grub_efi_get_device_path) (grub_efi_handle_t handle);
|
|
|
ecb9bb |
+grub_efi_device_path_t *
|
|
|
ecb9bb |
+EXPORT_FUNC(grub_efi_find_last_device_path) (const grub_efi_device_path_t *dp);
|
|
|
ecb9bb |
+grub_efi_device_path_t *
|
|
|
ecb9bb |
+EXPORT_FUNC(grub_efi_duplicate_device_path) (const grub_efi_device_path_t *dp);
|
|
|
ecb9bb |
grub_err_t EXPORT_FUNC (grub_efi_finish_boot_services) (grub_efi_uintn_t *outbuf_size, void *outbuf,
|
|
|
ecb9bb |
grub_efi_uintn_t *map_key,
|
|
|
ecb9bb |
grub_efi_uintn_t *efi_desc_size,
|