diff options
Diffstat (limited to 'drivers/mtd/ubi/build.c')
-rw-r--r-- | drivers/mtd/ubi/build.c | 99 |
1 files changed, 73 insertions, 26 deletions
diff --git a/drivers/mtd/ubi/build.c b/drivers/mtd/ubi/build.c index 961416ac0616..c7630a228310 100644 --- a/drivers/mtd/ubi/build.c +++ b/drivers/mtd/ubi/build.c | |||
@@ -51,14 +51,13 @@ | |||
51 | * @name: MTD device name or number string | 51 | * @name: MTD device name or number string |
52 | * @vid_hdr_offs: VID header offset | 52 | * @vid_hdr_offs: VID header offset |
53 | */ | 53 | */ |
54 | struct mtd_dev_param | 54 | struct mtd_dev_param { |
55 | { | ||
56 | char name[MTD_PARAM_LEN_MAX]; | 55 | char name[MTD_PARAM_LEN_MAX]; |
57 | int vid_hdr_offs; | 56 | int vid_hdr_offs; |
58 | }; | 57 | }; |
59 | 58 | ||
60 | /* Numbers of elements set in the @mtd_dev_param array */ | 59 | /* Numbers of elements set in the @mtd_dev_param array */ |
61 | static int mtd_devs = 0; | 60 | static int mtd_devs; |
62 | 61 | ||
63 | /* MTD devices specification parameters */ | 62 | /* MTD devices specification parameters */ |
64 | static struct mtd_dev_param mtd_dev_param[UBI_MAX_DEVICES]; | 63 | static struct mtd_dev_param mtd_dev_param[UBI_MAX_DEVICES]; |
@@ -160,8 +159,7 @@ void ubi_put_device(struct ubi_device *ubi) | |||
160 | } | 159 | } |
161 | 160 | ||
162 | /** | 161 | /** |
163 | * ubi_get_by_major - get UBI device description object by character device | 162 | * ubi_get_by_major - get UBI device by character device major number. |
164 | * major number. | ||
165 | * @major: major number | 163 | * @major: major number |
166 | * | 164 | * |
167 | * This function is similar to 'ubi_get_device()', but it searches the device | 165 | * This function is similar to 'ubi_get_device()', but it searches the device |
@@ -355,15 +353,34 @@ static void kill_volumes(struct ubi_device *ubi) | |||
355 | } | 353 | } |
356 | 354 | ||
357 | /** | 355 | /** |
356 | * free_user_volumes - free all user volumes. | ||
357 | * @ubi: UBI device description object | ||
358 | * | ||
359 | * Normally the volumes are freed at the release function of the volume device | ||
360 | * objects. However, on error paths the volumes have to be freed before the | ||
361 | * device objects have been initialized. | ||
362 | */ | ||
363 | static void free_user_volumes(struct ubi_device *ubi) | ||
364 | { | ||
365 | int i; | ||
366 | |||
367 | for (i = 0; i < ubi->vtbl_slots; i++) | ||
368 | if (ubi->volumes[i]) { | ||
369 | kfree(ubi->volumes[i]->eba_tbl); | ||
370 | kfree(ubi->volumes[i]); | ||
371 | } | ||
372 | } | ||
373 | |||
374 | /** | ||
358 | * uif_init - initialize user interfaces for an UBI device. | 375 | * uif_init - initialize user interfaces for an UBI device. |
359 | * @ubi: UBI device description object | 376 | * @ubi: UBI device description object |
360 | * | 377 | * |
361 | * This function returns zero in case of success and a negative error code in | 378 | * This function returns zero in case of success and a negative error code in |
362 | * case of failure. | 379 | * case of failure. Note, this function destroys all volumes if it failes. |
363 | */ | 380 | */ |
364 | static int uif_init(struct ubi_device *ubi) | 381 | static int uif_init(struct ubi_device *ubi) |
365 | { | 382 | { |
366 | int i, err; | 383 | int i, err, do_free = 0; |
367 | dev_t dev; | 384 | dev_t dev; |
368 | 385 | ||
369 | sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); | 386 | sprintf(ubi->ubi_name, UBI_NAME_STR "%d", ubi->ubi_num); |
@@ -384,7 +401,7 @@ static int uif_init(struct ubi_device *ubi) | |||
384 | 401 | ||
385 | ubi_assert(MINOR(dev) == 0); | 402 | ubi_assert(MINOR(dev) == 0); |
386 | cdev_init(&ubi->cdev, &ubi_cdev_operations); | 403 | cdev_init(&ubi->cdev, &ubi_cdev_operations); |
387 | dbg_msg("%s major is %u", ubi->ubi_name, MAJOR(dev)); | 404 | dbg_gen("%s major is %u", ubi->ubi_name, MAJOR(dev)); |
388 | ubi->cdev.owner = THIS_MODULE; | 405 | ubi->cdev.owner = THIS_MODULE; |
389 | 406 | ||
390 | err = cdev_add(&ubi->cdev, dev, 1); | 407 | err = cdev_add(&ubi->cdev, dev, 1); |
@@ -410,10 +427,13 @@ static int uif_init(struct ubi_device *ubi) | |||
410 | 427 | ||
411 | out_volumes: | 428 | out_volumes: |
412 | kill_volumes(ubi); | 429 | kill_volumes(ubi); |
430 | do_free = 0; | ||
413 | out_sysfs: | 431 | out_sysfs: |
414 | ubi_sysfs_close(ubi); | 432 | ubi_sysfs_close(ubi); |
415 | cdev_del(&ubi->cdev); | 433 | cdev_del(&ubi->cdev); |
416 | out_unreg: | 434 | out_unreg: |
435 | if (do_free) | ||
436 | free_user_volumes(ubi); | ||
417 | unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1); | 437 | unregister_chrdev_region(ubi->cdev.dev, ubi->vtbl_slots + 1); |
418 | ubi_err("cannot initialize UBI %s, error %d", ubi->ubi_name, err); | 438 | ubi_err("cannot initialize UBI %s, error %d", ubi->ubi_name, err); |
419 | return err; | 439 | return err; |
@@ -422,6 +442,10 @@ out_unreg: | |||
422 | /** | 442 | /** |
423 | * uif_close - close user interfaces for an UBI device. | 443 | * uif_close - close user interfaces for an UBI device. |
424 | * @ubi: UBI device description object | 444 | * @ubi: UBI device description object |
445 | * | ||
446 | * Note, since this function un-registers UBI volume device objects (@vol->dev), | ||
447 | * the memory allocated voe the volumes is freed as well (in the release | ||
448 | * function). | ||
425 | */ | 449 | */ |
426 | static void uif_close(struct ubi_device *ubi) | 450 | static void uif_close(struct ubi_device *ubi) |
427 | { | 451 | { |
@@ -432,6 +456,21 @@ static void uif_close(struct ubi_device *ubi) | |||
432 | } | 456 | } |
433 | 457 | ||
434 | /** | 458 | /** |
459 | * free_internal_volumes - free internal volumes. | ||
460 | * @ubi: UBI device description object | ||
461 | */ | ||
462 | static void free_internal_volumes(struct ubi_device *ubi) | ||
463 | { | ||
464 | int i; | ||
465 | |||
466 | for (i = ubi->vtbl_slots; | ||
467 | i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) { | ||
468 | kfree(ubi->volumes[i]->eba_tbl); | ||
469 | kfree(ubi->volumes[i]); | ||
470 | } | ||
471 | } | ||
472 | |||
473 | /** | ||
435 | * attach_by_scanning - attach an MTD device using scanning method. | 474 | * attach_by_scanning - attach an MTD device using scanning method. |
436 | * @ubi: UBI device descriptor | 475 | * @ubi: UBI device descriptor |
437 | * | 476 | * |
@@ -475,6 +514,7 @@ static int attach_by_scanning(struct ubi_device *ubi) | |||
475 | out_wl: | 514 | out_wl: |
476 | ubi_wl_close(ubi); | 515 | ubi_wl_close(ubi); |
477 | out_vtbl: | 516 | out_vtbl: |
517 | free_internal_volumes(ubi); | ||
478 | vfree(ubi->vtbl); | 518 | vfree(ubi->vtbl); |
479 | out_si: | 519 | out_si: |
480 | ubi_scan_destroy_si(si); | 520 | ubi_scan_destroy_si(si); |
@@ -482,7 +522,7 @@ out_si: | |||
482 | } | 522 | } |
483 | 523 | ||
484 | /** | 524 | /** |
485 | * io_init - initialize I/O unit for a given UBI device. | 525 | * io_init - initialize I/O sub-system for a given UBI device. |
486 | * @ubi: UBI device description object | 526 | * @ubi: UBI device description object |
487 | * | 527 | * |
488 | * If @ubi->vid_hdr_offset or @ubi->leb_start is zero, default offsets are | 528 | * If @ubi->vid_hdr_offset or @ubi->leb_start is zero, default offsets are |
@@ -530,7 +570,11 @@ static int io_init(struct ubi_device *ubi) | |||
530 | ubi->min_io_size = ubi->mtd->writesize; | 570 | ubi->min_io_size = ubi->mtd->writesize; |
531 | ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; | 571 | ubi->hdrs_min_io_size = ubi->mtd->writesize >> ubi->mtd->subpage_sft; |
532 | 572 | ||
533 | /* Make sure minimal I/O unit is power of 2 */ | 573 | /* |
574 | * Make sure minimal I/O unit is power of 2. Note, there is no | ||
575 | * fundamental reason for this assumption. It is just an optimization | ||
576 | * which allows us to avoid costly division operations. | ||
577 | */ | ||
534 | if (!is_power_of_2(ubi->min_io_size)) { | 578 | if (!is_power_of_2(ubi->min_io_size)) { |
535 | ubi_err("min. I/O unit (%d) is not power of 2", | 579 | ubi_err("min. I/O unit (%d) is not power of 2", |
536 | ubi->min_io_size); | 580 | ubi->min_io_size); |
@@ -581,7 +625,7 @@ static int io_init(struct ubi_device *ubi) | |||
581 | if (ubi->vid_hdr_offset < UBI_EC_HDR_SIZE || | 625 | if (ubi->vid_hdr_offset < UBI_EC_HDR_SIZE || |
582 | ubi->leb_start < ubi->vid_hdr_offset + UBI_VID_HDR_SIZE || | 626 | ubi->leb_start < ubi->vid_hdr_offset + UBI_VID_HDR_SIZE || |
583 | ubi->leb_start > ubi->peb_size - UBI_VID_HDR_SIZE || | 627 | ubi->leb_start > ubi->peb_size - UBI_VID_HDR_SIZE || |
584 | ubi->leb_start % ubi->min_io_size) { | 628 | ubi->leb_start & (ubi->min_io_size - 1)) { |
585 | ubi_err("bad VID header (%d) or data offsets (%d)", | 629 | ubi_err("bad VID header (%d) or data offsets (%d)", |
586 | ubi->vid_hdr_offset, ubi->leb_start); | 630 | ubi->vid_hdr_offset, ubi->leb_start); |
587 | return -EINVAL; | 631 | return -EINVAL; |
@@ -646,7 +690,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id) | |||
646 | 690 | ||
647 | /* | 691 | /* |
648 | * Clear the auto-resize flag in the volume in-memory copy of the | 692 | * Clear the auto-resize flag in the volume in-memory copy of the |
649 | * volume table, and 'ubi_resize_volume()' will propogate this change | 693 | * volume table, and 'ubi_resize_volume()' will propagate this change |
650 | * to the flash. | 694 | * to the flash. |
651 | */ | 695 | */ |
652 | ubi->vtbl[vol_id].flags &= ~UBI_VTBL_AUTORESIZE_FLG; | 696 | ubi->vtbl[vol_id].flags &= ~UBI_VTBL_AUTORESIZE_FLG; |
@@ -655,7 +699,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id) | |||
655 | struct ubi_vtbl_record vtbl_rec; | 699 | struct ubi_vtbl_record vtbl_rec; |
656 | 700 | ||
657 | /* | 701 | /* |
658 | * No avalilable PEBs to re-size the volume, clear the flag on | 702 | * No available PEBs to re-size the volume, clear the flag on |
659 | * flash and exit. | 703 | * flash and exit. |
660 | */ | 704 | */ |
661 | memcpy(&vtbl_rec, &ubi->vtbl[vol_id], | 705 | memcpy(&vtbl_rec, &ubi->vtbl[vol_id], |
@@ -682,13 +726,13 @@ static int autoresize(struct ubi_device *ubi, int vol_id) | |||
682 | 726 | ||
683 | /** | 727 | /** |
684 | * ubi_attach_mtd_dev - attach an MTD device. | 728 | * ubi_attach_mtd_dev - attach an MTD device. |
685 | * @mtd_dev: MTD device description object | 729 | * @mtd: MTD device description object |
686 | * @ubi_num: number to assign to the new UBI device | 730 | * @ubi_num: number to assign to the new UBI device |
687 | * @vid_hdr_offset: VID header offset | 731 | * @vid_hdr_offset: VID header offset |
688 | * | 732 | * |
689 | * This function attaches MTD device @mtd_dev to UBI and assign @ubi_num number | 733 | * This function attaches MTD device @mtd_dev to UBI and assign @ubi_num number |
690 | * to the newly created UBI device, unless @ubi_num is %UBI_DEV_NUM_AUTO, in | 734 | * to the newly created UBI device, unless @ubi_num is %UBI_DEV_NUM_AUTO, in |
691 | * which case this function finds a vacant device nubert and assings it | 735 | * which case this function finds a vacant device number and assigns it |
692 | * automatically. Returns the new UBI device number in case of success and a | 736 | * automatically. Returns the new UBI device number in case of success and a |
693 | * negative error code in case of failure. | 737 | * negative error code in case of failure. |
694 | * | 738 | * |
@@ -698,7 +742,7 @@ static int autoresize(struct ubi_device *ubi, int vol_id) | |||
698 | int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | 742 | int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) |
699 | { | 743 | { |
700 | struct ubi_device *ubi; | 744 | struct ubi_device *ubi; |
701 | int i, err; | 745 | int i, err, do_free = 1; |
702 | 746 | ||
703 | /* | 747 | /* |
704 | * Check if we already have the same MTD device attached. | 748 | * Check if we already have the same MTD device attached. |
@@ -735,7 +779,8 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
735 | if (!ubi_devices[ubi_num]) | 779 | if (!ubi_devices[ubi_num]) |
736 | break; | 780 | break; |
737 | if (ubi_num == UBI_MAX_DEVICES) { | 781 | if (ubi_num == UBI_MAX_DEVICES) { |
738 | dbg_err("only %d UBI devices may be created", UBI_MAX_DEVICES); | 782 | dbg_err("only %d UBI devices may be created", |
783 | UBI_MAX_DEVICES); | ||
739 | return -ENFILE; | 784 | return -ENFILE; |
740 | } | 785 | } |
741 | } else { | 786 | } else { |
@@ -760,6 +805,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
760 | 805 | ||
761 | mutex_init(&ubi->buf_mutex); | 806 | mutex_init(&ubi->buf_mutex); |
762 | mutex_init(&ubi->ckvol_mutex); | 807 | mutex_init(&ubi->ckvol_mutex); |
808 | mutex_init(&ubi->mult_mutex); | ||
763 | mutex_init(&ubi->volumes_mutex); | 809 | mutex_init(&ubi->volumes_mutex); |
764 | spin_lock_init(&ubi->volumes_lock); | 810 | spin_lock_init(&ubi->volumes_lock); |
765 | 811 | ||
@@ -798,7 +844,7 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
798 | 844 | ||
799 | err = uif_init(ubi); | 845 | err = uif_init(ubi); |
800 | if (err) | 846 | if (err) |
801 | goto out_detach; | 847 | goto out_nofree; |
802 | 848 | ||
803 | ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name); | 849 | ubi->bgt_thread = kthread_create(ubi_thread, ubi, ubi->bgt_name); |
804 | if (IS_ERR(ubi->bgt_thread)) { | 850 | if (IS_ERR(ubi->bgt_thread)) { |
@@ -824,20 +870,22 @@ int ubi_attach_mtd_dev(struct mtd_info *mtd, int ubi_num, int vid_hdr_offset) | |||
824 | ubi->beb_rsvd_pebs); | 870 | ubi->beb_rsvd_pebs); |
825 | ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); | 871 | ubi_msg("max/mean erase counter: %d/%d", ubi->max_ec, ubi->mean_ec); |
826 | 872 | ||
827 | /* Enable the background thread */ | 873 | if (!DBG_DISABLE_BGT) |
828 | if (!DBG_DISABLE_BGT) { | ||
829 | ubi->thread_enabled = 1; | 874 | ubi->thread_enabled = 1; |
830 | wake_up_process(ubi->bgt_thread); | 875 | wake_up_process(ubi->bgt_thread); |
831 | } | ||
832 | 876 | ||
833 | ubi_devices[ubi_num] = ubi; | 877 | ubi_devices[ubi_num] = ubi; |
834 | return ubi_num; | 878 | return ubi_num; |
835 | 879 | ||
836 | out_uif: | 880 | out_uif: |
837 | uif_close(ubi); | 881 | uif_close(ubi); |
882 | out_nofree: | ||
883 | do_free = 0; | ||
838 | out_detach: | 884 | out_detach: |
839 | ubi_eba_close(ubi); | ||
840 | ubi_wl_close(ubi); | 885 | ubi_wl_close(ubi); |
886 | if (do_free) | ||
887 | free_user_volumes(ubi); | ||
888 | free_internal_volumes(ubi); | ||
841 | vfree(ubi->vtbl); | 889 | vfree(ubi->vtbl); |
842 | out_free: | 890 | out_free: |
843 | vfree(ubi->peb_buf1); | 891 | vfree(ubi->peb_buf1); |
@@ -899,8 +947,8 @@ int ubi_detach_mtd_dev(int ubi_num, int anyway) | |||
899 | kthread_stop(ubi->bgt_thread); | 947 | kthread_stop(ubi->bgt_thread); |
900 | 948 | ||
901 | uif_close(ubi); | 949 | uif_close(ubi); |
902 | ubi_eba_close(ubi); | ||
903 | ubi_wl_close(ubi); | 950 | ubi_wl_close(ubi); |
951 | free_internal_volumes(ubi); | ||
904 | vfree(ubi->vtbl); | 952 | vfree(ubi->vtbl); |
905 | put_mtd_device(ubi->mtd); | 953 | put_mtd_device(ubi->mtd); |
906 | vfree(ubi->peb_buf1); | 954 | vfree(ubi->peb_buf1); |
@@ -1044,8 +1092,7 @@ static void __exit ubi_exit(void) | |||
1044 | module_exit(ubi_exit); | 1092 | module_exit(ubi_exit); |
1045 | 1093 | ||
1046 | /** | 1094 | /** |
1047 | * bytes_str_to_int - convert a string representing number of bytes to an | 1095 | * bytes_str_to_int - convert a number of bytes string into an integer. |
1048 | * integer. | ||
1049 | * @str: the string to convert | 1096 | * @str: the string to convert |
1050 | * | 1097 | * |
1051 | * This function returns positive resulting integer in case of success and a | 1098 | * This function returns positive resulting integer in case of success and a |