diff options
Diffstat (limited to 'usr.sbin/nandtool')
-rw-r--r-- | usr.sbin/nandtool/Makefile | 11 | ||||
-rw-r--r-- | usr.sbin/nandtool/nand_erase.c | 114 | ||||
-rw-r--r-- | usr.sbin/nandtool/nand_info.c | 86 | ||||
-rw-r--r-- | usr.sbin/nandtool/nand_read.c | 139 | ||||
-rw-r--r-- | usr.sbin/nandtool/nand_readoob.c | 111 | ||||
-rw-r--r-- | usr.sbin/nandtool/nand_write.c | 143 | ||||
-rw-r--r-- | usr.sbin/nandtool/nand_writeoob.c | 113 | ||||
-rw-r--r-- | usr.sbin/nandtool/nandtool.8 | 188 | ||||
-rw-r--r-- | usr.sbin/nandtool/nandtool.c | 283 | ||||
-rw-r--r-- | usr.sbin/nandtool/nandtool.h | 57 | ||||
-rw-r--r-- | usr.sbin/nandtool/usage.h | 112 |
11 files changed, 1357 insertions, 0 deletions
diff --git a/usr.sbin/nandtool/Makefile b/usr.sbin/nandtool/Makefile new file mode 100644 index 0000000..ae9de2d --- /dev/null +++ b/usr.sbin/nandtool/Makefile @@ -0,0 +1,11 @@ +# $FreeBSD$ + +PROG= nandtool +SRCS= nandtool.c nand_read.c nand_write.c nand_erase.c nand_info.c +SRCS+= nand_readoob.c nand_writeoob.c +BINDIR= /usr/sbin +DPADD= ${LIBGEOM} +LDADD= -lgeom +MAN= nandtool.8 + +.include <bsd.prog.mk> diff --git a/usr.sbin/nandtool/nand_erase.c b/usr.sbin/nandtool/nand_erase.c new file mode 100644 index 0000000..50bfaa6 --- /dev/null +++ b/usr.sbin/nandtool/nand_erase.c @@ -0,0 +1,114 @@ +/*- + * Copyright (c) 2010-2012 Semihalf. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/disk.h> +#include <libgeom.h> +#include <dev/nand/nand_dev.h> +#include "nandtool.h" + +int nand_erase(struct cmd_param *params) +{ + struct chip_param_io chip_params; + char *dev; + int fd = -1, ret = 0; + off_t pos, count; + off_t start, nblocks, i; + int block_size, mult; + + if (!(dev = param_get_string(params, "dev"))) { + fprintf(stderr, "Please supply valid 'dev' parameter.\n"); + return (1); + } + + if (param_has_value(params, "count")) + count = param_get_intx(params, "count"); + else + count = 1; + + if ((fd = g_open(dev, 1)) < 0) { + perrorf("Cannot open %s", dev); + return (1); + } + + if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { + perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); + ret = 1; + goto out; + } + + block_size = chip_params.page_size * chip_params.pages_per_block; + + if (param_has_value(params, "page")) { + pos = chip_params.page_size * param_get_intx(params, "page"); + mult = chip_params.page_size; + } else if (param_has_value(params, "block")) { + pos = block_size * param_get_intx(params, "block"); + mult = block_size; + } else if (param_has_value(params, "pos")) { + pos = param_get_intx(params, "pos"); + mult = 1; + } else { + /* Erase whole chip */ + if (ioctl(fd, DIOCGMEDIASIZE, &count) == -1) { + ret = 1; + goto out; + } + + pos = 0; + mult = 1; + } + + if (pos % block_size) { + fprintf(stderr, "Position must be block-size aligned!\n"); + ret = 1; + goto out; + } + + count *= mult; + start = pos / block_size; + nblocks = count / block_size; + + for (i = 0; i < nblocks; i++) { + if (g_delete(fd, (start + i) * block_size, block_size) == -1) { + perrorf("Cannot erase block %d - probably a bad block", + start + i); + ret = 1; + } + } + +out: + g_close(fd); + + return (ret); +} + diff --git a/usr.sbin/nandtool/nand_info.c b/usr.sbin/nandtool/nand_info.c new file mode 100644 index 0000000..38fe010 --- /dev/null +++ b/usr.sbin/nandtool/nand_info.c @@ -0,0 +1,86 @@ +/*- + * Copyright (c) 2010-2012 Semihalf. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stdio.h> +#include <stdlib.h> +#include <stdint.h> +#include <string.h> +#include <libgeom.h> +#include <sys/disk.h> +#include <dev/nand/nand_dev.h> +#include "nandtool.h" + +int nand_info(struct cmd_param *params) +{ + struct chip_param_io chip_params; + int fd = -1, ret = 0; + int block_size; + off_t chip_size, media_size; + const char *dev; + + if ((dev = param_get_string(params, "dev")) == NULL) { + fprintf(stderr, "Please supply 'dev' parameter, eg. " + "'dev=/dev/gnand0'\n"); + return (1); + } + + if ((fd = g_open(dev, 1)) == -1) { + perrorf("Cannot open %s", dev); + return (1); + } + + if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { + perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); + ret = 1; + goto out; + } + + if (ioctl(fd, DIOCGMEDIASIZE, &media_size) == -1) { + perrorf("Cannot ioctl(DIOCGMEDIASIZE)"); + ret = 1; + goto out; + } + + block_size = chip_params.page_size * chip_params.pages_per_block; + chip_size = block_size * chip_params.blocks; + + printf("Device:\t\t\t%s\n", dev); + printf("Page size:\t\t%d bytes\n", chip_params.page_size); + printf("Block size:\t\t%d bytes (%d KB)\n", block_size, + block_size / 1024); + printf("OOB size per page:\t%d bytes\n", chip_params.oob_size); + printf("Chip size:\t\t%jd MB\n", (uintmax_t)(chip_size / 1024 / 1024)); + printf("Slice size:\t\t%jd MB\n", + (uintmax_t)(media_size / 1024 / 1024)); + +out: + g_close(fd); + + return (ret); +} diff --git a/usr.sbin/nandtool/nand_read.c b/usr.sbin/nandtool/nand_read.c new file mode 100644 index 0000000..5267b7d --- /dev/null +++ b/usr.sbin/nandtool/nand_read.c @@ -0,0 +1,139 @@ +/*- + * Copyright (c) 2010-2012 Semihalf. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <libgeom.h> +#include <sys/disk.h> +#include <dev/nand/nand_dev.h> +#include "nandtool.h" + +int nand_read(struct cmd_param *params) +{ + struct chip_param_io chip_params; + int fd = -1, out_fd = -1, done = 0, ret = 0; + char *dev, *out; + int pos, count, mult, block_size; + uint8_t *buf = NULL; + + if (!(dev = param_get_string(params, "dev"))) { + fprintf(stderr, "You must specify 'dev' parameter\n"); + return (1); + } + + if ((out = param_get_string(params, "out"))) { + out_fd = open(out, O_WRONLY|O_CREAT); + if (out_fd == -1) { + perrorf("Cannot open %s for writing", out); + return (1); + } + } + + if ((fd = g_open(dev, 1)) == -1) { + perrorf("Cannot open %s", dev); + ret = 1; + goto out; + } + + if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { + perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); + ret = 1; + goto out; + } + + block_size = chip_params.page_size * chip_params.pages_per_block; + + if (param_has_value(params, "page")) { + pos = chip_params.page_size * param_get_int(params, "page"); + mult = chip_params.page_size; + } else if (param_has_value(params, "block")) { + pos = block_size * param_get_int(params, "block"); + mult = block_size; + } else if (param_has_value(params, "pos")) { + pos = param_get_int(params, "pos"); + mult = 1; + if (pos % chip_params.page_size) { + fprintf(stderr, "Position must be page-size aligned!\n"); + ret = 1; + goto out; + } + } else { + fprintf(stderr, "You must specify one of: 'block', 'page'," + "'pos' arguments\n"); + ret = 1; + goto out; + } + + if (!(param_has_value(params, "count"))) + count = mult; + else + count = param_get_int(params, "count") * mult; + + if (!(buf = malloc(chip_params.page_size))) { + perrorf("Cannot allocate buffer [size %x]", + chip_params.page_size); + ret = 1; + goto out; + } + + lseek(fd, pos, SEEK_SET); + + while (done < count) { + if ((ret = read(fd, buf, chip_params.page_size)) != + (int32_t)chip_params.page_size) { + perrorf("read error (read %d bytes)", ret); + goto out; + } + + if (out_fd != -1) { + done += ret; + if ((ret = write(out_fd, buf, chip_params.page_size)) != + (int32_t)chip_params.page_size) { + perrorf("write error (written %d bytes)", ret); + ret = 1; + goto out; + } + } else { + hexdumpoffset(buf, chip_params.page_size, done); + done += ret; + } + } + +out: + g_close(fd); + if (out_fd != -1) + close(out_fd); + if (buf) + free(buf); + + return (ret); +} + diff --git a/usr.sbin/nandtool/nand_readoob.c b/usr.sbin/nandtool/nand_readoob.c new file mode 100644 index 0000000..37fd14b --- /dev/null +++ b/usr.sbin/nandtool/nand_readoob.c @@ -0,0 +1,111 @@ +/*- + * Copyright (c) 2010-2012 Semihalf. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <libgeom.h> +#include <sys/types.h> +#include <sys/disk.h> +#include <dev/nand/nand_dev.h> +#include "nandtool.h" + +int nand_read_oob(struct cmd_param *params) +{ + struct chip_param_io chip_params; + struct nand_oob_rw req; + char *dev, *out; + int fd = -1, fd_out = -1, ret = 0; + int page; + uint8_t *buf = NULL; + + if ((page = param_get_int(params, "page")) < 0) { + fprintf(stderr, "You must supply valid 'page' argument.\n"); + return (1); + } + + if (!(dev = param_get_string(params, "dev"))) { + fprintf(stderr, "You must supply 'dev' argument.\n"); + return (1); + } + + if ((out = param_get_string(params, "out"))) { + if ((fd_out = open(out, O_WRONLY | O_CREAT)) == -1) { + perrorf("Cannot open %s", out); + ret = 1; + goto out; + } + } + + if ((fd = g_open(dev, 1)) == -1) { + perrorf("Cannot open %s", dev); + ret = 1; + goto out; + } + + if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { + perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); + ret = 1; + goto out; + } + + buf = malloc(chip_params.oob_size); + if (buf == NULL) { + perrorf("Cannot allocate %d bytes\n", chip_params.oob_size); + ret = 1; + goto out; + } + + req.page = page; + req.len = chip_params.oob_size; + req.data = buf; + + if (ioctl(fd, NAND_IO_OOB_READ, &req) == -1) { + perrorf("Cannot read OOB from %s", dev); + ret = 1; + goto out; + } + + if (fd_out != -1) + write(fd_out, buf, chip_params.oob_size); + else + hexdump(buf, chip_params.oob_size); + +out: + close(fd_out); + + if (fd != -1) + g_close(fd); + if (buf) + free(buf); + + return (ret); +} + diff --git a/usr.sbin/nandtool/nand_write.c b/usr.sbin/nandtool/nand_write.c new file mode 100644 index 0000000..157c6aa --- /dev/null +++ b/usr.sbin/nandtool/nand_write.c @@ -0,0 +1,143 @@ +/*- + * Copyright (c) 2010-2012 Semihalf. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <libgeom.h> +#include <sys/disk.h> +#include <dev/nand/nand_dev.h> +#include "nandtool.h" + +int nand_write(struct cmd_param *params) +{ + struct chip_param_io chip_params; + char *dev, *file; + int in_fd = -1, ret = 0, done = 0; + int fd, block_size, mult, pos, count; + uint8_t *buf = NULL; + + if (!(dev = param_get_string(params, "dev"))) { + fprintf(stderr, "Please supply 'dev' argument.\n"); + return (1); + } + + if (!(file = param_get_string(params, "in"))) { + fprintf(stderr, "Please supply 'in' argument.\n"); + return (1); + } + + if ((fd = g_open(dev, 1)) == -1) { + perrorf("Cannot open %s", dev); + return (1); + } + + if ((in_fd = open(file, O_RDONLY)) == -1) { + perrorf("Cannot open file %s", file); + ret = 1; + goto out; + } + + if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { + perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); + ret = 1; + goto out; + } + + block_size = chip_params.page_size * chip_params.pages_per_block; + + if (param_has_value(params, "page")) { + pos = chip_params.page_size * param_get_int(params, "page"); + mult = chip_params.page_size; + } else if (param_has_value(params, "block")) { + pos = block_size * param_get_int(params, "block"); + mult = block_size; + } else if (param_has_value(params, "pos")) { + pos = param_get_int(params, "pos"); + mult = 1; + if (pos % chip_params.page_size) { + fprintf(stderr, "Position must be page-size " + "aligned!\n"); + ret = 1; + goto out; + } + } else { + fprintf(stderr, "You must specify one of: 'block', 'page'," + "'pos' arguments\n"); + ret = 1; + goto out; + } + + if (!(param_has_value(params, "count"))) + count = mult; + else + count = param_get_int(params, "count") * mult; + + if (!(buf = malloc(chip_params.page_size))) { + perrorf("Cannot allocate buffer [size %x]", + chip_params.page_size); + ret = 1; + goto out; + } + + lseek(fd, pos, SEEK_SET); + + while (done < count) { + if ((ret = read(in_fd, buf, chip_params.page_size)) != + (int32_t)chip_params.page_size) { + if (ret > 0) { + /* End of file ahead, truncate here */ + break; + } else { + perrorf("Cannot read from %s", file); + ret = 1; + goto out; + } + } + + if ((ret = write(fd, buf, chip_params.page_size)) != + (int32_t)chip_params.page_size) { + ret = 1; + goto out; + } + + done += ret; + } + +out: + g_close(fd); + if (in_fd != -1) + close(in_fd); + if (buf) + free(buf); + + return (ret); +} + diff --git a/usr.sbin/nandtool/nand_writeoob.c b/usr.sbin/nandtool/nand_writeoob.c new file mode 100644 index 0000000..53cb32a --- /dev/null +++ b/usr.sbin/nandtool/nand_writeoob.c @@ -0,0 +1,113 @@ +/*- + * Copyright (c) 2010-2012 Semihalf. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <fcntl.h> +#include <libgeom.h> +#include <sys/disk.h> +#include <dev/nand/nand_dev.h> +#include "nandtool.h" + +int nand_write_oob(struct cmd_param *params) +{ + struct chip_param_io chip_params; + struct nand_oob_rw req; + char *dev, *in; + int fd = -1, fd_in = -1, ret = 0; + uint8_t *buf = NULL; + int page; + + if (!(dev = param_get_string(params, "dev"))) { + fprintf(stderr, "Please supply valid 'dev' parameter.\n"); + return (1); + } + + if (!(in = param_get_string(params, "in"))) { + fprintf(stderr, "Please supply valid 'in' parameter.\n"); + return (1); + } + + if ((page = param_get_int(params, "page")) < 0) { + fprintf(stderr, "Please supply valid 'page' parameter.\n"); + return (1); + } + + if ((fd = g_open(dev, 1)) == -1) { + perrorf("Cannot open %s", dev); + return (1); + } + + if ((fd_in = open(in, O_RDONLY)) == -1) { + perrorf("Cannot open %s", in); + ret = 1; + goto out; + } + + if (ioctl(fd, NAND_IO_GET_CHIP_PARAM, &chip_params) == -1) { + perrorf("Cannot ioctl(NAND_IO_GET_CHIP_PARAM)"); + ret = 1; + goto out; + } + + buf = malloc(chip_params.oob_size); + if (buf == NULL) { + perrorf("Cannot allocate %d bytes\n", chip_params.oob_size); + ret = 1; + goto out; + } + + if (read(fd_in, buf, chip_params.oob_size) == -1) { + perrorf("Cannot read from %s", in); + ret = 1; + goto out; + } + + req.page = page; + req.len = chip_params.oob_size; + req.data = buf; + + if (ioctl(fd, NAND_IO_OOB_PROG, &req) == -1) { + perrorf("Cannot write OOB to %s", dev); + ret = 1; + goto out; + } + +out: + g_close(fd); + if (fd_in != -1) + close(fd_in); + if (buf) + free(buf); + + return (ret); +} + + diff --git a/usr.sbin/nandtool/nandtool.8 b/usr.sbin/nandtool/nandtool.8 new file mode 100644 index 0000000..2cc4588 --- /dev/null +++ b/usr.sbin/nandtool/nandtool.8 @@ -0,0 +1,188 @@ +.\" Copyright (c) 2010 Semihalf +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.\" $FreeBSD$ +.\" +.Dd April 10, 2012 +.Dt NANDTOOL 8 +.Os +.Sh NAME +.Nm nandtool +.Nd NAND devices swiss army knife +.Sh SYNOPSIS +.Nm +.Ar command +.Op Ar operands ... +.Sh DESCRIPTION +The +.Nm +utility can be used to perform various operations on +.Xr gnand 4 +devices (read, write, erase, +read and write OOB area and to get info about NAND flash chip). +.Pp +The following commands are available: +.Bl -tag -width ".Cm of Ns = Ns Ar file" +.It Cm read Ns +Read pages from NAND device. +.It Cm write Ns +Write pages to NAND device. +.It Cm erase Ns +Erase blocks. +Requires offset aligned to block granularity. +.It Cm info Ns +Get information about NAND chip (page size, block size, OOB area size, chip size +and media size) +.It Cm readoob Ns +Read OOB area from specified page. +.It Cm writeoob Ns +Write OOB area bound to specified page. +.It Cm help Ns +Get usage info. +.El +.Sh COMMAND read +.Pp +The following operands are available for +.Nm +.Cm read +command: +.Bl -tag -width ".Cm of Ns = Ns Ar file" +.It Cm dev Ns = Ns Ar <path> +Path to a +.Xr gnand 4 +device node, required for all operations. +.It Cm out Ns = Ns Ar <file> +Output file path. If not specified, page contents +will be dumped to stdout in format similar to +.Xr hexdump 1 +.It Cm page Ns = Ns Ar <n> +Offset on device, expressed as page number. +.It Cm block Ns = Ns Ar <n> +Offset on device, expressed as block number. +.It Cm pos Ns = Ns Ar <n> +Offset on device, expressed in bytes (however, must be aligned +to page granularity). +.It Cm count Ns = Ns Ar <n> +Count of objects (pages, blocks, bytes). +.El +.Sh COMMAND readoob +.Bl -tag -width ".Cm of Ns = Ns Ar file" +.Pp +The following operands are available for +.Nm +.Cm readoob +command: +.Pp +.It Cm dev Ns = Ns Ar <path> +Path to NAND device node. +.It Cm page Ns = Ns Ar <n> +Offset on device, expressed as page number. +.It Cm out Ns = Ns Ar <file> +Output file path, optional. +.El +.Sh COMMAND write +.Bl -tag -width ".Cm of Ns = Ns Ar file" +The following operands are available for +.Nm +.Cm write +command: +.It Cm dev Ns = Ns Ar <path> +Path to NAND device node. +.It Cm page Ns = Ns Ar <n> +Offset on device, expressed as page number. +.It Cm block Ns = Ns Ar <n> +Offset on device, expressed as block number. +.It Cm pos Ns = Ns Ar <n> +Offset on device, expressed in bytes (however, must be aligned +to page granularity). +.It Cm in Ns = Ns Ar <file> +Input file path. +.El +.Sh COMMAND writeoob +.Bl -tag -width ".Cm of Ns = Ns Ar file" +The following operands are available for +.Nm +.Cm writeoob +command: +.It Cm dev Ns = Ns Ar <path> +Path to NAND device node. +.It Cm page Ns = Ns Ar <n> +Offset on device, expressed as page number. +.It Cm in Ns = Ns Ar <file> +Input file path. +.El +.Sh COMMAND erase +.Bl -tag -width ".Cm of Ns = Ns Ar file" +The following operands are available for +.Nm +.Cm erase +command: +.It Cm dev Ns = Ns Ar <path> +Path to NAND device node. +.It Cm page Ns = Ns Ar <n> +Offset on device, expressed as page number. +.It Cm block Ns = Ns Ar <n> +Offset on device, expressed as block number. +.It Cm pos Ns = Ns Ar <n> +Offset on device, epressed in bytes (however, must be aligned +to block granularity). +.It Cm count Ns = Ns Ar <n> +Count of objects (pages, blocks, bytes). +.El +.Pp +WARNING: The only required parameter for the \fBerase\fP command is +.Ar dev . +When no other arguments are provided the whole device is erased! +.Sh COMMAND info +.Bl -tag -width ".Cm of Ns = Ns Ar file" +There is only one operand available for +.Nm +.Cm info +command: +.It Cm dev Ns = Ns Ar <path> +Path to NAND device node. +.El +.Sh COMMAND help +.Bl -tag -width ".Cm of Ns = Ns Ar file" +There is only one operand available for +.Nm +.Cm help +command: +.Pp +.It Cm topic Ns = Ns Ar <name> +Help topic. +.El +.Sh EXIT STATUS +.Ex -std +If the supplied argument +.Ar dev +points to a device node other than gnand<num> or gnand.raw<num> both +.Nm +.Cm readoob +and +.Nm +.Cm writeoob +return error. +.Sh SEE ALSO +.Xr gnand 4 diff --git a/usr.sbin/nandtool/nandtool.c b/usr.sbin/nandtool/nandtool.c new file mode 100644 index 0000000..bd7075b --- /dev/null +++ b/usr.sbin/nandtool/nandtool.c @@ -0,0 +1,283 @@ +/*- + * Copyright (c) 2010-2012 Semihalf. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include <sys/cdefs.h> +__FBSDID("$FreeBSD$"); + +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <ctype.h> +#include <sysexits.h> +#include <libgeom.h> +#include "nandtool.h" +#include "usage.h" + +int usage(struct cmd_param *); + +static const struct { + const char *name; + const char *usage; + int (*handler)(struct cmd_param *); +} commands[] = { + { "help", nand_help_usage, usage }, + { "read", nand_read_usage, nand_read }, + { "write", nand_write_usage, nand_write }, + { "erase", nand_erase_usage, nand_erase }, + { "readoob", nand_read_oob_usage, nand_read_oob }, + { "writeoob", nand_write_oob_usage, nand_write_oob }, + { "info", nand_info_usage, nand_info }, + { NULL, NULL, NULL }, +}; + +static char * +_param_get_stringx(struct cmd_param *params, const char *name, int doexit) +{ + int i; + + for (i = 0; params[i].name[0] != '\0'; i++) { + if (!strcmp(params[i].name, name)) + return params[i].value; + } + + if (doexit) { + perrorf("Missing parameter %s", name); + exit(1); + } + return (NULL); +} + +char * +param_get_string(struct cmd_param *params, const char *name) +{ + + return (_param_get_stringx(params, name, 0)); +} + +static int +_param_get_intx(struct cmd_param *params, const char *name, int doexit) +{ + int ret; + char *str = _param_get_stringx(params, name, doexit); + + if (!str) + return (-1); + + errno = 0; + ret = (int)strtol(str, (char **)NULL, 10); + if (errno) { + if (doexit) { + perrorf("Invalid value for parameter %s", name); + exit(1); + } + return (-1); + } + + return (ret); +} + +int +param_get_intx(struct cmd_param *params, const char *name) +{ + + return (_param_get_intx(params, name, 1)); +} + +int +param_get_int(struct cmd_param *params, const char *name) +{ + + return (_param_get_intx(params, name, 0)); +} + +int +param_get_boolean(struct cmd_param *params, const char *name) +{ + char *str = param_get_string(params, name); + + if (!str) + return (0); + + if (!strcmp(str, "true") || !strcmp(str, "yes")) + return (1); + + return (0); +} + +int +param_has_value(struct cmd_param *params, const char *name) +{ + int i; + + for (i = 0; params[i].name[0] != '\0'; i++) { + if (!strcmp(params[i].name, name)) + return (1); + } + + return (0); +} + +int +param_get_count(struct cmd_param *params) +{ + int i; + + for (i = 0; params[i].name[0] != '\0'; i++); + + return (i); +} + +void +hexdumpoffset(uint8_t *buf, int length, int off) +{ + int i, j; + for (i = 0; i < length; i += 16) { + printf("%08x: ", off + i); + + for (j = 0; j < 16; j++) + printf("%02x ", buf[i+j]); + + printf("| "); + + for (j = 0; j < 16; j++) { + printf("%c", isalnum(buf[i+j]) + ? buf[i+j] + : '.'); + } + + printf("\n"); + } +} + +void +hexdump(uint8_t *buf, int length) +{ + + hexdumpoffset(buf, length, 0); +} + +void * +xmalloc(size_t len) +{ + void *ret = malloc(len); + + if (!ret) { + fprintf(stderr, "Cannot allocate buffer of %zd bytes. " + "Exiting.\n", len); + exit(EX_OSERR); + } + + return (ret); +} + +void +perrorf(const char *format, ...) +{ + va_list args; + + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); + fprintf(stderr, ": %s\n", strerror(errno)); +} + +int +usage(struct cmd_param *params) +{ + int i; + + if (!params || !param_get_count(params)) { + fprintf(stderr, "Usage: nandtool <command> [arguments...]\n"); + fprintf(stderr, "Arguments are in form 'name=value'.\n\n"); + fprintf(stderr, "Available commands:\n"); + + for (i = 0; commands[i].name != NULL; i++) + fprintf(stderr, "\t%s\n", commands[i].name); + + fprintf(stderr, "\n"); + fprintf(stderr, "For information about particular command, " + "type:\n"); + fprintf(stderr, "'nandtool help topic=<command>'\n"); + } else if (param_has_value(params, "topic")) { + for (i = 0; commands[i].name != NULL; i++) { + if (!strcmp(param_get_string(params, "topic"), + commands[i].name)) { + fprintf(stderr, commands[i].usage, "nandtool"); + return (0); + } + } + + fprintf(stderr, "No such command\n"); + return (EX_SOFTWARE); + } else { + fprintf(stderr, "Wrong arguments given. Try: 'nandtool help'\n"); + } + + return (EX_USAGE); +} + +int +main(int argc, const char *argv[]) +{ + struct cmd_param *params; + int i, ret, idx; + + if (argc < 2) { + usage(NULL); + return (0); + } + + params = malloc(sizeof(struct cmd_param) * (argc - 1)); + + for (i = 2, idx = 0; i < argc; i++, idx++) { + if (sscanf(argv[i], "%63[^=]=%63s", params[idx].name, + params[idx].value) < 2) { + fprintf(stderr, "Syntax error in argument %d. " + "Argument should be in form 'name=value'.\n", i); + free(params); + return (-1); + } + } + + params[idx].name[0] = '\0'; + params[idx].value[0] = '\0'; + + for (i = 0; commands[i].name != NULL; i++) { + if (!strcmp(commands[i].name, argv[1])) { + ret = commands[i].handler(params); + free(params); + return (ret); + } + } + + free(params); + fprintf(stderr, "Unknown command. Try '%s help'\n", argv[0]); + + return (-1); +} + diff --git a/usr.sbin/nandtool/nandtool.h b/usr.sbin/nandtool/nandtool.h new file mode 100644 index 0000000..639f95e --- /dev/null +++ b/usr.sbin/nandtool/nandtool.h @@ -0,0 +1,57 @@ +/*- + * Copyright (c) 2010-2012 Semihalf. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef __UTILS_H +#define __UTILS_H + +struct cmd_param +{ + char name[64]; + char value[64]; +}; + +char *param_get_string(struct cmd_param *, const char *); +int param_get_int(struct cmd_param *, const char *); +int param_get_intx(struct cmd_param *, const char *); +int param_get_boolean(struct cmd_param *, const char *); +int param_has_value(struct cmd_param *, const char *); +int param_get_count(struct cmd_param *); +void perrorf(const char *, ...); +void hexdumpoffset(uint8_t *, int, int); +void hexdump(uint8_t *, int); +void *xmalloc(size_t); + +/* Command handlers */ +int nand_read(struct cmd_param *); +int nand_write(struct cmd_param *); +int nand_read_oob(struct cmd_param *); +int nand_write_oob(struct cmd_param *); +int nand_erase(struct cmd_param *); +int nand_info(struct cmd_param *); + +#endif /* __UTILS_H */ diff --git a/usr.sbin/nandtool/usage.h b/usr.sbin/nandtool/usage.h new file mode 100644 index 0000000..74e8543 --- /dev/null +++ b/usr.sbin/nandtool/usage.h @@ -0,0 +1,112 @@ +/*- + * Copyright (c) 2010-2012 Semihalf. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#ifndef __USAGE_H +#define __USAGE_H + +static const char nand_help_usage[] = + "Usage: %s help topic=<cmd>\n" + "\n" + "Arguments:\n" + "\tcmd\t- [help|read|write|erase|readoob|writeoob|info]\n" + "\n"; + +static const char nand_read_usage[] = + "Usage: %s read dev=<gnand_device> (block|page|pos)=n [count=n]\n" + "\n" + "Arguments:\n" + "\tdev\t- path to gnand device node\n" + "\tblock\t- starting block or\n" + "\tpage\t- starting page or\n" + "\tpos\t- starting position (in bytes, must be page-aligned)\n" + "\tout\t- output file (hexdump to stdout if not supplied)\n" + "\n" + "Note that you can only specify only one of: 'block', 'page', 'pos'\n" + "parameters at once. 'count' parameter is meaningful in terms of used\n" + "unit (page, block or byte).\n"; + +static const char nand_write_usage[] = + "Usage: %s write dev=<gnand_device> in=<file> (block|page|pos)=n [count=n]\n" + "\n" + "Arguments:\n" + "\tdev\t- path to gnand device node\n" + "\tin\t- path to input file which be writed to gnand\n" + "\tblock\t- starting block or\n" + "\tpage\t- starting page or\n" + "\tpos\t- starting position (in bytes, must be page-aligned)\n" + "\tcount\t- byte/page/block count\n" + "\n" + ""; + +static const char nand_erase_usage[] = + "Usage: %s erase dev=<gnand_device> (block|page|pos)=n [count=n]\n" + "\n" + "Arguments:\n" + "\tdev\t- path to gnand device node\n" + "\tblock\t- starting block or\n" + "\tpage\t- starting page or\n" + "\tpos\t- starting position (in bytes, muse be block-aligned)\n" + "\tcount\t- byte/page/block count\n" + "\n" + "NOTE: position and count for erase operation MUST be block-aligned\n"; + +static const char nand_read_oob_usage[] = + "Usage: %s readoob dev=<gnand_device> page=n [out=file] [count=n]\n" + "\n" + "Arguments:\n" + "\tdev\t- path to gnand device node\n" + "\tpage\t- page (page) number\n" + "\tout\t- outut file (hexdump to stdout if not supplied)\n" + "\tcount\t- page count (default is 1)\n" + "\n" + "If you supply count parameter with value other than 1, data will be\n" + "read from subsequent page's OOB areas\n"; + +static const char nand_write_oob_usage[] = + "Usage: %s writeoob dev=<gnand_device> in=<file> page=n [count=n]\n" + "\n" + "\tdev\t- path to gnand device node\n" + "\tin\t- path to file containing data which will be written\n" + "\tpage\t- page (page) number\n" + "\n" + "If you supply count parameter with value other than 1, data will be\n" + "written to subsequent page's OOB areas\n"; + +static const char nand_info_usage[] = + "Usage: %s info dev=<gnand_device>\n" + "\n" + "Arguments:\n" + "\tdev\t- path to gnand device node\n"; + +static const char nand_stats_usage[] = + "Usage: %s stats dev=<gnand_device> (page|block)=<n>\n" + "\n" + "Arguments:\n" + "\tdev\t- path to gnand device node\n"; + +#endif /* __USAGE_H */ |