From: Paolo Bonzini <pbonzini@redhat.com>
To: qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 03/16] scsi: pass status when completing
Date: Wed, 3 Aug 2011 10:49:06 +0200 [thread overview]
Message-ID: <1312361359-15445-4-git-send-email-pbonzini@redhat.com> (raw)
In-Reply-To: <1312361359-15445-1-git-send-email-pbonzini@redhat.com>
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 <pbonzini@redhat.com>
---
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);
--
1.7.6
next prev parent reply other threads:[~2011-08-03 8:49 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2011-08-03 8:49 [Qemu-devel] [PATCH 00/16] SCSI sense and target request overhaul Paolo Bonzini
2011-08-03 8:49 ` [Qemu-devel] [PATCH 01/16] scsi-disk: no need to call scsi_req_data on a short read Paolo Bonzini
2011-08-03 16:32 ` Christoph Hellwig
2011-08-04 13:35 ` Stefan Hajnoczi
2011-08-04 13:46 ` Kevin Wolf
2011-08-03 8:49 ` [Qemu-devel] [PATCH 02/16] vscsi: always use get_sense Paolo Bonzini
2011-08-03 16:32 ` Christoph Hellwig
2011-08-03 8:49 ` Paolo Bonzini [this message]
2011-08-03 16:34 ` [Qemu-devel] [PATCH 03/16] scsi: pass status when completing Christoph Hellwig
2011-08-03 8:49 ` [Qemu-devel] [PATCH 04/16] scsi: move sense handling to generic code Paolo Bonzini
2011-08-03 16:34 ` Christoph Hellwig
2011-08-03 8:49 ` [Qemu-devel] [PATCH 05/16] scsi: introduce SCSIReqOps Paolo Bonzini
2011-08-03 8:49 ` [Qemu-devel] [PATCH 06/16] scsi: move request-related callbacks from SCSIDeviceInfo to SCSIReqOps Paolo Bonzini
2011-08-03 8:49 ` [Qemu-devel] [PATCH 07/16] scsi: pass cdb already to scsi_req_new Paolo Bonzini
2011-08-03 8:49 ` [Qemu-devel] [PATCH 08/16] scsi: introduce SCSICommand Paolo Bonzini
2011-08-03 8:49 ` [Qemu-devel] [PATCH 09/16] scsi: push lun field to SCSIDevice Paolo Bonzini
2011-08-03 8:49 ` [Qemu-devel] [PATCH 10/16] scsi: move request parsing to common code Paolo Bonzini
2011-08-12 16:12 ` Peter Maydell
2011-08-12 17:05 ` Paolo Bonzini
2011-08-12 16:55 ` Peter Maydell
2011-08-12 17:11 ` Paolo Bonzini
2011-08-03 8:49 ` [Qemu-devel] [PATCH 11/16] scsi: move handling of REPORT LUNS and invalid LUNs " Paolo Bonzini
2011-08-03 8:49 ` [Qemu-devel] [PATCH 12/16] scsi: move handling of REQUEST SENSE " Paolo Bonzini
2011-08-03 8:49 ` [Qemu-devel] [PATCH 13/16] scsi: add a bunch more common sense codes Paolo Bonzini
2011-08-03 8:49 ` [Qemu-devel] [PATCH 14/16] scsi: add support for unit attention conditions Paolo Bonzini
2011-08-03 8:49 ` [Qemu-devel] [PATCH 15/16] scsi: report unit attention on reset Paolo Bonzini
2011-08-03 8:49 ` [Qemu-devel] [PATCH 16/16] scsi: add special traces for common commands Paolo Bonzini
2011-08-12 13:49 ` [Qemu-devel] [PATCH 00/16] SCSI sense and target request overhaul Anthony Liguori
2011-08-12 15:48 ` Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1312361359-15445-4-git-send-email-pbonzini@redhat.com \
--to=pbonzini@redhat.com \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).