]> git.ipfire.org Git - people/ms/u-boot.git/blobdiff - lib/efi_loader/efi_disk.c
efi_loader: make efi_disk_create_partitions a global symbol
[people/ms/u-boot.git] / lib / efi_loader / efi_disk.c
index cccfc6dac5c3ca178393c88ed93aea54b218ad35..0050e5d98fbc67144661f9d538f3ca3548c0de78 100644 (file)
@@ -216,27 +216,31 @@ efi_fs_from_path(struct efi_device_path *full_path)
 }
 
 /*
- * Create a device for a disk
+ * Create a handle for a partition or disk
  *
- * @name       not used
+ * @parent     parent handle
+ * @dp_parent  parent device path
  * @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
+ * @return     disk object
  */
-static void efi_disk_add_dev(const char *name,
-                            const char *if_typename,
-                            struct blk_desc *desc,
-                            int dev_index,
-                            lbaint_t offset,
-                            unsigned int part)
+static struct efi_disk_obj *efi_disk_add_dev(
+                               efi_handle_t parent,
+                               struct efi_device_path *dp_parent,
+                               const char *if_typename,
+                               struct blk_desc *desc,
+                               int dev_index,
+                               lbaint_t offset,
+                               unsigned int part)
 {
        struct efi_disk_obj *diskobj;
        efi_status_t ret;
 
        /* Don't add empty devices */
        if (!desc->lba)
-               return;
+               return NULL;
 
        diskobj = calloc(1, sizeof(*diskobj));
        if (!diskobj)
@@ -246,7 +250,14 @@ static void efi_disk_add_dev(const char *name,
        efi_add_handle(&diskobj->parent);
 
        /* Fill in object data */
-       diskobj->dp = efi_dp_from_part(desc, part);
+       if (part) {
+               struct efi_device_path *node = efi_dp_part_node(desc, part);
+
+               diskobj->dp = efi_dp_append_node(dp_parent, node);
+               efi_free_pool(node);
+       } else {
+               diskobj->dp = efi_dp_from_part(desc, part);
+       }
        diskobj->part = part;
        ret = efi_add_protocol(diskobj->parent.handle, &efi_block_io_guid,
                               &diskobj->ops);
@@ -280,20 +291,38 @@ static void efi_disk_add_dev(const char *name,
        if (part != 0)
                diskobj->media.logical_partition = 1;
        diskobj->ops.media = &diskobj->media;
-       return;
+       return diskobj;
 out_of_memory:
        printf("ERROR: Out of memory\n");
+       return NULL;
 }
 
-static int efi_disk_create_partitions(struct blk_desc *desc,
-                                     const char *if_typename,
-                                     int diskid,
-                                     const char *pdevname)
+/*
+ * Create handles and protocols for the partitions of a block device
+ *
+ * @parent             handle of the parent disk
+ * @blk_desc           block device
+ * @if_typename                interface type
+ * @diskid             device number
+ * @pdevname           device name
+ * @return             number of partitions created
+ */
+int efi_disk_create_partitions(efi_handle_t parent, struct blk_desc *desc,
+                              const char *if_typename, int diskid,
+                              const char *pdevname)
 {
        int disks = 0;
        char devname[32] = { 0 }; /* dp->str is u16[32] long */
        disk_partition_t info;
        int part;
+       struct efi_device_path *dp = NULL;
+       efi_status_t ret;
+       struct efi_handler *handler;
+
+       /* Get the device path of the parent */
+       ret = efi_search_protocol(parent, &efi_guid_device_path, &handler);
+       if (ret == EFI_SUCCESS)
+               dp = handler->protocol_interface;
 
        /* Add devices for each partition */
        for (part = 1; part <= MAX_SEARCH_PARTITIONS; part++) {
@@ -301,7 +330,7 @@ static int efi_disk_create_partitions(struct blk_desc *desc,
                        continue;
                snprintf(devname, sizeof(devname), "%s:%d", pdevname,
                         part);
-               efi_disk_add_dev(devname, if_typename, desc, diskid,
+               efi_disk_add_dev(parent, dp, if_typename, desc, diskid,
                                 info.start, part);
                disks++;
        }
@@ -322,6 +351,7 @@ static int efi_disk_create_partitions(struct blk_desc *desc,
  */
 int efi_disk_register(void)
 {
+       struct efi_disk_obj *disk;
        int disks = 0;
 #ifdef CONFIG_BLK
        struct udevice *dev;
@@ -335,14 +365,16 @@ int efi_disk_register(void)
                printf("Scanning disk %s...\n", dev->name);
 
                /* Add block device for the full device */
-               efi_disk_add_dev(dev->name, if_typename, desc,
-                                desc->devnum, 0, 0);
-
+               disk = efi_disk_add_dev(NULL, NULL, if_typename,
+                                       desc, desc->devnum, 0, 0);
+               if (!disk)
+                       return -ENOMEM;
                disks++;
 
                /* Partitions show up as block devices in EFI */
-               disks += efi_disk_create_partitions(desc, if_typename,
-                                                   desc->devnum, dev->name);
+               disks += efi_disk_create_partitions(
+                                       disk->parent.handle, desc, if_typename,
+                                       desc->devnum, dev->name);
        }
 #else
        int i, if_type;
@@ -372,12 +404,16 @@ int efi_disk_register(void)
                                 if_typename, i);
 
                        /* Add block device for the full device */
-                       efi_disk_add_dev(devname, if_typename, desc, i, 0, 0);
+                       disk = efi_disk_add_dev(NULL, NULL, if_typename, desc,
+                                               i, 0, 0);
+                       if (!disk)
+                               return -ENOMEM;
                        disks++;
 
                        /* Partitions show up as block devices in EFI */
-                       disks += efi_disk_create_partitions(desc, if_typename,
-                                                           i, devname);
+                       disks += efi_disk_create_partitions(
+                                               disk->parent.handle, desc,
+                                               if_typename, i, devname);
                }
        }
 #endif