[U-Boot] [RFC PATCH 2/5] disk/part: introduce get_device_and_partition

Rob Herring robherring2 at gmail.com
Wed Mar 7 00:41:09 CET 2012


From: Rob Herring <rob.herring at calxeda.com>

All block device related commands (scsiboot, fatload, ext2ls, etc.) have
simliar duplicated device and partition parsing and selection code. This
adds a common function to replace various implementations.

The new function has some enhancements over current versions. If no device
or partition is specified on the command line, the bootdevice env variable
will be used (scsiboot does this). If the partition is not specified and
the device has partitions, then the first bootable partition will be used.

Signed-off-by: Rob Herring <rob.herring at calxeda.com>
---
 disk/part.c    |   60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/part.h |    4 +++
 2 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/disk/part.c b/disk/part.c
index f07a17f..e892c8d 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -291,6 +291,7 @@ void init_part (block_dev_desc_t * dev_desc)
 	    return;
 	}
 #endif
+	dev_desc->part_type = PART_TYPE_UNKNOWN;
 }
 
 
@@ -435,4 +436,63 @@ void print_part (block_dev_desc_t * dev_desc)
 # error nor CONFIG_EFI_PARTITION configured!
 #endif
 
+int get_device_and_partition(const char *ifname, const char *dev_str,
+			     block_dev_desc_t **dev_desc,
+			     disk_partition_t *info)
+{
+	int ret;
+	char *ep;
+	int dev;
+	block_dev_desc_t *desc;
+	int part = 1;
+	int do_scan_part = 1;
+	char *part_str;
+
+	if (dev_str)
+		dev = simple_strtoul(dev_str, &ep, 16);
+
+	if (!dev_str || (dev_str == ep)) {
+		dev_str = getenv("bootdevice");
+		if (dev_str)
+			dev = simple_strtoul(dev_str, &ep, 16);
+		if (!dev_str || dev_str == ep)
+			goto err;
+	}
+
+	desc = get_dev(ifname, dev);
+	if (!desc || (desc->type == DEV_TYPE_UNKNOWN))
+		goto err;
+
+	if (desc->part_type == PART_TYPE_UNKNOWN)
+		return 0;
+
+	part_str = strchr(dev_str, ':');
+	if (part_str) {
+		part = (int)simple_strtoul(++part_str, NULL, 16);
+		do_scan_part = 0;
+	}
+
+	while ((ret = get_partition_info(desc, part, info)) == 0 &&
+	       !info->bootable && do_scan_part)
+		part++;
+
+	if (ret) {
+		puts("** Invalid partition, use `dev[:part]' **\n");
+		return -1;
+	}
+	if (strncmp((char *)info->type, BOOT_PART_TYPE, sizeof(info->type)) != 0) {
+		printf("** Invalid partition type \"%.32s\""
+			" (expect \"" BOOT_PART_TYPE "\")\n",
+			info->type);
+		return -1;
+	}
+
+	*dev_desc = desc;
+	return part;
+
+ err:
+	puts("** Invalid boot device, use `dev[:part]' **\n");
+	return -1;
+}
+
 #endif
diff --git a/include/part.h b/include/part.h
index 79a3493..e44ca49 100644
--- a/include/part.h
+++ b/include/part.h
@@ -129,6 +129,10 @@ static inline void  init_part (block_dev_desc_t *dev_desc) {}
 static inline void dev_print(block_dev_desc_t *dev_desc) {}
 #endif
 
+int get_device_and_partition(const char *ifname, const char *dev_str,
+			     block_dev_desc_t **dev_desc,
+			     disk_partition_t *info);
+
 #ifdef CONFIG_MAC_PARTITION
 /* disk/part_mac.c */
 int get_partition_info_mac (block_dev_desc_t * dev_desc, int part, disk_partition_t *info);
-- 
1.7.5.4



More information about the U-Boot mailing list