iPXE
efi_snp.h File Reference

iPXE EFI SNP interface More...

Go to the source code of this file.

Data Structures

struct  efi_snp_device
 An SNP device. More...

Macros

#define EFI_SNP_NUM_TX   32
 SNP transmit completion ring size.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 FILE_SECBOOT (PERMITTED)
int efi_snp_hii_install (struct efi_snp_device *snpdev)
 Install HII protocol and packages for SNP device.
int efi_snp_hii_uninstall (struct efi_snp_device *snpdev)
 Uninstall HII protocol and package for SNP device.
struct efi_snp_devicefind_snpdev (EFI_HANDLE handle)
 Find SNP device by EFI device handle.
struct efi_snp_devicelast_opened_snpdev (void)
 Get most recently opened SNP device.
void efi_snp_add_claim (int delta)
 Add to SNP claimed/released count.
static void efi_snp_claim (void)
 Claim network devices for use by iPXE.
static void efi_snp_release (void)
 Release network devices for use via SNP.

Detailed Description

iPXE EFI SNP interface

Definition in file efi_snp.h.

Macro Definition Documentation

◆ EFI_SNP_NUM_TX

#define EFI_SNP_NUM_TX   32

SNP transmit completion ring size.

Definition at line 26 of file efi_snp.h.

Referenced by efi_snp_get_status(), and efi_snp_transmit().

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ efi_snp_hii_install()

int efi_snp_hii_install ( struct efi_snp_device * snpdev)
extern

Install HII protocol and packages for SNP device.

Parameters
snpdevSNP device
Return values
rcReturn status code

Definition at line 659 of file efi_snp_hii.c.

