diff options
Diffstat (limited to 'drivers/mtd/ubi/build.c')
-rw-r--r-- | drivers/mtd/ubi/build.c | 848 |
1 files changed, 848 insertions, 0 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c new file mode 100644 index 000000000000..555d594d1811 --- /dev/null +++ b/drivers/mtd/ubi/build.c | |||
@@ -0,0 +1,848 @@ | |||
1 | /* | ||
2 | * Copyright (c) International Business Machines Corp., 2006 | ||
3 | * Copyright (c) Nokia Corporation, 2007 | ||
4 | * | ||
5 | * This program is free software; you can redistribute it and/or modify | ||
6 | * it under the terms of the GNU General Public License as published by | ||
7 | * the Free Software Foundation; either version 2 of the License, or | ||
8 | * (at your option) any later version. | ||
9 | * | ||
10 | * This program is distributed in the hope that it will be useful, | ||
11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See | ||
13 | * the GNU General Public License for more details. | ||
14 | * | ||
15 | * You should have received a copy of the GNU General Public License | ||
16 | * along with this program; if not, write to the Free Software | ||
17 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
18 | * | ||
19 | * Author: Artem Bityutskiy (Битюцкий Артём), | ||
20 | * Frank Haverkamp | ||
21 | */ | ||
22 | |||
23 | /* | ||
24 | * This file includes UBI initialization and building of UBI devices. At the | ||
25 | * moment UBI devices may only be added while UBI is initialized, but dynamic | ||
26 | * device add/remove functionality is planned. Also, at the moment we only | ||
27 | * attach UBI devices by scanning, which will become a bottleneck when flashes | ||
28 | * reach certain large size. Then one may improve UBI and add other methods. | ||
29 | */ | ||
30 | |||
31 | #include <linux/err.h> | ||
32 | #include <linux/module.h> | ||
33 | #include <linux/moduleparam.h> | ||
34 | #include <linux/stringify.h> | ||
35 | #include <linux/stat.h> | ||
36 | #include "ubi.h" | ||
37 | |||
38 | /* Maximum length of the 'mtd=' parameter */ | ||
39 | #define MTD_PARAM_LEN_MAX 64 | ||
40 | |||
41 | /** | ||
42 | * struct mtd_dev_param - MTD device parameter description data structure. | ||
43 | * @name: MTD device name or number string | ||
44 | * @vid_hdr_offs: VID header offset | ||
45 | * @data_offs: data offset | ||
46 | */ | ||
47 | struct mtd_dev_param | ||
48 | { | ||
49 | char name[MTD_PARAM_LEN_MAX]; | ||
50 | int vid_hdr_offs; | ||
51 | int data_offs; | ||
52 | }; | ||
53 | |||
54 | /* Numbers of elements set in the @mtd_dev_param array */ | ||
55 | static int mtd_devs = 0; | ||
56 | |||
57 | /* MTD devices specification parameters */ | ||
58 | static struct mtd_dev_param mtd_dev_param[UBI_MAX_DEVICES]; | ||
59 | |||
60 | /* Number of UBI devices in system */ | ||
61 | int ubi_devices_cnt; | ||
62 | |||
63 | /* All UBI devices in system */ | ||
64 | struct ubi_device *ubi_devices[UBI_MAX_DEVICES]; | ||
65 | |||
66 | /* Root UBI "class" object (corresponds to '/<sysfs>/class/ubi/') */ | ||
67 | struct class *ubi_class; | ||
68 | |||
69 | /* "Show" method for files in '/<sysfs>/class/ubi/' */ | ||
70 | static ssize_t ubi_version_show(struct class *class, char *buf) | ||
71 | { | ||
72 | return sprintf(buf, "%d\n", UBI_VERSION); | ||
73 | } | ||
74 | |||
75 | /* UBI version attribute ('/<sysfs>/class/ubi/version') */ | ||
76 | static struct class_attribute ubi_version = | ||
77 | __ATTR(version, S_IRUGO, ubi_version_show, NULL); | ||
78 | |||
79 | static ssize_t dev_attribute_show(struct device *dev, | ||
80 | struct device_attribute *attr, char *buf); | ||
81 | |||
82 | /* UBI device attributes (correspond to files in '/<sysfs>/class/ubi/ubiX') */ | ||
83 | static struct device_attribute dev_eraseblock_size = | ||
84 | __ATTR(eraseblock_size, S_IRUGO, dev_attribute_show, NULL); | ||
85 | static struct device_attribute dev_avail_eraseblocks = | ||
86 | __ATTR(avail_eraseblocks, S_IRUGO, dev_attribute_show, NULL); | ||
87 | static struct device_attribute dev_total_eraseblocks = | ||
88 | __ATTR(total_eraseblocks, S_IRUGO, dev_attribute_show, NULL); | ||
89 | static struct device_attribute dev_volumes_count = | ||
90 | __ATTR(volumes_count, S_IRUGO, dev_attribute_show, NULL); | ||
91 | static struct device_attribute dev_max_ec = | ||
92 | __ATTR(max_ec, S_IRUGO, dev_attribute_show, NULL); | ||
93 | static struct device_attribute dev_reserved_for_bad = | ||
94 | __ATTR(reserved_for_bad, S_IRUGO, dev_attribute_show, NULL); | ||
95 | static struct device_attribute dev_bad_peb_count = | ||
96 | __ATTR(bad_peb_count, S_IRUGO, dev_attribute_show, NULL); | ||
97 | static struct device_attribute dev_max_vol_count = | ||
98 | __ATTR(max_vol_count, S_IRUGO, dev_attribute_show, NULL); | ||
99 | static struct device_attribute dev_min_io_size = | ||
100 | __ATTR(min_io_size, S_IRUGO, dev_attribute_show, NULL); | ||
101 | static struct device_attribute dev_bgt_enabled = | ||
102 | __ATTR(bgt_enabled, S_IRUGO, dev_attribute_show, NULL); | ||
103 | |||
104 | /* "Show" method for files in '/<sysfs>/class/ubi/ubiX/' */ | ||
105 | static ssize_t dev_attribute_show(struct device *dev, | ||
106 | struct device_attribute *attr, char *buf) | ||
107 | { | ||
108 | const struct ubi_device *ubi; | ||
109 | |||
110 | ubi = container_of(dev, struct ubi_device, dev); | ||
111 | if (attr == &dev_eraseblock_size) | ||
112 | return sprintf(buf, "%d\n", ubi->leb_size); | ||
113 | else if (attr == &dev_avail_eraseblocks) | ||
114 | return sprintf(buf, "%d\n", ubi->avail_pebs); | ||
115 | else if (attr == &dev_total_eraseblocks) | ||
116 | return sprintf(buf, "%d\n", ubi->good_peb_count); | ||
117 | else if (attr == &dev_volumes_count) | ||
118 | return sprintf(buf, "%d\n", ubi->vol_count); | ||
119 | else if (attr == &dev_max_ec) | ||
120 | return sprintf(buf, "%d\n", ubi->max_ec); | ||
121 | else if (attr == &dev_reserved_for_bad) | ||
122 | return sprintf(buf, "%d\n", ubi->beb_rsvd_pebs); | ||
123 | else if (attr == &dev_bad_peb_count) | ||
124 | return sprintf(buf, "%d\n", ubi->bad_peb_count); | ||
125 | else if (attr == &dev_max_vol_count) | ||
126 | return sprintf(buf, "%d\n", ubi->vtbl_slots); | ||
127 | else if (attr == &dev_min_io_size) | ||
128 | return sprintf(buf, "%d\n", ubi->min_io_size); | ||
129 | else if (attr == &dev_bgt_enabled) | ||
130 | return sprintf(buf, "%d\n", ubi->thread_enabled); | ||
131 | else | ||
132 | BUG(); | ||
133 | |||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | /* Fake "release" method for UBI devices */ | ||
138 | static void dev_release(struct device *dev) { } | ||
139 | |||
140 | /** | ||
141 | * ubi_sysfs_init - initialize sysfs for an UBI device. | ||
142 | * @ubi: UBI device description object | ||
143 | * | ||
144 | * This function returns zero in case of success and a negative error code in | ||
145 | * case of failure. | ||
146 | */ | ||
147 | static int ubi_sysfs_init(struct ubi_device *ubi) | ||
148 | { | ||
149 | int err; | ||
150 | |||
151 | ubi->dev.release = dev_release; | ||
152 | ubi->dev.devt = MKDEV(ubi->major, 0); | ||
153 | ubi->dev.class = ubi_class; | ||
154 | sprintf(&ubi->dev.bus_id[0], UBI_NAME_STR"%d", ubi->ubi_num); | ||
155 | err = device_register(&ubi->dev); | ||
156 | if (err) | ||
157 | goto out; | ||
158 | |||
159 | err = device_create_file(&ubi->dev, &dev_eraseblock_size); | ||
160 | if (err) | ||
161 | goto out_unregister; | ||
162 | err = device_create_file(&ubi->dev, &dev_avail_eraseblocks); | ||
163 | if (err) | ||
164 | goto out_eraseblock_size; | ||
165 | err = device_create_file(&ubi->dev, &dev_total_eraseblocks); | ||
166 | if (err) | ||
167 | goto out_avail_eraseblocks; | ||
168 | err = device_create_file(&ubi->dev, &dev_volumes_count); | ||
169 | if (err) | ||
170 | goto out_total_eraseblocks; | ||
171 | err = device_create_file(&ubi->dev, &dev_max_ec); | ||
172 | if (err) | ||
173 | goto out_volumes_count; | ||
174 | err = device_create_file(&ubi->dev, &dev_reserved_for_bad); | ||
175 | if (err) | ||
176 | goto out_volumes_max_ec; | ||
177 | err = device_create_file(&ubi->dev, &dev_bad_peb_count); | ||
178 | if (err) | ||
179 | goto out_reserved_for_bad; | ||
180 | err = device_create_file(&ubi->dev, &dev_max_vol_count); | ||
181 | if (err) | ||
182 | goto out_bad_peb_count; | ||
183 | err = device_create_file(&ubi->dev, &dev_min_io_size); | ||
184 | if (err) | ||
185 | goto out_max_vol_count; | ||
186 | err = device_create_file(&ubi->dev, &dev_bgt_enabled); | ||
187 | if (err) | ||
188 | goto out_min_io_size; | ||
189 | |||
190 | return 0; | ||
191 | |||
192 | out_min_io_size: | ||
193 | device_remove_file(&ubi->dev, &dev_min_io_size); | ||
194 | out_max_vol_count: | ||
195 | device_remove_file(&ubi->dev, &dev_max_vol_count); | ||
196 | out_bad_peb_count: | ||
197 | device_remove_file(&ubi->dev, &dev_bad_peb_count); | ||
198 | out_reserved_for_bad: | ||
199 | device_remove_file(&ubi->dev, &dev_reserved_for_bad); | ||
200 | out_volumes_max_ec: | ||
201 | device_remove_file(&ubi->dev, &dev_max_ec); | ||
202 | out_volumes_count: | ||
203 | device_remove_file(&ubi->dev, &dev_volumes_count); | ||
204 | out_total_eraseblocks: | ||
205 | device_remove_file(&ubi->dev, &dev_total_eraseblocks); | ||
206 | out_avail_eraseblocks: | ||
207 | device_remove_file(&ubi->dev, &dev_avail_eraseblocks); | ||
208 | out_eraseblock_size: | ||
209 | device_remove_file(&ubi->dev, &dev_eraseblock_size); | ||
210 | out_unregister: | ||
211 | device_unregister(&ubi->dev); | ||
212 | out: | ||
213 | ubi_err("failed to initialize sysfs for %s", ubi->ubi_name); | ||
214 | return err; | ||
215 | } | ||
216 | |||
217 | /** | ||
218 | * ubi_sysfs_close - close sysfs for an UBI device. | ||
219 | * @ubi: UBI device description object | ||
220 | */ | ||
221 | static void ubi_sysfs_close(struct ubi_device *ubi) | ||
222 | { | ||
223 | device_remove_file(&ubi->dev, &dev_bgt_enabled); | ||
224 | device_remove_file(&ubi->dev, &dev_min_io_size); | ||
225 | device_remove_file(&ubi->dev, &dev_max_vol_count); | ||
226 | device_remove_file(&ubi->dev, &dev_bad_peb_count); | ||
227 | device_remove_file(&ubi->dev, &dev_reserved_for_bad); | ||
228 | device_remove_file(&ubi->dev, &dev_max_ec); | ||
229 | device_remove_file(&ubi->dev, &dev_volumes_count); | ||
230 | device_remove_file(&ubi->dev, &dev_total_eraseblocks); | ||
231 | device_remove_file(&ubi->dev, &dev_avail_eraseblocks); | ||
232 | device_remove_file(&ubi->dev, &dev_eraseblock_size); | ||
233 | device_unregister(&ubi->dev); | ||
234 | } | ||
235 | |||
236 | /** | ||
237 | * kill_volumes - destroy all volumes. | ||
238 | * @ubi: UBI device description object | ||
239 | */ | ||
240 | static void kill_volumes(struct ubi_device *ubi) | ||
241 | { | ||
242 | int i; | ||
243 | |||
244 | for (i = 0; i < ubi->vtbl_slots; i++) | ||
245 | if (ubi->volumes[i]) | ||
246 | ubi_free_volume(ubi, i); | ||
247 | } | ||
248 | |||
249 | /** | ||
250 | * uif_init - initialize user interfaces for an UBI device. | ||
251 | * @ubi: UBI device description object | ||
252 | * | ||
253 | * This function returns zero in case of success and a negative error code in | ||
254 | * case of failure. | ||
255 | */ | ||
256 | static int uif_init(struct ubi_device *ubi) | ||
257 | { | ||
258 | int i, err; | ||
259 | dev_t dev; | ||
260 | |||
261 | mutex_init(&ubi->vtbl_mutex); | ||
262 | spin_lock_init(&ubi->volumes_lock); | ||
263 | |||
264 | sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); | ||
265 | |||
266 | /* | ||
267 | * Major numbers for the UBI character devices are allocated | ||
268 | * dynamically. Major numbers of volume character devices are | ||
269 | * equivalent to ones of the corresponding UBI character device. Minor | ||
270 | * numbers of UBI character devices are 0, while minor numbers of | ||
271 | * volume character devices start from 1. Thus, we allocate one major | ||
272 | * number and ubi->vtbl_slots + 1 minor numbers. | ||
273 | */ | ||
274 | err = alloc_chrdev_region(&dev, 0, ubi->vtbl_slots + 1, ubi->ubi_name); | ||
275 | if (err) { | ||
276 | ubi_err("cannot register UBI character devices"); | ||
277 | return err; | ||
278 | } | ||
279 | |||
280 | cdev_init(&ubi->cdev, &ubi_cdev_operations); | ||
281 | ubi->major = MAJOR(dev); | ||
282 | dbg_msg("%s major is %u", ubi->ubi_name, ubi->major); | ||
283 | ubi->cdev.owner = THIS_MODULE; | ||
284 | |||
285 | dev = MKDEV(ubi->major, 0); | ||
286 | err = cdev_add(&ubi->cdev, dev, 1); | ||
287 | if (err) { | ||
288 | ubi_err("cannot add character device %s", ubi->ubi_name); | ||
289 | goto out_unreg; | ||
290 | } | ||
291 | |||
292 | err = ubi_sysfs_init(ubi); | ||
293 | if (err) | ||
294 | goto out_cdev; | ||
295 | |||
296 | for (i = 0; i < ubi->vtbl_slots; i++) | ||
297 | if (ubi->volumes[i]) { | ||
298 | err = ubi_add_volume(ubi, i); | ||
299 | if (err) | ||
300 | goto out_volumes; | ||
301 | } | ||
302 | |||
303 | return 0; | ||
304 | |||
305 | out_volumes: | ||
306 | kill_volumes(ubi); | ||
307 | ubi_sysfs_close(ubi); | ||
308 | out_cdev: | ||
309 | cdev_del(&ubi->cdev); | ||
310 | out_unreg: | ||
311 | unregister_chrdev_region(MKDEV(ubi->major, 0), | ||
312 | ubi->vtbl_slots + 1); | ||
313 | return err; | ||
314 | } | ||
315 | |||
316 | /** | ||
317 | * uif_close - close user interfaces for an UBI device. | ||
318 | * @ubi: UBI device description object | ||
319 | */ | ||
320 | static void uif_close(struct ubi_device *ubi) | ||
321 | { | ||
322 | kill_volumes(ubi); | ||
323 | ubi_sysfs_close(ubi); | ||
324 | cdev_del(&ubi->cdev); | ||
325 | unregister_chrdev_region(MKDEV(ubi->major, 0), ubi->vtbl_slots + 1); | ||
326 | } | ||
327 | |||
328 | /** | ||
329 | * attach_by_scanning - attach an MTD device using scanning method. | ||
330 | * @ubi: UBI device descriptor | ||
331 | * | ||
332 | * This function returns zero in case of success and a negative error code in | ||
333 | * case of failure. | ||
334 | * | ||
335 | * Note, currently this is the only method to attach UBI devices. Hopefully in | ||
336 | * the future we'll have more scalable attaching methods and avoid full media | ||
337 | * scanning. But even in this case scanning will be needed as a fall-back | ||
338 | * attaching method if there are some on-flash table corruptions. | ||
339 | */ | ||
340 | static int attach_by_scanning(struct ubi_device *ubi) | ||
341 | { | ||
342 | int err; | ||
343 | struct ubi_scan_info *si; | ||
344 | |||
345 | si = ubi_scan(ubi); | ||
346 | if (IS_ERR(si)) | ||
347 | return PTR_ERR(si); | ||
348 | |||
349 | ubi->bad_peb_count = si->bad_peb_count; | ||
350 | ubi->good_peb_count = ubi->peb_count - ubi->bad_peb_count; | ||
351 | ubi->max_ec = si->max_ec; | ||
352 | ubi->mean_ec = si->mean_ec; | ||
353 | |||
354 | err = ubi_read_volume_table(ubi, si); | ||
355 | if (err) | ||
356 | goto out_si; | ||
357 | |||
358 | err = ubi_wl_init_scan(ubi, si); | ||
359 | if (err) | ||
360 | goto out_vtbl; | ||
361 | |||
362 | err = ubi_eba_init_scan(ubi, si); | ||
363 | if (err) | ||
364 | goto out_wl; | ||
365 | |||
366 | ubi_scan_destroy_si(si); | ||
367 | return 0; | ||
368 | |||
369 | out_wl: | ||
370 | ubi_wl_close(ubi); | ||
371 | out_vtbl: | ||
372 | kfree(ubi->vtbl); | ||
373 | out_si: | ||
374 | ubi_scan_destroy_si(si); | ||
375 | return err; | ||
376 | } | ||
377 | |||
378 | /** | ||
379 | * io_init - initialize I/O unit for a given UBI device. | ||
380 | * @ubi: UBI device description object | ||
381 | * | ||
382 | * If @ubi->vid_hdr_offset or @ubi->leb_start is zero, default offsets are | ||
383 | * assumed: | ||
384 | * o EC header is always at offset zero - this cannot be changed; | ||
385 | * o VID header starts just after the EC header at the closest address | ||
386 | * aligned to @io->@hdrs_min_io_size; | ||
387 | * o data starts just after the VID header at the closest address aligned to | ||
388 | * @io->@min_io_size | ||
389 | * | ||
390 | * This function returns zero in case of success and a negative error code in | ||
391 | * case of failure. | ||
392 | */ | ||
393 | static int io_init(struct ubi_device *ubi) | ||
394 | { | ||
395 | if (ubi->mtd->numeraseregions != 0) { | ||
396 | /* | ||
397 | * Some flashes have several erase regions. Different regions | ||
398 | * may have different eraseblock size and other | ||
399 | * characteristics. It looks like mostly multi-region flashes | ||
400 | * have one "main" region and one or more small regions to | ||
401 | * store boot loader code or boot parameters or whatever. I | ||
402 | * guess we should just pick the largest region. But this is | ||
403 | * not implemented. | ||
404 | */ | ||
405 | ubi_err("multiple regions, not implemented"); | ||
406 | return -EINVAL; | ||
407 | } | ||
408 | |||
409 | /* | ||
410 | * Note, in this implementation we support MTD devices with 0x7FFFFFFF | ||
411 | * physical eraseblocks maximum. | ||
412 | */ | ||
413 | |||
414 | ubi->peb_size = ubi->mtd->erasesize; | ||
415 | ubi->peb_count = ubi->mtd->size / ubi->mtd->erasesize; | ||
416 | ubi->flash_size = ubi->mtd->size; | ||
417 | |||
418 | if (ubi->mtd->block_isbad && ubi->mtd->block_markbad) | ||
419 | ubi->bad_allowed = 1; | ||
420 | |||
421 | ubi->min_io_size = ubi->mtd->writesize; | ||
422 | ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; | ||
423 | |||
424 | /* Make sure minimal I/O unit is power of 2 */ | ||
425 | if (ubi->min_io_size == 0 || | ||
426 | (ubi->min_io_size & (ubi->min_io_size - 1))) { | ||
427 | ubi_err("bad min. I/O unit"); | ||
428 | return -EINVAL; | ||
429 | } | ||
430 | |||
431 | ubi_assert(ubi->hdrs_min_io_size > 0); | ||
432 | ubi_assert(ubi->hdrs_min_io_size <= ubi->min_io_size); | ||
433 | ubi_assert(ubi->min_io_size % ubi->hdrs_min_io_size == 0); | ||
434 | |||
435 | /* Calculate default aligned sizes of EC and VID headers */ | ||
436 | ubi->ec_hdr_alsize = ALIGN(UBI_EC_HDR_SIZE, ubi->hdrs_min_io_size); | ||
437 | ubi->vid_hdr_alsize = ALIGN(UBI_VID_HDR_SIZE, ubi->hdrs_min_io_size); | ||
438 | |||
439 | dbg_msg("min_io_size %d", ubi->min_io_size); | ||
440 | dbg_msg("hdrs_min_io_size %d", ubi->hdrs_min_io_size); | ||
441 | dbg_msg("ec_hdr_alsize %d", ubi->ec_hdr_alsize); | ||
442 | dbg_msg("vid_hdr_alsize %d", ubi->vid_hdr_alsize); | ||
443 | |||
444 | if (ubi->vid_hdr_offset == 0) | ||
445 | /* Default offset */ | ||
446 | ubi->vid_hdr_offset = ubi->vid_hdr_aloffset = | ||
447 | ubi->ec_hdr_alsize; | ||
448 | else { | ||
449 | ubi->vid_hdr_aloffset = ubi->vid_hdr_offset & | ||
450 | ~(ubi->hdrs_min_io_size - 1); | ||
451 | ubi->vid_hdr_shift = ubi->vid_hdr_offset - | ||
452 | ubi->vid_hdr_aloffset; | ||
453 | } | ||
454 | |||
455 | /* Similar for the data offset */ | ||
456 | if (ubi->leb_start == 0) { | ||
457 | ubi->leb_start = ubi->vid_hdr_offset + ubi->vid_hdr_alsize; | ||
458 | ubi->leb_start = ALIGN(ubi->leb_start, ubi->min_io_size); | ||
459 | } | ||
460 | |||
461 | dbg_msg("vid_hdr_offset %d", ubi->vid_hdr_offset); | ||
462 | dbg_msg("vid_hdr_aloffset %d", ubi->vid_hdr_aloffset); | ||
463 | dbg_msg("vid_hdr_shift %d", ubi->vid_hdr_shift); | ||
464 | dbg_msg("leb_start %d", ubi->leb_start); | ||
465 | |||
466 | /* The shift must be aligned to 32-bit boundary */ | ||
467 | if (ubi->vid_hdr_shift % 4) { | ||
468 | ubi_err("unaligned VID header shift %d", | ||
469 | ubi->vid_hdr_shift); | ||
470 | return -EINVAL; | ||
471 | } | ||
472 | |||
473 | /* Check sanity */ | ||
474 | if (ubi->vid_hdr_offset < UBI_EC_HDR_SIZE || | ||
475 | ubi->leb_start < ubi->vid_hdr_offset + UBI_VID_HDR_SIZE || | ||
476 | ubi->leb_start > ubi->peb_size - UBI_VID_HDR_SIZE || | ||
477 | ubi->leb_start % ubi->min_io_size) { | ||
478 | ubi_err("bad VID header (%d) or data offsets (%d)", | ||
479 | ubi->vid_hdr_offset, ubi->leb_start); | ||
480 | return -EINVAL; | ||
481 | } | ||
482 | |||
483 | /* | ||
484 | * It may happen that EC and VID headers are situated in one minimal | ||
485 | * I/O unit. In this case we can only accept this UBI image in | ||
486 | * read-only mode. | ||
487 | */ | ||
488 | if (ubi->vid_hdr_offset + UBI_VID_HDR_SIZE <= ubi->hdrs_min_io_size) { | ||
489 | ubi_warn("EC and VID headers are in the same minimal I/O unit, " | ||
490 | "switch to read-only mode"); | ||
491 | ubi->ro_mode = 1; | ||
492 | } | ||
493 | |||
494 | ubi->leb_size = ubi->peb_size - ubi->leb_start; | ||
495 | |||
496 | if (!(ubi->mtd->flags & MTD_WRITEABLE)) { | ||
497 | ubi_msg("MTD device %d is write-protected, attach in " | ||
498 | "read-only mode", ubi->mtd->index); | ||
499 | ubi->ro_mode = 1; | ||
500 | } | ||
501 | |||
502 | dbg_msg("leb_size %d", ubi->leb_size); | ||
503 | dbg_msg("ro_mode %d", ubi->ro_mode); | ||
504 | |||
505 | /* | ||
506 | * Note, ideally, we have to initialize ubi->bad_peb_count here. But | ||
507 | * unfortunately, MTD does not provide this information. We should loop | ||
508 | * over all physical eraseblocks and invoke mtd->block_is_bad() for | ||
509 | * each physical eraseblock. So, we skip ubi->bad_peb_count | ||
510 | * uninitialized and initialize it after scanning. | ||
511 | */ | ||
512 | |||
513 | return 0; | ||
514 | } | ||
515 | |||
516 | /** | ||
517 | * attach_mtd_dev - attach an MTD device. | ||
518 | * @mtd_dev: MTD device name or number string | ||
519 | * @vid_hdr_offset: VID header offset | ||
520 | * @data_offset: data offset | ||
521 | * | ||
522 | * This function attaches an MTD device to UBI. It first treats @mtd_dev as the | ||
523 | * MTD device name, and tries to open it by this name. If it is unable to open, | ||
524 | * it tries to convert @mtd_dev to an integer and open the MTD device by its | ||
525 | * number. Returns zero in case of success and a negative error code in case of | ||
526 | * failure. | ||
527 | */ | ||
528 | static int attach_mtd_dev(const char *mtd_dev, int vid_hdr_offset, | ||
529 | int data_offset) | ||
530 | { | ||
531 | struct ubi_device *ubi; | ||
532 | struct mtd_info *mtd; | ||
533 | int i, err; | ||
534 | |||
535 | mtd = get_mtd_device_nm(mtd_dev); | ||
536 | if (IS_ERR(mtd)) { | ||
537 | int mtd_num; | ||
538 | char *endp; | ||
539 | |||
540 | if (PTR_ERR(mtd) != -ENODEV) | ||
541 | return PTR_ERR(mtd); | ||
542 | |||
543 | /* | ||
544 | * Probably this is not MTD device name but MTD device number - | ||
545 | * check this out. | ||
546 | */ | ||
547 | mtd_num = simple_strtoul(mtd_dev, &endp, 0); | ||
548 | if (*endp != '\0' || mtd_dev == endp) { | ||
549 | ubi_err("incorrect MTD device: \"%s\"", mtd_dev); | ||
550 | return -ENODEV; | ||
551 | } | ||
552 | |||
553 | mtd = get_mtd_device(NULL, mtd_num); | ||
554 | if (IS_ERR(mtd)) | ||
555 | return PTR_ERR(mtd); | ||
556 | } | ||
557 | |||
558 | /* Check if we already have the same MTD device attached */ | ||
559 | for (i = 0; i < ubi_devices_cnt; i++) | ||
560 | if (ubi_devices[i]->mtd->index == mtd->index) { | ||
561 | ubi_err("mtd%d is already attached to ubi%d", | ||
562 | mtd->index, i); | ||
563 | err = -EINVAL; | ||
564 | goto out_mtd; | ||
565 | } | ||
566 | |||
567 | ubi = ubi_devices[ubi_devices_cnt] = kzalloc(sizeof(struct ubi_device), | ||
568 | GFP_KERNEL); | ||
569 | if (!ubi) { | ||
570 | err = -ENOMEM; | ||
571 | goto out_mtd; | ||
572 | } | ||
573 | |||
574 | ubi->ubi_num = ubi_devices_cnt; | ||
575 | ubi->mtd = mtd; | ||
576 | |||
577 | dbg_msg("attaching mtd%d to ubi%d: VID header offset %d data offset %d", | ||
578 | ubi->mtd->index, ubi_devices_cnt, vid_hdr_offset, data_offset); | ||
579 | |||
580 | ubi->vid_hdr_offset = vid_hdr_offset; | ||
581 | ubi->leb_start = data_offset; | ||
582 | err = io_init(ubi); | ||
583 | if (err) | ||
584 | goto out_free; | ||
585 | |||
586 | err = attach_by_scanning(ubi); | ||
587 | if (err) { | ||
588 | dbg_err("failed to attach by scanning, error %d", err); | ||
589 | goto out_free; | ||
590 | } | ||
591 | |||
592 | err = uif_init(ubi); | ||
593 | if (err) | ||
594 | goto out_detach; | ||
595 | |||
596 | ubi_devices_cnt += 1; | ||
597 | |||
598 | ubi_msg("attached mtd%d to ubi%d", ubi->mtd->index, ubi_devices_cnt); | ||
599 | ubi_msg("MTD device name: \"%s\"", ubi->mtd->name); | ||
600 | ubi_msg("MTD device size: %llu MiB", ubi->flash_size >> 20); | ||
601 | ubi_msg("physical eraseblock size: %d bytes (%d KiB)", | ||
602 | ubi->peb_size, ubi->peb_size >> 10); | ||
603 | ubi_msg("logical eraseblock size: %d bytes", ubi->leb_size); | ||
604 | ubi_msg("number of good PEBs: %d", ubi->good_peb_count); | ||
605 | ubi_msg("number of bad PEBs: %d", ubi->bad_peb_count); | ||
606 | ubi_msg("smallest flash I/O unit: %d", ubi->min_io_size); | ||
607 | ubi_msg("VID header offset: %d (aligned %d)", | ||
608 | ubi->vid_hdr_offset, ubi->vid_hdr_aloffset); | ||
609 | ubi_msg("data offset: %d", ubi->leb_start); | ||
610 | ubi_msg("max. allowed volumes: %d", ubi->vtbl_slots); | ||
611 | ubi_msg("wear-leveling threshold: %d", CONFIG_MTD_UBI_WL_THRESHOLD); | ||
612 | ubi_msg("number of internal volumes: %d", UBI_INT_VOL_COUNT); | ||
613 | ubi_msg("number of user volumes: %d", | ||
614 | ubi->vol_count - UBI_INT_VOL_COUNT); | ||
615 | ubi_msg("available PEBs: %d", ubi->avail_pebs); | ||
616 | ubi_msg("total number of reserved PEBs: %d", ubi->rsvd_pebs); | ||
617 | ubi_msg("number of PEBs reserved for bad PEB handling: %d", | ||
618 | ubi->beb_rsvd_pebs); | ||
619 | ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); | ||
620 | |||
621 | /* Enable the background thread */ | ||
622 | if (!DBG_DISABLE_BGT) { | ||
623 | ubi->thread_enabled = 1; | ||
624 | wake_up_process(ubi->bgt_thread); | ||
625 | } | ||
626 | |||
627 | return 0; | ||
628 | |||
629 | out_detach: | ||
630 | ubi_eba_close(ubi); | ||
631 | ubi_wl_close(ubi); | ||
632 | kfree(ubi->vtbl); | ||
633 | out_free: | ||
634 | kfree(ubi); | ||
635 | out_mtd: | ||
636 | put_mtd_device(mtd); | ||
637 | ubi_devices[ubi_devices_cnt] = NULL; | ||
638 | return err; | ||
639 | } | ||
640 | |||
641 | /** | ||
642 | * detach_mtd_dev - detach an MTD device. | ||
643 | * @ubi: UBI device description object | ||
644 | */ | ||
645 | static void detach_mtd_dev(struct ubi_device *ubi) | ||
646 | { | ||
647 | int ubi_num = ubi->ubi_num, mtd_num = ubi->mtd->index; | ||
648 | |||
649 | dbg_msg("detaching mtd%d from ubi%d", ubi->mtd->index, ubi_num); | ||
650 | uif_close(ubi); | ||
651 | ubi_eba_close(ubi); | ||
652 | ubi_wl_close(ubi); | ||
653 | kfree(ubi->vtbl); | ||
654 | put_mtd_device(ubi->mtd); | ||
655 | kfree(ubi_devices[ubi_num]); | ||
656 | ubi_devices[ubi_num] = NULL; | ||
657 | ubi_devices_cnt -= 1; | ||
658 | ubi_assert(ubi_devices_cnt >= 0); | ||
659 | ubi_msg("mtd%d is detached from ubi%d", mtd_num, ubi_num); | ||
660 | } | ||
661 | |||
662 | static int __init ubi_init(void) | ||
663 | { | ||
664 | int err, i, k; | ||
665 | |||
666 | /* Ensure that EC and VID headers have correct size */ | ||
667 | BUILD_BUG_ON(sizeof(struct ubi_ec_hdr) != 64); | ||
668 | BUILD_BUG_ON(sizeof(struct ubi_vid_hdr) != 64); | ||
669 | |||
670 | if (mtd_devs > UBI_MAX_DEVICES) { | ||
671 | printk("UBI error: too many MTD devices, maximum is %d\n", | ||
672 | UBI_MAX_DEVICES); | ||
673 | return -EINVAL; | ||
674 | } | ||
675 | |||
676 | ubi_class = class_create(THIS_MODULE, UBI_NAME_STR); | ||
677 | if (IS_ERR(ubi_class)) | ||
678 | return PTR_ERR(ubi_class); | ||
679 | |||
680 | err = class_create_file(ubi_class, &ubi_version); | ||
681 | if (err) | ||
682 | goto out_class; | ||
683 | |||
684 | /* Attach MTD devices */ | ||
685 | for (i = 0; i < mtd_devs; i++) { | ||
686 | struct mtd_dev_param *p = &mtd_dev_param[i]; | ||
687 | |||
688 | cond_resched(); | ||
689 | |||
690 | if (!p->name) { | ||
691 | dbg_err("empty name"); | ||
692 | err = -EINVAL; | ||
693 | goto out_detach; | ||
694 | } | ||
695 | |||
696 | err = attach_mtd_dev(p->name, p->vid_hdr_offs, p->data_offs); | ||
697 | if (err) | ||
698 | goto out_detach; | ||
699 | } | ||
700 | |||
701 | return 0; | ||
702 | |||
703 | out_detach: | ||
704 | for (k = 0; k < i; k++) | ||
705 | detach_mtd_dev(ubi_devices[k]); | ||
706 | class_remove_file(ubi_class, &ubi_version); | ||
707 | out_class: | ||
708 | class_destroy(ubi_class); | ||
709 | return err; | ||
710 | } | ||
711 | module_init(ubi_init); | ||
712 | |||
713 | static void __exit ubi_exit(void) | ||
714 | { | ||
715 | int i, n = ubi_devices_cnt; | ||
716 | |||
717 | for (i = 0; i < n; i++) | ||
718 | detach_mtd_dev(ubi_devices[i]); | ||
719 | class_remove_file(ubi_class, &ubi_version); | ||
720 | class_destroy(ubi_class); | ||
721 | } | ||
722 | module_exit(ubi_exit); | ||
723 | |||
724 | /** | ||
725 | * bytes_str_to_int - convert a string representing number of bytes to an | ||
726 | * integer. | ||
727 | * @str: the string to convert | ||
728 | * | ||
729 | * This function returns positive resulting integer in case of success and a | ||
730 | * negative error code in case of failure. | ||
731 | */ | ||
732 | static int __init bytes_str_to_int(const char *str) | ||
733 | { | ||
734 | char *endp; | ||
735 | unsigned long result; | ||
736 | |||
737 | result = simple_strtoul(str, &endp, 0); | ||
738 | if (str == endp || result < 0) { | ||
739 | printk("UBI error: incorrect bytes count: \"%s\"\n", str); | ||
740 | return -EINVAL; | ||
741 | } | ||
742 | |||
743 | switch (*endp) { | ||
744 | case 'G': | ||
745 | result *= 1024; | ||
746 | case 'M': | ||
747 | result *= 1024; | ||
748 | case 'K': | ||
749 | case 'k': | ||
750 | result *= 1024; | ||
751 | if (endp[1] == 'i' && (endp[2] == '\0' || | ||
752 | endp[2] == 'B' || endp[2] == 'b')) | ||
753 | endp += 2; | ||
754 | case '\0': | ||
755 | break; | ||
756 | default: | ||
757 | printk("UBI error: incorrect bytes count: \"%s\"\n", str); | ||
758 | return -EINVAL; | ||
759 | } | ||
760 | |||
761 | return result; | ||
762 | } | ||
763 | |||
764 | /** | ||
765 | * ubi_mtd_param_parse - parse the 'mtd=' UBI parameter. | ||
766 | * @val: the parameter value to parse | ||
767 | * @kp: not used | ||
768 | * | ||
769 | * This function returns zero in case of success and a negative error code in | ||
770 | * case of error. | ||
771 | */ | ||
772 | static int __init ubi_mtd_param_parse(const char *val, struct kernel_param *kp) | ||
773 | { | ||
774 | int i, len; | ||
775 | struct mtd_dev_param *p; | ||
776 | char buf[MTD_PARAM_LEN_MAX]; | ||
777 | char *pbuf = &buf[0]; | ||
778 | char *tokens[3] = {NULL, NULL, NULL}; | ||
779 | |||
780 | if (mtd_devs == UBI_MAX_DEVICES) { | ||
781 | printk("UBI error: too many parameters, max. is %d\n", | ||
782 | UBI_MAX_DEVICES); | ||
783 | return -EINVAL; | ||
784 | } | ||
785 | |||
786 | len = strnlen(val, MTD_PARAM_LEN_MAX); | ||
787 | if (len == MTD_PARAM_LEN_MAX) { | ||
788 | printk("UBI error: parameter \"%s\" is too long, max. is %d\n", | ||
789 | val, MTD_PARAM_LEN_MAX); | ||
790 | return -EINVAL; | ||
791 | } | ||
792 | |||
793 | if (len == 0) { | ||
794 | printk("UBI warning: empty 'mtd=' parameter - ignored\n"); | ||
795 | return 0; | ||
796 | } | ||
797 | |||
798 | strcpy(buf, val); | ||
799 | |||
800 | /* Get rid of the final newline */ | ||
801 | if (buf[len - 1] == '\n') | ||
802 | buf[len - 1] = 0; | ||
803 | |||
804 | for (i = 0; i < 3; i++) | ||
805 | tokens[i] = strsep(&pbuf, ","); | ||
806 | |||
807 | if (pbuf) { | ||
808 | printk("UBI error: too many arguments at \"%s\"\n", val); | ||
809 | return -EINVAL; | ||
810 | } | ||
811 | |||
812 | if (tokens[0] == '\0') | ||
813 | return -EINVAL; | ||
814 | |||
815 | p = &mtd_dev_param[mtd_devs]; | ||
816 | strcpy(&p->name[0], tokens[0]); | ||
817 | |||
818 | if (tokens[1]) | ||
819 | p->vid_hdr_offs = bytes_str_to_int(tokens[1]); | ||
820 | if (tokens[2]) | ||
821 | p->data_offs = bytes_str_to_int(tokens[2]); | ||
822 | |||
823 | if (p->vid_hdr_offs < 0) | ||
824 | return p->vid_hdr_offs; | ||
825 | if (p->data_offs < 0) | ||
826 | return p->data_offs; | ||
827 | |||
828 | mtd_devs += 1; | ||
829 | return 0; | ||
830 | } | ||
831 | |||
832 | module_param_call(mtd, ubi_mtd_param_parse, NULL, NULL, 000); | ||
833 | MODULE_PARM_DESC(mtd, "MTD devices to attach. Parameter format: " | ||
834 | "mtd=<name|num>[,<vid_hdr_offs>,<data_offs>]. " | ||
835 | "Multiple \"mtd\" parameters may be specified.\n" | ||
836 | "MTD devices may be specified by their number or name. " | ||
837 | "Optional \"vid_hdr_offs\" and \"data_offs\" parameters " | ||
838 | "specify UBI VID header position and data starting " | ||
839 | "position to be used by UBI.\n" | ||
840 | "Example: mtd=content,1984,2048 mtd=4 - attach MTD device" | ||
841 | "with name content using VID header offset 1984 and data " | ||
842 | "start 2048, and MTD device number 4 using default " | ||
843 | "offsets"); | ||
844 | |||
845 | MODULE_VERSION(__stringify(UBI_VERSION)); | ||
846 | MODULE_DESCRIPTION("UBI - Unsorted Block Images"); | ||
847 | MODULE_AUTHOR("Artem Bityutskiy"); | ||
848 | MODULE_LICENSE("GPL"); | ||