aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/mtd/nand
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/mtd/nand')
-rw-r--r--drivers/mtd/nand/nand_base.c542
-rw-r--r--drivers/mtd/nand/nand_bbt.c188
2 files changed, 459 insertions, 271 deletions
diff --git a/drivers/mtd/nand/nand_base.c b/drivers/mtd/nand/nand_base.c
index e922b829c4be..b8e6e1579cf1 100644
--- a/drivers/mtd/nand/nand_base.c
+++ b/drivers/mtd/nand/nand_base.c
@@ -81,23 +81,12 @@ static struct nand_ecclayout nand_oob_64 = {
81 .length = 38}} 81 .length = 38}}
82}; 82};
83 83
84/* This is used for padding purposes in nand_write_oob */
85static uint8_t ffchars[] = {
86 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
87 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
88 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
89 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
90 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
91 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
92 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
93 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
94};
95
96static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
97 size_t *retlen, const uint8_t *buf);
98static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd, 84static int nand_get_device(struct nand_chip *chip, struct mtd_info *mtd,
99 int new_state); 85 int new_state);
100 86
87static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
88 struct mtd_oob_ops *ops);
89
101/* 90/*
102 * For devices which display every fart in the system on a seperate LED. Is 91 * For devices which display every fart in the system on a seperate LED. Is
103 * compiled away when LED support is disabled. 92 * compiled away when LED support is disabled.
@@ -358,7 +347,6 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
358{ 347{
359 struct nand_chip *chip = mtd->priv; 348 struct nand_chip *chip = mtd->priv;
360 uint8_t buf[2] = { 0, 0 }; 349 uint8_t buf[2] = { 0, 0 };
361 size_t retlen;
362 int block; 350 int block;
363 351
364 /* Get block number */ 352 /* Get block number */
@@ -371,8 +359,13 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
371 return nand_update_bbt(mtd, ofs); 359 return nand_update_bbt(mtd, ofs);
372 360
373 /* We write two bytes, so we dont have to mess with 16 bit access */ 361 /* We write two bytes, so we dont have to mess with 16 bit access */
374 ofs += mtd->oobsize + (chip->badblockpos & ~0x01); 362 ofs += mtd->oobsize;
375 return nand_write_oob(mtd, ofs, 2, &retlen, buf); 363 chip->ops.len = 2;
364 chip->ops.datbuf = NULL;
365 chip->ops.oobbuf = buf;
366 chip->ops.ooboffs = chip->badblockpos & ~0x01;
367
368 return nand_do_write_oob(mtd, ofs, &chip->ops);
376} 369}
377 370
378/** 371/**
@@ -740,6 +733,20 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *chip, int state)
740} 733}
741 734
742/** 735/**
736 * nand_read_page_raw - [Intern] read raw page data without ecc
737 * @mtd: mtd info structure
738 * @chip: nand chip info structure
739 * @buf: buffer to store read data
740 */
741static int nand_read_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
742 uint8_t *buf)
743{
744 chip->read_buf(mtd, buf, mtd->writesize);
745 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
746 return 0;
747}
748
749/**
743 * nand_read_page_swecc - {REPLACABLE] software ecc based page read function 750 * nand_read_page_swecc - {REPLACABLE] software ecc based page read function
744 * @mtd: mtd info structure 751 * @mtd: mtd info structure
745 * @chip: nand chip info structure 752 * @chip: nand chip info structure
@@ -756,11 +763,7 @@ static int nand_read_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
756 uint8_t *ecc_code = chip->buffers.ecccode; 763 uint8_t *ecc_code = chip->buffers.ecccode;
757 int *eccpos = chip->ecc.layout->eccpos; 764 int *eccpos = chip->ecc.layout->eccpos;
758 765
759 chip->read_buf(mtd, buf, mtd->writesize); 766 nand_read_page_raw(mtd, chip, buf);
760 chip->read_buf(mtd, chip->oob_poi, mtd->oobsize);
761
762 if (chip->ecc.mode == NAND_ECC_NONE)
763 return 0;
764 767
765 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) 768 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
766 chip->ecc.calculate(mtd, p, &ecc_calc[i]); 769 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
@@ -882,18 +885,50 @@ static int nand_read_page_syndrome(struct mtd_info *mtd, struct nand_chip *chip,
882} 885}
883 886
884/** 887/**
885 * nand_do_read - [Internal] Read data with ECC 888 * nand_transfer_oob - [Internal] Transfer oob to client buffer
889 * @chip: nand chip structure
890 * @ops: oob ops structure
891 */
892static uint8_t *nand_transfer_oob(struct nand_chip *chip, uint8_t *oob,
893 struct mtd_oob_ops *ops)
894{
895 size_t len = ops->ooblen;
896
897 switch(ops->mode) {
898
899 case MTD_OOB_PLACE:
900 case MTD_OOB_RAW:
901 memcpy(oob, chip->oob_poi + ops->ooboffs, len);
902 return oob + len;
903
904 case MTD_OOB_AUTO: {
905 struct nand_oobfree *free = chip->ecc.layout->oobfree;
906 size_t bytes;
907
908 for(; free->length && len; free++, len -= bytes) {
909 bytes = min(len, free->length);
910
911 memcpy(oob, chip->oob_poi + free->offset, bytes);
912 oob += bytes;
913 }
914 return oob;
915 }
916 default:
917 BUG();
918 }
919 return NULL;
920}
921
922/**
923 * nand_do_read_ops - [Internal] Read data with ECC
886 * 924 *
887 * @mtd: MTD device structure 925 * @mtd: MTD device structure
888 * @from: offset to read from 926 * @from: offset to read from
889 * @len: number of bytes to read
890 * @retlen: pointer to variable to store the number of read bytes
891 * @buf: the databuffer to put data
892 * 927 *
893 * Internal function. Called with chip held. 928 * Internal function. Called with chip held.
894 */ 929 */
895int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len, 930static int nand_do_read_ops(struct mtd_info *mtd, loff_t from,
896 size_t *retlen, uint8_t *buf) 931 struct mtd_oob_ops *ops)
897{ 932{
898 int chipnr, page, realpage, col, bytes, aligned; 933 int chipnr, page, realpage, col, bytes, aligned;
899 struct nand_chip *chip = mtd->priv; 934 struct nand_chip *chip = mtd->priv;
@@ -901,8 +936,8 @@ int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
901 int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; 936 int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
902 int sndcmd = 1; 937 int sndcmd = 1;
903 int ret = 0; 938 int ret = 0;
904 uint32_t readlen = len; 939 uint32_t readlen = ops->len;
905 uint8_t *bufpoi; 940 uint8_t *bufpoi, *oob, *buf;
906 941
907 stats = mtd->ecc_stats; 942 stats = mtd->ecc_stats;
908 943
@@ -915,12 +950,15 @@ int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
915 col = (int)(from & (mtd->writesize - 1)); 950 col = (int)(from & (mtd->writesize - 1));
916 chip->oob_poi = chip->buffers.oobrbuf; 951 chip->oob_poi = chip->buffers.oobrbuf;
917 952
953 buf = ops->datbuf;
954 oob = ops->oobbuf;
955
918 while(1) { 956 while(1) {
919 bytes = min(mtd->writesize - col, readlen); 957 bytes = min(mtd->writesize - col, readlen);
920 aligned = (bytes == mtd->writesize); 958 aligned = (bytes == mtd->writesize);
921 959
922 /* Is the current page in the buffer ? */ 960 /* Is the current page in the buffer ? */
923 if (realpage != chip->pagebuf) { 961 if (realpage != chip->pagebuf || oob) {
924 bufpoi = aligned ? buf : chip->buffers.databuf; 962 bufpoi = aligned ? buf : chip->buffers.databuf;
925 963
926 if (likely(sndcmd)) { 964 if (likely(sndcmd)) {
@@ -939,6 +977,16 @@ int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
939 memcpy(buf, chip->buffers.databuf + col, bytes); 977 memcpy(buf, chip->buffers.databuf + col, bytes);
940 } 978 }
941 979
980 buf += bytes;
981
982 if (unlikely(oob)) {
983 /* Raw mode does data:oob:data:oob */
984 if (ops->mode != MTD_OOB_RAW)
985 oob = nand_transfer_oob(chip, oob, ops);
986 else
987 buf = nand_transfer_oob(chip, buf, ops);
988 }
989
942 if (!(chip->options & NAND_NO_READRDY)) { 990 if (!(chip->options & NAND_NO_READRDY)) {
943 /* 991 /*
944 * Apply delay or wait for ready/busy pin. Do 992 * Apply delay or wait for ready/busy pin. Do
@@ -952,10 +1000,11 @@ int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
952 else 1000 else
953 nand_wait_ready(mtd); 1001 nand_wait_ready(mtd);
954 } 1002 }
955 } else 1003 } else {
956 memcpy(buf, chip->buffers.databuf + col, bytes); 1004 memcpy(buf, chip->buffers.databuf + col, bytes);
1005 buf += bytes;
1006 }
957 1007
958 buf += bytes;
959 readlen -= bytes; 1008 readlen -= bytes;
960 1009
961 if (!readlen) 1010 if (!readlen)
@@ -981,7 +1030,7 @@ int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
981 sndcmd = 1; 1030 sndcmd = 1;
982 } 1031 }
983 1032
984 *retlen = len - (size_t) readlen; 1033 ops->retlen = ops->len - (size_t) readlen;
985 1034
986 if (ret) 1035 if (ret)
987 return ret; 1036 return ret;
@@ -1002,57 +1051,49 @@ int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,
1002static int nand_read(struct mtd_info *mtd, loff_t from, size_t len, 1051static int nand_read(struct mtd_info *mtd, loff_t from, size_t len,
1003 size_t *retlen, uint8_t *buf) 1052 size_t *retlen, uint8_t *buf)
1004{ 1053{
1054 struct nand_chip *chip = mtd->priv;
1005 int ret; 1055 int ret;
1006 1056
1007 *retlen = 0;
1008 /* Do not allow reads past end of device */ 1057 /* Do not allow reads past end of device */
1009 if ((from + len) > mtd->size) 1058 if ((from + len) > mtd->size)
1010 return -EINVAL; 1059 return -EINVAL;
1011 if (!len) 1060 if (!len)
1012 return 0; 1061 return 0;
1013 1062
1014 nand_get_device(mtd->priv, mtd, FL_READING); 1063 nand_get_device(chip, mtd, FL_READING);
1015 1064
1016 ret = nand_do_read(mtd, from, len, retlen, buf); 1065 chip->ops.len = len;
1066 chip->ops.datbuf = buf;
1067 chip->ops.oobbuf = NULL;
1068
1069 ret = nand_do_read_ops(mtd, from, &chip->ops);
1017 1070
1018 nand_release_device(mtd); 1071 nand_release_device(mtd);
1019 1072
1073 *retlen = chip->ops.retlen;
1020 return ret; 1074 return ret;
1021} 1075}
1022 1076
1023/** 1077/**
1024 * nand_read_oob - [MTD Interface] NAND read out-of-band 1078 * nand_do_read_oob - [Intern] NAND read out-of-band
1025 * @mtd: MTD device structure 1079 * @mtd: MTD device structure
1026 * @from: offset to read from 1080 * @from: offset to read from
1027 * @len: number of bytes to read 1081 * @ops: oob operations description structure
1028 * @retlen: pointer to variable to store the number of read bytes
1029 * @buf: the databuffer to put data
1030 * 1082 *
1031 * NAND read out-of-band data from the spare area 1083 * NAND read out-of-band data from the spare area
1032 */ 1084 */
1033static int nand_read_oob(struct mtd_info *mtd, loff_t from, size_t len, 1085static int nand_do_read_oob(struct mtd_info *mtd, loff_t from,
1034 size_t *retlen, uint8_t *buf) 1086 struct mtd_oob_ops *ops)
1035{ 1087{
1036 int col, page, realpage, chipnr, sndcmd = 1; 1088 int col, page, realpage, chipnr, sndcmd = 1;
1037 struct nand_chip *chip = mtd->priv; 1089 struct nand_chip *chip = mtd->priv;
1038 int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1; 1090 int blkcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
1039 int readlen = len; 1091 int direct, bytes, readlen = ops->len;
1092 uint8_t *bufpoi, *buf = ops->oobbuf;
1040 1093
1041 DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08x, len = %i\n", 1094 DEBUG(MTD_DEBUG_LEVEL3, "nand_read_oob: from = 0x%08x, len = %i\n",
1042 (unsigned int)from, (int)len); 1095 (unsigned int)from, (int)len);
1043 1096
1044 /* Initialize return length value */
1045 *retlen = 0;
1046
1047 /* Do not allow reads past end of device */
1048 if ((from + len) > mtd->size) {
1049 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
1050 "Attempt read beyond end of device\n");
1051 return -EINVAL;
1052 }
1053
1054 nand_get_device(chip, mtd, FL_READING);
1055
1056 chipnr = (int)(from >> chip->chip_shift); 1097 chipnr = (int)(from >> chip->chip_shift);
1057 chip->select_chip(mtd, chipnr); 1098 chip->select_chip(mtd, chipnr);
1058 1099
@@ -1060,20 +1101,31 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
1060 realpage = (int)(from >> chip->page_shift); 1101 realpage = (int)(from >> chip->page_shift);
1061 page = realpage & chip->pagemask; 1102 page = realpage & chip->pagemask;
1062 1103
1063 /* Mask to get column */ 1104 if (ops->mode != MTD_OOB_AUTO) {
1064 col = from & (mtd->oobsize - 1); 1105 col = ops->ooboffs;
1106 direct = 1;
1107 } else {
1108 col = 0;
1109 direct = 0;
1110 }
1065 1111
1066 while(1) { 1112 while(1) {
1067 int bytes = min((int)(mtd->oobsize - col), readlen); 1113 bytes = direct ? ops->ooblen : mtd->oobsize;
1114 bufpoi = direct ? buf : chip->buffers.oobrbuf;
1068 1115
1069 if (likely(sndcmd)) { 1116 if (likely(sndcmd)) {
1070 chip->cmdfunc(mtd, NAND_CMD_READOOB, col, page); 1117 chip->cmdfunc(mtd, NAND_CMD_READOOB, col, page);
1071 sndcmd = 0; 1118 sndcmd = 0;
1072 } 1119 }
1073 1120
1074 chip->read_buf(mtd, buf, bytes); 1121 chip->read_buf(mtd, bufpoi, bytes);
1075 1122
1076 readlen -= bytes; 1123 if (unlikely(!direct))
1124 buf = nand_transfer_oob(chip, buf, ops);
1125 else
1126 buf += ops->ooblen;
1127
1128 readlen -= ops->ooblen;
1077 if (!readlen) 1129 if (!readlen)
1078 break; 1130 break;
1079 1131
@@ -1090,10 +1142,6 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
1090 nand_wait_ready(mtd); 1142 nand_wait_ready(mtd);
1091 } 1143 }
1092 1144
1093 buf += bytes;
1094 bytes = mtd->oobsize;
1095 col = 0;
1096
1097 /* Increment page address */ 1145 /* Increment page address */
1098 realpage++; 1146 realpage++;
1099 1147
@@ -1112,81 +1160,76 @@ static int nand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
1112 sndcmd = 1; 1160 sndcmd = 1;
1113 } 1161 }
1114 1162
1115 /* Deselect and wake up anyone waiting on the device */ 1163 ops->retlen = ops->len;
1116 nand_release_device(mtd);
1117
1118 *retlen = len;
1119 return 0; 1164 return 0;
1120} 1165}
1121 1166
1122/** 1167/**
1123 * nand_read_raw - [GENERIC] Read raw data including oob into buffer 1168 * nand_read_oob - [MTD Interface] NAND read data and/or out-of-band
1124 * @mtd: MTD device structure 1169 * @mtd: MTD device structure
1125 * @buf: temporary buffer
1126 * @from: offset to read from 1170 * @from: offset to read from
1127 * @len: number of bytes to read 1171 * @ops: oob operation description structure
1128 * @ooblen: number of oob data bytes to read
1129 * 1172 *
1130 * Read raw data including oob into buffer 1173 * NAND read data and/or out-of-band data
1131 */ 1174 */
1132int nand_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, 1175static int nand_read_oob(struct mtd_info *mtd, loff_t from,
1133 size_t ooblen) 1176 struct mtd_oob_ops *ops)
1134{ 1177{
1178 int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip,
1179 uint8_t *buf) = NULL;
1135 struct nand_chip *chip = mtd->priv; 1180 struct nand_chip *chip = mtd->priv;
1136 int page = (int)(from >> chip->page_shift); 1181 int ret = -ENOTSUPP;
1137 int chipnr = (int)(from >> chip->chip_shift); 1182
1138 int sndcmd = 1; 1183 ops->retlen = 0;
1139 int cnt = 0;
1140 int pagesize = mtd->writesize + mtd->oobsize;
1141 int blockcheck;
1142 1184
1143 /* Do not allow reads past end of device */ 1185 /* Do not allow reads past end of device */
1144 if ((from + len) > mtd->size) { 1186 if ((from + ops->len) > mtd->size) {
1145 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_raw: " 1187 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
1146 "Attempt read beyond end of device\n"); 1188 "Attempt read beyond end of device\n");
1147 return -EINVAL; 1189 return -EINVAL;
1148 } 1190 }
1149 1191
1150 /* Grab the lock and see if the device is available */
1151 nand_get_device(chip, mtd, FL_READING); 1192 nand_get_device(chip, mtd, FL_READING);
1152 1193
1153 chip->select_chip(mtd, chipnr); 1194 switch(ops->mode) {
1154 1195 case MTD_OOB_PLACE:
1155 /* Add requested oob length */ 1196 case MTD_OOB_AUTO:
1156 len += ooblen; 1197 break;
1157 blockcheck = (1 << (chip->phys_erase_shift - chip->page_shift)) - 1;
1158 1198
1159 while (len) { 1199 case MTD_OOB_RAW:
1160 if (likely(sndcmd)) { 1200 /* Replace the read_page algorithm temporary */
1161 chip->cmdfunc(mtd, NAND_CMD_READ0, 0, 1201 read_page = chip->ecc.read_page;
1162 page & chip->pagemask); 1202 chip->ecc.read_page = nand_read_page_raw;
1163 sndcmd = 0; 1203 break;
1164 }
1165 1204
1166 chip->read_buf(mtd, &buf[cnt], pagesize); 1205 default:
1206 goto out;
1207 }
1167 1208
1168 len -= pagesize; 1209 if (!ops->datbuf)
1169 cnt += pagesize; 1210 ret = nand_do_read_oob(mtd, from, ops);
1170 page++; 1211 else
1212 ret = nand_do_read_ops(mtd, from, ops);
1171 1213
1172 if (!(chip->options & NAND_NO_READRDY)) { 1214 if (unlikely(ops->mode == MTD_OOB_RAW))
1173 if (!chip->dev_ready) 1215 chip->ecc.read_page = read_page;
1174 udelay(chip->chip_delay); 1216 out:
1175 else 1217 nand_release_device(mtd);
1176 nand_wait_ready(mtd); 1218 return ret;
1177 } 1219}
1178 1220
1179 /*
1180 * Check, if the chip supports auto page increment or if we
1181 * cross a block boundary.
1182 */
1183 if (!NAND_CANAUTOINCR(chip) || !(page & blockcheck))
1184 sndcmd = 1;
1185 }
1186 1221
1187 /* Deselect and wake up anyone waiting on the device */ 1222/**
1188 nand_release_device(mtd); 1223 * nand_write_page_raw - [Intern] raw page write function
1189 return 0; 1224 * @mtd: mtd info structure
1225 * @chip: nand chip info structure
1226 * @buf: data buffer
1227 */
1228static void nand_write_page_raw(struct mtd_info *mtd, struct nand_chip *chip,
1229 const uint8_t *buf)
1230{
1231 chip->write_buf(mtd, buf, mtd->writesize);
1232 chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
1190} 1233}
1191 1234
1192/** 1235/**
@@ -1205,17 +1248,14 @@ static void nand_write_page_swecc(struct mtd_info *mtd, struct nand_chip *chip,
1205 const uint8_t *p = buf; 1248 const uint8_t *p = buf;
1206 int *eccpos = chip->ecc.layout->eccpos; 1249 int *eccpos = chip->ecc.layout->eccpos;
1207 1250
1208 if (chip->ecc.mode != NAND_ECC_NONE) { 1251 /* Software ecc calculation */
1209 /* Software ecc calculation */ 1252 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize)
1210 for (i = 0; eccsteps; eccsteps--, i += eccbytes, p += eccsize) 1253 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
1211 chip->ecc.calculate(mtd, p, &ecc_calc[i]);
1212 1254
1213 for (i = 0; i < chip->ecc.total; i++) 1255 for (i = 0; i < chip->ecc.total; i++)
1214 chip->oob_poi[eccpos[i]] = ecc_calc[i]; 1256 chip->oob_poi[eccpos[i]] = ecc_calc[i];
1215 }
1216 1257
1217 chip->write_buf(mtd, buf, mtd->writesize); 1258 nand_write_page_raw(mtd, chip, buf);
1218 chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
1219} 1259}
1220 1260
1221/** 1261/**
@@ -1342,51 +1382,77 @@ static int nand_write_page(struct mtd_info *mtd, struct nand_chip *chip,
1342 return 0; 1382 return 0;
1343} 1383}
1344 1384
1385/**
1386 * nand_fill_oob - [Internal] Transfer client buffer to oob
1387 * @chip: nand chip structure
1388 * @oob: oob data buffer
1389 * @ops: oob ops structure
1390 */
1391static uint8_t *nand_fill_oob(struct nand_chip *chip, uint8_t *oob,
1392 struct mtd_oob_ops *ops)
1393{
1394 size_t len = ops->ooblen;
1395
1396 switch(ops->mode) {
1397
1398 case MTD_OOB_PLACE:
1399 case MTD_OOB_RAW:
1400 memcpy(chip->oob_poi + ops->ooboffs, oob, len);
1401 return oob + len;
1402
1403 case MTD_OOB_AUTO: {
1404 struct nand_oobfree *free = chip->ecc.layout->oobfree;
1405 size_t bytes;
1406
1407 for(; free->length && len; free++, len -= bytes) {
1408 bytes = min(len, free->length);
1409 memcpy(chip->oob_poi + free->offset, oob, bytes);
1410 oob += bytes;
1411 }
1412 return oob;
1413 }
1414 default:
1415 BUG();
1416 }
1417 return NULL;
1418}
1419
1345#define NOTALIGNED(x) (x & (mtd->writesize-1)) != 0 1420#define NOTALIGNED(x) (x & (mtd->writesize-1)) != 0
1346 1421
1347/** 1422/**
1348 * nand_write - [MTD Interface] NAND write with ECC 1423 * nand_do_write_ops - [Internal] NAND write with ECC
1349 * @mtd: MTD device structure 1424 * @mtd: MTD device structure
1350 * @to: offset to write to 1425 * @to: offset to write to
1351 * @len: number of bytes to write 1426 * @ops: oob operations description structure
1352 * @retlen: pointer to variable to store the number of written bytes
1353 * @buf: the data to write
1354 * 1427 *
1355 * NAND write with ECC 1428 * NAND write with ECC
1356 */ 1429 */
1357static int nand_write(struct mtd_info *mtd, loff_t to, size_t len, 1430static int nand_do_write_ops(struct mtd_info *mtd, loff_t to,
1358 size_t *retlen, const uint8_t *buf) 1431 struct mtd_oob_ops *ops)
1359{ 1432{
1360 int chipnr, realpage, page, blockmask; 1433 int chipnr, realpage, page, blockmask;
1361 struct nand_chip *chip = mtd->priv; 1434 struct nand_chip *chip = mtd->priv;
1362 uint32_t writelen = len; 1435 uint32_t writelen = ops->len;
1436 uint8_t *oob = ops->oobbuf;
1437 uint8_t *buf = ops->datbuf;
1363 int bytes = mtd->writesize; 1438 int bytes = mtd->writesize;
1364 int ret = -EIO; 1439 int ret;
1365 1440
1366 *retlen = 0; 1441 ops->retlen = 0;
1367
1368 /* Do not allow write past end of device */
1369 if ((to + len) > mtd->size) {
1370 DEBUG(MTD_DEBUG_LEVEL0, "nand_write: "
1371 "Attempt to write past end of page\n");
1372 return -EINVAL;
1373 }
1374 1442
1375 /* reject writes, which are not page aligned */ 1443 /* reject writes, which are not page aligned */
1376 if (NOTALIGNED(to) || NOTALIGNED(len)) { 1444 if (NOTALIGNED(to) || NOTALIGNED(ops->len)) {
1377 printk(KERN_NOTICE "nand_write: " 1445 printk(KERN_NOTICE "nand_write: "
1378 "Attempt to write not page aligned data\n"); 1446 "Attempt to write not page aligned data\n");
1379 return -EINVAL; 1447 return -EINVAL;
1380 } 1448 }
1381 1449
1382 if (!len) 1450 if (!writelen)
1383 return 0; 1451 return 0;
1384 1452
1385 nand_get_device(chip, mtd, FL_WRITING);
1386
1387 /* Check, if it is write protected */ 1453 /* Check, if it is write protected */
1388 if (nand_check_wp(mtd)) 1454 if (nand_check_wp(mtd))
1389 goto out; 1455 return -EIO;
1390 1456
1391 chipnr = (int)(to >> chip->chip_shift); 1457 chipnr = (int)(to >> chip->chip_shift);
1392 chip->select_chip(mtd, chipnr); 1458 chip->select_chip(mtd, chipnr);
@@ -1397,7 +1463,7 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
1397 1463
1398 /* Invalidate the page cache, when we write to the cached page */ 1464 /* Invalidate the page cache, when we write to the cached page */
1399 if (to <= (chip->pagebuf << chip->page_shift) && 1465 if (to <= (chip->pagebuf << chip->page_shift) &&
1400 (chip->pagebuf << chip->page_shift) < (to + len)) 1466 (chip->pagebuf << chip->page_shift) < (to + ops->len))
1401 chip->pagebuf = -1; 1467 chip->pagebuf = -1;
1402 1468
1403 chip->oob_poi = chip->buffers.oobwbuf; 1469 chip->oob_poi = chip->buffers.oobwbuf;
@@ -1405,6 +1471,9 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
1405 while(1) { 1471 while(1) {
1406 int cached = writelen > bytes && page != blockmask; 1472 int cached = writelen > bytes && page != blockmask;
1407 1473
1474 if (unlikely(oob))
1475 oob = nand_fill_oob(chip, oob, ops);
1476
1408 ret = nand_write_page(mtd, chip, buf, page, cached); 1477 ret = nand_write_page(mtd, chip, buf, page, cached);
1409 if (ret) 1478 if (ret)
1410 break; 1479 break;
@@ -1424,94 +1493,74 @@ static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
1424 chip->select_chip(mtd, chipnr); 1493 chip->select_chip(mtd, chipnr);
1425 } 1494 }
1426 } 1495 }
1427 out: 1496
1428 *retlen = len - writelen; 1497 if (unlikely(oob))
1429 nand_release_device(mtd); 1498 memset(chip->oob_poi, 0xff, mtd->oobsize);
1499
1500 ops->retlen = ops->len - writelen;
1430 return ret; 1501 return ret;
1431} 1502}
1432 1503
1433/** 1504/**
1434 * nand_write_raw - [GENERIC] Write raw data including oob 1505 * nand_write - [MTD Interface] NAND write with ECC
1435 * @mtd: MTD device structure 1506 * @mtd: MTD device structure
1436 * @buf: source buffer
1437 * @to: offset to write to 1507 * @to: offset to write to
1438 * @len: number of bytes to write 1508 * @len: number of bytes to write
1439 * @buf: source buffer 1509 * @retlen: pointer to variable to store the number of written bytes
1440 * @oob: oob buffer 1510 * @buf: the data to write
1441 * 1511 *
1442 * Write raw data including oob 1512 * NAND write with ECC
1443 */ 1513 */
1444int nand_write_raw(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, 1514static int nand_write(struct mtd_info *mtd, loff_t to, size_t len,
1445 const uint8_t *buf, uint8_t *oob) 1515 size_t *retlen, const uint8_t *buf)
1446{ 1516{
1447 struct nand_chip *chip = mtd->priv; 1517 struct nand_chip *chip = mtd->priv;
1448 int page = (int)(to >> chip->page_shift);
1449 int chipnr = (int)(to >> chip->chip_shift);
1450 int ret; 1518 int ret;
1451 1519
1452 *retlen = 0; 1520 /* Do not allow reads past end of device */
1453 1521 if ((to + len) > mtd->size)
1454 /* Do not allow writes past end of device */
1455 if ((to + len) > mtd->size) {
1456 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_raw: Attempt write "
1457 "beyond end of device\n");
1458 return -EINVAL; 1522 return -EINVAL;
1459 } 1523 if (!len)
1524 return 0;
1460 1525
1461 /* Grab the lock and see if the device is available */ 1526 nand_get_device(chip, mtd, FL_READING);
1462 nand_get_device(chip, mtd, FL_WRITING);
1463 1527
1464 chip->select_chip(mtd, chipnr); 1528 chip->ops.len = len;
1465 chip->oob_poi = oob; 1529 chip->ops.datbuf = (uint8_t *)buf;
1530 chip->ops.oobbuf = NULL;
1466 1531
1467 while (len != *retlen) { 1532 ret = nand_do_write_ops(mtd, to, &chip->ops);
1468 ret = nand_write_page(mtd, chip, buf, page, 0);
1469 if (ret)
1470 return ret;
1471 page++;
1472 *retlen += mtd->writesize;
1473 buf += mtd->writesize;
1474 chip->oob_poi += mtd->oobsize;
1475 }
1476 1533
1477 /* Deselect and wake up anyone waiting on the device */
1478 nand_release_device(mtd); 1534 nand_release_device(mtd);
1479 return 0; 1535
1536 *retlen = chip->ops.retlen;
1537 return ret;
1480} 1538}
1481EXPORT_SYMBOL_GPL(nand_write_raw);
1482 1539
1483/** 1540/**
1484 * nand_write_oob - [MTD Interface] NAND write out-of-band 1541 * nand_do_write_oob - [MTD Interface] NAND write out-of-band
1485 * @mtd: MTD device structure 1542 * @mtd: MTD device structure
1486 * @to: offset to write to 1543 * @to: offset to write to
1487 * @len: number of bytes to write 1544 * @ops: oob operation description structure
1488 * @retlen: pointer to variable to store the number of written bytes
1489 * @buf: the data to write
1490 * 1545 *
1491 * NAND write out-of-band 1546 * NAND write out-of-band
1492 */ 1547 */
1493static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len, 1548static int nand_do_write_oob(struct mtd_info *mtd, loff_t to,
1494 size_t *retlen, const uint8_t *buf) 1549 struct mtd_oob_ops *ops)
1495{ 1550{
1496 int column, page, status, ret = -EIO, chipnr; 1551 int chipnr, page, status;
1497 struct nand_chip *chip = mtd->priv; 1552 struct nand_chip *chip = mtd->priv;
1498 1553
1499 DEBUG(MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n", 1554 DEBUG(MTD_DEBUG_LEVEL3, "nand_write_oob: to = 0x%08x, len = %i\n",
1500 (unsigned int)to, (int)len); 1555 (unsigned int)to, (int)ops->len);
1501
1502 /* Initialize return length value */
1503 *retlen = 0;
1504 1556
1505 /* Do not allow write past end of page */ 1557 /* Do not allow write past end of page */
1506 column = to & (mtd->oobsize - 1); 1558 if ((ops->ooboffs + ops->len) > mtd->oobsize) {
1507 if ((column + len) > mtd->oobsize) {
1508 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: " 1559 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: "
1509 "Attempt to write past end of page\n"); 1560 "Attempt to write past end of page\n");
1510 return -EINVAL; 1561 return -EINVAL;
1511 } 1562 }
1512 1563
1513 nand_get_device(chip, mtd, FL_WRITING);
1514
1515 chipnr = (int)(to >> chip->chip_shift); 1564 chipnr = (int)(to >> chip->chip_shift);
1516 chip->select_chip(mtd, chipnr); 1565 chip->select_chip(mtd, chipnr);
1517 1566
@@ -1528,26 +1577,27 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1528 1577
1529 /* Check, if it is write protected */ 1578 /* Check, if it is write protected */
1530 if (nand_check_wp(mtd)) 1579 if (nand_check_wp(mtd))
1531 goto out; 1580 return -EROFS;
1532 1581
1533 /* Invalidate the page cache, if we write to the cached page */ 1582 /* Invalidate the page cache, if we write to the cached page */
1534 if (page == chip->pagebuf) 1583 if (page == chip->pagebuf)
1535 chip->pagebuf = -1; 1584 chip->pagebuf = -1;
1536 1585
1537 if (NAND_MUST_PAD(chip)) { 1586 if (ops->mode == MTD_OOB_AUTO || NAND_MUST_PAD(chip)) {
1587 chip->oob_poi = chip->buffers.oobwbuf;
1588 memset(chip->oob_poi, 0xff, mtd->oobsize);
1589 nand_fill_oob(chip, ops->oobbuf, ops);
1538 chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize, 1590 chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize,
1539 page & chip->pagemask); 1591 page & chip->pagemask);
1540 /* prepad 0xff for partial programming */ 1592 chip->write_buf(mtd, chip->oob_poi, mtd->oobsize);
1541 chip->write_buf(mtd, ffchars, column); 1593 memset(chip->oob_poi, 0xff, mtd->oobsize);
1542 /* write data */
1543 chip->write_buf(mtd, buf, len);
1544 /* postpad 0xff for partial programming */
1545 chip->write_buf(mtd, ffchars, mtd->oobsize - (len + column));
1546 } else { 1594 } else {
1547 chip->cmdfunc(mtd, NAND_CMD_SEQIN, mtd->writesize + column, 1595 chip->cmdfunc(mtd, NAND_CMD_SEQIN,
1596 mtd->writesize + ops->ooboffs,
1548 page & chip->pagemask); 1597 page & chip->pagemask);
1549 chip->write_buf(mtd, buf, len); 1598 chip->write_buf(mtd, ops->oobbuf, ops->len);
1550 } 1599 }
1600
1551 /* Send command to program the OOB data */ 1601 /* Send command to program the OOB data */
1552 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1); 1602 chip->cmdfunc(mtd, NAND_CMD_PAGEPROG, -1, -1);
1553 1603
@@ -1557,27 +1607,75 @@ static int nand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
1557 if (status & NAND_STATUS_FAIL) { 1607 if (status & NAND_STATUS_FAIL) {
1558 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: " 1608 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: "
1559 "Failed write, page 0x%08x\n", page); 1609 "Failed write, page 0x%08x\n", page);
1560 ret = -EIO; 1610 return -EIO;
1561 goto out;
1562 } 1611 }
1563 *retlen = len; 1612 ops->retlen = ops->len;
1564 1613
1565#ifdef CONFIG_MTD_NAND_VERIFY_WRITE 1614#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
1566 /* Send command to read back the data */ 1615 if (ops->mode != MTD_OOB_AUTO) {
1567 chip->cmdfunc(mtd, NAND_CMD_READOOB, column, page & chip->pagemask); 1616 /* Send command to read back the data */
1617 chip->cmdfunc(mtd, NAND_CMD_READOOB, ops->ooboffs,
1618 page & chip->pagemask);
1568 1619
1569 if (chip->verify_buf(mtd, buf, len)) { 1620 if (chip->verify_buf(mtd, ops->oobbuf, ops->len)) {
1570 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: " 1621 DEBUG(MTD_DEBUG_LEVEL0, "nand_write_oob: "
1571 "Failed write verify, page 0x%08x\n", page); 1622 "Failed write verify, page 0x%08x\n", page);
1572 ret = -EIO; 1623 return -EIO;
1573 goto out; 1624 }
1574 } 1625 }
1575#endif 1626#endif
1576 ret = 0; 1627 return 0;
1628}
1629
1630/**
1631 * nand_write_oob - [MTD Interface] NAND write data and/or out-of-band
1632 * @mtd: MTD device structure
1633 * @from: offset to read from
1634 * @ops: oob operation description structure
1635 */
1636static int nand_write_oob(struct mtd_info *mtd, loff_t to,
1637 struct mtd_oob_ops *ops)
1638{
1639 void (*write_page)(struct mtd_info *mtd, struct nand_chip *chip,
1640 const uint8_t *buf) = NULL;
1641 struct nand_chip *chip = mtd->priv;
1642 int ret = -ENOTSUPP;
1643
1644 ops->retlen = 0;
1645
1646 /* Do not allow writes past end of device */
1647 if ((to + ops->len) > mtd->size) {
1648 DEBUG(MTD_DEBUG_LEVEL0, "nand_read_oob: "
1649 "Attempt read beyond end of device\n");
1650 return -EINVAL;
1651 }
1652
1653 nand_get_device(chip, mtd, FL_READING);
1654
1655 switch(ops->mode) {
1656 case MTD_OOB_PLACE:
1657 case MTD_OOB_AUTO:
1658 break;
1659
1660 case MTD_OOB_RAW:
1661 /* Replace the write_page algorithm temporary */
1662 write_page = chip->ecc.write_page;
1663 chip->ecc.write_page = nand_write_page_raw;
1664 break;
1665
1666 default:
1667 goto out;
1668 }
1669
1670 if (!ops->datbuf)
1671 ret = nand_do_write_oob(mtd, to, ops);
1672 else
1673 ret = nand_do_write_ops(mtd, to, ops);
1674
1675 if (unlikely(ops->mode == MTD_OOB_RAW))
1676 chip->ecc.write_page = write_page;
1577 out: 1677 out:
1578 /* Deselect and wake up anyone waiting on the device */
1579 nand_release_device(mtd); 1678 nand_release_device(mtd);
1580
1581 return ret; 1679 return ret;
1582} 1680}
1583 1681
@@ -2191,8 +2289,8 @@ int nand_scan(struct mtd_info *mtd, int maxchips)
2191 case NAND_ECC_NONE: 2289 case NAND_ECC_NONE:
2192 printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. " 2290 printk(KERN_WARNING "NAND_ECC_NONE selected by board driver. "
2193 "This is not recommended !!\n"); 2291 "This is not recommended !!\n");
2194 chip->ecc.read_page = nand_read_page_swecc; 2292 chip->ecc.read_page = nand_read_page_raw;
2195 chip->ecc.write_page = nand_write_page_swecc; 2293 chip->ecc.write_page = nand_write_page_raw;
2196 chip->ecc.size = mtd->writesize; 2294 chip->ecc.size = mtd->writesize;
2197 chip->ecc.bytes = 0; 2295 chip->ecc.bytes = 0;
2198 break; 2296 break;
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c
index 40f99304df76..480c3cbf9bf9 100644
--- a/drivers/mtd/nand/nand_bbt.c
+++ b/drivers/mtd/nand/nand_bbt.c
@@ -230,6 +230,42 @@ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
230 return 0; 230 return 0;
231} 231}
232 232
233/*
234 * Scan read raw data from flash
235 */
236static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs,
237 size_t len)
238{
239 struct mtd_oob_ops ops;
240
241 ops.mode = MTD_OOB_RAW;
242 ops.ooboffs = 0;
243 ops.ooblen = mtd->oobsize;
244 ops.oobbuf = buf;
245 ops.datbuf = buf;
246 ops.len = len;
247
248 return mtd->read_oob(mtd, offs, &ops);
249}
250
251/*
252 * Scan write data with oob to flash
253 */
254static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len,
255 uint8_t *buf, uint8_t *oob)
256{
257 struct mtd_oob_ops ops;
258
259 ops.mode = MTD_OOB_PLACE;
260 ops.ooboffs = 0;
261 ops.ooblen = mtd->oobsize;
262 ops.datbuf = buf;
263 ops.oobbuf = oob;
264 ops.len = len;
265
266 return mtd->write_oob(mtd, offs, &ops);
267}
268
233/** 269/**
234 * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page 270 * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
235 * @mtd: MTD device structure 271 * @mtd: MTD device structure
@@ -241,27 +277,85 @@ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc
241 * We assume that the bbt bits are in consecutive order. 277 * We assume that the bbt bits are in consecutive order.
242 * 278 *
243*/ 279*/
244static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md) 280static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf,
281 struct nand_bbt_descr *td, struct nand_bbt_descr *md)
245{ 282{
246 struct nand_chip *this = mtd->priv; 283 struct nand_chip *this = mtd->priv;
247 284
248 /* Read the primary version, if available */ 285 /* Read the primary version, if available */
249 if (td->options & NAND_BBT_VERSION) { 286 if (td->options & NAND_BBT_VERSION) {
250 nand_read_raw(mtd, buf, td->pages[0] << this->page_shift, mtd->writesize, mtd->oobsize); 287 scan_read_raw(mtd, buf, td->pages[0] << this->page_shift,
288 mtd->writesize);
251 td->version[0] = buf[mtd->writesize + td->veroffs]; 289 td->version[0] = buf[mtd->writesize + td->veroffs];
252 printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]); 290 printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
291 td->pages[0], td->version[0]);
253 } 292 }
254 293
255 /* Read the mirror version, if available */ 294 /* Read the mirror version, if available */
256 if (md && (md->options & NAND_BBT_VERSION)) { 295 if (md && (md->options & NAND_BBT_VERSION)) {
257 nand_read_raw(mtd, buf, md->pages[0] << this->page_shift, mtd->writesize, mtd->oobsize); 296 scan_read_raw(mtd, buf, md->pages[0] << this->page_shift,
297 mtd->writesize);
258 md->version[0] = buf[mtd->writesize + md->veroffs]; 298 md->version[0] = buf[mtd->writesize + md->veroffs];
259 printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]); 299 printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n",
300 md->pages[0], md->version[0]);
260 } 301 }
261
262 return 1; 302 return 1;
263} 303}
264 304
305/*
306 * Scan a given block full
307 */
308static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd,
309 loff_t offs, uint8_t *buf, size_t readlen,
310 int scanlen, int len)
311{
312 int ret, j;
313
314 ret = scan_read_raw(mtd, buf, offs, readlen);
315 if (ret)
316 return ret;
317
318 for (j = 0; j < len; j++, buf += scanlen) {
319 if (check_pattern(buf, scanlen, mtd->writesize, bd))
320 return 1;
321 }
322 return 0;
323}
324
325/*
326 * Scan a given block partially
327 */
328static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd,
329 loff_t offs, uint8_t *buf, int len)
330{
331 struct mtd_oob_ops ops;
332 int j, ret;
333
334 ops.len = mtd->oobsize;
335 ops.ooblen = mtd->oobsize;
336 ops.oobbuf = buf;
337 ops.ooboffs = 0;
338 ops.datbuf = NULL;
339 ops.mode = MTD_OOB_PLACE;
340
341 for (j = 0; j < len; j++) {
342 /*
343 * Read the full oob until read_oob is fixed to
344 * handle single byte reads for 16 bit
345 * buswidth
346 */
347 ret = mtd->read_oob(mtd, offs, &ops);
348 if (ret)
349 return ret;
350
351 if (check_short_pattern(buf, bd))
352 return 1;
353
354 offs += mtd->writesize;
355 }
356 return 0;
357}
358
265/** 359/**
266 * create_bbt - [GENERIC] Create a bad block table by scanning the device 360 * create_bbt - [GENERIC] Create a bad block table by scanning the device
267 * @mtd: MTD device structure 361 * @mtd: MTD device structure
@@ -273,13 +367,14 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
273 * Create a bad block table by scanning the device 367 * Create a bad block table by scanning the device
274 * for the given good/bad block identify pattern 368 * for the given good/bad block identify pattern
275 */ 369 */
276static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd, int chip) 370static int create_bbt(struct mtd_info *mtd, uint8_t *buf,
371 struct nand_bbt_descr *bd, int chip)
277{ 372{
278 struct nand_chip *this = mtd->priv; 373 struct nand_chip *this = mtd->priv;
279 int i, j, numblocks, len, scanlen; 374 int i, numblocks, len, scanlen;
280 int startblock; 375 int startblock;
281 loff_t from; 376 loff_t from;
282 size_t readlen, ooblen; 377 size_t readlen;
283 378
284 printk(KERN_INFO "Scanning device for bad blocks\n"); 379 printk(KERN_INFO "Scanning device for bad blocks\n");
285 380
@@ -294,18 +389,17 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
294 389
295 if (!(bd->options & NAND_BBT_SCANEMPTY)) { 390 if (!(bd->options & NAND_BBT_SCANEMPTY)) {
296 /* We need only read few bytes from the OOB area */ 391 /* We need only read few bytes from the OOB area */
297 scanlen = ooblen = 0; 392 scanlen = 0;
298 readlen = bd->len; 393 readlen = bd->len;
299 } else { 394 } else {
300 /* Full page content should be read */ 395 /* Full page content should be read */
301 scanlen = mtd->writesize + mtd->oobsize; 396 scanlen = mtd->writesize + mtd->oobsize;
302 readlen = len * mtd->writesize; 397 readlen = len * mtd->writesize;
303 ooblen = len * mtd->oobsize;
304 } 398 }
305 399
306 if (chip == -1) { 400 if (chip == -1) {
307 /* Note that numblocks is 2 * (real numblocks) here, see i+=2 below as it 401 /* Note that numblocks is 2 * (real numblocks) here, see i+=2
308 * makes shifting and masking less painful */ 402 * below as it makes shifting and masking less painful */
309 numblocks = mtd->size >> (this->bbt_erase_shift - 1); 403 numblocks = mtd->size >> (this->bbt_erase_shift - 1);
310 startblock = 0; 404 startblock = 0;
311 from = 0; 405 from = 0;
@@ -324,35 +418,21 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
324 for (i = startblock; i < numblocks;) { 418 for (i = startblock; i < numblocks;) {
325 int ret; 419 int ret;
326 420
327 if (bd->options & NAND_BBT_SCANEMPTY) 421 if (bd->options & NAND_BBT_SCANALLPAGES)
328 if ((ret = nand_read_raw(mtd, buf, from, readlen, ooblen))) 422 ret = scan_block_full(mtd, bd, from, buf, readlen,
329 return ret; 423 scanlen, len);
330 424 else
331 for (j = 0; j < len; j++) { 425 ret = scan_block_fast(mtd, bd, from, buf, len);
332 if (!(bd->options & NAND_BBT_SCANEMPTY)) { 426
333 size_t retlen; 427 if (ret < 0)
334 428 return ret;
335 /* Read the full oob until read_oob is fixed to 429
336 * handle single byte reads for 16 bit buswidth */ 430 if (ret) {
337 ret = mtd->read_oob(mtd, from + j * mtd->writesize, mtd->oobsize, &retlen, buf); 431 this->bbt[i >> 3] |= 0x03 << (i & 0x6);
338 if (ret) 432 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
339 return ret; 433 i >> 1, (unsigned int)from);
340
341 if (check_short_pattern(buf, bd)) {
342 this->bbt[i >> 3] |= 0x03 << (i & 0x6);
343 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
344 i >> 1, (unsigned int)from);
345 break;
346 }
347 } else {
348 if (check_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
349 this->bbt[i >> 3] |= 0x03 << (i & 0x6);
350 printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
351 i >> 1, (unsigned int)from);
352 break;
353 }
354 }
355 } 434 }
435
356 i += 2; 436 i += 2;
357 from += (1 << this->bbt_erase_shift); 437 from += (1 << this->bbt_erase_shift);
358 } 438 }
@@ -383,6 +463,7 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
383 int bits, startblock, block, dir; 463 int bits, startblock, block, dir;
384 int scanlen = mtd->writesize + mtd->oobsize; 464 int scanlen = mtd->writesize + mtd->oobsize;
385 int bbtblocks; 465 int bbtblocks;
466 int blocktopage = this->bbt_erase_shift - this->page_shift;
386 467
387 /* Search direction top -> down ? */ 468 /* Search direction top -> down ? */
388 if (td->options & NAND_BBT_LASTBLOCK) { 469 if (td->options & NAND_BBT_LASTBLOCK) {
@@ -412,11 +493,14 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
412 td->pages[i] = -1; 493 td->pages[i] = -1;
413 /* Scan the maximum number of blocks */ 494 /* Scan the maximum number of blocks */
414 for (block = 0; block < td->maxblocks; block++) { 495 for (block = 0; block < td->maxblocks; block++) {
496
415 int actblock = startblock + dir * block; 497 int actblock = startblock + dir * block;
498 loff_t offs = actblock << this->bbt_erase_shift;
499
416 /* Read first page */ 500 /* Read first page */
417 nand_read_raw(mtd, buf, actblock << this->bbt_erase_shift, mtd->writesize, mtd->oobsize); 501 scan_read_raw(mtd, buf, offs, mtd->writesize);
418 if (!check_pattern(buf, scanlen, mtd->writesize, td)) { 502 if (!check_pattern(buf, scanlen, mtd->writesize, td)) {
419 td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift); 503 td->pages[i] = actblock << blocktopage;
420 if (td->options & NAND_BBT_VERSION) { 504 if (td->options & NAND_BBT_VERSION) {
421 td->version[i] = buf[mtd->writesize + td->veroffs]; 505 td->version[i] = buf[mtd->writesize + td->veroffs];
422 } 506 }
@@ -481,8 +565,14 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
481 int nrchips, bbtoffs, pageoffs, ooboffs; 565 int nrchips, bbtoffs, pageoffs, ooboffs;
482 uint8_t msk[4]; 566 uint8_t msk[4];
483 uint8_t rcode = td->reserved_block_code; 567 uint8_t rcode = td->reserved_block_code;
484 size_t retlen, len = 0, ooblen; 568 size_t retlen, len = 0;
485 loff_t to; 569 loff_t to;
570 struct mtd_oob_ops ops;
571
572 ops.ooblen = mtd->oobsize;
573 ops.ooboffs = 0;
574 ops.datbuf = NULL;
575 ops.mode = MTD_OOB_PLACE;
486 576
487 if (!rcode) 577 if (!rcode)
488 rcode = 0xff; 578 rcode = 0xff;
@@ -583,10 +673,10 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
583 "bad block table\n"); 673 "bad block table\n");
584 } 674 }
585 /* Read oob data */ 675 /* Read oob data */
586 ooblen = (len >> this->page_shift) * mtd->oobsize; 676 ops.len = (len >> this->page_shift) * mtd->oobsize;
587 res = mtd->read_oob(mtd, to + mtd->writesize, ooblen, 677 ops.oobbuf = &buf[len];
588 &retlen, &buf[len]); 678 res = mtd->read_oob(mtd, to + mtd->writesize, &ops);
589 if (res < 0 || retlen != ooblen) 679 if (res < 0 || ops.retlen != ops.len)
590 goto outerr; 680 goto outerr;
591 681
592 /* Calc the byte offset in the buffer */ 682 /* Calc the byte offset in the buffer */
@@ -635,7 +725,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf,
635 if (res < 0) 725 if (res < 0)
636 goto outerr; 726 goto outerr;
637 727
638 res = nand_write_raw(mtd, to, len, &retlen, buf, &buf[len]); 728 res = scan_write_bbt(mtd, to, len, buf, &buf[len]);
639 if (res < 0) 729 if (res < 0)
640 goto outerr; 730 goto outerr;
641 731