dm: sandbox: Add driver-model block-device support for sandbox
Update the host driver to support driver model for block devices. A future commit will remove the old code, but for now it is useful to be able to use it both with and without CONFIG_BLK. Signed-off-by: Simon Glass <sjg@chromium.org> Tested-by: Stephen Warren <swarren@nvidia.com>
This commit is contained in:
parent
7ded959e4d
commit
40fd050890
@ -5,6 +5,7 @@
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <fs.h>
|
||||
#include <part.h>
|
||||
#include <sandboxblockdev.h>
|
||||
@ -80,7 +81,13 @@ static int do_host_info(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
|
||||
continue;
|
||||
}
|
||||
struct host_block_dev *host_dev = blk_dev->priv;
|
||||
struct host_block_dev *host_dev;
|
||||
|
||||
#ifdef CONFIG_BLK
|
||||
host_dev = dev_get_priv(blk_dev->bdev);
|
||||
#else
|
||||
host_dev = blk_dev->priv;
|
||||
#endif
|
||||
printf("%12lu %s\n", (unsigned long)blk_dev->lba,
|
||||
host_dev->filename);
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -8,7 +8,9 @@
|
||||
#define __SANDBOX_BLOCK_DEV__
|
||||
|
||||
struct host_block_dev {
|
||||
#ifndef CONFIG_BLK
|
||||
struct blk_desc blk_dev;
|
||||
#endif
|
||||
char *filename;
|
||||
int fd;
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user