aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/mtd/devices/mtd_dataflash.c16
-rw-r--r--drivers/mtd/mtdchar.c9
-rw-r--r--drivers/mtd/mtdcore.c12
3 files changed, 30 insertions, 7 deletions
diff --git a/drivers/mtd/devices/mtd_dataflash.c b/drivers/mtd/devices/mtd_dataflash.c
index a6fdbe83bad6..dd22ce2cc9ad 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,
542 struct dataflash *priv = mtd->priv; 542 struct dataflash *priv = mtd->priv;
543 int status; 543 int status;
544 544
545 if (len > 64) 545 if (from >= 64) {
546 return -EINVAL; 546 /*
547 * Attempting to write beyond the end of OTP memory,
548 * no data can be written.
549 */
550 *retlen = 0;
551 return 0;
552 }
547 553
548 /* Strictly speaking, we *could* truncate the write ... but 554 /* Truncate the write to fit into OTP memory. */
549 * let's not do that for the only write that's ever possible.
550 */
551 if ((from + len) > 64) 555 if ((from + len) > 64)
552 return -EINVAL; 556 len = 64 - from;
553 557
554 /* OUT: OP_WRITE_SECURITY, 3 zeroes, 64 data-or-zero bytes 558 /* OUT: OP_WRITE_SECURITY, 3 zeroes, 64 data-or-zero bytes
555 * IN: ignore all 559 * IN: ignore all
diff --git a/drivers/mtd/mtdchar.c b/drivers/mtd/mtdchar.c
index 250798cf76aa..7d4e7b9da3a1 100644
--- a/drivers/mtd/mtdchar.c
+++ b/drivers/mtd/mtdchar.c
@@ -324,6 +324,15 @@ static ssize_t mtdchar_write(struct file *file, const char __user *buf, size_t c
324 default: 324 default:
325 ret = mtd_write(mtd, *ppos, len, &retlen, kbuf); 325 ret = mtd_write(mtd, *ppos, len, &retlen, kbuf);
326 } 326 }
327
328 /*
329 * Return -ENOSPC only if no data could be written at all.
330 * Otherwise just return the number of bytes that actually
331 * have been written.
332 */
333 if ((ret == -ENOSPC) && (total_retlen))
334 break;
335
327 if (!ret) { 336 if (!ret) {
328 *ppos += retlen; 337 *ppos += retlen;
329 total_retlen += retlen; 338 total_retlen += retlen;
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