mtd: Fix the behavior of OTP write if there is not enough room for data
authorChristian Riesch <christian.riesch@omicron.at>
Thu, 6 Mar 2014 11:42:37 +0000 (12:42 +0100)
committerBrian Norris <computersforpeace@gmail.com>
Tue, 11 Mar 2014 05:42:31 +0000 (22:42 -0700)
commit9a78bc83b4c31f67202b7b0a77fa25da732f44a3
tree386d354b6cba9a22eca92c07ab10206c476c955a
parentea6d833a3fddcd1d60414d48f34c7f4fbe88608f
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>
drivers/mtd/devices/mtd_dataflash.c
drivers/mtd/mtdchar.c
drivers/mtd/mtdcore.c