diff options
| -rw-r--r-- | drivers/mtd/ubi/Kconfig.debug | 10 | ||||
| -rw-r--r-- | drivers/mtd/ubi/cdev.c | 36 | ||||
| -rw-r--r-- | drivers/mtd/ubi/ubi.h | 5 | ||||
| -rw-r--r-- | include/mtd/ubi-user.h | 34 |
4 files changed, 66 insertions, 19 deletions
diff --git a/drivers/mtd/ubi/Kconfig.debug b/drivers/mtd/ubi/Kconfig.debug index 1e2ee22edeff..2246f154e2f7 100644 --- a/drivers/mtd/ubi/Kconfig.debug +++ b/drivers/mtd/ubi/Kconfig.debug | |||
| @@ -33,16 +33,6 @@ config MTD_UBI_DEBUG_DISABLE_BGT | |||
| 33 | This option switches the background thread off by default. The thread | 33 | This option switches the background thread off by default. The thread |
| 34 | may be also be enabled/disabled via UBI sysfs. | 34 | may be also be enabled/disabled via UBI sysfs. |
| 35 | 35 | ||
| 36 | config MTD_UBI_DEBUG_USERSPACE_IO | ||
| 37 | bool "Direct user-space write/erase support" | ||
| 38 | default n | ||
| 39 | depends on MTD_UBI_DEBUG | ||
| 40 | help | ||
| 41 | By default, users cannot directly write and erase individual | ||
| 42 | eraseblocks of dynamic volumes, and have to use update operation | ||
| 43 | instead. This option enables this capability - it is very useful for | ||
| 44 | debugging and testing. | ||
| 45 | |||
| 46 | config MTD_UBI_DEBUG_EMULATE_BITFLIPS | 36 | config MTD_UBI_DEBUG_EMULATE_BITFLIPS |
| 47 | bool "Emulate flash bit-flips" | 37 | bool "Emulate flash bit-flips" |
| 48 | depends on MTD_UBI_DEBUG | 38 | depends on MTD_UBI_DEBUG |
diff --git a/drivers/mtd/ubi/cdev.c b/drivers/mtd/ubi/cdev.c index f9631eb3fef3..e63c8fc3df3a 100644 --- a/drivers/mtd/ubi/cdev.c +++ b/drivers/mtd/ubi/cdev.c | |||
| @@ -259,12 +259,9 @@ static ssize_t vol_cdev_read(struct file *file, __user char *buf, size_t count, | |||
| 259 | return err ? err : count_save - count; | 259 | return err ? err : count_save - count; |
| 260 | } | 260 | } |
| 261 | 261 | ||
| 262 | #ifdef CONFIG_MTD_UBI_DEBUG_USERSPACE_IO | ||
| 263 | |||
| 264 | /* | 262 | /* |
| 265 | * This function allows to directly write to dynamic UBI volumes, without | 263 | * This function allows to directly write to dynamic UBI volumes, without |
| 266 | * issuing the volume update operation. Available only as a debugging feature. | 264 | * issuing the volume update operation. |
| 267 | * Very useful for testing UBI. | ||
| 268 | */ | 265 | */ |
| 269 | static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, | 266 | static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, |
| 270 | size_t count, loff_t *offp) | 267 | size_t count, loff_t *offp) |
| @@ -276,6 +273,9 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, | |||
| 276 | size_t count_save = count; | 273 | size_t count_save = count; |
| 277 | char *tbuf; | 274 | char *tbuf; |
| 278 | 275 | ||
| 276 | if (!vol->direct_writes) | ||
| 277 | return -EPERM; | ||
| 278 | |||
| 279 | dbg_gen("requested: write %zd bytes to offset %lld of volume %u", | 279 | dbg_gen("requested: write %zd bytes to offset %lld of volume %u", |
| 280 | count, *offp, vol->vol_id); | 280 | count, *offp, vol->vol_id); |
| 281 | 281 | ||
| @@ -339,10 +339,6 @@ static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, | |||
| 339 | return err ? err : count_save - count; | 339 | return err ? err : count_save - count; |
| 340 | } | 340 | } |
| 341 | 341 | ||
| 342 | #else | ||
| 343 | #define vol_cdev_direct_write(file, buf, count, offp) (-EPERM) | ||
| 344 | #endif /* CONFIG_MTD_UBI_DEBUG_USERSPACE_IO */ | ||
| 345 | |||
| 346 | static ssize_t vol_cdev_write(struct file *file, const char __user *buf, | 342 | static ssize_t vol_cdev_write(struct file *file, const char __user *buf, |
| 347 | size_t count, loff_t *offp) | 343 | size_t count, loff_t *offp) |
| 348 | { | 344 | { |
| @@ -552,6 +548,30 @@ static long vol_cdev_ioctl(struct file *file, unsigned int cmd, | |||
| 552 | break; | 548 | break; |
| 553 | } | 549 | } |
| 554 | 550 | ||
| 551 | /* Set volume property command*/ | ||
| 552 | case UBI_IOCSETPROP: | ||
| 553 | { | ||
| 554 | struct ubi_set_prop_req req; | ||
| 555 | |||
| 556 | err = copy_from_user(&req, argp, | ||
| 557 | sizeof(struct ubi_set_prop_req)); | ||
| 558 | if (err) { | ||
| 559 | err = -EFAULT; | ||
| 560 | break; | ||
| 561 | } | ||
| 562 | switch (req.property) { | ||
| 563 | case UBI_PROP_DIRECT_WRITE: | ||
| 564 | mutex_lock(&ubi->volumes_mutex); | ||
| 565 | desc->vol->direct_writes = !!req.value; | ||
| 566 | mutex_unlock(&ubi->volumes_mutex); | ||
| 567 | break; | ||
| 568 | default: | ||
| 569 | err = -EINVAL; | ||
| 570 | break; | ||
| 571 | } | ||
| 572 | break; | ||
| 573 | } | ||
| 574 | |||
| 555 | default: | 575 | default: |
| 556 | err = -ENOTTY; | 576 | err = -ENOTTY; |
| 557 | break; | 577 | break; |
diff --git a/drivers/mtd/ubi/ubi.h b/drivers/mtd/ubi/ubi.h index 381f0e1d0a74..c055511bb1b2 100644 --- a/drivers/mtd/ubi/ubi.h +++ b/drivers/mtd/ubi/ubi.h | |||
| @@ -206,6 +206,7 @@ struct ubi_volume_desc; | |||
| 206 | * @upd_marker: %1 if the update marker is set for this volume | 206 | * @upd_marker: %1 if the update marker is set for this volume |
| 207 | * @updating: %1 if the volume is being updated | 207 | * @updating: %1 if the volume is being updated |
| 208 | * @changing_leb: %1 if the atomic LEB change ioctl command is in progress | 208 | * @changing_leb: %1 if the atomic LEB change ioctl command is in progress |
| 209 | * @direct_writes: %1 if direct writes are enabled for this volume | ||
| 209 | * | 210 | * |
| 210 | * @gluebi_desc: gluebi UBI volume descriptor | 211 | * @gluebi_desc: gluebi UBI volume descriptor |
| 211 | * @gluebi_refcount: reference count of the gluebi MTD device | 212 | * @gluebi_refcount: reference count of the gluebi MTD device |
| @@ -253,6 +254,7 @@ struct ubi_volume { | |||
| 253 | unsigned int upd_marker:1; | 254 | unsigned int upd_marker:1; |
| 254 | unsigned int updating:1; | 255 | unsigned int updating:1; |
| 255 | unsigned int changing_leb:1; | 256 | unsigned int changing_leb:1; |
| 257 | unsigned int direct_writes:1; | ||
| 256 | 258 | ||
| 257 | #ifdef CONFIG_MTD_UBI_GLUEBI | 259 | #ifdef CONFIG_MTD_UBI_GLUEBI |
| 258 | /* | 260 | /* |
| @@ -304,7 +306,8 @@ struct ubi_wl_entry; | |||
| 304 | * @vtbl_size: size of the volume table in bytes | 306 | * @vtbl_size: size of the volume table in bytes |
| 305 | * @vtbl: in-RAM volume table copy | 307 | * @vtbl: in-RAM volume table copy |
| 306 | * @volumes_mutex: protects on-flash volume table and serializes volume | 308 | * @volumes_mutex: protects on-flash volume table and serializes volume |
| 307 | * changes, like creation, deletion, update, re-size and re-name | 309 | * changes, like creation, deletion, update, re-size, |
| 310 | * re-name and set property | ||
| 308 | * | 311 | * |
| 309 | * @max_ec: current highest erase counter value | 312 | * @max_ec: current highest erase counter value |
| 310 | * @mean_ec: current mean erase counter value | 313 | * @mean_ec: current mean erase counter value |
diff --git a/include/mtd/ubi-user.h b/include/mtd/ubi-user.h index 82113e160a2c..296efae3525e 100644 --- a/include/mtd/ubi-user.h +++ b/include/mtd/ubi-user.h | |||
| @@ -124,6 +124,14 @@ | |||
| 124 | * To check if a logical eraseblock is mapped to a physical eraseblock, the | 124 | * To check if a logical eraseblock is mapped to a physical eraseblock, the |
| 125 | * %UBI_IOCEBISMAP ioctl command should be used. It returns %0 if the LEB is | 125 | * %UBI_IOCEBISMAP ioctl command should be used. It returns %0 if the LEB is |
| 126 | * not mapped, and %1 if it is mapped. | 126 | * not mapped, and %1 if it is mapped. |
| 127 | * | ||
| 128 | * Set an UBI volume property | ||
| 129 | * ~~~~~~~~~~~~~~~~~~~~~~~~~ | ||
| 130 | * | ||
| 131 | * To set an UBI volume property the %UBI_IOCSETPROP ioctl command should be | ||
| 132 | * used. A pointer to a &struct ubi_set_prop_req object is expected to be | ||
| 133 | * passed. The object describes which property should be set, and to which value | ||
| 134 | * it should be set. | ||
| 127 | */ | 135 | */ |
| 128 | 136 | ||
| 129 | /* | 137 | /* |
| @@ -175,6 +183,8 @@ | |||
| 175 | #define UBI_IOCEBUNMAP _IOW(UBI_VOL_IOC_MAGIC, 4, int32_t) | 183 | #define UBI_IOCEBUNMAP _IOW(UBI_VOL_IOC_MAGIC, 4, int32_t) |
| 176 | /* Check if LEB is mapped command */ | 184 | /* Check if LEB is mapped command */ |
| 177 | #define UBI_IOCEBISMAP _IOR(UBI_VOL_IOC_MAGIC, 5, int32_t) | 185 | #define UBI_IOCEBISMAP _IOR(UBI_VOL_IOC_MAGIC, 5, int32_t) |
| 186 | /* Set an UBI volume property */ | ||
| 187 | #define UBI_IOCSETPROP _IOW(UBI_VOL_IOC_MAGIC, 6, struct ubi_set_prop_req) | ||
| 178 | 188 | ||
| 179 | /* Maximum MTD device name length supported by UBI */ | 189 | /* Maximum MTD device name length supported by UBI */ |
| 180 | #define MAX_UBI_MTD_NAME_LEN 127 | 190 | #define MAX_UBI_MTD_NAME_LEN 127 |
| @@ -210,6 +220,16 @@ enum { | |||
| 210 | UBI_STATIC_VOLUME = 4, | 220 | UBI_STATIC_VOLUME = 4, |
| 211 | }; | 221 | }; |
| 212 | 222 | ||
| 223 | /* | ||
| 224 | * UBI set property ioctl constants | ||
| 225 | * | ||
| 226 | * @UBI_PROP_DIRECT_WRITE: allow / disallow user to directly write and | ||
| 227 | * erase individual eraseblocks on dynamic volumes | ||
| 228 | */ | ||
| 229 | enum { | ||
| 230 | UBI_PROP_DIRECT_WRITE = 1, | ||
| 231 | }; | ||
| 232 | |||
| 213 | /** | 233 | /** |
| 214 | * struct ubi_attach_req - attach MTD device request. | 234 | * struct ubi_attach_req - attach MTD device request. |
| 215 | * @ubi_num: UBI device number to create | 235 | * @ubi_num: UBI device number to create |
| @@ -373,4 +393,18 @@ struct ubi_map_req { | |||
| 373 | int8_t padding[3]; | 393 | int8_t padding[3]; |
| 374 | } __attribute__ ((packed)); | 394 | } __attribute__ ((packed)); |
| 375 | 395 | ||
| 396 | |||
| 397 | /** | ||
| 398 | * struct ubi_set_prop_req - a data structure used to set an ubi volume | ||
| 399 | * property. | ||
| 400 | * @property: property to set (%UBI_PROP_DIRECT_WRITE) | ||
| 401 | * @padding: reserved for future, not used, has to be zeroed | ||
| 402 | * @value: value to set | ||
| 403 | */ | ||
| 404 | struct ubi_set_prop_req { | ||
| 405 | uint8_t property; | ||
| 406 | uint8_t padding[7]; | ||
| 407 | uint64_t value; | ||
| 408 | } __attribute__ ((packed)); | ||
| 409 | |||
| 376 | #endif /* __UBI_USER_H__ */ | 410 | #endif /* __UBI_USER_H__ */ |
