diff options
Diffstat (limited to 'nand-utils')
| -rw-r--r-- | nand-utils/nanddump.c | 27 | 
1 files changed, 22 insertions, 5 deletions
diff --git a/nand-utils/nanddump.c b/nand-utils/nanddump.c index a3e6e92..bc22858 100644 --- a/nand-utils/nanddump.c +++ b/nand-utils/nanddump.c @@ -54,6 +54,7 @@ static void display_help(int status)  "-s addr    --startaddress=addr  Start address\n"  "           --skip-bad-blocks-to-start\n"  "                                Skip bad blocks when seeking to the start address\n" +"-C         --continuous         Continuous read up to a block of data at a time\n"  "\n"  "--bb=METHOD, where METHOD can be `padbad', `dumpbad', or `skipbad':\n"  "    padbad:  dump flash data, substituting 0xFF for any bad blocks\n" @@ -89,6 +90,7 @@ static bool			quiet = false;		// suppress diagnostic output  static bool			canonical = false;	// print nice + ascii  static bool			forcebinary = false;	// force printing binary to tty  static bool			skip_bad_blocks_to_start = false; +static bool			continuous = false;	// leverage continuous reads  static enum {  	padbad,   // dump flash data, substituting 0xFF for any bad blocks @@ -103,7 +105,7 @@ static void process_options(int argc, char * const argv[])  	for (;;) {  		int option_index = 0; -		static const char short_options[] = "hs:f:l:opqncaV"; +		static const char short_options[] = "hs:f:l:opqncaVC";  		static const struct option long_options[] = {  			{"version", no_argument, 0, 'V'},  			{"bb", required_argument, 0, 0}, @@ -119,6 +121,7 @@ static void process_options(int argc, char * const argv[])  			{"length", required_argument, 0, 'l'},  			{"noecc", no_argument, 0, 'n'},  			{"quiet", no_argument, 0, 'q'}, +			{"continuous", no_argument, 0, 'C'},  			{0, 0, 0, 0},  		}; @@ -191,6 +194,9 @@ static void process_options(int argc, char * const argv[])  			case 'n':  				noecc = true;  				break; +			case 'C': +				continuous = true; +				break;  			case 'h':  				display_help(EXIT_SUCCESS);  				break; @@ -220,6 +226,13 @@ static void process_options(int argc, char * const argv[])  		exit(EXIT_FAILURE);  	} +	if (continuous && !omitoob) { +		fprintf(stderr, "Sequential/continuous reads (when available) will\n" +				"always skip OOB data, so it is not possible to \n" +				"request both at the same time.\n"); +		exit(EXIT_FAILURE); +	} +  	if ((argc - optind) != 1 || error)  		display_help(EXIT_FAILURE); @@ -362,7 +375,7 @@ int main(int argc, char * const argv[])  		return errmsg("mtd_get_dev_info failed");  	/* Allocate buffers */ -	readbuf_sz = mtd.min_io_size; +	readbuf_sz = mtd.eb_size;  	oobbuf = xmalloc(mtd.oob_size);  	readbuf = xmalloc(readbuf_sz); @@ -428,8 +441,6 @@ int main(int argc, char * const argv[])  	if (!length || end_addr > mtd.size)  		end_addr = mtd.size; -	bs = mtd.min_io_size; -  	/* Print informative message */  	if (!quiet) {  		fprintf(stderr, "Block size %d, page size %d, OOB size %d\n", @@ -441,6 +452,8 @@ int main(int argc, char * const argv[])  	/* Dump the flash contents */  	for (ofs = start_addr; ofs < end_addr; ofs += bs) { +		long long size_left = end_addr - ofs; +  		/* Check for bad block */  		if (bb_method == dumpbad) {  			badblock = 0; @@ -454,6 +467,11 @@ int main(int argc, char * const argv[])  			}  		} +		if (continuous) +			bs = MIN(size_left, mtd.eb_size); +		else +			bs = mtd.min_io_size; +  		if (badblock) {  			/* skip bad block, increase end_addr */  			if (bb_method == skipbad) { @@ -500,7 +518,6 @@ int main(int argc, char * const argv[])  			}  		} else {  			/* Write requested length if oob is omitted */ -			long long size_left = end_addr - ofs;  			if (omitoob && (size_left < bs))  				err = ofd_write(ofd, readbuf, size_left);  			else  | 
