From nobody Sun Feb 8 14:52:47 2026 Delivered-To: importer@patchew.org Authentication-Results: mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org ARC-Seal: i=1; a=rsa-sha256; t=1605553291; cv=none; d=zohomail.com; s=zohoarc; b=LeSIf5Hh0Y+FwFmK6vqP/w0Rt+uhDYUfLJJKTg57WIkbKJnSRu+Tsl8jGi82FX609EPSUzU6ioYYOH3ONTQD/HDdiq1Zt7N7sHTD5EdB6w2t+6BmF/Ys9xXD4ROYtzRS15VghIHvURhwwWpBOtVXu7eHeaDjblZDnmvFO6omieU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1605553291; h=Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:Message-ID:References:Sender:Subject:To; bh=2u2mbUDRF44lEdP6HW9FVLA625HTxsMsSduZlLaQEsI=; b=TUnlRLZzKcZ2j4TDoj2quy2Ay1OjJl376HG1w/PYaS0LFk/ILXT+tFp8HmMphMy06J5CsclMJ6FdKsWhzNqWvYbCn9horwFX714TNtYQ8Pu5nqqNcOY1mMJzi6t3G4YHRjNv8vMNJ2DGf6EVn6MoU2EX4PdOV4mTdg6Gwq6EHYQ= ARC-Authentication-Results: i=1; mx.zohomail.com; spf=pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1605553291093524.5025537044271; Mon, 16 Nov 2020 11:01:31 -0800 (PST) Received: from localhost ([::1]:45664 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kejkn-0004fJ-EK for importer@patchew.org; Mon, 16 Nov 2020 14:01:29 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:39944) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kejR3-000426-Ur for qemu-devel@nongnu.org; Mon, 16 Nov 2020 13:41:05 -0500 Received: from mx2.suse.de ([195.135.220.15]:45376) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kejQu-0000qc-V5 for qemu-devel@nongnu.org; Mon, 16 Nov 2020 13:41:05 -0500 Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id 6BA07B019; Mon, 16 Nov 2020 18:40:49 +0000 (UTC) X-Virus-Scanned: by amavisd-new at test-mx.suse.de From: Hannes Reinecke To: Paolo Bonzini Subject: [PATCH 7/7] scsi: move host_status handling into SCSI drivers Date: Mon, 16 Nov 2020 19:40:41 +0100 Message-Id: <20201116184041.60465-8-hare@suse.de> X-Mailer: git-send-email 2.16.4 In-Reply-To: <20201116184041.60465-1-hare@suse.de> References: <20201116184041.60465-1-hare@suse.de> Received-SPF: pass (zohomail.com: domain of gnu.org designates 209.51.188.17 as permitted sender) client-ip=209.51.188.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Received-SPF: pass client-ip=195.135.220.15; envelope-from=hare@suse.de; helo=mx2.suse.de X-detected-operating-system: by eggs.gnu.org: First seen = 2020/11/16 12:53:11 X-ACL-Warn: Detected OS = Linux 2.2.x-3.x (no timestamps) [generic] X-Spam_score_int: -41 X-Spam_score: -4.2 X-Spam_bar: ---- X-Spam_report: (-4.2 / 5.0 requ) BAYES_00=-1.9, RCVD_IN_DNSWL_MED=-2.3, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: qemu-devel@nongnu.org, Hannes Reinecke Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Some SCSI drivers like virtio have an internal mapping for the host_status. This patch moves the host_status translation into the SCSI drivers to allow those drivers to set up the correct values. Signed-off-by: Hannes Reinecke --- hw/scsi/esp.c | 10 ++++++++++ hw/scsi/lsi53c895a.c | 11 +++++++++++ hw/scsi/megasas.c | 9 +++++++++ hw/scsi/mptsas.c | 9 +++++++++ hw/scsi/scsi-disk.c | 10 ++++------ hw/scsi/scsi-generic.c | 8 +++----- hw/scsi/spapr_vscsi.c | 12 +++++++++++- hw/scsi/virtio-scsi.c | 41 +++++++++++++++++++++++++++++++++++++++-- hw/scsi/vmw_pvscsi.c | 25 +++++++++++++++++++++++++ include/hw/scsi/scsi.h | 3 ++- 10 files changed, 123 insertions(+), 15 deletions(-) diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c index 93d9c9c7b9..fc88cfac23 100644 --- a/hw/scsi/esp.c +++ b/hw/scsi/esp.c @@ -28,6 +28,8 @@ #include "migration/vmstate.h" #include "hw/irq.h" #include "hw/scsi/esp.h" +#include "scsi/utils.h" +#include "scsi/constants.h" #include "trace.h" #include "qemu/log.h" #include "qemu/module.h" @@ -489,6 +491,14 @@ void esp_command_complete(SCSIRequest *req, size_t res= id) { ESPState *s =3D req->hba_private; =20 + if (req->host_status !=3D SCSI_HOST_OK) { + SCSISense sense; + + req->status =3D scsi_sense_from_host_status(req->host_status, &sen= se); + if (req->status =3D=3D CHECK_CONDITION) { + scsi_req_build_sense(req, sense); + } + } if (s->rregs[ESP_RSTAT] & STAT_INT) { /* Defer handling command complete until the previous * interrupt has been handled. diff --git a/hw/scsi/lsi53c895a.c b/hw/scsi/lsi53c895a.c index a4e58580e4..b6aa98c95a 100644 --- a/hw/scsi/lsi53c895a.c +++ b/hw/scsi/lsi53c895a.c @@ -18,6 +18,8 @@ #include "hw/irq.h" #include "hw/pci/pci.h" #include "hw/scsi/scsi.h" +#include "scsi/utils.h" +#include "scsi/constants.h" #include "migration/vmstate.h" #include "sysemu/dma.h" #include "qemu/log.h" @@ -792,6 +794,15 @@ static void lsi_command_complete(SCSIRequest *req, siz= e_t resid) LSIState *s =3D LSI53C895A(req->bus->qbus.parent); int out; =20 + if (req->host_status !=3D SCSI_HOST_OK) { + SCSISense sense; + + req->status =3D scsi_sense_from_host_status(req->host_status, &sen= se); + if (req->status =3D=3D CHECK_CONDITION) { + scsi_req_build_sense(req, sense); + } + } + out =3D (s->sstat1 & PHASE_MASK) =3D=3D PHASE_DO; trace_lsi_command_complete(req->status); s->status =3D req->status; diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c index 35867dbd40..1f7d806ffa 100644 --- a/hw/scsi/megasas.c +++ b/hw/scsi/megasas.c @@ -1857,6 +1857,15 @@ static void megasas_command_complete(SCSIRequest *re= q, size_t resid) MegasasCmd *cmd =3D req->hba_private; uint8_t cmd_status =3D MFI_STAT_OK; =20 + if (req->host_status !=3D SCSI_HOST_OK) { + SCSISense sense; + + req->status =3D scsi_sense_from_host_status(req->host_status, &sen= se); + if (req->status =3D=3D CHECK_CONDITION) { + scsi_req_build_sense(req, sense); + } + } + trace_megasas_command_complete(cmd->index, req->status, resid); =20 if (req->io_canceled) { diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c index d4fbfb2da7..be3875ce94 100644 --- a/hw/scsi/mptsas.c +++ b/hw/scsi/mptsas.c @@ -1143,6 +1143,15 @@ static void mptsas_command_complete(SCSIRequest *sre= q, hwaddr sense_buffer_addr =3D req->dev->sense_buffer_high_addr | req->scsi_io.SenseBufferLowAddr; =20 + if (sreq->host_status =3D=3D SCSI_HOST_OK) { + SCSISense sense; + + sreq->status =3D scsi_sense_from_host_status(sreq->host_status, &s= ense); + if (sreq->status =3D=3D CHECK_CONDITION) { + scsi_req_build_sense(sreq, sense); + } + } + trace_mptsas_command_complete(s, req->scsi_io.MsgContext, sreq->status, resid); =20 diff --git a/hw/scsi/scsi-disk.c b/hw/scsi/scsi-disk.c index 6eb0aa3d27..c0cb63707d 100644 --- a/hw/scsi/scsi-disk.c +++ b/hw/scsi/scsi-disk.c @@ -1840,7 +1840,7 @@ static void scsi_disk_emulate_write_data(SCSIRequest = *req) case VERIFY_10: case VERIFY_12: case VERIFY_16: - if (r->req.status =3D=3D -1) { + if (r->req.status =3D=3D GOOD) { scsi_check_condition(r, SENSE_CODE(INVALID_FIELD)); } break; @@ -2122,7 +2122,7 @@ static int32_t scsi_disk_emulate_command(SCSIRequest = *req, uint8_t *buf) } =20 illegal_request: - if (r->req.status =3D=3D -1) { + if (r->req.status =3D=3D GOOD) { scsi_check_condition(r, SENSE_CODE(INVALID_FIELD)); } return 0; @@ -2697,10 +2697,8 @@ static void scsi_block_sgio_complete(void *opaque, i= nt ret) scsi_req_build_sense(&r->req, sense); } else if (status =3D=3D GOOD && io_hdr.host_status !=3D SCSI_HOST_OK) { - status =3D scsi_sense_from_host_status(io_hdr.host_status, &sense); - if (status =3D=3D CHECK_CONDITION) { - scsi_req_build_sense(&r->req, sense); - } + status =3D INTERMEDIATE_GOOD; + r->req.host_status =3D io_hdr.host_status; } else if (io_hdr.status =3D=3D CHECK_CONDITION || io_hdr.driver_status & SG_ERR_DRIVER_SENSE) { status =3D CHECK_CONDITION; diff --git a/hw/scsi/scsi-generic.c b/hw/scsi/scsi-generic.c index a2b85678b5..eac108fc6e 100644 --- a/hw/scsi/scsi-generic.c +++ b/hw/scsi/scsi-generic.c @@ -86,11 +86,9 @@ static void scsi_command_complete_noio(SCSIGenericReq *r= , int ret) if (status =3D=3D CHECK_CONDITION) { scsi_req_build_sense(&r->req, sense); } else if (status =3D=3D GOOD && - io_hdr.host_status !=3D SCSI_HOST_OK) { - status =3D scsi_sense_from_host_status(io_hdr.host_status, &sense); - if (status =3D=3D CHECK_CONDITION) { - scsi_req_build_sense(&r->req, sense); - } + io_hdr.host_status !=3D SCSI_HOST_OK) { + status =3D INTERMEDIATE_GOOD; + r->req.host_status =3D io_hdr.host_status; } else if (io_hdr.status =3D=3D CHECK_CONDITION || io_hdr.driver_status & SG_ERR_DRIVER_SENSE) { status =3D CHECK_CONDITION; diff --git a/hw/scsi/spapr_vscsi.c b/hw/scsi/spapr_vscsi.c index d653b5a6ad..9327a493c3 100644 --- a/hw/scsi/spapr_vscsi.c +++ b/hw/scsi/spapr_vscsi.c @@ -556,6 +556,16 @@ static void vscsi_command_complete(SCSIRequest *sreq, = size_t resid) VSCSIState *s =3D VIO_SPAPR_VSCSI_DEVICE(sreq->bus->qbus.parent); vscsi_req *req =3D sreq->hba_private; int32_t res_in =3D 0, res_out =3D 0; + uint8_t status =3D sreq->status; + + if (sreq->host_status !=3D SCSI_HOST_OK) { + SCSISense sense; + + sreq->status =3D scsi_sense_from_host_status(sreq->host_status, &s= ense); + if (sreq->status =3D=3D CHECK_CONDITION) { + scsi_req_build_sense(sreq, sense); + } + } =20 trace_spapr_vscsi_command_complete(sreq->tag, sreq->status, req); if (req =3D=3D NULL) { @@ -575,7 +585,7 @@ static void vscsi_command_complete(SCSIRequest *sreq, s= ize_t resid) } =20 trace_spapr_vscsi_command_complete_status(sreq->status); - if (sreq->status =3D=3D 0) { + if (sreq->status =3D=3D GOOD) { /* We handle overflows, not underflows for normal commands, * but hopefully nobody cares */ diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c index 64cd852d82..62c56713d8 100644 --- a/hw/scsi/virtio-scsi.c +++ b/hw/scsi/virtio-scsi.c @@ -504,8 +504,45 @@ static void virtio_scsi_command_complete(SCSIRequest *= r, size_t resid) return; } =20 - req->resp.cmd.response =3D VIRTIO_SCSI_S_OK; - req->resp.cmd.status =3D r->status; + if (r->host_status !=3D SCSI_HOST_OK) { + req->resp.cmd.status =3D GOOD; + switch (r->host_status) { + case SCSI_HOST_NO_LUN: + req->resp.cmd.response =3D VIRTIO_SCSI_S_INCORRECT_LUN; + break; + case SCSI_HOST_BUSY: + req->resp.cmd.response =3D VIRTIO_SCSI_S_BUSY; + break; + case SCSI_HOST_TIME_OUT: + case SCSI_HOST_ABORTED: + req->resp.cmd.response =3D VIRTIO_SCSI_S_ABORTED; + break; + case SCSI_HOST_BAD_RESPONSE: + req->resp.cmd.response =3D VIRTIO_SCSI_S_BAD_TARGET; + break; + case SCSI_HOST_RESET: + req->resp.cmd.response =3D VIRTIO_SCSI_S_RESET; + break; + case SCSI_HOST_TRANSPORT_DISRUPTED: + req->resp.cmd.response =3D VIRTIO_SCSI_S_TRANSPORT_FAILURE; + break; + case SCSI_HOST_TARGET_FAILURE: + req->resp.cmd.response =3D VIRTIO_SCSI_S_TARGET_FAILURE; + break; + case SCSI_HOST_RESERVATION_ERROR: + req->resp.cmd.response =3D VIRTIO_SCSI_S_NEXUS_FAILURE; + break; + case SCSI_HOST_ALLOCATION_FAILURE: + case SCSI_HOST_MEDIUM_ERROR: + case SCSI_HOST_ERROR: + default: + req->resp.cmd.response =3D VIRTIO_SCSI_S_FAILURE; + break; + } + } else { + req->resp.cmd.response =3D VIRTIO_SCSI_S_OK; + req->resp.cmd.status =3D r->status; + } if (req->resp.cmd.status =3D=3D GOOD) { req->resp.cmd.resid =3D virtio_tswap32(vdev, resid); } else { diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c index 0da378ed50..2583105dfd 100644 --- a/hw/scsi/vmw_pvscsi.c +++ b/hw/scsi/vmw_pvscsi.c @@ -522,6 +522,31 @@ pvscsi_command_complete(SCSIRequest *req, size_t resid) } s =3D pvscsi_req->dev; =20 + if (req->host_status !=3D SCSI_HOST_OK) { + switch (req->host_status) { + case SCSI_HOST_NO_LUN: + pvscsi_req->cmp.hostStatus =3D BTSTAT_LUNMISMATCH; + break; + case SCSI_HOST_BUSY: + pvscsi_req->cmp.hostStatus =3D BTSTAT_ABORTQUEUE; + break; + case SCSI_HOST_TIME_OUT: + case SCSI_HOST_ABORTED: + pvscsi_req->cmp.hostStatus =3D BTSTAT_SENTRST; + break; + case SCSI_HOST_BAD_RESPONSE: + pvscsi_req->cmp.hostStatus =3D BTSTAT_SELTIMEO; + break; + case SCSI_HOST_RESET: + pvscsi_req->cmp.hostStatus =3D BTSTAT_BUSRESET; + break; + default: + pvscsi_req->cmp.hostStatus =3D BTSTAT_HASOFTWARE; + break; + } + req->status =3D GOOD; + } + if (resid) { /* Short transfer. */ trace_pvscsi_command_complete_data_run(); diff --git a/include/hw/scsi/scsi.h b/include/hw/scsi/scsi.h index 23a9b23e50..a097fecb2a 100644 --- a/include/hw/scsi/scsi.h +++ b/include/hw/scsi/scsi.h @@ -27,7 +27,8 @@ struct SCSIRequest { uint32_t refcount; uint32_t tag; uint32_t lun; - uint32_t status; + uint8_t status; + uint8_t host_status; void *hba_private; size_t resid; SCSICommand cmd; --=20 2.16.4