From patchwork Thu Sep 23 23:20:32 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Agner X-Patchwork-Id: 1531965 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=agner.ch header.i=@agner.ch header.a=rsa-sha256 header.s=dkim header.b=iyuzZn8L; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4HFrlM3pHNz9sSn for ; Fri, 24 Sep 2021 09:21:35 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 5765F8341D; Fri, 24 Sep 2021 01:21:27 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=agner.ch Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=agner.ch header.i=@agner.ch header.b="iyuzZn8L"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 6FC56833DA; Fri, 24 Sep 2021 01:21:09 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail.kmu-office.ch (mail.kmu-office.ch [IPv6:2a02:418:6a02::a2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 10C388336B for ; Fri, 24 Sep 2021 01:21:05 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=agner.ch Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=stefan@agner.ch Received: from localhost.localdomain (unknown [IPv6:2a02:169:3df5:10:5c1d:e28a:f461:57d5]) by mail.kmu-office.ch (Postfix) with ESMTPSA id B72055C2B75; Fri, 24 Sep 2021 01:21:03 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=agner.ch; s=dkim; t=1632439263; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type: content-transfer-encoding:content-transfer-encoding:in-reply-to: references; bh=o/nhzTm68dbqeoHEe3JDHiqmro6XFH4MyRa+IcvUxVU=; b=iyuzZn8La0mimS55aNIEcZCd0UFk82kaHHn1/UmS08eX4ZTCi3UuQVoqzx5wA2iMk/NlOd 2Vk6pXgdJAedcMZkcDz4+irp/3P7uSG/2SBJ912y/yO+7FsNS09xAaQmgDYrr9ylyU+buh qMHU9ZxHxYH6owE/xXgBrYCNIL2oNTc= From: Stefan Agner To: bmeng.cn@gmail.com Cc: nsaenz@kernel.org, u-boot@lists.denx.de, mbrugger@suse.com, m.szyprowski@samsung.com, s.nawrocki@samsung.com, Stefan Agner , Wesley Sheng Subject: [RFC PATCH 1/4] Revert "nvme: Correct the prps per page calculation method" Date: Fri, 24 Sep 2021 01:20:32 +0200 Message-Id: <10aa393df8062f14fbca0faff35e05efdcfffe96.1632439220.git.stefan@agner.ch> X-Mailer: git-send-email 2.33.0 MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean This reverts commit 859b33c948945f7904f60a2c12a3792d356d51ad. If there is more than one PRP List the last entry is a pointer to the next list. From the NVM Express specification: "The last entry within a memory page, as indicated by the memory page size in the CC.MPS field, shall be a PRP List pointer if there is more than a single memory page of data to be transferred." For the purpose of calculating the number of pages required for PRP lists we should always assume that the last entry is required for the next PRP list. Signed-off-by: Stefan Agner Cc: Wesley Sheng --- drivers/nvme/nvme.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c index f6465ea7f4..1ae3001a90 100644 --- a/drivers/nvme/nvme.c +++ b/drivers/nvme/nvme.c @@ -81,7 +81,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, u64 *prp_pool; int length = total_len; int i, nprps; - u32 prps_per_page = page_size >> 3; + u32 prps_per_page = (page_size >> 3) - 1; u32 num_pages; length -= (page_size - offset); From patchwork Thu Sep 23 23:20:33 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Agner X-Patchwork-Id: 1531964 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=agner.ch header.i=@agner.ch header.a=rsa-sha256 header.s=dkim header.b=k4QfEE9e; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4HFrl90Zdvz9sSn for ; Fri, 24 Sep 2021 09:21:23 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 438F0833DA; Fri, 24 Sep 2021 01:21:12 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=agner.ch Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=agner.ch header.i=@agner.ch header.b="k4QfEE9e"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 048978341A; Fri, 24 Sep 2021 01:21:09 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail.kmu-office.ch (mail.kmu-office.ch [IPv6:2a02:418:6a02::a2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 208FE83414 for ; Fri, 24 Sep 2021 01:21:05 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=agner.ch Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=stefan@agner.ch Received: from localhost.localdomain (unknown [IPv6:2a02:169:3df5:10:5c1d:e28a:f461:57d5]) by mail.kmu-office.ch (Postfix) with ESMTPSA id 1361F5C2BB5; Fri, 24 Sep 2021 01:21:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=agner.ch; s=dkim; t=1632439264; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=TtJLzib/I//5N36VJDWodnSkX4El0KfjV7OHi8muWq4=; b=k4QfEE9e+r3kwPozlEMNypMovJY9fde8/yCXLcXm+Xct8vyvjJt92JZU4iePtqktZmq3nL 9noHbexmLF0hxRZv/7IBM5pPzX/TKGKGRFV2EFYaZe8FyadO5hz7VpEGjsTOIzEptAgGET URHmfykbqjng/SaUjaoxRHGL9kb01q8= From: Stefan Agner To: bmeng.cn@gmail.com Cc: nsaenz@kernel.org, u-boot@lists.denx.de, mbrugger@suse.com, m.szyprowski@samsung.com, s.nawrocki@samsung.com, Stefan Agner Subject: [RFC PATCH 2/4] nvme: improve readability of nvme_setup_prps() Date: Fri, 24 Sep 2021 01:20:33 +0200 Message-Id: X-Mailer: git-send-email 2.33.0 In-Reply-To: <10aa393df8062f14fbca0faff35e05efdcfffe96.1632439220.git.stefan@agner.ch> References: <10aa393df8062f14fbca0faff35e05efdcfffe96.1632439220.git.stefan@agner.ch> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean Improve readability by introducing consts, reuse consts where appropriate and adding variables with discriptive name. Signed-off-by: Stefan Agner --- drivers/nvme/nvme.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c index 1ae3001a90..677e66b1bb 100644 --- a/drivers/nvme/nvme.c +++ b/drivers/nvme/nvme.c @@ -76,12 +76,12 @@ static int nvme_wait_ready(struct nvme_dev *dev, bool enabled) static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, int total_len, u64 dma_addr) { - u32 page_size = dev->page_size; + const u32 page_size = dev->page_size; + const u32 prps_per_page = (page_size >> 3) - 1; int offset = dma_addr & (page_size - 1); u64 *prp_pool; int length = total_len; int i, nprps; - u32 prps_per_page = (page_size >> 3) - 1; u32 num_pages; length -= (page_size - offset); @@ -119,9 +119,9 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, prp_pool = dev->prp_pool; i = 0; while (nprps) { - if (i == ((page_size >> 3) - 1)) { - *(prp_pool + i) = cpu_to_le64((ulong)prp_pool + - page_size); + if (i == prps_per_page) { + u64 next_prp_list = (u64)prp_pool + page_size; + *(prp_pool + i) = cpu_to_le64(next_prp_list); i = 0; prp_pool += page_size; } From patchwork Thu Sep 23 23:20:34 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Agner X-Patchwork-Id: 1531967 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=agner.ch header.i=@agner.ch header.a=rsa-sha256 header.s=dkim header.b=qaSQr+gL; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=2a01:238:438b:c500:173d:9f52:ddab:ee01; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [IPv6:2a01:238:438b:c500:173d:9f52:ddab:ee01]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4HFrlt6CCCz9sSn for ; Fri, 24 Sep 2021 09:22:02 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 4FB488341A; Fri, 24 Sep 2021 01:21:36 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=agner.ch Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=agner.ch header.i=@agner.ch header.b="qaSQr+gL"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 5AFA28341D; Fri, 24 Sep 2021 01:21:18 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail.kmu-office.ch (mail.kmu-office.ch [IPv6:2a02:418:6a02::a2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 191DA83404 for ; Fri, 24 Sep 2021 01:21:05 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=agner.ch Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=stefan@agner.ch Received: from localhost.localdomain (unknown [IPv6:2a02:169:3df5:10:5c1d:e28a:f461:57d5]) by mail.kmu-office.ch (Postfix) with ESMTPSA id 336505C2BB6; Fri, 24 Sep 2021 01:21:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=agner.ch; s=dkim; t=1632439264; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=NXPd29Gtbfhz1apy8aBJFBViifs4YE2OjgvPzJKfdYk=; b=qaSQr+gLVungr9LeEB1wNsw92COPkSKaY3BLsNFDDCGp/N+Ce5BCqap8SkHhfiGAzgwc38 vedeIuDQWkiBb9qu5C+5BblOTplKDc7Wkp8Zop5mdeIY+II5pqquzLWtR3sba1Tzl++bhJ MY/PWIzNOMY3KeQYSArVCJzvVTYmuEQ= From: Stefan Agner To: bmeng.cn@gmail.com Cc: nsaenz@kernel.org, u-boot@lists.denx.de, mbrugger@suse.com, m.szyprowski@samsung.com, s.nawrocki@samsung.com, Stefan Agner Subject: [RFC PATCH 3/4] nvme: Use pointer for CPU addressed buffers Date: Fri, 24 Sep 2021 01:20:34 +0200 Message-Id: <5d489f855fb32b70569b706dc0fb6f9ed01a6bca.1632439220.git.stefan@agner.ch> X-Mailer: git-send-email 2.33.0 In-Reply-To: <10aa393df8062f14fbca0faff35e05efdcfffe96.1632439220.git.stefan@agner.ch> References: <10aa393df8062f14fbca0faff35e05efdcfffe96.1632439220.git.stefan@agner.ch> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean Pass buffers which use CPU addressing as void pointers. This aligns with DMA APIs which use void pointers as argument. It will avoid unnecessary type casts when adding support bus address translations. Signed-off-by: Stefan Agner --- drivers/nvme/nvme.c | 50 ++++++++++++++++++++-------------------- drivers/nvme/nvme_show.c | 4 ++-- include/nvme.h | 12 +++++----- 3 files changed, 33 insertions(+), 33 deletions(-) diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c index 677e66b1bb..4c4dc7cc4d 100644 --- a/drivers/nvme/nvme.c +++ b/drivers/nvme/nvme.c @@ -74,11 +74,11 @@ static int nvme_wait_ready(struct nvme_dev *dev, bool enabled) } static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, - int total_len, u64 dma_addr) + int total_len, void *buffer) { const u32 page_size = dev->page_size; const u32 prps_per_page = (page_size >> 3) - 1; - int offset = dma_addr & (page_size - 1); + int offset = (uintptr_t)buffer & (page_size - 1); u64 *prp_pool; int length = total_len; int i, nprps; @@ -92,10 +92,10 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, } if (length) - dma_addr += (page_size - offset); + buffer += (page_size - offset); if (length <= page_size) { - *prp2 = dma_addr; + *prp2 = (u64)buffer; return 0; } @@ -125,11 +125,11 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, i = 0; prp_pool += page_size; } - *(prp_pool + i++) = cpu_to_le64(dma_addr); - dma_addr += page_size; + *(prp_pool + i++) = cpu_to_le64((u64)buffer); + buffer += page_size; nprps--; } - *prp2 = (ulong)dev->prp_pool; + *prp2 = (u64)dev->prp_pool; flush_dcache_range((ulong)dev->prp_pool, (ulong)dev->prp_pool + dev->prp_entry_num * sizeof(u64)); @@ -450,42 +450,42 @@ static int nvme_alloc_sq(struct nvme_dev *dev, u16 qid, } int nvme_identify(struct nvme_dev *dev, unsigned nsid, - unsigned cns, dma_addr_t dma_addr) + unsigned int cns, void *buffer) { struct nvme_command c; u32 page_size = dev->page_size; - int offset = dma_addr & (page_size - 1); + int offset = (uintptr_t)buffer & (page_size - 1); int length = sizeof(struct nvme_id_ctrl); int ret; memset(&c, 0, sizeof(c)); c.identify.opcode = nvme_admin_identify; c.identify.nsid = cpu_to_le32(nsid); - c.identify.prp1 = cpu_to_le64(dma_addr); + c.identify.prp1 = cpu_to_le64((u64)buffer); length -= (page_size - offset); if (length <= 0) { c.identify.prp2 = 0; } else { - dma_addr += (page_size - offset); - c.identify.prp2 = cpu_to_le64(dma_addr); + buffer += (page_size - offset); + c.identify.prp2 = cpu_to_le64((u64)buffer); } c.identify.cns = cpu_to_le32(cns); - invalidate_dcache_range(dma_addr, - dma_addr + sizeof(struct nvme_id_ctrl)); + invalidate_dcache_range((uintptr_t)buffer, + (uintptr_t)buffer + sizeof(struct nvme_id_ctrl)); ret = nvme_submit_admin_cmd(dev, &c, NULL); if (!ret) - invalidate_dcache_range(dma_addr, - dma_addr + sizeof(struct nvme_id_ctrl)); + invalidate_dcache_range((uintptr_t)buffer, + (uintptr_t)buffer + sizeof(struct nvme_id_ctrl)); return ret; } int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid, - dma_addr_t dma_addr, u32 *result) + void *buffer, u32 *result) { struct nvme_command c; int ret; @@ -493,7 +493,7 @@ int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid, memset(&c, 0, sizeof(c)); c.features.opcode = nvme_admin_get_features; c.features.nsid = cpu_to_le32(nsid); - c.features.prp1 = cpu_to_le64(dma_addr); + c.features.prp1 = cpu_to_le64((u64)buffer); c.features.fid = cpu_to_le32(fid); ret = nvme_submit_admin_cmd(dev, &c, result); @@ -513,13 +513,13 @@ int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid, } int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11, - dma_addr_t dma_addr, u32 *result) + void *buffer, u32 *result) { struct nvme_command c; memset(&c, 0, sizeof(c)); c.features.opcode = nvme_admin_set_features; - c.features.prp1 = cpu_to_le64(dma_addr); + c.features.prp1 = cpu_to_le64((u64)buffer); c.features.fid = cpu_to_le32(fid); c.features.dword11 = cpu_to_le32(dword11); @@ -570,7 +570,7 @@ static int nvme_set_queue_count(struct nvme_dev *dev, int count) u32 q_count = (count - 1) | ((count - 1) << 16); status = nvme_set_features(dev, NVME_FEAT_NUM_QUEUES, - q_count, 0, &result); + q_count, NULL, &result); if (status < 0) return status; @@ -622,7 +622,7 @@ static int nvme_get_info_from_identify(struct nvme_dev *dev) if (!ctrl) return -ENOMEM; - ret = nvme_identify(dev, 0, 1, (dma_addr_t)(long)ctrl); + ret = nvme_identify(dev, 0, 1, ctrl); if (ret) { free(ctrl); return -EIO; @@ -708,7 +708,7 @@ static int nvme_blk_probe(struct udevice *udev) ns->dev = ndev; /* extract the namespace id from the block device name */ ns->ns_id = trailing_strtol(udev->name); - if (nvme_identify(ndev, ns->ns_id, 0, (dma_addr_t)(long)id)) { + if (nvme_identify(ndev, ns->ns_id, 0, id)) { free(id); return -EIO; } @@ -770,7 +770,7 @@ static ulong nvme_blk_rw(struct udevice *udev, lbaint_t blknr, } if (nvme_setup_prps(dev, &prp2, - lbas << ns->lba_shift, (ulong)buffer)) + lbas << ns->lba_shift, buffer)) return -EIO; c.rw.slba = cpu_to_le64(slba); slba += lbas; @@ -889,7 +889,7 @@ static int nvme_probe(struct udevice *udev) char name[20]; memset(id, 0, sizeof(*id)); - if (nvme_identify(ndev, i, 0, (dma_addr_t)(long)id)) { + if (nvme_identify(ndev, i, 0, id)) { ret = -EIO; goto free_id; } diff --git a/drivers/nvme/nvme_show.c b/drivers/nvme/nvme_show.c index 15e459da1a..c30adfada5 100644 --- a/drivers/nvme/nvme_show.c +++ b/drivers/nvme/nvme_show.c @@ -111,14 +111,14 @@ int nvme_print_info(struct udevice *udev) ALLOC_CACHE_ALIGN_BUFFER(char, buf_ctrl, sizeof(struct nvme_id_ctrl)); struct nvme_id_ctrl *ctrl = (struct nvme_id_ctrl *)buf_ctrl; - if (nvme_identify(dev, 0, 1, (dma_addr_t)(long)ctrl)) + if (nvme_identify(dev, 0, 1, ctrl)) return -EIO; print_optional_admin_cmd(le16_to_cpu(ctrl->oacs), ns->devnum); print_optional_nvm_cmd(le16_to_cpu(ctrl->oncs), ns->devnum); print_format_nvme_attributes(ctrl->fna, ns->devnum); - if (nvme_identify(dev, ns->ns_id, 0, (dma_addr_t)(long)id)) + if (nvme_identify(dev, ns->ns_id, 0, id)) return -EIO; print_formats(id, ns); diff --git a/include/nvme.h b/include/nvme.h index 2cdf8ce320..8ff823cd81 100644 --- a/include/nvme.h +++ b/include/nvme.h @@ -18,12 +18,12 @@ struct nvme_dev; * @dev: NVMe controller device * @nsid: 0 for controller, namespace id for namespace to identify * @cns: 1 for controller, 0 for namespace - * @dma_addr: dma buffer address to store the identify result + * @buffer: dma buffer address to store the identify result * @return: 0 on success, -ETIMEDOUT on command execution timeout, * -EIO on command execution fails */ int nvme_identify(struct nvme_dev *dev, unsigned nsid, - unsigned cns, dma_addr_t dma_addr); + unsigned int cns, void *buffer); /** * nvme_get_features - retrieve the attributes of the feature specified @@ -33,13 +33,13 @@ int nvme_identify(struct nvme_dev *dev, unsigned nsid, * @dev: NVMe controller device * @fid: feature id to provide data * @nsid: namespace id the command applies to - * @dma_addr: data structure used as part of the specified feature + * @buffer: data structure used as part of the specified feature * @result: command-specific result in the completion queue entry * @return: 0 on success, -ETIMEDOUT on command execution timeout, * -EIO on command execution fails */ int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid, - dma_addr_t dma_addr, u32 *result); + void *buffer, u32 *result); /** * nvme_set_features - specify the attributes of the feature indicated @@ -49,13 +49,13 @@ int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid, * @dev: NVMe controller device * @fid: feature id to provide data * @dword11: command-specific input parameter - * @dma_addr: data structure used as part of the specified feature + * @buffer: data structure used as part of the specified feature * @result: command-specific result in the completion queue entry * @return: 0 on success, -ETIMEDOUT on command execution timeout, * -EIO on command execution fails */ int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11, - dma_addr_t dma_addr, u32 *result); + void *buffer, u32 *result); /** * nvme_scan_namespace - scan all namespaces attached to NVMe controllers From patchwork Thu Sep 23 23:20:35 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Stefan Agner X-Patchwork-Id: 1531966 X-Patchwork-Delegate: trini@ti.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=agner.ch header.i=@agner.ch header.a=rsa-sha256 header.s=dkim header.b=Zo4TixbW; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.denx.de (client-ip=85.214.62.61; helo=phobos.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Received: from phobos.denx.de (phobos.denx.de [85.214.62.61]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4HFrlZ1NlZz9sSn for ; Fri, 24 Sep 2021 09:21:46 +1000 (AEST) Received: from h2850616.stratoserver.net (localhost [IPv6:::1]) by phobos.denx.de (Postfix) with ESMTP id 618638342C; Fri, 24 Sep 2021 01:21:31 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=agner.ch Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=u-boot-bounces@lists.denx.de Authentication-Results: phobos.denx.de; dkim=pass (1024-bit key; unprotected) header.d=agner.ch header.i=@agner.ch header.b="Zo4TixbW"; dkim-atps=neutral Received: by phobos.denx.de (Postfix, from userid 109) id 42C16833F8; Fri, 24 Sep 2021 01:21:19 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on phobos.denx.de X-Spam-Level: X-Spam-Status: No, score=-2.1 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,SPF_HELO_PASS,SPF_PASS autolearn=ham autolearn_force=no version=3.4.2 Received: from mail.kmu-office.ch (mail.kmu-office.ch [IPv6:2a02:418:6a02::a2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)) (No client certificate requested) by phobos.denx.de (Postfix) with ESMTPS id 24FD083411 for ; Fri, 24 Sep 2021 01:21:05 +0200 (CEST) Authentication-Results: phobos.denx.de; dmarc=none (p=none dis=none) header.from=agner.ch Authentication-Results: phobos.denx.de; spf=pass smtp.mailfrom=stefan@agner.ch Received: from localhost.localdomain (unknown [IPv6:2a02:169:3df5:10:5c1d:e28a:f461:57d5]) by mail.kmu-office.ch (Postfix) with ESMTPSA id 5B48D5C2BB7; Fri, 24 Sep 2021 01:21:04 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=agner.ch; s=dkim; t=1632439264; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=WbxaIFp98kW2uDigSMhL4StA9AricZLO4eJSRKqDs/0=; b=Zo4TixbW7eM4zp/nzHMjyezWNT3/qoJrFEGF4+bDeppGXjWqNUIoKEGaYqegTr+lT5jTXZ CyQ9jfT+Olg3eW/75jC6lKILgBlqhu4ou/5P7QKb6gYJ0KDhKhHtOesnCYWQCPh7BPacjD W4u4c8v+6x2oP5R6yz/bJa1SyIXtOM4= From: Stefan Agner To: bmeng.cn@gmail.com Cc: nsaenz@kernel.org, u-boot@lists.denx.de, mbrugger@suse.com, m.szyprowski@samsung.com, s.nawrocki@samsung.com, Stefan Agner Subject: [RFC PATCH 4/4] nvme: translate virtual addresses into the bus's address space Date: Fri, 24 Sep 2021 01:20:35 +0200 Message-Id: X-Mailer: git-send-email 2.33.0 In-Reply-To: <10aa393df8062f14fbca0faff35e05efdcfffe96.1632439220.git.stefan@agner.ch> References: <10aa393df8062f14fbca0faff35e05efdcfffe96.1632439220.git.stefan@agner.ch> MIME-Version: 1.0 X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.34 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" X-Virus-Scanned: clamav-milter 0.103.2 at phobos.denx.de X-Virus-Status: Clean So far we've been content with passing physical/CPU addresses when configuring memory addresses into NVMe controllers, but not all platforms have buses with transparent mappings. Specifically the Raspberry Pi 4 might introduce an offset to memory accesses incoming from its PCIe port. Introduce nvme_virt_to_bus() and nvme_bus_to_virt() to cater with these limitations, and make sure we don't break non DM users. For devices where PCIe's view of host memory doesn't match the memory as seen by the CPU. A similar change has been introduced for XHCI controller with commit 1a474559d90a ("xhci: translate virtual addresses into the bus's address space"). Signed-off-by: Stefan Agner --- drivers/nvme/nvme.c | 32 ++++++++++++++++++-------------- drivers/nvme/nvme.h | 15 +++++++++++++++ 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/drivers/nvme/nvme.c b/drivers/nvme/nvme.c index 4c4dc7cc4d..0b7082d71b 100644 --- a/drivers/nvme/nvme.c +++ b/drivers/nvme/nvme.c @@ -95,7 +95,7 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, buffer += (page_size - offset); if (length <= page_size) { - *prp2 = (u64)buffer; + *prp2 = nvme_virt_to_bus(dev, buffer); return 0; } @@ -120,16 +120,16 @@ static int nvme_setup_prps(struct nvme_dev *dev, u64 *prp2, i = 0; while (nprps) { if (i == prps_per_page) { - u64 next_prp_list = (u64)prp_pool + page_size; - *(prp_pool + i) = cpu_to_le64(next_prp_list); + u64 next = nvme_virt_to_bus(dev, prp_pool + page_size); + *(prp_pool + i) = cpu_to_le64(next); i = 0; prp_pool += page_size; } - *(prp_pool + i++) = cpu_to_le64((u64)buffer); + *(prp_pool + i++) = cpu_to_le64(nvme_virt_to_bus(dev, buffer)); buffer += page_size; nprps--; } - *prp2 = (u64)dev->prp_pool; + *prp2 = nvme_virt_to_bus(dev, dev->prp_pool); flush_dcache_range((ulong)dev->prp_pool, (ulong)dev->prp_pool + dev->prp_entry_num * sizeof(u64)); @@ -356,6 +356,7 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) int result; u32 aqa; u64 cap = dev->cap; + u64 dma_addr; struct nvme_queue *nvmeq; /* most architectures use 4KB as the page size */ unsigned page_shift = 12; @@ -396,8 +397,10 @@ static int nvme_configure_admin_queue(struct nvme_dev *dev) dev->ctrl_config |= NVME_CC_IOSQES | NVME_CC_IOCQES; writel(aqa, &dev->bar->aqa); - nvme_writeq((ulong)nvmeq->sq_cmds, &dev->bar->asq); - nvme_writeq((ulong)nvmeq->cqes, &dev->bar->acq); + dma_addr = nvme_virt_to_bus(dev, nvmeq->sq_cmds); + nvme_writeq(dma_addr, &dev->bar->asq); + dma_addr = nvme_virt_to_bus(dev, nvmeq->cqes); + nvme_writeq(dma_addr, &dev->bar->acq); result = nvme_enable_ctrl(dev); if (result) @@ -423,7 +426,7 @@ static int nvme_alloc_cq(struct nvme_dev *dev, u16 qid, memset(&c, 0, sizeof(c)); c.create_cq.opcode = nvme_admin_create_cq; - c.create_cq.prp1 = cpu_to_le64((ulong)nvmeq->cqes); + c.create_cq.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, nvmeq->cqes)); c.create_cq.cqid = cpu_to_le16(qid); c.create_cq.qsize = cpu_to_le16(nvmeq->q_depth - 1); c.create_cq.cq_flags = cpu_to_le16(flags); @@ -440,7 +443,7 @@ static int nvme_alloc_sq(struct nvme_dev *dev, u16 qid, memset(&c, 0, sizeof(c)); c.create_sq.opcode = nvme_admin_create_sq; - c.create_sq.prp1 = cpu_to_le64((ulong)nvmeq->sq_cmds); + c.create_sq.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, nvmeq->sq_cmds)); c.create_sq.sqid = cpu_to_le16(qid); c.create_sq.qsize = cpu_to_le16(nvmeq->q_depth - 1); c.create_sq.sq_flags = cpu_to_le16(flags); @@ -461,14 +464,14 @@ int nvme_identify(struct nvme_dev *dev, unsigned nsid, memset(&c, 0, sizeof(c)); c.identify.opcode = nvme_admin_identify; c.identify.nsid = cpu_to_le32(nsid); - c.identify.prp1 = cpu_to_le64((u64)buffer); + c.identify.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, buffer)); length -= (page_size - offset); if (length <= 0) { c.identify.prp2 = 0; } else { buffer += (page_size - offset); - c.identify.prp2 = cpu_to_le64((u64)buffer); + c.identify.prp2 = cpu_to_le64(nvme_virt_to_bus(dev, buffer)); } c.identify.cns = cpu_to_le32(cns); @@ -493,7 +496,7 @@ int nvme_get_features(struct nvme_dev *dev, unsigned fid, unsigned nsid, memset(&c, 0, sizeof(c)); c.features.opcode = nvme_admin_get_features; c.features.nsid = cpu_to_le32(nsid); - c.features.prp1 = cpu_to_le64((u64)buffer); + c.features.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, buffer)); c.features.fid = cpu_to_le32(fid); ret = nvme_submit_admin_cmd(dev, &c, result); @@ -519,7 +522,7 @@ int nvme_set_features(struct nvme_dev *dev, unsigned fid, unsigned dword11, memset(&c, 0, sizeof(c)); c.features.opcode = nvme_admin_set_features; - c.features.prp1 = cpu_to_le64((u64)buffer); + c.features.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, buffer)); c.features.fid = cpu_to_le32(fid); c.features.dword11 = cpu_to_le32(dword11); @@ -775,7 +778,7 @@ static ulong nvme_blk_rw(struct udevice *udev, lbaint_t blknr, c.rw.slba = cpu_to_le64(slba); slba += lbas; c.rw.length = cpu_to_le16(lbas - 1); - c.rw.prp1 = cpu_to_le64((ulong)buffer); + c.rw.prp1 = cpu_to_le64(nvme_virt_to_bus(dev, buffer)); c.rw.prp2 = cpu_to_le64(prp2); status = nvme_submit_sync_cmd(dev->queues[NVME_IO_Q], &c, NULL, IO_TIMEOUT); @@ -834,6 +837,7 @@ static int nvme_probe(struct udevice *udev) struct nvme_id_ns *id; ndev->instance = trailing_strtol(udev->name); + ndev->dev = udev->parent; INIT_LIST_HEAD(&ndev->namespaces); ndev->bar = dm_pci_map_bar(udev, PCI_BASE_ADDRESS_0, diff --git a/drivers/nvme/nvme.h b/drivers/nvme/nvme.h index c6aae4da5d..31e6899bca 100644 --- a/drivers/nvme/nvme.h +++ b/drivers/nvme/nvme.h @@ -7,8 +7,15 @@ #ifndef __DRIVER_NVME_H__ #define __DRIVER_NVME_H__ +#include #include +#if CONFIG_IS_ENABLED(DM_USB) +#define nvme_to_dev(_dev) _dev->dev +#else +#define nvme_to_dev(_dev) NULL +#endif + struct nvme_id_power_state { __le16 max_power; /* centiwatts */ __u8 rsvd2; @@ -596,6 +603,9 @@ enum { /* Represents an NVM Express device. Each nvme_dev is a PCI function. */ struct nvme_dev { +#if CONFIG_IS_ENABLED(DM_USB) + struct udevice *dev; +#endif struct list_head node; struct nvme_queue **queues; u32 __iomem *dbs; @@ -635,4 +645,9 @@ struct nvme_ns { u8 flbas; }; +static inline dma_addr_t nvme_virt_to_bus(struct nvme_dev *dev, void *addr) +{ + return dev_phys_to_bus(nvme_to_dev(dev), virt_to_phys(addr)); +} + #endif /* __DRIVER_NVME_H__ */