diff options
| author | Frans Meulenbroeks <fransmeulenbroeks@gmail.com> | 2010-03-27 17:14:36 +0100 | 
|---|---|---|
| committer | Wolfgang Denk <wd@denx.de> | 2010-05-05 23:57:17 +0200 | 
| commit | 8cd852824d91e232f1f820a0772c3c1d8af84b05 (patch) | |
| tree | 91126ab80dc282461f3cd4c573b965fc689fc87c | |
| parent | 3882d7a5a57eb8d1f41570522445bab61c628e6f (diff) | |
| download | olio-uboot-2014.01-8cd852824d91e232f1f820a0772c3c1d8af84b05.tar.xz olio-uboot-2014.01-8cd852824d91e232f1f820a0772c3c1d8af84b05.zip  | |
cmd_onenand.c: moved to standard subcommand handling
On the fly also fixed the following things:
- write help talked about a parameter oob, but that one was not used, so
  removed it from the help message.
- the test command also allowed a force subcommand but didn't use it.
  eliminated the code.
- do_onenand made static
- do_onenand contained
	int blocksize;
	...
	mtd = &onenand_mtd;
	this = mtd->priv;
	blocksize = (1 << this->erase_shift);
  As blocksize was not used the last two statements were unneeded so
  removed them.
  The first statement (mtd = ....) assigns to a global. Not sure if it
  is needed, and since I could not test this, left the line for now
