From patchwork Mon Jul 30 15:46:34 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Miquel Raynal X-Patchwork-Id: 951073 X-Patchwork-Delegate: jagannadh.teki@gmail.com Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=lists.denx.de (client-ip=81.169.180.215; helo=lists.denx.de; envelope-from=u-boot-bounces@lists.denx.de; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=bootlin.com Received: from lists.denx.de (dione.denx.de [81.169.180.215]) by ozlabs.org (Postfix) with ESMTP id 41fPKG0xNbz9ryt for ; Tue, 31 Jul 2018 01:54:58 +1000 (AEST) Received: by lists.denx.de (Postfix, from userid 105) id D1A56C21FDB; Mon, 30 Jul 2018 15:49:05 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on lists.denx.de X-Spam-Level: X-Spam-Status: No, score=0.0 required=5.0 tests=KHOP_BIG_TO_CC autolearn=unavailable autolearn_force=no version=3.4.0 Received: from lists.denx.de (localhost [IPv6:::1]) by lists.denx.de (Postfix) with ESMTP id C7088C22048; Mon, 30 Jul 2018 15:47:36 +0000 (UTC) Received: by lists.denx.de (Postfix, from userid 105) id EDF48C22008; Mon, 30 Jul 2018 15:47:27 +0000 (UTC) Received: from mail.bootlin.com (mail.bootlin.com [62.4.15.54]) by lists.denx.de (Postfix) with ESMTP id EF7ABC22022 for ; Mon, 30 Jul 2018 15:47:19 +0000 (UTC) Received: by mail.bootlin.com (Postfix, from userid 110) id A9DED20731; Mon, 30 Jul 2018 17:47:18 +0200 (CEST) Received: from localhost.localdomain (AAubervilliers-681-1-89-120.w90-88.abo.wanadoo.fr [90.88.30.120]) by mail.bootlin.com (Postfix) with ESMTPSA id 885FB2082B; Mon, 30 Jul 2018 17:46:59 +0200 (CEST) From: Miquel Raynal To: Tom Rini , Daniel Schwierzeck Date: Mon, 30 Jul 2018 17:46:34 +0200 Message-Id: <20180730154657.20738-5-miquel.raynal@bootlin.com> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180730154657.20738-1-miquel.raynal@bootlin.com> References: <20180730154657.20738-1-miquel.raynal@bootlin.com> Cc: Scott Wood , Alexandre Belloni , Boris Brezillon , Antoine Tenart , Allan Nielsen , u-boot@lists.denx.de, Miquel Raynal , Stefan Roese , Jagan Teki Subject: [U-Boot] [PATCH v5 04/27] mtd: Fallback to ->_read/write() when ->_read/write_oob() is missing X-BeenThere: u-boot@lists.denx.de X-Mailman-Version: 2.1.18 Precedence: list List-Id: U-Boot discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: u-boot-bounces@lists.denx.de Sender: "U-Boot" Some MTD sublayers/drivers are implementing ->_read/write() and not ->_read/write_oob(). While for NAND devices both are usually valid, for NOR devices, using the _oob variant has no real meaning. But, as the MTD layer is supposed to hide as much as possible the flash complexity to the user, there is no reason to error out while it is just a matter of rewritting things internally. Add a fallback on mtd->_read() (resp. mtd->_write()) when the user calls mtd_read_oob() (resp. mtd_write_oob()) while mtd->_read_oob() (resp. mtd->_write_oob) is not implemented. There is already a fallback on the _oob variant if the former is used. Signed-off-by: Miquel Raynal --- drivers/mtd/mtdcore.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c index 9a3efe95df..fb1d68d5e2 100644 --- a/drivers/mtd/mtdcore.c +++ b/drivers/mtd/mtdcore.c @@ -1047,20 +1047,27 @@ int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops) { int ret_code; ops->retlen = ops->oobretlen = 0; - if (!mtd->_read_oob) - return -EOPNOTSUPP; ret_code = mtd_check_oob_ops(mtd, from, ops); if (ret_code) return ret_code; + /* Check the validity of a potential fallback on mtd->_read */ + if (!mtd->_read_oob && (!mtd->_read || ops->oobbuf)) + return -EOPNOTSUPP; + + if (mtd->_read_oob) + ret_code = mtd->_read_oob(mtd, from, ops); + else + ret_code = mtd->_read(mtd, from, ops->len, &ops->retlen, + ops->datbuf); + /* * In cases where ops->datbuf != NULL, mtd->_read_oob() has semantics * similar to mtd->_read(), returning a non-negative integer * representing max bitflips. In other cases, mtd->_read_oob() may * return -EUCLEAN. In all cases, perform similar logic to mtd_read(). */ - ret_code = mtd->_read_oob(mtd, from, ops); if (unlikely(ret_code < 0)) return ret_code; if (mtd->ecc_strength == 0) @@ -1075,8 +1082,7 @@ int mtd_write_oob(struct mtd_info *mtd, loff_t to, int ret; ops->retlen = ops->oobretlen = 0; - if (!mtd->_write_oob) - return -EOPNOTSUPP; + if (!(mtd->flags & MTD_WRITEABLE)) return -EROFS; @@ -1084,7 +1090,15 @@ int mtd_write_oob(struct mtd_info *mtd, loff_t to, if (ret) return ret; - return mtd->_write_oob(mtd, to, ops); + /* Check the validity of a potential fallback on mtd->_write */ + if (!mtd->_write_oob && (!mtd->_write || ops->oobbuf)) + return -EOPNOTSUPP; + + if (mtd->_write_oob) + return mtd->_write_oob(mtd, to, ops); + else + return mtd->_write(mtd, to, ops->len, &ops->retlen, + ops->datbuf); } EXPORT_SYMBOL_GPL(mtd_write_oob);