---
 disk/part.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 55 insertions(+)

diff --git a/disk/part.c b/disk/part.c
index a4b6d265da..7c995f583c 100644
--- a/disk/part.c
+++ b/disk/part.c
@@ -14,6 +14,9 @@
 #include <malloc.h>
 #include <part.h>
 #include <ubifs_uboot.h>
+#include <dm.h>
+#include <dm/device-internal.h>
+#include <dm/uclass-internal.h>
 
 #undef PART_DEBUG
 
@@ -524,6 +527,58 @@ int blk_get_device_part_str(const char *ifname, const char 
*dev_part_str,
        }
 #endif
 
+#if IS_ENABLED(CONFIG_CMD_UBI) && !IS_ENABLED(CONFIG_SPL_BUILD)
+       /*
+        * Also special-case UBI, which may use names to find the specific
+        * volumes, so this deviates a bit from the typical devnum:partnum
+        * syntax.
+        */
+       if (!strcmp(ifname, "ubi")) {
+               dev = dectoul(dev_part_str, &ep);
+               if (*ep == ':') {
+                       struct udevice *ubi_dev = NULL;
+                       struct udevice *vol_dev = NULL;
+                       part_str = &ep[1];
+
+                       ret = uclass_find_device(UCLASS_UBI, dev, &ubi_dev);
+                       if (!ubi_dev || ret) {
+                               printf("** Cannot find UBI %x\n", dev);
+                               return -EINVAL;
+                       }
+
+                       part = dectoul(part_str, &ep);
+                       if (!*ep) {
+                               struct udevice *tmp_dev;
+                               device_foreach_child(tmp_dev, ubi_dev) {
+                                       struct blk_desc *desc = 
dev_get_uclass_plat(tmp_dev);
+                                       if (desc->devnum == part) {
+                                               vol_dev = tmp_dev;
+                                               break;
+                                       }
+                               }
+                       } else {
+                               ret = device_find_child_by_name(ubi_dev, 
part_str, &vol_dev);
+                       }
+
+                       if (!vol_dev || ret) {
+                               printf("** UBI volume %s not found\n", 
part_str);
+                               return -EINVAL;
+                       }
+
+                       ret = device_probe(vol_dev);
+                       if (ret)
+                               return ret;
+
+                       *desc = dev_get_uclass_plat(vol_dev);
+                       part_get_info_whole_disk(*desc, info);
+                       return 0;
+               }
+
+               printf("UBIFS not mounted, use ubifsmount to mount volume 
first!\n");
+               return -EINVAL;
+       }
+#endif
+
        /* If no dev_part_str, use bootdevice environment variable */
        if (CONFIG_IS_ENABLED(ENV_SUPPORT)) {
                if (!dev_part_str || !strlen(dev_part_str) ||
-- 
2.41.0

Reply via email to