}
}
-static int mmc_env_partition_by_guid(struct blk_desc *desc, struct disk_partition *info)
+/*
+ * Look for one or two partitions with the U-Boot environment GUID.
+ *
+ * If *copy is 0, return the first such partition.
+ *
+ * If *copy is 1 on entry and two partitions are found, return the
+ * second partition and set *copy = 0.
+ *
+ * If *copy is 1 on entry and only one partition is found, return that
+ * partition, leaving *copy unmodified.
+ */
+static int mmc_env_partition_by_guid(struct blk_desc *desc, struct disk_partition *info,
+ int *copy)
{
const efi_guid_t env_guid = PARTITION_U_BOOT_ENVIRONMENT;
efi_guid_t type_guid;
- int i, ret;
+ int i, ret, found = 0;
+ struct disk_partition dp;
for (i = 1;; i++) {
- ret = part_get_info(desc, i, info);
+ ret = part_get_info(desc, i, &dp);
if (ret < 0)
- return ret;
-
- uuid_str_to_bin(disk_partition_type_guid(info), type_guid.b, UUID_STR_FORMAT_GUID);
- if (!memcmp(&env_guid, &type_guid, sizeof(efi_guid_t)))
- return 0;
+ break;
+
+ uuid_str_to_bin(disk_partition_type_guid(&dp), type_guid.b, UUID_STR_FORMAT_GUID);
+ if (!memcmp(&env_guid, &type_guid, sizeof(efi_guid_t))) {
+ memcpy(info, &dp, sizeof(dp));
+ /* If *copy is 0, we are only looking for the first partition. */
+ if (*copy == 0)
+ return 0;
+ /* This was the second such partition. */
+ if (found) {
+ *copy = 0;
+ return 0;
+ }
+ found = 1;
+ }
}
+
+ /* The loop ended after finding at most one matching partition. */
+ if (found)
+ ret = 0;
+ return ret;
}
if (str) {
ret = mmc_env_partition_by_name(desc, str, &info);
} else if (IS_ENABLED(CONFIG_PARTITION_TYPE_GUID) && !str) {
- ret = mmc_env_partition_by_guid(desc, &info);
+ ret = mmc_env_partition_by_guid(desc, &info, ©);
}
if (ret < 0)
return ret;