/*
 * Copyright (C) 2020 Michael Brown <mbrown@fensystems.co.uk>.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of the
 * License, or any later version.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 */

FILE_LICENCE ( GPL2_OR_LATER );
FILE_SECBOOT ( PERMITTED );

#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <errno.h>
#include <byteswap.h>
#include <ipxe/netdevice.h>
#include <ipxe/vlan.h>
#include <ipxe/uuid.h>
#include <ipxe/tcpip.h>
#include <ipxe/uri.h>
#include <ipxe/iscsi.h>
#include <ipxe/aoe.h>
#include <ipxe/fcp.h>
#include <ipxe/ib_srp.h>
#include <ipxe/usb.h>
#include <ipxe/settings.h>
#include <ipxe/dhcp.h>
#include <ipxe/ndp.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_driver.h>
#include <ipxe/efi/efi_strings.h>
#include <ipxe/efi/efi_path.h>

/** @file
 *
 * EFI device paths
 *
 */

/** Dummy parent device path
 *
 * This is used as the parent device path when we need to construct a
 * path for a device that has no EFI parent device.
 */
static struct {
	BBS_BBS_DEVICE_PATH bbs;
	CHAR8 tring[4];
	EFI_DEVICE_PATH_PROTOCOL end;
} __attribute__ (( packed )) efi_dummy_parent_path = {
	.bbs = {
		.Header = {
			.Type = BBS_DEVICE_PATH,
			.SubType = BBS_BBS_DP,
			.Length[0] = ( sizeof ( efi_dummy_parent_path.bbs ) +
				       sizeof ( efi_dummy_parent_path.tring )),
		},
		.DeviceType = BBS_TYPE_UNKNOWN,
		.String[0] = 'i',
	},
	.tring = "PXE",
	.end = {
		.Type = END_DEVICE_PATH_TYPE,
		.SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE,
		.Length[0] = sizeof ( efi_dummy_parent_path.end ),
	},
};

/** An EFI device path settings block */
struct efi_path_settings {
	/** Settings interface */
	struct settings settings;
	/** Device path */
	EFI_DEVICE_PATH_PROTOCOL *path;
};

/** An EFI device path setting */
struct efi_path_setting {
	/** Setting */
	const struct setting *setting;
	/**
	 * Fetch setting
	 *
	 * @v pathset		Path setting
	 * @v path		Device path
	 * @v data		Buffer to fill with setting data
	 * @v len		Length of buffer
	 * @ret len		Length of setting data, or negative error
	 */
	int ( * fetch ) ( struct efi_path_setting *pathset,
			  EFI_DEVICE_PATH_PROTOCOL *path,
			  void *data, size_t len );
	/** Path type */
	uint8_t type;
	/** Path subtype */
	uint8_t subtype;
	/** Offset within device path */
	uint8_t offset;
	/** Length (if fixed) */
	uint8_t len;
};

/**
 * 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 previous element of device path
 *
 * @v path		Device path, or NULL for no path
 * @v curr		Current element in device path, or NULL for end of path
 * @ret prev		Previous element in device path, or NULL
 */
EFI_DEVICE_PATH_PROTOCOL * efi_path_prev ( EFI_DEVICE_PATH_PROTOCOL *path,
					   EFI_DEVICE_PATH_PROTOCOL *curr ) {
	EFI_DEVICE_PATH_PROTOCOL *tmp;

	/* Find immediately preceding element */
	while ( ( tmp = efi_path_next ( path ) ) != curr ) {
		path = tmp;
	}

	return path;
}

/**
 * Find end of device path
 *
 * @v path		Device path, or NULL
 * @ret path_end	End of device path, or NULL
 */
EFI_DEVICE_PATH_PROTOCOL * efi_path_end ( EFI_DEVICE_PATH_PROTOCOL *path ) {

	return efi_path_prev ( path, NULL );
}

/**
 * Find length of device path (excluding terminator)
 *
 * @v path		Device path, or NULL
 * @ret path_len	Length of device path
 */
size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *path ) {
	EFI_DEVICE_PATH_PROTOCOL *end = efi_path_end ( path );

	return ( ( ( void * ) end ) - ( ( void * ) path ) );
}

/**
 * Check that device path is well-formed
 *
 * @v path		Device path, or NULL
 * @v max		Maximum device path length
 * @ret rc		Return status code
 */
int efi_path_check ( EFI_DEVICE_PATH_PROTOCOL *path, size_t max ) {
	EFI_DEVICE_PATH_PROTOCOL *next;
	size_t remaining = max;
	size_t len;

	/* Check that path terminates within maximum length */
	for ( ; ; path = next ) {
		if ( remaining < sizeof ( *path ) )
			return -EINVAL;
		next = efi_path_next ( path );
		if ( ! next )
			break;
		len = ( ( ( void * ) next ) - ( ( void * ) path ) );
		if ( remaining < len )
			return -EINVAL;
	}

	return 0;
}

