From: Loïc Minier <loic.min...@linaro.org> Track st_mode and use it to skip ioctls on file-backed fds. This allows writing to regular files transparently.
Signed-off-by: Loïc Minier <loic.min...@linaro.org> Tested-by: Steve Sakoman <steve.sako...@linaro.org> --- tools/env/fw_env.c | 92 ++++++++++++++++++++++++++++++++++----------------- 1 files changed, 61 insertions(+), 31 deletions(-) diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 75f6a98..d2f9748 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -60,6 +60,7 @@ struct envdev_s { ulong erase_size; /* device erase size */ ulong env_sectors; /* number of environment sectors */ uint8_t mtd_type; /* type of the MTD device */ + mode_t st_mode; /* protection / file type */ }; static struct envdev_s envdevices[2] = @@ -78,6 +79,7 @@ static int dev_current; #define DEVESIZE(i) envdevices[(i)].erase_size #define ENVSECTORS(i) envdevices[(i)].env_sectors #define DEVTYPE(i) envdevices[(i)].mtd_type +#define STMODE(i) envdevices[(i)].st_mode #define CONFIG_ENV_SIZE ENVSIZE(dev_current) @@ -633,8 +635,12 @@ int fw_parse_script(char *fname) * > 0 - block is bad * < 0 - failed to test */ -static int flash_bad_block (int fd, uint8_t mtd_type, loff_t *blockstart) +static int flash_bad_block (int fd, uint8_t mtd_type, loff_t *blockstart, + int is_mtd) { + if (!is_mtd) + return 0; + if (mtd_type == MTD_NANDFLASH) { int badblock = ioctl (fd, MEMGETBADBLOCK, blockstart); @@ -661,7 +667,7 @@ static int flash_bad_block (int fd, uint8_t mtd_type, loff_t *blockstart) * the DEVOFFSET (dev) block. On NOR the loop is only run once. */ static int flash_read_buf (int dev, int fd, void *buf, size_t count, - off_t offset, uint8_t mtd_type) + off_t offset, uint8_t mtd_type, int is_mtd) { size_t blocklen; /* erase / write length - one block on NAND, 0 on NOR */ @@ -683,7 +689,7 @@ static int flash_read_buf (int dev, int fd, void *buf, size_t count, /* Offset inside a block */ block_seek = offset - blockstart; - if (mtd_type == MTD_NANDFLASH) { + if (!is_mtd || mtd_type == MTD_NANDFLASH) { /* * NAND: calculate which blocks we are reading. We have * to read one block at a time to skip bad blocks. @@ -707,7 +713,7 @@ static int flash_read_buf (int dev, int fd, void *buf, size_t count, /* This only runs once on NOR flash */ while (processed < count) { - rc = flash_bad_block (fd, mtd_type, &blockstart); + rc = flash_bad_block (fd, mtd_type, &blockstart, is_mtd); if (rc < 0) /* block test failed */ return -1; @@ -754,7 +760,7 @@ static int flash_read_buf (int dev, int fd, void *buf, size_t count, * the whole data at once. */ static int flash_write_buf (int dev, int fd, void *buf, size_t count, - off_t offset, uint8_t mtd_type) + off_t offset, uint8_t mtd_type, int is_mtd) { void *data; struct erase_info_user erase; @@ -812,7 +818,7 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, } rc = flash_read_buf (dev, fd, data, write_total, erase_offset, - mtd_type); + mtd_type, is_mtd); if (write_total != rc) return -1; @@ -826,7 +832,7 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, data = buf; } - if (mtd_type == MTD_NANDFLASH) { + if (!is_mtd || mtd_type == MTD_NANDFLASH) { /* * NAND: calculate which blocks we are writing. We have * to write one block at a time to skip bad blocks. @@ -840,7 +846,7 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, /* This only runs once on NOR flash */ while (processed < write_total) { - rc = flash_bad_block (fd, mtd_type, &blockstart); + rc = flash_bad_block (fd, mtd_type, &blockstart, is_mtd); if (rc < 0) /* block test failed */ return rc; @@ -854,14 +860,16 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, continue; } - erase.start = blockstart; - ioctl (fd, MEMUNLOCK, &erase); + if (is_mtd) { + erase.start = blockstart; + ioctl (fd, MEMUNLOCK, &erase); - if (ioctl (fd, MEMERASE, &erase) != 0) { - fprintf (stderr, "MTD erase error on %s: %s\n", - DEVNAME (dev), - strerror (errno)); - return -1; + if (ioctl (fd, MEMERASE, &erase) != 0) { + fprintf (stderr, "MTD erase error on %s: %s\n", + DEVNAME (dev), + strerror (errno)); + return -1; + } } if (lseek (fd, blockstart, SEEK_SET) == -1) { @@ -880,7 +888,9 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, return -1; } - ioctl (fd, MEMLOCK, &erase); + if (is_mtd) { + ioctl (fd, MEMLOCK, &erase); + } processed += blocklen; block_seek = 0; @@ -919,7 +929,8 @@ static int flash_flag_obsolete (int dev, int fd, off_t offset) return rc; } -static int flash_write (int fd_current, int fd_target, int dev_target) +static int flash_write (int fd_current, int fd_target, int dev_target, + int is_mtd) { int rc; @@ -944,7 +955,7 @@ static int flash_write (int fd_current, int fd_target, int dev_target) #endif rc = flash_write_buf (dev_target, fd_target, environment.image, CONFIG_ENV_SIZE, DEVOFFSET (dev_target), - DEVTYPE(dev_target)); + DEVTYPE(dev_target), is_mtd); if (rc < 0) return rc; @@ -962,26 +973,32 @@ static int flash_write (int fd_current, int fd_target, int dev_target) return 0; } -static int flash_read (int fd) +static int flash_read (int fd, int is_mtd) { struct mtd_info_user mtdinfo; int rc; - rc = ioctl (fd, MEMGETINFO, &mtdinfo); - if (rc < 0) { - perror ("Cannot get MTD information"); - return -1; - } + if (is_mtd) { + rc = ioctl (fd, MEMGETINFO, &mtdinfo); + if (rc < 0) { + perror ("Cannot get MTD information"); + return -1; + } - if (mtdinfo.type != MTD_NORFLASH && mtdinfo.type != MTD_NANDFLASH) { - fprintf (stderr, "Unsupported flash type %u\n", mtdinfo.type); - return -1; + if (mtdinfo.type != MTD_NORFLASH && + mtdinfo.type != MTD_NANDFLASH) { + fprintf (stderr, + "Unsupported flash type %u\n", + mtdinfo.type); + return -1; } - DEVTYPE(dev_current) = mtdinfo.type; + DEVTYPE(dev_current) = mtdinfo.type; + } rc = flash_read_buf (dev_current, fd, environment.image, CONFIG_ENV_SIZE, - DEVOFFSET (dev_current), mtdinfo.type); + DEVOFFSET (dev_current), DEVTYPE(dev_current), + is_mtd); return (rc != CONFIG_ENV_SIZE) ? -1 : 0; } @@ -989,6 +1006,7 @@ static int flash_read (int fd) static int flash_io (int mode) { int fd_current, fd_target, rc, dev_target; + int is_mtd; /* dev_current: fd_current, erase_current */ fd_current = open (DEVNAME (dev_current), mode); @@ -999,6 +1017,16 @@ static int flash_io (int mode) return -1; } + /* Check whether fd is a MTD device, otherwise assume regular file */ + if (S_ISREG (STMODE (dev_current))) + is_mtd = 0; + else if (S_ISCHR (STMODE (dev_current))) + is_mtd = 1; + else + fprintf (stderr, + "%s has unknown file type: %u\n", + DEVNAME (dev_current), STMODE (dev_current)); + if (mode == O_RDWR) { if (HaveRedundEnv) { /* switch to next partition for writing */ @@ -1018,7 +1046,7 @@ static int flash_io (int mode) fd_target = fd_current; } - rc = flash_write (fd_current, fd_target, dev_target); + rc = flash_write (fd_current, fd_target, dev_target, is_mtd); if (HaveRedundEnv) { if (close (fd_target)) { @@ -1030,7 +1058,7 @@ static int flash_io (int mode) } } } else { - rc = flash_read (fd_current); + rc = flash_read (fd_current, is_mtd); } exit: @@ -1258,6 +1286,7 @@ static int parse_config () DEVNAME (0), strerror (errno)); return -1; } + STMODE(0) = st.st_mode; if (HaveRedundEnv && stat (DEVNAME (1), &st)) { fprintf (stderr, @@ -1265,6 +1294,7 @@ static int parse_config () DEVNAME (1), strerror (errno)); return -1; } + STMODE(1) = st.st_mode; return 0; } -- 1.7.0.4 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot