mirror of https://github.com/ipxe/ipxe.git
[efi] Split efi_netdev_path() out to a separate function
Provide efi_netdev_path() as a standalone function, to allow for reuse when constructing child device paths. Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/171/head
parent
b50ad5f09a
commit
6154b1fb20
|
@ -13,12 +13,14 @@ FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
|
|||
#include <ipxe/efi/efi.h>
|
||||
#include <ipxe/efi/Protocol/DevicePath.h>
|
||||
|
||||
struct net_device;
|
||||
struct uri;
|
||||
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_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 );
|
||||
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <byteswap.h>
|
||||
#include <ipxe/netdevice.h>
|
||||
#include <ipxe/vlan.h>
|
||||
#include <ipxe/uri.h>
|
||||
#include <ipxe/usb.h>
|
||||
#include <ipxe/efi/efi.h>
|
||||
|
@ -61,6 +64,68 @@ size_t efi_path_len ( EFI_DEVICE_PATH_PROTOCOL *path ) {
|
|||
return ( ( ( void * ) end ) - ( ( void * ) path ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 ) {
|
||||
struct efi_device *efidev;
|
||||
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;
|
||||
|
||||
/* Find parent EFI device */
|
||||
efidev = efidev_parent ( netdev->dev );
|
||||
if ( ! efidev )
|
||||
return NULL;
|
||||
|
||||
/* Calculate device path length */
|
||||
prefix_len = efi_path_len ( efidev->path );
|
||||
len = ( prefix_len + sizeof ( *macpath ) + sizeof ( *vlanpath ) +
|
||||
sizeof ( *end ) );
|
||||
|
||||
/* Allocate device path */
|
||||
path = zalloc ( len );
|
||||
if ( ! path )
|
||||
return NULL;
|
||||
|
||||
/* Construct device path */
|
||||
memcpy ( path, efidev->path, 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 ) );
|
||||
}
|
||||
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 URI
|
||||
*
|
||||
|
|
|
@ -1624,12 +1624,7 @@ static int efi_snp_probe ( struct net_device *netdev ) {
|
|||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||
struct efi_device *efidev;
|
||||
struct efi_snp_device *snpdev;
|
||||
EFI_DEVICE_PATH_PROTOCOL *path_end;
|
||||
MAC_ADDR_DEVICE_PATH *macpath;
|
||||
VLAN_DEVICE_PATH *vlanpath;
|
||||
size_t path_prefix_len = 0;
|
||||
unsigned int ifcnt;
|
||||
unsigned int tag;
|
||||
void *interface;
|
||||
EFI_STATUS efirc;
|
||||
int rc;
|
||||
|
@ -1714,41 +1709,13 @@ static int efi_snp_probe ( struct net_device *netdev ) {
|
|||
sizeof ( snpdev->name[0] ) ),
|
||||
"%s", netdev->name );
|
||||
|
||||
/* Allocate the new device path */
|
||||
path_prefix_len = efi_path_len ( efidev->path );
|
||||
snpdev->path = zalloc ( path_prefix_len + sizeof ( *macpath ) +
|
||||
sizeof ( *vlanpath ) + sizeof ( *path_end ) );
|
||||
/* Construct device path */
|
||||
snpdev->path = efi_netdev_path ( netdev );
|
||||
if ( ! snpdev->path ) {
|
||||
rc = -ENOMEM;
|
||||
goto err_alloc_device_path;
|
||||
goto err_path;
|
||||
}
|
||||
|
||||
/* Populate the device path */
|
||||
memcpy ( snpdev->path, efidev->path, path_prefix_len );
|
||||
macpath = ( ( ( void * ) snpdev->path ) + path_prefix_len );
|
||||
memset ( macpath, 0, sizeof ( *macpath ) );
|
||||
macpath->Header.Type = MESSAGING_DEVICE_PATH;
|
||||
macpath->Header.SubType = MSG_MAC_ADDR_DP;
|
||||
macpath->Header.Length[0] = sizeof ( *macpath );
|
||||
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 ) );
|
||||
memset ( vlanpath, 0, sizeof ( *vlanpath ) );
|
||||
vlanpath->Header.Type = MESSAGING_DEVICE_PATH;
|
||||
vlanpath->Header.SubType = MSG_VLAN_DP;
|
||||
vlanpath->Header.Length[0] = sizeof ( *vlanpath );
|
||||
vlanpath->VlanId = tag;
|
||||
path_end = ( ( ( void * ) vlanpath ) + sizeof ( *vlanpath ) );
|
||||
} else {
|
||||
path_end = ( ( ( void * ) macpath ) + sizeof ( *macpath ) );
|
||||
}
|
||||
memset ( path_end, 0, sizeof ( *path_end ) );
|
||||
path_end->Type = END_DEVICE_PATH_TYPE;
|
||||
path_end->SubType = END_ENTIRE_DEVICE_PATH_SUBTYPE;
|
||||
path_end->Length[0] = sizeof ( *path_end );
|
||||
|
||||
/* Install the SNP */
|
||||
if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
|
||||
&snpdev->handle,
|
||||
|
@ -1847,7 +1814,7 @@ static int efi_snp_probe ( struct net_device *netdev ) {
|
|||
NULL );
|
||||
err_install_protocol_interface:
|
||||
free ( snpdev->path );
|
||||
err_alloc_device_path:
|
||||
err_path:
|
||||
bs->CloseEvent ( snpdev->snp.WaitForPacket );
|
||||
err_create_event:
|
||||
err_ll_addr_len:
|
||||
|
|
Loading…
Reference in New Issue