Browse Source

[efi] Generalise snpnet_pci_info() to efi_locate_device()

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 9 years ago
parent
commit
5c4f1da2ce
3 changed files with 63 additions and 34 deletions
  1. 9
    34
      src/drivers/net/efi/snpnet.c
  2. 2
    0
      src/include/ipxe/efi/efi_utils.h
  3. 52
    0
      src/interface/efi/efi_utils.c

+ 9
- 34
src/drivers/net/efi/snpnet.c View File

@@ -31,6 +31,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
31 31
 #include <ipxe/efi/Protocol/SimpleNetwork.h>
32 32
 #include <ipxe/efi/efi_driver.h>
33 33
 #include <ipxe/efi/efi_pci.h>
34
+#include <ipxe/efi/efi_utils.h>
34 35
 #include "snpnet.h"
35 36
 
36 37
 /** @file
@@ -414,57 +415,31 @@ static struct net_device_operations snpnet_operations = {
414 415
  * @ret rc		Return status code
415 416
  */
416 417
 static int snpnet_pci_info ( struct efi_device *efidev, struct device *dev ) {
417
-	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
418 418
 	EFI_HANDLE device = efidev->device;
419
-	union {
420
-		EFI_DEVICE_PATH_PROTOCOL *path;
421
-		void *interface;
422
-	} path;
423
-	EFI_DEVICE_PATH_PROTOCOL *devpath;
424
-	struct pci_device pci;
425 419
 	EFI_HANDLE pci_device;
426
-	EFI_STATUS efirc;
420
+	struct pci_device pci;
427 421
 	int rc;
428 422
 
429
-	/* Get device path */
430
-	if ( ( efirc = bs->OpenProtocol ( device,
431
-					  &efi_device_path_protocol_guid,
432
-					  &path.interface,
433
-					  efi_image_handle, device,
434
-					  EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
435
-		rc = -EEFI ( efirc );
436
-		DBGC ( device, "SNP %p %s cannot open device path: %s\n",
423
+	/* Find parent PCI device */
424
+	if ( ( rc = efi_locate_device ( device, &efi_pci_io_protocol_guid,
425
+					&pci_device ) ) != 0 ) {
426
+		DBGC ( device, "SNP %p %s is not a PCI device: %s\n",
437 427
 		       device, efi_handle_name ( device ), strerror ( rc ) );
438
-		goto err_open_device_path;
439
-	}
440
-	devpath = path.path;
441
-
442
-	/* Check for presence of PCI I/O protocol */
443
-	if ( ( efirc = bs->LocateDevicePath ( &efi_pci_io_protocol_guid,
444
-					      &devpath, &pci_device ) ) != 0 ) {
445
-		rc = -EEFI ( efirc );
446
-		DBGC ( device, "SNP %p %s is not a PCI device\n",
447
-		       device, efi_handle_name ( device ) );
448
-		goto err_locate_pci_io;
428
+		return rc;
449 429
 	}
450 430
 
451 431
 	/* Get PCI device information */
452 432
 	if ( ( rc = efipci_info ( pci_device, &pci ) ) != 0 ) {
453 433
 		DBGC ( device, "SNP %p %s could not get PCI information: %s\n",
454 434
 		       device, efi_handle_name ( device ), strerror ( rc ) );
455
-		goto err_efipci_info;
435
+		return rc;
456 436
 	}
457 437
 
458 438
 	/* Populate SNP device information */
459 439
 	memcpy ( &dev->desc, &pci.dev.desc, sizeof ( dev->desc ) );
460 440
 	snprintf ( dev->name, sizeof ( dev->name ), "SNP-%s", pci.dev.name );
461 441
 
462
- err_efipci_info:
463
- err_locate_pci_io:
464
-	bs->CloseProtocol ( device, &efi_device_path_protocol_guid,
465
-			    efi_image_handle, device );
466
- err_open_device_path:
467
-	return rc;
442
+	return 0;
468 443
 }
469 444
 
470 445
 /**

+ 2
- 0
src/include/ipxe/efi/efi_utils.h View File

@@ -13,6 +13,8 @@ FILE_LICENCE ( GPL2_OR_LATER );
13 13
 
14 14
 extern EFI_DEVICE_PATH_PROTOCOL *
15 15
 efi_devpath_end ( EFI_DEVICE_PATH_PROTOCOL *path );
16
+extern int efi_locate_device ( EFI_HANDLE device, EFI_GUID *protocol,
17
+			       EFI_HANDLE *parent );
16 18
 extern int efi_child_add ( EFI_HANDLE parent, EFI_HANDLE child );
17 19
 extern void efi_child_del ( EFI_HANDLE parent, EFI_HANDLE child );
18 20
 

+ 52
- 0
src/interface/efi/efi_utils.c View File

@@ -48,6 +48,58 @@ EFI_DEVICE_PATH_PROTOCOL * efi_devpath_end ( EFI_DEVICE_PATH_PROTOCOL *path ) {
48 48
 	return path;
49 49
 }
50 50
 
51
+/**
52
+ * Locate parent device supporting a given protocol
53
+ *
54
+ * @v device		EFI device handle
55
+ * @v protocol		Protocol GUID
56
+ * @v parent		Parent EFI device handle to fill in
57
+ * @ret rc		Return status code
58
+ */
59
+int efi_locate_device ( EFI_HANDLE device, EFI_GUID *protocol,
60
+			EFI_HANDLE *parent ) {
61
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
62
+	union {
63
+		EFI_DEVICE_PATH_PROTOCOL *path;
64
+		void *interface;
65
+	} path;
66
+	EFI_DEVICE_PATH_PROTOCOL *devpath;
67
+	EFI_STATUS efirc;
68
+	int rc;
69
+
70
+	/* Get device path */
71
+	if ( ( efirc = bs->OpenProtocol ( device,
72
+					  &efi_device_path_protocol_guid,
73
+					  &path.interface,
74
+					  efi_image_handle, device,
75
+					  EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
76
+		rc = -EEFI ( efirc );
77
+		DBGC ( device, "EFIDEV %p %s cannot open device path: %s\n",
78
+		       device, efi_handle_name ( device ), strerror ( rc ) );
79
+		goto err_open_device_path;
80
+	}
81
+	devpath = path.path;
82
+
83
+	/* Check for presence of specified protocol */
84
+	if ( ( efirc = bs->LocateDevicePath ( protocol, &devpath,
85
+					      parent ) ) != 0 ) {
86
+		rc = -EEFI ( efirc );
87
+		DBGC ( device, "EFIDEV %p %s has no parent supporting %s: %s\n",
88
+		       device, efi_handle_name ( device ),
89
+		       efi_guid_ntoa ( protocol ), strerror ( rc ) );
90
+		goto err_locate_protocol;
91
+	}
92
+
93
+	/* Success */
94
+	rc = 0;
95
+
96
+ err_locate_protocol:
97
+	bs->CloseProtocol ( device, &efi_device_path_protocol_guid,
98
+			    efi_image_handle, device );
99
+ err_open_device_path:
100
+	return rc;
101
+}
102
+
51 103
 /**
52 104
  * Add EFI device as child of another EFI device
53 105
  *

Loading…
Cancel
Save