659 {
660 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
661 VENDOR_DEVICE_PATH *vendor_path;
662 EFI_DEVICE_PATH_PROTOCOL *path_end;
663 size_t path_prefix_len;
664 int leak = 0;
665 EFI_STATUS efirc;
666 int rc;
667
668 /* Do nothing if HII database protocol is not supported */
669 if ( ! efihii ) {
670 rc = -ENOTSUP;
671 goto err_no_hii;
672 }
673
674 /* Initialise HII protocol */
675 memcpy ( &snpdev->hii, &efi_snp_device_hii, sizeof ( snpdev->hii ) );
676
677 /* Create HII package list */
678 snpdev->package_list = efi_snp_hii_package_list ( snpdev );
679 if ( ! snpdev->package_list ) {
680 DBGC ( snpdev, "SNPDEV %p could not create HII package list\n",
681 snpdev );
682 rc = -ENOMEM;
683 goto err_build_package_list;
684 }
685
686 /* Allocate the new device path */
687 path_prefix_len = efi_path_len ( snpdev->path );
688 snpdev->hii_child_path = zalloc ( path_prefix_len +
689 sizeof ( *vendor_path ) +
690 sizeof ( *path_end ) );
691 if ( ! snpdev->hii_child_path ) {
692 DBGC ( snpdev,
693 "SNPDEV %p could not allocate HII child device path\n",
694 snpdev );
695 rc = -ENOMEM;
696 goto err_alloc_child_path;
697 }
698
699 /* Populate the device path */
700 memcpy ( snpdev->hii_child_path, snpdev->path, path_prefix_len );
701 vendor_path = ( ( ( void * ) snpdev->hii_child_path ) +
702 path_prefix_len );
703 vendor_path->Header.Type = HARDWARE_DEVICE_PATH;
704 vendor_path->Header.SubType = HW_VENDOR_DP;
705 vendor_path->Header.Length[0] = sizeof ( *vendor_path );
706 efi_snp_hii_random_guid ( &vendor_path->Guid );
707 path_end = ( ( void * ) ( vendor_path + 1 ) );
708 efi_path_terminate ( path_end );
709
710 /* Create device path and child handle for HII association */
711 if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
712 &snpdev->hii_child_handle,
714 NULL ) ) != 0 ) {
715 rc = -EEFI ( efirc );
716 DBGC ( snpdev, "SNPDEV %p could not create HII child handle: "
717 "%s\n", snpdev, strerror ( rc ) );
718 goto err_hii_child_handle;
719 }
720
721 /* Add HII packages */
722 if ( ( efirc = efihii->NewPackageList ( efihii, snpdev->package_list,
723 snpdev->hii_child_handle,
724 &snpdev->hii_handle ) ) != 0 ) {
725 rc = -EEFI ( efirc );
726 DBGC ( snpdev, "SNPDEV %p could not add HII packages: %s\n",
727 snpdev, strerror ( rc ) );
728 goto err_new_package_list;
729 }
730
731 /* Install HII protocol */
732 if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
733 &snpdev->hii_child_handle,
735 NULL ) ) != 0 ) {
736 rc = -EEFI ( efirc );
737 DBGC ( snpdev, "SNPDEV %p could not install HII protocol: %s\n",
738 snpdev, strerror ( rc ) );
739 goto err_install_protocol;
740 }
741
742 /* Add as child of handle with SNP instance */
743 if ( ( rc = efi_child_add ( snpdev->handle,
744 snpdev->hii_child_handle ) ) != 0 ) {
745 DBGC ( snpdev,
746 "SNPDEV %p could not adopt HII child handle: %s\n",
747 snpdev, strerror ( rc ) );
748 goto err_efi_child_add;
749 }
750
751 return 0;
752
753 efi_child_del ( snpdev->handle, snpdev->hii_child_handle );
754 err_efi_child_add:
755 if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
756 snpdev->hii_child_handle,
758 NULL ) ) != 0 ) {
759 DBGC ( snpdev, "SNPDEV %p could not uninstall HII protocol: "
760 "%s\n", snpdev, strerror ( -EEFI ( efirc ) ) );
761 leak = 1;
762 }
763 efi_nullify_hii ( &snpdev->hii );
764 err_install_protocol:
765 if ( ! leak )
766 efihii->RemovePackageList ( efihii, snpdev->hii_handle );
767 err_new_package_list:
768 if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
769 snpdev->hii_child_handle,
771 NULL ) ) != 0 ) {
772 DBGC ( snpdev, "SNPDEV %p could not uninstall HII path: %s\n",
773 snpdev, strerror ( -EEFI ( efirc ) ) );
774 leak = 1;
775 }
776 err_hii_child_handle:
777 if ( ! leak ) {
778 free ( snpdev->hii_child_path );
779 snpdev->hii_child_path = NULL;
780 }
781 err_alloc_child_path:
782 if ( ! leak ) {
783 free ( snpdev->package_list );
784 snpdev->package_list = NULL;
785 }
786 err_build_package_list:
787 err_no_hii:
788 return rc;
789}
#define NULL
NULL pointer (VOID *)
Definition Base.h:322
#define HARDWARE_DEVICE_PATH
Hardware Device Paths.
Definition DevicePath.h:71
#define HW_VENDOR_DP
Hardware Vendor Device Path SubType.
Definition DevicePath.h:136
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition efi_guid.c:169
EFI_GUID efi_hii_config_access_protocol_guid
HII configuration access protocol GUID.
Definition efi_guid.c:221
void efi_nullify_hii(EFI_HII_CONFIG_ACCESS_PROTOCOL *hii)
Nullify HII configuration access protocol.
Definition efi_null.c:344
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition efi_path.c:174
static void efi_path_terminate(EFI_DEVICE_PATH_PROTOCOL *end)
Terminate device path.
Definition efi_path.h:31
static EFI_HII_PACKAGE_LIST_HEADER * efi_snp_hii_package_list(struct efi_snp_device *snpdev)
Build HII package list for SNP device.
static void efi_snp_hii_random_guid(EFI_GUID *guid)
Generate a random GUID.
static EFI_HII_DATABASE_PROTOCOL * efihii
EFI HII database protocol.
Definition efi_snp_hii.c:81
static EFI_HII_CONFIG_ACCESS_PROTOCOL efi_snp_device_hii
HII configuration access protocol.
void efi_child_del(EFI_HANDLE parent, EFI_HANDLE child)
Remove EFI device as child of another EFI device.
Definition efi_utils.c:138
int efi_child_add(EFI_HANDLE parent, EFI_HANDLE child)
Add EFI device as child of another EFI device.
Definition efi_utils.c:111
#define DBGC(...)
Definition compiler.h:505
#define ENOMEM
Not enough space.
Definition errno.h:535
#define ENOTSUP
Operation not supported.
Definition errno.h:590
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition efi.h:175
EFI_SYSTEM_TABLE * efi_systab
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * zalloc(size_t size)
Allocate cleared memory.
Definition malloc.c:662
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
EFI Boot Services Table.
Definition UefiSpec.h:1931
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition UefiSpec.h:2011
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition UefiSpec.h:2010
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition DevicePath.h:46
UINT8 Type
0x01 Hardware Device Path.
Definition DevicePath.h:47
UINT8 Length[2]
Specific Device Path data.
Definition DevicePath.h:59
UINT8 SubType
Varies by Type 0xFF End Entire Device Path, or 0x01 End This Instance of a Device Path and start a ne...
Definition DevicePath.h:54
The Vendor Device Path allows the creation of vendor-defined Device Paths.
Definition DevicePath.h:143
EFI_DEVICE_PATH_PROTOCOL Header
Definition DevicePath.h:144
EFI_GUID Guid
Vendor-assigned GUID that defines the data that follows.
Definition DevicePath.h:148
EFI_HANDLE handle
EFI device handle.
Definition efi_snp.h:37
EFI_DEVICE_PATH_PROTOCOL * hii_child_path
Device path of HII child handle.
Definition efi_snp.h:69
EFI_HII_PACKAGE_LIST_HEADER * package_list
HII package list.
Definition efi_snp.h:65
EFI_DEVICE_PATH_PROTOCOL * path
The device path.
Definition efi_snp.h:79
EFI_HII_CONFIG_ACCESS_PROTOCOL hii
HII configuration access protocol.
Definition efi_snp.h:63
EFI_HII_HANDLE hii_handle
HII handle.
Definition efi_snp.h:71
EFI_HANDLE hii_child_handle
EFI child handle for HII association.
Definition efi_snp.h:67

