From patchwork Thu Nov 26 14:34:02 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gerd Hoffmann X-Patchwork-Id: 39550 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [199.232.76.165]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id BB1931007D9 for ; Fri, 27 Nov 2009 02:58:39 +1100 (EST) Received: from localhost ([127.0.0.1]:48028 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NDgjr-0005Vd-Vm for incoming@patchwork.ozlabs.org; Thu, 26 Nov 2009 10:58:36 -0500 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1NDfRB-00074Q-3i for qemu-devel@nongnu.org; Thu, 26 Nov 2009 09:35:15 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1NDfQz-0006pj-TD for qemu-devel@nongnu.org; Thu, 26 Nov 2009 09:35:07 -0500 Received: from [199.232.76.173] (port=56172 helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1NDfQz-0006pO-GE for qemu-devel@nongnu.org; Thu, 26 Nov 2009 09:35:01 -0500 Received: from mx1.redhat.com ([209.132.183.28]:60981) by monty-python.gnu.org with esmtp (Exim 4.60) (envelope-from ) id 1NDfQz-0000IG-3E for qemu-devel@nongnu.org; Thu, 26 Nov 2009 09:35:01 -0500 Received: from int-mx01.intmail.prod.int.phx2.redhat.com (int-mx01.intmail.prod.int.phx2.redhat.com [10.5.11.11]) by mx1.redhat.com (8.13.8/8.13.8) with ESMTP id nAQEZ0iF012663 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK) for ; Thu, 26 Nov 2009 09:35:00 -0500 Received: from zweiblum.home.kraxel.org (vpn2-8-164.ams2.redhat.com [10.36.8.164]) by int-mx01.intmail.prod.int.phx2.redhat.com (8.13.8/8.13.8) with SMTP id nAQEYpao009978; Thu, 26 Nov 2009 09:34:54 -0500 Received: by zweiblum.home.kraxel.org (Postfix, from userid 500) id 4525112008; Thu, 26 Nov 2009 15:34:18 +0100 (CET) From: Gerd Hoffmann To: qemu-devel@nongnu.org Date: Thu, 26 Nov 2009 15:34:02 +0100 Message-Id: <1259246056-5389-17-git-send-email-kraxel@redhat.com> In-Reply-To: <1259246056-5389-1-git-send-email-kraxel@redhat.com> References: <1259246056-5389-1-git-send-email-kraxel@redhat.com> X-Scanned-By: MIMEDefang 2.67 on 10.5.11.11 X-detected-operating-system: by monty-python.gnu.org: Genre and OS details not recognized. Cc: Gerd Hoffmann Subject: [Qemu-devel] [PATCH 16/30] scsi-disk: restruct emulation: core + TEST_UNIT_READY. X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Add new scsi_disk_emulate_command() function, which will -- when finished -- handle all scsi disk command emulation except actual I/O (READ+WRITE commands) which goes to the block layer. The function builds on top of the new SCSIRequest struct. SCSI command emulation code is moved over from scsi_send_command() in steps to ease review and make it easier to pin down regressions (if any) using bisect. This patch moves over TEST_UNIT_READY only. Signed-off-by: Gerd Hoffmann --- hw/scsi-disk.c | 47 ++++++++++++++++++++++++++++++++++++++++++----- 1 files changed, 42 insertions(+), 5 deletions(-) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index bc8270c..f851694 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -306,6 +306,31 @@ static uint8_t *scsi_get_buf(SCSIDevice *d, uint32_t tag) return (uint8_t *)r->iov.iov_base; } +static int scsi_disk_emulate_command(SCSIRequest *req, uint8_t *outbuf) +{ + BlockDriverState *bdrv = req->dev->dinfo->bdrv; + int buflen = 0; + + switch (req->cmd.buf[0]) { + case TEST_UNIT_READY: + if (!bdrv_is_inserted(bdrv)) + goto not_ready; + break; + default: + goto illegal_request; + } + scsi_req_set_status(req, GOOD, NO_SENSE); + return buflen; + +not_ready: + scsi_req_set_status(req, CHECK_CONDITION, NOT_READY); + return 0; + +illegal_request: + scsi_req_set_status(req, CHECK_CONDITION, ILLEGAL_REQUEST); + return 0; +} + /* Execute a scsi command. Returns the length of the data expected by the command. This will be Positive for data transfers from the device (eg. disk reads), negative for transfers to the device (eg. disk writes), @@ -323,6 +348,7 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, uint8_t command; uint8_t *outbuf; SCSIDiskReq *r; + int rc; command = buf[0]; r = scsi_find_request(s, tag); @@ -377,6 +403,14 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, printf("\n"); } #endif + + if (scsi_req_parse(&r->req, buf) != 0) { + BADF("Unsupported command length, command %x\n", command); + goto fail; + } + assert(r->req.cmd.len == cmdlen); + assert(r->req.cmd.lba == lba); + if (lun || buf[1] >> 5) { /* Only LUN 0 supported. */ DPRINTF("Unimplemented LUN %d\n", lun ? lun : buf[1] >> 5); @@ -385,10 +419,14 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, } switch (command) { case TEST_UNIT_READY: - DPRINTF("Test Unit Ready\n"); - if (!bdrv_is_inserted(s->qdev.dinfo->bdrv)) - goto notready; - break; + rc = scsi_disk_emulate_command(&r->req, outbuf); + if (rc > 0) { + r->iov.iov_len = rc; + } else { + scsi_req_complete(&r->req); + scsi_remove_request(r); + } + return rc; case REQUEST_SENSE: DPRINTF("Request Sense (len %d)\n", len); if (len < 4) @@ -761,7 +799,6 @@ static int32_t scsi_send_command(SCSIDevice *d, uint32_t tag, outbuf[7] = 0; r->iov.iov_len = 8; } else { - notready: scsi_command_complete(r, CHECK_CONDITION, NOT_READY); return 0; }