diff options
Diffstat (limited to 'lib/efi_loader/efi_disk.c')
-rw-r--r-- | lib/efi_loader/efi_disk.c | 103 |
1 files changed, 44 insertions, 59 deletions
diff --git a/lib/efi_loader/efi_disk.c b/lib/efi_loader/efi_disk.c index e61dbc8058..4e457a841b 100644 --- a/lib/efi_loader/efi_disk.c +++ b/lib/efi_loader/efi_disk.c @@ -196,6 +196,15 @@ efi_fs_from_path(struct efi_device_path *fp) return diskobj->volume; } +/* + * Create a device for a disk + * + * @name not used + * @if_typename interface name for block device + * @desc internal block device + * @dev_index device index for block device + * @offset offset into disk for simple partitions + */ static void efi_disk_add_dev(const char *name, const char *if_typename, struct blk_desc *desc, @@ -204,29 +213,39 @@ static void efi_disk_add_dev(const char *name, unsigned int part) { struct efi_disk_obj *diskobj; + efi_status_t ret; /* Don't add empty devices */ if (!desc->lba) return; diskobj = calloc(1, sizeof(*diskobj)); + if (!diskobj) + goto out_of_memory; + + /* Hook up to the device list */ + efi_add_handle(&diskobj->parent); /* Fill in object data */ diskobj->dp = efi_dp_from_part(desc, part); diskobj->part = part; - diskobj->parent.protocols[0].guid = &efi_block_io_guid; - diskobj->parent.protocols[0].protocol_interface = &diskobj->ops; - diskobj->parent.protocols[1].guid = &efi_guid_device_path; - diskobj->parent.protocols[1].protocol_interface = diskobj->dp; + ret = efi_add_protocol(diskobj->parent.handle, &efi_block_io_guid, + &diskobj->ops); + if (ret != EFI_SUCCESS) + goto out_of_memory; + ret = efi_add_protocol(diskobj->parent.handle, &efi_guid_device_path, + diskobj->dp); + if (ret != EFI_SUCCESS) + goto out_of_memory; if (part >= 1) { diskobj->volume = efi_simple_file_system(desc, part, diskobj->dp); - diskobj->parent.protocols[2].guid = - &efi_simple_file_system_protocol_guid; - diskobj->parent.protocols[2].protocol_interface = - diskobj->volume; + ret = efi_add_protocol(diskobj->parent.handle, + &efi_simple_file_system_protocol_guid, + &diskobj->volume); + if (ret != EFI_SUCCESS) + goto out_of_memory; } - diskobj->parent.handle = diskobj; diskobj->ops = block_io_disk_template; diskobj->ifname = if_typename; diskobj->dev_index = dev_index; @@ -240,26 +259,22 @@ static void efi_disk_add_dev(const char *name, diskobj->media.io_align = desc->blksz; diskobj->media.last_block = desc->lba - offset; diskobj->ops.media = &diskobj->media; - - /* Hook up to the device list */ - list_add_tail(&diskobj->parent.link, &efi_obj_list); + return; +out_of_memory: + printf("ERROR: Out of memory\n"); } -static int efi_disk_create_eltorito(struct blk_desc *desc, - const char *if_typename, - int diskid, - const char *pdevname) +static int efi_disk_create_partitions(struct blk_desc *desc, + const char *if_typename, + int diskid, + const char *pdevname) { int disks = 0; -#if CONFIG_IS_ENABLED(ISO_PARTITION) char devname[32] = { 0 }; /* dp->str is u16[32] long */ disk_partition_t info; int part; - if (desc->part_type != PART_TYPE_ISO) - return 0; - - /* and devices for each partition: */ + /* Add devices for each partition */ for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) { if (part_get_info(desc, part, &info)) continue; @@ -270,10 +285,6 @@ static int efi_disk_create_eltorito(struct blk_desc *desc, disks++; } - /* ... and add block device: */ - efi_disk_add_dev(devname, if_typename, desc, diskid, 0, 0); -#endif - return disks; } @@ -299,31 +310,18 @@ int efi_disk_register(void) uclass_next_device_check(&dev)) { struct blk_desc *desc = dev_get_uclass_platdata(dev); const char *if_typename = dev->driver->name; - disk_partition_t info; - int part; printf("Scanning disk %s...\n", dev->name); - /* add devices for each partition: */ - for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) { - if (part_get_info(desc, part, &info)) - continue; - efi_disk_add_dev(dev->name, if_typename, desc, - desc->devnum, 0, part); - } - - /* ... and add block device: */ + /* Add block device for the full device */ efi_disk_add_dev(dev->name, if_typename, desc, desc->devnum, 0, 0); disks++; - /* - * El Torito images show up as block devices in an EFI world, - * so let's create them here - */ - disks += efi_disk_create_eltorito(desc, if_typename, - desc->devnum, dev->name); + /* Partitions show up as block devices in EFI */ + disks += efi_disk_create_partitions(desc, if_typename, + desc->devnum, dev->name); } #else int i, if_type; @@ -342,8 +340,6 @@ int efi_disk_register(void) for (i = 0; i < 4; i++) { struct blk_desc *desc; char devname[32] = { 0 }; /* dp->str is u16[32] long */ - disk_partition_t info; - int part; desc = blk_get_devnum_by_type(if_type, i); if (!desc) @@ -354,24 +350,13 @@ int efi_disk_register(void) snprintf(devname, sizeof(devname), "%s%d", if_typename, i); - /* add devices for each partition: */ - for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) { - if (part_get_info(desc, part, &info)) - continue; - efi_disk_add_dev(devname, if_typename, desc, - i, 0, part); - } - - /* ... and add block device: */ + /* Add block device for the full device */ efi_disk_add_dev(devname, if_typename, desc, i, 0, 0); disks++; - /* - * El Torito images show up as block devices - * in an EFI world, so let's create them here - */ - disks += efi_disk_create_eltorito(desc, if_typename, - i, devname); + /* Partitions show up as block devices in EFI */ + disks += efi_disk_create_partitions(desc, if_typename, + i, devname); } } #endif |