From 5d8acbde8892cbf8a3b6652092fd473ab439f7a8 Mon Sep 17 00:00:00 2001 From: Fam Zheng Date: Thu, 7 Aug 2014 11:52:09 -0500 Subject: [CHANGE 3/4] scsi: Ensure command and transfer lengths are set for all SCSI devices To: rhvirt-patches@redhat.com, jen@redhat.com RH-Author: Fam Zheng Message-id: <1407412329-29980-1-git-send-email-famz@redhat.com> Patchwork-id: 60473 O-Subject: [RHEL-6.6 qemu-kvm PATCH v2] scsi: Ensure command and transfer lengths are set for all SCSI devices Bugzilla: 1113068 RH-Acked-by: Stefan Hajnoczi RH-Acked-by: Paolo Bonzini RH-Acked-by: Markus Armbruster From: Paolo Bonzini Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1113068 Brew: http://brewweb.devel.redhat.com/brew/taskinfo?taskID=7802048 (RHEL) http://brewweb.devel.redhat.com/brew/taskinfo?taskID=7802062 (RHEV) scsi-generic relies on those values to be correct, so it is important that those values are initialized properly for all device types. Reported-by: Christian Hoff Reported-by: Christian Borntraeger Signed-off-by: Paolo Bonzini (cherry picked from commit 28b70c9dbdce0d517ade9c04c7d7ae05c8b76d2f) Signed-off-by: Fam Zheng Signed-off-by: jen Conflicts: hw/scsi-bus.c Instances of removed assignments to cmd->len in scsi_req_length and scsi_req_stream_length are different. --- v2: Rebase to current head. (Only contextual change. Thanks to Markus for spotting the conflict). Updated brew ID's. --- hw/scsi-bus.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) Signed-off-by: jen --- hw/scsi-bus.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 27874a7..b60281a 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -763,22 +763,18 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf) switch (buf[0] >> 5) { case 0: cmd->xfer = (uint64_t) buf[4]; - cmd->len = 6; break; case 1: case 2: cmd->xfer = (uint64_t) buf[8] | ((uint64_t) buf[7] << 8); - cmd->len = 10; break; case 4: cmd->xfer = (uint64_t) buf[13] | ((uint64_t) buf[12] << 8) | ((uint64_t) buf[11] << 16) | ((uint64_t) buf[10] << 24); - cmd->len = 16; break; case 5: cmd->xfer = (uint64_t) buf[9] | ((uint64_t) buf[8] << 8) | ((uint64_t) buf[7] << 16) | ((uint64_t) buf[6] << 24); - cmd->len = 12; break; default: return -1; @@ -917,7 +913,6 @@ static int scsi_req_stream_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *bu case READ_REVERSE: case RECOVER_BUFFERED_DATA: case WRITE_6: - cmd->len = 6; cmd->xfer = buf[4] | (buf[3] << 8) | (buf[2] << 16); if (buf[1] & 0x01) { /* fixed */ cmd->xfer *= dev->blocksize; @@ -925,7 +920,6 @@ static int scsi_req_stream_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *bu break; case REWIND: case START_STOP: - cmd->len = 6; cmd->xfer = 0; break; case SPACE_16: @@ -1031,6 +1025,24 @@ int scsi_req_parse_cdb(SCSIDevice *dev, SCSICommand *cmd, uint8_t *buf) int rc; cmd->lba = -1; + switch (buf[0] >> 5) { + case 0: + cmd->len = 6; + break; + case 1: + case 2: + cmd->len = 10; + break; + case 4: + cmd->len = 16; + break; + case 5: + cmd->len = 12; + break; + default: + return -1; + } + if (dev->type == TYPE_TAPE) { rc = scsi_req_stream_length(cmd, dev, buf); } else { -- 1.9.3