2 * Copyright (c) International Business Machines Corp., 2006
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
12 * the GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 * Author: Artem Bityutskiy (Битюцкий Артём), Joern Engel
22 * This file includes implementation of fake MTD devices for each UBI volume.
23 * This sounds strange, but it is in fact quite useful to make MTD-oriented
24 * software (including all the legacy software) to work on top of UBI.
26 * Gluebi emulates MTD devices of "MTD_UBIVOLUME" type. Their minimal I/O unit
27 * size (mtd->writesize) is equivalent to the UBI minimal I/O unit. The
28 * eraseblock size is equivalent to the logical eraseblock size of the volume.
31 #include <asm/div64.h>
35 * gluebi_get_device - get MTD device reference.
36 * @mtd: the MTD device description object
38 * This function is called every time the MTD device is being opened and
39 * implements the MTD get_device() operation. Returns zero in case of success
40 * and a negative error code in case of failure.
42 static int gluebi_get_device(struct mtd_info
*mtd
)
44 struct ubi_volume
*vol
;
46 vol
= container_of(mtd
, struct ubi_volume
, gluebi_mtd
);
49 * We do not introduce locks for gluebi reference count because the
50 * get_device()/put_device() calls are already serialized at MTD.
52 if (vol
->gluebi_refcount
> 0) {
54 * The MTD device is already referenced and this is just one
55 * more reference. MTD allows many users to open the same
56 * volume simultaneously and do not distinguish between
57 * readers/writers/exclusive openers as UBI does. So we do not
58 * open the UBI volume again - just increase the reference
61 vol
->gluebi_refcount
+= 1;
66 * This is the first reference to this UBI volume via the MTD device
67 * interface. Open the corresponding volume in read-write mode.
69 vol
->gluebi_desc
= ubi_open_volume(vol
->ubi
->ubi_num
, vol
->vol_id
,
71 if (IS_ERR(vol
->gluebi_desc
))
72 return PTR_ERR(vol
->gluebi_desc
);
73 vol
->gluebi_refcount
+= 1;
78 * gluebi_put_device - put MTD device reference.
79 * @mtd: the MTD device description object
81 * This function is called every time the MTD device is being put. Returns
82 * zero in case of success and a negative error code in case of failure.
84 static void gluebi_put_device(struct mtd_info
*mtd
)
86 struct ubi_volume
*vol
;
88 vol
= container_of(mtd
, struct ubi_volume
, gluebi_mtd
);
89 vol
->gluebi_refcount
-= 1;
90 ubi_assert(vol
->gluebi_refcount
>= 0);
91 if (vol
->gluebi_refcount
== 0)
92 ubi_close_volume(vol
->gluebi_desc
);
96 * gluebi_read - read operation of emulated MTD devices.
97 * @mtd: MTD device description object
98 * @from: absolute offset from where to read
99 * @len: how many bytes to read
100 * @retlen: count of read bytes is returned here
101 * @buf: buffer to store the read data
103 * This function returns zero in case of success and a negative error code in
106 static int gluebi_read(struct mtd_info
*mtd
, loff_t from
, size_t len
,
107 size_t *retlen
, unsigned char *buf
)
109 int err
= 0, lnum
, offs
, total_read
;
110 struct ubi_volume
*vol
;
111 struct ubi_device
*ubi
;
114 dbg_msg("read %zd bytes from offset %lld", len
, from
);
116 if (len
< 0 || from
< 0 || from
+ len
> mtd
->size
)
119 vol
= container_of(mtd
, struct ubi_volume
, gluebi_mtd
);
122 offs
= do_div(tmp
, mtd
->erasesize
);
127 size_t to_read
= mtd
->erasesize
- offs
;
129 if (to_read
> total_read
)
130 to_read
= total_read
;
132 err
= ubi_eba_read_leb(ubi
, vol
, lnum
, buf
, offs
, to_read
, 0);
138 total_read
-= to_read
;
142 *retlen
= len
- total_read
;
147 * gluebi_write - write operation of emulated MTD devices.
148 * @mtd: MTD device description object
149 * @to: absolute offset where to write
150 * @len: how many bytes to write
151 * @retlen: count of written bytes is returned here
152 * @buf: buffer with data to write
154 * This function returns zero in case of success and a negative error code in
157 static int gluebi_write(struct mtd_info
*mtd
, loff_t to
, size_t len
,
158 size_t *retlen
, const u_char
*buf
)
160 int err
= 0, lnum
, offs
, total_written
;
161 struct ubi_volume
*vol
;
162 struct ubi_device
*ubi
;
165 dbg_msg("write %zd bytes to offset %lld", len
, to
);
167 if (len
< 0 || to
< 0 || len
+ to
> mtd
->size
)
170 vol
= container_of(mtd
, struct ubi_volume
, gluebi_mtd
);
176 offs
= do_div(tmp
, mtd
->erasesize
);
179 if (len
% mtd
->writesize
|| offs
% mtd
->writesize
)
183 while (total_written
) {
184 size_t to_write
= mtd
->erasesize
- offs
;
186 if (to_write
> total_written
)
187 to_write
= total_written
;
189 err
= ubi_eba_write_leb(ubi
, vol
, lnum
, buf
, offs
, to_write
,
196 total_written
-= to_write
;
200 *retlen
= len
- total_written
;
205 * gluebi_erase - erase operation of emulated MTD devices.
206 * @mtd: the MTD device description object
207 * @instr: the erase operation description
209 * This function calls the erase callback when finishes. Returns zero in case
210 * of success and a negative error code in case of failure.
212 static int gluebi_erase(struct mtd_info
*mtd
, struct erase_info
*instr
)
214 int err
, i
, lnum
, count
;
215 struct ubi_volume
*vol
;
216 struct ubi_device
*ubi
;
218 dbg_msg("erase %u bytes at offset %u", instr
->len
, instr
->addr
);
220 if (instr
->addr
< 0 || instr
->addr
> mtd
->size
- mtd
->erasesize
)
223 if (instr
->len
< 0 || instr
->addr
+ instr
->len
> mtd
->size
)
226 if (instr
->addr
% mtd
->writesize
|| instr
->len
% mtd
->writesize
)
229 lnum
= instr
->addr
/ mtd
->erasesize
;
230 count
= instr
->len
/ mtd
->erasesize
;
232 vol
= container_of(mtd
, struct ubi_volume
, gluebi_mtd
);
238 for (i
= 0; i
< count
; i
++) {
239 err
= ubi_eba_unmap_leb(ubi
, vol
, lnum
+ i
);
245 * MTD erase operations are synchronous, so we have to make sure the
246 * physical eraseblock is wiped out.
248 err
= ubi_wl_flush(ubi
);
252 instr
->state
= MTD_ERASE_DONE
;
253 mtd_erase_callback(instr
);
257 instr
->state
= MTD_ERASE_FAILED
;
258 instr
->fail_addr
= lnum
* mtd
->erasesize
;
263 * ubi_create_gluebi - initialize gluebi for an UBI volume.
264 * @ubi: UBI device description object
265 * @vol: volume description object
267 * This function is called when an UBI volume is created in order to create
268 * corresponding fake MTD device. Returns zero in case of success and a
269 * negative error code in case of failure.
271 int ubi_create_gluebi(struct ubi_device
*ubi
, struct ubi_volume
*vol
)
273 struct mtd_info
*mtd
= &vol
->gluebi_mtd
;
275 mtd
->name
= kmemdup(vol
->name
, vol
->name_len
+ 1, GFP_KERNEL
);
279 mtd
->type
= MTD_UBIVOLUME
;
281 mtd
->flags
= MTD_WRITEABLE
;
282 mtd
->writesize
= ubi
->min_io_size
;
283 mtd
->owner
= THIS_MODULE
;
284 mtd
->erasesize
= vol
->usable_leb_size
;
285 mtd
->read
= gluebi_read
;
286 mtd
->write
= gluebi_write
;
287 mtd
->erase
= gluebi_erase
;
288 mtd
->get_device
= gluebi_get_device
;
289 mtd
->put_device
= gluebi_put_device
;
292 * In case of dynamic volume, MTD device size is just volume size. In
293 * case of a static volume the size is equivalent to the amount of data
296 if (vol
->vol_type
== UBI_DYNAMIC_VOLUME
)
297 mtd
->size
= vol
->usable_leb_size
* vol
->reserved_pebs
;
299 mtd
->size
= vol
->used_bytes
;
301 if (add_mtd_device(mtd
)) {
302 ubi_err("cannot not add MTD device\n");
307 dbg_msg("added mtd%d (\"%s\"), size %u, EB size %u",
308 mtd
->index
, mtd
->name
, mtd
->size
, mtd
->erasesize
);
313 * ubi_destroy_gluebi - close gluebi for an UBI volume.
314 * @vol: volume description object
316 * This function is called when an UBI volume is removed in order to remove
317 * corresponding fake MTD device. Returns zero in case of success and a
318 * negative error code in case of failure.
320 int ubi_destroy_gluebi(struct ubi_volume
*vol
)
323 struct mtd_info
*mtd
= &vol
->gluebi_mtd
;
325 dbg_msg("remove mtd%d", mtd
->index
);
326 err
= del_mtd_device(mtd
);
334 * ubi_gluebi_updated - UBI volume was updated notifier.
335 * @vol: volume description object
337 * This function is called every time an UBI volume is updated. This function
338 * does nothing if volume @vol is dynamic, and changes MTD device size if the
339 * volume is static. This is needed because static volumes cannot be read past
342 void ubi_gluebi_updated(struct ubi_volume
*vol
)
344 struct mtd_info
*mtd
= &vol
->gluebi_mtd
;
346 if (vol
->vol_type
== UBI_STATIC_VOLUME
)
347 mtd
->size
= vol
->used_bytes
;