diff options
| author | Remy Bohmer <linux@bohmer.net> | 2011-02-12 19:06:26 +0100 | 
|---|---|---|
| committer | Wolfgang Denk <wd@denx.de> | 2011-04-12 22:58:34 +0200 | 
| commit | 9eeaa8e66ce1b34ddac9ebb1f31043f473a7c176 (patch) | |
| tree | 2c699b404371499f7007c97227a0d6e8e1585dc7 /tools/env/fw_env.c | |
| parent | 976b38c0742dc1db13af03cae9ded4392e47182d (diff) | |
| download | olio-uboot-2014.01-9eeaa8e66ce1b34ddac9ebb1f31043f473a7c176.tar.xz olio-uboot-2014.01-9eeaa8e66ce1b34ddac9ebb1f31043f473a7c176.zip | |
Add support for dataflash to U-boot environment settings tool.
* The sector size for SPI-dataflash (like AT45 flashes) are not always
  a power-of-2. So, the sector calculations are rewritten such that it
  works for either power-of-2 as any size sectors.
* Make the flash sector size optional in case it is the same value as
  the environment size.
Signed-off-by: Remy Bohmer <linux@bohmer.net>
Diffstat (limited to 'tools/env/fw_env.c')
| -rw-r--r-- | tools/env/fw_env.c | 72 | 
1 files changed, 47 insertions, 25 deletions
| diff --git a/tools/env/fw_env.c b/tools/env/fw_env.c index 8ff705224..e0f46bcd1 100644 --- a/tools/env/fw_env.c +++ b/tools/env/fw_env.c @@ -674,11 +674,7 @@ static int flash_read_buf (int dev, int fd, void *buf, size_t count,  				   MEMGETBADBLOCK needs 64 bits */  	int rc; -	/* -	 * Start of the first block to be read, relies on the fact, that -	 * erase sector size is always a power of 2 -	 */ -	blockstart = offset & ~(DEVESIZE (dev) - 1); +	blockstart = (offset / DEVESIZE (dev)) * DEVESIZE (dev);  	/* Offset inside a block */  	block_seek = offset - blockstart; @@ -694,8 +690,8 @@ static int flash_read_buf (int dev, int fd, void *buf, size_t count,  		 * To calculate the top of the range, we have to use the  		 * global DEVOFFSET (dev), which can be different from offset  		 */ -		top_of_range = (DEVOFFSET (dev) & ~(blocklen - 1)) + -			ENVSECTORS (dev) * blocklen; +		top_of_range = ((DEVOFFSET(dev) / blocklen) + +				ENVSECTORS (dev)) * blocklen;  		/* Limit to one block for the first read */  		if (readlen > blocklen - block_seek) @@ -749,9 +745,9 @@ static int flash_read_buf (int dev, int fd, void *buf, size_t count,  }  /* - * Write count bytes at offset, but stay within ENVSETCORS (dev) sectors of - * DEVOFFSET (dev). Similar to the read case above, on NOR we erase and write - * the whole data at once. + * Write count bytes at offset, but stay within ENVSECTORS (dev) sectors of + * DEVOFFSET (dev). Similar to the read case above, on NOR and dataflash we + * erase and write the whole data at once.   */  static int flash_write_buf (int dev, int fd, void *buf, size_t count,  			    off_t offset, uint8_t mtd_type) @@ -764,7 +760,7 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,  	size_t erasesize;	/* erase / write length - one block on NAND,  				   whole area on NOR */  	size_t processed = 0;	/* progress counter */ -	size_t write_total;	/* total size to actually write - excludinig +	size_t write_total;	/* total size to actually write - excluding  				   bad blocks */  	off_t erase_offset;	/* offset to the first erase block (aligned)  				   below offset */ @@ -777,11 +773,10 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,  	blocklen = DEVESIZE (dev); -	/* Erase sector size is always a power of 2 */ -	top_of_range = (DEVOFFSET (dev) & ~(blocklen - 1)) + -		ENVSECTORS (dev) * blocklen; +	top_of_range = ((DEVOFFSET(dev) / blocklen) + +					ENVSECTORS (dev)) * blocklen; -	erase_offset = offset & ~(blocklen - 1); +	erase_offset = (offset / blocklen) * blocklen;  	/* Maximum area we may use */  	erase_len = top_of_range - erase_offset; @@ -795,7 +790,8 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,  	 * to the start of the data, then count bytes of data, and to the  	 * end of the block  	 */ -	write_total = (block_seek + count + blocklen - 1) & ~(blocklen - 1); +	write_total = ((block_seek + count + blocklen - 1) / +						blocklen) * blocklen;  	/*  	 * Support data anywhere within erase sectors: read out the complete @@ -838,7 +834,7 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,  	erase.length = erasesize; -	/* This only runs once on NOR flash */ +	/* This only runs once on NOR flash and SPI-dataflash */  	while (processed < write_total) {  		rc = flash_bad_block (fd, mtd_type, &blockstart);  		if (rc < 0)		/* block test failed */ @@ -857,12 +853,14 @@ static int flash_write_buf (int dev, int fd, void *buf, size_t count,  		erase.start = blockstart;  		ioctl (fd, MEMUNLOCK, &erase); -		if (ioctl (fd, MEMERASE, &erase) != 0) { -			fprintf (stderr, "MTD erase error on %s: %s\n", -				 DEVNAME (dev), -				 strerror (errno)); -			return -1; -		} +		/* Dataflash does not need an explicit erase cycle */ +		if (mtd_type != MTD_DATAFLASH) +			if (ioctl (fd, MEMERASE, &erase) != 0) { +				fprintf (stderr, "MTD erase error on %s: %s\n", +					 DEVNAME (dev), +					 strerror (errno)); +				return -1; +			}  		if (lseek (fd, blockstart, SEEK_SET) == -1) {  			fprintf (stderr, @@ -973,7 +971,9 @@ static int flash_read (int fd)  		return -1;  	} -	if (mtdinfo.type != MTD_NORFLASH && mtdinfo.type != MTD_NANDFLASH) { +	if (mtdinfo.type != MTD_NORFLASH && +	    mtdinfo.type != MTD_NANDFLASH && +	    mtdinfo.type != MTD_DATAFLASH) {  		fprintf (stderr, "Unsupported flash type %u\n", mtdinfo.type);  		return -1;  	} @@ -1143,6 +1143,9 @@ int fw_env_open(void)  		} else if (DEVTYPE(dev_current) == MTD_NANDFLASH &&  			   DEVTYPE(!dev_current) == MTD_NANDFLASH) {  			environment.flag_scheme = FLAG_INCREMENTAL; +		} else if (DEVTYPE(dev_current) == MTD_DATAFLASH && +			   DEVTYPE(!dev_current) == MTD_DATAFLASH) { +			environment.flag_scheme = FLAG_BOOLEAN;  		} else {  			fprintf (stderr, "Incompatible flash types!\n");  			return -1; @@ -1234,14 +1237,29 @@ static int parse_config ()  	strcpy (DEVNAME (0), DEVICE1_NAME);  	DEVOFFSET (0) = DEVICE1_OFFSET;  	ENVSIZE (0) = ENV1_SIZE; +	/* Default values are: erase-size=env-size, #sectors=1 */ +	DEVESIZE (0) = ENVSIZE (0); +	ENVSECTORS (0) = 1; +#ifdef DEVICE1_ESIZE  	DEVESIZE (0) = DEVICE1_ESIZE; +#endif +#ifdef DEVICE1_ENVSECTORS  	ENVSECTORS (0) = DEVICE1_ENVSECTORS; +#endif +  #ifdef HAVE_REDUND  	strcpy (DEVNAME (1), DEVICE2_NAME);  	DEVOFFSET (1) = DEVICE2_OFFSET;  	ENVSIZE (1) = ENV2_SIZE; +	/* Default values are: erase-size=env-size, #sectors=1 */ +	DEVESIZE (1) = ENVSIZE (1); +	ENVSECTORS (1) = 1; +#ifdef DEVICE2_ESIZE  	DEVESIZE (1) = DEVICE2_ESIZE; +#endif +#ifdef DEVICE2_ENVSECTORS  	ENVSECTORS (1) = DEVICE2_ENVSECTORS; +#endif  	HaveRedundEnv = 1;  #endif  #endif @@ -1285,9 +1303,13 @@ static int get_config (char *fname)  			     &DEVESIZE (i),  			     &ENVSECTORS (i)); -		if (rc < 4) +		if (rc < 3)  			continue; +		if (rc < 4) +			/* Assume the erase size is the same as the env-size */ +			DEVESIZE(i) = ENVSIZE(i); +  		if (rc < 5)  			/* Default - 1 sector */  			ENVSECTORS (i) = 1; |