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__ */ |