// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) 2007-2008 Samuel Thibault.
 * (C) Copyright 2020 EPAM Systems Inc.
 */

#define LOG_CATEGORY UCLASS_PVBLOCK

#include <blk.h>
#include <common.h>
#include <dm.h>
#include <dm/device-internal.h>
#include <malloc.h>
#include <part.h>

#include <asm/armv8/mmu.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <asm/xen/system.h>

#include <linux/bug.h>
#include <linux/compat.h>

#include <xen/events.h>
#include <xen/gnttab.h>
#include <xen/hvm.h>
#include <xen/xenbus.h>

#include <xen/interface/io/ring.h>
#include <xen/interface/io/blkif.h>
#include <xen/interface/io/protocols.h>

#define DRV_NAME	"pvblock"
#define DRV_NAME_BLK	"pvblock_blk"

#define O_RDONLY	00
#define O_RDWR		02
#define WAIT_RING_TO_MS	10

struct blkfront_info {
	u64 sectors;
	unsigned int sector_size;
	int mode;
	int info;
	int barrier;
	int flush;
};

/**
 * struct blkfront_dev - Struct representing blkfront device
 * @dom: Domain id
 * @ring: Front_ring structure
 * @ring_ref: The grant reference, allowing us to grant access
 *	      to the ring to the other end/domain
 * @evtchn: Event channel used to signal ring events
 * @handle: Events handle
 * @nodename: Device XenStore path in format "device/vbd/" + @devid
 * @backend: Backend XenStore path
 * @info: Private data
 * @devid: Device id
 */
struct blkfront_dev {
	domid_t dom;

	struct blkif_front_ring ring;
	grant_ref_t ring_ref;
	evtchn_port_t evtchn;
	blkif_vdev_t handle;

	char *nodename;
	char *backend;
	struct blkfront_info info;
	unsigned int devid;
	u8 *bounce_buffer;
};

struct blkfront_plat {
	unsigned int devid;
};

/**
 * struct blkfront_aiocb - AIO control block
 * @aio_dev: Blockfront device
 * @aio_buf: Memory buffer, which must be sector-aligned for
 *	     @aio_dev sector
 * @aio_nbytes: Size of AIO, which must be less than @aio_dev
 *		sector-sized amounts
 * @aio_offset: Offset, which must not go beyond @aio_dev
 *		sector-aligned location
 * @data: Data used to receiving response from ring
 * @gref: Array of grant references
 * @n: Number of segments
 * @aio_cb: Represents one I/O request.
 */
struct blkfront_aiocb {
	struct blkfront_dev *aio_dev;
	u8 *aio_buf;
	size_t aio_nbytes;
	off_t aio_offset;
	void *data;

	grant_ref_t gref[BLKIF_MAX_SEGMENTS_PER_REQUEST];
	int n;

	void (*aio_cb)(struct blkfront_aiocb *aiocb, int ret);
};

static void blkfront_sync(struct blkfront_dev *dev);

static void free_blkfront(struct blkfront_dev *dev)
{
	mask_evtchn(dev->evtchn);
	free(dev->backend);

	gnttab_end_access(dev->ring_ref);
	free(dev->ring.sring);

	unbind_evtchn(dev->evtchn);

	free(dev->bounce_buffer);
	free(dev->nodename);
	free(dev);
}

