From patchwork Thu May 19 16:49:24 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Gardiner X-Patchwork-Id: 96427 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from theia.denx.de (theia.denx.de [85.214.87.163]) by ozlabs.org (Postfix) with ESMTP id AEBACB6F88 for ; Fri, 20 May 2011 02:50:10 +1000 (EST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 8FECE280CD; Thu, 19 May 2011 18:49:54 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id v-UAYtPwyGfU; Thu, 19 May 2011 18:49:54 +0200 (CEST) Received: from theia.denx.de (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 2B22A280A7; Thu, 19 May 2011 18:49:43 +0200 (CEST) Received: from localhost (localhost [127.0.0.1]) by theia.denx.de (Postfix) with ESMTP id 9D9A32807E for ; Thu, 19 May 2011 18:49:37 +0200 (CEST) X-Virus-Scanned: Debian amavisd-new at theia.denx.de Received: from theia.denx.de ([127.0.0.1]) by localhost (theia.denx.de [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id xLEPGs5czUit for ; Thu, 19 May 2011 18:49:36 +0200 (CEST) X-policyd-weight: NOT_IN_SBL_XBL_SPAMHAUS=-1.5 NOT_IN_SPAMCOP=-1.5 NOT_IN_BL_NJABL=-1.5 (only DNSBL check requested) Received: from na3sys009aog108.obsmtp.com (na3sys009aog108.obsmtp.com [74.125.149.199]) by theia.denx.de (Postfix) with ESMTPS id 0557B2808B for ; Thu, 19 May 2011 18:49:33 +0200 (CEST) Received: from mail-yx0-f182.google.com ([209.85.213.182]) (using TLSv1) by na3sys009aob108.postini.com ([74.125.148.12]) with SMTP ID DSNKTdVKGy9C59M3Hf7gHDhjmue5IQtIaon2@postini.com; Thu, 19 May 2011 09:49:35 PDT Received: by mail-yx0-f182.google.com with SMTP id 31so1583110yxl.27 for ; Thu, 19 May 2011 09:49:31 -0700 (PDT) Received: by 10.101.141.11 with SMTP id t11mr1895034ann.137.1305823771536; Thu, 19 May 2011 09:49:31 -0700 (PDT) Received: from localhost.localdomain ([206.191.47.130]) by mx.google.com with ESMTPS id o6sm1944761ank.47.2011.05.19.09.49.30 (version=TLSv1/SSLv3 cipher=OTHER); Thu, 19 May 2011 09:49:31 -0700 (PDT) From: Ben Gardiner To: Scott Wood , u-boot@lists.denx.de Date: Thu, 19 May 2011 12:49:24 -0400 Message-Id: <5f4c5335ba60c7a41055d7069d92bbc46a5f8366.1305823168.git.bengardiner@nanometrics.ca> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: References: Cc: Artem Bityutskiy Subject: [U-Boot] [PATCH 3/4] [v2] nand_util: drop trailing all-0xff pages if requested X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.9 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: u-boot-bounces@lists.denx.de Errors-To: u-boot-bounces@lists.denx.de Add a flag to nand_read_skip_bad() such that if true, any trailing pages in an eraseblock whose contents are entirely 0xff will be dropped. The implementation is via a new drop_ffs() function which is based on the function of the same name from the ubiformat utility by Artem Bityutskiy. This is as-per the reccomendations of the UBI FAQ [1] Signed-off-by: Ben Gardiner CC: Artem Bityutskiy [1] http://www.linux-mtd.infradead.org/doc/ubi.html#L_flasher_algo Acked-by: Detlev Zundel --- This behaviour was found to fix both UBI and JFFS2 images written to cleanly erased NAND partitions on da850evm. Changes since v1: * rebased to HEAD of git://git.denx.de/u-boot-nand-flash.git : ff7b4a0 ("env_nand: zero-initialize variable nand_erase_options") * wrap the new functionality in a CONFIG_CMD_NAND_TRIMFFS ifdef to reduce size impact of new feature --- drivers/mtd/nand/nand_util.c | 32 +++++++++++++++++++++++++++++--- include/nand.h | 1 + 2 files changed, 30 insertions(+), 3 deletions(-) diff --git a/drivers/mtd/nand/nand_util.c b/drivers/mtd/nand/nand_util.c index 03ccd02..2bfe743 100644 --- a/drivers/mtd/nand/nand_util.c +++ b/drivers/mtd/nand/nand_util.c @@ -436,6 +436,24 @@ static int check_skip_len(nand_info_t *nand, loff_t offset, size_t length) return ret; } +#ifdef CONFIG_CMD_NAND_TRIMFFS +static size_t drop_ffs(const nand_info_t *nand, const u_char *buf, + const size_t *len) +{ + size_t i, l = *len; + + for (i = l - 1; i >= 0; i--) + if (((const uint8_t *)buf)[i] != 0xFF) + break; + + /* The resulting length must be aligned to the minimum flash I/O size */ + l = i + 1; + l = (l + nand->writesize - 1) / nand->writesize; + l *= nand->writesize; + return l; +} +#endif + /** * nand_write_skip_bad: * @@ -499,7 +517,7 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, return -EINVAL; } - if (!need_skip) { + if (!need_skip && !(flags & WITH_DROP_FFS)) { rval = nand_write (nand, offset, length, buffer); if (rval == 0) return 0; @@ -512,7 +530,7 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, while (left_to_write > 0) { size_t block_offset = offset & (nand->erasesize - 1); - size_t write_size; + size_t write_size, truncated_write_size; WATCHDOG_RESET (); @@ -558,7 +576,15 @@ int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, else #endif { - rval = nand_write (nand, offset, &write_size, p_buffer); + truncated_write_size = write_size; +#ifdef CONFIG_CMD_NAND_TRIMFFS + if (flags & WITH_DROP_FFS) + truncated_write_size = drop_ffs(nand, p_buffer, + &write_size); +#endif + + rval = nand_write(nand, offset, &truncated_write_size, + p_buffer); offset += write_size; p_buffer += write_size; } diff --git a/include/nand.h b/include/nand.h index 95b83a0..a5368e2 100644 --- a/include/nand.h +++ b/include/nand.h @@ -116,6 +116,7 @@ int nand_read_skip_bad(nand_info_t *nand, loff_t offset, size_t *length, u_char *buffer); #define WITH_YAFFS_OOB (1 << 0) /* whether write with yaffs format */ +#define WITH_DROP_FFS (1 << 1) /* drop trailing all-0xff pages */ #define WITH_DEFAULTS 0 int nand_write_skip_bad(nand_info_t *nand, loff_t offset, size_t *length,