Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 10 Mar 2012 02:40:02 +0000 (UTC)
From:      Grzegorz Bernacki <gber@FreeBSD.org>
To:        src-committers@freebsd.org, svn-src-projects@freebsd.org
Subject:   svn commit: r232759 - projects/nand/usr.sbin/nandtool
Message-ID:  <201203100240.q2A2e2fd035876@svn.freebsd.org>

next in thread | raw e-mail | index | archive | help
Author: gber
Date: Sat Mar 10 02:40:01 2012
New Revision: 232759
URL: http://svn.freebsd.org/changeset/base/232759

Log:
  Add nandtool utility.
  
  The nandtool utility can be used to perform various operations on
  gnand(4) devices (read, write, erase, read and write OOB area and to get
  info about NAND flash chip).
  
  Obtained from: Semihalf
  Supported by:  FreeBSD Foundation, Juniper Networks

Added:
  projects/nand/usr.sbin/nandtool/
  projects/nand/usr.sbin/nandtool/Makefile
  projects/nand/usr.sbin/nandtool/nand_erase.c
  projects/nand/usr.sbin/nandtool/nand_info.c
  projects/nand/usr.sbin/nandtool/nand_read.c
  projects/nand/usr.sbin/nandtool/nand_readoob.c
  projects/nand/usr.sbin/nandtool/nand_write.c
  projects/nand/usr.sbin/nandtool/nand_writeoob.c
  projects/nand/usr.sbin/nandtool/nandtool.8
  projects/nand/usr.sbin/nandtool/nandtool.c
  projects/nand/usr.sbin/nandtool/nandtool.h
  projects/nand/usr.sbin/nandtool/usage.h

Added: projects/nand/usr.sbin/nandtool/Makefile
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/nand/usr.sbin/nandtool/Makefile	Sat Mar 10 02:40:01 2012	(r232759)
@@ -0,0 +1,11 @@
+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
+
+WARNS?=	7
+
+.include <bsd.prog.mk>

Added: projects/nand/usr.sbin/nandtool/nand_erase.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/nand/usr.sbin/nandtool/nand_erase.c	Sat Mar 10 02:40:01 2012	(r232759)
@@ -0,0 +1,117 @@
+/*-
+ * 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 <errno.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <sys/disk.h>
+#include <libgeom.h>
+#include <dev/nand/nand_cdev.h>
+#include "nandtool.h"
+
+int nand_erase(struct cmd_param *params)
+{
+	char *dev;
+	int fd = -1;
+	off_t pos, count, err = 0;
+	off_t start, nblocks, i;
+	int page_size, block_size, mult;
+
+	if (!(dev = param_get_string(params, "dev"))) {
+		fprintf(stderr, "Please supply valid 'dev' parameter.\n");
+		return (EINVAL);
+	}
+
+	if ((fd = g_open(dev, 1)) < 0) {
+		perrorf("Cannot open %s", dev);
+		return (errno);
+	}
+
+	if ((count = param_get_int(params, "count")) < 0)
+		count = 1;
+
+	if (ioctl(fd, DIOCGSECTORSIZE, &page_size)) {
+		perrorf("Cannot get page size for %s", dev);
+		err = errno;
+		goto out;
+	}
+
+	if (ioctl(fd, DIOCNBLKSIZE, &block_size)) {
+		perrorf("Cannot get block size for %s", dev);
+		err = errno;
+		goto out;
+	}
+
+	if (param_has_value(params, "page")) {
+		pos = page_size * param_get_int(params, "page");
+		mult = 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;
+
+	} else {
+		/* Erase all chip */
+		if (ioctl(fd, DIOCGMEDIASIZE, &count) < 0) {
+			err = errno;
+			goto out;
+		}
+
+		pos = 0;
+		mult = 1;
+	}
+
+	if (pos % block_size) {
+		fprintf(stderr, "Position must be block-size aligned!\n");
+		err = errno;
+		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) < 0) {
+			perrorf("Cannot erase block %d - probably a bad block",
+			    start + i);
+		}
+	}
+
+out:
+	if (fd)
+		g_close(fd);
+
+	return (err);
+}
+

