]> git.sur5r.net Git - u-boot/blobdiff - drivers/mtd/ubi/vmt.c
ubi,ubifs: sync with linux v4.2
[u-boot] / drivers / mtd / ubi / vmt.c
index f4392f59692ab0403e70935b457cc6bfd128f7c7..f8ab08f9df00a3eec4acf8f284a83b59410fed72 100644 (file)
@@ -114,6 +114,19 @@ static ssize_t vol_attribute_show(struct device *dev,
        ubi_put_device(ubi);
        return ret;
 }
+
+static struct attribute *volume_dev_attrs[] = {
+       &attr_vol_reserved_ebs.attr,
+       &attr_vol_type.attr,
+       &attr_vol_name.attr,
+       &attr_vol_corrupted.attr,
+       &attr_vol_alignment.attr,
+       &attr_vol_usable_eb_size.attr,
+       &attr_vol_data_bytes.attr,
+       &attr_vol_upd_marker.attr,
+       NULL
+};
+ATTRIBUTE_GROUPS(volume_dev);
 #endif
 
 /* Release method for volume devices */
@@ -125,66 +138,6 @@ static void vol_release(struct device *dev)
        kfree(vol);
 }
 
-#ifndef __UBOOT__
-/**
- * volume_sysfs_init - initialize sysfs for new volume.
- * @ubi: UBI device description object
- * @vol: volume description object
- *
- * This function returns zero in case of success and a negative error code in
- * case of failure.
- *
- * Note, this function does not free allocated resources in case of failure -
- * the caller does it. This is because this would cause release() here and the
- * caller would oops.
- */
-static int volume_sysfs_init(struct ubi_device *ubi, struct ubi_volume *vol)
-{
-       int err;
-
-       err = device_create_file(&vol->dev, &attr_vol_reserved_ebs);
-       if (err)
-               return err;
-       err = device_create_file(&vol->dev, &attr_vol_type);
-       if (err)
-               return err;
-       err = device_create_file(&vol->dev, &attr_vol_name);
-       if (err)
-               return err;
-       err = device_create_file(&vol->dev, &attr_vol_corrupted);
-       if (err)
-               return err;
-       err = device_create_file(&vol->dev, &attr_vol_alignment);
-       if (err)
-               return err;
-       err = device_create_file(&vol->dev, &attr_vol_usable_eb_size);
-       if (err)
-               return err;
-       err = device_create_file(&vol->dev, &attr_vol_data_bytes);
-       if (err)
-               return err;
-       err = device_create_file(&vol->dev, &attr_vol_upd_marker);
-       return err;
-}
-
-/**
- * volume_sysfs_close - close sysfs for a volume.
- * @vol: volume description object
- */
-static void volume_sysfs_close(struct ubi_volume *vol)
-{
-       device_remove_file(&vol->dev, &attr_vol_upd_marker);
-       device_remove_file(&vol->dev, &attr_vol_data_bytes);
-       device_remove_file(&vol->dev, &attr_vol_usable_eb_size);
-       device_remove_file(&vol->dev, &attr_vol_alignment);
-       device_remove_file(&vol->dev, &attr_vol_corrupted);
-       device_remove_file(&vol->dev, &attr_vol_name);
-       device_remove_file(&vol->dev, &attr_vol_type);
-       device_remove_file(&vol->dev, &attr_vol_reserved_ebs);
-       device_unregister(&vol->dev);
-}
-#endif
-
 /**
  * ubi_create_volume - create volume.
  * @ubi: UBI device description object
@@ -221,7 +174,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
                        }
 
                if (vol_id == UBI_VOL_NUM_AUTO) {
-                       ubi_err("out of volume IDs");
+                       ubi_err(ubi, "out of volume IDs");
                        err = -ENFILE;
                        goto out_unlock;
                }
@@ -235,7 +188,7 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
        /* Ensure that this volume does not exist */
        err = -EEXIST;
        if (ubi->volumes[vol_id]) {
-               ubi_err("volume %d already exists", vol_id);
+               ubi_err(ubi, "volume %d already exists", vol_id);
                goto out_unlock;
        }
 
