Kaynağa Gözat

[efi] Include a copy of the device path within struct efi_device

Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Michael Brown 8 yıl önce
ebeveyn
işleme
e727f576c2

+ 2
- 0
src/include/ipxe/efi/efi_driver.h Dosyayı Görüntüle

@@ -19,6 +19,8 @@ struct efi_device {
19 19
 	struct device dev;
20 20
 	/** EFI device handle */
21 21
 	EFI_HANDLE device;
22
+	/** EFI device path copy */
23
+	EFI_DEVICE_PATH_PROTOCOL *path;
22 24
 	/** Driver for this device */
23 25
 	struct efi_driver *driver;
24 26
 	/** Driver-private data */

+ 34
- 1
src/interface/efi/efi_driver.c Dosyayı Görüntüle

@@ -30,6 +30,7 @@ FILE_LICENCE ( GPL2_OR_LATER );
30 30
 #include <ipxe/efi/Protocol/ComponentName2.h>
31 31
 #include <ipxe/efi/Protocol/DevicePath.h>
32 32
 #include <ipxe/efi/efi_strings.h>
33
+#include <ipxe/efi/efi_utils.h>
33 34
 #include <ipxe/efi/efi_driver.h>
34 35
 
35 36
 /** @file
@@ -132,8 +133,15 @@ efi_driver_supported ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
132 133
 static EFI_STATUS EFIAPI
133 134
 efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
134 135
 		   EFI_HANDLE device, EFI_DEVICE_PATH_PROTOCOL *child ) {
136
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
135 137
 	struct efi_driver *efidrv;
136 138
 	struct efi_device *efidev;
139
+	union {
140
+		EFI_DEVICE_PATH_PROTOCOL *path;
141
+		void *interface;
142
+	} path;
143
+	EFI_DEVICE_PATH_PROTOCOL *path_end;
144
+	size_t path_len;
137 145
 	EFI_STATUS efirc;
138 146
 	int rc;
139 147
 
@@ -151,17 +159,37 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
151 159
 		goto err_already_started;
152 160
 	}
153 161
 
162
+	/* Open device path */
163
+	if ( ( efirc = bs->OpenProtocol ( device,
164
+					  &efi_device_path_protocol_guid,
165
+					  &path.interface, efi_image_handle,
166
+					  device,
167
+					  EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
168
+		rc = -EEFI ( efirc );
169
+		DBGC ( device, "EFIDRV %s could not open device path: %s\n",
170
+		       efi_handle_name ( device ), strerror ( rc ) );
171
+		goto err_open_path;
172
+	}
173
+	path_len = ( efi_devpath_len ( path.path ) + sizeof ( *path_end ) );
174
+
154 175
 	/* Allocate and initialise structure */
155
-	efidev = zalloc ( sizeof ( *efidev ) );
176
+	efidev = zalloc ( sizeof ( *efidev ) + path_len );
156 177
 	if ( ! efidev ) {
157 178
 		efirc = EFI_OUT_OF_RESOURCES;
158 179
 		goto err_alloc;
159 180
 	}
160 181
 	efidev->device = device;
161 182
 	efidev->dev.desc.bus_type = BUS_TYPE_EFI;
183
+	efidev->path = ( ( ( void * ) efidev ) + sizeof ( *efidev ) );
184
+	memcpy ( efidev->path, path.path, path_len );
162 185
 	INIT_LIST_HEAD ( &efidev->dev.children );
163 186
 	list_add ( &efidev->dev.siblings, &efi_devices );
164 187
 
188
+	/* Close device path */
189
+	bs->CloseProtocol ( device, &efi_device_path_protocol_guid,
190
+			    efi_image_handle, device );
191
+	path.path = NULL;
192
+
165 193
 	/* Try to start this device */
166 194
 	for_each_table_entry ( efidrv, EFI_DRIVERS ) {
167 195
 		if ( ( rc = efidrv->supported ( device ) ) != 0 ) {
@@ -187,6 +215,11 @@ efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
187 215
 	list_del ( &efidev->dev.siblings );
188 216
 	free ( efidev );
189 217
  err_alloc:
218
+	if ( path.path ) {
219
+		bs->CloseProtocol ( device, &efi_device_path_protocol_guid,
220
+				    efi_image_handle, device );
221
+	}
222
+ err_open_path:
190 223
  err_already_started:
191 224
 	return efirc;
192 225
 }

+ 2
- 22
src/interface/efi/efi_snp.c Dosyayı Görüntüle

@@ -936,10 +936,6 @@ static int efi_snp_probe ( struct net_device *netdev ) {
936 936
 	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
937 937
 	struct efi_device *efidev;
938 938
 	struct efi_snp_device *snpdev;
939
-	union {
940
-		EFI_DEVICE_PATH_PROTOCOL *path;
941
-		void *interface;
942
-	} path;
943 939
 	EFI_DEVICE_PATH_PROTOCOL *path_end;
944 940
 	MAC_ADDR_DEVICE_PATH *macpath;
945 941
 	size_t path_prefix_len = 0;
@@ -1019,21 +1015,8 @@ static int efi_snp_probe ( struct net_device *netdev ) {
1019 1015
 				       sizeof ( snpdev->name[0] ) ),
1020 1016
 		       "%s", netdev->name );
1021 1017
 
1022
-	/* Get the parent device path */
1023
-	if ( ( efirc = bs->OpenProtocol ( efidev->device,
1024
-					  &efi_device_path_protocol_guid,
1025
-					  &path.interface, efi_image_handle,
1026
-					  efidev->device,
1027
-					  EFI_OPEN_PROTOCOL_GET_PROTOCOL ))!=0){
1028
-		rc = -EEFI ( efirc );
1029
-		DBGC ( snpdev, "SNPDEV %p cannot get %s device path: %s\n",
1030
-		       snpdev, efi_handle_name ( efidev->device ),
1031
-		       strerror ( rc ) );
1032
-		goto err_open_device_path;
1033
-	}
1034
-
1035 1018
 	/* Allocate the new device path */
1036
-	path_prefix_len = efi_devpath_len ( path.path );
1019
+	path_prefix_len = efi_devpath_len ( efidev->path );
1037 1020
 	snpdev->path = zalloc ( path_prefix_len + sizeof ( *macpath ) +
1038 1021
 				sizeof ( *path_end ) );
1039 1022
 	if ( ! snpdev->path ) {
@@ -1042,7 +1025,7 @@ static int efi_snp_probe ( struct net_device *netdev ) {
1042 1025
 	}
1043 1026
 
1044 1027
 	/* Populate the device path */
1045
-	memcpy ( snpdev->path, path.path, path_prefix_len );
1028
+	memcpy ( snpdev->path, efidev->path, path_prefix_len );
1046 1029
 	macpath = ( ( ( void * ) snpdev->path ) + path_prefix_len );
1047 1030
 	path_end = ( ( void * ) ( macpath + 1 ) );
1048 1031
 	memset ( macpath, 0, sizeof ( *macpath ) );
@@ -1119,9 +1102,6 @@ static int efi_snp_probe ( struct net_device *netdev ) {
1119 1102
  err_install_protocol_interface:
1120 1103
 	free ( snpdev->path );
1121 1104
  err_alloc_device_path:
1122
-	bs->CloseProtocol ( efidev->device, &efi_device_path_protocol_guid,
1123
-			    efi_image_handle, efidev->device );
1124
- err_open_device_path:
1125 1105
 	bs->CloseEvent ( snpdev->snp.WaitForPacket );
1126 1106
  err_create_event:
1127 1107
  err_ll_addr_len:

Loading…
İptal
Kaydet