]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Expose efi_path_next() utility function
authorMichael Brown <mcb30@ipxe.org>
Thu, 22 Dec 2022 13:33:38 +0000 (13:33 +0000)
committerMichael Brown <mcb30@ipxe.org>
Thu, 22 Dec 2022 13:34:28 +0000 (13:34 +0000)
Provide a single central implementation of the logic for stepping
through elements of an EFI device path.

Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/include/ipxe/efi/efi_path.h
src/interface/efi/efi_local.c
src/interface/efi/efi_path.c

index 76ded728c6bc6732a9769868fbd6b8a21ae08ee9..18810a751977220b1c9c84e32333d772f42441e0 100644 (file)
@@ -21,6 +21,8 @@ struct fcp_description;
 struct ib_srp_device;
 struct usb_function;
 
+extern EFI_DEVICE_PATH_PROTOCOL *
+efi_path_next ( EFI_DEVICE_PATH_PROTOCOL *path );
 extern EFI_DEVICE_PATH_PROTOCOL *
 efi_path_end ( EFI_DEVICE_PATH_PROTOCOL *path );
 extern size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *path );
index d8edb62633772c73339411415f58aa21361e1ab4..f54f5daeadee3d8768c9103f57ea79b730586ada 100644 (file)
@@ -419,14 +419,15 @@ static int efi_local_open_resolved ( struct efi_local *local,
  * Open specified path
  *
  * @v local            Local file
- * @v path             Path to file
+ * @v filename         Path to file relative to our own image
  * @ret rc             Return status code
  */
-static int efi_local_open_path ( struct efi_local *local, const char *path ) {
-       FILEPATH_DEVICE_PATH *fp = container_of ( efi_loaded_image->FilePath,
-                                                 FILEPATH_DEVICE_PATH, Header);
-       size_t fp_len = efi_path_len ( &fp->Header );
-       char base[ fp_len / 2 /* Cannot exceed this length */ ];
+static int efi_local_open_path ( struct efi_local *local,
+                                const char *filename ) {
+       EFI_DEVICE_PATH_PROTOCOL *path = efi_loaded_image->FilePath;
+       EFI_DEVICE_PATH_PROTOCOL *next;
+       FILEPATH_DEVICE_PATH *fp;
+       char base[ efi_path_len ( path ) / 2 /* Cannot exceed this length */ ];
        size_t remaining = sizeof ( base );
        size_t len;
        char *resolved;
@@ -436,13 +437,12 @@ static int efi_local_open_path ( struct efi_local *local, const char *path ) {
        /* Construct base path to our own image, if possible */
        memset ( base, 0, sizeof ( base ) );
        tmp = base;
-       while ( fp && ( fp->Header.Type != END_DEVICE_PATH_TYPE ) ) {
+       for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {
+               fp = container_of ( path, FILEPATH_DEVICE_PATH, Header );
                len = snprintf ( tmp, remaining, "%ls", fp->PathName );
                assert ( len < remaining );
                tmp += len;
                remaining -= len;
-               fp = ( ( ( void * ) fp ) + ( ( fp->Header.Length[1] << 8 ) |
-                                            fp->Header.Length[0] ) );
        }
        DBGC2 ( local, "LOCAL %p base path \"%s\"\n",
                local, base );
@@ -454,7 +454,7 @@ static int efi_local_open_path ( struct efi_local *local, const char *path ) {
        }
 
        /* Resolve path */
-       resolved = resolve_path ( base, path );
+       resolved = resolve_path ( base, filename );
        if ( ! resolved ) {
                rc = -ENOMEM;
                goto err_resolve;
index 1a95a3b9a0baeb1c17bb02f96161d6e7422004f1..937d3c7046db810b3434ed078c21dfe7b47e7ca3 100644 (file)
  *
  */
 
+/**
+ * Find next element in device path
+ *
+ * @v path             Device path, or NULL
+ * @v next             Next element in device path, or NULL if at end
+ */
+EFI_DEVICE_PATH_PROTOCOL * efi_path_next ( EFI_DEVICE_PATH_PROTOCOL *path ) {
+
+       /* Check for non-existent device path */
+       if ( ! path )
+               return NULL;
+
+       /* Check for end of device path */
+       if ( path->Type == END_DEVICE_PATH_TYPE )
+               return NULL;
+
+       /* Move to next component of the device path */
+       path = ( ( ( void * ) path ) +
+                /* There's this amazing new-fangled thing known as
+                 * a UINT16, but who wants to use one of those? */
+                ( ( path->Length[1] << 8 ) | path->Length[0] ) );
+
+       return path;
+}
+
 /**
  * Find end of device path
  *
  * @ret path_end       End of device path, or NULL
  */
 EFI_DEVICE_PATH_PROTOCOL * efi_path_end ( EFI_DEVICE_PATH_PROTOCOL *path ) {
+       EFI_DEVICE_PATH_PROTOCOL *next;
 
-       while ( path && ( path->Type != END_DEVICE_PATH_TYPE ) ) {
-               path = ( ( ( void * ) path ) +
-                        /* There's this amazing new-fangled thing known as
-                         * a UINT16, but who wants to use one of those? */
-                        ( ( path->Length[1] << 8 ) | path->Length[0] ) );
+       /* Find end of device path */
+       while ( ( next = efi_path_next ( path ) ) != NULL ) {
+               path = next;
        }
 
        return path;