[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 24/47] scsi-disk: provide maximum transfer length
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PULL 24/47] scsi-disk: provide maximum transfer length |
Date: |
Mon, 15 Dec 2014 17:38:08 +0100 |
The QEMU block layer has a limit of INT_MAX bytes per transfer.
Expose it in the block limits VPD page for both regular transfers
and WRITE SAME.
Reported-by: Ming Lei <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
---
hw/scsi/scsi-disk.c | 27 +++++++++++++++++++++++++++
1 file changed, 27 insertions(+)
diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c
index 2f75d7d..f65618d 100644
--- a/hw/scsi/scsi-disk.c
+++ b/hw/scsi/scsi-disk.c
@@ -49,6 +49,7 @@ do { printf("scsi-disk: " fmt , ## __VA_ARGS__); } while (0)
#define DEFAULT_DISCARD_GRANULARITY 4096
#define DEFAULT_MAX_UNMAP_SIZE (1 << 30) /* 1 GB */
+#define DEFAULT_MAX_IO_SIZE INT_MAX /* 2 GB - 1 block */
typedef struct SCSIDiskState SCSIDiskState;
@@ -79,6 +80,7 @@ struct SCSIDiskState
uint64_t port_wwn;
uint16_t port_index;
uint64_t max_unmap_size;
+ uint64_t max_io_size;
QEMUBH *bh;
char *version;
char *serial;
@@ -635,6 +637,8 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req,
uint8_t *outbuf)
s->qdev.conf.opt_io_size / s->qdev.blocksize;
unsigned int max_unmap_sectors =
s->max_unmap_size / s->qdev.blocksize;
+ unsigned int max_io_sectors =
+ s->max_io_size / s->qdev.blocksize;
if (s->qdev.type == TYPE_ROM) {
DPRINTF("Inquiry (EVPD[%02X] not supported for CDROM\n",
@@ -651,6 +655,12 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req,
uint8_t *outbuf)
outbuf[6] = (min_io_size >> 8) & 0xff;
outbuf[7] = min_io_size & 0xff;
+ /* maximum transfer length */
+ outbuf[8] = (max_io_sectors >> 24) & 0xff;
+ outbuf[9] = (max_io_sectors >> 16) & 0xff;
+ outbuf[10] = (max_io_sectors >> 8) & 0xff;
+ outbuf[11] = max_io_sectors & 0xff;
+
/* optimal transfer length */
outbuf[12] = (opt_io_size >> 24) & 0xff;
outbuf[13] = (opt_io_size >> 16) & 0xff;
@@ -674,6 +684,17 @@ static int scsi_disk_emulate_inquiry(SCSIRequest *req,
uint8_t *outbuf)
outbuf[29] = (unmap_sectors >> 16) & 0xff;
outbuf[30] = (unmap_sectors >> 8) & 0xff;
outbuf[31] = unmap_sectors & 0xff;
+
+ /* max write same size */
+ outbuf[36] = 0;
+ outbuf[37] = 0;
+ outbuf[38] = 0;
+ outbuf[39] = 0;
+
+ outbuf[40] = (max_io_sectors >> 24) & 0xff;
+ outbuf[41] = (max_io_sectors >> 16) & 0xff;
+ outbuf[42] = (max_io_sectors >> 8) & 0xff;
+ outbuf[43] = max_io_sectors & 0xff;
break;
}
case 0xb2: /* thin provisioning */
@@ -2579,6 +2600,8 @@ static Property scsi_hd_properties[] = {
DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
DEFAULT_MAX_UNMAP_SIZE),
+ DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
+ DEFAULT_MAX_IO_SIZE),
DEFINE_BLOCK_CHS_PROPERTIES(SCSIDiskState, qdev.conf),
DEFINE_PROP_END_OF_LIST(),
};
@@ -2625,6 +2648,8 @@ static Property scsi_cd_properties[] = {
DEFINE_PROP_UINT64("wwn", SCSIDiskState, wwn, 0),
DEFINE_PROP_UINT64("port_wwn", SCSIDiskState, port_wwn, 0),
DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
+ DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
+ DEFAULT_MAX_IO_SIZE),
DEFINE_PROP_END_OF_LIST(),
};
@@ -2690,6 +2715,8 @@ static Property scsi_disk_properties[] = {
DEFINE_PROP_UINT16("port_index", SCSIDiskState, port_index, 0),
DEFINE_PROP_UINT64("max_unmap_size", SCSIDiskState, max_unmap_size,
DEFAULT_MAX_UNMAP_SIZE),
+ DEFINE_PROP_UINT64("max_io_size", SCSIDiskState, max_io_size,
+ DEFAULT_MAX_IO_SIZE),
DEFINE_PROP_END_OF_LIST(),
};
--
1.8.3.1
- [Qemu-devel] [PULL 13/47] coverity/s390x: avoid false positive in kvm_irqchip_add_adapter_route, (continued)
- [Qemu-devel] [PULL 13/47] coverity/s390x: avoid false positive in kvm_irqchip_add_adapter_route, Paolo Bonzini, 2014/12/15
- [Qemu-devel] [PULL 16/47] target-i386: get/set/migrate XSAVES state, Paolo Bonzini, 2014/12/15
- [Qemu-devel] [PULL 15/47] target-mips: kvm: do not use get_clock(), Paolo Bonzini, 2014/12/15
- [Qemu-devel] [PULL 18/47] x86: Fuse g_malloc(); memset() into g_malloc0(), Paolo Bonzini, 2014/12/15
- [Qemu-devel] [PULL 17/47] x86: Drop superfluous conditionals around g_free(), Paolo Bonzini, 2014/12/15
- [Qemu-devel] [PULL 19/47] x86: Use g_new() & friends where that makes obvious sense, Paolo Bonzini, 2014/12/15
- [Qemu-devel] [PULL 20/47] x86: Drop some superfluous casts from void *, Paolo Bonzini, 2014/12/15
- [Qemu-devel] [PULL 21/47] scsi: Drop superfluous conditionals around g_free(), Paolo Bonzini, 2014/12/15
- [Qemu-devel] [PULL 22/47] scsi: Fuse g_malloc(); memset() into g_malloc0(), Paolo Bonzini, 2014/12/15
- [Qemu-devel] [PULL 23/47] scsi: Use g_new() & friends where that makes obvious sense, Paolo Bonzini, 2014/12/15
- [Qemu-devel] [PULL 24/47] scsi-disk: provide maximum transfer length,
Paolo Bonzini <=
- [Qemu-devel] [PULL 26/47] cpu-exec: reset exception_index correctly, Paolo Bonzini, 2014/12/15
- [Qemu-devel] [PULL 27/47] icount: set can_do_io outside TB execution, Paolo Bonzini, 2014/12/15
- [Qemu-devel] [PULL 25/47] cpu-exec: fix cpu_exec_nocache, Paolo Bonzini, 2014/12/15
- [Qemu-devel] [PULL 28/47] icount: introduce cpu_get_icount_raw, Paolo Bonzini, 2014/12/15
- [Qemu-devel] [PULL 29/47] cpu-exec: invalidate nocache translation if they are interrupted, Paolo Bonzini, 2014/12/15