From patchwork Fri Aug 3 08:06:20 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 174946 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 8323F2C00AD for ; Fri, 3 Aug 2012 18:08:36 +1000 (EST) Received: from localhost ([::1]:37013 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SxCvy-0004X2-GF for incoming@patchwork.ozlabs.org; Fri, 03 Aug 2012 04:08:34 -0400 Received: from eggs.gnu.org ([208.118.235.92]:47591) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SxCuV-0001J7-NX for qemu-devel@nongnu.org; Fri, 03 Aug 2012 04:07:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SxCuU-0007Dq-Fd for qemu-devel@nongnu.org; Fri, 03 Aug 2012 04:07:03 -0400 Received: from mail-gg0-f173.google.com ([209.85.161.173]:44126) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SxCuU-0006jV-B0 for qemu-devel@nongnu.org; Fri, 03 Aug 2012 04:07:02 -0400 Received: by mail-gg0-f173.google.com with SMTP id p1so499152ggn.4 for ; Fri, 03 Aug 2012 01:07:02 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:from:to:cc:subject:date:message-id:x-mailer:in-reply-to :references; bh=jRvTlmR24XapfaYPAV5H/TnViG9QEvCKRhOsLviDoDc=; b=pLGTUoST774vhT4SDe69stSliKdrkLSnR5iIDPKkgEgqN2/+l6054iQS3b+EYBzxnB JkSzBx3vclxQCezdV1OnCYJLuO58i1vFOo8zjZ81DL1pi+x/23ziDbuWHpWPYVAM+dmD aGERo8ccOeJQvXFlBXhupRYo1pVJjCMtnYGEqtgXzRQ60Gb7b3e49e4j9NosQZnwsaPO /2ZtTCGhKjSznJt/C9KJ4rf8hwJNqUNLMhu4Uqj1FAFg0F9egOzyRNX4zMLdueWVOAkh E2/fXPmAdME8EwDfQxScWzzIc5adrMnx3n9amp8rOusQw2/hgwvs2fpp/Oj5p0MmONev m1xw== Received: by 10.50.47.231 with SMTP id g7mr1668526ign.62.1343981221819; Fri, 03 Aug 2012 01:07:01 -0700 (PDT) Received: from yakj.usersys.redhat.com (93-34-169-1.ip50.fastwebnet.it. [93.34.169.1]) by mx.google.com with ESMTPS id rd8sm19683913igb.3.2012.08.03.01.06.58 (version=TLSv1/SSLv3 cipher=OTHER); Fri, 03 Aug 2012 01:07:00 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Fri, 3 Aug 2012 10:06:20 +0200 Message-Id: <1343981180-23817-11-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.10.4 In-Reply-To: <1343981180-23817-1-git-send-email-pbonzini@redhat.com> References: <1343981180-23817-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 209.85.161.173 Cc: Cong Meng Subject: [Qemu-devel] [PATCH 10/10] scsi: add support for ATA_PASSTHROUGH_xx scsi command X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org From: Cong Meng Correct the command names of opcode 0x85 and 0xa1, and calculate their xfer size from CDB. Signed-off-by: Cong Meng Signed-off-by: Paolo Bonzini --- hw/scsi-bus.c | 88 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- hw/scsi-defs.h | 4 +-- 2 files changed, 87 insertions(+), 5 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 68049f6..6120cc8 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -733,6 +733,72 @@ static int scsi_get_performance_length(int num_desc, int type, int data_type) } } +static int ata_passthrough_xfer_unit(SCSIDevice *dev, uint8_t *buf) +{ + int byte_block = (buf[2] >> 2) & 0x1; + int type = (buf[2] >> 4) & 0x1; + int xfer_unit; + + if (byte_block) { + if (type) { + xfer_unit = dev->blocksize; + } else { + xfer_unit = 512; + } + } else { + xfer_unit = 1; + } + + return xfer_unit; +} + +static int ata_passthrough_12_xfer_size(SCSIDevice *dev, uint8_t *buf) +{ + int length = buf[2] & 0x3; + int xfer; + int unit = ata_passthrough_xfer_unit(dev, buf); + + switch (length) { + case 0: + case 3: /* USB-specific. */ + xfer = 0; + break; + case 1: + xfer = buf[3]; + break; + case 2: + xfer = buf[4]; + break; + } + + return xfer * unit; +} + +static int ata_passthrough_16_xfer_size(SCSIDevice *dev, uint8_t *buf) +{ + int extend = buf[1] & 0x1; + int length = buf[2] & 0x3; + int xfer; + int unit = ata_passthrough_xfer_unit(dev, buf); + + switch (length) { + case 0: + case 3: /* USB-specific. */ + xfer = 0; + break; + case 1: + xfer = buf[4]; + xfer |= (extend ? buf[3] << 8 : 0); + break; + case 2: + xfer = buf[6]; + xfer |= (extend ? buf[5] << 8 : 0); + break; + } + + return xfer * unit; +} + static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf) { switch (buf[0] >> 5) { @@ -867,6 +933,17 @@ static int scsi_req_length(SCSICommand *cmd, SCSIDevice *dev, uint8_t *buf) cmd->xfer = buf[9] | (buf[8] << 8); } break; + case ATA_PASSTHROUGH_12: + if (dev->type == TYPE_ROM) { + /* BLANK command of MMC */ + cmd->xfer = 0; + } else { + cmd->xfer = ata_passthrough_12_xfer_size(dev, buf); + } + break; + case ATA_PASSTHROUGH_16: + cmd->xfer = ata_passthrough_16_xfer_size(dev, buf); + break; } return 0; } @@ -996,9 +1073,14 @@ static void scsi_cmd_xfer_mode(SCSICommand *cmd) case SEND_DVD_STRUCTURE: case PERSISTENT_RESERVE_OUT: case MAINTENANCE_OUT: - case ATA_PASSTHROUGH: cmd->mode = SCSI_XFER_TO_DEV; break; + case ATA_PASSTHROUGH_12: + case ATA_PASSTHROUGH_16: + /* T_DIR */ + cmd->mode = (cmd->buf[2] & 0x8) ? + SCSI_XFER_FROM_DEV : SCSI_XFER_TO_DEV; + break; default: cmd->mode = SCSI_XFER_FROM_DEV; break; @@ -1335,7 +1417,7 @@ static const char *scsi_command_name(uint8_t cmd) [ PERSISTENT_RESERVE_OUT ] = "PERSISTENT_RESERVE_OUT", [ WRITE_FILEMARKS_16 ] = "WRITE_FILEMARKS_16", [ EXTENDED_COPY ] = "EXTENDED_COPY", - [ ATA_PASSTHROUGH ] = "ATA_PASSTHROUGH", + [ ATA_PASSTHROUGH_16 ] = "ATA_PASSTHROUGH_16", [ ACCESS_CONTROL_IN ] = "ACCESS_CONTROL_IN", [ ACCESS_CONTROL_OUT ] = "ACCESS_CONTROL_OUT", [ READ_16 ] = "READ_16", @@ -1352,7 +1434,7 @@ static const char *scsi_command_name(uint8_t cmd) [ SERVICE_ACTION_IN_16 ] = "SERVICE_ACTION_IN_16", [ WRITE_LONG_16 ] = "WRITE_LONG_16", [ REPORT_LUNS ] = "REPORT_LUNS", - [ BLANK ] = "BLANK", + [ ATA_PASSTHROUGH_12 ] = "BLANK/ATA_PASSTHROUGH_12", [ MOVE_MEDIUM ] = "MOVE_MEDIUM", [ EXCHANGE_MEDIUM ] = "EXCHANGE MEDIUM", [ LOAD_UNLOAD ] = "LOAD_UNLOAD", diff --git a/hw/scsi-defs.h b/hw/scsi-defs.h index 8a73f74..d7a4019 100644 --- a/hw/scsi-defs.h +++ b/hw/scsi-defs.h @@ -100,7 +100,7 @@ #define READ_REVERSE_16 0x81 #define ALLOW_OVERWRITE 0x82 #define EXTENDED_COPY 0x83 -#define ATA_PASSTHROUGH 0x85 +#define ATA_PASSTHROUGH_16 0x85 #define ACCESS_CONTROL_IN 0x86 #define ACCESS_CONTROL_OUT 0x87 #define READ_16 0x88 @@ -117,7 +117,7 @@ #define SERVICE_ACTION_IN_16 0x9e #define WRITE_LONG_16 0x9f #define REPORT_LUNS 0xa0 -#define BLANK 0xa1 +#define ATA_PASSTHROUGH_12 0xa1 #define MAINTENANCE_IN 0xa3 #define MAINTENANCE_OUT 0xa4 #define MOVE_MEDIUM 0xa5