References DBGC, EEFI, efi_child_add(), efi_child_del(), efi_device_path_protocol_guid, efi_hii_config_access_protocol_guid, efi_nullify_hii(), efi_path_len(), efi_path_terminate(), efi_snp_device_hii, efi_snp_hii_package_list(), efi_snp_hii_random_guid(), efi_systab, efihii, ENOMEM, ENOTSUP, free, VENDOR_DEVICE_PATH::Guid, efi_snp_device::handle, HARDWARE_DEVICE_PATH, VENDOR_DEVICE_PATH::Header, efi_snp_device::hii, efi_snp_device::hii_child_handle, efi_snp_device::hii_child_path, efi_snp_device::hii_handle, HW_VENDOR_DP, EFI_BOOT_SERVICES::InstallMultipleProtocolInterfaces, EFI_DEVICE_PATH_PROTOCOL::Length, memcpy(), NULL, efi_snp_device::package_list, efi_snp_device::path, rc, strerror(), EFI_DEVICE_PATH_PROTOCOL::SubType, EFI_DEVICE_PATH_PROTOCOL::Type, EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces, and zalloc().

Referenced by efi_snp_probe().

◆ efi_snp_hii_uninstall()

int efi_snp_hii_uninstall ( struct efi_snp_device * snpdev)
extern

Uninstall HII protocol and package for SNP device.

Parameters
snpdevSNP device
Return values
leakUninstallation failed: leak memory

Definition at line 797 of file efi_snp_hii.c.

797 {
798 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
799 int leak = efi_shutdown_in_progress;
800 EFI_STATUS efirc;
801
802 /* Do nothing if HII database protocol is not supported */
803 if ( ! efihii )
804 return 0;
805
806 /* Uninstall protocols and remove package list */
807 efi_child_del ( snpdev->handle, snpdev->hii_child_handle );
808 if ( ( ! efi_shutdown_in_progress ) &&
810 snpdev->hii_child_handle,
812 NULL ) ) != 0 ) ) {
813 DBGC ( snpdev, "SNPDEV %p could not uninstall HII protocol: "
814 "%s\n", snpdev, strerror ( -EEFI ( efirc ) ) );
815 leak = 1;
816 }
817 efi_nullify_hii ( &snpdev->hii );
818 if ( ! leak )
819 efihii->RemovePackageList ( efihii, snpdev->hii_handle );
820 if ( ( ! efi_shutdown_in_progress ) &&
822 snpdev->hii_child_handle,
824 NULL ) ) != 0 ) ) {
825 DBGC ( snpdev, "SNPDEV %p could not uninstall HII path: %s\n",
826 snpdev, strerror ( -EEFI ( efirc ) ) );
827 leak = 1;
828 }
829 if ( ! leak ) {
830 free ( snpdev->hii_child_path );
831 snpdev->hii_child_path = NULL;
832 free ( snpdev->package_list );
833 snpdev->package_list = NULL;
834 }
835
836 /* Report leakage, if applicable */
837 if ( leak && ( ! efi_shutdown_in_progress ) )
838 DBGC ( snpdev, "SNPDEV %p HII nullified and leaked\n", snpdev );
839 return leak;
840}
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition efi_init.c:60