static int init_blkfront(unsigned int devid, struct blkfront_dev *dev)
{
	xenbus_transaction_t xbt;
	char *err = NULL;
	char *message = NULL;
	struct blkif_sring *s;
	int retry = 0;
	char *msg = NULL;
	char *c;
	char nodename[32];
	char path[ARRAY_SIZE(nodename) + strlen("/backend-id") + 1];

	sprintf(nodename, "device/vbd/%d", devid);

	memset(dev, 0, sizeof(*dev));
	dev->nodename = strdup(nodename);
	dev->devid = devid;

	snprintf(path, sizeof(path), "%s/backend-id", nodename);
	dev->dom = xenbus_read_integer(path);
	evtchn_alloc_unbound(dev->dom, NULL, dev, &dev->evtchn);

	s = (struct blkif_sring *)memalign(PAGE_SIZE, PAGE_SIZE);
	if (!s) {
		printf("Failed to allocate shared ring\n");
		goto error;
	}

	SHARED_RING_INIT(s);
	FRONT_RING_INIT(&dev->ring, s, PAGE_SIZE);

	dev->ring_ref = gnttab_grant_access(dev->dom, virt_to_pfn(s), 0);

again:
	err = xenbus_transaction_start(&xbt);
	if (err) {
		printf("starting transaction\n");
		free(err);
	}

	err = xenbus_printf(xbt, nodename, "ring-ref", "%u", dev->ring_ref);
	if (err) {
		message = "writing ring-ref";
		goto abort_transaction;
	}
	err = xenbus_printf(xbt, nodename, "event-channel", "%u", dev->evtchn);
	if (err) {
		message = "writing event-channel";
		goto abort_transaction;
	}
	err = xenbus_printf(xbt, nodename, "protocol", "%s",
			    XEN_IO_PROTO_ABI_NATIVE);
	if (err) {
		message = "writing protocol";
		goto abort_transaction;
	}

	snprintf(path, sizeof(path), "%s/state", nodename);
	err = xenbus_switch_state(xbt, path, XenbusStateConnected);
	if (err) {
		message = "switching state";
		goto abort_transaction;
	}

	err = xenbus_transaction_end(xbt, 0, &retry);
	free(err);
	if (retry) {
		goto again;
		printf("completing transaction\n");
	}

	goto done;

abort_transaction:
	free(err);
	err = xenbus_transaction_end(xbt, 1, &retry);
	printf("Abort transaction %s\n", message);
	goto error;

done:
	snprintf(path, sizeof(path), "%s/backend", nodename);
	msg = xenbus_read(XBT_NIL, path, &dev->backend);
	if (msg) {
		printf("Error %s when reading the backend path %s\n",
		       msg, path);
		goto error;
	}

	dev->handle = strtoul(strrchr(nodename, '/') + 1, NULL, 0);

	{
		XenbusState state;
		char path[strlen(dev->backend) +
			strlen("/feature-flush-cache") + 1];

		snprintf(path, sizeof(path), "%s/mode", dev->backend);
		msg = xenbus_read(XBT_NIL, path, &c);
		if (msg) {
			printf("Error %s when reading the mode\n", msg);
			goto error;
		}
		if (*c == 'w')
			dev->info.mode = O_RDWR;
		else
			dev->info.mode = O_RDONLY;
		free(c);

		snprintf(path, sizeof(path), "%s/state", dev->backend);

		msg = NULL;
		state = xenbus_read_integer(path);
		while (!msg && state < XenbusStateConnected)
			msg = xenbus_wait_for_state_change(path, &state);
		if (msg || state != XenbusStateConnected) {
			printf("backend not available, state=%d\n", state);
			goto error;
		}

		snprintf(path, sizeof(path), "%s/info", dev->backend);
		dev->info.info = xenbus_read_integer(path);

		snprintf(path, sizeof(path), "%s/sectors", dev->backend);
		/*
		 * FIXME: read_integer returns an int, so disk size
		 * limited to 1TB for now
		 */
		dev->info.sectors = xenbus_read_integer(path);

		snprintf(path, sizeof(path), "%s/sector-size", dev->backend);
		dev->info.sector_size = xenbus_read_integer(path);

		snprintf(path, sizeof(path), "%s/feature-barrier",
			 dev->backend);
		dev->info.barrier = xenbus_read_integer(path);

		snprintf(path, sizeof(path), "%s/feature-flush-cache",
			 dev->backend);
		dev->info.flush = xenbus_read_integer(path);
	}
	unmask_evtchn(dev->evtchn);

	dev->bounce_buffer = memalign(dev->info.sector_size,
				      dev->info.sector_size);
	if (!dev->bounce_buffer) {
		printf("Failed to allocate bouncing buffer\n");
		goto error;
	}

	debug("%llu sectors of %u bytes, bounce buffer at %p\n",
	      dev->info.sectors, dev->info.sector_size,
	      dev->bounce_buffer);

	return 0;

error:
	free(msg);
	free(err);
	free_blkfront(dev);
	return -ENODEV;
}

static void shutdown_blkfront(struct blkfront_dev *dev)
{
	char *err = NULL, *err2;
	XenbusState state;

	char path[strlen(dev->backend) + strlen("/state") + 1];
	char nodename[strlen(dev->nodename) + strlen("/event-channel") + 1];

	debug("Close " DRV_NAME ", device ID %d\n", dev->devid);

	blkfront_sync(dev);

	snprintf(path, sizeof(path), "%s/state", dev->backend);
	snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);

	err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosing);
	if (err) {
		printf("%s: error changing state to %d: %s\n", __func__,
		       XenbusStateClosing, err);
		goto close;
	}

	state = xenbus_read_integer(path);
	while (!err && state < XenbusStateClosing)
		err = xenbus_wait_for_state_change(path, &state);
	free(err);

	err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateClosed);
	if (err) {
		printf("%s: error changing state to %d: %s\n", __func__,
		       XenbusStateClosed, err);
		goto close;
	}

	state = xenbus_read_integer(path);
	while (state < XenbusStateClosed) {
		err = xenbus_wait_for_state_change(path, &state);
		free(err);
	}

	err = xenbus_switch_state(XBT_NIL, nodename, XenbusStateInitialising);
	if (err) {
		printf("%s: error changing state to %d: %s\n", __func__,
		       XenbusStateInitialising, err);
		goto close;
	}

	state = xenbus_read_integer(path);
	while (!err &&
	       (state < XenbusStateInitWait || state >= XenbusStateClosed))
		err = xenbus_wait_for_state_change(path, &state);

close:
	free(err);

	snprintf(nodename, sizeof(nodename), "%s/ring-ref", dev->nodename);
	err2 = xenbus_rm(XBT_NIL, nodename);
	free(err2);
	snprintf(nodename, sizeof(nodename), "%s/event-channel", dev->nodename);
	err2 = xenbus_rm(XBT_NIL, nodename);
	free(err2);

	if (!err)
		free_blkfront(dev);
}

/**
 * blkfront_aio_poll() - AIO polling function.
 * @dev: Blkfront device
 *
 * Here we receive response from the ring and check its status. This happens
 * until we read all data from the ring. We read the data from consumed pointer
 * to the response pointer. Then increase consumed pointer to make it clear that
 * the data has been read.
 *
 * Return: Number of consumed bytes.
 */
static int blkfront_aio_poll(struct blkfront_dev *dev)
{
	RING_IDX rp, cons;
	struct blkif_response *rsp;
	int more;
	int nr_consumed;

moretodo:
	rp = dev->ring.sring->rsp_prod;
	rmb(); /* Ensure we see queued responses up to 'rp'. */
	cons = dev->ring.rsp_cons;

	nr_consumed = 0;
	while ((cons != rp)) {
		struct blkfront_aiocb *aiocbp;
		int status;

		rsp = RING_GET_RESPONSE(&dev->ring, cons);
		nr_consumed++;

		aiocbp = (void *)(uintptr_t)rsp->id;
		status = rsp->status;

		switch (rsp->operation) {
		case BLKIF_OP_READ:
		case BLKIF_OP_WRITE:
		{
			int j;

			if (status != BLKIF_RSP_OKAY)
				printf("%s error %d on %s at offset %llu, num bytes %llu\n",
				       rsp->operation == BLKIF_OP_READ ?
				       "read" : "write",
				       status, aiocbp->aio_dev->nodename,
				       (unsigned long long)aiocbp->aio_offset,
				       (unsigned long long)aiocbp->aio_nbytes);

			for (j = 0; j < aiocbp->n; j++)
				gnttab_end_access(aiocbp->gref[j]);

			break;
		}

		case BLKIF_OP_WRITE_BARRIER:
			if (status != BLKIF_RSP_OKAY)
				printf("write barrier error %d\n", status);
			break;
		case BLKIF_OP_FLUSH_DISKCACHE:
			if (status != BLKIF_RSP_OKAY)
				printf("flush error %d\n", status);
			break;

		default:
			printf("unrecognized block operation %d response (status %d)\n",
			       rsp->operation, status);
			break;
		}

		dev->ring.rsp_cons = ++cons;
		/* Nota: callback frees aiocbp itself */
		if (aiocbp && aiocbp->aio_cb)
			aiocbp->aio_cb(aiocbp, status ? -EIO : 0);
		if (dev->ring.rsp_cons != cons)
			/* We reentered, we must not continue here */
			break;
	}

	RING_FINAL_CHECK_FOR_RESPONSES(&dev->ring, more);
	if (more)
		goto moretodo;

	return nr_consumed;
}

static void blkfront_wait_slot(struct blkfront_dev *dev)
{
	/* Wait for a slot */
	if (RING_FULL(&dev->ring)) {
		while (true) {
			blkfront_aio_poll(dev);
			if (!RING_FULL(&dev->ring))
				break;
			wait_event_timeout(NULL, !RING_FULL(&dev->ring),
					   WAIT_RING_TO_MS);
		}
	}
}

/**
 * blkfront_aio_poll() - Issue an aio.
 * @aiocbp: AIO control block structure
 * @write: Describes is it read or write operation
 *	   0 - read
 *	   1 - write
 *
 * We check whether the AIO parameters meet the requirements of the device.
 * Then receive request from ring and define its arguments. After this we
 * grant access to the grant references. The last step is notifying about AIO
 * via event channel.
 */
static void blkfront_aio(struct blkfront_aiocb *aiocbp, int write)
{
	struct blkfront_dev *dev = aiocbp->aio_dev;
	struct blkif_request *req;
	RING_IDX i;
	int notify;
	int n, j;
	uintptr_t start, end;

	/* Can't io at non-sector-aligned location */
	BUG_ON(aiocbp->aio_offset & (dev->info.sector_size - 1));
	/* Can't io non-sector-sized amounts */
	BUG_ON(aiocbp->aio_nbytes & (dev->info.sector_size - 1));
	/* Can't io non-sector-aligned buffer */
	BUG_ON(((uintptr_t)aiocbp->aio_buf & (dev->info.sector_size - 1)));

	start = (uintptr_t)aiocbp->aio_buf & PAGE_MASK;
	end = ((uintptr_t)aiocbp->aio_buf + aiocbp->aio_nbytes +
	       PAGE_SIZE - 1) & PAGE_MASK;
	n = (end - start) / PAGE_SIZE;
	aiocbp->n = n;

	BUG_ON(n > BLKIF_MAX_SEGMENTS_PER_REQUEST);

	blkfront_wait_slot(dev);
	i = dev->ring.req_prod_pvt;
	req = RING_GET_REQUEST(&dev->ring, i);

	req->operation = write ? BLKIF_OP_WRITE : BLKIF_OP_READ;
	req->nr_segments = n;
	req->handle = dev->handle;
	req->id = (uintptr_t)aiocbp;
	req->sector_number = aiocbp->aio_offset / dev->info.sector_size;

	for (j = 0; j < n; j++) {
		req->seg[j].first_sect = 0;
		req->seg[j].last_sect = PAGE_SIZE / dev->info.sector_size - 1;
	}
	req->seg[0].first_sect = ((uintptr_t)aiocbp->aio_buf & ~PAGE_MASK) /
		dev->info.sector_size;
	req->seg[n - 1].last_sect = (((uintptr_t)aiocbp->aio_buf +
		aiocbp->aio_nbytes - 1) & ~PAGE_MASK) / dev->info.sector_size;
	for (j = 0; j < n; j++) {
		uintptr_t data = start + j * PAGE_SIZE;

		if (!write) {
			/* Trigger CoW if needed */
			*(char *)(data + (req->seg[j].first_sect *
					  dev->info.sector_size)) = 0;
			barrier();
		}
		req->seg[j].gref = gnttab_grant_access(dev->dom,
						       virt_to_pfn((void *)data),
						       write);
		aiocbp->gref[j] = req->seg[j].gref;
	}

	dev->ring.req_prod_pvt = i + 1;

	wmb();
	RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&dev->ring, notify);

	if (notify)
		notify_remote_via_evtchn(dev->evtchn);
}

static void blkfront_aio_cb(struct blkfront_aiocb *aiocbp, int ret)
{
	aiocbp->data = (void *)1;
	aiocbp->aio_cb = NULL;
}

static void blkfront_io(struct blkfront_aiocb *aiocbp, int write)
{
	aiocbp->aio_cb = blkfront_aio_cb;
	blkfront_aio(aiocbp, write);
	aiocbp->data = NULL;

	while (true) {
		blkfront_aio_poll(aiocbp->aio_dev);
		if (aiocbp->data)
			break;
		cpu_relax();
	}
}

static void blkfront_push_operation(struct blkfront_dev *dev, u8 op,
				    uint64_t id)
{
	struct blkif_request *req;
	int notify, i;

	blkfront_wait_slot(dev);
	i = dev->ring.req_prod_pvt;
	req = RING_GET_REQUEST(&dev->ring, i);
	req->operation = op;
	req->nr_segments = 0;
	req->handle = dev->handle;
	req->id = id;
	req->sector_number = 0;
	dev->ring.req_prod_pvt = i + 1;
	wmb();
	RING_PUSH_REQUESTS_AND_CHECK_NOTIFY(&dev->ring, notify);
	if (notify)
		notify_remote_via_evtchn(dev->evtchn);
}

