From patchwork Mon Mar 16 14:28:57 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Klaus Jensen X-Patchwork-Id: 11440849 Return-Path: Received: from mail.kernel.org (pdx-korg-mail-1.web.codeaurora.org [172.30.200.123]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id A8BC6139A for ; Mon, 16 Mar 2020 16:58:47 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 88B9A20679 for ; Mon, 16 Mar 2020 16:58:47 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 88B9A20679 Authentication-Results: mail.kernel.org; dmarc=none (p=none dis=none) header.from=irrelevant.dk Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Received: from localhost ([::1]:42938 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jDt4g-0000sE-LU for patchwork-qemu-devel@patchwork.kernel.org; Mon, 16 Mar 2020 12:58:46 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:53408) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1jDqkq-00009H-3A for qemu-devel@nongnu.org; Mon, 16 Mar 2020 10:30:10 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1jDqko-0002EA-CK for qemu-devel@nongnu.org; Mon, 16 Mar 2020 10:30:07 -0400 Received: from charlie.dont.surf ([128.199.63.193]:48540) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1jDqkk-0007Wn-Dy; Mon, 16 Mar 2020 10:30:02 -0400 Received: from apples.local (80-62-117-52-mobile.dk.customer.tdc.net [80.62.117.52]) by charlie.dont.surf (Postfix) with ESMTPSA id 03608BF7B4; Mon, 16 Mar 2020 14:29:40 +0000 (UTC) From: Klaus Jensen To: qemu-block@nongnu.org Subject: [PATCH v6 11/42] nvme: add temperature threshold feature Date: Mon, 16 Mar 2020 07:28:57 -0700 Message-Id: <20200316142928.153431-12-its@irrelevant.dk> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200316142928.153431-1-its@irrelevant.dk> References: <20200316142928.153431-1-its@irrelevant.dk> MIME-Version: 1.0 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 , Beata Michalska , qemu-devel@nongnu.org, Max Reitz , Klaus Jensen , Keith Busch , Javier Gonzalez , Maxim Levitsky Errors-To: qemu-devel-bounces+patchwork-qemu-devel=patchwork.kernel.org@nongnu.org Sender: "Qemu-devel" From: Klaus Jensen It might seem wierd to implement this feature for an emulated device, but it is mandatory to support and the feature is useful for testing asynchronous event request support, which will be added in a later patch. Signed-off-by: Klaus Jensen Acked-by: Keith Busch Reviewed-by: Maxim Levitsky --- hw/block/nvme.c | 48 ++++++++++++++++++++++++++++++++++++++++++++ hw/block/nvme.h | 2 ++ include/block/nvme.h | 8 +++++++- 3 files changed, 57 insertions(+), 1 deletion(-) diff --git a/hw/block/nvme.c b/hw/block/nvme.c index 665485045066..64c42101df5c 100644 --- a/hw/block/nvme.c +++ b/hw/block/nvme.c @@ -45,6 +45,9 @@ #include "nvme.h" #define NVME_CMB_BIR 2 +#define NVME_TEMPERATURE 0x143 +#define NVME_TEMPERATURE_WARNING 0x157 +#define NVME_TEMPERATURE_CRITICAL 0x175 #define NVME_GUEST_ERR(trace, fmt, ...) \ do { \ @@ -798,9 +801,31 @@ static uint16_t nvme_get_feature_timestamp(NvmeCtrl *n, NvmeCmd *cmd) static uint16_t nvme_get_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req) { uint32_t dw10 = le32_to_cpu(cmd->cdw10); + uint32_t dw11 = le32_to_cpu(cmd->cdw11); uint32_t result; switch (dw10) { + case NVME_TEMPERATURE_THRESHOLD: + result = 0; + + /* + * The controller only implements the Composite Temperature sensor, so + * return 0 for all other sensors. + */ + if (NVME_TEMP_TMPSEL(dw11)) { + break; + } + + switch (NVME_TEMP_THSEL(dw11)) { + case 0x0: + result = cpu_to_le16(n->features.temp_thresh_hi); + break; + case 0x1: + result = cpu_to_le16(n->features.temp_thresh_low); + break; + } + + break; case NVME_VOLATILE_WRITE_CACHE: result = blk_enable_write_cache(n->conf.blk); trace_nvme_dev_getfeat_vwcache(result ? "enabled" : "disabled"); @@ -845,6 +870,23 @@ static uint16_t nvme_set_feature(NvmeCtrl *n, NvmeCmd *cmd, NvmeRequest *req) uint32_t dw11 = le32_to_cpu(cmd->cdw11); switch (dw10) { + case NVME_TEMPERATURE_THRESHOLD: + if (NVME_TEMP_TMPSEL(dw11)) { + break; + } + + switch (NVME_TEMP_THSEL(dw11)) { + case 0x0: + n->features.temp_thresh_hi = NVME_TEMP_TMPTH(dw11); + break; + case 0x1: + n->features.temp_thresh_low = NVME_TEMP_TMPTH(dw11); + break; + default: + return NVME_INVALID_FIELD | NVME_DNR; + } + + break; case NVME_VOLATILE_WRITE_CACHE: blk_set_enable_write_cache(n->conf.blk, dw11 & 1); break; @@ -1374,6 +1416,7 @@ static void nvme_init_state(NvmeCtrl *n) n->namespaces = g_new0(NvmeNamespace, n->num_namespaces); n->sq = g_new0(NvmeSQueue *, n->params.max_ioqpairs + 1); n->cq = g_new0(NvmeCQueue *, n->params.max_ioqpairs + 1); + n->features.temp_thresh_hi = NVME_TEMPERATURE_WARNING; } static void nvme_init_cmb(NvmeCtrl *n, PCIDevice *pci_dev) @@ -1451,6 +1494,11 @@ static void nvme_init_ctrl(NvmeCtrl *n) id->acl = 3; id->frmw = 7 << 1; id->lpa = 1 << 0; + + /* recommended default value (~70 C) */ + id->wctemp = cpu_to_le16(NVME_TEMPERATURE_WARNING); + id->cctemp = cpu_to_le16(NVME_TEMPERATURE_CRITICAL); + id->sqes = (0x6 << 4) | 0x6; id->cqes = (0x4 << 4) | 0x4; id->nn = cpu_to_le32(n->num_namespaces); diff --git a/hw/block/nvme.h b/hw/block/nvme.h index b7c465560eea..8cda5f02c622 100644 --- a/hw/block/nvme.h +++ b/hw/block/nvme.h @@ -108,6 +108,7 @@ typedef struct NvmeCtrl { uint64_t irq_status; uint64_t host_timestamp; /* Timestamp sent by the host */ uint64_t timestamp_set_qemu_clock_ms; /* QEMU clock time */ + uint16_t temperature; NvmeNamespace *namespaces; NvmeSQueue **sq; @@ -115,6 +116,7 @@ typedef struct NvmeCtrl { NvmeSQueue admin_sq; NvmeCQueue admin_cq; NvmeIdCtrl id_ctrl; + NvmeFeatureVal features; } NvmeCtrl; static inline uint64_t nvme_ns_nlbas(NvmeCtrl *n, NvmeNamespace *ns) diff --git a/include/block/nvme.h b/include/block/nvme.h index a083c1b3a613..91fc4738a3e0 100644 --- a/include/block/nvme.h +++ b/include/block/nvme.h @@ -688,7 +688,13 @@ enum NvmeIdCtrlOncs { typedef struct NvmeFeatureVal { uint32_t arbitration; uint32_t power_mgmt; - uint32_t temp_thresh; + union { + struct { + uint16_t temp_thresh_hi; + uint16_t temp_thresh_low; + }; + uint32_t temp_thresh; + }; uint32_t err_rec; uint32_t volatile_wc; uint32_t num_queues;