Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci-2.6.23
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci-2.6.23
Commits
61b03bd7
Commit
61b03bd7
authored
Nov 07, 2005
by
Thomas Gleixner
Committed by
Thomas Gleixner
Nov 07, 2005
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[MTD] NAND: Clean up trailing white spaces
Signed-off-by:
Thomas Gleixner
<
tglx@linutronix.de
>
parent
e5580fbe
Changes
17
Hide whitespace changes
Inline
Side-by-side
Showing
17 changed files
with
695 additions
and
695 deletions
+695
-695
drivers/mtd/nand/Kconfig
drivers/mtd/nand/Kconfig
+5
-5
drivers/mtd/nand/au1550nd.c
drivers/mtd/nand/au1550nd.c
+29
-29
drivers/mtd/nand/autcpu12.c
drivers/mtd/nand/autcpu12.c
+11
-11
drivers/mtd/nand/diskonchip.c
drivers/mtd/nand/diskonchip.c
+50
-50
drivers/mtd/nand/edb7312.c
drivers/mtd/nand/edb7312.c
+24
-24
drivers/mtd/nand/h1910.c
drivers/mtd/nand/h1910.c
+24
-24
drivers/mtd/nand/nand_base.c
drivers/mtd/nand/nand_base.c
+239
-239
drivers/mtd/nand/nand_bbt.c
drivers/mtd/nand/nand_bbt.c
+124
-124
drivers/mtd/nand/nand_ecc.c
drivers/mtd/nand/nand_ecc.c
+22
-22
drivers/mtd/nand/nand_ids.c
drivers/mtd/nand/nand_ids.c
+15
-15
drivers/mtd/nand/nandsim.c
drivers/mtd/nand/nandsim.c
+81
-81
drivers/mtd/nand/ppchameleonevb.c
drivers/mtd/nand/ppchameleonevb.c
+3
-3
drivers/mtd/nand/rtc_from4.c
drivers/mtd/nand/rtc_from4.c
+29
-29
drivers/mtd/nand/s3c2410.c
drivers/mtd/nand/s3c2410.c
+15
-15
drivers/mtd/nand/sharpsl.c
drivers/mtd/nand/sharpsl.c
+11
-11
drivers/mtd/nand/spia.c
drivers/mtd/nand/spia.c
+3
-3
drivers/mtd/nand/toto.c
drivers/mtd/nand/toto.c
+10
-10
No files found.
drivers/mtd/nand/Kconfig
View file @
61b03bd7
# drivers/mtd/nand/Kconfig
# $Id: Kconfig,v 1.3
4 2005/09/23 01:44:55 ppopov
Exp $
# $Id: Kconfig,v 1.3
5 2005/11/07 11:14:30 gleixner
Exp $
menu "NAND Flash Device Drivers"
depends on MTD!=n
...
...
@@ -27,14 +27,14 @@ config MTD_NAND_AUTCPU12
tristate "SmartMediaCard on autronix autcpu12 board"
depends on MTD_NAND && ARCH_AUTCPU12
help
This enables the driver for the autronix autcpu12 board to
This enables the driver for the autronix autcpu12 board to
access the SmartMediaCard.
config MTD_NAND_EDB7312
tristate "Support for Cirrus Logic EBD7312 evaluation board"
depends on MTD_NAND && ARCH_EDB7312
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.
config MTD_NAND_H1900
...
...
@@ -71,7 +71,7 @@ config MTD_NAND_RTC_FROM4
select REED_SOLOMON
select REED_SOLOMON_DEC8
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)
config MTD_NAND_PPCHAMELEONEVB
...
...
@@ -88,7 +88,7 @@ config MTD_NAND_S3C2410
SoCs
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
bool "S3C2410 NAND driver debug"
...
...
drivers/mtd/nand/au1550nd.c
View file @
61b03bd7
...
...
@@ -3,7 +3,7 @@
*
* Copyright (C) 2004 Embedded Edge, LLC
*
* $Id: au1550nd.c,v 1.1
2 2005/09/23 01:44:55 ppopov
Exp $
* $Id: au1550nd.c,v 1.1
3 2005/11/07 11:14:30 gleixner
Exp $
*
* 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
...
...
@@ -25,10 +25,10 @@
#else
#include <asm/au1000.h>
#ifdef CONFIG_MIPS_PB1550
#include <asm/pb1550.h>
#include <asm/pb1550.h>
#endif
#ifdef CONFIG_MIPS_DB1550
#include <asm/db1x00.h>
#include <asm/db1x00.h>
#endif
#endif
...
...
@@ -43,12 +43,12 @@ static int nand_width = 1; /* default x8*/
* Define partitions for flash device
*/
const
static
struct
mtd_partition
partition_info
[]
=
{
{
{
.
name
=
"NAND FS 0"
,
.
offset
=
0
,
.
size
=
8
*
1024
*
1024
.
size
=
8
*
1024
*
1024
},
{
{
.
name
=
"NAND FS 1"
,
.
offset
=
MTDPART_OFS_APPEND
,
.
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
* @mtd: MTD device structure
*
* read function for 16bit buswith with
* read function for 16bit buswith with
* endianess conversion
*/
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
* @mtd: MTD device structure
*
* read function for 16bit buswith without
* read function for 16bit buswith without
* endianess conversion
*/
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
* @word: data word to write
*
* write function for 16bit buswith without
* write function for 16bit buswith without
* endianess conversion
*/
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
* @buf: buffer to store date
* @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
++
)
{
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
* @buf: buffer containing the data 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
;
u16
*
p
=
(
u16
*
)
buf
;
len
>>=
1
;
for
(
i
=
0
;
i
<
len
;
i
++
)
{
writew
(
p
[
i
],
this
->
IO_ADDR_W
);
au_sync
();
}
}
/**
* au_read_buf16 - read chip data into buffer
* au_read_buf16 - read chip data into buffer
* @mtd: MTD device structure
* @buf: buffer to store date
* @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
* @buf: buffer containing the data 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_SETALE
:
this
->
IO_ADDR_W
=
p_nand
+
MEM_STNAND_ADDR
;
break
;
case
NAND_CTL_CLRALE
:
this
->
IO_ADDR_W
=
p_nand
+
MEM_STNAND_DATA
;
/* FIXME: Nobody knows why this is neccecary,
case
NAND_CTL_CLRALE
:
this
->
IO_ADDR_W
=
p_nand
+
MEM_STNAND_DATA
;
/* FIXME: Nobody knows why this is neccecary,
* but it works only that way */
udelay
(
1
);
udelay
(
1
);
break
;
case
NAND_CTL_SETNCE
:
case
NAND_CTL_SETNCE
:
/* assert (force assert) chip enable */
au_writel
((
1
<<
(
4
+
NAND_CS
))
,
MEM_STNDCTL
);
break
;
break
;
case
NAND_CTL_CLRNCE
:
case
NAND_CTL_CLRNCE
:
/* deassert chip enable */
au_writel
(
0
,
MEM_STNDCTL
);
break
;
break
;
}
this
->
IO_ADDR_R
=
this
->
IO_ADDR_W
;
/* Drain the writebuffer */
au_sync
();
}
...
...
@@ -325,7 +325,7 @@ int __init au1xxx_nand_init (void)
u32
nand_phys
;
/* 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
);
if
(
!
au1550_mtd
)
{
printk
(
"Unable to allocate NAND MTD dev structure.
\n
"
);
...
...
@@ -345,7 +345,7 @@ int __init au1xxx_nand_init (void)
/* disable interrupts */
au_writel
(
au_readl
(
MEM_STNDCTL
)
&
~
(
1
<<
8
),
MEM_STNDCTL
);
/* disable NAND boot */
au_writel
(
au_readl
(
MEM_STNDCTL
)
&
~
(
1
<<
0
),
MEM_STNDCTL
);
...
...
@@ -353,7 +353,7 @@ int __init au1xxx_nand_init (void)
/* set gpio206 high */
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
);
switch
(
boot_swapboot
)
{
case
0
:
...
...
@@ -402,7 +402,7 @@ int __init au1xxx_nand_init (void)
au_writel
(
NAND_STADDR
,
MEM_STADDR3
);
}
#endif
/* Locate NAND chip-select in order to determine NAND phys address */
mem_staddr
=
0x00000000
;
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
->
dev_ready
=
au1550_device_ready
;
/* 30 us command delay time */
this
->
chip_delay
=
30
;
this
->
chip_delay
=
30
;
this
->
eccmode
=
NAND_ECC_SOFT
;
this
->
options
=
NAND_NO_AUTOINCR
;
...
...
@@ -467,7 +467,7 @@ int __init au1xxx_nand_init (void)
outio:
iounmap
((
void
*
)
p_nand
);
outmem:
kfree
(
au1550_mtd
);
return
retval
;
...
...
drivers/mtd/nand/autcpu12.c
View file @
61b03bd7
...
...
@@ -5,8 +5,8 @@
*
* Derived from drivers/mtd/spia.c
* Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
*
* $Id: autcpu12.c,v 1.2
2 2004/11/04 12:53:1
0 gleixner Exp $
*
* $Id: autcpu12.c,v 1.2
3 2005/11/07 11:14:3
0 gleixner Exp $
*
* 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
...
...
@@ -14,7 +14,7 @@
*
* Overview:
* 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.
*
*
...
...
@@ -93,7 +93,7 @@ static struct mtd_partition partition_info128k[] = {
#define NUM_PARTITIONS32K 2
#define NUM_PARTITIONS64K 2
#define NUM_PARTITIONS128K 2
/*
/*
* hardware specific access to control-lines
*/
static
void
autcpu12_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
...
...
@@ -163,7 +163,7 @@ int __init autcpu12_init (void)
this
->
hwcontrol
=
autcpu12_hwcontrol
;
this
->
dev_ready
=
autcpu12_device_ready
;
/* 20 us command delay time */
this
->
chip_delay
=
20
;
this
->
chip_delay
=
20
;
this
->
eccmode
=
NAND_ECC_SOFT
;
/* 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
;
/* Scan to find existance of the device */
if
(
nand_scan
(
autcpu12_mtd
,
1
))
{
err
=
-
ENXIO
;
goto
out_ior
;
}
/* Register the partitions */
switch
(
autcpu12_mtd
->
size
){
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_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_64M
:
add_mtd_partitions
(
autcpu12_mtd
,
partition_info64k
,
NUM_PARTITIONS64K
);
break
;
case
SZ_128M
:
add_mtd_partitions
(
autcpu12_mtd
,
partition_info128k
,
NUM_PARTITIONS128K
);
break
;
default:
{
printk
(
"Unsupported SmartMedia device
\n
"
);
printk
(
"Unsupported SmartMedia device
\n
"
);
err
=
-
ENXIO
;
goto
out_ior
;
}
...
...
@@ -213,7 +213,7 @@ static void __exit autcpu12_cleanup (void)
/* unmap physical adress */
iounmap
((
void
*
)
autcpu12_fio_base
);
/* Free the MTD device structure */
kfree
(
autcpu12_mtd
);
}
...
...
drivers/mtd/nand/diskonchip.c
View file @
61b03bd7
/*
/*
* drivers/mtd/nand/diskonchip.c
*
* (C) 2003 Red Hat, Inc.
...
...
@@ -8,15 +8,15 @@
* Author: David Woodhouse <dwmw2@infradead.org>
* Additional Diskonchip 2000 and Millennium support by Dan Brown <dan_brown@ieee.org>
* Diskonchip Millennium Plus support by Kalev Lember <kalev@smartlink.ee>
*
*
* 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.
* converted to the generic Reed-Solomon library by Thomas Gleixner <tglx@linutronix.de>
*
*
* Interface to generic NAND code for M-Systems DiskOnChip devices
*
* $Id: diskonchip.c,v 1.5
4 2005/04/07 14:22:55 dbrown
Exp $
* $Id: diskonchip.c,v 1.5
5 2005/11/07 11:14:30 gleixner
Exp $
*/
#include <linux/kernel.h>
...
...
@@ -42,16 +42,16 @@
static
unsigned
long
__initdata
doc_locations
[]
=
{
#if defined (__alpha__) || defined(__i386__) || defined(__x86_64__)
#ifdef CONFIG_MTD_NAND_DISKONCHIP_PROBE_HIGH
0xfffc8000
,
0xfffca000
,
0xfffcc000
,
0xfffce000
,
0xfffc8000
,
0xfffca000
,
0xfffcc000
,
0xfffce000
,
0xfffd0000
,
0xfffd2000
,
0xfffd4000
,
0xfffd6000
,
0xfffd8000
,
0xfffda000
,
0xfffdc000
,
0xfffde000
,
0xfffe0000
,
0xfffe2000
,
0xfffe4000
,
0xfffe6000
,
0xfffd8000
,
0xfffda000
,
0xfffdc000
,
0xfffde000
,
0xfffe0000
,
0xfffe2000
,
0xfffe4000
,
0xfffe6000
,
0xfffe8000
,
0xfffea000
,
0xfffec000
,
0xfffee000
,
#else
/* CONFIG_MTD_DOCPROBE_HIGH */
0xc8000
,
0xca000
,
0xcc000
,
0xce000
,
0xc8000
,
0xca000
,
0xcc000
,
0xce000
,
0xd0000
,
0xd2000
,
0xd4000
,
0xd6000
,
0xd8000
,
0xda000
,
0xdc000
,
0xde000
,
0xe0000
,
0xe2000
,
0xe4000
,
0xe6000
,
0xd8000
,
0xda000
,
0xdc000
,
0xde000
,
0xe0000
,
0xe2000
,
0xe4000
,
0xe6000
,
0xe8000
,
0xea000
,
0xec000
,
0xee000
,
#endif
/* CONFIG_MTD_DOCPROBE_HIGH */
#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 */
static
struct
rs_control
*
rs_decoder
;
/*
/*
* 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
* 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 */
for
(
i
=
0
;
i
<
NROOTS
;
i
++
)
s
[
i
]
=
ds
[
0
];
/*
* Evaluate
/*
* Evaluate
* s[i] = ds[3]x^3 + ds[2]x^2 + ds[1]x^1 + ds[0]
* 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
)
return
nerr
;
/*
/*
* Correct the errors. The bitpositions are a bit of magic,
* but they are given by the design of the de/encoder circuit
* 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 */
index
=
(
pos
>>
3
)
^
1
;
bitpos
=
pos
&
7
;
if
((
index
>=
0
&&
index
<
SECTOR_SIZE
)
||
if
((
index
>=
0
&&
index
<
SECTOR_SIZE
)
||
index
==
(
SECTOR_SIZE
+
1
))
{
val
=
(
uint8_t
)
(
errval
[
i
]
>>
(
2
+
bitpos
));
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
;
if
(
bitpos
==
0
)
bitpos
=
8
;
if
((
index
>=
0
&&
index
<
SECTOR_SIZE
)
||
if
((
index
>=
0
&&
index
<
SECTOR_SIZE
)
||
index
==
(
SECTOR_SIZE
+
1
))
{
val
=
(
uint8_t
)(
errval
[
i
]
<<
(
8
-
bitpos
));
parity
^=
val
;
...
...
@@ -233,7 +233,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
{
volatile
char
dummy
;
int
i
;
for
(
i
=
0
;
i
<
cycles
;
i
++
)
{
if
(
DoC_is_Millennium
(
doc
))
dummy
=
ReadDOC
(
doc
->
virtadr
,
NOP
);
...
...
@@ -242,7 +242,7 @@ static void DoC_Delay(struct doc_priv *doc, unsigned short cycles)
else
dummy
=
ReadDOC
(
doc
->
virtadr
,
DOCStatus
);
}
}
#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
;
}
static
void
doc2000_writebuf
(
struct
mtd_info
*
mtd
,
static
void
doc2000_writebuf
(
struct
mtd_info
*
mtd
,
const
u_char
*
buf
,
int
len
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
...
...
@@ -343,7 +343,7 @@ static void doc2000_writebuf(struct mtd_info *mtd,
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
)
{
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
)
{
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
)
{
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
);
this
->
write_byte
(
mtd
,
0
);
doc200x_hwcontrol
(
mtd
,
NAND_CTL_CLRALE
);
/* We cant' use dev_ready here, but at least we wait for the
* command to complete
* command to complete
*/
udelay
(
50
);
ret
=
this
->
read_byte
(
mtd
)
<<
8
;
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
;
}
}
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
;
int
status
;
DoC_WaitReady
(
doc
);
this
->
cmdfunc
(
mtd
,
NAND_CMD_STATUS
,
-
1
,
-
1
);
DoC_WaitReady
(
doc
);
...
...
@@ -503,7 +503,7 @@ static u_char doc2001_read_byte(struct mtd_info *mtd)
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
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
...
...
@@ -517,7 +517,7 @@ static void doc2001_writebuf(struct mtd_info *mtd,
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
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
...
...
@@ -535,7 +535,7 @@ static void doc2001_readbuf(struct mtd_info *mtd,
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
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
...
...
@@ -570,7 +570,7 @@ static u_char doc2001plus_read_byte(struct mtd_info *mtd)
return
ret
;
}
static
void
doc2001plus_writebuf
(
struct
mtd_info
*
mtd
,
static
void
doc2001plus_writebuf
(
struct
mtd_info
*
mtd
,
const
u_char
*
buf
,
int
len
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
...
...
@@ -587,7 +587,7 @@ static void doc2001plus_writebuf(struct mtd_info *mtd,
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
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
...
...
@@ -617,7 +617,7 @@ static void doc2001plus_readbuf(struct mtd_info *mtd,
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
)
{
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
);
}
/*
/*
* program and erase have their own busy handlers
* 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 */
default:
/*
/*
* If we don't have access to the busy pin, we apply the given
* 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
++
)
{
if
(
DoC_is_MillenniumPlus
(
doc
))
ecc_code
[
i
]
=
ReadDOC_
(
docptr
,
DoC_Mplus_ECCSyndrome0
+
i
);
else
else
ecc_code
[
i
]
=
ReadDOC_
(
docptr
,
DoC_ECCSyndrome0
+
i
);
if
(
ecc_code
[
i
]
!=
empty_write_ecc
[
i
])
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
;
volatile
u_char
dummy
;
int
emptymatch
=
1
;
/* flush the pipeline */
if
(
DoC_is_2000
(
doc
))
{
dummy
=
ReadDOC
(
docptr
,
2
k_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
);
}
/* Error occured ? */
if
(
dummy
&
0x80
)
{
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
(
ret
>
0
)
printk
(
KERN_ERR
"doc200x_correct_data corrected %d errors
\n
"
,
ret
);
}
}
if
(
DoC_is_MillenniumPlus
(
doc
))
WriteDOC
(
DOC_ECC_DIS
,
docptr
,
Mplus_ECCConf
);
else
...
...
@@ -1046,7 +1046,7 @@ static int doc200x_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_
}
return
ret
;
}
//u_char mydatabuf[528];
/* 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
},
.
oobfree
=
{
{
8
,
8
},
{
6
,
2
}
}
};
/* 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
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
->
FormatFlags
=
le32_to_cpu
(
mh
->
FormatFlags
);
mh
->
PercentUsed
=
le32_to_cpu
(
mh
->
PercentUsed
);
printk
(
KERN_INFO
" bootRecordID = %s
\n
"
" NoOfBootImageBlocks = %d
\n
"
" NoOfBinaryPartitions = %d
\n
"
...
...
@@ -1468,7 +1468,7 @@ static inline int __init doc2001_init(struct mtd_info *mtd)
ReadDOC
(
doc
->
virtadr
,
ChipID
);
if
(
ReadDOC
(
doc
->
virtadr
,
ChipID
)
!=
DOC_ChipID_DocMil
)
{
/* 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
can have multiple chips. */
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
* 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
* found it.
* found it.
*/
save_control
=
ReadDOC
(
virtadr
,
DOCControl
);
/* 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
);
WriteDOC
(
DOC_MODE_CLR_ERR
|
DOC_MODE_MDWREN
|
DOC_MODE_RESET
,
WriteDOC
(
DOC_MODE_CLR_ERR
|
DOC_MODE_MDWREN
|
DOC_MODE_RESET
,
virtadr
,
DOCControl
);
/* 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
);
WriteDOC
(
DOC_MODE_CLR_ERR
|
DOC_MODE_MDWREN
|
DOC_MODE_NORMAL
,
WriteDOC
(
DOC_MODE_CLR_ERR
|
DOC_MODE_MDWREN
|
DOC_MODE_NORMAL
,
virtadr
,
DOCControl
);
ChipID
=
ReadDOC
(
virtadr
,
ChipID
);
...
...
@@ -1738,7 +1738,7 @@ static int __init init_nanddoc(void)
int
i
,
ret
=
0
;
/* 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)
* Primitve polynomial is x^10+x^3+1
...
...
drivers/mtd/nand/edb7312.c
View file @
61b03bd7
...
...
@@ -6,7 +6,7 @@
* Derived from drivers/mtd/nand/autcpu12.c
* Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
*
* $Id: edb7312.c,v 1.1
1 2004/11/04 12:53:1
0 gleixner Exp $
* $Id: edb7312.c,v 1.1
2 2005/11/07 11:14:3
0 gleixner Exp $
*
* 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
...
...
@@ -71,27 +71,27 @@ static struct mtd_partition partition_info[] = {
#endif
/*
/*
* 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
)
{
case
NAND_CTL_SETCLE
:
clps_writeb
(
clps_readb
(
ep7312_pxdr
)
|
0x10
,
ep7312_pxdr
);
case
NAND_CTL_SETCLE
:
clps_writeb
(
clps_readb
(
ep7312_pxdr
)
|
0x10
,
ep7312_pxdr
);
break
;
case
NAND_CTL_CLRCLE
:
case
NAND_CTL_CLRCLE
:
clps_writeb
(
clps_readb
(
ep7312_pxdr
)
&
~
0x10
,
ep7312_pxdr
);
break
;
case
NAND_CTL_SETALE
:
clps_writeb
(
clps_readb
(
ep7312_pxdr
)
|
0x20
,
ep7312_pxdr
);
break
;
case
NAND_CTL_CLRALE
:
clps_writeb
(
clps_readb
(
ep7312_pxdr
)
&
~
0x20
,
ep7312_pxdr
);
break
;
case
NAND_CTL_SETNCE
:
clps_writeb
((
clps_readb
(
ep7312_pxdr
)
|
0x80
)
&
~
0x40
,
ep7312_pxdr
);
break
;
...
...
@@ -122,16 +122,16 @@ static int __init ep7312_init (void)
int
mtd_parts_nb
=
0
;
struct
mtd_partition
*
mtd_parts
=
0
;
void
__iomem
*
ep7312_fio_base
;
/* 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
),
GFP_KERNEL
);
if
(
!
ep7312_mtd
)
{
printk
(
"Unable to allocate EDB7312 NAND MTD device structure.
\n
"
);
return
-
ENOMEM
;
}
/* map physical adress */
ep7312_fio_base
=
ioremap
(
ep7312_fio_pbase
,
SZ_1K
);
if
(
!
ep7312_fio_base
)
{
...
...
@@ -139,23 +139,23 @@ static int __init ep7312_init (void)
kfree
(
ep7312_mtd
);
return
-
EIO
;
}
/* Get pointer to private data */
this
=
(
struct
nand_chip
*
)
(
&
ep7312_mtd
[
1
]);
/* Initialize structures */
memset
((
char
*
)
ep7312_mtd
,
0
,
sizeof
(
struct
mtd_info
));
memset
((
char
*
)
this
,
0
,
sizeof
(
struct
nand_chip
));
/* Link the private data with the MTD structure */
ep7312_mtd
->
priv
=
this
;
/*
* Set GPIO Port B control register so that the pins are configured
* to be outputs for controlling the NAND flash.
*/
clps_writeb
(
0xf0
,
ep7312_pxddr
);
/* insert callbacks */
this
->
IO_ADDR_R
=
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
;
/* 15 us command delay time */
this
->
chip_delay
=
15
;
/* Scan to find existence of the device */
if
(
nand_scan
(
ep7312_mtd
,
1
))
{
iounmap
((
void
*
)
ep7312_fio_base
);
kfree
(
ep7312_mtd
);
return
-
ENXIO
;
}
#ifdef CONFIG_MTD_PARTITIONS
ep7312_mtd
->
name
=
"edb7312-nand"
;
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
;
part_type
=
"static"
;
}
/* Register the partitions */
printk
(
KERN_NOTICE
"Using %s partition definition
\n
"
,
part_type
);
add_mtd_partitions
(
ep7312_mtd
,
mtd_parts
,
mtd_parts_nb
);
/* Return happy */
return
0
;
}
...
...
@@ -201,13 +201,13 @@ module_init(ep7312_init);
static
void
__exit
ep7312_cleanup
(
void
)
{
struct
nand_chip
*
this
=
(
struct
nand_chip
*
)
&
ep7312_mtd
[
1
];
/* Release resources, unregister device */
nand_release
(
ap7312_mtd
);
/* Free internal data buffer */
kfree
(
this
->
data_buf
);
/* Free the MTD device structure */
kfree
(
ep7312_mtd
);
}
...
...
drivers/mtd/nand/h1910.c
View file @
61b03bd7
...
...
@@ -7,7 +7,7 @@
* Copyright (C) 2002 Marius Grger (mag@sysgo.de)
* Copyright (c) 2001 Thomas Gleixner (gleixner@autronix.de)
*
* $Id: h1910.c,v 1.
5 2004/11/04 12:53:1
0 gleixner Exp $
* $Id: h1910.c,v 1.
6 2005/11/07 11:14:3
0 gleixner Exp $
*
* 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
...
...
@@ -54,24 +54,24 @@ static struct mtd_partition partition_info[] = {
#endif
/*
/*
* 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
);
switch
(
cmd
)
{
case
NAND_CTL_SETCLE
:
case
NAND_CTL_SETCLE
:
this
->
IO_ADDR_R
|=
(
1
<<
2
);
this
->
IO_ADDR_W
|=
(
1
<<
2
);
break
;
case
NAND_CTL_CLRCLE
:
case
NAND_CTL_CLRCLE
:
this
->
IO_ADDR_R
&=
~
(
1
<<
2
);
this
->
IO_ADDR_W
&=
~
(
1
<<
2
);
break
;
case
NAND_CTL_SETALE
:
this
->
IO_ADDR_R
|=
(
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_W
&=
~
(
1
<<
3
);
break
;
case
NAND_CTL_SETNCE
:
break
;
case
NAND_CTL_CLRNCE
:
...
...
@@ -108,18 +108,18 @@ static int __init h1910_init (void)
int
mtd_parts_nb
=
0
;
struct
mtd_partition
*
mtd_parts
=
0
;
void
__iomem
*
nandaddr
;
if
(
!
machine_is_h1900
())
return
-
ENODEV
;
nandaddr
=
__ioremap
(
0x08000000
,
0x1000
,
0
,
1
);
if
(
!
nandaddr
)
{
printk
(
"Failed to ioremap nand flash.
\n
"
);
return
-
ENOMEM
;
}
/* 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
),
GFP_KERNEL
);
if
(
!
h1910_nand_mtd
)
{
...
...
@@ -127,22 +127,22 @@ static int __init h1910_init (void)
iounmap
((
void
*
)
nandaddr
);
return
-
ENOMEM
;
}
/* Get pointer to private data */
this
=
(
struct
nand_chip
*
)
(
&
h1910_nand_mtd
[
1
]);
/* Initialize structures */
memset
((
char
*
)
h1910_nand_mtd
,
0
,
sizeof
(
struct
mtd_info
));
memset
((
char
*
)
this
,
0
,
sizeof
(
struct
nand_chip
));
/* Link the private data with the MTD structure */
h1910_nand_mtd
->
priv
=
this
;
/*
* Enable VPEN
*/
GPSR
(
37
)
=
GPIO_bit
(
37
);
/* insert callbacks */
this
->
IO_ADDR_R
=
nandaddr
;
this
->
IO_ADDR_W
=
nandaddr
;
...
...
@@ -152,7 +152,7 @@ static int __init h1910_init (void)
this
->
chip_delay
=
50
;
this
->
eccmode
=
NAND_ECC_SOFT
;
this
->
options
=
NAND_NO_AUTOINCR
;
/* Scan to find existence of the device */
if
(
nand_scan
(
h1910_nand_mtd
,
1
))
{
printk
(
KERN_NOTICE
"No NAND device - returning -ENXIO
\n
"
);
...
...
@@ -160,9 +160,9 @@ static int __init h1910_init (void)
iounmap
((
void
*
)
nandaddr
);
return
-
ENXIO
;
}
#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"
);
if
(
mtd_parts_nb
>
0
)
part_type
=
"command line"
;
...
...
@@ -175,11 +175,11 @@ static int __init h1910_init (void)
mtd_parts_nb
=
NUM_PARTITIONS
;
part_type
=
"static"
;
}
/* Register the partitions */
printk
(
KERN_NOTICE
"Using %s partition definition
\n
"
,
part_type
);
add_mtd_partitions
(
h1910_nand_mtd
,
mtd_parts
,
mtd_parts_nb
);
/* Return happy */
return
0
;
}
...
...
@@ -191,7 +191,7 @@ module_init(h1910_init);
static
void
__exit
h1910_cleanup
(
void
)
{
struct
nand_chip
*
this
=
(
struct
nand_chip
*
)
&
h1910_nand_mtd
[
1
];
/* Release resources, unregister device */
nand_release
(
h1910_nand_mtd
);
...
...
drivers/mtd/nand/nand_base.c
View file @
61b03bd7
...
...
@@ -5,14 +5,14 @@
* This is the generic MTD driver for NAND flash devices. It should be
* capable of working with almost all NAND chips currently available.
* Basic support for AG-AND chips is provided.
*
*
* Additional technical information is available on
* http://www.linux-mtd.infradead.org/tech/nand.html
*
*
* Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
* 2002 Thomas Gleixner (tglx@linutronix.de)
*
* 02-08-2004 tglx: support for strange chips, which cannot auto increment
* 02-08-2004 tglx: support for strange chips, which cannot auto increment
* pages on read / read_oob
*
* 03-17-2004 tglx: Check ready before auto increment check. Simon Bayes
...
...
@@ -21,7 +21,7 @@
* Make reads over block boundaries work too
*
* 04-14-2004 tglx: first working version for 2k page size chips
*
*
* 05-19-2004 tglx: Basic support for Renesas AG-AND chips
*
* 09-24-2004 tglx: add support for hardware controllers (e.g. ECC) shared
...
...
@@ -30,27 +30,27 @@
*
* 12-05-2004 dmarlin: add workaround for Renesas AG-AND chips "disturb" issue.
* Basically, any block not rewritten may lose data when surrounding blocks
* are rewritten many times. JFFS2 ensures this doesn't happen for blocks
* are rewritten many times. JFFS2 ensures this doesn't happen for blocks
* it uses, but the Bad Block Table(s) may not be rewritten. To ensure they
* do not lose data, force them to be rewritten when some of the surrounding
* blocks are erased. Rather than tracking a specific nearby block (which
* could itself go bad), use a page address 'mask' to select several blocks
* blocks are erased. Rather than tracking a specific nearby block (which
* could itself go bad), use a page address 'mask' to select several blocks
* in the same area, and rewrite the BBT when any of them are erased.
*
* 01-03-2005 dmarlin: added support for the device recovery command sequence for Renesas
* 01-03-2005 dmarlin: added support for the device recovery command sequence for Renesas
* AG-AND chips. If there was a sudden loss of power during an erase operation,
* a "device recovery" operation must be performed when power is restored
* to ensure correct operation.
*
* 01-20-2005 dmarlin: added support for optional hardware specific callback routine to
* 01-20-2005 dmarlin: added support for optional hardware specific callback routine to
* perform extra error status checks on erase and write failures. This required
* adding a wrapper function for nand_read_ecc.
*
* 08-20-2005 vwool: suspend/resume added
*
* Credits:
* David Woodhouse for adding multichip support
*
* David Woodhouse for adding multichip support
*
* Aleph One Ltd. and Toby Churchill Ltd. for supporting the
* rework for 2K page size chips
*
...
...
@@ -105,8 +105,8 @@ static struct nand_oobinfo nand_oob_64 = {
.
useecc
=
MTD_NANDECC_AUTOPLACE
,
.
eccbytes
=
24
,
.
eccpos
=
{
40
,
41
,
42
,
43
,
44
,
45
,
46
,
47
,
48
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
40
,
41
,
42
,
43
,
44
,
45
,
46
,
47
,
48
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
},
.
oobfree
=
{
{
2
,
38
}
}
};
...
...
@@ -149,19 +149,19 @@ static void nand_sync (struct mtd_info *mtd);
static
int
nand_write_page
(
struct
mtd_info
*
mtd
,
struct
nand_chip
*
this
,
int
page
,
u_char
*
oob_buf
,
struct
nand_oobinfo
*
oobsel
,
int
mode
);
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
static
int
nand_verify_pages
(
struct
mtd_info
*
mtd
,
struct
nand_chip
*
this
,
int
page
,
int
numpages
,
static
int
nand_verify_pages
(
struct
mtd_info
*
mtd
,
struct
nand_chip
*
this
,
int
page
,
int
numpages
,
u_char
*
oob_buf
,
struct
nand_oobinfo
*
oobsel
,
int
chipnr
,
int
oobmode
);
#else
#define nand_verify_pages(...) (0)
#endif
static
int
nand_get_device
(
struct
nand_chip
*
this
,
struct
mtd_info
*
mtd
,
int
new_state
);
/**
* nand_release_device - [GENERIC] release chip
* @mtd: MTD device structure
*
* Deselect, release chip lock and wake up anyone waiting on the device
*
* Deselect, release chip lock and wake up anyone waiting on the device
*/
static
void
nand_release_device
(
struct
mtd_info
*
mtd
)
{
...
...
@@ -215,7 +215,7 @@ static void nand_write_byte(struct mtd_info *mtd, u_char byte)
* nand_read_byte16 - [DEFAULT] read one byte endianess aware from the chip
* @mtd: MTD device structure
*
* Default read function for 16bit buswith with
* Default read function for 16bit buswith with
* endianess conversion
*/
static
u_char
nand_read_byte16
(
struct
mtd_info
*
mtd
)
...
...
@@ -242,7 +242,7 @@ static void nand_write_byte16(struct mtd_info *mtd, u_char byte)
* nand_read_word - [DEFAULT] read one word from the chip
* @mtd: MTD device structure
*
* Default read function for 16bit buswith without
* Default read function for 16bit buswith without
* endianess conversion
*/
static
u16
nand_read_word
(
struct
mtd_info
*
mtd
)
...
...
@@ -256,7 +256,7 @@ static u16 nand_read_word(struct mtd_info *mtd)
* @mtd: MTD device structure
* @word: data word to write
*
* Default write function for 16bit buswith without
* Default write function for 16bit buswith without
* endianess conversion
*/
static
void
nand_write_word
(
struct
mtd_info
*
mtd
,
u16
word
)
...
...
@@ -277,7 +277,7 @@ static void nand_select_chip(struct mtd_info *mtd, int chip)
struct
nand_chip
*
this
=
mtd
->
priv
;
switch
(
chip
)
{
case
-
1
:
this
->
hwcontrol
(
mtd
,
NAND_CTL_CLRNCE
);
this
->
hwcontrol
(
mtd
,
NAND_CTL_CLRNCE
);
break
;
case
0
:
this
->
hwcontrol
(
mtd
,
NAND_CTL_SETNCE
);
...
...
@@ -306,7 +306,7 @@ static void nand_write_buf(struct mtd_info *mtd, const u_char *buf, int len)
}
/**
* nand_read_buf - [DEFAULT] read chip data into buffer
* nand_read_buf - [DEFAULT] read chip data into buffer
* @mtd: MTD device structure
* @buf: buffer to store date
* @len: number of bytes to read
...
...
@@ -323,7 +323,7 @@ static void nand_read_buf(struct mtd_info *mtd, u_char *buf, int len)
}
/**
* nand_verify_buf - [DEFAULT] Verify chip data against buffer
* nand_verify_buf - [DEFAULT] Verify chip data against buffer
* @mtd: MTD device structure
* @buf: buffer containing the data to compare
* @len: number of bytes to compare
...
...
@@ -356,14 +356,14 @@ static void nand_write_buf16(struct mtd_info *mtd, const u_char *buf, int len)
struct
nand_chip
*
this
=
mtd
->
priv
;
u16
*
p
=
(
u16
*
)
buf
;
len
>>=
1
;
for
(
i
=
0
;
i
<
len
;
i
++
)
writew
(
p
[
i
],
this
->
IO_ADDR_W
);
}
/**
* nand_read_buf16 - [DEFAULT] read chip data into buffer
* nand_read_buf16 - [DEFAULT] read chip data into buffer
* @mtd: MTD device structure
* @buf: buffer to store date
* @len: number of bytes to read
...
...
@@ -382,7 +382,7 @@ static void nand_read_buf16(struct mtd_info *mtd, u_char *buf, int len)
}
/**
* nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
* nand_verify_buf16 - [DEFAULT] Verify chip data against buffer
* @mtd: MTD device structure
* @buf: buffer containing the data to compare
* @len: number of bytes to compare
...
...
@@ -409,7 +409,7 @@ static int nand_verify_buf16(struct mtd_info *mtd, const u_char *buf, int len)
* @ofs: offset from device start
* @getchip: 0, if the chip is already selected
*
* Check, if the block is bad.
* Check, if the block is bad.
*/
static
int
nand_block_bad
(
struct
mtd_info
*
mtd
,
loff_t
ofs
,
int
getchip
)
{
...
...
@@ -426,8 +426,8 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
/* Select the NAND device */
this
->
select_chip
(
mtd
,
chipnr
);
}
else
page
=
(
int
)
ofs
;
}
else
page
=
(
int
)
ofs
;
if
(
this
->
options
&
NAND_BUSWIDTH_16
)
{
this
->
cmdfunc
(
mtd
,
NAND_CMD_READOOB
,
this
->
badblockpos
&
0xFE
,
page
&
this
->
pagemask
);
...
...
@@ -441,12 +441,12 @@ static int nand_block_bad(struct mtd_info *mtd, loff_t ofs, int getchip)
if
(
this
->
read_byte
(
mtd
)
!=
0xff
)
res
=
1
;
}
if
(
getchip
)
{
/* Deselect and wake up anyone waiting on the device */
nand_release_device
(
mtd
);
}
}
return
res
;
}
...
...
@@ -464,7 +464,7 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
u_char
buf
[
2
]
=
{
0
,
0
};
size_t
retlen
;
int
block
;
/* Get block number */
block
=
((
int
)
ofs
)
>>
this
->
bbt_erase_shift
;
if
(
this
->
bbt
)
...
...
@@ -473,25 +473,25 @@ static int nand_default_block_markbad(struct mtd_info *mtd, loff_t ofs)
/* Do we have a flash based bad block table ? */
if
(
this
->
options
&
NAND_USE_FLASH_BBT
)
return
nand_update_bbt
(
mtd
,
ofs
);
/* We write two bytes, so we dont have to mess with 16 bit access */
ofs
+=
mtd
->
oobsize
+
(
this
->
badblockpos
&
~
0x01
);
return
nand_write_oob
(
mtd
,
ofs
,
2
,
&
retlen
,
buf
);
}
/**
/**
* nand_check_wp - [GENERIC] check if the chip is write protected
* @mtd: MTD device structure
* Check, if the device is write protected
* Check, if the device is write protected
*
* The function expects, that the device is already selected
* The function expects, that the device is already selected
*/
static
int
nand_check_wp
(
struct
mtd_info
*
mtd
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
/* Check the WP bit */
this
->
cmdfunc
(
mtd
,
NAND_CMD_STATUS
,
-
1
,
-
1
);
return
(
this
->
read_byte
(
mtd
)
&
NAND_STATUS_WP
)
?
0
:
1
;
return
(
this
->
read_byte
(
mtd
)
&
NAND_STATUS_WP
)
?
0
:
1
;
}
/**
...
...
@@ -507,15 +507,15 @@ static int nand_check_wp (struct mtd_info *mtd)
static
int
nand_block_checkbad
(
struct
mtd_info
*
mtd
,
loff_t
ofs
,
int
getchip
,
int
allowbbt
)
{
struct
nand_chip
*
this
=
mtd
->
priv
;
if
(
!
this
->
bbt
)
return
this
->
block_bad
(
mtd
,
ofs
,
getchip
);
/* Return info from the table */
return
nand_isbad_bbt
(
mtd
,
ofs
,
allowbbt
);
}
/*
/*
* Wait for the ready pin, after a command
* The timeout is catched later.
*/
...
...
@@ -529,7 +529,7 @@ static void nand_wait_ready(struct mtd_info *mtd)
if
(
this
->
dev_ready
(
mtd
))
return
;
touch_softlockup_watchdog
();
}
while
(
time_before
(
jiffies
,
timeo
));
}
while
(
time_before
(
jiffies
,
timeo
));
}
/**
...
...
@@ -592,13 +592,13 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
/* Latch in address */
this
->
hwcontrol
(
mtd
,
NAND_CTL_CLRALE
);
}
/*
* program and erase have their own busy handlers
/*
* program and erase have their own busy handlers
* status and sequential in needs no delay
*/
switch
(
command
)
{
case
NAND_CMD_PAGEPROG
:
case
NAND_CMD_ERASE1
:
case
NAND_CMD_ERASE2
:
...
...
@@ -607,7 +607,7 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
return
;
case
NAND_CMD_RESET
:
if
(
this
->
dev_ready
)
if
(
this
->
dev_ready
)
break
;
udelay
(
this
->
chip_delay
);
this
->
hwcontrol
(
mtd
,
NAND_CTL_SETCLE
);
...
...
@@ -616,16 +616,16 @@ static void nand_command (struct mtd_info *mtd, unsigned command, int column, in
while
(
!
(
this
->
read_byte
(
mtd
)
&
NAND_STATUS_READY
));
return
;
/* This applies to read commands */
/* This applies to read commands */
default:
/*
/*
* If we don't have access to the busy pin, we apply the given
* command delay
*/
if
(
!
this
->
dev_ready
)
{
udelay
(
this
->
chip_delay
);
return
;
}
}
}
/* Apply this short delay always to ensure that we do wait tWB in
* any case on any machine. */
...
...
@@ -655,8 +655,8 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
column
+=
mtd
->
oobblock
;
command
=
NAND_CMD_READ0
;
}
/* Begin command latch cycle */
this
->
hwcontrol
(
mtd
,
NAND_CTL_SETCLE
);
/* Write out the command to the device. */
...
...
@@ -674,7 +674,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
column
>>=
1
;
this
->
write_byte
(
mtd
,
column
&
0xff
);
this
->
write_byte
(
mtd
,
column
>>
8
);
}
}
if
(
page_addr
!=
-
1
)
{
this
->
write_byte
(
mtd
,
(
unsigned
char
)
(
page_addr
&
0xff
));
this
->
write_byte
(
mtd
,
(
unsigned
char
)
((
page_addr
>>
8
)
&
0xff
));
...
...
@@ -685,13 +685,13 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
/* Latch in address */
this
->
hwcontrol
(
mtd
,
NAND_CTL_CLRALE
);
}
/*
* program and erase have their own busy handlers
/*
* program and erase have their own busy handlers
* status, sequential in, and deplete1 need no delay
*/
switch
(
command
)
{
case
NAND_CMD_CACHEDPROG
:
case
NAND_CMD_PAGEPROG
:
case
NAND_CMD_ERASE1
:
...
...
@@ -701,7 +701,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
case
NAND_CMD_DEPLETE1
:
return
;
/*
/*
* read error status commands require only a short delay
*/
case
NAND_CMD_STATUS_ERROR
:
...
...
@@ -713,7 +713,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
return
;
case
NAND_CMD_RESET
:
if
(
this
->
dev_ready
)
if
(
this
->
dev_ready
)
break
;
udelay
(
this
->
chip_delay
);
this
->
hwcontrol
(
mtd
,
NAND_CTL_SETCLE
);
...
...
@@ -730,17 +730,17 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
/* End command latch cycle */
this
->
hwcontrol
(
mtd
,
NAND_CTL_CLRCLE
);
/* Fall through into ready check */
/* This applies to read commands */
/* This applies to read commands */
default:
/*
/*
* If we don't have access to the busy pin, we apply the given
* command delay
*/
if
(
!
this
->
dev_ready
)
{
udelay
(
this
->
chip_delay
);
return
;
}
}
}
/* Apply this short delay always to ensure that we do wait tWB in
...
...
@@ -754,7 +754,7 @@ static void nand_command_lp (struct mtd_info *mtd, unsigned command, int column,
* nand_get_device - [GENERIC] Get chip for selected access
* @this: the nand chip descriptor
* @mtd: MTD device structure
* @new_state: the state which is requested
* @new_state: the state which is requested
*
* Get the device and lock it for exclusive access
*/
...
...
@@ -802,7 +802,7 @@ retry:
* @state: state to select the max. timeout value
*
* Wait for command done. This applies to erase and program only
* Erase can take up to 400ms and program up to 20ms according to
* Erase can take up to 400ms and program up to 20ms according to
* general NAND and SmartMedia specs
*
*/
...
...
@@ -811,7 +811,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
unsigned
long
timeo
=
jiffies
;
int
status
;
if
(
state
==
FL_ERASING
)
timeo
+=
(
HZ
*
400
)
/
1000
;
else
...
...
@@ -823,17 +823,17 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
if
((
state
==
FL_ERASING
)
&&
(
this
->
options
&
NAND_IS_AND
))
this
->
cmdfunc
(
mtd
,
NAND_CMD_STATUS_MULTI
,
-
1
,
-
1
);
else
else
this
->
cmdfunc
(
mtd
,
NAND_CMD_STATUS
,
-
1
,
-
1
);
while
(
time_before
(
jiffies
,
timeo
))
{
while
(
time_before
(
jiffies
,
timeo
))
{
/* Check, if we were interrupted */
if
(
this
->
state
!=
state
)
return
0
;
if
(
this
->
dev_ready
)
{
if
(
this
->
dev_ready
(
mtd
))
break
;
break
;
}
else
{
if
(
this
->
read_byte
(
mtd
)
&
NAND_STATUS_READY
)
break
;
...
...
@@ -859,7 +859,7 @@ static int nand_wait(struct mtd_info *mtd, struct nand_chip *this, int state)
*
* Cached programming is not supported yet.
*/
static
int
nand_write_page
(
struct
mtd_info
*
mtd
,
struct
nand_chip
*
this
,
int
page
,
static
int
nand_write_page
(
struct
mtd_info
*
mtd
,
struct
nand_chip
*
this
,
int
page
,
u_char
*
oob_buf
,
struct
nand_oobinfo
*
oobsel
,
int
cached
)
{
int
i
,
status
;
...
...
@@ -868,10 +868,10 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
int
*
oob_config
=
oobsel
->
eccpos
;
int
datidx
=
0
,
eccidx
=
0
,
eccsteps
=
this
->
eccsteps
;
int
eccbytes
=
0
;
/* FIXME: Enable cached programming */
cached
=
0
;
/* Send command to begin auto page programming */
this
->
cmdfunc
(
mtd
,
NAND_CMD_SEQIN
,
0x00
,
page
);
...
...
@@ -882,7 +882,7 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
printk
(
KERN_WARNING
"Writing data without ECC to NAND-FLASH is not recommended
\n
"
);
this
->
write_buf
(
mtd
,
this
->
data_poi
,
mtd
->
oobblock
);
break
;
/* Software ecc 3/256, write all */
case
NAND_ECC_SOFT
:
for
(;
eccsteps
;
eccsteps
--
)
{
...
...
@@ -911,11 +911,11 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
}
break
;
}
/* Write out OOB data */
if
(
this
->
options
&
NAND_HWECC_SYNDROME
)
this
->
write_buf
(
mtd
,
&
oob_buf
[
oobsel
->
eccbytes
],
mtd
->
oobsize
-
oobsel
->
eccbytes
);
else
else
this
->
write_buf
(
mtd
,
oob_buf
,
mtd
->
oobsize
);
/* Send command to actually program the data */
...
...
@@ -940,7 +940,7 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
/* wait until cache is ready*/
// status = this->waitfunc (mtd, this, FL_CACHEDRPG);
}
return
0
;
return
0
;
}
#ifdef CONFIG_MTD_NAND_VERIFY_WRITE
...
...
@@ -956,19 +956,19 @@ static int nand_write_page (struct mtd_info *mtd, struct nand_chip *this, int pa
* @oobmode: 1 = full buffer verify, 0 = ecc only
*
* The NAND device assumes that it is always writing to a cleanly erased page.
* Hence, it performs its internal write verification only on bits that
* Hence, it performs its internal write verification only on bits that
* transitioned from 1 to 0. The device does NOT verify the whole page on a
* byte by byte basis. It is possible that the page was not completely erased
* or the page is becoming unusable due to wear. The read with ECC would catch
* the error later when the ECC page check fails, but we would rather catch
* byte by byte basis. It is possible that the page was not completely erased
* or the page is becoming unusable due to wear. The read with ECC would catch
* the error later when the ECC page check fails, but we would rather catch
* it early in the page write stage. Better to write no data than invalid data.
*/
static
int
nand_verify_pages
(
struct
mtd_info
*
mtd
,
struct
nand_chip
*
this
,
int
page
,
int
numpages
,
static
int
nand_verify_pages
(
struct
mtd_info
*
mtd
,
struct
nand_chip
*
this
,
int
page
,
int
numpages
,
u_char
*
oob_buf
,
struct
nand_oobinfo
*
oobsel
,
int
chipnr
,
int
oobmode
)
{
int
i
,
j
,
datidx
=
0
,
oobofs
=
0
,
res
=
-
EIO
;
int
eccsteps
=
this
->
eccsteps
;
int
hweccbytes
;
int
hweccbytes
;
u_char
oobdata
[
64
];
hweccbytes
=
(
this
->
options
&
NAND_HWECC_SYNDROME
)
?
(
oobsel
->
eccbytes
/
eccsteps
)
:
0
;
...
...
@@ -1008,7 +1008,7 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
if
(
oobsel
->
useecc
!=
MTD_NANDECC_OFF
&&
!
hweccbytes
)
{
int
ecccnt
=
oobsel
->
eccbytes
;
for
(
i
=
0
;
i
<
ecccnt
;
i
++
)
{
int
idx
=
oobsel
->
eccpos
[
i
];
if
(
oobdata
[
idx
]
!=
oob_buf
[
oobofs
+
idx
]
)
{
...
...
@@ -1018,20 +1018,20 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
goto
out
;
}
}
}
}
}
oobofs
+=
mtd
->
oobsize
-
hweccbytes
*
eccsteps
;
page
++
;
numpages
--
;
/* Apply delay or wait for ready/busy pin
/* Apply delay or wait for ready/busy pin
* Do this before the AUTOINCR check, so no problems
* arise if a chip which does auto increment
* is marked as NOAUTOINCR by the board driver.
* Do this also before returning, so the chip is
* ready for the next command.
*/
if
(
!
this
->
dev_ready
)
if
(
!
this
->
dev_ready
)
udelay
(
this
->
chip_delay
);
else
nand_wait_ready
(
mtd
);
...
...
@@ -1039,17 +1039,17 @@ static int nand_verify_pages (struct mtd_info *mtd, struct nand_chip *this, int
/* All done, return happy */
if
(
!
numpages
)
return
0
;
/* Check, if the chip supports auto page increment */
/* Check, if the chip supports auto page increment */
if
(
!
NAND_CANAUTOINCR
(
this
))
this
->
cmdfunc
(
mtd
,
NAND_CMD_READ0
,
0x00
,
page
);
}
/*
/*
* Terminate the read command. We come here in case of an error
* So we must issue a reset command.
*/
out:
out:
this
->
cmdfunc
(
mtd
,
NAND_CMD_RESET
,
-
1
,
-
1
);
return
res
;
}
...
...
@@ -1111,7 +1111,7 @@ static int nand_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
* NAND read with ECC
*/
int
nand_do_read_ecc
(
struct
mtd_info
*
mtd
,
loff_t
from
,
size_t
len
,
size_t
*
retlen
,
u_char
*
buf
,
u_char
*
oob_buf
,
size_t
*
retlen
,
u_char
*
buf
,
u_char
*
oob_buf
,
struct
nand_oobinfo
*
oobsel
,
int
flags
)
{
...
...
@@ -1145,7 +1145,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
/* Autoplace of oob data ? Use the default placement scheme */
if
(
oobsel
->
useecc
==
MTD_NANDECC_AUTOPLACE
)
oobsel
=
this
->
autooob
;
eccmode
=
oobsel
->
useecc
?
this
->
eccmode
:
NAND_ECC_NONE
;
oob_config
=
oobsel
->
eccpos
;
...
...
@@ -1163,28 +1163,28 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
end
=
mtd
->
oobblock
;
ecc
=
this
->
eccsize
;
eccbytes
=
this
->
eccbytes
;
if
((
eccmode
==
NAND_ECC_NONE
)
||
(
this
->
options
&
NAND_HWECC_SYNDROME
))
compareecc
=
0
;
oobreadlen
=
mtd
->
oobsize
;
if
(
this
->
options
&
NAND_HWECC_SYNDROME
)
if
(
this
->
options
&
NAND_HWECC_SYNDROME
)
oobreadlen
-=
oobsel
->
eccbytes
;
/* Loop until all data read */
while
(
read
<
len
)
{
int
aligned
=
(
!
col
&&
(
len
-
read
)
>=
end
);
/*
/*
* If the read is not page aligned, we have to read into data buffer
* due to ecc, else we read into return buffer direct
*/
if
(
aligned
)
data_poi
=
&
buf
[
read
];
else
else
data_poi
=
this
->
data_buf
;
/* Check, if we have this page in the buffer
/* Check, if we have this page in the buffer
*
* FIXME: Make it work when we must provide oob data too,
* check the usage of data_buf oob field
...
...
@@ -1200,7 +1200,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
if
(
sndcmd
)
{
this
->
cmdfunc
(
mtd
,
NAND_CMD_READ0
,
0x00
,
page
);
sndcmd
=
0
;
}
}
/* get oob area, if we have no oob buffer from fs-driver */
if
(
!
oob_buf
||
oobsel
->
useecc
==
MTD_NANDECC_AUTOPLACE
||
...
...
@@ -1208,7 +1208,7 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
oob_data
=
&
this
->
data_buf
[
end
];
eccsteps
=
this
->
eccsteps
;
switch
(
eccmode
)
{
case
NAND_ECC_NONE
:
{
/* No ECC, Read in a page */
static
unsigned
long
lastwhinge
=
0
;
...
...
@@ -1219,12 +1219,12 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
this
->
read_buf
(
mtd
,
data_poi
,
end
);
break
;
}
case
NAND_ECC_SOFT
:
/* Software ECC 3/256: Read in a page + oob data */
this
->
read_buf
(
mtd
,
data_poi
,
end
);
for
(
i
=
0
,
datidx
=
0
;
eccsteps
;
eccsteps
--
,
i
+=
3
,
datidx
+=
ecc
)
for
(
i
=
0
,
datidx
=
0
;
eccsteps
;
eccsteps
--
,
i
+=
3
,
datidx
+=
ecc
)
this
->
calculate_ecc
(
mtd
,
&
data_poi
[
datidx
],
&
ecc_calc
[
i
]);
break
;
break
;
default:
for
(
i
=
0
,
datidx
=
0
;
eccsteps
;
eccsteps
--
,
i
+=
eccbytes
,
datidx
+=
ecc
)
{
...
...
@@ -1243,15 +1243,15 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
* does the error correction on the fly */
ecc_status
=
this
->
correct_data
(
mtd
,
&
data_poi
[
datidx
],
&
oob_data
[
i
],
&
ecc_code
[
i
]);
if
((
ecc_status
==
-
1
)
||
(
ecc_status
>
(
flags
&&
0xff
)))
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_read_ecc: "
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_read_ecc: "
"Failed ECC read, page 0x%08x on chip %d
\n
"
,
page
,
chipnr
);
ecc_failed
++
;
}
}
else
{
this
->
calculate_ecc
(
mtd
,
&
data_poi
[
datidx
],
&
ecc_calc
[
i
]);
}
}
}
break
;
break
;
}
/* read oobdata */
...
...
@@ -1259,8 +1259,8 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
/* Skip ECC check, if not requested (ECC_NONE or HW_ECC with syndromes) */
if
(
!
compareecc
)
goto
readoob
;
goto
readoob
;
/* Pick the ECC bytes out of the oob data */
for
(
j
=
0
;
j
<
oobsel
->
eccbytes
;
j
++
)
ecc_code
[
j
]
=
oob_data
[
oob_config
[
j
]];
...
...
@@ -1268,24 +1268,24 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
/* correct data, if neccecary */
for
(
i
=
0
,
j
=
0
,
datidx
=
0
;
i
<
this
->
eccsteps
;
i
++
,
datidx
+=
ecc
)
{
ecc_status
=
this
->
correct_data
(
mtd
,
&
data_poi
[
datidx
],
&
ecc_code
[
j
],
&
ecc_calc
[
j
]);
/* Get next chunk of ecc bytes */
j
+=
eccbytes
;
/* Check, if we have a fs supplied oob-buffer,
/* Check, if we have a fs supplied oob-buffer,
* This is the legacy mode. Used by YAFFS1
* Should go away some day
*/
if
(
oob_buf
&&
oobsel
->
useecc
==
MTD_NANDECC_PLACE
)
{
if
(
oob_buf
&&
oobsel
->
useecc
==
MTD_NANDECC_PLACE
)
{
int
*
p
=
(
int
*
)(
&
oob_data
[
mtd
->
oobsize
]);
p
[
i
]
=
ecc_status
;
}
if
((
ecc_status
==
-
1
)
||
(
ecc_status
>
(
flags
&&
0xff
)))
{
if
((
ecc_status
==
-
1
)
||
(
ecc_status
>
(
flags
&&
0xff
)))
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_read_ecc: "
"Failed ECC read, page 0x%08x
\n
"
,
page
);
ecc_failed
++
;
}
}
}
readoob:
/* check, if we have a fs supplied oob-buffer */
...
...
@@ -1311,25 +1311,25 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
}
readdata:
/* Partial page read, transfer data into fs buffer */
if
(
!
aligned
)
{
if
(
!
aligned
)
{
for
(
j
=
col
;
j
<
end
&&
read
<
len
;
j
++
)
buf
[
read
++
]
=
data_poi
[
j
];
this
->
pagebuf
=
realpage
;
}
else
this
->
pagebuf
=
realpage
;
}
else
read
+=
mtd
->
oobblock
;
/* Apply delay or wait for ready/busy pin
/* Apply delay or wait for ready/busy pin
* Do this before the AUTOINCR check, so no problems
* arise if a chip which does auto increment
* is marked as NOAUTOINCR by the board driver.
*/
if
(
!
this
->
dev_ready
)
if
(
!
this
->
dev_ready
)
udelay
(
this
->
chip_delay
);
else
nand_wait_ready
(
mtd
);
if
(
read
==
len
)
break
;
break
;
/* For subsequent reads align to page boundary. */
col
=
0
;
...
...
@@ -1343,11 +1343,11 @@ int nand_do_read_ecc (struct mtd_info *mtd, loff_t from, size_t len,
this
->
select_chip
(
mtd
,
-
1
);
this
->
select_chip
(
mtd
,
chipnr
);
}
/* Check, if the chip supports auto page increment
* or if we have hit a block boundary.
*/
/* Check, if the chip supports auto page increment
* or if we have hit a block boundary.
*/
if
(
!
NAND_CANAUTOINCR
(
this
)
||
!
(
page
&
blockcheck
))
sndcmd
=
1
;
sndcmd
=
1
;
}
/* Deselect and wake up anyone waiting on the device */
...
...
@@ -1384,7 +1384,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
/* Shift to get page */
page
=
(
int
)(
from
>>
this
->
page_shift
);
chipnr
=
(
int
)(
from
>>
this
->
chip_shift
);
/* Mask to get column */
col
=
from
&
(
mtd
->
oobsize
-
1
);
...
...
@@ -1406,7 +1406,7 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
/* Send the read command */
this
->
cmdfunc
(
mtd
,
NAND_CMD_READOOB
,
col
,
page
&
this
->
pagemask
);
/*
/*
* Read the data, if we read more than one page
* oob data, let the device transfer the data !
*/
...
...
@@ -1428,20 +1428,20 @@ static int nand_read_oob (struct mtd_info *mtd, loff_t from, size_t len, size_t
this
->
select_chip
(
mtd
,
-
1
);
this
->
select_chip
(
mtd
,
chipnr
);
}
/* Apply delay or wait for ready/busy pin
/* Apply delay or wait for ready/busy pin
* Do this before the AUTOINCR check, so no problems
* arise if a chip which does auto increment
* is marked as NOAUTOINCR by the board driver.
*/
if
(
!
this
->
dev_ready
)
if
(
!
this
->
dev_ready
)
udelay
(
this
->
chip_delay
);
else
nand_wait_ready
(
mtd
);
/* Check, if the chip supports auto page increment
* or if we have hit a block boundary.
*/
/* Check, if the chip supports auto page increment
* or if we have hit a block boundary.
*/
if
(
!
NAND_CANAUTOINCR
(
this
)
||
!
(
page
&
blockcheck
))
{
/* For subsequent page reads set offset to 0 */
this
->
cmdfunc
(
mtd
,
NAND_CMD_READOOB
,
0x0
,
page
&
this
->
pagemask
);
...
...
@@ -1487,27 +1487,27 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len,
nand_get_device
(
this
,
mtd
,
FL_READING
);
this
->
select_chip
(
mtd
,
chip
);
/* Add requested oob length */
len
+=
ooblen
;
while
(
len
)
{
if
(
sndcmd
)
this
->
cmdfunc
(
mtd
,
NAND_CMD_READ0
,
0
,
page
&
this
->
pagemask
);
sndcmd
=
0
;
sndcmd
=
0
;
this
->
read_buf
(
mtd
,
&
buf
[
cnt
],
pagesize
);
len
-=
pagesize
;
cnt
+=
pagesize
;
page
++
;
if
(
!
this
->
dev_ready
)
if
(
!
this
->
dev_ready
)
udelay
(
this
->
chip_delay
);
else
nand_wait_ready
(
mtd
);
/* Check, if the chip supports auto page increment */
/* Check, if the chip supports auto page increment */
if
(
!
NAND_CANAUTOINCR
(
this
)
||
!
(
page
&
blockcheck
))
sndcmd
=
1
;
}
...
...
@@ -1518,8 +1518,8 @@ int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len,
}
/**
* nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer
/**
* nand_prepare_oobbuf - [GENERIC] Prepare the out of band buffer
* @mtd: MTD device structure
* @fsbuf: buffer given by fs driver
* @oobsel: out of band selection structre
...
...
@@ -1548,20 +1548,20 @@ static u_char * nand_prepare_oobbuf (struct mtd_info *mtd, u_char *fsbuf, struct
int
i
,
len
,
ofs
;
/* Zero copy fs supplied buffer */
if
(
fsbuf
&&
!
autoplace
)
if
(
fsbuf
&&
!
autoplace
)
return
fsbuf
;
/* Check, if the buffer must be filled with ff again */
if
(
this
->
oobdirty
)
{
memset
(
this
->
oob_buf
,
0xff
,
if
(
this
->
oobdirty
)
{
memset
(
this
->
oob_buf
,
0xff
,
mtd
->
oobsize
<<
(
this
->
phys_erase_shift
-
this
->
page_shift
));
this
->
oobdirty
=
0
;
}
}
/* If we have no autoplacement or no fs buffer use the internal one */
if
(
!
autoplace
||
!
fsbuf
)
return
this
->
oob_buf
;
/* Walk through the pages and place the data */
this
->
oobdirty
=
1
;
ofs
=
0
;
...
...
@@ -1595,7 +1595,7 @@ static int nand_write (struct mtd_info *mtd, loff_t to, size_t len, size_t * ret
{
return
(
nand_write_ecc
(
mtd
,
to
,
len
,
retlen
,
buf
,
NULL
,
NULL
));
}
/**
* nand_write_ecc - [MTD Interface] NAND write with ECC
* @mtd: MTD device structure
...
...
@@ -1628,7 +1628,7 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
return
-
EINVAL
;
}
/* reject writes, which are not page aligned */
/* reject writes, which are not page aligned */
if
(
NOTALIGNED
(
to
)
||
NOTALIGNED
(
len
))
{
printk
(
KERN_NOTICE
"nand_write_ecc: Attempt to write not page aligned data
\n
"
);
return
-
EINVAL
;
...
...
@@ -1647,14 +1647,14 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
goto
out
;
/* if oobsel is NULL, use chip defaults */
if
(
oobsel
==
NULL
)
oobsel
=
&
mtd
->
oobinfo
;
if
(
oobsel
==
NULL
)
oobsel
=
&
mtd
->
oobinfo
;
/* Autoplace of oob data ? Use the default placement scheme */
if
(
oobsel
->
useecc
==
MTD_NANDECC_AUTOPLACE
)
{
oobsel
=
this
->
autooob
;
autoplace
=
1
;
}
}
if
(
oobsel
->
useecc
==
MTD_NANDECC_AUTOPL_USR
)
autoplace
=
1
;
...
...
@@ -1662,9 +1662,9 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
totalpages
=
len
>>
this
->
page_shift
;
page
=
(
int
)
(
to
>>
this
->
page_shift
);
/* Invalidate the page cache, if we write to the cached page */
if
(
page
<=
this
->
pagebuf
&&
this
->
pagebuf
<
(
page
+
totalpages
))
if
(
page
<=
this
->
pagebuf
&&
this
->
pagebuf
<
(
page
+
totalpages
))
this
->
pagebuf
=
-
1
;
/* Set it relative to chip */
page
&=
this
->
pagemask
;
startpage
=
page
;
...
...
@@ -1686,14 +1686,14 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
if
(
ret
)
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_write_ecc: write_page failed %d
\n
"
,
ret
);
goto
out
;
}
}
/* Next oob page */
oob
+=
mtd
->
oobsize
;
/* Update written bytes count */
written
+=
mtd
->
oobblock
;
if
(
written
==
len
)
if
(
written
==
len
)
goto
cmp
;
/* Increment page address */
page
++
;
...
...
@@ -1704,13 +1704,13 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
if
(
!
(
page
&
(
ppblock
-
1
))){
int
ofs
;
this
->
data_poi
=
bufstart
;
ret
=
nand_verify_pages
(
mtd
,
this
,
startpage
,
ret
=
nand_verify_pages
(
mtd
,
this
,
startpage
,
page
-
startpage
,
oobbuf
,
oobsel
,
chipnr
,
(
eccbuf
!=
NULL
));
if
(
ret
)
{
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_write_ecc: verify_pages failed %d
\n
"
,
ret
);
goto
out
;
}
}
*
retlen
=
written
;
ofs
=
autoplace
?
mtd
->
oobavail
:
mtd
->
oobsize
;
...
...
@@ -1720,7 +1720,7 @@ static int nand_write_ecc (struct mtd_info *mtd, loff_t to, size_t len,
numpages
=
min
(
totalpages
,
ppblock
);
page
&=
this
->
pagemask
;
startpage
=
page
;
oobbuf
=
nand_prepare_oobbuf
(
mtd
,
eccbuf
,
oobsel
,
oobbuf
=
nand_prepare_oobbuf
(
mtd
,
eccbuf
,
oobsel
,
autoplace
,
numpages
);
oob
=
0
;
/* Check, if we cross a chip boundary */
...
...
@@ -1738,7 +1738,7 @@ cmp:
oobbuf
,
oobsel
,
chipnr
,
(
eccbuf
!=
NULL
));
if
(
!
ret
)
*
retlen
=
written
;
else
else
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_write_ecc: verify_pages failed %d
\n
"
,
ret
);
out:
...
...
@@ -1798,7 +1798,7 @@ static int nand_write_oob (struct mtd_info *mtd, loff_t to, size_t len, size_t *
/* Check, if it is write protected */
if
(
nand_check_wp
(
mtd
))
goto
out
;
/* Invalidate the page cache, if we write to the cached page */
if
(
page
==
this
->
pagebuf
)
this
->
pagebuf
=
-
1
;
...
...
@@ -1861,10 +1861,10 @@ out:
*
* NAND write with kvec. This just calls the ecc function
*/
static
int
nand_writev
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
static
int
nand_writev
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
)
{
return
(
nand_writev_ecc
(
mtd
,
vecs
,
count
,
to
,
retlen
,
NULL
,
NULL
));
return
(
nand_writev_ecc
(
mtd
,
vecs
,
count
,
to
,
retlen
,
NULL
,
NULL
));
}
/**
...
...
@@ -1879,7 +1879,7 @@ static int nand_writev (struct mtd_info *mtd, const struct kvec *vecs, unsigned
*
* NAND write with iovec with ecc
*/
static
int
nand_writev_ecc
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
static
int
nand_writev_ecc
(
struct
mtd_info
*
mtd
,
const
struct
kvec
*
vecs
,
unsigned
long
count
,
loff_t
to
,
size_t
*
retlen
,
u_char
*
eccbuf
,
struct
nand_oobinfo
*
oobsel
)
{
int
i
,
page
,
len
,
total_len
,
ret
=
-
EIO
,
written
=
0
,
chipnr
;
...
...
@@ -1905,7 +1905,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
return
-
EINVAL
;
}
/* reject writes, which are not page aligned */
/* reject writes, which are not page aligned */
if
(
NOTALIGNED
(
to
)
||
NOTALIGNED
(
total_len
))
{
printk
(
KERN_NOTICE
"nand_write_ecc: Attempt to write not page aligned data
\n
"
);
return
-
EINVAL
;
...
...
@@ -1924,21 +1924,21 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
goto
out
;
/* if oobsel is NULL, use chip defaults */
if
(
oobsel
==
NULL
)
oobsel
=
&
mtd
->
oobinfo
;
if
(
oobsel
==
NULL
)
oobsel
=
&
mtd
->
oobinfo
;
/* Autoplace of oob data ? Use the default placement scheme */
if
(
oobsel
->
useecc
==
MTD_NANDECC_AUTOPLACE
)
{
oobsel
=
this
->
autooob
;
autoplace
=
1
;
}
}
if
(
oobsel
->
useecc
==
MTD_NANDECC_AUTOPL_USR
)
autoplace
=
1
;
/* Setup start page */
page
=
(
int
)
(
to
>>
this
->
page_shift
);
/* Invalidate the page cache, if we write to the cached page */
if
(
page
<=
this
->
pagebuf
&&
this
->
pagebuf
<
((
to
+
total_len
)
>>
this
->
page_shift
))
if
(
page
<=
this
->
pagebuf
&&
this
->
pagebuf
<
((
to
+
total_len
)
>>
this
->
page_shift
))
this
->
pagebuf
=
-
1
;
startpage
=
page
&
this
->
pagemask
;
...
...
@@ -1962,10 +1962,10 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
oob
=
0
;
for
(
i
=
1
;
i
<=
numpages
;
i
++
)
{
/* Write one page. If this is the last page to write
* then use the real pageprogram command, else select
* then use the real pageprogram command, else select
* cached programming if supported by the chip.
*/
ret
=
nand_write_page
(
mtd
,
this
,
page
&
this
->
pagemask
,
ret
=
nand_write_page
(
mtd
,
this
,
page
&
this
->
pagemask
,
&
oobbuf
[
oob
],
oobsel
,
i
!=
numpages
);
if
(
ret
)
goto
out
;
...
...
@@ -1981,12 +1981,12 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
count
--
;
}
}
else
{
/* We must use the internal buffer, read data out of each
/* We must use the internal buffer, read data out of each
* tuple until we have a full page to write
*/
int
cnt
=
0
;
while
(
cnt
<
mtd
->
oobblock
)
{
if
(
vecs
->
iov_base
!=
NULL
&&
vecs
->
iov_len
)
if
(
vecs
->
iov_base
!=
NULL
&&
vecs
->
iov_len
)
this
->
data_buf
[
cnt
++
]
=
((
u_char
*
)
vecs
->
iov_base
)[
len
++
];
/* Check, if we have to switch to the next tuple */
if
(
len
>=
(
int
)
vecs
->
iov_len
)
{
...
...
@@ -1995,10 +1995,10 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
count
--
;
}
}
this
->
pagebuf
=
page
;
this
->
data_poi
=
this
->
data_buf
;
this
->
pagebuf
=
page
;
this
->
data_poi
=
this
->
data_buf
;
bufstart
=
this
->
data_poi
;
numpages
=
1
;
numpages
=
1
;
oobbuf
=
nand_prepare_oobbuf
(
mtd
,
NULL
,
oobsel
,
autoplace
,
numpages
);
ret
=
nand_write_page
(
mtd
,
this
,
page
&
this
->
pagemask
,
oobbuf
,
oobsel
,
0
);
...
...
@@ -2011,7 +2011,7 @@ static int nand_writev_ecc (struct mtd_info *mtd, const struct kvec *vecs, unsig
ret
=
nand_verify_pages
(
mtd
,
this
,
startpage
,
numpages
,
oobbuf
,
oobsel
,
chipnr
,
0
);
if
(
ret
)
goto
out
;
written
+=
mtd
->
oobblock
*
numpages
;
/* All done ? */
if
(
!
count
)
...
...
@@ -2079,7 +2079,7 @@ static int nand_erase (struct mtd_info *mtd, struct erase_info *instr)
{
return
nand_erase_nand
(
mtd
,
instr
,
0
);
}
#define BBT_PAGE_MASK 0xffffff3f
/**
* nand_erase_intern - [NAND Interface] erase block(s)
...
...
@@ -2161,14 +2161,14 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
instr
->
state
=
MTD_ERASE_FAILED
;
goto
erase_exit
;
}
/* Invalidate the page cache, if we erase the block which contains
/* Invalidate the page cache, if we erase the block which contains
the current cached page */
if
(
page
<=
this
->
pagebuf
&&
this
->
pagebuf
<
(
page
+
pages_per_block
))
this
->
pagebuf
=
-
1
;
this
->
erase_cmd
(
mtd
,
page
&
this
->
pagemask
);
status
=
this
->
waitfunc
(
mtd
,
this
,
FL_ERASING
);
/* See if operation failed and additional status checks are available */
...
...
@@ -2186,12 +2186,12 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
/* if BBT requires refresh, set the BBT rewrite flag to the page being erased */
if
(
this
->
options
&
BBT_AUTO_REFRESH
)
{
if
(((
page
&
BBT_PAGE_MASK
)
==
bbt_masked_page
)
&&
if
(((
page
&
BBT_PAGE_MASK
)
==
bbt_masked_page
)
&&
(
page
!=
this
->
bbt_td
->
pages
[
chipnr
]))
{
rewrite_bbt
[
chipnr
]
=
(
page
<<
this
->
page_shift
);
}
}
/* Increment page address and decrement length */
len
-=
(
1
<<
this
->
phys_erase_shift
);
page
+=
pages_per_block
;
...
...
@@ -2202,7 +2202,7 @@ int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbb
this
->
select_chip
(
mtd
,
-
1
);
this
->
select_chip
(
mtd
,
chipnr
);
/* if BBT requires refresh and BBT-PERCHIP,
/* if BBT requires refresh and BBT-PERCHIP,
* set the BBT page mask to see if this BBT should be rewritten */
if
((
this
->
options
&
BBT_AUTO_REFRESH
)
&&
(
this
->
bbt_td
->
options
&
NAND_BBT_PERCHIP
))
{
bbt_masked_page
=
this
->
bbt_td
->
pages
[
chipnr
]
&
BBT_PAGE_MASK
;
...
...
@@ -2227,7 +2227,7 @@ erase_exit:
for
(
chipnr
=
0
;
chipnr
<
this
->
numchips
;
chipnr
++
)
{
if
(
rewrite_bbt
[
chipnr
])
{
/* update the BBT for chip */
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)
\n
"
,
DEBUG
(
MTD_DEBUG_LEVEL0
,
"nand_erase_nand: nand_update_bbt (%d:0x%0x 0x%0x)
\n
"
,
chipnr
,
rewrite_bbt
[
chipnr
],
this
->
bbt_td
->
pages
[
chipnr
]);
nand_update_bbt
(
mtd
,
rewrite_bbt
[
chipnr
]);
}
...
...
@@ -2265,9 +2265,9 @@ static void nand_sync (struct mtd_info *mtd)
static
int
nand_block_isbad
(
struct
mtd_info
*
mtd
,
loff_t
ofs
)
{
/* Check for invalid offset */
if
(
ofs
>
mtd
->
size
)
if
(
ofs
>
mtd
->
size
)
return
-
EINVAL
;
return
nand_block_checkbad
(
mtd
,
ofs
,
1
,
0
);
}
...
...
@@ -2386,13 +2386,13 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
/* Print and store flash device information */
for
(
i
=
0
;
nand_flash_ids
[
i
].
name
!=
NULL
;
i
++
)
{
if
(
nand_dev_id
!=
nand_flash_ids
[
i
].
id
)
if
(
nand_dev_id
!=
nand_flash_ids
[
i
].
id
)
continue
;
if
(
!
mtd
->
name
)
mtd
->
name
=
nand_flash_ids
[
i
].
name
;
this
->
chipsize
=
nand_flash_ids
[
i
].
chipsize
<<
20
;
/* New devices have all the information in additional id bytes */
if
(
!
nand_flash_ids
[
i
].
pagesize
)
{
int
extid
;
...
...
@@ -2411,7 +2411,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
extid
>>=
2
;
/* Get buswidth information */
busw
=
(
extid
&
0x01
)
?
NAND_BUSWIDTH_16
:
0
;
}
else
{
/* Old devices have this data hardcoded in the
* device id table */
...
...
@@ -2431,23 +2431,23 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
* this correct ! */
if
(
busw
!=
(
this
->
options
&
NAND_BUSWIDTH_16
))
{
printk
(
KERN_INFO
"NAND device: Manufacturer ID:"
" 0x%02x, Chip ID: 0x%02x (%s %s)
\n
"
,
nand_maf_id
,
nand_dev_id
,
" 0x%02x, Chip ID: 0x%02x (%s %s)
\n
"
,
nand_maf_id
,
nand_dev_id
,
nand_manuf_ids
[
maf_id
].
name
,
mtd
->
name
);
printk
(
KERN_WARNING
"NAND bus width %d instead %d bit
\n
"
,
printk
(
KERN_WARNING
"NAND bus width %d instead %d bit
\n
"
,
(
this
->
options
&
NAND_BUSWIDTH_16
)
?
16
:
8
,
busw
?
16
:
8
);
this
->
select_chip
(
mtd
,
-
1
);
return
1
;
return
1
;
}
/* Calculate the address shift from the page size */
/* Calculate the address shift from the page size */
this
->
page_shift
=
ffs
(
mtd
->
oobblock
)
-
1
;
this
->
bbt_erase_shift
=
this
->
phys_erase_shift
=
ffs
(
mtd
->
erasesize
)
-
1
;
this
->
chip_shift
=
ffs
(
this
->
chipsize
)
-
1
;
/* Set the bad block position */
this
->
badblockpos
=
mtd
->
oobblock
>
512
?
this
->
badblockpos
=
mtd
->
oobblock
>
512
?
NAND_LARGE_BADBLOCK_POS
:
NAND_SMALL_BADBLOCK_POS
;
/* Get chip options, preserve non chip based options */
...
...
@@ -2457,10 +2457,10 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
this
->
options
|=
NAND_NO_AUTOINCR
;
/* Check if this is a not a samsung device. Do not clear the options
* for chips which are not having an extended id.
*/
*/
if
(
nand_maf_id
!=
NAND_MFR_SAMSUNG
&&
!
nand_flash_ids
[
i
].
pagesize
)
this
->
options
&=
~
NAND_SAMSUNG_LP_OPTIONS
;
/* Check for AND chips with 4 page planes */
if
(
this
->
options
&
NAND_4PAGE_ARRAY
)
this
->
erase_cmd
=
multi_erase_cmd
;
...
...
@@ -2470,9 +2470,9 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
/* Do not replace user supplied command function ! */
if
(
mtd
->
oobblock
>
512
&&
this
->
cmdfunc
==
nand_command
)
this
->
cmdfunc
=
nand_command_lp
;
printk
(
KERN_INFO
"NAND device: Manufacturer ID:"
" 0x%02x, Chip ID: 0x%02x (%s %s)
\n
"
,
nand_maf_id
,
nand_dev_id
,
" 0x%02x, Chip ID: 0x%02x (%s %s)
\n
"
,
nand_maf_id
,
nand_dev_id
,
nand_manuf_ids
[
maf_id
].
name
,
nand_flash_ids
[
i
].
name
);
break
;
}
...
...
@@ -2496,7 +2496,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
}
if
(
i
>
1
)
printk
(
KERN_INFO
"%d NAND chips detected
\n
"
,
i
);
/* Allocate buffers, if neccecary */
if
(
!
this
->
oob_buf
)
{
size_t
len
;
...
...
@@ -2508,7 +2508,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
}
this
->
options
|=
NAND_OOBBUF_ALLOC
;
}
if
(
!
this
->
data_buf
)
{
size_t
len
;
len
=
mtd
->
oobblock
+
mtd
->
oobsize
;
...
...
@@ -2535,7 +2535,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
if
(
!
this
->
autooob
)
{
/* Select the appropriate default oob placement scheme for
* placement agnostic filesystems */
switch
(
mtd
->
oobsize
)
{
switch
(
mtd
->
oobsize
)
{
case
8
:
this
->
autooob
=
&
nand_oob_8
;
break
;
...
...
@@ -2551,19 +2551,19 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
BUG
();
}
}
/* The number of bytes available for the filesystem to place fs dependend
* oob data */
mtd
->
oobavail
=
0
;
for
(
i
=
0
;
this
->
autooob
->
oobfree
[
i
][
1
];
i
++
)
mtd
->
oobavail
+=
this
->
autooob
->
oobfree
[
i
][
1
];
/*
/*
* check ECC mode, default to software
* if 3byte/512byte hardware ECC is selected and we have 256 byte pagesize
* fallback to software ECC
* fallback to software ECC
*/
this
->
eccsize
=
256
;
/* set default eccsize */
this
->
eccsize
=
256
;
/* set default eccsize */
this
->
eccbytes
=
3
;
switch
(
this
->
eccmode
)
{
...
...
@@ -2578,56 +2578,56 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
this
->
eccsize
=
2048
;
break
;
case
NAND_ECC_HW3_512
:
case
NAND_ECC_HW6_512
:
case
NAND_ECC_HW8_512
:
case
NAND_ECC_HW3_512
:
case
NAND_ECC_HW6_512
:
case
NAND_ECC_HW8_512
:
if
(
mtd
->
oobblock
==
256
)
{
printk
(
KERN_WARNING
"512 byte HW ECC not possible on 256 Byte pagesize, fallback to SW ECC
\n
"
);
this
->
eccmode
=
NAND_ECC_SOFT
;
this
->
calculate_ecc
=
nand_calculate_ecc
;
this
->
correct_data
=
nand_correct_data
;
}
else
}
else
this
->
eccsize
=
512
;
/* set eccsize to 512 */
break
;
case
NAND_ECC_HW3_256
:
break
;
case
NAND_ECC_NONE
:
case
NAND_ECC_NONE
:
printk
(
KERN_WARNING
"NAND_ECC_NONE selected by board driver. This is not recommended !!
\n
"
);
this
->
eccmode
=
NAND_ECC_NONE
;
break
;
case
NAND_ECC_SOFT
:
case
NAND_ECC_SOFT
:
this
->
calculate_ecc
=
nand_calculate_ecc
;
this
->
correct_data
=
nand_correct_data
;
break
;
default:
printk
(
KERN_WARNING
"Invalid NAND_ECC_MODE %d
\n
"
,
this
->
eccmode
);
BUG
();
}
BUG
();
}
/* Check hardware ecc function availability and adjust number of ecc bytes per
/* Check hardware ecc function availability and adjust number of ecc bytes per
* calculation step
*/
switch
(
this
->
eccmode
)
{
case
NAND_ECC_HW12_2048
:
this
->
eccbytes
+=
4
;
case
NAND_ECC_HW8_512
:
case
NAND_ECC_HW8_512
:
this
->
eccbytes
+=
2
;
case
NAND_ECC_HW6_512
:
case
NAND_ECC_HW6_512
:
this
->
eccbytes
+=
3
;
case
NAND_ECC_HW3_512
:
case
NAND_ECC_HW3_512
:
case
NAND_ECC_HW3_256
:
if
(
this
->
calculate_ecc
&&
this
->
correct_data
&&
this
->
enable_hwecc
)
break
;
printk
(
KERN_WARNING
"No ECC functions supplied, Hardware ECC not possible
\n
"
);
BUG
();
BUG
();
}
mtd
->
eccsize
=
this
->
eccsize
;
/* Set the number of read / write steps for one page to ensure ECC generation */
switch
(
this
->
eccmode
)
{
case
NAND_ECC_HW12_2048
:
...
...
@@ -2639,15 +2639,15 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
this
->
eccsteps
=
mtd
->
oobblock
/
512
;
break
;
case
NAND_ECC_HW3_256
:
case
NAND_ECC_SOFT
:
case
NAND_ECC_SOFT
:
this
->
eccsteps
=
mtd
->
oobblock
/
256
;
break
;
case
NAND_ECC_NONE
:
case
NAND_ECC_NONE
:
this
->
eccsteps
=
1
;
break
;
}
/* Initialize state, waitqueue and spinlock */
this
->
state
=
FL_READY
;
init_waitqueue_head
(
&
this
->
wq
);
...
...
@@ -2687,7 +2687,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
memcpy
(
&
mtd
->
oobinfo
,
this
->
autooob
,
sizeof
(
mtd
->
oobinfo
));
mtd
->
owner
=
THIS_MODULE
;
/* Check, if we should skip the bad block table scan */
if
(
this
->
options
&
NAND_SKIP_BBTSCAN
)
return
0
;
...
...
@@ -2697,7 +2697,7 @@ int nand_scan (struct mtd_info *mtd, int maxchips)
}
/**
* nand_release - [NAND Interface] Free resources held by the NAND device
* nand_release - [NAND Interface] Free resources held by the NAND device
* @mtd: MTD device structure
*/
void
nand_release
(
struct
mtd_info
*
mtd
)
...
...
drivers/mtd/nand/nand_bbt.c
View file @
61b03bd7
...
...
@@ -3,10 +3,10 @@
*
* Overview:
* Bad block table support for the NAND driver
*
*
* Copyright (C) 2004 Thomas Gleixner (tglx@linutronix.de)
*
* $Id: nand_bbt.c,v 1.3
5 2005/07/15 13:53:47
gleixner Exp $
* $Id: nand_bbt.c,v 1.3
6 2005/11/07 11:14:30
gleixner Exp $
*
* 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
...
...
@@ -14,23 +14,23 @@
*
* Description:
*
* 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
* then the contents are read and the memory based bbt is created. If a
* 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
* 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
* 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.
* 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 no bbt exists at all then the device is scanned for factory marked
* good / bad blocks and the bad block tables are 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
* 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 autogenerated bad block table is located in the last good blocks
* 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 autogenerated bad block table is located in the last good blocks
* 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
* number which indicates which of both tables is more up to date.
*
* The table uses 2 bits per block
...
...
@@ -43,13 +43,13 @@
* 01b: block is marked bad due to wear
* 10b: block is reserved (to protect the bbt area)
* 11b: block is factory marked bad
*
*
* Multichip devices like DOC store the bad block info per floor.
*
* Following assumptions are made:
* - 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
*
*
*/
#include <linux/slab.h>
...
...
@@ -62,7 +62,7 @@
#include <linux/delay.h>
/**
/**
* check_pattern - [GENERIC] check if a pattern is in the buffer
* @buf: the 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
)
return
-
1
;
}
}
}
p
+=
end
;
/* Compare the pattern */
for
(
i
=
0
;
i
<
td
->
len
;
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
;
}
/**
/**
* check_short_pattern - [GENERIC] check if a pattern is in the buffer
* @buf: the buffer to search
* @td: search pattern descriptor
*
* 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
*
*/
...
...
@@ -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.
*
*/
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
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
;
from
=
((
loff_t
)
page
)
<<
this
->
page_shift
;
while
(
totlen
)
{
len
=
min
(
totlen
,
(
size_t
)
(
1
<<
this
->
bbt_erase_shift
));
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
;
}
printk
(
KERN_WARNING
"nand_bbt: ECC error while reading bad block table
\n
"
);
}
}
/* Analyse data */
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 */
printk
(
KERN_DEBUG
"nand_read_bbt: Bad block at 0x%08x
\n
"
,
((
offs
<<
2
)
+
(
act
>>
1
))
<<
this
->
bbt_erase_shift
);
/* Factory marked bad or worn out ? */
/* Factory marked bad or worn out ? */
if
(
tmp
==
0
)
this
->
bbt
[
offs
+
(
act
>>
3
)]
|=
0x3
<<
(
act
&
0x06
);
else
this
->
bbt
[
offs
+
(
act
>>
3
)]
|=
0x1
<<
(
act
&
0x06
);
}
}
}
totlen
-=
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
* @mtd: MTD device structure
* @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.
* 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
* @mtd: MTD device structure
* @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
*
* 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
;
/* Read the primary version, if available */
/* Read the primary version, if available */
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
];
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
))
{
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
];
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
{
if
(
bd
->
options
&
NAND_BBT_SCAN2NDPAGE
)
len
=
2
;
else
else
len
=
1
;
}
...
...
@@ -322,10 +322,10 @@ static int create_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
numblocks
+=
startblock
;
from
=
startblock
<<
(
this
->
bbt_erase_shift
-
1
);
}
for
(
i
=
startblock
;
i
<
numblocks
;)
{
int
ret
;
if
(
bd
->
options
&
NAND_BBT_SCANEMPTY
)
if
((
ret
=
nand_read_raw
(
mtd
,
buf
,
from
,
readlen
,
ooblen
)))
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
++
)
{
if
(
!
(
bd
->
options
&
NAND_BBT_SCANEMPTY
))
{
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 */
ret
=
mtd
->
read_oob
(
mtd
,
from
+
j
*
mtd
->
oobblock
,
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
))
{
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
);
break
;
}
}
else
{
if
(
check_pattern
(
&
buf
[
j
*
scanlen
],
scanlen
,
mtd
->
oobblock
,
bd
))
{
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
);
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
*
* 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
* 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.
* This is neccecary to provide support for certain DOC devices.
*
* The bbt ident pattern resides in the oob area of the first page
* in a block.
* The bbt ident pattern resides in the oob area of the first page
* in a block.
*/
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
;
dir
=
-
1
;
}
else
{
startblock
=
0
;
startblock
=
0
;
dir
=
1
;
}
}
/* Do we have a bbt per chip ? */
if
(
td
->
options
&
NAND_BBT_PERCHIP
)
{
chips
=
this
->
numchips
;
...
...
@@ -405,19 +405,19 @@ static int search_bbt (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_descr
chips
=
1
;
bbtblocks
=
mtd
->
size
>>
this
->
bbt_erase_shift
;
}
/* Number of bits for each erase block in the bbt */
bits
=
td
->
options
&
NAND_BBT_NRBITS_MSK
;
for
(
i
=
0
;
i
<
chips
;
i
++
)
{
/* Reset version information */
td
->
version
[
i
]
=
0
;
td
->
version
[
i
]
=
0
;
td
->
pages
[
i
]
=
-
1
;
/* Scan the maximum number of blocks */
for
(
block
=
0
;
block
<
td
->
maxblocks
;
block
++
)
{
int
actblock
=
startblock
+
dir
*
block
;
/* 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
))
{
td
->
pages
[
i
]
=
actblock
<<
(
this
->
bbt_erase_shift
-
this
->
page_shift
);
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
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)
* @mtd: MTD device structure
* @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
*
* 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
)
{
/* Search the primary table */
search_bbt
(
mtd
,
buf
,
td
);
/* Search the mirror table */
if
(
md
)
search_bbt
(
mtd
,
buf
,
md
);
/* Force result check */
return
1
;
return
1
;
}
/**
/**
* write_bbt - [GENERIC] (Re)write the bad block table
*
* @mtd: MTD device structure
* @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
* @chipsel: selector for a specific chip, -1 for all
*
* (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_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 ? */
if
(
td
->
options
&
NAND_BBT_PERCHIP
)
{
numblocks
=
(
int
)
(
this
->
chipsize
>>
this
->
bbt_erase_shift
);
/* Full device write or specific chip ? */
/* Full device write or specific chip ? */
if
(
chipsel
==
-
1
)
{
nrchips
=
this
->
numchips
;
}
else
{
...
...
@@ -503,19 +503,19 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
}
else
{
numblocks
=
(
int
)
(
mtd
->
size
>>
this
->
bbt_erase_shift
);
nrchips
=
1
;
}
}
/* Loop through the chips */
for
(;
chip
<
nrchips
;
chip
++
)
{
/* There was already a version of the table, reuse the page
* This applies for absolute placement too, as we have the
/* There was already a version of the table, reuse the page
* This applies for absolute placement too, as we have the
* page nr. in td->pages.
*/
if
(
td
->
pages
[
chip
]
!=
-
1
)
{
page
=
td
->
pages
[
chip
];
goto
write
;
}
}
/* Automatic placement of the bad block table */
/* Search direction top -> down ? */
...
...
@@ -525,7 +525,7 @@ static int write_bbt (struct mtd_info *mtd, uint8_t *buf,
}
else
{
startblock
=
chip
*
numblocks
;
dir
=
1
;
}
}
for
(
i
=
0
;
i
<
td
->
maxblocks
;
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
"
);
return
-
ENOSPC
;
write:
write:
/* Set up shift count and masks for the flash table */
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
;
default:
return
-
EINVAL
;
}
bbtoffs
=
chip
*
(
numblocks
>>
2
);
to
=
((
loff_t
)
page
)
<<
this
->
page_shift
;
memcpy
(
&
oobinfo
,
this
->
autooob
,
sizeof
(
oobinfo
));
oobinfo
.
useecc
=
MTD_NANDECC_PLACEONLY
;
/* Must we save the block contents ? */
if
(
td
->
options
&
NAND_BBT_SAVECONTENT
)
{
/* Make it block aligned */
...
...
@@ -599,7 +599,7 @@ write:
buf
[
len
+
td
->
veroffs
]
=
td
->
version
[
chip
];
}
}
/* walk through the memory table */
for
(
i
=
0
;
i
<
numblocks
;
)
{
uint8_t
dat
;
...
...
@@ -611,7 +611,7 @@ write:
dat
>>=
2
;
}
}
memset
(
&
einfo
,
0
,
sizeof
(
einfo
));
einfo
.
mtd
=
mtd
;
einfo
.
addr
=
(
unsigned
long
)
to
;
...
...
@@ -621,18 +621,18 @@ write:
printk
(
KERN_WARNING
"nand_bbt: Error during block erase: %d
\n
"
,
res
);
return
res
;
}
res
=
mtd
->
write_ecc
(
mtd
,
to
,
len
,
&
retlen
,
buf
,
&
buf
[
len
],
&
oobinfo
);
if
(
res
<
0
)
{
printk
(
KERN_WARNING
"nand_bbt: Error while writing bad block table %d
\n
"
,
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
]);
/* Mark it as used */
td
->
pages
[
chip
]
=
page
;
}
}
return
0
;
}
...
...
@@ -641,7 +641,7 @@ write:
* @mtd: MTD device structure
* @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
*/
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
;
/* Do we have a bbt per chip ? */
if
(
td
->
options
&
NAND_BBT_PERCHIP
)
if
(
td
->
options
&
NAND_BBT_PERCHIP
)
chips
=
this
->
numchips
;
else
else
chips
=
1
;
for
(
i
=
0
;
i
<
chips
;
i
++
)
{
writeops
=
0
;
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
)
{
rd
=
md
;
rd
=
md
;
td
->
version
[
i
]
=
md
->
version
[
i
];
writeops
=
1
;
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
))
rd2
=
md
;
goto
writecheck
;
}
}
if
(((
int8_t
)
(
td
->
version
[
i
]
-
md
->
version
[
i
]))
>
0
)
{
rd
=
td
;
...
...
@@ -735,15 +735,15 @@ static int check_create (struct mtd_info *mtd, uint8_t *buf, struct nand_bbt_des
create:
/* Create the bad block table by scanning the device ? */
if
(
!
(
td
->
options
&
NAND_BBT_CREATE
))
continue
;
continue
;
/* Create the table in memory by scanning the chip(s) */
create_bbt
(
mtd
,
buf
,
bd
,
chipsel
);
td
->
version
[
i
]
=
1
;
if
(
md
)
md
->
version
[
i
]
=
1
;
writecheck:
md
->
version
[
i
]
=
1
;
writecheck:
/* read back first ? */
if
(
rd
)
read_abs_bbt
(
mtd
,
buf
,
rd
,
chipsel
);
...
...
@@ -757,7 +757,7 @@ writecheck:
if
(
res
<
0
)
return
res
;
}
/* Write the mirror bad block table to the device ? */
if
((
writeops
&
0x02
)
&&
md
&&
(
md
->
options
&
NAND_BBT_WRITE
))
{
res
=
write_bbt
(
mtd
,
buf
,
md
,
td
,
chipsel
);
...
...
@@ -765,11 +765,11 @@ writecheck:
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
* @td: bad block table descriptor
*
...
...
@@ -790,14 +790,14 @@ static void mark_bbt_region (struct mtd_info *mtd, struct nand_bbt_descr *td)
}
else
{
chips
=
1
;
nrblocks
=
(
int
)(
mtd
->
size
>>
this
->
bbt_erase_shift
);
}
}
for
(
i
=
0
;
i
<
chips
;
i
++
)
{
if
((
td
->
options
&
NAND_BBT_ABSPAGE
)
||
!
(
td
->
options
&
NAND_BBT_WRITE
))
{
if
(
td
->
pages
[
i
]
==
-
1
)
continue
;
block
=
td
->
pages
[
i
]
>>
(
this
->
bbt_erase_shift
-
this
->
page_shift
);
block
<<=
1
;
block
<<=
1
;
oldval
=
this
->
bbt
[(
block
>>
3
)];
newval
=
oldval
|
(
0x2
<<
(
block
&
0x06
));
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
;
if
(
td
->
options
&
NAND_BBT_LASTBLOCK
)
block
=
((
i
+
1
)
*
nrblocks
)
-
td
->
maxblocks
;
else
else
block
=
i
*
nrblocks
;
block
<<=
1
;
block
<<=
1
;
for
(
j
=
0
;
j
<
td
->
maxblocks
;
j
++
)
{
oldval
=
this
->
bbt
[(
block
>>
3
)];
newval
=
oldval
|
(
0x2
<<
(
block
&
0x06
));
this
->
bbt
[(
block
>>
3
)]
=
newval
;
if
(
oldval
!=
newval
)
update
=
1
;
block
+=
2
;
}
}
/* If we want reserved blocks to be recorded to flash, and some
new ones have been marked, then we need to update the stored
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
* @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
* marked good / bad blocks and writes the bad block table(s) to
* the selected place.
...
...
@@ -880,30 +880,30 @@ int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd)
this
->
bbt
=
NULL
;
return
-
ENOMEM
;
}
/* Is the bbt at a given page ? */
if
(
td
->
options
&
NAND_BBT_ABSPAGE
)
{
res
=
read_abs_bbts
(
mtd
,
buf
,
td
,
md
);
}
else
{
}
else
{
/* Search the bad block table using a pattern in oob */
res
=
search_read_bbts
(
mtd
,
buf
,
td
,
md
);
}
}
if
(
res
)
if
(
res
)
res
=
check_create
(
mtd
,
buf
,
bd
);
/* Prevent the bbt regions from erasing / writing */
mark_bbt_region
(
mtd
,
td
);
if
(
md
)
mark_bbt_region
(
mtd
,
md
);
kfree
(
buf
);
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
* @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
"
);
return
-
ENOMEM
;
}
writeops
=
md
!=
NULL
?
0x03
:
0x01
;
/* 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
]
++
;
if
(
md
)
md
->
version
[
chip
]
++
;
md
->
version
[
chip
]
++
;
/* Write the bad block table to the device ? */
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
);
}
out:
out:
kfree
(
buf
);
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. */
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
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
,
.
offs
=
8
,
.
len
=
4
,
...
...
@@ -1019,7 +1019,7 @@ static struct nand_bbt_descr bbt_main_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
,
.
offs
=
8
,
.
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
*
* 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
)
{
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
* _good_ blocks. Erasing those blocks leads to loss
* 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
*/
if
(
this
->
options
&
NAND_IS_AND
)
{
/* Use the default pattern descriptors */
if
(
!
this
->
bbt_td
)
{
if
(
!
this
->
bbt_td
)
{
this
->
bbt_td
=
&
bbt_main_descr
;
this
->
bbt_md
=
&
bbt_mirror_descr
;
}
}
this
->
options
|=
NAND_USE_FLASH_BBT
;
return
nand_scan_bbt
(
mtd
,
&
agand_flashbased
);
}
/* Is a flash based bad block table requested ? */
if
(
this
->
options
&
NAND_USE_FLASH_BBT
)
{
/* Use the default pattern descriptors */
if
(
!
this
->
bbt_td
)
{
/* Use the default pattern descriptors */
if
(
!
this
->
bbt_td
)
{
this
->
bbt_td
=
&
bbt_main_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
* @offs: offset in the device
* @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
;
int
block
;
uint8_t
res
;
/* Get block number * 2 */
block
=
(
int
)
(
offs
>>
(
this
->
bbt_erase_shift
-
1
));
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
);
switch
((
int
)
res
)
{
...
...
drivers/mtd/nand/nand_ecc.c
View file @
61b03bd7
...
...
@@ -7,22 +7,22 @@
* Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com)
* Toshiba America Electronics Components, Inc.
*
* $Id: nand_ecc.c,v 1.1
4 2004/06/16 15:34:37
gleixner Exp $
* $Id: nand_ecc.c,v 1.1
5 2005/11/07 11:14:30
gleixner Exp $
*
* 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
* Free Software Foundation; either version 2 or (at your option) any
* later version.
*
*
* This file is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details.
*
*
* 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.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
*
*
* As a special exception, if other files instantiate templates or use
* 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
...
...
@@ -30,7 +30,7 @@
* covered by the GNU General Public License. However the source code for
* these files must still be made available in accordance with section (3)
* of the GNU General Public License.
*
*
* This exception does not invalidate any other reasons why a work based on
* 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
* @reg2: line parity reg 2
* @reg3: line parity reg 3
* @ecc_code: ecc
* @ecc_code: ecc
*
* 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
a
,
b
,
i
,
tmp1
,
tmp2
;
/* Initialize variables */
a
=
b
=
0x80
;
tmp1
=
tmp2
=
0
;
/* Calculate first ECC byte */
for
(
i
=
0
;
i
<
4
;
i
++
)
{
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
;
a
>>=
1
;
}
/* Calculate second ECC byte */
b
=
0x80
;
for
(
i
=
0
;
i
<
4
;
i
++
)
{
...
...
@@ -102,7 +102,7 @@ static void nand_trans_result(u_char reg2, u_char reg3,
b
>>=
1
;
a
>>=
1
;
}
/* Store two of the ECC bytes */
ecc_code
[
0
]
=
tmp1
;
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
;
int
j
;
/* Initialize variables */
reg1
=
reg2
=
reg3
=
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
++
)
{
/* Get CP0 - CP5 from table */
idx
=
nand_ecc_precalc_table
[
dat
[
j
]];
reg1
^=
(
idx
&
0x3f
);
/* All bit XOR = 1 ? */
if
(
idx
&
0x40
)
{
reg3
^=
(
u_char
)
j
;
reg2
^=
~
((
u_char
)
j
);
}
}
/* Create non-inverted ECC code from line parity */
nand_trans_result
(
reg2
,
reg3
,
ecc_code
);
/* Calculate final ECC code */
ecc_code
[
0
]
=
~
ecc_code
[
0
];
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
)
{
u_char
a
,
b
,
c
,
d1
,
d2
,
d3
,
add
,
bit
,
i
;
/* Do error detection */
/* Do error detection */
d1
=
calc_ecc
[
0
]
^
read_ecc
[
0
];
d2
=
calc_ecc
[
1
]
^
read_ecc
[
1
];
d3
=
calc_ecc
[
2
]
^
read_ecc
[
2
];
if
((
d1
|
d2
|
d3
)
==
0
)
{
/* No errors */
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
;
b
=
(
d2
^
(
d2
>>
1
))
&
0x55
;
c
=
(
d3
^
(
d3
>>
1
))
&
0x54
;
/* Found and will correct single bit error in the data */
if
((
a
==
0x55
)
&&
(
b
==
0x55
)
&&
(
c
==
0x54
))
{
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 */
return
-
1
;
}
...
...
drivers/mtd/nand/nand_ids.c
View file @
61b03bd7
...
...
@@ -3,7 +3,7 @@
*
* Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de)
*
* $Id: nand_ids.c,v 1.1
4 2005/06/23 09:38:50
gleixner Exp $
* $Id: nand_ids.c,v 1.1
6 2005/11/07 11:14:31
gleixner Exp $
*
* 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
...
...
@@ -14,14 +14,14 @@
#include <linux/mtd/nand.h>
/*
* Chip ID list
*
*
* Name. ID code, pagesize, chipsize in MegaByte, eraseblock size,
* options
*
*
* Pagesize; 0, 256, 512
* 0 get this information from the extended chip ID
+ 256 256 Byte page size
* 512 512 Byte page size
* 512 512 Byte page size
*/
struct
nand_flash_dev
nand_flash_ids
[]
=
{
{
"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"
,
0xe5
,
512
,
4
,
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 3,3V 8-bit"
,
0xe6
,
512
,
8
,
0x2000
,
0
},
{
"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 16MiB 1,8V 8-bit"
,
0x33
,
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 3,3V 16-bit"
,
0x53
,
512
,
16
,
0x4000
,
NAND_BUSWIDTH_16
},
{
"NAND 32MiB 1,8V 8-bit"
,
0x35
,
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 3,3V 16-bit"
,
0x55
,
512
,
32
,
0x4000
,
NAND_BUSWIDTH_16
},
{
"NAND 64MiB 1,8V 8-bit"
,
0x36
,
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 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"
,
0x39
,
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 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 256MiB 3,3V 8-bit"
,
0x71
,
512
,
256
,
0x4000
,
0
},
/* 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 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
},
/* 1 Gigabit */
{
"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
},
...
...
@@ -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 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
},
/* 4 Gigabit */
{
"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 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
},
/* 8 Gigabit */
{
"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
},
...
...
@@ -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 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
* 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
* 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
},
...
...
drivers/mtd/nand/nandsim.c
View file @
61b03bd7
...
...
@@ -3,7 +3,7 @@
*
* 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: 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 */
#define NS_LARGEST_PAGE_SIZE 2048
/* The prefix for simulator output */
#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)
#define NS_MDELAY(us) \
do { if (do_delays) mdelay(us); } while(0)
/* Is the nandsim structure initialized ? */
#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)))
/* 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 */
#define NS_RAW_OFFSET(ns) \
(((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 */
#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 */
#define NS_STATE(x) ((x) & ~ACTION_MASK)
/*
/*
* Maximum previous states which need to be saved. Currently saving is
* only needed for page programm operation with preceeded read command
* (which is only valid for 512-byte pages).
*/
#define NS_MAX_PREVSTATES 1
/*
/*
* The structure which describes all the internal simulator data.
*/
struct
nandsim
{
...
...
@@ -242,7 +242,7 @@ struct nandsim {
uint32_t
options
;
/* chip's characteristic bits */
uint32_t
state
;
/* current chip state */
uint32_t
nxstate
;
/* next expected state */
uint32_t
*
op
;
/* current operation, NULL operations isn't known yet */
uint32_t
pstates
[
NS_MAX_PREVSTATES
];
/* previous states */
uint16_t
npstates
;
/* number of previous states saved */
...
...
@@ -413,7 +413,7 @@ init_nandsim(struct mtd_info *mtd)
ns
->
geom
.
secaddrbytes
=
3
;
}
}
/* Detect how many ID bytes the NAND chip outputs */
for
(
i
=
0
;
nand_flash_ids
[
i
].
name
!=
NULL
;
i
++
)
{
if
(
second_id_byte
!=
nand_flash_ids
[
i
].
id
)
...
...
@@ -444,7 +444,7 @@ init_nandsim(struct mtd_info *mtd)
#ifdef CONFIG_NS_ABS_POS
ns
->
mem
.
byte
=
ioremap
(
CONFIG_NS_ABS_POS
,
ns
->
geom
.
totszoob
);
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
);
return
-
ENOMEM
;
}
...
...
@@ -567,7 +567,7 @@ static int
check_command
(
int
cmd
)
{
switch
(
cmd
)
{
case
NAND_CMD_READ0
:
case
NAND_CMD_READSTART
:
case
NAND_CMD_PAGEPROG
:
...
...
@@ -580,7 +580,7 @@ check_command(int cmd)
case
NAND_CMD_RESET
:
case
NAND_CMD_READ1
:
return
0
;
case
NAND_CMD_STATUS_MULTI
:
default:
return
1
;
...
...
@@ -631,7 +631,7 @@ static inline void
accept_addr_byte
(
struct
nandsim
*
ns
,
u_char
bt
)
{
uint
byte
=
(
uint
)
bt
;
if
(
ns
->
regs
.
count
<
(
ns
->
geom
.
pgaddrbytes
-
ns
->
geom
.
secaddrbytes
))
ns
->
regs
.
column
|=
(
byte
<<
8
*
ns
->
regs
.
count
);
else
{
...
...
@@ -642,11 +642,11 @@ accept_addr_byte(struct nandsim *ns, u_char bt)
return
;
}
/*
* Switch to STATE_READY state.
*/
static
inline
void
static
inline
void
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
));
...
...
@@ -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
* second half operations both begin with the READ1 command). In this
* case the ns->pstates[] array contains previous states.
*
*
* Thus, the function tries to find operation containing the following
* states (if the 'flag' parameter is 0):
* 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 (
* ns->ops, ns->state, ns->nxstate are initialized, ns->npstate is
* zeroed).
*
*
* If there are several maches, the current state is pushed to the
* 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
* operation is searched using the following pattern:
* ns->pstates[0], ... ns->pstates[ns->npstates], <address input>
*
*
* It is supposed that this pattern must either match one operation on
* 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
i
,
j
,
idx
=
0
;
for
(
i
=
0
;
i
<
NS_OPER_NUM
;
i
++
)
{
int
found
=
1
;
if
(
!
(
ns
->
options
&
ops
[
i
].
reqopts
))
/* Ignore operations we can't perform */
continue
;
if
(
flag
)
{
if
(
!
(
ops
[
i
].
states
[
ns
->
npstates
]
&
STATE_ADDR_MASK
))
continue
;
...
...
@@ -728,7 +728,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
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
])
&&
(
ns
->
options
&
ops
[
idx
].
reqopts
))
{
found
=
0
;
...
...
@@ -745,7 +745,7 @@ find_operation(struct nandsim *ns, uint32_t flag)
/* Exact match */
ns
->
op
=
&
ops
[
idx
].
states
[
0
];
if
(
flag
)
{
/*
/*
* In this case the find_operation function was
* called when address has just began input. But it isn't
* 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
));
return
0
;
}
if
(
opsfound
==
0
)
{
/* Nothing was found. Try to ignore previous commands (if any) and search again */
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
));
return
-
2
;
}
if
(
flag
)
{
/* This shouldn't happen */
NS_DBG
(
"find_operation: BUG, operation must be known if address is input
\n
"
);
return
-
2
;
}
NS_DBG
(
"find_operation: there is still ambiguity
\n
"
);
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
;
action
&=
ACTION_MASK
;
/* Check that page address input is correct */
if
(
action
!=
ACTION_SECERASE
&&
ns
->
regs
.
row
>=
ns
->
geom
.
pgnum
)
{
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
"
,
num
,
NS_RAW_OFFSET
(
ns
)
+
ns
->
regs
.
off
);
if
(
ns
->
regs
.
off
==
0
)
NS_LOG
(
"read page %d
\n
"
,
ns
->
regs
.
row
);
else
if
(
ns
->
regs
.
off
<
ns
->
geom
.
pgsz
)
NS_LOG
(
"read page %d (second half)
\n
"
,
ns
->
regs
.
row
);
else
NS_LOG
(
"read OOB of page %d
\n
"
,
ns
->
regs
.
row
);
NS_UDELAY
(
access_delay
);
NS_UDELAY
(
input_cycle
*
ns
->
geom
.
pgsz
/
1000
/
busdiv
);
...
...
@@ -844,30 +844,30 @@ do_state_action(struct nandsim *ns, uint32_t action)
/*
* Erase sector.
*/
if
(
ns
->
lines
.
wp
)
{
NS_ERR
(
"do_state_action: device is write-protected, ignore sector erase
\n
"
);
return
-
1
;
}
if
(
ns
->
regs
.
row
>=
ns
->
geom
.
pgnum
-
ns
->
geom
.
pgsec
||
(
ns
->
regs
.
row
&
~
(
ns
->
geom
.
secsz
-
1
)))
{
NS_ERR
(
"do_state_action: wrong sector address (%#x)
\n
"
,
ns
->
regs
.
row
);
return
-
1
;
}
ns
->
regs
.
row
=
(
ns
->
regs
.
row
<<
8
*
(
ns
->
geom
.
pgaddrbytes
-
ns
->
geom
.
secaddrbytes
))
|
ns
->
regs
.
column
;
ns
->
regs
.
column
=
0
;
NS_DBG
(
"do_state_action: erase sector at address %#x, off = %d
\n
"
,
ns
->
regs
.
row
,
NS_RAW_OFFSET
(
ns
));
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
);
NS_MDELAY
(
erase_delay
);
break
;
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
"
,
num
,
ns
->
regs
.
row
,
ns
->
regs
.
column
,
NS_RAW_OFFSET
(
ns
)
+
ns
->
regs
.
off
);
NS_LOG
(
"programm page %d
\n
"
,
ns
->
regs
.
row
);
NS_UDELAY
(
programm_delay
);
NS_UDELAY
(
output_cycle
*
ns
->
geom
.
pgsz
/
1000
/
busdiv
);
break
;
case
ACTION_ZEROOFF
:
NS_DBG
(
"do_state_action: set internal offset to 0
\n
"
);
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
->
regs
.
off
=
ns
->
geom
.
pgsz
;
break
;
default:
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.
* Just follow the states chain.
*/
ns
->
stateidx
+=
1
;
ns
->
state
=
ns
->
nxstate
;
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
));
return
;
}
}
else
{
/*
* We don't yet know which operation we perform.
* Try to identify it.
*/
/*
/*
* The only event causing the switch_state function to
* 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
);
/* In case of data states, see if all bytes were input/output */
if
((
ns
->
state
&
(
STATE_DATAIN_MASK
|
STATE_DATAOUT_MASK
))
&&
ns
->
regs
.
count
!=
ns
->
regs
.
num
)
{
...
...
@@ -995,17 +995,17 @@ switch_state(struct nandsim *ns)
ns
->
regs
.
num
-
ns
->
regs
.
count
);
status
=
NS_STATUS_FAILED
(
ns
);
}
NS_DBG
(
"switch_state: operation complete, switch to STATE_READY state
\n
"
);
switch_to_ready_state
(
ns
,
status
);
return
;
}
else
if
(
ns
->
nxstate
&
(
STATE_DATAIN_MASK
|
STATE_DATAOUT_MASK
))
{
/*
/*
* If the next state is data input/output, switch to it now
*/
ns
->
state
=
ns
->
nxstate
;
ns
->
nxstate
=
ns
->
op
[
++
ns
->
stateidx
+
1
];
ns
->
regs
.
num
=
ns
->
regs
.
count
=
0
;
...
...
@@ -1023,16 +1023,16 @@ switch_state(struct nandsim *ns)
case
STATE_DATAOUT
:
ns
->
regs
.
num
=
ns
->
geom
.
pgszoob
-
ns
->
regs
.
off
-
ns
->
regs
.
column
;
break
;
case
STATE_DATAOUT_ID
:
ns
->
regs
.
num
=
ns
->
geom
.
idbytes
;
break
;
case
STATE_DATAOUT_STATUS
:
case
STATE_DATAOUT_STATUS_M
:
ns
->
regs
.
count
=
ns
->
regs
.
num
=
0
;
break
;
default:
NS_ERR
(
"switch_state: BUG! unknown data state
\n
"
);
}
...
...
@@ -1044,16 +1044,16 @@ switch_state(struct nandsim *ns)
*/
ns
->
regs
.
count
=
0
;
switch
(
NS_STATE
(
ns
->
nxstate
))
{
case
STATE_ADDR_PAGE
:
ns
->
regs
.
num
=
ns
->
geom
.
pgaddrbytes
;
break
;
case
STATE_ADDR_SEC
:
ns
->
regs
.
num
=
ns
->
geom
.
secaddrbytes
;
break
;
case
STATE_ADDR_ZERO
:
ns
->
regs
.
num
=
1
;
break
;
...
...
@@ -1062,7 +1062,7 @@ switch_state(struct nandsim *ns)
NS_ERR
(
"switch_state: BUG! unknown address state
\n
"
);
}
}
else
{
/*
/*
* Just reset internal counters.
*/
...
...
@@ -1184,7 +1184,7 @@ ns_nand_read_byte(struct mtd_info *mtd)
default:
BUG
();
}
if
(
ns
->
regs
.
count
==
ns
->
regs
.
num
)
{
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
)
switch_state
(
ns
);
}
return
outb
;
}
...
...
@@ -1211,7 +1211,7 @@ static void
ns_nand_write_byte
(
struct
mtd_info
*
mtd
,
u_char
byte
)
{
struct
nandsim
*
ns
=
(
struct
nandsim
*
)((
struct
nand_chip
*
)
mtd
->
priv
)
->
priv
;
/* Sanity and correctness checks */
if
(
!
ns
->
lines
.
ce
)
{
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
"
);
return
;
}
if
(
ns
->
lines
.
cle
==
1
)
{
/*
* The byte written is a command.
...
...
@@ -1233,7 +1233,7 @@ ns_nand_write_byte(struct mtd_info *mtd, u_char byte)
return
;
}
/*
/*
* Chip might still be in STATE_DATAOUT
* (if OPT_AUTOINCR feature is supported), STATE_DATAOUT_STATUS or
* 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
));
switch_to_ready_state
(
ns
,
NS_STATUS_FAILED
(
ns
));
}
/* Check that the command byte is correct */
if
(
check_command
(
byte
))
{
NS_ERR
(
"write_byte: unknown command %#x
\n
"
,
(
uint
)
byte
);
return
;
}
NS_DBG
(
"command byte corresponding to %s state accepted
\n
"
,
get_state_name
(
get_state_by_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
)
return
;
if
((
ns
->
state
&
ACTION_MASK
)
&&
do_state_action
(
ns
,
ns
->
state
)
<
0
)
{
switch_to_ready_state
(
ns
,
NS_STATUS_FAILED
(
ns
));
return
;
}
ns
->
regs
.
count
=
0
;
switch
(
NS_STATE
(
ns
->
nxstate
))
{
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
));
return
;
}
/* Check if this is expected byte */
if
(
ns
->
regs
.
count
==
ns
->
regs
.
num
)
{
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
);
switch_state
(
ns
);
}
}
else
{
/*
* The byte written is an input data.
*/
/* Check that chip is expecting data input */
if
(
!
(
ns
->
state
&
STATE_DATAIN_MASK
))
{
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
;
NS_DBG
(
"read_word
\n
"
);
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
)
{
struct
nand_chip
*
chip
=
(
struct
nand_chip
*
)
mtd
->
priv
;
NS_DBG
(
"write_word
\n
"
);
chip
->
write_byte
(
mtd
,
word
&
0xFF
);
chip
->
write_byte
(
mtd
,
word
>>
8
);
}
static
void
static
void
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
;
...
...
@@ -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
);
ns
->
regs
.
count
+=
len
;
if
(
ns
->
regs
.
count
==
ns
->
regs
.
num
)
{
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
)
{
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
);
ns
->
regs
.
count
+=
len
;
if
(
ns
->
regs
.
count
==
ns
->
regs
.
num
)
{
if
((
ns
->
options
&
OPT_AUTOINCR
)
&&
NS_STATE
(
ns
->
state
)
==
STATE_DATAOUT
)
{
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
)
switch_state
(
ns
);
}
return
;
}
static
int
static
int
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
);
...
...
@@ -1496,7 +1496,7 @@ int __init ns_init_module(void)
NS_ERR
(
"wrong bus width (%d), use only 8 or 16
\n
"
,
bus_width
);
return
-
EINVAL
;
}
/* Allocate and initialize mtd_info, nand_chip and nandsim structures */
nsmtd
=
kmalloc
(
sizeof
(
struct
mtd_info
)
+
sizeof
(
struct
nand_chip
)
+
sizeof
(
struct
nandsim
),
GFP_KERNEL
);
...
...
@@ -1509,7 +1509,7 @@ int __init ns_init_module(void)
chip
=
(
struct
nand_chip
*
)(
nsmtd
+
1
);
nsmtd
->
priv
=
(
void
*
)
chip
;
nand
=
(
struct
nandsim
*
)(
chip
+
1
);
chip
->
priv
=
(
void
*
)
nand
;
chip
->
priv
=
(
void
*
)
nand
;
/*
* Register simulator's callbacks.
...
...
@@ -1526,9 +1526,9 @@ int __init ns_init_module(void)
chip
->
eccmode
=
NAND_ECC_SOFT
;
chip
->
options
|=
NAND_SKIP_BBTSCAN
;
/*
/*
* 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
)
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
"
);
goto
error
;
}
if
((
retval
=
nand_default_bbt
(
nsmtd
))
!=
0
)
{
free_nandsim
(
nand
);
goto
error
;
...
...
drivers/mtd/nand/ppchameleonevb.c
View file @
61b03bd7
...
...
@@ -6,7 +6,7 @@
* 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
* 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_TSRL
,
in_be32
((
volatile
unsigned
*
)
GPIO0_TSRL
)
&
0x3FFFFFFF
);
/* 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
);
#ifdef USE_READY_BUSY_PIN
/* three-state select */
...
...
@@ -402,7 +402,7 @@ static void __exit ppchameleonevb_cleanup (void)
/* Release resources, unregister device(s) */
nand_release
(
ppchameleon_mtd
);
nand_release
(
ppchameleonevb_mtd
);
/* Release iomaps */
this
=
(
struct
nand_chip
*
)
&
ppchameleon_mtd
[
1
];
iounmap
((
void
*
)
this
->
IO_ADDR_R
;
...
...
drivers/mtd/nand/rtc_from4.c
View file @
61b03bd7
...
...
@@ -2,11 +2,11 @@
* drivers/mtd/nand/rtc_from4.c
*
* Copyright (C) 2004 Red Hat, Inc.
*
*
* Derived from drivers/mtd/nand/spia.c
* 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
* it under the terms of the GNU General Public License version 2 as
...
...
@@ -14,8 +14,8 @@
*
* Overview:
* 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),
* which utilizes the Renesas HN29V1G91T-30 part.
* Renesas Technology Corp. Flash ROM 4-slot interface board (FROM_BOARD4),
* which utilizes the Renesas HN29V1G91T-30 part.
* 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
/*
/*
* 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
*
*/
...
...
@@ -141,7 +141,7 @@ static struct nand_bbt_descr rtc_from4_bbt_mirror_descr = {
/* the Reed Solomon control structure */
static
struct
rs_control
*
rs_decoder
;
/*
/*
* hardware specific Out Of Band information
*/
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
* @mtd: MTD device structure
* @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.
*
* 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.
*
*/
static
void
rtc_from4_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
{
struct
nand_chip
*
this
=
(
struct
nand_chip
*
)
(
mtd
->
priv
);
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
);
break
;
case
NAND_CTL_CLRCLE
:
case
NAND_CTL_CLRCLE
:
this
->
IO_ADDR_W
=
(
void
__iomem
*
)((
unsigned
long
)
this
->
IO_ADDR_W
&
~
RTC_FROM4_CLE
);
break
;
case
NAND_CTL_SETALE
:
this
->
IO_ADDR_W
=
(
void
__iomem
*
)((
unsigned
long
)
this
->
IO_ADDR_W
|
RTC_FROM4_ALE
);
break
;
case
NAND_CTL_CLRALE
:
this
->
IO_ADDR_W
=
(
void
__iomem
*
)((
unsigned
long
)
this
->
IO_ADDR_W
&
~
RTC_FROM4_ALE
);
break
;
case
NAND_CTL_SETNCE
:
break
;
case
NAND_CTL_CLRNCE
:
...
...
@@ -296,7 +296,7 @@ static int rtc_from4_nand_device_ready(struct mtd_info *mtd)
* @mtd: MTD device structure
* @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
* to ensure correct operation. This routine performs the required steps
* for the requested chip.
...
...
@@ -312,7 +312,7 @@ static void deplete(struct mtd_info *mtd, int chip)
while
(
!
this
->
dev_ready
(
mtd
));
this
->
select_chip
(
mtd
,
chip
);
/* Send the commands for device recovery, phase 1 */
this
->
cmdfunc
(
mtd
,
NAND_CMD_DEPLETE1
,
0x0000
,
0x0000
);
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
* @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
)
...
...
@@ -340,7 +340,7 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
switch
(
mode
)
{
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
;
*
rs_ecc_ctl
=
status
;
...
...
@@ -353,8 +353,8 @@ static void rtc_from4_enable_hwecc(struct mtd_info *mtd, int mode)
break
;
case
NAND_ECC_WRITE
:
status
=
RTC_FROM4_RS_ECC_CTL_CLR
|
RTC_FROM4_RS_ECC_CTL_GEN
status
=
RTC_FROM4_RS_ECC_CTL_CLR
|
RTC_FROM4_RS_ECC_CTL_GEN
|
RTC_FROM4_RS_ECC_CTL_FD_E
;
*
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
)
{
int
i
,
j
,
res
;
unsigned
short
status
;
unsigned
short
status
;
uint16_t
par
[
6
],
syn
[
6
];
uint8_t
ecc
[
8
];
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 */
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
)];
par
[
4
]
=
rs_decoder
->
index_of
[(((
uint16_t
)
ecc
[
1
]
>>
2
)
&
0x03f
)
|
(((
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.*/
res
=
decode_rs8
(
rs_decoder
,
(
uint8_t
*
)
buf
,
par
,
512
,
syn
,
0
,
NULL
,
0xff
,
NULL
);
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
);
}
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
* @status: status code returned from read status
* @page: startpage inside the chip, must be called with (page & this->pagemask)
*
* Perform additional error status checks on erase and write failures
* to determine if errors are correctable. For this device, correctable
*
* Perform additional error status checks on erase and write failures
* to determine if errors are correctable. For this device, correctable
* 1-bit errors on erase and write are considered acceptable.
*
* note: see pages 34..37 of data sheet for details.
...
...
@@ -633,7 +633,7 @@ int __init rtc_from4_init (void)
#ifdef RTC_FROM4_HWECC
/* 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)
* Primitve polynomial is x^10+x^3+1
...
...
drivers/mtd/nand/s3c2410.c
View file @
61b03bd7
...
...
@@ -19,7 +19,7 @@
* 08-Jul-2005 BJD Fix OOPS when no platform data supplied
* 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
* 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 */
static
int
s3c2410_nand_inithw
(
struct
s3c2410_nand_info
*
info
,
static
int
s3c2410_nand_inithw
(
struct
s3c2410_nand_info
*
info
,
struct
device
*
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
;
twrph1
=
8
;
}
if
(
tacls
<
0
||
twrph0
<
0
||
twrph1
<
0
)
{
printk
(
KERN_ERR
PFX
"cannot get timings suitable for board
\n
"
);
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
"
,
tacls
,
to_ns
(
tacls
,
clkrate
),
twrph0
,
to_ns
(
twrph0
,
clkrate
),
twrph0
,
to_ns
(
twrph0
,
clkrate
),
twrph1
,
to_ns
(
twrph1
,
clkrate
));
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
)
{
struct
s3c2410_nand_info
*
info
;
struct
s3c2410_nand_mtd
*
nmtd
;
struct
s3c2410_nand_mtd
*
nmtd
;
struct
nand_chip
*
this
=
mtd
->
priv
;
void
__iomem
*
reg
;
unsigned
long
cur
;
...
...
@@ -252,7 +252,7 @@ static void s3c2410_nand_select_chip(struct mtd_info *mtd, int chip)
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
* 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
)
{
struct
s3c2410_nand_info
*
info
=
s3c2410_nand_mtd_toinfo
(
mtd
);
if
(
info
->
is_s3c2440
)
return
readb
(
info
->
regs
+
S3C2440_NFSTAT
)
&
S3C2440_NFSTAT_READY
;
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
]
&&
read_ecc
[
1
]
==
calc_ecc
[
1
]
&&
read_ecc
[
2
]
==
calc_ecc
[
2
])
read_ecc
[
2
]
==
calc_ecc
[
2
])
return
0
;
/* 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
);
if
(
info
==
NULL
)
if
(
info
==
NULL
)
return
0
;
/* first thing we need to do is release all our mtds
* and their partitions, then go through freeing the
* resources used
* resources used
*/
if
(
info
->
mtds
!=
NULL
)
{
struct
s3c2410_nand_mtd
*
ptr
=
info
->
mtds
;
int
mtdno
;
...
...
@@ -507,7 +507,7 @@ static int s3c2410_nand_add_partition(struct s3c2410_nand_info *info,
/* 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
,
...
...
@@ -625,7 +625,7 @@ static int s3c24xx_nand_probe(struct device *dev, int is_s3c2440)
dev_err
(
dev
,
"cannot reserve register region
\n
"
);
err
=
-
EIO
;
goto
exit_error
;
}
}
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
++
)
{
pr_debug
(
"initialising set %d (%p, info %p)
\n
"
,
setno
,
nmtd
,
info
);
s3c2410_nand_init_chip
(
info
,
nmtd
,
sets
);
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
)
sets
++
;
}
pr_debug
(
"initialised ok
\n
"
);
return
0
;
...
...
drivers/mtd/nand/sharpsl.c
View file @
61b03bd7
...
...
@@ -3,7 +3,7 @@
*
* 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
*
...
...
@@ -76,14 +76,14 @@ static struct mtd_partition sharpsl_nand_default_partition_info[] = {
},
};
/*
/*
* hardware specific access to control-lines
*/
static
void
sharpsl_nand_hwcontrol
(
struct
mtd_info
*
mtd
,
int
cmd
)
{
switch
(
cmd
)
{
case
NAND_CTL_SETCLE
:
case
NAND_CTL_SETCLE
:
writeb
(
readb
(
FLASHCTL
)
|
FLCLE
,
FLASHCTL
);
break
;
case
NAND_CTL_CLRCLE
:
...
...
@@ -97,10 +97,10 @@ sharpsl_nand_hwcontrol(struct mtd_info* mtd, int cmd)
writeb
(
readb
(
FLASHCTL
)
&
~
FLALE
,
FLASHCTL
);
break
;
case
NAND_CTL_SETNCE
:
case
NAND_CTL_SETNCE
:
writeb
(
readb
(
FLASHCTL
)
&
~
(
FLCE0
|
FLCE1
),
FLASHCTL
);
break
;
case
NAND_CTL_CLRNCE
:
case
NAND_CTL_CLRNCE
:
writeb
(
readb
(
FLASHCTL
)
|
(
FLCE0
|
FLCE1
),
FLASHCTL
);
break
;
}
...
...
@@ -126,8 +126,8 @@ static struct nand_oobinfo akita_oobinfo = {
.
useecc
=
MTD_NANDECC_AUTOPLACE
,
.
eccbytes
=
24
,
.
eccpos
=
{
0x5
,
0x1
,
0x2
,
0x3
,
0x6
,
0x7
,
0x15
,
0x11
,
0x12
,
0x13
,
0x16
,
0x17
,
0x25
,
0x21
,
0x22
,
0x23
,
0x5
,
0x1
,
0x2
,
0x3
,
0x6
,
0x7
,
0x15
,
0x11
,
0x12
,
0x13
,
0x16
,
0x17
,
0x25
,
0x21
,
0x22
,
0x23
,
0x26
,
0x27
,
0x35
,
0x31
,
0x32
,
0x33
,
0x36
,
0x37
},
.
oobfree
=
{
{
0x08
,
0x09
}
}
};
...
...
@@ -177,7 +177,7 @@ sharpsl_nand_init(void)
printk
(
"Unable to allocate SharpSL NAND MTD device structure.
\n
"
);
return
-
ENOMEM
;
}
/* map physical adress */
sharpsl_io_base
=
ioremap
(
sharpsl_phys_base
,
0x1000
);
if
(
!
sharpsl_io_base
){
...
...
@@ -185,7 +185,7 @@ sharpsl_nand_init(void)
kfree
(
sharpsl_mtd
);
return
-
EIO
;
}
/* Get pointer to private data */
this
=
(
struct
nand_chip
*
)
(
&
sharpsl_mtd
[
1
]);
...
...
@@ -211,7 +211,7 @@ sharpsl_nand_init(void)
this
->
chip_delay
=
15
;
/* set eccmode using hardware ECC */
this
->
eccmode
=
NAND_ECC_HW3_256
;
this
->
badblock_pattern
=
&
sharpsl_bbt
;
this
->
badblock_pattern
=
&
sharpsl_bbt
;
if
(
machine_is_akita
()
||
machine_is_borzoi
())
{
this
->
badblock_pattern
=
&
sharpsl_akita_bbt
;
this
->
autooob
=
&
akita_oobinfo
;
...
...
@@ -232,7 +232,7 @@ sharpsl_nand_init(void)
sharpsl_mtd
->
name
=
"sharpsl-nand"
;
nr_partitions
=
parse_mtd_partitions
(
sharpsl_mtd
,
part_probes
,
&
sharpsl_partition_info
,
0
);
if
(
nr_partitions
<=
0
)
{
nr_partitions
=
DEFAULT_NUM_PARTITIONS
;
sharpsl_partition_info
=
sharpsl_nand_default_partition_info
;
...
...
drivers/mtd/nand/spia.c
View file @
61b03bd7
...
...
@@ -8,7 +8,7 @@
* to controllines (due to change in nand.c)
* page_cache added
*
* $Id: spia.c,v 1.2
4 2004/11/04 12:53:10
gleixner Exp $
* $Id: spia.c,v 1.2
5 2005/11/07 11:14:31
gleixner Exp $
*
* 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
...
...
@@ -82,7 +82,7 @@ const static struct mtd_partition partition_info[] = {
#define NUM_PARTITIONS 2
/*
/*
* hardware specific access to control-lines
*/
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 */
this
->
hwcontrol
=
spia_hwcontrol
;
/* 15 us command delay time */
this
->
chip_delay
=
15
;
this
->
chip_delay
=
15
;
/* Scan to find existence of the device */
if
(
nand_scan
(
spia_mtd
,
1
))
{
...
...
drivers/mtd/nand/toto.c
View file @
61b03bd7
...
...
@@ -15,7 +15,7 @@
* This is a device driver for the NAND flash device found on the
* 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>
...
...
@@ -57,7 +57,7 @@ static unsigned long toto_io_base = OMAP_FLASH_1_BASE;
#endif
#define T_NAND_CTL_SETNCE(iob) gpiosetout(NAND_NCE, 0)
#define T_NAND_CTL_CLRNCE(iob) gpiosetout(NAND_NCE, NAND_NCE)
/*
* Define partitions for flash devices
*/
...
...
@@ -91,7 +91,7 @@ static struct mtd_partition partition_info32M[] = {
#define NUM_PARTITIONS32M 3
#define NUM_PARTITIONS64M 4
/*
/*
* hardware specific access to control-lines
*/
...
...
@@ -146,7 +146,7 @@ int __init toto_init (void)
this
->
hwcontrol
=
toto_hwcontrol
;
this
->
dev_ready
=
NULL
;
/* 25 us command delay time */
this
->
chip_delay
=
30
;
this
->
chip_delay
=
30
;
this
->
eccmode
=
NAND_ECC_SOFT
;
/* Scan to find existance of the device */
...
...
@@ -157,10 +157,10 @@ int __init toto_init (void)
/* Register the partitions */
switch
(
toto_mtd
->
size
){
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_64M
:
add_mtd_partitions
(
toto_mtd
,
partition_info64M
,
NUM_PARTITIONS64M
);
break
;
case
SZ_32M
:
add_mtd_partitions
(
toto_mtd
,
partition_info32M
,
NUM_PARTITIONS32M
);
break
;
default:
{
printk
(
KERN_WARNING
"Unsupported Nand device
\n
"
);
printk
(
KERN_WARNING
"Unsupported Nand device
\n
"
);
err
=
-
ENXIO
;
goto
out_buf
;
}
...
...
@@ -170,9 +170,9 @@ int __init toto_init (void)
archflashwp
(
0
,
0
);
/* open up flash for writing */
goto
out
;
out_buf:
kfree
(
this
->
data_buf
);
kfree
(
this
->
data_buf
);
out_mtd:
kfree
(
toto_mtd
);
out:
...
...
@@ -194,7 +194,7 @@ static void __exit toto_cleanup (void)
/* stop flash writes */
archflashwp
(
0
,
1
);
/* release gpios to system */
gpiorelease
(
NAND_MASK
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment