@ -46,6 +46,12 @@ struct trx_header {
uint32_t offsets [ 3 ] ; /* Offsets of partitions from start of header */
uint32_t offsets [ 3 ] ; /* Offsets of partitions from start of header */
} ;
} ;
# define min(x,y) ({ \
typeof ( x ) _x = ( x ) ; \
typeof ( y ) _y = ( y ) ; \
( void ) ( & _x = = & _y ) ; \
_x < _y ? _x : _y ; } )
# if __BYTE_ORDER == __BIG_ENDIAN
# if __BYTE_ORDER == __BIG_ENDIAN
# define STORE32_LE(X) ((((X) & 0x000000FF) << 24) | (((X) & 0x0000FF00) << 8) | (((X) & 0x00FF0000) >> 8) | (((X) & 0xFF000000) >> 24))
# define STORE32_LE(X) ((((X) & 0x000000FF) << 24) | (((X) & 0x0000FF00) << 8) | (((X) & 0x00FF0000) >> 8) | (((X) & 0xFF000000) >> 24))
# elif __BYTE_ORDER == __LITTLE_ENDIAN
# elif __BYTE_ORDER == __LITTLE_ENDIAN
@ -156,7 +162,7 @@ mtd_fixtrx(const char *mtd, size_t offset, size_t data_size)
int fd ;
int fd ;
struct trx_header * trx ;
struct trx_header * trx ;
char * first_block ;
char * first_block ;
char * buf ;
char * buf , * to ;
ssize_t res ;
ssize_t res ;
size_t block_offset ;
size_t block_offset ;
@ -214,11 +220,28 @@ mtd_fixtrx(const char *mtd, size_t offset, size_t data_size)
exit ( 1 ) ;
exit ( 1 ) ;
}
}
res = pread ( fd , buf , data_size , data_offset ) ;
to = buf ;
if ( res ! = data_size ) {
while ( data_size ) {
perror ( " pread " ) ;
size_t read_block_offset = data_offset & ~ ( erasesize - 1 ) ;
exit ( 1 ) ;
size_t read_chunk ;
read_chunk = erasesize - ( data_offset & ( erasesize - 1 ) ) ;
read_chunk = min ( read_chunk , data_size ) ;
/* Read from good blocks only to match CFE behavior */
if ( ! mtd_block_is_bad ( fd , read_block_offset ) ) {
res = pread ( fd , to , read_chunk , data_offset ) ;
if ( res ! = read_chunk ) {
perror ( " pread " ) ;
exit ( 1 ) ;
}
to + = read_chunk ;
}
data_offset + = read_chunk ;
data_size - = read_chunk ;
}
}
data_size = to - buf ;
trx - > len = STORE32_LE ( data_size + offsetof ( struct trx_header , flag_version ) ) ;
trx - > len = STORE32_LE ( data_size + offsetof ( struct trx_header , flag_version ) ) ;
@ -244,4 +267,3 @@ mtd_fixtrx(const char *mtd, size_t offset, size_t data_size)
return 0 ;
return 0 ;
}
}