Patch by Ladislav Michl, 29 Jun 2005master
parent
024447b186
commit
932394ac43
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,17 @@ |
||||
include $(TOPDIR)/config.mk |
||||
|
||||
LIB := libnand.a
|
||||
|
||||
OBJS := nand.o nand_base.o nand_ids.o nand_ecc.o nand_bbt.o
|
||||
all: $(LIB) |
||||
|
||||
$(LIB): $(OBJS) |
||||
$(AR) crv $@ $(OBJS)
|
||||
|
||||
#########################################################################
|
||||
|
||||
.depend: Makefile $(OBJS:.o=.c) |
||||
$(CC) -M $(CFLAGS) $(OBJS:.o=.c) > $@
|
||||
|
||||
sinclude .depend |
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,71 @@ |
||||
/*
|
||||
* (C) Copyright 2005 |
||||
* 2N Telekomunikace, a.s. <www.2n.cz> |
||||
* Ladislav Michl <michl@2n.cz> |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* 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 published by the Free Software Foundation. |
||||
* |
||||
* This program 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 program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NAND) |
||||
|
||||
#include <nand.h> |
||||
|
||||
#ifndef CFG_NAND_BASE_LIST |
||||
#define CFG_NAND_BASE_LIST { CFG_NAND_BASE } |
||||
#endif |
||||
|
||||
int nand_curr_device = -1; |
||||
nand_info_t nand_info[CFG_MAX_NAND_DEVICE]; |
||||
|
||||
static struct nand_chip nand_chip[CFG_MAX_NAND_DEVICE]; |
||||
static ulong base_address[CFG_MAX_NAND_DEVICE] = CFG_NAND_BASE_LIST; |
||||
|
||||
static const char default_nand_name[] = "nand"; |
||||
|
||||
extern void board_nand_init(struct nand_chip *nand); |
||||
|
||||
static void nand_init_chip(struct mtd_info *mtd, struct nand_chip *nand, |
||||
ulong base_addr) |
||||
{ |
||||
mtd->priv = nand; |
||||
|
||||
nand->IO_ADDR_R = nand->IO_ADDR_W = base_addr; |
||||
board_nand_init(nand); |
||||
|
||||
if (nand_scan(mtd, 1) == 0) { |
||||
if (!mtd->name) |
||||
mtd->name = default_nand_name; |
||||
} else |
||||
mtd->name = NULL; |
||||
|
||||
} |
||||
|
||||
void nand_init(void) |
||||
{ |
||||
int i; |
||||
|
||||
for (i = 0; i < CFG_MAX_NAND_DEVICE; i++) { |
||||
nand_init_chip(&nand_info[i], &nand_chip[i], base_address[i]); |
||||
if (nand_curr_device == -1) |
||||
nand_curr_device = i; |
||||
} |
||||
} |
||||
|
||||
#endif |
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,244 @@ |
||||
/*
|
||||
* This file contains an ECC algorithm from Toshiba that detects and |
||||
* corrects 1 bit errors in a 256 byte block of data. |
||||
* |
||||
* drivers/mtd/nand/nand_ecc.c |
||||
* |
||||
* Copyright (C) 2000-2004 Steven J. Hill (sjhill@realitydiluted.com) |
||||
* Toshiba America Electronics Components, Inc. |
||||
* |
||||
* $Id: nand_ecc.c,v 1.14 2004/06/16 15:34:37 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 |
||||
* files, these files do not by themselves cause the resulting work to be |
||||
* 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. |
||||
*/ |
||||
|
||||
#include <common.h> |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NAND) |
||||
|
||||
/*
|
||||
* Pre-calculated 256-way 1 byte column parity |
||||
*/ |
||||
static const u_char nand_ecc_precalc_table[] = { |
||||
0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00, |
||||
0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, |
||||
0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, |
||||
0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, |
||||
0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, |
||||
0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, |
||||
0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, |
||||
0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, |
||||
0x6a, 0x3f, 0x3c, 0x69, 0x33, 0x66, 0x65, 0x30, 0x30, 0x65, 0x66, 0x33, 0x69, 0x3c, 0x3f, 0x6a, |
||||
0x0f, 0x5a, 0x59, 0x0c, 0x56, 0x03, 0x00, 0x55, 0x55, 0x00, 0x03, 0x56, 0x0c, 0x59, 0x5a, 0x0f, |
||||
0x0c, 0x59, 0x5a, 0x0f, 0x55, 0x00, 0x03, 0x56, 0x56, 0x03, 0x00, 0x55, 0x0f, 0x5a, 0x59, 0x0c, |
||||
0x69, 0x3c, 0x3f, 0x6a, 0x30, 0x65, 0x66, 0x33, 0x33, 0x66, 0x65, 0x30, 0x6a, 0x3f, 0x3c, 0x69, |
||||
0x03, 0x56, 0x55, 0x00, 0x5a, 0x0f, 0x0c, 0x59, 0x59, 0x0c, 0x0f, 0x5a, 0x00, 0x55, 0x56, 0x03, |
||||
0x66, 0x33, 0x30, 0x65, 0x3f, 0x6a, 0x69, 0x3c, 0x3c, 0x69, 0x6a, 0x3f, 0x65, 0x30, 0x33, 0x66, |
||||
0x65, 0x30, 0x33, 0x66, 0x3c, 0x69, 0x6a, 0x3f, 0x3f, 0x6a, 0x69, 0x3c, 0x66, 0x33, 0x30, 0x65, |
||||
0x00, 0x55, 0x56, 0x03, 0x59, 0x0c, 0x0f, 0x5a, 0x5a, 0x0f, 0x0c, 0x59, 0x03, 0x56, 0x55, 0x00 |
||||
}; |
||||
|
||||
|
||||
/**
|
||||
* nand_trans_result - [GENERIC] create non-inverted ECC |
||||
* @reg2: line parity reg 2 |
||||
* @reg3: line parity reg 3 |
||||
* @ecc_code: ecc
|
||||
* |
||||
* Creates non-inverted ECC code from line parity |
||||
*/ |
||||
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] */ |
||||
tmp1 |= b; |
||||
b >>= 1; |
||||
if (reg2 & a) /* LP14,12,10,8 --> ecc_code[0] */ |
||||
tmp1 |= b; |
||||
b >>= 1; |
||||
a >>= 1; |
||||
} |
||||
|
||||
/* Calculate second ECC byte */ |
||||
b = 0x80; |
||||
for (i = 0; i < 4; i++) { |
||||
if (reg3 & a) /* LP7,5,3,1 --> ecc_code[1] */ |
||||
tmp2 |= b; |
||||
b >>= 1; |
||||
if (reg2 & a) /* LP6,4,2,0 --> ecc_code[1] */ |
||||
tmp2 |= b; |
||||
b >>= 1; |
||||
a >>= 1; |
||||
} |
||||
|
||||
/* Store two of the ECC bytes */ |
||||
ecc_code[0] = tmp1; |
||||
ecc_code[1] = tmp2; |
||||
} |
||||
|
||||
/**
|
||||
* nand_calculate_ecc - [NAND Interface] Calculate 3 byte ECC code for 256 byte block |
||||
* @mtd: MTD block structure |
||||
* @dat: raw data |
||||
* @ecc_code: buffer for ECC |
||||
*/ |
||||
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 */
|
||||
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]; |
||||
ecc_code[2] = ((~reg1) << 2) | 0x03; |
||||
return 0; |
||||
} |
||||
|
||||
/**
|
||||
* nand_correct_data - [NAND Interface] Detect and correct bit error(s) |
||||
* @mtd: MTD block structure |
||||
* @dat: raw data read from the chip |
||||
* @read_ecc: ECC from the chip |
||||
* @calc_ecc: the ECC calculated from raw data |
||||
* |
||||
* Detect and correct a 1 bit error for 256 byte block |
||||
*/ |
||||
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 */
|
||||
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; |
||||
} |
||||
else { |
||||
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; |
||||
add = 0; |
||||
a = 0x80; |
||||
for (i=0; i<4; i++) { |
||||
if (d1 & c) |
||||
add |= a; |
||||
c >>= 2; |
||||
a >>= 1; |
||||
} |
||||
c = 0x80; |
||||
for (i=0; i<4; i++) { |
||||
if (d2 & c) |
||||
add |= a; |
||||
c >>= 2; |
||||
a >>= 1; |
||||
} |
||||
bit = 0; |
||||
b = 0x04; |
||||
c = 0x80; |
||||
for (i=0; i<3; i++) { |
||||
if (d3 & c) |
||||
bit |= b; |
||||
c >>= 2; |
||||
b >>= 1; |
||||
} |
||||
b = 0x01; |
||||
a = dat[add]; |
||||
a ^= (b << bit); |
||||
dat[add] = a; |
||||
return 1; |
||||
} |
||||
else { |
||||
i = 0; |
||||
while (d1) { |
||||
if (d1 & 0x01) |
||||
++i; |
||||
d1 >>= 1; |
||||
} |
||||
while (d2) { |
||||
if (d2 & 0x01) |
||||
++i; |
||||
d2 >>= 1; |
||||
} |
||||
while (d3) { |
||||
if (d3 & 0x01) |
||||
++i; |
||||
d3 >>= 1; |
||||
} |
||||
if (i == 1) { |
||||
/* ECC Code Error Correction */ |
||||
read_ecc[0] = calc_ecc[0]; |
||||
read_ecc[1] = calc_ecc[1]; |
||||
read_ecc[2] = calc_ecc[2]; |
||||
return 2; |
||||
} |
||||
else { |
||||
/* Uncorrectable Error */ |
||||
return -1; |
||||
} |
||||
} |
||||
} |
||||
|
||||
/* Should never happen */ |
||||
return -1; |
||||
} |
||||
|
||||
#endif /* CONFIG_COMMANDS & CFG_CMD_NAND */ |
@ -0,0 +1,127 @@ |
||||
/*
|
||||
* drivers/mtd/nandids.c |
||||
* |
||||
* Copyright (C) 2002 Thomas Gleixner (tglx@linutronix.de) |
||||
* |
||||
* $Id: nand_ids.c,v 1.10 2004/05/26 13:40:12 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 |
||||
* published by the Free Software Foundation. |
||||
* |
||||
*/ |
||||
#include <common.h> |
||||
|
||||
#if (CONFIG_COMMANDS & CFG_CMD_NAND) |
||||
|
||||
#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
|
||||
*/ |
||||
struct nand_flash_dev nand_flash_ids[] = { |
||||
{"NAND 1MiB 5V 8-bit", 0x6e, 256, 1, 0x1000, 0}, |
||||
{"NAND 2MiB 5V 8-bit", 0x64, 256, 2, 0x1000, 0}, |
||||
{"NAND 4MiB 5V 8-bit", 0x6b, 512, 4, 0x2000, 0}, |
||||
{"NAND 1MiB 3,3V 8-bit", 0xe8, 256, 1, 0x1000, 0}, |
||||
{"NAND 1MiB 3,3V 8-bit", 0xec, 256, 1, 0x1000, 0}, |
||||
{"NAND 2MiB 3,3V 8-bit", 0xea, 256, 2, 0x1000, 0}, |
||||
{"NAND 4MiB 3,3V 8-bit", 0xd5, 512, 4, 0x2000, 0}, |
||||
{"NAND 4MiB 3,3V 8-bit", 0xe3, 512, 4, 0x2000, 0}, |
||||
{"NAND 4MiB 3,3V 8-bit", 0xe5, 512, 4, 0x2000, 0}, |
||||
{"NAND 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 3,3V 8-bit", 0x79, 512, 128, 0x4000, 0}, |
||||
{"NAND 128MiB 1,8V 16-bit", 0x72, 512, 128, 0x4000, NAND_BUSWIDTH_16}, |
||||
{"NAND 128MiB 3,3V 16-bit", 0x74, 512, 128, 0x4000, NAND_BUSWIDTH_16}, |
||||
|
||||
{"NAND 256MiB 3,3V 8-bit", 0x71, 512, 256, 0x4000, 0}, |
||||
|
||||
{"NAND 512MiB 3,3V 8-bit", 0xDC, 512, 512, 0x4000, 0}, |
||||
|
||||
/* These are the new chips with large page size. The pagesize
|
||||
* and the erasesize is determined from the extended id bytes |
||||
*/ |
||||
/* 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}, |
||||
{"NAND 128MiB 1,8V 16-bit", 0xB1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, |
||||
{"NAND 128MiB 3,3V 16-bit", 0xC1, 0, 128, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, |
||||
|
||||
/* 2 Gigabit */ |
||||
{"NAND 256MiB 1,8V 8-bit", 0xAA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, |
||||
{"NAND 256MiB 3,3V 8-bit", 0xDA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, |
||||
{"NAND 256MiB 1,8V 16-bit", 0xBA, 0, 256, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, |
||||
{"NAND 256MiB 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}, |
||||
{"NAND 1GiB 1,8V 16-bit", 0xB3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, |
||||
{"NAND 1GiB 3,3V 16-bit", 0xC3, 0, 1024, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, |
||||
|
||||
/* 16 Gigabit */ |
||||
{"NAND 2GiB 1,8V 8-bit", 0xA5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, |
||||
{"NAND 2GiB 3,3V 8-bit", 0xD5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_NO_AUTOINCR}, |
||||
{"NAND 2GiB 1,8V 16-bit", 0xB5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, |
||||
{"NAND 2GiB 3,3V 16-bit", 0xC5, 0, 2048, 0, NAND_SAMSUNG_LP_OPTIONS | NAND_BUSWIDTH_16 | NAND_NO_AUTOINCR}, |
||||
|
||||
/* 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
|
||||
*/ |
||||
{"AND 128MiB 3,3V 8-bit", 0x01, 2048, 128, 0x4000, NAND_IS_AND | NAND_NO_AUTOINCR | NAND_4PAGE_ARRAY}, |
||||
|
||||
{NULL,} |
||||
}; |
||||
|
||||
/*
|
||||
* Manufacturer ID list |
||||
*/ |
||||
struct nand_manufacturers nand_manuf_ids[] = { |
||||
{NAND_MFR_TOSHIBA, "Toshiba"}, |
||||
{NAND_MFR_SAMSUNG, "Samsung"}, |
||||
{NAND_MFR_FUJITSU, "Fujitsu"}, |
||||
{NAND_MFR_NATIONAL, "National"}, |
||||
{NAND_MFR_RENESAS, "Renesas"}, |
||||
{NAND_MFR_STMICRO, "ST Micro"}, |
||||
{0x0, "Unknown"} |
||||
}; |
||||
#endif |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,133 @@ |
||||
#ifndef jffs2_private_h |
||||
#define jffs2_private_h |
||||
|
||||
#include <jffs2/jffs2.h> |
||||
|
||||
struct b_node { |
||||
struct b_node *next; |
||||
}; |
||||
|
||||
struct b_inode { |
||||
struct b_inode *next; |
||||
u32 offset; /* physical offset to beginning of real inode */ |
||||
u32 version; |
||||
u32 ino; |
||||
u32 isize; |
||||
u32 csize; |
||||
}; |
||||
|
||||
struct b_dirent { |
||||
struct b_dirent *next; |
||||
u32 offset; /* physical offset to beginning of real dirent */ |
||||
u32 version; |
||||
u32 pino; |
||||
u32 ino; |
||||
unsigned int nhash; |
||||
unsigned char nsize; |
||||
unsigned char type; |
||||
}; |
||||
|
||||
struct b_list { |
||||
struct b_node *listTail; |
||||
struct b_node *listHead; |
||||
unsigned int listCount; |
||||
struct mem_block *listMemBase; |
||||
}; |
||||
|
||||
struct b_lists { |
||||
char *partOffset; |
||||
struct b_list dir; |
||||
struct b_list frag; |
||||
}; |
||||
|
||||
struct b_compr_info { |
||||
u32 num_frags; |
||||
u32 compr_sum; |
||||
u32 decompr_sum; |
||||
}; |
||||
|
||||
struct b_jffs2_info { |
||||
struct b_compr_info compr_info[JFFS2_NUM_COMPR]; |
||||
}; |
||||
|
||||
static inline int |
||||
hdr_crc(struct jffs2_unknown_node *node) |
||||
{ |
||||
#if 1 |
||||
u32 crc = crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4); |
||||
#else |
||||
/* what's the semantics of this? why is this here? */ |
||||
u32 crc = crc32_no_comp(~0, (unsigned char *)node, sizeof(struct jffs2_unknown_node) - 4); |
||||
|
||||
crc ^= ~0; |
||||
#endif |
||||
if (node->hdr_crc != crc) { |
||||
return 0; |
||||
} else { |
||||
return 1; |
||||
} |
||||
} |
||||
|
||||
static inline int |
||||
dirent_crc(struct jffs2_raw_dirent *node) |
||||
{ |
||||
if (node->node_crc != crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_raw_dirent) - 8)) { |
||||
return 0; |
||||
} else { |
||||
return 1; |
||||
} |
||||
} |
||||
|
||||
static inline int |
||||
dirent_name_crc(struct jffs2_raw_dirent *node) |
||||
{ |
||||
if (node->name_crc != crc32_no_comp(0, (unsigned char *)&(node->name), node->nsize)) { |
||||
return 0; |
||||
} else { |
||||
return 1; |
||||
} |
||||
} |
||||
|
||||
static inline int |
||||
inode_crc(struct jffs2_raw_inode *node) |
||||
{ |
||||
if (node->node_crc != crc32_no_comp(0, (unsigned char *)node, sizeof(struct jffs2_raw_inode) - 8)) { |
||||
return 0; |
||||
} else { |
||||
return 1; |
||||
} |
||||
} |
||||
|
||||
/* Borrowed from include/linux/dcache.h */ |
||||
|
||||
/* Name hashing routines. Initial hash value */ |
||||
/* Hash courtesy of the R5 hash in reiserfs modulo sign bits */ |
||||
#define init_name_hash() 0 |
||||
|
||||
/* partial hash update function. Assume roughly 4 bits per character */ |
||||
static inline unsigned long |
||||
partial_name_hash(unsigned long c, unsigned long prevhash) |
||||
{ |
||||
return (prevhash + (c << 4) + (c >> 4)) * 11; |
||||
} |
||||
|
||||
/*
|
||||
* Finally: cut down the number of bits to a int value (and try to avoid |
||||
* losing bits) |
||||
*/ |
||||
static inline unsigned long end_name_hash(unsigned long hash) |
||||
{ |
||||
return (unsigned int) hash; |
||||
} |
||||
|
||||
/* Compute the hash for a name string. */ |
||||
static inline unsigned int |
||||
full_name_hash(const unsigned char *name, unsigned int len) |
||||
{ |
||||
unsigned long hash = init_name_hash(); |
||||
while (len--) |
||||
hash = partial_name_hash(*name++, hash); |
||||
return end_name_hash(hash); |
||||
} |
||||
|
||||
#endif /* jffs2_private.h */ |
@ -0,0 +1,44 @@ |
||||
#ifndef _LINUX_COMPAT_H_ |
||||
#define _LINUX_COMPAT_H_ |
||||
|
||||
#define __user |
||||
#define __iomem |
||||
|
||||
#define ndelay(x) udelay(1) |
||||
|
||||
#define printk printf |
||||
|
||||
#define KERN_EMERG |
||||
#define KERN_ALERT |
||||
#define KERN_CRIT |
||||
#define KERN_ERR |
||||
#define KERN_WARNING |
||||
#define KERN_NOTICE |
||||
#define KERN_INFO |
||||
#define KERN_DEBUG |
||||
|
||||
#define kmalloc(size, flags) malloc(size) |
||||
#define kfree(ptr) free(ptr) |
||||
|
||||
/*
|
||||
* ..and if you can't take the strict |
||||
* types, you can specify one yourself. |
||||
* |
||||
* Or not use min/max at all, of course. |
||||
*/ |
||||
#define min_t(type,x,y) \ |
||||
({ type __x = (x); type __y = (y); __x < __y ? __x: __y; }) |
||||
#define max_t(type,x,y) \ |
||||
({ type __x = (x); type __y = (y); __x > __y ? __x: __y; }) |
||||
|
||||
#define BUG() do { \ |
||||
printf("U-Boot BUG at %s:%d!\n", __FILE__, __LINE__); \
|
||||
} while (0) |
||||
|
||||
#define BUG_ON(condition) do { if (condition) BUG(); } while(0) |
||||
|
||||
#define likely(x) __builtin_expect(!!(x), 1) |
||||
#define unlikely(x) __builtin_expect(!!(x), 0) |
||||
|
||||
#define PAGE_SIZE 4096 |
||||
#endif |
@ -0,0 +1,99 @@ |
||||
/*
|
||||
* $Id: mtd-abi.h,v 1.7 2004/11/23 15:37:32 gleixner Exp $ |
||||
* |
||||
* Portions of MTD ABI definition which are shared by kernel and user space
|
||||
*/ |
||||
|
||||
#ifndef __MTD_ABI_H__ |
||||
#define __MTD_ABI_H__ |
||||
|
||||
struct erase_info_user { |
||||
uint32_t start; |
||||
uint32_t length; |
||||
}; |
||||
|
||||
struct mtd_oob_buf { |
||||
uint32_t start; |
||||
uint32_t length; |
||||
unsigned char *ptr; |
||||
}; |
||||
|
||||
#define MTD_ABSENT 0 |
||||
#define MTD_RAM 1 |
||||
#define MTD_ROM 2 |
||||
#define MTD_NORFLASH 3 |
||||
#define MTD_NANDFLASH 4 |
||||
#define MTD_PEROM 5 |
||||
#define MTD_OTHER 14 |
||||
#define MTD_UNKNOWN 15 |
||||
|
||||
#define MTD_CLEAR_BITS 1 // Bits can be cleared (flash)
|
||||
#define MTD_SET_BITS 2 // Bits can be set
|
||||
#define MTD_ERASEABLE 4 // Has an erase function
|
||||
#define MTD_WRITEB_WRITEABLE 8 // Direct IO is possible
|
||||
#define MTD_VOLATILE 16 // Set for RAMs
|
||||
#define MTD_XIP 32 // eXecute-In-Place possible
|
||||
#define MTD_OOB 64 // Out-of-band data (NAND flash)
|
||||
#define MTD_ECC 128 // Device capable of automatic ECC
|
||||
#define MTD_NO_VIRTBLOCKS 256 // Virtual blocks not allowed
|
||||
|
||||
// Some common devices / combinations of capabilities
|
||||
#define MTD_CAP_ROM 0 |
||||
#define MTD_CAP_RAM (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEB_WRITEABLE) |
||||
#define MTD_CAP_NORFLASH (MTD_CLEAR_BITS|MTD_ERASEABLE) |
||||
#define MTD_CAP_NANDFLASH (MTD_CLEAR_BITS|MTD_ERASEABLE|MTD_OOB) |
||||
#define MTD_WRITEABLE (MTD_CLEAR_BITS|MTD_SET_BITS) |
||||
|
||||
|
||||
// Types of automatic ECC/Checksum available
|
||||
#define MTD_ECC_NONE 0 // No automatic ECC available
|
||||
#define MTD_ECC_RS_DiskOnChip 1 // Automatic ECC on DiskOnChip
|
||||
#define MTD_ECC_SW 2 // SW ECC for Toshiba & Samsung devices
|
||||
|
||||
/* ECC byte placement */ |
||||
#define MTD_NANDECC_OFF 0 // Switch off ECC (Not recommended)
|
||||
#define MTD_NANDECC_PLACE 1 // Use the given placement in the structure (YAFFS1 legacy mode)
|
||||
#define MTD_NANDECC_AUTOPLACE 2 // Use the default placement scheme
|
||||
#define MTD_NANDECC_PLACEONLY 3 // Use the given placement in the structure (Do not store ecc result on read)
|
||||
#define MTD_NANDECC_AUTOPL_USR 4 // Use the given autoplacement scheme rather than using the default
|
||||
|
||||
struct mtd_info_user { |
||||
uint8_t type; |
||||
uint32_t flags; |
||||
uint32_t size; // Total size of the MTD
|
||||
uint32_t erasesize; |
||||
uint32_t oobblock; // Size of OOB blocks (e.g. 512)
|
||||
uint32_t oobsize; // Amount of OOB data per block (e.g. 16)
|
||||
uint32_t ecctype; |
||||
uint32_t eccsize; |
||||
}; |
||||
|
||||
struct region_info_user { |
||||
uint32_t offset; /* At which this region starts,
|
||||
* from the beginning of the MTD */ |
||||
uint32_t erasesize; /* For this region */ |
||||
uint32_t numblocks; /* Number of blocks in this region */ |
||||
uint32_t regionindex; |
||||
}; |
||||
|
||||
#define MEMGETINFO _IOR('M', 1, struct mtd_info_user) |
||||
#define MEMERASE _IOW('M', 2, struct erase_info_user) |
||||
#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf) |
||||
#define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf) |
||||
#define MEMLOCK _IOW('M', 5, struct erase_info_user) |
||||
#define MEMUNLOCK _IOW('M', 6, struct erase_info_user) |
||||
#define MEMGETREGIONCOUNT _IOR('M', 7, int) |
||||
#define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user) |
||||
#define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo) |
||||
#define MEMGETOOBSEL _IOR('M', 10, struct nand_oobinfo) |
||||
#define MEMGETBADBLOCK _IOW('M', 11, loff_t) |
||||
#define MEMSETBADBLOCK _IOW('M', 12, loff_t) |
||||
|
||||
struct nand_oobinfo { |
||||
uint32_t useecc; |
||||
uint32_t eccbytes; |
||||
uint32_t oobfree[8][2]; |
||||
uint32_t eccpos[32]; |
||||
}; |
||||
|
||||
#endif /* __MTD_ABI_H__ */ |
@ -0,0 +1,214 @@ |
||||
/*
|
||||
* $Id: mtd.h,v 1.56 2004/08/09 18:46:04 dmarlin Exp $ |
||||
* |
||||
* Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al. |
||||
* |
||||
* Released under GPL |
||||
*/ |
||||
|
||||
#ifndef __MTD_MTD_H__ |
||||
#define __MTD_MTD_H__ |
||||
#include <linux/types.h> |
||||
#include <linux/mtd/mtd-abi.h> |
||||
|
||||
#define MAX_MTD_DEVICES 16 |
||||
|
||||
#define MTD_ERASE_PENDING 0x01 |
||||
#define MTD_ERASING 0x02 |
||||
#define MTD_ERASE_SUSPEND 0x04 |
||||
#define MTD_ERASE_DONE 0x08 |
||||
#define MTD_ERASE_FAILED 0x10 |
||||
|
||||
/* If the erase fails, fail_addr might indicate exactly which block failed. If
|
||||
fail_addr = 0xffffffff, the failure was not at the device level or was not |
||||
specific to any particular block. */ |
||||
struct erase_info { |
||||
struct mtd_info *mtd; |
||||
u_int32_t addr; |
||||
u_int32_t len; |
||||
u_int32_t fail_addr; |
||||
u_long time; |
||||
u_long retries; |
||||
u_int dev; |
||||
u_int cell; |
||||
void (*callback) (struct erase_info *self); |
||||
u_long priv; |
||||
u_char state; |
||||
struct erase_info *next; |
||||
}; |
||||
|
||||
struct mtd_erase_region_info { |
||||
u_int32_t offset; /* At which this region starts, from the beginning of the MTD */ |
||||
u_int32_t erasesize; /* For this region */ |
||||
u_int32_t numblocks; /* Number of blocks of erasesize in this region */ |
||||
}; |
||||
|
||||
struct mtd_info { |
||||
u_char type; |
||||
u_int32_t flags; |
||||
u_int32_t size; // Total size of the MTD
|
||||
|
||||
/* "Major" erase size for the device. Naïve users may take this
|
||||
* to be the only erase size available, or may use the more detailed |
||||
* information below if they desire |
||||
*/ |
||||
u_int32_t erasesize; |
||||
|
||||
u_int32_t oobblock; // Size of OOB blocks (e.g. 512)
|
||||
u_int32_t oobsize; // Amount of OOB data per block (e.g. 16)
|
||||
u_int32_t oobavail; // Number of bytes in OOB area available for fs
|
||||
u_int32_t ecctype; |
||||
u_int32_t eccsize; |
||||
|
||||
|
||||
// Kernel-only stuff starts here.
|
||||
char *name; |
||||
int index; |
||||
|
||||
// oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO)
|
||||
struct nand_oobinfo oobinfo; |
||||
|
||||
/* Data for variable erase regions. If numeraseregions is zero,
|
||||
* it means that the whole device has erasesize as given above.
|
||||
*/ |
||||
int numeraseregions; |
||||
struct mtd_erase_region_info *eraseregions;
|
||||
|
||||
/* This really shouldn't be here. It can go away in 2.5 */ |
||||
u_int32_t bank_size; |
||||
|
||||
int (*erase) (struct mtd_info *mtd, struct erase_info *instr); |
||||
|
||||
/* This stuff for eXecute-In-Place */ |
||||
int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); |
||||
|
||||
/* We probably shouldn't allow XIP if the unpoint isn't a NULL */ |
||||
void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len); |
||||
|
||||
|
||||
int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); |
||||
int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); |
||||
|
||||
int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); |
||||
int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel); |
||||
|
||||
int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); |
||||
int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); |
||||
|
||||
/*
|
||||
* Methods to access the protection register area, present in some
|
||||
* flash devices. The user data is one time programmable but the |
||||
* factory data is read only.
|
||||
*/ |
||||
int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); |
||||
|
||||
int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); |
||||
|
||||
/* This function is not yet implemented */ |
||||
int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); |
||||
#if 0 |
||||
/* kvec-based read/write methods. We need these especially for NAND flash,
|
||||
with its limited number of write cycles per erase. |
||||
NB: The 'count' parameter is the number of _vectors_, each of
|
||||
which contains an (ofs, len) tuple. |
||||
*/ |
||||
int (*readv) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen); |
||||
int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from,
|
||||
size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); |
||||
int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); |
||||
int (*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); |
||||
#endif |
||||
/* Sync */ |
||||
void (*sync) (struct mtd_info *mtd); |
||||
#if 0 |
||||
/* Chip-supported device locking */ |
||||
int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len); |
||||
int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len); |
||||
|
||||
/* Power Management functions */ |
||||
int (*suspend) (struct mtd_info *mtd); |
||||
void (*resume) (struct mtd_info *mtd); |
||||
#endif |
||||
/* Bad block management functions */ |
||||
int (*block_isbad) (struct mtd_info *mtd, loff_t ofs); |
||||
int (*block_markbad) (struct mtd_info *mtd, loff_t ofs); |
||||
|
||||
void *priv; |
||||
|
||||
struct module *owner; |
||||
int usecount; |
||||
}; |
||||
|
||||
|
||||
/* Kernel-side ioctl definitions */ |
||||
|
||||
extern int add_mtd_device(struct mtd_info *mtd); |
||||
extern int del_mtd_device (struct mtd_info *mtd); |
||||
|
||||
extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num); |
||||
|
||||
extern void put_mtd_device(struct mtd_info *mtd); |
||||
|
||||
#if 0 |
||||
struct mtd_notifier { |
||||
void (*add)(struct mtd_info *mtd); |
||||
void (*remove)(struct mtd_info *mtd); |
||||
struct list_head list; |
||||
}; |
||||
|
||||
|
||||
extern void register_mtd_user (struct mtd_notifier *new); |
||||
extern int unregister_mtd_user (struct mtd_notifier *old); |
||||
|
||||
int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, |
||||
unsigned long count, loff_t to, size_t *retlen); |
||||
|
||||
int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, |
||||
unsigned long count, loff_t from, size_t *retlen); |
||||
#endif |
||||
|
||||
#define MTD_ERASE(mtd, args...) (*(mtd->erase))(mtd, args) |
||||
#define MTD_POINT(mtd, a,b,c,d) (*(mtd->point))(mtd, a,b,c, (u_char **)(d)) |
||||
#define MTD_UNPOINT(mtd, arg) (*(mtd->unpoint))(mtd, (u_char *)arg) |
||||
#define MTD_READ(mtd, args...) (*(mtd->read))(mtd, args) |
||||
#define MTD_WRITE(mtd, args...) (*(mtd->write))(mtd, args) |
||||
#define MTD_READV(mtd, args...) (*(mtd->readv))(mtd, args) |
||||
#define MTD_WRITEV(mtd, args...) (*(mtd->writev))(mtd, args) |
||||
#define MTD_READECC(mtd, args...) (*(mtd->read_ecc))(mtd, args) |
||||
#define MTD_WRITEECC(mtd, args...) (*(mtd->write_ecc))(mtd, args) |
||||
#define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args) |
||||
#define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args) |
||||
#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0) |
||||
|
||||
|
||||
#ifdef CONFIG_MTD_PARTITIONS |
||||
void mtd_erase_callback(struct erase_info *instr); |
||||
#else |
||||
static inline void mtd_erase_callback(struct erase_info *instr) |
||||
{ |
||||
if (instr->callback) |
||||
instr->callback(instr); |
||||
} |
||||
#endif |
||||
|
||||
/*
|
||||
* Debugging macro and defines |
||||
*/ |
||||
#define MTD_DEBUG_LEVEL0 (0) /* Quiet */ |
||||
#define MTD_DEBUG_LEVEL1 (1) /* Audible */ |
||||
#define MTD_DEBUG_LEVEL2 (2) /* Loud */ |
||||
#define MTD_DEBUG_LEVEL3 (3) /* Noisy */ |
||||
|
||||
#ifdef CONFIG_MTD_DEBUG |
||||
#define DEBUG(n, args...) \ |
||||
do { \
|
||||
if (n <= CONFIG_MTD_DEBUG_VERBOSE) \
|
||||
printk(KERN_INFO args); \
|
||||
} while(0) |
||||
#else /* CONFIG_MTD_DEBUG */ |
||||
#define DEBUG(n, args...) do { } while(0) |
||||
|
||||
#endif /* CONFIG_MTD_DEBUG */ |
||||
|
||||
#endif /* __MTD_MTD_H__ */ |
@ -0,0 +1,30 @@ |
||||
/*
|
||||
* drivers/mtd/nand_ecc.h |
||||
* |
||||
* Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) |
||||
* |
||||
* $Id: nand_ecc.h,v 1.4 2004/06/17 02:35:02 dbrown 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 |
||||
* published by the Free Software Foundation. |
||||
* |
||||
* This file is the header for the ECC algorithm. |
||||
*/ |
||||
|
||||
#ifndef __MTD_NAND_ECC_H__ |
||||
#define __MTD_NAND_ECC_H__ |
||||
|
||||
struct mtd_info; |
||||
|
||||
/*
|
||||
* Calculate 3 byte ECC code for 256 byte block |
||||
*/ |
||||
int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); |
||||
|
||||
/*
|
||||
* Detect and correct a 1 bit error for 256 byte block |
||||
*/ |
||||
int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); |
||||
|
||||
#endif /* __MTD_NAND_ECC_H__ */ |
@ -0,0 +1,56 @@ |
||||
/*
|
||||
* (C) Copyright 2005 |
||||
* 2N Telekomunikace, a.s. <www.2n.cz> |
||||
* Ladislav Michl <michl@2n.cz> |
||||
* |
||||
* See file CREDITS for list of people who contributed to this |
||||
* project. |
||||
* |
||||
* 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 published by the Free Software Foundation. |
||||
* |
||||
* This program 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 program; if not, write to the Free Software |
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, |
||||
* MA 02111-1307 USA |
||||
*/ |
||||
|
||||
#ifndef _NAND_H_ |
||||
#define _NAND_H_ |
||||
|
||||
#include <linux_compat.h> |
||||
#include <linux/mtd/mtd.h> |
||||
#include <linux/mtd/nand.h> |
||||
|
||||
typedef struct mtd_info nand_info_t; |
||||
|
||||
extern int nand_curr_device; |
||||
extern nand_info_t nand_info[]; |
||||
|
||||
static inline int nand_read(nand_info_t *info, ulong ofs, ulong *len, u_char *buf) |
||||
{ |
||||
return info->read(info, ofs, *len, len, buf); |
||||
} |
||||
|
||||
static inline int nand_write(nand_info_t *info, ulong ofs, ulong *len, u_char *buf) |
||||
{ |
||||
return info->write(info, ofs, *len, len, buf); |
||||
} |
||||
|
||||
static inline int nand_block_isbad(nand_info_t *info, ulong ofs) |
||||
{ |
||||
return info->block_isbad(info, ofs); |
||||
} |
||||
|
||||
static inline int nand_erase(nand_info_t *info, ulong off, ulong size) |
||||
{ |
||||
return 0; /* FIXME */ |
||||
} |
||||
|
||||
#endif |
Loading…
Reference in new issue