summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/misc/qfw.c87
-rw-r--r--drivers/virtio/virtio-uclass.c8
-rw-r--r--drivers/virtio/virtio_blk.c7
3 files changed, 100 insertions, 2 deletions
diff --git a/drivers/misc/qfw.c b/drivers/misc/qfw.c
index 1d54b7542b8..9ef95caa895 100644
--- a/drivers/misc/qfw.c
+++ b/drivers/misc/qfw.c
@@ -7,6 +7,9 @@
#define LOG_CATEGORY UCLASS_QFW
#include <common.h>
+#include <bootdev.h>
+#include <bootflow.h>
+#include <bootmeth.h>
#include <command.h>
#include <errno.h>
#include <log.h>
@@ -310,8 +313,92 @@ int qfw_register(struct udevice *dev)
return 0;
}
+static int qfw_post_bind(struct udevice *dev)
+{
+ int ret;
+
+ ret = bootdev_setup_for_dev(dev, "qfw_bootdev");
+ if (ret)
+ return log_msg_ret("dev", ret);
+
+ return 0;
+}
+
+static int qfw_get_bootflow(struct udevice *dev, struct bootflow_iter *iter,
+ struct bootflow *bflow)
+{
+ const struct udevice *media = dev_get_parent(dev);
+ int ret;
+
+ if (!CONFIG_IS_ENABLED(BOOTSTD))
+ return -ENOSYS;
+
+ log_debug("media=%s\n", media->name);
+ ret = bootmeth_check(bflow->method, iter);
+ if (ret)
+ return log_msg_ret("check", ret);
+
+ log_debug("iter->part=%d\n", iter->part);
+
+ /* We only support the whole device, not partitions */
+ if (iter->part)
+ return log_msg_ret("max", -ESHUTDOWN);
+
+ log_debug("reading bootflow with method: %s\n", bflow->method->name);
+ ret = bootmeth_read_bootflow(bflow->method, bflow);
+ if (ret)
+ return log_msg_ret("method", ret);
+
+ return 0;
+}
+
+static int qfw_bootdev_bind(struct udevice *dev)
+{
+ struct bootdev_uc_plat *ucp = dev_get_uclass_plat(dev);
+
+ ucp->prio = BOOTDEVP_4_SCAN_FAST;
+
+ return 0;
+}
+
+static int qfw_bootdev_hunt(struct bootdev_hunter *info, bool show)
+{
+ int ret;
+
+ ret = uclass_probe_all(UCLASS_QFW);
+ if (ret && ret != -ENOENT)
+ return log_msg_ret("vir", ret);
+
+ return 0;
+}
+
UCLASS_DRIVER(qfw) = {
.id = UCLASS_QFW,
.name = "qfw",
+ .post_bind = qfw_post_bind,
.per_device_auto = sizeof(struct qfw_dev),
};
+
+struct bootdev_ops qfw_bootdev_ops = {
+ .get_bootflow = qfw_get_bootflow,
+};
+
+static const struct udevice_id qfw_bootdev_ids[] = {
+ { .compatible = "u-boot,bootdev-qfw" },
+ { }
+};
+
+U_BOOT_DRIVER(qfw_bootdev) = {
+ .name = "qfw_bootdev",
+ .id = UCLASS_BOOTDEV,
+ .ops = &qfw_bootdev_ops,
+ .bind = qfw_bootdev_bind,
+ .of_match = qfw_bootdev_ids,
+};
+
+BOOTDEV_HUNTER(qfw_bootdev_hunter) = {
+ .prio = BOOTDEVP_4_SCAN_FAST,
+ .uclass = UCLASS_QFW,
+ .hunt = qfw_bootdev_hunt,
+ .drv = DM_DRIVER_REF(qfw_bootdev),
+};
diff --git a/drivers/virtio/virtio-uclass.c b/drivers/virtio/virtio-uclass.c
index 91af412ec1d..de9bc90359c 100644
--- a/drivers/virtio/virtio-uclass.c
+++ b/drivers/virtio/virtio-uclass.c
@@ -247,8 +247,8 @@ static int virtio_uclass_post_probe(struct udevice *udev)
}
device_set_name_alloced(vdev);
- if (uc_priv->device == VIRTIO_ID_BLOCK) {
- ret = bootdev_setup_for_dev(udev, name);
+ if (uc_priv->device == VIRTIO_ID_BLOCK && !IS_ENABLED(CONFIG_SANDBOX)) {
+ ret = bootdev_setup_sibling_blk(vdev, "virtio_bootdev");
if (ret)
return log_msg_ret("bootdev", ret);
}
@@ -275,6 +275,10 @@ static int virtio_uclass_child_pre_probe(struct udevice *vdev)
int i;
int ret;
+ /* bootdevs are not virtio devices */
+ if (device_get_uclass_id(vdev) == UCLASS_BOOTDEV)
+ return 0;
+
/*
* Save the real virtio device (eg: virtio-net, virtio-blk) to
* the transport (parent) device's uclass priv for future use.
diff --git a/drivers/virtio/virtio_blk.c b/drivers/virtio/virtio_blk.c
index 30cfc56725c..95810582867 100644
--- a/drivers/virtio/virtio_blk.c
+++ b/drivers/virtio/virtio_blk.c
@@ -4,6 +4,8 @@
* Copyright (C) 2018, Bin Meng <bmeng.cn@gmail.com>
*/
+#define LOG_CATEGORY UCLASS_VIRTIO
+
#include <common.h>
#include <blk.h>
#include <dm.h>
@@ -42,6 +44,8 @@ static ulong virtio_blk_do_req(struct udevice *dev, u64 sector,
sgs[num_out + num_in++] = &data_sg;
sgs[num_out + num_in++] = &status_sg;
+ log_debug("dev=%s, active=%d, priv=%p, priv->vq=%p\n", dev->name,
+ device_active(dev), priv, priv->vq);
ret = virtqueue_add(priv->vq, sgs, num_out, num_in);
if (ret)
@@ -49,8 +53,10 @@ static ulong virtio_blk_do_req(struct udevice *dev, u64 sector,
virtqueue_kick(priv->vq);
+ log_debug("wait...");
while (!virtqueue_get_buf(priv->vq, NULL))
;
+ log_debug("done\n");
return status == VIRTIO_BLK_S_OK ? blkcnt : -EIO;
}
@@ -58,6 +64,7 @@ static ulong virtio_blk_do_req(struct udevice *dev, u64 sector,
static ulong virtio_blk_read(struct udevice *dev, lbaint_t start,
lbaint_t blkcnt, void *buffer)
{
+ log_debug("read %s\n", dev->name);
return virtio_blk_do_req(dev, start, blkcnt, buffer,
VIRTIO_BLK_T_IN);
}