Commit e387efbd6535724051364fd78469ef611165e489
Committed by
Tom Rini
1 parent
23ef62d741
Exists in
master
and in
56 other branches
fw_env: fix writing environment for mtd devices
Signed-off-by: Oliver Metz <oliver@freetz.org> Tested-by: Luka Perkov <luka@openwrt.org>
Showing 1 changed file with 42 additions and 28 deletions Side-by-side Diff
tools/env/fw_env.c
| ... | ... | @@ -727,27 +727,39 @@ |
| 727 | 727 | MEMGETBADBLOCK needs 64 bits */ |
| 728 | 728 | int rc; |
| 729 | 729 | |
| 730 | - blocklen = DEVESIZE (dev); | |
| 730 | + /* | |
| 731 | + * For mtd devices only offset and size of the environment do matter | |
| 732 | + */ | |
| 733 | + if (mtd_type == MTD_ABSENT) { | |
| 734 | + blocklen = count; | |
| 735 | + top_of_range = offset + count; | |
| 736 | + erase_len = blocklen; | |
| 737 | + blockstart = offset; | |
| 738 | + block_seek = 0; | |
| 739 | + write_total = blocklen; | |
| 740 | + } else { | |
| 741 | + blocklen = DEVESIZE(dev); | |
| 731 | 742 | |
| 732 | - top_of_range = ((DEVOFFSET(dev) / blocklen) + | |
| 733 | - ENVSECTORS (dev)) * blocklen; | |
| 743 | + top_of_range = ((DEVOFFSET(dev) / blocklen) + | |
| 744 | + ENVSECTORS(dev)) * blocklen; | |
| 734 | 745 | |
| 735 | - erase_offset = (offset / blocklen) * blocklen; | |
| 746 | + erase_offset = (offset / blocklen) * blocklen; | |
| 736 | 747 | |
| 737 | - /* Maximum area we may use */ | |
| 738 | - erase_len = top_of_range - erase_offset; | |
| 748 | + /* Maximum area we may use */ | |
| 749 | + erase_len = top_of_range - erase_offset; | |
| 739 | 750 | |
| 740 | - blockstart = erase_offset; | |
| 741 | - /* Offset inside a block */ | |
| 742 | - block_seek = offset - erase_offset; | |
| 751 | + blockstart = erase_offset; | |
| 752 | + /* Offset inside a block */ | |
| 753 | + block_seek = offset - erase_offset; | |
| 743 | 754 | |
| 744 | - /* | |
| 745 | - * Data size we actually have to write: from the start of the block | |
| 746 | - * to the start of the data, then count bytes of data, and to the | |
| 747 | - * end of the block | |
| 748 | - */ | |
| 749 | - write_total = ((block_seek + count + blocklen - 1) / | |
| 750 | - blocklen) * blocklen; | |
| 755 | + /* | |
| 756 | + * Data size we actually write: from the start of the block | |
| 757 | + * to the start of the data, then count bytes of data, and | |
| 758 | + * to the end of the block | |
| 759 | + */ | |
| 760 | + write_total = ((block_seek + count + blocklen - 1) / | |
| 761 | + blocklen) * blocklen; | |
| 762 | + } | |
| 751 | 763 | |
| 752 | 764 | /* |
| 753 | 765 | * Support data anywhere within erase sectors: read out the complete |
| ... | ... | @@ -818,17 +830,18 @@ |
| 818 | 830 | continue; |
| 819 | 831 | } |
| 820 | 832 | |
| 821 | - erase.start = blockstart; | |
| 822 | - ioctl (fd, MEMUNLOCK, &erase); | |
| 823 | - /* These do not need an explicit erase cycle */ | |
| 824 | - if (mtd_type != MTD_ABSENT && | |
| 825 | - mtd_type != MTD_DATAFLASH) | |
| 826 | - if (ioctl (fd, MEMERASE, &erase) != 0) { | |
| 827 | - fprintf (stderr, "MTD erase error on %s: %s\n", | |
| 828 | - DEVNAME (dev), | |
| 829 | - strerror (errno)); | |
| 830 | - return -1; | |
| 831 | - } | |
| 833 | + if (mtd_type != MTD_ABSENT) { | |
| 834 | + erase.start = blockstart; | |
| 835 | + ioctl(fd, MEMUNLOCK, &erase); | |
| 836 | + /* These do not need an explicit erase cycle */ | |
| 837 | + if (mtd_type != MTD_DATAFLASH) | |
| 838 | + if (ioctl(fd, MEMERASE, &erase) != 0) { | |
| 839 | + fprintf(stderr, | |
| 840 | + "MTD erase error on %s: %s\n", | |
| 841 | + DEVNAME(dev), strerror(errno)); | |
| 842 | + return -1; | |
| 843 | + } | |
| 844 | + } | |
| 832 | 845 | |
| 833 | 846 | if (lseek (fd, blockstart, SEEK_SET) == -1) { |
| 834 | 847 | fprintf (stderr, |
| ... | ... | @@ -847,7 +860,8 @@ |
| 847 | 860 | return -1; |
| 848 | 861 | } |
| 849 | 862 | |
| 850 | - ioctl (fd, MEMLOCK, &erase); | |
| 863 | + if (mtd_type != MTD_ABSENT) | |
| 864 | + ioctl(fd, MEMLOCK, &erase); | |
| 851 | 865 | |
| 852 | 866 | processed += blocklen; |
| 853 | 867 | block_seek = 0; |