Message ID | 1399486743-23807-2-git-send-email-swarren@wwwdotorg.org |
---|---|
State | Accepted |
Delegated to: | Pantelis Antoniou |
Headers | show |
Hi Stephen, On May 7, 2014, at 9:19 PM, Stephen Warren wrote: > From: Stephen Warren <swarren@nvidia.com> > > Some device types (e.g. eMMC) have hardware-level partitions (for eMMC, > separate boot and user data partitions). This change allows the user to > specify the HW partition they wish to access when passing a device ID to > U-Boot Commands such as part, ls, load, ums, etc. > > The syntax allows an optional ".$hwpartid" to be appended to the device > name string for those commands. > > Existing syntax, for MMC device 0, default HW partition ID, SW partition > ID 1: > > ls mmc 0:1 / > > New syntax, for MMC device 0, HW partition ID 1 (boot0), SW partition > ID 2: > > ls mmc 0.1:2 / > > For my purposes, this is most useful for the ums (USB mass storage > gadget) command, but there's no reason not to allow the new syntax > globally. > > This patch adds the core support infra-structure. The next patch will > provide the implementation for MMC. > > Signed-off-by: Stephen Warren <swarren@nvidia.com> > --- > disk/part.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- > 1 file changed, 64 insertions(+), 10 deletions(-) > > diff --git a/disk/part.c b/disk/part.c > index b8c6aac80162..5e10cae015e5 100644 > --- a/disk/part.c > +++ b/disk/part.c > @@ -22,6 +22,7 @@ > struct block_drvr { > char *name; > block_dev_desc_t* (*get_dev)(int dev); > + int (*select_hwpart)(int dev_num, int hwpart); > }; > > static const struct block_drvr block_drvr[] = { > @@ -52,11 +53,13 @@ static const struct block_drvr block_drvr[] = { > DECLARE_GLOBAL_DATA_PTR; > > #ifdef HAVE_BLOCK_DEVICE > -block_dev_desc_t *get_dev(const char *ifname, int dev) > +block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart) > { > const struct block_drvr *drvr = block_drvr; > block_dev_desc_t* (*reloc_get_dev)(int dev); > + int (*select_hwpart)(int dev_num, int hwpart); > char *name; > + int ret; > > if (!ifname) > return NULL; > @@ -68,17 +71,41 @@ block_dev_desc_t *get_dev(const char *ifname, int dev) > while (drvr->name) { > name = drvr->name; > reloc_get_dev = drvr->get_dev; > + select_hwpart = drvr->select_hwpart; > #ifdef CONFIG_NEEDS_MANUAL_RELOC > name += gd->reloc_off; > reloc_get_dev += gd->reloc_off; > -#endif > - if (strncmp(ifname, name, strlen(name)) == 0) > - return reloc_get_dev(dev); > + if (select_hwpart) > + select_hwpart += gd->reloc_off; > +#endif > + if (strncmp(ifname, name, strlen(name)) == 0) { > + block_dev_desc_t *dev_desc = reloc_get_dev(dev); > + if (!dev_desc) > + return NULL; > + if (hwpart == -1) > + return dev_desc; > + if (!select_hwpart) > + return NULL; > + ret = select_hwpart(dev_desc->dev, hwpart); > + if (ret < 0) > + return NULL; > + return dev_desc; > + } > drvr++; > } > return NULL; > } > + > +block_dev_desc_t *get_dev(const char *ifname, int dev) > +{ > + return get_dev_hwpart(ifname, dev, -1); > +} > #else > +block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart) > +{ > + return NULL; > +} > + > block_dev_desc_t *get_dev(const char *ifname, int dev) > { > return NULL; > @@ -413,25 +440,52 @@ int get_partition_info(block_dev_desc_t *dev_desc, int part > return -1; > } > > -int get_device(const char *ifname, const char *dev_str, > +int get_device(const char *ifname, const char *dev_hwpart_str, > block_dev_desc_t **dev_desc) > { > char *ep; > - int dev; > + char *dup_str = NULL; > + const char *dev_str, *hwpart_str; > + int dev, hwpart; > + > + hwpart_str = strchr(dev_hwpart_str, '.'); > + if (hwpart_str) { > + dup_str = strdup(dev_hwpart_str); > + dup_str[hwpart_str - dev_hwpart_str] = 0; > + dev_str = dup_str; > + hwpart_str++; > + } else { > + dev_str = dev_hwpart_str; > + hwpart = -1; > + } > > dev = simple_strtoul(dev_str, &ep, 16); > if (*ep) { > printf("** Bad device specification %s %s **\n", > ifname, dev_str); > - return -1; > + dev = -1; > + goto cleanup; > + } > + > + if (hwpart_str) { > + hwpart = simple_strtoul(hwpart_str, &ep, 16); > + if (*ep) { > + printf("** Bad HW partition specification %s %s **\n", > + ifname, hwpart_str); > + dev = -1; > + goto cleanup; > + } > } > > - *dev_desc = get_dev(ifname, dev); > + *dev_desc = get_dev_hwpart(ifname, dev, hwpart); > if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) { > - printf("** Bad device %s %s **\n", ifname, dev_str); > - return -1; > + printf("** Bad device %s %s **\n", ifname, dev_hwpart_str); > + dev = -1; > + goto cleanup; > } > > +cleanup: > + free(dup_str); > return dev; > } > > -- > 1.8.1.5 > Applied Thanks -- Pantelis Acked-by: Pantelis Antoniou <panto@antoniou-consulting.com>
diff --git a/disk/part.c b/disk/part.c index b8c6aac80162..5e10cae015e5 100644 --- a/disk/part.c +++ b/disk/part.c @@ -22,6 +22,7 @@ struct block_drvr { char *name; block_dev_desc_t* (*get_dev)(int dev); + int (*select_hwpart)(int dev_num, int hwpart); }; static const struct block_drvr block_drvr[] = { @@ -52,11 +53,13 @@ static const struct block_drvr block_drvr[] = { DECLARE_GLOBAL_DATA_PTR; #ifdef HAVE_BLOCK_DEVICE -block_dev_desc_t *get_dev(const char *ifname, int dev) +block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart) { const struct block_drvr *drvr = block_drvr; block_dev_desc_t* (*reloc_get_dev)(int dev); + int (*select_hwpart)(int dev_num, int hwpart); char *name; + int ret; if (!ifname) return NULL; @@ -68,17 +71,41 @@ block_dev_desc_t *get_dev(const char *ifname, int dev) while (drvr->name) { name = drvr->name; reloc_get_dev = drvr->get_dev; + select_hwpart = drvr->select_hwpart; #ifdef CONFIG_NEEDS_MANUAL_RELOC name += gd->reloc_off; reloc_get_dev += gd->reloc_off; -#endif - if (strncmp(ifname, name, strlen(name)) == 0) - return reloc_get_dev(dev); + if (select_hwpart) + select_hwpart += gd->reloc_off; +#endif + if (strncmp(ifname, name, strlen(name)) == 0) { + block_dev_desc_t *dev_desc = reloc_get_dev(dev); + if (!dev_desc) + return NULL; + if (hwpart == -1) + return dev_desc; + if (!select_hwpart) + return NULL; + ret = select_hwpart(dev_desc->dev, hwpart); + if (ret < 0) + return NULL; + return dev_desc; + } drvr++; } return NULL; } + +block_dev_desc_t *get_dev(const char *ifname, int dev) +{ + return get_dev_hwpart(ifname, dev, -1); +} #else +block_dev_desc_t *get_dev_hwpart(const char *ifname, int dev, int hwpart) +{ + return NULL; +} + block_dev_desc_t *get_dev(const char *ifname, int dev) { return NULL; @@ -413,25 +440,52 @@ int get_partition_info(block_dev_desc_t *dev_desc, int part return -1; } -int get_device(const char *ifname, const char *dev_str, +int get_device(const char *ifname, const char *dev_hwpart_str, block_dev_desc_t **dev_desc) { char *ep; - int dev; + char *dup_str = NULL; + const char *dev_str, *hwpart_str; + int dev, hwpart; + + hwpart_str = strchr(dev_hwpart_str, '.'); + if (hwpart_str) { + dup_str = strdup(dev_hwpart_str); + dup_str[hwpart_str - dev_hwpart_str] = 0; + dev_str = dup_str; + hwpart_str++; + } else { + dev_str = dev_hwpart_str; + hwpart = -1; + } dev = simple_strtoul(dev_str, &ep, 16); if (*ep) { printf("** Bad device specification %s %s **\n", ifname, dev_str); - return -1; + dev = -1; + goto cleanup; + } + + if (hwpart_str) { + hwpart = simple_strtoul(hwpart_str, &ep, 16); + if (*ep) { + printf("** Bad HW partition specification %s %s **\n", + ifname, hwpart_str); + dev = -1; + goto cleanup; + } } - *dev_desc = get_dev(ifname, dev); + *dev_desc = get_dev_hwpart(ifname, dev, hwpart); if (!(*dev_desc) || ((*dev_desc)->type == DEV_TYPE_UNKNOWN)) { - printf("** Bad device %s %s **\n", ifname, dev_str); - return -1; + printf("** Bad device %s %s **\n", ifname, dev_hwpart_str); + dev = -1; + goto cleanup; } +cleanup: + free(dup_str); return dev; }