uint64_t vhost_scsi_common_get_features(VirtIODevice *vdev, uint64_t features, Error **errp) { VHostSCSICommon *vsc = VHOST_SCSI_COMMON(vdev); return vhost_get_features(&vsc->dev, vsc->feature_bits, features); }
/* * Implementation of an interface to adjust firmware path * for the bootindex property handling. */ char *vhost_scsi_common_get_fw_dev_path(FWPathProvider *p, BusState *bus, DeviceState *dev) { VHostSCSICommon *vsc = VHOST_SCSI_COMMON(dev); /* format: /channel@channel/vhost-scsi@target,lun */ return g_strdup_printf("/channel@%x/%s@%x,%x", vsc->channel, qdev_fw_name(dev), vsc->target, vsc->lun); }
static void vhost_user_scsi_instance_init(Object *obj) { VHostSCSICommon *vsc = VHOST_SCSI_COMMON(obj); vsc->feature_bits = user_feature_bits; /* Add the bootindex property for this object */ device_add_bootindex_property(obj, &vsc->bootindex, "bootindex", NULL, DEVICE(vsc), NULL); }
static void vhost_user_scsi_unrealize(DeviceState *dev, Error **errp) { VirtIODevice *vdev = VIRTIO_DEVICE(dev); VHostUserSCSI *s = VHOST_USER_SCSI(dev); VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s); struct vhost_virtqueue *vqs = vsc->dev.vqs; /* This will stop the vhost backend. */ vhost_user_scsi_set_status(vdev, 0); vhost_dev_cleanup(&vsc->dev); g_free(vqs); virtio_scsi_common_unrealize(dev, errp); vhost_user_cleanup(&s->vhost_user); }
static void vhost_user_scsi_realize(DeviceState *dev, Error **errp) { VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev); VHostUserSCSI *s = VHOST_USER_SCSI(dev); VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s); Error *err = NULL; int ret; if (!vs->conf.chardev.chr) { error_setg(errp, "vhost-user-scsi: missing chardev"); return; } virtio_scsi_common_realize(dev, vhost_dummy_handle_output, vhost_dummy_handle_output, vhost_dummy_handle_output, &err); if (err != NULL) { error_propagate(errp, err); return; } if (!vhost_user_init(&s->vhost_user, &vs->conf.chardev, errp)) { return; } vsc->dev.nvqs = 2 + vs->conf.num_queues; vsc->dev.vqs = g_new(struct vhost_virtqueue, vsc->dev.nvqs); vsc->dev.vq_index = 0; vsc->dev.backend_features = 0; ret = vhost_dev_init(&vsc->dev, &s->vhost_user, VHOST_BACKEND_TYPE_USER, 0); if (ret < 0) { error_setg(errp, "vhost-user-scsi: vhost initialization failed: %s", strerror(-ret)); vhost_user_cleanup(&s->vhost_user); return; } /* Channel and lun both are 0 for bootable vhost-user-scsi disk */ vsc->channel = 0; vsc->lun = 0; vsc->target = vs->conf.boot_tpgt; }
static void vhost_user_scsi_set_status(VirtIODevice *vdev, uint8_t status) { VHostUserSCSI *s = (VHostUserSCSI *)vdev; VHostSCSICommon *vsc = VHOST_SCSI_COMMON(s); bool start = (status & VIRTIO_CONFIG_S_DRIVER_OK) && vdev->vm_running; if (vsc->dev.started == start) { return; } if (start) { int ret; ret = vhost_scsi_common_start(vsc); if (ret < 0) { error_report("unable to start vhost-user-scsi: %s", strerror(-ret)); exit(1); } } else { vhost_scsi_common_stop(vsc); } }