summaryrefslogtreecommitdiff
path: root/lib/efi_loader/efi_device_path.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/efi_loader/efi_device_path.c')
-rw-r--r--lib/efi_loader/efi_device_path.c56
1 files changed, 48 insertions, 8 deletions
diff --git a/lib/efi_loader/efi_device_path.c b/lib/efi_loader/efi_device_path.c
index b4e2f933cb6..ccb59337f18 100644
--- a/lib/efi_loader/efi_device_path.c
+++ b/lib/efi_loader/efi_device_path.c
@@ -36,6 +36,24 @@ static const struct efi_device_path_vendor ROOT = {
.guid = U_BOOT_GUID,
};
+#if defined(CONFIG_DM_MMC) && defined(CONFIG_MMC)
+/*
+ * Determine if an MMC device is an SD card.
+ *
+ * @desc block device descriptor
+ * @return true if the device is an SD card
+ */
+static bool is_sd(struct blk_desc *desc)
+{
+ struct mmc *mmc = find_mmc_device(desc->devnum);
+
+ if (!mmc)
+ return false;
+
+ return IS_SD(mmc) != 0U;
+}
+#endif
+
static void *dp_alloc(size_t sz)
{
void *buf;
@@ -126,6 +144,7 @@ static struct efi_object *find_obj(struct efi_device_path *dp, bool short_path,
struct efi_device_path **rem)
{
struct efi_object *efiobj;
+ unsigned int dp_size = efi_dp_size(dp);
list_for_each_entry(efiobj, &efi_obj_list, link) {
struct efi_handler *handler;
@@ -141,10 +160,18 @@ static struct efi_object *find_obj(struct efi_device_path *dp, bool short_path,
do {
if (efi_dp_match(dp, obj_dp) == 0) {
if (rem) {
+ /*
+ * Allow partial matches, but inform
+ * the caller.
+ */
*rem = ((void *)dp) +
efi_dp_size(obj_dp);
+ return efiobj;
+ } else {
+ /* Only return on exact matches */
+ if (efi_dp_size(obj_dp) == dp_size)
+ return efiobj;
}
- return efiobj;
}
obj_dp = shorten_path(efi_dp_next(obj_dp));
@@ -164,8 +191,14 @@ struct efi_object *efi_dp_find_obj(struct efi_device_path *dp,
{
struct efi_object *efiobj;
- efiobj = find_obj(dp, false, rem);
+ /* Search for an exact match first */
+ efiobj = find_obj(dp, false, NULL);
+
+ /* Then for a fuzzy match */
+ if (!efiobj)
+ efiobj = find_obj(dp, false, rem);
+ /* And now for a fuzzy short match */
if (!efiobj)
efiobj = find_obj(dp, true, rem);
@@ -298,9 +331,9 @@ static void *dp_fill(void *buf, struct udevice *dev)
struct blk_desc *desc = mmc_get_blk_desc(mmc);
sddp->dp.type = DEVICE_PATH_TYPE_MESSAGING_DEVICE;
- sddp->dp.sub_type = (desc->if_type == IF_TYPE_MMC) ?
- DEVICE_PATH_SUB_TYPE_MSG_MMC :
- DEVICE_PATH_SUB_TYPE_MSG_SD;
+ sddp->dp.sub_type = is_sd(desc) ?
+ DEVICE_PATH_SUB_TYPE_MSG_SD :
+ DEVICE_PATH_SUB_TYPE_MSG_MMC;
sddp->dp.length = sizeof(*sddp);
sddp->slot_number = dev->seq;
@@ -366,6 +399,13 @@ static unsigned dp_part_size(struct blk_desc *desc, int part)
return dpsize;
}
+/*
+ * Create a device path for a block device or one of its partitions.
+ *
+ * @buf buffer to which the device path is wirtten
+ * @desc block device descriptor
+ * @part partition number, 0 identifies a block device
+ */
static void *dp_part_fill(void *buf, struct blk_desc *desc, int part)
{
disk_partition_t info;
@@ -378,7 +418,7 @@ static void *dp_part_fill(void *buf, struct blk_desc *desc, int part)
* and handling all the different cases like we do for non-
* legacy (ie CONFIG_BLK=y) case. But most important thing
* is just to have a unique device-path for if_type+devnum.
- * So map things to a fictional USB device:
+ * So map things to a fictitious USB device.
*/
struct efi_device_path_usb *udp;
@@ -402,7 +442,7 @@ static void *dp_part_fill(void *buf, struct blk_desc *desc, int part)
if (desc->part_type == PART_TYPE_ISO) {
struct efi_device_path_cdrom_path *cddp = buf;
- cddp->boot_entry = part - 1;
+ cddp->boot_entry = part;
cddp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
cddp->dp.sub_type = DEVICE_PATH_SUB_TYPE_CDROM_PATH;
cddp->dp.length = sizeof(*cddp);
@@ -416,7 +456,7 @@ static void *dp_part_fill(void *buf, struct blk_desc *desc, int part)
hddp->dp.type = DEVICE_PATH_TYPE_MEDIA_DEVICE;
hddp->dp.sub_type = DEVICE_PATH_SUB_TYPE_HARD_DRIVE_PATH;
hddp->dp.length = sizeof(*hddp);
- hddp->partition_number = part - 1;
+ hddp->partition_number = part;
hddp->partition_start = info.start;
hddp->partition_end = info.size;
if (desc->part_type == PART_TYPE_EFI)