|
Paolo Bonzini |
0fb2b2 |
From 1ebf7935eca7f2a1f5a1376ee3b234f4fce98023 Mon Sep 17 00:00:00 2001
|
|
Paolo Bonzini |
0fb2b2 |
From: Paolo Bonzini <pbonzini@redhat.com>
|
|
Paolo Bonzini |
0fb2b2 |
Date: Tue, 22 Aug 2017 09:43:14 +0200
|
|
Paolo Bonzini |
0fb2b2 |
Subject: [PATCH 10/15] scsi: introduce sg_io_sense_from_errno
|
|
Paolo Bonzini |
0fb2b2 |
|
|
Paolo Bonzini |
0fb2b2 |
Move more knowledge of SG_IO out of hw/scsi/scsi-generic.c, for
|
|
Paolo Bonzini |
0fb2b2 |
reusability.
|
|
Paolo Bonzini |
0fb2b2 |
|
|
Paolo Bonzini |
0fb2b2 |
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
Paolo Bonzini |
0fb2b2 |
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
Paolo Bonzini |
0fb2b2 |
---
|
|
Paolo Bonzini |
0fb2b2 |
hw/scsi/scsi-generic.c | 40 +++++++---------------------------------
|
|
Paolo Bonzini |
0fb2b2 |
include/scsi/utils.h | 3 +++
|
|
Paolo Bonzini |
0fb2b2 |
scsi/utils.c | 35 +++++++++++++++++++++++++++++++++++
|
|
Paolo Bonzini |
0fb2b2 |
3 files changed, 45 insertions(+), 33 deletions(-)
|
|
Paolo Bonzini |
0fb2b2 |
|
|
Paolo Bonzini |
0fb2b2 |
diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c
|
|
Paolo Bonzini |
0fb2b2 |
index 7a8f500934..04c687ee76 100644
|
|
Paolo Bonzini |
0fb2b2 |
--- a/hw/scsi/scsi-generic.c
|
|
Paolo Bonzini |
0fb2b2 |
+++ b/hw/scsi/scsi-generic.c
|
|
Paolo Bonzini |
0fb2b2 |
@@ -81,6 +81,7 @@ static void scsi_free_request(SCSIRequest *req)
|
|
Paolo Bonzini |
0fb2b2 |
static void scsi_command_complete_noio(SCSIGenericReq *r, int ret)
|
|
Paolo Bonzini |
0fb2b2 |
{
|
|
Paolo Bonzini |
0fb2b2 |
int status;
|
|
Paolo Bonzini |
0fb2b2 |
+ SCSISense sense;
|
|
Paolo Bonzini |
0fb2b2 |
|
|
Paolo Bonzini |
0fb2b2 |
assert(r->req.aiocb == NULL);
|
|
Paolo Bonzini |
0fb2b2 |
|
|
Paolo Bonzini |
0fb2b2 |
@@ -88,42 +89,15 @@ static void scsi_command_complete_noio(SCSIGenericReq *r, int ret)
|
|
Paolo Bonzini |
0fb2b2 |
scsi_req_cancel_complete(&r->req);
|
|
Paolo Bonzini |
0fb2b2 |
goto done;
|
|
Paolo Bonzini |
0fb2b2 |
}
|
|
Paolo Bonzini |
0fb2b2 |
- if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
|
|
Paolo Bonzini |
0fb2b2 |
- r->req.sense_len = r->io_header.sb_len_wr;
|
|
Paolo Bonzini |
0fb2b2 |
- }
|
|
Paolo Bonzini |
0fb2b2 |
-
|
|
Paolo Bonzini |
0fb2b2 |
- if (ret != 0) {
|
|
Paolo Bonzini |
0fb2b2 |
- switch (ret) {
|
|
Paolo Bonzini |
0fb2b2 |
- case -EDOM:
|
|
Paolo Bonzini |
0fb2b2 |
- status = TASK_SET_FULL;
|
|
Paolo Bonzini |
0fb2b2 |
- break;
|
|
Paolo Bonzini |
0fb2b2 |
- case -ENOMEM:
|
|
Paolo Bonzini |
0fb2b2 |
- status = CHECK_CONDITION;
|
|
Paolo Bonzini |
0fb2b2 |
- scsi_req_build_sense(&r->req, SENSE_CODE(TARGET_FAILURE));
|
|
Paolo Bonzini |
0fb2b2 |
- break;
|
|
Paolo Bonzini |
0fb2b2 |
- default:
|
|
Paolo Bonzini |
0fb2b2 |
- status = CHECK_CONDITION;
|
|
Paolo Bonzini |
0fb2b2 |
- scsi_req_build_sense(&r->req, SENSE_CODE(IO_ERROR));
|
|
Paolo Bonzini |
0fb2b2 |
- break;
|
|
Paolo Bonzini |
0fb2b2 |
- }
|
|
Paolo Bonzini |
0fb2b2 |
- } else {
|
|
Paolo Bonzini |
0fb2b2 |
- if (r->io_header.host_status == SG_ERR_DID_NO_CONNECT ||
|
|
Paolo Bonzini |
0fb2b2 |
- r->io_header.host_status == SG_ERR_DID_BUS_BUSY ||
|
|
Paolo Bonzini |
0fb2b2 |
- r->io_header.host_status == SG_ERR_DID_TIME_OUT ||
|
|
Paolo Bonzini |
0fb2b2 |
- (r->io_header.driver_status & SG_ERR_DRIVER_TIMEOUT)) {
|
|
Paolo Bonzini |
0fb2b2 |
- status = BUSY;
|
|
Paolo Bonzini |
0fb2b2 |
- BADF("Driver Timeout\n");
|
|
Paolo Bonzini |
0fb2b2 |
- } else if (r->io_header.host_status) {
|
|
Paolo Bonzini |
0fb2b2 |
- status = CHECK_CONDITION;
|
|
Paolo Bonzini |
0fb2b2 |
- scsi_req_build_sense(&r->req, SENSE_CODE(I_T_NEXUS_LOSS));
|
|
Paolo Bonzini |
0fb2b2 |
- } else if (r->io_header.status) {
|
|
Paolo Bonzini |
0fb2b2 |
- status = r->io_header.status;
|
|
Paolo Bonzini |
0fb2b2 |
- } else if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
|
|
Paolo Bonzini |
0fb2b2 |
- status = CHECK_CONDITION;
|
|
Paolo Bonzini |
0fb2b2 |
+ status = sg_io_sense_from_errno(-ret, &r->io_header, &sense);
|
|
Paolo Bonzini |
0fb2b2 |
+ if (status == CHECK_CONDITION) {
|
|
Paolo Bonzini |
0fb2b2 |
+ if (r->io_header.driver_status & SG_ERR_DRIVER_SENSE) {
|
|
Paolo Bonzini |
0fb2b2 |
+ r->req.sense_len = r->io_header.sb_len_wr;
|
|
Paolo Bonzini |
0fb2b2 |
} else {
|
|
Paolo Bonzini |
0fb2b2 |
- status = GOOD;
|
|
Paolo Bonzini |
0fb2b2 |
+ scsi_req_build_sense(&r->req, sense);
|
|
Paolo Bonzini |
0fb2b2 |
}
|
|
Paolo Bonzini |
0fb2b2 |
}
|
|
Paolo Bonzini |
0fb2b2 |
+
|
|
Paolo Bonzini |
0fb2b2 |
DPRINTF("Command complete 0x%p tag=0x%x status=%d\n",
|
|
Paolo Bonzini |
0fb2b2 |
r, r->req.tag, status);
|
|
Paolo Bonzini |
0fb2b2 |
|
|
Paolo Bonzini |
0fb2b2 |
diff --git a/include/scsi/utils.h b/include/scsi/utils.h
|
|
Paolo Bonzini |
0fb2b2 |
index b49392d841..d301b31768 100644
|
|
Paolo Bonzini |
0fb2b2 |
--- a/include/scsi/utils.h
|
|
Paolo Bonzini |
0fb2b2 |
+++ b/include/scsi/utils.h
|
|
Paolo Bonzini |
0fb2b2 |
@@ -116,6 +116,9 @@ int scsi_cdb_length(uint8_t *buf);
|
|
Paolo Bonzini |
0fb2b2 |
#define SG_ERR_DID_TIME_OUT 0x03
|
|
Paolo Bonzini |
0fb2b2 |
|
|
Paolo Bonzini |
0fb2b2 |
#define SG_ERR_DRIVER_SENSE 0x08
|
|
Paolo Bonzini |
0fb2b2 |
+
|
|
Paolo Bonzini |
0fb2b2 |
+int sg_io_sense_from_errno(int errno_value, struct sg_io_hdr *io_hdr,
|
|
Paolo Bonzini |
0fb2b2 |
+ SCSISense *sense);
|
|
Paolo Bonzini |
0fb2b2 |
#endif
|
|
Paolo Bonzini |
0fb2b2 |
|
|
Paolo Bonzini |
0fb2b2 |
#endif
|
|
Paolo Bonzini |
0fb2b2 |
diff --git a/scsi/utils.c b/scsi/utils.c
|
|
Paolo Bonzini |
0fb2b2 |
index 89d9167d9d..6ee9f4095b 100644
|
|
Paolo Bonzini |
0fb2b2 |
--- a/scsi/utils.c
|
|
Paolo Bonzini |
0fb2b2 |
+++ b/scsi/utils.c
|
|
Paolo Bonzini |
0fb2b2 |
@@ -501,3 +501,38 @@ const char *scsi_command_name(uint8_t cmd)
|
|
Paolo Bonzini |
0fb2b2 |
}
|
|
Paolo Bonzini |
0fb2b2 |
return names[cmd];
|
|
Paolo Bonzini |
0fb2b2 |
}
|
|
Paolo Bonzini |
0fb2b2 |
+
|
|
Paolo Bonzini |
0fb2b2 |
+#ifdef CONFIG_LINUX
|
|
Paolo Bonzini |
0fb2b2 |
+int sg_io_sense_from_errno(int errno_value, struct sg_io_hdr *io_hdr,
|
|
Paolo Bonzini |
0fb2b2 |
+ SCSISense *sense)
|
|
Paolo Bonzini |
0fb2b2 |
+{
|
|
Paolo Bonzini |
0fb2b2 |
+ if (errno_value != 0) {
|
|
Paolo Bonzini |
0fb2b2 |
+ switch (errno_value) {
|
|
Paolo Bonzini |
0fb2b2 |
+ case EDOM:
|
|
Paolo Bonzini |
0fb2b2 |
+ return TASK_SET_FULL;
|
|
Paolo Bonzini |
0fb2b2 |
+ case ENOMEM:
|
|
Paolo Bonzini |
0fb2b2 |
+ *sense = SENSE_CODE(TARGET_FAILURE);
|
|
Paolo Bonzini |
0fb2b2 |
+ return CHECK_CONDITION;
|
|
Paolo Bonzini |
0fb2b2 |
+ default:
|
|
Paolo Bonzini |
0fb2b2 |
+ *sense = SENSE_CODE(IO_ERROR);
|
|
Paolo Bonzini |
0fb2b2 |
+ return CHECK_CONDITION;
|
|
Paolo Bonzini |
0fb2b2 |
+ }
|
|
Paolo Bonzini |
0fb2b2 |
+ } else {
|
|
Paolo Bonzini |
0fb2b2 |
+ if (io_hdr->host_status == SG_ERR_DID_NO_CONNECT ||
|
|
Paolo Bonzini |
0fb2b2 |
+ io_hdr->host_status == SG_ERR_DID_BUS_BUSY ||
|
|
Paolo Bonzini |
0fb2b2 |
+ io_hdr->host_status == SG_ERR_DID_TIME_OUT ||
|
|
Paolo Bonzini |
0fb2b2 |
+ (io_hdr->driver_status & SG_ERR_DRIVER_TIMEOUT)) {
|
|
Paolo Bonzini |
0fb2b2 |
+ return BUSY;
|
|
Paolo Bonzini |
0fb2b2 |
+ } else if (io_hdr->host_status) {
|
|
Paolo Bonzini |
0fb2b2 |
+ *sense = SENSE_CODE(I_T_NEXUS_LOSS);
|
|
Paolo Bonzini |
0fb2b2 |
+ return CHECK_CONDITION;
|
|
Paolo Bonzini |
0fb2b2 |
+ } else if (io_hdr->status) {
|
|
Paolo Bonzini |
0fb2b2 |
+ return io_hdr->status;
|
|
Paolo Bonzini |
0fb2b2 |
+ } else if (io_hdr->driver_status & SG_ERR_DRIVER_SENSE) {
|
|
Paolo Bonzini |
0fb2b2 |
+ return CHECK_CONDITION;
|
|
Paolo Bonzini |
0fb2b2 |
+ } else {
|
|
Paolo Bonzini |
0fb2b2 |
+ return GOOD;
|
|
Paolo Bonzini |
0fb2b2 |
+ }
|
|
Paolo Bonzini |
0fb2b2 |
+ }
|
|
Paolo Bonzini |
0fb2b2 |
+}
|
|
Paolo Bonzini |
0fb2b2 |
+#endif
|
|
Paolo Bonzini |
0fb2b2 |
--
|
|
Paolo Bonzini |
0fb2b2 |
2.13.5
|
|
Paolo Bonzini |
0fb2b2 |
|