Added: projects/nand/usr.sbin/nandtool/nand_info.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/nand/usr.sbin/nandtool/nand_info.c	Sat Mar 10 02:40:01 2012	(r232759)
@@ -0,0 +1,92 @@
+/*-
+ * 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 <errno.h>
+#include <libgeom.h>
+#include <sys/disk.h>
+#include <dev/nand/nand_cdev.h>
+#include "nandtool.h"
+
+int nand_info(struct cmd_param *params)
+{
+	int fd = -1, page_size, block_size, oob_size, err = 0;
+	off_t 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 (EINVAL);
+	}
+
+	if ((fd = g_open(dev, 1)) < 0) {
+		perrorf("Cannot open %s", dev);
+		return (errno);
+	}
+
+	if (ioctl(fd, DIOCGSECTORSIZE, &page_size) < 0) {
+		perrorf("Cannot ioctl(DIOCGSECTORSIZE)");
+		err = errno;
+		goto out;
+	}
+
+	if (ioctl(fd, DIOCNBLKSIZE, &block_size) < 0) {
+		perrorf("Cannot ioctl(DIOCGSECTORSIZE)");
+		err = errno;
+		goto out;
+	}
+
+	if (ioctl(fd, DIOCNOOBSIZE, &oob_size) < 0) {
+		perrorf("Cannot ioctl(DIOCGSECTORSIZE)");
+		err = errno;
+		goto out;
+	}
+
+	if (ioctl(fd, DIOCGMEDIASIZE, &media_size) < 0) {
+		perrorf("Cannot ioctl(DIOCGMEDIASIZE)");
+		err = errno;
+		goto out;
+	}
+
+	printf("Device:\t\t\t%s\n", dev);
+	printf("Page size:\t\t%d bytes\n", 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", oob_size);
+	printf("Chip size:\t\t%jd MB\n", (uintmax_t)(media_size / 1024 / 1024));
+
+out:
+	if (fd != -1)
+		g_close(fd);
+
+	return (err);
+}
+

Added: projects/nand/usr.sbin/nandtool/nand_read.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/nand/usr.sbin/nandtool/nand_read.c	Sat Mar 10 02:40:01 2012	(r232759)
@@ -0,0 +1,141 @@
+/*-
+ * 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 <errno.h>
+#include <fcntl.h>
+#include <libgeom.h>
+#include <sys/disk.h>
+#include <dev/nand/nand_cdev.h>
+#include "nandtool.h"
+
+int nand_read(struct cmd_param *params)
+{
+	int fd = -1, out_fd = -1, ret;
+	char *dev, *out;
+	uint8_t *buf = NULL;
+	int pos, done = 0, count, mult, page_size, block_size;
+	int err = 0;
+
+	if (!(dev = param_get_string(params, "dev"))) {
+		fprintf(stderr, "You must specify 'dev' parameter\n");
+		return (EINVAL);
+	}
+
+	if ((out = param_get_string(params, "out"))) {
+		out_fd = open(out, O_WRONLY|O_CREAT);
+		if (out_fd < 0) {
+			perrorf("Cannot open %s for writing", out);
+			return (EINVAL);
+		}
+	}
+
+	if ((fd = g_open(dev, 1)) < 0) {
+		perrorf("Cannot open %s", dev);
+		err = errno;
+		goto out;
+	}
+
+	if (ioctl(fd, DIOCNBLKSIZE, &block_size) < 0) {
+		perrorf("ioctl(DIOCNBLKSIZE) failed");
+		err = errno;
+		goto out;
+	}
+
+	if (ioctl(fd, DIOCGSECTORSIZE, &page_size) < 0) {
+		perrorf("ioctl(DIOCGSECTORSIZE) failed");
+		err = errno;
+		goto out;
+	}
+
+	if (param_has_value(params, "page")) {
+		pos = page_size * param_get_int(params, "page");
+		mult = 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 % page_size) {
+			fprintf(stderr, "Position must be page-size aligned!\n");
+			err = errno;
+			goto out;
+		}
+	} else {
+		fprintf(stderr, "You must specify one of: 'block', 'page',"
+		    "'pos' arguments\n");
+		err = errno;
+		goto out;
+	}
+
+	if (!(param_has_value(params, "count")))
+		count = mult;
+	else
+		count = param_get_int(params, "count") * mult;
+
+	if (!(buf = malloc(page_size))) {
+		perrorf("Cannot allocate buffer [size %x]", page_size);
+		err = errno;
+		goto out;
+	}
+
+	lseek(fd, pos, SEEK_SET);
+
+	while (done < count) {
+		if ((ret = read(fd, buf, page_size)) != page_size) {
+			perrorf("read error (read %d bytes)", ret);
+			goto out;
+		}
+
+		done += ret;
+
+		if (out_fd != -1) {
+			if ((ret = write(out_fd, buf, page_size)) != page_size) {
+				perrorf("write error (written %d bytes)", ret);
+				err = errno;
+				goto out;
+			}
+		} else
+			hexdump(buf, page_size);
+	}
+
+out:
+	if (fd != -1)
+		g_close(fd);
+	if (out_fd != -1)
+		close(out_fd);
+	if (buf)
+		free(buf);
+
+	return (err);
+}
+

Added: projects/nand/usr.sbin/nandtool/nand_readoob.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/nand/usr.sbin/nandtool/nand_readoob.c	Sat Mar 10 02:40:01 2012	(r232759)
@@ -0,0 +1,118 @@
+/*-
+ * 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 <errno.h>
+#include <fcntl.h>
+#include <libgeom.h>
+#include <sys/types.h>
+#include <sys/disk.h>
+#include <dev/nand/nand_cdev.h>
+#include "nandtool.h"
+
+int nand_read_oob(struct cmd_param *params)
+{
+	char *dev, *out;
+	int fd = -1, fd_out = -1;
+	int err = 0;
+	uint8_t *buf = NULL;
+	int oobsize, page, pagesize;
+	struct nand_oob_request req;
+
+	if ((page = param_get_int(params, "page")) < 0) {
+		fprintf(stderr, "You must supply valid 'page' argument.\n");
+		return (EINVAL);
+	}
+
+	if (!(dev = param_get_string(params, "dev"))){
+		fprintf(stderr, "You must supply 'dev' argument.\n");
+		return (EINVAL);
+	}
+
+	if ((out = param_get_string(params, "out"))) {
+		if ((fd_out = open(out, O_WRONLY | O_CREAT)) < 0) {
+			perrorf("Cannot open %s", out);
+			err = errno;
+			goto out;
+		}
+	}
+
+	if ((fd = g_open(dev, 1)) < 0) {
+		perrorf("Cannot open %s", dev);
+		err = errno;
+		goto out;
+	}
+
+	if (ioctl(fd, DIOCGSECTORSIZE, &pagesize)) {
+		perrorf("Cannot get page size for %s", dev);
+		err = errno;
+		goto out;
+	}
+
+	if (ioctl(fd, DIOCNOOBSIZE, &oobsize)) {
+		perrorf("Cannot get OOB size for %s", dev);
+		err = errno;
+		goto out;
+	}
+
+	buf = malloc(oobsize);
+	if (buf == NULL) {
+		perrorf("Cannot allocate %d bytes\n", oobsize);
+		err = errno;
+		goto out;
+	}
+
+	req.length = oobsize;
+	req.offset = page * pagesize;
+	req.ubuf = buf;
+
+	if (ioctl(fd, DIOCNREADOOB, &req)) {
+		perrorf("Cannot read OOB from %s", dev);
+		err = errno;
+		goto out;
+	}
+
+	if (fd_out != -1)
+		write(fd_out, buf, oobsize);
+	else
+		hexdump(buf, oobsize);
+
+out:
+	if (fd != -1)
+		close(fd);
+	if (fd_out != -1)
+		g_close(fd_out);
+	if (buf)
+		free(buf);
+
+	return (err);
+}
+

Added: projects/nand/usr.sbin/nandtool/nand_write.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/nand/usr.sbin/nandtool/nand_write.c	Sat Mar 10 02:40:01 2012	(r232759)
@@ -0,0 +1,147 @@
+/*-
+ * 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 <errno.h>
+#include <fcntl.h>
+#include <libgeom.h>
+#include <sys/disk.h>
+#include <dev/nand/nand_cdev.h>
+#include "nandtool.h"
+
+int nand_write(struct cmd_param *params)
+{
+	char *dev, *file;
+	int fd = -1, in_fd = -1, ret, err = 0;
+	uint8_t *buf = NULL;
+	int page_size, block_size, mult, pos, done = 0, count, raw;
+
+	raw = param_get_boolean(params, "raw");
+
+	if (!(dev = param_get_string(params, "dev"))) {
+		fprintf(stderr, "Please supply 'dev' argument.\n");
+		return (EINVAL);
+	}
+
+	if (!(file = param_get_string(params, "in"))) {
+		fprintf(stderr, "Please supply 'in' argument.\n");
+		return (EINVAL);
+	}
+
+	if ((fd = g_open(dev, 1)) < 0) {
+		perrorf("Cannot open %s", dev);
+		return (errno);
+	}
+
+	if ((in_fd = open(file, O_RDONLY)) < 0) {
+		perrorf("Cannot open file %s", file);
+		err = errno;
+		goto out;
+	}
+
+	if (ioctl(fd, DIOCGSECTORSIZE, &page_size) < 0) {
+		perrorf("ioctl(DIOCGSECTORSIZE) failed");
+		err = errno;
+		goto out;
+	}
+
+	if (ioctl(fd, DIOCNBLKSIZE, &block_size) < 0) {
+		perrorf("ioctl(DIOCNBLKSIZE) failed");
+		err = errno;
+		goto out;
+	}
+
+	if (param_has_value(params, "page")) {
+		pos = page_size * param_get_int(params, "page");
+		mult = 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 % page_size) {
+			fprintf(stderr, "Position must be page-size aligned!\n");
+			errno = EINVAL;
+			goto out;
+		}
+	} else {
+		fprintf(stderr, "You must specify one of: 'block', 'page',"
+		    "'pos' arguments\n");
+		errno = EINVAL;
+		goto out;
+	}
+
+	if (!(param_has_value(params, "count")))
+		count = mult;
+	else
+		count = param_get_int(params, "count") * mult;
+
+	if (!(buf = malloc(page_size))) {
+		perrorf("Cannot allocate buffer [size %x]", page_size);
+		err = errno;
+		goto out;
+	}
+
+	lseek(fd, pos, SEEK_SET);
+
+	while (done < count)
+	{
+		if ((ret = read(in_fd, buf, page_size)) != page_size) {
+			if (ret > 0) {
+				/* End of file ahead, truncate here */
+				break;
+			} else {
+				perrorf("Cannot read from %s", file);
+				err = errno;
+				goto out;
+			}
+		}
+
+		if ((ret = write(fd, buf, page_size)) != page_size) {
+			err = errno;
+			goto out;
+		}
+
+		done += ret;
+	}
+
+out:
+	if (fd != -1)
+		g_close(fd);
+	if (in_fd != -1)
+		close(in_fd);
+	if (buf)
+		free(buf);
+
+	return (0);
+}
+

