All of lore.kernel.org
 help / color / mirror / Atom feed
From: Heinrich Schuchardt <xypron.glpk@gmx.de>
To: u-boot@lists.denx.de
Subject: [U-Boot] [PATCH v3 04/18] efi_loader: fix efi_convert_device_node_to_text
Date: Sun, 26 Nov 2017 14:05:09 +0100	[thread overview]
Message-ID: <20171126130523.4993-5-xypron.glpk@gmx.de> (raw)
In-Reply-To: <20171126130523.4993-1-xypron.glpk@gmx.de>

We need to implement to different functions for the
EFI_DEVICE_PATH_TO_TEXT_PROTOCOL:
ConvertDeviceNodeToText
ConvertDevicePathToText

A recent patch screwed up efi_convert_device_node_to_text
to expect a device path and not a node.

The patch makes both service functions work again.

efi_convert_device_node_to_text is renamed to
efi_convert_single_device_node_to_text and
efi_convert_device_node_to_text_ext is renamed to
efi_convert_device_node_to_text to avoid future
confusion.

A test of ConvertDeviceNodeToText will be provided in
a follow-up patch.

Fixes: adae4313cdd efi_loader: flesh out device-path to text
Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
---
v3
	Correctly handle NULL values.
v2
	no change
---
 lib/efi_loader/efi_device_path_to_text.c | 154 ++++++++++++++++++-------------
 1 file changed, 88 insertions(+), 66 deletions(-)

diff --git a/lib/efi_loader/efi_device_path_to_text.c b/lib/efi_loader/efi_device_path_to_text.c
index ad248cb492..43af5dfd8d 100644
--- a/lib/efi_loader/efi_device_path_to_text.c
+++ b/lib/efi_loader/efi_device_path_to_text.c
@@ -12,12 +12,31 @@
 #define MAC_OUTPUT_LEN 22
 #define UNKNOWN_OUTPUT_LEN 23
 
+#define MAX_NODE_LEN 512
+#define MAX_PATH_LEN 1024
+
 const efi_guid_t efi_guid_device_path_to_text_protocol =
 		EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID;
 
+static u16 *efi_str_to_u16(char *str)
+{
+	efi_uintn_t len;
+	u16 *out;
+	efi_status_t ret;
+
+	len = strlen(str) + 1;
+	ret = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, len * sizeof(u16),
+				(void **)&out);
+	if (ret != EFI_SUCCESS)
+		return NULL;
+	ascii2unicode(out, str);
+	out[len - 1] = 0;
+	return out;
+}
+
 static char *dp_unknown(char *s, struct efi_device_path *dp)
 {
-	s += sprintf(s, "/UNKNOWN(%04x,%04x)", dp->type, dp->sub_type);
+	s += sprintf(s, "UNKNOWN(%04x,%04x)", dp->type, dp->sub_type);
 	return s;
 }
 
@@ -27,7 +46,7 @@ static char *dp_hardware(char *s, struct efi_device_path *dp)
 	case DEVICE_PATH_SUB_TYPE_MEMORY: {
 		struct efi_device_path_memory *mdp =
 			(struct efi_device_path_memory *)dp;
-		s += sprintf(s, "/MemoryMapped(0x%x,0x%llx,0x%llx)",
+		s += sprintf(s, "MemoryMapped(0x%x,0x%llx,0x%llx)",
 			     mdp->memory_type,
 			     mdp->start_address,
 			     mdp->end_address);
@@ -36,7 +55,7 @@ static char *dp_hardware(char *s, struct efi_device_path *dp)
 	case DEVICE_PATH_SUB_TYPE_VENDOR: {
 		struct efi_device_path_vendor *vdp =
 			(struct efi_device_path_vendor *)dp;
-		s += sprintf(s, "/VenHw(%pUl)", &vdp->guid);
+		s += sprintf(s, "VenHw(%pUl)", &vdp->guid);
 		break;
 	}
 	default:
@@ -52,7 +71,7 @@ static char *dp_acpi(char *s, struct efi_device_path *dp)
 	case DEVICE_PATH_SUB_TYPE_ACPI_DEVICE: {
 		struct efi_device_path_acpi_path *adp =
 			(struct efi_device_path_acpi_path *)dp;
-		s += sprintf(s, "/Acpi(PNP%04x", EISA_PNP_NUM(adp->hid));
+		s += sprintf(s, "Acpi(PNP%04x", EISA_PNP_NUM(adp->hid));
 		if (adp->uid)
 			s += sprintf(s, ",%d", adp->uid);
 		s += sprintf(s, ")");
@@ -71,7 +90,7 @@ static char *dp_msging(char *s, struct efi_device_path *dp)
 	case DEVICE_PATH_SUB_TYPE_MSG_USB: {
 		struct efi_device_path_usb *udp =
 			(struct efi_device_path_usb *)dp;
-		s += sprintf(s, "/Usb(0x%x,0x%x)", udp->parent_port_number,
+		s += sprintf(s, "Usb(0x%x,0x%x)", udp->parent_port_number,
 			     udp->usb_interface);
 		break;
 	}
@@ -82,7 +101,7 @@ static char *dp_msging(char *s, struct efi_device_path *dp)
 		if (mdp->if_type != 0 && mdp->if_type != 1)
 			break;
 
-		s += sprintf(s, "/MAC(%02x%02x%02x%02x%02x%02x,0x%1x)",
+		s += sprintf(s, "MAC(%02x%02x%02x%02x%02x%02x,0x%1x)",
 			mdp->mac.addr[0], mdp->mac.addr[1],
 			mdp->mac.addr[2], mdp->mac.addr[3],
 			mdp->mac.addr[4], mdp->mac.addr[5],
@@ -94,7 +113,7 @@ static char *dp_msging(char *s, struct efi_device_path *dp)
 		struct efi_device_path_usb_class *ucdp =
 			(struct efi_device_path_usb_class *)dp;
 
-		s += sprintf(s, "/USBClass(%x,%x,%x,%x,%x)",
+		s += sprintf(s, "USBClass(%x,%x,%x,%x,%x)",
 			ucdp->vendor_id, ucdp->product_id,
 			ucdp->device_class, ucdp->device_subclass,
 			ucdp->device_protocol);
@@ -108,7 +127,7 @@ static char *dp_msging(char *s, struct efi_device_path *dp)
 					"SDCard" : "MMC";
 		struct efi_device_path_sd_mmc_path *sddp =
 			(struct efi_device_path_sd_mmc_path *)dp;
-		s += sprintf(s, "/%s(Slot%u)", typename, sddp->slot_number);
+		s += sprintf(s, "%s(Slot%u)", typename, sddp->slot_number);
 		break;
 	}
 	default:
@@ -128,15 +147,15 @@ static char *dp_media(char *s, struct efi_device_path *dp)
 
 		switch (hddp->signature_type) {
 		case SIG_TYPE_MBR:
-			s += sprintf(s, "/HD(Part%d,Sig%08x)",
+			s += sprintf(s, "HD(Part%d,Sig%08x)",
 				     hddp->partition_number,
 				     *(uint32_t *)sig);
 			break;
 		case SIG_TYPE_GUID:
-			s += sprintf(s, "/HD(Part%d,Sig%pUl)",
+			s += sprintf(s, "HD(Part%d,Sig%pUl)",
 				     hddp->partition_number, sig);
 		default:
-			s += sprintf(s, "/HD(Part%d,MBRType=%02x,SigType=%02x)",
+			s += sprintf(s, "HD(Part%d,MBRType=%02x,SigType=%02x)",
 				     hddp->partition_number, hddp->partmap_type,
 				     hddp->signature_type);
 		}
@@ -146,14 +165,16 @@ static char *dp_media(char *s, struct efi_device_path *dp)
 	case DEVICE_PATH_SUB_TYPE_CDROM_PATH: {
 		struct efi_device_path_cdrom_path *cddp =
 			(struct efi_device_path_cdrom_path *)dp;
-		s += sprintf(s, "/CDROM(0x%x)", cddp->boot_entry);
+		s += sprintf(s, "CDROM(0x%x)", cddp->boot_entry);
 		break;
 	}
 	case DEVICE_PATH_SUB_TYPE_FILE_PATH: {
 		struct efi_device_path_file_path *fp =
 			(struct efi_device_path_file_path *)dp;
 		int slen = (dp->length - sizeof(*dp)) / 2;
-		s += sprintf(s, "/%-.*ls", slen, fp->str);
+		if (slen > MAX_NODE_LEN - 2)
+			slen = MAX_NODE_LEN - 2;
+		s += sprintf(s, "%-.*ls", slen, fp->str);
 		break;
 	}
 	default:
@@ -163,65 +184,59 @@ static char *dp_media(char *s, struct efi_device_path *dp)
 	return s;
 }
 
-static uint16_t *efi_convert_device_node_to_text(
-		struct efi_device_path *dp,
-		bool display_only,
-		bool allow_shortcuts)
+/*
+ * Converts a single node to a char string.
+ *
+ * @buffer		output buffer
+ * @dp			device path or node
+ * @return		end of string
+ */
+static char *efi_convert_single_device_node_to_text(
+		char *buffer,
+		struct efi_device_path *dp)
 {
-	unsigned long len;
-	efi_status_t r;
-	char buf[512];  /* this ought be be big enough for worst case */
-	char *str = buf;
-	uint16_t *out;
-
-	while (dp) {
-		switch (dp->type) {
-		case DEVICE_PATH_TYPE_HARDWARE_DEVICE:
-			str = dp_hardware(str, dp);
-			break;
-		case DEVICE_PATH_TYPE_ACPI_DEVICE:
-			str = dp_acpi(str, dp);
-			break;
-		case DEVICE_PATH_TYPE_MESSAGING_DEVICE:
-			str = dp_msging(str, dp);
-			break;
-		case DEVICE_PATH_TYPE_MEDIA_DEVICE:
-			str = dp_media(str, dp);
-			break;
-		default:
-			str = dp_unknown(str, dp);
-		}
+	char *str = buffer;
 
-		dp = efi_dp_next(dp);
+	switch (dp->type) {
+	case DEVICE_PATH_TYPE_HARDWARE_DEVICE:
+		str = dp_hardware(str, dp);
+		break;
+	case DEVICE_PATH_TYPE_ACPI_DEVICE:
+		str = dp_acpi(str, dp);
+		break;
+	case DEVICE_PATH_TYPE_MESSAGING_DEVICE:
+		str = dp_msging(str, dp);
+		break;
+	case DEVICE_PATH_TYPE_MEDIA_DEVICE:
+		str = dp_media(str, dp);
+		break;
+	default:
+		str = dp_unknown(str, dp);
 	}
 
-	*str++ = '\0';
-
-	len = str - buf;
-	r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES, 2 * len, (void **)&out);
-	if (r != EFI_SUCCESS)
-		return NULL;
-
-	ascii2unicode(out, buf);
-	out[len - 1] = 0;
-
-	return out;
+	*str = '\0';
+	return str;
 }
 
-static uint16_t EFIAPI *efi_convert_device_node_to_text_ext(
+static uint16_t EFIAPI *efi_convert_device_node_to_text(
 		struct efi_device_path *device_node,
 		bool display_only,
 		bool allow_shortcuts)
 {
-	uint16_t *buffer;
+	char str[MAX_NODE_LEN];
+	uint16_t *text = NULL;
 
 	EFI_ENTRY("%p, %d, %d", device_node, display_only, allow_shortcuts);
 
-	buffer = efi_convert_device_node_to_text(device_node, display_only,
-						 allow_shortcuts);
+	if (!device_node)
+		goto out;
+	efi_convert_single_device_node_to_text(str, device_node);
+
+	text = efi_str_to_u16(str);
 
+out:
 	EFI_EXIT(EFI_SUCCESS);
-	return buffer;
+	return text;
 }
 
 static uint16_t EFIAPI *efi_convert_device_path_to_text(
@@ -229,19 +244,26 @@ static uint16_t EFIAPI *efi_convert_device_path_to_text(
 		bool display_only,
 		bool allow_shortcuts)
 {
-	uint16_t *buffer;
+	uint16_t *text = NULL;
+	char buffer[MAX_PATH_LEN];
+	char *str = buffer;
 
 	EFI_ENTRY("%p, %d, %d", device_path, display_only, allow_shortcuts);
 
-	/*
-	 * Our device paths are all of depth one. So its is sufficient to
-	 * to convert the first node.
-	 */
-	buffer = efi_convert_device_node_to_text(device_path, display_only,
-						 allow_shortcuts);
+	if (!device_path)
+		goto out;
+	while (device_path &&
+	       str + MAX_NODE_LEN < buffer + MAX_PATH_LEN) {
+		*str++ = '/';
+		str = efi_convert_single_device_node_to_text(str, device_path);
+		device_path = efi_dp_next(device_path);
+	}
+
+	text = efi_str_to_u16(buffer);
 
+out:
 	EFI_EXIT(EFI_SUCCESS);
-	return buffer;
+	return text;
 }
 
 /* helper for debug prints.. efi_free_pool() the result. */
@@ -251,6 +273,6 @@ uint16_t *efi_dp_str(struct efi_device_path *dp)
 }
 
 const struct efi_device_path_to_text_protocol efi_device_path_to_text = {
-	.convert_device_node_to_text = efi_convert_device_node_to_text_ext,
+	.convert_device_node_to_text = efi_convert_device_node_to_text,
 	.convert_device_path_to_text = efi_convert_device_path_to_text,
 };
-- 
2.14.2

  parent reply	other threads:[~2017-11-26 13:05 UTC|newest]

Thread overview: 25+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-11-26 13:05 [U-Boot] [PATCH v3 00/18] efi_loader: manage protocols in a linked list (v3) Heinrich Schuchardt
2017-11-26 13:05 ` [U-Boot] [PATCH v3 01/18] efi_loader: helloworld.c: remove superfluous include Heinrich Schuchardt
2017-11-26 13:05 ` [U-Boot] [PATCH v3 02/18] efi_loader: size of media device path node represenation Heinrich Schuchardt
2017-11-26 13:05 ` [U-Boot] [PATCH v3 03/18] efi_loader: efi_dp_str should print path not node Heinrich Schuchardt
2017-11-26 13:05 ` Heinrich Schuchardt [this message]
2017-11-26 13:05 ` [U-Boot] [PATCH v3 05/18] efi_loader: reimplement LocateDevicePath Heinrich Schuchardt
2017-11-26 13:05 ` [U-Boot] [PATCH v3 06/18] efi_selftest: test EFI_DEVICE_PATH_TO_TEXT_PROTOCOL Heinrich Schuchardt
2017-11-26 13:05 ` [U-Boot] [PATCH v3 07/18] efi_loader: efi_disk: use efi_add_protocol Heinrich Schuchardt
2017-11-26 13:05 ` [U-Boot] [PATCH v3 08/18] efi_loader: efi_net: " Heinrich Schuchardt
2017-11-26 13:05 ` [U-Boot] [PATCH v3 09/18] efi_loader: efi_gop: " Heinrich Schuchardt
2017-11-26 13:05 ` [U-Boot] [PATCH v3 10/18] efi_loader: simplify efi_open_protocol Heinrich Schuchardt
2017-11-26 13:05 ` [U-Boot] [PATCH v3 11/18] efi_loader: simplify find_obj Heinrich Schuchardt
2017-11-26 13:05 ` [U-Boot] [PATCH v3 12/18] efi_loader: manage protocols in a linked list Heinrich Schuchardt
2017-11-26 13:05 ` [U-Boot] [PATCH v3 13/18] efi_selftest: compile without special compiler flags Heinrich Schuchardt
2017-11-26 13:05 ` [U-Boot] [PATCH v3 14/18] efi_selftest: add missing line feed Heinrich Schuchardt
2017-11-26 13:05 ` [U-Boot] [PATCH v3 15/18] efi_loader: output load options in helloworld Heinrich Schuchardt
2017-12-09 23:09   ` Florian Fainelli
2017-12-10  6:40     ` Heinrich Schuchardt
2017-12-10 22:20       ` Florian Fainelli
2017-12-11  8:15         ` Alexander Graf
2017-11-26 13:05 ` [U-Boot] [PATCH v3 16/18] test/py: check return code of helloworld Heinrich Schuchardt
2017-11-26 13:05 ` [U-Boot] [PATCH v3 17/18] efi_loader: pass handle of loaded image Heinrich Schuchardt
2017-11-26 13:05 ` [U-Boot] [PATCH v3 18/18] efi_loader: helper function to add EFI object to list Heinrich Schuchardt
2017-11-27 17:09 ` [U-Boot] [PATCH v3 00/18] efi_loader: manage protocols in a linked list (v3) Simon Glass
2017-12-01 12:42   ` Alexander Graf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20171126130523.4993-5-xypron.glpk@gmx.de \
    --to=xypron.glpk@gmx.de \
    --cc=u-boot@lists.denx.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.