efi_loader: implement ConvertDeviceNodeToText
authorxypron.glpk@gmx.de <xypron.glpk@gmx.de>
Fri, 21 Jul 2017 17:12:08 +0000 (19:12 +0200)
committerAlexander Graf <agraf@suse.de>
Mon, 24 Jul 2017 12:47:04 +0000 (14:47 +0200)
Move the logic for converting a node to text from
efi_convert_device_path_to_text to convert_device_node_to_text.

Provide a wrapper function convert_device_node_to_text_ext.

As we use only shallow device paths so we can call
directly call efi_device_node_to_text from efi_device_path_to_text.

Add output for MAC addresses.

Add output for not yet supported types/subtypes.

Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de>
Signed-off-by: Alexander Graf <agraf@suse.de>
lib/efi_loader/efi_device_path_to_text.c

index a7a5130..612e380 100644 (file)
 #include <common.h>
 #include <efi_loader.h>
 
-#define MEDIA_DEVICE_PATH 4
-#define FILE_PATH_MEDIA_DEVICE_PATH 4
+#define MAC_OUTPUT_LEN 22
+#define UNKNOWN_OUTPUT_LEN 23
 
 const efi_guid_t efi_guid_device_path_to_text_protocol =
                EFI_DEVICE_PATH_TO_TEXT_PROTOCOL_GUID;
 
-uint16_t *efi_convert_device_node_to_text(
+static uint16_t *efi_convert_device_node_to_text(
                struct efi_device_path_protocol *device_node,
                bool display_only,
                bool allow_shortcuts)
 {
-       EFI_ENTRY("%p, %d, %d", device_node, display_only, allow_shortcuts);
-
-       EFI_EXIT(EFI_UNSUPPORTED);
-       return NULL;
-}
-
-uint16_t *efi_convert_device_path_to_text(
-               struct efi_device_path_protocol *device_path,
-               bool display_only,
-               bool allow_shortcuts)
-{
-       EFI_ENTRY("%p, %d, %d", device_path, display_only, allow_shortcuts);
-
        unsigned long buffer_size;
        efi_status_t r;
        uint16_t *buffer = NULL;
+       int i;
+
+       switch (device_node->type) {
+       case DEVICE_PATH_TYPE_END:
+               return NULL;
+       case DEVICE_PATH_TYPE_MESSAGING_DEVICE:
+               switch (device_node->sub_type) {
+               case DEVICE_PATH_SUB_TYPE_MSG_MAC_ADDR: {
+                       struct efi_device_path_mac_addr *dp =
+                               (struct efi_device_path_mac_addr *)device_node;
 
-       switch (device_path->type) {
-       case MEDIA_DEVICE_PATH:
-               switch (device_path->sub_type) {
-               case FILE_PATH_MEDIA_DEVICE_PATH:
-                       buffer_size = device_path->length - 4;
+                       if (dp->if_type != 0 && dp->if_type != 1)
+                               break;
+                       r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES,
+                                             2 * MAC_OUTPUT_LEN,
+                                             (void **)&buffer);
+                       if (r != EFI_SUCCESS)
+                               return NULL;
+                       sprintf((char *)buffer,
+                               "MAC(%02x%02x%02x%02x%02x%02x,0x%1x)",
+                               dp->mac.addr[0], dp->mac.addr[1],
+                               dp->mac.addr[2], dp->mac.addr[3],
+                               dp->mac.addr[4], dp->mac.addr[5],
+                               dp->if_type);
+                       for (i = MAC_OUTPUT_LEN - 1; i >= 0; --i)
+                               buffer[i] = ((uint8_t *)buffer)[i];
+                       break;
+                       }
+               }
+       case DEVICE_PATH_TYPE_MEDIA_DEVICE:
+               switch (device_node->sub_type) {
+               case DEVICE_PATH_SUB_TYPE_FILE_PATH:
+                       buffer_size = device_node->length - 4;
                        r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES,
                                              buffer_size, (void **) &buffer);
-                       if (r == EFI_SUCCESS)
-                               memcpy(buffer, device_path->data, buffer_size);
+                       if (r != EFI_SUCCESS)
+                               return NULL;
+                       memcpy(buffer, device_node->data, buffer_size);
                        break;
                }
        }
 
-       if (buffer) {
-               EFI_EXIT(EFI_SUCCESS);
-       } else {
-               debug("type %d, subtype %d\n",
-                     device_path->type, device_path->sub_type);
-               EFI_EXIT(EFI_UNSUPPORTED);
+       /*
+        * For all node types that we do not yet support return
+        * 'UNKNOWN(type,subtype)'.
+        */
+       if (!buffer) {
+               r = efi_allocate_pool(EFI_ALLOCATE_ANY_PAGES,
+                                     2 * UNKNOWN_OUTPUT_LEN,
+                                     (void **)&buffer);
+               if (r != EFI_SUCCESS)
+                       return NULL;
+               sprintf((char *)buffer,
+                       "UNKNOWN(%04x,%04x)",
+                       device_node->type,
+                       device_node->sub_type);
+               for (i = UNKNOWN_OUTPUT_LEN - 1; i >= 0; --i)
+                       buffer[i] = ((uint8_t *)buffer)[i];
        }
 
        return buffer;
 }
 
+static uint16_t EFIAPI *efi_convert_device_node_to_text_ext(
+               struct efi_device_path_protocol *device_node,
+               bool display_only,
+               bool allow_shortcuts)
+{
+       uint16_t *buffer;
+
+       EFI_ENTRY("%p, %d, %d", device_node, display_only, allow_shortcuts);
+
+       buffer = efi_convert_device_node_to_text(device_node, display_only,
+                                                allow_shortcuts);
+
+       EFI_EXIT(EFI_SUCCESS);
+       return buffer;
+}
+
+static uint16_t EFIAPI *efi_convert_device_path_to_text(
+               struct efi_device_path_protocol *device_path,
+               bool display_only,
+               bool allow_shortcuts)
+{
+       uint16_t *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);
+
+       EFI_EXIT(EFI_SUCCESS);
+       return buffer;
+}
+
 const struct efi_device_path_to_text_protocol efi_device_path_to_text = {
-       .convert_device_node_to_text = efi_convert_device_node_to_text,
+       .convert_device_node_to_text = efi_convert_device_node_to_text_ext,
        .convert_device_path_to_text = efi_convert_device_path_to_text,
 };