aboutsummaryrefslogtreecommitdiffstats
path: root/src/interface/efi/efi_utils.c
diff options
context:
space:
mode:
authorMichael Brown <mcb30@ipxe.org>2014-08-06 14:04:02 +0100
committerMichael Brown <mcb30@ipxe.org>2014-08-06 14:27:45 +0100
commit5c4f1da2ceac87ab13ca946f2dfbaadcd19e208d (patch)
treea651a2d33e1954e904f2aaf321d26f47deb071f7 /src/interface/efi/efi_utils.c
parent2bf428c2a9de75ee130d366f5139fc762106e220 (diff)
downloadipxe-5c4f1da2ceac87ab13ca946f2dfbaadcd19e208d.tar.gz
[efi] Generalise snpnet_pci_info() to efi_locate_device()
Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/interface/efi/efi_utils.c')
-rw-r--r--src/interface/efi/efi_utils.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/src/interface/efi/efi_utils.c b/src/interface/efi/efi_utils.c
index 9a3ec159..b4f07330 100644
--- a/src/interface/efi/efi_utils.c
+++ b/src/interface/efi/efi_utils.c
@@ -49,6 +49,58 @@ EFI_DEVICE_PATH_PROTOCOL * efi_devpath_end ( EFI_DEVICE_PATH_PROTOCOL *path ) {
}
/**
+ * Locate parent device supporting a given protocol
+ *
+ * @v device EFI device handle
+ * @v protocol Protocol GUID
+ * @v parent Parent EFI device handle to fill in
+ * @ret rc Return status code
+ */
+int efi_locate_device ( EFI_HANDLE device, EFI_GUID *protocol,
+ EFI_HANDLE *parent ) {
+ EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
+ union {
+ EFI_DEVICE_PATH_PROTOCOL *path;
+ void *interface;
+ } path;
+ EFI_DEVICE_PATH_PROTOCOL *devpath;
+ EFI_STATUS efirc;
+ int rc;
+
+ /* Get 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, "EFIDEV %p %s cannot open device path: %s\n",
+ device, efi_handle_name ( device ), strerror ( rc ) );
+ goto err_open_device_path;
+ }
+ devpath = path.path;
+
+ /* Check for presence of specified protocol */
+ if ( ( efirc = bs->LocateDevicePath ( protocol, &devpath,
+ parent ) ) != 0 ) {
+ rc = -EEFI ( efirc );
+ DBGC ( device, "EFIDEV %p %s has no parent supporting %s: %s\n",
+ device, efi_handle_name ( device ),
+ efi_guid_ntoa ( protocol ), strerror ( rc ) );
+ goto err_locate_protocol;
+ }
+
+ /* Success */
+ rc = 0;
+
+ err_locate_protocol:
+ bs->CloseProtocol ( device, &efi_device_path_protocol_guid,
+ efi_image_handle, device );
+ err_open_device_path:
+ return rc;
+}
+
+/**
* Add EFI device as child of another EFI device
*
* @v parent EFI parent device handle