Hi, Below is a patch that allows fw_printenv/fw_setenv to also operate on MMC memory.
Thanks, csd >From b835008c9654cce32b11059cde4f339ccd250672 Mon Sep 17 00:00:00 2001 From: Christian Daudt <c...@broadcom.com> Date: Mon, 19 Dec 2011 17:50:18 -0800 Subject: [PATCH] Add support for MMC to fw_printenv/setenv This patch checks if the fd is MTD and if not (using an MTD-specific IOCTL) and skips the flash unlock/erase/lock sequence if it is not MTD. - fd_is_mtd function added to determine MTD/MMC - flash_write_block made to not try MTD operations if mtd_type == MTD_ABSENT - flash_read works with MMC devices now. Signed-off-by: Christian Daudt <c...@broadcom.com> --- tools/env/fw_env.c | 100 +++++++++++++++++++++++++++++++++++---------------- 1 files changed, 68 insertions(+), 32 deletions(-) diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 996682e..b7aa771 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -211,6 +211,27 @@ static int flash_io (int mode); static char *envmatch (char * s1, char * s2); static int parse_config (void); + +/* + * Returns 1 if it is MTD and 0 if it is not MTD + */ +static int fd_is_mtd(int fd) +{ + struct mtd_info_user mtdinfo; + int rc; + + rc = ioctl (fd, MEMGETINFO, &mtdinfo); + if (rc < 0) { + // Failed MEMGETINFO, not MTD + return 0; + } else { + // Succeeded, MTD + return 1; + } +} + + + #if defined(CONFIG_FILE) static int get_config (char *); #endif @@ -836,31 +857,33 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, /* This only runs once on NOR flash and SPI-dataflash */ while (processed < write_total) { - rc = flash_bad_block (fd, mtd_type, &blockstart); - if (rc < 0) /* block test failed */ - return rc; + if (mtd_type != MTD_ABSENT) { + rc = flash_bad_block (fd, mtd_type, &blockstart); + if (rc < 0) /* block test failed */ + return rc; - if (blockstart + erasesize > top_of_range) { - fprintf (stderr, "End of range reached, aborting\n"); - return -1; - } + if (blockstart + erasesize > top_of_range) { + fprintf (stderr, "End of range reached, aborting\n"); + return -1; + } - if (rc) { /* block is bad */ - blockstart += blocklen; - continue; - } + if (rc) { /* block is bad */ + blockstart += blocklen; + continue; + } - erase.start = blockstart; - ioctl (fd, MEMUNLOCK, &erase); + erase.start = blockstart; + ioctl (fd, MEMUNLOCK, &erase); - /* Dataflash does not need an explicit erase cycle */ - if (mtd_type != MTD_DATAFLASH) - if (ioctl (fd, MEMERASE, &erase) != 0) { - fprintf (stderr, "MTD erase error on %s: %s\n", - DEVNAME (dev), - strerror (errno)); - return -1; - } + /* Dataflash does not need an explicit erase cycle */ + if (mtd_type != MTD_DATAFLASH) + 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) { fprintf (stderr, @@ -878,7 +901,8 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count, return -1; } - ioctl (fd, MEMLOCK, &erase); + if (mtd_type != MTD_ABSENT) + ioctl (fd, MEMLOCK, &erase); processed += blocklen; block_seek = 0; @@ -964,18 +988,30 @@ static int flash_read (int fd) { struct mtd_info_user mtdinfo; int rc; + int is_mtd; - rc = ioctl (fd, MEMGETINFO, &mtdinfo); - if (rc < 0) { - perror ("Cannot get MTD information"); - return -1; - } + is_mtd = fd_is_mtd(fd); - if (mtdinfo.type != MTD_NORFLASH && - mtdinfo.type != MTD_NANDFLASH && - mtdinfo.type != MTD_DATAFLASH) { - fprintf (stderr, "Unsupported flash type %u\n", mtdinfo.type); - 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 && + mtdinfo.type != MTD_DATAFLASH) { + fprintf (stderr, "Unsupported flash type %u\n", mtdinfo.type); + return -1; + } + } else { + /* + * Kinda hacky assuming !MTD means == MMC + * but seems to be the easiest way to + * determine that. + */ + mtdinfo.type = MTD_ABSENT; } DEVTYPE(dev_current) = mtdinfo.type; -- 1.7.1 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot