@ -58,6 +58,7 @@ int no_erase;
int mtdsize = 0 ;
int erasesize = 0 ;
int jffs2_skip_bytes = 0 ;
int mtdtype = 0 ;
int mtd_open ( const char * mtd , bool block )
{
@ -103,10 +104,28 @@ int mtd_check_open(const char *mtd)
}
mtdsize = mtdInfo . size ;
erasesize = mtdInfo . erasesize ;
mtdtype = mtdInfo . type ;
return fd ;
}
int mtd_block_is_bad ( int fd , int offset )
{
int r = 0 ;
loff_t o = offset ;
if ( mtdtype = = MTD_NANDFLASH )
{
r = ioctl ( fd , MEMGETBADBLOCK , & o ) ;
if ( r < 0 )
{
fprintf ( stderr , " Failed to get erase block status \n " ) ;
exit ( 1 ) ;
}
}
return r ;
}
int mtd_erase_block ( int fd , int offset )
{
struct erase_info_user mtdEraseInfo ;
@ -236,10 +255,14 @@ mtd_erase(const char *mtd)
for ( mtdEraseInfo . start = 0 ;
mtdEraseInfo . start < mtdsize ;
mtdEraseInfo . start + = erasesize ) {
ioctl ( fd , MEMUNLOCK , & mtdEraseInfo ) ;
if ( ioctl ( fd , MEMERASE , & mtdEraseInfo ) )
fprintf ( stderr , " Failed to erase block on %s at 0x%x \n " , mtd , mtdEraseInfo . start ) ;
if ( mtd_block_is_bad ( fd , mtdEraseInfo . start ) ) {
if ( ! quiet )
fprintf ( stderr , " \n Skipping bad block at 0x%x " , mtdEraseInfo . start ) ;
} else {
ioctl ( fd , MEMUNLOCK , & mtdEraseInfo ) ;
if ( ioctl ( fd , MEMERASE , & mtdEraseInfo ) )
fprintf ( stderr , " Failed to erase block on %s at 0x%x \n " , mtd , mtdEraseInfo . start ) ;
}
}
close ( fd ) ;
@ -324,6 +347,7 @@ mtd_write(int imagefd, const char *mtd, char *fis_layout, size_t part_offset)
ssize_t skip = 0 ;
uint32_t offset = 0 ;
int jffs2_replaced = 0 ;
int skip_bad_blocks = 0 ;
# ifdef FIS_SUPPORT
static struct fis_part new_parts [ MAX_ARGS ] ;
@ -429,6 +453,12 @@ resume:
if ( buflen = = 0 )
break ;
if ( buflen < erasesize ) {
/* Pad block to eraseblock size */
memset ( & buf [ buflen ] , 0xff , erasesize - buflen ) ;
buflen = erasesize ;
}
if ( skip > 0 ) {
skip - = buflen ;
buflen = 0 ;
@ -466,10 +496,21 @@ resume:
/* need to erase the next block before writing data to it */
if ( ! no_erase )
{
while ( w + buflen > e ) {
while ( w + buflen > e - skip_bad_blocks ) {
if ( ! quiet )
fprintf ( stderr , " \b \b \b [e] " ) ;
if ( mtd_block_is_bad ( fd , e ) ) {
if ( ! quiet )
fprintf ( stderr , " \n Skipping bad block at 0x%08x " , e ) ;
skip_bad_blocks + = erasesize ;
e + = erasesize ;
// Move the file pointer along over the bad block.
lseek ( fd , erasesize , SEEK_CUR ) ;
continue ;
}
if ( mtd_erase_block ( fd , e ) < 0 ) {
if ( next ) {