2 * Copyright (C) 2013 Henrik Nordstrom <henrik@henriknordstrom.net>
4 * SPDX-License-Identifier: GPL-2.0+
14 #include <sandboxblockdev.h>
15 #include <asm/errno.h>
16 #include <dm/device-internal.h>
18 DECLARE_GLOBAL_DATA_PTR;
20 static unsigned long host_block_read(struct udevice *dev,
21 unsigned long start, lbaint_t blkcnt,
24 struct host_block_dev *host_dev = dev_get_priv(dev);
25 struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
27 if (os_lseek(host_dev->fd, start * block_dev->blksz, OS_SEEK_SET) ==
29 printf("ERROR: Invalid block %lx\n", start);
32 ssize_t len = os_read(host_dev->fd, buffer, blkcnt * block_dev->blksz);
34 return len / block_dev->blksz;
38 static unsigned long host_block_write(struct udevice *dev,
39 unsigned long start, lbaint_t blkcnt,
42 struct host_block_dev *host_dev = dev_get_priv(dev);
43 struct blk_desc *block_dev = dev_get_uclass_platdata(dev);
45 if (os_lseek(host_dev->fd, start * block_dev->blksz, OS_SEEK_SET) ==
47 printf("ERROR: Invalid block %lx\n", start);
50 ssize_t len = os_write(host_dev->fd, buffer, blkcnt * block_dev->blksz);
52 return len / block_dev->blksz;
56 int host_dev_bind(int devnum, char *filename)
58 struct host_block_dev *host_dev;
60 char dev_name[20], *str, *fname;
63 /* Remove and unbind the old device, if any */
64 ret = blk_get_device(IF_TYPE_HOST, devnum, &dev);
66 ret = device_remove(dev);
69 ret = device_unbind(dev);
72 } else if (ret != -ENODEV) {
79 snprintf(dev_name, sizeof(dev_name), "host%d", devnum);
80 str = strdup(dev_name);
83 fname = strdup(filename);
89 fd = os_open(filename, OS_O_RDWR);
91 printf("Failed to access host backing file '%s'\n", filename);
95 ret = blk_create_device(gd->dm_root, "sandbox_host_blk", str,
96 IF_TYPE_HOST, devnum, 512,
97 os_lseek(fd, 0, OS_SEEK_END), &dev);
100 ret = device_probe(dev);
106 host_dev = dev_get_priv(dev);
108 host_dev->filename = fname;
110 return blk_prepare_device(dev);
119 int host_get_dev_err(int devnum, struct blk_desc **blk_devp)
124 ret = blk_get_device(IF_TYPE_HOST, devnum, &dev);
127 *blk_devp = dev_get_uclass_platdata(dev);
132 struct blk_desc *host_get_dev(int dev)
134 struct blk_desc *blk_dev;
136 if (host_get_dev_err(dev, &blk_dev))
142 static const struct blk_ops sandbox_host_blk_ops = {
143 .read = host_block_read,
144 .write = host_block_write,
147 U_BOOT_DRIVER(sandbox_host_blk) = {
148 .name = "sandbox_host_blk",
150 .ops = &sandbox_host_blk_ops,
151 .priv_auto_alloc_size = sizeof(struct host_block_dev),