From mboxrd@z Thu Jan 1 00:00:00 1970 From: Simon Glass Date: Sun, 14 Feb 2016 19:16:53 -0700 Subject: [U-Boot] [PATCH 24/30] dm: sandbox: Add driver-model block-device support for sandbox In-Reply-To: <1455502619-16093-1-git-send-email-sjg@chromium.org> References: <1455502619-16093-1-git-send-email-sjg@chromium.org> Message-ID: <1455502619-16093-25-git-send-email-sjg@chromium.org> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: u-boot@lists.denx.de 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 --- cmd/host.c | 9 +++- drivers/block/sandbox.c | 118 +++++++++++++++++++++++++++++++++++++++++++++- include/sandboxblockdev.h | 2 + 3 files changed, 127 insertions(+), 2 deletions(-) diff --git a/cmd/host.c b/cmd/host.c index ee219ce..8d84415 100644 --- a/cmd/host.c +++ b/cmd/host.c @@ -5,6 +5,7 @@ */ #include +#include #include #include #include @@ -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); } diff --git a/drivers/block/sandbox.c b/drivers/block/sandbox.c index dde9d68..f5a8688 100644 --- a/drivers/block/sandbox.c +++ b/drivers/block/sandbox.c @@ -4,14 +4,20 @@ * SPDX-License-Identifier: GPL-2.0+ */ -#include #include +#include +#include +#include #include #include #include #include #include +#include +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; + + sprintf(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 diff --git a/include/sandboxblockdev.h b/include/sandboxblockdev.h index 59f9519..5174f45 100644 --- a/include/sandboxblockdev.h +++ b/include/sandboxblockdev.h @@ -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; }; -- 2.7.0.rc3.207.g0ac5344