Added: projects/nand/usr.sbin/nandtool/nand_writeoob.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/nand/usr.sbin/nandtool/nand_writeoob.c	Sat Mar 10 02:40:01 2012	(r232759)
@@ -0,0 +1,122 @@
+/*-
+ * 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 <errno.h>
+#include <fcntl.h>
+#include <libgeom.h>
+#include <sys/disk.h>
+#include <dev/nand/nand_cdev.h>
+#include "nandtool.h"
+
+int nand_write_oob(struct cmd_param *params)
+{
+	char *dev, *in;
+	int fd = -1, fd_in = -1;
+	uint8_t *buf = NULL;
+	int pagesize, oobsize, page, err = 0;
+	struct nand_oob_request req;
+
+	if (!(dev = param_get_string(params, "dev"))) {
+		fprintf(stderr, "Please supply valid 'dev' parameter.\n");
+		return (EINVAL);
+	}
+
+	if (!(in = param_get_string(params, "in"))) {
+		fprintf(stderr, "Please supply valid 'in' parameter.\n");
+		return (EINVAL);
+	}
+
+	if ((page = param_get_int(params, "page")) < 0) {
+		fprintf(stderr, "Please supply valid 'page' parameter.\n");
+		return (EINVAL);
+	}
+
+	if ((fd = g_open(dev, 1)) < 0) {
+		perrorf("Cannot open %s", dev);
+		return (errno);
+	}
+
+	if ((fd_in = open(in, O_RDONLY)) < 0) {
+		perrorf("Cannot open %s", in);
+		err = errno;
+		goto out;
+	}
+
+	if (ioctl(fd, DIOCGSECTORSIZE, &pagesize)) {
+		perrorf("Cannot get page size for %s", dev);
+		err = errno;
+		goto out;
+	}
+
+
+	if (ioctl(fd, DIOCNOOBSIZE, &oobsize)) {
+		perrorf("Cannot get OOB size for %s", dev);
+		err = errno;
+		goto out;
+	}
+
+	buf = xmalloc(oobsize);
+	if (buf == NULL) {
+		perrorf("Cannot allocate %d bytes\n", oobsize);
+		err = errno;
+		goto out;
+	}
+
+	if (read(fd_in, buf, oobsize) < 0) {
+		perrorf("Cannot read from %s", in);
+		err = errno;
+		goto out;
+	}
+
+
+	req.offset = page * pagesize;
+	req.length = oobsize;
+	req.ubuf = buf;
+
+	if (ioctl(fd, DIOCNWRITEOOB, &req)) {
+		perrorf("Cannot write OOB to %s", dev);
+		err = errno;
+		goto out;
+	}
+
+out:
+	if (fd != -1)
+		g_close(fd);
+	if (fd_in != -1)
+		close(fd_in);
+	if (buf)
+		free(buf);
+
+	return (err);
+}
+
+

Added: projects/nand/usr.sbin/nandtool/nandtool.8
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/nand/usr.sbin/nandtool/nandtool.8	Sat Mar 10 02:40:01 2012	(r232759)
@@ -0,0 +1,171 @@
+.\" 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.
+.\"
+.\"
+.Dd August 18, 2010
+.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.
+Arguments:
+.It Cm write Ns
+Write pages to NAND device.
+.It Cm erase Ns
+Erase blocks.  Requires offset to be specified in block granularity.
+.It Cm info Ns
+Get information about NAND chip (page size, block size, OOB area 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
+.Va nandtool 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
+.Va nandtool 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
+.Va nandtool 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
+.Va nandtool 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
+.Va nandtool 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 availble for
+.Va nandtool 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 availble for
+.Va nandtool help
+command:
+.Pp
+.It Cm topic Ns = Ns Ar <name>
+Help topic.
+.El
+.Sh EXIT STATUS
+.Ex -std
+.Sh SEE ALSO
+.Xr gnand 4

Added: projects/nand/usr.sbin/nandtool/nandtool.c
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ projects/nand/usr.sbin/nandtool/nandtool.c	Sat Mar 10 02:40:01 2012	(r232759)
@@ -0,0 +1,234 @@
+/*-
+ * 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 <string.h>
+#include <errno.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 },

*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201203100240.q2A2e2fd035876>