Lines Matching +full:multi +full:- +full:attr

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 = sync_blockdev(blkif->vbd.bdev); 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->be->dev, 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()
380 struct device_attribute *attr, \
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; \
412 &dev_attr_oo_req.attr,
413 &dev_attr_rd_req.attr,
414 &dev_attr_wr_req.attr,
415 &dev_attr_f_req.attr,
416 &dev_attr_ds_req.attr,
417 &dev_attr_rd_sect.attr,
418 &dev_attr_wr_sect.attr,
429 struct device_attribute *attr, \
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, NULL); in xen_vbd_free()
477 vbd->bdev = NULL; in xen_vbd_free()
487 vbd = &blkif->vbd; in xen_vbd_create()
488 vbd->handle = handle; in xen_vbd_create()
489 vbd->readonly = readonly; in xen_vbd_create()
490 vbd->type = 0; in xen_vbd_create()
492 vbd->pdevice = MKDEV(major, minor); in xen_vbd_create()
494 bdev = blkdev_get_by_dev(vbd->pdevice, vbd->readonly ? in xen_vbd_create()
499 vbd->pdevice); in xen_vbd_create()
500 return -ENOENT; in xen_vbd_create()
503 vbd->bdev = bdev; in xen_vbd_create()
504 if (vbd->bdev->bd_disk == NULL) { in xen_vbd_create()
506 vbd->pdevice); in xen_vbd_create()
508 return -ENOENT; in xen_vbd_create()
510 vbd->size = vbd_sz(vbd); in xen_vbd_create()
512 if (cdrom || disk_to_cdi(vbd->bdev->bd_disk)) in xen_vbd_create()
513 vbd->type |= VDISK_CDROM; in xen_vbd_create()
514 if (vbd->bdev->bd_disk->flags & GENHD_FL_REMOVABLE) in xen_vbd_create()
515 vbd->type |= VDISK_REMOVABLE; in xen_vbd_create()
518 vbd->flush_support = true; in xen_vbd_create()
520 vbd->discard_secure = true; in xen_vbd_create()
523 handle, blkif->domid); in xen_vbd_create()
529 struct backend_info *be = dev_get_drvdata(&dev->dev); in xen_blkbk_remove()
531 pr_debug("%s %p %d\n", __func__, dev, dev->otherend_id); in xen_blkbk_remove()
533 if (be->major || be->minor) in xen_blkbk_remove()
536 if (be->backend_watch.node) { in xen_blkbk_remove()
537 unregister_xenbus_watch(&be->backend_watch); in xen_blkbk_remove()
538 kfree(be->backend_watch.node); in xen_blkbk_remove()
539 be->backend_watch.node = NULL; in xen_blkbk_remove()
542 dev_set_drvdata(&dev->dev, NULL); in xen_blkbk_remove()
544 if (be->blkif) { in xen_blkbk_remove()
545 xen_blkif_disconnect(be->blkif); in xen_blkbk_remove()
548 xen_blkif_put(be->blkif); in xen_blkbk_remove()
555 struct xenbus_device *dev = be->dev; in xen_blkbk_flush_diskcache()
558 err = xenbus_printf(xbt, dev->nodename, "feature-flush-cache", in xen_blkbk_flush_diskcache()
561 dev_warn(&dev->dev, "writing feature-flush-cache (%d)", err); in xen_blkbk_flush_diskcache()
568 struct xenbus_device *dev = be->dev; in xen_blkbk_discard()
569 struct xen_blkif *blkif = be->blkif; in xen_blkbk_discard()
572 struct block_device *bdev = be->blkif->vbd.bdev; in xen_blkbk_discard()
574 if (!xenbus_read_unsigned(dev->nodename, "discard-enable", 1)) in xen_blkbk_discard()
578 err = xenbus_printf(xbt, dev->nodename, in xen_blkbk_discard()
579 "discard-granularity", "%u", in xen_blkbk_discard()
582 dev_warn(&dev->dev, "writing discard-granularity (%d)", err); in xen_blkbk_discard()
585 err = xenbus_printf(xbt, dev->nodename, in xen_blkbk_discard()
586 "discard-alignment", "%u", in xen_blkbk_discard()
589 dev_warn(&dev->dev, "writing discard-alignment (%d)", err); in xen_blkbk_discard()
594 err = xenbus_printf(xbt, dev->nodename, in xen_blkbk_discard()
595 "discard-secure", "%d", in xen_blkbk_discard()
596 blkif->vbd.discard_secure); in xen_blkbk_discard()
598 dev_warn(&dev->dev, "writing discard-secure (%d)", err); in xen_blkbk_discard()
602 err = xenbus_printf(xbt, dev->nodename, "feature-discard", in xen_blkbk_discard()
605 dev_warn(&dev->dev, "writing feature-discard (%d)", err); in xen_blkbk_discard()
611 struct xenbus_device *dev = be->dev; in xen_blkbk_barrier()
614 err = xenbus_printf(xbt, dev->nodename, "feature-barrier", in xen_blkbk_barrier()
617 dev_warn(&dev->dev, "writing feature-barrier (%d)", err); in xen_blkbk_barrier()
635 pr_debug("%s %p %d\n", __func__, dev, dev->otherend_id); in xen_blkbk_probe()
638 xenbus_dev_fatal(dev, -ENOMEM, in xen_blkbk_probe()
640 return -ENOMEM; in xen_blkbk_probe()
642 be->dev = dev; in xen_blkbk_probe()
643 dev_set_drvdata(&dev->dev, be); in xen_blkbk_probe()
645 be->blkif = xen_blkif_alloc(dev->otherend_id); in xen_blkbk_probe()
646 if (IS_ERR(be->blkif)) { in xen_blkbk_probe()
647 err = PTR_ERR(be->blkif); in xen_blkbk_probe()
648 be->blkif = NULL; in xen_blkbk_probe()
653 err = xenbus_printf(XBT_NIL, dev->nodename, in xen_blkbk_probe()
654 "feature-max-indirect-segments", "%u", in xen_blkbk_probe()
657 dev_warn(&dev->dev, in xen_blkbk_probe()
658 "writing %s/feature-max-indirect-segments (%d)", in xen_blkbk_probe()
659 dev->nodename, err); in xen_blkbk_probe()
661 /* Multi-queue: advertise how many queues are supported by us.*/ in xen_blkbk_probe()
662 err = xenbus_printf(XBT_NIL, dev->nodename, in xen_blkbk_probe()
663 "multi-queue-max-queues", "%u", xenblk_max_queues); in xen_blkbk_probe()
665 pr_warn("Error writing multi-queue-max-queues\n"); in xen_blkbk_probe()
668 be->blkif->be = be; in xen_blkbk_probe()
670 err = xenbus_watch_pathfmt(dev, &be->backend_watch, NULL, in xen_blkbk_probe()
672 "%s/%s", dev->nodename, "physical-device"); in xen_blkbk_probe()
676 err = xenbus_printf(XBT_NIL, dev->nodename, "max-ring-page-order", "%u", in xen_blkbk_probe()
679 pr_warn("%s write out 'max-ring-page-order' failed\n", __func__); in xen_blkbk_probe()
694 * Callback received when the hotplug scripts have placed the physical-device
706 struct xenbus_device *dev = be->dev; in backend_changed()
711 pr_debug("%s %p %d\n", __func__, dev, dev->otherend_id); in backend_changed()
713 err = xenbus_scanf(XBT_NIL, dev->nodename, "physical-device", "%x:%x", in backend_changed()
724 xenbus_dev_fatal(dev, err, "reading physical-device"); in backend_changed()
728 if (be->major | be->minor) { in backend_changed()
729 if (be->major != major || be->minor != minor) in backend_changed()
731 be->major, be->minor, major, minor); in backend_changed()
735 be->mode = xenbus_read(XBT_NIL, dev->nodename, "mode", NULL); in backend_changed()
736 if (IS_ERR(be->mode)) { in backend_changed()
737 err = PTR_ERR(be->mode); in backend_changed()
738 be->mode = NULL; in backend_changed()
743 device_type = xenbus_read(XBT_NIL, dev->otherend, "device-type", NULL); in backend_changed()
750 err = kstrtoul(strrchr(dev->otherend, '/') + 1, 0, &handle); in backend_changed()
752 kfree(be->mode); in backend_changed()
753 be->mode = NULL; in backend_changed()
757 be->major = major; in backend_changed()
758 be->minor = minor; in backend_changed()
760 err = xen_vbd_create(be->blkif, handle, major, minor, in backend_changed()
761 !strchr(be->mode, 'w'), cdrom); in backend_changed()
768 xen_vbd_free(&be->blkif->vbd); in backend_changed()
774 kfree(be->mode); in backend_changed()
775 be->mode = NULL; in backend_changed()
776 be->major = 0; in backend_changed()
777 be->minor = 0; in backend_changed()
780 xen_update_blkif_status(be->blkif); in backend_changed()
790 struct backend_info *be = dev_get_drvdata(&dev->dev); in frontend_changed()
797 if (dev->state == XenbusStateClosed) { in frontend_changed()
798 pr_info("%s: prepare for reconnect\n", dev->nodename); in frontend_changed()
810 if (dev->state == XenbusStateConnected) in frontend_changed()
817 err = xen_blkif_disconnect(be->blkif); in frontend_changed()
829 xen_blkif_disconnect(be->blkif); in frontend_changed()
832 xen_update_blkif_status(be->blkif); in frontend_changed()
840 xen_blkif_disconnect(be->blkif); in frontend_changed()
848 device_unregister(&dev->dev); in frontend_changed()
852 xenbus_dev_fatal(dev, -EINVAL, "saw state %d at frontend", in frontend_changed()
870 struct backend_info *be = dev_get_drvdata(&dev->dev); in reclaim_memory()
874 be->blkif->buffer_squeeze_end = jiffies + in reclaim_memory()
888 struct xenbus_device *dev = be->dev; in connect()
890 pr_debug("%s %s\n", __func__, dev->otherend); in connect()
901 xen_blkbk_flush_diskcache(xbt, be, be->blkif->vbd.flush_support); in connect()
905 xen_blkbk_barrier(xbt, be, be->blkif->vbd.flush_support); in connect()
907 err = xenbus_printf(xbt, dev->nodename, "feature-persistent", "%u", in connect()
908 be->blkif->vbd.feature_gnt_persistent_parm); in connect()
910 xenbus_dev_fatal(dev, err, "writing %s/feature-persistent", in connect()
911 dev->nodename); in connect()
915 err = xenbus_printf(xbt, dev->nodename, "sectors", "%llu", in connect()
916 (unsigned long long)vbd_sz(&be->blkif->vbd)); in connect()
919 dev->nodename); in connect()
924 err = xenbus_printf(xbt, dev->nodename, "info", "%u", in connect()
925 be->blkif->vbd.type | in connect()
926 (be->blkif->vbd.readonly ? VDISK_READONLY : 0)); in connect()
929 dev->nodename); in connect()
932 err = xenbus_printf(xbt, dev->nodename, "sector-size", "%lu", in connect()
934 bdev_logical_block_size(be->blkif->vbd.bdev)); in connect()
936 xenbus_dev_fatal(dev, err, "writing %s/sector-size", in connect()
937 dev->nodename); in connect()
940 err = xenbus_printf(xbt, dev->nodename, "physical-sector-size", "%u", in connect()
941 bdev_physical_block_size(be->blkif->vbd.bdev)); in connect()
943 xenbus_dev_error(dev, err, "writing %s/physical-sector-size", in connect()
944 dev->nodename); in connect()
947 if (err == -EAGAIN) in connect()
955 dev->nodename); in connect()
963 * Each ring may have multi pages, depends on "ring-page-order".
970 struct xen_blkif *blkif = ring->blkif; in read_per_ring_refs()
971 struct xenbus_device *dev = blkif->be->dev; in read_per_ring_refs()
974 err = xenbus_scanf(XBT_NIL, dir, "event-channel", "%u", in read_per_ring_refs()
977 err = -EINVAL; in read_per_ring_refs()
978 xenbus_dev_fatal(dev, err, "reading %s/event-channel", dir); in read_per_ring_refs()
982 nr_grefs = blkif->nr_ring_pages; in read_per_ring_refs()
986 return -EINVAL; in read_per_ring_refs()
992 if (blkif->multi_ref) in read_per_ring_refs()
993 snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref%u", i); in read_per_ring_refs()
996 snprintf(ring_ref_name, RINGREF_NAME_LEN, "ring-ref"); in read_per_ring_refs()
1003 err = -EINVAL; in read_per_ring_refs()
1010 err = -ENOMEM; in read_per_ring_refs()
1015 list_add_tail(&req->free_list, &ring->pending_free); in read_per_ring_refs()
1017 req->segments[j] = kzalloc(sizeof(*req->segments[0]), GFP_KERNEL); in read_per_ring_refs()
1018 if (!req->segments[j]) in read_per_ring_refs()
1022 req->indirect_pages[j] = kzalloc(sizeof(*req->indirect_pages[0]), in read_per_ring_refs()
1024 if (!req->indirect_pages[j]) in read_per_ring_refs()
1032 xenbus_dev_fatal(dev, err, "mapping ring-ref port %u", evtchn); in read_per_ring_refs()
1039 list_for_each_entry_safe(req, n, &ring->pending_free, free_list) { in read_per_ring_refs()
1040 list_del(&req->free_list); in read_per_ring_refs()
1042 if (!req->segments[j]) in read_per_ring_refs()
1044 kfree(req->segments[j]); in read_per_ring_refs()
1047 if (!req->indirect_pages[j]) in read_per_ring_refs()
1049 kfree(req->indirect_pages[j]); in read_per_ring_refs()
1058 struct xenbus_device *dev = be->dev; in connect_ring()
1059 struct xen_blkif *blkif = be->blkif; in connect_ring()
1064 const size_t xenstore_path_ext_size = 11; /* sufficient for "/queue-NNN" */ in connect_ring()
1068 pr_debug("%s %s\n", __func__, dev->otherend); in connect_ring()
1070 blkif->blk_protocol = BLKIF_PROTOCOL_DEFAULT; in connect_ring()
1071 err = xenbus_scanf(XBT_NIL, dev->otherend, "protocol", in connect_ring()
1076 blkif->blk_protocol = BLKIF_PROTOCOL_NATIVE; in connect_ring()
1078 blkif->blk_protocol = BLKIF_PROTOCOL_X86_32; in connect_ring()
1080 blkif->blk_protocol = BLKIF_PROTOCOL_X86_64; in connect_ring()
1083 return -ENOSYS; in connect_ring()
1086 blkif->vbd.feature_gnt_persistent_parm = feature_persistent; in connect_ring()
1087 blkif->vbd.feature_gnt_persistent = in connect_ring()
1088 blkif->vbd.feature_gnt_persistent_parm && in connect_ring()
1089 xenbus_read_unsigned(dev->otherend, "feature-persistent", 0); in connect_ring()
1091 blkif->vbd.overflow_max_grants = 0; in connect_ring()
1096 requested_num_queues = xenbus_read_unsigned(dev->otherend, in connect_ring()
1097 "multi-queue-num-queues", in connect_ring()
1105 return -ENOSYS; in connect_ring()
1107 blkif->nr_rings = requested_num_queues; in connect_ring()
1109 return -ENOMEM; in connect_ring()
1111 pr_info("%s: using %d queues, protocol %d (%s) %s\n", dev->nodename, in connect_ring()
1112 blkif->nr_rings, blkif->blk_protocol, protocol, in connect_ring()
1113 blkif->vbd.feature_gnt_persistent ? "persistent grants" : ""); in connect_ring()
1115 err = xenbus_scanf(XBT_NIL, dev->otherend, "ring-page-order", "%u", in connect_ring()
1118 blkif->nr_ring_pages = 1; in connect_ring()
1119 blkif->multi_ref = false; in connect_ring()
1121 blkif->nr_ring_pages = 1 << ring_page_order; in connect_ring()
1122 blkif->multi_ref = true; in connect_ring()
1124 err = -EINVAL; in connect_ring()
1132 if (blkif->nr_rings == 1) in connect_ring()
1133 return read_per_ring_refs(&blkif->rings[0], dev->otherend); in connect_ring()
1135 xspathsize = strlen(dev->otherend) + xenstore_path_ext_size; in connect_ring()
1138 xenbus_dev_fatal(dev, -ENOMEM, "reading ring references"); in connect_ring()
1139 return -ENOMEM; in connect_ring()
1142 for (i = 0; i < blkif->nr_rings; i++) { in connect_ring()
1144 snprintf(xspath, xspathsize, "%s/queue-%u", dev->otherend, i); in connect_ring()
1145 err = read_per_ring_refs(&blkif->rings[i], xspath); in connect_ring()