1 // SPDX-License-Identifier: GPL-2.0+
3 * Driver for sandbox host interface, used to access files on the host which
4 * contain partitions and filesystem
6 * Copyright 2022 Google LLC
10 #define LOG_CATEGORY UCLASS_HOST
18 #include <sandbox_host.h>
19 #include <dm/device-internal.h>
21 static int host_sb_attach_file(struct udevice *dev, const char *filename)
23 struct host_sb_plat *plat = dev_get_plat(dev);
24 struct blk_desc *desc;
34 return log_msg_ret("fd", -EEXIST);
36 /* Sanity check that host_sb_bind() has been used */
37 ret = blk_find_from_parent(dev, &blk);
41 fd = os_open(filename, OS_O_RDWR);
43 printf("Failed to access host backing file '%s', trying read-only\n",
45 fd = os_open(filename, OS_O_RDONLY);
47 printf("- still failed\n");
48 return log_msg_ret("open", -ENOENT);
52 fname = strdup(filename);
58 size = os_filesize(fd);
59 desc = dev_get_uclass_plat(blk);
60 if (size % desc->blksz) {
61 printf("The size of host backing file '%s' is not multiple of "
62 "the device block size\n", filename);
66 desc->lba = size / desc->blksz;
68 /* write this in last, when nothing can go wrong */
69 plat = dev_get_plat(dev);
71 plat->filename = fname;
81 static int host_sb_detach_file(struct udevice *dev)
83 struct host_sb_plat *plat = dev_get_plat(dev);
87 return log_msg_ret("fd", -ENOENT);
89 ret = device_remove(dev, DM_REMOVE_NORMAL);
91 return log_msg_ret("rem", ret);
93 /* Unbind all children */
94 ret = device_chld_unbind(dev, NULL);
96 return log_msg_ret("unb", ret);
100 free(plat->filename);
106 static int host_sb_bind(struct udevice *dev)
108 struct udevice *blk, *bdev;
109 struct blk_desc *desc;
112 ret = blk_create_devicef(dev, "sandbox_host_blk", "blk", UCLASS_HOST,
113 dev_seq(dev), DEFAULT_BLKSZ, 0, &blk);
115 return log_msg_ret("blk", ret);
117 desc = dev_get_uclass_plat(blk);
118 snprintf(desc->vendor, BLK_VEN_SIZE, "U-Boot");
119 snprintf(desc->product, BLK_PRD_SIZE, "hostfile");
120 snprintf(desc->revision, BLK_REV_SIZE, "1.0");
122 if (CONFIG_IS_ENABLED(BOOTSTD)) {
123 ret = bootdev_bind(dev, "host_bootdev", "bootdev", &bdev);
125 return log_msg_ret("bd", ret);
131 static struct host_ops host_sb_ops = {
132 .attach_file = host_sb_attach_file,
133 .detach_file = host_sb_detach_file,
136 static const struct udevice_id host_ids[] = {
137 { .compatible = "sandbox,host" },
141 U_BOOT_DRIVER(host_sb_drv) = {
142 .name = "host_sb_drv",
144 .of_match = host_ids,
146 .bind = host_sb_bind,
147 .plat_auto = sizeof(struct host_sb_plat),