@ -18,11 +18,29 @@ static unsigned char __aligned(CONFIG_SYS_CACHELINE_SIZE)
dfu_file_buf [ CONFIG_SYS_DFU_MAX_FILE_SIZE ] ;
static long dfu_file_buf_len ;
static int mmc_access_part ( struct dfu_entity * dfu , struct mmc * mmc , int part )
{
int ret ;
if ( part = = mmc - > part_num )
return 0 ;
ret = mmc_switch_part ( dfu - > dev_num , part ) ;
if ( ret ) {
error ( " Cannot switch to partition %d \n " , part ) ;
return ret ;
}
mmc - > part_num = part ;
return 0 ;
}
static int mmc_block_op ( enum dfu_op op , struct dfu_entity * dfu ,
u64 offset , void * buf , long * len )
{
struct mmc * mmc = find_mmc_device ( dfu - > dev_num ) ;
u32 blk_start , blk_count , n = 0 ;
int ret , part_num_bkp = 0 ;
/*
* We must ensure that we work in lba_blk_size chunks , so ALIGN
@ -39,6 +57,13 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
return - EINVAL ;
}
if ( dfu - > data . mmc . hw_partition > = 0 ) {
part_num_bkp = mmc - > part_num ;
ret = mmc_access_part ( dfu , mmc , dfu - > data . mmc . hw_partition ) ;
if ( ret )
return ret ;
}
debug ( " %s: %s dev: %d start: %d cnt: %d buf: 0x%p \n " , __func__ ,
op = = DFU_OP_READ ? " MMC READ " : " MMC WRITE " , dfu - > dev_num ,
blk_start , blk_count , buf ) ;
@ -57,9 +82,17 @@ static int mmc_block_op(enum dfu_op op, struct dfu_entity *dfu,
if ( n ! = blk_count ) {
error ( " MMC operation failed " ) ;
if ( dfu - > data . mmc . hw_partition > = 0 )
mmc_access_part ( dfu , mmc , part_num_bkp ) ;
return - EIO ;
}
if ( dfu - > data . mmc . hw_partition > = 0 ) {
ret = mmc_access_part ( dfu , mmc , part_num_bkp ) ;
if ( ret )
return ret ;
}
return 0 ;
}
@ -194,6 +227,8 @@ int dfu_read_medium_mmc(struct dfu_entity *dfu, u64 offset, void *buf,
* 2 nd and 3 rd :
* lba_start and lba_size , for raw write
* mmc_dev and mmc_part , for filesystems and part
* 4 th ( optional ) :
* mmcpart < num > ( access to HW eMMC partitions )
*/
int dfu_fill_entity_mmc ( struct dfu_entity * dfu , char * s )
{
@ -233,11 +268,22 @@ int dfu_fill_entity_mmc(struct dfu_entity *dfu, char *s)
return - ENODEV ;
}
dfu - > data . mmc . hw_partition = - EINVAL ;
if ( ! strcmp ( entity_type , " raw " ) ) {
dfu - > layout = DFU_RAW_ADDR ;
dfu - > data . mmc . lba_start = second_arg ;
dfu - > data . mmc . lba_size = third_arg ;
dfu - > data . mmc . lba_blk_size = mmc - > read_bl_len ;
/*
* Check for an extra entry at dfu_alt_info env variable
* specifying the mmc HW defined partition number
*/
if ( s )
if ( ! strcmp ( strsep ( & s , " " ) , " mmcpart " ) )
dfu - > data . mmc . hw_partition =
simple_strtoul ( s , NULL , 0 ) ;
} else if ( ! strcmp ( entity_type , " part " ) ) {
disk_partition_t partinfo ;
block_dev_desc_t * blk_dev = & mmc - > block_dev ;