/**
 * Get MAC address from device path
 *
 * @v path		Device path
 * @ret mac		MAC address, or NULL if not found
 */
void * efi_path_mac ( EFI_DEVICE_PATH_PROTOCOL *path ) {
	EFI_DEVICE_PATH_PROTOCOL *next;
	MAC_ADDR_DEVICE_PATH *mac;

	/* Search for MAC address path */
	for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {
		if ( ( path->Type == MESSAGING_DEVICE_PATH ) &&
		     ( path->SubType == MSG_MAC_ADDR_DP ) ) {
			mac = container_of ( path, MAC_ADDR_DEVICE_PATH,
					     Header );
			return &mac->MacAddress;
		}
	}

	/* No MAC address found */
	return NULL;
}

/**
 * Get VLAN tag from device path
 *
 * @v path		Device path
 * @ret tag		VLAN tag, or 0 if not a VLAN
 */
unsigned int efi_path_vlan ( EFI_DEVICE_PATH_PROTOCOL *path ) {
	EFI_DEVICE_PATH_PROTOCOL *next;
	VLAN_DEVICE_PATH *vlan;

	/* Search for VLAN device path */
	for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {
		if ( ( path->Type == MESSAGING_DEVICE_PATH ) &&
		     ( path->SubType == MSG_VLAN_DP ) ) {
			vlan = container_of ( path, VLAN_DEVICE_PATH, Header );
			return vlan->VlanId;
		}
	}

	/* No VLAN device path found */
	return 0;
}

/**
 * Get IP address family from device path
 *
 * @v path		Device path
 * @ret family		Address family, or 0 if not recognised
 */
unsigned int efi_path_family ( EFI_DEVICE_PATH_PROTOCOL *path ) {
	EFI_DEVICE_PATH_PROTOCOL *next;

	/* Search for IP address device path */
	for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {
		if ( path->Type == MESSAGING_DEVICE_PATH ) {
			if ( path->SubType == MSG_IPv4_DP ) {
				return AF_INET;
			} else if ( path->SubType == MSG_IPv6_DP ) {
				return AF_INET6;
			}
		}
	}

	/* No IP address device path found */
	return 0;
}

/**
 * Get partition GUID from device path
 *
 * @v path		Device path
 * @v guid		Partition GUID to fill in
 * @ret rc		Return status code
 */
int efi_path_guid ( EFI_DEVICE_PATH_PROTOCOL *path, union uuid *guid ) {
	EFI_DEVICE_PATH_PROTOCOL *next;
	HARDDRIVE_DEVICE_PATH *hd;
	int rc;

	/* Search for most specific partition device path */
	rc = -ENOENT;
	for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {

		/* Skip non-harddrive device paths */
		if ( path->Type != MEDIA_DEVICE_PATH )
			continue;
		if ( path->SubType != MEDIA_HARDDRIVE_DP )
			continue;

		/* Skip non-GUID signatures */
		hd = container_of ( path, HARDDRIVE_DEVICE_PATH, Header );
		if ( hd->SignatureType != SIGNATURE_TYPE_GUID )
			continue;

		/* Extract GUID */
		memcpy ( guid, hd->Signature, sizeof ( *guid ) );
		uuid_mangle ( guid );

		/* Record success, but continue searching in case
		 * there exists a more specific GUID (e.g. a partition
		 * GUID rather than a disk GUID).
		 */
		rc = 0;
	}

	return rc;
}

/**
 * Parse URI from device path
 *
 * @v path		Device path
 * @ret uri		URI, or NULL if not a URI
 */
struct uri * efi_path_uri ( EFI_DEVICE_PATH_PROTOCOL *path ) {
	EFI_DEVICE_PATH_PROTOCOL *next;
	URI_DEVICE_PATH *uripath;
	char *uristring;
	struct uri *uri;
	size_t len;

	/* Search for URI device path */
	for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {
		if ( ( path->Type == MESSAGING_DEVICE_PATH ) &&
		     ( path->SubType == MSG_URI_DP ) ) {

			/* Calculate path length */
			uripath = container_of ( path, URI_DEVICE_PATH,
						 Header );
			len = ( ( ( path->Length[1] << 8 ) | path->Length[0] )
				- offsetof ( typeof ( *uripath ), Uri ) );

			/* Parse URI */
			uristring = zalloc ( len + 1 /* NUL */ );
			if ( ! uristring )
				return NULL;
			memcpy ( uristring, uripath->Uri, len );
			uri = parse_uri ( uristring );
			free ( uristring );

			return uri;
		}
	}

	/* No URI path found */
	return NULL;
}

/**
 * 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;
	efi_path_terminate ( end );

	return path;
}

/**
 * Construct EFI parent device path
 *
 * @v dev		Generic device
 * @ret path		Parent (or dummy) device path
 */
