Refactor the part_get_info_extended() helper function (which already
recursively traverses DOS partitions) to optionally return the raw MBR
partition structure (dos_partition_t).

This allows other subsystems, such as EFI, to retrieve the partition
details in the legacy MBR format.

Signed-off-by: Javier Martinez Canillas <[email protected]>
---

(no changes since v1)

 disk/part_dos.c | 66 ++++++++++++++++++++++++++++++-------------------
 include/part.h  | 14 +++++++++++
 2 files changed, 55 insertions(+), 25 deletions(-)

diff --git a/disk/part_dos.c b/disk/part_dos.c
index a69ad8962106..4e1d01b2f21e 100644
--- a/disk/part_dos.c
+++ b/disk/part_dos.c
@@ -204,7 +204,8 @@ static void print_partition_extended(struct blk_desc *desc,
  * @relative:          Relative offset for the partition
  * @part_num:          Current partition number
  * @which_part:                Target partition number
- * @info:              Returns a pointer to the partition info
+ * @info:              Returns partition information (optional)
+ * @mbr:               Returns MBR partition entry (optional)
  * @disksig:           Disk signature
  *
  * Return:             0 on success, negative on error
@@ -212,7 +213,9 @@ static void print_partition_extended(struct blk_desc *desc,
 static int part_get_info_extended(struct blk_desc *desc,
                                  lbaint_t ext_part_sector, lbaint_t relative,
                                  int part_num, int which_part,
-                                 struct disk_partition *info, uint disksig)
+                                 struct disk_partition *info,
+                                 dos_partition_t *mbr,
+                                 uint disksig)
 {
        ALLOC_CACHE_ALIGN_BUFFER(unsigned char, buffer, desc->blksz);
        struct disk_partition wdinfo = { 0 };
@@ -243,9 +246,11 @@ static int part_get_info_extended(struct blk_desc *desc,
        if (CONFIG_IS_ENABLED(PARTITION_UUIDS) && !ext_part_sector)
                disksig = get_unaligned_le32(&buffer[DOS_PART_DISKSIG_OFFSET]);
 
-       ret = part_get_info_whole_disk(desc, &wdinfo);
-       if (ret)
-               return ret;
+       if (info) {
+               ret = part_get_info_whole_disk(desc, &wdinfo);
+               if (ret)
+                       return ret;
+       }
 
        /* Print all primary/logical partitions */
        pt = (dos_partition_t *) (buffer + DOS_PART_TBL_OFFSET);
@@ -258,25 +263,29 @@ static int part_get_info_extended(struct blk_desc *desc,
                    (pt->sys_ind != 0) &&
                    (part_num == which_part) &&
                    (ext_part_sector == 0 || is_extended(pt->sys_ind) == 0)) {
-                       if (wdinfo.blksz > DOS_PART_DEFAULT_SECTOR)
-                               info->blksz = wdinfo.blksz;
-                       else
-                               info->blksz = DOS_PART_DEFAULT_SECTOR;
-                       info->start = (lbaint_t)(ext_part_sector +
-                                       get_unaligned_le32(&pt->start_sect));
-                       info->size  = 
(lbaint_t)get_unaligned_le32(&pt->nr_sects);
-                       part_set_generic_name(desc, part_num,
-                                             (char *)info->name);
-                       /* sprintf(info->type, "%d, pt->sys_ind); */
-                       strcpy((char *)info->type, "U-Boot");
-                       info->bootable = get_bootable(pt);
-                       if (CONFIG_IS_ENABLED(PARTITION_UUIDS)) {
-                               char str[12];
-
-                               sprintf(str, "%08x-%02x", disksig, part_num);
-                               disk_partition_set_uuid(info, str);
+                       if (info) {
+                               if (wdinfo.blksz > DOS_PART_DEFAULT_SECTOR)
+                                       info->blksz = wdinfo.blksz;
+                               else
+                                       info->blksz = DOS_PART_DEFAULT_SECTOR;
+                               info->start = (lbaint_t)(ext_part_sector +
+                                                        
get_unaligned_le32(&pt->start_sect));
+                               info->size  = 
(lbaint_t)get_unaligned_le32(&pt->nr_sects);
+                               part_set_generic_name(desc, part_num,
+                                                     (char *)info->name);
+                               /* sprintf(info->type, "%d, pt->sys_ind); */
+                               strcpy((char *)info->type, "U-Boot");
+                               info->bootable = get_bootable(pt);
+                               if (CONFIG_IS_ENABLED(PARTITION_UUIDS)) {
+                                       char str[12];
+
+                                       sprintf(str, "%08x-%02x", disksig, 
part_num);
+                                       disk_partition_set_uuid(info, str);
+                               }
+                               info->sys_ind = pt->sys_ind;
                        }
-                       info->sys_ind = pt->sys_ind;
+                       if (mbr)
+                               memcpy(mbr, pt, sizeof(*mbr));
                        return 0;
                }
 
@@ -296,7 +305,8 @@ static int part_get_info_extended(struct blk_desc *desc,
 
                        return part_get_info_extended(desc, lba_start,
                                 ext_part_sector == 0 ? lba_start : relative,
-                                part_num, which_part, info, disksig);
+                                                     part_num, which_part, 
info,
+                                                     mbr, disksig);
                }
        }
 
@@ -328,7 +338,13 @@ static void __maybe_unused part_print_dos(struct blk_desc 
*desc)
 static int __maybe_unused part_get_info_dos(struct blk_desc *desc, int part,
                                            struct disk_partition *info)
 {
-       return part_get_info_extended(desc, 0, 0, 1, part, info, 0);
+       return part_get_info_extended(desc, 0, 0, 1, part, info, NULL, 0);
+}
+
+int __maybe_unused part_get_mbr(struct blk_desc *desc, int part,
+                               dos_partition_t *mbr)
+{
+       return part_get_info_extended(desc, 0, 0, 1, part, NULL, mbr, 0);
 }
 
 int is_valid_dos_buf(void *buf)
diff --git a/include/part.h b/include/part.h
index daebbbc2e68f..aed089d00f64 100644
--- a/include/part.h
+++ b/include/part.h
@@ -704,6 +704,20 @@ int write_mbr_partitions(struct blk_desc *dev,
 int layout_mbr_partitions(struct disk_partition *p, int count,
                          lbaint_t total_sectors);
 
+/**
+ * part_get_mbr() - get the MBR partition record of a partition
+ *
+ * This function reads the MBR partition record for a given block
+ * device and partition number.
+ *
+ * @desc:      block device descriptor
+ * @part:      partition number for which to return the partition record
+ * @mbr:       MBR partition record
+ *
+ * Return:     0 on success, otherwise error
+ */
+int part_get_mbr(struct blk_desc *desc, int part, dos_partition_t *mbr);
+
 #endif
 
 #if CONFIG_IS_ENABLED(PARTITIONS)
-- 
2.53.0

Reply via email to