Received: by 2002:ac0:a5a7:0:0:0:0:0 with SMTP id m36-v6csp1437486imm; Thu, 19 Jul 2018 01:26:16 -0700 (PDT) X-Google-Smtp-Source: AAOMgpfBY64f38LsoHoAdHoIv1SUtdZAZYFvRT+pd+3mpBHLp8dHK2PcdNo9ZJnVx/UbUFg+Hff4 X-Received: by 2002:a63:e452:: with SMTP id i18-v6mr8926524pgk.185.1531988776408; Thu, 19 Jul 2018 01:26:16 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1531988776; cv=none; d=google.com; s=arc-20160816; b=kEPenmgsYz5AlOravEfd8LB/T65uSYkzPjyXLlOSkKJ6pk+qhDGftqqiz26/7Cxh9g 3ec2bmSElM1Ov3C7MSdvVNSIp5CdsOWwZhECo7z/H8TVB2Ni1iH2TabQHZ6wsKJKteBG GyTCwxFlFzOhuA+rDJiXvqMhQgxa40ngIH9VMfjmEylExpRHy35l1A8CB3OIP6kvB5eR ihmddTSzNl35Z/RrDmw8zQMQTb9nUjtrcuG0Pue3keQB9tFPj9qJAMIP2gbYbI3Pf8MH jGkTzc9WGcL8rjqqS1Ax6LcHhKJEnSXLFIrIe1yesLILtVTF0u+JjfY0XYtY1SONX1N/ tkeQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:subject:cc:to:from:date :arc-authentication-results; bh=dsZ03nWL/yV0Ys07ZFd2THUHZ+NJ8CJXK4b7tkoA7eI=; b=DDxiAx/w/iaFhDK9IiTxo5qitgfvD5FbVZV0akLZXvHvS1nfgdTvLnI3QYFKOv/WnV pZ2G1XH9MgRgu3uoCbBqpjPOrib7f0N4dEFClAeS7v3Y2d652tZfjSnf4TwMnIDMq/Il JgZf8ZtM75G8Ijerel06zK7TJ+6bYmUHkeh3DYhf2CAcwFvfHj6DJULYi6CbQGZeny8p rieMfoKvkIgGtfDcRkBD6IA/uVi/C4G+8Rd39Wp0Xu9e7wvNioYNt4LZz+bMhXqqv6nt TCMlsoIOgtnkBRyXFVCgyPHfKYSHbeHyKFrOwoYG0IXh/Ij9rDtYLlXVwNr9Sjtbd3iq ULQA== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id i6-v6si5504350pgk.517.2018.07.19.01.26.00; Thu, 19 Jul 2018 01:26:16 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1731527AbeGSJG0 (ORCPT + 99 others); Thu, 19 Jul 2018 05:06:26 -0400 Received: from mail.bootlin.com ([62.4.15.54]:55121 "EHLO mail.bootlin.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1731262AbeGSJG0 (ORCPT ); Thu, 19 Jul 2018 05:06:26 -0400 Received: by mail.bootlin.com (Postfix, from userid 110) id 08F41207AD; Thu, 19 Jul 2018 10:24:25 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on mail.bootlin.com X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED,SHORTCIRCUIT shortcircuit=ham autolearn=disabled version=3.4.0 Received: from bbrezillon (AAubervilliers-681-1-27-161.w90-88.abo.wanadoo.fr [90.88.147.161]) by mail.bootlin.com (Postfix) with ESMTPSA id BD17C20731; Thu, 19 Jul 2018 10:24:24 +0200 (CEST) Date: Thu, 19 Jul 2018 10:24:24 +0200 From: Boris Brezillon To: KOBAYASHI Yoshitake Cc: miquel.raynal@bootlin.com, richard@nod.at, dwmw2@infradead.org, computersforpeace@gmail.com, marek.vasut@gmail.com, linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org Subject: Re: [RFC PATCH] mtd: nand: toshiba: Add support for ->exec_op() Message-ID: <20180719102424.30ffa07e@bbrezillon> In-Reply-To: <1531986827-18743-1-git-send-email-yoshitake.kobayashi@toshiba.co.jp> References: <1531986827-18743-1-git-send-email-yoshitake.kobayashi@toshiba.co.jp> X-Mailer: Claws Mail 3.15.0-dirty (GTK+ 2.24.31; x86_64-pc-linux-gnu) MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On Thu, 19 Jul 2018 16:53:47 +0900 KOBAYASHI Yoshitake wrote: > This patch is a patch to support TOSHIBA MEMORY CORPORATION BENAND > memory devices. This use vendor specific command > (TOSHIBA_NAND_CMD_ECC_STATUS) to know the exact bitflips. However, I > could not test this patch because I do not have a platform that > supports chip-> exec_op. Therefore, I post this patch as RFC. > > As soon as I get a platform that supports chip-> exec_op, I would like > to test and re-post. > > Signed-off-by: KOBAYASHI Yoshitake > --- > drivers/mtd/nand/raw/nand_toshiba.c | 76 > +++++++++++++++++++++++++++++-------- 1 file changed, 61 > insertions(+), 15 deletions(-) > > diff --git a/drivers/mtd/nand/raw/nand_toshiba.c > b/drivers/mtd/nand/raw/nand_toshiba.c index 6cec923..12218cd 100644 > --- a/drivers/mtd/nand/raw/nand_toshiba.c > +++ b/drivers/mtd/nand/raw/nand_toshiba.c > @@ -17,28 +17,74 @@ > > #include > > +/* ECC Status Read Command for BENAND */ > +#define TOSHIBA_NAND_CMD_ECC_STATUS_READ 0x7A > + > +/* ECC Status Mask for BENAND */ > +#define TOSHIBA_NAND_ECC_STATUS_MASK 0x0F > + > /* Recommended to rewrite for BENAND */ > #define TOSHIBA_NAND_STATUS_REWRITE_RECOMMENDED BIT(3) > > +static int toshiba_nand_benand_read_eccstatus_op(struct nand_chip > *chip, > + u8 *buf) > +{ > + u8 *ecc_status = buf; > + How about letting this function return -ENOTSUPP when ->exec_op() is not implemented? if (!chip->exec_op) return -ENOTSUPP; > + const struct nand_sdr_timings *sdr = > + nand_get_sdr_timings(&chip->data_interface); > + struct nand_op_instr instrs[] = { > + NAND_OP_CMD(TOSHIBA_NAND_CMD_ECC_STATUS_READ, > + PSEC_TO_NSEC(sdr->tADL_min)), > + NAND_OP_8BIT_DATA_IN(chip->ecc.steps, ecc_status, 0), > + }; > + struct nand_operation op = NAND_OPERATION(instrs); > + > + /* Drop the DATA_IN instruction if chip->ecc.steps is set to > 0. */ > + if (!chip->ecc.steps) Can this really happen? I hope not. > + op.ninstrs--; > + > + return nand_exec_op(chip, &op); > +} > + > static int toshiba_nand_benand_eccstatus(struct mtd_info *mtd, > struct nand_chip *chip) > { > - int ret; > + int ret, i; > unsigned int max_bitflips = 0; > - u8 status; > - > - /* Check Status */ > - ret = nand_status_op(chip, &status); > - if (ret) > - return ret; > - > - if (status & NAND_STATUS_FAIL) { > - /* uncorrected */ > - mtd->ecc_stats.failed++; > - } else if (status & TOSHIBA_NAND_STATUS_REWRITE_RECOMMENDED) > { > - /* corrected */ > - max_bitflips = mtd->bitflip_threshold; > - mtd->ecc_stats.corrected += max_bitflips; > + u8 status, bitflips, ecc_status[8]; > + > + if (chip->exec_op) { > + /* Check ECC Status */ > + ret = toshiba_nand_benand_read_eccstatus_op(chip, > ecc_status); > + if (ret) > + return ret; > + > + for (i = 0; i < chip->ecc.steps; i++) { > + bitflips = (ecc_status[i] & > + TOSHIBA_NAND_ECC_STATUS_MASK); Unneeded parens. > + if (bitflips == 0x0F) { Please define a macro for the UNCORRECTABLE (0xf) value. > + mtd->ecc_stats.failed++; > + } else { > + mtd->ecc_stats.corrected += bitflips; > + max_bitflips = max_t(unsigned int, > + max_bitflips, > bitflips); Declare bitflips as an unsigned int, so that you can use max() instead of max_t(). > + } > + } > + } else { > + /* Check Status */ > + ret = nand_status_op(chip, &status); > + if (ret) > + return ret; > + > + if (status & NAND_STATUS_FAIL) { > + /* uncorrected */ > + mtd->ecc_stats.failed++; > + } else if (status & > TOSHIBA_NAND_STATUS_REWRITE_RECOMMENDED) { > + /* corrected */ > + max_bitflips = mtd->bitflip_threshold; > + mtd->ecc_stats.corrected += max_bitflips; > + } > } If you go for the "toshiba_nand_benand_read_eccstatus_op() returns -ENOTSUPP solution", you could replace the above section by: ret = toshiba_nand_benand_read_eccstatus_op(chip, ecc_status); if (!ret) { u8 ecc_status[8]; unsigned int i; for (i = 0; i < chip->ecc.steps; i++) { bitflips = ecc_status[i] & TOSHIBA_NAND_ECC_STATUS_MASK; if (bitflips == TOSHIBA_NAND_ECC_STATUS_UNCORR) { mtd->ecc_stats.failed++; } else { mtd->ecc_stats.corrected += bitflips; max_bitflips = max(max_bitflips,bitflips); } } return max_bitflips; } /* * Fallback to regular status check if * toshiba_nand_benand_read_eccstatus_op() failed. */ ret = nand_status_op(chip, &status); if (ret) return ret; if (status & NAND_STATUS_FAIL) { /* uncorrected */ mtd->ecc_stats.failed++; } else if (status & TOSHIBA_NAND_STATUS_REWRITE_RECOMMENDED) { /* corrected */ max_bitflips = mtd->bitflip_threshold; mtd->ecc_stats.corrected += max_bitflips; } return max_bitflips; }