From nobody Mon Feb 9 22:20:11 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.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; Authentication-Results: mx.zohomail.com; spf=pass (zoho.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=1571136918; cv=none; d=zoho.com; s=zohoarc; b=HdyfNTUd8legF7vef6D+iFrIjEOk7xbnOdtauLaUP8qNk3rWlVtRbad8RP7CLO6+xH3ad3YdCjBbh2kIMPt3eerTXaolFNvPXf08HozyHBCB+ghOJuDP2TEcb/9Dbps7B3t3EuyUILxBWi0fpWqswGxnk0U4c6n0uxsBOg5yW9g= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1571136918; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To; bh=Q7Mmf2MqLKlIIXI7nBJojhvXFLk46GUv0qfyJW18AJI=; b=JsrzTrGheAXR8dQZqpXTij+Vj8ictfk1LeiX3yL7sf3YikqDvLgN4dpEyDhHXSDKGpfbX7Cd7ND7d7s9+wIb50YuGOU45Y7Hf5Jo8pM2uGFf+oTZGZk2aUAf6zXupHgrOG14JweozfzL3MRtVeuMgwJyubGawkqLFfQRg4RAYOc= ARC-Authentication-Results: i=1; mx.zoho.com; spf=pass (zoho.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 1571136918747494.53570888597267; Tue, 15 Oct 2019 03:55:18 -0700 (PDT) Received: from localhost ([::1]:40706 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iKKU1-0000CL-Gp for importer@patchew.org; Tue, 15 Oct 2019 06:55:17 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:48099) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iKKF0-0007tO-9k for qemu-devel@nongnu.org; Tue, 15 Oct 2019 06:39:47 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iKKEy-0006dd-Au for qemu-devel@nongnu.org; Tue, 15 Oct 2019 06:39:46 -0400 Received: from charlie.dont.surf ([128.199.63.193]:54852) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iKKEs-0006Dk-0z; Tue, 15 Oct 2019 06:39:38 -0400 Received: from apples.localdomain (unknown [194.62.217.57]) by charlie.dont.surf (Postfix) with ESMTPSA id 73DD0BF925; Tue, 15 Oct 2019 10:39:16 +0000 (UTC) From: Klaus Jensen To: qemu-block@nongnu.org Subject: [PATCH v2 11/20] nvme: add missing mandatory features Date: Tue, 15 Oct 2019 12:38:51 +0200 Message-Id: <20191015103900.313928-12-its@irrelevant.dk> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20191015103900.313928-1-its@irrelevant.dk> References: <20191015103900.313928-1-its@irrelevant.dk> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 128.199.63.193 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: Kevin Wolf , Fam Zheng , Javier Gonzalez , qemu-devel@nongnu.org, Max Reitz , Keith Busch , Paul Durrant , Stephen Bates Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" Add support for returning a resonable response to Get/Set Features of mandatory features. Signed-off-by: Klaus Jensen --- hw/block/nvme.c | 51 ++++++++++++++++++++++++++++++++++++++++--- hw/block/trace-events | 2 ++ include/block/nvme.h | 3 ++- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/hw/block/nvme.c b/hw/block/nvme.c index 32381d7df655..e7d46dcc6afe 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -1007,12 +1007,24 @@ static uint16_t nvme_get_feature_timestamp(NvmeCtrl= *n, NvmeCmd *cmd) static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *r= eq) { uint32_t dw10 =3D le32_to_cpu(cmd->cdw10); + uint32_t dw11 =3D le32_to_cpu(cmd->cdw11); uint32_t result; =20 + trace_nvme_getfeat(dw10); + switch (dw10) { + case NVME_ARBITRATION: + result =3D cpu_to_le32(n->features.arbitration); + break; + case NVME_POWER_MANAGEMENT: + result =3D cpu_to_le32(n->features.power_mgmt); + break; case NVME_TEMPERATURE_THRESHOLD: result =3D cpu_to_le32(n->features.temp_thresh); break; + case NVME_ERROR_RECOVERY: + result =3D cpu_to_le32(n->features.err_rec); + break; case NVME_VOLATILE_WRITE_CACHE: result =3D blk_enable_write_cache(n->conf.blk); trace_nvme_getfeat_vwcache(result ? "enabled" : "disabled"); @@ -1024,6 +1036,19 @@ static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeCm= d *cmd, NvmeRequest *req) break; case NVME_TIMESTAMP: return nvme_get_feature_timestamp(n, cmd); + case NVME_INTERRUPT_COALESCING: + result =3D cpu_to_le32(n->features.int_coalescing); + break; + case NVME_INTERRUPT_VECTOR_CONF: + if ((dw11 & 0xffff) > n->params.num_queues) { + return NVME_INVALID_FIELD | NVME_DNR; + } + + result =3D cpu_to_le32(n->features.int_vector_config[dw11 & 0xffff= ]); + break; + case NVME_WRITE_ATOMICITY: + result =3D cpu_to_le32(n->features.write_atomicity); + break; case NVME_ASYNCHRONOUS_EVENT_CONF: result =3D cpu_to_le32(n->features.async_config); break; @@ -1059,6 +1084,8 @@ static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeCmd= *cmd, NvmeRequest *req) uint32_t dw10 =3D le32_to_cpu(cmd->cdw10); uint32_t dw11 =3D le32_to_cpu(cmd->cdw11); =20 + trace_nvme_setfeat(dw10, dw11); + switch (dw10) { case NVME_TEMPERATURE_THRESHOLD: n->features.temp_thresh =3D dw11; @@ -1086,6 +1113,13 @@ static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeCm= d *cmd, NvmeRequest *req) case NVME_ASYNCHRONOUS_EVENT_CONF: n->features.async_config =3D dw11; break; + case NVME_ARBITRATION: + case NVME_POWER_MANAGEMENT: + case NVME_ERROR_RECOVERY: + case NVME_INTERRUPT_COALESCING: + case NVME_INTERRUPT_VECTOR_CONF: + case NVME_WRITE_ATOMICITY: + return NVME_FEAT_NOT_CHANGABLE | NVME_DNR; default: trace_nvme_err_invalid_setfeat(dw10); return NVME_INVALID_FIELD | NVME_DNR; @@ -1709,6 +1743,14 @@ static void nvme_init_state(NvmeCtrl *n) n->starttime_ms =3D qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); n->temperature =3D NVME_TEMPERATURE; n->features.temp_thresh =3D 0x14d; + n->features.int_vector_config =3D g_malloc0_n(n->params.num_queues, + sizeof(*n->features.int_vector_config)); + + /* disable coalescing (not supported) */ + for (int i =3D 0; i < n->params.num_queues; i++) { + n->features.int_vector_config[i] =3D i | (1 << 16); + } + n->aer_reqs =3D g_new0(NvmeRequest *, n->params.aerl + 1); } =20 @@ -1786,15 +1828,17 @@ static void nvme_init_ctrl(NvmeCtrl *n) id->nn =3D cpu_to_le32(n->num_namespaces); id->oncs =3D cpu_to_le16(NVME_ONCS_WRITE_ZEROS | NVME_ONCS_TIMESTAMP); =20 + + if (blk_enable_write_cache(n->conf.blk)) { + id->vwc =3D 1; + } + strcpy((char *) id->subnqn, "nqn.2019-08.org.qemu:"); pstrcat((char *) id->subnqn, sizeof(id->subnqn), n->params.serial); =20 id->psd[0].mp =3D cpu_to_le16(0x9c4); id->psd[0].enlat =3D cpu_to_le32(0x10); id->psd[0].exlat =3D cpu_to_le32(0x4); - if (blk_enable_write_cache(n->conf.blk)) { - id->vwc =3D 1; - } =20 n->bar.cap =3D 0; NVME_CAP_SET_MQES(n->bar.cap, 0x7ff); @@ -1866,6 +1910,7 @@ static void nvme_exit(PCIDevice *pci_dev) g_free(n->sq); g_free(n->elpes); g_free(n->aer_reqs); + g_free(n->features.int_vector_config); =20 if (n->params.cmb_size_mb) { g_free(n->cmbuf); diff --git a/hw/block/trace-events b/hw/block/trace-events index 6ddb13d34061..a20a68d85d5a 100644 --- a/hw/block/trace-events +++ b/hw/block/trace-events @@ -41,6 +41,8 @@ nvme_del_cq(uint16_t cqid) "deleted completion queue, sqi= d=3D%"PRIu16"" nvme_identify_ctrl(void) "identify controller" nvme_identify_ns(uint16_t ns) "identify namespace, nsid=3D%"PRIu16"" nvme_identify_nslist(uint16_t ns) "identify namespace list, nsid=3D%"PRIu1= 6"" +nvme_getfeat(uint32_t fid) "fid 0x%"PRIx32"" +nvme_setfeat(uint32_t fid, uint32_t val) "fid 0x%"PRIx32" val 0x%"PRIx32"" nvme_getfeat_vwcache(const char* result) "get feature volatile write cache= , result=3D%s" nvme_getfeat_numq(int result) "get feature number of queues, result=3D%d" nvme_setfeat_numq(int reqcq, int reqsq, int gotcq, int gotsq) "requested c= q_count=3D%d sq_count=3D%d, responding with cq_count=3D%d sq_count=3D%d" diff --git a/include/block/nvme.h b/include/block/nvme.h index 7f1832d531f0..9726839f75bb 100644 --- a/include/block/nvme.h +++ b/include/block/nvme.h @@ -445,7 +445,8 @@ enum NvmeStatusCodes { NVME_FW_REQ_RESET =3D 0x010b, NVME_INVALID_QUEUE_DEL =3D 0x010c, NVME_FID_NOT_SAVEABLE =3D 0x010d, - NVME_FID_NOT_NSID_SPEC =3D 0x010f, + NVME_FEAT_NOT_CHANGABLE =3D 0x010e, + NVME_FEAT_NOT_NSID_SPEC =3D 0x010f, NVME_FW_REQ_SUSYSTEM_RESET =3D 0x0110, NVME_CONFLICTING_ATTRS =3D 0x0180, NVME_INVALID_PROT_INFO =3D 0x0181, --=20 2.23.0