aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSidney Amani <seed@uffs.org>2009-01-27 04:11:46 -0500
committerArtem Bityutskiy <Artem.Bityutskiy@nokia.com>2009-01-27 09:54:41 -0500
commit766fb95ba06e1bbf531d30dc05e21b2d4a0e8dd2 (patch)
treea7041e919ca5f6d5460b7d7ecfb27e08b9119236
parent36b477d005fbda29e7581c3cef7ee31a59d8970b (diff)
UBI: allow direct user-space I/O
Introduce a new ioctl UBI_IOCSETPROP to set properties on a volume. Also add the first property: UBI_PROP_DIRECT_WRITE, this property is used to set the ability to use direct writes in userspace Signed-off-by: Sidney Amani <seed@uffs.org> Signed-off-by: Corentin Chary <corentincj@iksaif.net> Signed-off-by: Artem Bityutskiy <Artem.Bityutskiy@nokia.com>
-rw-r--r--drivers/mtd/ubi/Kconfig.debug10
-rw-r--r--drivers/mtd/ubi/cdev.c36
-rw-r--r--drivers/mtd/ubi/ubi.h5
-rw-r--r--include/mtd/ubi-user.h34
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
36config 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
46config MTD_UBI_DEBUG_EMULATE_BITFLIPS 36config 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 */
269static ssize_t vol_cdev_direct_write(struct file *file, const char __user *buf, 266static 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
346static ssize_t vol_cdev_write(struct file *file, const char __user *buf, 342static 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 */
229enum {
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 */
404struct 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__ */