aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/onenand
diff options
context:
space:
mode:
authorAdrian Hunter <ext-adrian.hunter@nokia.com>2007-02-06 20:55:23 -0500
committerKyungmin Park <kyungmin.park@samsung.com>2007-02-06 20:55:23 -0500
commit81f38e11233dae671c0673bbdcea01194b75d68f (patch)
tree17de464852c14cec8ddf4cfcc0a66a3ec6259146 /drivers/mtd/onenand
parent52e4200a6da2d98c537b95f7c502ddadf96a6934 (diff)
[MTD] OneNAND: Subpage write returned incorrect length written
When a write is done, the length written is returned. When a single subpage is written the length returned should be the subpage size, however the page size was being returned. Signed-off-by: Adrian Hunter <ext-adrian.hunter@nokia.com> Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Diffstat (limited to 'drivers/mtd/onenand')
-rw-r--r--drivers/mtd/onenand/onenand_base.c20
1 files changed, 9 insertions, 11 deletions
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index 553b24d93335..3d6f880cba9c 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -1051,40 +1051,37 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
1051 } 1051 }
1052 1052
1053 column = to & (mtd->writesize - 1); 1053 column = to & (mtd->writesize - 1);
1054 subpage = column || (len & (mtd->writesize - 1));
1055 1054
1056 /* Grab the lock and see if the device is available */ 1055 /* Grab the lock and see if the device is available */
1057 onenand_get_device(mtd, FL_WRITING); 1056 onenand_get_device(mtd, FL_WRITING);
1058 1057
1059 /* Loop until all data write */ 1058 /* Loop until all data write */
1060 while (written < len) { 1059 while (written < len) {
1061 int bytes = mtd->writesize; 1060 int thislen = min_t(int, mtd->writesize - column, len - written);
1062 int thislen = min_t(int, bytes, len - written);
1063 u_char *wbuf = (u_char *) buf; 1061 u_char *wbuf = (u_char *) buf;
1064 1062
1065 cond_resched(); 1063 cond_resched();
1066 1064
1067 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, bytes); 1065 this->command(mtd, ONENAND_CMD_BUFFERRAM, to, thislen);
1068 1066
1069 /* Partial page write */ 1067 /* Partial page write */
1068 subpage = thislen < mtd->writesize;
1070 if (subpage) { 1069 if (subpage) {
1071 bytes = min_t(int, bytes - column, (int) len);
1072 memset(this->page_buf, 0xff, mtd->writesize); 1070 memset(this->page_buf, 0xff, mtd->writesize);
1073 memcpy(this->page_buf + column, buf, bytes); 1071 memcpy(this->page_buf + column, buf, thislen);
1074 wbuf = this->page_buf; 1072 wbuf = this->page_buf;
1075 /* Even though partial write, we need page size */
1076 thislen = mtd->writesize;
1077 } 1073 }
1078 1074
1079 this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, thislen); 1075 this->write_bufferram(mtd, ONENAND_DATARAM, wbuf, 0, mtd->writesize);
1080 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize); 1076 this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0, mtd->oobsize);
1081 1077
1082 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize); 1078 this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
1083 1079
1080 ret = this->wait(mtd, FL_WRITING);
1081
1084 /* In partial page write we don't update bufferram */ 1082 /* In partial page write we don't update bufferram */
1085 onenand_update_bufferram(mtd, to, !subpage); 1083 onenand_update_bufferram(mtd, to, !ret && !subpage);
1086 1084
1087 ret = this->wait(mtd, FL_WRITING);
1088 if (ret) { 1085 if (ret) {
1089 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: write filaed %d\n", ret); 1086 DEBUG(MTD_DEBUG_LEVEL0, "onenand_write: write filaed %d\n", ret);
1090 break; 1087 break;
@@ -1098,6 +1095,7 @@ static int onenand_write(struct mtd_info *mtd, loff_t to, size_t len,
1098 } 1095 }
1099 1096
1100 written += thislen; 1097 written += thislen;
1098
1101 if (written == len) 1099 if (written == len)
1102 break; 1100 break;
1103 1101