]> git.ipfire.org Git - thirdparty/ipxe.git/commitdiff
[efi] Generalise snpnet_pci_info() to efi_locate_device()
authorMichael Brown <mcb30@ipxe.org>
Wed, 6 Aug 2014 13:04:02 +0000 (14:04 +0100)
committerMichael Brown <mcb30@ipxe.org>
Wed, 6 Aug 2014 13:27:45 +0000 (14:27 +0100)
Signed-off-by: Michael Brown <mcb30@ipxe.org>
src/drivers/net/efi/snpnet.c
src/include/ipxe/efi/efi_utils.h
src/interface/efi/efi_utils.c

index 0348e7d1a1d96b1f6aa0dcf72b972b15c4771ff5..f5b294aca5c895dee87e4e8226d649d31d672b96 100644 (file)
@@ -31,6 +31,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
 #include <ipxe/efi/Protocol/SimpleNetwork.h>
 #include <ipxe/efi/efi_driver.h>
 #include <ipxe/efi/efi_pci.h>
+#include <ipxe/efi/efi_utils.h>
 #include "snpnet.h"
 
 /** @file
@@ -414,57 +415,31 @@ static struct net_device_operations snpnet_operations = {
  * @ret rc             Return status code
  */
 static int snpnet_pci_info ( struct efi_device *efidev, struct device *dev ) {
-       EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
        EFI_HANDLE device = efidev->device;
-       union {
-               EFI_DEVICE_PATH_PROTOCOL *path;
-               void *interface;
-       } path;
-       EFI_DEVICE_PATH_PROTOCOL *devpath;
-       struct pci_device pci;
        EFI_HANDLE pci_device;
-       EFI_STATUS efirc;
+       struct pci_device pci;
        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, "SNP %p %s cannot open device path: %s\n",
+       /* Find parent PCI device */
+       if ( ( rc = efi_locate_device ( device, &efi_pci_io_protocol_guid,
+                                       &pci_device ) ) != 0 ) {
+               DBGC ( device, "SNP %p %s is not a PCI device: %s\n",
                       device, efi_handle_name ( device ), strerror ( rc ) );
-               goto err_open_device_path;
-       }
-       devpath = path.path;
-
-       /* Check for presence of PCI I/O protocol */
-       if ( ( efirc = bs->LocateDevicePath ( &efi_pci_io_protocol_guid,
-                                             &devpath, &pci_device ) ) != 0 ) {
-               rc = -EEFI ( efirc );
-               DBGC ( device, "SNP %p %s is not a PCI device\n",
-                      device, efi_handle_name ( device ) );
-               goto err_locate_pci_io;
+               return rc;
        }
 
        /* Get PCI device information */
        if ( ( rc = efipci_info ( pci_device, &pci ) ) != 0 ) {
                DBGC ( device, "SNP %p %s could not get PCI information: %s\n",
                       device, efi_handle_name ( device ), strerror ( rc ) );
-               goto err_efipci_info;
+               return rc;
        }
 
        /* Populate SNP device information */
        memcpy ( &dev->desc, &pci.dev.desc, sizeof ( dev->desc ) );
        snprintf ( dev->name, sizeof ( dev->name ), "SNP-%s", pci.dev.name );
 
- err_efipci_info:
- err_locate_pci_io:
-       bs->CloseProtocol ( device, &efi_device_path_protocol_guid,
-                           efi_image_handle, device );
- err_open_device_path:
-       return rc;
+       return 0;
 }
 
 /**
index 23972c7a3cb4caa308243bd32d3dbbd14546dc86..92ca0a9c530aa80465790838ae784149793c9c16 100644 (file)
@@ -13,6 +13,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
 
 extern EFI_DEVICE_PATH_PROTOCOL *
 efi_devpath_end ( EFI_DEVICE_PATH_PROTOCOL *path );
+extern int efi_locate_device ( EFI_HANDLE device, EFI_GUID *protocol,
+                              EFI_HANDLE *parent );
 extern int efi_child_add ( EFI_HANDLE parent, EFI_HANDLE child );
 extern void efi_child_del ( EFI_HANDLE parent, EFI_HANDLE child );
 
index 9a3ec159839bf163f3b467b79a3fb342b6f151ae..b4f073304565d5728cd3e3a55b497b40ac0e12b8 100644 (file)
@@ -48,6 +48,58 @@ EFI_DEVICE_PATH_PROTOCOL * efi_devpath_end ( EFI_DEVICE_PATH_PROTOCOL *path ) {
        return 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
  *