Lines Matching +full:num +full:- +full:rings

1 // SPDX-License-Identifier: GPL-2.0-or-later
9 #define pr_fmt(fmt) "xen-blkback: " fmt
18 /* On the XenBus the max length of 'ring-ref%u'. */
40 return be->dev; in xen_blkbk_xenbus()
58 struct xenbus_device *dev = blkif->be->dev; in blkback_name()
60 devpath = xenbus_read(XBT_NIL, dev->nodename, "dev", NULL); in blkback_name()
70 snprintf(buf, TASK_COMM_LEN, "%d.%s", blkif->domid, devname); in blkback_name()
84 if (!blkif->rings || !blkif->rings[0].irq || !blkif->vbd.bdev) in xen_update_blkif_status()
88 if (blkif->be->dev->state == XenbusStateConnected) in xen_update_blkif_status()
92 connect(blkif->be); in xen_update_blkif_status()
93 if (blkif->be->dev->state != XenbusStateConnected) in xen_update_blkif_status()
98 xenbus_dev_error(blkif->be->dev, err, "get blkback dev name"); in xen_update_blkif_status()
102 err = filemap_write_and_wait(blkif->vbd.bdev->bd_inode->i_mapping); in xen_update_blkif_status()
104 xenbus_dev_error(blkif->be->dev, err, "block flush"); in xen_update_blkif_status()
107 invalidate_inode_pages2(blkif->vbd.bdev->bd_inode->i_mapping); in xen_update_blkif_status()
109 for (i = 0; i < blkif->nr_rings; i++) { in xen_update_blkif_status()
110 ring = &blkif->rings[i]; in xen_update_blkif_status()
111 ring->xenblkd = kthread_run(xen_blkif_schedule, ring, "%s-%d", name, i); in xen_update_blkif_status()
112 if (IS_ERR(ring->xenblkd)) { in xen_update_blkif_status()
113 err = PTR_ERR(ring->xenblkd); in xen_update_blkif_status()
114 ring->xenblkd = NULL; in xen_update_blkif_status()
115 xenbus_dev_fatal(blkif->be->dev, err, in xen_update_blkif_status()
116 "start %s-%d xenblkd", name, i); in xen_update_blkif_status()
123 while (--i >= 0) { in xen_update_blkif_status()
124 ring = &blkif->rings[i]; in xen_update_blkif_status()
125 kthread_stop(ring->xenblkd); in xen_update_blkif_status()
134 blkif->rings = kcalloc(blkif->nr_rings, sizeof(struct xen_blkif_ring), in xen_blkif_alloc_rings()
136 if (!blkif->rings) in xen_blkif_alloc_rings()
137 return -ENOMEM; in xen_blkif_alloc_rings()
139 for (r = 0; r < blkif->nr_rings; r++) { in xen_blkif_alloc_rings()
140 struct xen_blkif_ring *ring = &blkif->rings[r]; in xen_blkif_alloc_rings()
142 spin_lock_init(&ring->blk_ring_lock); in xen_blkif_alloc_rings()
143 init_waitqueue_head(&ring->wq); in xen_blkif_alloc_rings()
144 INIT_LIST_HEAD(&ring->pending_free); in xen_blkif_alloc_rings()
145 INIT_LIST_HEAD(&ring->persistent_purge_list); in xen_blkif_alloc_rings()
146 INIT_WORK(&ring->persistent_purge_work, xen_blkbk_unmap_purged_grants); in xen_blkif_alloc_rings()
147 gnttab_page_cache_init(&ring->free_pages); in xen_blkif_alloc_rings()
149 spin_lock_init(&ring->pending_free_lock); in xen_blkif_alloc_rings()
150 init_waitqueue_head(&ring->pending_free_wq); in xen_blkif_alloc_rings()
151 init_waitqueue_head(&ring->shutdown_wq); in xen_blkif_alloc_rings()
152 ring->blkif = blkif; in xen_blkif_alloc_rings()
153 ring->st_print = jiffies; in xen_blkif_alloc_rings()
154 ring->active = true; in xen_blkif_alloc_rings()
173 return ERR_PTR(-ENOMEM); in xen_blkif_alloc()
175 blkif->domid = domid; in xen_blkif_alloc()
176 atomic_set(&blkif->refcnt, 1); in xen_blkif_alloc()
177 init_completion(&blkif->drain_complete); in xen_blkif_alloc()
187 INIT_WORK(&blkif->free_work, xen_blkif_deferred_free); in xen_blkif_alloc()
196 struct xen_blkif *blkif = ring->blkif; in xen_blkif_map()
202 if (ring->irq) in xen_blkif_map()
205 err = xenbus_map_ring_valloc(blkif->be->dev, gref, nr_grefs, in xen_blkif_map()
206 &ring->blk_ring); in xen_blkif_map()
210 sring_common = (struct blkif_common_sring *)ring->blk_ring; in xen_blkif_map()
211 rsp_prod = READ_ONCE(sring_common->rsp_prod); in xen_blkif_map()
212 req_prod = READ_ONCE(sring_common->req_prod); in xen_blkif_map()
214 switch (blkif->blk_protocol) { in xen_blkif_map()
218 (struct blkif_sring *)ring->blk_ring; in xen_blkif_map()
220 BACK_RING_ATTACH(&ring->blk_rings.native, sring_native, in xen_blkif_map()
228 (struct blkif_x86_32_sring *)ring->blk_ring; in xen_blkif_map()
230 BACK_RING_ATTACH(&ring->blk_rings.x86_32, sring_x86_32, in xen_blkif_map()
238 (struct blkif_x86_64_sring *)ring->blk_ring; in xen_blkif_map()
240 BACK_RING_ATTACH(&ring->blk_rings.x86_64, sring_x86_64, in xen_blkif_map()
249 err = -EIO; in xen_blkif_map()
250 if (req_prod - rsp_prod > size) in xen_blkif_map()
253 err = bind_interdomain_evtchn_to_irqhandler_lateeoi(blkif->domid, in xen_blkif_map()
254 evtchn, xen_blkif_be_int, 0, "blkif-backend", ring); in xen_blkif_map()
257 ring->irq = err; in xen_blkif_map()
262 xenbus_unmap_ring_vfree(blkif->be->dev, ring->blk_ring); in xen_blkif_map()
263 ring->blk_rings.common.sring = NULL; in xen_blkif_map()
273 for (r = 0; r < blkif->nr_rings; r++) { in xen_blkif_disconnect()
274 struct xen_blkif_ring *ring = &blkif->rings[r]; in xen_blkif_disconnect()
277 if (!ring->active) in xen_blkif_disconnect()
280 if (ring->xenblkd) { in xen_blkif_disconnect()
281 kthread_stop(ring->xenblkd); in xen_blkif_disconnect()
282 ring->xenblkd = NULL; in xen_blkif_disconnect()
283 wake_up(&ring->shutdown_wq); in xen_blkif_disconnect()
290 if (atomic_read(&ring->inflight) > 0) { in xen_blkif_disconnect()
295 if (ring->irq) { in xen_blkif_disconnect()
296 unbind_from_irqhandler(ring->irq, ring); in xen_blkif_disconnect()
297 ring->irq = 0; in xen_blkif_disconnect()
300 if (ring->blk_rings.common.sring) { in xen_blkif_disconnect()
301 xenbus_unmap_ring_vfree(blkif->be->dev, ring->blk_ring); in xen_blkif_disconnect()
302 ring->blk_rings.common.sring = NULL; in xen_blkif_disconnect()
309 list_for_each_entry_safe(req, n, &ring->pending_free, free_list) { in xen_blkif_disconnect()
310 list_del(&req->free_list); in xen_blkif_disconnect()
313 kfree(req->segments[j]); in xen_blkif_disconnect()
316 kfree(req->indirect_pages[j]); in xen_blkif_disconnect()
322 BUG_ON(atomic_read(&ring->persistent_gnt_in_use) != 0); in xen_blkif_disconnect()
323 BUG_ON(!list_empty(&ring->persistent_purge_list)); in xen_blkif_disconnect()
324 BUG_ON(!RB_EMPTY_ROOT(&ring->persistent_gnts)); in xen_blkif_disconnect()
325 BUG_ON(ring->free_pages.num_pages != 0); in xen_blkif_disconnect()
326 BUG_ON(ring->persistent_gnt_c != 0); in xen_blkif_disconnect()
327 WARN_ON(i != (XEN_BLKIF_REQS_PER_PAGE * blkif->nr_ring_pages)); in xen_blkif_disconnect()
328 ring->active = false; in xen_blkif_disconnect()
331 return -EBUSY; in xen_blkif_disconnect()
333 blkif->nr_ring_pages = 0; in xen_blkif_disconnect()
335 * blkif->rings was allocated in connect_ring, so we should free it in in xen_blkif_disconnect()
338 kfree(blkif->rings); in xen_blkif_disconnect()
339 blkif->rings = NULL; in xen_blkif_disconnect()
340 blkif->nr_rings = 0; in xen_blkif_disconnect()
348 xen_vbd_free(&blkif->vbd); in xen_blkif_free()
349 kfree(blkif->be->mode); in xen_blkif_free()
350 kfree(blkif->be); in xen_blkif_free()
363 return -ENOMEM; in xen_blkif_interface_init()
384 struct backend_info *be = dev_get_drvdata(&dev->dev); \
385 struct xen_blkif *blkif = be->blkif; \
389 if (!blkif->rings) \
392 for (i = 0; i < blkif->nr_rings; i++) { \
393 struct xen_blkif_ring *ring = &blkif->rings[i]; \
395 result += ring->st_##name; \
433 struct backend_info *be = dev_get_drvdata(&dev->dev); \
439 VBD_SHOW(physical_device, "%x:%x\n", be->major, be->minor);
440 VBD_SHOW(mode, "%s\n", be->mode);
446 error = device_create_file(&dev->dev, &dev_attr_physical_device); in xenvbd_sysfs_addif()
450 error = device_create_file(&dev->dev, &dev_attr_mode); in xenvbd_sysfs_addif()
454 error = sysfs_create_group(&dev->dev.kobj, &xen_vbdstat_group); in xenvbd_sysfs_addif()
460 fail3: sysfs_remove_group(&dev->dev.kobj, &xen_vbdstat_group); in xenvbd_sysfs_addif()
461 fail2: device_remove_file(&dev->dev, &dev_attr_mode); in xenvbd_sysfs_addif()
462 fail1: device_remove_file(&dev->dev, &dev_attr_physical_device); in xenvbd_sysfs_addif()
468 sysfs_remove_group(&dev->dev.kobj, &xen_vbdstat_group); in xenvbd_sysfs_delif()
469 device_remove_file(&dev->dev, &dev_attr_mode); in xenvbd_sysfs_delif()
470 device_remove_file(&dev->dev, &dev_attr_physical_device); in xenvbd_sysfs_delif()
475 if (vbd->bdev) in xen_vbd_free()
476 blkdev_put(vbd->bdev, vbd->readonly ? FMODE_READ : FMODE_WRITE); in xen_vbd_free()
477 vbd->bdev = NULL; in xen_vbd_free()
488 vbd = &blkif->vbd; in xen_vbd_create()
489 vbd->handle = handle; in xen_vbd_create()
490 vbd->readonly = readonly; in xen_vbd_create()
491 vbd->type = 0; in xen_vbd_create()
493 vbd->pdevice = MKDEV(major, minor); in xen_vbd_create()
495 bdev = blkdev_get_by_dev(vbd->pdevice, vbd->readonly ? in xen_vbd_create()
500 vbd->pdevice); in xen_vbd_create()
501 return -ENOENT; in xen_vbd_create()
504 vbd->bdev = bdev; in xen_vbd_create()
505 if (vbd->bdev->bd_disk == NULL) { in xen_vbd_create()
507 vbd->pdevice); in xen_vbd_create()
509 return -ENOENT; in xen_vbd_create()
511 vbd->size = vbd_sz(vbd); in xen_vbd_create()
513 if (vbd->bdev->bd_disk->flags & GENHD_FL_CD || cdrom) in xen_vbd_create()
514 vbd->type |= VDISK_CDROM; in xen_vbd_create()
515 if (vbd->bdev->bd_disk->flags & GENHD_FL_REMOVABLE) in xen_vbd_create()
516 vbd->type |= VDISK_REMOVABLE; in xen_vbd_create()
519 if (q && test_bit(QUEUE_FLAG_WC, &q->queue_flags)) in xen_vbd_create()
520 vbd->flush_support = true; in xen_vbd_create()
523 vbd->discard_secure = true; in xen_vbd_create()
526 handle, blkif->domid); in xen_vbd_create()
532 struct backend_info *be = dev_get_drvdata(&dev->dev); in xen_blkbk_remove()
534 pr_debug("%s %p %d\n", __func__, dev, dev->otherend_id); in xen_blkbk_remove()
536 if (be->major || be->minor) in xen_blkbk_remove()
539 if (be->backend_watch.node) { in xen_blkbk_remove()
540 unregister_xenbus_watch(&be->backend_watch); in xen_blkbk_remove()
541 kfree(be->backend_watch.node); in xen_blkbk_remove()
542 be->backend_watch.node = NULL; in xen_blkbk_remove()
545 dev_set_drvdata(&dev->dev, NULL); in xen_blkbk_remove()
547 if (be->blkif) { in xen_blkbk_remove()
548 xen_blkif_disconnect(be->blkif); in xen_blkbk_remove()
551 xen_blkif_put(be->blkif); in xen_blkbk_remove()
560 struct xenbus_device *dev = be->dev; in xen_blkbk_flush_diskcache()
563 err = xenbus_printf(xbt, dev->nodename, "feature-flush-cache", in xen_blkbk_flush_diskcache()
566 dev_warn(&dev->dev, "writing feature-flush-cache (%d)", err); in xen_blkbk_flush_diskcache()
573 struct xenbus_device *dev = be->dev; in xen_blkbk_discard()
574 struct xen_blkif *blkif = be->blkif; in xen_blkbk_discard()
577 struct block_device *bdev = be->blkif->vbd.bdev; in xen_blkbk_discard()
580 if (!xenbus_read_unsigned(dev->nodename, "discard-enable", 1)) in xen_blkbk_discard()
584 err = xenbus_printf(xbt, dev->nodename, in xen_blkbk_discard()
585 "discard-granularity", "%u", in xen_blkbk_discard()
586 q->limits.discard_granularity); in xen_blkbk_discard()
588 dev_warn(&dev->dev, "writing discard-granularity (%d)", err); in xen_blkbk_discard()
591 err = xenbus_printf(xbt, dev->nodename, in xen_blkbk_discard()
592 "discard-alignment", "%u", in xen_blkbk_discard()
593 q->limits.discard_alignment); in xen_blkbk_discard()
595 dev_warn(&dev->dev, "writing discard-alignment (%d)", err); in xen_blkbk_discard()
600 err = xenbus_printf(xbt, dev->nodename, in xen_blkbk_discard()
601 "discard-secure", "%d", in xen_blkbk_discard()
602 blkif->vbd.discard_secure); in xen_blkbk_discard()
604 dev_warn(&dev->dev, "writing discard-secure (%d)", err); in xen_blkbk_discard()
608 err = xenbus_printf(xbt, dev->nodename, "feature-discard", in xen_blkbk_discard()
611 dev_warn(&dev->dev, "writing feature-discard (%d)", err); in xen_blkbk_discard()
617 struct xenbus_device *dev = be->dev; in xen_blkbk_barrier()
620 err = xenbus_printf(xbt, dev->nodename, "feature-barrier", in xen_blkbk_barrier()
623 dev_warn(&dev->dev, "writing feature-barrier (%d)", err); in xen_blkbk_barrier()
641 pr_debug("%s %p %d\n", __func__, dev, dev->otherend_id); in xen_blkbk_probe()
644 xenbus_dev_fatal(dev, -ENOMEM, in xen_blkbk_probe()
646 return -ENOMEM; in xen_blkbk_probe()
648 be->dev = dev; in xen_blkbk_probe()
649 dev_set_drvdata(&dev->dev, be); in xen_blkbk_probe()
651 be->blkif = xen_blkif_alloc(dev->otherend_id); in xen_blkbk_probe()
652 if (IS_ERR(be->blkif)) { in xen_blkbk_probe()
653 err = PTR_ERR(be->blkif); in xen_blkbk_probe()
654 be->blkif = NULL; in xen_blkbk_probe()
659 err = xenbus_printf(XBT_NIL, dev->nodename, in xen_blkbk_probe()
660 "feature-max-indirect-segments", "%u", in xen_blkbk_probe()
663 dev_warn(&dev->dev, in xen_blkbk_probe()
664 "writing %s/feature-max-indirect-segments (%d)", in xen_blkbk_probe()
665 dev->nodename, err); in xen_blkbk_probe()
667 /* Multi-queue: advertise how many queues are supported by us.*/ in xen_blkbk_probe()
668 err = xenbus_printf(XBT_NIL, dev->nodename, in xen_blkbk_probe()
669 "multi-queue-max-queues", "%u", xenblk_max_queues); in xen_blkbk_probe()
671 pr_warn("Error writing multi-queue-max-queues\n"); in xen_blkbk_probe()
674 be->blkif->be = be; in xen_blkbk_probe()
676 err = xenbus_watch_pathfmt(dev, &be->backend_watch, NULL, in xen_blkbk_probe()
678 "%s/%s", dev->nodename, "physical-device"); in xen_blkbk_probe()
682 err = xenbus_printf(XBT_NIL, dev->nodename, "max-ring-page-order", "%u", in xen_blkbk_probe()
685 pr_warn("%s write out 'max-ring-page-order' failed\n", __func__); in xen_blkbk_probe()
700 * Callback received when the hotplug scripts have placed the physical-device
712 struct xenbus_device *dev = be->dev; in backend_changed()
717 pr_debug("%s %p %d\n", __func__, dev, dev->otherend_id); in backend_changed()
719 err = xenbus_scanf(XBT_NIL, dev->nodename, "physical-device", "%x:%x", in backend_changed()
730 xenbus_dev_fatal(dev, err, "reading physical-device"); in backend_changed()
734 if (be->major | be->minor) { in backend_changed()
735 if (be->major != major || be->minor != minor) in backend_changed()
737 be->major, be->minor, major, minor); in backend_changed()
741 be->mode = xenbus_read(XBT_NIL, dev->nodename, "mode", NULL); in backend_changed()
742 if (IS_ERR(be->mode)) { in backend_changed()
743 err = PTR_ERR(be->mode); in backend_changed()
744 be->mode = NULL; in backend_changed()
749 device_type = xenbus_read(XBT_NIL, dev->otherend, "device-type", NULL); in backend_changed()
756 err = kstrtoul(strrchr(dev->otherend, '/') + 1, 0, &handle); in backend_changed()
758 kfree(be->mode); in backend_changed()
759 be->mode = NULL; in backend_changed()
763 be->major = major; in backend_changed()
764 be->minor = minor; in backend_changed()
766 err = xen_vbd_create(be->blkif, handle, major, minor, in backend_changed()
767 !strchr(be->mode, 'w'), cdrom); in backend_changed()
774 xen_vbd_free(&be->blkif->vbd); in backend_changed()
780 kfree(be->mode); in backend_changed()
781 be->mode = NULL; in backend_changed()
782 be->major = 0; in backend_changed()
783 be->minor = 0; in backend_changed()
786 xen_update_blkif_status(be->blkif); in backend_changed()
796 struct backend_info *be = dev_get_drvdata(&dev->dev); in frontend_changed()
803 if (dev->state == XenbusStateClosed) { in frontend_changed()
804 pr_info("%s: prepare for reconnect\n", dev->nodename); in frontend_changed()
816 if (dev->state == XenbusStateConnected) in frontend_changed()
823 err = xen_blkif_disconnect(be->blkif); in frontend_changed()
835 xen_blkif_disconnect(be->blkif); in frontend_changed()
838 xen_update_blkif_status(be->blkif); in frontend_changed()
846 xen_blkif_disconnect(be->blkif); in frontend_changed()
854 device_unregister(&dev->dev); in frontend_changed()
858 xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend", in frontend_changed()
876 struct backend_info *be = dev_get_drvdata(&dev->dev); in reclaim_memory()
880 be->blkif->buffer_squeeze_end = jiffies + in reclaim_memory()
894 struct xenbus_device *dev = be->dev; in connect()
896 pr_debug("%s %s\n", __func__, dev->otherend); in connect()
907 xen_blkbk_flush_diskcache(xbt, be, be->blkif->vbd.flush_support); in connect()
911 xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support); in connect()
913 err = xenbus_printf(xbt, dev->nodename, "feature-persistent", "%u", in connect()
914 be->blkif->vbd.feature_gnt_persistent_parm); in connect()
916 xenbus_dev_fatal(dev, err, "writing %s/feature-persistent", in connect()
917 dev->nodename); in connect()
921 err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu", in connect()
922 (unsigned long long)vbd_sz(&be->blkif->vbd)); in connect()
925 dev->nodename); in connect()
930 err = xenbus_printf(xbt, dev->nodename, "info", "%u", in connect()
931 be->blkif->vbd.type | in connect()
932 (be->blkif->vbd.readonly ? VDISK_READONLY : 0)); in connect()
935 dev->nodename); in connect()
938 err = xenbus_printf(xbt, dev->nodename, "sector-size", "%lu", in connect()
940 bdev_logical_block_size(be->blkif->vbd.bdev)); in connect()
942 xenbus_dev_fatal(dev, err, "writing %s/sector-size", in connect()
943 dev->nodename); in connect()
946 err = xenbus_printf(xbt, dev->nodename, "physical-sector-size", "%u", in connect()
947 bdev_physical_block_size(be->blkif->vbd.bdev)); in connect()
949 xenbus_dev_error(dev, err, "writing %s/physical-sector-size", in connect()
950 dev->nodename); in connect()
953 if (err == -EAGAIN) in connect()
961 dev->nodename); in connect()
969 * Each ring may have multi pages, depends on "ring-page-order".
976 struct xen_blkif *blkif = ring->blkif; in read_per_ring_refs()
977 struct xenbus_device *dev = blkif->be->dev; in read_per_ring_refs()
980 err = xenbus_scanf(XBT_NIL, dir, "event-channel", "%u", in read_per_ring_refs()
983 err = -EINVAL; in read_per_ring_refs()
984 xenbus_dev_fatal(dev, err, "reading %s/event-channel", dir); in read_per_ring_refs()
988 nr_grefs = blkif->nr_ring_pages; in read_per_ring_refs()
992 return -EINVAL; in read_per_ring_refs()
998 if (blkif->multi_ref) in read_per_ring_refs()
999 snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref%u", i); in read_per_ring_refs()
1002 snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref"); in read_per_ring_refs()
1009 err = -EINVAL; in read_per_ring_refs()
1016 err = -ENOMEM; in read_per_ring_refs()
1021 list_add_tail(&req->free_list, &ring->pending_free); in read_per_ring_refs()
1023 req->segments[j] = kzalloc(sizeof(*req->segments[0]), GFP_KERNEL); in read_per_ring_refs()
1024 if (!req->segments[j]) in read_per_ring_refs()
1028 req->indirect_pages[j] = kzalloc(sizeof(*req->indirect_pages[0]), in read_per_ring_refs()
1030 if (!req->indirect_pages[j]) in read_per_ring_refs()
1038 xenbus_dev_fatal(dev, err, "mapping ring-ref port %u", evtchn); in read_per_ring_refs()
1045 list_for_each_entry_safe(req, n, &ring->pending_free, free_list) { in read_per_ring_refs()
1046 list_del(&req->free_list); in read_per_ring_refs()
1048 if (!req->segments[j]) in read_per_ring_refs()
1050 kfree(req->segments[j]); in read_per_ring_refs()
1053 if (!req->indirect_pages[j]) in read_per_ring_refs()
1055 kfree(req->indirect_pages[j]); in read_per_ring_refs()
1064 struct xenbus_device *dev = be->dev; in connect_ring()
1065 struct xen_blkif *blkif = be->blkif; in connect_ring()
1070 const size_t xenstore_path_ext_size = 11; /* sufficient for "/queue-NNN" */ in connect_ring()
1074 pr_debug("%s %s\n", __func__, dev->otherend); in connect_ring()
1076 blkif->blk_protocol = BLKIF_PROTOCOL_DEFAULT; in connect_ring()
1077 err = xenbus_scanf(XBT_NIL, dev->otherend, "protocol", in connect_ring()
1082 blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE; in connect_ring()
1084 blkif->blk_protocol = BLKIF_PROTOCOL_X86_32; in connect_ring()
1086 blkif->blk_protocol = BLKIF_PROTOCOL_X86_64; in connect_ring()
1089 return -ENOSYS; in connect_ring()
1092 blkif->vbd.feature_gnt_persistent_parm = feature_persistent; in connect_ring()
1093 blkif->vbd.feature_gnt_persistent = in connect_ring()
1094 blkif->vbd.feature_gnt_persistent_parm && in connect_ring()
1095 xenbus_read_unsigned(dev->otherend, "feature-persistent", 0); in connect_ring()
1097 blkif->vbd.overflow_max_grants = 0; in connect_ring()
1102 requested_num_queues = xenbus_read_unsigned(dev->otherend, in connect_ring()
1103 "multi-queue-num-queues", in connect_ring()
1111 return -ENOSYS; in connect_ring()
1113 blkif->nr_rings = requested_num_queues; in connect_ring()
1115 return -ENOMEM; in connect_ring()
1117 pr_info("%s: using %d queues, protocol %d (%s) %s\n", dev->nodename, in connect_ring()
1118 blkif->nr_rings, blkif->blk_protocol, protocol, in connect_ring()
1119 blkif->vbd.feature_gnt_persistent ? "persistent grants" : ""); in connect_ring()
1121 err = xenbus_scanf(XBT_NIL, dev->otherend, "ring-page-order", "%u", in connect_ring()
1124 blkif->nr_ring_pages = 1; in connect_ring()
1125 blkif->multi_ref = false; in connect_ring()
1127 blkif->nr_ring_pages = 1 << ring_page_order; in connect_ring()
1128 blkif->multi_ref = true; in connect_ring()
1130 err = -EINVAL; in connect_ring()
1138 if (blkif->nr_rings == 1) in connect_ring()
1139 return read_per_ring_refs(&blkif->rings[0], dev->otherend); in connect_ring()
1141 xspathsize = strlen(dev->otherend) + xenstore_path_ext_size; in connect_ring()
1144 xenbus_dev_fatal(dev, -ENOMEM, "reading ring references"); in connect_ring()
1145 return -ENOMEM; in connect_ring()
1148 for (i = 0; i < blkif->nr_rings; i++) { in connect_ring()
1150 snprintf(xspath, xspathsize, "%s/queue-%u", dev->otherend, i); in connect_ring()
1151 err = read_per_ring_refs(&blkif->rings[i], xspath); in connect_ring()