From bc3eebb25d5ee340e56047d0e46b81d5af85ff17 Mon Sep 17 00:00:00 2001 From: Yann Gautier Date: Wed, 5 Aug 2020 14:39:00 +0200 Subject: [PATCH] feat(nand): count bad blocks before a given offset In case of FIP, the offsets given in the FIP header are relative. If bad blocks are found between the FIP base address and this offset, the offset should be updated, taking care of the bad blocks. Change-Id: I96fefabb583b3d030ab05191bae7d45cfeefe341 Signed-off-by: Lionel Debieve Signed-off-by: Yann Gautier --- drivers/mtd/nand/core.c | 43 ++++++++++++++++++++++++++++++++++++++++- include/drivers/nand.h | 12 +++++++++++- 2 files changed, 53 insertions(+), 2 deletions(-) diff --git a/drivers/mtd/nand/core.c b/drivers/mtd/nand/core.c index 44b001e35..9f0331ad7 100644 --- a/drivers/mtd/nand/core.c +++ b/drivers/mtd/nand/core.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -112,6 +112,47 @@ int nand_read(unsigned int offset, uintptr_t buffer, size_t length, return 0; } +int nand_seek_bb(uintptr_t base, unsigned int offset, size_t *extra_offset) +{ + unsigned int block; + unsigned int offset_block; + unsigned int max_block; + int is_bad; + size_t count_bb = 0U; + + block = base / nand_dev.block_size; + + if (offset != 0U) { + offset_block = (base + offset - 1U) / nand_dev.block_size; + } else { + offset_block = block; + } + + max_block = nand_dev.size / nand_dev.block_size; + + while (block <= offset_block) { + if (offset_block >= max_block) { + return -EIO; + } + + is_bad = nand_dev.mtd_block_is_bad(block); + if (is_bad < 0) { + return is_bad; + } + + if (is_bad == 1) { + count_bb++; + offset_block++; + } + + block++; + } + + *extra_offset = count_bb * nand_dev.block_size; + + return 0; +} + struct nand_device *get_nand_device(void) { return &nand_dev; diff --git a/include/drivers/nand.h b/include/drivers/nand.h index 1dbb008f9..1b78ad41b 100644 --- a/include/drivers/nand.h +++ b/include/drivers/nand.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, STMicroelectronics - All Rights Reserved + * Copyright (c) 2019-2021, STMicroelectronics - All Rights Reserved * * SPDX-License-Identifier: BSD-3-Clause */ @@ -45,6 +45,16 @@ struct nand_device { int nand_read(unsigned int offset, uintptr_t buffer, size_t length, size_t *length_read); +/* + * Look for an extra offset to be added in case of bad blocks + * + * @base: Base address of the area + * @offset: Byte offset to read from in device + * @extra_offset: [out] Extra offset to be added if bad blocks are found + * Return: 0 on success, a negative errno on failure + */ +int nand_seek_bb(uintptr_t base, unsigned int offset, size_t *extra_offset); + /* * Get NAND device instance *