Commit 40fd0508 authored by Simon Glass's avatar Simon Glass

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: default avatarSimon Glass <sjg@chromium.org>
Tested-by: default avatarStephen Warren <swarren@nvidia.com>
parent 7ded959e
......@@ -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;
};
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment