Commit c1f16258 authored by David Woodhouse's avatar David Woodhouse
parents 552a8278 cde36b37
This diff is collapsed.
...@@ -17,8 +17,8 @@ ...@@ -17,8 +17,8 @@
#include <linux/mtd/onenand.h> #include <linux/mtd/onenand.h>
#include <linux/mtd/compatmac.h> #include <linux/mtd/compatmac.h>
extern int onenand_do_read_oob(struct mtd_info *mtd, loff_t from, size_t len, extern int onenand_bbt_read_oob(struct mtd_info *mtd, loff_t from,
size_t *retlen, u_char *buf); struct mtd_oob_ops *ops);
/** /**
* check_short_pattern - [GENERIC] check if a pattern is in the buffer * check_short_pattern - [GENERIC] check if a pattern is in the buffer
...@@ -65,10 +65,11 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr ...@@ -65,10 +65,11 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
int startblock; int startblock;
loff_t from; loff_t from;
size_t readlen, ooblen; size_t readlen, ooblen;
struct mtd_oob_ops ops;
printk(KERN_INFO "Scanning device for bad blocks\n"); printk(KERN_INFO "Scanning device for bad blocks\n");
len = 1; len = 2;
/* We need only read few bytes from the OOB area */ /* We need only read few bytes from the OOB area */
scanlen = ooblen = 0; scanlen = ooblen = 0;
...@@ -82,22 +83,24 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr ...@@ -82,22 +83,24 @@ static int create_bbt(struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
startblock = 0; startblock = 0;
from = 0; from = 0;
ops.mode = MTD_OOB_PLACE;
ops.ooblen = readlen;
ops.oobbuf = buf;
ops.len = ops.ooboffs = ops.retlen = ops.oobretlen = 0;
for (i = startblock; i < numblocks; ) { for (i = startblock; i < numblocks; ) {
int ret; int ret;
for (j = 0; j < len; j++) { for (j = 0; j < len; j++) {
size_t retlen;
/* No need to read pages fully, /* No need to read pages fully,
* just read required OOB bytes */ * just read required OOB bytes */
ret = onenand_do_read_oob(mtd, from + j * mtd->writesize + bd->offs, ret = onenand_bbt_read_oob(mtd, from + j * mtd->writesize + bd->offs, &ops);
readlen, &retlen, &buf[0]);
/* If it is a initial bad block, just ignore it */ /* If it is a initial bad block, just ignore it */
if (ret && !(ret & ONENAND_CTRL_LOAD)) if (ret == ONENAND_BBT_READ_FATAL_ERROR)
return ret; return -EIO;
if (check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) { if (ret || check_short_pattern(&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
bbm->bbt[i >> 3] |= 0x03 << (i & 0x6); bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n", printk(KERN_WARNING "Bad eraseblock %d at 0x%08x\n",
i >> 1, (unsigned int) from); i >> 1, (unsigned int) from);
...@@ -168,8 +171,8 @@ static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt) ...@@ -168,8 +171,8 @@ static int onenand_isbad_bbt(struct mtd_info *mtd, loff_t offs, int allowbbt)
* marked good / bad blocks and writes the bad block table(s) to * marked good / bad blocks and writes the bad block table(s) to
* the selected place. * the selected place.
* *
* The bad block table memory is allocated here. It must be freed * The bad block table memory is allocated here. It is freed
* by calling the onenand_free_bbt function. * by the onenand_release function.
* *
*/ */
int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd) int onenand_scan_bbt(struct mtd_info *mtd, struct nand_bbt_descr *bd)
......
...@@ -92,6 +92,13 @@ struct nand_bbt_descr { ...@@ -92,6 +92,13 @@ struct nand_bbt_descr {
*/ */
#define ONENAND_BADBLOCK_POS 0 #define ONENAND_BADBLOCK_POS 0
/*
* Bad block scanning errors
*/
#define ONENAND_BBT_READ_ERROR 1
#define ONENAND_BBT_READ_ECC_ERROR 2
#define ONENAND_BBT_READ_FATAL_ERROR 4
/** /**
* struct bbm_info - [GENERIC] Bad Block Table data structure * struct bbm_info - [GENERIC] Bad Block Table data structure
* @bbt_erase_shift: [INTERN] number of address bits in a bbt entry * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry
......
/* /*
* linux/include/linux/mtd/onenand.h * linux/include/linux/mtd/onenand.h
* *
* Copyright (C) 2005-2006 Samsung Electronics * Copyright (C) 2005-2007 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com> * Kyungmin Park <kyungmin.park@samsung.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
...@@ -42,14 +42,10 @@ typedef enum { ...@@ -42,14 +42,10 @@ typedef enum {
/** /**
* struct onenand_bufferram - OneNAND BufferRAM Data * struct onenand_bufferram - OneNAND BufferRAM Data
* @block: block address in BufferRAM * @blockpage: block & page address in BufferRAM
* @page: page address in BufferRAM
* @valid: valid flag
*/ */
struct onenand_bufferram { struct onenand_bufferram {
int block; int blockpage;
int page;
int valid;
}; };
/** /**
...@@ -63,7 +59,6 @@ struct onenand_bufferram { ...@@ -63,7 +59,6 @@ struct onenand_bufferram {
* partly be set to inform onenand_scan about * partly be set to inform onenand_scan about
* @erase_shift: [INTERN] number of address bits in a block * @erase_shift: [INTERN] number of address bits in a block
* @page_shift: [INTERN] number of address bits in a page * @page_shift: [INTERN] number of address bits in a page
* @ppb_shift: [INTERN] number of address bits in a pages per block
* @page_mask: [INTERN] a page per block mask * @page_mask: [INTERN] a page per block mask
* @bufferram_index: [INTERN] BufferRAM index * @bufferram_index: [INTERN] BufferRAM index
* @bufferram: [INTERN] BufferRAM info * @bufferram: [INTERN] BufferRAM info
...@@ -103,7 +98,6 @@ struct onenand_chip { ...@@ -103,7 +98,6 @@ struct onenand_chip {
unsigned int erase_shift; unsigned int erase_shift;
unsigned int page_shift; unsigned int page_shift;
unsigned int ppb_shift; /* Pages per block shift */
unsigned int page_mask; unsigned int page_mask;
unsigned int bufferram_index; unsigned int bufferram_index;
...@@ -150,6 +144,9 @@ struct onenand_chip { ...@@ -150,6 +144,9 @@ struct onenand_chip {
#define ONENAND_SET_SYS_CFG1(v, this) \ #define ONENAND_SET_SYS_CFG1(v, this) \
(this->write_word(v, this->base + ONENAND_REG_SYS_CFG1)) (this->write_word(v, this->base + ONENAND_REG_SYS_CFG1))
#define ONENAND_IS_DDP(this) \
(this->device_id & ONENAND_DEVICE_IS_DDP)
/* Check byte access in OneNAND */ /* Check byte access in OneNAND */
#define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1) #define ONENAND_CHECK_BYTE_ACCESS(addr) (addr & 0x1)
......
...@@ -3,7 +3,8 @@ ...@@ -3,7 +3,8 @@
* *
* OneNAND Register header file * OneNAND Register header file
* *
* Copyright (C) 2005-2006 Samsung Electronics * Copyright (C) 2005-2007 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
* *
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as * it under the terms of the GNU General Public License version 2 as
...@@ -80,9 +81,11 @@ ...@@ -80,9 +81,11 @@
#define ONENAND_VERSION_PROCESS_SHIFT (8) #define ONENAND_VERSION_PROCESS_SHIFT (8)
/* /*
* Start Address 1 F100h (R/W) * Start Address 1 F100h (R/W) & Start Address 2 F101h (R/W)
*/ */
#define ONENAND_DDP_SHIFT (15) #define ONENAND_DDP_SHIFT (15)
#define ONENAND_DDP_CHIP0 (0)
#define ONENAND_DDP_CHIP1 (1 << ONENAND_DDP_SHIFT)
/* /*
* Start Address 8 F107h (R/W) * Start Address 8 F107h (R/W)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment