Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S965301AbbD0Vgp (ORCPT ); Mon, 27 Apr 2015 17:36:45 -0400 Received: from skprod2.natinst.com ([130.164.80.23]:39894 "EHLO ni.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S965128AbbD0Vgk (ORCPT ); Mon, 27 Apr 2015 17:36:40 -0400 Date: Mon, 27 Apr 2015 16:35:58 -0500 From: Ben Shelton To: Richard Weinberger Cc: linux-mtd@lists.infradead.org, linux-kernel@vger.kernel.org, dwmw2@infradead.org, computersforpeace@gmail.com, punnaiah.choudary.kalluri@xilinx.com Subject: Re: [PATCH 1/3] mtd: nand: Add on-die ECC support Message-ID: <20150427213558.GA22780@bshelton-desktop> References: <1427292151-3835-1-git-send-email-richard@nod.at> <1427292151-3835-2-git-send-email-richard@nod.at> MIME-Version: 1.0 In-Reply-To: <1427292151-3835-2-git-send-email-richard@nod.at> User-Agent: Mutt/1.5.21 (2010-09-15) X-MIMETrack: Itemize by SMTP Server on US-AUS-MGWOut1/AUS/H/NIC(Release 8.5.3FP6|November 21, 2013) at 04/27/2015 04:36:05 PM, Serialize by Router on US-AUS-MGWOut1/AUS/H/NIC(Release 8.5.3FP6|November 21, 2013) at 04/27/2015 04:36:05 PM, Serialize complete at 04/27/2015 04:36:05 PM Content-Type: text/plain; charset=us-ascii Content-Disposition: inline X-Proofpoint-Virus-Version: vendor=fsecure engine=2.50.10432:,, definitions=2015-04-27_05:,, signatures=0 Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 3780 Lines: 103 Hi Richard, On 03/25, Richard Weinberger wrote: > Some Micron NAND chips offer an on-die ECC (AKA internal ECC) > feature. It is useful when the host-platform does not offer > multi-bit ECC and software ECC is not feasible. > > Based on original work by David Mosberger > > Signed-off-by: Richard Weinberger > --- [...] > + > +static int check_read_status_on_die(struct mtd_info *mtd, int page) > +{ > + struct nand_chip *chip = mtd->priv; > + int max_bitflips = 0; > + uint8_t status; > + > + /* Check ECC status of page just transferred into NAND's page buffer */ > + chip->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); > + status = chip->read_byte(mtd); > + > + /* Switch back to data reading */ > + chip->cmd_ctrl(mtd, NAND_CMD_READ0, NAND_NCE | NAND_CLE | NAND_CTRL_CHANGE); > + chip->cmd_ctrl(mtd, NAND_CMD_NONE, NAND_NCE | NAND_CTRL_CHANGE); I tested this against the latest version of the PL353 NAND driver that Punnaiah has been working to upstream (copying her on this message). With a few changes to that driver, I got it most of the way through initialization with on-die ECC enabled, but it segfaults here with a null pointer dereference because the PL353 driver does not implement chip->cmd_ctrl. Instead, it implements a custom override of cmd->cmdfunc that does not call cmd_ctrl. Looking through the other in-tree NAND drivers, it looks like most of them do implement cmd_ctrl, but quite a few of them do not (e.g. au1550nd, denali, docg4). What do you think would be the best way to handle this? It seems like this gap could be bridged from either side -- either the PL353 driver could implement cmd_ctrl, at least as a stub version that provides the expected behavior in this case; or the on-die framework could break this out into a callback function with a default implementation that the driver could override to perform this behavior in the manner of its choosing. > + > + if (status & NAND_STATUS_FAIL) { > + /* Page has invalid ECC */ > + mtd->ecc_stats.failed++; > + } else if (status & NAND_STATUS_REWRITE) { > + /* > + * Micron on-die ECC doesn't report the number of > + * bitflips, so we have to count them ourself to see > + * if the error rate is too high. This is > + * particularly important for pages with stuck bits. > + */ > + max_bitflips = check_for_bitflips(mtd, page); > + } > + return max_bitflips; > +} > + [...] > +#else /* !CONFIG_MTD_NAND_ECC_ON_DIE */ > +static inline int mtd_nand_has_on_die(void) { return 0; } > +static inline int nand_read_subpage_on_die(struct mtd_info *mtd, > + struct nand_chip *chip, > + uint32_t data_offs, > + uint32_t readlen, > + uint8_t *bufpoi, int page) > +{ > + BUG(); When I build this without CONFIG_MTD_NAND_ECC_ON_DIE enabled, I get the following warning here: In file included from drivers/mtd/nand/nand_base.c:46:0: include/linux/mtd/nand_ondie.h: In function 'nand_read_subpage_on_die': include/linux/mtd/nand_ondie.h:28:1: warning: no return statement in function returning non-void [-Wreturn-type] include/linux/mtd/nand_ondie.h: In function 'nand_read_page_on_die': include/linux/mtd/nand_ondie.h:34:1: warning: no return statement in function returning non-void [-Wreturn-type] Perhaps return an error code here, even though you'll never get past the BUG()? > +} > + > +static inline int nand_read_page_on_die(struct mtd_info *mtd, struct nand_chip *chip, > + uint8_t *buf, int oob_required, int page) > +{ > + BUG(); Same here. > +} Thanks, Ben -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/