static EFI_DEVICE_PATH_PROTOCOL * efi_parent_path ( struct device *dev ) {
	struct efi_device *efidev;

	/* Use EFI parent device's path, if possible */
	efidev = efidev_parent ( dev );
	if ( efidev )
		return efidev->path;

	/* Otherwise, use a dummy parent device path */
	return &efi_dummy_parent_path.bbs.Header;
}

/**
 * Construct EFI device path for network device
 *
 * @v netdev		Network device
 * @ret path		EFI device path, or NULL on error
 *
 * The caller is responsible for eventually calling free() on the
 * allocated device path.
 */
EFI_DEVICE_PATH_PROTOCOL * efi_netdev_path ( struct net_device *netdev ) {
	EFI_DEVICE_PATH_PROTOCOL *parent;
	EFI_DEVICE_PATH_PROTOCOL *path;
	MAC_ADDR_DEVICE_PATH *macpath;
	VLAN_DEVICE_PATH *vlanpath;
	EFI_DEVICE_PATH_PROTOCOL *end;
	unsigned int tag;
	size_t prefix_len;
	size_t len;

	/* Get parent EFI device path */
	parent = efi_parent_path ( netdev->dev );

	/* Calculate device path length */
	prefix_len = efi_path_len ( parent );
	len = ( prefix_len + sizeof ( *macpath ) + sizeof ( *vlanpath ) +
		sizeof ( *end ) );

	/* Allocate device path */
	path = zalloc ( len );
	if ( ! path )
		return NULL;

	/* Construct device path */
	memcpy ( path, parent, prefix_len );
	macpath = ( ( ( void * ) path ) + prefix_len );
	macpath->Header.Type = MESSAGING_DEVICE_PATH;
	macpath->Header.SubType = MSG_MAC_ADDR_DP;
	macpath->Header.Length[0] = sizeof ( *macpath );
	assert ( netdev->ll_protocol->ll_addr_len <
		 sizeof ( macpath->MacAddress ) );
	memcpy ( &macpath->MacAddress, netdev->ll_addr,
		 netdev->ll_protocol->ll_addr_len );
	macpath->IfType = ntohs ( netdev->ll_protocol->ll_proto );
	if ( ( tag = vlan_tag ( netdev ) ) ) {
		vlanpath = ( ( ( void * ) macpath ) + sizeof ( *macpath ) );
		vlanpath->Header.Type = MESSAGING_DEVICE_PATH;
		vlanpath->Header.SubType = MSG_VLAN_DP;
		vlanpath->Header.Length[0] = sizeof ( *vlanpath );
		vlanpath->VlanId = tag;
		end = ( ( ( void * ) vlanpath ) + sizeof ( *vlanpath ) );
	} else {
		end = ( ( ( void * ) macpath ) + sizeof ( *macpath ) );
	}
	efi_path_terminate ( end );

	return path;
}

/**
 * Construct EFI device path for URI
 *
 * @v uri		URI
 * @ret path		EFI device path, or NULL on error
 *
 * The caller is responsible for eventually calling free() on the
 * allocated device path.
 */
EFI_DEVICE_PATH_PROTOCOL * efi_uri_path ( struct uri *uri ) {
	EFI_DEVICE_PATH_PROTOCOL *path;
	EFI_DEVICE_PATH_PROTOCOL *end;
	URI_DEVICE_PATH *uripath;
	size_t uri_len;
	size_t uripath_len;
	size_t len;

	/* Calculate device path length */
	uri_len = ( format_uri ( uri, NULL, 0 ) + 1 /* NUL */ );
	uripath_len = ( sizeof ( *uripath ) + uri_len );
	len = ( uripath_len + sizeof ( *end ) );

	/* Allocate device path */
	path = zalloc ( len );
	if ( ! path )
		return NULL;

	/* Construct device path */
	uripath = ( ( void * ) path );
	uripath->Header.Type = MESSAGING_DEVICE_PATH;
	uripath->Header.SubType = MSG_URI_DP;
	uripath->Header.Length[0] = ( uripath_len & 0xff );
	uripath->Header.Length[1] = ( uripath_len >> 8 );
	format_uri ( uri, uripath->Uri, uri_len );
	end = ( ( ( void * ) path ) + uripath_len );
	efi_path_terminate ( end );

	return path;
}

/**
 * Construct EFI device path for iSCSI device
 *
 * @v iscsi		iSCSI session
 * @ret path		EFI device path, or NULL on error
 */
