Commit 64e4db0f119151a1345e1da19d152eda550394e7

Authored by Heinrich Schuchardt
Committed by Alexander Graf
1 parent 98d48bdf41

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