1 // SPDX-License-Identifier: GPL-2.0+
3 * (C) 2007-2008 Samuel Thibault.
4 * (C) Copyright 2020 EPAM Systems Inc.
9 #include <dm/device-internal.h>
13 #include <asm/armv8/mmu.h>
15 #include <asm/xen/system.h>
17 #include <linux/compat.h>
19 #include <xen/events.h>
20 #include <xen/gnttab.h>
22 #include <xen/xenbus.h>
24 #include <xen/interface/io/ring.h>
25 #include <xen/interface/io/blkif.h>
26 #include <xen/interface/io/protocols.h>
28 #define DRV_NAME "pvblock"
29 #define DRV_NAME_BLK "pvblock_blk"
34 struct blkfront_info {
36 unsigned int sector_size;
44 * struct blkfront_dev - Struct representing blkfront device
46 * @ring: Front_ring structure
47 * @ring_ref: The grant reference, allowing us to grant access
48 * to the ring to the other end/domain
49 * @evtchn: Event channel used to signal ring events
50 * @handle: Events handle
51 * @nodename: Device XenStore path in format "device/vbd/" + @devid
52 * @backend: Backend XenStore path
59 struct blkif_front_ring ring;
66 struct blkfront_info info;
70 struct blkfront_platdata {
74 static void free_blkfront(struct blkfront_dev *dev)
76 mask_evtchn(dev->evtchn);
79 gnttab_end_access(dev->ring_ref);
80 free(dev->ring.sring);
82 unbind_evtchn(dev->evtchn);
88 static void blkfront_handler(evtchn_port_t port, struct pt_regs *regs,
91 printf("%s [Port %d] - event received\n", __func__, port);
94 static int init_blkfront(unsigned int devid, struct blkfront_dev *dev)
96 xenbus_transaction_t xbt;
99 struct blkif_sring *s;
104 char path[ARRAY_SIZE(nodename) + strlen("/backend-id") + 1];
106 sprintf(nodename, "device/vbd/%d", devid);
108 memset(dev, 0, sizeof(*dev));
109 dev->nodename = strdup(nodename);
112 snprintf(path, sizeof(path), "%s/backend-id", nodename);
113 dev->dom = xenbus_read_integer(path);
114 evtchn_alloc_unbound(dev->dom, blkfront_handler, dev, &dev->evtchn);
116 s = (struct blkif_sring *)memalign(PAGE_SIZE, PAGE_SIZE);
118 printf("Failed to allocate shared ring\n");
123 FRONT_RING_INIT(&dev->ring, s, PAGE_SIZE);
125 dev->ring_ref = gnttab_grant_access(dev->dom, virt_to_pfn(s), 0);
128 err = xenbus_transaction_start(&xbt);
130 printf("starting transaction\n");
134 err = xenbus_printf(xbt, nodename, "ring-ref", "%u", dev->ring_ref);
136 message = "writing ring-ref";
137 goto abort_transaction;
139 err = xenbus_printf(xbt, nodename, "event-channel", "%u", dev->evtchn);
141 message = "writing event-channel";
142 goto abort_transaction;
144 err = xenbus_printf(xbt, nodename, "protocol", "%s",
145 XEN_IO_PROTO_ABI_NATIVE);
147 message = "writing protocol";
148 goto abort_transaction;
151 snprintf(path, sizeof(path), "%s/state", nodename);
152 err = xenbus_switch_state(xbt, path, XenbusStateConnected);
154 message = "switching state";
155 goto abort_transaction;
158 err = xenbus_transaction_end(xbt, 0, &retry);
162 printf("completing transaction\n");
169 err = xenbus_transaction_end(xbt, 1, &retry);
170 printf("Abort transaction %s\n", message);
174 snprintf(path, sizeof(path), "%s/backend", nodename);
175 msg = xenbus_read(XBT_NIL, path, &dev->backend);
177 printf("Error %s when reading the backend path %s\n",
182 dev->handle = strtoul(strrchr(nodename, '/') + 1, NULL, 0);
186 char path[strlen(dev->backend) +
187 strlen("/feature-flush-cache") + 1];
189 snprintf(path, sizeof(path), "%s/mode", dev->backend);
190 msg = xenbus_read(XBT_NIL, path, &c);
192 printf("Error %s when reading the mode\n", msg);
196 dev->info.mode = O_RDWR;
198 dev->info.mode = O_RDONLY;
201 snprintf(path, sizeof(path), "%s/state", dev->backend);
204 state = xenbus_read_integer(path);
205 while (!msg && state < XenbusStateConnected)
206 msg = xenbus_wait_for_state_change(path, &state);
207 if (msg || state != XenbusStateConnected) {
208 printf("backend not available, state=%d\n", state);
212 snprintf(path, sizeof(path), "%s/info", dev->backend);
213 dev->info.info = xenbus_read_integer(path);
215 snprintf(path, sizeof(path), "%s/sectors", dev->backend);
217 * FIXME: read_integer returns an int, so disk size
218 * limited to 1TB for now
220 dev->info.sectors = xenbus_read_integer(path);
222 snprintf(path, sizeof(path), "%s/sector-size", dev->backend);
223 dev->info.sector_size = xenbus_read_integer(path);
225 snprintf(path, sizeof(path), "%s/feature-barrier",
227 dev->info.barrier = xenbus_read_integer(path);
229 snprintf(path, sizeof(path), "%s/feature-flush-cache",
231 dev->info.flush = xenbus_read_integer(path);
233 unmask_evtchn(dev->evtchn);
235 debug("%llu sectors of %u bytes\n",
236 dev->info.sectors, dev->info.sector_size);
247 static void shutdown_blkfront(struct blkfront_dev *dev)
249 char *err = NULL, *err2;
252 char path[strlen(dev->backend) + strlen("/state") + 1];
253 char nodename[strlen(dev->nodename) + strlen("/event-channel") + 1];
255 debug("Close " DRV_NAME ", device ID %d\n", dev->devid);
257 snprintf(path, sizeof(path), "%s/state", dev->backend);
258 snprintf(nodename, sizeof(nodename), "%s/state", dev->nodename);
260 if ((err = xenbus_switch_state(XBT_NIL, nodename,
261 XenbusStateClosing)) != NULL) {
262 printf("%s: error changing state to %d: %s\n", __func__,
263 XenbusStateClosing, err);
267 state = xenbus_read_integer(path);
268 while (!err && state < XenbusStateClosing)
269 err = xenbus_wait_for_state_change(path, &state);
272 if ((err = xenbus_switch_state(XBT_NIL, nodename,
273 XenbusStateClosed)) != NULL) {
274 printf("%s: error changing state to %d: %s\n", __func__,
275 XenbusStateClosed, err);
279 state = xenbus_read_integer(path);
280 while (state < XenbusStateClosed) {
281 err = xenbus_wait_for_state_change(path, &state);
285 if ((err = xenbus_switch_state(XBT_NIL, nodename,
286 XenbusStateInitialising)) != NULL) {
287 printf("%s: error changing state to %d: %s\n", __func__,
288 XenbusStateInitialising, err);
292 state = xenbus_read_integer(path);
294 (state < XenbusStateInitWait || state >= XenbusStateClosed))
295 err = xenbus_wait_for_state_change(path, &state);
300 snprintf(nodename, sizeof(nodename), "%s/ring-ref", dev->nodename);
301 err2 = xenbus_rm(XBT_NIL, nodename);
303 snprintf(nodename, sizeof(nodename), "%s/event-channel", dev->nodename);
304 err2 = xenbus_rm(XBT_NIL, nodename);
311 ulong pvblock_blk_read(struct udevice *udev, lbaint_t blknr, lbaint_t blkcnt,
317 ulong pvblock_blk_write(struct udevice *udev, lbaint_t blknr, lbaint_t blkcnt,
323 static int pvblock_blk_bind(struct udevice *udev)
325 struct blk_desc *desc = dev_get_uclass_platdata(udev);
328 desc->if_type = IF_TYPE_PVBLOCK;
330 * Initialize the devnum to -ENODEV. This is to make sure that
331 * blk_next_free_devnum() works as expected, since the default
332 * value 0 is a valid devnum.
334 desc->devnum = -ENODEV;
335 devnum = blk_next_free_devnum(IF_TYPE_PVBLOCK);
338 desc->devnum = devnum;
339 desc->part_type = PART_TYPE_UNKNOWN;
342 strncpy(desc->vendor, "Xen", sizeof(desc->vendor));
343 strncpy(desc->revision, "1", sizeof(desc->revision));
344 strncpy(desc->product, "Virtual disk", sizeof(desc->product));
349 static int pvblock_blk_probe(struct udevice *udev)
351 struct blkfront_dev *blk_dev = dev_get_priv(udev);
352 struct blkfront_platdata *platdata = dev_get_platdata(udev);
353 struct blk_desc *desc = dev_get_uclass_platdata(udev);
356 devid = platdata->devid;
359 ret = init_blkfront(devid, blk_dev);
363 desc->blksz = blk_dev->info.sector_size;
364 desc->lba = blk_dev->info.sectors;
365 desc->log2blksz = LOG2(blk_dev->info.sector_size);
370 static int pvblock_blk_remove(struct udevice *udev)
372 struct blkfront_dev *blk_dev = dev_get_priv(udev);
374 shutdown_blkfront(blk_dev);
378 static const struct blk_ops pvblock_blk_ops = {
379 .read = pvblock_blk_read,
380 .write = pvblock_blk_write,
383 U_BOOT_DRIVER(pvblock_blk) = {
384 .name = DRV_NAME_BLK,
386 .ops = &pvblock_blk_ops,
387 .bind = pvblock_blk_bind,
388 .probe = pvblock_blk_probe,
389 .remove = pvblock_blk_remove,
390 .priv_auto_alloc_size = sizeof(struct blkfront_dev),
391 .flags = DM_FLAG_OS_PREPARE,
394 /*******************************************************************************
395 * Para-virtual block device class
396 *******************************************************************************/
398 typedef int (*enum_vbd_callback)(struct udevice *parent, unsigned int devid);
400 static int on_new_vbd(struct udevice *parent, unsigned int devid)
402 struct driver_info info;
403 struct udevice *udev;
404 struct blkfront_platdata *platdata;
407 debug("New " DRV_NAME_BLK ", device ID %d\n", devid);
409 platdata = malloc(sizeof(struct blkfront_platdata));
411 printf("Failed to allocate platform data\n");
415 platdata->devid = devid;
417 info.name = DRV_NAME_BLK;
418 info.platdata = platdata;
420 ret = device_bind_by_name(parent, false, &info, &udev);
422 printf("Failed to bind " DRV_NAME_BLK " to device with ID %d, ret: %d\n",
429 static int xenbus_enumerate_vbd(struct udevice *udev, enum_vbd_callback clb)
434 msg = xenbus_ls(XBT_NIL, "device/vbd", &dirs);
436 printf("Failed to read device/vbd directory: %s\n", msg);
441 for (i = 0; dirs[i]; i++) {
444 sscanf(dirs[i], "%d", &devid);
445 ret = clb(udev, devid);
460 void pvblock_init(void)
462 struct driver_info info;
463 struct udevice *udev;
468 * At this point Xen drivers have already initialized,
469 * so we can instantiate the class driver and enumerate
470 * virtual block devices.
472 info.name = DRV_NAME;
473 ret = device_bind_by_name(gd->dm_root, false, &info, &udev);
475 printf("Failed to bind " DRV_NAME ", ret: %d\n", ret);
477 /* Bootstrap virtual block devices class driver */
478 ret = uclass_get(UCLASS_PVBLOCK, &uc);
481 uclass_foreach_dev_probe(UCLASS_PVBLOCK, udev);
484 static int pvblock_probe(struct udevice *udev)
489 if (xenbus_enumerate_vbd(udev, on_new_vbd) < 0)
492 ret = uclass_get(UCLASS_BLK, &uc);
495 uclass_foreach_dev_probe(UCLASS_BLK, udev) {
502 U_BOOT_DRIVER(pvblock_drv) = {
504 .id = UCLASS_PVBLOCK,
505 .probe = pvblock_probe,
508 UCLASS_DRIVER(pvblock) = {
510 .id = UCLASS_PVBLOCK,