diff options
Diffstat (limited to 'package/boot/uboot-envtools/patches/011-fw_env-keep-calling-read-until-whole-flash-block-is-.patch')
| -rw-r--r-- | package/boot/uboot-envtools/patches/011-fw_env-keep-calling-read-until-whole-flash-block-is-.patch | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/package/boot/uboot-envtools/patches/011-fw_env-keep-calling-read-until-whole-flash-block-is-.patch b/package/boot/uboot-envtools/patches/011-fw_env-keep-calling-read-until-whole-flash-block-is-.patch new file mode 100644 index 00000000000..af1c32fe91c --- /dev/null +++ b/package/boot/uboot-envtools/patches/011-fw_env-keep-calling-read-until-whole-flash-block-is-.patch @@ -0,0 +1,75 @@ +From 9e3003f79d168eac7ee65cd457e3904e2fb4eea8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Rafa=C5=82=20Mi=C5=82ecki?= <rafal@milecki.pl> +Date: Wed, 13 Dec 2023 13:13:54 +0100 +Subject: [PATCH] fw_env: keep calling read() until whole flash block is read +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +It's totally valid for read() to provide less bytes than requested +maximum. It may happen if there is no more data available yet or source +pushes data in small chunks. + +This actually happens when trying to read env data from NVMEM device. +Kernel may provide NVMEM content in page size parts (like 4096 B). + +This fixes warnings like: +Warning on /sys/bus/nvmem/devices/u-boot-env0/nvmem: Attempted to read 16384 bytes but got 4096 +Warning on /sys/bus/nvmem/devices/u-boot-env0/nvmem: Attempted to read 12288 bytes but got 4096 +Warning on /sys/bus/nvmem/devices/u-boot-env0/nvmem: Attempted to read 8192 bytes but got 4096 + +Since the main loop in flash_read_buf() is used to read blocks this +patch adds a new nested one. + +Signed-off-by: Rafał Miłecki <rafal@milecki.pl> +--- + tools/env/fw_env.c | 34 +++++++++++++++------------------- + 1 file changed, 15 insertions(+), 19 deletions(-) + +--- a/tools/env/fw_env.c ++++ b/tools/env/fw_env.c +@@ -948,29 +948,25 @@ static int flash_read_buf(int dev, int f + */ + lseek(fd, blockstart + block_seek, SEEK_SET); + +- rc = read(fd, buf + processed, readlen); +- if (rc == -1) { +- fprintf(stderr, "Read error on %s: %s\n", +- DEVNAME(dev), strerror(errno)); +- return -1; +- } ++ while (readlen) { ++ rc = read(fd, buf + processed, readlen); ++ if (rc == -1) { ++ fprintf(stderr, "Read error on %s: %s\n", ++ DEVNAME(dev), strerror(errno)); ++ return -1; ++ } + #ifdef DEBUG +- fprintf(stderr, "Read 0x%x bytes at 0x%llx on %s\n", +- rc, (unsigned long long)blockstart + block_seek, +- DEVNAME(dev)); ++ fprintf(stderr, "Read 0x%x bytes at 0x%llx on %s\n", ++ rc, (unsigned long long)blockstart + block_seek, ++ DEVNAME(dev)); + #endif +- processed += rc; +- if (rc != readlen) { +- fprintf(stderr, +- "Warning on %s: Attempted to read %zd bytes but got %d\n", +- DEVNAME(dev), readlen, rc); ++ processed += rc; + readlen -= rc; +- block_seek += rc; +- } else { +- blockstart += blocklen; +- readlen = min(blocklen, count - processed); +- block_seek = 0; + } ++ ++ blockstart += blocklen; ++ readlen = min(blocklen, count - processed); ++ block_seek = 0; + } + + return processed; |
