aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/mtdcore.c
diff options
context:
space:
mode:
authorChristian Riesch <christian.riesch@omicron.at>2014-03-06 06:42:37 -0500
committerBrian Norris <computersforpeace@gmail.com>2014-03-11 01:42:31 -0400
commit9a78bc83b4c31f67202b7b0a77fa25da732f44a3 (patch)
tree386d354b6cba9a22eca92c07ab10206c476c955a /drivers/mtd/mtdcore.c
parentea6d833a3fddcd1d60414d48f34c7f4fbe88608f (diff)
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/mtdcore.c')
-rw-r--r--drivers/mtd/mtdcore.c12
1 files changed, 11 insertions, 1 deletions
diff --git a/drivers/mtd/mtdcore.c b/drivers/mtd/mtdcore.c
index 0a7d77e65335..d201feeb3ca6 100644
--- a/drivers/mtd/mtdcore.c
+++ b/drivers/mtd/mtdcore.c
@@ -932,12 +932,22 @@ EXPORT_SYMBOL_GPL(mtd_read_user_prot_reg);
932int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len, 932int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len,
933 size_t *retlen, u_char *buf) 933 size_t *retlen, u_char *buf)
934{ 934{
935 int ret;
936
935 *retlen = 0; 937 *retlen = 0;
936 if (!mtd->_write_user_prot_reg) 938 if (!mtd->_write_user_prot_reg)
937 return -EOPNOTSUPP; 939 return -EOPNOTSUPP;
938 if (!len) 940 if (!len)
939 return 0; 941 return 0;
940 return mtd->_write_user_prot_reg(mtd, to, len, retlen, buf); 942 ret = mtd->_write_user_prot_reg(mtd, to, len, retlen, buf);
943 if (ret)
944 return ret;
945
946 /*
947 * If no data could be written at all, we are out of memory and
948 * must return -ENOSPC.
949 */
950 return (*retlen) ? 0 : -ENOSPC;
941} 951}
942EXPORT_SYMBOL_GPL(mtd_write_user_prot_reg); 952EXPORT_SYMBOL_GPL(mtd_write_user_prot_reg);
943 953