From patchwork Fri Oct 16 03:45:18 2026 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: James Hilliard X-Patchwork-Id: 3632 Return-Path: X-Original-To: noreply@patchwork.local Delivered-To: noreply@patchwork.local Received: from sto.lore.kernel.org (sto.lore.kernel.org [172.232.135.74]) by mxe881.netcup.net (Postfix) with ESMTPS id 640691C1CBB for ; Fri, 16 Oct 2026 05:45:51 +0200 (CEST) Authentication-Results: mxe881; dkim=pass header.d=gmail.com; spf=pass (sender IP is 172.232.135.74) smtp.mailfrom=linux-sunxi+bounces-26678-noreply=patchwork.local@lists.linux.dev smtp.helo=sto.lore.kernel.org Received-SPF: pass (mxe881: domain of lists.linux.dev designates 172.232.135.74 as permitted sender) client-ip=172.232.135.74; envelope-from=linux-sunxi+bounces-26678-noreply=patchwork.local@lists.linux.dev; helo=sto.lore.kernel.org; Received: from smtp.subspace.kernel.org (conduit.subspace.kernel.org [100.90.174.1]) by sto.lore.kernel.org (Postfix) with ESMTP id A3C8E6061F1 for ; Fri, 16 Oct 2026 03:45:42 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id ADF9B37E5D0; Fri, 16 Oct 2026 03:45:34 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="acH64NKi" X-Original-To: linux-sunxi@lists.linux.dev Received: from mail-oo1-f45.google.com (mail-oo1-f45.google.com [209.85.161.45]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5FFF1346A18 for ; Fri, 16 Oct 2026 03:45:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.161.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792122334; cv=none; b=WAexiX68xEqLRzX81c1DxbPBdAp69CvfbKrUsysgykgefV3Ozbw9PsiYaKtZXhSmDLsSUVtErWQ4BUwTyXmLUb+7801S+jA/zKpFGan9BHJZSAQi5Y7Qr8631MCbkRUx9v0369HT41xCcwqzTrFgbtnY4vzbwnV2lb2/PMmBNew= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1792122334; c=relaxed/simple; bh=5swNrnjhpqGxZeyGDlWe9TNZCEAsFDPalqzTOJ3Aefg=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=cNbiaFaVi6AI2duwqmcj7aLvQDiCdMludEgVpXtKHZ+0JYwmdLcw0TRanLtPpg4+hGYDq+wSxSkL9OvSAx4bBQ3D3LiiiZ7pbZFnIJSIDowsmnNgZVKZJBsyjCu6ZtJcyUGA74shm10WmPCL0AssTVt8ATFo5zt6JdyE2cUlvDM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=acH64NKi; arc=none smtp.client-ip=209.85.161.45 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-oo1-f45.google.com with SMTP id 006d021491bc7-6b19e291cc6so5523559eaf.2 for ; Thu, 15 Oct 2026 20:45:32 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1792122331; x=1792727131; darn=lists.linux.dev; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=hlWVFZs9qMdbAGtAdGz2zNdnsjoirOAt+ztYuqFoEV4=; b=acH64NKiyGVn/ffUblXF4m6JX8cwlQ/OYY/knan+tu/jZZdRuIR1JlPN7lZ8gyEems Qbfh91W/u0m89whCkA+FOIS4rk0lIF8z+NlCYrjG3ulRrwkTnM2vNGMCJ/zq9xbOCrTI on7TUXdHE2DD8jGF6OguLArP/57xY0tAQLvlqwhRuAhWQw6IWm6KomLrSOtksMxBIhMs i0A+37WMx0kObpHke8M2hQfFkL/eN/lirWuIcPhgxl3DDf0UvfetkQgXmXYXo16JcKsN AfKXZ0CjSzs+lr/qTLyH6yc+PWVknsxFriq4alRDvbyzkAIEb0Y1rFxYoTnGfWvEPhwa hDkw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20260707; t=1792122331; x=1792727131; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :content-type:mime-version:subject:date:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=hlWVFZs9qMdbAGtAdGz2zNdnsjoirOAt+ztYuqFoEV4=; b=Uc1RpmB5qQnj4rXoZZc5P1HZAPBQBHyB8sBkrWUAngBhHKLpOAWbikXWTAkPkawkpJ 4jMI8Z4DGW4Pa7FADk0c3HvD+P4Iia1EJag+Mscx6aunOiRxk8StKT97uhPLgIxgSL9H 3jA0ZVjNV+gMgiF5XPEDOIBaqhyCl6xYb+xDR3Bvl/TuIOX40zWSRRkRRnbEnaYAEEHF w+Na3MYZWS2rlVHsZMjYj39AH5JjQetg/VhaBlj+hHS7PQyaY9aERY6sOW8nP8itIBch P0CUhMmuq5yPazWE3VuwaWQ0UwTRYPo1IVAxZQiPOBR3yhw+w7HocJikKKk0c/IxK4Ya iXqQ== X-Forwarded-Encrypted: i=1; AKwUvByT8LddxzDHyIR7r7cUpFv52cm6JZ0Xw0jGSMgPVsz8ON5632ToPcAratlSbOLUj8F7whbBGwRHrUC1NQ==@lists.linux.dev X-Gm-Message-State: AFq9FYJ5i6gDEgvmPlIMKZVSScrTMagXqeMjrHToU0laOl8lr4GWGyAP 4ujD9vdXh8KysuNxqD6XvRjALAf9ruIhZioLkbCBOpD5sX5F5gQBO09I X-Gm-Gg: AYBFou0Oq9vuKc4N7g4hw2Cm1kvussFAesV/GdRp9XWzPybNnvugi343ZVrskCqfVfj mOtcLW4Oz7A1d54kMcHus/YfEoVIirEzxwIPs3Cs6XzOsvrepQ6EKaCcelfNH+5VKCc1yGAlXd+ uPjYlShOlm1w6h9C2grysHdHHV7NIn4GH622s85JxtuaXyW8E0epqBMiB7zAJ1vzB1QjGP3+UzM 4dVzZ7Y3QiOfLplL4FTx+q1cXNU6052WfnRMKVbVji6u14vAHCr2sKI+r3AIKm4wCuW2pF22XYt 54bnmeaES/tFleEqhCXjMEPFxSh+gtE+azyqIPQNwCroI9yRn+gc0Sk1OhIRqpfbO44GPh0ZW9t 6ZIkTfM2YCU1NGppT0PQVjgqgL3r9k/aoLptxjk0na12WgrjSDJ5j1aaYTOGd1SzdtK9u+8+9IT syD9HDEpeOfyszgBIFZEltkGrxsA1+CYmBq6l71H+j1bOeqTyMXG/bftq0DyDkQsRm3w5AmC6bZ W+I6O7MsMgQ4Mm1s5JZNvhAVSBHU7gNpiv3/8Iwa0iDrujzgMM9QVFSJkFFUTMyNWV+Papz9vX7 e8mMf2BRXrEE89gG/qQB7wZbM/9d9Myq0zEkMtg4doqVRQiKlnECsI4ysHPgBdKZUDa+i7JuxVy QTLKuFtVRF16JCkwvvkfCVw== X-Received: by 2002:a05:6820:1503:b0:6d7:cd0c:752a with SMTP id 006d021491bc7-6ef0faaa6f2mr17901293eaf.54.1792122331029; Thu, 15 Oct 2026 20:45:31 -0700 (PDT) Received: from [127.0.1.1] (174-29-1-49.hlrn.qwest.net. [174.29.1.49]) by smtp.gmail.com with ESMTPSA id 46e09a7af769-8429b57870fsm834402a34.0.2026.10.15.20.45.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 15 Oct 2026 20:45:30 -0700 (PDT) From: James Hilliard Date: Thu, 15 Oct 2026 21:45:18 -0600 Subject: [PATCH v8 03/17] mtd: rawnand: sunxi: propagate page-setup and erased-check errors Precedence: bulk X-Mailing-List: linux-sunxi@lists.linux.dev List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20261015-submit-sunxi-nand-vendor-oob-layout-v1-v8-3-8ba4881fbee8@gmail.com> References: <20261015-submit-sunxi-nand-vendor-oob-layout-v1-v8-0-8ba4881fbee8@gmail.com> In-Reply-To: <20261015-submit-sunxi-nand-vendor-oob-layout-v1-v8-0-8ba4881fbee8@gmail.com> To: Miquel Raynal , Richard Weinberger , Vignesh Raghavendra , Sebastian Andrzej Siewior , Clark Williams , Steven Rostedt , Rob Herring , Krzysztof Kozlowski , Conor Dooley Cc: Chen-Yu Tsai , Jernej Skrabec , Samuel Holland , Maxime Ripard , Richard Genoud , Boris Brezillon , Masahiro Yamada , Brian Norris , linux-mtd@lists.infradead.org, linux-arm-kernel@lists.infradead.org, linux-sunxi@lists.linux.dev, linux-kernel@vger.kernel.org, linux-rt-devel@lists.linux.dev, devicetree@vger.kernel.org, James Hilliard X-Mailer: b4 0.15.2 X-MORS-Enabled: yes X-MORS-DOMAIN: patchwork.local X-MORS-HOSTING: hosting172546 X-MORS-USER: hosting172546 X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= The ECC read callbacks ignore nand_read_page_op() failures. A command or ready timeout can therefore leave the requested page unselected, yet the driver continues with data transfers and can report success for stale data. Return the setup error before starting PIO or DMA. After an ECC error, the driver rereads the physical data and OOB with randomization disabled to distinguish an erased chunk from corrupt data. Those rereads can also fail. Do not pass stale buffers to nand_check_erased_ecc_chunk() or count a transport failure as an ECC result: return the reread error instead. Successful erased checks retain their existing statistics and correction-count behavior. Route PIO read errors through ECC disable. DMA has already released its transfer resources before interpreting the results, and its caller retries a failed read in PIO. Restore the corrected/failed counters from before that DMA attempt so earlier steps are not counted again by the retry; leave bad-block counters unchanged. These unchecked returns were found by inspecting the read callbacks and their NAND-operation helpers. Fixes: 97d90da8a886 ("mtd: nand: provide several helpers to do common NAND operations") Fixes: 25f815f66a14 ("mtd: nand: force drivers to explicitly send READ/PROG commands") Signed-off-by: James Hilliard --- drivers/mtd/nand/raw/sunxi_nand.c | 56 ++++++++++++++++++++++++++++++--------- 1 file changed, 44 insertions(+), 12 deletions(-) diff --git a/drivers/mtd/nand/raw/sunxi_nand.c b/drivers/mtd/nand/raw/sunxi_nand.c index c2e97b8656f7..6c0d3e2d2be2 100644 --- a/drivers/mtd/nand/raw/sunxi_nand.c +++ b/drivers/mtd/nand/raw/sunxi_nand.c @@ -1030,7 +1030,10 @@ static void sunxi_nfc_hw_ecc_update_stats(struct nand_chip *nand, } } -/* Return whether the chunk is erased, and account for its ECC result. */ +/* + * Return 1 for an erased chunk or 0 for an uncorrectable chunk, with ECC + * statistics updated in either case. Negative values report transport errors. + */ static int sunxi_nfc_hw_ecc_read_error(struct nand_chip *nand, u8 *data, int data_off, u8 *oob, int oob_off, @@ -1042,10 +1045,16 @@ static int sunxi_nfc_hw_ecc_read_error(struct nand_chip *nand, int ret; /* Check the physical representation for bitflips in erased pages. */ - if (nand->options & NAND_NEED_SCRAMBLING) - nand_change_read_column_op(nand, data_off, data, ecc->size, false); + if (nand->options & NAND_NEED_SCRAMBLING) { + ret = nand_change_read_column_op(nand, data_off, data, + ecc->size, false); + if (ret) + return ret; + } - nand_change_read_column_op(nand, oob_off, oob, oob_len, false); + ret = nand_change_read_column_op(nand, oob_off, oob, oob_len, false); + if (ret) + return ret; ret = nand_check_erased_ecc_chunk(data, ecc->size, oob, oob_len, NULL, 0, ecc->strength); @@ -1308,6 +1317,7 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, u8 *buf, { struct sunxi_nand_chip *sunxi_nand = to_sunxi_nand(nand); struct sunxi_nfc *nfc = to_sunxi_nfc(nand->controller); + struct mtd_info *mtd = nand_to_mtd(nand); struct nand_ecc_ctrl *ecc = &nand->ecc; struct sunxi_nfc_ecc_read read = { .buf = buf, @@ -1315,6 +1325,8 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, u8 *buf, .oob_required = oob_required, .dma = true, }; + unsigned int corrected = mtd->ecc_stats.corrected; + unsigned int failed = mtd->ecc_stats.failed; struct scatterlist sg; int ret, i; u32 status, pattern_found, wait; @@ -1366,9 +1378,19 @@ static int sunxi_nfc_hw_ecc_read_chunks_dma(struct nand_chip *nand, u8 *buf, ret = sunxi_nand->oob_ops->read_batch(nand, &read, status, pattern_found, 0, nchunks); if (ret) - return ret; + goto err_stats; + + ret = sunxi_nand->oob_ops->finish_read(nand, &read, NULL); + if (ret < 0) + goto err_stats; + + return ret; - return sunxi_nand->oob_ops->finish_read(nand, &read, NULL); +err_stats: + /* The caller retries the whole read in PIO mode. */ + mtd->ecc_stats.corrected = corrected; + mtd->ecc_stats.failed = failed; + return ret; } static int sunxi_nfc_hw_ecc_write_chunk(struct nand_chip *nand, @@ -1456,7 +1478,9 @@ static int sunxi_nfc_hw_ecc_read_page(struct nand_chip *nand, uint8_t *buf, sunxi_nfc_select_chip(nand, nand->cur_cs); - nand_read_page_op(nand, page, 0, NULL, 0); + ret = nand_read_page_op(nand, page, 0, NULL, 0); + if (ret) + return ret; sunxi_nfc_hw_ecc_enable(nand); @@ -1464,10 +1488,11 @@ static int sunxi_nfc_hw_ecc_read_page(struct nand_chip *nand, uint8_t *buf, for (i = 0; i < ecc->steps; i++) { ret = sunxi_nfc_hw_ecc_read_chunk(nand, &read, i, &cur_off); if (ret < 0) - return ret; + goto out; } ret = sunxi_nand->oob_ops->finish_read(nand, &read, &cur_off); +out: sunxi_nfc_hw_ecc_disable(nand); return ret; @@ -1480,7 +1505,9 @@ static int sunxi_nfc_hw_ecc_read_page_dma(struct nand_chip *nand, u8 *buf, sunxi_nfc_select_chip(nand, nand->cur_cs); - nand_read_page_op(nand, page, 0, NULL, 0); + ret = nand_read_page_op(nand, page, 0, NULL, 0); + if (ret) + return ret; ret = sunxi_nfc_hw_ecc_read_chunks_dma(nand, buf, oob_required, page, nand->ecc.steps); @@ -1505,7 +1532,9 @@ static int sunxi_nfc_hw_ecc_read_subpage(struct nand_chip *nand, sunxi_nfc_select_chip(nand, nand->cur_cs); - nand_read_page_op(nand, page, 0, NULL, 0); + ret = nand_read_page_op(nand, page, 0, NULL, 0); + if (ret) + return ret; sunxi_nfc_hw_ecc_enable(nand); @@ -1514,10 +1543,11 @@ static int sunxi_nfc_hw_ecc_read_subpage(struct nand_chip *nand, i < DIV_ROUND_UP(data_offs + readlen, ecc->size); i++) { ret = sunxi_nfc_hw_ecc_read_chunk(nand, &read, i, &cur_off); if (ret < 0) - return ret; + goto out; } ret = read.max_bitflips; +out: sunxi_nfc_hw_ecc_disable(nand); return ret; @@ -1532,7 +1562,9 @@ static int sunxi_nfc_hw_ecc_read_subpage_dma(struct nand_chip *nand, sunxi_nfc_select_chip(nand, nand->cur_cs); - nand_read_page_op(nand, page, 0, NULL, 0); + ret = nand_read_page_op(nand, page, 0, NULL, 0); + if (ret) + return ret; ret = sunxi_nfc_hw_ecc_read_chunks_dma(nand, buf, false, page, nchunks); if (ret >= 0)