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
->vol_id
, lnum
, buf
, offs
,
139 total_read
-= to_read
;
143 *retlen
= len
- total_read
;
148 * gluebi_write - write operation of emulated MTD devices.
149 * @mtd: MTD device description object
150 * @to: absolute offset where to write
151 * @len: how many bytes to write
152 * @retlen: count of written bytes is returned here
153 * @buf: buffer with data to write
155 * This function returns zero in case of success and a negative error code in
158 static int gluebi_write(struct mtd_info
*mtd
, loff_t to
, size_t len
,
159 size_t *retlen
, const u_char
*buf
)
161 int err
= 0, lnum
, offs
, total_written
;
162 struct ubi_volume
*vol
;
163 struct ubi_device
*ubi
;
166 dbg_msg("write %zd bytes to offset %lld", len
, to
);
168 if (len
< 0 || to
< 0 || len
+ to
> mtd
->size
)
171 vol
= container_of(mtd
, struct ubi_volume
, gluebi_mtd
);
177 offs
= do_div(tmp
, mtd
->erasesize
);
180 if (len
% mtd
->writesize
|| offs
% mtd
->writesize
)
184 while (total_written
) {
185 size_t to_write
= mtd
->erasesize
- offs
;
187 if (to_write
> total_written
)
188 to_write
= total_written
;
190 err
= ubi_eba_write_leb(ubi
, vol
->vol_id
, lnum
, buf
, offs
,
191 to_write
, UBI_UNKNOWN
);
197 total_written
-= to_write
;
201 *retlen
= len
- total_written
;
206 * gluebi_erase - erase operation of emulated MTD devices.
207 * @mtd: the MTD device description object
208 * @instr: the erase operation description
210 * This function calls the erase callback when finishes. Returns zero in case
211 * of success and a negative error code in case of failure.
213 static int gluebi_erase(struct mtd_info
*mtd
, struct erase_info
*instr
)
215 int err
, i
, lnum
, count
;
216 struct ubi_volume
*vol
;
217 struct ubi_device
*ubi
;
219 dbg_msg("erase %u bytes at offset %u", instr
->len
, instr
->addr
);
221 if (instr
->addr
< 0 || instr
->addr
> mtd
->size
- mtd
->erasesize
)
224 if (instr
->len
< 0 || instr
->addr
+ instr
->len
> mtd
->size
)
227 if (instr
->addr
% mtd
->writesize
|| instr
->len
% mtd
->writesize
)
230 lnum
= instr
->addr
/ mtd
->erasesize
;
231 count
= instr
->len
/ mtd
->erasesize
;
233 vol
= container_of(mtd
, struct ubi_volume
, gluebi_mtd
);
239 for (i
= 0; i
< count
; i
++) {
240 err
= ubi_eba_unmap_leb(ubi
, vol
->vol_id
, lnum
+ i
);
246 * MTD erase operations are synchronous, so we have to make sure the
247 * physical eraseblock is wiped out.
249 err
= ubi_wl_flush(ubi
);
253 instr
->state
= MTD_ERASE_DONE
;
254 mtd_erase_callback(instr
);
258 instr
->state
= MTD_ERASE_FAILED
;
259 instr
->fail_addr
= lnum
* mtd
->erasesize
;
264 * ubi_create_gluebi - initialize gluebi for an UBI volume.
265 * @ubi: UBI device description object
266 * @vol: volume description object
268 * This function is called when an UBI volume is created in order to create
269 * corresponding fake MTD device. Returns zero in case of success and a
270 * negative error code in case of failure.
272 int ubi_create_gluebi(struct ubi_device
*ubi
, struct ubi_volume
*vol
)
274 struct mtd_info
*mtd
= &vol
->gluebi_mtd
;
276 mtd
->name
= kmemdup(vol
->name
, vol
->name_len
+ 1, GFP_KERNEL
);
280 mtd
->type
= MTD_UBIVOLUME
;
282 mtd
->flags
= MTD_WRITEABLE
;
283 mtd
->writesize
= ubi
->min_io_size
;
284 mtd
->owner
= THIS_MODULE
;
285 mtd
->erasesize
= vol
->usable_leb_size
;
286 mtd
->read
= gluebi_read
;
287 mtd
->write
= gluebi_write
;
288 mtd
->erase
= gluebi_erase
;
289 mtd
->get_device
= gluebi_get_device
;
290 mtd
->put_device
= gluebi_put_device
;
293 * In case of dynamic volume, MTD device size is just volume size. In
294 * case of a static volume the size is equivalent to the amount of data
295 * bytes, which is zero at this moment and will be changed after volume
298 if (vol
->vol_type
== UBI_DYNAMIC_VOLUME
)
299 mtd
->size
= vol
->usable_leb_size
* vol
->reserved_pebs
;
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
;