summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/user/ubi.rst44
-rw-r--r--commands/detect.c5
-rw-r--r--commands/mount.c2
-rw-r--r--common/blspec.c9
-rw-r--r--drivers/base/driver.c25
-rw-r--r--drivers/mtd/core.c40
-rw-r--r--drivers/mtd/ubi/build.c9
-rw-r--r--drivers/mtd/ubi/cdev.c4
8 files changed, 84 insertions, 54 deletions
diff --git a/Documentation/user/ubi.rst b/Documentation/user/ubi.rst
index a187680e2c..c300c0f951 100644
--- a/Documentation/user/ubi.rst
+++ b/Documentation/user/ubi.rst
@@ -5,9 +5,6 @@ barebox has both UBI and UBIFS support. For handling UBI barebox has commands si
the Linux commands :ref:`command_ubiformat`, :ref:`command_ubiattach`, :ref:`command_ubidetach`,
:ref:`command_ubimkvol` and :ref:`command_ubirmvol`.
-The following examples assume we work on the first UBI device. Replace ``ubi0`` with
-the appropriate number when you have multiple UBI devices.
-
The first step for preparing a pristine Flash for UBI is to :ref:`command_ubiformat` the
device:
@@ -28,17 +25,17 @@ After a device has been formatted it can be attached with :ref:`command_ubiattac
ubiattach /dev/nand0.root
-This will create the controlling node ``/dev/ubi0`` and also register all volumes present
-on the device as ``/dev/ubi0.<volname>``. When freshly formatted there won't be any volumes
-present. A volume can be created with:
+This will create the controlling node ``/dev/nand0.root.ubi`` and also register all volumes
+present on the device as ``/dev/nand0.root.ubi.<volname>``. When freshly formatted there won't
+be any volumes present. A volume can be created with:
.. code-block:: sh
- ubimkvol /dev/ubi0 root 0
+ ubimkvol /dev/nand0.root.ubi root 0
The first parameter is the controlling node. The second parameter is the name of the volume.
-In this case the volume can be found under ``/dev/ubi.root``. The third parameter contains
-the size. A size of zero means that all available space shall be used.
+In this case the volume can be found under ``/dev/dev/nand0.root.ubi.root``. The third
+parameter contains the size. A size of zero means that all available space shall be used.
The next step is to write a UBIFS image to the volume. The image must be created on a host using
the ``mkfs.ubifs`` command. ``mkfs.ubifs`` requires several arguments for describing the
@@ -46,7 +43,7 @@ flash layout. Values for these arguments can be retrieved from a ``devinfo ubi``
.. code-block:: sh
- barebox@Phytec pcm970:/ devinfo ubi0
+ barebox@Phytec pcm970:/ devinfo nand0.root.ubi
Parameters:
peb_size: 16384
leb_size: 15360
@@ -76,38 +73,27 @@ The UBIFS image can be transferred to the board for example with TFTP:
.. code-block:: sh
- cp /mnt/tftp/root.ubifs /dev/ubi0.root
+ cp /mnt/tftp/root.ubifs /dev/nand0.root.ubi.root
Finally it can be mounted using the :ref:`command_mount` command:
.. code-block:: sh
- mkdir -p /mnt/ubi
- mount -t ubifs /dev/ubi0.root /mnt/ubi
+ mount /dev/nand0.root.ubi.root
+The default mount path when the mount point is skipped is ``/mnt/<devname>``,
+so in this example it will be ``/mnt/nand0.root.ubi.root``.
The second time the UBIFS is mounted the above can be simplified to:
.. code-block:: sh
ubiattach /dev/nand0.root
- mount -t ubifs /dev/ubi0.root /mnt/ubi
+ mount /dev/nand0.root.ubi.root
Mounting the UBIFS can also be made transparent with the automount command.
-With this helper script in ``/env/bin/automount-ubi:``:
-
-.. code-block:: sh
-
- #!/bin/sh
-
- if [ ! -e /dev/ubi0 ]; then
- ubiattach /dev/nand0 || exit 1
- fi
-
- mount -t ubifs /dev/ubi0.root $automount_path
-
-
-The command ``automount -d /mnt/ubi/ '/env/bin/automount-ubi'`` will automatically
-attach the UBI device and mount the UBIFS image to ``/mnt/ubi`` whenever ``/mnt/ubi``
+The command ``automount -d /mnt/nand0.root.ubi.root 'mount nand0.root.ubi.root'``
+will automatically attach the UBI device and mount the UBIFS image to
+``/mnt/nand0.root.ubi.root`` whenever ``/mnt/nand0.root.ubi.root``
is first accessed. The automount command can be added to ``/env/init/automount`` to
execute it during startup.
diff --git a/commands/detect.c b/commands/detect.c
index d8e0afc314..1586a6fb54 100644
--- a/commands/detect.c
+++ b/commands/detect.c
@@ -68,10 +68,7 @@ static int do_detect(int argc, char *argv[])
return COMMAND_ERROR_USAGE;
for (i = optind; i < argc; i++) {
- dev = get_device_by_name(argv[i]);
- if (!dev)
- return -ENODEV;
- ret = device_detect(dev);
+ ret = device_detect_by_name(argv[i]);
if (ret && option_error)
return ret;
}
diff --git a/commands/mount.c b/commands/mount.c
index 939e9bc853..aa769d46fe 100644
--- a/commands/mount.c
+++ b/commands/mount.c
@@ -79,6 +79,8 @@ static int do_mount(int argc, char *argv[])
if (!strncmp(devstr, "/dev/", 5))
devstr += 5;
+ device_detect_by_name(devstr);
+
cdev = cdev_by_name(devstr);
if (!cdev)
return -ENOENT;
diff --git a/common/blspec.c b/common/blspec.c
index aef246d7f5..7e84ff3cec 100644
--- a/common/blspec.c
+++ b/common/blspec.c
@@ -615,17 +615,10 @@ int blspec_scan_devicename(struct blspec *blspec, const char *devname)
{
struct device_d *dev;
struct cdev *cdev;
- const char *colon;
pr_debug("%s: %s\n", __func__, devname);
- colon = strchr(devname, '.');
- if (colon) {
- char *name = xstrdup(devname);
- *strchr(name, '.') = 0;
- device_detect_by_name(name);
- free(name);
- }
+ device_detect_by_name(devname);
cdev = cdev_by_name(devname);
if (cdev) {
diff --git a/drivers/base/driver.c b/drivers/base/driver.c
index 24cb5bc62b..338bea1280 100644
--- a/drivers/base/driver.c
+++ b/drivers/base/driver.c
@@ -113,14 +113,29 @@ int device_detect(struct device_d *dev)
return dev->detect(dev);
}
-int device_detect_by_name(const char *devname)
+int device_detect_by_name(const char *__devname)
{
- struct device_d *dev = get_device_by_name(devname);
+ char *devname = xstrdup(__devname);
+ char *str = devname;
+ struct device_d *dev;
+ int ret = -ENODEV;
+
+ while (1) {
+ strsep(&str, ".");
+
+ dev = get_device_by_name(devname);
+ if (dev)
+ ret = device_detect(dev);
- if (!dev)
- return -ENODEV;
+ if (!str)
+ break;
+ else
+ *(str - 1) = '.';
+ }
- return device_detect(dev);
+ free(devname);
+
+ return ret;
}
static int match(struct driver_d *drv, struct device_d *dev)
diff --git a/drivers/mtd/core.c b/drivers/mtd/core.c
index 8b8254c2d3..fda903441c 100644
--- a/drivers/mtd/core.c
+++ b/drivers/mtd/core.c
@@ -18,7 +18,9 @@
#include <common.h>
#include <linux/mtd/nand.h>
#include <linux/mtd/mtd.h>
+#include <mtd/ubi-user.h>
#include <cmdlinepart.h>
+#include <filetype.h>
#include <init.h>
#include <xfuncs.h>
#include <driver.h>
@@ -542,6 +544,41 @@ static int of_mtd_fixup(struct device_node *root, void *ctx)
return 0;
}
+static int mtd_detect(struct device_d *dev)
+{
+ struct mtd_info *mtd = container_of(dev, struct mtd_info, class_dev);
+ int bufsize = 512;
+ void *buf;
+ int ret;
+ enum filetype filetype;
+ size_t retlen;
+
+ /*
+ * Do not try to attach an UBI device if this device has partitions
+ * as it's not a good idea to attach UBI on a raw device when the
+ * real UBI only spans the first partition.
+ */
+ if (!list_empty(&mtd->partitions))
+ return -EBUSY;
+
+ buf = xmalloc(bufsize);
+
+ ret = mtd_read(mtd, 0, bufsize, &retlen, buf);
+ if (ret)
+ goto out;
+
+ filetype = file_detect_type(buf, bufsize);
+ if (filetype == filetype_ubi) {
+ ret = ubi_attach_mtd_dev(mtd, UBI_DEV_NUM_AUTO, 0, 20);
+ if (ret == -EEXIST)
+ ret = 0;
+ }
+out:
+ free(buf);
+
+ return ret;
+}
+
int add_mtd_device(struct mtd_info *mtd, const char *devname, int device_id)
{
struct mtddev_hook *hook;
@@ -554,6 +591,9 @@ int add_mtd_device(struct mtd_info *mtd, const char *devname, int device_id)
if (mtd->parent)
mtd->class_dev.parent = mtd->parent;
+ if (IS_ENABLED(CONFIG_MTD_UBI))
+ mtd->class_dev.detect = mtd_detect;
+
ret = register_device(&mtd->class_dev);
if (ret)
return ret;
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c
index b02880eb79..797022636d 100644
--- a/drivers/mtd/ubi/build.c
+++ b/drivers/mtd/ubi/build.c
@@ -155,8 +155,8 @@ static int uif_init(struct ubi_device *ubi, int *ref)
*ref = 0;
sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num);
- sprintf(ubi->dev.name, "ubi");
- ubi->dev.id = DEVICE_ID_DYNAMIC;
+ sprintf(ubi->dev.name, "%s.ubi", ubi->mtd->cdev.name);
+ ubi->dev.id = DEVICE_ID_SINGLE;
ubi->dev.parent = &ubi->mtd->class_dev;
err = register_device(&ubi->dev);
@@ -518,7 +518,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
for (i = 0; i < UBI_MAX_DEVICES; i++) {
ubi = ubi_devices[i];
if (ubi && mtd == ubi->mtd) {
- ubi_err("mtd%d is already attached to ubi%d",
+ ubi_debug("mtd%d is already attached to ubi%d",
mtd->index, i);
return -EEXIST;
}
@@ -596,9 +596,6 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num,
#else
ubi->fm_disabled = 1;
#endif
-
- ubi_msg("attaching mtd%d to ubi%d", mtd->index, ubi_num);
-
err = io_init(ubi, max_beb_per1024);
if (err)
goto out_free;
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c
index 90d5b2dd66..fe71a8d609 100644
--- a/drivers/mtd/ubi/cdev.c
+++ b/drivers/mtd/ubi/cdev.c
@@ -176,7 +176,7 @@ int ubi_volume_cdev_add(struct ubi_device *ubi, struct ubi_volume *vol)
priv->ubi = ubi;
cdev->ops = &ubi_volume_fops;
- cdev->name = asprintf("ubi%d.%s", ubi->ubi_num, vol->name);
+ cdev->name = asprintf("%s.%s", ubi->cdev.name, vol->name);
cdev->priv = priv;
cdev->size = vol->used_bytes;
cdev->dev = &vol->dev;
@@ -239,7 +239,7 @@ int ubi_cdev_add(struct ubi_device *ubi)
int ret;
cdev->ops = &ubi_fops;
- cdev->name = asprintf("ubi%d", ubi->ubi_num);
+ cdev->name = asprintf("%s.ubi", ubi->mtd->cdev.name);
cdev->priv = ubi;
cdev->size = 0;