Browse Source

[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 9 years ago
parent
commit
e727f576c2
3 changed files with 38 additions and 23 deletions
  1. 2
    0
      src/include/ipxe/efi/efi_driver.h
  2. 34
    1
      src/interface/efi/efi_driver.c
  3. 2
    22
      src/interface/efi/efi_snp.c

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

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

+ 34
- 1
src/interface/efi/efi_driver.c View File

30
 #include <ipxe/efi/Protocol/ComponentName2.h>
30
 #include <ipxe/efi/Protocol/ComponentName2.h>
31
 #include <ipxe/efi/Protocol/DevicePath.h>
31
 #include <ipxe/efi/Protocol/DevicePath.h>
32
 #include <ipxe/efi/efi_strings.h>
32
 #include <ipxe/efi/efi_strings.h>
33
+#include <ipxe/efi/efi_utils.h>
33
 #include <ipxe/efi/efi_driver.h>
34
 #include <ipxe/efi/efi_driver.h>
34
 
35
 
35
 /** @file
36
 /** @file
132
 static EFI_STATUS EFIAPI
133
 static EFI_STATUS EFIAPI
133
 efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
134
 efi_driver_start ( EFI_DRIVER_BINDING_PROTOCOL *driver __unused,
134
 		   EFI_HANDLE device, EFI_DEVICE_PATH_PROTOCOL *child ) {
135
 		   EFI_HANDLE device, EFI_DEVICE_PATH_PROTOCOL *child ) {
136
+	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
135
 	struct efi_driver *efidrv;
137
 	struct efi_driver *efidrv;
136
 	struct efi_device *efidev;
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
 	EFI_STATUS efirc;
145
 	EFI_STATUS efirc;
138
 	int rc;
146
 	int rc;
139
 
147
 
151
 		goto err_already_started;
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
 	/* Allocate and initialise structure */
175
 	/* Allocate and initialise structure */
155
-	efidev = zalloc ( sizeof ( *efidev ) );
176
+	efidev = zalloc ( sizeof ( *efidev ) + path_len );
156
 	if ( ! efidev ) {
177
 	if ( ! efidev ) {
157
 		efirc = EFI_OUT_OF_RESOURCES;
178
 		efirc = EFI_OUT_OF_RESOURCES;
158
 		goto err_alloc;
179
 		goto err_alloc;
159
 	}
180
 	}
160
 	efidev->device = device;
181
 	efidev->device = device;
161
 	efidev->dev.desc.bus_type = BUS_TYPE_EFI;
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
 	INIT_LIST_HEAD ( &efidev->dev.children );
185
 	INIT_LIST_HEAD ( &efidev->dev.children );
163
 	list_add ( &efidev->dev.siblings, &efi_devices );
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
 	/* Try to start this device */
193
 	/* Try to start this device */
166
 	for_each_table_entry ( efidrv, EFI_DRIVERS ) {
194
 	for_each_table_entry ( efidrv, EFI_DRIVERS ) {
167
 		if ( ( rc = efidrv->supported ( device ) ) != 0 ) {
195
 		if ( ( rc = efidrv->supported ( device ) ) != 0 ) {
187
 	list_del ( &efidev->dev.siblings );
215
 	list_del ( &efidev->dev.siblings );
188
 	free ( efidev );
216
 	free ( efidev );
189
  err_alloc:
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
  err_already_started:
223
  err_already_started:
191
 	return efirc;
224
 	return efirc;
192
 }
225
 }

+ 2
- 22
src/interface/efi/efi_snp.c View File

936
 	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
936
 	EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
937
 	struct efi_device *efidev;
937
 	struct efi_device *efidev;
938
 	struct efi_snp_device *snpdev;
938
 	struct efi_snp_device *snpdev;
939
-	union {
940
-		EFI_DEVICE_PATH_PROTOCOL *path;
941
-		void *interface;
942
-	} path;
943
 	EFI_DEVICE_PATH_PROTOCOL *path_end;
939
 	EFI_DEVICE_PATH_PROTOCOL *path_end;
944
 	MAC_ADDR_DEVICE_PATH *macpath;
940
 	MAC_ADDR_DEVICE_PATH *macpath;
945
 	size_t path_prefix_len = 0;
941
 	size_t path_prefix_len = 0;
1019
 				       sizeof ( snpdev->name[0] ) ),
1015
 				       sizeof ( snpdev->name[0] ) ),
1020
 		       "%s", netdev->name );
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
 	/* Allocate the new device path */
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
 	snpdev->path = zalloc ( path_prefix_len + sizeof ( *macpath ) +
1020
 	snpdev->path = zalloc ( path_prefix_len + sizeof ( *macpath ) +
1038
 				sizeof ( *path_end ) );
1021
 				sizeof ( *path_end ) );
1039
 	if ( ! snpdev->path ) {
1022
 	if ( ! snpdev->path ) {
1042
 	}
1025
 	}
1043
 
1026
 
1044
 	/* Populate the device path */
1027
 	/* Populate the device path */
1045
-	memcpy ( snpdev->path, path.path, path_prefix_len );
1028
+	memcpy ( snpdev->path, efidev->path, path_prefix_len );
1046
 	macpath = ( ( ( void * ) snpdev->path ) + path_prefix_len );
1029
 	macpath = ( ( ( void * ) snpdev->path ) + path_prefix_len );
1047
 	path_end = ( ( void * ) ( macpath + 1 ) );
1030
 	path_end = ( ( void * ) ( macpath + 1 ) );
1048
 	memset ( macpath, 0, sizeof ( *macpath ) );
1031
 	memset ( macpath, 0, sizeof ( *macpath ) );
1119
  err_install_protocol_interface:
1102
  err_install_protocol_interface:
1120
 	free ( snpdev->path );
1103
 	free ( snpdev->path );
1121
  err_alloc_device_path:
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
 	bs->CloseEvent ( snpdev->snp.WaitForPacket );
1105
 	bs->CloseEvent ( snpdev->snp.WaitForPacket );
1126
  err_create_event:
1106
  err_create_event:
1127
  err_ll_addr_len:
1107
  err_ll_addr_len:

Loading…
Cancel
Save