]> git.sur5r.net Git - u-boot/commitdiff
dm: sandbox: Add driver-model block-device support for sandbox
authorSimon Glass <sjg@chromium.org>
Mon, 29 Feb 2016 22:25:57 +0000 (15:25 -0700)
committerSimon Glass <sjg@chromium.org>
Mon, 14 Mar 2016 21:34:50 +0000 (15:34 -0600)
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>
cmd/host.c
drivers/block/sandbox.c
include/sandboxblockdev.h

index ee219ce914506857662e7459d0f35b6769f39d29..8d84415301f9ec6454676c334595b786d04a0af8 100644 (file)
@@ -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);
        }
index dde9d6845f713e7d26eb95ecf44623109b4f35ee..6d41508d5c17c15c388e5e2baae9545db35d324c 100644 (file)
@@ -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
index 59f951934660c83434ed7af65110cf7f7ef0efdc..5174f45f5e282ed02a0899ceeda0d7d02fdf1dd4 100644 (file)
@@ -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;
 };