[MTD] NAND: Clean up trailing white spaces

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Thomas Gleixner 2005-11-07 11:15:49 +00:00 committed by Thomas Gleixner
parent e5580fbe8a
commit 61b03bd7c3
17 changed files with 697 additions and 697 deletions

View File

@ -1,5 +1,5 @@
# drivers/mtd/nand/Kconfig # drivers/mtd/nand/Kconfig
# $Id: Kconfig,v 1.34 2005/09/23 01:44:55 ppopov Exp $ # $Id: Kconfig,v 1.35 2005/11/07 11:14:30 gleixner Exp $
menu "NAND Flash Device Drivers" menu "NAND Flash Device Drivers"
depends on MTD!=n depends on MTD!=n
@ -27,14 +27,14 @@ config MTD_NAND_AUTCPU12
tristate "SmartMediaCard on autronix autcpu12 board" tristate "SmartMediaCard on autronix autcpu12 board"
depends on MTD_NAND && ARCH_AUTCPU12 depends on MTD_NAND && ARCH_AUTCPU12
help help
This enables the driver for the autronix autcpu12 board to This enables the driver for the autronix autcpu12 board to
access the SmartMediaCard. access the SmartMediaCard.
config MTD_NAND_EDB7312 config MTD_NAND_EDB7312
tristate "Support for Cirrus Logic EBD7312 evaluation board" tristate "Support for Cirrus Logic EBD7312 evaluation board"
depends on MTD_NAND && ARCH_EDB7312 depends on MTD_NAND && ARCH_EDB7312
help help
This enables the driver for the Cirrus Logic EBD7312 evaluation This enables the driver for the Cirrus Logic EBD7312 evaluation
board to access the onboard NAND Flash. board to access the onboard NAND Flash.
config MTD_NAND_H1900 config MTD_NAND_H1900
@ -71,7 +71,7 @@ config MTD_NAND_RTC_FROM4
select REED_SOLOMON select REED_SOLOMON
select REED_SOLOMON_DEC8 select REED_SOLOMON_DEC8
help help
This enables the driver for the Renesas Technology AG-AND This enables the driver for the Renesas Technology AG-AND
flash interface board (FROM_BOARD4) flash interface board (FROM_BOARD4)
config MTD_NAND_PPCHAMELEONEVB config MTD_NAND_PPCHAMELEONEVB
@ -88,7 +88,7 @@ config MTD_NAND_S3C2410
SoCs SoCs
No board specfic support is done by this driver, each board No board specfic support is done by this driver, each board
must advertise a platform_device for the driver to attach. must advertise a platform_device for the driver to attach.
config MTD_NAND_S3C2410_DEBUG config MTD_NAND_S3C2410_DEBUG
bool "S3C2410 NAND driver debug" bool "S3C2410 NAND driver debug"

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2004 Embedded Edge, LLC * Copyright (C) 2004 Embedded Edge, LLC
* *
* $Id: au1550nd.c,v 1.12 2005/09/23 01:44:55 ppopov Exp $ * $Id: au1550nd.c,v 1.13 2005/11/07 11:14:30 gleixner Exp $
* *
* 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
@ -25,10 +25,10 @@
#else #else
#include <asm/au1000.h> #include <asm/au1000.h>
#ifdef CONFIG_MIPS_PB1550 #ifdef CONFIG_MIPS_PB1550
#include <asm/pb1550.h> #include <asm/pb1550.h>
#endif #endif
#ifdef CONFIG_MIPS_DB1550 #ifdef CONFIG_MIPS_DB1550
#include <asm/db1x00.h> #include <asm/db1x00.h>
#endif #endif
#endif #endif
@ -43,12 +43,12 @@ static int nand_width = 1; /* default x8*/
* Define partitions for flash device * Define partitions for flash device
*/ */
const static struct mtd_partition partition_info[] = { const static struct mtd_partition partition_info[] = {
{ {
.name = "NAND FS 0", .name = "NAND FS 0",
.offset = 0, .offset = 0,
.size = 8*1024*1024 .size = 8*1024*1024
}, },
{ {
.name = "NAND FS 1", .name = "NAND FS 1",
.offset = MTDPART_OFS_APPEND, .offset = MTDPART_OFS_APPEND,
.size = MTDPART_SIZ_FULL .size = MTDPART_SIZ_FULL
@ -89,7 +89,7 @@ static void au_write_byte(struct mtd_info *mtd, u_char byte)
* au_read_byte16 - read one byte endianess aware from the chip * au_read_byte16 - read one byte endianess aware from the chip
* @mtd: MTD device structure * @mtd: MTD device structure
* *
* read function for 16bit buswith with * read function for 16bit buswith with
* endianess conversion * endianess conversion
*/ */
static u_char au_read_byte16(struct mtd_info *mtd) static u_char au_read_byte16(struct mtd_info *mtd)
@ -119,7 +119,7 @@ static void au_write_byte16(struct mtd_info *mtd, u_char byte)
* au_read_word - read one word from the chip * au_read_word - read one word from the chip
* @mtd: MTD device structure * @mtd: MTD device structure
* *
* read function for 16bit buswith without * read function for 16bit buswith without
* endianess conversion * endianess conversion
*/ */
static u16 au_read_word(struct mtd_info *mtd) static u16 au_read_word(struct mtd_info *mtd)
@ -135,7 +135,7 @@ static u16 au_read_word(struct mtd_info *mtd)
* @mtd: MTD device structure * @mtd: MTD device structure
* @word: data word to write * @word: data word to write
* *
* write function for 16bit buswith without * write function for 16bit buswith without
* endianess conversion * endianess conversion
*/ */
static void au_write_word(struct mtd_info *mtd, u16 word) static void au_write_word(struct mtd_info *mtd, u16 word)
@ -165,7 +165,7 @@ static void au_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
} }
/** /**
* au_read_buf - read chip data into buffer * au_read_buf - read chip data into buffer
* @mtd: MTD device structure * @mtd: MTD device structure
* @buf: buffer to store date * @buf: buffer to store date
* @len: number of bytes to read * @len: number of bytes to read
@ -179,12 +179,12 @@ static void au_read_buf(struct mtd_info *mtd, u_char *buf, int len)
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
buf[i] = readb(this->IO_ADDR_R); buf[i] = readb(this->IO_ADDR_R);
au_sync(); au_sync();
} }
} }
/** /**
* au_verify_buf - Verify chip data against buffer * au_verify_buf - Verify chip data against buffer
* @mtd: MTD device structure * @mtd: MTD device structure
* @buf: buffer containing the data to compare * @buf: buffer containing the data to compare
* @len: number of bytes to compare * @len: number of bytes to compare
@ -219,16 +219,16 @@ static void au_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
u16 *p = (u16 *) buf; u16 *p = (u16 *) buf;
len >>= 1; len >>= 1;
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
writew(p[i], this->IO_ADDR_W); writew(p[i], this->IO_ADDR_W);
au_sync(); au_sync();
} }
} }
/** /**
* au_read_buf16 - read chip data into buffer * au_read_buf16 - read chip data into buffer
* @mtd: MTD device structure * @mtd: MTD device structure
* @buf: buffer to store date * @buf: buffer to store date
* @len: number of bytes to read * @len: number of bytes to read
@ -249,7 +249,7 @@ static void au_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
} }
/** /**
* au_verify_buf16 - Verify chip data against buffer * au_verify_buf16 - Verify chip data against buffer
* @mtd: MTD device structure * @mtd: MTD device structure
* @buf: buffer containing the data to compare * @buf: buffer containing the data to compare
* @len: number of bytes to compare * @len: number of bytes to compare
@ -282,26 +282,26 @@ static void au1550_hwcontrol(struct mtd_info *mtd, int cmd)
case NAND_CTL_CLRCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; break; case NAND_CTL_CLRCLE: this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; break;
case NAND_CTL_SETALE: this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; break; case NAND_CTL_SETALE: this->IO_ADDR_W = p_nand + MEM_STNAND_ADDR; break;
case NAND_CTL_CLRALE: case NAND_CTL_CLRALE:
this->IO_ADDR_W = p_nand + MEM_STNAND_DATA; this->IO_ADDR_W = p_nand + MEM_STNAND_DATA;
/* FIXME: Nobody knows why this is neccecary, /* FIXME: Nobody knows why this is neccecary,
* but it works only that way */ * but it works only that way */
udelay(1); udelay(1);
break; break;
case NAND_CTL_SETNCE: case NAND_CTL_SETNCE:
/* assert (force assert) chip enable */ /* assert (force assert) chip enable */
au_writel((1<<(4+NAND_CS)) , MEM_STNDCTL); break; au_writel((1<<(4+NAND_CS)) , MEM_STNDCTL); break;
break; break;
case NAND_CTL_CLRNCE: case NAND_CTL_CLRNCE:
/* deassert chip enable */ /* deassert chip enable */
au_writel(0, MEM_STNDCTL); break; au_writel(0, MEM_STNDCTL); break;
break; break;
} }
this->IO_ADDR_R = this->IO_ADDR_W; this->IO_ADDR_R = this->IO_ADDR_W;
/* Drain the writebuffer */ /* Drain the writebuffer */
au_sync(); au_sync();
} }
@ -325,7 +325,7 @@ int __init au1xxx_nand_init (void)
u32 nand_phys; u32 nand_phys;
/* Allocate memory for MTD device structure and private data */ /* Allocate memory for MTD device structure and private data */
au1550_mtd = kmalloc (sizeof(struct mtd_info) + au1550_mtd = kmalloc (sizeof(struct mtd_info) +
sizeof (struct nand_chip), GFP_KERNEL); sizeof (struct nand_chip), GFP_KERNEL);
if (!au1550_mtd) { if (!au1550_mtd) {
printk ("Unable to allocate NAND MTD dev structure.\n"); printk ("Unable to allocate NAND MTD dev structure.\n");
@ -345,7 +345,7 @@ int __init au1xxx_nand_init (void)
/* disable interrupts */ /* disable interrupts */
au_writel(au_readl(MEM_STNDCTL) & ~(1<<8), MEM_STNDCTL); au_writel(au_readl(MEM_STNDCTL) & ~(1<<8), MEM_STNDCTL);
/* disable NAND boot */ /* disable NAND boot */
au_writel(au_readl(MEM_STNDCTL) & ~(1<<0), MEM_STNDCTL); au_writel(au_readl(MEM_STNDCTL) & ~(1<<0), MEM_STNDCTL);
@ -353,7 +353,7 @@ int __init au1xxx_nand_init (void)
/* set gpio206 high */ /* set gpio206 high */
au_writel(au_readl(GPIO2_DIR) & ~(1<<6), GPIO2_DIR); au_writel(au_readl(GPIO2_DIR) & ~(1<<6), GPIO2_DIR);
boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) | boot_swapboot = (au_readl(MEM_STSTAT) & (0x7<<1)) |
((bcsr->status >> 6) & 0x1); ((bcsr->status >> 6) & 0x1);
switch (boot_swapboot) { switch (boot_swapboot) {
case 0: case 0:
@ -402,7 +402,7 @@ int __init au1xxx_nand_init (void)
au_writel(NAND_STADDR, MEM_STADDR3); au_writel(NAND_STADDR, MEM_STADDR3);
} }
#endif #endif
/* Locate NAND chip-select in order to determine NAND phys address */ /* Locate NAND chip-select in order to determine NAND phys address */
mem_staddr = 0x00000000; mem_staddr = 0x00000000;
if (((au_readl(MEM_STCFG0) & 0x7) == 0x5) && (NAND_CS == 0)) if (((au_readl(MEM_STCFG0) & 0x7) == 0x5) && (NAND_CS == 0))
@ -438,7 +438,7 @@ int __init au1xxx_nand_init (void)
this->hwcontrol = au1550_hwcontrol; this->hwcontrol = au1550_hwcontrol;
this->dev_ready = au1550_device_ready; this->dev_ready = au1550_device_ready;
/* 30 us command delay time */ /* 30 us command delay time */
this->chip_delay = 30; this->chip_delay = 30;
this->eccmode = NAND_ECC_SOFT; this->eccmode = NAND_ECC_SOFT;
this->options = NAND_NO_AUTOINCR; this->options = NAND_NO_AUTOINCR;
@ -467,7 +467,7 @@ int __init au1xxx_nand_init (void)
outio: outio:
iounmap ((void *)p_nand); iounmap ((void *)p_nand);
outmem: outmem:
kfree (au1550_mtd); kfree (au1550_mtd);
return retval; return retval;

View File

@ -5,8 +5,8 @@
* *
* Derived from drivers/mtd/spia.c * Derived from drivers/mtd/spia.c
* Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
* *
* $Id: autcpu12.c,v 1.22 2004/11/04 12:53:10 gleixner Exp $ * $Id: autcpu12.c,v 1.23 2005/11/07 11:14:30 gleixner Exp $
* *
* 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
@ -14,7 +14,7 @@
* *
* Overview: * Overview:
* This is a device driver for the NAND flash device found on the * This is a device driver for the NAND flash device found on the
* autronix autcpu12 board, which is a SmartMediaCard. It supports * autronix autcpu12 board, which is a SmartMediaCard. It supports
* 16MiB, 32MiB and 64MiB cards. * 16MiB, 32MiB and 64MiB cards.
* *
* *
@ -93,7 +93,7 @@ static struct mtd_partition partition_info128k[] = {
#define NUM_PARTITIONS32K 2 #define NUM_PARTITIONS32K 2
#define NUM_PARTITIONS64K 2 #define NUM_PARTITIONS64K 2
#define NUM_PARTITIONS128K 2 #define NUM_PARTITIONS128K 2
/* /*
* hardware specific access to control-lines * hardware specific access to control-lines
*/ */
static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd) static void autcpu12_hwcontrol(struct mtd_info *mtd, int cmd)
@ -163,7 +163,7 @@ int __init autcpu12_init (void)
this->hwcontrol = autcpu12_hwcontrol; this->hwcontrol = autcpu12_hwcontrol;
this->dev_ready = autcpu12_device_ready; this->dev_ready = autcpu12_device_ready;
/* 20 us command delay time */ /* 20 us command delay time */
this->chip_delay = 20; this->chip_delay = 20;
this->eccmode = NAND_ECC_SOFT; this->eccmode = NAND_ECC_SOFT;
/* Enable the following for a flash based bad block table */ /* Enable the following for a flash based bad block table */
@ -171,21 +171,21 @@ int __init autcpu12_init (void)
this->options = NAND_USE_FLASH_BBT; this->options = NAND_USE_FLASH_BBT;
*/ */
this->options = NAND_USE_FLASH_BBT; this->options = NAND_USE_FLASH_BBT;
/* Scan to find existance of the device */ /* Scan to find existance of the device */
if (nand_scan (autcpu12_mtd, 1)) { if (nand_scan (autcpu12_mtd, 1)) {
err = -ENXIO; err = -ENXIO;
goto out_ior; goto out_ior;
} }
/* Register the partitions */ /* Register the partitions */
switch(autcpu12_mtd->size){ switch(autcpu12_mtd->size){
case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break; case SZ_16M: add_mtd_partitions(autcpu12_mtd, partition_info16k, NUM_PARTITIONS16K); break;
case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break; case SZ_32M: add_mtd_partitions(autcpu12_mtd, partition_info32k, NUM_PARTITIONS32K); break;
case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break; case SZ_64M: add_mtd_partitions(autcpu12_mtd, partition_info64k, NUM_PARTITIONS64K); break;
case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break; case SZ_128M: add_mtd_partitions(autcpu12_mtd, partition_info128k, NUM_PARTITIONS128K); break;
default: { default: {
printk ("Unsupported SmartMedia device\n"); printk ("Unsupported SmartMedia device\n");
err = -ENXIO; err = -ENXIO;
goto out_ior; goto out_ior;
} }
@ -213,7 +213,7 @@ static void __exit autcpu12_cleanup (void)
/* unmap physical adress */ /* unmap physical adress */
iounmap((void *)autcpu12_fio_base); iounmap((void *)autcpu12_fio_base);
/* Free the MTD device structure */ /* Free the MTD device structure */
kfree (autcpu12_mtd); kfree (autcpu12_mtd);
} }

View File

@ -1,4 +1,4 @@
/* /*
* drivers/mtd/nand/diskonchip.c * drivers/mtd/nand/diskonchip.c
* *
* (C) 2003 Red Hat, Inc. * (C) 2003 Red Hat, Inc.
@ -8,15 +8,15 @@
* Author: David Woodhouse <dwmw2@infradead.org> * Author: David Woodhouse <dwmw2@infradead.org>
* Additional Diskonchip 2000 and Millennium support by Dan Brown <dan_brown@ieee.org> * Additional Diskonchip 2000 and Millennium support by Dan Brown <dan_brown@ieee.org>
* Diskonchip Millennium Plus support by Kalev Lember <kalev@smartlink.ee> * Diskonchip Millennium Plus support by Kalev Lember <kalev@smartlink.ee>
* *
* Error correction code lifted from the old docecc code * Error correction code lifted from the old docecc code
* Author: Fabrice Bellard (fabrice.bellard@netgem.com) * Author: Fabrice Bellard (fabrice.bellard@netgem.com)
* Copyright (C) 2000 Netgem S.A. * Copyright (C) 2000 Netgem S.A.
* converted to the generic Reed-Solomon library by Thomas Gleixner <tglx@linutronix.de> * converted to the generic Reed-Solomon library by Thomas Gleixner <tglx@linutronix.de>
* *
* Interface to generic NAND code for M-Systems DiskOnChip devices * Interface to generic NAND code for M-Systems DiskOnChip devices
* *
* $Id: diskonchip.c,v 1.54 2005/04/07 14:22:55 dbrown Exp $ * $Id: diskonchip.c,v 1.55 2005/11/07 11:14:30 gleixner Exp $
*/ */
#include <linux/kernel.h> #include <linux/kernel.h>
@ -42,16 +42,16 @@
static unsigned long __initdata doc_locations[] = { static unsigned long __initdata doc_locations[] = {
#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__) #if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH #ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH
0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000, 0xfffc8000, 0xfffca000, 0xfffcc000, 0xfffce000,
0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000, 0xfffd0000, 0xfffd2000, 0xfffd4000, 0xfffd6000,
0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000, 0xfffd8000, 0xfffda000, 0xfffdc000, 0xfffde000,
0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000, 0xfffe0000, 0xfffe2000, 0xfffe4000, 0xfffe6000,
0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000, 0xfffe8000, 0xfffea000, 0xfffec000, 0xfffee000,
#else /* CONFIG_MTD_DOCPROBE_HIGH */ #else /* CONFIG_MTD_DOCPROBE_HIGH */
0xc8000, 0xca000, 0xcc000, 0xce000, 0xc8000, 0xca000, 0xcc000, 0xce000,
0xd0000, 0xd2000, 0xd4000, 0xd6000, 0xd0000, 0xd2000, 0xd4000, 0xd6000,
0xd8000, 0xda000, 0xdc000, 0xde000, 0xd8000, 0xda000, 0xdc000, 0xde000,
0xe0000, 0xe2000, 0xe4000, 0xe6000, 0xe0000, 0xe2000, 0xe4000, 0xe6000,
0xe8000, 0xea000, 0xec000, 0xee000, 0xe8000, 0xea000, 0xec000, 0xee000,
#endif /* CONFIG_MTD_DOCPROBE_HIGH */ #endif /* CONFIG_MTD_DOCPROBE_HIGH */
#elif defined(__PPC__) #elif defined(__PPC__)
@ -138,7 +138,7 @@ MODULE_PARM_DESC(doc_config_location, "Physical memory address at which to probe
/* the Reed Solomon control structure */ /* the Reed Solomon control structure */
static struct rs_control *rs_decoder; static struct rs_control *rs_decoder;
/* /*
* The HW decoder in the DoC ASIC's provides us a error syndrome, * The HW decoder in the DoC ASIC's provides us a error syndrome,
* which we must convert to a standard syndrom usable by the generic * which we must convert to a standard syndrom usable by the generic
* Reed-Solomon library code. * Reed-Solomon library code.
@ -163,8 +163,8 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
/* Initialize the syndrom buffer */ /* Initialize the syndrom buffer */
for (i = 0; i < NROOTS; i++) for (i = 0; i < NROOTS; i++)
s[i] = ds[0]; s[i] = ds[0];
/* /*
* Evaluate * Evaluate
* s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0] * s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0]
* where x = alpha^(FCR + i) * where x = alpha^(FCR + i)
*/ */
@ -188,7 +188,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
if (nerr < 0) if (nerr < 0)
return nerr; return nerr;
/* /*
* Correct the errors. The bitpositions are a bit of magic, * Correct the errors. The bitpositions are a bit of magic,
* but they are given by the design of the de/encoder circuit * but they are given by the design of the de/encoder circuit
* in the DoC ASIC's. * in the DoC ASIC's.
@ -205,7 +205,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
can be modified since pos is even */ can be modified since pos is even */
index = (pos >> 3) ^ 1; index = (pos >> 3) ^ 1;
bitpos = pos & 7; bitpos = pos & 7;
if ((index >= 0 && index < SECTOR_SIZE) || if ((index >= 0 && index < SECTOR_SIZE) ||
index == (SECTOR_SIZE + 1)) { index == (SECTOR_SIZE + 1)) {
val = (uint8_t) (errval[i] >> (2 + bitpos)); val = (uint8_t) (errval[i] >> (2 + bitpos));
parity ^= val; parity ^= val;
@ -216,7 +216,7 @@ static int doc_ecc_decode (struct rs_control *rs, uint8_t *data, uint8_t *ecc)
bitpos = (bitpos + 10) & 7; bitpos = (bitpos + 10) & 7;
if (bitpos == 0) if (bitpos == 0)
bitpos = 8; bitpos = 8;
if ((index >= 0 && index < SECTOR_SIZE) || if ((index >= 0 && index < SECTOR_SIZE) ||
index == (SECTOR_SIZE + 1)) { index == (SECTOR_SIZE + 1)) {
val = (uint8_t)(errval[i] << (8 - bitpos)); val = (uint8_t)(errval[i] << (8 - bitpos));
parity ^= val; parity ^= val;
@ -233,7 +233,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
{ {
volatile char dummy; volatile char dummy;
int i; int i;
for (i = 0; i < cycles; i++) { for (i = 0; i < cycles; i++) {
if (DoC_is_Millennium(doc)) if (DoC_is_Millennium(doc))
dummy = ReadDOC(doc->virtadr, NOP); dummy = ReadDOC(doc->virtadr, NOP);
@ -242,7 +242,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
else else
dummy = ReadDOC(doc->virtadr, DOCStatus); dummy = ReadDOC(doc->virtadr, DOCStatus);
} }
} }
#define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1) #define CDSN_CTRL_FR_B_MASK (CDSN_CTRL_FR_B0 | CDSN_CTRL_FR_B1)
@ -327,7 +327,7 @@ static u_char doc2000_read_byte(struct mtd_info *mtd)
return ret; return ret;
} }
static void doc2000_writebuf(struct mtd_info *mtd, static void doc2000_writebuf(struct mtd_info *mtd,
const u_char *buf, int len) const u_char *buf, int len)
{ {
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
@ -343,7 +343,7 @@ static void doc2000_writebuf(struct mtd_info *mtd,
if (debug) printk("\n"); if (debug) printk("\n");
} }
static void doc2000_readbuf(struct mtd_info *mtd, static void doc2000_readbuf(struct mtd_info *mtd,
u_char *buf, int len) u_char *buf, int len)
{ {
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
@ -358,7 +358,7 @@ static void doc2000_readbuf(struct mtd_info *mtd,
} }
} }
static void doc2000_readbuf_dword(struct mtd_info *mtd, static void doc2000_readbuf_dword(struct mtd_info *mtd,
u_char *buf, int len) u_char *buf, int len)
{ {
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
@ -379,7 +379,7 @@ static void doc2000_readbuf_dword(struct mtd_info *mtd,
} }
} }
static int doc2000_verifybuf(struct mtd_info *mtd, static int doc2000_verifybuf(struct mtd_info *mtd,
const u_char *buf, int len) const u_char *buf, int len)
{ {
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
@ -406,12 +406,12 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
doc200x_hwcontrol(mtd, NAND_CTL_SETALE); doc200x_hwcontrol(mtd, NAND_CTL_SETALE);
this->write_byte(mtd, 0); this->write_byte(mtd, 0);
doc200x_hwcontrol(mtd, NAND_CTL_CLRALE); doc200x_hwcontrol(mtd, NAND_CTL_CLRALE);
/* We cant' use dev_ready here, but at least we wait for the /* We cant' use dev_ready here, but at least we wait for the
* command to complete * command to complete
*/ */
udelay(50); udelay(50);
ret = this->read_byte(mtd) << 8; ret = this->read_byte(mtd) << 8;
ret |= this->read_byte(mtd); ret |= this->read_byte(mtd);
@ -438,7 +438,7 @@ static uint16_t __init doc200x_ident_chip(struct mtd_info *mtd, int nr)
this->read_buf = &doc2000_readbuf_dword; this->read_buf = &doc2000_readbuf_dword;
} }
} }
return ret; return ret;
} }
@ -469,7 +469,7 @@ static int doc200x_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
struct doc_priv *doc = this->priv; struct doc_priv *doc = this->priv;
int status; int status;
DoC_WaitReady(doc); DoC_WaitReady(doc);
this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1); this->cmdfunc(mtd, NAND_CMD_STATUS, -1, -1);
DoC_WaitReady(doc); DoC_WaitReady(doc);
@ -503,7 +503,7 @@ static u_char doc2001_read_byte(struct mtd_info *mtd)
return ReadDOC(docptr, LastDataRead); return ReadDOC(docptr, LastDataRead);
} }
static void doc2001_writebuf(struct mtd_info *mtd, static void doc2001_writebuf(struct mtd_info *mtd,
const u_char *buf, int len) const u_char *buf, int len)
{ {
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
@ -517,7 +517,7 @@ static void doc2001_writebuf(struct mtd_info *mtd,
WriteDOC(0x00, docptr, WritePipeTerm); WriteDOC(0x00, docptr, WritePipeTerm);
} }
static void doc2001_readbuf(struct mtd_info *mtd, static void doc2001_readbuf(struct mtd_info *mtd,
u_char *buf, int len) u_char *buf, int len)
{ {
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
@ -535,7 +535,7 @@ static void doc2001_readbuf(struct mtd_info *mtd,
buf[i] = ReadDOC(docptr, LastDataRead); buf[i] = ReadDOC(docptr, LastDataRead);
} }
static int doc2001_verifybuf(struct mtd_info *mtd, static int doc2001_verifybuf(struct mtd_info *mtd,
const u_char *buf, int len) const u_char *buf, int len)
{ {
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
@ -570,7 +570,7 @@ static u_char doc2001plus_read_byte(struct mtd_info *mtd)
return ret; return ret;
} }
static void doc2001plus_writebuf(struct mtd_info *mtd, static void doc2001plus_writebuf(struct mtd_info *mtd,
const u_char *buf, int len) const u_char *buf, int len)
{ {
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
@ -587,7 +587,7 @@ static void doc2001plus_writebuf(struct mtd_info *mtd,
if (debug) printk("\n"); if (debug) printk("\n");
} }
static void doc2001plus_readbuf(struct mtd_info *mtd, static void doc2001plus_readbuf(struct mtd_info *mtd,
u_char *buf, int len) u_char *buf, int len)
{ {
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
@ -617,7 +617,7 @@ static void doc2001plus_readbuf(struct mtd_info *mtd,
if (debug) printk("\n"); if (debug) printk("\n");
} }
static int doc2001plus_verifybuf(struct mtd_info *mtd, static int doc2001plus_verifybuf(struct mtd_info *mtd,
const u_char *buf, int len) const u_char *buf, int len)
{ {
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
@ -797,7 +797,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
WriteDOC(0, docptr, Mplus_FlashControl); WriteDOC(0, docptr, Mplus_FlashControl);
} }
/* /*
* program and erase have their own busy handlers * program and erase have their own busy handlers
* status and sequential in needs no delay * status and sequential in needs no delay
*/ */
@ -822,7 +822,7 @@ static void doc2001plus_command (struct mtd_info *mtd, unsigned command, int col
/* This applies to read commands */ /* This applies to read commands */
default: default:
/* /*
* If we don't have access to the busy pin, we apply the given * If we don't have access to the busy pin, we apply the given
* command delay * command delay
*/ */
@ -945,7 +945,7 @@ static int doc200x_calculate_ecc(struct mtd_info *mtd, const u_char *dat,
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
if (DoC_is_MillenniumPlus(doc)) if (DoC_is_MillenniumPlus(doc))
ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i); ecc_code[i] = ReadDOC_(docptr, DoC_Mplus_ECCSyndrome0 + i);
else else
ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i); ecc_code[i] = ReadDOC_(docptr, DoC_ECCSyndrome0 + i);
if (ecc_code[i] != empty_write_ecc[i]) if (ecc_code[i] != empty_write_ecc[i])
emptymatch = 0; emptymatch = 0;
@ -982,7 +982,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
void __iomem *docptr = doc->virtadr; void __iomem *docptr = doc->virtadr;
volatile u_char dummy; volatile u_char dummy;
int emptymatch = 1; int emptymatch = 1;
/* flush the pipeline */ /* flush the pipeline */
if (DoC_is_2000(doc)) { if (DoC_is_2000(doc)) {
dummy = ReadDOC(docptr, 2k_ECCStatus); dummy = ReadDOC(docptr, 2k_ECCStatus);
@ -997,7 +997,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
dummy = ReadDOC(docptr, ECCConf); dummy = ReadDOC(docptr, ECCConf);
dummy = ReadDOC(docptr, ECCConf); dummy = ReadDOC(docptr, ECCConf);
} }
/* Error occured ? */ /* Error occured ? */
if (dummy & 0x80) { if (dummy & 0x80) {
for (i = 0; i < 6; i++) { for (i = 0; i < 6; i++) {
@ -1035,7 +1035,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc); if (!emptymatch) ret = doc_ecc_decode (rs_decoder, dat, calc_ecc);
if (ret > 0) if (ret > 0)
printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret); printk(KERN_ERR "doc200x_correct_data corrected %d errors\n", ret);
} }
if (DoC_is_MillenniumPlus(doc)) if (DoC_is_MillenniumPlus(doc))
WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf); WriteDOC(DOC_ECC_DIS, docptr, Mplus_ECCConf);
else else
@ -1046,7 +1046,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
} }
return ret; return ret;
} }
//u_char mydatabuf[528]; //u_char mydatabuf[528];
/* The strange out-of-order .oobfree list below is a (possibly unneeded) /* The strange out-of-order .oobfree list below is a (possibly unneeded)
@ -1065,7 +1065,7 @@ static struct nand_oobinfo doc200x_oobinfo = {
.eccpos = {0, 1, 2, 3, 4, 5}, .eccpos = {0, 1, 2, 3, 4, 5},
.oobfree = { {8, 8}, {6, 2} } .oobfree = { {8, 8}, {6, 2} }
}; };
/* Find the (I)NFTL Media Header, and optionally also the mirror media header. /* Find the (I)NFTL Media Header, and optionally also the mirror media header.
On sucessful return, buf will contain a copy of the media header for On sucessful return, buf will contain a copy of the media header for
further processing. id is the string to scan for, and will presumably be further processing. id is the string to scan for, and will presumably be
@ -1251,7 +1251,7 @@ static inline int __init inftl_partscan(struct mtd_info *mtd,
mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits); mh->BlockMultiplierBits = le32_to_cpu(mh->BlockMultiplierBits);
mh->FormatFlags = le32_to_cpu(mh->FormatFlags); mh->FormatFlags = le32_to_cpu(mh->FormatFlags);
mh->PercentUsed = le32_to_cpu(mh->PercentUsed); mh->PercentUsed = le32_to_cpu(mh->PercentUsed);
printk(KERN_INFO " bootRecordID = %s\n" printk(KERN_INFO " bootRecordID = %s\n"
" NoOfBootImageBlocks = %d\n" " NoOfBootImageBlocks = %d\n"
" NoOfBinaryPartitions = %d\n" " NoOfBinaryPartitions = %d\n"
@ -1468,7 +1468,7 @@ static inline int __init doc2001_init(struct mtd_info *mtd)
ReadDOC(doc->virtadr, ChipID); ReadDOC(doc->virtadr, ChipID);
if (ReadDOC(doc->virtadr, ChipID) != DOC_ChipID_DocMil) { if (ReadDOC(doc->virtadr, ChipID) != DOC_ChipID_DocMil) {
/* It's not a Millennium; it's one of the newer /* It's not a Millennium; it's one of the newer
DiskOnChip 2000 units with a similar ASIC. DiskOnChip 2000 units with a similar ASIC.
Treat it like a Millennium, except that it Treat it like a Millennium, except that it
can have multiple chips. */ can have multiple chips. */
doc2000_count_chips(mtd); doc2000_count_chips(mtd);
@ -1530,20 +1530,20 @@ static inline int __init doc_probe(unsigned long physadr)
* to the DOCControl register. So we store the current contents * to the DOCControl register. So we store the current contents
* of the DOCControl register's location, in case we later decide * of the DOCControl register's location, in case we later decide
* that it's not a DiskOnChip, and want to put it back how we * that it's not a DiskOnChip, and want to put it back how we
* found it. * found it.
*/ */
save_control = ReadDOC(virtadr, DOCControl); save_control = ReadDOC(virtadr, DOCControl);
/* Reset the DiskOnChip ASIC */ /* Reset the DiskOnChip ASIC */
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
virtadr, DOCControl); virtadr, DOCControl);
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET, WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_RESET,
virtadr, DOCControl); virtadr, DOCControl);
/* Enable the DiskOnChip ASIC */ /* Enable the DiskOnChip ASIC */
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
virtadr, DOCControl); virtadr, DOCControl);
WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL, WriteDOC(DOC_MODE_CLR_ERR | DOC_MODE_MDWREN | DOC_MODE_NORMAL,
virtadr, DOCControl); virtadr, DOCControl);
ChipID = ReadDOC(virtadr, ChipID); ChipID = ReadDOC(virtadr, ChipID);
@ -1738,7 +1738,7 @@ static int __init init_nanddoc(void)
int i, ret = 0; int i, ret = 0;
/* We could create the decoder on demand, if memory is a concern. /* We could create the decoder on demand, if memory is a concern.
* This way we have it handy, if an error happens * This way we have it handy, if an error happens
* *
* Symbolsize is 10 (bits) * Symbolsize is 10 (bits)
* Primitve polynomial is x^10+x^3+1 * Primitve polynomial is x^10+x^3+1

View File

@ -6,7 +6,7 @@
* Derived from drivers/mtd/nand/autcpu12.c * Derived from drivers/mtd/nand/autcpu12.c
* Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
* *
* $Id: edb7312.c,v 1.11 2004/11/04 12:53:10 gleixner Exp $ * $Id: edb7312.c,v 1.12 2005/11/07 11:14:30 gleixner Exp $
* *
* 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
@ -71,27 +71,27 @@ static struct mtd_partition partition_info[] = {
#endif #endif
/* /*
* hardware specific access to control-lines * hardware specific access to control-lines
*/ */
static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd) static void ep7312_hwcontrol(struct mtd_info *mtd, int cmd)
{ {
switch(cmd) { switch(cmd) {
case NAND_CTL_SETCLE: case NAND_CTL_SETCLE:
clps_writeb(clps_readb(ep7312_pxdr) | 0x10, ep7312_pxdr); clps_writeb(clps_readb(ep7312_pxdr) | 0x10, ep7312_pxdr);
break; break;
case NAND_CTL_CLRCLE: case NAND_CTL_CLRCLE:
clps_writeb(clps_readb(ep7312_pxdr) & ~0x10, ep7312_pxdr); clps_writeb(clps_readb(ep7312_pxdr) & ~0x10, ep7312_pxdr);
break; break;
case NAND_CTL_SETALE: case NAND_CTL_SETALE:
clps_writeb(clps_readb(ep7312_pxdr) | 0x20, ep7312_pxdr); clps_writeb(clps_readb(ep7312_pxdr) | 0x20, ep7312_pxdr);
break; break;
case NAND_CTL_CLRALE: case NAND_CTL_CLRALE:
clps_writeb(clps_readb(ep7312_pxdr) & ~0x20, ep7312_pxdr); clps_writeb(clps_readb(ep7312_pxdr) & ~0x20, ep7312_pxdr);
break; break;
case NAND_CTL_SETNCE: case NAND_CTL_SETNCE:
clps_writeb((clps_readb(ep7312_pxdr) | 0x80) & ~0x40, ep7312_pxdr); clps_writeb((clps_readb(ep7312_pxdr) | 0x80) & ~0x40, ep7312_pxdr);
break; break;
@ -122,16 +122,16 @@ static int __init ep7312_init (void)
int mtd_parts_nb = 0; int mtd_parts_nb = 0;
struct mtd_partition *mtd_parts = 0; struct mtd_partition *mtd_parts = 0;
void __iomem * ep7312_fio_base; void __iomem * ep7312_fio_base;
/* Allocate memory for MTD device structure and private data */ /* Allocate memory for MTD device structure and private data */
ep7312_mtd = kmalloc(sizeof(struct mtd_info) + ep7312_mtd = kmalloc(sizeof(struct mtd_info) +
sizeof(struct nand_chip), sizeof(struct nand_chip),
GFP_KERNEL); GFP_KERNEL);
if (!ep7312_mtd) { if (!ep7312_mtd) {
printk("Unable to allocate EDB7312 NAND MTD device structure.\n"); printk("Unable to allocate EDB7312 NAND MTD device structure.\n");
return -ENOMEM; return -ENOMEM;
} }
/* map physical adress */ /* map physical adress */
ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K); ep7312_fio_base = ioremap(ep7312_fio_pbase, SZ_1K);
if(!ep7312_fio_base) { if(!ep7312_fio_base) {
@ -139,23 +139,23 @@ static int __init ep7312_init (void)
kfree(ep7312_mtd); kfree(ep7312_mtd);
return -EIO; return -EIO;
} }
/* Get pointer to private data */ /* Get pointer to private data */
this = (struct nand_chip *) (&ep7312_mtd[1]); this = (struct nand_chip *) (&ep7312_mtd[1]);
/* Initialize structures */ /* Initialize structures */
memset((char *) ep7312_mtd, 0, sizeof(struct mtd_info)); memset((char *) ep7312_mtd, 0, sizeof(struct mtd_info));
memset((char *) this, 0, sizeof(struct nand_chip)); memset((char *) this, 0, sizeof(struct nand_chip));
/* Link the private data with the MTD structure */ /* Link the private data with the MTD structure */
ep7312_mtd->priv = this; ep7312_mtd->priv = this;
/* /*
* Set GPIO Port B control register so that the pins are configured * Set GPIO Port B control register so that the pins are configured
* to be outputs for controlling the NAND flash. * to be outputs for controlling the NAND flash.
*/ */
clps_writeb(0xf0, ep7312_pxddr); clps_writeb(0xf0, ep7312_pxddr);
/* insert callbacks */ /* insert callbacks */
this->IO_ADDR_R = ep7312_fio_base; this->IO_ADDR_R = ep7312_fio_base;
this->IO_ADDR_W = ep7312_fio_base; this->IO_ADDR_W = ep7312_fio_base;
@ -163,14 +163,14 @@ static int __init ep7312_init (void)
this->dev_ready = ep7312_device_ready; this->dev_ready = ep7312_device_ready;
/* 15 us command delay time */ /* 15 us command delay time */
this->chip_delay = 15; this->chip_delay = 15;
/* Scan to find existence of the device */ /* Scan to find existence of the device */
if (nand_scan (ep7312_mtd, 1)) { if (nand_scan (ep7312_mtd, 1)) {
iounmap((void *)ep7312_fio_base); iounmap((void *)ep7312_fio_base);
kfree (ep7312_mtd); kfree (ep7312_mtd);
return -ENXIO; return -ENXIO;
} }
#ifdef CONFIG_MTD_PARTITIONS #ifdef CONFIG_MTD_PARTITIONS
ep7312_mtd->name = "edb7312-nand"; ep7312_mtd->name = "edb7312-nand";
mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes, mtd_parts_nb = parse_mtd_partitions(ep7312_mtd, part_probes,
@ -185,11 +185,11 @@ static int __init ep7312_init (void)
mtd_parts_nb = NUM_PARTITIONS; mtd_parts_nb = NUM_PARTITIONS;
part_type = "static"; part_type = "static";
} }
/* Register the partitions */ /* Register the partitions */
printk(KERN_NOTICE "Using %s partition definition\n", part_type); printk(KERN_NOTICE "Using %s partition definition\n", part_type);
add_mtd_partitions(ep7312_mtd, mtd_parts, mtd_parts_nb); add_mtd_partitions(ep7312_mtd, mtd_parts, mtd_parts_nb);
/* Return happy */ /* Return happy */
return 0; return 0;
} }
@ -201,13 +201,13 @@ module_init(ep7312_init);
static void __exit ep7312_cleanup (void) static void __exit ep7312_cleanup (void)
{ {
struct nand_chip *this = (struct nand_chip *) &ep7312_mtd[1]; struct nand_chip *this = (struct nand_chip *) &ep7312_mtd[1];
/* Release resources, unregister device */ /* Release resources, unregister device */
nand_release (ap7312_mtd); nand_release (ap7312_mtd);
/* Free internal data buffer */ /* Free internal data buffer */
kfree (this->data_buf); kfree (this->data_buf);
/* Free the MTD device structure */ /* Free the MTD device structure */
kfree (ep7312_mtd); kfree (ep7312_mtd);
} }

View File

@ -7,7 +7,7 @@
* Copyright (C) 2002 Marius Gröger (mag@sysgo.de) * Copyright (C) 2002 Marius Gröger (mag@sysgo.de)
* Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de) * Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
* *
* $Id: h1910.c,v 1.5 2004/11/04 12:53:10 gleixner Exp $ * $Id: h1910.c,v 1.6 2005/11/07 11:14:30 gleixner Exp $
* *
* 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
@ -54,24 +54,24 @@ static struct mtd_partition partition_info[] = {
#endif #endif
/* /*
* hardware specific access to control-lines * hardware specific access to control-lines
*/ */
static void h1910_hwcontrol(struct mtd_info *mtd, int cmd) static void h1910_hwcontrol(struct mtd_info *mtd, int cmd)
{ {
struct nand_chip* this = (struct nand_chip *) (mtd->priv); struct nand_chip* this = (struct nand_chip *) (mtd->priv);
switch(cmd) { switch(cmd) {
case NAND_CTL_SETCLE: case NAND_CTL_SETCLE:
this->IO_ADDR_R |= (1 << 2); this->IO_ADDR_R |= (1 << 2);
this->IO_ADDR_W |= (1 << 2); this->IO_ADDR_W |= (1 << 2);
break; break;
case NAND_CTL_CLRCLE: case NAND_CTL_CLRCLE:
this->IO_ADDR_R &= ~(1 << 2); this->IO_ADDR_R &= ~(1 << 2);
this->IO_ADDR_W &= ~(1 << 2); this->IO_ADDR_W &= ~(1 << 2);
break; break;
case NAND_CTL_SETALE: case NAND_CTL_SETALE:
this->IO_ADDR_R |= (1 << 3); this->IO_ADDR_R |= (1 << 3);
this->IO_ADDR_W |= (1 << 3); this->IO_ADDR_W |= (1 << 3);
@ -80,7 +80,7 @@ static void h1910_hwcontrol(struct mtd_info *mtd, int cmd)
this->IO_ADDR_R &= ~(1 << 3); this->IO_ADDR_R &= ~(1 << 3);
this->IO_ADDR_W &= ~(1 << 3); this->IO_ADDR_W &= ~(1 << 3);
break; break;
case NAND_CTL_SETNCE: case NAND_CTL_SETNCE:
break; break;
case NAND_CTL_CLRNCE: case NAND_CTL_CLRNCE:
@ -108,18 +108,18 @@ static int __init h1910_init (void)
int mtd_parts_nb = 0; int mtd_parts_nb = 0;
struct mtd_partition *mtd_parts = 0; struct mtd_partition *mtd_parts = 0;
void __iomem *nandaddr; void __iomem *nandaddr;
if (!machine_is_h1900()) if (!machine_is_h1900())
return -ENODEV; return -ENODEV;
nandaddr = __ioremap(0x08000000, 0x1000, 0, 1); nandaddr = __ioremap(0x08000000, 0x1000, 0, 1);
if (!nandaddr) { if (!nandaddr) {
printk("Failed to ioremap nand flash.\n"); printk("Failed to ioremap nand flash.\n");
return -ENOMEM; return -ENOMEM;
} }
/* Allocate memory for MTD device structure and private data */ /* Allocate memory for MTD device structure and private data */
h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) + h1910_nand_mtd = kmalloc(sizeof(struct mtd_info) +
sizeof(struct nand_chip), sizeof(struct nand_chip),
GFP_KERNEL); GFP_KERNEL);
if (!h1910_nand_mtd) { if (!h1910_nand_mtd) {
@ -127,22 +127,22 @@ static int __init h1910_init (void)
iounmap ((void *) nandaddr); iounmap ((void *) nandaddr);
return -ENOMEM; return -ENOMEM;
} }
/* Get pointer to private data */ /* Get pointer to private data */
this = (struct nand_chip *) (&h1910_nand_mtd[1]); this = (struct nand_chip *) (&h1910_nand_mtd[1]);
/* Initialize structures */ /* Initialize structures */
memset((char *) h1910_nand_mtd, 0, sizeof(struct mtd_info)); memset((char *) h1910_nand_mtd, 0, sizeof(struct mtd_info));
memset((char *) this, 0, sizeof(struct nand_chip)); memset((char *) this, 0, sizeof(struct nand_chip));
/* Link the private data with the MTD structure */ /* Link the private data with the MTD structure */
h1910_nand_mtd->priv = this; h1910_nand_mtd->priv = this;
/* /*
* Enable VPEN * Enable VPEN
*/ */
GPSR(37) = GPIO_bit(37); GPSR(37) = GPIO_bit(37);
/* insert callbacks */ /* insert callbacks */
this->IO_ADDR_R = nandaddr; this->IO_ADDR_R = nandaddr;
this->IO_ADDR_W = nandaddr; this->IO_ADDR_W = nandaddr;
@ -152,7 +152,7 @@ static int __init h1910_init (void)
this->chip_delay = 50; this->chip_delay = 50;
this->eccmode = NAND_ECC_SOFT; this->eccmode = NAND_ECC_SOFT;
this->options = NAND_NO_AUTOINCR; this->options = NAND_NO_AUTOINCR;
/* Scan to find existence of the device */ /* Scan to find existence of the device */
if (nand_scan (h1910_nand_mtd, 1)) { if (nand_scan (h1910_nand_mtd, 1)) {
printk(KERN_NOTICE "No NAND device - returning -ENXIO\n"); printk(KERN_NOTICE "No NAND device - returning -ENXIO\n");
@ -160,9 +160,9 @@ static int __init h1910_init (void)
iounmap ((void *) nandaddr); iounmap ((void *) nandaddr);
return -ENXIO; return -ENXIO;
} }
#ifdef CONFIG_MTD_CMDLINE_PARTS #ifdef CONFIG_MTD_CMDLINE_PARTS
mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts, mtd_parts_nb = parse_cmdline_partitions(h1910_nand_mtd, &mtd_parts,
"h1910-nand"); "h1910-nand");
if (mtd_parts_nb > 0) if (mtd_parts_nb > 0)
part_type = "command line"; part_type = "command line";
@ -175,11 +175,11 @@ static int __init h1910_init (void)
mtd_parts_nb = NUM_PARTITIONS; mtd_parts_nb = NUM_PARTITIONS;
part_type = "static"; part_type = "static";
} }
/* Register the partitions */ /* Register the partitions */
printk(KERN_NOTICE "Using %s partition definition\n", part_type); printk(KERN_NOTICE "Using %s partition definition\n", part_type);
add_mtd_partitions(h1910_nand_mtd, mtd_parts, mtd_parts_nb); add_mtd_partitions(h1910_nand_mtd, mtd_parts, mtd_parts_nb);
/* Return happy */ /* Return happy */
return 0; return 0;
} }
@ -191,7 +191,7 @@ module_init(h1910_init);
static void __exit h1910_cleanup (void) static void __exit h1910_cleanup (void)
{ {
struct nand_chip *this = (struct nand_chip *) &h1910_nand_mtd[1]; struct nand_chip *this = (struct nand_chip *) &h1910_nand_mtd[1];
/* Release resources, unregister device */ /* Release resources, unregister device */
nand_release (h1910_nand_mtd); nand_release (h1910_nand_mtd);

File diff suppressed because it is too large Load Diff

View File

@ -3,10 +3,10 @@
* *
* Overview: * Overview:
* Bad block table support for the NAND driver * Bad block table support for the NAND driver
* *
* Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de) * Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
* *
* $Id: nand_bbt.c,v 1.35 2005/07/15 13:53:47 gleixner Exp $ * $Id: nand_bbt.c,v 1.36 2005/11/07 11:14:30 gleixner Exp $
* *
* 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
@ -14,23 +14,23 @@
* *
* Description: * Description:
* *
* When nand_scan_bbt is called, then it tries to find the bad block table * When nand_scan_bbt is called, then it tries to find the bad block table
* depending on the options in the bbt descriptor(s). If a bbt is found * depending on the options in the bbt descriptor(s). If a bbt is found
* then the contents are read and the memory based bbt is created. If a * then the contents are read and the memory based bbt is created. If a
* mirrored bbt is selected then the mirror is searched too and the * mirrored bbt is selected then the mirror is searched too and the
* versions are compared. If the mirror has a greater version number * versions are compared. If the mirror has a greater version number
* than the mirror bbt is used to build the memory based bbt. * than the mirror bbt is used to build the memory based bbt.
* If the tables are not versioned, then we "or" the bad block information. * If the tables are not versioned, then we "or" the bad block information.
* If one of the bbt's is out of date or does not exist it is (re)created. * If one of the bbt's is out of date or does not exist it is (re)created.
* If no bbt exists at all then the device is scanned for factory marked * If no bbt exists at all then the device is scanned for factory marked
* good / bad blocks and the bad block tables are created. * good / bad blocks and the bad block tables are created.
* *
* For manufacturer created bbts like the one found on M-SYS DOC devices * For manufacturer created bbts like the one found on M-SYS DOC devices
* the bbt is searched and read but never created * the bbt is searched and read but never created
* *
* The autogenerated bad block table is located in the last good blocks * The autogenerated bad block table is located in the last good blocks
* of the device. The table is mirrored, so it can be updated eventually. * of the device. The table is mirrored, so it can be updated eventually.
* The table is marked in the oob area with an ident pattern and a version * The table is marked in the oob area with an ident pattern and a version
* number which indicates which of both tables is more up to date. * number which indicates which of both tables is more up to date.
* *
* The table uses 2 bits per block * The table uses 2 bits per block
@ -43,13 +43,13 @@
* 01b: block is marked bad due to wear * 01b: block is marked bad due to wear
* 10b: block is reserved (to protect the bbt area) * 10b: block is reserved (to protect the bbt area)
* 11b: block is factory marked bad * 11b: block is factory marked bad
* *
* Multichip devices like DOC store the bad block info per floor. * Multichip devices like DOC store the bad block info per floor.
* *
* Following assumptions are made: * Following assumptions are made:
* - bbts start at a page boundary, if autolocated on a block boundary * - bbts start at a page boundary, if autolocated on a block boundary
* - the space neccecary for a bbt in FLASH does not exceed a block boundary * - the space neccecary for a bbt in FLASH does not exceed a block boundary
* *
*/ */
#include <linux/slab.h> #include <linux/slab.h>
@ -62,7 +62,7 @@
#include <linux/delay.h> #include <linux/delay.h>
/** /**
* check_pattern - [GENERIC] check if a pattern is in the buffer * check_pattern - [GENERIC] check if a pattern is in the buffer
* @buf: the buffer to search * @buf: the buffer to search
* @len: the length of buffer to search * @len: the length of buffer to search
@ -86,9 +86,9 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
if (p[i] != 0xff) if (p[i] != 0xff)
return -1; return -1;
} }
} }
p += end; p += end;
/* Compare the pattern */ /* Compare the pattern */
for (i = 0; i < td->len; i++) { for (i = 0; i < td->len; i++) {
if (p[i] != td->pattern[i]) if (p[i] != td->pattern[i])
@ -106,13 +106,13 @@ static int check_pattern (uint8_t *buf, int len, int paglen, struct nand_bbt_des
return 0; return 0;
} }
/** /**
* check_short_pattern - [GENERIC] check if a pattern is in the buffer * check_short_pattern - [GENERIC] check if a pattern is in the buffer
* @buf: the buffer to search * @buf: the buffer to search
* @td: search pattern descriptor * @td: search pattern descriptor
* *
* Check for a pattern at the given place. Used to search bad block * Check for a pattern at the given place. Used to search bad block
* tables and good / bad block identifiers. Same as check_pattern, but * tables and good / bad block identifiers. Same as check_pattern, but
* no optional empty check * no optional empty check
* *
*/ */
@ -142,7 +142,7 @@ static int check_short_pattern (uint8_t *buf, struct nand_bbt_descr *td)
* Read the bad block table starting from page. * Read the bad block table starting from page.
* *
*/ */
static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num, static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
int bits, int offs, int reserved_block_code) int bits, int offs, int reserved_block_code)
{ {
int res, i, j, act = 0; int res, i, j, act = 0;
@ -153,7 +153,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
totlen = (num * bits) >> 3; totlen = (num * bits) >> 3;
from = ((loff_t)page) << this->page_shift; from = ((loff_t)page) << this->page_shift;
while (totlen) { while (totlen) {
len = min (totlen, (size_t) (1 << this->bbt_erase_shift)); len = min (totlen, (size_t) (1 << this->bbt_erase_shift));
res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob); res = mtd->read_ecc (mtd, from, len, &retlen, buf, NULL, this->autooob);
@ -163,7 +163,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
return res; return res;
} }
printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n"); printk (KERN_WARNING "nand_bbt: ECC error while reading bad block table\n");
} }
/* Analyse data */ /* Analyse data */
for (i = 0; i < len; i++) { for (i = 0; i < len; i++) {
@ -183,12 +183,12 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
* message to MTD_DEBUG_LEVEL0 */ * message to MTD_DEBUG_LEVEL0 */
printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n", printk (KERN_DEBUG "nand_read_bbt: Bad block at 0x%08x\n",
((offs << 2) + (act >> 1)) << this->bbt_erase_shift); ((offs << 2) + (act >> 1)) << this->bbt_erase_shift);
/* Factory marked bad or worn out ? */ /* Factory marked bad or worn out ? */
if (tmp == 0) if (tmp == 0)
this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06); this->bbt[offs + (act >> 3)] |= 0x3 << (act & 0x06);
else else
this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06); this->bbt[offs + (act >> 3)] |= 0x1 << (act & 0x06);
} }
} }
totlen -= len; totlen -= len;
from += len; from += len;
@ -200,7 +200,7 @@ static int read_bbt (struct mtd_info *mtd, uint8_t *buf, int page, int num,
* read_abs_bbt - [GENERIC] Read the bad block table starting at a given page * read_abs_bbt - [GENERIC] Read the bad block table starting at a given page
* @mtd: MTD device structure * @mtd: MTD device structure
* @buf: temporary buffer * @buf: temporary buffer
* @td: descriptor for the bad block table * @td: descriptor for the bad block table
* @chip: read the table for a specific chip, -1 read all chips. * @chip: read the table for a specific chip, -1 read all chips.
* Applies only if NAND_BBT_PERCHIP option is set * Applies only if NAND_BBT_PERCHIP option is set
* *
@ -235,7 +235,7 @@ static int read_abs_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
* read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page * read_abs_bbts - [GENERIC] Read the bad block table(s) for all chips starting at a given page
* @mtd: MTD device structure * @mtd: MTD device structure
* @buf: temporary buffer * @buf: temporary buffer
* @td: descriptor for the bad block table * @td: descriptor for the bad block table
* @md: descriptor for the bad block table mirror * @md: descriptor for the bad block table mirror
* *
* Read the bad block table(s) for all chips starting at a given page * Read the bad block table(s) for all chips starting at a given page
@ -247,16 +247,16 @@ static int read_abs_bbts (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_de
{ {
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
/* Read the primary version, if available */ /* Read the primary version, if available */
if (td->options & NAND_BBT_VERSION) { if (td->options & NAND_BBT_VERSION) {
nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); nand_read_raw (mtd, buf, td->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
td->version[0] = buf[mtd->oobblock + td->veroffs]; td->version[0] = buf[mtd->oobblock + td->veroffs];
printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]); printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", td->pages[0], td->version[0]);
} }
/* Read the mirror version, if available */ /* Read the mirror version, if available */
if (md && (md->options & NAND_BBT_VERSION)) { if (md && (md->options & NAND_BBT_VERSION)) {
nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize); nand_read_raw (mtd, buf, md->pages[0] << this->page_shift, mtd->oobblock, mtd->oobsize);
md->version[0] = buf[mtd->oobblock + md->veroffs]; md->version[0] = buf[mtd->oobblock + md->veroffs];
printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]); printk (KERN_DEBUG "Bad block table at page %d, version 0x%02X\n", md->pages[0], md->version[0]);
} }
@ -290,7 +290,7 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
else { else {
if (bd->options & NAND_BBT_SCAN2NDPAGE) if (bd->options & NAND_BBT_SCAN2NDPAGE)
len = 2; len = 2;
else else
len = 1; len = 1;
} }
@ -322,10 +322,10 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
numblocks += startblock; numblocks += startblock;
from = startblock << (this->bbt_erase_shift - 1); from = startblock << (this->bbt_erase_shift - 1);
} }
for (i = startblock; i < numblocks;) { for (i = startblock; i < numblocks;) {
int ret; int ret;
if (bd->options & NAND_BBT_SCANEMPTY) if (bd->options & NAND_BBT_SCANEMPTY)
if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen))) if ((ret = nand_read_raw (mtd, buf, from, readlen, ooblen)))
return ret; return ret;
@ -333,8 +333,8 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
for (j = 0; j < len; j++) { for (j = 0; j < len; j++) {
if (!(bd->options & NAND_BBT_SCANEMPTY)) { if (!(bd->options & NAND_BBT_SCANEMPTY)) {
size_t retlen; size_t retlen;
/* Read the full oob until read_oob is fixed to /* Read the full oob until read_oob is fixed to
* handle single byte reads for 16 bit buswidth */ * handle single byte reads for 16 bit buswidth */
ret = mtd->read_oob(mtd, from + j * mtd->oobblock, ret = mtd->read_oob(mtd, from + j * mtd->oobblock,
mtd->oobsize, &retlen, buf); mtd->oobsize, &retlen, buf);
@ -343,14 +343,14 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
if (check_short_pattern (buf, bd)) { if (check_short_pattern (buf, bd)) {
this->bbt[i >> 3] |= 0x03 << (i & 0x6); this->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);
break; break;
} }
} else { } else {
if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) { if (check_pattern (&buf[j * scanlen], scanlen, mtd->oobblock, bd)) {
this->bbt[i >> 3] |= 0x03 << (i & 0x6); this->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);
break; break;
} }
@ -369,15 +369,15 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
* @td: descriptor for the bad block table * @td: descriptor for the bad block table
* *
* Read the bad block table by searching for a given ident pattern. * Read the bad block table by searching for a given ident pattern.
* Search is preformed either from the beginning up or from the end of * Search is preformed either from the beginning up or from the end of
* the device downwards. The search starts always at the start of a * the device downwards. The search starts always at the start of a
* block. * block.
* If the option NAND_BBT_PERCHIP is given, each chip is searched * If the option NAND_BBT_PERCHIP is given, each chip is searched
* for a bbt, which contains the bad block information of this chip. * for a bbt, which contains the bad block information of this chip.
* This is neccecary to provide support for certain DOC devices. * This is neccecary to provide support for certain DOC devices.
* *
* The bbt ident pattern resides in the oob area of the first page * The bbt ident pattern resides in the oob area of the first page
* in a block. * in a block.
*/ */
static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td) static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr *td)
{ {
@ -392,10 +392,10 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
startblock = (mtd->size >> this->bbt_erase_shift) -1; startblock = (mtd->size >> this->bbt_erase_shift) -1;
dir = -1; dir = -1;
} else { } else {
startblock = 0; startblock = 0;
dir = 1; dir = 1;
} }
/* Do we have a bbt per chip ? */ /* Do we have a bbt per chip ? */
if (td->options & NAND_BBT_PERCHIP) { if (td->options & NAND_BBT_PERCHIP) {
chips = this->numchips; chips = this->numchips;
@ -405,19 +405,19 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
chips = 1; chips = 1;
bbtblocks = mtd->size >> this->bbt_erase_shift; bbtblocks = mtd->size >> this->bbt_erase_shift;
} }
/* Number of bits for each erase block in the bbt */ /* Number of bits for each erase block in the bbt */
bits = td->options & NAND_BBT_NRBITS_MSK; bits = td->options & NAND_BBT_NRBITS_MSK;
for (i = 0; i < chips; i++) { for (i = 0; i < chips; i++) {
/* Reset version information */ /* Reset version information */
td->version[i] = 0; td->version[i] = 0;
td->pages[i] = -1; td->pages[i] = -1;
/* Scan the maximum number of blocks */ /* Scan the maximum number of blocks */
for (block = 0; block < td->maxblocks; block++) { for (block = 0; block < td->maxblocks; block++) {
int actblock = startblock + dir * block; int actblock = startblock + dir * block;
/* Read first page */ /* Read first page */
nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize); nand_read_raw (mtd, buf, actblock << this->bbt_erase_shift, mtd->oobblock, mtd->oobsize);
if (!check_pattern(buf, scanlen, mtd->oobblock, td)) { if (!check_pattern(buf, scanlen, mtd->oobblock, td)) {
td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift); td->pages[i] = actblock << (this->bbt_erase_shift - this->page_shift);
if (td->options & NAND_BBT_VERSION) { if (td->options & NAND_BBT_VERSION) {
@ -435,46 +435,46 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
else else
printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]); printk (KERN_DEBUG "Bad block table found at page %d, version 0x%02X\n", td->pages[i], td->version[i]);
} }
return 0; return 0;
} }
/** /**
* search_read_bbts - [GENERIC] scan the device for bad block table(s) * search_read_bbts - [GENERIC] scan the device for bad block table(s)
* @mtd: MTD device structure * @mtd: MTD device structure
* @buf: temporary buffer * @buf: temporary buffer
* @td: descriptor for the bad block table * @td: descriptor for the bad block table
* @md: descriptor for the bad block table mirror * @md: descriptor for the bad block table mirror
* *
* Search and read the bad block table(s) * Search and read the bad block table(s)
*/ */
static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf, static int search_read_bbts (struct mtd_info *mtd, uint8_t *buf,
struct nand_bbt_descr *td, struct nand_bbt_descr *md) struct nand_bbt_descr *td, struct nand_bbt_descr *md)
{ {
/* Search the primary table */ /* Search the primary table */
search_bbt (mtd, buf, td); search_bbt (mtd, buf, td);
/* Search the mirror table */ /* Search the mirror table */
if (md) if (md)
search_bbt (mtd, buf, md); search_bbt (mtd, buf, md);
/* Force result check */
return 1;
}
/** /* Force result check */
return 1;
}
/**
* write_bbt - [GENERIC] (Re)write the bad block table * write_bbt - [GENERIC] (Re)write the bad block table
* *
* @mtd: MTD device structure * @mtd: MTD device structure
* @buf: temporary buffer * @buf: temporary buffer
* @td: descriptor for the bad block table * @td: descriptor for the bad block table
* @md: descriptor for the bad block table mirror * @md: descriptor for the bad block table mirror
* @chipsel: selector for a specific chip, -1 for all * @chipsel: selector for a specific chip, -1 for all
* *
* (Re)write the bad block table * (Re)write the bad block table
* *
*/ */
static int write_bbt (struct mtd_info *mtd, uint8_t *buf, static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel) struct nand_bbt_descr *td, struct nand_bbt_descr *md, int chipsel)
{ {
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
@ -493,7 +493,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
/* Write bad block table per chip rather than per device ? */ /* Write bad block table per chip rather than per device ? */
if (td->options & NAND_BBT_PERCHIP) { if (td->options & NAND_BBT_PERCHIP) {
numblocks = (int) (this->chipsize >> this->bbt_erase_shift); numblocks = (int) (this->chipsize >> this->bbt_erase_shift);
/* Full device write or specific chip ? */ /* Full device write or specific chip ? */
if (chipsel == -1) { if (chipsel == -1) {
nrchips = this->numchips; nrchips = this->numchips;
} else { } else {
@ -503,19 +503,19 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
} else { } else {
numblocks = (int) (mtd->size >> this->bbt_erase_shift); numblocks = (int) (mtd->size >> this->bbt_erase_shift);
nrchips = 1; nrchips = 1;
} }
/* Loop through the chips */ /* Loop through the chips */
for (; chip < nrchips; chip++) { for (; chip < nrchips; chip++) {
/* There was already a version of the table, reuse the page /* There was already a version of the table, reuse the page
* This applies for absolute placement too, as we have the * This applies for absolute placement too, as we have the
* page nr. in td->pages. * page nr. in td->pages.
*/ */
if (td->pages[chip] != -1) { if (td->pages[chip] != -1) {
page = td->pages[chip]; page = td->pages[chip];
goto write; goto write;
} }
/* Automatic placement of the bad block table */ /* Automatic placement of the bad block table */
/* Search direction top -> down ? */ /* Search direction top -> down ? */
@ -525,7 +525,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
} else { } else {
startblock = chip * numblocks; startblock = chip * numblocks;
dir = 1; dir = 1;
} }
for (i = 0; i < td->maxblocks; i++) { for (i = 0; i < td->maxblocks; i++) {
int block = startblock + dir * i; int block = startblock + dir * i;
@ -542,7 +542,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
} }
printk (KERN_ERR "No space left to write bad block table\n"); printk (KERN_ERR "No space left to write bad block table\n");
return -ENOSPC; return -ENOSPC;
write: write:
/* Set up shift count and masks for the flash table */ /* Set up shift count and masks for the flash table */
bits = td->options & NAND_BBT_NRBITS_MSK; bits = td->options & NAND_BBT_NRBITS_MSK;
@ -553,14 +553,14 @@ write:
case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break; case 8: sft = 0; sftmsk = 0x00; msk[0] = 0x00; msk[1] = 0x0F; msk[2] = ~rcode; msk[3] = 0xff; break;
default: return -EINVAL; default: return -EINVAL;
} }
bbtoffs = chip * (numblocks >> 2); bbtoffs = chip * (numblocks >> 2);
to = ((loff_t) page) << this->page_shift; to = ((loff_t) page) << this->page_shift;
memcpy (&oobinfo, this->autooob, sizeof(oobinfo)); memcpy (&oobinfo, this->autooob, sizeof(oobinfo));
oobinfo.useecc = MTD_NANDECC_PLACEONLY; oobinfo.useecc = MTD_NANDECC_PLACEONLY;
/* Must we save the block contents ? */ /* Must we save the block contents ? */
if (td->options & NAND_BBT_SAVECONTENT) { if (td->options & NAND_BBT_SAVECONTENT) {
/* Make it block aligned */ /* Make it block aligned */
@ -599,7 +599,7 @@ write:
buf[len + td->veroffs] = td->version[chip]; buf[len + td->veroffs] = td->version[chip];
} }
} }
/* walk through the memory table */ /* walk through the memory table */
for (i = 0; i < numblocks; ) { for (i = 0; i < numblocks; ) {
uint8_t dat; uint8_t dat;
@ -611,7 +611,7 @@ write:
dat >>= 2; dat >>= 2;
} }
} }
memset (&einfo, 0, sizeof (einfo)); memset (&einfo, 0, sizeof (einfo));
einfo.mtd = mtd; einfo.mtd = mtd;
einfo.addr = (unsigned long) to; einfo.addr = (unsigned long) to;
@ -621,18 +621,18 @@ write:
printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res); printk (KERN_WARNING "nand_bbt: Error during block erase: %d\n", res);
return res; return res;
} }
res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo); res = mtd->write_ecc (mtd, to, len, &retlen, buf, &buf[len], &oobinfo);
if (res < 0) { if (res < 0) {
printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res); printk (KERN_WARNING "nand_bbt: Error while writing bad block table %d\n", res);
return res; return res;
} }
printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n", printk (KERN_DEBUG "Bad block table written to 0x%08x, version 0x%02X\n",
(unsigned int) to, td->version[chip]); (unsigned int) to, td->version[chip]);
/* Mark it as used */ /* Mark it as used */
td->pages[chip] = page; td->pages[chip] = page;
} }
return 0; return 0;
} }
@ -641,7 +641,7 @@ write:
* @mtd: MTD device structure * @mtd: MTD device structure
* @bd: descriptor for the good/bad block search pattern * @bd: descriptor for the good/bad block search pattern
* *
* The function creates a memory based bbt by scanning the device * The function creates a memory based bbt by scanning the device
* for manufacturer / software marked good / bad blocks * for manufacturer / software marked good / bad blocks
*/ */
static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd) static inline int nand_memory_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
@ -673,11 +673,11 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
struct nand_bbt_descr *rd, *rd2; struct nand_bbt_descr *rd, *rd2;
/* Do we have a bbt per chip ? */ /* Do we have a bbt per chip ? */
if (td->options & NAND_BBT_PERCHIP) if (td->options & NAND_BBT_PERCHIP)
chips = this->numchips; chips = this->numchips;
else else
chips = 1; chips = 1;
for (i = 0; i < chips; i++) { for (i = 0; i < chips; i++) {
writeops = 0; writeops = 0;
rd = NULL; rd = NULL;
@ -692,7 +692,7 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
} }
if (td->pages[i] == -1) { if (td->pages[i] == -1) {
rd = md; rd = md;
td->version[i] = md->version[i]; td->version[i] = md->version[i];
writeops = 1; writeops = 1;
goto writecheck; goto writecheck;
@ -710,7 +710,7 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
if (!(td->options & NAND_BBT_VERSION)) if (!(td->options & NAND_BBT_VERSION))
rd2 = md; rd2 = md;
goto writecheck; goto writecheck;
} }
if (((int8_t) (td->version[i] - md->version[i])) > 0) { if (((int8_t) (td->version[i] - md->version[i])) > 0) {
rd = td; rd = td;
@ -735,15 +735,15 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
create: create:
/* Create the bad block table by scanning the device ? */ /* Create the bad block table by scanning the device ? */
if (!(td->options & NAND_BBT_CREATE)) if (!(td->options & NAND_BBT_CREATE))
continue; continue;
/* Create the table in memory by scanning the chip(s) */ /* Create the table in memory by scanning the chip(s) */
create_bbt (mtd, buf, bd, chipsel); create_bbt (mtd, buf, bd, chipsel);
td->version[i] = 1; td->version[i] = 1;
if (md) if (md)
md->version[i] = 1; md->version[i] = 1;
writecheck: writecheck:
/* read back first ? */ /* read back first ? */
if (rd) if (rd)
read_abs_bbt (mtd, buf, rd, chipsel); read_abs_bbt (mtd, buf, rd, chipsel);
@ -757,7 +757,7 @@ writecheck:
if (res < 0) if (res < 0)
return res; return res;
} }
/* Write the mirror bad block table to the device ? */ /* Write the mirror bad block table to the device ? */
if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) { if ((writeops & 0x02) && md && (md->options & NAND_BBT_WRITE)) {
res = write_bbt (mtd, buf, md, td, chipsel); res = write_bbt (mtd, buf, md, td, chipsel);
@ -765,11 +765,11 @@ writecheck:
return res; return res;
} }
} }
return 0; return 0;
} }
/** /**
* mark_bbt_regions - [GENERIC] mark the bad block table regions * mark_bbt_regions - [GENERIC] mark the bad block table regions
* @mtd: MTD device structure * @mtd: MTD device structure
* @td: bad block table descriptor * @td: bad block table descriptor
* *
@ -790,14 +790,14 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
} else { } else {
chips = 1; chips = 1;
nrblocks = (int)(mtd->size >> this->bbt_erase_shift); nrblocks = (int)(mtd->size >> this->bbt_erase_shift);
} }
for (i = 0; i < chips; i++) { for (i = 0; i < chips; i++) {
if ((td->options & NAND_BBT_ABSPAGE) || if ((td->options & NAND_BBT_ABSPAGE) ||
!(td->options & NAND_BBT_WRITE)) { !(td->options & NAND_BBT_WRITE)) {
if (td->pages[i] == -1) continue; if (td->pages[i] == -1) continue;
block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift); block = td->pages[i] >> (this->bbt_erase_shift - this->page_shift);
block <<= 1; block <<= 1;
oldval = this->bbt[(block >> 3)]; oldval = this->bbt[(block >> 3)];
newval = oldval | (0x2 << (block & 0x06)); newval = oldval | (0x2 << (block & 0x06));
this->bbt[(block >> 3)] = newval; this->bbt[(block >> 3)] = newval;
@ -808,16 +808,16 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
update = 0; update = 0;
if (td->options & NAND_BBT_LASTBLOCK) if (td->options & NAND_BBT_LASTBLOCK)
block = ((i + 1) * nrblocks) - td->maxblocks; block = ((i + 1) * nrblocks) - td->maxblocks;
else else
block = i * nrblocks; block = i * nrblocks;
block <<= 1; block <<= 1;
for (j = 0; j < td->maxblocks; j++) { for (j = 0; j < td->maxblocks; j++) {
oldval = this->bbt[(block >> 3)]; oldval = this->bbt[(block >> 3)];
newval = oldval | (0x2 << (block & 0x06)); newval = oldval | (0x2 << (block & 0x06));
this->bbt[(block >> 3)] = newval; this->bbt[(block >> 3)] = newval;
if (oldval != newval) update = 1; if (oldval != newval) update = 1;
block += 2; block += 2;
} }
/* If we want reserved blocks to be recorded to flash, and some /* If we want reserved blocks to be recorded to flash, and some
new ones have been marked, then we need to update the stored new ones have been marked, then we need to update the stored
bbts. This should only happen once. */ bbts. This should only happen once. */
@ -831,7 +831,7 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
* @mtd: MTD device structure * @mtd: MTD device structure
* @bd: descriptor for the good/bad block search pattern * @bd: descriptor for the good/bad block search pattern
* *
* The function checks, if a bad block table(s) is/are already * The function checks, if a bad block table(s) is/are already
* available. If not it scans the device for manufacturer * available. If not it scans the device for manufacturer
* 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.
@ -880,30 +880,30 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
this->bbt = NULL; this->bbt = NULL;
return -ENOMEM; return -ENOMEM;
} }
/* Is the bbt at a given page ? */ /* Is the bbt at a given page ? */
if (td->options & NAND_BBT_ABSPAGE) { if (td->options & NAND_BBT_ABSPAGE) {
res = read_abs_bbts (mtd, buf, td, md); res = read_abs_bbts (mtd, buf, td, md);
} else { } else {
/* Search the bad block table using a pattern in oob */ /* Search the bad block table using a pattern in oob */
res = search_read_bbts (mtd, buf, td, md); res = search_read_bbts (mtd, buf, td, md);
} }
if (res) if (res)
res = check_create (mtd, buf, bd); res = check_create (mtd, buf, bd);
/* Prevent the bbt regions from erasing / writing */ /* Prevent the bbt regions from erasing / writing */
mark_bbt_region (mtd, td); mark_bbt_region (mtd, td);
if (md) if (md)
mark_bbt_region (mtd, md); mark_bbt_region (mtd, md);
kfree (buf); kfree (buf);
return res; return res;
} }
/** /**
* nand_update_bbt - [NAND Interface] update bad block table(s) * nand_update_bbt - [NAND Interface] update bad block table(s)
* @mtd: MTD device structure * @mtd: MTD device structure
* @offs: the offset of the newly marked block * @offs: the offset of the newly marked block
* *
@ -930,7 +930,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
printk (KERN_ERR "nand_update_bbt: Out of memory\n"); printk (KERN_ERR "nand_update_bbt: Out of memory\n");
return -ENOMEM; return -ENOMEM;
} }
writeops = md != NULL ? 0x03 : 0x01; writeops = md != NULL ? 0x03 : 0x01;
/* Do we have a bbt per chip ? */ /* Do we have a bbt per chip ? */
@ -944,7 +944,7 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
td->version[chip]++; td->version[chip]++;
if (md) if (md)
md->version[chip]++; md->version[chip]++;
/* Write the bad block table to the device ? */ /* Write the bad block table to the device ? */
if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) { if ((writeops & 0x01) && (td->options & NAND_BBT_WRITE)) {
@ -957,12 +957,12 @@ int nand_update_bbt (struct mtd_info *mtd, loff_t offs)
res = write_bbt (mtd, buf, md, td, chipsel); res = write_bbt (mtd, buf, md, td, chipsel);
} }
out: out:
kfree (buf); kfree (buf);
return res; return res;
} }
/* Define some generic bad / good block scan pattern which are used /* Define some generic bad / good block scan pattern which are used
* while scanning a device for factory marked good / bad blocks. */ * while scanning a device for factory marked good / bad blocks. */
static uint8_t scan_ff_pattern[] = { 0xff, 0xff }; static uint8_t scan_ff_pattern[] = { 0xff, 0xff };
@ -1009,7 +1009,7 @@ static uint8_t bbt_pattern[] = {'B', 'b', 't', '0' };
static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' }; static uint8_t mirror_pattern[] = {'1', 't', 'b', 'B' };
static struct nand_bbt_descr bbt_main_descr = { static struct nand_bbt_descr bbt_main_descr = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
.offs = 8, .offs = 8,
.len = 4, .len = 4,
@ -1019,7 +1019,7 @@ static struct nand_bbt_descr bbt_main_descr = {
}; };
static struct nand_bbt_descr bbt_mirror_descr = { static struct nand_bbt_descr bbt_mirror_descr = {
.options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE .options = NAND_BBT_LASTBLOCK | NAND_BBT_CREATE | NAND_BBT_WRITE
| NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP, | NAND_BBT_2BIT | NAND_BBT_VERSION | NAND_BBT_PERCHIP,
.offs = 8, .offs = 8,
.len = 4, .len = 4,
@ -1029,7 +1029,7 @@ static struct nand_bbt_descr bbt_mirror_descr = {
}; };
/** /**
* nand_default_bbt - [NAND Interface] Select a default bad block table for the device * nand_default_bbt - [NAND Interface] Select a default bad block table for the device
* @mtd: MTD device structure * @mtd: MTD device structure
* *
* This function selects the default bad block table * This function selects the default bad block table
@ -1039,29 +1039,29 @@ static struct nand_bbt_descr bbt_mirror_descr = {
int nand_default_bbt (struct mtd_info *mtd) int nand_default_bbt (struct mtd_info *mtd)
{ {
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
/* Default for AG-AND. We must use a flash based /* Default for AG-AND. We must use a flash based
* bad block table as the devices have factory marked * bad block table as the devices have factory marked
* _good_ blocks. Erasing those blocks leads to loss * _good_ blocks. Erasing those blocks leads to loss
* of the good / bad information, so we _must_ store * of the good / bad information, so we _must_ store
* this information in a good / bad table during * this information in a good / bad table during
* startup * startup
*/ */
if (this->options & NAND_IS_AND) { if (this->options & NAND_IS_AND) {
/* Use the default pattern descriptors */ /* Use the default pattern descriptors */
if (!this->bbt_td) { if (!this->bbt_td) {
this->bbt_td = &bbt_main_descr; this->bbt_td = &bbt_main_descr;
this->bbt_md = &bbt_mirror_descr; this->bbt_md = &bbt_mirror_descr;
} }
this->options |= NAND_USE_FLASH_BBT; this->options |= NAND_USE_FLASH_BBT;
return nand_scan_bbt (mtd, &agand_flashbased); return nand_scan_bbt (mtd, &agand_flashbased);
} }
/* Is a flash based bad block table requested ? */ /* Is a flash based bad block table requested ? */
if (this->options & NAND_USE_FLASH_BBT) { if (this->options & NAND_USE_FLASH_BBT) {
/* Use the default pattern descriptors */ /* Use the default pattern descriptors */
if (!this->bbt_td) { if (!this->bbt_td) {
this->bbt_td = &bbt_main_descr; this->bbt_td = &bbt_main_descr;
this->bbt_md = &bbt_mirror_descr; this->bbt_md = &bbt_mirror_descr;
} }
@ -1081,7 +1081,7 @@ int nand_default_bbt (struct mtd_info *mtd)
} }
/** /**
* nand_isbad_bbt - [NAND Interface] Check if a block is bad * nand_isbad_bbt - [NAND Interface] Check if a block is bad
* @mtd: MTD device structure * @mtd: MTD device structure
* @offs: offset in the device * @offs: offset in the device
* @allowbbt: allow access to bad block table region * @allowbbt: allow access to bad block table region
@ -1092,12 +1092,12 @@ int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt)
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
int block; int block;
uint8_t res; uint8_t res;
/* Get block number * 2 */ /* Get block number * 2 */
block = (int) (offs >> (this->bbt_erase_shift - 1)); block = (int) (offs >> (this->bbt_erase_shift - 1));
res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03; res = (this->bbt[block >> 3] >> (block & 0x06)) & 0x03;
DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n", DEBUG (MTD_DEBUG_LEVEL2, "nand_isbad_bbt(): bbt info for offs 0x%08x: (block %d) 0x%02x\n",
(unsigned int)offs, block >> 1, res); (unsigned int)offs, block >> 1, res);
switch ((int)res) { switch ((int)res) {

View File

@ -7,22 +7,22 @@
* Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com) * Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com)
* Toshiba America Electronics Components, Inc. * Toshiba America Electronics Components, Inc.
* *
* $Id: nand_ecc.c,v 1.14 2004/06/16 15:34:37 gleixner Exp $ * $Id: nand_ecc.c,v 1.15 2005/11/07 11:14:30 gleixner Exp $
* *
* This file is free software; you can redistribute it and/or modify it * This file is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License as published by the * under the terms of the GNU General Public License as published by the
* Free Software Foundation; either version 2 or (at your option) any * Free Software Foundation; either version 2 or (at your option) any
* later version. * later version.
* *
* This file is distributed in the hope that it will be useful, but WITHOUT * This file is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details. * for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this file; if not, write to the Free Software Foundation, Inc., * with this file; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
* *
* As a special exception, if other files instantiate templates or use * As a special exception, if other files instantiate templates or use
* macros or inline functions from these files, or you compile these * macros or inline functions from these files, or you compile these
* files and link them with other works to produce a work based on these * files and link them with other works to produce a work based on these
@ -30,7 +30,7 @@
* covered by the GNU General Public License. However the source code for * covered by the GNU General Public License. However the source code for
* these files must still be made available in accordance with section (3) * these files must still be made available in accordance with section (3)
* of the GNU General Public License. * of the GNU General Public License.
* *
* This exception does not invalidate any other reasons why a work based on * This exception does not invalidate any other reasons why a work based on
* this file might be covered by the GNU General Public License. * this file might be covered by the GNU General Public License.
*/ */
@ -67,7 +67,7 @@ static const u_char nand_ecc_precalc_table[] = {
* nand_trans_result - [GENERIC] create non-inverted ECC * nand_trans_result - [GENERIC] create non-inverted ECC
* @reg2: line parity reg 2 * @reg2: line parity reg 2
* @reg3: line parity reg 3 * @reg3: line parity reg 3
* @ecc_code: ecc * @ecc_code: ecc
* *
* Creates non-inverted ECC code from line parity * Creates non-inverted ECC code from line parity
*/ */
@ -75,11 +75,11 @@ static void nand_trans_result(u_char reg2, u_char reg3,
u_char *ecc_code) u_char *ecc_code)
{ {
u_char a, b, i, tmp1, tmp2; u_char a, b, i, tmp1, tmp2;
/* Initialize variables */ /* Initialize variables */
a = b = 0x80; a = b = 0x80;
tmp1 = tmp2 = 0; tmp1 = tmp2 = 0;
/* Calculate first ECC byte */ /* Calculate first ECC byte */
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */ if (reg3 & a) /* LP15,13,11,9 --> ecc_code[0] */
@ -90,7 +90,7 @@ static void nand_trans_result(u_char reg2, u_char reg3,
b >>= 1; b >>= 1;
a >>= 1; a >>= 1;
} }
/* Calculate second ECC byte */ /* Calculate second ECC byte */
b = 0x80; b = 0x80;
for (i = 0; i < 4; i++) { for (i = 0; i < 4; i++) {
@ -102,7 +102,7 @@ static void nand_trans_result(u_char reg2, u_char reg3,
b >>= 1; b >>= 1;
a >>= 1; a >>= 1;
} }
/* Store two of the ECC bytes */ /* Store two of the ECC bytes */
ecc_code[0] = tmp1; ecc_code[0] = tmp1;
ecc_code[1] = tmp2; ecc_code[1] = tmp2;
@ -118,28 +118,28 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
{ {
u_char idx, reg1, reg2, reg3; u_char idx, reg1, reg2, reg3;
int j; int j;
/* Initialize variables */ /* Initialize variables */
reg1 = reg2 = reg3 = 0; reg1 = reg2 = reg3 = 0;
ecc_code[0] = ecc_code[1] = ecc_code[2] = 0; ecc_code[0] = ecc_code[1] = ecc_code[2] = 0;
/* Build up column parity */ /* Build up column parity */
for(j = 0; j < 256; j++) { for(j = 0; j < 256; j++) {
/* Get CP0 - CP5 from table */ /* Get CP0 - CP5 from table */
idx = nand_ecc_precalc_table[dat[j]]; idx = nand_ecc_precalc_table[dat[j]];
reg1 ^= (idx & 0x3f); reg1 ^= (idx & 0x3f);
/* All bit XOR = 1 ? */ /* All bit XOR = 1 ? */
if (idx & 0x40) { if (idx & 0x40) {
reg3 ^= (u_char) j; reg3 ^= (u_char) j;
reg2 ^= ~((u_char) j); reg2 ^= ~((u_char) j);
} }
} }
/* Create non-inverted ECC code from line parity */ /* Create non-inverted ECC code from line parity */
nand_trans_result(reg2, reg3, ecc_code); nand_trans_result(reg2, reg3, ecc_code);
/* Calculate final ECC code */ /* Calculate final ECC code */
ecc_code[0] = ~ecc_code[0]; ecc_code[0] = ~ecc_code[0];
ecc_code[1] = ~ecc_code[1]; ecc_code[1] = ~ecc_code[1];
@ -159,12 +159,12 @@ int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code
int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc) int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc)
{ {
u_char a, b, c, d1, d2, d3, add, bit, i; u_char a, b, c, d1, d2, d3, add, bit, i;
/* Do error detection */ /* Do error detection */
d1 = calc_ecc[0] ^ read_ecc[0]; d1 = calc_ecc[0] ^ read_ecc[0];
d2 = calc_ecc[1] ^ read_ecc[1]; d2 = calc_ecc[1] ^ read_ecc[1];
d3 = calc_ecc[2] ^ read_ecc[2]; d3 = calc_ecc[2] ^ read_ecc[2];
if ((d1 | d2 | d3) == 0) { if ((d1 | d2 | d3) == 0) {
/* No errors */ /* No errors */
return 0; return 0;
@ -173,7 +173,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
a = (d1 ^ (d1 >> 1)) & 0x55; a = (d1 ^ (d1 >> 1)) & 0x55;
b = (d2 ^ (d2 >> 1)) & 0x55; b = (d2 ^ (d2 >> 1)) & 0x55;
c = (d3 ^ (d3 >> 1)) & 0x54; c = (d3 ^ (d3 >> 1)) & 0x54;
/* Found and will correct single bit error in the data */ /* Found and will correct single bit error in the data */
if ((a == 0x55) && (b == 0x55) && (c == 0x54)) { if ((a == 0x55) && (b == 0x55) && (c == 0x54)) {
c = 0x80; c = 0x80;
@ -237,7 +237,7 @@ int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_cha
} }
} }
} }
/* Should never happen */ /* Should never happen */
return -1; return -1;
} }

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de) * Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de)
* *
* $Id: nand_ids.c,v 1.14 2005/06/23 09:38:50 gleixner Exp $ * $Id: nand_ids.c,v 1.16 2005/11/07 11:14:31 gleixner Exp $
* *
* 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
@ -14,14 +14,14 @@
#include <linux/mtd/nand.h> #include <linux/mtd/nand.h>
/* /*
* Chip ID list * Chip ID list
* *
* Name. ID code, pagesize, chipsize in MegaByte, eraseblock size, * Name. ID code, pagesize, chipsize in MegaByte, eraseblock size,
* options * options
* *
* Pagesize; 0, 256, 512 * Pagesize; 0, 256, 512
* 0 get this information from the extended chip ID * 0 get this information from the extended chip ID
+ 256 256 Byte page size + 256 256 Byte page size
* 512 512 Byte page size * 512 512 Byte page size
*/ */
struct nand_flash_dev nand_flash_ids[] = { struct nand_flash_dev nand_flash_ids[] = {
{"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0}, {"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0},
@ -34,27 +34,27 @@ struct nand_flash_dev nand_flash_ids[] = {
{"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0}, {"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0},
{"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0}, {"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0},
{"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0}, {"NAND 8MiB 3,3V 8-bit", 0xd6, 512, 8, 0x2000, 0},
{"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0}, {"NAND 8MiB 1,8V 8-bit", 0x39, 512, 8, 0x2000, 0},
{"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0}, {"NAND 8MiB 3,3V 8-bit", 0xe6, 512, 8, 0x2000, 0},
{"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16}, {"NAND 8MiB 1,8V 16-bit", 0x49, 512, 8, 0x2000, NAND_BUSWIDTH_16},
{"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16}, {"NAND 8MiB 3,3V 16-bit", 0x59, 512, 8, 0x2000, NAND_BUSWIDTH_16},
{"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0}, {"NAND 16MiB 1,8V 8-bit", 0x33, 512, 16, 0x4000, 0},
{"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0}, {"NAND 16MiB 3,3V 8-bit", 0x73, 512, 16, 0x4000, 0},
{"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16}, {"NAND 16MiB 1,8V 16-bit", 0x43, 512, 16, 0x4000, NAND_BUSWIDTH_16},
{"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16}, {"NAND 16MiB 3,3V 16-bit", 0x53, 512, 16, 0x4000, NAND_BUSWIDTH_16},
{"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0}, {"NAND 32MiB 1,8V 8-bit", 0x35, 512, 32, 0x4000, 0},
{"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0}, {"NAND 32MiB 3,3V 8-bit", 0x75, 512, 32, 0x4000, 0},
{"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16}, {"NAND 32MiB 1,8V 16-bit", 0x45, 512, 32, 0x4000, NAND_BUSWIDTH_16},
{"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16}, {"NAND 32MiB 3,3V 16-bit", 0x55, 512, 32, 0x4000, NAND_BUSWIDTH_16},
{"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0}, {"NAND 64MiB 1,8V 8-bit", 0x36, 512, 64, 0x4000, 0},
{"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0}, {"NAND 64MiB 3,3V 8-bit", 0x76, 512, 64, 0x4000, 0},
{"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16}, {"NAND 64MiB 1,8V 16-bit", 0x46, 512, 64, 0x4000, NAND_BUSWIDTH_16},
{"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16}, {"NAND 64MiB 3,3V 16-bit", 0x56, 512, 64, 0x4000, NAND_BUSWIDTH_16},
{"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0}, {"NAND 128MiB 1,8V 8-bit", 0x78, 512, 128, 0x4000, 0},
{"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0}, {"NAND 128MiB 1,8V 8-bit", 0x39, 512, 128, 0x4000, 0},
{"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0}, {"NAND 128MiB 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0},
@ -62,7 +62,7 @@ struct nand_flash_dev nand_flash_ids[] = {
{"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16}, {"NAND 128MiB 1,8V 16-bit", 0x49, 512, 128, 0x4000, NAND_BUSWIDTH_16},
{"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16}, {"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16},
{"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16}, {"NAND 128MiB 3,3V 16-bit", 0x59, 512, 128, 0x4000, NAND_BUSWIDTH_16},
{"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0}, {"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0},
/* These are the new chips with large page size. The pagesize /* These are the new chips with large page size. The pagesize
@ -73,7 +73,7 @@ struct nand_flash_dev nand_flash_ids[] = {
{"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, {"NAND 64MiB 3,3V 8-bit", 0xF2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
{"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, {"NAND 64MiB 1,8V 16-bit", 0xB2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
{"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, {"NAND 64MiB 3,3V 16-bit", 0xC2, 0, 64, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
/* 1 Gigabit */ /* 1 Gigabit */
{"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, {"NAND 128MiB 1,8V 8-bit", 0xA1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
{"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, {"NAND 128MiB 3,3V 8-bit", 0xF1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
@ -85,13 +85,13 @@ struct nand_flash_dev nand_flash_ids[] = {
{"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, {"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
{"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, {"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
{"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, {"NAND 256MiB 3,3V 16-bit", 0xCA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
/* 4 Gigabit */ /* 4 Gigabit */
{"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, {"NAND 512MiB 1,8V 8-bit", 0xAC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
{"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, {"NAND 512MiB 3,3V 8-bit", 0xDC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
{"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, {"NAND 512MiB 1,8V 16-bit", 0xBC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
{"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, {"NAND 512MiB 3,3V 16-bit", 0xCC, 0, 512, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
/* 8 Gigabit */ /* 8 Gigabit */
{"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, {"NAND 1GiB 1,8V 8-bit", 0xA3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
{"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, {"NAND 1GiB 3,3V 8-bit", 0xD3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR},
@ -104,11 +104,11 @@ struct nand_flash_dev nand_flash_ids[] = {
{"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, {"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
{"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, {"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR},
/* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout ! /* Renesas AND 1 Gigabit. Those chips do not support extended id and have a strange page/block layout !
* The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes * The chosen minimum erasesize is 4 * 2 * 2048 = 16384 Byte, as those chips have an array of 4 page planes
* 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7 * 1 block = 2 pages, but due to plane arrangement the blocks 0-3 consists of page 0 + 4,1 + 5, 2 + 6, 3 + 7
* Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go * Anyway JFFS2 would increase the eraseblock size so we chose a combined one which can be erased in one go
* There are more speed improvements for reads and writes possible, but not implemented now * There are more speed improvements for reads and writes possible, but not implemented now
*/ */
{"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH}, {"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY | BBT_AUTO_REFRESH},

View File

@ -3,7 +3,7 @@
* *
* Author: Artem B. Bityuckiy <dedekind@oktetlabs.ru>, <dedekind@infradead.org> * Author: Artem B. Bityuckiy <dedekind@oktetlabs.ru>, <dedekind@infradead.org>
* *
* Copyright (C) 2004 Nokia Corporation * Copyright (C) 2004 Nokia Corporation
* *
* Note: NS means "NAND Simulator". * Note: NS means "NAND Simulator".
* Note: Input means input TO flash chip, output means output FROM chip. * Note: Input means input TO flash chip, output means output FROM chip.
@ -126,7 +126,7 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
/* The largest possible page size */ /* The largest possible page size */
#define NS_LARGEST_PAGE_SIZE 2048 #define NS_LARGEST_PAGE_SIZE 2048
/* The prefix for simulator output */ /* The prefix for simulator output */
#define NS_OUTPUT_PREFIX "[nandsim]" #define NS_OUTPUT_PREFIX "[nandsim]"
@ -145,7 +145,7 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
do { if (do_delays) udelay(us); } while(0) do { if (do_delays) udelay(us); } while(0)
#define NS_MDELAY(us) \ #define NS_MDELAY(us) \
do { if (do_delays) mdelay(us); } while(0) do { if (do_delays) mdelay(us); } while(0)
/* Is the nandsim structure initialized ? */ /* Is the nandsim structure initialized ? */
#define NS_IS_INITIALIZED(ns) ((ns)->geom.totsz != 0) #define NS_IS_INITIALIZED(ns) ((ns)->geom.totsz != 0)
@ -153,12 +153,12 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
#define NS_STATUS_OK(ns) (NAND_STATUS_READY | (NAND_STATUS_WP * ((ns)->lines.wp == 0))) #define NS_STATUS_OK(ns) (NAND_STATUS_READY | (NAND_STATUS_WP * ((ns)->lines.wp == 0)))
/* Operation failed completion status */ /* Operation failed completion status */
#define NS_STATUS_FAILED(ns) (NAND_STATUS_FAIL | NS_STATUS_OK(ns)) #define NS_STATUS_FAILED(ns) (NAND_STATUS_FAIL | NS_STATUS_OK(ns))
/* Calculate the page offset in flash RAM image by (row, column) address */ /* Calculate the page offset in flash RAM image by (row, column) address */
#define NS_RAW_OFFSET(ns) \ #define NS_RAW_OFFSET(ns) \
(((ns)->regs.row << (ns)->geom.pgshift) + ((ns)->regs.row * (ns)->geom.oobsz) + (ns)->regs.column) (((ns)->regs.row << (ns)->geom.pgshift) + ((ns)->regs.row * (ns)->geom.oobsz) + (ns)->regs.column)
/* Calculate the OOB offset in flash RAM image by (row, column) address */ /* Calculate the OOB offset in flash RAM image by (row, column) address */
#define NS_RAW_OFFSET_OOB(ns) (NS_RAW_OFFSET(ns) + ns->geom.pgsz) #define NS_RAW_OFFSET_OOB(ns) (NS_RAW_OFFSET(ns) + ns->geom.pgsz)
@ -223,15 +223,15 @@ MODULE_PARM_DESC(dbg, "Output debug information if not zero");
/* Remove action bits ftom state */ /* Remove action bits ftom state */
#define NS_STATE(x) ((x) & ~ACTION_MASK) #define NS_STATE(x) ((x) & ~ACTION_MASK)
/* /*
* Maximum previous states which need to be saved. Currently saving is * Maximum previous states which need to be saved. Currently saving is
* only needed for page programm operation with preceeded read command * only needed for page programm operation with preceeded read command
* (which is only valid for 512-byte pages). * (which is only valid for 512-byte pages).
*/ */
#define NS_MAX_PREVSTATES 1 #define NS_MAX_PREVSTATES 1
/* /*
* The structure which describes all the internal simulator data. * The structure which describes all the internal simulator data.
*/ */
struct nandsim { struct nandsim {
@ -242,7 +242,7 @@ struct nandsim {
uint32_t options; /* chip's characteristic bits */ uint32_t options; /* chip's characteristic bits */
uint32_t state; /* current chip state */ uint32_t state; /* current chip state */
uint32_t nxstate; /* next expected state */ uint32_t nxstate; /* next expected state */
uint32_t *op; /* current operation, NULL operations isn't known yet */ uint32_t *op; /* current operation, NULL operations isn't known yet */
uint32_t pstates[NS_MAX_PREVSTATES]; /* previous states */ uint32_t pstates[NS_MAX_PREVSTATES]; /* previous states */
uint16_t npstates; /* number of previous states saved */ uint16_t npstates; /* number of previous states saved */
@ -413,7 +413,7 @@ init_nandsim(struct mtd_info *mtd)
ns->geom.secaddrbytes = 3; ns->geom.secaddrbytes = 3;
} }
} }
/* Detect how many ID bytes the NAND chip outputs */ /* Detect how many ID bytes the NAND chip outputs */
for (i = 0; nand_flash_ids[i].name != NULL; i++) { for (i = 0; nand_flash_ids[i].name != NULL; i++) {
if (second_id_byte != nand_flash_ids[i].id) if (second_id_byte != nand_flash_ids[i].id)
@ -444,7 +444,7 @@ init_nandsim(struct mtd_info *mtd)
#ifdef CONFIG_NS_ABS_POS #ifdef CONFIG_NS_ABS_POS
ns->mem.byte = ioremap(CONFIG_NS_ABS_POS, ns->geom.totszoob); ns->mem.byte = ioremap(CONFIG_NS_ABS_POS, ns->geom.totszoob);
if (!ns->mem.byte) { if (!ns->mem.byte) {
NS_ERR("init_nandsim: failed to map the NAND flash image at address %p\n", NS_ERR("init_nandsim: failed to map the NAND flash image at address %p\n",
(void *)CONFIG_NS_ABS_POS); (void *)CONFIG_NS_ABS_POS);
return -ENOMEM; return -ENOMEM;
} }
@ -567,7 +567,7 @@ static int
check_command(int cmd) check_command(int cmd)
{ {
switch (cmd) { switch (cmd) {
case NAND_CMD_READ0: case NAND_CMD_READ0:
case NAND_CMD_READSTART: case NAND_CMD_READSTART:
case NAND_CMD_PAGEPROG: case NAND_CMD_PAGEPROG:
@ -580,7 +580,7 @@ check_command(int cmd)
case NAND_CMD_RESET: case NAND_CMD_RESET:
case NAND_CMD_READ1: case NAND_CMD_READ1:
return 0; return 0;
case NAND_CMD_STATUS_MULTI: case NAND_CMD_STATUS_MULTI:
default: default:
return 1; return 1;
@ -631,7 +631,7 @@ static inline void
accept_addr_byte(struct nandsim *ns, u_char bt) accept_addr_byte(struct nandsim *ns, u_char bt)
{ {
uint byte = (uint)bt; uint byte = (uint)bt;
if (ns->regs.count < (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) if (ns->regs.count < (ns->geom.pgaddrbytes - ns->geom.secaddrbytes))
ns->regs.column |= (byte << 8 * ns->regs.count); ns->regs.column |= (byte << 8 * ns->regs.count);
else { else {
@ -642,11 +642,11 @@ accept_addr_byte(struct nandsim *ns, u_char bt)
return; return;
} }
/* /*
* Switch to STATE_READY state. * Switch to STATE_READY state.
*/ */
static inline void static inline void
switch_to_ready_state(struct nandsim *ns, u_char status) switch_to_ready_state(struct nandsim *ns, u_char status)
{ {
NS_DBG("switch_to_ready_state: switch to %s state\n", get_state_name(STATE_READY)); NS_DBG("switch_to_ready_state: switch to %s state\n", get_state_name(STATE_READY));
@ -675,7 +675,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status)
* (for example program from the second half and read from the * (for example program from the second half and read from the
* second half operations both begin with the READ1 command). In this * second half operations both begin with the READ1 command). In this
* case the ns->pstates[] array contains previous states. * case the ns->pstates[] array contains previous states.
* *
* Thus, the function tries to find operation containing the following * Thus, the function tries to find operation containing the following
* states (if the 'flag' parameter is 0): * states (if the 'flag' parameter is 0):
* ns->pstates[0], ... ns->pstates[ns->npstates], ns->state * ns->pstates[0], ... ns->pstates[ns->npstates], ns->state
@ -683,7 +683,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status)
* If (one and only one) matching operation is found, it is accepted ( * If (one and only one) matching operation is found, it is accepted (
* ns->ops, ns->state, ns->nxstate are initialized, ns->npstate is * ns->ops, ns->state, ns->nxstate are initialized, ns->npstate is
* zeroed). * zeroed).
* *
* If there are several maches, the current state is pushed to the * If there are several maches, the current state is pushed to the
* ns->pstates. * ns->pstates.
* *
@ -692,7 +692,7 @@ switch_to_ready_state(struct nandsim *ns, u_char status)
* In such situation the function is called with 'flag' != 0, and the * In such situation the function is called with 'flag' != 0, and the
* operation is searched using the following pattern: * operation is searched using the following pattern:
* ns->pstates[0], ... ns->pstates[ns->npstates], <address input> * ns->pstates[0], ... ns->pstates[ns->npstates], <address input>
* *
* It is supposed that this pattern must either match one operation on * It is supposed that this pattern must either match one operation on
* none. There can't be ambiguity in that case. * none. There can't be ambiguity in that case.
* *
@ -711,15 +711,15 @@ find_operation(struct nandsim *ns, uint32_t flag)
{ {
int opsfound = 0; int opsfound = 0;
int i, j, idx = 0; int i, j, idx = 0;
for (i = 0; i < NS_OPER_NUM; i++) { for (i = 0; i < NS_OPER_NUM; i++) {
int found = 1; int found = 1;
if (!(ns->options & ops[i].reqopts)) if (!(ns->options & ops[i].reqopts))
/* Ignore operations we can't perform */ /* Ignore operations we can't perform */
continue; continue;
if (flag) { if (flag) {
if (!(ops[i].states[ns->npstates] & STATE_ADDR_MASK)) if (!(ops[i].states[ns->npstates] & STATE_ADDR_MASK))
continue; continue;
@ -728,7 +728,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
continue; continue;
} }
for (j = 0; j < ns->npstates; j++) for (j = 0; j < ns->npstates; j++)
if (NS_STATE(ops[i].states[j]) != NS_STATE(ns->pstates[j]) if (NS_STATE(ops[i].states[j]) != NS_STATE(ns->pstates[j])
&& (ns->options & ops[idx].reqopts)) { && (ns->options & ops[idx].reqopts)) {
found = 0; found = 0;
@ -745,7 +745,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
/* Exact match */ /* Exact match */
ns->op = &ops[idx].states[0]; ns->op = &ops[idx].states[0];
if (flag) { if (flag) {
/* /*
* In this case the find_operation function was * In this case the find_operation function was
* called when address has just began input. But it isn't * called when address has just began input. But it isn't
* yet fully input and the current state must * yet fully input and the current state must
@ -763,7 +763,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
idx, get_state_name(ns->state), get_state_name(ns->nxstate)); idx, get_state_name(ns->state), get_state_name(ns->nxstate));
return 0; return 0;
} }
if (opsfound == 0) { if (opsfound == 0) {
/* Nothing was found. Try to ignore previous commands (if any) and search again */ /* Nothing was found. Try to ignore previous commands (if any) and search again */
if (ns->npstates != 0) { if (ns->npstates != 0) {
@ -777,13 +777,13 @@ find_operation(struct nandsim *ns, uint32_t flag)
switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
return -2; return -2;
} }
if (flag) { if (flag) {
/* This shouldn't happen */ /* This shouldn't happen */
NS_DBG("find_operation: BUG, operation must be known if address is input\n"); NS_DBG("find_operation: BUG, operation must be known if address is input\n");
return -2; return -2;
} }
NS_DBG("find_operation: there is still ambiguity\n"); NS_DBG("find_operation: there is still ambiguity\n");
ns->pstates[ns->npstates++] = ns->state; ns->pstates[ns->npstates++] = ns->state;
@ -803,7 +803,7 @@ do_state_action(struct nandsim *ns, uint32_t action)
int busdiv = ns->busw == 8 ? 1 : 2; int busdiv = ns->busw == 8 ? 1 : 2;
action &= ACTION_MASK; action &= ACTION_MASK;
/* Check that page address input is correct */ /* Check that page address input is correct */
if (action != ACTION_SECERASE && ns->regs.row >= ns->geom.pgnum) { if (action != ACTION_SECERASE && ns->regs.row >= ns->geom.pgnum) {
NS_WARN("do_state_action: wrong page number (%#x)\n", ns->regs.row); NS_WARN("do_state_action: wrong page number (%#x)\n", ns->regs.row);
@ -827,14 +827,14 @@ do_state_action(struct nandsim *ns, uint32_t action)
NS_DBG("do_state_action: (ACTION_CPY:) copy %d bytes to int buf, raw offset %d\n", NS_DBG("do_state_action: (ACTION_CPY:) copy %d bytes to int buf, raw offset %d\n",
num, NS_RAW_OFFSET(ns) + ns->regs.off); num, NS_RAW_OFFSET(ns) + ns->regs.off);
if (ns->regs.off == 0) if (ns->regs.off == 0)
NS_LOG("read page %d\n", ns->regs.row); NS_LOG("read page %d\n", ns->regs.row);
else if (ns->regs.off < ns->geom.pgsz) else if (ns->regs.off < ns->geom.pgsz)
NS_LOG("read page %d (second half)\n", ns->regs.row); NS_LOG("read page %d (second half)\n", ns->regs.row);
else else
NS_LOG("read OOB of page %d\n", ns->regs.row); NS_LOG("read OOB of page %d\n", ns->regs.row);
NS_UDELAY(access_delay); NS_UDELAY(access_delay);
NS_UDELAY(input_cycle * ns->geom.pgsz / 1000 / busdiv); NS_UDELAY(input_cycle * ns->geom.pgsz / 1000 / busdiv);
@ -844,30 +844,30 @@ do_state_action(struct nandsim *ns, uint32_t action)
/* /*
* Erase sector. * Erase sector.
*/ */
if (ns->lines.wp) { if (ns->lines.wp) {
NS_ERR("do_state_action: device is write-protected, ignore sector erase\n"); NS_ERR("do_state_action: device is write-protected, ignore sector erase\n");
return -1; return -1;
} }
if (ns->regs.row >= ns->geom.pgnum - ns->geom.pgsec if (ns->regs.row >= ns->geom.pgnum - ns->geom.pgsec
|| (ns->regs.row & ~(ns->geom.secsz - 1))) { || (ns->regs.row & ~(ns->geom.secsz - 1))) {
NS_ERR("do_state_action: wrong sector address (%#x)\n", ns->regs.row); NS_ERR("do_state_action: wrong sector address (%#x)\n", ns->regs.row);
return -1; return -1;
} }
ns->regs.row = (ns->regs.row << ns->regs.row = (ns->regs.row <<
8 * (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) | ns->regs.column; 8 * (ns->geom.pgaddrbytes - ns->geom.secaddrbytes)) | ns->regs.column;
ns->regs.column = 0; ns->regs.column = 0;
NS_DBG("do_state_action: erase sector at address %#x, off = %d\n", NS_DBG("do_state_action: erase sector at address %#x, off = %d\n",
ns->regs.row, NS_RAW_OFFSET(ns)); ns->regs.row, NS_RAW_OFFSET(ns));
NS_LOG("erase sector %d\n", ns->regs.row >> (ns->geom.secshift - ns->geom.pgshift)); NS_LOG("erase sector %d\n", ns->regs.row >> (ns->geom.secshift - ns->geom.pgshift));
memset(ns->mem.byte + NS_RAW_OFFSET(ns), 0xFF, ns->geom.secszoob); memset(ns->mem.byte + NS_RAW_OFFSET(ns), 0xFF, ns->geom.secszoob);
NS_MDELAY(erase_delay); NS_MDELAY(erase_delay);
break; break;
case ACTION_PRGPAGE: case ACTION_PRGPAGE:
@ -893,12 +893,12 @@ do_state_action(struct nandsim *ns, uint32_t action)
NS_DBG("do_state_action: copy %d bytes from int buf to (%#x, %#x), raw off = %d\n", NS_DBG("do_state_action: copy %d bytes from int buf to (%#x, %#x), raw off = %d\n",
num, ns->regs.row, ns->regs.column, NS_RAW_OFFSET(ns) + ns->regs.off); num, ns->regs.row, ns->regs.column, NS_RAW_OFFSET(ns) + ns->regs.off);
NS_LOG("programm page %d\n", ns->regs.row); NS_LOG("programm page %d\n", ns->regs.row);
NS_UDELAY(programm_delay); NS_UDELAY(programm_delay);
NS_UDELAY(output_cycle * ns->geom.pgsz / 1000 / busdiv); NS_UDELAY(output_cycle * ns->geom.pgsz / 1000 / busdiv);
break; break;
case ACTION_ZEROOFF: case ACTION_ZEROOFF:
NS_DBG("do_state_action: set internal offset to 0\n"); NS_DBG("do_state_action: set internal offset to 0\n");
ns->regs.off = 0; ns->regs.off = 0;
@ -918,7 +918,7 @@ do_state_action(struct nandsim *ns, uint32_t action)
NS_DBG("do_state_action: set internal offset to %d\n", ns->geom.pgsz); NS_DBG("do_state_action: set internal offset to %d\n", ns->geom.pgsz);
ns->regs.off = ns->geom.pgsz; ns->regs.off = ns->geom.pgsz;
break; break;
default: default:
NS_DBG("do_state_action: BUG! unknown action\n"); NS_DBG("do_state_action: BUG! unknown action\n");
} }
@ -937,7 +937,7 @@ switch_state(struct nandsim *ns)
* The current operation have already been identified. * The current operation have already been identified.
* Just follow the states chain. * Just follow the states chain.
*/ */
ns->stateidx += 1; ns->stateidx += 1;
ns->state = ns->nxstate; ns->state = ns->nxstate;
ns->nxstate = ns->op[ns->stateidx + 1]; ns->nxstate = ns->op[ns->stateidx + 1];
@ -951,14 +951,14 @@ switch_state(struct nandsim *ns)
switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
return; return;
} }
} else { } else {
/* /*
* We don't yet know which operation we perform. * We don't yet know which operation we perform.
* Try to identify it. * Try to identify it.
*/ */
/* /*
* The only event causing the switch_state function to * The only event causing the switch_state function to
* be called with yet unknown operation is new command. * be called with yet unknown operation is new command.
*/ */
@ -987,7 +987,7 @@ switch_state(struct nandsim *ns)
*/ */
u_char status = NS_STATUS_OK(ns); u_char status = NS_STATUS_OK(ns);
/* In case of data states, see if all bytes were input/output */ /* In case of data states, see if all bytes were input/output */
if ((ns->state & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) if ((ns->state & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK))
&& ns->regs.count != ns->regs.num) { && ns->regs.count != ns->regs.num) {
@ -995,17 +995,17 @@ switch_state(struct nandsim *ns)
ns->regs.num - ns->regs.count); ns->regs.num - ns->regs.count);
status = NS_STATUS_FAILED(ns); status = NS_STATUS_FAILED(ns);
} }
NS_DBG("switch_state: operation complete, switch to STATE_READY state\n"); NS_DBG("switch_state: operation complete, switch to STATE_READY state\n");
switch_to_ready_state(ns, status); switch_to_ready_state(ns, status);
return; return;
} else if (ns->nxstate & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) { } else if (ns->nxstate & (STATE_DATAIN_MASK | STATE_DATAOUT_MASK)) {
/* /*
* If the next state is data input/output, switch to it now * If the next state is data input/output, switch to it now
*/ */
ns->state = ns->nxstate; ns->state = ns->nxstate;
ns->nxstate = ns->op[++ns->stateidx + 1]; ns->nxstate = ns->op[++ns->stateidx + 1];
ns->regs.num = ns->regs.count = 0; ns->regs.num = ns->regs.count = 0;
@ -1023,16 +1023,16 @@ switch_state(struct nandsim *ns)
case STATE_DATAOUT: case STATE_DATAOUT:
ns->regs.num = ns->geom.pgszoob - ns->regs.off - ns->regs.column; ns->regs.num = ns->geom.pgszoob - ns->regs.off - ns->regs.column;
break; break;
case STATE_DATAOUT_ID: case STATE_DATAOUT_ID:
ns->regs.num = ns->geom.idbytes; ns->regs.num = ns->geom.idbytes;
break; break;
case STATE_DATAOUT_STATUS: case STATE_DATAOUT_STATUS:
case STATE_DATAOUT_STATUS_M: case STATE_DATAOUT_STATUS_M:
ns->regs.count = ns->regs.num = 0; ns->regs.count = ns->regs.num = 0;
break; break;
default: default:
NS_ERR("switch_state: BUG! unknown data state\n"); NS_ERR("switch_state: BUG! unknown data state\n");
} }
@ -1044,16 +1044,16 @@ switch_state(struct nandsim *ns)
*/ */
ns->regs.count = 0; ns->regs.count = 0;
switch (NS_STATE(ns->nxstate)) { switch (NS_STATE(ns->nxstate)) {
case STATE_ADDR_PAGE: case STATE_ADDR_PAGE:
ns->regs.num = ns->geom.pgaddrbytes; ns->regs.num = ns->geom.pgaddrbytes;
break; break;
case STATE_ADDR_SEC: case STATE_ADDR_SEC:
ns->regs.num = ns->geom.secaddrbytes; ns->regs.num = ns->geom.secaddrbytes;
break; break;
case STATE_ADDR_ZERO: case STATE_ADDR_ZERO:
ns->regs.num = 1; ns->regs.num = 1;
break; break;
@ -1062,7 +1062,7 @@ switch_state(struct nandsim *ns)
NS_ERR("switch_state: BUG! unknown address state\n"); NS_ERR("switch_state: BUG! unknown address state\n");
} }
} else { } else {
/* /*
* Just reset internal counters. * Just reset internal counters.
*/ */
@ -1184,7 +1184,7 @@ ns_nand_read_byte(struct mtd_info *mtd)
default: default:
BUG(); BUG();
} }
if (ns->regs.count == ns->regs.num) { if (ns->regs.count == ns->regs.num) {
NS_DBG("read_byte: all bytes were read\n"); NS_DBG("read_byte: all bytes were read\n");
@ -1201,9 +1201,9 @@ ns_nand_read_byte(struct mtd_info *mtd)
} }
else if (NS_STATE(ns->nxstate) == STATE_READY) else if (NS_STATE(ns->nxstate) == STATE_READY)
switch_state(ns); switch_state(ns);
} }
return outb; return outb;
} }
@ -1211,7 +1211,7 @@ static void
ns_nand_write_byte(struct mtd_info *mtd, u_char byte) ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
{ {
struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
/* Sanity and correctness checks */ /* Sanity and correctness checks */
if (!ns->lines.ce) { if (!ns->lines.ce) {
NS_ERR("write_byte: chip is disabled, ignore write\n"); NS_ERR("write_byte: chip is disabled, ignore write\n");
@ -1221,7 +1221,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
NS_ERR("write_byte: ALE and CLE pins are high simultaneously, ignore write\n"); NS_ERR("write_byte: ALE and CLE pins are high simultaneously, ignore write\n");
return; return;
} }
if (ns->lines.cle == 1) { if (ns->lines.cle == 1) {
/* /*
* The byte written is a command. * The byte written is a command.
@ -1233,7 +1233,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
return; return;
} }
/* /*
* Chip might still be in STATE_DATAOUT * Chip might still be in STATE_DATAOUT
* (if OPT_AUTOINCR feature is supported), STATE_DATAOUT_STATUS or * (if OPT_AUTOINCR feature is supported), STATE_DATAOUT_STATUS or
* STATE_DATAOUT_STATUS_M state. If so, switch state. * STATE_DATAOUT_STATUS_M state. If so, switch state.
@ -1254,13 +1254,13 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
"ignore previous states\n", (uint)byte, get_state_name(ns->nxstate)); "ignore previous states\n", (uint)byte, get_state_name(ns->nxstate));
switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
} }
/* Check that the command byte is correct */ /* Check that the command byte is correct */
if (check_command(byte)) { if (check_command(byte)) {
NS_ERR("write_byte: unknown command %#x\n", (uint)byte); NS_ERR("write_byte: unknown command %#x\n", (uint)byte);
return; return;
} }
NS_DBG("command byte corresponding to %s state accepted\n", NS_DBG("command byte corresponding to %s state accepted\n",
get_state_name(get_state_by_command(byte))); get_state_name(get_state_by_command(byte)));
ns->regs.command = byte; ns->regs.command = byte;
@ -1277,12 +1277,12 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
if (find_operation(ns, 1) < 0) if (find_operation(ns, 1) < 0)
return; return;
if ((ns->state & ACTION_MASK) && do_state_action(ns, ns->state) < 0) { if ((ns->state & ACTION_MASK) && do_state_action(ns, ns->state) < 0) {
switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
return; return;
} }
ns->regs.count = 0; ns->regs.count = 0;
switch (NS_STATE(ns->nxstate)) { switch (NS_STATE(ns->nxstate)) {
case STATE_ADDR_PAGE: case STATE_ADDR_PAGE:
@ -1306,7 +1306,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
switch_to_ready_state(ns, NS_STATUS_FAILED(ns)); switch_to_ready_state(ns, NS_STATUS_FAILED(ns));
return; return;
} }
/* Check if this is expected byte */ /* Check if this is expected byte */
if (ns->regs.count == ns->regs.num) { if (ns->regs.count == ns->regs.num) {
NS_ERR("write_byte: no more address bytes expected\n"); NS_ERR("write_byte: no more address bytes expected\n");
@ -1325,12 +1325,12 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
NS_DBG("address (%#x, %#x) is accepted\n", ns->regs.row, ns->regs.column); NS_DBG("address (%#x, %#x) is accepted\n", ns->regs.row, ns->regs.column);
switch_state(ns); switch_state(ns);
} }
} else { } else {
/* /*
* The byte written is an input data. * The byte written is an input data.
*/ */
/* Check that chip is expecting data input */ /* Check that chip is expecting data input */
if (!(ns->state & STATE_DATAIN_MASK)) { if (!(ns->state & STATE_DATAIN_MASK)) {
NS_ERR("write_byte: data input (%#x) isn't expected, state is %s, " NS_ERR("write_byte: data input (%#x) isn't expected, state is %s, "
@ -1372,7 +1372,7 @@ ns_nand_read_word(struct mtd_info *mtd)
struct nand_chip *chip = (struct nand_chip *)mtd->priv; struct nand_chip *chip = (struct nand_chip *)mtd->priv;
NS_DBG("read_word\n"); NS_DBG("read_word\n");
return chip->read_byte(mtd) | (chip->read_byte(mtd) << 8); return chip->read_byte(mtd) | (chip->read_byte(mtd) << 8);
} }
@ -1380,14 +1380,14 @@ static void
ns_nand_write_word(struct mtd_info *mtd, uint16_t word) ns_nand_write_word(struct mtd_info *mtd, uint16_t word)
{ {
struct nand_chip *chip = (struct nand_chip *)mtd->priv; struct nand_chip *chip = (struct nand_chip *)mtd->priv;
NS_DBG("write_word\n"); NS_DBG("write_word\n");
chip->write_byte(mtd, word & 0xFF); chip->write_byte(mtd, word & 0xFF);
chip->write_byte(mtd, word >> 8); chip->write_byte(mtd, word >> 8);
} }
static void static void
ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len) ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
{ {
struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
@ -1409,13 +1409,13 @@ ns_nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
memcpy(ns->buf.byte + ns->regs.count, buf, len); memcpy(ns->buf.byte + ns->regs.count, buf, len);
ns->regs.count += len; ns->regs.count += len;
if (ns->regs.count == ns->regs.num) { if (ns->regs.count == ns->regs.num) {
NS_DBG("write_buf: %d bytes were written\n", ns->regs.count); NS_DBG("write_buf: %d bytes were written\n", ns->regs.count);
} }
} }
static void static void
ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len) ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
{ {
struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv; struct nandsim *ns = (struct nandsim *)((struct nand_chip *)mtd->priv)->priv;
@ -1453,7 +1453,7 @@ ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
memcpy(buf, ns->buf.byte + ns->regs.count, len); memcpy(buf, ns->buf.byte + ns->regs.count, len);
ns->regs.count += len; ns->regs.count += len;
if (ns->regs.count == ns->regs.num) { if (ns->regs.count == ns->regs.num) {
if ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT) { if ((ns->options & OPT_AUTOINCR) && NS_STATE(ns->state) == STATE_DATAOUT) {
ns->regs.count = 0; ns->regs.count = 0;
@ -1465,11 +1465,11 @@ ns_nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
else if (NS_STATE(ns->nxstate) == STATE_READY) else if (NS_STATE(ns->nxstate) == STATE_READY)
switch_state(ns); switch_state(ns);
} }
return; return;
} }
static int static int
ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len) ns_nand_verify_buf(struct mtd_info *mtd, const u_char *buf, int len)
{ {
ns_nand_read_buf(mtd, (u_char *)&ns_verify_buf[0], len); ns_nand_read_buf(mtd, (u_char *)&ns_verify_buf[0], len);
@ -1496,7 +1496,7 @@ int __init ns_init_module(void)
NS_ERR("wrong bus width (%d), use only 8 or 16\n", bus_width); NS_ERR("wrong bus width (%d), use only 8 or 16\n", bus_width);
return -EINVAL; return -EINVAL;
} }
/* Allocate and initialize mtd_info, nand_chip and nandsim structures */ /* Allocate and initialize mtd_info, nand_chip and nandsim structures */
nsmtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip) nsmtd = kmalloc(sizeof(struct mtd_info) + sizeof(struct nand_chip)
+ sizeof(struct nandsim), GFP_KERNEL); + sizeof(struct nandsim), GFP_KERNEL);
@ -1509,7 +1509,7 @@ int __init ns_init_module(void)
chip = (struct nand_chip *)(nsmtd + 1); chip = (struct nand_chip *)(nsmtd + 1);
nsmtd->priv = (void *)chip; nsmtd->priv = (void *)chip;
nand = (struct nandsim *)(chip + 1); nand = (struct nandsim *)(chip + 1);
chip->priv = (void *)nand; chip->priv = (void *)nand;
/* /*
* Register simulator's callbacks. * Register simulator's callbacks.
@ -1526,9 +1526,9 @@ int __init ns_init_module(void)
chip->eccmode = NAND_ECC_SOFT; chip->eccmode = NAND_ECC_SOFT;
chip->options |= NAND_SKIP_BBTSCAN; chip->options |= NAND_SKIP_BBTSCAN;
/* /*
* Perform minimum nandsim structure initialization to handle * Perform minimum nandsim structure initialization to handle
* the initial ID read command correctly * the initial ID read command correctly
*/ */
if (third_id_byte != 0xFF || fourth_id_byte != 0xFF) if (third_id_byte != 0xFF || fourth_id_byte != 0xFF)
nand->geom.idbytes = 4; nand->geom.idbytes = 4;
@ -1557,7 +1557,7 @@ int __init ns_init_module(void)
NS_ERR("scan_bbt: can't initialize the nandsim structure\n"); NS_ERR("scan_bbt: can't initialize the nandsim structure\n");
goto error; goto error;
} }
if ((retval = nand_default_bbt(nsmtd)) != 0) { if ((retval = nand_default_bbt(nsmtd)) != 0) {
free_nandsim(nand); free_nandsim(nand);
goto error; goto error;

View File

@ -6,7 +6,7 @@
* Derived from drivers/mtd/nand/edb7312.c * Derived from drivers/mtd/nand/edb7312.c
* *
* *
* $Id: ppchameleonevb.c,v 1.6 2004/11/05 16:07:16 kalev Exp $ * $Id: ppchameleonevb.c,v 1.7 2005/11/07 11:14:31 gleixner Exp $
* *
* 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
@ -338,7 +338,7 @@ nand_evb_init:
out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xFFFFFFF0); out_be32((volatile unsigned*)GPIO0_TSRH, in_be32((volatile unsigned*)GPIO0_TSRH) & 0xFFFFFFF0);
out_be32((volatile unsigned*)GPIO0_TSRL, in_be32((volatile unsigned*)GPIO0_TSRL) & 0x3FFFFFFF); out_be32((volatile unsigned*)GPIO0_TSRL, in_be32((volatile unsigned*)GPIO0_TSRL) & 0x3FFFFFFF);
/* enable output driver */ /* enable output driver */
out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN | out_be32((volatile unsigned*)GPIO0_TCR, in_be32((volatile unsigned*)GPIO0_TCR) | NAND_EVB_nCE_GPIO_PIN |
NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN); NAND_EVB_CLE_GPIO_PIN | NAND_EVB_ALE_GPIO_PIN);
#ifdef USE_READY_BUSY_PIN #ifdef USE_READY_BUSY_PIN
/* three-state select */ /* three-state select */
@ -402,7 +402,7 @@ static void __exit ppchameleonevb_cleanup (void)
/* Release resources, unregister device(s) */ /* Release resources, unregister device(s) */
nand_release (ppchameleon_mtd); nand_release (ppchameleon_mtd);
nand_release (ppchameleonevb_mtd); nand_release (ppchameleonevb_mtd);
/* Release iomaps */ /* Release iomaps */
this = (struct nand_chip *) &ppchameleon_mtd[1]; this = (struct nand_chip *) &ppchameleon_mtd[1];
iounmap((void *) this->IO_ADDR_R; iounmap((void *) this->IO_ADDR_R;

View File

@ -2,11 +2,11 @@
* drivers/mtd/nand/rtc_from4.c * drivers/mtd/nand/rtc_from4.c
* *
* Copyright (C) 2004 Red Hat, Inc. * Copyright (C) 2004 Red Hat, Inc.
* *
* Derived from drivers/mtd/nand/spia.c * Derived from drivers/mtd/nand/spia.c
* Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
* *
* $Id: rtc_from4.c,v 1.9 2005/01/24 20:40:11 dmarlin Exp $ * $Id: rtc_from4.c,v 1.10 2005/11/07 11:14:31 gleixner Exp $
* *
* 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
@ -14,8 +14,8 @@
* *
* Overview: * Overview:
* This is a device driver for the AG-AND flash device found on the * This is a device driver for the AG-AND flash device found on the
* Renesas Technology Corp. Flash ROM 4-slot interface board (FROM_BOARD4), * Renesas Technology Corp. Flash ROM 4-slot interface board (FROM_BOARD4),
* which utilizes the Renesas HN29V1G91T-30 part. * which utilizes the Renesas HN29V1G91T-30 part.
* This chip is a 1 GBibit (128MiB x 8 bits) AG-AND flash device. * This chip is a 1 GBibit (128MiB x 8 bits) AG-AND flash device.
*/ */
@ -105,9 +105,9 @@ const static struct mtd_partition partition_info[] = {
}; };
#define NUM_PARTITIONS 1 #define NUM_PARTITIONS 1
/* /*
* hardware specific flash bbt decriptors * hardware specific flash bbt decriptors
* Note: this is to allow debugging by disabling * Note: this is to allow debugging by disabling
* NAND_BBT_CREATE and/or NAND_BBT_WRITE * NAND_BBT_CREATE and/or NAND_BBT_WRITE
* *
*/ */
@ -141,7 +141,7 @@ static struct nand_bbt_descr rtc_from4_bbt_mirror_descr = {
/* the Reed Solomon control structure */ /* the Reed Solomon control structure */
static struct rs_control *rs_decoder; static struct rs_control *rs_decoder;
/* /*
* hardware specific Out Of Band information * hardware specific Out Of Band information
*/ */
static struct nand_oobinfo rtc_from4_nand_oobinfo = { static struct nand_oobinfo rtc_from4_nand_oobinfo = {
@ -200,38 +200,38 @@ static uint8_t revbits[256] = {
/* /*
* rtc_from4_hwcontrol - hardware specific access to control-lines * rtc_from4_hwcontrol - hardware specific access to control-lines
* @mtd: MTD device structure * @mtd: MTD device structure
* @cmd: hardware control command * @cmd: hardware control command
* *
* Address lines (A5 and A4) are used to control Command and Address Latch * Address lines (A5 and A4) are used to control Command and Address Latch
* Enable on this board, so set the read/write address appropriately. * Enable on this board, so set the read/write address appropriately.
* *
* Chip Enable is also controlled by the Chip Select (CS5) and * Chip Enable is also controlled by the Chip Select (CS5) and
* Address lines (A24-A22), so no action is required here. * Address lines (A24-A22), so no action is required here.
* *
*/ */
static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd) static void rtc_from4_hwcontrol(struct mtd_info *mtd, int cmd)
{ {
struct nand_chip* this = (struct nand_chip *) (mtd->priv); struct nand_chip* this = (struct nand_chip *) (mtd->priv);
switch(cmd) { switch(cmd) {
case NAND_CTL_SETCLE: case NAND_CTL_SETCLE:
this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_CLE); this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_CLE);
break; break;
case NAND_CTL_CLRCLE: case NAND_CTL_CLRCLE:
this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_CLE); this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_CLE);
break; break;
case NAND_CTL_SETALE: case NAND_CTL_SETALE:
this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_ALE); this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W | RTC_FROM4_ALE);
break; break;
case NAND_CTL_CLRALE: case NAND_CTL_CLRALE:
this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_ALE); this->IO_ADDR_W = (void __iomem *)((unsigned long)this->IO_ADDR_W & ~RTC_FROM4_ALE);
break; break;
case NAND_CTL_SETNCE: case NAND_CTL_SETNCE:
break; break;
case NAND_CTL_CLRNCE: case NAND_CTL_CLRNCE:
@ -296,7 +296,7 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd)
* @mtd: MTD device structure * @mtd: MTD device structure
* @chip: Chip to select (0 == slot 3, 1 == slot 4) * @chip: Chip to select (0 == slot 3, 1 == slot 4)
* *
* If there was a sudden loss of power during an erase operation, a * If there was a sudden loss of power during an erase operation, a
* "device recovery" operation must be performed when power is restored * "device recovery" operation must be performed when power is restored
* to ensure correct operation. This routine performs the required steps * to ensure correct operation. This routine performs the required steps
* for the requested chip. * for the requested chip.
@ -312,7 +312,7 @@ static void deplete(struct mtd_info *mtd, int chip)
while (!this->dev_ready(mtd)); while (!this->dev_ready(mtd));
this->select_chip(mtd, chip); this->select_chip(mtd, chip);
/* Send the commands for device recovery, phase 1 */ /* Send the commands for device recovery, phase 1 */
this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000); this->cmdfunc (mtd, NAND_CMD_DEPLETE1, 0x0000, 0x0000);
this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1); this->cmdfunc (mtd, NAND_CMD_DEPLETE2, -1, -1);
@ -330,7 +330,7 @@ static void deplete(struct mtd_info *mtd, int chip)
* @mtd: MTD device structure * @mtd: MTD device structure
* @mode: I/O mode; read or write * @mode: I/O mode; read or write
* *
* enable hardware ECC for data read or write * enable hardware ECC for data read or write
* *
*/ */
static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode) static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
@ -340,7 +340,7 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
switch (mode) { switch (mode) {
case NAND_ECC_READ : case NAND_ECC_READ :
status = RTC_FROM4_RS_ECC_CTL_CLR status = RTC_FROM4_RS_ECC_CTL_CLR
| RTC_FROM4_RS_ECC_CTL_FD_E; | RTC_FROM4_RS_ECC_CTL_FD_E;
*rs_ecc_ctl = status; *rs_ecc_ctl = status;
@ -353,8 +353,8 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
break; break;
case NAND_ECC_WRITE : case NAND_ECC_WRITE :
status = RTC_FROM4_RS_ECC_CTL_CLR status = RTC_FROM4_RS_ECC_CTL_CLR
| RTC_FROM4_RS_ECC_CTL_GEN | RTC_FROM4_RS_ECC_CTL_GEN
| RTC_FROM4_RS_ECC_CTL_FD_E; | RTC_FROM4_RS_ECC_CTL_FD_E;
*rs_ecc_ctl = status; *rs_ecc_ctl = status;
@ -411,7 +411,7 @@ static void rtc_from4_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_c
static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_char *ecc1, u_char *ecc2) static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_char *ecc1, u_char *ecc2)
{ {
int i, j, res; int i, j, res;
unsigned short status; unsigned short status;
uint16_t par[6], syn[6]; uint16_t par[6], syn[6];
uint8_t ecc[8]; uint8_t ecc[8];
volatile unsigned short *rs_ecc; volatile unsigned short *rs_ecc;
@ -430,7 +430,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
} }
/* convert into 6 10bit syndrome fields */ /* convert into 6 10bit syndrome fields */
par[5] = rs_decoder->index_of[(((uint16_t)ecc[0] >> 0) & 0x0ff) | par[5] = rs_decoder->index_of[(((uint16_t)ecc[0] >> 0) & 0x0ff) |
(((uint16_t)ecc[1] << 8) & 0x300)]; (((uint16_t)ecc[1] << 8) & 0x300)];
par[4] = rs_decoder->index_of[(((uint16_t)ecc[1] >> 2) & 0x03f) | par[4] = rs_decoder->index_of[(((uint16_t)ecc[1] >> 2) & 0x03f) |
(((uint16_t)ecc[2] << 6) & 0x3c0)]; (((uint16_t)ecc[2] << 6) & 0x3c0)];
@ -456,7 +456,7 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
/* Let the library code do its magic.*/ /* Let the library code do its magic.*/
res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL); res = decode_rs8(rs_decoder, (uint8_t *)buf, par, 512, syn, 0, NULL, 0xff, NULL);
if (res > 0) { if (res > 0) {
DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: " DEBUG (MTD_DEBUG_LEVEL0, "rtc_from4_correct_data: "
"ECC corrected %d errors on read\n", res); "ECC corrected %d errors on read\n", res);
} }
return res; return res;
@ -470,9 +470,9 @@ static int rtc_from4_correct_data(struct mtd_info *mtd, const u_char *buf, u_cha
* @state: state or the operation * @state: state or the operation
* @status: status code returned from read status * @status: status code returned from read status
* @page: startpage inside the chip, must be called with (page & this->pagemask) * @page: startpage inside the chip, must be called with (page & this->pagemask)
* *
* Perform additional error status checks on erase and write failures * Perform additional error status checks on erase and write failures
* to determine if errors are correctable. For this device, correctable * to determine if errors are correctable. For this device, correctable
* 1-bit errors on erase and write are considered acceptable. * 1-bit errors on erase and write are considered acceptable.
* *
* note: see pages 34..37 of data sheet for details. * note: see pages 34..37 of data sheet for details.
@ -633,7 +633,7 @@ int __init rtc_from4_init (void)
#ifdef RTC_FROM4_HWECC #ifdef RTC_FROM4_HWECC
/* We could create the decoder on demand, if memory is a concern. /* We could create the decoder on demand, if memory is a concern.
* This way we have it handy, if an error happens * This way we have it handy, if an error happens
* *
* Symbolsize is 10 (bits) * Symbolsize is 10 (bits)
* Primitve polynomial is x^10+x^3+1 * Primitve polynomial is x^10+x^3+1

View File

@ -19,7 +19,7 @@
* 08-Jul-2005 BJD Fix OOPS when no platform data supplied * 08-Jul-2005 BJD Fix OOPS when no platform data supplied
* 20-Oct-2005 BJD Fix timing calculation bug * 20-Oct-2005 BJD Fix timing calculation bug
* *
* $Id: s3c2410.c,v 1.18 2005/10/20 21:22:55 bjd Exp $ * $Id: s3c2410.c,v 1.20 2005/11/07 11:14:31 gleixner Exp $
* *
* 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 as published by * it under the terms of the GNU General Public License as published by
@ -164,7 +164,7 @@ static int s3c2410_nand_calc_rate(int wanted, unsigned long clk, int max)
/* controller setup */ /* controller setup */
static int s3c2410_nand_inithw(struct s3c2410_nand_info *info, static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
struct device *dev) struct device *dev)
{ {
struct s3c2410_platform_nand *plat = to_nand_plat(dev); struct s3c2410_platform_nand *plat = to_nand_plat(dev);
@ -186,7 +186,7 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
twrph0 = 8; twrph0 = 8;
twrph1 = 8; twrph1 = 8;
} }
if (tacls < 0 || twrph0 < 0 || twrph1 < 0) { if (tacls < 0 || twrph0 < 0 || twrph1 < 0) {
printk(KERN_ERR PFX "cannot get timings suitable for board\n"); printk(KERN_ERR PFX "cannot get timings suitable for board\n");
return -EINVAL; return -EINVAL;
@ -194,7 +194,7 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
printk(KERN_INFO PFX "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n", printk(KERN_INFO PFX "Tacls=%d, %dns Twrph0=%d %dns, Twrph1=%d %dns\n",
tacls, to_ns(tacls, clkrate), tacls, to_ns(tacls, clkrate),
twrph0, to_ns(twrph0, clkrate), twrph0, to_ns(twrph0, clkrate),
twrph1, to_ns(twrph1, clkrate)); twrph1, to_ns(twrph1, clkrate));
if (!info->is_s3c2440) { if (!info->is_s3c2440) {
@ -219,7 +219,7 @@ static int s3c2410_nand_inithw(struct s3c2410_nand_info *info,
static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip) static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
{ {
struct s3c2410_nand_info *info; struct s3c2410_nand_info *info;
struct s3c2410_nand_mtd *nmtd; struct s3c2410_nand_mtd *nmtd;
struct nand_chip *this = mtd->priv; struct nand_chip *this = mtd->priv;
void __iomem *reg; void __iomem *reg;
unsigned long cur; unsigned long cur;
@ -252,7 +252,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
writel(cur, reg); writel(cur, reg);
} }
/* command and control functions /* command and control functions
* *
* Note, these all use tglx's method of changing the IO_ADDR_W field * Note, these all use tglx's method of changing the IO_ADDR_W field
* to make the code simpler, and use the nand layer's code to issue the * to make the code simpler, and use the nand layer's code to issue the
@ -324,7 +324,7 @@ static void s3c2440_nand_hwcontrol(struct mtd_info *mtd, int cmd)
static int s3c2410_nand_devready(struct mtd_info *mtd) static int s3c2410_nand_devready(struct mtd_info *mtd)
{ {
struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd); struct s3c2410_nand_info *info = s3c2410_nand_mtd_toinfo(mtd);
if (info->is_s3c2440) if (info->is_s3c2440)
return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY; return readb(info->regs + S3C2440_NFSTAT) & S3C2440_NFSTAT_READY;
return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY; return readb(info->regs + S3C2410_NFSTAT) & S3C2410_NFSTAT_BUSY;
@ -345,7 +345,7 @@ static int s3c2410_nand_correct_data(struct mtd_info *mtd, u_char *dat,
if (read_ecc[0] == calc_ecc[0] && if (read_ecc[0] == calc_ecc[0] &&
read_ecc[1] == calc_ecc[1] && read_ecc[1] == calc_ecc[1] &&
read_ecc[2] == calc_ecc[2]) read_ecc[2] == calc_ecc[2])
return 0; return 0;
/* we curently have no method for correcting the error */ /* we curently have no method for correcting the error */
@ -436,14 +436,14 @@ static int s3c2410_nand_remove(struct device *dev)
dev_set_drvdata(dev, NULL); dev_set_drvdata(dev, NULL);
if (info == NULL) if (info == NULL)
return 0; return 0;
/* first thing we need to do is release all our mtds /* first thing we need to do is release all our mtds
* and their partitions, then go through freeing the * and their partitions, then go through freeing the
* resources used * resources used
*/ */
if (info->mtds != NULL) { if (info->mtds != NULL) {
struct s3c2410_nand_mtd *ptr = info->mtds; struct s3c2410_nand_mtd *ptr = info->mtds;
int mtdno; int mtdno;
@ -507,7 +507,7 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
/* s3c2410_nand_init_chip /* s3c2410_nand_init_chip
* *
* init a single instance of an chip * init a single instance of an chip
*/ */
static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info, static void s3c2410_nand_init_chip(struct s3c2410_nand_info *info,
@ -625,7 +625,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
dev_err(dev, "cannot reserve register region\n"); dev_err(dev, "cannot reserve register region\n");
err = -EIO; err = -EIO;
goto exit_error; goto exit_error;
} }
dev_dbg(dev, "mapped registers at %p\n", info->regs); dev_dbg(dev, "mapped registers at %p\n", info->regs);
@ -659,7 +659,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
for (setno = 0; setno < nr_sets; setno++, nmtd++) { for (setno = 0; setno < nr_sets; setno++, nmtd++) {
pr_debug("initialising set %d (%p, info %p)\n", pr_debug("initialising set %d (%p, info %p)\n",
setno, nmtd, info); setno, nmtd, info);
s3c2410_nand_init_chip(info, nmtd, sets); s3c2410_nand_init_chip(info, nmtd, sets);
nmtd->scan_res = nand_scan(&nmtd->mtd, nmtd->scan_res = nand_scan(&nmtd->mtd,
@ -672,7 +672,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
if (sets != NULL) if (sets != NULL)
sets++; sets++;
} }
pr_debug("initialised ok\n"); pr_debug("initialised ok\n");
return 0; return 0;

View File

@ -3,7 +3,7 @@
* *
* Copyright (C) 2004 Richard Purdie * Copyright (C) 2004 Richard Purdie
* *
* $Id: sharpsl.c,v 1.6 2005/11/03 11:36:42 rpurdie Exp $ * $Id: sharpsl.c,v 1.7 2005/11/07 11:14:31 gleixner Exp $
* *
* Based on Sharp's NAND driver sharp_sl.c * Based on Sharp's NAND driver sharp_sl.c
* *
@ -76,14 +76,14 @@ static struct mtd_partition sharpsl_nand_default_partition_info[] = {
}, },
}; };
/* /*
* hardware specific access to control-lines * hardware specific access to control-lines
*/ */
static void static void
sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd) sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd)
{ {
switch (cmd) { switch (cmd) {
case NAND_CTL_SETCLE: case NAND_CTL_SETCLE:
writeb(readb(FLASHCTL) | FLCLE, FLASHCTL); writeb(readb(FLASHCTL) | FLCLE, FLASHCTL);
break; break;
case NAND_CTL_CLRCLE: case NAND_CTL_CLRCLE:
@ -97,10 +97,10 @@ sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd)
writeb(readb(FLASHCTL) & ~FLALE, FLASHCTL); writeb(readb(FLASHCTL) & ~FLALE, FLASHCTL);
break; break;
case NAND_CTL_SETNCE: case NAND_CTL_SETNCE:
writeb(readb(FLASHCTL) & ~(FLCE0|FLCE1), FLASHCTL); writeb(readb(FLASHCTL) & ~(FLCE0|FLCE1), FLASHCTL);
break; break;
case NAND_CTL_CLRNCE: case NAND_CTL_CLRNCE:
writeb(readb(FLASHCTL) | (FLCE0|FLCE1), FLASHCTL); writeb(readb(FLASHCTL) | (FLCE0|FLCE1), FLASHCTL);
break; break;
} }
@ -126,8 +126,8 @@ static struct nand_oobinfo akita_oobinfo = {
.useecc = MTD_NANDECC_AUTOPLACE, .useecc = MTD_NANDECC_AUTOPLACE,
.eccbytes = 24, .eccbytes = 24,
.eccpos = { .eccpos = {
0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11, 0x5, 0x1, 0x2, 0x3, 0x6, 0x7, 0x15, 0x11,
0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23, 0x12, 0x13, 0x16, 0x17, 0x25, 0x21, 0x22, 0x23,
0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37}, 0x26, 0x27, 0x35, 0x31, 0x32, 0x33, 0x36, 0x37},
.oobfree = { {0x08, 0x09} } .oobfree = { {0x08, 0x09} }
}; };
@ -177,7 +177,7 @@ sharpsl_nand_init(void)
printk ("Unable to allocate SharpSL NAND MTD device structure.\n"); printk ("Unable to allocate SharpSL NAND MTD device structure.\n");
return -ENOMEM; return -ENOMEM;
} }
/* map physical adress */ /* map physical adress */
sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000); sharpsl_io_base = ioremap(sharpsl_phys_base, 0x1000);
if(!sharpsl_io_base){ if(!sharpsl_io_base){
@ -185,7 +185,7 @@ sharpsl_nand_init(void)
kfree(sharpsl_mtd); kfree(sharpsl_mtd);
return -EIO; return -EIO;
} }
/* Get pointer to private data */ /* Get pointer to private data */
this = (struct nand_chip *) (&sharpsl_mtd[1]); this = (struct nand_chip *) (&sharpsl_mtd[1]);
@ -211,7 +211,7 @@ sharpsl_nand_init(void)
this->chip_delay = 15; this->chip_delay = 15;
/* set eccmode using hardware ECC */ /* set eccmode using hardware ECC */
this->eccmode = NAND_ECC_HW3_256; this->eccmode = NAND_ECC_HW3_256;
this->badblock_pattern = &sharpsl_bbt; this->badblock_pattern = &sharpsl_bbt;
if (machine_is_akita() || machine_is_borzoi()) { if (machine_is_akita() || machine_is_borzoi()) {
this->badblock_pattern = &sharpsl_akita_bbt; this->badblock_pattern = &sharpsl_akita_bbt;
this->autooob = &akita_oobinfo; this->autooob = &akita_oobinfo;
@ -232,7 +232,7 @@ sharpsl_nand_init(void)
sharpsl_mtd->name = "sharpsl-nand"; sharpsl_mtd->name = "sharpsl-nand";
nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes, nr_partitions = parse_mtd_partitions(sharpsl_mtd, part_probes,
&sharpsl_partition_info, 0); &sharpsl_partition_info, 0);
if (nr_partitions <= 0) { if (nr_partitions <= 0) {
nr_partitions = DEFAULT_NUM_PARTITIONS; nr_partitions = DEFAULT_NUM_PARTITIONS;
sharpsl_partition_info = sharpsl_nand_default_partition_info; sharpsl_partition_info = sharpsl_nand_default_partition_info;

View File

@ -8,7 +8,7 @@
* to controllines (due to change in nand.c) * to controllines (due to change in nand.c)
* page_cache added * page_cache added
* *
* $Id: spia.c,v 1.24 2004/11/04 12:53:10 gleixner Exp $ * $Id: spia.c,v 1.25 2005/11/07 11:14:31 gleixner Exp $
* *
* 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
@ -82,7 +82,7 @@ const static struct mtd_partition partition_info[] = {
#define NUM_PARTITIONS 2 #define NUM_PARTITIONS 2
/* /*
* hardware specific access to control-lines * hardware specific access to control-lines
*/ */
static void spia_hwcontrol(struct mtd_info *mtd, int cmd){ static void spia_hwcontrol(struct mtd_info *mtd, int cmd){
@ -137,7 +137,7 @@ int __init spia_init (void)
/* Set address of hardware control function */ /* Set address of hardware control function */
this->hwcontrol = spia_hwcontrol; this->hwcontrol = spia_hwcontrol;
/* 15 us command delay time */ /* 15 us command delay time */
this->chip_delay = 15; this->chip_delay = 15;
/* Scan to find existence of the device */ /* Scan to find existence of the device */
if (nand_scan (spia_mtd, 1)) { if (nand_scan (spia_mtd, 1)) {

View File

@ -15,7 +15,7 @@
* This is a device driver for the NAND flash device found on the * This is a device driver for the NAND flash device found on the
* TI fido board. It supports 32MiB and 64MiB cards * TI fido board. It supports 32MiB and 64MiB cards
* *
* $Id: toto.c,v 1.4 2004/10/05 13:50:20 gleixner Exp $ * $Id: toto.c,v 1.5 2005/11/07 11:14:31 gleixner Exp $
*/ */
#include <linux/slab.h> #include <linux/slab.h>
@ -57,7 +57,7 @@ static unsigned long toto_io_base = OMAP_FLASH_1_BASE;
#endif #endif
#define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0) #define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0)
#define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE) #define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE)
/* /*
* Define partitions for flash devices * Define partitions for flash devices
*/ */
@ -91,7 +91,7 @@ static struct mtd_partition partition_info32M[] = {
#define NUM_PARTITIONS32M 3 #define NUM_PARTITIONS32M 3
#define NUM_PARTITIONS64M 4 #define NUM_PARTITIONS64M 4
/* /*
* hardware specific access to control-lines * hardware specific access to control-lines
*/ */
@ -146,7 +146,7 @@ int __init toto_init (void)
this->hwcontrol = toto_hwcontrol; this->hwcontrol = toto_hwcontrol;
this->dev_ready = NULL; this->dev_ready = NULL;
/* 25 us command delay time */ /* 25 us command delay time */
this->chip_delay = 30; this->chip_delay = 30;
this->eccmode = NAND_ECC_SOFT; this->eccmode = NAND_ECC_SOFT;
/* Scan to find existance of the device */ /* Scan to find existance of the device */
@ -157,10 +157,10 @@ int __init toto_init (void)
/* Register the partitions */ /* Register the partitions */
switch(toto_mtd->size){ switch(toto_mtd->size){
case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break; case SZ_64M: add_mtd_partitions(toto_mtd, partition_info64M, NUM_PARTITIONS64M); break;
case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break; case SZ_32M: add_mtd_partitions(toto_mtd, partition_info32M, NUM_PARTITIONS32M); break;
default: { default: {
printk (KERN_WARNING "Unsupported Nand device\n"); printk (KERN_WARNING "Unsupported Nand device\n");
err = -ENXIO; err = -ENXIO;
goto out_buf; goto out_buf;
} }
@ -170,9 +170,9 @@ int __init toto_init (void)
archflashwp(0,0); /* open up flash for writing */ archflashwp(0,0); /* open up flash for writing */
goto out; goto out;
out_buf: out_buf:
kfree (this->data_buf); kfree (this->data_buf);
out_mtd: out_mtd:
kfree (toto_mtd); kfree (toto_mtd);
out: out:
@ -194,7 +194,7 @@ static void __exit toto_cleanup (void)
/* stop flash writes */ /* stop flash writes */
archflashwp(0,1); archflashwp(0,1);
/* release gpios to system */ /* release gpios to system */
gpiorelease(NAND_MASK); gpiorelease(NAND_MASK);
} }