diff options
author | Peter Maydell | 2019-02-01 18:58:27 +0100 |
---|---|---|
committer | Peter Maydell | 2019-02-01 18:58:27 +0100 |
commit | b3fc0af1ff5e922d4dd7c875394dbd26dc7313b4 (patch) | |
tree | 2c59c91e8112e0be05a43543f7d11394f2d52653 /hw/scsi/scsi-disk.c | |
parent | Merge remote-tracking branch 'remotes/pmaydell/tags/pull-target-arm-20190201'... (diff) | |
parent | scsi-disk: Add device_id property (diff) | |
download | qemu-b3fc0af1ff5e922d4dd7c875394dbd26dc7313b4.tar.gz qemu-b3fc0af1ff5e922d4dd7c875394dbd26dc7313b4.tar.xz qemu-b3fc0af1ff5e922d4dd7c875394dbd26dc7313b4.zip |
Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging
Block layer patches:
- vmdk: Support for blockdev-create
- block: Apply auto-read-only for ro-whitelist drivers
- virtio-scsi: Fixes related to attaching/detaching iothreads
- scsi-disk: Fixed erroneously detected multipath setup with multiple
disks created with node-names. Added device_id property.
- block: Fix hangs in synchronous APIs with iothreads
- block: Fix invalidate_cache error path for parent activation
- block-backend, mirror, qcow2, vpc, vdi, qemu-iotests:
Minor fixes and code improvements
# gpg: Signature made Fri 01 Feb 2019 15:23:10 GMT
# gpg: using RSA key 7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full]
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6
* remotes/kevin/tags/for-upstream: (27 commits)
scsi-disk: Add device_id property
scsi-disk: Don't use empty string as device id
qtest.py: Wait for the result of qtest commands
block: Fix invalidate_cache error path for parent activation
iotests/236: fix transaction kwarg order
iotests: Filter second BLOCK_JOB_ERROR from 229
virtio-scsi: Forbid devices with different iothreads sharing a blockdev
scsi-disk: Acquire the AioContext in scsi_*_realize()
virtio-scsi: Move BlockBackend back to the main AioContext on unplug
block: Eliminate the S_1KiB, S_2KiB, ... macros
block: Remove blk_attach_dev_legacy() / legacy_dev code
block: Apply auto-read-only for ro-whitelist drivers
uuid: Make qemu_uuid_bswap() take and return a QemuUUID
block/vdi: Don't take address of fields in packed structs
block/vpc: Don't take address of fields in packed structs
vmdk: Reject excess extents in blockdev-create
iotests: Add VMDK tests for blockdev-create
iotests: Filter cid numbers in VMDK extent info
vmdk: Implement .bdrv_co_create callback
vmdk: Refactor vmdk_create_extent
...
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'hw/scsi/scsi-disk.c')
-rw-r--r-- | hw/scsi/scsi-disk.c | 59 |
1 files changed, 43 insertions, 16 deletions
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index 0e9027c8f3..e6db6d7c15 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(), |