Signed-off-by: Frans Meulenbroeks <fransmeulenbroeks@gmail.com>
| -rw-r--r-- | common/cmd_onenand.c | 301 | 
1 files changed, 189 insertions, 112 deletions
diff --git a/common/cmd_onenand.c b/common/cmd_onenand.c index 565257cf4..2646ae91d 100644 --- a/common/cmd_onenand.c +++ b/common/cmd_onenand.c @@ -330,154 +330,231 @@ static int onenand_dump(struct mtd_info *mtd, ulong off, int only_oob)  	return 0;  } -int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +static int do_onenand_info(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[])  { -	struct onenand_chip *this; -	int blocksize; +	printf("%s\n", mtd->name); +	return 0; +} + +static int do_onenand_bad(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ +	ulong ofs; + +	mtd = &onenand_mtd; +	/* Currently only one OneNAND device is supported */ +	printf("\nDevice %d bad blocks:\n", 0); +	for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) { +		if (mtd->block_isbad(mtd, ofs)) +			printf("  %08x\n", (u32)ofs); +	} + +	return 0; +} + +static int do_onenand_read(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ +	char *s; +	int oob = 0;  	ulong addr, ofs; -	size_t len, retlen = 0; +	size_t len;  	int ret = 0; -	char *cmd, *s; +	size_t retlen = 0; -	mtd = &onenand_mtd; -	this = mtd->priv; -	blocksize = (1 << this->erase_shift); +	if (argc < 3) +	{ +		cmd_usage(cmdtp); +		return 1; +	} -	cmd = argv[1]; +	s = strchr(argv[0], '.'); +	if ((s != NULL) && (!strcmp(s, ".oob"))) +		oob = 1; -	switch (argc) { -	case 0: -	case 1: -		goto usage; +	addr = (ulong)simple_strtoul(argv[1], NULL, 16); -	case 2: -		if (strcmp(cmd, "info") == 0) { -			printf("%s\n", mtd->name); -			return 0; -		} +	printf("\nOneNAND read: "); +	if (arg_off_size(argc - 2, argv + 2, &ofs, &len) != 0) +		return 1; -		if (strcmp(cmd, "bad") == 0) { -			/* Currently only one OneNAND device is supported */ -			printf("\nDevice %d bad blocks:\n", 0); -			for (ofs = 0; ofs < mtd->size; ofs += mtd->erasesize) { -				if (mtd->block_isbad(mtd, ofs)) -					printf("  %08x\n", (u32)ofs); -			} +	ret = onenand_block_read(ofs, len, &retlen, (u8 *)addr, oob); -			return 0; -		} +	printf(" %d bytes read: %s\n", retlen, ret ? "ERROR" : "OK"); -	default: -		/* At least 4 args */ +	return ret == 0 ? 0 : 1; +} -		/* -		 * Syntax is: -		 *   0       1     2       3    4 -		 *   onenand erase [force] [off size] -		 */ -		if ((strcmp(cmd, "erase") == 0) || (strcmp(cmd, "test") == 0)) { -			int force = argc > 2 && !strcmp("force", argv[2]); -			int o = force ? 3 : 2; -			int erase; +static int do_onenand_write(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ +	ulong addr, ofs; +	size_t len; +	int ret = 0; +	size_t retlen = 0; -			erase = strcmp(cmd, "erase") == 0; /* 1 = erase, 0 = test */ -			printf("\nOneNAND %s: ", erase ? "erase" : "test"); +	if (argc < 3) +	{ +		cmd_usage(cmdtp); +		return 1; +	} -			/* skip first two or three arguments, look for offset and size */ -			if (arg_off_size(argc - o, argv + o, &ofs, &len) != 0) -				return 1; +	addr = (ulong)simple_strtoul(argv[1], NULL, 16); + +	printf("\nOneNAND write: "); +	if (arg_off_size(argc - 2, argv + 2, &ofs, &len) != 0) +		return 1; -			if (erase) -				ret = onenand_block_erase(ofs, len, force); -			else -				ret = onenand_block_test(ofs, len); +	ret = onenand_block_write(ofs, len, &retlen, (u8 *)addr); -			printf("%s\n", ret ? "ERROR" : "OK"); +	printf(" %d bytes written: %s\n", retlen, ret ? "ERROR" : "OK"); -			return ret == 0 ? 0 : 1; +	return ret == 0 ? 0 : 1; +} + +static int do_onenand_erase(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ +	ulong ofs; +	int ret = 0; +	size_t len; +	int force; + +	/* +	 * Syntax is: +	 *   0       1     2       3    4 +	 *   onenand erase [force] [off size] +	 */ +	argc--; +	argv++; +	if (argc) +	{ +		if (!strcmp("force", argv[0])) +		{ +			force = 1; +			argc--; +			argv++;  		} +	} +	printf("\nOneNAND erase: "); -		if (strncmp(cmd, "read", 4) == 0 || strncmp(cmd, "write", 5) == 0) { -			int read; -			int oob = 0; +	/* skip first two or three arguments, look for offset and size */ +	if (arg_off_size(argc, argv, &ofs, &len) != 0) +		return 1; -			if (argc < 4) -				goto usage; +	ret = onenand_block_erase(ofs, len, force); -			addr = (ulong)simple_strtoul(argv[2], NULL, 16); +	printf("%s\n", ret ? "ERROR" : "OK"); -			read = strncmp(cmd, "read", 4) == 0; /* 1 = read, 0 = write */ -			printf("\nOneNAND %s: ", read ? "read" : "write"); -			if (arg_off_size(argc - 3, argv + 3, &ofs, &len) != 0) -				return 1; +	return ret == 0 ? 0 : 1; +} -			s = strchr(cmd, '.'); -			if ((s != NULL) && (!strcmp(s, ".oob"))) -				oob = 1; +static int do_onenand_test(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ +	ulong ofs; +	int ret = 0; +	size_t len; -			if (read) { -				ret = onenand_block_read(ofs, len, &retlen, -							 (u8 *)addr, oob); -			} else { -				ret = onenand_block_write(ofs, len, &retlen, -							  (u8 *)addr); -			} +	/* +	 * Syntax is: +	 *   0       1     2       3    4 +	 *   onenand test [force] [off size] +	 */ -			printf(" %d bytes %s: %s\n", retlen, -			       read ? "read" : "written", ret ? "ERROR" : "OK"); +	printf("\nOneNAND test: "); -			return ret == 0 ? 0 : 1; -		} +	/* skip first two or three arguments, look for offset and size */ +	if (arg_off_size(argc - 1, argv + 1, &ofs, &len) != 0) +		return 1; -		if (strcmp(cmd, "markbad") == 0) { -			argc -= 2; -			argv += 2; +	ret = onenand_block_test(ofs, len); -			if (argc <= 0) -				goto usage; +	printf("%s\n", ret ? "ERROR" : "OK"); -			while (argc > 0) { -				addr = simple_strtoul(*argv, NULL, 16); +	return ret == 0 ? 0 : 1; +} -				if (mtd->block_markbad(mtd, addr)) { -					printf("block 0x%08lx NOT marked " -						"as bad! ERROR %d\n", -						addr, ret); -					ret = 1; -				} else { -					printf("block 0x%08lx successfully " -						"marked as bad\n", -						addr); -				} -				--argc; -				++argv; -			} -			return ret; -		} +static int do_onenand_dump(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ +	ulong ofs; +	int ret = 0; +	char *s; -		if (strncmp(cmd, "dump", 4) == 0) { -			if (argc < 3) -				goto usage; +	if (argc < 2) +	{ +		cmd_usage(cmdtp); +		return 1; +	} -			s = strchr(cmd, '.'); -			ofs = (int)simple_strtoul(argv[2], NULL, 16); +	s = strchr(argv[0], '.'); +	ofs = (int)simple_strtoul(argv[1], NULL, 16); -			if (s != NULL && strcmp(s, ".oob") == 0) -				ret = onenand_dump(mtd, ofs, 1); -			else -				ret = onenand_dump(mtd, ofs, 0); +	if (s != NULL && strcmp(s, ".oob") == 0) +		ret = onenand_dump(mtd, ofs, 1); +	else +		ret = onenand_dump(mtd, ofs, 0); -			return ret == 0 ? 1 : 0; -		} +	return ret == 0 ? 1 : 0; +} + +static int do_onenand_markbad(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ +	int ret = 0; +	ulong addr; + +	argc -= 2; +	argv += 2; -		break; +	if (argc <= 0) +	{ +		cmd_usage(cmdtp); +		return 1;  	} -	return 0; +	while (argc > 0) { +		addr = simple_strtoul(*argv, NULL, 16); + +		if (mtd->block_markbad(mtd, addr)) { +			printf("block 0x%08lx NOT marked " +				"as bad! ERROR %d\n", +				addr, ret); +			ret = 1; +		} else { +			printf("block 0x%08lx successfully " +				"marked as bad\n", +				addr); +		} +		--argc; +		++argv; +	} +	return ret; +} + +static cmd_tbl_t cmd_onenand_sub[] = { +	U_BOOT_CMD_MKENT(info, 1, 0, do_onenand_info, "", ""), +	U_BOOT_CMD_MKENT(bad, 1, 0, do_onenand_bad, "", ""), +	U_BOOT_CMD_MKENT(read, 4, 0, do_onenand_read, "", ""), +	U_BOOT_CMD_MKENT(write, 4, 0, do_onenand_write, "", ""), +	U_BOOT_CMD_MKENT(erase, 3, 0, do_onenand_erase, "", ""), +	U_BOOT_CMD_MKENT(test, 3, 0, do_onenand_test, "", ""), +	U_BOOT_CMD_MKENT(dump, 2, 0, do_onenand_dump, "", ""), +	U_BOOT_CMD_MKENT(markbad, CONFIG_SYS_MAXARGS, 0, do_onenand_markbad, "", ""), +}; + +static int do_onenand(cmd_tbl_t * cmdtp, int flag, int argc, char *argv[]) +{ +	cmd_tbl_t *c; + +	mtd = &onenand_mtd; + +	/* Strip off leading 'onenand' command argument */ +	argc--; +	argv++; -usage: -	cmd_usage(cmdtp); -	return 1; +	c = find_cmd_tbl(argv[0], &cmd_onenand_sub[0], ARRAY_SIZE(cmd_onenand_sub)); + +	if (c) { +		return  c->cmd(cmdtp, flag, argc, argv); +	} else { +		cmd_usage(cmdtp); +		return 1; +	}  }  U_BOOT_CMD( @@ -486,7 +563,7 @@ U_BOOT_CMD(  	"info - show available OneNAND devices\n"  	"onenand bad - show bad blocks\n"  	"onenand read[.oob] addr off size\n" -	"onenand write[.oob] addr off size\n" +	"onenand write addr off size\n"  	"    read/write 'size' bytes starting at offset 'off'\n"  	"    to/from memory address 'addr', skipping bad blocks.\n"  	"onenand erase [force] [off size] - erase 'size' bytes from\n"  |