diff options
Diffstat (limited to 'hw')
-rw-r--r-- | hw/acpi/vmgenid.c | 6 | ||||
-rw-r--r-- | hw/scsi/scsi-disk.c | 59 | ||||
-rw-r--r-- | hw/scsi/virtio-scsi.c | 13 |
3 files changed, 58 insertions, 20 deletions
diff --git a/hw/acpi/vmgenid.c b/hw/acpi/vmgenid.c index d78b579..02717a8 100644 --- a/hw/acpi/vmgenid.c +++ b/hw/acpi/vmgenid.c @@ -30,8 +30,7 @@ void vmgenid_build_acpi(VmGenIdState *vms, GArray *table_data, GArray *guid, * first, since that's what the guest expects */ g_array_set_size(guid, VMGENID_FW_CFG_SIZE - ARRAY_SIZE(guid_le.data)); - guid_le = vms->guid; - qemu_uuid_bswap(&guid_le); + guid_le = qemu_uuid_bswap(vms->guid); /* The GUID is written at a fixed offset into the fw_cfg file * in order to implement the "OVMF SDT Header probe suppressor" * see docs/specs/vmgenid.txt for more details @@ -149,8 +148,7 @@ static void vmgenid_update_guest(VmGenIdState *vms) * however, will expect the fields to be little-endian. * Perform a byte swap immediately before writing. */ - guid_le = vms->guid; - qemu_uuid_bswap(&guid_le); + guid_le = qemu_uuid_bswap(vms->guid); /* The GUID is written at a fixed offset into the fw_cfg file * in order to implement the "OVMF SDT Header probe suppressor" * see docs/specs/vmgenid.txt for more details. diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index 0e9027c..e6db6d7 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -104,6 +104,7 @@ typedef struct SCSIDiskState char *serial; char *vendor; char *product; + char *device_id; bool tray_open; bool tray_locked; /* @@ -642,22 +643,19 @@ static int scsi_disk_emulate_vpd_page(SCSIRequest *req, uint8_t *outbuf) case 0x83: /* Device identification page, mandatory */ { - const char *str = s->serial ?: blk_name(s->qdev.conf.blk); - int max_len = s->serial ? 20 : 255 - 8; - int id_len = strlen(str); + int id_len = s->device_id ? MIN(strlen(s->device_id), 255 - 8) : 0; - if (id_len > max_len) { - id_len = max_len; - } DPRINTF("Inquiry EVPD[Device identification] " "buffer size %zd\n", req->cmd.xfer); - outbuf[buflen++] = 0x2; /* ASCII */ - outbuf[buflen++] = 0; /* not officially assigned */ - outbuf[buflen++] = 0; /* reserved */ - outbuf[buflen++] = id_len; /* length of data following */ - memcpy(outbuf + buflen, str, id_len); - buflen += id_len; + if (id_len) { + outbuf[buflen++] = 0x2; /* ASCII */ + outbuf[buflen++] = 0; /* not officially assigned */ + outbuf[buflen++] = 0; /* reserved */ + outbuf[buflen++] = id_len; /* length of data following */ + memcpy(outbuf + buflen, s->device_id, id_len); + buflen += id_len; + } if (s->qdev.wwn) { outbuf[buflen++] = 0x1; /* Binary */ @@ -2361,6 +2359,16 @@ static void scsi_realize(SCSIDevice *dev, Error **errp) if (!s->vendor) { s->vendor = g_strdup("QEMU"); } + if (!s->device_id) { + if (s->serial) { + s->device_id = g_strdup_printf("%.20s", s->serial); + } else { + const char *str = blk_name(s->qdev.conf.blk); + if (str && *str) { + s->device_id = g_strdup(str); + } + } + } if (blk_is_sg(s->qdev.conf.blk)) { error_setg(errp, "unwanted /dev/sg*"); @@ -2381,10 +2389,13 @@ static void scsi_realize(SCSIDevice *dev, Error **errp) static void scsi_hd_realize(SCSIDevice *dev, Error **errp) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); + AioContext *ctx = NULL; /* can happen for devices without drive. The error message for missing * backend will be issued in scsi_realize */ if (s->qdev.conf.blk) { + ctx = blk_get_aio_context(s->qdev.conf.blk); + aio_context_acquire(ctx); blkconf_blocksizes(&s->qdev.conf); } s->qdev.blocksize = s->qdev.conf.logical_block_size; @@ -2393,11 +2404,15 @@ static void scsi_hd_realize(SCSIDevice *dev, Error **errp) s->product = g_strdup("QEMU HARDDISK"); } scsi_realize(&s->qdev, errp); + if (ctx) { + aio_context_release(ctx); + } } static void scsi_cd_realize(SCSIDevice *dev, Error **errp) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); + AioContext *ctx; int ret; if (!dev->conf.blk) { @@ -2408,6 +2423,8 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp) assert(ret == 0); } + ctx = blk_get_aio_context(dev->conf.blk); + aio_context_acquire(ctx); s->qdev.blocksize = 2048; s->qdev.type = TYPE_ROM; s->features |= 1 << SCSI_DISK_F_REMOVABLE; @@ -2415,6 +2432,7 @@ static void scsi_cd_realize(SCSIDevice *dev, Error **errp) s->product = g_strdup("QEMU CD-ROM"); } scsi_realize(&s->qdev, errp); + aio_context_release(ctx); } static void scsi_disk_realize(SCSIDevice *dev, Error **errp) @@ -2553,6 +2571,7 @@ static int get_device_type(SCSIDiskState *s) static void scsi_block_realize(SCSIDevice *dev, Error **errp) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev); + AioContext *ctx; int sg_version; int rc; @@ -2567,6 +2586,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp) "be removed in a future version"); } + ctx = blk_get_aio_context(s->qdev.conf.blk); + aio_context_acquire(ctx); + /* check we are using a driver managing SG_IO (version 3 and after) */ rc = blk_ioctl(s->qdev.conf.blk, SG_GET_VERSION_NUM, &sg_version); if (rc < 0) { @@ -2574,18 +2596,18 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp) if (rc != -EPERM) { error_append_hint(errp, "Is this a SCSI device?\n"); } - return; + goto out; } if (sg_version < 30000) { error_setg(errp, "scsi generic interface too old"); - return; + goto out; } /* get device type from INQUIRY data */ rc = get_device_type(s); if (rc < 0) { error_setg(errp, "INQUIRY failed"); - return; + goto out; } /* Make a guess for the block size, we'll fix it when the guest sends. @@ -2605,6 +2627,9 @@ static void scsi_block_realize(SCSIDevice *dev, Error **errp) scsi_realize(&s->qdev, errp); scsi_generic_read_device_inquiry(&s->qdev); + +out: + aio_context_release(ctx); } typedef struct SCSIBlockReq { @@ -2902,7 +2927,9 @@ static const TypeInfo scsi_disk_base_info = { DEFINE_PROP_STRING("ver", SCSIDiskState, version), \ DEFINE_PROP_STRING("serial", SCSIDiskState, serial), \ DEFINE_PROP_STRING("vendor", SCSIDiskState, vendor), \ - DEFINE_PROP_STRING("product", SCSIDiskState, product) + DEFINE_PROP_STRING("product", SCSIDiskState, product), \ + DEFINE_PROP_STRING("device_id", SCSIDiskState, device_id) + static Property scsi_hd_properties[] = { DEFINE_SCSI_DISK_PROPERTIES(), diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 3aa9971..eb90288 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -791,9 +791,16 @@ static void virtio_scsi_hotplug(HotplugHandler *hotplug_dev, DeviceState *dev, SCSIDevice *sd = SCSI_DEVICE(dev); if (s->ctx && !s->dataplane_fenced) { + AioContext *ctx; if (blk_op_is_blocked(sd->conf.blk, BLOCK_OP_TYPE_DATAPLANE, errp)) { return; } + ctx = blk_get_aio_context(sd->conf.blk); + if (ctx != s->ctx && ctx != qemu_get_aio_context()) { + error_setg(errp, "Cannot attach a blockdev that is using " + "a different iothread"); + return; + } virtio_scsi_acquire(s); blk_set_aio_context(sd->conf.blk, s->ctx); virtio_scsi_release(s); @@ -824,6 +831,12 @@ static void virtio_scsi_hotunplug(HotplugHandler *hotplug_dev, DeviceState *dev, virtio_scsi_release(s); } + if (s->ctx) { + virtio_scsi_acquire(s); + blk_set_aio_context(sd->conf.blk, qemu_get_aio_context()); + virtio_scsi_release(s); + } + qdev_simple_device_unplug_cb(hotplug_dev, dev, errp); } |