qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

vhost-scsi: create a vhost-scsi-common abstraction

In order to introduce a new vhost-user-scsi host device type, it makes
sense to abstract part of vhost-scsi into a common parent class. This
commit does exactly that.

Signed-off-by: Felipe Franciosi <felipe@nutanix.com>
Message-Id: <1488479153-21203-3-git-send-email-felipe@nutanix.com>

authored by

Felipe Franciosi and committed by
Paolo Bonzini
95615ce5 eae0f543

+252 -148
+1 -1
hw/scsi/Makefile.objs
··· 10 10 11 11 ifeq ($(CONFIG_VIRTIO),y) 12 12 obj-y += virtio-scsi.o virtio-scsi-dataplane.o 13 - obj-$(CONFIG_VHOST_SCSI) += vhost-scsi.o 13 + obj-$(CONFIG_VHOST_SCSI) += vhost-scsi-common.o vhost-scsi.o 14 14 endif
+143
hw/scsi/vhost-scsi-common.c
··· 1 + /* 2 + * vhost-scsi-common 3 + * 4 + * Copyright (c) 2016 Nutanix Inc. All rights reserved. 5 + * 6 + * Author: 7 + * Felipe Franciosi <felipe@nutanix.com> 8 + * 9 + * This work is largely based on the "vhost-scsi" implementation by: 10 + * Stefan Hajnoczi <stefanha@linux.vnet.ibm.com> 11 + * Nicholas Bellinger <nab@risingtidesystems.com> 12 + * 13 + * This work is licensed under the terms of the GNU LGPL, version 2 or later. 14 + * See the COPYING.LIB file in the top-level directory. 15 + * 16 + */ 17 + 18 + #include "qemu/osdep.h" 19 + #include <linux/vhost.h> 20 + #include "qapi/error.h" 21 + #include "qemu/error-report.h" 22 + #include "migration/migration.h" 23 + #include "hw/virtio/vhost.h" 24 + #include "hw/virtio/vhost-scsi-common.h" 25 + #include "hw/virtio/virtio-scsi.h" 26 + #include "hw/virtio/virtio-bus.h" 27 + #include "hw/virtio/virtio-access.h" 28 + #include "hw/fw-path-provider.h" 29 + 30 + int vhost_scsi_common_start(VHostSCSICommon *vsc) 31 + { 32 + int ret, i; 33 + VirtIODevice *vdev = VIRTIO_DEVICE(vsc); 34 + BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); 35 + VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); 36 + 37 + if (!k->set_guest_notifiers) { 38 + error_report("binding does not support guest notifiers"); 39 + return -ENOSYS; 40 + } 41 + 42 + ret = vhost_dev_enable_notifiers(&vsc->dev, vdev); 43 + if (ret < 0) { 44 + return ret; 45 + } 46 + 47 + ret = k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, true); 48 + if (ret < 0) { 49 + error_report("Error binding guest notifier"); 50 + goto err_host_notifiers; 51 + } 52 + 53 + vsc->dev.acked_features = vdev->guest_features; 54 + ret = vhost_dev_start(&vsc->dev, vdev); 55 + if (ret < 0) { 56 + error_report("Error start vhost dev"); 57 + goto err_guest_notifiers; 58 + } 59 + 60 + /* guest_notifier_mask/pending not used yet, so just unmask 61 + * everything here. virtio-pci will do the right thing by 62 + * enabling/disabling irqfd. 63 + */ 64 + for (i = 0; i < vsc->dev.nvqs; i++) { 65 + vhost_virtqueue_mask(&vsc->dev, vdev, vsc->dev.vq_index + i, false); 66 + } 67 + 68 + return ret; 69 + 70 + err_guest_notifiers: 71 + k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false); 72 + err_host_notifiers: 73 + vhost_dev_disable_notifiers(&vsc->dev, vdev); 74 + return ret; 75 + } 76 + 77 + void vhost_scsi_common_stop(VHostSCSICommon *vsc) 78 + { 79 + VirtIODevice *vdev = VIRTIO_DEVICE(vsc); 80 + BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); 81 + VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); 82 + int ret = 0; 83 + 84 + vhost_dev_stop(&vsc->dev, vdev); 85 + 86 + if (k->set_guest_notifiers) { 87 + ret = k->set_guest_notifiers(qbus->parent, vsc->dev.nvqs, false); 88 + if (ret < 0) { 89 + error_report("vhost guest notifier cleanup failed: %d", ret); 90 + } 91 + } 92 + assert(ret >= 0); 93 + 94 + vhost_dev_disable_notifiers(&vsc->dev, vdev); 95 + } 96 + 97 + uint64_t vhost_scsi_common_get_features(VirtIODevice *vdev, uint64_t features, 98 + Error **errp) 99 + { 100 + VHostSCSICommon *vsc = VHOST_SCSI_COMMON(vdev); 101 + 102 + return vhost_get_features(&vsc->dev, vsc->feature_bits, features); 103 + } 104 + 105 + void vhost_scsi_common_set_config(VirtIODevice *vdev, const uint8_t *config) 106 + { 107 + VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config; 108 + VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev); 109 + 110 + if ((uint32_t)virtio_ldl_p(vdev, &scsiconf->sense_size) != vs->sense_size || 111 + (uint32_t)virtio_ldl_p(vdev, &scsiconf->cdb_size) != vs->cdb_size) { 112 + error_report("vhost-scsi does not support changing the sense data and " 113 + "CDB sizes"); 114 + exit(1); 115 + } 116 + } 117 + 118 + /* 119 + * Implementation of an interface to adjust firmware path 120 + * for the bootindex property handling. 121 + */ 122 + char *vhost_scsi_common_get_fw_dev_path(FWPathProvider *p, BusState *bus, 123 + DeviceState *dev) 124 + { 125 + VHostSCSICommon *vsc = VHOST_SCSI_COMMON(dev); 126 + /* format: /channel@channel/vhost-scsi@target,lun */ 127 + return g_strdup_printf("/channel@%x/%s@%x,%x", vsc->channel, 128 + qdev_fw_name(dev), vsc->target, vsc->lun); 129 + } 130 + 131 + static const TypeInfo vhost_scsi_common_info = { 132 + .name = TYPE_VHOST_SCSI_COMMON, 133 + .parent = TYPE_VIRTIO_SCSI_COMMON, 134 + .instance_size = sizeof(VHostSCSICommon), 135 + .abstract = true, 136 + }; 137 + 138 + static void virtio_register_types(void) 139 + { 140 + type_register_static(&vhost_scsi_common_info); 141 + } 142 + 143 + type_init(virtio_register_types)
+56 -138
hw/scsi/vhost-scsi.c
··· 42 42 static int vhost_scsi_set_endpoint(VHostSCSI *s) 43 43 { 44 44 VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s); 45 - const VhostOps *vhost_ops = s->dev.vhost_ops; 45 + VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s); 46 + const VhostOps *vhost_ops = vsc->dev.vhost_ops; 46 47 struct vhost_scsi_target backend; 47 48 int ret; 48 49 49 50 memset(&backend, 0, sizeof(backend)); 50 51 pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn); 51 - ret = vhost_ops->vhost_scsi_set_endpoint(&s->dev, &backend); 52 + ret = vhost_ops->vhost_scsi_set_endpoint(&vsc->dev, &backend); 52 53 if (ret < 0) { 53 54 return -errno; 54 55 } ··· 58 59 static void vhost_scsi_clear_endpoint(VHostSCSI *s) 59 60 { 60 61 VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(s); 62 + VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s); 61 63 struct vhost_scsi_target backend; 62 - const VhostOps *vhost_ops = s->dev.vhost_ops; 64 + const VhostOps *vhost_ops = vsc->dev.vhost_ops; 63 65 64 66 memset(&backend, 0, sizeof(backend)); 65 67 pstrcpy(backend.vhost_wwpn, sizeof(backend.vhost_wwpn), vs->conf.wwpn); 66 - vhost_ops->vhost_scsi_clear_endpoint(&s->dev, &backend); 68 + vhost_ops->vhost_scsi_clear_endpoint(&vsc->dev, &backend); 67 69 } 68 70 69 71 static int vhost_scsi_start(VHostSCSI *s) 70 72 { 71 - int ret, abi_version, i; 72 - VirtIODevice *vdev = VIRTIO_DEVICE(s); 73 - BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); 74 - VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); 75 - const VhostOps *vhost_ops = s->dev.vhost_ops; 73 + int ret, abi_version; 74 + VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s); 75 + const VhostOps *vhost_ops = vsc->dev.vhost_ops; 76 76 77 - if (!k->set_guest_notifiers) { 78 - error_report("binding does not support guest notifiers"); 79 - return -ENOSYS; 80 - } 81 - 82 - ret = vhost_ops->vhost_scsi_get_abi_version(&s->dev, &abi_version); 77 + ret = vhost_ops->vhost_scsi_get_abi_version(&vsc->dev, &abi_version); 83 78 if (ret < 0) { 84 79 return -errno; 85 80 } 86 81 if (abi_version > VHOST_SCSI_ABI_VERSION) { 87 82 error_report("vhost-scsi: The running tcm_vhost kernel abi_version:" 88 - " %d is greater than vhost_scsi userspace supports: %d, please" 89 - " upgrade your version of QEMU", abi_version, 83 + " %d is greater than vhost_scsi userspace supports: %d," 84 + " please upgrade your version of QEMU", abi_version, 90 85 VHOST_SCSI_ABI_VERSION); 91 86 return -ENOSYS; 92 87 } 93 88 94 - ret = vhost_dev_enable_notifiers(&s->dev, vdev); 89 + ret = vhost_scsi_common_start(vsc); 95 90 if (ret < 0) { 96 91 return ret; 97 92 } 98 93 99 - s->dev.acked_features = vdev->guest_features; 100 - ret = vhost_dev_start(&s->dev, vdev); 101 - if (ret < 0) { 102 - error_report("Error start vhost dev"); 103 - goto err_notifiers; 104 - } 105 - 106 94 ret = vhost_scsi_set_endpoint(s); 107 95 if (ret < 0) { 108 - error_report("Error set vhost-scsi endpoint"); 109 - goto err_vhost_stop; 110 - } 111 - 112 - ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, true); 113 - if (ret < 0) { 114 - error_report("Error binding guest notifier"); 115 - goto err_endpoint; 96 + error_report("Error setting vhost-scsi endpoint"); 97 + vhost_scsi_common_stop(vsc); 116 98 } 117 99 118 - /* guest_notifier_mask/pending not used yet, so just unmask 119 - * everything here. virtio-pci will do the right thing by 120 - * enabling/disabling irqfd. 121 - */ 122 - for (i = 0; i < s->dev.nvqs; i++) { 123 - vhost_virtqueue_mask(&s->dev, vdev, s->dev.vq_index + i, false); 124 - } 125 - 126 - return ret; 127 - 128 - err_endpoint: 129 - vhost_scsi_clear_endpoint(s); 130 - err_vhost_stop: 131 - vhost_dev_stop(&s->dev, vdev); 132 - err_notifiers: 133 - vhost_dev_disable_notifiers(&s->dev, vdev); 134 100 return ret; 135 101 } 136 102 137 103 static void vhost_scsi_stop(VHostSCSI *s) 138 104 { 139 - VirtIODevice *vdev = VIRTIO_DEVICE(s); 140 - BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev))); 141 - VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus); 142 - int ret = 0; 143 - 144 - if (k->set_guest_notifiers) { 145 - ret = k->set_guest_notifiers(qbus->parent, s->dev.nvqs, false); 146 - if (ret < 0) { 147 - error_report("vhost guest notifier cleanup failed: %d", ret); 148 - } 149 - } 150 - assert(ret >= 0); 105 + VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s); 151 106 152 107 vhost_scsi_clear_endpoint(s); 153 - vhost_dev_stop(&s->dev, vdev); 154 - vhost_dev_disable_notifiers(&s->dev, vdev); 155 - } 156 - 157 - static uint64_t vhost_scsi_get_features(VirtIODevice *vdev, 158 - uint64_t features, 159 - Error **errp) 160 - { 161 - VHostSCSI *s = VHOST_SCSI(vdev); 162 - 163 - return vhost_get_features(&s->dev, kernel_feature_bits, features); 164 - } 165 - 166 - static void vhost_scsi_set_config(VirtIODevice *vdev, 167 - const uint8_t *config) 168 - { 169 - VirtIOSCSIConfig *scsiconf = (VirtIOSCSIConfig *)config; 170 - VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev); 171 - 172 - if ((uint32_t) virtio_ldl_p(vdev, &scsiconf->sense_size) != vs->sense_size || 173 - (uint32_t) virtio_ldl_p(vdev, &scsiconf->cdb_size) != vs->cdb_size) { 174 - error_report("vhost-scsi does not support changing the sense data and CDB sizes"); 175 - exit(1); 176 - } 108 + vhost_scsi_common_stop(vsc); 177 109 } 178 110 179 111 static void vhost_scsi_set_status(VirtIODevice *vdev, uint8_t val) 180 112 { 181 - VHostSCSI *s = (VHostSCSI *)vdev; 113 + VHostSCSI *s = VHOST_SCSI(vdev); 114 + VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s); 182 115 bool start = (val & VIRTIO_CONFIG_S_DRIVER_OK); 183 116 184 - if (s->dev.started == start) { 117 + if (vsc->dev.started == start) { 185 118 return; 186 119 } 187 120 ··· 190 123 191 124 ret = vhost_scsi_start(s); 192 125 if (ret < 0) { 193 - error_report("virtio-scsi: unable to start vhost: %s", 194 - strerror(-ret)); 195 - 196 - /* There is no userspace virtio-scsi fallback so exit */ 126 + error_report("unable to start vhost-scsi: %s", strerror(-ret)); 197 127 exit(1); 198 128 } 199 129 } else { ··· 208 138 static void vhost_scsi_realize(DeviceState *dev, Error **errp) 209 139 { 210 140 VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev); 211 - VHostSCSI *s = VHOST_SCSI(dev); 141 + VHostSCSICommon *vsc = VHOST_SCSI_COMMON(dev); 212 142 Error *err = NULL; 213 143 int vhostfd = -1; 214 144 int ret; ··· 243 173 goto close_fd; 244 174 } 245 175 246 - error_setg(&s->migration_blocker, 176 + error_setg(&vsc->migration_blocker, 247 177 "vhost-scsi does not support migration"); 248 - migrate_add_blocker(s->migration_blocker, &err); 178 + migrate_add_blocker(vsc->migration_blocker, &err); 249 179 if (err) { 250 180 error_propagate(errp, err); 251 - error_free(s->migration_blocker); 181 + error_free(vsc->migration_blocker); 252 182 goto close_fd; 253 183 } 254 184 255 - s->dev.nvqs = VHOST_SCSI_VQ_NUM_FIXED + vs->conf.num_queues; 256 - s->dev.vqs = g_new(struct vhost_virtqueue, s->dev.nvqs); 257 - s->dev.vq_index = 0; 258 - s->dev.backend_features = 0; 185 + vsc->dev.nvqs = VHOST_SCSI_VQ_NUM_FIXED + vs->conf.num_queues; 186 + vsc->dev.vqs = g_new(struct vhost_virtqueue, vsc->dev.nvqs); 187 + vsc->dev.vq_index = 0; 188 + vsc->dev.backend_features = 0; 259 189 260 - ret = vhost_dev_init(&s->dev, (void *)(uintptr_t)vhostfd, 190 + ret = vhost_dev_init(&vsc->dev, (void *)(uintptr_t)vhostfd, 261 191 VHOST_BACKEND_TYPE_KERNEL, 0); 262 192 if (ret < 0) { 263 193 error_setg(errp, "vhost-scsi: vhost initialization failed: %s", ··· 266 196 } 267 197 268 198 /* At present, channel and lun both are 0 for bootable vhost-scsi disk */ 269 - s->channel = 0; 270 - s->lun = 0; 199 + vsc->channel = 0; 200 + vsc->lun = 0; 271 201 /* Note: we can also get the minimum tpgt from kernel */ 272 - s->target = vs->conf.boot_tpgt; 202 + vsc->target = vs->conf.boot_tpgt; 273 203 274 204 return; 275 205 276 206 free_vqs: 277 - migrate_del_blocker(s->migration_blocker); 278 - g_free(s->dev.vqs); 207 + migrate_del_blocker(vsc->migration_blocker); 208 + g_free(vsc->dev.vqs); 279 209 close_fd: 280 210 close(vhostfd); 281 211 return; ··· 284 214 static void vhost_scsi_unrealize(DeviceState *dev, Error **errp) 285 215 { 286 216 VirtIODevice *vdev = VIRTIO_DEVICE(dev); 287 - VHostSCSI *s = VHOST_SCSI(dev); 217 + VHostSCSICommon *vsc = VHOST_SCSI_COMMON(dev); 288 218 289 - migrate_del_blocker(s->migration_blocker); 290 - error_free(s->migration_blocker); 219 + migrate_del_blocker(vsc->migration_blocker); 220 + error_free(vsc->migration_blocker); 291 221 292 222 /* This will stop vhost backend. */ 293 223 vhost_scsi_set_status(vdev, 0); 294 224 295 - vhost_dev_cleanup(&s->dev); 296 - g_free(s->dev.vqs); 225 + vhost_dev_cleanup(&vsc->dev); 226 + g_free(vsc->dev.vqs); 297 227 298 228 virtio_scsi_common_unrealize(dev, errp); 299 229 } 300 230 301 - /* 302 - * Implementation of an interface to adjust firmware path 303 - * for the bootindex property handling. 304 - */ 305 - static char *vhost_scsi_get_fw_dev_path(FWPathProvider *p, BusState *bus, 306 - DeviceState *dev) 307 - { 308 - VHostSCSI *s = VHOST_SCSI(dev); 309 - /* format: channel@channel/vhost-scsi@target,lun */ 310 - return g_strdup_printf("/channel@%x/%s@%x,%x", s->channel, 311 - qdev_fw_name(dev), s->target, s->lun); 312 - } 313 - 314 231 static Property vhost_scsi_properties[] = { 315 - DEFINE_PROP_STRING("vhostfd", VHostSCSI, parent_obj.conf.vhostfd), 316 - DEFINE_PROP_STRING("wwpn", VHostSCSI, parent_obj.conf.wwpn), 317 - DEFINE_PROP_UINT32("boot_tpgt", VHostSCSI, parent_obj.conf.boot_tpgt, 0), 318 - DEFINE_PROP_UINT32("num_queues", VHostSCSI, parent_obj.conf.num_queues, 1), 319 - DEFINE_PROP_UINT32("max_sectors", VHostSCSI, parent_obj.conf.max_sectors, 320 - 0xFFFF), 321 - DEFINE_PROP_UINT32("cmd_per_lun", VHostSCSI, parent_obj.conf.cmd_per_lun, 322 - 128), 232 + DEFINE_PROP_STRING("vhostfd", VirtIOSCSICommon, conf.vhostfd), 233 + DEFINE_PROP_STRING("wwpn", VirtIOSCSICommon, conf.wwpn), 234 + DEFINE_PROP_UINT32("boot_tpgt", VirtIOSCSICommon, conf.boot_tpgt, 0), 235 + DEFINE_PROP_UINT32("num_queues", VirtIOSCSICommon, conf.num_queues, 1), 236 + DEFINE_PROP_UINT32("max_sectors", VirtIOSCSICommon, conf.max_sectors, 237 + 0xFFFF), 238 + DEFINE_PROP_UINT32("cmd_per_lun", VirtIOSCSICommon, conf.cmd_per_lun, 128), 323 239 DEFINE_PROP_END_OF_LIST(), 324 240 }; 325 241 ··· 333 249 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories); 334 250 vdc->realize = vhost_scsi_realize; 335 251 vdc->unrealize = vhost_scsi_unrealize; 336 - vdc->get_features = vhost_scsi_get_features; 337 - vdc->set_config = vhost_scsi_set_config; 252 + vdc->get_features = vhost_scsi_common_get_features; 253 + vdc->set_config = vhost_scsi_common_set_config; 338 254 vdc->set_status = vhost_scsi_set_status; 339 - fwc->get_dev_path = vhost_scsi_get_fw_dev_path; 255 + fwc->get_dev_path = vhost_scsi_common_get_fw_dev_path; 340 256 } 341 257 342 258 static void vhost_scsi_instance_init(Object *obj) 343 259 { 344 - VHostSCSI *dev = VHOST_SCSI(obj); 260 + VHostSCSICommon *vsc = VHOST_SCSI_COMMON(obj); 345 261 346 - device_add_bootindex_property(obj, &dev->bootindex, "bootindex", NULL, 347 - DEVICE(dev), NULL); 262 + vsc->feature_bits = kernel_feature_bits; 263 + 264 + device_add_bootindex_property(obj, &vsc->bootindex, "bootindex", NULL, 265 + DEVICE(vsc), NULL); 348 266 } 349 267 350 268 static const TypeInfo vhost_scsi_info = { 351 269 .name = TYPE_VHOST_SCSI, 352 - .parent = TYPE_VIRTIO_SCSI_COMMON, 270 + .parent = TYPE_VHOST_SCSI_COMMON, 353 271 .instance_size = sizeof(VHostSCSI), 354 272 .class_init = vhost_scsi_class_init, 355 273 .instance_init = vhost_scsi_instance_init,
+48
include/hw/virtio/vhost-scsi-common.h
··· 1 + /* 2 + * vhost_scsi host device 3 + * 4 + * Copyright (c) 2016 Nutanix Inc. All rights reserved. 5 + * 6 + * Author: 7 + * Felipe Franciosi <felipe@nutanix.com> 8 + * 9 + * This work is licensed under the terms of the GNU LGPL, version 2 or later. 10 + * See the COPYING.LIB file in the top-level directory. 11 + * 12 + */ 13 + 14 + #ifndef VHOST_SCSI_COMMON_H 15 + #define VHOST_SCSI_COMMON_H 16 + 17 + #include "qemu-common.h" 18 + #include "hw/qdev.h" 19 + #include "hw/virtio/virtio-scsi.h" 20 + #include "hw/virtio/vhost.h" 21 + #include "hw/fw-path-provider.h" 22 + 23 + #define TYPE_VHOST_SCSI_COMMON "vhost-scsi-common" 24 + #define VHOST_SCSI_COMMON(obj) \ 25 + OBJECT_CHECK(VHostSCSICommon, (obj), TYPE_VHOST_SCSI_COMMON) 26 + 27 + typedef struct VHostSCSICommon { 28 + VirtIOSCSICommon parent_obj; 29 + 30 + Error *migration_blocker; 31 + 32 + struct vhost_dev dev; 33 + const int *feature_bits; 34 + int32_t bootindex; 35 + int channel; 36 + int target; 37 + int lun; 38 + } VHostSCSICommon; 39 + 40 + int vhost_scsi_common_start(VHostSCSICommon *vsc); 41 + void vhost_scsi_common_stop(VHostSCSICommon *vsc); 42 + char *vhost_scsi_common_get_fw_dev_path(FWPathProvider *p, BusState *bus, 43 + DeviceState *dev); 44 + void vhost_scsi_common_set_config(VirtIODevice *vdev, const uint8_t *config); 45 + uint64_t vhost_scsi_common_get_features(VirtIODevice *vdev, uint64_t features, 46 + Error **errp); 47 + 48 + #endif /* VHOST_SCSI_COMMON_H */
+2 -9
include/hw/virtio/vhost-scsi.h
··· 18 18 #include "hw/qdev.h" 19 19 #include "hw/virtio/virtio-scsi.h" 20 20 #include "hw/virtio/vhost.h" 21 + #include "hw/virtio/vhost-scsi-common.h" 21 22 22 23 enum vhost_scsi_vq_list { 23 24 VHOST_SCSI_VQ_CONTROL = 0, ··· 30 31 OBJECT_CHECK(VHostSCSI, (obj), TYPE_VHOST_SCSI) 31 32 32 33 typedef struct VHostSCSI { 33 - VirtIOSCSICommon parent_obj; 34 - 35 - Error *migration_blocker; 36 - 37 - struct vhost_dev dev; 38 - int32_t bootindex; 39 - int channel; 40 - int target; 41 - int lun; 34 + VHostSCSICommon parent_obj; 42 35 } VHostSCSI; 43 36 44 37 #endif
+2
include/hw/virtio/virtio-scsi.h
··· 49 49 uint32_t num_queues; 50 50 uint32_t max_sectors; 51 51 uint32_t cmd_per_lun; 52 + #ifdef CONFIG_VHOST_SCSI 52 53 char *vhostfd; 53 54 char *wwpn; 55 + #endif 54 56 uint32_t boot_tpgt; 55 57 IOThread *iothread; 56 58 };