EFI_DEVICE_PATH_PROTOCOL * efi_iscsi_path ( struct iscsi_session *iscsi ) {
	struct sockaddr_tcpip *st_target;
	struct net_device *netdev;
	EFI_DEVICE_PATH_PROTOCOL *netpath;
	EFI_DEVICE_PATH_PROTOCOL *path;
	EFI_DEVICE_PATH_PROTOCOL *end;
	ISCSI_DEVICE_PATH *iscsipath;
	char *name;
	size_t prefix_len;
	size_t name_len;
	size_t iscsi_len;
	size_t len;

	/* Get network device associated with target address */
	st_target = ( ( struct sockaddr_tcpip * ) &iscsi->target_sockaddr );
	netdev = tcpip_netdev ( st_target );
	if ( ! netdev )
		goto err_netdev;

	/* Get network device path */
	netpath = efi_netdev_path ( netdev );
	if ( ! netpath )
		goto err_netpath;

	/* Calculate device path length */
	prefix_len = efi_path_len ( netpath );
	name_len = ( strlen ( iscsi->target_iqn ) + 1 /* NUL */ );
	iscsi_len = ( sizeof ( *iscsipath ) + name_len );
	len = ( prefix_len + iscsi_len + sizeof ( *end ) );

	/* Allocate device path */
	path = zalloc ( len );
	if ( ! path )
		goto err_alloc;

	/* Construct device path */
	memcpy ( path, netpath, prefix_len );
	iscsipath = ( ( ( void * ) path ) + prefix_len );
	iscsipath->Header.Type = MESSAGING_DEVICE_PATH;
	iscsipath->Header.SubType = MSG_ISCSI_DP;
	iscsipath->Header.Length[0] = iscsi_len;
	iscsipath->LoginOption = ISCSI_LOGIN_OPTION_AUTHMETHOD_NON;
	memcpy ( &iscsipath->Lun, &iscsi->lun, sizeof ( iscsipath->Lun ) );
	name = ( ( ( void * ) iscsipath ) + sizeof ( *iscsipath ) );
	memcpy ( name, iscsi->target_iqn, name_len );
	end = ( ( ( void * ) name ) + name_len );
	efi_path_terminate ( end );

	/* Free temporary paths */
	free ( netpath );

	return path;

 err_alloc:
	free ( netpath );
 err_netpath:
 err_netdev:
	return NULL;
}

/**
 * Construct EFI device path for AoE device
 *
 * @v aoedev		AoE device
 * @ret path		EFI device path, or NULL on error
 */
EFI_DEVICE_PATH_PROTOCOL * efi_aoe_path ( struct aoe_device *aoedev ) {
	struct {
		SATA_DEVICE_PATH sata;
		EFI_DEVICE_PATH_PROTOCOL end;
	} satapath;
	EFI_DEVICE_PATH_PROTOCOL *netpath;
	EFI_DEVICE_PATH_PROTOCOL *path;

	/* Get network device path */
	netpath = efi_netdev_path ( aoedev->netdev );
	if ( ! netpath )
		goto err_netdev;

	/* Construct SATA path */
	memset ( &satapath, 0, sizeof ( satapath ) );
	satapath.sata.Header.Type = MESSAGING_DEVICE_PATH;
	satapath.sata.Header.SubType = MSG_SATA_DP;
	satapath.sata.Header.Length[0] = sizeof ( satapath.sata );
	satapath.sata.HBAPortNumber = aoedev->major;
	satapath.sata.PortMultiplierPortNumber = aoedev->minor;
	efi_path_terminate ( &satapath.end );

	/* Construct overall device path */
	path = efi_paths ( netpath, &satapath, NULL );
	if ( ! path )
		goto err_paths;

	/* Free temporary paths */
	free ( netpath );

	return path;

 err_paths:
	free ( netpath );
 err_netdev:
	return NULL;
}

/**
 * Construct EFI device path for Fibre Channel device
 *
 * @v desc		FCP device description
 * @ret path		EFI device path, or NULL on error
 */
EFI_DEVICE_PATH_PROTOCOL * efi_fcp_path ( struct fcp_description *desc ) {
	struct {
		FIBRECHANNELEX_DEVICE_PATH fc;
		EFI_DEVICE_PATH_PROTOCOL end;
	} __attribute__ (( packed )) *path;

	/* Allocate device path */
	path = zalloc ( sizeof ( *path ) );
	if ( ! path )
		return NULL;

	/* Construct device path */
	path->fc.Header.Type = MESSAGING_DEVICE_PATH;
	path->fc.Header.SubType = MSG_FIBRECHANNELEX_DP;
	path->fc.Header.Length[0] = sizeof ( path->fc );
	memcpy ( path->fc.WWN, &desc->wwn, sizeof ( path->fc.WWN ) );
	memcpy ( path->fc.Lun, &desc->lun, sizeof ( path->fc.Lun ) );
	efi_path_terminate ( &path->end );

	return &path->fc.Header;
}

/**
 * Construct EFI device path for Infiniband SRP device
 *
 * @v ib_srp		Infiniband SRP device
 * @ret path		EFI device path, or NULL on error
 */
