@@ -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,
@@ -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
@@ -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;
@@ -3316,7 +3316,16 @@ 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;
}
/**
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 <christian.riesch@omicron.at> Cc: Artem Bityutskiy <artem.bityutskiy@linux.intel.com> Cc: Kyungmin Park <kyungmin.park@samsung.com> Cc: Amul Kumar Saha <amul.saha@samsung.com> --- 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 | 11 ++++++++++- 4 files changed, 33 insertions(+), 11 deletions(-)