]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
efi_loader: use proper device-paths for partitions
authorRob Clark <robdclark@gmail.com>
Wed, 13 Sep 2017 22:05:31 +0000 (18:05 -0400)
committerAlexander Graf <agraf@suse.de>
Wed, 20 Sep 2017 08:34:42 +0000 (10:34 +0200)
Also, create disk objects for the disk itself, in addition to the
partitions.  (UEFI terminology is a bit confusing, a "disk" object is
really a partition.)  This helps grub properly identify the boot device
since it is trying to match up partition "disk" object with it's parent
device.

Now instead of seeing devices like:

  /File(sdhci@07864000.blk)/EndEntire
  /File(usb_mass_storage.lun0)/EndEntire

You see:

  /ACPI(133741d0,0)/UnknownMessaging(1d)/EndEntire
  /ACPI(133741d0,0)/UnknownMessaging(1d)/HD(0,800,64000,dd904a8c00000000,1,1)/EndEntire
  /ACPI(133741d0,0)/UnknownMessaging(1d)/HD(1,64800,200000,dd904a8c00000000,1,1)/EndEntire
  /ACPI(133741d0,0)/UnknownMessaging(1d)/HD(2,264800,19a000,dd904a8c00000000,1,1)/EndEntire
  /ACPI(133741d0,0)/USB(0,0)/USB(0,0)/USB(0,0)/EndEntire
  /ACPI(133741d0,0)/USB(0,0)/USB(0,0)/USB(0,0)/HD(0,800,60000,38ca680200000000,1,1)/EndEntire
  /ACPI(133741d0,0)/USB(0,0)/USB(0,0)/USB(0,0)/HD(1,61000,155000,38ca680200000000,1,1)/EndEntire
  /ACPI(133741d0,0)/USB(0,0)/USB(0,0)/USB(0,0)/HD(2,20fa800,1bbf8800,38ca680200000000,1,1)/EndEntire
  /ACPI(133741d0,0)/USB(0,0)/USB(0,0)/USB(0,0)/HD(3,1b6800,1f44000,38ca680200000000,1,1)/EndEntire

This is on a board with single USB disk and single sd-card.  The
UnknownMessaging(1d) node in the device-path is the MMC device,
but grub_efi_print_device_path() hasn't been updated yet for some
of the newer device-path sub-types.

This patch is inspired by a patch originally from Peter Jones, but
re-worked to use efi_device_path, so it doesn't much resemble the
original.

Signed-off-by: Rob Clark <robdclark@gmail.com>
[agraf: s/unsigned/unsigned int/]
Signed-off-by: Alexander Graf <agraf@suse.de>
lib/efi_loader/efi_disk.c

index 4e78ade2ed22c1ca39385b5b90dcb82595fd47e7..c815711e5758fa5f2592d7c37437924e87eb657b 100644 (file)
@@ -28,11 +28,13 @@ struct efi_disk_obj {
        /* EFI Interface Media descriptor struct, referenced by ops */
        struct efi_block_io_media media;
        /* EFI device path to this block device */
-       struct efi_device_path_file_path *dp;
+       struct efi_device_path *dp;
+       /* partition # */
+       unsigned int part;
        /* Offset into disk for simple partitions */
        lbaint_t offset;
        /* Internal block device */
-       const struct blk_desc *desc;
+       struct blk_desc *desc;
 };
 
 static efi_status_t EFIAPI efi_disk_reset(struct efi_block_io *this,
@@ -172,26 +174,26 @@ static const struct efi_block_io block_io_disk_template = {
 
 static void efi_disk_add_dev(const char *name,
                             const char *if_typename,
-                            const struct blk_desc *desc,
+                            struct blk_desc *desc,
                             int dev_index,
-                            lbaint_t offset)
+                            lbaint_t offset,
+                            unsigned int part)
 {
        struct efi_disk_obj *diskobj;
-       struct efi_device_path_file_path *dp;
-       int objlen = sizeof(*diskobj) + (sizeof(*dp) * 2);
 
        /* Don't add empty devices */
        if (!desc->lba)
                return;
 
-       diskobj = calloc(1, objlen);
+       diskobj = calloc(1, sizeof(*diskobj));
 
        /* Fill in object data */
-       dp = (void *)&diskobj[1];
+       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 = dp;
+       diskobj->parent.protocols[1].protocol_interface = diskobj->dp;
        diskobj->parent.handle = diskobj;
        diskobj->ops = block_io_disk_template;
        diskobj->ifname = if_typename;
@@ -207,17 +209,6 @@ static void efi_disk_add_dev(const char *name,
        diskobj->media.last_block = desc->lba - offset;
        diskobj->ops.media = &diskobj->media;
 
-       /* Fill in device path */
-       diskobj->dp = dp;
-       dp[0].dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
-       dp[0].dp.sub_type = DEVICE_PATH_SUB_TYPE_FILE_PATH;
-       dp[0].dp.length = sizeof(*dp);
-       ascii2unicode(dp[0].str, name);
-
-       dp[1].dp.type = DEVICE_PATH_TYPE_END;
-       dp[1].dp.sub_type = DEVICE_PATH_SUB_TYPE_END;
-       dp[1].dp.length = sizeof(*dp);
-
        /* Hook up to the device list */
        list_add_tail(&diskobj->parent.link, &efi_obj_list);
 }
@@ -236,14 +227,18 @@ static int efi_disk_create_eltorito(struct blk_desc *desc,
        if (desc->part_type != PART_TYPE_ISO)
                return 0;
 
+       /* and devices for each partition: */
        while (!part_get_info(desc, part, &info)) {
                snprintf(devname, sizeof(devname), "%s:%d", pdevname,
                         part);
                efi_disk_add_dev(devname, if_typename, desc, diskid,
-                                info.start);
+                                info.start, part);
                part++;
                disks++;
        }
+
+       /* ... and add block device: */
+       efi_disk_add_dev(devname, if_typename, desc, diskid, 0, 0);
 #endif
 
        return disks;
@@ -271,9 +266,22 @@ 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 = 1;
 
                printf("Scanning disk %s...\n", dev->name);
-               efi_disk_add_dev(dev->name, if_typename, desc, desc->devnum, 0);
+
+               /* add devices for each partition: */
+               while (!part_get_info(desc, part, &info)) {
+                       efi_disk_add_dev(dev->name, if_typename, desc,
+                                        desc->devnum, 0, part);
+                       part++;
+               }
+
+               /* ... and add block device: */
+               efi_disk_add_dev(dev->name, if_typename, desc,
+                                desc->devnum, 0, 0);
+
                disks++;
 
                /*
@@ -309,7 +317,7 @@ int efi_disk_register(void)
 
                        snprintf(devname, sizeof(devname), "%s%d",
                                 if_typename, i);
-                       efi_disk_add_dev(devname, if_typename, desc, i, 0);
+                       efi_disk_add_dev(devname, if_typename, desc, i, 0, 0);
                        disks++;
 
                        /*