@ -4,14 +4,20 @@
* SPDX - License - Identifier : GPL - 2.0 +
*/
# include <config.h>
# include <common.h>
# include <blk.h>
# include <dm.h>
# include <fdtdec.h>
# include <part.h>
# include <os.h>
# include <malloc.h>
# include <sandboxblockdev.h>
# include <asm/errno.h>
# include <dm/device-internal.h>
DECLARE_GLOBAL_DATA_PTR ;
# ifndef CONFIG_BLK
static struct host_block_dev host_devices [ CONFIG_HOST_MAX_DEVICES ] ;
static struct host_block_dev * find_host_device ( int dev )
@ -21,7 +27,17 @@ static struct host_block_dev *find_host_device(int dev)
return NULL ;
}
# endif
# ifdef CONFIG_BLK
static unsigned long host_block_read ( struct udevice * dev ,
unsigned long start , lbaint_t blkcnt ,
void * buffer )
{
struct host_block_dev * host_dev = dev_get_priv ( dev ) ;
struct blk_desc * block_dev = dev_get_uclass_platdata ( dev ) ;
# else
static unsigned long host_block_read ( struct blk_desc * block_dev ,
unsigned long start , lbaint_t blkcnt ,
void * buffer )
@ -31,6 +47,7 @@ static unsigned long host_block_read(struct blk_desc *block_dev,
if ( ! host_dev )
return - 1 ;
# endif
if ( os_lseek ( host_dev - > fd , start * block_dev - > blksz , OS_SEEK_SET ) = =
- 1 ) {
@ -43,12 +60,21 @@ static unsigned long host_block_read(struct blk_desc *block_dev,
return - 1 ;
}
# ifdef CONFIG_BLK
static unsigned long host_block_write ( struct udevice * dev ,
unsigned long start , lbaint_t blkcnt ,
const void * buffer )
{
struct host_block_dev * host_dev = dev_get_priv ( dev ) ;
struct blk_desc * block_dev = dev_get_uclass_platdata ( dev ) ;
# else
static unsigned long host_block_write ( struct blk_desc * block_dev ,
unsigned long start , lbaint_t blkcnt ,
const void * buffer )
{
int dev = block_dev - > devnum ;
struct host_block_dev * host_dev = find_host_device ( dev ) ;
# endif
if ( os_lseek ( host_dev - > fd , start * block_dev - > blksz , OS_SEEK_SET ) = =
- 1 ) {
@ -61,6 +87,70 @@ static unsigned long host_block_write(struct blk_desc *block_dev,
return - 1 ;
}
# ifdef CONFIG_BLK
int host_dev_bind ( int devnum , char * filename )
{
struct host_block_dev * host_dev ;
struct udevice * dev ;
char dev_name [ 20 ] , * str , * fname ;
int ret , fd ;
/* Remove and unbind the old device, if any */
ret = blk_get_device ( IF_TYPE_HOST , devnum , & dev ) ;
if ( ret = = 0 ) {
ret = device_remove ( dev ) ;
if ( ret )
return ret ;
ret = device_unbind ( dev ) ;
if ( ret )
return ret ;
} else if ( ret ! = - ENODEV ) {
return ret ;
}
if ( ! filename )
return 0 ;
snprintf ( dev_name , sizeof ( dev_name ) , " host%d " , devnum ) ;
str = strdup ( dev_name ) ;
if ( ! str )
return - ENOMEM ;
fname = strdup ( filename ) ;
if ( ! fname ) {
free ( str ) ;
return - ENOMEM ;
}
fd = os_open ( filename , OS_O_RDWR ) ;
if ( fd = = - 1 ) {
printf ( " Failed to access host backing file '%s' \n " , filename ) ;
ret = - ENOENT ;
goto err ;
}
ret = blk_create_device ( gd - > dm_root , " sandbox_host_blk " , str ,
IF_TYPE_HOST , devnum , 512 ,
os_lseek ( fd , 0 , OS_SEEK_END ) , & dev ) ;
if ( ret )
goto err_file ;
ret = device_probe ( dev ) ;
if ( ret ) {
device_unbind ( dev ) ;
goto err_file ;
}
host_dev = dev_get_priv ( dev ) ;
host_dev - > fd = fd ;
host_dev - > filename = fname ;
return blk_prepare_device ( dev ) ;
err_file :
os_close ( fd ) ;
err :
free ( fname ) ;
free ( str ) ;
return ret ;
}
# else
int host_dev_bind ( int dev , char * filename )
{
struct host_block_dev * host_dev = find_host_device ( dev ) ;
@ -100,9 +190,19 @@ int host_dev_bind(int dev, char *filename)
return 0 ;
}
# endif
int host_get_dev_err ( int devnum , struct blk_desc * * blk_devp )
{
# ifdef CONFIG_BLK
struct udevice * dev ;
int ret ;
ret = blk_get_device ( IF_TYPE_HOST , devnum , & dev ) ;
if ( ret )
return ret ;
* blk_devp = dev_get_uclass_platdata ( dev ) ;
# else
struct host_block_dev * host_dev = find_host_device ( devnum ) ;
if ( ! host_dev )
@ -112,6 +212,8 @@ int host_get_dev_err(int devnum, struct blk_desc **blk_devp)
return - ENOENT ;
* blk_devp = & host_dev - > blk_dev ;
# endif
return 0 ;
}
@ -124,3 +226,17 @@ struct blk_desc *host_get_dev(int dev)
return blk_dev ;
}
# ifdef CONFIG_BLK
static const struct blk_ops sandbox_host_blk_ops = {
. read = host_block_read ,
. write = host_block_write ,
} ;
U_BOOT_DRIVER ( sandbox_host_blk ) = {
. name = " sandbox_host_blk " ,
. id = UCLASS_BLK ,
. ops = & sandbox_host_blk_ops ,
. priv_auto_alloc_size = sizeof ( struct host_block_dev ) ,
} ;
# endif