mirror of https://github.com/ipxe/ipxe.git
[efi] Include a copy of the device path within struct efi_device
Signed-off-by: Michael Brown <mcb30@ipxe.org>pull/41/head
parent
7107334391
commit
e727f576c2
|
@ -19,6 +19,8 @@ struct efi_device {
|
||||||
struct device dev;
|
struct device dev;
|
||||||
/** EFI device handle */
|
/** EFI device handle */
|
||||||
EFI_HANDLE device;
|
EFI_HANDLE device;
|
||||||
|
/** EFI device path copy */
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *path;
|
||||||
/** Driver for this device */
|
/** Driver for this device */
|
||||||
struct efi_driver *driver;
|
struct efi_driver *driver;
|
||||||
/** Driver-private data */
|
/** Driver-private data */
|
||||||
|
|
|
@ -30,6 +30,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
|
||||||
#include <ipxe/efi/Protocol/ComponentName2.h>
|
#include <ipxe/efi/Protocol/ComponentName2.h>
|
||||||
#include <ipxe/efi/Protocol/DevicePath.h>
|
#include <ipxe/efi/Protocol/DevicePath.h>
|
||||||
#include <ipxe/efi/efi_strings.h>
|
#include <ipxe/efi/efi_strings.h>
|
||||||
|
#include <ipxe/efi/efi_utils.h>
|
||||||
#include <ipxe/efi/efi_driver.h>
|
#include <ipxe/efi/efi_driver.h>
|
||||||
|
|
||||||
/** @file
|
/** @file
|
||||||
|
@ -132,8 +133,15 @@ efi_driver_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
||||||
static EFI_STATUS EFIAPI
|
static EFI_STATUS EFIAPI
|
||||||
efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
||||||
EFI_HANDLE device, EFI_DEVICE_PATH_PROTOCOL *child ) {
|
EFI_HANDLE device, EFI_DEVICE_PATH_PROTOCOL *child ) {
|
||||||
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
struct efi_driver *efidrv;
|
struct efi_driver *efidrv;
|
||||||
struct efi_device *efidev;
|
struct efi_device *efidev;
|
||||||
|
union {
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *path;
|
||||||
|
void *interface;
|
||||||
|
} path;
|
||||||
|
EFI_DEVICE_PATH_PROTOCOL *path_end;
|
||||||
|
size_t path_len;
|
||||||
EFI_STATUS efirc;
|
EFI_STATUS efirc;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -151,17 +159,37 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
||||||
goto err_already_started;
|
goto err_already_started;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Open device path */
|
||||||
|
if ( ( efirc = bs->OpenProtocol ( device,
|
||||||
|
&efi_device_path_protocol_guid,
|
||||||
|
&path.interface, efi_image_handle,
|
||||||
|
device,
|
||||||
|
EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
|
||||||
|
rc = -EEFI ( efirc );
|
||||||
|
DBGC ( device, "EFIDRV %s could not open device path: %s\n",
|
||||||
|
efi_handle_name ( device ), strerror ( rc ) );
|
||||||
|
goto err_open_path;
|
||||||
|
}
|
||||||
|
path_len = ( efi_devpath_len ( path.path ) + sizeof ( *path_end ) );
|
||||||
|
|
||||||
/* Allocate and initialise structure */
|
/* Allocate and initialise structure */
|
||||||
efidev = zalloc ( sizeof ( *efidev ) );
|
efidev = zalloc ( sizeof ( *efidev ) + path_len );
|
||||||
if ( ! efidev ) {
|
if ( ! efidev ) {
|
||||||
efirc = EFI_OUT_OF_RESOURCES;
|
efirc = EFI_OUT_OF_RESOURCES;
|
||||||
goto err_alloc;
|
goto err_alloc;
|
||||||
}
|
}
|
||||||
efidev->device = device;
|
efidev->device = device;
|
||||||
efidev->dev.desc.bus_type = BUS_TYPE_EFI;
|
efidev->dev.desc.bus_type = BUS_TYPE_EFI;
|
||||||
|
efidev->path = ( ( ( void * ) efidev ) + sizeof ( *efidev ) );
|
||||||
|
memcpy ( efidev->path, path.path, path_len );
|
||||||
INIT_LIST_HEAD ( &efidev->dev.children );
|
INIT_LIST_HEAD ( &efidev->dev.children );
|
||||||
list_add ( &efidev->dev.siblings, &efi_devices );
|
list_add ( &efidev->dev.siblings, &efi_devices );
|
||||||
|
|
||||||
|
/* Close device path */
|
||||||
|
bs->CloseProtocol ( device, &efi_device_path_protocol_guid,
|
||||||
|
efi_image_handle, device );
|
||||||
|
path.path = NULL;
|
||||||
|
|
||||||
/* Try to start this device */
|
/* Try to start this device */
|
||||||
for_each_table_entry ( efidrv, EFI_DRIVERS ) {
|
for_each_table_entry ( efidrv, EFI_DRIVERS ) {
|
||||||
if ( ( rc = efidrv->supported ( device ) ) != 0 ) {
|
if ( ( rc = efidrv->supported ( device ) ) != 0 ) {
|
||||||
|
@ -187,6 +215,11 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
|
||||||
list_del ( &efidev->dev.siblings );
|
list_del ( &efidev->dev.siblings );
|
||||||
free ( efidev );
|
free ( efidev );
|
||||||
err_alloc:
|
err_alloc:
|
||||||
|
if ( path.path ) {
|
||||||
|
bs->CloseProtocol ( device, &efi_device_path_protocol_guid,
|
||||||
|
efi_image_handle, device );
|
||||||
|
}
|
||||||
|
err_open_path:
|
||||||
err_already_started:
|
err_already_started:
|
||||||
return efirc;
|
return efirc;
|
||||||
}
|
}
|
||||||
|
|
|
@ -936,10 +936,6 @@ static int efi_snp_probe ( struct net_device *netdev ) {
|
||||||
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
|
||||||
struct efi_device *efidev;
|
struct efi_device *efidev;
|
||||||
struct efi_snp_device *snpdev;
|
struct efi_snp_device *snpdev;
|
||||||
union {
|
|
||||||
EFI_DEVICE_PATH_PROTOCOL *path;
|
|
||||||
void *interface;
|
|
||||||
} path;
|
|
||||||
EFI_DEVICE_PATH_PROTOCOL *path_end;
|
EFI_DEVICE_PATH_PROTOCOL *path_end;
|
||||||
MAC_ADDR_DEVICE_PATH *macpath;
|
MAC_ADDR_DEVICE_PATH *macpath;
|
||||||
size_t path_prefix_len = 0;
|
size_t path_prefix_len = 0;
|
||||||
|
@ -1019,21 +1015,8 @@ static int efi_snp_probe ( struct net_device *netdev ) {
|
||||||
sizeof ( snpdev->name[0] ) ),
|
sizeof ( snpdev->name[0] ) ),
|
||||||
"%s", netdev->name );
|
"%s", netdev->name );
|
||||||
|
|
||||||
/* Get the parent device path */
|
|
||||||
if ( ( efirc = bs->OpenProtocol ( efidev->device,
|
|
||||||
&efi_device_path_protocol_guid,
|
|
||||||
&path.interface, efi_image_handle,
|
|
||||||
efidev->device,
|
|
||||||
EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
|
|
||||||
rc = -EEFI ( efirc );
|
|
||||||
DBGC ( snpdev, "SNPDEV %p cannot get %s device path: %s\n",
|
|
||||||
snpdev, efi_handle_name ( efidev->device ),
|
|
||||||
strerror ( rc ) );
|
|
||||||
goto err_open_device_path;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate the new device path */
|
/* Allocate the new device path */
|
||||||
path_prefix_len = efi_devpath_len ( path.path );
|
path_prefix_len = efi_devpath_len ( efidev->path );
|
||||||
snpdev->path = zalloc ( path_prefix_len + sizeof ( *macpath ) +
|
snpdev->path = zalloc ( path_prefix_len + sizeof ( *macpath ) +
|
||||||
sizeof ( *path_end ) );
|
sizeof ( *path_end ) );
|
||||||
if ( ! snpdev->path ) {
|
if ( ! snpdev->path ) {
|
||||||
|
@ -1042,7 +1025,7 @@ static int efi_snp_probe ( struct net_device *netdev ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Populate the device path */
|
/* Populate the device path */
|
||||||
memcpy ( snpdev->path, path.path, path_prefix_len );
|
memcpy ( snpdev->path, efidev->path, path_prefix_len );
|
||||||
macpath = ( ( ( void * ) snpdev->path ) + path_prefix_len );
|
macpath = ( ( ( void * ) snpdev->path ) + path_prefix_len );
|
||||||
path_end = ( ( void * ) ( macpath + 1 ) );
|
path_end = ( ( void * ) ( macpath + 1 ) );
|
||||||
memset ( macpath, 0, sizeof ( *macpath ) );
|
memset ( macpath, 0, sizeof ( *macpath ) );
|
||||||
|
@ -1119,9 +1102,6 @@ static int efi_snp_probe ( struct net_device *netdev ) {
|
||||||
err_install_protocol_interface:
|
err_install_protocol_interface:
|
||||||
free ( snpdev->path );
|
free ( snpdev->path );
|
||||||
err_alloc_device_path:
|
err_alloc_device_path:
|
||||||
bs->CloseProtocol ( efidev->device, &efi_device_path_protocol_guid,
|
|
||||||
efi_image_handle, efidev->device );
|
|
||||||
err_open_device_path:
|
|
||||||
bs->CloseEvent ( snpdev->snp.WaitForPacket );
|
bs->CloseEvent ( snpdev->snp.WaitForPacket );
|
||||||
err_create_event:
|
err_create_event:
|
||||||
err_ll_addr_len:
|
err_ll_addr_len:
|
||||||
|
|
Loading…
Reference in New Issue