[U-Boot] [PATCH v2 24/32] dm: sandbox: Add driver-model block-device support for sandbox

Simon Glass sjg at chromium.org
Mon Feb 29 23:25:57 CET 2016


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 at chromium.org>
---

Changes in v2:
- Use snprintf() to avoid overflow

 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 <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);
 	}
diff --git a/drivers/block/sandbox.c b/drivers/block/sandbox.c
index dde9d68..6d41508 100644
--- a/drivers/block/sandbox.c
+++ b/drivers/block/sandbox.c
@@ -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
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



More information about the U-Boot mailing list