EFI_DEVICE_PATH_PROTOCOL * efi_ib_srp_path ( struct ib_srp_device *ib_srp ) {
	const struct ipxe_ib_sbft *sbft = &ib_srp->sbft;
	union ib_srp_target_port_id *id =
		container_of ( &sbft->srp.target, union ib_srp_target_port_id,
			       srp );
	EFI_DEVICE_PATH_PROTOCOL *parent;
	EFI_DEVICE_PATH_PROTOCOL *path;
	INFINIBAND_DEVICE_PATH *ibpath;
	EFI_DEVICE_PATH_PROTOCOL *end;
	size_t prefix_len;
	size_t len;

	/* Get parent EFI device path */
	parent = efi_parent_path ( ib_srp->ibdev->dev );

	/* Calculate device path length */
	prefix_len = efi_path_len ( parent );
	len = ( prefix_len + sizeof ( *ibpath ) + sizeof ( *end ) );

	/* Allocate device path */
	path = zalloc ( len );
	if ( ! path )
		return NULL;

	/* Construct device path */
	memcpy ( path, parent, prefix_len );
	ibpath = ( ( ( void * ) path ) + prefix_len );
	ibpath->Header.Type = MESSAGING_DEVICE_PATH;
	ibpath->Header.SubType = MSG_INFINIBAND_DP;
	ibpath->Header.Length[0] = sizeof ( *ibpath );
	ibpath->ResourceFlags = INFINIBAND_RESOURCE_FLAG_STORAGE_PROTOCOL;
	memcpy ( ibpath->PortGid, &sbft->ib.dgid, sizeof ( ibpath->PortGid ) );
	memcpy ( &ibpath->ServiceId, &sbft->ib.service_id,
		 sizeof ( ibpath->ServiceId ) );
	memcpy ( &ibpath->TargetPortId, &id->ib.ioc_guid,
		 sizeof ( ibpath->TargetPortId ) );
	memcpy ( &ibpath->DeviceId, &id->ib.id_ext,
		 sizeof ( ibpath->DeviceId ) );
	end = ( ( ( void * ) ibpath ) + sizeof ( *ibpath ) );
	efi_path_terminate ( end );

	return path;
}

/**
 * Construct EFI device path for USB function
 *
 * @v func		USB function
 * @ret path		EFI device path, or NULL on error
 *
 * The caller is responsible for eventually calling free() on the
 * allocated device path.
 */
EFI_DEVICE_PATH_PROTOCOL * efi_usb_path ( struct usb_function *func ) {
	struct usb_device *usb = func->usb;
	EFI_DEVICE_PATH_PROTOCOL *parent;
	EFI_DEVICE_PATH_PROTOCOL *path;
	EFI_DEVICE_PATH_PROTOCOL *end;
	USB_DEVICE_PATH *usbpath;
	unsigned int count;
	size_t prefix_len;
	size_t len;

	/* Sanity check */
	assert ( func->desc.count >= 1 );

	/* Get parent EFI device path */
	parent = efi_parent_path ( &func->dev );

	/* Calculate device path length */
	count = ( usb_depth ( usb ) + 1 );
	prefix_len = efi_path_len ( parent );
	len = ( prefix_len + ( count * sizeof ( *usbpath ) ) +
		sizeof ( *end ) );

	/* Allocate device path */
	path = zalloc ( len );
	if ( ! path )
		return NULL;

	/* Construct device path */
	memcpy ( path, parent, prefix_len );
	end = ( ( ( void * ) path ) + len - sizeof ( *end ) );
	efi_path_terminate ( end );
	usbpath = ( ( ( void * ) end ) - sizeof ( *usbpath ) );
	usbpath->InterfaceNumber = func->interface[0];
	for ( ; usb ; usbpath--, usb = usb->port->hub->usb ) {
		usbpath->Header.Type = MESSAGING_DEVICE_PATH;
		usbpath->Header.SubType = MSG_USB_DP;
		usbpath->Header.Length[0] = sizeof ( *usbpath );
		usbpath->ParentPortNumber = ( usb->port->address - 1 );
	}

	return path;
}

/**
 * Get EFI device path from load option
 *
 * @v load		EFI load option
 * @v len		Length of EFI load option
 * @ret path		EFI device path, or NULL on error
 *
 * The caller is responsible for eventually calling free() on the
 * allocated device path.
 */
