diff options
Diffstat (limited to 'package/cfgfs/src/mtd.c')
-rw-r--r-- | package/cfgfs/src/mtd.c | 379 |
1 files changed, 0 insertions, 379 deletions
diff --git a/package/cfgfs/src/mtd.c b/package/cfgfs/src/mtd.c deleted file mode 100644 index 6812c5e31..000000000 --- a/package/cfgfs/src/mtd.c +++ /dev/null @@ -1,379 +0,0 @@ -/* - * mtd - simple memory technology device manipulation tool - * - * Copyright (c) 2006, 2007 Thorsten Glaser <tg@freewrt.org> - * Copyright (C) 2005 Waldemar Brodkorb <wbx@freewrt.org>, - * Felix Fietkau <nbd@openwrt.org> - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation; either version 2 - * of the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - * - * The code is based on the linux-mtd examples. - */ - -#include <sys/param.h> -#include <sys/types.h> -#include <sys/ioctl.h> -#include <sys/mount.h> -#include <sys/stat.h> -#include <sys/ioctl.h> -#include <sys/syscall.h> -#include <limits.h> -#include <unistd.h> -#include <stdbool.h> -#include <stdlib.h> -#include <stdio.h> -#include <stdint.h> -#include <fcntl.h> -#include <errno.h> -#include <error.h> -#include <err.h> -#include <time.h> -#include <string.h> - -#include <mtd/mtd-user.h> - -#define BUFSIZE (16 * 1024) -#define MAX_ARGS 8 - -#define DEBUG - -int mtd_check(char *); -int mtd_unlock(const char *); -int mtd_open(const char *, int); -int mtd_erase(const char *); -int mtd_write(int, const char *, int, bool); -void usage(void) __attribute__((noreturn)); - -char buf[BUFSIZE]; -int buflen; - -int -mtd_check(char *mtd) -{ - struct mtd_info_user mtdInfo; - int fd; - - fd = mtd_open(mtd, O_RDWR | O_SYNC); - if(fd < 0) { - fprintf(stderr, "Could not open mtd device: %s\n", mtd); - return 0; - } - - if(ioctl(fd, MEMGETINFO, &mtdInfo)) { - fprintf(stderr, "Could not get MTD device info from %s\n", mtd); - close(fd); - return 0; - } - - close(fd); - return 1; -} - -int -mtd_unlock(const char *mtd) -{ - int fd; - struct mtd_info_user mtdInfo; - struct erase_info_user mtdLockInfo; - - fd = mtd_open(mtd, O_RDWR | O_SYNC); - if(fd < 0) { - fprintf(stderr, "Could not open mtd device: %s\n", mtd); - exit(1); - } - - if(ioctl(fd, MEMGETINFO, &mtdInfo)) { - fprintf(stderr, "Could not get MTD device info from %s\n", mtd); - close(fd); - exit(1); - } - - mtdLockInfo.start = 0; - mtdLockInfo.length = mtdInfo.size; - if(ioctl(fd, MEMUNLOCK, &mtdLockInfo)) { - close(fd); - return 0; - } - - close(fd); - return 0; -} - -int -mtd_open(const char *mtd, int flags) -{ - FILE *fp; - char dev[PATH_MAX]; - int i; - - if ((fp = fopen("/proc/mtd", "r"))) { - while (fgets(dev, sizeof(dev), fp)) { - if (sscanf(dev, "mtd%d:", &i) && strstr(dev, mtd)) { - snprintf(dev, sizeof(dev), "/dev/mtd%d", i); - fclose(fp); - return open(dev, flags); - } - } - fclose(fp); - } - - return open(mtd, flags); -} - -int -mtd_erase(const char *mtd) -{ - int fd; - struct mtd_info_user mtdInfo; - struct erase_info_user mtdEraseInfo; - - fd = mtd_open(mtd, O_RDWR | O_SYNC); - if(fd < 0) { - fprintf(stderr, "Could not open mtd device: %s\n", mtd); - exit(1); - } - - if(ioctl(fd, MEMGETINFO, &mtdInfo)) { - fprintf(stderr, "Could not get MTD device info from %s\n", mtd); - close(fd); - exit(1); - } - - mtdEraseInfo.length = mtdInfo.erasesize; - - for (mtdEraseInfo.start = 0; - mtdEraseInfo.start < mtdInfo.size; - mtdEraseInfo.start += mtdInfo.erasesize) { - - ioctl(fd, MEMUNLOCK, &mtdEraseInfo); - if(ioctl(fd, MEMERASE, &mtdEraseInfo)) { - fprintf(stderr, "Could not erase MTD device: %s\n", mtd); - close(fd); - exit(1); - } - } - - close(fd); - return 0; - -} - -int -mtd_write(int imagefd, const char *mtd, int quiet, bool do_erase) -{ - int fd, result; - size_t r, w, e; - struct mtd_info_user mtdInfo; - struct erase_info_user mtdEraseInfo; - - fd = mtd_open(mtd, O_RDWR | O_SYNC); - if(fd < 0) { - fprintf(stderr, "Could not open mtd device: %s\n", mtd); - exit(1); - } - - if(ioctl(fd, MEMGETINFO, &mtdInfo)) { - fprintf(stderr, "Could not get MTD device info from %s\n", mtd); - close(fd); - exit(1); - } - - r = w = e = 0; - if (!quiet) - fprintf(stderr, " [ ]"); - - for (;;) { - /* buffer may contain data already (from trx check) */ - r = buflen; - r += read(imagefd, buf + buflen, BUFSIZE - buflen); - w += r; - - /* EOF */ - if (r <= 0) break; - - /* need to erase the next block before writing data to it */ - while (do_erase && w > e) { - mtdEraseInfo.start = e; - mtdEraseInfo.length = mtdInfo.erasesize; - - if (!quiet) - fprintf(stderr, "\b\b\b[e]"); - /* erase the chunk */ - if (ioctl (fd,MEMERASE,&mtdEraseInfo) < 0) { - fprintf(stderr, "Erasing mtd failed: %s\n", mtd); - exit(1); - } - e += mtdInfo.erasesize; - } - - if (!quiet) - fprintf(stderr, "\b\b\b[w]"); - - if ((result = write(fd, buf, r)) < (ssize_t)r) { - if (result < 0) { - fprintf(stderr, "Error writing image.\n"); - exit(1); - } else { - fprintf(stderr, "Insufficient space.\n"); - exit(1); - } - } - - buflen = 0; - } - if (!quiet) - fprintf(stderr, "\b\b\b\b"); - - close(fd); - return 0; -} - -void -usage(void) -{ - fprintf(stderr, "Usage: mtd [<options> ...] <command> [<arguments> ...] <device>\n\n" - "The device is in the format of mtdX (eg: mtd4) or its label.\n" - "mtd recognises these commands:\n" - " unlock unlock the device\n" - " erase erase all data on device\n" - " write <imagefile>|- write <imagefile> (use - for stdin) to device\n" - "Following options are available:\n" - " -q quiet mode (once: no [w] on writing,\n" - " twice: no status messages)\n" - " -e <device> erase <device> before executing the command\n\n" - "Example: To write linux.trx to mtd1 labeled as linux\n" - " mtd write linux.trx linux\n\n"); - exit(1); -} - -int -main(int argc, char **argv) -{ - int ch, i, imagefd = -1, quiet, unlocked; - char *erase[MAX_ARGS], *device; - const char *imagefile = NULL; - enum { - CMD_ERASE, - CMD_WRITE, - CMD_UNLOCK - } cmd; - - erase[0] = NULL; - buflen = 0; - quiet = 0; - - while ((ch = getopt(argc, argv, "Fqe:")) != -1) - switch (ch) { - case 'F': - quiet = 1; - /* FALLTHROUGH */ - case 'q': - quiet++; - break; - case 'e': - i = 0; - while ((erase[i] != NULL) && ((i + 1) < MAX_ARGS)) - i++; - - erase[i++] = optarg; - erase[i] = NULL; - break; - - case '?': - default: - usage(); - } - argc -= optind; - argv += optind; - - if (argc < 2) - usage(); - - if ((strcmp(argv[0], "unlock") == 0) && (argc == 2)) { - cmd = CMD_UNLOCK; - device = argv[1]; - } else if ((strcmp(argv[0], "erase") == 0) && (argc == 2)) { - cmd = CMD_ERASE; - device = argv[1]; - } else if ((strcmp(argv[0], "write") == 0) && (argc == 3)) { - cmd = CMD_WRITE; - device = argv[2]; - - if (strcmp(argv[1], "-") == 0) { - imagefile = "<stdin>"; - imagefd = 0; - } else { - imagefile = argv[1]; - if ((imagefd = open(argv[1], O_RDONLY)) < 0) { - fprintf(stderr, "Couldn't open image file: %s!\n", imagefile); - exit(1); - } - } - - if (!mtd_check(device)) { - fprintf(stderr, "Can't open device for writing!\n"); - exit(1); - } - } else { - usage(); - } - - sync(); - - i = 0; - unlocked = 0; - while (erase[i] != NULL) { - if (quiet < 2) - fprintf(stderr, "Unlocking %s ...\n", erase[i]); - mtd_unlock(erase[i]); - if (quiet < 2) - fprintf(stderr, "Erasing %s ...\n", erase[i]); - mtd_erase(erase[i]); - if (strcmp(erase[i], device) == 0) - /* this means that <device> is unlocked and erased */ - unlocked = 1; - i++; - } - - if (!unlocked) { - if (quiet < 2) - fprintf(stderr, "Unlocking %s ...\n", device); - mtd_unlock(device); - } - - switch (cmd) { - case CMD_UNLOCK: - break; - case CMD_ERASE: - if (unlocked) { - fprintf(stderr, "Already erased: %s\n", device); - break; - } - if (quiet < 2) - fprintf(stderr, "Erasing %s ...\n", device); - mtd_erase(device); - break; - case CMD_WRITE: - if (quiet < 2) - fprintf(stderr, "Writing from %s to %s ... ", imagefile, device); - mtd_write(imagefd, device, quiet, (unlocked == 0)); - if (quiet < 2) - fprintf(stderr, "\n"); - break; - } - - sync(); - return 0; -} |