static void blkfront_sync(struct blkfront_dev *dev)
{
	if (dev->info.mode == O_RDWR) {
		if (dev->info.barrier == 1)
			blkfront_push_operation(dev,
						BLKIF_OP_WRITE_BARRIER, 0);

		if (dev->info.flush == 1)
			blkfront_push_operation(dev,
						BLKIF_OP_FLUSH_DISKCACHE, 0);
	}

	while (true) {
		blkfront_aio_poll(dev);
		if (RING_FREE_REQUESTS(&dev->ring) == RING_SIZE(&dev->ring))
			break;
		cpu_relax();
	}
}

/**
 * pvblock_iop() - Issue an aio.
 * @udev: Pvblock device
 * @blknr: Block number to read from / write to
 * @blkcnt: Amount of blocks to read / write
 * @buffer: Memory buffer with data to be read / write
 * @write: Describes is it read or write operation
 *	   0 - read
 *	   1 - write
 *
 * Depending on the operation - reading or writing, data is read / written from the
 * specified address (@buffer) to the sector (@blknr).
 */
static ulong pvblock_iop(struct udevice *udev, lbaint_t blknr,
			 lbaint_t blkcnt, void *buffer, int write)
{
	struct blkfront_dev *blk_dev = dev_get_priv(udev);
	struct blk_desc *desc = dev_get_uclass_plat(udev);
	struct blkfront_aiocb aiocb;
	lbaint_t blocks_todo;
	bool unaligned;

	if (blkcnt == 0)
		return 0;

	if ((blknr + blkcnt) > desc->lba) {
		printf(DRV_NAME ": block number 0x" LBAF " exceeds max(0x" LBAF ")\n",
		       blknr + blkcnt, desc->lba);
		return 0;
	}

	unaligned = (uintptr_t)buffer & (blk_dev->info.sector_size - 1);

	aiocb.aio_dev = blk_dev;
	aiocb.aio_offset = blknr * desc->blksz;
	aiocb.aio_cb = NULL;
	aiocb.data = NULL;
	blocks_todo = blkcnt;
	do {
		aiocb.aio_buf = unaligned ? blk_dev->bounce_buffer : buffer;

		if (write && unaligned)
			memcpy(blk_dev->bounce_buffer, buffer, desc->blksz);

		aiocb.aio_nbytes = unaligned ? desc->blksz :
			min((size_t)((BLKIF_MAX_SEGMENTS_PER_REQUEST - 1)
					* PAGE_SIZE),
			    (size_t)(blocks_todo * desc->blksz));

		blkfront_io(&aiocb, write);

		if (!write && unaligned)
			memcpy(buffer, blk_dev->bounce_buffer, desc->blksz);

		aiocb.aio_offset += aiocb.aio_nbytes;
		buffer += aiocb.aio_nbytes;
		blocks_todo -= aiocb.aio_nbytes / desc->blksz;
	} while (blocks_todo > 0);

	return blkcnt;
}

ulong pvblock_blk_read(struct udevice *udev, lbaint_t blknr, lbaint_t blkcnt,
		       void *buffer)
{
	return pvblock_iop(udev, blknr, blkcnt, buffer, 0);
}

ulong pvblock_blk_write(struct udevice *udev, lbaint_t blknr, lbaint_t blkcnt,
			const void *buffer)
{
	return pvblock_iop(udev, blknr, blkcnt, (void *)buffer, 1);
}

static int pvblock_blk_bind(struct udevice *udev)
{
	struct blk_desc *desc = dev_get_uclass_plat(udev);
	int devnum;

	desc->uclass_id = UCLASS_PVBLOCK;
	/*
	 * Initialize the devnum to -ENODEV. This is to make sure that
	 * blk_next_free_devnum() works as expected, since the default
	 * value 0 is a valid devnum.
	 */
	desc->devnum = -ENODEV;
	devnum = blk_next_free_devnum(UCLASS_PVBLOCK);
	if (devnum < 0)
		return devnum;
	desc->devnum = devnum;
	desc->part_type = PART_TYPE_UNKNOWN;
	desc->bdev = udev;

	strncpy(desc->vendor, "Xen", sizeof(desc->vendor));
	strncpy(desc->revision, "1", sizeof(desc->revision));
	strncpy(desc->product, "Virtual disk", sizeof(desc->product));

	return 0;
}

static int pvblock_blk_probe(struct udevice *udev)
{
	struct blkfront_dev *blk_dev = dev_get_priv(udev);
	struct blkfront_plat *plat = dev_get_plat(udev);
	struct blk_desc *desc = dev_get_uclass_plat(udev);
	int ret, devid;

	devid = plat->devid;
	free(plat);

	ret = init_blkfront(devid, blk_dev);
	if (ret < 0)
		return ret;

	desc->blksz = blk_dev->info.sector_size;
	desc->lba = blk_dev->info.sectors;
	desc->log2blksz = LOG2(blk_dev->info.sector_size);

	return 0;
}