EFI_DEVICE_PATH_PROTOCOL * efi_load_path ( EFI_LOAD_OPTION *load,
					   size_t len ) {
	EFI_DEVICE_PATH_PROTOCOL *path;
	EFI_DEVICE_PATH_PROTOCOL *copy;
	CHAR16 *wdesc;
	size_t path_max;
	size_t wmax;
	size_t wlen;

	/* Check basic structure size */
	if ( len < sizeof ( *load ) ) {
		DBGC ( load, "EFI load option too short for header:\n" );
		DBGC_HDA ( load, 0, load, len );
		return NULL;
	}

	/* Get length of description */
	wdesc = ( ( ( void * ) load ) + sizeof ( *load ) );
	wmax = ( ( len - sizeof ( *load ) ) / sizeof ( wdesc[0] ) );
	wlen = wcsnlen ( wdesc, wmax );
	if ( wlen == wmax ) {
		DBGC ( load, "EFI load option has unterminated "
		       "description:\n" );
		DBGC_HDA ( load, 0, load, len );
		return NULL;
	}

	/* Get inline device path */
	path = ( ( ( void * ) load ) + sizeof ( *load ) +
		 ( wlen * sizeof ( wdesc[0] ) ) + 2 /* wNUL */ );
	path_max = ( len - sizeof ( *load ) - ( wlen * sizeof ( wdesc[0] ) )
		     - 2 /* wNUL */ );
	if ( load->FilePathListLength > path_max ) {
		DBGC ( load, "EFI load option too short for path(s):\n" );
		DBGC_HDA ( load, 0, load, len );
		return NULL;
	}

	/* Check path length */
	if ( efi_path_check ( path, path_max ) != 0 ) {
		DBGC ( load, "EFI load option has unterminated device "
		       "path:\n" );
		DBGC_HDA ( load, 0, load, len );
		return NULL;
	}

	/* Allocate copy of path */
	copy = malloc ( path_max );
	if ( ! copy )
		return NULL;
	memcpy ( copy, path, path_max );

	return copy;
}

/**
 * Get EFI device path for numbered boot option
 *
 * @v number		Boot option number
 * @ret path		EFI device path, or NULL on error
 *
 * The caller is responsible for eventually calling free() on the
 * allocated device path.
 */
EFI_DEVICE_PATH_PROTOCOL * efi_boot_path ( unsigned int number ) {
	EFI_RUNTIME_SERVICES *rs = efi_systab->RuntimeServices;
	EFI_GUID *guid = &efi_global_variable;
	CHAR16 wname[ 9 /* "BootXXXX" + wNUL */ ];
	EFI_LOAD_OPTION *load;
	EFI_DEVICE_PATH *path;
	UINT32 attrs;
	UINTN size;
	EFI_STATUS efirc;
	int rc;

	/* Construct variable name */
	efi_snprintf ( wname, ( sizeof ( wname ) / sizeof ( wname[0] ) ),
		       "Boot%04X", number );

	/* Get variable length */
	size = 0;
	if ( ( efirc = rs->GetVariable ( wname, guid, &attrs, &size,
					 NULL ) != EFI_BUFFER_TOO_SMALL ) ) {
		rc = -EEFI ( efirc );
		DBGC ( rs, "EFI could not get size of %ls: %s\n",
		       wname, strerror ( rc ) );
		goto err_size;
	}

	/* Allocate temporary buffer for EFI_LOAD_OPTION */
	load = malloc ( size );
	if ( ! load ) {
		rc = -ENOMEM;
		goto err_alloc;
	}

	/* Read variable */
	if ( ( efirc = rs->GetVariable ( wname, guid, &attrs, &size,
					 load ) != 0 ) ) {
		rc = -EEFI ( efirc );
		DBGC ( rs, "EFI could not read %ls: %s\n",
		       wname, strerror ( rc ) );
		goto err_read;
	}
	DBGC2 ( rs, "EFI boot option %ls is:\n", wname );
	DBGC2_HDA ( rs, 0, load, size );

	/* Get device path from load option */
	path = efi_load_path ( load, size );
	if ( ! path ) {
		rc = -EINVAL;
		DBGC ( rs, "EFI could not parse %ls: %s\n",
		       wname, strerror ( rc ) );
		goto err_path;
	}

	/* Free temporary buffer */
	free ( load );

	return path;

 err_path:
 err_read:
	free ( load );
 err_alloc:
 err_size:
	return NULL;
}

/**
 * Get EFI device path for current boot option
 *
 * @ret path		EFI device path, or NULL on error
 *
 * The caller is responsible for eventually calling free() on the
 * allocated device path.
 */
EFI_DEVICE_PATH_PROTOCOL * efi_current_boot_path ( void ) {
	EFI_RUNTIME_SERVICES *rs = efi_systab->RuntimeServices;
	EFI_GUID *guid = &efi_global_variable;
	CHAR16 wname[] = L"BootCurrent";
	UINT16 current;
	UINT32 attrs;
	UINTN size;
	EFI_STATUS efirc;
	int rc;

	/* Read current boot option index */
	size = sizeof ( current );
	if ( ( efirc = rs->GetVariable ( wname, guid, &attrs, &size,
					 &current ) != 0 ) ) {
		rc = -EEFI ( efirc );
		DBGC ( rs, "EFI could not read %ls: %s\n",
		       wname, strerror ( rc ) );
		return NULL;
	}

	/* Get device path from this boot option */
	return efi_boot_path ( current );
}

/**
 * Describe object as an EFI device path
 *
 * @v intf		Interface
 * @ret path		EFI device path, or NULL
 *
 * The caller is responsible for eventually calling free() on the
 * allocated device path.
 */
EFI_DEVICE_PATH_PROTOCOL * efi_describe ( struct interface *intf ) {
	struct interface *dest;
	efi_describe_TYPE ( void * ) *op =
		intf_get_dest_op ( intf, efi_describe, &dest );
	void *object = intf_object ( dest );
	EFI_DEVICE_PATH_PROTOCOL *path;

	if ( op ) {
		path = op ( object );
	} else {
		path = NULL;
	}

	intf_put ( dest );
	return path;
}

/**
 * Fetch an EFI device path fixed-size setting
 *
 * @v pathset		Path setting
 * @v path		Device path
 * @v data		Buffer to fill with setting data
 * @v len		Length of buffer
 * @ret len		Length of setting data, or negative error
 */
static int efi_path_fetch_fixed ( struct efi_path_setting *pathset,
				  EFI_DEVICE_PATH_PROTOCOL *path,
				  void *data, size_t len ) {

	/* Copy data */
	if ( len > pathset->len )
		len = pathset->len;
	memcpy ( data, ( ( ( void * ) path ) + pathset->offset ), len );

	return pathset->len;
}

/**
 * Fetch an EFI device path DNS setting
 *
 * @v pathset		Path setting
 * @v path		Device path
 * @v data		Buffer to fill with setting data
 * @v len		Length of buffer
 * @ret len		Length of setting data, or negative error
 */
static int efi_path_fetch_dns ( struct efi_path_setting *pathset,
				EFI_DEVICE_PATH_PROTOCOL *path,
				void *data, size_t len ) {
	DNS_DEVICE_PATH *dns = container_of ( path, DNS_DEVICE_PATH, Header );
	unsigned int count;
	unsigned int i;
	size_t frag_len;

	/* Check applicability */
	if ( ( !! dns->IsIPv6 ) !=
	     ( pathset->setting->type == &setting_type_ipv6 ) )
		return -ENOENT;

	/* Calculate number of addresses */
	count = ( ( ( ( path->Length[1] << 8 ) | path->Length[0] ) -
		    pathset->offset ) / sizeof ( dns->DnsServerIp[0] ) );

	/* Copy data */
	for ( i = 0 ; i < count ; i++ ) {
		frag_len = len;
		if ( frag_len > pathset->len )
			frag_len = pathset->len;
		memcpy ( data, &dns->DnsServerIp[i], frag_len );
		data += frag_len;
		len -= frag_len;
	}

	return ( count * pathset->len );
}

/* Avoid dragging in IPv4, IPv6, and DNS support if not otherwise used */
extern const struct setting ip_setting __attribute__ (( weak ));
extern const struct setting netmask_setting __attribute__ (( weak ));
extern const struct setting gateway_setting __attribute__ (( weak ));
extern const struct setting ip6_setting __attribute__ (( weak ));
extern const struct setting len6_setting __attribute__ (( weak ));
extern const struct setting gateway6_setting __attribute__ (( weak ));
extern const struct setting dns_setting __attribute__ (( weak ));
extern const struct setting dns6_setting __attribute__ (( weak ));

/** EFI device path settings */
static struct efi_path_setting efi_path_settings[] = {
	{ &ip_setting, efi_path_fetch_fixed, MESSAGING_DEVICE_PATH,
	  MSG_IPv4_DP, offsetof ( IPv4_DEVICE_PATH, LocalIpAddress ),
	  sizeof ( struct in_addr ) },
	{ &netmask_setting, efi_path_fetch_fixed, MESSAGING_DEVICE_PATH,
	  MSG_IPv4_DP, offsetof ( IPv4_DEVICE_PATH, SubnetMask ),
	  sizeof ( struct in_addr ) },
	{ &gateway_setting, efi_path_fetch_fixed, MESSAGING_DEVICE_PATH,
	  MSG_IPv4_DP, offsetof ( IPv4_DEVICE_PATH, GatewayIpAddress ),
	  sizeof ( struct in_addr ) },
	{ &ip6_setting, efi_path_fetch_fixed, MESSAGING_DEVICE_PATH,
	  MSG_IPv6_DP, offsetof ( IPv6_DEVICE_PATH, LocalIpAddress ),
	  sizeof ( struct in6_addr ) },
	{ &len6_setting, efi_path_fetch_fixed, MESSAGING_DEVICE_PATH,
	  MSG_IPv6_DP, offsetof ( IPv6_DEVICE_PATH, PrefixLength ),
	  sizeof ( uint8_t ) },
	{ &gateway6_setting, efi_path_fetch_fixed, MESSAGING_DEVICE_PATH,
	  MSG_IPv6_DP, offsetof ( IPv6_DEVICE_PATH, GatewayIpAddress ),
	  sizeof ( struct in6_addr ) },
	{ &dns_setting, efi_path_fetch_dns, MESSAGING_DEVICE_PATH,
	  MSG_DNS_DP, offsetof ( DNS_DEVICE_PATH, DnsServerIp ),
	  sizeof ( struct in_addr ) },
	{ &dns6_setting, efi_path_fetch_dns, MESSAGING_DEVICE_PATH,
	  MSG_DNS_DP, offsetof ( DNS_DEVICE_PATH, DnsServerIp ),
	  sizeof ( struct in6_addr ) },
};

