mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-09-29 08:00:26 +09:00
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 <common.h>
|
||||||
|
#include <dm.h>
|
||||||
#include <fs.h>
|
#include <fs.h>
|
||||||
#include <part.h>
|
#include <part.h>
|
||||||
#include <sandboxblockdev.h>
|
#include <sandboxblockdev.h>
|
||||||
@ -80,7 +81,13 @@ static int do_host_info(cmd_tbl_t *cmdtp, int flag, int argc,
|
|||||||
|
|
||||||
continue;
|
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,
|
printf("%12lu %s\n", (unsigned long)blk_dev->lba,
|
||||||
host_dev->filename);
|
host_dev->filename);
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,20 @@
|
|||||||
* SPDX-License-Identifier: GPL-2.0+
|
* SPDX-License-Identifier: GPL-2.0+
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <config.h>
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
|
#include <blk.h>
|
||||||
|
#include <dm.h>
|
||||||
|
#include <fdtdec.h>
|
||||||
#include <part.h>
|
#include <part.h>
|
||||||
#include <os.h>
|
#include <os.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <sandboxblockdev.h>
|
#include <sandboxblockdev.h>
|
||||||
#include <asm/errno.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 host_devices[CONFIG_HOST_MAX_DEVICES];
|
||||||
|
|
||||||
static struct host_block_dev *find_host_device(int dev)
|
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;
|
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,
|
static unsigned long host_block_read(struct blk_desc *block_dev,
|
||||||
unsigned long start, lbaint_t blkcnt,
|
unsigned long start, lbaint_t blkcnt,
|
||||||
void *buffer)
|
void *buffer)
|
||||||
@ -31,6 +47,7 @@ static unsigned long host_block_read(struct blk_desc *block_dev,
|
|||||||
|
|
||||||
if (!host_dev)
|
if (!host_dev)
|
||||||
return -1;
|
return -1;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (os_lseek(host_dev->fd, start * block_dev->blksz, OS_SEEK_SET) ==
|
if (os_lseek(host_dev->fd, start * block_dev->blksz, OS_SEEK_SET) ==
|
||||||
-1) {
|
-1) {
|
||||||
@ -43,12 +60,21 @@ static unsigned long host_block_read(struct blk_desc *block_dev,
|
|||||||
return -1;
|
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,
|
static unsigned long host_block_write(struct blk_desc *block_dev,
|
||||||
unsigned long start, lbaint_t blkcnt,
|
unsigned long start, lbaint_t blkcnt,
|
||||||
const void *buffer)
|
const void *buffer)
|
||||||
{
|
{
|
||||||
int dev = block_dev->devnum;
|
int dev = block_dev->devnum;
|
||||||
struct host_block_dev *host_dev = find_host_device(dev);
|
struct host_block_dev *host_dev = find_host_device(dev);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (os_lseek(host_dev->fd, start * block_dev->blksz, OS_SEEK_SET) ==
|
if (os_lseek(host_dev->fd, start * block_dev->blksz, OS_SEEK_SET) ==
|
||||||
-1) {
|
-1) {
|
||||||
@ -61,6 +87,70 @@ static unsigned long host_block_write(struct blk_desc *block_dev,
|
|||||||
return -1;
|
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)
|
int host_dev_bind(int dev, char *filename)
|
||||||
{
|
{
|
||||||
struct host_block_dev *host_dev = find_host_device(dev);
|
struct host_block_dev *host_dev = find_host_device(dev);
|
||||||
@ -100,9 +190,19 @@ int host_dev_bind(int dev, char *filename)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
int host_get_dev_err(int devnum, struct blk_desc **blk_devp)
|
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);
|
struct host_block_dev *host_dev = find_host_device(devnum);
|
||||||
|
|
||||||
if (!host_dev)
|
if (!host_dev)
|
||||||
@ -112,6 +212,8 @@ int host_get_dev_err(int devnum, struct blk_desc **blk_devp)
|
|||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
|
|
||||||
*blk_devp = &host_dev->blk_dev;
|
*blk_devp = &host_dev->blk_dev;
|
||||||
|
#endif
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,3 +226,17 @@ struct blk_desc *host_get_dev(int dev)
|
|||||||
|
|
||||||
return blk_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__
|
#define __SANDBOX_BLOCK_DEV__
|
||||||
|
|
||||||
struct host_block_dev {
|
struct host_block_dev {
|
||||||
|
#ifndef CONFIG_BLK
|
||||||
struct blk_desc blk_dev;
|
struct blk_desc blk_dev;
|
||||||
|
#endif
|
||||||
char *filename;
|
char *filename;
|
||||||
int fd;
|
int fd;
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user