summaryrefslogtreecommitdiffstats
path: root/drivers/mtd/devices/mtd_dataflash.c
diff options
context:
space:
mode:
authorChristian Riesch <christian.riesch@omicron.at>2014-03-06 12:42:37 +0100
committerBrian Norris <computersforpeace@gmail.com>2014-03-10 22:42:31 -0700
commit9a78bc83b4c31f67202b7b0a77fa25da732f44a3 (patch)
tree386d354b6cba9a22eca92c07ab10206c476c955a /drivers/mtd/devices/mtd_dataflash.c
parentea6d833a3fddcd1d60414d48f34c7f4fbe88608f (diff)
downloadop-kernel-dev-9a78bc83b4c31f67202b7b0a77fa25da732f44a3.zip
op-kernel-dev-9a78bc83b4c31f67202b7b0a77fa25da732f44a3.tar.gz
mtd: Fix the behavior of OTP write if there is not enough room for data
If a write to one time programmable memory (OTP) hits the end of this memory area, no more data can be written. The count variable in mtdchar_write() in drivers/mtd/mtdchar.c is not decreased anymore. We are trapped in the loop forever, mtdchar_write() will never return in this case. The desired behavior of a write in such a case is described in [1]: - Try to write as much data as possible, truncate the write to fit into the available memory and return the number of bytes that actually have been written. - If no data could be written at all, return -ENOSPC. This patch fixes the behavior of OTP write if there is not enough space for all data: 1) mtd_write_user_prot_reg() in drivers/mtd/mtdcore.c is modified to return -ENOSPC if no data could be written at all. 2) mtdchar_write() is modified to handle -ENOSPC correctly. Exit if a write returned -ENOSPC and yield the correct return value, either then number of bytes that could be written, or -ENOSPC, if no data could be written at all. Furthermore the patch harmonizes the behavior of the OTP memory write in drivers/mtd/devices/mtd_dataflash.c with the other implementations and the requirements from [1]. Instead of returning -EINVAL if the data does not fit into the OTP memory, we try to write as much data as possible/truncate the write. [1] http://pubs.opengroup.org/onlinepubs/9699919799/functions/write.html Signed-off-by: Christian Riesch <christian.riesch@omicron.at> Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Diffstat (limited to 'drivers/mtd/devices/mtd_dataflash.c')
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index a6fdbe8..dd22ce2 100644
--- a/drivers/mtd/devices/mtd_dataflash.c
+++ b/drivers/mtd/devices/mtd_dataflash.c
@@ -542,14 +542,18 @@ static int dataflash_write_user_otp(struct mtd_info *mtd,
struct dataflash *priv = mtd->priv;
int status;
- if (len > 64)
- return -EINVAL;
+ if (from >= 64) {
+ /*
+ * Attempting to write beyond the end of OTP memory,
+ * no data can be written.
+ */
+ *retlen = 0;
+ return 0;
+ }
- /* Strictly speaking, we *could* truncate the write ... but
- * let's not do that for the only write that's ever possible.
- */
+ /* Truncate the write to fit into OTP memory. */
if ((from + len) > 64)
- return -EINVAL;
+ len = 64 - from;
/* OUT: OP_WRITE_SECURITY, 3 zeroes, 64 data-or-zero bytes
* IN: ignore all
OpenPOWER on IntegriCloud