// 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 <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,
};
