Commit 64e4db0f119151a1345e1da19d152eda550394e7
Committed by
Alexander Graf
1 parent
98d48bdf41
Exists in
smarc_8mq_lf_v2020.04
and in
17 other branches
efi_loader: make efi_disk_create_partitions a global symbol
Up to now we have been using efi_disk_create_partitions() to create partitions for block devices that existed before starting an EFI application. We need to call it for block devices created by EFI applications at run time. The EFI application will define the handle for the block device and install a device path protocol on it. We have to use this device path as stem for the partition device paths. Signed-off-by: Heinrich Schuchardt <xypron.glpk@gmx.de> Signed-off-by: Alexander Graf <agraf@suse.de>
Showing 2 changed files with 64 additions and 24 deletions Side-by-side Diff
include/efi_loader.h
... | ... | @@ -174,6 +174,10 @@ |
174 | 174 | int efi_console_register(void); |
175 | 175 | /* Called by bootefi to make all disk storage accessible as EFI objects */ |
176 | 176 | int efi_disk_register(void); |
177 | +/* Create handles and protocols for the partitions of a block device */ | |
178 | +int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc, | |
179 | + const char *if_typename, int diskid, | |
180 | + const char *pdevname); | |
177 | 181 | /* Called by bootefi to make GOP (graphical) interface available */ |
178 | 182 | int efi_gop_register(void); |
179 | 183 | /* Called by bootefi to make the network interface available */ |
lib/efi_loader/efi_disk.c
... | ... | @@ -216,27 +216,31 @@ |
216 | 216 | } |
217 | 217 | |
218 | 218 | /* |
219 | - * Create a device for a disk | |
219 | + * Create a handle for a partition or disk | |
220 | 220 | * |
221 | - * @name not used | |
221 | + * @parent parent handle | |
222 | + * @dp_parent parent device path | |
222 | 223 | * @if_typename interface name for block device |
223 | 224 | * @desc internal block device |
224 | 225 | * @dev_index device index for block device |
225 | 226 | * @offset offset into disk for simple partitions |
227 | + * @return disk object | |
226 | 228 | */ |
227 | -static void efi_disk_add_dev(const char *name, | |
228 | - const char *if_typename, | |
229 | - struct blk_desc *desc, | |
230 | - int dev_index, | |
231 | - lbaint_t offset, | |
232 | - unsigned int part) | |
229 | +static struct efi_disk_obj *efi_disk_add_dev( | |
230 | + efi_handle_t parent, | |
231 | + struct efi_device_path *dp_parent, | |
232 | + const char *if_typename, | |
233 | + struct blk_desc *desc, | |
234 | + int dev_index, | |
235 | + lbaint_t offset, | |
236 | + unsigned int part) | |
233 | 237 | { |
234 | 238 | struct efi_disk_obj *diskobj; |
235 | 239 | efi_status_t ret; |
236 | 240 | |
237 | 241 | /* Don't add empty devices */ |
238 | 242 | if (!desc->lba) |
239 | - return; | |
243 | + return NULL; | |
240 | 244 | |
241 | 245 | diskobj = calloc(1, sizeof(*diskobj)); |
242 | 246 | if (!diskobj) |
... | ... | @@ -246,7 +250,14 @@ |
246 | 250 | efi_add_handle(&diskobj->parent); |
247 | 251 | |
248 | 252 | /* Fill in object data */ |
249 | - diskobj->dp = efi_dp_from_part(desc, part); | |
253 | + if (part) { | |
254 | + struct efi_device_path *node = efi_dp_part_node(desc, part); | |
255 | + | |
256 | + diskobj->dp = efi_dp_append_node(dp_parent, node); | |
257 | + efi_free_pool(node); | |
258 | + } else { | |
259 | + diskobj->dp = efi_dp_from_part(desc, part); | |
260 | + } | |
250 | 261 | diskobj->part = part; |
251 | 262 | ret = efi_add_protocol(diskobj->parent.handle, &efi_block_io_guid, |
252 | 263 | &diskobj->ops); |
253 | 264 | |
254 | 265 | |
255 | 266 | |
256 | 267 | |
257 | 268 | |
... | ... | @@ -280,28 +291,46 @@ |
280 | 291 | if (part != 0) |
281 | 292 | diskobj->media.logical_partition = 1; |
282 | 293 | diskobj->ops.media = &diskobj->media; |
283 | - return; | |
294 | + return diskobj; | |
284 | 295 | out_of_memory: |
285 | 296 | printf("ERROR: Out of memory\n"); |
297 | + return NULL; | |
286 | 298 | } |
287 | 299 | |
288 | -static int efi_disk_create_partitions(struct blk_desc *desc, | |
289 | - const char *if_typename, | |
290 | - int diskid, | |
291 | - const char *pdevname) | |
300 | +/* | |
301 | + * Create handles and protocols for the partitions of a block device | |
302 | + * | |
303 | + * @parent handle of the parent disk | |
304 | + * @blk_desc block device | |
305 | + * @if_typename interface type | |
306 | + * @diskid device number | |
307 | + * @pdevname device name | |
308 | + * @return number of partitions created | |
309 | + */ | |
310 | +int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc, | |
311 | + const char *if_typename, int diskid, | |
312 | + const char *pdevname) | |
292 | 313 | { |
293 | 314 | int disks = 0; |
294 | 315 | char devname[32] = { 0 }; /* dp->str is u16[32] long */ |
295 | 316 | disk_partition_t info; |
296 | 317 | int part; |
318 | + struct efi_device_path *dp = NULL; | |
319 | + efi_status_t ret; | |
320 | + struct efi_handler *handler; | |
297 | 321 | |
322 | + /* Get the device path of the parent */ | |
323 | + ret = efi_search_protocol(parent, &efi_guid_device_path, &handler); | |
324 | + if (ret == EFI_SUCCESS) | |
325 | + dp = handler->protocol_interface; | |
326 | + | |
298 | 327 | /* Add devices for each partition */ |
299 | 328 | for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) { |
300 | 329 | if (part_get_info(desc, part, &info)) |
301 | 330 | continue; |
302 | 331 | snprintf(devname, sizeof(devname), "%s:%d", pdevname, |
303 | 332 | part); |
304 | - efi_disk_add_dev(devname, if_typename, desc, diskid, | |
333 | + efi_disk_add_dev(parent, dp, if_typename, desc, diskid, | |
305 | 334 | info.start, part); |
306 | 335 | disks++; |
307 | 336 | } |
... | ... | @@ -322,6 +351,7 @@ |
322 | 351 | */ |
323 | 352 | int efi_disk_register(void) |
324 | 353 | { |
354 | + struct efi_disk_obj *disk; | |
325 | 355 | int disks = 0; |
326 | 356 | #ifdef CONFIG_BLK |
327 | 357 | struct udevice *dev; |
328 | 358 | |
... | ... | @@ -335,14 +365,16 @@ |
335 | 365 | printf("Scanning disk %s...\n", dev->name); |
336 | 366 | |
337 | 367 | /* Add block device for the full device */ |
338 | - efi_disk_add_dev(dev->name, if_typename, desc, | |
339 | - desc->devnum, 0, 0); | |
340 | - | |
368 | + disk = efi_disk_add_dev(NULL, NULL, if_typename, | |
369 | + desc, desc->devnum, 0, 0); | |
370 | + if (!disk) | |
371 | + return -ENOMEM; | |
341 | 372 | disks++; |
342 | 373 | |
343 | 374 | /* Partitions show up as block devices in EFI */ |
344 | - disks += efi_disk_create_partitions(desc, if_typename, | |
345 | - desc->devnum, dev->name); | |
375 | + disks += efi_disk_create_partitions( | |
376 | + disk->parent.handle, desc, if_typename, | |
377 | + desc->devnum, dev->name); | |
346 | 378 | } |
347 | 379 | #else |
348 | 380 | int i, if_type; |
349 | 381 | |
... | ... | @@ -372,12 +404,16 @@ |
372 | 404 | if_typename, i); |
373 | 405 | |
374 | 406 | /* Add block device for the full device */ |
375 | - efi_disk_add_dev(devname, if_typename, desc, i, 0, 0); | |
407 | + disk = efi_disk_add_dev(NULL, NULL, if_typename, desc, | |
408 | + i, 0, 0); | |
409 | + if (!disk) | |
410 | + return -ENOMEM; | |
376 | 411 | disks++; |
377 | 412 | |
378 | 413 | /* Partitions show up as block devices in EFI */ |
379 | - disks += efi_disk_create_partitions(desc, if_typename, | |
380 | - i, devname); | |
414 | + disks += efi_disk_create_partitions( | |
415 | + disk->parent.handle, desc, | |
416 | + if_typename, i, devname); | |
381 | 417 | } |
382 | 418 | } |
383 | 419 | #endif |