summaryrefslogtreecommitdiff
path: root/disk/part.c
diff options
context:
space:
mode:
authorRob Herring <rob.herring@calxeda.com>2012-09-21 04:08:17 +0000
committerTom Rini <trini@ti.com>2012-09-25 14:44:40 -0700
commit99d2c205d4a151faf5f9a406316b9dd960f43475 (patch)
tree8c25f66afa7eae3879f134ff8bc8bdd62fc22203 /disk/part.c
parent40e0e5686accd2f7ae7fd81297620d0e132624d9 (diff)
downloadu-boot-99d2c205d4a151faf5f9a406316b9dd960f43475.tar.gz
disk/part: introduce get_device_and_partition
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 an enhancement over current versions. If no device or partition is specified on the command line, the bootdevice env variable will be used (scsiboot does this). Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Diffstat (limited to 'disk/part.c')
-rw-r--r--disk/part.c69
1 files changed, 67 insertions, 2 deletions
diff --git a/disk/part.c b/disk/part.c
index f659cc39cd..f0afd89553 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -70,7 +70,7 @@ static const struct block_drvr block_drvr[] = {
DECLARE_GLOBAL_DATA_PTR;
-block_dev_desc_t *get_dev(char* ifname, int dev)
+block_dev_desc_t *get_dev(const char *ifname, int dev)
{
const struct block_drvr *drvr = block_drvr;
block_dev_desc_t* (*reloc_get_dev)(int dev);
@@ -97,7 +97,7 @@ block_dev_desc_t *get_dev(char* ifname, int dev)
return NULL;
}
#else
-block_dev_desc_t *get_dev(char* ifname, int dev)
+block_dev_desc_t *get_dev(const char *ifname, int dev)
{
return NULL;
}
@@ -288,6 +288,7 @@ void init_part (block_dev_desc_t * dev_desc)
return;
}
#endif
+ dev_desc->part_type = PART_TYPE_UNKNOWN;
}
@@ -441,3 +442,67 @@ int get_partition_info(block_dev_desc_t *dev_desc, int part
return -1;
}
+
+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 = 0;
+ 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) {
+ /* disk doesn't use partition table */
+ if (!desc->lba) {
+ printf("**Bad disk size - %s %d:0 **\n", ifname, dev);
+ return -1;
+ }
+ info->start = 0;
+ info->size = desc->lba;
+ info->blksz = desc->blksz;
+
+ *dev_desc = desc;
+ return 0;
+ }
+
+ part_str = strchr(dev_str, ':');
+ if (part_str)
+ part = (int)simple_strtoul(++part_str, NULL, 16);
+
+ ret = get_partition_info(desc, part, info);
+ if (ret) {
+ printf("** Invalid partition %d, use `dev[:part]' **\n", part);
+ 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;
+}