From nobody Wed Nov 12 20:48:19 2025 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=1573475733; cv=none; d=zoho.com; s=zohoarc; b=FyYqri1PH9BB5HqNw1bSlIT/fB5mqkCK6mS+Qkpuf0+4Fn0a4YOjr97aYJLod1zmcvXvtR7ytfrVyUQWTMGljQSlM+K9LKl092QFijD9iItv4mjihATOXzjT67Rrh5xvvmyZOONAUCcIawVnIF8OZExlSIFa+UiYqXzRQ7XpNCk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1573475733; 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=bWGMeu7CxwbfffyRYxFQaHznx0rJwJ4+hZkoXgqCprk=; b=letWbZ/EHREnojW5zEKF4Tpt26I3jXqKnWnZtCENRl6b4jovw3p4zYy6ARFwdzonn8XL4YP45U+knxfW0pKf7q+0WZ60IkcrSnpsnKBMc0aqJ2olMzgM/M80yf7zHQPru4dKgNo/5B1Id1LlbEj9YPllragazfVuzEWaP5FYjUA= 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 1573475733511114.55646141610771; Mon, 11 Nov 2019 04:35:33 -0800 (PST) Received: from localhost ([::1]:51872 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iU8up-0001JA-UC for importer@patchew.org; Mon, 11 Nov 2019 07:35:31 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:37119) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1iU8m3-0008Cy-EN for qemu-devel@nongnu.org; Mon, 11 Nov 2019 07:26:29 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1iU8m1-0003YH-4l for qemu-devel@nongnu.org; Mon, 11 Nov 2019 07:26:27 -0500 Received: from charlie.dont.surf ([128.199.63.193]:52214) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1iU8lx-0003Oi-Qt; Mon, 11 Nov 2019 07:26:22 -0500 Received: from apples.localdomain (unknown [194.62.217.57]) by charlie.dont.surf (Postfix) with ESMTPSA id BB086BFAF3; Mon, 11 Nov 2019 12:26:00 +0000 (UTC) From: Klaus Jensen To: qemu-block@nongnu.org Subject: [PATCH v3 11/21] nvme: add missing mandatory features Date: Mon, 11 Nov 2019 13:25:35 +0100 Message-Id: <20191111122545.252478-12-its@irrelevant.dk> X-Mailer: git-send-email 2.24.0 In-Reply-To: <20191111122545.252478-1-its@irrelevant.dk> References: <20191111122545.252478-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 , Javier Gonzalez , qemu-devel@nongnu.org, Max Reitz , Ross Lagerwall , Paul Durrant , Keith Busch , 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 47f7c5cfcff9..5c3dc49416ec 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -1006,12 +1006,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"); @@ -1023,6 +1035,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; @@ -1058,6 +1083,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; @@ -1085,6 +1112,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; @@ -1708,6 +1742,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 @@ -1785,15 +1827,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); @@ -1865,6 +1909,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 ded2ade1b462..6940b71e0e3e 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.24.0