diff options
Diffstat (limited to 'drivers/mtd/ubi/vtbl.c')
-rw-r--r-- | drivers/mtd/ubi/vtbl.c | 85 |
1 files changed, 44 insertions, 41 deletions
diff --git a/drivers/mtd/ubi/vtbl.c b/drivers/mtd/ubi/vtbl.c index b6fd6bbd941e..bc5df50813d6 100644 --- a/drivers/mtd/ubi/vtbl.c +++ b/drivers/mtd/ubi/vtbl.c | |||
@@ -93,12 +93,9 @@ int ubi_change_vtbl_record(struct ubi_device *ubi, int idx, | |||
93 | vtbl_rec = &empty_vtbl_record; | 93 | vtbl_rec = &empty_vtbl_record; |
94 | else { | 94 | else { |
95 | crc = crc32(UBI_CRC32_INIT, vtbl_rec, UBI_VTBL_RECORD_SIZE_CRC); | 95 | crc = crc32(UBI_CRC32_INIT, vtbl_rec, UBI_VTBL_RECORD_SIZE_CRC); |
96 | vtbl_rec->crc = cpu_to_ubi32(crc); | 96 | vtbl_rec->crc = cpu_to_be32(crc); |
97 | } | 97 | } |
98 | 98 | ||
99 | dbg_msg("change record %d", idx); | ||
100 | ubi_dbg_dump_vtbl_record(vtbl_rec, idx); | ||
101 | |||
102 | mutex_lock(&ubi->vtbl_mutex); | 99 | mutex_lock(&ubi->vtbl_mutex); |
103 | memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record)); | 100 | memcpy(&ubi->vtbl[idx], vtbl_rec, sizeof(struct ubi_vtbl_record)); |
104 | for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { | 101 | for (i = 0; i < UBI_LAYOUT_VOLUME_EBS; i++) { |
@@ -141,18 +138,18 @@ static int vtbl_check(const struct ubi_device *ubi, | |||
141 | for (i = 0; i < ubi->vtbl_slots; i++) { | 138 | for (i = 0; i < ubi->vtbl_slots; i++) { |
142 | cond_resched(); | 139 | cond_resched(); |
143 | 140 | ||
144 | reserved_pebs = ubi32_to_cpu(vtbl[i].reserved_pebs); | 141 | reserved_pebs = be32_to_cpu(vtbl[i].reserved_pebs); |
145 | alignment = ubi32_to_cpu(vtbl[i].alignment); | 142 | alignment = be32_to_cpu(vtbl[i].alignment); |
146 | data_pad = ubi32_to_cpu(vtbl[i].data_pad); | 143 | data_pad = be32_to_cpu(vtbl[i].data_pad); |
147 | upd_marker = vtbl[i].upd_marker; | 144 | upd_marker = vtbl[i].upd_marker; |
148 | vol_type = vtbl[i].vol_type; | 145 | vol_type = vtbl[i].vol_type; |
149 | name_len = ubi16_to_cpu(vtbl[i].name_len); | 146 | name_len = be16_to_cpu(vtbl[i].name_len); |
150 | name = &vtbl[i].name[0]; | 147 | name = &vtbl[i].name[0]; |
151 | 148 | ||
152 | crc = crc32(UBI_CRC32_INIT, &vtbl[i], UBI_VTBL_RECORD_SIZE_CRC); | 149 | crc = crc32(UBI_CRC32_INIT, &vtbl[i], UBI_VTBL_RECORD_SIZE_CRC); |
153 | if (ubi32_to_cpu(vtbl[i].crc) != crc) { | 150 | if (be32_to_cpu(vtbl[i].crc) != crc) { |
154 | ubi_err("bad CRC at record %u: %#08x, not %#08x", | 151 | ubi_err("bad CRC at record %u: %#08x, not %#08x", |
155 | i, crc, ubi32_to_cpu(vtbl[i].crc)); | 152 | i, crc, be32_to_cpu(vtbl[i].crc)); |
156 | ubi_dbg_dump_vtbl_record(&vtbl[i], i); | 153 | ubi_dbg_dump_vtbl_record(&vtbl[i], i); |
157 | return 1; | 154 | return 1; |
158 | } | 155 | } |
@@ -225,8 +222,8 @@ static int vtbl_check(const struct ubi_device *ubi, | |||
225 | /* Checks that all names are unique */ | 222 | /* Checks that all names are unique */ |
226 | for (i = 0; i < ubi->vtbl_slots - 1; i++) { | 223 | for (i = 0; i < ubi->vtbl_slots - 1; i++) { |
227 | for (n = i + 1; n < ubi->vtbl_slots; n++) { | 224 | for (n = i + 1; n < ubi->vtbl_slots; n++) { |
228 | int len1 = ubi16_to_cpu(vtbl[i].name_len); | 225 | int len1 = be16_to_cpu(vtbl[i].name_len); |
229 | int len2 = ubi16_to_cpu(vtbl[n].name_len); | 226 | int len2 = be16_to_cpu(vtbl[n].name_len); |
230 | 227 | ||
231 | if (len1 > 0 && len1 == len2 && | 228 | if (len1 > 0 && len1 == len2 && |
232 | !strncmp(vtbl[i].name, vtbl[n].name, len1)) { | 229 | !strncmp(vtbl[i].name, vtbl[n].name, len1)) { |
@@ -288,13 +285,13 @@ retry: | |||
288 | } | 285 | } |
289 | 286 | ||
290 | vid_hdr->vol_type = UBI_VID_DYNAMIC; | 287 | vid_hdr->vol_type = UBI_VID_DYNAMIC; |
291 | vid_hdr->vol_id = cpu_to_ubi32(UBI_LAYOUT_VOL_ID); | 288 | vid_hdr->vol_id = cpu_to_be32(UBI_LAYOUT_VOL_ID); |
292 | vid_hdr->compat = UBI_LAYOUT_VOLUME_COMPAT; | 289 | vid_hdr->compat = UBI_LAYOUT_VOLUME_COMPAT; |
293 | vid_hdr->data_size = vid_hdr->used_ebs = | 290 | vid_hdr->data_size = vid_hdr->used_ebs = |
294 | vid_hdr->data_pad = cpu_to_ubi32(0); | 291 | vid_hdr->data_pad = cpu_to_be32(0); |
295 | vid_hdr->lnum = cpu_to_ubi32(copy); | 292 | vid_hdr->lnum = cpu_to_be32(copy); |
296 | vid_hdr->sqnum = cpu_to_ubi64(++si->max_sqnum); | 293 | vid_hdr->sqnum = cpu_to_be64(++si->max_sqnum); |
297 | vid_hdr->leb_ver = cpu_to_ubi32(old_seb ? old_seb->leb_ver + 1: 0); | 294 | vid_hdr->leb_ver = cpu_to_be32(old_seb ? old_seb->leb_ver + 1: 0); |
298 | 295 | ||
299 | /* The EC header is already there, write the VID header */ | 296 | /* The EC header is already there, write the VID header */ |
300 | err = ubi_io_write_vid_hdr(ubi, new_seb->pnum, vid_hdr); | 297 | err = ubi_io_write_vid_hdr(ubi, new_seb->pnum, vid_hdr); |
@@ -317,14 +314,15 @@ retry: | |||
317 | return err; | 314 | return err; |
318 | 315 | ||
319 | write_error: | 316 | write_error: |
320 | kfree(new_seb); | 317 | if (err == -EIO && ++tries <= 5) { |
321 | /* May be this physical eraseblock went bad, try to pick another one */ | 318 | /* |
322 | if (++tries <= 5) { | 319 | * Probably this physical eraseblock went bad, try to pick |
323 | err = ubi_scan_add_to_list(si, new_seb->pnum, new_seb->ec, | 320 | * another one. |
324 | &si->corr); | 321 | */ |
325 | if (!err) | 322 | list_add_tail(&new_seb->u.list, &si->corr); |
326 | goto retry; | 323 | goto retry; |
327 | } | 324 | } |
325 | kfree(new_seb); | ||
328 | out_free: | 326 | out_free: |
329 | ubi_free_vid_hdr(ubi, vid_hdr); | 327 | ubi_free_vid_hdr(ubi, vid_hdr); |
330 | return err; | 328 | return err; |
@@ -380,11 +378,12 @@ static struct ubi_vtbl_record *process_lvol(const struct ubi_device *ubi, | |||
380 | 378 | ||
381 | /* Read both LEB 0 and LEB 1 into memory */ | 379 | /* Read both LEB 0 and LEB 1 into memory */ |
382 | ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) { | 380 | ubi_rb_for_each_entry(rb, seb, &sv->root, u.rb) { |
383 | leb[seb->lnum] = kzalloc(ubi->vtbl_size, GFP_KERNEL); | 381 | leb[seb->lnum] = vmalloc(ubi->vtbl_size); |
384 | if (!leb[seb->lnum]) { | 382 | if (!leb[seb->lnum]) { |
385 | err = -ENOMEM; | 383 | err = -ENOMEM; |
386 | goto out_free; | 384 | goto out_free; |
387 | } | 385 | } |
386 | memset(leb[seb->lnum], 0, ubi->vtbl_size); | ||
388 | 387 | ||
389 | err = ubi_io_read_data(ubi, leb[seb->lnum], seb->pnum, 0, | 388 | err = ubi_io_read_data(ubi, leb[seb->lnum], seb->pnum, 0, |
390 | ubi->vtbl_size); | 389 | ubi->vtbl_size); |
@@ -415,7 +414,7 @@ static struct ubi_vtbl_record *process_lvol(const struct ubi_device *ubi, | |||
415 | } | 414 | } |
416 | 415 | ||
417 | /* Both LEB 1 and LEB 2 are OK and consistent */ | 416 | /* Both LEB 1 and LEB 2 are OK and consistent */ |
418 | kfree(leb[1]); | 417 | vfree(leb[1]); |
419 | return leb[0]; | 418 | return leb[0]; |
420 | } else { | 419 | } else { |
421 | /* LEB 0 is corrupted or does not exist */ | 420 | /* LEB 0 is corrupted or does not exist */ |
@@ -436,13 +435,13 @@ static struct ubi_vtbl_record *process_lvol(const struct ubi_device *ubi, | |||
436 | goto out_free; | 435 | goto out_free; |
437 | ubi_msg("volume table was restored"); | 436 | ubi_msg("volume table was restored"); |
438 | 437 | ||
439 | kfree(leb[0]); | 438 | vfree(leb[0]); |
440 | return leb[1]; | 439 | return leb[1]; |
441 | } | 440 | } |
442 | 441 | ||
443 | out_free: | 442 | out_free: |
444 | kfree(leb[0]); | 443 | vfree(leb[0]); |
445 | kfree(leb[1]); | 444 | vfree(leb[1]); |
446 | return ERR_PTR(err); | 445 | return ERR_PTR(err); |
447 | } | 446 | } |
448 | 447 | ||
@@ -460,9 +459,10 @@ static struct ubi_vtbl_record *create_empty_lvol(const struct ubi_device *ubi, | |||
460 | int i; | 459 | int i; |
461 | struct ubi_vtbl_record *vtbl; | 460 | struct ubi_vtbl_record *vtbl; |
462 | 461 | ||
463 | vtbl = kzalloc(ubi->vtbl_size, GFP_KERNEL); | 462 | vtbl = vmalloc(ubi->vtbl_size); |
464 | if (!vtbl) | 463 | if (!vtbl) |
465 | return ERR_PTR(-ENOMEM); | 464 | return ERR_PTR(-ENOMEM); |
465 | memset(vtbl, 0, ubi->vtbl_size); | ||
466 | 466 | ||
467 | for (i = 0; i < ubi->vtbl_slots; i++) | 467 | for (i = 0; i < ubi->vtbl_slots; i++) |
468 | memcpy(&vtbl[i], &empty_vtbl_record, UBI_VTBL_RECORD_SIZE); | 468 | memcpy(&vtbl[i], &empty_vtbl_record, UBI_VTBL_RECORD_SIZE); |
@@ -472,7 +472,7 @@ static struct ubi_vtbl_record *create_empty_lvol(const struct ubi_device *ubi, | |||
472 | 472 | ||
473 | err = create_vtbl(ubi, si, i, vtbl); | 473 | err = create_vtbl(ubi, si, i, vtbl); |
474 | if (err) { | 474 | if (err) { |
475 | kfree(vtbl); | 475 | vfree(vtbl); |
476 | return ERR_PTR(err); | 476 | return ERR_PTR(err); |
477 | } | 477 | } |
478 | } | 478 | } |
@@ -500,19 +500,19 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si, | |||
500 | for (i = 0; i < ubi->vtbl_slots; i++) { | 500 | for (i = 0; i < ubi->vtbl_slots; i++) { |
501 | cond_resched(); | 501 | cond_resched(); |
502 | 502 | ||
503 | if (ubi32_to_cpu(vtbl[i].reserved_pebs) == 0) | 503 | if (be32_to_cpu(vtbl[i].reserved_pebs) == 0) |
504 | continue; /* Empty record */ | 504 | continue; /* Empty record */ |
505 | 505 | ||
506 | vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL); | 506 | vol = kzalloc(sizeof(struct ubi_volume), GFP_KERNEL); |
507 | if (!vol) | 507 | if (!vol) |
508 | return -ENOMEM; | 508 | return -ENOMEM; |
509 | 509 | ||
510 | vol->reserved_pebs = ubi32_to_cpu(vtbl[i].reserved_pebs); | 510 | vol->reserved_pebs = be32_to_cpu(vtbl[i].reserved_pebs); |
511 | vol->alignment = ubi32_to_cpu(vtbl[i].alignment); | 511 | vol->alignment = be32_to_cpu(vtbl[i].alignment); |
512 | vol->data_pad = ubi32_to_cpu(vtbl[i].data_pad); | 512 | vol->data_pad = be32_to_cpu(vtbl[i].data_pad); |
513 | vol->vol_type = vtbl[i].vol_type == UBI_VID_DYNAMIC ? | 513 | vol->vol_type = vtbl[i].vol_type == UBI_VID_DYNAMIC ? |
514 | UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME; | 514 | UBI_DYNAMIC_VOLUME : UBI_STATIC_VOLUME; |
515 | vol->name_len = ubi16_to_cpu(vtbl[i].name_len); | 515 | vol->name_len = be16_to_cpu(vtbl[i].name_len); |
516 | vol->usable_leb_size = ubi->leb_size - vol->data_pad; | 516 | vol->usable_leb_size = ubi->leb_size - vol->data_pad; |
517 | memcpy(vol->name, vtbl[i].name, vol->name_len); | 517 | memcpy(vol->name, vtbl[i].name, vol->name_len); |
518 | vol->name[vol->name_len] = '\0'; | 518 | vol->name[vol->name_len] = '\0'; |
@@ -531,7 +531,8 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si, | |||
531 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) { | 531 | if (vol->vol_type == UBI_DYNAMIC_VOLUME) { |
532 | vol->used_ebs = vol->reserved_pebs; | 532 | vol->used_ebs = vol->reserved_pebs; |
533 | vol->last_eb_bytes = vol->usable_leb_size; | 533 | vol->last_eb_bytes = vol->usable_leb_size; |
534 | vol->used_bytes = vol->used_ebs * vol->usable_leb_size; | 534 | vol->used_bytes = |
535 | (long long)vol->used_ebs * vol->usable_leb_size; | ||
535 | continue; | 536 | continue; |
536 | } | 537 | } |
537 | 538 | ||
@@ -561,7 +562,8 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si, | |||
561 | } | 562 | } |
562 | 563 | ||
563 | vol->used_ebs = sv->used_ebs; | 564 | vol->used_ebs = sv->used_ebs; |
564 | vol->used_bytes = (vol->used_ebs - 1) * vol->usable_leb_size; | 565 | vol->used_bytes = |
566 | (long long)(vol->used_ebs - 1) * vol->usable_leb_size; | ||
565 | vol->used_bytes += sv->last_data_size; | 567 | vol->used_bytes += sv->last_data_size; |
566 | vol->last_eb_bytes = sv->last_data_size; | 568 | vol->last_eb_bytes = sv->last_data_size; |
567 | } | 569 | } |
@@ -578,7 +580,8 @@ static int init_volumes(struct ubi_device *ubi, const struct ubi_scan_info *si, | |||
578 | vol->usable_leb_size = ubi->leb_size; | 580 | vol->usable_leb_size = ubi->leb_size; |
579 | vol->used_ebs = vol->reserved_pebs; | 581 | vol->used_ebs = vol->reserved_pebs; |
580 | vol->last_eb_bytes = vol->reserved_pebs; | 582 | vol->last_eb_bytes = vol->reserved_pebs; |
581 | vol->used_bytes = vol->used_ebs * (ubi->leb_size - vol->data_pad); | 583 | vol->used_bytes = |
584 | (long long)vol->used_ebs * (ubi->leb_size - vol->data_pad); | ||
582 | vol->vol_id = UBI_LAYOUT_VOL_ID; | 585 | vol->vol_id = UBI_LAYOUT_VOL_ID; |
583 | 586 | ||
584 | ubi_assert(!ubi->volumes[i]); | 587 | ubi_assert(!ubi->volumes[i]); |
@@ -718,7 +721,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si) | |||
718 | int i, err; | 721 | int i, err; |
719 | struct ubi_scan_volume *sv; | 722 | struct ubi_scan_volume *sv; |
720 | 723 | ||
721 | empty_vtbl_record.crc = cpu_to_ubi32(0xf116c36b); | 724 | empty_vtbl_record.crc = cpu_to_be32(0xf116c36b); |
722 | 725 | ||
723 | /* | 726 | /* |
724 | * The number of supported volumes is limited by the eraseblock size | 727 | * The number of supported volumes is limited by the eraseblock size |
@@ -783,7 +786,7 @@ int ubi_read_volume_table(struct ubi_device *ubi, struct ubi_scan_info *si) | |||
783 | return 0; | 786 | return 0; |
784 | 787 | ||
785 | out_free: | 788 | out_free: |
786 | kfree(ubi->vtbl); | 789 | vfree(ubi->vtbl); |
787 | for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) | 790 | for (i = 0; i < ubi->vtbl_slots + UBI_INT_VOL_COUNT; i++) |
788 | if (ubi->volumes[i]) { | 791 | if (ubi->volumes[i]) { |
789 | kfree(ubi->volumes[i]); | 792 | kfree(ubi->volumes[i]); |