References DBGC, EEFI, efi_child_del(), efi_device_path_protocol_guid, efi_hii_config_access_protocol_guid, efi_nullify_hii(), efi_shutdown_in_progress, efi_systab, efihii, free, efi_snp_device::handle, efi_snp_device::hii, efi_snp_device::hii_child_handle, efi_snp_device::hii_child_path, efi_snp_device::hii_handle, NULL, efi_snp_device::package_list, strerror(), and EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces.

Referenced by efi_snp_probe(), and efi_snp_remove().

◆ find_snpdev()

struct efi_snp_device * find_snpdev ( EFI_HANDLE handle)
extern

Find SNP device by EFI device handle.

Parameters
handleEFI device handle
Return values
snpdevSNP device, or NULL

Definition at line 2104 of file efi_snp.c.

2104 {
2105 struct efi_snp_device *snpdev;
2106
2107 list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
2108 if ( snpdev->handle == handle )
2109 return snpdev;
2110 }
2111 return NULL;
2112}
uint16_t handle
Handle.
Definition smbios.h:5
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition list.h:432
An SNP device.
Definition efi_snp.h:29
struct list_head list
List of SNP devices.
Definition efi_snp.h:31

References EFI_HANDLE, efi_snp_device::handle, handle, efi_snp_device::list, list_for_each_entry, and NULL.

Referenced by snpnet_supported().

◆ last_opened_snpdev()

struct efi_snp_device * last_opened_snpdev ( void )
extern

Get most recently opened SNP device.

Return values
snpdevMost recently opened SNP device, or NULL

Definition at line 2119 of file efi_snp.c.

2119 {
2120 struct net_device *netdev;
2121
2123 if ( ! netdev )
2124 return NULL;
2125
2126 return efi_snp_demux ( netdev );
2127}
static struct efi_snp_device * efi_snp_demux(struct net_device *netdev)
Locate SNP device corresponding to network device.
Definition efi_snp.c:1767
static struct net_device * netdev
Definition gdbudp.c:53
struct net_device * last_opened_netdev(void)
Get most recently opened network device.
Definition netdevice.c:1048
A network device.
Definition netdevice.h:353

References efi_snp_demux(), last_opened_netdev(), netdev, and NULL.

Referenced by efi_image_exec().

◆ efi_snp_add_claim()

void efi_snp_add_claim ( int delta)
extern

Add to SNP claimed/released count.

Parameters
deltaClaim count change

Definition at line 2134 of file efi_snp.c.

2134 {
2135 struct efi_snp_device *snpdev;
2136
2137 /* Raise TPL if we are about to claim devices */
2138 if ( ! efi_snp_claimed )
2140
2141 /* Claim SNP devices */
2142 efi_snp_claimed += delta;
2143 assert ( efi_snp_claimed >= 0 );
2144
2145 /* Update SNP mode state for each interface */
2146 list_for_each_entry ( snpdev, &efi_snp_devices, list )
2147 efi_snp_set_state ( snpdev );
2148
2149 /* Restore TPL if we have released devices */
2150 if ( ! efi_snp_claimed )
2152}
#define assert(condition)
Assert a condition at run-time.
Definition assert.h:50
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to internal level.
Definition efi_init.c:383
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition efi_init.c:399
static void efi_snp_set_state(struct efi_snp_device *snpdev)
Set EFI SNP mode state.
Definition efi_snp.c:92
static struct efi_saved_tpl efi_snp_saved_tpl
TPL prior to network devices being claimed.
Definition efi_snp.c:52
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition efi_snp.c:49

References assert, efi_raise_tpl(), efi_restore_tpl(), efi_snp_claimed, efi_snp_saved_tpl, efi_snp_set_state(), efi_snp_device::list, and list_for_each_entry.

Referenced by efi_snp_claim(), and efi_snp_release().

◆ efi_snp_claim()

void efi_snp_claim ( void )
inlinestatic

Claim network devices for use by iPXE.

Definition at line 92 of file efi_snp.h.

92 {
93 efi_snp_add_claim ( +1 );
94}
void efi_snp_add_claim(int delta)
Add to SNP claimed/released count.
Definition efi_snp.c:2134

References efi_snp_add_claim().

Referenced by _efi_start(), efi_block_boot(), efi_block_io_read(), efi_block_io_reset(), efi_block_io_write(), efi_download_start(), efi_image_exec(), efi_pxe_dhcp(), efi_pxe_mtftp(), efi_pxe_udp_open(), and efi_snp_load_file().

◆ efi_snp_release()

void efi_snp_release ( void )
inlinestatic