/**
 * Fetch value of EFI device path setting
 *
 * @v settings		Settings block
 * @v setting		Setting to fetch
 * @v data		Buffer to fill with setting data
 * @v len		Length of buffer
 * @ret len		Length of setting data, or negative error
 */
static int efi_path_fetch ( struct settings *settings, struct setting *setting,
			    void *data, size_t len ) {
	struct efi_path_settings *pathsets =
		container_of ( settings, struct efi_path_settings, settings );
	EFI_DEVICE_PATH_PROTOCOL *path = pathsets->path;
	EFI_DEVICE_PATH_PROTOCOL *next;
	struct efi_path_setting *pathset;
	unsigned int i;
	int ret;

	/* Find matching path setting, if any */
	for ( i = 0 ; i < ( sizeof ( efi_path_settings ) /
			    sizeof ( efi_path_settings[0] ) ) ; i++ ) {

		/* Check for a matching setting */
		pathset = &efi_path_settings[i];
		if ( ! pathset->setting )
			continue;
		if ( setting_cmp ( setting, pathset->setting ) != 0 )
			continue;

		/* Find matching device path element, if any */
		for ( ; ( next = efi_path_next ( path ) ) ; path = next ) {

			/* Check for a matching path type */
			if ( ( path->Type != pathset->type ) ||
			     ( path->SubType != pathset->subtype ) )
				continue;

			/* Fetch value */
			if ( ( ret = pathset->fetch ( pathset, path,
						      data, len ) ) < 0 )
				return ret;

			/* Apply default type, if not already set */
			if ( ! setting->type )
				setting->type = pathset->setting->type;

			return ret;
		}
		break;
	}

	return -ENOENT;
}

/** EFI device path settings operations */
static struct settings_operations efi_path_settings_operations = {
	.fetch = efi_path_fetch,
};

/**
 * Create per-netdevice EFI path settings
 *
 * @v netdev		Network device
 * @v priv		Private data
 * @ret rc		Return status code
 */
static int efi_path_net_probe ( struct net_device *netdev, void *priv ) {
	struct efi_path_settings *pathsets = priv;
	struct settings *settings = &pathsets->settings;
	EFI_DEVICE_PATH_PROTOCOL *path = efi_loaded_image_path;
	const char *name;
	unsigned int vlan;
	unsigned int family;
	void *mac;
	int rc;

	/* Check applicability */
	pathsets->path = path;
	mac = efi_path_mac ( path );
	vlan = efi_path_vlan ( path );
	family = efi_path_family ( path );
	if ( ( mac == NULL ) ||
	     ( memcmp ( mac, netdev->ll_addr,
			netdev->ll_protocol->ll_addr_len ) != 0 ) ||
	     ( vlan != vlan_tag ( netdev ) ) ) {
		DBGC ( settings, "EFI path %s does not apply to %s\n",
		       efi_devpath_text ( path ), netdev->name );
		return 0;
	}

	/* Mark network device to be opened automatically */
	netdev->state |= NETDEV_AUTO_OPEN;

	/* Determine settings block name */
	switch ( family ) {
	case AF_INET:
		name = DHCP_SETTINGS_NAME;
		break;
	case AF_INET6:
		name = NDP_SETTINGS_NAME;
		break;
	default:
		DBGC ( settings, "EFI path %s has no IP address\n",
		       efi_devpath_text ( path ) );
		return 0;
	}

	/* Never override a real settings block */
	if ( find_child_settings ( netdev_settings ( netdev ), name ) ) {
		DBGC ( settings, "EFI path %s not overriding %s.%s settings\n",
		       efi_devpath_text ( path ), netdev->name, name );
		return 0;
	}

	/* Initialise and register settings */
	settings_init ( settings, &efi_path_settings_operations,
			&netdev->refcnt, NULL );
	if ( ( rc = register_settings ( settings, netdev_settings ( netdev ),
					name ) ) != 0 ) {
		DBGC ( settings, "EFI path %s could not register %s.%s: %s\n",
		       efi_devpath_text ( path ), netdev->name, name,
		       strerror ( rc ) );
		return rc;
	}
	DBGC ( settings, "EFI path %s registered %s.%s\n",
	       efi_devpath_text ( path ), netdev->name, name );

	return 0;
}

/** EFI path settings per-netdevice driver */
struct net_driver efi_path_net_driver __net_driver = {
	.name = "EFI path",
	.priv_len = sizeof ( struct efi_path_settings ),
	.probe = efi_path_net_probe,
};
