diff options
author | Brian Norris <computersforpeace@gmail.com> | 2011-08-30 21:45:37 -0400 |
---|---|---|
committer | Artem Bityutskiy <artem.bityutskiy@intel.com> | 2011-09-11 08:02:18 -0400 |
commit | 9ce244b3fb416ce6600e05612ac46b9692dcc638 (patch) | |
tree | 34b9b77f38ce65f8efe9f9f40e71efd22bc43507 /include | |
parent | 10a2bcae99267b28e058b089fda30de7397b69f5 (diff) |
mtd: support writing OOB without ECC
This fixes issues with `nandwrite -n -o' and the MEMWRITEOOB[64] ioctls
on hardware that writes ECC when writing OOB. The problem arises as
follows: `nandwrite -n' can write page data to flash without applying
ECC, but when used with the `-o' option, ECC is applied (incorrectly),
contrary to the `--noecc' option.
I found that this is the case because my hardware computes and writes
ECC data to flash upon either OOB write or page write. Thus, to support
a proper "no ECC" write, my driver must know when we're performing a raw
OOB write vs. a normal ECC OOB write. However, MTD does not pass any raw
mode information to the write_oob functions. This patch addresses the
problems by:
1) Passing MTD_OOB_RAW down to lower layers, instead of just defaulting
to MTD_OOB_PLACE
2) Handling MTD_OOB_RAW within the NAND layer's `nand_do_write_oob'
3) Adding a new (replaceable) function pointer in struct ecc_ctrl; this
function should support writing OOB without ECC data. Current
hardware often can use the same OOB write function when writing
either with or without ECC
This was tested with nandsim as well as on actual SLC NAND.
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Cc: Jim Quinlan <jim2101024@gmail.com>
Signed-off-by: Artem Bityutskiy <artem.bityutskiy@intel.com>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/mtd/nand.h | 3 |
1 files changed, 3 insertions, 0 deletions
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 85fef68a379d..5f3fdd9877b7 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h | |||
@@ -340,6 +340,7 @@ struct nand_hw_control { | |||
340 | * @read_subpage: function to read parts of the page covered by ECC. | 340 | * @read_subpage: function to read parts of the page covered by ECC. |
341 | * @write_page: function to write a page according to the ECC generator | 341 | * @write_page: function to write a page according to the ECC generator |
342 | * requirements. | 342 | * requirements. |
343 | * @write_oob_raw: function to write chip OOB data without ECC | ||
343 | * @read_oob: function to read chip OOB data | 344 | * @read_oob: function to read chip OOB data |
344 | * @write_oob: function to write chip OOB data | 345 | * @write_oob: function to write chip OOB data |
345 | */ | 346 | */ |
@@ -368,6 +369,8 @@ struct nand_ecc_ctrl { | |||
368 | uint32_t offs, uint32_t len, uint8_t *buf); | 369 | uint32_t offs, uint32_t len, uint8_t *buf); |
369 | void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip, | 370 | void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip, |
370 | const uint8_t *buf); | 371 | const uint8_t *buf); |
372 | int (*write_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip, | ||
373 | int page); | ||
371 | int (*read_oob)(struct mtd_info *mtd, struct nand_chip *chip, int page, | 374 | int (*read_oob)(struct mtd_info *mtd, struct nand_chip *chip, int page, |
372 | int sndcmd); | 375 | int sndcmd); |
373 | int (*write_oob)(struct mtd_info *mtd, struct nand_chip *chip, | 376 | int (*write_oob)(struct mtd_info *mtd, struct nand_chip *chip, |