Lines Matching refs:ai
79 static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai);
103 static struct ubi_ainf_volume *find_or_add_av(struct ubi_attach_info *ai, in find_or_add_av() argument
108 struct rb_node **p = &ai->volumes.rb_node, *parent = NULL; in find_or_add_av()
140 if (vol_id > ai->highest_vol_id) in find_or_add_av()
141 ai->highest_vol_id = vol_id; in find_or_add_av()
144 rb_insert_color(&av->rb, &ai->volumes); in find_or_add_av()
145 ai->vols_found += 1; in find_or_add_av()
161 static struct ubi_ainf_volume *ubi_find_or_add_av(struct ubi_attach_info *ai, in ubi_find_or_add_av() argument
164 return find_or_add_av(ai, vol_id, AV_FIND_OR_ADD, created); in ubi_find_or_add_av()
178 struct ubi_ainf_peb *ubi_alloc_aeb(struct ubi_attach_info *ai, int pnum, in ubi_alloc_aeb() argument
183 aeb = kmem_cache_zalloc(ai->aeb_slab_cache, GFP_KERNEL); in ubi_alloc_aeb()
203 void ubi_free_aeb(struct ubi_attach_info *ai, struct ubi_ainf_peb *aeb) in ubi_free_aeb() argument
205 kmem_cache_free(ai->aeb_slab_cache, aeb); in ubi_free_aeb()
229 static int add_to_list(struct ubi_attach_info *ai, int pnum, int vol_id, in add_to_list() argument
234 if (list == &ai->free) { in add_to_list()
236 } else if (list == &ai->erase) { in add_to_list()
238 } else if (list == &ai->alien) { in add_to_list()
240 ai->alien_peb_count += 1; in add_to_list()
244 aeb = ubi_alloc_aeb(ai, pnum, ec); in add_to_list()
268 static int add_corrupted(struct ubi_attach_info *ai, int pnum, int ec) in add_corrupted() argument
274 aeb = ubi_alloc_aeb(ai, pnum, ec); in add_corrupted()
278 ai->corr_peb_count += 1; in add_corrupted()
279 list_add(&aeb->u.list, &ai->corr); in add_corrupted()
296 static int add_fastmap(struct ubi_attach_info *ai, int pnum, in add_fastmap() argument
301 aeb = ubi_alloc_aeb(ai, pnum, ec); in add_fastmap()
307 list_add(&aeb->u.list, &ai->fastmap); in add_fastmap()
396 static struct ubi_ainf_volume *add_volume(struct ubi_attach_info *ai, in add_volume() argument
405 av = ubi_find_or_add_av(ai, vol_id, &created); in add_volume()
563 int ubi_add_to_av(struct ubi_device *ubi, struct ubi_attach_info *ai, int pnum, in ubi_add_to_av() argument
579 av = add_volume(ai, vol_id, pnum, vid_hdr); in ubi_add_to_av()
583 if (ai->max_sqnum < sqnum) in ubi_add_to_av()
584 ai->max_sqnum = sqnum; in ubi_add_to_av()
650 err = add_to_list(ai, aeb->pnum, aeb->vol_id, in ubi_add_to_av()
652 &ai->erase); in ubi_add_to_av()
674 return add_to_list(ai, pnum, vol_id, lnum, ec, in ubi_add_to_av()
675 cmp_res & 4, &ai->erase); in ubi_add_to_av()
688 aeb = ubi_alloc_aeb(ai, pnum, ec); in ubi_add_to_av()
717 struct ubi_ainf_volume *ubi_add_av(struct ubi_attach_info *ai, int vol_id) in ubi_add_av() argument
721 return find_or_add_av(ai, vol_id, AV_ADD, &created); in ubi_add_av()
732 struct ubi_ainf_volume *ubi_find_av(const struct ubi_attach_info *ai, in ubi_find_av() argument
737 return find_or_add_av((struct ubi_attach_info *)ai, vol_id, AV_FIND, in ubi_find_av()
741 static void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av,
749 void ubi_remove_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av) in ubi_remove_av() argument
753 rb_erase(&av->rb, &ai->volumes); in ubi_remove_av()
754 destroy_av(ai, av, &ai->erase); in ubi_remove_av()
755 ai->vols_found -= 1; in ubi_remove_av()
772 const struct ubi_attach_info *ai, int pnum, int ec) in early_erase_peb() argument
819 struct ubi_attach_info *ai) in ubi_early_get_peb() argument
824 if (!list_empty(&ai->free)) { in ubi_early_get_peb()
825 aeb = list_entry(ai->free.next, struct ubi_ainf_peb, u.list); in ubi_early_get_peb()
837 list_for_each_entry_safe(aeb, tmp_aeb, &ai->erase, u.list) { in ubi_early_get_peb()
839 aeb->ec = ai->mean_ec; in ubi_early_get_peb()
841 err = early_erase_peb(ubi, ai, aeb->pnum, aeb->ec+1); in ubi_early_get_peb()
941 static int scan_peb(struct ubi_device *ubi, struct ubi_attach_info *ai, in scan_peb() argument
944 struct ubi_ec_hdr *ech = ai->ech; in scan_peb()
945 struct ubi_vid_io_buf *vidb = ai->vidb; in scan_peb()
957 ai->bad_peb_count += 1; in scan_peb()
971 ai->empty_peb_count += 1; in scan_peb()
972 return add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN, in scan_peb()
973 UBI_UNKNOWN, 0, &ai->erase); in scan_peb()
975 ai->empty_peb_count += 1; in scan_peb()
976 return add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN, in scan_peb()
977 UBI_UNKNOWN, 1, &ai->erase); in scan_peb()
1061 ai->maybe_bad_peb_count += 1; in scan_peb()
1076 ai->force_full_scan = 1; in scan_peb()
1103 err = add_to_list(ai, pnum, UBI_UNKNOWN, in scan_peb()
1104 UBI_UNKNOWN, ec, 1, &ai->erase); in scan_peb()
1107 err = add_corrupted(ai, pnum, ec); in scan_peb()
1112 err = add_to_list(ai, pnum, UBI_UNKNOWN, UBI_UNKNOWN, in scan_peb()
1113 ec, 1, &ai->erase); in scan_peb()
1119 err = add_to_list(ai, pnum, UBI_UNKNOWN, in scan_peb()
1120 UBI_UNKNOWN, ec, 1, &ai->erase); in scan_peb()
1122 err = add_to_list(ai, pnum, UBI_UNKNOWN, in scan_peb()
1123 UBI_UNKNOWN, ec, 0, &ai->free); in scan_peb()
1143 err = add_to_list(ai, pnum, vol_id, lnum, in scan_peb()
1144 ec, 1, &ai->erase); in scan_peb()
1158 err = add_to_list(ai, pnum, vol_id, lnum, in scan_peb()
1159 ec, 0, &ai->alien); in scan_peb()
1176 err = add_fastmap(ai, pnum, vidh, ec); in scan_peb()
1178 err = ubi_add_to_av(ubi, ai, pnum, ec, vidh, bitflips); in scan_peb()
1185 ai->ec_sum += ec; in scan_peb()
1186 ai->ec_count += 1; in scan_peb()
1187 if (ec > ai->max_ec) in scan_peb()
1188 ai->max_ec = ec; in scan_peb()
1189 if (ec < ai->min_ec) in scan_peb()
1190 ai->min_ec = ec; in scan_peb()
1207 static int late_analysis(struct ubi_device *ubi, struct ubi_attach_info *ai) in late_analysis() argument
1212 peb_count = ubi->peb_count - ai->bad_peb_count - ai->alien_peb_count; in late_analysis()
1220 if (ai->corr_peb_count) { in late_analysis()
1222 ai->corr_peb_count); in late_analysis()
1224 list_for_each_entry(aeb, &ai->corr, u.list) in late_analysis()
1232 if (ai->corr_peb_count >= max_corr) { in late_analysis()
1238 if (ai->empty_peb_count + ai->maybe_bad_peb_count == peb_count) { in late_analysis()
1254 if (ai->maybe_bad_peb_count <= 2) { in late_analysis()
1255 ai->is_empty = 1; in late_analysis()
1277 static void destroy_av(struct ubi_attach_info *ai, struct ubi_ainf_volume *av, in destroy_av() argument
1301 ubi_free_aeb(ai, aeb); in destroy_av()
1311 static void destroy_ai(struct ubi_attach_info *ai) in destroy_ai() argument
1317 list_for_each_entry_safe(aeb, aeb_tmp, &ai->alien, u.list) { in destroy_ai()
1319 ubi_free_aeb(ai, aeb); in destroy_ai()
1321 list_for_each_entry_safe(aeb, aeb_tmp, &ai->erase, u.list) { in destroy_ai()
1323 ubi_free_aeb(ai, aeb); in destroy_ai()
1325 list_for_each_entry_safe(aeb, aeb_tmp, &ai->corr, u.list) { in destroy_ai()
1327 ubi_free_aeb(ai, aeb); in destroy_ai()
1329 list_for_each_entry_safe(aeb, aeb_tmp, &ai->free, u.list) { in destroy_ai()
1331 ubi_free_aeb(ai, aeb); in destroy_ai()
1333 list_for_each_entry_safe(aeb, aeb_tmp, &ai->fastmap, u.list) { in destroy_ai()
1335 ubi_free_aeb(ai, aeb); in destroy_ai()
1339 rb = ai->volumes.rb_node; in destroy_ai()
1356 destroy_av(ai, av, NULL); in destroy_ai()
1360 kmem_cache_destroy(ai->aeb_slab_cache); in destroy_ai()
1361 kfree(ai); in destroy_ai()
1374 static int scan_all(struct ubi_device *ubi, struct ubi_attach_info *ai, in scan_all() argument
1384 ai->ech = kzalloc(ubi->ec_hdr_alsize, GFP_KERNEL); in scan_all()
1385 if (!ai->ech) in scan_all()
1388 ai->vidb = ubi_alloc_vid_buf(ubi, GFP_KERNEL); in scan_all()
1389 if (!ai->vidb) in scan_all()
1396 err = scan_peb(ubi, ai, pnum, false); in scan_all()
1404 if (ai->ec_count) in scan_all()
1405 ai->mean_ec = div_u64(ai->ec_sum, ai->ec_count); in scan_all()
1407 err = late_analysis(ubi, ai); in scan_all()
1415 ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { in scan_all()
1418 aeb->ec = ai->mean_ec; in scan_all()
1421 list_for_each_entry(aeb, &ai->free, u.list) { in scan_all()
1423 aeb->ec = ai->mean_ec; in scan_all()
1426 list_for_each_entry(aeb, &ai->corr, u.list) in scan_all()
1428 aeb->ec = ai->mean_ec; in scan_all()
1430 list_for_each_entry(aeb, &ai->erase, u.list) in scan_all()
1432 aeb->ec = ai->mean_ec; in scan_all()
1434 err = self_check_ai(ubi, ai); in scan_all()
1438 ubi_free_vid_buf(ai->vidb); in scan_all()
1439 kfree(ai->ech); in scan_all()
1444 ubi_free_vid_buf(ai->vidb); in scan_all()
1446 kfree(ai->ech); in scan_all()
1452 struct ubi_attach_info *ai; in alloc_ai() local
1454 ai = kzalloc(sizeof(struct ubi_attach_info), GFP_KERNEL); in alloc_ai()
1455 if (!ai) in alloc_ai()
1456 return ai; in alloc_ai()
1458 INIT_LIST_HEAD(&ai->corr); in alloc_ai()
1459 INIT_LIST_HEAD(&ai->free); in alloc_ai()
1460 INIT_LIST_HEAD(&ai->erase); in alloc_ai()
1461 INIT_LIST_HEAD(&ai->alien); in alloc_ai()
1462 INIT_LIST_HEAD(&ai->fastmap); in alloc_ai()
1463 ai->volumes = RB_ROOT; in alloc_ai()
1464 ai->aeb_slab_cache = kmem_cache_create("ubi_aeb_slab_cache", in alloc_ai()
1467 if (!ai->aeb_slab_cache) { in alloc_ai()
1468 kfree(ai); in alloc_ai()
1469 ai = NULL; in alloc_ai()
1472 return ai; in alloc_ai()
1487 static int scan_fast(struct ubi_device *ubi, struct ubi_attach_info **ai) in scan_fast() argument
1521 err = ubi_scan_fastmap(ubi, *ai, scan_ai); in scan_fast()
1528 destroy_ai(*ai); in scan_fast()
1529 *ai = scan_ai; in scan_fast()
1558 struct ubi_attach_info *ai; in ubi_attach() local
1560 ai = alloc_ai(); in ubi_attach()
1561 if (!ai) in ubi_attach()
1572 err = scan_all(ubi, ai, 0); in ubi_attach()
1574 err = scan_fast(ubi, &ai); in ubi_attach()
1577 destroy_ai(ai); in ubi_attach()
1578 ai = alloc_ai(); in ubi_attach()
1579 if (!ai) in ubi_attach()
1582 err = scan_all(ubi, ai, 0); in ubi_attach()
1584 err = scan_all(ubi, ai, UBI_FM_MAX_START); in ubi_attach()
1589 err = scan_all(ubi, ai, 0); in ubi_attach()
1594 ubi->bad_peb_count = ai->bad_peb_count; in ubi_attach()
1596 ubi->corr_peb_count = ai->corr_peb_count; in ubi_attach()
1597 ubi->max_ec = ai->max_ec; in ubi_attach()
1598 ubi->mean_ec = ai->mean_ec; in ubi_attach()
1599 dbg_gen("max. sequence number: %llu", ai->max_sqnum); in ubi_attach()
1601 err = ubi_read_volume_table(ubi, ai); in ubi_attach()
1605 err = ubi_wl_init(ubi, ai); in ubi_attach()
1609 err = ubi_eba_init(ubi, ai); in ubi_attach()
1629 err = self_check_eba(ubi, ai, scan_ai); in ubi_attach()
1637 destroy_ai(ai); in ubi_attach()
1646 destroy_ai(ai); in ubi_attach()
1658 static int self_check_ai(struct ubi_device *ubi, struct ubi_attach_info *ai) in self_check_ai() argument
1660 struct ubi_vid_io_buf *vidb = ai->vidb; in self_check_ai()
1674 ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { in self_check_ai()
1681 if (ai->is_empty) { in self_check_ai()
1699 if (av->vol_id > ai->highest_vol_id) { in self_check_ai()
1701 ai->highest_vol_id, av->vol_id); in self_check_ai()
1728 if (aeb->ec < ai->min_ec) { in self_check_ai()
1730 ai->min_ec, aeb->ec); in self_check_ai()
1734 if (aeb->ec > ai->max_ec) { in self_check_ai()
1736 ai->max_ec, aeb->ec); in self_check_ai()
1781 if (vols_found != ai->vols_found) { in self_check_ai()
1783 ai->vols_found, vols_found); in self_check_ai()
1788 ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) { in self_check_ai()
1876 ubi_rb_for_each_entry(rb1, av, &ai->volumes, rb) in self_check_ai()
1880 list_for_each_entry(aeb, &ai->free, u.list) in self_check_ai()
1883 list_for_each_entry(aeb, &ai->corr, u.list) in self_check_ai()
1886 list_for_each_entry(aeb, &ai->erase, u.list) in self_check_ai()
1889 list_for_each_entry(aeb, &ai->alien, u.list) in self_check_ai()