From patchwork Wed Aug 3 08:49:06 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Paolo Bonzini X-Patchwork-Id: 108055 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id CB1E1B7199 for ; Wed, 3 Aug 2011 18:50:12 +1000 (EST) Received: from localhost ([::1]:51757 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QoX9V-0006ja-QL for incoming@patchwork.ozlabs.org; Wed, 03 Aug 2011 04:50:09 -0400 Received: from eggs.gnu.org ([140.186.70.92]:44570) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QoX8t-0005U1-Cs for qemu-devel@nongnu.org; Wed, 03 Aug 2011 04:49:32 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QoX8r-0003gd-IS for qemu-devel@nongnu.org; Wed, 03 Aug 2011 04:49:31 -0400 Received: from mail-ww0-f53.google.com ([74.125.82.53]:42749) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QoX8r-0003g6-DH for qemu-devel@nongnu.org; Wed, 03 Aug 2011 04:49:29 -0400 Received: by mail-ww0-f53.google.com with SMTP id 26so527679wwf.10 for ; Wed, 03 Aug 2011 01:49:29 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=gamma; h=sender:from:to:subject:date:message-id:x-mailer:in-reply-to :references; bh=Mv3AN4VkJBlOyE4KgBQcMFtPeyDbb4l69zMshNrTna4=; b=MBFHesPuasDtKRXLF8z2xUEsJIeh3jJXJQfijVFt37nQYp6dSEjwciQCDcjs2tc54g mrcMihBwTk0b4D+NUmm5QkiESu73HN/sASndEBRdYJOBMTNdSl6ntR9+H45Hk0ni3f/X qrYws8qA6+8L3gIUksAcQh7sZLCN+GD3P9wZQ= Received: by 10.216.170.6 with SMTP id o6mr439464wel.6.1312361368949; Wed, 03 Aug 2011 01:49:28 -0700 (PDT) Received: from localhost.localdomain (93-34-199-31.ip51.fastwebnet.it [93.34.199.31]) by mx.google.com with ESMTPS id ff6sm485877wbb.66.2011.08.03.01.49.28 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 03 Aug 2011 01:49:28 -0700 (PDT) From: Paolo Bonzini To: qemu-devel@nongnu.org Date: Wed, 3 Aug 2011 10:49:06 +0200 Message-Id: <1312361359-15445-4-git-send-email-pbonzini@redhat.com> X-Mailer: git-send-email 1.7.6 In-Reply-To: <1312361359-15445-1-git-send-email-pbonzini@redhat.com> References: <1312361359-15445-1-git-send-email-pbonzini@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 74.125.82.53 Subject: [Qemu-devel] [PATCH 03/16] scsi: pass status when completing 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 A small improvement in the SCSI request API. Pass the status at the time the request is completed, so that we can assert that no request is completed twice. This would have detected the problem fixed in the previous patch. Signed-off-by: Paolo Bonzini Reviewed-by: Christoph Hellwig --- hw/scsi-bus.c | 8 ++++---- hw/scsi-disk.c | 15 ++++----------- hw/scsi-generic.c | 31 ++++++++++++++++--------------- hw/scsi.h | 2 +- 4 files changed, 25 insertions(+), 31 deletions(-) diff --git a/hw/scsi-bus.c b/hw/scsi-bus.c index 8b1a412..bff2f5b 100644 --- a/hw/scsi-bus.c +++ b/hw/scsi-bus.c @@ -672,9 +672,10 @@ void scsi_req_print(SCSIRequest *req) } } -void scsi_req_complete(SCSIRequest *req) +void scsi_req_complete(SCSIRequest *req, int status) { - assert(req->status != -1); + assert(req->status == -1); + req->status = status; scsi_req_ref(req); scsi_req_dequeue(req); req->bus->ops->complete(req, req->status); @@ -696,11 +697,10 @@ void scsi_req_cancel(SCSIRequest *req) void scsi_req_abort(SCSIRequest *req, int status) { - req->status = status; if (req->dev && req->dev->info->cancel_io) { req->dev->info->cancel_io(req); } - scsi_req_complete(req); + scsi_req_complete(req, status); } void scsi_device_purge_requests(SCSIDevice *sdev) diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 814bf74..8beaebf 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -105,21 +105,15 @@ static void scsi_disk_clear_sense(SCSIDiskState *s) memset(&s->sense, 0, sizeof(s->sense)); } -static void scsi_req_set_status(SCSIDiskReq *r, int status, SCSISense sense) -{ - SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); - - r->req.status = status; - s->sense = sense; -} - /* Helper function for command completion. */ static void scsi_command_complete(SCSIDiskReq *r, int status, SCSISense sense) { + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); + DPRINTF("Command complete tag=0x%x status=%d sense=%d/%d/%d\n", r->req.tag, status, sense.key, sense.asc, sense.ascq); - scsi_req_set_status(r, status, sense); - scsi_req_complete(&r->req); + s->sense = sense; + scsi_req_complete(&r->req, status); } /* Cancel a pending data transfer. */ @@ -979,7 +973,6 @@ static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf) scsi_command_complete(r, CHECK_CONDITION, SENSE_CODE(INVALID_OPCODE)); return -1; } - scsi_req_set_status(r, GOOD, SENSE_CODE(NO_SENSE)); return buflen; not_ready: diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index 63361b3..f119f33 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -115,6 +115,7 @@ static void scsi_free_request(SCSIRequest *req) /* Helper function for command completion. */ static void scsi_command_complete(void *opaque, int ret) { + int status; SCSIGenericReq *r = (SCSIGenericReq *)opaque; SCSIGenericState *s = DO_UPCAST(SCSIGenericState, qdev, r->req.dev); @@ -126,36 +127,37 @@ static void scsi_command_complete(void *opaque, int ret) if (ret != 0) { switch (ret) { case -EDOM: - r->req.status = TASK_SET_FULL; + status = TASK_SET_FULL; break; case -EINVAL: - r->req.status = CHECK_CONDITION; + status = CHECK_CONDITION; scsi_set_sense(s, SENSE_CODE(INVALID_FIELD)); break; case -ENOMEM: - r->req.status = CHECK_CONDITION; + status = CHECK_CONDITION; scsi_set_sense(s, SENSE_CODE(TARGET_FAILURE)); break; default: - r->req.status = CHECK_CONDITION; + status = CHECK_CONDITION; scsi_set_sense(s, SENSE_CODE(IO_ERROR)); break; } } else { if (s->driver_status & SG_ERR_DRIVER_TIMEOUT) { - r->req.status = BUSY; + status = BUSY; BADF("Driver Timeout\n"); - } else if (r->io_header.status) - r->req.status = r->io_header.status; - else if (s->driver_status & SG_ERR_DRIVER_SENSE) - r->req.status = CHECK_CONDITION; - else - r->req.status = GOOD; + } else if (r->io_header.status) { + status = r->io_header.status; + } else if (s->driver_status & SG_ERR_DRIVER_SENSE) { + status = CHECK_CONDITION; + } else { + status = GOOD; + } } DPRINTF("Command complete 0x%p tag=0x%x status=%d\n", - r, r->req.tag, r->req.status); + r, r->req.tag, status); - scsi_req_complete(&r->req); + scsi_req_complete(&r->req, status); } /* Cancel a pending data transfer. */ @@ -341,8 +343,7 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *cmd) if (cmd[0] != REQUEST_SENSE && req->lun != s->lun) { DPRINTF("Unimplemented LUN %d\n", req->lun); scsi_set_sense(s, SENSE_CODE(LUN_NOT_SUPPORTED)); - r->req.status = CHECK_CONDITION; - scsi_req_complete(&r->req); + scsi_req_complete(&r->req, CHECK_CONDITION); return 0; } diff --git a/hw/scsi.h b/hw/scsi.h index 6b15bbc..18d3643 100644 --- a/hw/scsi.h +++ b/hw/scsi.h @@ -153,7 +153,7 @@ int scsi_req_parse(SCSIRequest *req, uint8_t *buf); void scsi_req_print(SCSIRequest *req); void scsi_req_continue(SCSIRequest *req); void scsi_req_data(SCSIRequest *req, int len); -void scsi_req_complete(SCSIRequest *req); +void scsi_req_complete(SCSIRequest *req, int status); uint8_t *scsi_req_get_buf(SCSIRequest *req); int scsi_req_get_sense(SCSIRequest *req, uint8_t *buf, int len); void scsi_req_abort(SCSIRequest *req, int status);