diff options
Diffstat (limited to 'drivers/mtd/nand/nand_bbt.c')
-rw-r--r-- | drivers/mtd/nand/nand_bbt.c | 692 |
1 files changed, 324 insertions, 368 deletions
diff --git a/drivers/mtd/nand/nand_bbt.c b/drivers/mtd/nand/nand_bbt.c index 4165857752ca..69148ae3bf58 100644 --- a/drivers/mtd/nand/nand_bbt.c +++ b/drivers/mtd/nand/nand_bbt.c | |||
@@ -14,7 +14,7 @@ | |||
14 | * | 14 | * |
15 | * When nand_scan_bbt is called, then it tries to find the bad block table | 15 | * When nand_scan_bbt is called, then it tries to find the bad block table |
16 | * depending on the options in the BBT descriptor(s). If no flash based BBT | 16 | * depending on the options in the BBT descriptor(s). If no flash based BBT |
17 | * (NAND_USE_FLASH_BBT) is specified then the device is scanned for factory | 17 | * (NAND_BBT_USE_FLASH) is specified then the device is scanned for factory |
18 | * marked good / bad blocks. This information is used to create a memory BBT. | 18 | * marked good / bad blocks. This information is used to create a memory BBT. |
19 | * Once a new bad block is discovered then the "factory" information is updated | 19 | * Once a new bad block is discovered then the "factory" information is updated |
20 | * on the device. | 20 | * on the device. |
@@ -36,9 +36,9 @@ | |||
36 | * The table is marked in the OOB area with an ident pattern and a version | 36 | * The table is marked in the OOB area with an ident pattern and a version |
37 | * number which indicates which of both tables is more up to date. If the NAND | 37 | * number which indicates which of both tables is more up to date. If the NAND |
38 | * controller needs the complete OOB area for the ECC information then the | 38 | * controller needs the complete OOB area for the ECC information then the |
39 | * option NAND_USE_FLASH_BBT_NO_OOB should be used: it moves the ident pattern | 39 | * option NAND_BBT_NO_OOB should be used (along with NAND_BBT_USE_FLASH, of |
40 | * and the version byte into the data area and the OOB area will remain | 40 | * course): it moves the ident pattern and the version byte into the data area |
41 | * untouched. | 41 | * and the OOB area will remain untouched. |
42 | * | 42 | * |
43 | * The table uses 2 bits per block | 43 | * The table uses 2 bits per block |
44 | * 11b: block is good | 44 | * 11b: block is good |
@@ -81,17 +81,15 @@ static int check_pattern_no_oob(uint8_t *buf, struct nand_bbt_descr *td) | |||
81 | 81 | ||
82 | /** | 82 | /** |
83 | * check_pattern - [GENERIC] check if a pattern is in the buffer | 83 | * check_pattern - [GENERIC] check if a pattern is in the buffer |
84 | * @buf: the buffer to search | 84 | * @buf: the buffer to search |
85 | * @len: the length of buffer to search | 85 | * @len: the length of buffer to search |
86 | * @paglen: the pagelength | 86 | * @paglen: the pagelength |
87 | * @td: search pattern descriptor | 87 | * @td: search pattern descriptor |
88 | * | 88 | * |
89 | * Check for a pattern at the given place. Used to search bad block | 89 | * Check for a pattern at the given place. Used to search bad block tables and |
90 | * tables and good / bad block identifiers. | 90 | * good / bad block identifiers. If the SCAN_EMPTY option is set then check, if |
91 | * If the SCAN_EMPTY option is set then check, if all bytes except the | 91 | * all bytes except the pattern area contain 0xff. |
92 | * pattern area contain 0xff | 92 | */ |
93 | * | ||
94 | */ | ||
95 | static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td) | 93 | static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_descr *td) |
96 | { | 94 | { |
97 | int i, end = 0; | 95 | int i, end = 0; |
@@ -110,32 +108,8 @@ static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_desc | |||
110 | p += end; | 108 | p += end; |
111 | 109 | ||
112 | /* Compare the pattern */ | 110 | /* Compare the pattern */ |
113 | for (i = 0; i < td->len; i++) { | 111 | if (memcmp(p, td->pattern, td->len)) |
114 | if (p[i] != td->pattern[i]) | 112 | return -1; |
115 | return -1; | ||
116 | } | ||
117 | |||
118 | /* Check both positions 1 and 6 for pattern? */ | ||
119 | if (td->options & NAND_BBT_SCANBYTE1AND6) { | ||
120 | if (td->options & NAND_BBT_SCANEMPTY) { | ||
121 | p += td->len; | ||
122 | end += NAND_SMALL_BADBLOCK_POS - td->offs; | ||
123 | /* Check region between positions 1 and 6 */ | ||
124 | for (i = 0; i < NAND_SMALL_BADBLOCK_POS - td->offs - td->len; | ||
125 | i++) { | ||
126 | if (*p++ != 0xff) | ||
127 | return -1; | ||
128 | } | ||
129 | } | ||
130 | else { | ||
131 | p += NAND_SMALL_BADBLOCK_POS - td->offs; | ||
132 | } | ||
133 | /* Compare the pattern */ | ||
134 | for (i = 0; i < td->len; i++) { | ||
135 | if (p[i] != td->pattern[i]) | ||
136 | return -1; | ||
137 | } | ||
138 | } | ||
139 | 113 | ||
140 | if (td->options & NAND_BBT_SCANEMPTY) { | 114 | if (td->options & NAND_BBT_SCANEMPTY) { |
141 | p += td->len; | 115 | p += td->len; |
@@ -150,14 +124,13 @@ static int check_pattern(uint8_t *buf, int len, int paglen, struct nand_bbt_desc | |||
150 | 124 | ||
151 | /** | 125 | /** |
152 | * check_short_pattern - [GENERIC] check if a pattern is in the buffer | 126 | * check_short_pattern - [GENERIC] check if a pattern is in the buffer |
153 | * @buf: the buffer to search | 127 | * @buf: the buffer to search |
154 | * @td: search pattern descriptor | 128 | * @td: search pattern descriptor |
155 | * | ||
156 | * Check for a pattern at the given place. Used to search bad block | ||
157 | * tables and good / bad block identifiers. Same as check_pattern, but | ||
158 | * no optional empty check | ||
159 | * | 129 | * |
160 | */ | 130 | * Check for a pattern at the given place. Used to search bad block tables and |
131 | * good / bad block identifiers. Same as check_pattern, but no optional empty | ||
132 | * check. | ||
133 | */ | ||
161 | static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td) | 134 | static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td) |
162 | { | 135 | { |
163 | int i; | 136 | int i; |
@@ -168,21 +141,14 @@ static int check_short_pattern(uint8_t *buf, struct nand_bbt_descr *td) | |||
168 | if (p[td->offs + i] != td->pattern[i]) | 141 | if (p[td->offs + i] != td->pattern[i]) |
169 | return -1; | 142 | return -1; |
170 | } | 143 | } |
171 | /* Need to check location 1 AND 6? */ | ||
172 | if (td->options & NAND_BBT_SCANBYTE1AND6) { | ||
173 | for (i = 0; i < td->len; i++) { | ||
174 | if (p[NAND_SMALL_BADBLOCK_POS + i] != td->pattern[i]) | ||
175 | return -1; | ||
176 | } | ||
177 | } | ||
178 | return 0; | 144 | return 0; |
179 | } | 145 | } |
180 | 146 | ||
181 | /** | 147 | /** |
182 | * add_marker_len - compute the length of the marker in data area | 148 | * add_marker_len - compute the length of the marker in data area |
183 | * @td: BBT descriptor used for computation | 149 | * @td: BBT descriptor used for computation |
184 | * | 150 | * |
185 | * The length will be 0 if the markeris located in OOB area. | 151 | * The length will be 0 if the marker is located in OOB area. |
186 | */ | 152 | */ |
187 | static u32 add_marker_len(struct nand_bbt_descr *td) | 153 | static u32 add_marker_len(struct nand_bbt_descr *td) |
188 | { | 154 | { |
@@ -199,34 +165,33 @@ static u32 add_marker_len(struct nand_bbt_descr *td) | |||
199 | 165 | ||
200 | /** | 166 | /** |
201 | * read_bbt - [GENERIC] Read the bad block table starting from page | 167 | * read_bbt - [GENERIC] Read the bad block table starting from page |
202 | * @mtd: MTD device structure | 168 | * @mtd: MTD device structure |
203 | * @buf: temporary buffer | 169 | * @buf: temporary buffer |
204 | * @page: the starting page | 170 | * @page: the starting page |
205 | * @num: the number of bbt descriptors to read | 171 | * @num: the number of bbt descriptors to read |
206 | * @td: the bbt describtion table | 172 | * @td: the bbt describtion table |
207 | * @offs: offset in the memory table | 173 | * @offs: offset in the memory table |
208 | * | 174 | * |
209 | * Read the bad block table starting from page. | 175 | * Read the bad block table starting from page. |
210 | * | ||
211 | */ | 176 | */ |
212 | static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, | 177 | static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, |
213 | struct nand_bbt_descr *td, int offs) | 178 | struct nand_bbt_descr *td, int offs) |
214 | { | 179 | { |
215 | int res, i, j, act = 0; | 180 | int res, ret = 0, i, j, act = 0; |
216 | struct nand_chip *this = mtd->priv; | 181 | struct nand_chip *this = mtd->priv; |
217 | size_t retlen, len, totlen; | 182 | size_t retlen, len, totlen; |
218 | loff_t from; | 183 | loff_t from; |
219 | int bits = td->options & NAND_BBT_NRBITS_MSK; | 184 | int bits = td->options & NAND_BBT_NRBITS_MSK; |
220 | uint8_t msk = (uint8_t) ((1 << bits) - 1); | 185 | uint8_t msk = (uint8_t)((1 << bits) - 1); |
221 | u32 marker_len; | 186 | u32 marker_len; |
222 | int reserved_block_code = td->reserved_block_code; | 187 | int reserved_block_code = td->reserved_block_code; |
223 | 188 | ||
224 | totlen = (num * bits) >> 3; | 189 | totlen = (num * bits) >> 3; |
225 | marker_len = add_marker_len(td); | 190 | marker_len = add_marker_len(td); |
226 | from = ((loff_t) page) << this->page_shift; | 191 | from = ((loff_t)page) << this->page_shift; |
227 | 192 | ||
228 | while (totlen) { | 193 | while (totlen) { |
229 | len = min(totlen, (size_t) (1 << this->bbt_erase_shift)); | 194 | len = min(totlen, (size_t)(1 << this->bbt_erase_shift)); |
230 | if (marker_len) { | 195 | if (marker_len) { |
231 | /* | 196 | /* |
232 | * In case the BBT marker is not in the OOB area it | 197 | * In case the BBT marker is not in the OOB area it |
@@ -238,11 +203,18 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, | |||
238 | } | 203 | } |
239 | res = mtd->read(mtd, from, len, &retlen, buf); | 204 | res = mtd->read(mtd, from, len, &retlen, buf); |
240 | if (res < 0) { | 205 | if (res < 0) { |
241 | if (retlen != len) { | 206 | if (mtd_is_eccerr(res)) { |
242 | printk(KERN_INFO "nand_bbt: Error reading bad block table\n"); | 207 | pr_info("nand_bbt: ECC error in BBT at " |
208 | "0x%012llx\n", from & ~mtd->writesize); | ||
209 | return res; | ||
210 | } else if (mtd_is_bitflip(res)) { | ||
211 | pr_info("nand_bbt: corrected error in BBT at " | ||
212 | "0x%012llx\n", from & ~mtd->writesize); | ||
213 | ret = res; | ||
214 | } else { | ||
215 | pr_info("nand_bbt: error reading BBT\n"); | ||
243 | return res; | 216 | return res; |
244 | } | 217 | } |
245 | printk(KERN_WARNING "nand_bbt: ECC error while reading bad block table\n"); | ||
246 | } | 218 | } |
247 | 219 | ||
248 | /* Analyse data */ | 220 | /* Analyse data */ |
@@ -253,17 +225,19 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, | |||
253 | if (tmp == msk) | 225 | if (tmp == msk) |
254 | continue; | 226 | continue; |
255 | if (reserved_block_code && (tmp == reserved_block_code)) { | 227 | if (reserved_block_code && (tmp == reserved_block_code)) { |
256 | printk(KERN_DEBUG "nand_read_bbt: Reserved block at 0x%012llx\n", | 228 | pr_info("nand_read_bbt: reserved block at 0x%012llx\n", |
257 | (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift); | 229 | (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift); |
258 | this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06); | 230 | this->bbt[offs + (act >> 3)] |= 0x2 << (act & 0x06); |
259 | mtd->ecc_stats.bbtblocks++; | 231 | mtd->ecc_stats.bbtblocks++; |
260 | continue; | 232 | continue; |
261 | } | 233 | } |
262 | /* Leave it for now, if its matured we can move this | 234 | /* |
263 | * message to MTD_DEBUG_LEVEL0 */ | 235 | * Leave it for now, if it's matured we can |
264 | printk(KERN_DEBUG "nand_read_bbt: Bad block at 0x%012llx\n", | 236 | * move this message to pr_debug. |
265 | (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift); | 237 | */ |
266 | /* Factory marked bad or worn out ? */ | 238 | pr_info("nand_read_bbt: bad block at 0x%012llx\n", |
239 | (loff_t)((offs << 2) + (act >> 1)) << this->bbt_erase_shift); | ||
240 | /* Factory marked bad or worn out? */ | ||
267 | if (tmp == 0) | 241 | if (tmp == 0) |
268 | this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06); | 242 | this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06); |
269 | else | 243 | else |
@@ -274,20 +248,20 @@ static int read_bbt(struct mtd_info *mtd, uint8_t *buf, int page, int num, | |||
274 | totlen -= len; | 248 | totlen -= len; |
275 | from += len; | 249 | from += len; |
276 | } | 250 | } |
277 | return 0; | 251 | return ret; |
278 | } | 252 | } |
279 | 253 | ||
280 | /** | 254 | /** |
281 | * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page | 255 | * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page |
282 | * @mtd: MTD device structure | 256 | * @mtd: MTD device structure |
283 | * @buf: temporary buffer | 257 | * @buf: temporary buffer |
284 | * @td: descriptor for the bad block table | 258 | * @td: descriptor for the bad block table |
285 | * @chip: read the table for a specific chip, -1 read all chips. | 259 | * @chip: read the table for a specific chip, -1 read all chips; applies only if |
286 | * Applies only if NAND_BBT_PERCHIP option is set | 260 | * NAND_BBT_PERCHIP option is set |
287 | * | 261 | * |
288 | * Read the bad block table for all chips starting at a given page | 262 | * Read the bad block table for all chips starting at a given page. We assume |
289 | * We assume that the bbt bits are in consecutive order. | 263 | * that the bbt bits are in consecutive order. |
290 | */ | 264 | */ |
291 | static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip) | 265 | static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td, int chip) |
292 | { | 266 | { |
293 | struct nand_chip *this = mtd->priv; | 267 | struct nand_chip *this = mtd->priv; |
@@ -313,9 +287,7 @@ static int read_abs_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc | |||
313 | return 0; | 287 | return 0; |
314 | } | 288 | } |
315 | 289 | ||
316 | /* | 290 | /* BBT marker is in the first page, no OOB */ |
317 | * BBT marker is in the first page, no OOB. | ||
318 | */ | ||
319 | static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs, | 291 | static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs, |
320 | struct nand_bbt_descr *td) | 292 | struct nand_bbt_descr *td) |
321 | { | 293 | { |
@@ -329,35 +301,26 @@ static int scan_read_raw_data(struct mtd_info *mtd, uint8_t *buf, loff_t offs, | |||
329 | return mtd->read(mtd, offs, len, &retlen, buf); | 301 | return mtd->read(mtd, offs, len, &retlen, buf); |
330 | } | 302 | } |
331 | 303 | ||
332 | /* | 304 | /* Scan read raw data from flash */ |
333 | * Scan read raw data from flash | ||
334 | */ | ||
335 | static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs, | 305 | static int scan_read_raw_oob(struct mtd_info *mtd, uint8_t *buf, loff_t offs, |
336 | size_t len) | 306 | size_t len) |
337 | { | 307 | { |
338 | struct mtd_oob_ops ops; | 308 | struct mtd_oob_ops ops; |
339 | int res; | 309 | int res; |
340 | 310 | ||
341 | ops.mode = MTD_OOB_RAW; | 311 | ops.mode = MTD_OPS_RAW; |
342 | ops.ooboffs = 0; | 312 | ops.ooboffs = 0; |
343 | ops.ooblen = mtd->oobsize; | 313 | ops.ooblen = mtd->oobsize; |
344 | 314 | ||
345 | |||
346 | while (len > 0) { | 315 | while (len > 0) { |
347 | if (len <= mtd->writesize) { | 316 | ops.datbuf = buf; |
348 | ops.oobbuf = buf + len; | 317 | ops.len = min(len, (size_t)mtd->writesize); |
349 | ops.datbuf = buf; | 318 | ops.oobbuf = buf + ops.len; |
350 | ops.len = len; | ||
351 | return mtd->read_oob(mtd, offs, &ops); | ||
352 | } else { | ||
353 | ops.oobbuf = buf + mtd->writesize; | ||
354 | ops.datbuf = buf; | ||
355 | ops.len = mtd->writesize; | ||
356 | res = mtd->read_oob(mtd, offs, &ops); | ||
357 | 319 | ||
358 | if (res) | 320 | res = mtd->read_oob(mtd, offs, &ops); |
359 | return res; | 321 | |
360 | } | 322 | if (res) |
323 | return res; | ||
361 | 324 | ||
362 | buf += mtd->oobsize + mtd->writesize; | 325 | buf += mtd->oobsize + mtd->writesize; |
363 | len -= mtd->writesize; | 326 | len -= mtd->writesize; |
@@ -374,15 +337,13 @@ static int scan_read_raw(struct mtd_info *mtd, uint8_t *buf, loff_t offs, | |||
374 | return scan_read_raw_oob(mtd, buf, offs, len); | 337 | return scan_read_raw_oob(mtd, buf, offs, len); |
375 | } | 338 | } |
376 | 339 | ||
377 | /* | 340 | /* Scan write data with oob to flash */ |
378 | * Scan write data with oob to flash | ||
379 | */ | ||
380 | static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len, | 341 | static int scan_write_bbt(struct mtd_info *mtd, loff_t offs, size_t len, |
381 | uint8_t *buf, uint8_t *oob) | 342 | uint8_t *buf, uint8_t *oob) |
382 | { | 343 | { |
383 | struct mtd_oob_ops ops; | 344 | struct mtd_oob_ops ops; |
384 | 345 | ||
385 | ops.mode = MTD_OOB_PLACE; | 346 | ops.mode = MTD_OPS_PLACE_OOB; |
386 | ops.ooboffs = 0; | 347 | ops.ooboffs = 0; |
387 | ops.ooblen = mtd->oobsize; | 348 | ops.ooblen = mtd->oobsize; |
388 | ops.datbuf = buf; | 349 | ops.datbuf = buf; |
@@ -403,15 +364,14 @@ static u32 bbt_get_ver_offs(struct mtd_info *mtd, struct nand_bbt_descr *td) | |||
403 | 364 | ||
404 | /** | 365 | /** |
405 | * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page | 366 | * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page |
406 | * @mtd: MTD device structure | 367 | * @mtd: MTD device structure |
407 | * @buf: temporary buffer | 368 | * @buf: temporary buffer |
408 | * @td: descriptor for the bad block table | 369 | * @td: descriptor for the bad block table |
409 | * @md: descriptor for the bad block table mirror | 370 | * @md: descriptor for the bad block table mirror |
410 | * | 371 | * |
411 | * Read the bad block table(s) for all chips starting at a given page | 372 | * Read the bad block table(s) for all chips starting at a given page. We |
412 | * We assume that the bbt bits are in consecutive order. | 373 | * assume that the bbt bits are in consecutive order. |
413 | * | 374 | */ |
414 | */ | ||
415 | static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, | 375 | static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, |
416 | struct nand_bbt_descr *td, struct nand_bbt_descr *md) | 376 | struct nand_bbt_descr *td, struct nand_bbt_descr *md) |
417 | { | 377 | { |
@@ -422,8 +382,8 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, | |||
422 | scan_read_raw(mtd, buf, (loff_t)td->pages[0] << this->page_shift, | 382 | scan_read_raw(mtd, buf, (loff_t)td->pages[0] << this->page_shift, |
423 | mtd->writesize, td); | 383 | mtd->writesize, td); |
424 | td->version[0] = buf[bbt_get_ver_offs(mtd, td)]; | 384 | td->version[0] = buf[bbt_get_ver_offs(mtd, td)]; |
425 | printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", | 385 | pr_info("Bad block table at page %d, version 0x%02X\n", |
426 | td->pages[0], td->version[0]); | 386 | td->pages[0], td->version[0]); |
427 | } | 387 | } |
428 | 388 | ||
429 | /* Read the mirror version, if available */ | 389 | /* Read the mirror version, if available */ |
@@ -431,15 +391,13 @@ static int read_abs_bbts(struct mtd_info *mtd, uint8_t *buf, | |||
431 | scan_read_raw(mtd, buf, (loff_t)md->pages[0] << this->page_shift, | 391 | scan_read_raw(mtd, buf, (loff_t)md->pages[0] << this->page_shift, |
432 | mtd->writesize, td); | 392 | mtd->writesize, td); |
433 | md->version[0] = buf[bbt_get_ver_offs(mtd, md)]; | 393 | md->version[0] = buf[bbt_get_ver_offs(mtd, md)]; |
434 | printk(KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", | 394 | pr_info("Bad block table at page %d, version 0x%02X\n", |
435 | md->pages[0], md->version[0]); | 395 | md->pages[0], md->version[0]); |
436 | } | 396 | } |
437 | return 1; | 397 | return 1; |
438 | } | 398 | } |
439 | 399 | ||
440 | /* | 400 | /* Scan a given block full */ |
441 | * Scan a given block full | ||
442 | */ | ||
443 | static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd, | 401 | static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd, |
444 | loff_t offs, uint8_t *buf, size_t readlen, | 402 | loff_t offs, uint8_t *buf, size_t readlen, |
445 | int scanlen, int len) | 403 | int scanlen, int len) |
@@ -447,7 +405,8 @@ static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd, | |||
447 | int ret, j; | 405 | int ret, j; |
448 | 406 | ||
449 | ret = scan_read_raw_oob(mtd, buf, offs, readlen); | 407 | ret = scan_read_raw_oob(mtd, buf, offs, readlen); |
450 | if (ret) | 408 | /* Ignore ECC errors when checking for BBM */ |
409 | if (ret && !mtd_is_bitflip_or_eccerr(ret)) | ||
451 | return ret; | 410 | return ret; |
452 | 411 | ||
453 | for (j = 0; j < len; j++, buf += scanlen) { | 412 | for (j = 0; j < len; j++, buf += scanlen) { |
@@ -457,9 +416,7 @@ static int scan_block_full(struct mtd_info *mtd, struct nand_bbt_descr *bd, | |||
457 | return 0; | 416 | return 0; |
458 | } | 417 | } |
459 | 418 | ||
460 | /* | 419 | /* Scan a given block partially */ |
461 | * Scan a given block partially | ||
462 | */ | ||
463 | static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd, | 420 | static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd, |
464 | loff_t offs, uint8_t *buf, int len) | 421 | loff_t offs, uint8_t *buf, int len) |
465 | { | 422 | { |
@@ -470,16 +427,16 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd, | |||
470 | ops.oobbuf = buf; | 427 | ops.oobbuf = buf; |
471 | ops.ooboffs = 0; | 428 | ops.ooboffs = 0; |
472 | ops.datbuf = NULL; | 429 | ops.datbuf = NULL; |
473 | ops.mode = MTD_OOB_PLACE; | 430 | ops.mode = MTD_OPS_PLACE_OOB; |
474 | 431 | ||
475 | for (j = 0; j < len; j++) { | 432 | for (j = 0; j < len; j++) { |
476 | /* | 433 | /* |
477 | * Read the full oob until read_oob is fixed to | 434 | * Read the full oob until read_oob is fixed to handle single |
478 | * handle single byte reads for 16 bit | 435 | * byte reads for 16 bit buswidth. |
479 | * buswidth | ||
480 | */ | 436 | */ |
481 | ret = mtd->read_oob(mtd, offs, &ops); | 437 | ret = mtd->read_oob(mtd, offs, &ops); |
482 | if (ret) | 438 | /* Ignore ECC errors when checking for BBM */ |
439 | if (ret && !mtd_is_bitflip_or_eccerr(ret)) | ||
483 | return ret; | 440 | return ret; |
484 | 441 | ||
485 | if (check_short_pattern(buf, bd)) | 442 | if (check_short_pattern(buf, bd)) |
@@ -492,14 +449,14 @@ static int scan_block_fast(struct mtd_info *mtd, struct nand_bbt_descr *bd, | |||
492 | 449 | ||
493 | /** | 450 | /** |
494 | * create_bbt - [GENERIC] Create a bad block table by scanning the device | 451 | * create_bbt - [GENERIC] Create a bad block table by scanning the device |
495 | * @mtd: MTD device structure | 452 | * @mtd: MTD device structure |
496 | * @buf: temporary buffer | 453 | * @buf: temporary buffer |
497 | * @bd: descriptor for the good/bad block search pattern | 454 | * @bd: descriptor for the good/bad block search pattern |
498 | * @chip: create the table for a specific chip, -1 read all chips. | 455 | * @chip: create the table for a specific chip, -1 read all chips; applies only |
499 | * Applies only if NAND_BBT_PERCHIP option is set | 456 | * if NAND_BBT_PERCHIP option is set |
500 | * | 457 | * |
501 | * Create a bad block table by scanning the device | 458 | * Create a bad block table by scanning the device for the given good/bad block |
502 | * for the given good/bad block identify pattern | 459 | * identify pattern. |
503 | */ | 460 | */ |
504 | static int create_bbt(struct mtd_info *mtd, uint8_t *buf, | 461 | static int create_bbt(struct mtd_info *mtd, uint8_t *buf, |
505 | struct nand_bbt_descr *bd, int chip) | 462 | struct nand_bbt_descr *bd, int chip) |
@@ -510,7 +467,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
510 | loff_t from; | 467 | loff_t from; |
511 | size_t readlen; | 468 | size_t readlen; |
512 | 469 | ||
513 | printk(KERN_INFO "Scanning device for bad blocks\n"); | 470 | pr_info("Scanning device for bad blocks\n"); |
514 | 471 | ||
515 | if (bd->options & NAND_BBT_SCANALLPAGES) | 472 | if (bd->options & NAND_BBT_SCANALLPAGES) |
516 | len = 1 << (this->bbt_erase_shift - this->page_shift); | 473 | len = 1 << (this->bbt_erase_shift - this->page_shift); |
@@ -530,14 +487,16 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
530 | } | 487 | } |
531 | 488 | ||
532 | if (chip == -1) { | 489 | if (chip == -1) { |
533 | /* Note that numblocks is 2 * (real numblocks) here, see i+=2 | 490 | /* |
534 | * below as it makes shifting and masking less painful */ | 491 | * Note that numblocks is 2 * (real numblocks) here, see i+=2 |
492 | * below as it makes shifting and masking less painful | ||
493 | */ | ||
535 | numblocks = mtd->size >> (this->bbt_erase_shift - 1); | 494 | numblocks = mtd->size >> (this->bbt_erase_shift - 1); |
536 | startblock = 0; | 495 | startblock = 0; |
537 | from = 0; | 496 | from = 0; |
538 | } else { | 497 | } else { |
539 | if (chip >= this->numchips) { | 498 | if (chip >= this->numchips) { |
540 | printk(KERN_WARNING "create_bbt(): chipnr (%d) > available chips (%d)\n", | 499 | pr_warn("create_bbt(): chipnr (%d) > available chips (%d)\n", |
541 | chip + 1, this->numchips); | 500 | chip + 1, this->numchips); |
542 | return -EINVAL; | 501 | return -EINVAL; |
543 | } | 502 | } |
@@ -547,7 +506,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
547 | from = (loff_t)startblock << (this->bbt_erase_shift - 1); | 506 | from = (loff_t)startblock << (this->bbt_erase_shift - 1); |
548 | } | 507 | } |
549 | 508 | ||
550 | if (this->options & NAND_BBT_SCANLASTPAGE) | 509 | if (this->bbt_options & NAND_BBT_SCANLASTPAGE) |
551 | from += mtd->erasesize - (mtd->writesize * len); | 510 | from += mtd->erasesize - (mtd->writesize * len); |
552 | 511 | ||
553 | for (i = startblock; i < numblocks;) { | 512 | for (i = startblock; i < numblocks;) { |
@@ -566,8 +525,8 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
566 | 525 | ||
567 | if (ret) { | 526 | if (ret) { |
568 | this->bbt[i >> 3] |= 0x03 << (i & 0x6); | 527 | this->bbt[i >> 3] |= 0x03 << (i & 0x6); |
569 | printk(KERN_WARNING "Bad eraseblock %d at 0x%012llx\n", | 528 | pr_warn("Bad eraseblock %d at 0x%012llx\n", |
570 | i >> 1, (unsigned long long)from); | 529 | i >> 1, (unsigned long long)from); |
571 | mtd->ecc_stats.badblocks++; | 530 | mtd->ecc_stats.badblocks++; |
572 | } | 531 | } |
573 | 532 | ||
@@ -579,20 +538,18 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
579 | 538 | ||
580 | /** | 539 | /** |
581 | * search_bbt - [GENERIC] scan the device for a specific bad block table | 540 | * search_bbt - [GENERIC] scan the device for a specific bad block table |
582 | * @mtd: MTD device structure | 541 | * @mtd: MTD device structure |
583 | * @buf: temporary buffer | 542 | * @buf: temporary buffer |
584 | * @td: descriptor for the bad block table | 543 | * @td: descriptor for the bad block table |
585 | * | 544 | * |
586 | * Read the bad block table by searching for a given ident pattern. | 545 | * Read the bad block table by searching for a given ident pattern. Search is |
587 | * Search is preformed either from the beginning up or from the end of | 546 | * preformed either from the beginning up or from the end of the device |
588 | * the device downwards. The search starts always at the start of a | 547 | * downwards. The search starts always at the start of a block. If the option |
589 | * block. | 548 | * NAND_BBT_PERCHIP is given, each chip is searched for a bbt, which contains |
590 | * If the option NAND_BBT_PERCHIP is given, each chip is searched | 549 | * the bad block information of this chip. This is necessary to provide support |
591 | * for a bbt, which contains the bad block information of this chip. | 550 | * for certain DOC devices. |
592 | * This is necessary to provide support for certain DOC devices. | ||
593 | * | 551 | * |
594 | * The bbt ident pattern resides in the oob area of the first page | 552 | * The bbt ident pattern resides in the oob area of the first page in a block. |
595 | * in a block. | ||
596 | */ | 553 | */ |
597 | static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td) | 554 | static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td) |
598 | { | 555 | { |
@@ -603,7 +560,7 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr | |||
603 | int bbtblocks; | 560 | int bbtblocks; |
604 | int blocktopage = this->bbt_erase_shift - this->page_shift; | 561 | int blocktopage = this->bbt_erase_shift - this->page_shift; |
605 | 562 | ||
606 | /* Search direction top -> down ? */ | 563 | /* Search direction top -> down? */ |
607 | if (td->options & NAND_BBT_LASTBLOCK) { | 564 | if (td->options & NAND_BBT_LASTBLOCK) { |
608 | startblock = (mtd->size >> this->bbt_erase_shift) - 1; | 565 | startblock = (mtd->size >> this->bbt_erase_shift) - 1; |
609 | dir = -1; | 566 | dir = -1; |
@@ -612,7 +569,7 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr | |||
612 | dir = 1; | 569 | dir = 1; |
613 | } | 570 | } |
614 | 571 | ||
615 | /* Do we have a bbt per chip ? */ | 572 | /* Do we have a bbt per chip? */ |
616 | if (td->options & NAND_BBT_PERCHIP) { | 573 | if (td->options & NAND_BBT_PERCHIP) { |
617 | chips = this->numchips; | 574 | chips = this->numchips; |
618 | bbtblocks = this->chipsize >> this->bbt_erase_shift; | 575 | bbtblocks = this->chipsize >> this->bbt_erase_shift; |
@@ -651,23 +608,23 @@ static int search_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr | |||
651 | /* Check, if we found a bbt for each requested chip */ | 608 | /* Check, if we found a bbt for each requested chip */ |
652 | for (i = 0; i < chips; i++) { | 609 | for (i = 0; i < chips; i++) { |
653 | if (td->pages[i] == -1) | 610 | if (td->pages[i] == -1) |
654 | printk(KERN_WARNING "Bad block table not found for chip %d\n", i); | 611 | pr_warn("Bad block table not found for chip %d\n", i); |
655 | else | 612 | else |
656 | printk(KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], | 613 | pr_info("Bad block table found at page %d, version " |
657 | td->version[i]); | 614 | "0x%02X\n", td->pages[i], td->version[i]); |
658 | } | 615 | } |
659 | return 0; | 616 | return 0; |
660 | } | 617 | } |
661 | 618 | ||
662 | /** | 619 | /** |
663 | * search_read_bbts - [GENERIC] scan the device for bad block table(s) | 620 | * search_read_bbts - [GENERIC] scan the device for bad block table(s) |
664 | * @mtd: MTD device structure | 621 | * @mtd: MTD device structure |
665 | * @buf: temporary buffer | 622 | * @buf: temporary buffer |
666 | * @td: descriptor for the bad block table | 623 | * @td: descriptor for the bad block table |
667 | * @md: descriptor for the bad block table mirror | 624 | * @md: descriptor for the bad block table mirror |
668 | * | 625 | * |
669 | * Search and read the bad block table(s) | 626 | * Search and read the bad block table(s). |
670 | */ | 627 | */ |
671 | static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md) | 628 | static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt_descr *td, struct nand_bbt_descr *md) |
672 | { | 629 | { |
673 | /* Search the primary table */ | 630 | /* Search the primary table */ |
@@ -683,16 +640,14 @@ static int search_read_bbts(struct mtd_info *mtd, uint8_t * buf, struct nand_bbt | |||
683 | 640 | ||
684 | /** | 641 | /** |
685 | * write_bbt - [GENERIC] (Re)write the bad block table | 642 | * write_bbt - [GENERIC] (Re)write the bad block table |
643 | * @mtd: MTD device structure | ||
644 | * @buf: temporary buffer | ||
645 | * @td: descriptor for the bad block table | ||
646 | * @md: descriptor for the bad block table mirror | ||
647 | * @chipsel: selector for a specific chip, -1 for all | ||
686 | * | 648 | * |
687 | * @mtd: MTD device structure | 649 | * (Re)write the bad block table. |
688 | * @buf: temporary buffer | 650 | */ |
689 | * @td: descriptor for the bad block table | ||
690 | * @md: descriptor for the bad block table mirror | ||
691 | * @chipsel: selector for a specific chip, -1 for all | ||
692 | * | ||
693 | * (Re)write the bad block table | ||
694 | * | ||
695 | */ | ||
696 | static int write_bbt(struct mtd_info *mtd, uint8_t *buf, | 651 | static int write_bbt(struct mtd_info *mtd, uint8_t *buf, |
697 | struct nand_bbt_descr *td, struct nand_bbt_descr *md, | 652 | struct nand_bbt_descr *td, struct nand_bbt_descr *md, |
698 | int chipsel) | 653 | int chipsel) |
@@ -711,14 +666,14 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
711 | ops.ooblen = mtd->oobsize; | 666 | ops.ooblen = mtd->oobsize; |
712 | ops.ooboffs = 0; | 667 | ops.ooboffs = 0; |
713 | ops.datbuf = NULL; | 668 | ops.datbuf = NULL; |
714 | ops.mode = MTD_OOB_PLACE; | 669 | ops.mode = MTD_OPS_PLACE_OOB; |
715 | 670 | ||
716 | if (!rcode) | 671 | if (!rcode) |
717 | rcode = 0xff; | 672 | rcode = 0xff; |
718 | /* Write bad block table per chip rather than per device ? */ | 673 | /* Write bad block table per chip rather than per device? */ |
719 | if (td->options & NAND_BBT_PERCHIP) { | 674 | if (td->options & NAND_BBT_PERCHIP) { |
720 | numblocks = (int)(this->chipsize >> this->bbt_erase_shift); | 675 | numblocks = (int)(this->chipsize >> this->bbt_erase_shift); |
721 | /* Full device write or specific chip ? */ | 676 | /* Full device write or specific chip? */ |
722 | if (chipsel == -1) { | 677 | if (chipsel == -1) { |
723 | nrchips = this->numchips; | 678 | nrchips = this->numchips; |
724 | } else { | 679 | } else { |
@@ -732,8 +687,8 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
732 | 687 | ||
733 | /* Loop through the chips */ | 688 | /* Loop through the chips */ |
734 | for (; chip < nrchips; chip++) { | 689 | for (; chip < nrchips; chip++) { |
735 | 690 | /* | |
736 | /* There was already a version of the table, reuse the page | 691 | * There was already a version of the table, reuse the page |
737 | * This applies for absolute placement too, as we have the | 692 | * This applies for absolute placement too, as we have the |
738 | * page nr. in td->pages. | 693 | * page nr. in td->pages. |
739 | */ | 694 | */ |
@@ -742,8 +697,10 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
742 | goto write; | 697 | goto write; |
743 | } | 698 | } |
744 | 699 | ||
745 | /* Automatic placement of the bad block table */ | 700 | /* |
746 | /* Search direction top -> down ? */ | 701 | * Automatic placement of the bad block table. Search direction |
702 | * top -> down? | ||
703 | */ | ||
747 | if (td->options & NAND_BBT_LASTBLOCK) { | 704 | if (td->options & NAND_BBT_LASTBLOCK) { |
748 | startblock = numblocks * (chip + 1) - 1; | 705 | startblock = numblocks * (chip + 1) - 1; |
749 | dir = -1; | 706 | dir = -1; |
@@ -767,7 +724,7 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
767 | if (!md || md->pages[chip] != page) | 724 | if (!md || md->pages[chip] != page) |
768 | goto write; | 725 | goto write; |
769 | } | 726 | } |
770 | printk(KERN_ERR "No space left to write bad block table\n"); | 727 | pr_err("No space left to write bad block table\n"); |
771 | return -ENOSPC; | 728 | return -ENOSPC; |
772 | write: | 729 | write: |
773 | 730 | ||
@@ -792,24 +749,22 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
792 | 749 | ||
793 | bbtoffs = chip * (numblocks >> 2); | 750 | bbtoffs = chip * (numblocks >> 2); |
794 | 751 | ||
795 | to = ((loff_t) page) << this->page_shift; | 752 | to = ((loff_t)page) << this->page_shift; |
796 | 753 | ||
797 | /* Must we save the block contents ? */ | 754 | /* Must we save the block contents? */ |
798 | if (td->options & NAND_BBT_SAVECONTENT) { | 755 | if (td->options & NAND_BBT_SAVECONTENT) { |
799 | /* Make it block aligned */ | 756 | /* Make it block aligned */ |
800 | to &= ~((loff_t) ((1 << this->bbt_erase_shift) - 1)); | 757 | to &= ~((loff_t)((1 << this->bbt_erase_shift) - 1)); |
801 | len = 1 << this->bbt_erase_shift; | 758 | len = 1 << this->bbt_erase_shift; |
802 | res = mtd->read(mtd, to, len, &retlen, buf); | 759 | res = mtd->read(mtd, to, len, &retlen, buf); |
803 | if (res < 0) { | 760 | if (res < 0) { |
804 | if (retlen != len) { | 761 | if (retlen != len) { |
805 | printk(KERN_INFO "nand_bbt: Error " | 762 | pr_info("nand_bbt: error reading block " |
806 | "reading block for writing " | 763 | "for writing the bad block table\n"); |
807 | "the bad block table\n"); | ||
808 | return res; | 764 | return res; |
809 | } | 765 | } |
810 | printk(KERN_WARNING "nand_bbt: ECC error " | 766 | pr_warn("nand_bbt: ECC error while reading " |
811 | "while reading block for writing " | 767 | "block for writing bad block table\n"); |
812 | "bad block table\n"); | ||
813 | } | 768 | } |
814 | /* Read oob data */ | 769 | /* Read oob data */ |
815 | ops.ooblen = (len >> this->page_shift) * mtd->oobsize; | 770 | ops.ooblen = (len >> this->page_shift) * mtd->oobsize; |
@@ -822,19 +777,19 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
822 | pageoffs = page - (int)(to >> this->page_shift); | 777 | pageoffs = page - (int)(to >> this->page_shift); |
823 | offs = pageoffs << this->page_shift; | 778 | offs = pageoffs << this->page_shift; |
824 | /* Preset the bbt area with 0xff */ | 779 | /* Preset the bbt area with 0xff */ |
825 | memset(&buf[offs], 0xff, (size_t) (numblocks >> sft)); | 780 | memset(&buf[offs], 0xff, (size_t)(numblocks >> sft)); |
826 | ooboffs = len + (pageoffs * mtd->oobsize); | 781 | ooboffs = len + (pageoffs * mtd->oobsize); |
827 | 782 | ||
828 | } else if (td->options & NAND_BBT_NO_OOB) { | 783 | } else if (td->options & NAND_BBT_NO_OOB) { |
829 | ooboffs = 0; | 784 | ooboffs = 0; |
830 | offs = td->len; | 785 | offs = td->len; |
831 | /* the version byte */ | 786 | /* The version byte */ |
832 | if (td->options & NAND_BBT_VERSION) | 787 | if (td->options & NAND_BBT_VERSION) |
833 | offs++; | 788 | offs++; |
834 | /* Calc length */ | 789 | /* Calc length */ |
835 | len = (size_t) (numblocks >> sft); | 790 | len = (size_t)(numblocks >> sft); |
836 | len += offs; | 791 | len += offs; |
837 | /* Make it page aligned ! */ | 792 | /* Make it page aligned! */ |
838 | len = ALIGN(len, mtd->writesize); | 793 | len = ALIGN(len, mtd->writesize); |
839 | /* Preset the buffer with 0xff */ | 794 | /* Preset the buffer with 0xff */ |
840 | memset(buf, 0xff, len); | 795 | memset(buf, 0xff, len); |
@@ -842,8 +797,8 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
842 | memcpy(buf, td->pattern, td->len); | 797 | memcpy(buf, td->pattern, td->len); |
843 | } else { | 798 | } else { |
844 | /* Calc length */ | 799 | /* Calc length */ |
845 | len = (size_t) (numblocks >> sft); | 800 | len = (size_t)(numblocks >> sft); |
846 | /* Make it page aligned ! */ | 801 | /* Make it page aligned! */ |
847 | len = ALIGN(len, mtd->writesize); | 802 | len = ALIGN(len, mtd->writesize); |
848 | /* Preset the buffer with 0xff */ | 803 | /* Preset the buffer with 0xff */ |
849 | memset(buf, 0xff, len + | 804 | memset(buf, 0xff, len + |
@@ -857,13 +812,13 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
857 | if (td->options & NAND_BBT_VERSION) | 812 | if (td->options & NAND_BBT_VERSION) |
858 | buf[ooboffs + td->veroffs] = td->version[chip]; | 813 | buf[ooboffs + td->veroffs] = td->version[chip]; |
859 | 814 | ||
860 | /* walk through the memory table */ | 815 | /* Walk through the memory table */ |
861 | for (i = 0; i < numblocks;) { | 816 | for (i = 0; i < numblocks;) { |
862 | uint8_t dat; | 817 | uint8_t dat; |
863 | dat = this->bbt[bbtoffs + (i >> 2)]; | 818 | dat = this->bbt[bbtoffs + (i >> 2)]; |
864 | for (j = 0; j < 4; j++, i++) { | 819 | for (j = 0; j < 4; j++, i++) { |
865 | int sftcnt = (i << (3 - sft)) & sftmsk; | 820 | int sftcnt = (i << (3 - sft)) & sftmsk; |
866 | /* Do not store the reserved bbt blocks ! */ | 821 | /* Do not store the reserved bbt blocks! */ |
867 | buf[offs + (i >> sft)] &= | 822 | buf[offs + (i >> sft)] &= |
868 | ~(msk[dat & 0x03] << sftcnt); | 823 | ~(msk[dat & 0x03] << sftcnt); |
869 | dat >>= 2; | 824 | dat >>= 2; |
@@ -884,8 +839,8 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
884 | if (res < 0) | 839 | if (res < 0) |
885 | goto outerr; | 840 | goto outerr; |
886 | 841 | ||
887 | printk(KERN_DEBUG "Bad block table written to 0x%012llx, version " | 842 | pr_info("Bad block table written to 0x%012llx, version 0x%02X\n", |
888 | "0x%02X\n", (unsigned long long)to, td->version[chip]); | 843 | (unsigned long long)to, td->version[chip]); |
889 | 844 | ||
890 | /* Mark it as used */ | 845 | /* Mark it as used */ |
891 | td->pages[chip] = page; | 846 | td->pages[chip] = page; |
@@ -893,19 +848,18 @@ static int write_bbt(struct mtd_info *mtd, uint8_t *buf, | |||
893 | return 0; | 848 | return 0; |
894 | 849 | ||
895 | outerr: | 850 | outerr: |
896 | printk(KERN_WARNING | 851 | pr_warn("nand_bbt: error while writing bad block table %d\n", res); |
897 | "nand_bbt: Error while writing bad block table %d\n", res); | ||
898 | return res; | 852 | return res; |
899 | } | 853 | } |
900 | 854 | ||
901 | /** | 855 | /** |
902 | * nand_memory_bbt - [GENERIC] create a memory based bad block table | 856 | * nand_memory_bbt - [GENERIC] create a memory based bad block table |
903 | * @mtd: MTD device structure | 857 | * @mtd: MTD device structure |
904 | * @bd: descriptor for the good/bad block search pattern | 858 | * @bd: descriptor for the good/bad block search pattern |
905 | * | 859 | * |
906 | * The function creates a memory based bbt by scanning the device | 860 | * The function creates a memory based bbt by scanning the device for |
907 | * for manufacturer / software marked good / bad blocks | 861 | * manufacturer / software marked good / bad blocks. |
908 | */ | 862 | */ |
909 | static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) | 863 | static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) |
910 | { | 864 | { |
911 | struct nand_chip *this = mtd->priv; | 865 | struct nand_chip *this = mtd->priv; |
@@ -916,25 +870,24 @@ static inline int nand_memory_bbt(struct mtd_info *mtd, struct nand_bbt_descr *b | |||
916 | 870 | ||
917 | /** | 871 | /** |
918 | * check_create - [GENERIC] create and write bbt(s) if necessary | 872 | * check_create - [GENERIC] create and write bbt(s) if necessary |
919 | * @mtd: MTD device structure | 873 | * @mtd: MTD device structure |
920 | * @buf: temporary buffer | 874 | * @buf: temporary buffer |
921 | * @bd: descriptor for the good/bad block search pattern | 875 | * @bd: descriptor for the good/bad block search pattern |
922 | * | 876 | * |
923 | * The function checks the results of the previous call to read_bbt | 877 | * The function checks the results of the previous call to read_bbt and creates |
924 | * and creates / updates the bbt(s) if necessary | 878 | * / updates the bbt(s) if necessary. Creation is necessary if no bbt was found |
925 | * Creation is necessary if no bbt was found for the chip/device | 879 | * for the chip/device. Update is necessary if one of the tables is missing or |
926 | * Update is necessary if one of the tables is missing or the | 880 | * the version nr. of one table is less than the other. |
927 | * version nr. of one table is less than the other | 881 | */ |
928 | */ | ||
929 | static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd) | 882 | static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *bd) |
930 | { | 883 | { |
931 | int i, chips, writeops, chipsel, res; | 884 | int i, chips, writeops, create, chipsel, res, res2; |
932 | struct nand_chip *this = mtd->priv; | 885 | struct nand_chip *this = mtd->priv; |
933 | struct nand_bbt_descr *td = this->bbt_td; | 886 | struct nand_bbt_descr *td = this->bbt_td; |
934 | struct nand_bbt_descr *md = this->bbt_md; | 887 | struct nand_bbt_descr *md = this->bbt_md; |
935 | struct nand_bbt_descr *rd, *rd2; | 888 | struct nand_bbt_descr *rd, *rd2; |
936 | 889 | ||
937 | /* Do we have a bbt per chip ? */ | 890 | /* Do we have a bbt per chip? */ |
938 | if (td->options & NAND_BBT_PERCHIP) | 891 | if (td->options & NAND_BBT_PERCHIP) |
939 | chips = this->numchips; | 892 | chips = this->numchips; |
940 | else | 893 | else |
@@ -942,86 +895,98 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc | |||
942 | 895 | ||
943 | for (i = 0; i < chips; i++) { | 896 | for (i = 0; i < chips; i++) { |
944 | writeops = 0; | 897 | writeops = 0; |
898 | create = 0; | ||
945 | rd = NULL; | 899 | rd = NULL; |
946 | rd2 = NULL; | 900 | rd2 = NULL; |
947 | /* Per chip or per device ? */ | 901 | res = res2 = 0; |
902 | /* Per chip or per device? */ | ||
948 | chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1; | 903 | chipsel = (td->options & NAND_BBT_PERCHIP) ? i : -1; |
949 | /* Mirrored table available ? */ | 904 | /* Mirrored table available? */ |
950 | if (md) { | 905 | if (md) { |
951 | if (td->pages[i] == -1 && md->pages[i] == -1) { | 906 | if (td->pages[i] == -1 && md->pages[i] == -1) { |
907 | create = 1; | ||
952 | writeops = 0x03; | 908 | writeops = 0x03; |
953 | goto create; | 909 | } else if (td->pages[i] == -1) { |
954 | } | ||
955 | |||
956 | if (td->pages[i] == -1) { | ||
957 | rd = md; | 910 | rd = md; |
958 | td->version[i] = md->version[i]; | 911 | writeops = 0x01; |
959 | writeops = 1; | 912 | } else if (md->pages[i] == -1) { |
960 | goto writecheck; | ||
961 | } | ||
962 | |||
963 | if (md->pages[i] == -1) { | ||
964 | rd = td; | 913 | rd = td; |
965 | md->version[i] = td->version[i]; | 914 | writeops = 0x02; |
966 | writeops = 2; | 915 | } else if (td->version[i] == md->version[i]) { |
967 | goto writecheck; | ||
968 | } | ||
969 | |||
970 | if (td->version[i] == md->version[i]) { | ||
971 | rd = td; | 916 | rd = td; |
972 | if (!(td->options & NAND_BBT_VERSION)) | 917 | if (!(td->options & NAND_BBT_VERSION)) |
973 | rd2 = md; | 918 | rd2 = md; |
974 | goto writecheck; | 919 | } else if (((int8_t)(td->version[i] - md->version[i])) > 0) { |
975 | } | ||
976 | |||
977 | if (((int8_t) (td->version[i] - md->version[i])) > 0) { | ||
978 | rd = td; | 920 | rd = td; |
979 | md->version[i] = td->version[i]; | 921 | writeops = 0x02; |
980 | writeops = 2; | ||
981 | } else { | 922 | } else { |
982 | rd = md; | 923 | rd = md; |
983 | td->version[i] = md->version[i]; | 924 | writeops = 0x01; |
984 | writeops = 1; | ||
985 | } | 925 | } |
986 | |||
987 | goto writecheck; | ||
988 | |||
989 | } else { | 926 | } else { |
990 | if (td->pages[i] == -1) { | 927 | if (td->pages[i] == -1) { |
928 | create = 1; | ||
991 | writeops = 0x01; | 929 | writeops = 0x01; |
992 | goto create; | 930 | } else { |
931 | rd = td; | ||
993 | } | 932 | } |
994 | rd = td; | ||
995 | goto writecheck; | ||
996 | } | 933 | } |
997 | create: | ||
998 | /* Create the bad block table by scanning the device ? */ | ||
999 | if (!(td->options & NAND_BBT_CREATE)) | ||
1000 | continue; | ||
1001 | 934 | ||
1002 | /* Create the table in memory by scanning the chip(s) */ | 935 | if (create) { |
1003 | if (!(this->options & NAND_CREATE_EMPTY_BBT)) | 936 | /* Create the bad block table by scanning the device? */ |
1004 | create_bbt(mtd, buf, bd, chipsel); | 937 | if (!(td->options & NAND_BBT_CREATE)) |
1005 | 938 | continue; | |
1006 | td->version[i] = 1; | 939 | |
1007 | if (md) | 940 | /* Create the table in memory by scanning the chip(s) */ |
1008 | md->version[i] = 1; | 941 | if (!(this->bbt_options & NAND_BBT_CREATE_EMPTY)) |
1009 | writecheck: | 942 | create_bbt(mtd, buf, bd, chipsel); |
1010 | /* read back first ? */ | 943 | |
1011 | if (rd) | 944 | td->version[i] = 1; |
1012 | read_abs_bbt(mtd, buf, rd, chipsel); | 945 | if (md) |
1013 | /* If they weren't versioned, read both. */ | 946 | md->version[i] = 1; |
1014 | if (rd2) | 947 | } |
1015 | read_abs_bbt(mtd, buf, rd2, chipsel); | 948 | |
1016 | 949 | /* Read back first? */ | |
1017 | /* Write the bad block table to the device ? */ | 950 | if (rd) { |
951 | res = read_abs_bbt(mtd, buf, rd, chipsel); | ||
952 | if (mtd_is_eccerr(res)) { | ||
953 | /* Mark table as invalid */ | ||
954 | rd->pages[i] = -1; | ||
955 | rd->version[i] = 0; | ||
956 | i--; | ||
957 | continue; | ||
958 | } | ||
959 | } | ||
960 | /* If they weren't versioned, read both */ | ||
961 | if (rd2) { | ||
962 | res2 = read_abs_bbt(mtd, buf, rd2, chipsel); | ||
963 | if (mtd_is_eccerr(res2)) { | ||
964 | /* Mark table as invalid */ | ||
965 | rd2->pages[i] = -1; | ||
966 | rd2->version[i] = 0; | ||
967 | i--; | ||
968 | continue; | ||
969 | } | ||
970 | } | ||
971 | |||
972 | /* Scrub the flash table(s)? */ | ||
973 | if (mtd_is_bitflip(res) || mtd_is_bitflip(res2)) | ||
974 | writeops = 0x03; | ||
975 | |||
976 | /* Update version numbers before writing */ | ||
977 | if (md) { | ||
978 | td->version[i] = max(td->version[i], md->version[i]); | ||
979 | md->version[i] = td->version[i]; | ||
980 | } | ||
981 | |||
982 | /* Write the bad block table to the device? */ | ||
1018 | if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { | 983 | if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { |
1019 | res = write_bbt(mtd, buf, td, md, chipsel); | 984 | res = write_bbt(mtd, buf, td, md, chipsel); |
1020 | if (res < 0) | 985 | if (res < 0) |
1021 | return res; | 986 | return res; |
1022 | } | 987 | } |
1023 | 988 | ||
1024 | /* Write the mirror bad block table to the device ? */ | 989 | /* Write the mirror bad block table to the device? */ |
1025 | if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { | 990 | if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { |
1026 | res = write_bbt(mtd, buf, md, td, chipsel); | 991 | res = write_bbt(mtd, buf, md, td, chipsel); |
1027 | if (res < 0) | 992 | if (res < 0) |
@@ -1033,20 +998,19 @@ static int check_create(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_desc | |||
1033 | 998 | ||
1034 | /** | 999 | /** |
1035 | * mark_bbt_regions - [GENERIC] mark the bad block table regions | 1000 | * mark_bbt_regions - [GENERIC] mark the bad block table regions |
1036 | * @mtd: MTD device structure | 1001 | * @mtd: MTD device structure |
1037 | * @td: bad block table descriptor | 1002 | * @td: bad block table descriptor |
1038 | * | 1003 | * |
1039 | * The bad block table regions are marked as "bad" to prevent | 1004 | * The bad block table regions are marked as "bad" to prevent accidental |
1040 | * accidental erasures / writes. The regions are identified by | 1005 | * erasures / writes. The regions are identified by the mark 0x02. |
1041 | * the mark 0x02. | 1006 | */ |
1042 | */ | ||
1043 | static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) | 1007 | static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) |
1044 | { | 1008 | { |
1045 | struct nand_chip *this = mtd->priv; | 1009 | struct nand_chip *this = mtd->priv; |
1046 | int i, j, chips, block, nrblocks, update; | 1010 | int i, j, chips, block, nrblocks, update; |
1047 | uint8_t oldval, newval; | 1011 | uint8_t oldval, newval; |
1048 | 1012 | ||
1049 | /* Do we have a bbt per chip ? */ | 1013 | /* Do we have a bbt per chip? */ |
1050 | if (td->options & NAND_BBT_PERCHIP) { | 1014 | if (td->options & NAND_BBT_PERCHIP) { |
1051 | chips = this->numchips; | 1015 | chips = this->numchips; |
1052 | nrblocks = (int)(this->chipsize >> this->bbt_erase_shift); | 1016 | nrblocks = (int)(this->chipsize >> this->bbt_erase_shift); |
@@ -1083,9 +1047,11 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) | |||
1083 | update = 1; | 1047 | update = 1; |
1084 | block += 2; | 1048 | block += 2; |
1085 | } | 1049 | } |
1086 | /* If we want reserved blocks to be recorded to flash, and some | 1050 | /* |
1087 | new ones have been marked, then we need to update the stored | 1051 | * If we want reserved blocks to be recorded to flash, and some |
1088 | bbts. This should only happen once. */ | 1052 | * new ones have been marked, then we need to update the stored |
1053 | * bbts. This should only happen once. | ||
1054 | */ | ||
1089 | if (update && td->reserved_block_code) | 1055 | if (update && td->reserved_block_code) |
1090 | nand_update_bbt(mtd, (loff_t)(block - 2) << (this->bbt_erase_shift - 1)); | 1056 | nand_update_bbt(mtd, (loff_t)(block - 2) << (this->bbt_erase_shift - 1)); |
1091 | } | 1057 | } |
@@ -1093,8 +1059,8 @@ static void mark_bbt_region(struct mtd_info *mtd, struct nand_bbt_descr *td) | |||
1093 | 1059 | ||
1094 | /** | 1060 | /** |
1095 | * verify_bbt_descr - verify the bad block description | 1061 | * verify_bbt_descr - verify the bad block description |
1096 | * @mtd: MTD device structure | 1062 | * @mtd: MTD device structure |
1097 | * @bd: the table to verify | 1063 | * @bd: the table to verify |
1098 | * | 1064 | * |
1099 | * This functions performs a few sanity checks on the bad block description | 1065 | * This functions performs a few sanity checks on the bad block description |
1100 | * table. | 1066 | * table. |
@@ -1112,16 +1078,16 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd) | |||
1112 | pattern_len = bd->len; | 1078 | pattern_len = bd->len; |
1113 | bits = bd->options & NAND_BBT_NRBITS_MSK; | 1079 | bits = bd->options & NAND_BBT_NRBITS_MSK; |
1114 | 1080 | ||
1115 | BUG_ON((this->options & NAND_USE_FLASH_BBT_NO_OOB) && | 1081 | BUG_ON((this->bbt_options & NAND_BBT_NO_OOB) && |
1116 | !(this->options & NAND_USE_FLASH_BBT)); | 1082 | !(this->bbt_options & NAND_BBT_USE_FLASH)); |
1117 | BUG_ON(!bits); | 1083 | BUG_ON(!bits); |
1118 | 1084 | ||
1119 | if (bd->options & NAND_BBT_VERSION) | 1085 | if (bd->options & NAND_BBT_VERSION) |
1120 | pattern_len++; | 1086 | pattern_len++; |
1121 | 1087 | ||
1122 | if (bd->options & NAND_BBT_NO_OOB) { | 1088 | if (bd->options & NAND_BBT_NO_OOB) { |
1123 | BUG_ON(!(this->options & NAND_USE_FLASH_BBT)); | 1089 | BUG_ON(!(this->bbt_options & NAND_BBT_USE_FLASH)); |
1124 | BUG_ON(!(this->options & NAND_USE_FLASH_BBT_NO_OOB)); | 1090 | BUG_ON(!(this->bbt_options & NAND_BBT_NO_OOB)); |
1125 | BUG_ON(bd->offs); | 1091 | BUG_ON(bd->offs); |
1126 | if (bd->options & NAND_BBT_VERSION) | 1092 | if (bd->options & NAND_BBT_VERSION) |
1127 | BUG_ON(bd->veroffs != bd->len); | 1093 | BUG_ON(bd->veroffs != bd->len); |
@@ -1141,18 +1107,16 @@ static void verify_bbt_descr(struct mtd_info *mtd, struct nand_bbt_descr *bd) | |||
1141 | 1107 | ||
1142 | /** | 1108 | /** |
1143 | * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s) | 1109 | * nand_scan_bbt - [NAND Interface] scan, find, read and maybe create bad block table(s) |
1144 | * @mtd: MTD device structure | 1110 | * @mtd: MTD device structure |
1145 | * @bd: descriptor for the good/bad block search pattern | 1111 | * @bd: descriptor for the good/bad block search pattern |
1146 | * | ||
1147 | * The function checks, if a bad block table(s) is/are already | ||
1148 | * available. If not it scans the device for manufacturer | ||
1149 | * marked good / bad blocks and writes the bad block table(s) to | ||
1150 | * the selected place. | ||
1151 | * | 1112 | * |
1152 | * The bad block table memory is allocated here. It must be freed | 1113 | * The function checks, if a bad block table(s) is/are already available. If |
1153 | * by calling the nand_free_bbt function. | 1114 | * not it scans the device for manufacturer marked good / bad blocks and writes |
1115 | * the bad block table(s) to the selected place. | ||
1154 | * | 1116 | * |
1155 | */ | 1117 | * The bad block table memory is allocated here. It must be freed by calling |
1118 | * the nand_free_bbt function. | ||
1119 | */ | ||
1156 | int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) | 1120 | int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) |
1157 | { | 1121 | { |
1158 | struct nand_chip *this = mtd->priv; | 1122 | struct nand_chip *this = mtd->priv; |
@@ -1162,19 +1126,21 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) | |||
1162 | struct nand_bbt_descr *md = this->bbt_md; | 1126 | struct nand_bbt_descr *md = this->bbt_md; |
1163 | 1127 | ||
1164 | len = mtd->size >> (this->bbt_erase_shift + 2); | 1128 | len = mtd->size >> (this->bbt_erase_shift + 2); |
1165 | /* Allocate memory (2bit per block) and clear the memory bad block table */ | 1129 | /* |
1130 | * Allocate memory (2bit per block) and clear the memory bad block | ||
1131 | * table. | ||
1132 | */ | ||
1166 | this->bbt = kzalloc(len, GFP_KERNEL); | 1133 | this->bbt = kzalloc(len, GFP_KERNEL); |
1167 | if (!this->bbt) { | 1134 | if (!this->bbt) |
1168 | printk(KERN_ERR "nand_scan_bbt: Out of memory\n"); | ||
1169 | return -ENOMEM; | 1135 | return -ENOMEM; |
1170 | } | ||
1171 | 1136 | ||
1172 | /* If no primary table decriptor is given, scan the device | 1137 | /* |
1173 | * to build a memory based bad block table | 1138 | * If no primary table decriptor is given, scan the device to build a |
1139 | * memory based bad block table. | ||
1174 | */ | 1140 | */ |
1175 | if (!td) { | 1141 | if (!td) { |
1176 | if ((res = nand_memory_bbt(mtd, bd))) { | 1142 | if ((res = nand_memory_bbt(mtd, bd))) { |
1177 | printk(KERN_ERR "nand_bbt: Can't scan flash and build the RAM-based BBT\n"); | 1143 | pr_err("nand_bbt: can't scan flash and build the RAM-based BBT\n"); |
1178 | kfree(this->bbt); | 1144 | kfree(this->bbt); |
1179 | this->bbt = NULL; | 1145 | this->bbt = NULL; |
1180 | } | 1146 | } |
@@ -1188,13 +1154,12 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) | |||
1188 | len += (len >> this->page_shift) * mtd->oobsize; | 1154 | len += (len >> this->page_shift) * mtd->oobsize; |
1189 | buf = vmalloc(len); | 1155 | buf = vmalloc(len); |
1190 | if (!buf) { | 1156 | if (!buf) { |
1191 | printk(KERN_ERR "nand_bbt: Out of memory\n"); | ||
1192 | kfree(this->bbt); | 1157 | kfree(this->bbt); |
1193 | this->bbt = NULL; | 1158 | this->bbt = NULL; |
1194 | return -ENOMEM; | 1159 | return -ENOMEM; |
1195 | } | 1160 | } |
1196 | 1161 | ||
1197 | /* Is the bbt at a given page ? */ | 1162 | /* Is the bbt at a given page? */ |
1198 | if (td->options & NAND_BBT_ABSPAGE) { | 1163 | if (td->options & NAND_BBT_ABSPAGE) { |
1199 | res = read_abs_bbts(mtd, buf, td, md); | 1164 | res = read_abs_bbts(mtd, buf, td, md); |
1200 | } else { | 1165 | } else { |
@@ -1216,15 +1181,15 @@ int nand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) | |||
1216 | 1181 | ||
1217 | /** | 1182 | /** |
1218 | * nand_update_bbt - [NAND Interface] update bad block table(s) | 1183 | * nand_update_bbt - [NAND Interface] update bad block table(s) |
1219 | * @mtd: MTD device structure | 1184 | * @mtd: MTD device structure |
1220 | * @offs: the offset of the newly marked block | 1185 | * @offs: the offset of the newly marked block |
1221 | * | 1186 | * |
1222 | * The function updates the bad block table(s) | 1187 | * The function updates the bad block table(s). |
1223 | */ | 1188 | */ |
1224 | int nand_update_bbt(struct mtd_info *mtd, loff_t offs) | 1189 | int nand_update_bbt(struct mtd_info *mtd, loff_t offs) |
1225 | { | 1190 | { |
1226 | struct nand_chip *this = mtd->priv; | 1191 | struct nand_chip *this = mtd->priv; |
1227 | int len, res = 0, writeops = 0; | 1192 | int len, res = 0; |
1228 | int chip, chipsel; | 1193 | int chip, chipsel; |
1229 | uint8_t *buf; | 1194 | uint8_t *buf; |
1230 | struct nand_bbt_descr *td = this->bbt_td; | 1195 | struct nand_bbt_descr *td = this->bbt_td; |
@@ -1237,14 +1202,10 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs) | |||
1237 | len = (1 << this->bbt_erase_shift); | 1202 | len = (1 << this->bbt_erase_shift); |
1238 | len += (len >> this->page_shift) * mtd->oobsize; | 1203 | len += (len >> this->page_shift) * mtd->oobsize; |
1239 | buf = kmalloc(len, GFP_KERNEL); | 1204 | buf = kmalloc(len, GFP_KERNEL); |
1240 | if (!buf) { | 1205 | if (!buf) |
1241 | printk(KERN_ERR "nand_update_bbt: Out of memory\n"); | ||
1242 | return -ENOMEM; | 1206 | return -ENOMEM; |
1243 | } | ||
1244 | |||
1245 | writeops = md != NULL ? 0x03 : 0x01; | ||
1246 | 1207 | ||
1247 | /* Do we have a bbt per chip ? */ | 1208 | /* Do we have a bbt per chip? */ |
1248 | if (td->options & NAND_BBT_PERCHIP) { | 1209 | if (td->options & NAND_BBT_PERCHIP) { |
1249 | chip = (int)(offs >> this->chip_shift); | 1210 | chip = (int)(offs >> this->chip_shift); |
1250 | chipsel = chip; | 1211 | chipsel = chip; |
@@ -1257,14 +1218,14 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs) | |||
1257 | if (md) | 1218 | if (md) |
1258 | md->version[chip]++; | 1219 | md->version[chip]++; |
1259 | 1220 | ||
1260 | /* Write the bad block table to the device ? */ | 1221 | /* Write the bad block table to the device? */ |
1261 | if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { | 1222 | if (td->options & NAND_BBT_WRITE) { |
1262 | res = write_bbt(mtd, buf, td, md, chipsel); | 1223 | res = write_bbt(mtd, buf, td, md, chipsel); |
1263 | if (res < 0) | 1224 | if (res < 0) |
1264 | goto out; | 1225 | goto out; |
1265 | } | 1226 | } |
1266 | /* Write the mirror bad block table to the device ? */ | 1227 | /* Write the mirror bad block table to the device? */ |
1267 | if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { | 1228 | if (md && (md->options & NAND_BBT_WRITE)) { |
1268 | res = write_bbt(mtd, buf, md, td, chipsel); | 1229 | res = write_bbt(mtd, buf, md, td, chipsel); |
1269 | } | 1230 | } |
1270 | 1231 | ||
@@ -1273,8 +1234,10 @@ int nand_update_bbt(struct mtd_info *mtd, loff_t offs) | |||
1273 | return res; | 1234 | return res; |
1274 | } | 1235 | } |
1275 | 1236 | ||
1276 | /* Define some generic bad / good block scan pattern which are used | 1237 | /* |
1277 | * while scanning a device for factory marked good / bad blocks. */ | 1238 | * Define some generic bad / good block scan pattern which are used |
1239 | * while scanning a device for factory marked good / bad blocks. | ||
1240 | */ | ||
1278 | static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; | 1241 | static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; |
1279 | 1242 | ||
1280 | static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 }; | 1243 | static uint8_t scan_agand_pattern[] = { 0x1C, 0x71, 0xC7, 0x1C, 0x71, 0xC7 }; |
@@ -1286,8 +1249,7 @@ static struct nand_bbt_descr agand_flashbased = { | |||
1286 | .pattern = scan_agand_pattern | 1249 | .pattern = scan_agand_pattern |
1287 | }; | 1250 | }; |
1288 | 1251 | ||
1289 | /* Generic flash bbt decriptors | 1252 | /* Generic flash bbt descriptors */ |
1290 | */ | ||
1291 | static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' }; | 1253 | static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' }; |
1292 | static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; | 1254 | static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; |
1293 | 1255 | ||
@@ -1331,31 +1293,27 @@ static struct nand_bbt_descr bbt_mirror_no_bbt_descr = { | |||
1331 | .pattern = mirror_pattern | 1293 | .pattern = mirror_pattern |
1332 | }; | 1294 | }; |
1333 | 1295 | ||
1334 | #define BBT_SCAN_OPTIONS (NAND_BBT_SCANLASTPAGE | NAND_BBT_SCAN2NDPAGE | \ | 1296 | #define BADBLOCK_SCAN_MASK (~NAND_BBT_NO_OOB) |
1335 | NAND_BBT_SCANBYTE1AND6) | ||
1336 | /** | 1297 | /** |
1337 | * nand_create_default_bbt_descr - [Internal] Creates a BBT descriptor structure | 1298 | * nand_create_badblock_pattern - [INTERN] Creates a BBT descriptor structure |
1338 | * @this: NAND chip to create descriptor for | 1299 | * @this: NAND chip to create descriptor for |
1339 | * | 1300 | * |
1340 | * This function allocates and initializes a nand_bbt_descr for BBM detection | 1301 | * This function allocates and initializes a nand_bbt_descr for BBM detection |
1341 | * based on the properties of "this". The new descriptor is stored in | 1302 | * based on the properties of @this. The new descriptor is stored in |
1342 | * this->badblock_pattern. Thus, this->badblock_pattern should be NULL when | 1303 | * this->badblock_pattern. Thus, this->badblock_pattern should be NULL when |
1343 | * passed to this function. | 1304 | * passed to this function. |
1344 | * | ||
1345 | */ | 1305 | */ |
1346 | static int nand_create_default_bbt_descr(struct nand_chip *this) | 1306 | static int nand_create_badblock_pattern(struct nand_chip *this) |
1347 | { | 1307 | { |
1348 | struct nand_bbt_descr *bd; | 1308 | struct nand_bbt_descr *bd; |
1349 | if (this->badblock_pattern) { | 1309 | if (this->badblock_pattern) { |
1350 | printk(KERN_WARNING "BBT descr already allocated; not replacing.\n"); | 1310 | pr_warn("Bad block pattern already allocated; not replacing\n"); |
1351 | return -EINVAL; | 1311 | return -EINVAL; |
1352 | } | 1312 | } |
1353 | bd = kzalloc(sizeof(*bd), GFP_KERNEL); | 1313 | bd = kzalloc(sizeof(*bd), GFP_KERNEL); |
1354 | if (!bd) { | 1314 | if (!bd) |
1355 | printk(KERN_ERR "nand_create_default_bbt_descr: Out of memory\n"); | ||
1356 | return -ENOMEM; | 1315 | return -ENOMEM; |
1357 | } | 1316 | bd->options = this->bbt_options & BADBLOCK_SCAN_MASK; |
1358 | bd->options = this->options & BBT_SCAN_OPTIONS; | ||
1359 | bd->offs = this->badblockpos; | 1317 | bd->offs = this->badblockpos; |
1360 | bd->len = (this->options & NAND_BUSWIDTH_16) ? 2 : 1; | 1318 | bd->len = (this->options & NAND_BUSWIDTH_16) ? 2 : 1; |
1361 | bd->pattern = scan_ff_pattern; | 1319 | bd->pattern = scan_ff_pattern; |
@@ -1366,22 +1324,20 @@ static int nand_create_default_bbt_descr(struct nand_chip *this) | |||
1366 | 1324 | ||
1367 | /** | 1325 | /** |
1368 | * nand_default_bbt - [NAND Interface] Select a default bad block table for the device | 1326 | * nand_default_bbt - [NAND Interface] Select a default bad block table for the device |
1369 | * @mtd: MTD device structure | 1327 | * @mtd: MTD device structure |
1370 | * | ||
1371 | * This function selects the default bad block table | ||
1372 | * support for the device and calls the nand_scan_bbt function | ||
1373 | * | 1328 | * |
1374 | */ | 1329 | * This function selects the default bad block table support for the device and |
1330 | * calls the nand_scan_bbt function. | ||
1331 | */ | ||
1375 | int nand_default_bbt(struct mtd_info *mtd) | 1332 | int nand_default_bbt(struct mtd_info *mtd) |
1376 | { | 1333 | { |
1377 | struct nand_chip *this = mtd->priv; | 1334 | struct nand_chip *this = mtd->priv; |
1378 | 1335 | ||
1379 | /* Default for AG-AND. We must use a flash based | 1336 | /* |
1380 | * bad block table as the devices have factory marked | 1337 | * Default for AG-AND. We must use a flash based bad block table as the |
1381 | * _good_ blocks. Erasing those blocks leads to loss | 1338 | * devices have factory marked _good_ blocks. Erasing those blocks |
1382 | * of the good / bad information, so we _must_ store | 1339 | * leads to loss of the good / bad information, so we _must_ store this |
1383 | * this information in a good / bad table during | 1340 | * information in a good / bad table during startup. |
1384 | * startup | ||
1385 | */ | 1341 | */ |
1386 | if (this->options & NAND_IS_AND) { | 1342 | if (this->options & NAND_IS_AND) { |
1387 | /* Use the default pattern descriptors */ | 1343 | /* Use the default pattern descriptors */ |
@@ -1389,15 +1345,15 @@ int nand_default_bbt(struct mtd_info *mtd) | |||
1389 | this->bbt_td = &bbt_main_descr; | 1345 | this->bbt_td = &bbt_main_descr; |
1390 | this->bbt_md = &bbt_mirror_descr; | 1346 | this->bbt_md = &bbt_mirror_descr; |
1391 | } | 1347 | } |
1392 | this->options |= NAND_USE_FLASH_BBT; | 1348 | this->bbt_options |= NAND_BBT_USE_FLASH; |
1393 | return nand_scan_bbt(mtd, &agand_flashbased); | 1349 | return nand_scan_bbt(mtd, &agand_flashbased); |
1394 | } | 1350 | } |
1395 | 1351 | ||
1396 | /* Is a flash based bad block table requested ? */ | 1352 | /* Is a flash based bad block table requested? */ |
1397 | if (this->options & NAND_USE_FLASH_BBT) { | 1353 | if (this->bbt_options & NAND_BBT_USE_FLASH) { |
1398 | /* Use the default pattern descriptors */ | 1354 | /* Use the default pattern descriptors */ |
1399 | if (!this->bbt_td) { | 1355 | if (!this->bbt_td) { |
1400 | if (this->options & NAND_USE_FLASH_BBT_NO_OOB) { | 1356 | if (this->bbt_options & NAND_BBT_NO_OOB) { |
1401 | this->bbt_td = &bbt_main_no_bbt_descr; | 1357 | this->bbt_td = &bbt_main_no_bbt_descr; |
1402 | this->bbt_md = &bbt_mirror_no_bbt_descr; | 1358 | this->bbt_md = &bbt_mirror_no_bbt_descr; |
1403 | } else { | 1359 | } else { |
@@ -1411,18 +1367,17 @@ int nand_default_bbt(struct mtd_info *mtd) | |||
1411 | } | 1367 | } |
1412 | 1368 | ||
1413 | if (!this->badblock_pattern) | 1369 | if (!this->badblock_pattern) |
1414 | nand_create_default_bbt_descr(this); | 1370 | nand_create_badblock_pattern(this); |
1415 | 1371 | ||
1416 | return nand_scan_bbt(mtd, this->badblock_pattern); | 1372 | return nand_scan_bbt(mtd, this->badblock_pattern); |
1417 | } | 1373 | } |
1418 | 1374 | ||
1419 | /** | 1375 | /** |
1420 | * nand_isbad_bbt - [NAND Interface] Check if a block is bad | 1376 | * nand_isbad_bbt - [NAND Interface] Check if a block is bad |
1421 | * @mtd: MTD device structure | 1377 | * @mtd: MTD device structure |
1422 | * @offs: offset in the device | 1378 | * @offs: offset in the device |
1423 | * @allowbbt: allow access to bad block table region | 1379 | * @allowbbt: allow access to bad block table region |
1424 | * | 1380 | */ |
1425 | */ | ||
1426 | int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) | 1381 | int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) |
1427 | { | 1382 | { |
1428 | struct nand_chip *this = mtd->priv; | 1383 | struct nand_chip *this = mtd->priv; |
@@ -1433,8 +1388,9 @@ int nand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) | |||
1433 | block = (int)(offs >> (this->bbt_erase_shift - 1)); | 1388 | block = (int)(offs >> (this->bbt_erase_shift - 1)); |
1434 | res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03; | 1389 | res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03; |
1435 | 1390 | ||
1436 | DEBUG(MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n", | 1391 | pr_debug("nand_isbad_bbt(): bbt info for offs 0x%08x: " |
1437 | (unsigned int)offs, block >> 1, res); | 1392 | "(block %d) 0x%02x\n", |
1393 | (unsigned int)offs, block >> 1, res); | ||
1438 | 1394 | ||
1439 | switch ((int)res) { | 1395 | switch ((int)res) { |
1440 | case 0x00: | 1396 | case 0x00: |