From: Kyungmin Park <kmpark@infradead.org>
To: u-boot@lists.denx.de
Subject: [U-Boot-Users] [PATCH] Fix OneNAND build break
Date: Wed, 13 Aug 2008 09:11:02 +0900 [thread overview]
Message-ID: <20080813001102.GA27788@july> (raw)
Since page size field is changed from oobblock to writesize. But OneNAND is not updated.
- fix bufferram management at erase operation
This patch includes the NAND/OneNAND state filed too.
generated against latest git tree
Thank you,
Kyungmin Park
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
---
diff --git a/common/env_onenand.c b/common/env_onenand.c
index dbd0883..d5c907c 100644
--- a/common/env_onenand.c
+++ b/common/env_onenand.c
@@ -40,7 +40,7 @@ extern struct onenand_chip onenand_chip;
/* References to names in env_common.c */
extern uchar default_environment[];
-#define ONENAND_ENV_SIZE(mtd) (mtd.oobblock - ENV_HEADER_SIZE)
+#define ONENAND_ENV_SIZE(mtd) (mtd.writesize - ENV_HEADER_SIZE)
char *env_name_spec = "OneNAND";
@@ -68,12 +68,12 @@ void env_relocate_spec(void)
env_addr = CFG_ENV_ADDR;
/* Check OneNAND exist */
- if (onenand_mtd.oobblock)
+ if (onenand_mtd.writesize)
/* Ignore read fail */
- onenand_read(&onenand_mtd, env_addr, onenand_mtd.oobblock,
+ onenand_read(&onenand_mtd, env_addr, onenand_mtd.writesize,
&retlen, (u_char *) env_ptr);
else
- onenand_mtd.oobblock = MAX_ONENAND_PAGESIZE;
+ onenand_mtd.writesize = MAX_ONENAND_PAGESIZE;
if (crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd)) !=
env_ptr->crc)
@@ -109,7 +109,7 @@ int saveenv(void)
env_ptr->crc =
crc32(0, env_ptr->data, ONENAND_ENV_SIZE(onenand_mtd));
- if (onenand_write(&onenand_mtd, env_addr, onenand_mtd.oobblock, &retlen,
+ if (onenand_write(&onenand_mtd, env_addr, onenand_mtd.writesize, &retlen,
(u_char *) env_ptr)) {
printf("OneNAND: write failed at 0x%08x\n", instr.addr);
return 2;
diff --git a/drivers/mtd/onenand/onenand_base.c b/drivers/mtd/onenand/onenand_base.c
index ded1706..d63f392 100644
--- a/drivers/mtd/onenand/onenand_base.c
+++ b/drivers/mtd/onenand/onenand_base.c
@@ -331,7 +331,7 @@ static inline int onenand_bufferram_offset(struct mtd_info *mtd, int area)
if (ONENAND_CURRENT_BUFFERRAM(this)) {
if (area == ONENAND_DATARAM)
- return mtd->oobblock;
+ return mtd->writesize;
if (area == ONENAND_SPARERAM)
return mtd->oobsize;
}
@@ -482,6 +482,30 @@ static int onenand_update_bufferram(struct mtd_info *mtd, loff_t addr,
}
/**
+ * onenand_invalidate_bufferram - [GENERIC] Invalidate BufferRAM information
+ * @param mtd MTD data structure
+ * @param addr start address to invalidate
+ * @param len length to invalidate
+ *
+ * Invalidate BufferRAM information
+ */
+static void onenand_invalidate_bufferram(struct mtd_info *mtd, loff_t addr,
+ unsigned int len)
+{
+ struct onenand_chip *this = mtd->priv;
+ int i;
+ loff_t end_addr = addr + len;
+
+ /* Invalidate BufferRAM */
+ for (i = 0; i < MAX_BUFFERRAM; i++) {
+ loff_t buf_addr = this->bufferram[i].block << this->erase_shift;
+
+ if (buf_addr >= addr && buf_addr < end_addr)
+ this->bufferram[i].valid = 0;
+ }
+}
+
+/**
* onenand_get_device - [GENERIC] Get chip for selected access
* @param mtd MTD device structure
* @param new_state the state which is requested
@@ -541,15 +565,15 @@ static int onenand_read_ecc(struct mtd_info *mtd, loff_t from, size_t len,
onenand_get_device(mtd, FL_READING);
while (read < len) {
- thislen = min_t(int, mtd->oobblock, len - read);
+ thislen = min_t(int, mtd->writesize, len - read);
- column = from & (mtd->oobblock - 1);
- if (column + thislen > mtd->oobblock)
- thislen = mtd->oobblock - column;
+ column = from & (mtd->writesize - 1);
+ if (column + thislen > mtd->writesize)
+ thislen = mtd->writesize - column;
if (!onenand_check_bufferram(mtd, from)) {
this->command(mtd, ONENAND_CMD_READ, from,
- mtd->oobblock);
+ mtd->writesize);
ret = this->wait(mtd, FL_READING);
/* First copy data and check return value for ECC handling */
onenand_update_bufferram(mtd, from, 1);
@@ -664,7 +688,7 @@ int onenand_read_oob(struct mtd_info *mtd, loff_t from, size_t len,
/* Read more? */
if (read < len) {
/* Page size */
- from += mtd->oobblock;
+ from += mtd->writesize;
column = 0;
}
}
@@ -691,7 +715,7 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
void __iomem *dataram0, *dataram1;
int ret = 0;
- this->command(mtd, ONENAND_CMD_READ, addr, mtd->oobblock);
+ this->command(mtd, ONENAND_CMD_READ, addr, mtd->writesize);
ret = this->wait(mtd, FL_READING);
if (ret)
@@ -701,9 +725,9 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
/* Check, if the two dataram areas are same */
dataram0 = this->base + ONENAND_DATARAM;
- dataram1 = dataram0 + mtd->oobblock;
+ dataram1 = dataram0 + mtd->writesize;
- if (memcmp(dataram0, dataram1, mtd->oobblock))
+ if (memcmp(dataram0, dataram1, mtd->writesize))
return -EBADMSG;
return 0;
@@ -712,7 +736,7 @@ static int onenand_verify_page(struct mtd_info *mtd, u_char * buf,
#define onenand_verify_page(...) (0)
#endif
-#define NOTALIGNED(x) ((x & (mtd->oobblock - 1)) != 0)
+#define NOTALIGNED(x) ((x & (mtd->writesize - 1)) != 0)
/**
* onenand_write_ecc - [MTD Interface] OneNAND write with ECC
@@ -760,15 +784,15 @@ static int onenand_write_ecc(struct mtd_info *mtd, loff_t to, size_t len,
/* Loop until all data write */
while (written < len) {
- int thislen = min_t(int, mtd->oobblock, len - written);
+ int thislen = min_t(int, mtd->writesize, len - written);
- this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->oobblock);
+ this->command(mtd, ONENAND_CMD_BUFFERRAM, to, mtd->writesize);
this->write_bufferram(mtd, ONENAND_DATARAM, buf, 0, thislen);
this->write_bufferram(mtd, ONENAND_SPARERAM, ffchars, 0,
mtd->oobsize);
- this->command(mtd, ONENAND_CMD_PROG, to, mtd->oobblock);
+ this->command(mtd, ONENAND_CMD_PROG, to, mtd->writesize);
onenand_update_bufferram(mtd, to, 1);
@@ -893,6 +917,25 @@ int onenand_write_oob(struct mtd_info *mtd, loff_t to, size_t len,
}
/**
+ * onenand_block_isbad_nolock - [GENERIC] Check if a block is marked bad
+ * @param mtd MTD device structure
+ * @param ofs offset from device start
+ * @param allowbbt 1, if its allowed to access the bbt area
+ *
+ * Check, if the block is bad, Either by reading the bad block table or
+ * calling of the scan function.
+ */
+static int onenand_block_isbad_nolock(struct mtd_info *mtd, loff_t ofs, int allowbbt)
+{
+ struct onenand_chip *this = mtd->priv;
+ struct bbm_info *bbm = this->bbm;
+
+ /* Return info from the table */
+ return bbm->isbad_bbt(mtd, ofs, allowbbt);
+}
+
+
+/**
* onenand_erase - [MTD Interface] erase block(s)
* @param mtd MTD device structure
* @param instr erase instruction
@@ -950,6 +993,8 @@ int onenand_erase(struct mtd_info *mtd, struct erase_info *instr)
this->command(mtd, ONENAND_CMD_ERASE, addr, block_size);
+ onenand_invalidate_bufferram(mtd, addr, block_size);
+
ret = this->wait(mtd, FL_ERASING);
/* Check, if it is write protected */
if (ret) {
@@ -1005,30 +1050,45 @@ void onenand_sync(struct mtd_info *mtd)
* onenand_block_isbad - [MTD Interface] Check whether the block at the given offset is bad
* @param mtd MTD device structure
* @param ofs offset relative to mtd start
+ *
+ * Check whether the block is bad
*/
int onenand_block_isbad(struct mtd_info *mtd, loff_t ofs)
{
- /*
- * TODO
- * 1. Bad block table (BBT)
- * -> using NAND BBT to support JFFS2
- * 2. Bad block management (BBM)
- * -> bad block replace scheme
- *
- * Currently we do nothing
- */
- return 0;
+ int ret;
+
+ /* Check for invalid offset */
+ if (ofs > mtd->size)
+ return -EINVAL;
+
+ onenand_get_device(mtd, FL_READING);
+ ret = onenand_block_isbad_nolock(mtd,ofs, 0);
+ onenand_release_device(mtd);
+ return ret;
}
/**
* onenand_block_markbad - [MTD Interface] Mark the block at the given offset as bad
* @param mtd MTD device structure
* @param ofs offset relative to mtd start
+ *
+ * Mark the block as bad
*/
int onenand_block_markbad(struct mtd_info *mtd, loff_t ofs)
{
- /* see above */
- return 0;
+ struct onenand_chip *this = mtd->priv;
+ int ret;
+
+ ret = onenand_block_isbad(mtd, ofs);
+ if (ret) {
+ /* If it was bad already, return success and do nothing */
+ if (ret > 0)
+ return 0;
+ return ret;
+ }
+
+ ret = this->block_markbad(mtd, ofs);
+ return ret;
}
/**
@@ -1184,10 +1244,8 @@ static int onenand_probe(struct mtd_info *mtd)
/* Reset OneNAND to read default register values */
this->write_word(ONENAND_CMD_RESET, this->base + ONENAND_BOOTRAM);
- {
- int i;
- for (i = 0; i < 10000; i++) ;
- }
+ /* Wait reset */
+ this->wait(mtd, FL_RESETING);
/* Read manufacturer and device IDs from Register */
maf_id = this->read_word(this->base + ONENAND_REG_MANUFACTURER_ID);
@@ -1212,16 +1270,16 @@ static int onenand_probe(struct mtd_info *mtd)
/* OneNAND page size & block size */
/* The data buffer size is equal to page size */
- mtd->oobblock =
+ mtd->writesize =
this->read_word(this->base + ONENAND_REG_DATA_BUFFER_SIZE);
- mtd->oobsize = mtd->oobblock >> 5;
+ mtd->oobsize = mtd->writesize >> 5;
/* Pagers per block is always 64 in OneNAND */
- mtd->erasesize = mtd->oobblock << 6;
+ mtd->erasesize = mtd->writesize << 6;
this->erase_shift = ffs(mtd->erasesize) - 1;
- this->page_shift = ffs(mtd->oobblock) - 1;
+ this->page_shift = ffs(mtd->writesize) - 1;
this->ppb_shift = (this->erase_shift - this->page_shift);
- this->page_mask = (mtd->erasesize / mtd->oobblock) - 1;
+ this->page_mask = (mtd->erasesize / mtd->writesize) - 1;
/* REVIST: Multichip handling */
@@ -1240,11 +1298,10 @@ static int onenand_probe(struct mtd_info *mtd)
this->options |= ONENAND_CONT_LOCK;
}
+ mtd->flags = MTD_CAP_NANDFLASH;
mtd->erase = onenand_erase;
mtd->read = onenand_read;
mtd->write = onenand_write;
- mtd->read_ecc = onenand_read_ecc;
- mtd->write_ecc = onenand_write_ecc;
mtd->read_oob = onenand_read_oob;
mtd->write_oob = onenand_write_oob;
mtd->sync = onenand_sync;
diff --git a/drivers/mtd/onenand/onenand_bbt.c b/drivers/mtd/onenand/onenand_bbt.c
index 87344ab..318d877 100644
--- a/drivers/mtd/onenand/onenand_bbt.c
+++ b/drivers/mtd/onenand/onenand_bbt.c
@@ -97,7 +97,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
/* No need to read pages fully,
* just read required OOB bytes */
ret = onenand_read_oob(mtd,
- from + j * mtd->oobblock +
+ from + j * mtd->writesize +
bd->offs, readlen, &retlen,
&buf[0]);
@@ -107,7 +107,7 @@ static int create_bbt(struct mtd_info *mtd, uint8_t * buf,
}
if (check_short_pattern
- (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
+ (&buf[j * scanlen], scanlen, mtd->writesize, bd)) {
bbm->bbt[i >> 3] |= 0x03 << (i & 0x6);
printk(KERN_WARNING
"Bad eraseblock %d@0x%08x\n", i >> 1,
diff --git a/include/linux/mtd/compat.h b/include/linux/mtd/compat.h
index 9036b74..a4dc3e9 100644
--- a/include/linux/mtd/compat.h
+++ b/include/linux/mtd/compat.h
@@ -18,7 +18,11 @@
#define KERN_DEBUG
#define kmalloc(size, flags) malloc(size)
-#define kzalloc(size, flags) calloc(size, 1)
+#define kzalloc(size, flags) ({ \
+ void *__ret = malloc(size); \
+ memset(__ret, 0, size); \
+ __ret; \
+})
#define vmalloc(size) malloc(size)
#define kfree(ptr) free(ptr)
#define vfree(ptr) free(ptr)
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 8e0dc00..131d7aa 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -22,6 +22,21 @@
#define MTD_ERASE_DONE 0x08
#define MTD_ERASE_FAILED 0x10
+/*
+ * Enumeration for NAND/OneNAND flash chip state
+ */
+enum {
+ FL_READY,
+ FL_READING,
+ FL_WRITING,
+ FL_ERASING,
+ FL_SYNCING,
+ FL_CACHEDPRG,
+ FL_RESETING,
+ FL_UNLOCKING,
+ FL_LOCKING,
+};
+
/* If the erase fails, fail_addr might indicate exactly which block failed. If
fail_addr = 0xffffffff, the failure was not at the device level or was not
specific to any particular block. */
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 2993a89..7ac72de 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -213,20 +213,6 @@ typedef enum {
#define NAND_CI_CHIPNR_MSK 0x03
#define NAND_CI_CELLTYPE_MSK 0x0C
-/*
- * nand_state_t - chip states
- * Enumeration for NAND flash chip state
- */
-typedef enum {
- FL_READY,
- FL_READING,
- FL_WRITING,
- FL_ERASING,
- FL_SYNCING,
- FL_CACHEDPRG,
- FL_PM_SUSPENDED,
-} nand_state_t;
-
/* Keep gcc happy */
struct nand_chip;
@@ -416,7 +402,7 @@ struct nand_chip {
uint8_t cellinfo;
int badblockpos;
- nand_state_t state;
+ int state;
uint8_t *oob_poi;
struct nand_hw_control *controller;
diff --git a/include/linux/mtd/nand_legacy.h b/include/linux/mtd/nand_legacy.h
index b05e726..bb66e45 100644
--- a/include/linux/mtd/nand_legacy.h
+++ b/include/linux/mtd/nand_legacy.h
@@ -55,18 +55,6 @@
#define NAND_CMD_RESET 0xff
/*
- * Enumeration for NAND flash chip state
- */
-typedef enum {
- FL_READY,
- FL_READING,
- FL_WRITING,
- FL_ERASING,
- FL_SYNCING
-} nand_state_t;
-
-
-/*
* NAND Private Flash Chip Data
*
* Structure overview:
diff --git a/include/linux/mtd/onenand.h b/include/linux/mtd/onenand.h
index 4b0c2df..8a0fd0d 100644
--- a/include/linux/mtd/onenand.h
+++ b/include/linux/mtd/onenand.h
@@ -17,6 +17,7 @@
/* Note: The header order is impoertant */
#include <onenand_uboot.h>
+#include <linux/mtd/compat.h>
#include <linux/mtd/bbm.h>
#define MAX_BUFFERRAM 2
@@ -28,20 +29,6 @@ extern int onenand_scan (struct mtd_info *mtd, int max_chips);
extern void onenand_release (struct mtd_info *mtd);
/**
- * onenand_state_t - chip states
- * Enumeration for OneNAND flash chip state
- */
-typedef enum {
- FL_READY,
- FL_READING,
- FL_WRITING,
- FL_ERASING,
- FL_SYNCING,
- FL_UNLOCKING,
- FL_LOCKING,
-} onenand_state_t;
-
-/**
* struct onenand_bufferram - OneNAND BufferRAM Data
* @param block block address in BufferRAM
* @param page page address in BufferRAM
@@ -103,10 +90,12 @@ struct onenand_chip {
unsigned short (*read_word) (void __iomem * addr);
void (*write_word) (unsigned short value, void __iomem * addr);
void (*mmcontrol) (struct mtd_info * mtd, int sync_read);
+ int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
+ int (*scan_bbt)(struct mtd_info *mtd);
spinlock_t chip_lock;
wait_queue_head_t wq;
- onenand_state_t state;
+ int state;
struct nand_oobinfo *autooob;
diff --git a/include/onenand_uboot.h b/include/onenand_uboot.h
index 4260ee7..41e30a2 100644
--- a/include/onenand_uboot.h
+++ b/include/onenand_uboot.h
@@ -15,18 +15,13 @@
#define __UBOOT_ONENAND_H
#include <linux/types.h>
-
-struct kvec {
- void *iov_base;
- size_t iov_len;
-};
-
-typedef int spinlock_t;
-typedef int wait_queue_head_t;
+#include <mtd_uboot.h>
struct mtd_info;
struct erase_info;
+extern struct mtd_info onenand_mtd;
+
/* Functions */
extern void onenand_init(void);
extern int onenand_read(struct mtd_info *mtd, loff_t from, size_t len,
next reply other threads:[~2008-08-13 0:11 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-08-13 0:11 Kyungmin Park [this message]
2008-08-13 16:02 ` [U-Boot-Users] [PATCH] Fix OneNAND build break Scott Wood
2008-08-26 21:04 ` [U-Boot] " Wolfgang Denk
2008-08-26 21:19 ` Scott Wood
2008-08-26 21:53 ` Wolfgang Denk
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20080813001102.GA27788@july \
--to=kmpark@infradead.org \
--cc=u-boot@lists.denx.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.