@@ -244,20 +197,22 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
                if (ubi->volumes[i] &&
                    ubi->volumes[i]->name_len == req->name_len &&
                    !strcmp(ubi->volumes[i]->name, req->name)) {
-                       ubi_err("volume \"%s\" exists (ID %d)", req->name, i);
+                       ubi_err(ubi, "volume \"%s\" exists (ID %d)",
+                               req->name, i);
                        goto out_unlock;
                }
 
        /* Calculate how many eraseblocks are requested */
        vol->usable_leb_size = ubi->leb_size - ubi->leb_size % req->alignment;
-       vol->reserved_pebs += div_u64(req->bytes + vol->usable_leb_size - 1,
-                                     vol->usable_leb_size);
+       vol->reserved_pebs = div_u64(req->bytes + vol->usable_leb_size - 1,
+                                    vol->usable_leb_size);
 
        /* Reserve physical eraseblocks */
        if (vol->reserved_pebs > ubi->avail_pebs) {
-               ubi_err("not enough PEBs, only %d available", ubi->avail_pebs);
+               ubi_err(ubi, "not enough PEBs, only %d available",
+                       ubi->avail_pebs);
                if (ubi->corr_peb_count)
-                       ubi_err("%d PEBs are corrupted and not used",
+                       ubi_err(ubi, "%d PEBs are corrupted and not used",
                                ubi->corr_peb_count);
                err = -ENOSPC;
                goto out_unlock;
@@ -312,26 +267,25 @@ int ubi_create_volume(struct ubi_device *ubi, struct ubi_mkvol_req *req)
        dev = MKDEV(MAJOR(ubi->cdev.dev), vol_id + 1);
        err = cdev_add(&vol->cdev, dev, 1);
        if (err) {
-               ubi_err("cannot add character device");
+               ubi_err(ubi, "cannot add character device");
                goto out_mapping;
        }
 
        vol->dev.release = vol_release;
        vol->dev.parent = &ubi->dev;
        vol->dev.devt = dev;
-       vol->dev.class = ubi_class;
+#ifndef __UBOOT__
+       vol->dev.class = &ubi_class;
+       vol->dev.groups = volume_dev_groups;
+#endif
 
        dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id);
        err = device_register(&vol->dev);
        if (err) {
-               ubi_err("cannot register device");
+               ubi_err(ubi, "cannot register device");
                goto out_cdev;
        }
 
-       err = volume_sysfs_init(ubi, vol);
-       if (err)
-               goto out_sysfs;
-
        /* Fill volume table record */
        memset(&vtbl_rec, 0, sizeof(struct ubi_vtbl_record));
        vtbl_rec.reserved_pebs = cpu_to_be32(vol->reserved_pebs);
@@ -368,7 +322,7 @@ out_sysfs:
         */
        do_free = 0;
        get_device(&vol->dev);
-       volume_sysfs_close(vol);
+       device_unregister(&vol->dev);
 out_cdev:
        cdev_del(&vol->cdev);
 out_mapping:
@@ -384,7 +338,7 @@ out_unlock:
                kfree(vol);
        else
                put_device(&vol->dev);
-       ubi_err("cannot create volume %d, error %d", vol_id, err);
+       ubi_err(ubi, "cannot create volume %d, error %d", vol_id, err);
        return err;
 }
 
@@ -436,7 +390,7 @@ int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl)
        }
 
        cdev_del(&vol->cdev);
-       volume_sysfs_close(vol);
+       device_unregister(&vol->dev);
 
        spin_lock(&ubi->volumes_lock);
        ubi->rsvd_pebs -= reserved_pebs;
@@ -452,7 +406,7 @@ int ubi_remove_volume(struct ubi_volume_desc *desc, int no_vtbl)
        return err;
 
 out_err:
-       ubi_err("cannot remove volume %d, error %d", vol_id, err);
+       ubi_err(ubi, "cannot remove volume %d, error %d", vol_id, err);
        spin_lock(&ubi->volumes_lock);
        ubi->volumes[vol_id] = vol;
 out_unlock:
@@ -485,7 +439,7 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
 
        if (vol->vol_type == UBI_STATIC_VOLUME &&
            reserved_pebs < vol->used_ebs) {
-               ubi_err("too small size %d, %d LEBs contain data",
+               ubi_err(ubi, "too small size %d, %d LEBs contain data",
                        reserved_pebs, vol->used_ebs);
                return -EINVAL;
        }
@@ -514,10 +468,10 @@ int ubi_resize_volume(struct ubi_volume_desc *desc, int reserved_pebs)
        if (pebs > 0) {
                spin_lock(&ubi->volumes_lock);
                if (pebs > ubi->avail_pebs) {
-                       ubi_err("not enough PEBs: requested %d, available %d",
+                       ubi_err(ubi, "not enough PEBs: requested %d, available %d",
                                pebs, ubi->avail_pebs);
                        if (ubi->corr_peb_count)
-                               ubi_err("%d PEBs are corrupted and not used",
+                               ubi_err(ubi, "%d PEBs are corrupted and not used",
                                        ubi->corr_peb_count);
                        spin_unlock(&ubi->volumes_lock);
                        err = -ENOSPC;
@@ -641,7 +595,7 @@ int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol)
        dev = MKDEV(MAJOR(ubi->cdev.dev), vol->vol_id + 1);
        err = cdev_add(&vol->cdev, dev, 1);
        if (err) {
-               ubi_err("cannot add character device for volume %d, error %d",
+               ubi_err(ubi, "cannot add character device for volume %d, error %d",
                        vol_id, err);
                return err;
        }
@@ -649,19 +603,15 @@ int ubi_add_volume(struct ubi_device *ubi, struct ubi_volume *vol)
        vol->dev.release = vol_release;
        vol->dev.parent = &ubi->dev;
        vol->dev.devt = dev;
-       vol->dev.class = ubi_class;
+#ifndef __UBOOT__
+       vol->dev.class = &ubi_class;
+       vol->dev.groups = volume_dev_groups;
+#endif
        dev_set_name(&vol->dev, "%s_%d", ubi->ubi_name, vol->vol_id);
        err = device_register(&vol->dev);
        if (err)
                goto out_cdev;
 
-       err = volume_sysfs_init(ubi, vol);
-       if (err) {
-               cdev_del(&vol->cdev);
-               volume_sysfs_close(vol);
-               return err;
-       }
-
        self_check_volumes(ubi);
        return err;
 
@@ -684,7 +634,7 @@ void ubi_free_volume(struct ubi_device *ubi, struct ubi_volume *vol)
 
        ubi->volumes[vol->vol_id] = NULL;
        cdev_del(&vol->cdev);
-       volume_sysfs_close(vol);
+       device_unregister(&vol->dev);
 }
 
 /**
@@ -708,7 +658,7 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id)
 
        if (!vol) {
                if (reserved_pebs) {
-                       ubi_err("no volume info, but volume exists");
+                       ubi_err(ubi, "no volume info, but volume exists");
                        goto fail;
                }
                spin_unlock(&ubi->volumes_lock);
@@ -717,90 +667,91 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id)
 
        if (vol->reserved_pebs < 0 || vol->alignment < 0 || vol->data_pad < 0 ||
            vol->name_len < 0) {
-               ubi_err("negative values");
+               ubi_err(ubi, "negative values");
                goto fail;
        }
        if (vol->alignment > ubi->leb_size || vol->alignment == 0) {
-               ubi_err("bad alignment");
+               ubi_err(ubi, "bad alignment");
                goto fail;
        }
 
        n = vol->alignment & (ubi->min_io_size - 1);
        if (vol->alignment != 1 && n) {
-               ubi_err("alignment is not multiple of min I/O unit");
+               ubi_err(ubi, "alignment is not multiple of min I/O unit");
                goto fail;
        }
 
        n = ubi->leb_size % vol->alignment;
        if (vol->data_pad != n) {
-               ubi_err("bad data_pad, has to be %lld", n);
+               ubi_err(ubi, "bad data_pad, has to be %lld", n);
                goto fail;
        }
 
        if (vol->vol_type != UBI_DYNAMIC_VOLUME &&
            vol->vol_type != UBI_STATIC_VOLUME) {
-               ubi_err("bad vol_type");
+               ubi_err(ubi, "bad vol_type");
                goto fail;
        }
 
        if (vol->upd_marker && vol->corrupted) {
-               ubi_err("update marker and corrupted simultaneously");
+               ubi_err(ubi, "update marker and corrupted simultaneously");
                goto fail;
        }
 
        if (vol->reserved_pebs > ubi->good_peb_count) {
-               ubi_err("too large reserved_pebs");
+               ubi_err(ubi, "too large reserved_pebs");
                goto fail;
        }
 
        n = ubi->leb_size - vol->data_pad;
        if (vol->usable_leb_size != ubi->leb_size - vol->data_pad) {
-               ubi_err("bad usable_leb_size, has to be %lld", n);
+               ubi_err(ubi, "bad usable_leb_size, has to be %lld", n);
                goto fail;
        }
 
        if (vol->name_len > UBI_VOL_NAME_MAX) {
-               ubi_err("too long volume name, max is %d", UBI_VOL_NAME_MAX);
+               ubi_err(ubi, "too long volume name, max is %d",
+                       UBI_VOL_NAME_MAX);
                goto fail;
        }
 
        n = strnlen(vol->name, vol->name_len + 1);
        if (n != vol->name_len) {
-               ubi_err("bad name_len %lld", n);
+               ubi_err(ubi, "bad name_len %lld", n);
                goto fail;
        }
 
        n = (long long)vol->used_ebs * vol->usable_leb_size;
        if (vol->vol_type == UBI_DYNAMIC_VOLUME) {
                if (vol->corrupted) {
-                       ubi_err("corrupted dynamic volume");
+                       ubi_err(ubi, "corrupted dynamic volume");
                        goto fail;
                }
                if (vol->used_ebs != vol->reserved_pebs) {
-                       ubi_err("bad used_ebs");
+                       ubi_err(ubi, "bad used_ebs");
                        goto fail;
                }
                if (vol->last_eb_bytes != vol->usable_leb_size) {
-                       ubi_err("bad last_eb_bytes");
+                       ubi_err(ubi, "bad last_eb_bytes");
                        goto fail;
                }
                if (vol->used_bytes != n) {
-                       ubi_err("bad used_bytes");
+                       ubi_err(ubi, "bad used_bytes");
                        goto fail;
                }
        } else {
                if (vol->used_ebs < 0 || vol->used_ebs > vol->reserved_pebs) {
-                       ubi_err("bad used_ebs");
+                       ubi_err(ubi, "bad used_ebs");
                        goto fail;
                }
                if (vol->last_eb_bytes < 0 ||
                    vol->last_eb_bytes > vol->usable_leb_size) {
-                       ubi_err("bad last_eb_bytes");
+                       ubi_err(ubi, "bad last_eb_bytes");
                        goto fail;
                }
                if (vol->used_bytes < 0 || vol->used_bytes > n ||
                    vol->used_bytes < n - vol->usable_leb_size) {
-                       ubi_err("bad used_bytes");
+                       ubi_err(ubi, "bad used_bytes");
                        goto fail;
                }
        }
@@ -818,7 +769,7 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id)
        if (alignment != vol->alignment || data_pad != vol->data_pad ||
            upd_marker != vol->upd_marker || vol_type != vol->vol_type ||
            name_len != vol->name_len || strncmp(name, vol->name, name_len)) {
-               ubi_err("volume info is different");
+               ubi_err(ubi, "volume info is different");
                goto fail;
        }
 
@@ -826,7 +777,7 @@ static int self_check_volume(struct ubi_device *ubi, int vol_id)
        return 0;
 
 fail:
-       ubi_err("self-check failed for volume %d", vol_id);
+       ubi_err(ubi, "self-check failed for volume %d", vol_id);
        if (vol)
                ubi_dump_vol_info(vol);
        ubi_dump_vtbl_record(&ubi->vtbl[vol_id], vol_id);