static int pvblock_blk_remove(struct udevice *udev)
{
	struct blkfront_dev *blk_dev = dev_get_priv(udev);

	shutdown_blkfront(blk_dev);
	return 0;
}

static const struct blk_ops pvblock_blk_ops = {
	.read	= pvblock_blk_read,
	.write	= pvblock_blk_write,
};

U_BOOT_DRIVER(pvblock_blk) = {
	.name			= DRV_NAME_BLK,
	.id			= UCLASS_BLK,
	.ops			= &pvblock_blk_ops,
	.bind			= pvblock_blk_bind,
	.probe			= pvblock_blk_probe,
	.remove			= pvblock_blk_remove,
	.priv_auto	= sizeof(struct blkfront_dev),
	.flags			= DM_FLAG_OS_PREPARE,
};

/*******************************************************************************
 * Para-virtual block device class
 *******************************************************************************/

typedef int (*enum_vbd_callback)(struct udevice *parent, unsigned int devid);

static int on_new_vbd(struct udevice *parent, unsigned int devid)
{
	struct driver_info info;
	struct udevice *udev;
	struct blkfront_plat *plat;
	int ret;

	debug("New " DRV_NAME_BLK ", device ID %d\n", devid);

	plat = malloc(sizeof(struct blkfront_plat));
	if (!plat) {
		printf("Failed to allocate platform data\n");
		return -ENOMEM;
	}

	plat->devid = devid;

	info.name = DRV_NAME_BLK;
	info.plat = plat;

	ret = device_bind_by_name(parent, false, &info, &udev);
	if (ret < 0) {
		printf("Failed to bind " DRV_NAME_BLK " to device with ID %d, ret: %d\n",
		       devid, ret);
		free(plat);
	}
	return ret;
}

static int xenbus_enumerate_vbd(struct udevice *udev, enum_vbd_callback clb)
{
	char **dirs, *msg;
	int i, ret;

	msg = xenbus_ls(XBT_NIL, "device/vbd", &dirs);
	if (msg) {
		printf("Failed to read device/vbd directory: %s\n", msg);
		free(msg);
		return -ENODEV;
	}

	for (i = 0; dirs[i]; i++) {
		int devid;

		sscanf(dirs[i], "%d", &devid);
		ret = clb(udev, devid);
		if (ret < 0)
			goto fail;

		free(dirs[i]);
	}
	ret = 0;

fail:
	for (; dirs[i]; i++)
		free(dirs[i]);
	free(dirs);
	return ret;
}

static void print_pvblock_devices(void)
{
	struct udevice *udev;
	bool first = true;
	const char *class_name;

	class_name = uclass_get_name(UCLASS_PVBLOCK);
	for (blk_first_device(UCLASS_PVBLOCK, &udev); udev;
	     blk_next_device(&udev), first = false) {
		struct blk_desc *desc = dev_get_uclass_plat(udev);

		if (!first)
			puts(", ");
		printf("%s: %d", class_name, desc->devnum);
	}
	printf("\n");
}

void pvblock_init(void)
{
	struct driver_info info;
	int ret;

	/*
	 * At this point Xen drivers have already initialized,
	 * so we can instantiate the class driver and enumerate
	 * virtual block devices.
	 */
	info.name = DRV_NAME;
	ret = device_bind_by_name(gd->dm_root, false, &info, NULL);
	if (ret < 0)
		printf("Failed to bind " DRV_NAME ", ret: %d\n", ret);

	/* Bootstrap virtual block devices class driver */
	uclass_probe_all(UCLASS_PVBLOCK);

	print_pvblock_devices();
}

static int pvblock_probe(struct udevice *udev)
{
	struct uclass *uc;
	int ret;

	if (xenbus_enumerate_vbd(udev, on_new_vbd) < 0)
		return -ENODEV;

	ret = uclass_get(UCLASS_BLK, &uc);
	if (ret)
		return ret;
	uclass_foreach_dev_probe(UCLASS_BLK, udev);
	return 0;
}

U_BOOT_DRIVER(pvblock_drv) = {
	.name		= DRV_NAME,
	.id		= UCLASS_PVBLOCK,
	.probe		= pvblock_probe,
};

UCLASS_DRIVER(pvblock) = {
	.name		= DRV_NAME,
	.id		= UCLASS_PVBLOCK,
};
