[efi] Provide utility function to concatenate device paths

Signed-off-by: Michael Brown <mcb30@ipxe.org>
pull/171/head
Michael Brown 2020-10-19 14:12:48 +01:00
parent 6154b1fb20
commit 2d49ce6f08
2 changed files with 54 additions and 0 deletions

View File

@ -20,6 +20,8 @@ struct usb_function;
extern EFI_DEVICE_PATH_PROTOCOL *
efi_path_end ( EFI_DEVICE_PATH_PROTOCOL *path );
extern size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *path );
extern EFI_DEVICE_PATH_PROTOCOL * efi_paths ( EFI_DEVICE_PATH_PROTOCOL *first,
... );
extern EFI_DEVICE_PATH_PROTOCOL * efi_netdev_path ( struct net_device *netdev );
extern EFI_DEVICE_PATH_PROTOCOL * efi_uri_path ( struct uri *uri );
extern EFI_DEVICE_PATH_PROTOCOL * efi_usb_path ( struct usb_function *func );

View File

@ -18,6 +18,7 @@
*/
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <byteswap.h>
#include <ipxe/netdevice.h>
@ -64,6 +65,57 @@ size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *path ) {
return ( ( ( void * ) end ) - ( ( void * ) path ) );
}
/**
* Concatenate EFI device paths
*
* @v ... List of device paths (NULL terminated)
* @ret path Concatenated device path, or NULL on error
*
* The caller is responsible for eventually calling free() on the
* allocated device path.
*/
EFI_DEVICE_PATH_PROTOCOL * efi_paths ( EFI_DEVICE_PATH_PROTOCOL *first, ... ) {
EFI_DEVICE_PATH_PROTOCOL *path;
EFI_DEVICE_PATH_PROTOCOL *src;
EFI_DEVICE_PATH_PROTOCOL *dst;
EFI_DEVICE_PATH_PROTOCOL *end;
va_list args;
size_t len;
/* Calculate device path length */
va_start ( args, first );
len = 0;
src = first;
while ( src ) {
len += efi_path_len ( src );
src = va_arg ( args, EFI_DEVICE_PATH_PROTOCOL * );
}
va_end ( args );
/* Allocate device path */
path = zalloc ( len + sizeof ( *end ) );
if ( ! path )
return NULL;
/* Populate device path */
va_start ( args, first );
dst = path;
src = first;
while ( src ) {
len = efi_path_len ( src );
memcpy ( dst, src, len );
dst = ( ( ( void * ) dst ) + len );
src = va_arg ( args, EFI_DEVICE_PATH_PROTOCOL * );
}
va_end ( args );
end = dst;
end->Type = END_DEVICE_PATH_TYPE;
end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
end->Length[0] = sizeof ( *end );
return path;
}
/**
* Construct EFI device path for network device
*