aboutsummaryrefslogtreecommitdiffstats
path: root/include/linux/mtd/bbm.h
blob: 25a3d3a3d1529629ad52daf433c9528bdaea9f36 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
/*
 *  linux/include/linux/mtd/bbm.h
 *
 *  NAND family Bad Block Management (BBM) header file
 *    - Bad Block Table (BBT) implementation
 *
 *  Copyright (c) 2005-2007 Samsung Electronics
 *  Kyungmin Park <kyungmin.park@samsung.com>
 *
 *  Copyright (c) 2000-2005
 *  Thomas Gleixner <tglx@linuxtronix.de>
 *
 * SPDX-License-Identifier:	GPL-2.0+
 */
#ifndef __LINUX_MTD_BBM_H
#define __LINUX_MTD_BBM_H

/* The maximum number of NAND chips in an array */
#ifndef CONFIG_SYS_NAND_MAX_CHIPS
#define CONFIG_SYS_NAND_MAX_CHIPS	1
#endif

/**
 * struct nand_bbt_descr - bad block table descriptor
 * @param options	options for this descriptor
 * @param pages		the page(s) where we find the bbt, used with
 *			option BBT_ABSPAGE when bbt is searched,
 *			then we store the found bbts pages here.
 *			Its an array and supports up to 8 chips now
 * @param offs		offset of the pattern in the oob area of the page
 * @param veroffs	offset of the bbt version counter in the oob are of the page
 * @param version	version read from the bbt page during scan
 * @param len		length of the pattern, if 0 no pattern check is performed
 * @param maxblocks	maximum number of blocks to search for a bbt. This number of
 *			blocks is reserved at the end of the device
 *			where the tables are written.
 * @param reserved_block_code	if non-0, this pattern denotes a reserved
 *			(rather than bad) block in the stored bbt
 * @param pattern	pattern to identify bad block table or factory marked
 *			good / bad blocks, can be NULL, if len = 0
 *
 * Descriptor for the bad block table marker and the descriptor for the
 * pattern which identifies good and bad blocks. The assumption is made
 * that the pattern and the version count are always located in the oob area
 * of the first block.
 */
struct nand_bbt_descr {
	int options;
	int pages[CONFIG_SYS_NAND_MAX_CHIPS];
	int offs;
	int veroffs;
	uint8_t version[CONFIG_SYS_NAND_MAX_CHIPS];
	int len;
	int maxblocks;
	int reserved_block_code;
	uint8_t *pattern;
};

/* Options for the bad block table descriptors */

/* The number of bits used per block in the bbt on the device */
#define NAND_BBT_NRBITS_MSK	0x0000000F
#define NAND_BBT_1BIT		0x00000001
#define NAND_BBT_2BIT		0x00000002
#define NAND_BBT_4BIT		0x00000004
#define NAND_BBT_8BIT		0x00000008
/* The bad block table is in the last good block of the device */
#define NAND_BBT_LASTBLOCK	0x00000010
/* The bbt is at the given page, else we must scan for the bbt */
#define NAND_BBT_ABSPAGE	0x00000020
/* bbt is stored per chip on multichip devices */
#define NAND_BBT_PERCHIP	0x00000080
/* bbt has a version counter at offset veroffs */
#define NAND_BBT_VERSION	0x00000100
/* Create a bbt if none exists */
#define NAND_BBT_CREATE		0x00000200
/*
 * Create an empty BBT with no vendor information. Vendor's information may be
 * unavailable, for example, if the NAND controller has a different data and OOB
 * layout or if this information is already purged. Must be used in conjunction
 * with NAND_BBT_CREATE.
 */
#define NAND_BBT_CREATE_EMPTY	0x00000400
/* Search good / bad pattern through all pages of a block */
#define NAND_BBT_SCANALLPAGES	0x00000800
/* Scan block empty during good / bad block scan */
#define NAND_BBT_SCANEMPTY	0x00001000
/* Write bbt if neccecary */
#define NAND_BBT_WRITE		0x00002000
/* Read and write back block contents when writing bbt */
#define NAND_BBT_SAVECONTENT	0x00004000
/* Search good / bad pattern on the first and the second page */
#define NAND_BBT_SCAN2NDPAGE	0x00008000
/* Search good / bad pattern on the last page of the eraseblock */
#define NAND_BBT_SCANLASTPAGE	0x00010000
/*
 * Use a flash based bad block table. By default, OOB identifier is saved in
 * OOB area. This option is passed to the default bad block table function.
 */
#define NAND_BBT_USE_FLASH	0x00020000
/*
 * Do not store flash based bad block table marker in the OOB area; store it
 * in-band.
 */
#define NAND_BBT_NO_OOB		0x00040000
/*
 * Do not write new bad block markers to OOB; useful, e.g., when ECC covers
 * entire spare area. Must be used with NAND_BBT_USE_FLASH.
 */
#define NAND_BBT_NO_OOB_BBM	0x00080000

/*
 * Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr
 * was allocated dynamicaly and must be freed in nand_release(). Has no meaning
 * in nand_chip.bbt_options.
 */
#define NAND_BBT_DYNAMICSTRUCT	0x80000000

/* The maximum number of blocks to scan for a bbt */
#define NAND_BBT_SCAN_MAXBLOCKS	4

/*
 * Constants for oob configuration
 */
#define ONENAND_BADBLOCK_POS	0

/*
 * Bad block scanning errors
 */
#define ONENAND_BBT_READ_ERROR          1
#define ONENAND_BBT_READ_ECC_ERROR      2
#define ONENAND_BBT_READ_FATAL_ERROR    4

/**
 * struct bbt_info - [GENERIC] Bad Block Table data structure
 * @param bbt_erase_shift	[INTERN] number of address bits in a bbt entry
 * @param badblockpos		[INTERN] position of the bad block marker in the oob area
 * @param bbt			[INTERN] bad block table pointer
 * @param badblock_pattern	[REPLACEABLE] bad block scan pattern used for initial bad block scan
 * @param priv			[OPTIONAL] pointer to private bbm date
 */
struct bbm_info {
	int bbt_erase_shift;
	int badblockpos;
	int options;

	uint8_t *bbt;

	int (*isbad_bbt) (struct mtd_info * mtd, loff_t ofs, int allowbbt);

	/* TODO Add more NAND specific fileds */
	struct nand_bbt_descr *badblock_pattern;

	void *priv;
};

/* OneNAND BBT interface */
extern int onenand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd);
extern int onenand_default_bbt (struct mtd_info *mtd);

#endif				/* __LINUX_MTD_BBM_H */