diff options
author | Eric Farman <farman@linux.vnet.ibm.com> | 2017-05-10 17:53:57 +0200 |
---|---|---|
committer | Cornelia Huck <cornelia.huck@de.ibm.com> | 2017-05-19 12:29:01 +0200 |
commit | fe921fc8b7e92020bb140079a9f47f14fb8e9075 (patch) | |
tree | b40bd42284828ff0b2908e692369d2f0e84ce29c /pc-bios/s390-ccw/virtio-scsi.c | |
parent | 8edfe85bef669d676ad17cd84b4e3dce43b110e4 (diff) | |
download | qemu-fe921fc8b7e92020bb140079a9f47f14fb8e9075.zip qemu-fe921fc8b7e92020bb140079a9f47f14fb8e9075.tar.gz qemu-fe921fc8b7e92020bb140079a9f47f14fb8e9075.tar.bz2 |
pc-bios/s390-ccw: Get Block Limits VPD device data
The "Block Limits" Inquiry VPD page is optional for any SCSI device,
but if it's supported it provides a hint of the maximum I/O transfer
length for this particular device. If this page is supported by the
disk, let's issue that Inquiry and use the minimum of it and the
SCSI controller limit. That will cover this scenario:
qemu-system-s390x ...
-device virtio-scsi-ccw,id=scsi0,max_sectors=32768 ...
-drive file=/dev/sda,if=none,id=drive0,format=raw ...
-device scsi-hd,bus=scsi0.0,channel=0,scsi-id=0,
drive=drive0,id=disk0,max_io_size=1048576
controller: 32768 sectors x 512 bytes/sector = 16777216 bytes
disk: 1048576 bytes
Now that we have a limit for a virtio-scsi disk, compare that with the
limit for the virtio-scsi controller when we actually build the I/O.
The minimum of these two limits should be the one we use.
Signed-off-by: Eric Farman <farman@linux.vnet.ibm.com>
Message-Id: <20170510155359.32727-7-farman@linux.vnet.ibm.com>
Signed-off-by: Cornelia Huck <cornelia.huck@de.ibm.com>
Diffstat (limited to 'pc-bios/s390-ccw/virtio-scsi.c')
-rw-r--r-- | pc-bios/s390-ccw/virtio-scsi.c | 21 |
1 files changed, 20 insertions, 1 deletions
diff --git a/pc-bios/s390-ccw/virtio-scsi.c b/pc-bios/s390-ccw/virtio-scsi.c index e34755c..b722f25 100644 --- a/pc-bios/s390-ccw/virtio-scsi.c +++ b/pc-bios/s390-ccw/virtio-scsi.c @@ -20,6 +20,7 @@ static VirtioScsiCmdResp resp; static uint8_t scsi_inquiry_std_response[256]; static ScsiInquiryEvpdPages scsi_inquiry_evpd_pages_response; +static ScsiInquiryEvpdBl scsi_inquiry_evpd_bl_response; static inline void vs_assert(bool term, const char **msgs) { @@ -262,9 +263,11 @@ int virtio_scsi_read_many(VDev *vdev, int sector_count; int f = vdev->blk_factor; unsigned int data_size; + unsigned int max_transfer = MIN_NON_ZERO(vdev->config.scsi.max_sectors, + vdev->max_transfer); do { - sector_count = MIN_NON_ZERO(sec_num, vdev->config.scsi.max_sectors); + sector_count = MIN_NON_ZERO(sec_num, max_transfer); data_size = sector_count * virtio_get_block_size() * f; if (!scsi_read_10(vdev, sector * f, sector_count * f, load_addr, data_size)) { @@ -321,6 +324,7 @@ void virtio_scsi_setup(VDev *vdev) uint8_t data[256]; uint32_t data_size = sizeof(data); ScsiInquiryEvpdPages *evpd = &scsi_inquiry_evpd_pages_response; + ScsiInquiryEvpdBl *evpd_bl = &scsi_inquiry_evpd_bl_response; int i; vdev->scsi_device = &default_scsi_device; @@ -378,6 +382,21 @@ void virtio_scsi_setup(VDev *vdev) for (i = 0; i <= evpd->page_length; i++) { debug_print_int("supported EVPD page", evpd->byte[i]); + + if (evpd->byte[i] != SCSI_INQUIRY_EVPD_BLOCK_LIMITS) { + continue; + } + + if (!scsi_inquiry(vdev, + SCSI_INQUIRY_EVPD, + SCSI_INQUIRY_EVPD_BLOCK_LIMITS, + evpd_bl, + sizeof(*evpd_bl))) { + virtio_scsi_verify_response(&resp, "virtio-scsi:setup:blocklimits"); + } + + debug_print_int("max transfer", evpd_bl->max_transfer); + vdev->max_transfer = evpd_bl->max_transfer; } if (!scsi_read_capacity(vdev, data, data_size)) { |