Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1fbb938d authored by Brian Norris's avatar Brian Norris Committed by David Woodhouse
Browse files

mtd: nand: add 'oob_required' argument to NAND {read,write}_page interfaces



New NAND controllers can perform read/write via HW engines which don't expose
OOB data in their DMA mode. To reflect this, we should rework the nand_chip /
nand_ecc_ctrl interfaces that assume that drivers will always read/write OOB
data in the nand_chip.oob_poi buffer. A better interface includes a boolean
argument that explicitly tells the callee when OOB data is requested by the
calling layer (for reading/writing to/from nand_chip.oob_poi).

This patch adds the 'oob_required' parameter to each relevant {read,write}_page
interface; all 'oob_required' parameters are left unused for now. The next
patch will set the parameter properly in the nand_base.c callers, and follow-up
patches will make use of 'oob_required' in some of the callee functions.

Note that currently, there is no harm in ignoring the 'oob_required' parameter
and *always* utilizing nand_chip.oob_poi, but there can be
performance/complexity/design benefits from avoiding filling oob_poi in the
common case. I will try to implement this for some drivers which can be ported
easily.

Note: I couldn't compile-test all of these easily, as some had ARCH
dependencies.

[dwmw2: Merge later 1/0 vs. true/false cleanup]
Signed-off-by: default avatarBrian Norris <computersforpeace@gmail.com>
Reviewed-by: default avatarShmulik Ladkani <shmulik.ladkani@gmail.com>
Acked-by: default avatarJiandong Zheng <jdzheng@broadcom.com>
Acked-by: default avatarMike Dunn <mikedunn@newsguy.com>
Signed-off-by: default avatarArtem Bityutskiy <artem.bityutskiy@linux.intel.com>
Signed-off-by: default avatarDavid Woodhouse <David.Woodhouse@intel.com>
parent b4f7aa84
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -324,9 +324,10 @@ static int atmel_nand_calculate(struct mtd_info *mtd,
 * mtd:        mtd info structure
 * chip:       nand chip info structure
 * buf:        buffer to store read data
 * oob_required:    caller expects OOB data read to chip->oob_poi
 */
static int atmel_nand_read_page(struct mtd_info *mtd,
		struct nand_chip *chip, uint8_t *buf, int page)
static int atmel_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
				uint8_t *buf, int oob_required, int page)
{
	int eccsize = chip->ecc.size;
	int eccbytes = chip->ecc.bytes;
+6 −4
Original line number Diff line number Diff line
@@ -22,9 +22,9 @@

/* ---- Private Function Prototypes -------------------------------------- */
static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
	struct nand_chip *chip, uint8_t *buf, int page);
	struct nand_chip *chip, uint8_t *buf, int oob_required, int page);
static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd,
	struct nand_chip *chip, const uint8_t *buf);
	struct nand_chip *chip, const uint8_t *buf, int oob_required);

/* ---- Private Variables ------------------------------------------------ */

@@ -103,11 +103,12 @@ static struct nand_ecclayout nand_hw_eccoob_4096 = {
*  @mtd:	mtd info structure
*  @chip:	nand chip info structure
*  @buf:	buffer to store read data
*  @oob_required:	caller expects OOB data read to chip->oob_poi
*
***************************************************************************/
static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
				       struct nand_chip *chip, uint8_t * buf,
						 int page)
				       int oob_required, int page)
{
	int sectorIdx = 0;
	int eccsize = chip->ecc.size;
@@ -190,10 +191,11 @@ static int bcm_umi_bch_read_page_hwecc(struct mtd_info *mtd,
*  @mtd:	mtd info structure
*  @chip:	nand chip info structure
*  @buf:	data buffer
*  @oob_required:	must write chip->oob_poi to OOB
*
***************************************************************************/
static void bcm_umi_bch_write_page_hwecc(struct mtd_info *mtd,
	struct nand_chip *chip, const uint8_t *buf)
	struct nand_chip *chip, const uint8_t *buf, int oob_required)
{
	int sectorIdx = 0;
	int eccsize = chip->ecc.size;
+1 −1
Original line number Diff line number Diff line
@@ -341,7 +341,7 @@ static int bcm_umi_nand_verify_buf(struct mtd_info *mtd, const u_char * buf,
	 * for MLC parts which may have permanently stuck bits.
	 */
	struct nand_chip *chip = mtd->priv;
	int ret = chip->ecc.read_page(mtd, chip, readbackbuf, 0);
	int ret = chip->ecc.read_page(mtd, chip, readbackbuf, 0, 0);
	if (ret < 0)
		return -EFAULT;
	else {
+2 −2
Original line number Diff line number Diff line
@@ -558,7 +558,7 @@ static void bf5xx_nand_dma_write_buf(struct mtd_info *mtd,
}

static int bf5xx_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
		uint8_t *buf, int page)
		uint8_t *buf, int oob_required, int page)
{
	bf5xx_nand_read_buf(mtd, buf, mtd->writesize);
	bf5xx_nand_read_buf(mtd, chip->oob_poi, mtd->oobsize);
@@ -567,7 +567,7 @@ static int bf5xx_nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip
}

static void bf5xx_nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
		const uint8_t *buf)
		const uint8_t *buf, int oob_required)
{
	bf5xx_nand_write_buf(mtd, buf, mtd->writesize);
	bf5xx_nand_write_buf(mtd, chip->oob_poi, mtd->oobsize);
+8 −5
Original line number Diff line number Diff line
@@ -375,12 +375,13 @@ static int cafe_nand_read_oob(struct mtd_info *mtd, struct nand_chip *chip,
 * @mtd:	mtd info structure
 * @chip:	nand chip info structure
 * @buf:	buffer to store read data
 * @oob_required:	caller expects OOB data read to chip->oob_poi
 *
 * The hw generator calculates the error syndrome automatically. Therefor
 * we need a special oob layout and handling.
 */
static int cafe_nand_read_page(struct mtd_info *mtd, struct nand_chip *chip,
			       uint8_t *buf, int page)
			       uint8_t *buf, int oob_required, int page)
{
	struct cafe_priv *cafe = mtd->priv;
	unsigned int max_bitflips = 0;
@@ -520,7 +521,8 @@ static struct nand_bbt_descr cafe_bbt_mirror_descr_512 = {


static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd,
					  struct nand_chip *chip, const uint8_t *buf)
					  struct nand_chip *chip,
					  const uint8_t *buf, int oob_required)
{
	struct cafe_priv *cafe = mtd->priv;

@@ -532,16 +534,17 @@ static void cafe_nand_write_page_lowlevel(struct mtd_info *mtd,
}

static int cafe_nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
				const uint8_t *buf, int page, int cached, int raw)
				const uint8_t *buf, int oob_required, int page,
				int cached, int raw)
{
	int status;

	chip->cmdfunc(mtd, NAND_CMD_SEQIN, 0x00, page);

	if (unlikely(raw))
		chip->ecc.write_page_raw(mtd, chip, buf);
		chip->ecc.write_page_raw(mtd, chip, buf, oob_required);
	else
		chip->ecc.write_page(mtd, chip, buf);
		chip->ecc.write_page(mtd, chip, buf, oob_required);

	/*
	 * Cached progamming disabled for now, Not sure if its worth the
Loading