diff options
-rw-r--r-- | Documentation/user/ubi.rst | 44 | ||||
-rw-r--r-- | commands/detect.c | 5 | ||||
-rw-r--r-- | commands/mount.c | 2 | ||||
-rw-r--r-- | common/blspec.c | 9 | ||||
-rw-r--r-- | drivers/base/driver.c | 25 | ||||
-rw-r--r-- | drivers/mtd/core.c | 40 | ||||
-rw-r--r-- | drivers/mtd/ubi/build.c | 9 | ||||
-rw-r--r-- | drivers/mtd/ubi/cdev.c | 4 |
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; |