From patchwork Tue Jan 28 08:29:45 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Christian Riesch X-Patchwork-Id: 314624 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from casper.infradead.org (casper.infradead.org [IPv6:2001:770:15f::2]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 515EF2C009F for ; Tue, 28 Jan 2014 19:31:00 +1100 (EST) Received: from merlin.infradead.org ([2001:4978:20e::2]) by casper.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1W844J-0003jP-NZ; Tue, 28 Jan 2014 08:30:51 +0000 Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.80.1 #2 (Red Hat Linux)) id 1W844I-0006ho-4a; Tue, 28 Jan 2014 08:30:50 +0000 Received: from ns.omicron.at ([212.183.10.25]) by merlin.infradead.org with esmtps (Exim 4.80.1 #2 (Red Hat Linux)) id 1W844E-0006gX-7S for linux-mtd@lists.infradead.org; Tue, 28 Jan 2014 08:30:47 +0000 Received: from counter.omicron.at ([212.183.10.29]) by ns.omicron.at (8.13.1/8.13.1) with ESMTP id s0S8TrY2018080; Tue, 28 Jan 2014 09:29:58 +0100 Received: from mary.at.omicron.at (mary.at.omicron.at [172.22.100.48]) by counter.omicron.at (8.14.4/8.14.4) with ESMTP id s0S8Tq78019433; Tue, 28 Jan 2014 09:29:52 +0100 Received: from ChrRie22.omicron.at (172.22.2.20) by mary-special.at.omicron.at (172.22.100.48) with Microsoft SMTP Server id 8.3.327.1; Tue, 28 Jan 2014 09:29:52 +0100 From: Christian Riesch To: Subject: [PATCH v2 RESEND 2/2] mtd: Fix the behavior of otp write if there is not enough room for data Date: Tue, 28 Jan 2014 09:29:45 +0100 X-Mailer: git-send-email 1.7.9.5 In-Reply-To: <1390897785-991-1-git-send-email-christian.riesch@omicron.at> References: <1390897785-991-1-git-send-email-christian.riesch@omicron.at> MIME-Version: 1.0 Message-ID: X-CRM114-Version: 20100106-BlameMichelson ( TRE 0.8.0 (BSD) ) MR-646709E3 X-CRM114-CacheID: sfid-20140128_033046_552580_86866C20 X-CRM114-Status: GOOD ( 18.49 ) X-Spam-Score: -2.4 (--) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-2.4 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 SPF_PASS SPF: sender matches SPF record -0.5 RP_MATCHES_RCVD Envelope sender domain matches handover relay domain 0.0 T_TVD_FUZZY_SECURITIES BODY: T_TVD_FUZZY_SECURITIES -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Amul Kumar Saha , Artem Bityutskiy , Kyungmin Park , Christian Riesch , linux-kernel@vger.kernel.org X-BeenThere: linux-mtd@lists.infradead.org X-Mailman-Version: 2.1.15 Precedence: list List-Id: Linux MTD discussion mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Sender: "linux-mtd" Errors-To: linux-mtd-bounces+incoming=patchwork.ozlabs.org@lists.infradead.org An OTP write shall write as much data as possible to the OTP memory and return the number of bytes that have actually been written. If no data could be written at all due to lack of OTP memory, return -ENOSPC. Signed-off-by: Christian Riesch Cc: Artem Bityutskiy Cc: Kyungmin Park Cc: Amul Kumar Saha --- drivers/mtd/chips/cfi_cmdset_0001.c | 13 +++++++++++-- drivers/mtd/devices/mtd_dataflash.c | 13 +++++-------- drivers/mtd/mtdchar.c | 7 +++++++ drivers/mtd/onenand/onenand_base.c | 10 +++++++++- 4 files changed, 32 insertions(+), 11 deletions(-) diff --git a/drivers/mtd/chips/cfi_cmdset_0001.c b/drivers/mtd/chips/cfi_cmdset_0001.c index 7aa581f..cf423a6 100644 --- a/drivers/mtd/chips/cfi_cmdset_0001.c +++ b/drivers/mtd/chips/cfi_cmdset_0001.c @@ -2387,8 +2387,17 @@ static int cfi_intelext_write_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { - return cfi_intelext_otp_walk(mtd, from, len, retlen, - buf, do_otp_write, 1); + int ret; + + ret = cfi_intelext_otp_walk(mtd, from, len, retlen, + buf, do_otp_write, 1); + + /* if no data could be written due to lack of OTP memory, + return ENOSPC */ + if (!ret && len && !(*retlen)) + return -ENOSPC; + + return ret; } static int cfi_intelext_lock_user_prot_reg(struct mtd_info *mtd, diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c index 09c69ce..5236d85 100644 --- a/drivers/mtd/devices/mtd_dataflash.c +++ b/drivers/mtd/devices/mtd_dataflash.c @@ -545,14 +545,11 @@ static int dataflash_write_user_otp(struct mtd_info *mtd, struct dataflash *priv = mtd->priv; int status; - if (len > 64) - return -EINVAL; - - /* Strictly speaking, we *could* truncate the write ... but - * let's not do that for the only write that's ever possible. - */ - if ((from + len) > 64) - return -EINVAL; + if ((from + len) > 64) { + len = 64 - from; + if (len <= 0) + return -ENOSPC; + } /* OUT: OP_WRITE_SECURITY, 3 zeroes, 64 data-or-zero bytes * IN: ignore all diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c index 0edb0ca..db99031 100644 --- a/drivers/mtd/mtdchar.c +++ b/drivers/mtd/mtdchar.c @@ -323,6 +323,13 @@ static ssize_t mtdchar_write(struct file *file, const char __user *buf, size_t c default: ret = mtd_write(mtd, *ppos, len, &retlen, kbuf); } + /* return -ENOSPC only if no data was written */ + if ((ret == -ENOSPC) && (total_retlen)) { + ret = 0; + retlen = 0; + /* drop the remaining data */ + count = 0; + } if (!ret) { *ppos += retlen; total_retlen += retlen; diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c index 419c538..6c49a6f 100644 --- a/drivers/mtd/onenand/onenand_base.c +++ b/drivers/mtd/onenand/onenand_base.c @@ -3316,7 +3316,15 @@ static int onenand_read_user_prot_reg(struct mtd_info *mtd, loff_t from, static int onenand_write_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf) { - return onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write, MTD_OTP_USER); + int ret; + ret = onenand_otp_walk(mtd, from, len, retlen, buf, do_otp_write, MTD_OTP_USER); + + /* if no data could be written due to lack of OTP memory, + return ENOSPC */ + if (!ret && len && !(*retlen)) + return -ENOSPC; + + return ret; } /**