diff options
Diffstat (limited to 'include/linux/mtd')
-rw-r--r-- | include/linux/mtd/blktrans.h | 72 | ||||
-rw-r--r-- | include/linux/mtd/cfi.h | 394 | ||||
-rw-r--r-- | include/linux/mtd/cfi_endian.h | 57 | ||||
-rw-r--r-- | include/linux/mtd/compatmac.h | 10 | ||||
-rw-r--r-- | include/linux/mtd/concat.h | 23 | ||||
-rw-r--r-- | include/linux/mtd/doc2000.h | 195 | ||||
-rw-r--r-- | include/linux/mtd/flashchip.h | 89 | ||||
-rw-r--r-- | include/linux/mtd/ftl.h | 76 | ||||
-rw-r--r-- | include/linux/mtd/gen_probe.h | 23 | ||||
-rw-r--r-- | include/linux/mtd/iflash.h | 98 | ||||
-rw-r--r-- | include/linux/mtd/inftl.h | 57 | ||||
-rw-r--r-- | include/linux/mtd/jedec.h | 66 | ||||
-rw-r--r-- | include/linux/mtd/map.h | 412 | ||||
-rw-r--r-- | include/linux/mtd/mtd.h | 226 | ||||
-rw-r--r-- | include/linux/mtd/nand.h | 469 | ||||
-rw-r--r-- | include/linux/mtd/nand_ecc.h | 30 | ||||
-rw-r--r-- | include/linux/mtd/nftl.h | 54 | ||||
-rw-r--r-- | include/linux/mtd/partitions.h | 75 | ||||
-rw-r--r-- | include/linux/mtd/physmap.h | 61 | ||||
-rw-r--r-- | include/linux/mtd/pmc551.h | 79 | ||||
-rw-r--r-- | include/linux/mtd/xip.h | 107 |
21 files changed, 2673 insertions, 0 deletions
diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h new file mode 100644 index 000000000000..4ebc2e5a16e2 --- /dev/null +++ b/include/linux/mtd/blktrans.h | |||
@@ -0,0 +1,72 @@ | |||
1 | /* | ||
2 | * $Id: blktrans.h,v 1.5 2003/06/23 12:00:08 dwmw2 Exp $ | ||
3 | * | ||
4 | * (C) 2003 David Woodhouse <dwmw2@infradead.org> | ||
5 | * | ||
6 | * Interface to Linux block layer for MTD 'translation layers'. | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #ifndef __MTD_TRANS_H__ | ||
11 | #define __MTD_TRANS_H__ | ||
12 | |||
13 | #include <asm/semaphore.h> | ||
14 | |||
15 | struct hd_geometry; | ||
16 | struct mtd_info; | ||
17 | struct mtd_blktrans_ops; | ||
18 | struct file; | ||
19 | struct inode; | ||
20 | |||
21 | struct mtd_blktrans_dev { | ||
22 | struct mtd_blktrans_ops *tr; | ||
23 | struct list_head list; | ||
24 | struct mtd_info *mtd; | ||
25 | struct semaphore sem; | ||
26 | int devnum; | ||
27 | int blksize; | ||
28 | unsigned long size; | ||
29 | int readonly; | ||
30 | void *blkcore_priv; /* gendisk in 2.5, devfs_handle in 2.4 */ | ||
31 | }; | ||
32 | |||
33 | struct blkcore_priv; /* Differs for 2.4 and 2.5 kernels; private */ | ||
34 | |||
35 | struct mtd_blktrans_ops { | ||
36 | char *name; | ||
37 | int major; | ||
38 | int part_bits; | ||
39 | |||
40 | /* Access functions */ | ||
41 | int (*readsect)(struct mtd_blktrans_dev *dev, | ||
42 | unsigned long block, char *buffer); | ||
43 | int (*writesect)(struct mtd_blktrans_dev *dev, | ||
44 | unsigned long block, char *buffer); | ||
45 | |||
46 | /* Block layer ioctls */ | ||
47 | int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo); | ||
48 | int (*flush)(struct mtd_blktrans_dev *dev); | ||
49 | |||
50 | /* Called with mtd_table_mutex held; no race with add/remove */ | ||
51 | int (*open)(struct mtd_blktrans_dev *dev); | ||
52 | int (*release)(struct mtd_blktrans_dev *dev); | ||
53 | |||
54 | /* Called on {de,}registration and on subsequent addition/removal | ||
55 | of devices, with mtd_table_mutex held. */ | ||
56 | void (*add_mtd)(struct mtd_blktrans_ops *tr, struct mtd_info *mtd); | ||
57 | void (*remove_dev)(struct mtd_blktrans_dev *dev); | ||
58 | |||
59 | struct list_head devs; | ||
60 | struct list_head list; | ||
61 | struct module *owner; | ||
62 | |||
63 | struct mtd_blkcore_priv *blkcore_priv; | ||
64 | }; | ||
65 | |||
66 | extern int register_mtd_blktrans(struct mtd_blktrans_ops *tr); | ||
67 | extern int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr); | ||
68 | extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); | ||
69 | extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev); | ||
70 | |||
71 | |||
72 | #endif /* __MTD_TRANS_H__ */ | ||
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h new file mode 100644 index 000000000000..2ed8c585021e --- /dev/null +++ b/include/linux/mtd/cfi.h | |||
@@ -0,0 +1,394 @@ | |||
1 | |||
2 | /* Common Flash Interface structures | ||
3 | * See http://support.intel.com/design/flash/technote/index.htm | ||
4 | * $Id: cfi.h,v 1.50 2004/11/20 12:46:51 dwmw2 Exp $ | ||
5 | */ | ||
6 | |||
7 | #ifndef __MTD_CFI_H__ | ||
8 | #define __MTD_CFI_H__ | ||
9 | |||
10 | #include <linux/config.h> | ||
11 | #include <linux/version.h> | ||
12 | #include <linux/delay.h> | ||
13 | #include <linux/types.h> | ||
14 | #include <linux/interrupt.h> | ||
15 | #include <linux/mtd/flashchip.h> | ||
16 | #include <linux/mtd/map.h> | ||
17 | #include <linux/mtd/cfi_endian.h> | ||
18 | |||
19 | #ifdef CONFIG_MTD_CFI_I1 | ||
20 | #define cfi_interleave(cfi) 1 | ||
21 | #define cfi_interleave_is_1(cfi) (cfi_interleave(cfi) == 1) | ||
22 | #else | ||
23 | #define cfi_interleave_is_1(cfi) (0) | ||
24 | #endif | ||
25 | |||
26 | #ifdef CONFIG_MTD_CFI_I2 | ||
27 | # ifdef cfi_interleave | ||
28 | # undef cfi_interleave | ||
29 | # define cfi_interleave(cfi) ((cfi)->interleave) | ||
30 | # else | ||
31 | # define cfi_interleave(cfi) 2 | ||
32 | # endif | ||
33 | #define cfi_interleave_is_2(cfi) (cfi_interleave(cfi) == 2) | ||
34 | #else | ||
35 | #define cfi_interleave_is_2(cfi) (0) | ||
36 | #endif | ||
37 | |||
38 | #ifdef CONFIG_MTD_CFI_I4 | ||
39 | # ifdef cfi_interleave | ||
40 | # undef cfi_interleave | ||
41 | # define cfi_interleave(cfi) ((cfi)->interleave) | ||
42 | # else | ||
43 | # define cfi_interleave(cfi) 4 | ||
44 | # endif | ||
45 | #define cfi_interleave_is_4(cfi) (cfi_interleave(cfi) == 4) | ||
46 | #else | ||
47 | #define cfi_interleave_is_4(cfi) (0) | ||
48 | #endif | ||
49 | |||
50 | #ifdef CONFIG_MTD_CFI_I8 | ||
51 | # ifdef cfi_interleave | ||
52 | # undef cfi_interleave | ||
53 | # define cfi_interleave(cfi) ((cfi)->interleave) | ||
54 | # else | ||
55 | # define cfi_interleave(cfi) 8 | ||
56 | # endif | ||
57 | #define cfi_interleave_is_8(cfi) (cfi_interleave(cfi) == 8) | ||
58 | #else | ||
59 | #define cfi_interleave_is_8(cfi) (0) | ||
60 | #endif | ||
61 | |||
62 | static inline int cfi_interleave_supported(int i) | ||
63 | { | ||
64 | switch (i) { | ||
65 | #ifdef CONFIG_MTD_CFI_I1 | ||
66 | case 1: | ||
67 | #endif | ||
68 | #ifdef CONFIG_MTD_CFI_I2 | ||
69 | case 2: | ||
70 | #endif | ||
71 | #ifdef CONFIG_MTD_CFI_I4 | ||
72 | case 4: | ||
73 | #endif | ||
74 | #ifdef CONFIG_MTD_CFI_I8 | ||
75 | case 8: | ||
76 | #endif | ||
77 | return 1; | ||
78 | |||
79 | default: | ||
80 | return 0; | ||
81 | } | ||
82 | } | ||
83 | |||
84 | |||
85 | /* NB: these values must represents the number of bytes needed to meet the | ||
86 | * device type (x8, x16, x32). Eg. a 32 bit device is 4 x 8 bytes. | ||
87 | * These numbers are used in calculations. | ||
88 | */ | ||
89 | #define CFI_DEVICETYPE_X8 (8 / 8) | ||
90 | #define CFI_DEVICETYPE_X16 (16 / 8) | ||
91 | #define CFI_DEVICETYPE_X32 (32 / 8) | ||
92 | #define CFI_DEVICETYPE_X64 (64 / 8) | ||
93 | |||
94 | /* NB: We keep these structures in memory in HOST byteorder, except | ||
95 | * where individually noted. | ||
96 | */ | ||
97 | |||
98 | /* Basic Query Structure */ | ||
99 | struct cfi_ident { | ||
100 | uint8_t qry[3]; | ||
101 | uint16_t P_ID; | ||
102 | uint16_t P_ADR; | ||
103 | uint16_t A_ID; | ||
104 | uint16_t A_ADR; | ||
105 | uint8_t VccMin; | ||
106 | uint8_t VccMax; | ||
107 | uint8_t VppMin; | ||
108 | uint8_t VppMax; | ||
109 | uint8_t WordWriteTimeoutTyp; | ||
110 | uint8_t BufWriteTimeoutTyp; | ||
111 | uint8_t BlockEraseTimeoutTyp; | ||
112 | uint8_t ChipEraseTimeoutTyp; | ||
113 | uint8_t WordWriteTimeoutMax; | ||
114 | uint8_t BufWriteTimeoutMax; | ||
115 | uint8_t BlockEraseTimeoutMax; | ||
116 | uint8_t ChipEraseTimeoutMax; | ||
117 | uint8_t DevSize; | ||
118 | uint16_t InterfaceDesc; | ||
119 | uint16_t MaxBufWriteSize; | ||
120 | uint8_t NumEraseRegions; | ||
121 | uint32_t EraseRegionInfo[0]; /* Not host ordered */ | ||
122 | } __attribute__((packed)); | ||
123 | |||
124 | /* Extended Query Structure for both PRI and ALT */ | ||
125 | |||
126 | struct cfi_extquery { | ||
127 | uint8_t pri[3]; | ||
128 | uint8_t MajorVersion; | ||
129 | uint8_t MinorVersion; | ||
130 | } __attribute__((packed)); | ||
131 | |||
132 | /* Vendor-Specific PRI for Intel/Sharp Extended Command Set (0x0001) */ | ||
133 | |||
134 | struct cfi_pri_intelext { | ||
135 | uint8_t pri[3]; | ||
136 | uint8_t MajorVersion; | ||
137 | uint8_t MinorVersion; | ||
138 | uint32_t FeatureSupport; /* if bit 31 is set then an additional uint32_t feature | ||
139 | block follows - FIXME - not currently supported */ | ||
140 | uint8_t SuspendCmdSupport; | ||
141 | uint16_t BlkStatusRegMask; | ||
142 | uint8_t VccOptimal; | ||
143 | uint8_t VppOptimal; | ||
144 | uint8_t NumProtectionFields; | ||
145 | uint16_t ProtRegAddr; | ||
146 | uint8_t FactProtRegSize; | ||
147 | uint8_t UserProtRegSize; | ||
148 | uint8_t extra[0]; | ||
149 | } __attribute__((packed)); | ||
150 | |||
151 | struct cfi_intelext_blockinfo { | ||
152 | uint16_t NumIdentBlocks; | ||
153 | uint16_t BlockSize; | ||
154 | uint16_t MinBlockEraseCycles; | ||
155 | uint8_t BitsPerCell; | ||
156 | uint8_t BlockCap; | ||
157 | } __attribute__((packed)); | ||
158 | |||
159 | struct cfi_intelext_regioninfo { | ||
160 | uint16_t NumIdentPartitions; | ||
161 | uint8_t NumOpAllowed; | ||
162 | uint8_t NumOpAllowedSimProgMode; | ||
163 | uint8_t NumOpAllowedSimEraMode; | ||
164 | uint8_t NumBlockTypes; | ||
165 | struct cfi_intelext_blockinfo BlockTypes[1]; | ||
166 | } __attribute__((packed)); | ||
167 | |||
168 | /* Vendor-Specific PRI for AMD/Fujitsu Extended Command Set (0x0002) */ | ||
169 | |||
170 | struct cfi_pri_amdstd { | ||
171 | uint8_t pri[3]; | ||
172 | uint8_t MajorVersion; | ||
173 | uint8_t MinorVersion; | ||
174 | uint8_t SiliconRevision; /* bits 1-0: Address Sensitive Unlock */ | ||
175 | uint8_t EraseSuspend; | ||
176 | uint8_t BlkProt; | ||
177 | uint8_t TmpBlkUnprotect; | ||
178 | uint8_t BlkProtUnprot; | ||
179 | uint8_t SimultaneousOps; | ||
180 | uint8_t BurstMode; | ||
181 | uint8_t PageMode; | ||
182 | uint8_t VppMin; | ||
183 | uint8_t VppMax; | ||
184 | uint8_t TopBottom; | ||
185 | } __attribute__((packed)); | ||
186 | |||
187 | struct cfi_pri_query { | ||
188 | uint8_t NumFields; | ||
189 | uint32_t ProtField[1]; /* Not host ordered */ | ||
190 | } __attribute__((packed)); | ||
191 | |||
192 | struct cfi_bri_query { | ||
193 | uint8_t PageModeReadCap; | ||
194 | uint8_t NumFields; | ||
195 | uint32_t ConfField[1]; /* Not host ordered */ | ||
196 | } __attribute__((packed)); | ||
197 | |||
198 | #define P_ID_NONE 0x0000 | ||
199 | #define P_ID_INTEL_EXT 0x0001 | ||
200 | #define P_ID_AMD_STD 0x0002 | ||
201 | #define P_ID_INTEL_STD 0x0003 | ||
202 | #define P_ID_AMD_EXT 0x0004 | ||
203 | #define P_ID_WINBOND 0x0006 | ||
204 | #define P_ID_ST_ADV 0x0020 | ||
205 | #define P_ID_MITSUBISHI_STD 0x0100 | ||
206 | #define P_ID_MITSUBISHI_EXT 0x0101 | ||
207 | #define P_ID_SST_PAGE 0x0102 | ||
208 | #define P_ID_INTEL_PERFORMANCE 0x0200 | ||
209 | #define P_ID_INTEL_DATA 0x0210 | ||
210 | #define P_ID_RESERVED 0xffff | ||
211 | |||
212 | |||
213 | #define CFI_MODE_CFI 1 | ||
214 | #define CFI_MODE_JEDEC 0 | ||
215 | |||
216 | struct cfi_private { | ||
217 | uint16_t cmdset; | ||
218 | void *cmdset_priv; | ||
219 | int interleave; | ||
220 | int device_type; | ||
221 | int cfi_mode; /* Are we a JEDEC device pretending to be CFI? */ | ||
222 | int addr_unlock1; | ||
223 | int addr_unlock2; | ||
224 | struct mtd_info *(*cmdset_setup)(struct map_info *); | ||
225 | struct cfi_ident *cfiq; /* For now only one. We insist that all devs | ||
226 | must be of the same type. */ | ||
227 | int mfr, id; | ||
228 | int numchips; | ||
229 | unsigned long chipshift; /* Because they're of the same type */ | ||
230 | const char *im_name; /* inter_module name for cmdset_setup */ | ||
231 | struct flchip chips[0]; /* per-chip data structure for each chip */ | ||
232 | }; | ||
233 | |||
234 | /* | ||
235 | * Returns the command address according to the given geometry. | ||
236 | */ | ||
237 | static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, int interleave, int type) | ||
238 | { | ||
239 | return (cmd_ofs * type) * interleave; | ||
240 | } | ||
241 | |||
242 | /* | ||
243 | * Transforms the CFI command for the given geometry (bus width & interleave). | ||
244 | * It looks too long to be inline, but in the common case it should almost all | ||
245 | * get optimised away. | ||
246 | */ | ||
247 | static inline map_word cfi_build_cmd(u_char cmd, struct map_info *map, struct cfi_private *cfi) | ||
248 | { | ||
249 | map_word val = { {0} }; | ||
250 | int wordwidth, words_per_bus, chip_mode, chips_per_word; | ||
251 | unsigned long onecmd; | ||
252 | int i; | ||
253 | |||
254 | /* We do it this way to give the compiler a fighting chance | ||
255 | of optimising away all the crap for 'bankwidth' larger than | ||
256 | an unsigned long, in the common case where that support is | ||
257 | disabled */ | ||
258 | if (map_bankwidth_is_large(map)) { | ||
259 | wordwidth = sizeof(unsigned long); | ||
260 | words_per_bus = (map_bankwidth(map)) / wordwidth; // i.e. normally 1 | ||
261 | } else { | ||
262 | wordwidth = map_bankwidth(map); | ||
263 | words_per_bus = 1; | ||
264 | } | ||
265 | |||
266 | chip_mode = map_bankwidth(map) / cfi_interleave(cfi); | ||
267 | chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map); | ||
268 | |||
269 | /* First, determine what the bit-pattern should be for a single | ||
270 | device, according to chip mode and endianness... */ | ||
271 | switch (chip_mode) { | ||
272 | default: BUG(); | ||
273 | case 1: | ||
274 | onecmd = cmd; | ||
275 | break; | ||
276 | case 2: | ||
277 | onecmd = cpu_to_cfi16(cmd); | ||
278 | break; | ||
279 | case 4: | ||
280 | onecmd = cpu_to_cfi32(cmd); | ||
281 | break; | ||
282 | } | ||
283 | |||
284 | /* Now replicate it across the size of an unsigned long, or | ||
285 | just to the bus width as appropriate */ | ||
286 | switch (chips_per_word) { | ||
287 | default: BUG(); | ||
288 | #if BITS_PER_LONG >= 64 | ||
289 | case 8: | ||
290 | onecmd |= (onecmd << (chip_mode * 32)); | ||
291 | #endif | ||
292 | case 4: | ||
293 | onecmd |= (onecmd << (chip_mode * 16)); | ||
294 | case 2: | ||
295 | onecmd |= (onecmd << (chip_mode * 8)); | ||
296 | case 1: | ||
297 | ; | ||
298 | } | ||
299 | |||
300 | /* And finally, for the multi-word case, replicate it | ||
301 | in all words in the structure */ | ||
302 | for (i=0; i < words_per_bus; i++) { | ||
303 | val.x[i] = onecmd; | ||
304 | } | ||
305 | |||
306 | return val; | ||
307 | } | ||
308 | #define CMD(x) cfi_build_cmd((x), map, cfi) | ||
309 | |||
310 | /* | ||
311 | * Sends a CFI command to a bank of flash for the given geometry. | ||
312 | * | ||
313 | * Returns the offset in flash where the command was written. | ||
314 | * If prev_val is non-null, it will be set to the value at the command address, | ||
315 | * before the command was written. | ||
316 | */ | ||
317 | static inline uint32_t cfi_send_gen_cmd(u_char cmd, uint32_t cmd_addr, uint32_t base, | ||
318 | struct map_info *map, struct cfi_private *cfi, | ||
319 | int type, map_word *prev_val) | ||
320 | { | ||
321 | map_word val; | ||
322 | uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, cfi_interleave(cfi), type); | ||
323 | |||
324 | val = cfi_build_cmd(cmd, map, cfi); | ||
325 | |||
326 | if (prev_val) | ||
327 | *prev_val = map_read(map, addr); | ||
328 | |||
329 | map_write(map, val, addr); | ||
330 | |||
331 | return addr - base; | ||
332 | } | ||
333 | |||
334 | static inline uint8_t cfi_read_query(struct map_info *map, uint32_t addr) | ||
335 | { | ||
336 | map_word val = map_read(map, addr); | ||
337 | |||
338 | if (map_bankwidth_is_1(map)) { | ||
339 | return val.x[0]; | ||
340 | } else if (map_bankwidth_is_2(map)) { | ||
341 | return cfi16_to_cpu(val.x[0]); | ||
342 | } else { | ||
343 | /* No point in a 64-bit byteswap since that would just be | ||
344 | swapping the responses from different chips, and we are | ||
345 | only interested in one chip (a representative sample) */ | ||
346 | return cfi32_to_cpu(val.x[0]); | ||
347 | } | ||
348 | } | ||
349 | |||
350 | static inline void cfi_udelay(int us) | ||
351 | { | ||
352 | if (us >= 1000) { | ||
353 | msleep((us+999)/1000); | ||
354 | } else { | ||
355 | udelay(us); | ||
356 | cond_resched(); | ||
357 | } | ||
358 | } | ||
359 | |||
360 | static inline void cfi_spin_lock(spinlock_t *mutex) | ||
361 | { | ||
362 | spin_lock_bh(mutex); | ||
363 | } | ||
364 | |||
365 | static inline void cfi_spin_unlock(spinlock_t *mutex) | ||
366 | { | ||
367 | spin_unlock_bh(mutex); | ||
368 | } | ||
369 | |||
370 | struct cfi_extquery *cfi_read_pri(struct map_info *map, uint16_t adr, uint16_t size, | ||
371 | const char* name); | ||
372 | struct cfi_fixup { | ||
373 | uint16_t mfr; | ||
374 | uint16_t id; | ||
375 | void (*fixup)(struct mtd_info *mtd, void* param); | ||
376 | void* param; | ||
377 | }; | ||
378 | |||
379 | #define CFI_MFR_ANY 0xffff | ||
380 | #define CFI_ID_ANY 0xffff | ||
381 | |||
382 | #define CFI_MFR_AMD 0x0001 | ||
383 | #define CFI_MFR_ST 0x0020 /* STMicroelectronics */ | ||
384 | |||
385 | void cfi_fixup(struct mtd_info *mtd, struct cfi_fixup* fixups); | ||
386 | |||
387 | typedef int (*varsize_frob_t)(struct map_info *map, struct flchip *chip, | ||
388 | unsigned long adr, int len, void *thunk); | ||
389 | |||
390 | int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob, | ||
391 | loff_t ofs, size_t len, void *thunk); | ||
392 | |||
393 | |||
394 | #endif /* __MTD_CFI_H__ */ | ||
diff --git a/include/linux/mtd/cfi_endian.h b/include/linux/mtd/cfi_endian.h new file mode 100644 index 000000000000..25724f7d3867 --- /dev/null +++ b/include/linux/mtd/cfi_endian.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * $Id: cfi_endian.h,v 1.11 2002/01/30 23:20:48 awozniak Exp $ | ||
3 | * | ||
4 | */ | ||
5 | |||
6 | #include <asm/byteorder.h> | ||
7 | |||
8 | #ifndef CONFIG_MTD_CFI_ADV_OPTIONS | ||
9 | |||
10 | #define CFI_HOST_ENDIAN | ||
11 | |||
12 | #else | ||
13 | |||
14 | #ifdef CONFIG_MTD_CFI_NOSWAP | ||
15 | #define CFI_HOST_ENDIAN | ||
16 | #endif | ||
17 | |||
18 | #ifdef CONFIG_MTD_CFI_LE_BYTE_SWAP | ||
19 | #define CFI_LITTLE_ENDIAN | ||
20 | #endif | ||
21 | |||
22 | #ifdef CONFIG_MTD_CFI_BE_BYTE_SWAP | ||
23 | #define CFI_BIG_ENDIAN | ||
24 | #endif | ||
25 | |||
26 | #endif | ||
27 | |||
28 | #if defined(CFI_LITTLE_ENDIAN) | ||
29 | #define cpu_to_cfi8(x) (x) | ||
30 | #define cfi8_to_cpu(x) (x) | ||
31 | #define cpu_to_cfi16(x) cpu_to_le16(x) | ||
32 | #define cpu_to_cfi32(x) cpu_to_le32(x) | ||
33 | #define cpu_to_cfi64(x) cpu_to_le64(x) | ||
34 | #define cfi16_to_cpu(x) le16_to_cpu(x) | ||
35 | #define cfi32_to_cpu(x) le32_to_cpu(x) | ||
36 | #define cfi64_to_cpu(x) le64_to_cpu(x) | ||
37 | #elif defined (CFI_BIG_ENDIAN) | ||
38 | #define cpu_to_cfi8(x) (x) | ||
39 | #define cfi8_to_cpu(x) (x) | ||
40 | #define cpu_to_cfi16(x) cpu_to_be16(x) | ||
41 | #define cpu_to_cfi32(x) cpu_to_be32(x) | ||
42 | #define cpu_to_cfi64(x) cpu_to_be64(x) | ||
43 | #define cfi16_to_cpu(x) be16_to_cpu(x) | ||
44 | #define cfi32_to_cpu(x) be32_to_cpu(x) | ||
45 | #define cfi64_to_cpu(x) be64_to_cpu(x) | ||
46 | #elif defined (CFI_HOST_ENDIAN) | ||
47 | #define cpu_to_cfi8(x) (x) | ||
48 | #define cfi8_to_cpu(x) (x) | ||
49 | #define cpu_to_cfi16(x) (x) | ||
50 | #define cpu_to_cfi32(x) (x) | ||
51 | #define cpu_to_cfi64(x) (x) | ||
52 | #define cfi16_to_cpu(x) (x) | ||
53 | #define cfi32_to_cpu(x) (x) | ||
54 | #define cfi64_to_cpu(x) (x) | ||
55 | #else | ||
56 | #error No CFI endianness defined | ||
57 | #endif | ||
diff --git a/include/linux/mtd/compatmac.h b/include/linux/mtd/compatmac.h new file mode 100644 index 000000000000..7d1300d9bd51 --- /dev/null +++ b/include/linux/mtd/compatmac.h | |||
@@ -0,0 +1,10 @@ | |||
1 | |||
2 | #ifndef __LINUX_MTD_COMPATMAC_H__ | ||
3 | #define __LINUX_MTD_COMPATMAC_H__ | ||
4 | |||
5 | /* Nothing to see here. We write 2.5-compatible code and this | ||
6 | file makes it all OK in older kernels, but it's empty in _current_ | ||
7 | kernels. Include guard just to make GCC ignore it in future inclusions | ||
8 | anyway... */ | ||
9 | |||
10 | #endif /* __LINUX_MTD_COMPATMAC_H__ */ | ||
diff --git a/include/linux/mtd/concat.h b/include/linux/mtd/concat.h new file mode 100644 index 000000000000..ed8dc6755219 --- /dev/null +++ b/include/linux/mtd/concat.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * MTD device concatenation layer definitions | ||
3 | * | ||
4 | * (C) 2002 Robert Kaiser <rkaiser@sysgo.de> | ||
5 | * | ||
6 | * This code is GPL | ||
7 | * | ||
8 | * $Id: concat.h,v 1.1 2002/03/08 16:34:36 rkaiser Exp $ | ||
9 | */ | ||
10 | |||
11 | #ifndef MTD_CONCAT_H | ||
12 | #define MTD_CONCAT_H | ||
13 | |||
14 | |||
15 | struct mtd_info *mtd_concat_create( | ||
16 | struct mtd_info *subdev[], /* subdevices to concatenate */ | ||
17 | int num_devs, /* number of subdevices */ | ||
18 | char *name); /* name for the new device */ | ||
19 | |||
20 | void mtd_concat_destroy(struct mtd_info *mtd); | ||
21 | |||
22 | #endif | ||
23 | |||
diff --git a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h new file mode 100644 index 000000000000..953e64fb8ac5 --- /dev/null +++ b/include/linux/mtd/doc2000.h | |||
@@ -0,0 +1,195 @@ | |||
1 | /* | ||
2 | * Linux driver for Disk-On-Chip devices | ||
3 | * | ||
4 | * Copyright (C) 1999 Machine Vision Holdings, Inc. | ||
5 | * Copyright (C) 2001-2003 David Woodhouse <dwmw2@infradead.org> | ||
6 | * Copyright (C) 2002-2003 Greg Ungerer <gerg@snapgear.com> | ||
7 | * Copyright (C) 2002-2003 SnapGear Inc | ||
8 | * | ||
9 | * $Id: doc2000.h,v 1.24 2005/01/05 12:40:38 dwmw2 Exp $ | ||
10 | * | ||
11 | * Released under GPL | ||
12 | */ | ||
13 | |||
14 | #ifndef __MTD_DOC2000_H__ | ||
15 | #define __MTD_DOC2000_H__ | ||
16 | |||
17 | #include <linux/mtd/mtd.h> | ||
18 | #include <asm/semaphore.h> | ||
19 | |||
20 | #define DoC_Sig1 0 | ||
21 | #define DoC_Sig2 1 | ||
22 | |||
23 | #define DoC_ChipID 0x1000 | ||
24 | #define DoC_DOCStatus 0x1001 | ||
25 | #define DoC_DOCControl 0x1002 | ||
26 | #define DoC_FloorSelect 0x1003 | ||
27 | #define DoC_CDSNControl 0x1004 | ||
28 | #define DoC_CDSNDeviceSelect 0x1005 | ||
29 | #define DoC_ECCConf 0x1006 | ||
30 | #define DoC_2k_ECCStatus 0x1007 | ||
31 | |||
32 | #define DoC_CDSNSlowIO 0x100d | ||
33 | #define DoC_ECCSyndrome0 0x1010 | ||
34 | #define DoC_ECCSyndrome1 0x1011 | ||
35 | #define DoC_ECCSyndrome2 0x1012 | ||
36 | #define DoC_ECCSyndrome3 0x1013 | ||
37 | #define DoC_ECCSyndrome4 0x1014 | ||
38 | #define DoC_ECCSyndrome5 0x1015 | ||
39 | #define DoC_AliasResolution 0x101b | ||
40 | #define DoC_ConfigInput 0x101c | ||
41 | #define DoC_ReadPipeInit 0x101d | ||
42 | #define DoC_WritePipeTerm 0x101e | ||
43 | #define DoC_LastDataRead 0x101f | ||
44 | #define DoC_NOP 0x1020 | ||
45 | |||
46 | #define DoC_Mil_CDSN_IO 0x0800 | ||
47 | #define DoC_2k_CDSN_IO 0x1800 | ||
48 | |||
49 | #define DoC_Mplus_NOP 0x1002 | ||
50 | #define DoC_Mplus_AliasResolution 0x1004 | ||
51 | #define DoC_Mplus_DOCControl 0x1006 | ||
52 | #define DoC_Mplus_AccessStatus 0x1008 | ||
53 | #define DoC_Mplus_DeviceSelect 0x1008 | ||
54 | #define DoC_Mplus_Configuration 0x100a | ||
55 | #define DoC_Mplus_OutputControl 0x100c | ||
56 | #define DoC_Mplus_FlashControl 0x1020 | ||
57 | #define DoC_Mplus_FlashSelect 0x1022 | ||
58 | #define DoC_Mplus_FlashCmd 0x1024 | ||
59 | #define DoC_Mplus_FlashAddress 0x1026 | ||
60 | #define DoC_Mplus_FlashData0 0x1028 | ||
61 | #define DoC_Mplus_FlashData1 0x1029 | ||
62 | #define DoC_Mplus_ReadPipeInit 0x102a | ||
63 | #define DoC_Mplus_LastDataRead 0x102c | ||
64 | #define DoC_Mplus_LastDataRead1 0x102d | ||
65 | #define DoC_Mplus_WritePipeTerm 0x102e | ||
66 | #define DoC_Mplus_ECCSyndrome0 0x1040 | ||
67 | #define DoC_Mplus_ECCSyndrome1 0x1041 | ||
68 | #define DoC_Mplus_ECCSyndrome2 0x1042 | ||
69 | #define DoC_Mplus_ECCSyndrome3 0x1043 | ||
70 | #define DoC_Mplus_ECCSyndrome4 0x1044 | ||
71 | #define DoC_Mplus_ECCSyndrome5 0x1045 | ||
72 | #define DoC_Mplus_ECCConf 0x1046 | ||
73 | #define DoC_Mplus_Toggle 0x1046 | ||
74 | #define DoC_Mplus_DownloadStatus 0x1074 | ||
75 | #define DoC_Mplus_CtrlConfirm 0x1076 | ||
76 | #define DoC_Mplus_Power 0x1fff | ||
77 | |||
78 | /* How to access the device? | ||
79 | * On ARM, it'll be mmap'd directly with 32-bit wide accesses. | ||
80 | * On PPC, it's mmap'd and 16-bit wide. | ||
81 | * Others use readb/writeb | ||
82 | */ | ||
83 | #if defined(__arm__) | ||
84 | #define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)))) | ||
85 | #define WriteDOC_(d, adr, reg) do{ *(volatile __u32 *)(((unsigned long)adr)+((reg)<<2)) = (__u32)d; wmb();} while(0) | ||
86 | #define DOC_IOREMAP_LEN 0x8000 | ||
87 | #elif defined(__ppc__) | ||
88 | #define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u16 *)(((unsigned long)adr)+((reg)<<1)))) | ||
89 | #define WriteDOC_(d, adr, reg) do{ *(volatile __u16 *)(((unsigned long)adr)+((reg)<<1)) = (__u16)d; wmb();} while(0) | ||
90 | #define DOC_IOREMAP_LEN 0x4000 | ||
91 | #else | ||
92 | #define ReadDOC_(adr, reg) readb((void __iomem *)(adr) + (reg)) | ||
93 | #define WriteDOC_(d, adr, reg) writeb(d, (void __iomem *)(adr) + (reg)) | ||
94 | #define DOC_IOREMAP_LEN 0x2000 | ||
95 | |||
96 | #endif | ||
97 | |||
98 | #if defined(__i386__) || defined(__x86_64__) | ||
99 | #define USE_MEMCPY | ||
100 | #endif | ||
101 | |||
102 | /* These are provided to directly use the DoC_xxx defines */ | ||
103 | #define ReadDOC(adr, reg) ReadDOC_(adr,DoC_##reg) | ||
104 | #define WriteDOC(d, adr, reg) WriteDOC_(d,adr,DoC_##reg) | ||
105 | |||
106 | #define DOC_MODE_RESET 0 | ||
107 | #define DOC_MODE_NORMAL 1 | ||
108 | #define DOC_MODE_RESERVED1 2 | ||
109 | #define DOC_MODE_RESERVED2 3 | ||
110 | |||
111 | #define DOC_MODE_CLR_ERR 0x80 | ||
112 | #define DOC_MODE_RST_LAT 0x10 | ||
113 | #define DOC_MODE_BDECT 0x08 | ||
114 | #define DOC_MODE_MDWREN 0x04 | ||
115 | |||
116 | #define DOC_ChipID_Doc2k 0x20 | ||
117 | #define DOC_ChipID_Doc2kTSOP 0x21 /* internal number for MTD */ | ||
118 | #define DOC_ChipID_DocMil 0x30 | ||
119 | #define DOC_ChipID_DocMilPlus32 0x40 | ||
120 | #define DOC_ChipID_DocMilPlus16 0x41 | ||
121 | |||
122 | #define CDSN_CTRL_FR_B 0x80 | ||
123 | #define CDSN_CTRL_FR_B0 0x40 | ||
124 | #define CDSN_CTRL_FR_B1 0x80 | ||
125 | |||
126 | #define CDSN_CTRL_ECC_IO 0x20 | ||
127 | #define CDSN_CTRL_FLASH_IO 0x10 | ||
128 | #define CDSN_CTRL_WP 0x08 | ||
129 | #define CDSN_CTRL_ALE 0x04 | ||
130 | #define CDSN_CTRL_CLE 0x02 | ||
131 | #define CDSN_CTRL_CE 0x01 | ||
132 | |||
133 | #define DOC_ECC_RESET 0 | ||
134 | #define DOC_ECC_ERROR 0x80 | ||
135 | #define DOC_ECC_RW 0x20 | ||
136 | #define DOC_ECC__EN 0x08 | ||
137 | #define DOC_TOGGLE_BIT 0x04 | ||
138 | #define DOC_ECC_RESV 0x02 | ||
139 | #define DOC_ECC_IGNORE 0x01 | ||
140 | |||
141 | #define DOC_FLASH_CE 0x80 | ||
142 | #define DOC_FLASH_WP 0x40 | ||
143 | #define DOC_FLASH_BANK 0x02 | ||
144 | |||
145 | /* We have to also set the reserved bit 1 for enable */ | ||
146 | #define DOC_ECC_EN (DOC_ECC__EN | DOC_ECC_RESV) | ||
147 | #define DOC_ECC_DIS (DOC_ECC_RESV) | ||
148 | |||
149 | struct Nand { | ||
150 | char floor, chip; | ||
151 | unsigned long curadr; | ||
152 | unsigned char curmode; | ||
153 | /* Also some erase/write/pipeline info when we get that far */ | ||
154 | }; | ||
155 | |||
156 | #define MAX_FLOORS 4 | ||
157 | #define MAX_CHIPS 4 | ||
158 | |||
159 | #define MAX_FLOORS_MIL 1 | ||
160 | #define MAX_CHIPS_MIL 1 | ||
161 | |||
162 | #define MAX_FLOORS_MPLUS 2 | ||
163 | #define MAX_CHIPS_MPLUS 1 | ||
164 | |||
165 | #define ADDR_COLUMN 1 | ||
166 | #define ADDR_PAGE 2 | ||
167 | #define ADDR_COLUMN_PAGE 3 | ||
168 | |||
169 | struct DiskOnChip { | ||
170 | unsigned long physadr; | ||
171 | void __iomem *virtadr; | ||
172 | unsigned long totlen; | ||
173 | unsigned char ChipID; /* Type of DiskOnChip */ | ||
174 | int ioreg; | ||
175 | |||
176 | unsigned long mfr; /* Flash IDs - only one type of flash per device */ | ||
177 | unsigned long id; | ||
178 | int chipshift; | ||
179 | char page256; | ||
180 | char pageadrlen; | ||
181 | char interleave; /* Internal interleaving - Millennium Plus style */ | ||
182 | unsigned long erasesize; | ||
183 | |||
184 | int curfloor; | ||
185 | int curchip; | ||
186 | |||
187 | int numchips; | ||
188 | struct Nand *chips; | ||
189 | struct mtd_info *nextdoc; | ||
190 | struct semaphore lock; | ||
191 | }; | ||
192 | |||
193 | int doc_decode_ecc(unsigned char sector[512], unsigned char ecc1[6]); | ||
194 | |||
195 | #endif /* __MTD_DOC2000_H__ */ | ||
diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h new file mode 100644 index 000000000000..c66ba812bf90 --- /dev/null +++ b/include/linux/mtd/flashchip.h | |||
@@ -0,0 +1,89 @@ | |||
1 | |||
2 | /* | ||
3 | * struct flchip definition | ||
4 | * | ||
5 | * Contains information about the location and state of a given flash device | ||
6 | * | ||
7 | * (C) 2000 Red Hat. GPLd. | ||
8 | * | ||
9 | * $Id: flashchip.h,v 1.15 2004/11/05 22:41:06 nico Exp $ | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #ifndef __MTD_FLASHCHIP_H__ | ||
14 | #define __MTD_FLASHCHIP_H__ | ||
15 | |||
16 | /* For spinlocks. sched.h includes spinlock.h from whichever directory it | ||
17 | * happens to be in - so we don't have to care whether we're on 2.2, which | ||
18 | * has asm/spinlock.h, or 2.4, which has linux/spinlock.h | ||
19 | */ | ||
20 | #include <linux/sched.h> | ||
21 | |||
22 | typedef enum { | ||
23 | FL_READY, | ||
24 | FL_STATUS, | ||
25 | FL_CFI_QUERY, | ||
26 | FL_JEDEC_QUERY, | ||
27 | FL_ERASING, | ||
28 | FL_ERASE_SUSPENDING, | ||
29 | FL_ERASE_SUSPENDED, | ||
30 | FL_WRITING, | ||
31 | FL_WRITING_TO_BUFFER, | ||
32 | FL_WRITE_SUSPENDING, | ||
33 | FL_WRITE_SUSPENDED, | ||
34 | FL_PM_SUSPENDED, | ||
35 | FL_SYNCING, | ||
36 | FL_UNLOADING, | ||
37 | FL_LOCKING, | ||
38 | FL_UNLOCKING, | ||
39 | FL_POINT, | ||
40 | FL_XIP_WHILE_ERASING, | ||
41 | FL_XIP_WHILE_WRITING, | ||
42 | FL_UNKNOWN | ||
43 | } flstate_t; | ||
44 | |||
45 | |||
46 | |||
47 | /* NOTE: confusingly, this can be used to refer to more than one chip at a time, | ||
48 | if they're interleaved. This can even refer to individual partitions on | ||
49 | the same physical chip when present. */ | ||
50 | |||
51 | struct flchip { | ||
52 | unsigned long start; /* Offset within the map */ | ||
53 | // unsigned long len; | ||
54 | /* We omit len for now, because when we group them together | ||
55 | we insist that they're all of the same size, and the chip size | ||
56 | is held in the next level up. If we get more versatile later, | ||
57 | it'll make it a damn sight harder to find which chip we want from | ||
58 | a given offset, and we'll want to add the per-chip length field | ||
59 | back in. | ||
60 | */ | ||
61 | int ref_point_counter; | ||
62 | flstate_t state; | ||
63 | flstate_t oldstate; | ||
64 | |||
65 | int write_suspended:1; | ||
66 | int erase_suspended:1; | ||
67 | unsigned long in_progress_block_addr; | ||
68 | |||
69 | spinlock_t *mutex; | ||
70 | spinlock_t _spinlock; /* We do it like this because sometimes they'll be shared. */ | ||
71 | wait_queue_head_t wq; /* Wait on here when we're waiting for the chip | ||
72 | to be ready */ | ||
73 | int word_write_time; | ||
74 | int buffer_write_time; | ||
75 | int erase_time; | ||
76 | |||
77 | void *priv; | ||
78 | }; | ||
79 | |||
80 | /* This is used to handle contention on write/erase operations | ||
81 | between partitions of the same physical chip. */ | ||
82 | struct flchip_shared { | ||
83 | spinlock_t lock; | ||
84 | struct flchip *writing; | ||
85 | struct flchip *erasing; | ||
86 | }; | ||
87 | |||
88 | |||
89 | #endif /* __MTD_FLASHCHIP_H__ */ | ||
diff --git a/include/linux/mtd/ftl.h b/include/linux/mtd/ftl.h new file mode 100644 index 000000000000..3678459b4535 --- /dev/null +++ b/include/linux/mtd/ftl.h | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * $Id: ftl.h,v 1.6 2003/01/24 13:20:04 dwmw2 Exp $ | ||
3 | * | ||
4 | * Derived from (and probably identical to): | ||
5 | * ftl.h 1.7 1999/10/25 20:23:17 | ||
6 | * | ||
7 | * The contents of this file are subject to the Mozilla Public License | ||
8 | * Version 1.1 (the "License"); you may not use this file except in | ||
9 | * compliance with the License. You may obtain a copy of the License | ||
10 | * at http://www.mozilla.org/MPL/ | ||
11 | * | ||
12 | * Software distributed under the License is distributed on an "AS IS" | ||
13 | * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See | ||
14 | * the License for the specific language governing rights and | ||
15 | * limitations under the License. | ||
16 | * | ||
17 | * The initial developer of the original code is David A. Hinds | ||
18 | * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds | ||
19 | * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. | ||
20 | * | ||
21 | * Alternatively, the contents of this file may be used under the | ||
22 | * terms of the GNU General Public License version 2 (the "GPL"), in | ||
23 | * which case the provisions of the GPL are applicable instead of the | ||
24 | * above. If you wish to allow the use of your version of this file | ||
25 | * only under the terms of the GPL and not to allow others to use | ||
26 | * your version of this file under the MPL, indicate your decision by | ||
27 | * deleting the provisions above and replace them with the notice and | ||
28 | * other provisions required by the GPL. If you do not delete the | ||
29 | * provisions above, a recipient may use your version of this file | ||
30 | * under either the MPL or the GPL. | ||
31 | */ | ||
32 | |||
33 | #ifndef _LINUX_FTL_H | ||
34 | #define _LINUX_FTL_H | ||
35 | |||
36 | typedef struct erase_unit_header_t { | ||
37 | u_int8_t LinkTargetTuple[5]; | ||
38 | u_int8_t DataOrgTuple[10]; | ||
39 | u_int8_t NumTransferUnits; | ||
40 | u_int32_t EraseCount; | ||
41 | u_int16_t LogicalEUN; | ||
42 | u_int8_t BlockSize; | ||
43 | u_int8_t EraseUnitSize; | ||
44 | u_int16_t FirstPhysicalEUN; | ||
45 | u_int16_t NumEraseUnits; | ||
46 | u_int32_t FormattedSize; | ||
47 | u_int32_t FirstVMAddress; | ||
48 | u_int16_t NumVMPages; | ||
49 | u_int8_t Flags; | ||
50 | u_int8_t Code; | ||
51 | u_int32_t SerialNumber; | ||
52 | u_int32_t AltEUHOffset; | ||
53 | u_int32_t BAMOffset; | ||
54 | u_int8_t Reserved[12]; | ||
55 | u_int8_t EndTuple[2]; | ||
56 | } erase_unit_header_t; | ||
57 | |||
58 | /* Flags in erase_unit_header_t */ | ||
59 | #define HIDDEN_AREA 0x01 | ||
60 | #define REVERSE_POLARITY 0x02 | ||
61 | #define DOUBLE_BAI 0x04 | ||
62 | |||
63 | /* Definitions for block allocation information */ | ||
64 | |||
65 | #define BLOCK_FREE(b) ((b) == 0xffffffff) | ||
66 | #define BLOCK_DELETED(b) (((b) == 0) || ((b) == 0xfffffffe)) | ||
67 | |||
68 | #define BLOCK_TYPE(b) ((b) & 0x7f) | ||
69 | #define BLOCK_ADDRESS(b) ((b) & ~0x7f) | ||
70 | #define BLOCK_NUMBER(b) ((b) >> 9) | ||
71 | #define BLOCK_CONTROL 0x30 | ||
72 | #define BLOCK_DATA 0x40 | ||
73 | #define BLOCK_REPLACEMENT 0x60 | ||
74 | #define BLOCK_BAD 0x70 | ||
75 | |||
76 | #endif /* _LINUX_FTL_H */ | ||
diff --git a/include/linux/mtd/gen_probe.h b/include/linux/mtd/gen_probe.h new file mode 100644 index 000000000000..3d7bdec14f97 --- /dev/null +++ b/include/linux/mtd/gen_probe.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * (C) 2001, 2001 Red Hat, Inc. | ||
3 | * GPL'd | ||
4 | * $Id: gen_probe.h,v 1.3 2004/10/20 22:10:33 dwmw2 Exp $ | ||
5 | */ | ||
6 | |||
7 | #ifndef __LINUX_MTD_GEN_PROBE_H__ | ||
8 | #define __LINUX_MTD_GEN_PROBE_H__ | ||
9 | |||
10 | #include <linux/mtd/flashchip.h> | ||
11 | #include <linux/mtd/map.h> | ||
12 | #include <linux/mtd/cfi.h> | ||
13 | #include <linux/bitops.h> | ||
14 | |||
15 | struct chip_probe { | ||
16 | char *name; | ||
17 | int (*probe_chip)(struct map_info *map, __u32 base, | ||
18 | unsigned long *chip_map, struct cfi_private *cfi); | ||
19 | }; | ||
20 | |||
21 | struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp); | ||
22 | |||
23 | #endif /* __LINUX_MTD_GEN_PROBE_H__ */ | ||
diff --git a/include/linux/mtd/iflash.h b/include/linux/mtd/iflash.h new file mode 100644 index 000000000000..9aa5b4f02666 --- /dev/null +++ b/include/linux/mtd/iflash.h | |||
@@ -0,0 +1,98 @@ | |||
1 | /* $Id: iflash.h,v 1.2 2000/11/13 18:01:54 dwmw2 Exp $ */ | ||
2 | |||
3 | #ifndef __MTD_IFLASH_H__ | ||
4 | #define __MTD_IFLASH_H__ | ||
5 | |||
6 | /* Extended CIS registers for Series 2 and 2+ cards */ | ||
7 | /* The registers are all offsets from 0x4000 */ | ||
8 | #define CISREG_CSR 0x0100 | ||
9 | #define CISREG_WP 0x0104 | ||
10 | #define CISREG_RDYBSY 0x0140 | ||
11 | |||
12 | /* Extended CIS registers for Series 2 cards */ | ||
13 | #define CISREG_SLEEP 0x0118 | ||
14 | #define CISREG_RDY_MASK 0x0120 | ||
15 | #define CISREG_RDY_STATUS 0x0130 | ||
16 | |||
17 | /* Extended CIS registers for Series 2+ cards */ | ||
18 | #define CISREG_VCR 0x010c | ||
19 | |||
20 | /* Card Status Register */ | ||
21 | #define CSR_SRESET 0x20 /* Soft reset */ | ||
22 | #define CSR_CMWP 0x10 /* Common memory write protect */ | ||
23 | #define CSR_PWRDOWN 0x08 /* Power down status */ | ||
24 | #define CSR_CISWP 0x04 /* Common memory CIS WP */ | ||
25 | #define CSR_WP 0x02 /* Mechanical write protect */ | ||
26 | #define CSR_READY 0x01 /* Ready/busy status */ | ||
27 | |||
28 | /* Write Protection Register */ | ||
29 | #define WP_BLKEN 0x04 /* Enable block locking */ | ||
30 | #define WP_CMWP 0x02 /* Common memory write protect */ | ||
31 | #define WP_CISWP 0x01 /* Common memory CIS WP */ | ||
32 | |||
33 | /* Voltage Control Register */ | ||
34 | #define VCR_VCC_LEVEL 0x80 /* 0 = 5V, 1 = 3.3V */ | ||
35 | #define VCR_VPP_VALID 0x02 /* Vpp Valid */ | ||
36 | #define VCR_VPP_GEN 0x01 /* Integrated Vpp generator */ | ||
37 | |||
38 | /* Ready/Busy Mode Register */ | ||
39 | #define RDYBSY_RACK 0x02 /* Ready acknowledge */ | ||
40 | #define RDYBSY_MODE 0x01 /* 1 = high performance */ | ||
41 | |||
42 | #define LOW(x) ((x) & 0xff) | ||
43 | |||
44 | /* 28F008SA-Compatible Command Set */ | ||
45 | #define IF_READ_ARRAY 0xffff | ||
46 | #define IF_INTEL_ID 0x9090 | ||
47 | #define IF_READ_CSR 0x7070 | ||
48 | #define IF_CLEAR_CSR 0x5050 | ||
49 | #define IF_WRITE 0x4040 | ||
50 | #define IF_BLOCK_ERASE 0x2020 | ||
51 | #define IF_ERASE_SUSPEND 0xb0b0 | ||
52 | #define IF_CONFIRM 0xd0d0 | ||
53 | |||
54 | /* 28F016SA Performance Enhancement Commands */ | ||
55 | #define IF_READ_PAGE 0x7575 | ||
56 | #define IF_PAGE_SWAP 0x7272 | ||
57 | #define IF_SINGLE_LOAD 0x7474 | ||
58 | #define IF_SEQ_LOAD 0xe0e0 | ||
59 | #define IF_PAGE_WRITE 0x0c0c | ||
60 | #define IF_RDY_MODE 0x9696 | ||
61 | #define IF_RDY_LEVEL 0x0101 | ||
62 | #define IF_RDY_PULSE_WRITE 0x0202 | ||
63 | #define IF_RDY_PULSE_ERASE 0x0303 | ||
64 | #define IF_RDY_DISABLE 0x0404 | ||
65 | #define IF_LOCK_BLOCK 0x7777 | ||
66 | #define IF_UPLOAD_STATUS 0x9797 | ||
67 | #define IF_READ_ESR 0x7171 | ||
68 | #define IF_ERASE_UNLOCKED 0xa7a7 | ||
69 | #define IF_SLEEP 0xf0f0 | ||
70 | #define IF_ABORT 0x8080 | ||
71 | #define IF_UPLOAD_DEVINFO 0x9999 | ||
72 | |||
73 | /* Definitions for Compatible Status Register */ | ||
74 | #define CSR_WR_READY 0x8080 /* Write state machine status */ | ||
75 | #define CSR_ERA_SUSPEND 0x4040 /* Erase suspend status */ | ||
76 | #define CSR_ERA_ERR 0x2020 /* Erase status */ | ||
77 | #define CSR_WR_ERR 0x1010 /* Data write status */ | ||
78 | #define CSR_VPP_LOW 0x0808 /* Vpp status */ | ||
79 | |||
80 | /* Definitions for Global Status Register */ | ||
81 | #define GSR_WR_READY 0x8080 /* Write state machine status */ | ||
82 | #define GSR_OP_SUSPEND 0x4040 /* Operation suspend status */ | ||
83 | #define GSR_OP_ERR 0x2020 /* Device operation status */ | ||
84 | #define GSR_SLEEP 0x1010 /* Device sleep status */ | ||
85 | #define GSR_QUEUE_FULL 0x0808 /* Queue status */ | ||
86 | #define GSR_PAGE_AVAIL 0x0404 /* Page buffer available status */ | ||
87 | #define GSR_PAGE_READY 0x0202 /* Page buffer status */ | ||
88 | #define GSR_PAGE_SELECT 0x0101 /* Page buffer select status */ | ||
89 | |||
90 | /* Definitions for Block Status Register */ | ||
91 | #define BSR_READY 0x8080 /* Block status */ | ||
92 | #define BSR_UNLOCK 0x4040 /* Block lock status */ | ||
93 | #define BSR_FAILED 0x2020 /* Block operation status */ | ||
94 | #define BSR_ABORTED 0x1010 /* Operation abort status */ | ||
95 | #define BSR_QUEUE_FULL 0x0808 /* Queue status */ | ||
96 | #define BSR_VPP_LOW 0x0404 /* Vpp status */ | ||
97 | |||
98 | #endif /* __MTD_IFLASH_H__ */ | ||
diff --git a/include/linux/mtd/inftl.h b/include/linux/mtd/inftl.h new file mode 100644 index 000000000000..b52c8cbd235c --- /dev/null +++ b/include/linux/mtd/inftl.h | |||
@@ -0,0 +1,57 @@ | |||
1 | /* | ||
2 | * inftl.h -- defines to support the Inverse NAND Flash Translation Layer | ||
3 | * | ||
4 | * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com) | ||
5 | * | ||
6 | * $Id: inftl.h,v 1.6 2004/06/30 14:49:00 dbrown Exp $ | ||
7 | */ | ||
8 | |||
9 | #ifndef __MTD_INFTL_H__ | ||
10 | #define __MTD_INFTL_H__ | ||
11 | |||
12 | #ifndef __KERNEL__ | ||
13 | #error This is a kernel header. Perhaps include nftl-user.h instead? | ||
14 | #endif | ||
15 | |||
16 | #include <linux/mtd/blktrans.h> | ||
17 | #include <linux/mtd/mtd.h> | ||
18 | #include <linux/mtd/nftl.h> | ||
19 | |||
20 | #include <mtd/inftl-user.h> | ||
21 | |||
22 | #ifndef INFTL_MAJOR | ||
23 | #define INFTL_MAJOR 94 | ||
24 | #endif | ||
25 | #define INFTL_PARTN_BITS 4 | ||
26 | |||
27 | #ifdef __KERNEL__ | ||
28 | |||
29 | struct INFTLrecord { | ||
30 | struct mtd_blktrans_dev mbd; | ||
31 | __u16 MediaUnit; | ||
32 | __u32 EraseSize; | ||
33 | struct INFTLMediaHeader MediaHdr; | ||
34 | int usecount; | ||
35 | unsigned char heads; | ||
36 | unsigned char sectors; | ||
37 | unsigned short cylinders; | ||
38 | __u16 numvunits; | ||
39 | __u16 firstEUN; | ||
40 | __u16 lastEUN; | ||
41 | __u16 numfreeEUNs; | ||
42 | __u16 LastFreeEUN; /* To speed up finding a free EUN */ | ||
43 | int head,sect,cyl; | ||
44 | __u16 *PUtable; /* Physical Unit Table */ | ||
45 | __u16 *VUtable; /* Virtual Unit Table */ | ||
46 | unsigned int nb_blocks; /* number of physical blocks */ | ||
47 | unsigned int nb_boot_blocks; /* number of blocks used by the bios */ | ||
48 | struct erase_info instr; | ||
49 | struct nand_oobinfo oobinfo; | ||
50 | }; | ||
51 | |||
52 | int INFTL_mount(struct INFTLrecord *s); | ||
53 | int INFTL_formatblock(struct INFTLrecord *s, int block); | ||
54 | |||
55 | #endif /* __KERNEL__ */ | ||
56 | |||
57 | #endif /* __MTD_INFTL_H__ */ | ||
diff --git a/include/linux/mtd/jedec.h b/include/linux/mtd/jedec.h new file mode 100644 index 000000000000..2ba0f700ddbc --- /dev/null +++ b/include/linux/mtd/jedec.h | |||
@@ -0,0 +1,66 @@ | |||
1 | |||
2 | /* JEDEC Flash Interface. | ||
3 | * This is an older type of interface for self programming flash. It is | ||
4 | * commonly use in older AMD chips and is obsolete compared with CFI. | ||
5 | * It is called JEDEC because the JEDEC association distributes the ID codes | ||
6 | * for the chips. | ||
7 | * | ||
8 | * See the AMD flash databook for information on how to operate the interface. | ||
9 | * | ||
10 | * $Id: jedec.h,v 1.3 2003/05/21 11:51:01 dwmw2 Exp $ | ||
11 | */ | ||
12 | |||
13 | #ifndef __LINUX_MTD_JEDEC_H__ | ||
14 | #define __LINUX_MTD_JEDEC_H__ | ||
15 | |||
16 | #include <linux/types.h> | ||
17 | |||
18 | #define MAX_JEDEC_CHIPS 16 | ||
19 | |||
20 | // Listing of all supported chips and their information | ||
21 | struct JEDECTable | ||
22 | { | ||
23 | __u16 jedec; | ||
24 | char *name; | ||
25 | unsigned long size; | ||
26 | unsigned long sectorsize; | ||
27 | __u32 capabilities; | ||
28 | }; | ||
29 | |||
30 | // JEDEC being 0 is the end of the chip array | ||
31 | struct jedec_flash_chip | ||
32 | { | ||
33 | __u16 jedec; | ||
34 | unsigned long size; | ||
35 | unsigned long sectorsize; | ||
36 | |||
37 | // *(__u8*)(base + (adder << addrshift)) = data << datashift | ||
38 | // Address size = size << addrshift | ||
39 | unsigned long base; // Byte 0 of the flash, will be unaligned | ||
40 | unsigned int datashift; // Useful for 32bit/16bit accesses | ||
41 | unsigned int addrshift; | ||
42 | unsigned long offset; // linerized start. base==offset for unbanked, uninterleaved flash | ||
43 | |||
44 | __u32 capabilities; | ||
45 | |||
46 | // These markers are filled in by the flash_chip_scan function | ||
47 | unsigned long start; | ||
48 | unsigned long length; | ||
49 | }; | ||
50 | |||
51 | struct jedec_private | ||
52 | { | ||
53 | unsigned long size; // Total size of all the devices | ||
54 | |||
55 | /* Bank handling. If sum(bank_fill) == size then this is linear flash. | ||
56 | Otherwise the mapping has holes in it. bank_fill may be used to | ||
57 | find the holes, but in the common symetric case | ||
58 | bank_fill[0] == bank_fill[*], thus addresses may be computed | ||
59 | mathmatically. bank_fill must be powers of two */ | ||
60 | unsigned is_banked; | ||
61 | unsigned long bank_fill[MAX_JEDEC_CHIPS]; | ||
62 | |||
63 | struct jedec_flash_chip chips[MAX_JEDEC_CHIPS]; | ||
64 | }; | ||
65 | |||
66 | #endif | ||
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h new file mode 100644 index 000000000000..f0268b99c900 --- /dev/null +++ b/include/linux/mtd/map.h | |||
@@ -0,0 +1,412 @@ | |||
1 | |||
2 | /* Overhauled routines for dealing with different mmap regions of flash */ | ||
3 | /* $Id: map.h,v 1.46 2005/01/05 17:09:44 dwmw2 Exp $ */ | ||
4 | |||
5 | #ifndef __LINUX_MTD_MAP_H__ | ||
6 | #define __LINUX_MTD_MAP_H__ | ||
7 | |||
8 | #include <linux/config.h> | ||
9 | #include <linux/types.h> | ||
10 | #include <linux/list.h> | ||
11 | #include <linux/mtd/compatmac.h> | ||
12 | #include <asm/unaligned.h> | ||
13 | #include <asm/system.h> | ||
14 | #include <asm/io.h> | ||
15 | #include <asm/bug.h> | ||
16 | |||
17 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1 | ||
18 | #define map_bankwidth(map) 1 | ||
19 | #define map_bankwidth_is_1(map) (map_bankwidth(map) == 1) | ||
20 | #define map_bankwidth_is_large(map) (0) | ||
21 | #define map_words(map) (1) | ||
22 | #define MAX_MAP_BANKWIDTH 1 | ||
23 | #else | ||
24 | #define map_bankwidth_is_1(map) (0) | ||
25 | #endif | ||
26 | |||
27 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_2 | ||
28 | # ifdef map_bankwidth | ||
29 | # undef map_bankwidth | ||
30 | # define map_bankwidth(map) ((map)->bankwidth) | ||
31 | # else | ||
32 | # define map_bankwidth(map) 2 | ||
33 | # define map_bankwidth_is_large(map) (0) | ||
34 | # define map_words(map) (1) | ||
35 | # endif | ||
36 | #define map_bankwidth_is_2(map) (map_bankwidth(map) == 2) | ||
37 | #undef MAX_MAP_BANKWIDTH | ||
38 | #define MAX_MAP_BANKWIDTH 2 | ||
39 | #else | ||
40 | #define map_bankwidth_is_2(map) (0) | ||
41 | #endif | ||
42 | |||
43 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_4 | ||
44 | # ifdef map_bankwidth | ||
45 | # undef map_bankwidth | ||
46 | # define map_bankwidth(map) ((map)->bankwidth) | ||
47 | # else | ||
48 | # define map_bankwidth(map) 4 | ||
49 | # define map_bankwidth_is_large(map) (0) | ||
50 | # define map_words(map) (1) | ||
51 | # endif | ||
52 | #define map_bankwidth_is_4(map) (map_bankwidth(map) == 4) | ||
53 | #undef MAX_MAP_BANKWIDTH | ||
54 | #define MAX_MAP_BANKWIDTH 4 | ||
55 | #else | ||
56 | #define map_bankwidth_is_4(map) (0) | ||
57 | #endif | ||
58 | |||
59 | /* ensure we never evaluate anything shorted than an unsigned long | ||
60 | * to zero, and ensure we'll never miss the end of an comparison (bjd) */ | ||
61 | |||
62 | #define map_calc_words(map) ((map_bankwidth(map) + (sizeof(unsigned long)-1))/ sizeof(unsigned long)) | ||
63 | |||
64 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_8 | ||
65 | # ifdef map_bankwidth | ||
66 | # undef map_bankwidth | ||
67 | # define map_bankwidth(map) ((map)->bankwidth) | ||
68 | # if BITS_PER_LONG < 64 | ||
69 | # undef map_bankwidth_is_large | ||
70 | # define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8) | ||
71 | # undef map_words | ||
72 | # define map_words(map) map_calc_words(map) | ||
73 | # endif | ||
74 | # else | ||
75 | # define map_bankwidth(map) 8 | ||
76 | # define map_bankwidth_is_large(map) (BITS_PER_LONG < 64) | ||
77 | # define map_words(map) map_calc_words(map) | ||
78 | # endif | ||
79 | #define map_bankwidth_is_8(map) (map_bankwidth(map) == 8) | ||
80 | #undef MAX_MAP_BANKWIDTH | ||
81 | #define MAX_MAP_BANKWIDTH 8 | ||
82 | #else | ||
83 | #define map_bankwidth_is_8(map) (0) | ||
84 | #endif | ||
85 | |||
86 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_16 | ||
87 | # ifdef map_bankwidth | ||
88 | # undef map_bankwidth | ||
89 | # define map_bankwidth(map) ((map)->bankwidth) | ||
90 | # undef map_bankwidth_is_large | ||
91 | # define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8) | ||
92 | # undef map_words | ||
93 | # define map_words(map) map_calc_words(map) | ||
94 | # else | ||
95 | # define map_bankwidth(map) 16 | ||
96 | # define map_bankwidth_is_large(map) (1) | ||
97 | # define map_words(map) map_calc_words(map) | ||
98 | # endif | ||
99 | #define map_bankwidth_is_16(map) (map_bankwidth(map) == 16) | ||
100 | #undef MAX_MAP_BANKWIDTH | ||
101 | #define MAX_MAP_BANKWIDTH 16 | ||
102 | #else | ||
103 | #define map_bankwidth_is_16(map) (0) | ||
104 | #endif | ||
105 | |||
106 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_32 | ||
107 | # ifdef map_bankwidth | ||
108 | # undef map_bankwidth | ||
109 | # define map_bankwidth(map) ((map)->bankwidth) | ||
110 | # undef map_bankwidth_is_large | ||
111 | # define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8) | ||
112 | # undef map_words | ||
113 | # define map_words(map) map_calc_words(map) | ||
114 | # else | ||
115 | # define map_bankwidth(map) 32 | ||
116 | # define map_bankwidth_is_large(map) (1) | ||
117 | # define map_words(map) map_calc_words(map) | ||
118 | # endif | ||
119 | #define map_bankwidth_is_32(map) (map_bankwidth(map) == 32) | ||
120 | #undef MAX_MAP_BANKWIDTH | ||
121 | #define MAX_MAP_BANKWIDTH 32 | ||
122 | #else | ||
123 | #define map_bankwidth_is_32(map) (0) | ||
124 | #endif | ||
125 | |||
126 | #ifndef map_bankwidth | ||
127 | #error "No bus width supported. What's the point?" | ||
128 | #endif | ||
129 | |||
130 | static inline int map_bankwidth_supported(int w) | ||
131 | { | ||
132 | switch (w) { | ||
133 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_1 | ||
134 | case 1: | ||
135 | #endif | ||
136 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_2 | ||
137 | case 2: | ||
138 | #endif | ||
139 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_4 | ||
140 | case 4: | ||
141 | #endif | ||
142 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_8 | ||
143 | case 8: | ||
144 | #endif | ||
145 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_16 | ||
146 | case 16: | ||
147 | #endif | ||
148 | #ifdef CONFIG_MTD_MAP_BANK_WIDTH_32 | ||
149 | case 32: | ||
150 | #endif | ||
151 | return 1; | ||
152 | |||
153 | default: | ||
154 | return 0; | ||
155 | } | ||
156 | } | ||
157 | |||
158 | #define MAX_MAP_LONGS ( ((MAX_MAP_BANKWIDTH*8) + BITS_PER_LONG - 1) / BITS_PER_LONG ) | ||
159 | |||
160 | typedef union { | ||
161 | unsigned long x[MAX_MAP_LONGS]; | ||
162 | } map_word; | ||
163 | |||
164 | /* The map stuff is very simple. You fill in your struct map_info with | ||
165 | a handful of routines for accessing the device, making sure they handle | ||
166 | paging etc. correctly if your device needs it. Then you pass it off | ||
167 | to a chip probe routine -- either JEDEC or CFI probe or both -- via | ||
168 | do_map_probe(). If a chip is recognised, the probe code will invoke the | ||
169 | appropriate chip driver (if present) and return a struct mtd_info. | ||
170 | At which point, you fill in the mtd->module with your own module | ||
171 | address, and register it with the MTD core code. Or you could partition | ||
172 | it and register the partitions instead, or keep it for your own private | ||
173 | use; whatever. | ||
174 | |||
175 | The mtd->priv field will point to the struct map_info, and any further | ||
176 | private data required by the chip driver is linked from the | ||
177 | mtd->priv->fldrv_priv field. This allows the map driver to get at | ||
178 | the destructor function map->fldrv_destroy() when it's tired | ||
179 | of living. | ||
180 | */ | ||
181 | |||
182 | struct map_info { | ||
183 | char *name; | ||
184 | unsigned long size; | ||
185 | unsigned long phys; | ||
186 | #define NO_XIP (-1UL) | ||
187 | |||
188 | void __iomem *virt; | ||
189 | void *cached; | ||
190 | |||
191 | int bankwidth; /* in octets. This isn't necessarily the width | ||
192 | of actual bus cycles -- it's the repeat interval | ||
193 | in bytes, before you are talking to the first chip again. | ||
194 | */ | ||
195 | |||
196 | #ifdef CONFIG_MTD_COMPLEX_MAPPINGS | ||
197 | map_word (*read)(struct map_info *, unsigned long); | ||
198 | void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t); | ||
199 | |||
200 | void (*write)(struct map_info *, const map_word, unsigned long); | ||
201 | void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t); | ||
202 | |||
203 | /* We can perhaps put in 'point' and 'unpoint' methods, if we really | ||
204 | want to enable XIP for non-linear mappings. Not yet though. */ | ||
205 | #endif | ||
206 | /* It's possible for the map driver to use cached memory in its | ||
207 | copy_from implementation (and _only_ with copy_from). However, | ||
208 | when the chip driver knows some flash area has changed contents, | ||
209 | it will signal it to the map driver through this routine to let | ||
210 | the map driver invalidate the corresponding cache as needed. | ||
211 | If there is no cache to care about this can be set to NULL. */ | ||
212 | void (*inval_cache)(struct map_info *, unsigned long, ssize_t); | ||
213 | |||
214 | /* set_vpp() must handle being reentered -- enable, enable, disable | ||
215 | must leave it enabled. */ | ||
216 | void (*set_vpp)(struct map_info *, int); | ||
217 | |||
218 | unsigned long map_priv_1; | ||
219 | unsigned long map_priv_2; | ||
220 | void *fldrv_priv; | ||
221 | struct mtd_chip_driver *fldrv; | ||
222 | }; | ||
223 | |||
224 | struct mtd_chip_driver { | ||
225 | struct mtd_info *(*probe)(struct map_info *map); | ||
226 | void (*destroy)(struct mtd_info *); | ||
227 | struct module *module; | ||
228 | char *name; | ||
229 | struct list_head list; | ||
230 | }; | ||
231 | |||
232 | void register_mtd_chip_driver(struct mtd_chip_driver *); | ||
233 | void unregister_mtd_chip_driver(struct mtd_chip_driver *); | ||
234 | |||
235 | struct mtd_info *do_map_probe(const char *name, struct map_info *map); | ||
236 | void map_destroy(struct mtd_info *mtd); | ||
237 | |||
238 | #define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0) | ||
239 | #define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0) | ||
240 | |||
241 | #define INVALIDATE_CACHED_RANGE(map, from, size) \ | ||
242 | do { if(map->inval_cache) map->inval_cache(map, from, size); } while(0) | ||
243 | |||
244 | |||
245 | static inline int map_word_equal(struct map_info *map, map_word val1, map_word val2) | ||
246 | { | ||
247 | int i; | ||
248 | for (i=0; i<map_words(map); i++) { | ||
249 | if (val1.x[i] != val2.x[i]) | ||
250 | return 0; | ||
251 | } | ||
252 | return 1; | ||
253 | } | ||
254 | |||
255 | static inline map_word map_word_and(struct map_info *map, map_word val1, map_word val2) | ||
256 | { | ||
257 | map_word r; | ||
258 | int i; | ||
259 | |||
260 | for (i=0; i<map_words(map); i++) { | ||
261 | r.x[i] = val1.x[i] & val2.x[i]; | ||
262 | } | ||
263 | return r; | ||
264 | } | ||
265 | |||
266 | static inline map_word map_word_or(struct map_info *map, map_word val1, map_word val2) | ||
267 | { | ||
268 | map_word r; | ||
269 | int i; | ||
270 | |||
271 | for (i=0; i<map_words(map); i++) { | ||
272 | r.x[i] = val1.x[i] | val2.x[i]; | ||
273 | } | ||
274 | return r; | ||
275 | } | ||
276 | #define map_word_andequal(m, a, b, z) map_word_equal(m, z, map_word_and(m, a, b)) | ||
277 | |||
278 | static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2) | ||
279 | { | ||
280 | int i; | ||
281 | |||
282 | for (i=0; i<map_words(map); i++) { | ||
283 | if (val1.x[i] & val2.x[i]) | ||
284 | return 1; | ||
285 | } | ||
286 | return 0; | ||
287 | } | ||
288 | |||
289 | static inline map_word map_word_load(struct map_info *map, const void *ptr) | ||
290 | { | ||
291 | map_word r; | ||
292 | |||
293 | if (map_bankwidth_is_1(map)) | ||
294 | r.x[0] = *(unsigned char *)ptr; | ||
295 | else if (map_bankwidth_is_2(map)) | ||
296 | r.x[0] = get_unaligned((uint16_t *)ptr); | ||
297 | else if (map_bankwidth_is_4(map)) | ||
298 | r.x[0] = get_unaligned((uint32_t *)ptr); | ||
299 | #if BITS_PER_LONG >= 64 | ||
300 | else if (map_bankwidth_is_8(map)) | ||
301 | r.x[0] = get_unaligned((uint64_t *)ptr); | ||
302 | #endif | ||
303 | else if (map_bankwidth_is_large(map)) | ||
304 | memcpy(r.x, ptr, map->bankwidth); | ||
305 | |||
306 | return r; | ||
307 | } | ||
308 | |||
309 | static inline map_word map_word_load_partial(struct map_info *map, map_word orig, const unsigned char *buf, int start, int len) | ||
310 | { | ||
311 | int i; | ||
312 | |||
313 | if (map_bankwidth_is_large(map)) { | ||
314 | char *dest = (char *)&orig; | ||
315 | memcpy(dest+start, buf, len); | ||
316 | } else { | ||
317 | for (i=start; i < start+len; i++) { | ||
318 | int bitpos; | ||
319 | #ifdef __LITTLE_ENDIAN | ||
320 | bitpos = i*8; | ||
321 | #else /* __BIG_ENDIAN */ | ||
322 | bitpos = (map_bankwidth(map)-1-i)*8; | ||
323 | #endif | ||
324 | orig.x[0] &= ~(0xff << bitpos); | ||
325 | orig.x[0] |= buf[i-start] << bitpos; | ||
326 | } | ||
327 | } | ||
328 | return orig; | ||
329 | } | ||
330 | |||
331 | static inline map_word map_word_ff(struct map_info *map) | ||
332 | { | ||
333 | map_word r; | ||
334 | int i; | ||
335 | |||
336 | for (i=0; i<map_words(map); i++) { | ||
337 | r.x[i] = ~0UL; | ||
338 | } | ||
339 | return r; | ||
340 | } | ||
341 | static inline map_word inline_map_read(struct map_info *map, unsigned long ofs) | ||
342 | { | ||
343 | map_word r; | ||
344 | |||
345 | if (map_bankwidth_is_1(map)) | ||
346 | r.x[0] = __raw_readb(map->virt + ofs); | ||
347 | else if (map_bankwidth_is_2(map)) | ||
348 | r.x[0] = __raw_readw(map->virt + ofs); | ||
349 | else if (map_bankwidth_is_4(map)) | ||
350 | r.x[0] = __raw_readl(map->virt + ofs); | ||
351 | #if BITS_PER_LONG >= 64 | ||
352 | else if (map_bankwidth_is_8(map)) | ||
353 | r.x[0] = __raw_readq(map->virt + ofs); | ||
354 | #endif | ||
355 | else if (map_bankwidth_is_large(map)) | ||
356 | memcpy_fromio(r.x, map->virt+ofs, map->bankwidth); | ||
357 | |||
358 | return r; | ||
359 | } | ||
360 | |||
361 | static inline void inline_map_write(struct map_info *map, const map_word datum, unsigned long ofs) | ||
362 | { | ||
363 | if (map_bankwidth_is_1(map)) | ||
364 | __raw_writeb(datum.x[0], map->virt + ofs); | ||
365 | else if (map_bankwidth_is_2(map)) | ||
366 | __raw_writew(datum.x[0], map->virt + ofs); | ||
367 | else if (map_bankwidth_is_4(map)) | ||
368 | __raw_writel(datum.x[0], map->virt + ofs); | ||
369 | #if BITS_PER_LONG >= 64 | ||
370 | else if (map_bankwidth_is_8(map)) | ||
371 | __raw_writeq(datum.x[0], map->virt + ofs); | ||
372 | #endif | ||
373 | else if (map_bankwidth_is_large(map)) | ||
374 | memcpy_toio(map->virt+ofs, datum.x, map->bankwidth); | ||
375 | mb(); | ||
376 | } | ||
377 | |||
378 | static inline void inline_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len) | ||
379 | { | ||
380 | if (map->cached) | ||
381 | memcpy(to, (char *)map->cached + from, len); | ||
382 | else | ||
383 | memcpy_fromio(to, map->virt + from, len); | ||
384 | } | ||
385 | |||
386 | static inline void inline_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len) | ||
387 | { | ||
388 | memcpy_toio(map->virt + to, from, len); | ||
389 | } | ||
390 | |||
391 | #ifdef CONFIG_MTD_COMPLEX_MAPPINGS | ||
392 | #define map_read(map, ofs) (map)->read(map, ofs) | ||
393 | #define map_copy_from(map, to, from, len) (map)->copy_from(map, to, from, len) | ||
394 | #define map_write(map, datum, ofs) (map)->write(map, datum, ofs) | ||
395 | #define map_copy_to(map, to, from, len) (map)->copy_to(map, to, from, len) | ||
396 | |||
397 | extern void simple_map_init(struct map_info *); | ||
398 | #define map_is_linear(map) (map->phys != NO_XIP) | ||
399 | |||
400 | #else | ||
401 | #define map_read(map, ofs) inline_map_read(map, ofs) | ||
402 | #define map_copy_from(map, to, from, len) inline_map_copy_from(map, to, from, len) | ||
403 | #define map_write(map, datum, ofs) inline_map_write(map, datum, ofs) | ||
404 | #define map_copy_to(map, to, from, len) inline_map_copy_to(map, to, from, len) | ||
405 | |||
406 | |||
407 | #define simple_map_init(map) BUG_ON(!map_bankwidth_supported((map)->bankwidth)) | ||
408 | #define map_is_linear(map) (1) | ||
409 | |||
410 | #endif /* !CONFIG_MTD_COMPLEX_MAPPINGS */ | ||
411 | |||
412 | #endif /* __LINUX_MTD_MAP_H__ */ | ||
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h new file mode 100644 index 000000000000..b3d134392b31 --- /dev/null +++ b/include/linux/mtd/mtd.h | |||
@@ -0,0 +1,226 @@ | |||
1 | /* | ||
2 | * $Id: mtd.h,v 1.56 2004/08/09 18:46:04 dmarlin Exp $ | ||
3 | * | ||
4 | * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al. | ||
5 | * | ||
6 | * Released under GPL | ||
7 | */ | ||
8 | |||
9 | #ifndef __MTD_MTD_H__ | ||
10 | #define __MTD_MTD_H__ | ||
11 | |||
12 | #ifndef __KERNEL__ | ||
13 | #error This is a kernel header. Perhaps include mtd-user.h instead? | ||
14 | #endif | ||
15 | |||
16 | #include <linux/config.h> | ||
17 | #include <linux/version.h> | ||
18 | #include <linux/types.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/uio.h> | ||
21 | |||
22 | #include <linux/mtd/compatmac.h> | ||
23 | #include <mtd/mtd-abi.h> | ||
24 | |||
25 | #define MTD_CHAR_MAJOR 90 | ||
26 | #define MTD_BLOCK_MAJOR 31 | ||
27 | #define MAX_MTD_DEVICES 16 | ||
28 | |||
29 | #define MTD_ERASE_PENDING 0x01 | ||
30 | #define MTD_ERASING 0x02 | ||
31 | #define MTD_ERASE_SUSPEND 0x04 | ||
32 | #define MTD_ERASE_DONE 0x08 | ||
33 | #define MTD_ERASE_FAILED 0x10 | ||
34 | |||
35 | /* If the erase fails, fail_addr might indicate exactly which block failed. If | ||
36 | fail_addr = 0xffffffff, the failure was not at the device level or was not | ||
37 | specific to any particular block. */ | ||
38 | struct erase_info { | ||
39 | struct mtd_info *mtd; | ||
40 | u_int32_t addr; | ||
41 | u_int32_t len; | ||
42 | u_int32_t fail_addr; | ||
43 | u_long time; | ||
44 | u_long retries; | ||
45 | u_int dev; | ||
46 | u_int cell; | ||
47 | void (*callback) (struct erase_info *self); | ||
48 | u_long priv; | ||
49 | u_char state; | ||
50 | struct erase_info *next; | ||
51 | }; | ||
52 | |||
53 | struct mtd_erase_region_info { | ||
54 | u_int32_t offset; /* At which this region starts, from the beginning of the MTD */ | ||
55 | u_int32_t erasesize; /* For this region */ | ||
56 | u_int32_t numblocks; /* Number of blocks of erasesize in this region */ | ||
57 | }; | ||
58 | |||
59 | struct mtd_info { | ||
60 | u_char type; | ||
61 | u_int32_t flags; | ||
62 | u_int32_t size; // Total size of the MTD | ||
63 | |||
64 | /* "Major" erase size for the device. Naïve users may take this | ||
65 | * to be the only erase size available, or may use the more detailed | ||
66 | * information below if they desire | ||
67 | */ | ||
68 | u_int32_t erasesize; | ||
69 | |||
70 | u_int32_t oobblock; // Size of OOB blocks (e.g. 512) | ||
71 | u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) | ||
72 | u_int32_t oobavail; // Number of bytes in OOB area available for fs | ||
73 | u_int32_t ecctype; | ||
74 | u_int32_t eccsize; | ||
75 | |||
76 | |||
77 | // Kernel-only stuff starts here. | ||
78 | char *name; | ||
79 | int index; | ||
80 | |||
81 | // oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO) | ||
82 | struct nand_oobinfo oobinfo; | ||
83 | |||
84 | /* Data for variable erase regions. If numeraseregions is zero, | ||
85 | * it means that the whole device has erasesize as given above. | ||
86 | */ | ||
87 | int numeraseregions; | ||
88 | struct mtd_erase_region_info *eraseregions; | ||
89 | |||
90 | /* This really shouldn't be here. It can go away in 2.5 */ | ||
91 | u_int32_t bank_size; | ||
92 | |||
93 | int (*erase) (struct mtd_info *mtd, struct erase_info *instr); | ||
94 | |||
95 | /* This stuff for eXecute-In-Place */ | ||
96 | int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); | ||
97 | |||
98 | /* We probably shouldn't allow XIP if the unpoint isn't a NULL */ | ||
99 | void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len); | ||
100 | |||
101 | |||
102 | int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | ||
103 | int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); | ||
104 | |||
105 | 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); | ||
106 | 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); | ||
107 | |||
108 | int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | ||
109 | int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); | ||
110 | |||
111 | /* | ||
112 | * Methods to access the protection register area, present in some | ||
113 | * flash devices. The user data is one time programmable but the | ||
114 | * factory data is read only. | ||
115 | */ | ||
116 | int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | ||
117 | |||
118 | int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | ||
119 | |||
120 | /* This function is not yet implemented */ | ||
121 | int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); | ||
122 | |||
123 | /* kvec-based read/write methods. We need these especially for NAND flash, | ||
124 | with its limited number of write cycles per erase. | ||
125 | NB: The 'count' parameter is the number of _vectors_, each of | ||
126 | which contains an (ofs, len) tuple. | ||
127 | */ | ||
128 | int (*readv) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen); | ||
129 | int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, | ||
130 | size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); | ||
131 | int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); | ||
132 | int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, | ||
133 | size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel); | ||
134 | |||
135 | /* Sync */ | ||
136 | void (*sync) (struct mtd_info *mtd); | ||
137 | |||
138 | /* Chip-supported device locking */ | ||
139 | int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len); | ||
140 | int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len); | ||
141 | |||
142 | /* Power Management functions */ | ||
143 | int (*suspend) (struct mtd_info *mtd); | ||
144 | void (*resume) (struct mtd_info *mtd); | ||
145 | |||
146 | /* Bad block management functions */ | ||
147 | int (*block_isbad) (struct mtd_info *mtd, loff_t ofs); | ||
148 | int (*block_markbad) (struct mtd_info *mtd, loff_t ofs); | ||
149 | |||
150 | void *priv; | ||
151 | |||
152 | struct module *owner; | ||
153 | int usecount; | ||
154 | }; | ||
155 | |||
156 | |||
157 | /* Kernel-side ioctl definitions */ | ||
158 | |||
159 | extern int add_mtd_device(struct mtd_info *mtd); | ||
160 | extern int del_mtd_device (struct mtd_info *mtd); | ||
161 | |||
162 | extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num); | ||
163 | |||
164 | extern void put_mtd_device(struct mtd_info *mtd); | ||
165 | |||
166 | |||
167 | struct mtd_notifier { | ||
168 | void (*add)(struct mtd_info *mtd); | ||
169 | void (*remove)(struct mtd_info *mtd); | ||
170 | struct list_head list; | ||
171 | }; | ||
172 | |||
173 | |||
174 | extern void register_mtd_user (struct mtd_notifier *new); | ||
175 | extern int unregister_mtd_user (struct mtd_notifier *old); | ||
176 | |||
177 | int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, | ||
178 | unsigned long count, loff_t to, size_t *retlen); | ||
179 | |||
180 | int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, | ||
181 | unsigned long count, loff_t from, size_t *retlen); | ||
182 | |||
183 | #define MTD_ERASE(mtd, args...) (*(mtd->erase))(mtd, args) | ||
184 | #define MTD_POINT(mtd, a,b,c,d) (*(mtd->point))(mtd, a,b,c, (u_char **)(d)) | ||
185 | #define MTD_UNPOINT(mtd, arg) (*(mtd->unpoint))(mtd, (u_char *)arg) | ||
186 | #define MTD_READ(mtd, args...) (*(mtd->read))(mtd, args) | ||
187 | #define MTD_WRITE(mtd, args...) (*(mtd->write))(mtd, args) | ||
188 | #define MTD_READV(mtd, args...) (*(mtd->readv))(mtd, args) | ||
189 | #define MTD_WRITEV(mtd, args...) (*(mtd->writev))(mtd, args) | ||
190 | #define MTD_READECC(mtd, args...) (*(mtd->read_ecc))(mtd, args) | ||
191 | #define MTD_WRITEECC(mtd, args...) (*(mtd->write_ecc))(mtd, args) | ||
192 | #define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args) | ||
193 | #define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args) | ||
194 | #define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0) | ||
195 | |||
196 | |||
197 | #ifdef CONFIG_MTD_PARTITIONS | ||
198 | void mtd_erase_callback(struct erase_info *instr); | ||
199 | #else | ||
200 | static inline void mtd_erase_callback(struct erase_info *instr) | ||
201 | { | ||
202 | if (instr->callback) | ||
203 | instr->callback(instr); | ||
204 | } | ||
205 | #endif | ||
206 | |||
207 | /* | ||
208 | * Debugging macro and defines | ||
209 | */ | ||
210 | #define MTD_DEBUG_LEVEL0 (0) /* Quiet */ | ||
211 | #define MTD_DEBUG_LEVEL1 (1) /* Audible */ | ||
212 | #define MTD_DEBUG_LEVEL2 (2) /* Loud */ | ||
213 | #define MTD_DEBUG_LEVEL3 (3) /* Noisy */ | ||
214 | |||
215 | #ifdef CONFIG_MTD_DEBUG | ||
216 | #define DEBUG(n, args...) \ | ||
217 | do { \ | ||
218 | if (n <= CONFIG_MTD_DEBUG_VERBOSE) \ | ||
219 | printk(KERN_INFO args); \ | ||
220 | } while(0) | ||
221 | #else /* CONFIG_MTD_DEBUG */ | ||
222 | #define DEBUG(n, args...) do { } while(0) | ||
223 | |||
224 | #endif /* CONFIG_MTD_DEBUG */ | ||
225 | |||
226 | #endif /* __MTD_MTD_H__ */ | ||
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h new file mode 100644 index 000000000000..9a19c65abd74 --- /dev/null +++ b/include/linux/mtd/nand.h | |||
@@ -0,0 +1,469 @@ | |||
1 | /* | ||
2 | * linux/include/linux/mtd/nand.h | ||
3 | * | ||
4 | * Copyright (c) 2000 David Woodhouse <dwmw2@mvhi.com> | ||
5 | * Steven J. Hill <sjhill@realitydiluted.com> | ||
6 | * Thomas Gleixner <tglx@linutronix.de> | ||
7 | * | ||
8 | * $Id: nand.h,v 1.68 2004/11/12 10:40:37 gleixner Exp $ | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | * Info: | ||
15 | * Contains standard defines and IDs for NAND flash devices | ||
16 | * | ||
17 | * Changelog: | ||
18 | * 01-31-2000 DMW Created | ||
19 | * 09-18-2000 SJH Moved structure out of the Disk-On-Chip drivers | ||
20 | * so it can be used by other NAND flash device | ||
21 | * drivers. I also changed the copyright since none | ||
22 | * of the original contents of this file are specific | ||
23 | * to DoC devices. David can whack me with a baseball | ||
24 | * bat later if I did something naughty. | ||
25 | * 10-11-2000 SJH Added private NAND flash structure for driver | ||
26 | * 10-24-2000 SJH Added prototype for 'nand_scan' function | ||
27 | * 10-29-2001 TG changed nand_chip structure to support | ||
28 | * hardwarespecific function for accessing control lines | ||
29 | * 02-21-2002 TG added support for different read/write adress and | ||
30 | * ready/busy line access function | ||
31 | * 02-26-2002 TG added chip_delay to nand_chip structure to optimize | ||
32 | * command delay times for different chips | ||
33 | * 04-28-2002 TG OOB config defines moved from nand.c to avoid duplicate | ||
34 | * defines in jffs2/wbuf.c | ||
35 | * 08-07-2002 TG forced bad block location to byte 5 of OOB, even if | ||
36 | * CONFIG_MTD_NAND_ECC_JFFS2 is not set | ||
37 | * 08-10-2002 TG extensions to nand_chip structure to support HW-ECC | ||
38 | * | ||
39 | * 08-29-2002 tglx nand_chip structure: data_poi for selecting | ||
40 | * internal / fs-driver buffer | ||
41 | * support for 6byte/512byte hardware ECC | ||
42 | * read_ecc, write_ecc extended for different oob-layout | ||
43 | * oob layout selections: NAND_NONE_OOB, NAND_JFFS2_OOB, | ||
44 | * NAND_YAFFS_OOB | ||
45 | * 11-25-2002 tglx Added Manufacturer code FUJITSU, NATIONAL | ||
46 | * Split manufacturer and device ID structures | ||
47 | * | ||
48 | * 02-08-2004 tglx added option field to nand structure for chip anomalities | ||
49 | * 05-25-2004 tglx added bad block table support, ST-MICRO manufacturer id | ||
50 | * update of nand_chip structure description | ||
51 | */ | ||
52 | #ifndef __LINUX_MTD_NAND_H | ||
53 | #define __LINUX_MTD_NAND_H | ||
54 | |||
55 | #include <linux/config.h> | ||
56 | #include <linux/wait.h> | ||
57 | #include <linux/spinlock.h> | ||
58 | #include <linux/mtd/mtd.h> | ||
59 | |||
60 | struct mtd_info; | ||
61 | /* Scan and identify a NAND device */ | ||
62 | extern int nand_scan (struct mtd_info *mtd, int max_chips); | ||
63 | /* Free resources held by the NAND device */ | ||
64 | extern void nand_release (struct mtd_info *mtd); | ||
65 | |||
66 | /* Read raw data from the device without ECC */ | ||
67 | extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen); | ||
68 | |||
69 | |||
70 | /* The maximum number of NAND chips in an array */ | ||
71 | #define NAND_MAX_CHIPS 8 | ||
72 | |||
73 | /* This constant declares the max. oobsize / page, which | ||
74 | * is supported now. If you add a chip with bigger oobsize/page | ||
75 | * adjust this accordingly. | ||
76 | */ | ||
77 | #define NAND_MAX_OOBSIZE 64 | ||
78 | |||
79 | /* | ||
80 | * Constants for hardware specific CLE/ALE/NCE function | ||
81 | */ | ||
82 | /* Select the chip by setting nCE to low */ | ||
83 | #define NAND_CTL_SETNCE 1 | ||
84 | /* Deselect the chip by setting nCE to high */ | ||
85 | #define NAND_CTL_CLRNCE 2 | ||
86 | /* Select the command latch by setting CLE to high */ | ||
87 | #define NAND_CTL_SETCLE 3 | ||
88 | /* Deselect the command latch by setting CLE to low */ | ||
89 | #define NAND_CTL_CLRCLE 4 | ||
90 | /* Select the address latch by setting ALE to high */ | ||
91 | #define NAND_CTL_SETALE 5 | ||
92 | /* Deselect the address latch by setting ALE to low */ | ||
93 | #define NAND_CTL_CLRALE 6 | ||
94 | /* Set write protection by setting WP to high. Not used! */ | ||
95 | #define NAND_CTL_SETWP 7 | ||
96 | /* Clear write protection by setting WP to low. Not used! */ | ||
97 | #define NAND_CTL_CLRWP 8 | ||
98 | |||
99 | /* | ||
100 | * Standard NAND flash commands | ||
101 | */ | ||
102 | #define NAND_CMD_READ0 0 | ||
103 | #define NAND_CMD_READ1 1 | ||
104 | #define NAND_CMD_PAGEPROG 0x10 | ||
105 | #define NAND_CMD_READOOB 0x50 | ||
106 | #define NAND_CMD_ERASE1 0x60 | ||
107 | #define NAND_CMD_STATUS 0x70 | ||
108 | #define NAND_CMD_STATUS_MULTI 0x71 | ||
109 | #define NAND_CMD_SEQIN 0x80 | ||
110 | #define NAND_CMD_READID 0x90 | ||
111 | #define NAND_CMD_ERASE2 0xd0 | ||
112 | #define NAND_CMD_RESET 0xff | ||
113 | |||
114 | /* Extended commands for large page devices */ | ||
115 | #define NAND_CMD_READSTART 0x30 | ||
116 | #define NAND_CMD_CACHEDPROG 0x15 | ||
117 | |||
118 | /* Status bits */ | ||
119 | #define NAND_STATUS_FAIL 0x01 | ||
120 | #define NAND_STATUS_FAIL_N1 0x02 | ||
121 | #define NAND_STATUS_TRUE_READY 0x20 | ||
122 | #define NAND_STATUS_READY 0x40 | ||
123 | #define NAND_STATUS_WP 0x80 | ||
124 | |||
125 | /* | ||
126 | * Constants for ECC_MODES | ||
127 | */ | ||
128 | |||
129 | /* No ECC. Usage is not recommended ! */ | ||
130 | #define NAND_ECC_NONE 0 | ||
131 | /* Software ECC 3 byte ECC per 256 Byte data */ | ||
132 | #define NAND_ECC_SOFT 1 | ||
133 | /* Hardware ECC 3 byte ECC per 256 Byte data */ | ||
134 | #define NAND_ECC_HW3_256 2 | ||
135 | /* Hardware ECC 3 byte ECC per 512 Byte data */ | ||
136 | #define NAND_ECC_HW3_512 3 | ||
137 | /* Hardware ECC 3 byte ECC per 512 Byte data */ | ||
138 | #define NAND_ECC_HW6_512 4 | ||
139 | /* Hardware ECC 8 byte ECC per 512 Byte data */ | ||
140 | #define NAND_ECC_HW8_512 6 | ||
141 | /* Hardware ECC 12 byte ECC per 2048 Byte data */ | ||
142 | #define NAND_ECC_HW12_2048 7 | ||
143 | |||
144 | /* | ||
145 | * Constants for Hardware ECC | ||
146 | */ | ||
147 | /* Reset Hardware ECC for read */ | ||
148 | #define NAND_ECC_READ 0 | ||
149 | /* Reset Hardware ECC for write */ | ||
150 | #define NAND_ECC_WRITE 1 | ||
151 | /* Enable Hardware ECC before syndrom is read back from flash */ | ||
152 | #define NAND_ECC_READSYN 2 | ||
153 | |||
154 | /* Option constants for bizarre disfunctionality and real | ||
155 | * features | ||
156 | */ | ||
157 | /* Chip can not auto increment pages */ | ||
158 | #define NAND_NO_AUTOINCR 0x00000001 | ||
159 | /* Buswitdh is 16 bit */ | ||
160 | #define NAND_BUSWIDTH_16 0x00000002 | ||
161 | /* Device supports partial programming without padding */ | ||
162 | #define NAND_NO_PADDING 0x00000004 | ||
163 | /* Chip has cache program function */ | ||
164 | #define NAND_CACHEPRG 0x00000008 | ||
165 | /* Chip has copy back function */ | ||
166 | #define NAND_COPYBACK 0x00000010 | ||
167 | /* AND Chip which has 4 banks and a confusing page / block | ||
168 | * assignment. See Renesas datasheet for further information */ | ||
169 | #define NAND_IS_AND 0x00000020 | ||
170 | /* Chip has a array of 4 pages which can be read without | ||
171 | * additional ready /busy waits */ | ||
172 | #define NAND_4PAGE_ARRAY 0x00000040 | ||
173 | |||
174 | /* Options valid for Samsung large page devices */ | ||
175 | #define NAND_SAMSUNG_LP_OPTIONS \ | ||
176 | (NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK) | ||
177 | |||
178 | /* Macros to identify the above */ | ||
179 | #define NAND_CANAUTOINCR(chip) (!(chip->options & NAND_NO_AUTOINCR)) | ||
180 | #define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING)) | ||
181 | #define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG)) | ||
182 | #define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK)) | ||
183 | |||
184 | /* Mask to zero out the chip options, which come from the id table */ | ||
185 | #define NAND_CHIPOPTIONS_MSK (0x0000ffff & ~NAND_NO_AUTOINCR) | ||
186 | |||
187 | /* Non chip related options */ | ||
188 | /* Use a flash based bad block table. This option is passed to the | ||
189 | * default bad block table function. */ | ||
190 | #define NAND_USE_FLASH_BBT 0x00010000 | ||
191 | /* The hw ecc generator provides a syndrome instead a ecc value on read | ||
192 | * This can only work if we have the ecc bytes directly behind the | ||
193 | * data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */ | ||
194 | #define NAND_HWECC_SYNDROME 0x00020000 | ||
195 | |||
196 | |||
197 | /* Options set by nand scan */ | ||
198 | /* Nand scan has allocated oob_buf */ | ||
199 | #define NAND_OOBBUF_ALLOC 0x40000000 | ||
200 | /* Nand scan has allocated data_buf */ | ||
201 | #define NAND_DATABUF_ALLOC 0x80000000 | ||
202 | |||
203 | |||
204 | /* | ||
205 | * nand_state_t - chip states | ||
206 | * Enumeration for NAND flash chip state | ||
207 | */ | ||
208 | typedef enum { | ||
209 | FL_READY, | ||
210 | FL_READING, | ||
211 | FL_WRITING, | ||
212 | FL_ERASING, | ||
213 | FL_SYNCING, | ||
214 | FL_CACHEDPRG, | ||
215 | } nand_state_t; | ||
216 | |||
217 | /* Keep gcc happy */ | ||
218 | struct nand_chip; | ||
219 | |||
220 | /** | ||
221 | * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices | ||
222 | * @lock: protection lock | ||
223 | * @active: the mtd device which holds the controller currently | ||
224 | */ | ||
225 | struct nand_hw_control { | ||
226 | spinlock_t lock; | ||
227 | struct nand_chip *active; | ||
228 | }; | ||
229 | |||
230 | /** | ||
231 | * struct nand_chip - NAND Private Flash Chip Data | ||
232 | * @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device | ||
233 | * @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device | ||
234 | * @read_byte: [REPLACEABLE] read one byte from the chip | ||
235 | * @write_byte: [REPLACEABLE] write one byte to the chip | ||
236 | * @read_word: [REPLACEABLE] read one word from the chip | ||
237 | * @write_word: [REPLACEABLE] write one word to the chip | ||
238 | * @write_buf: [REPLACEABLE] write data from the buffer to the chip | ||
239 | * @read_buf: [REPLACEABLE] read data from the chip into the buffer | ||
240 | * @verify_buf: [REPLACEABLE] verify buffer contents against the chip data | ||
241 | * @select_chip: [REPLACEABLE] select chip nr | ||
242 | * @block_bad: [REPLACEABLE] check, if the block is bad | ||
243 | * @block_markbad: [REPLACEABLE] mark the block bad | ||
244 | * @hwcontrol: [BOARDSPECIFIC] hardwarespecific function for accesing control-lines | ||
245 | * @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line | ||
246 | * If set to NULL no access to ready/busy is available and the ready/busy information | ||
247 | * is read from the chip status register | ||
248 | * @cmdfunc: [REPLACEABLE] hardwarespecific function for writing commands to the chip | ||
249 | * @waitfunc: [REPLACEABLE] hardwarespecific function for wait on ready | ||
250 | * @calculate_ecc: [REPLACEABLE] function for ecc calculation or readback from ecc hardware | ||
251 | * @correct_data: [REPLACEABLE] function for ecc correction, matching to ecc generator (sw/hw) | ||
252 | * @enable_hwecc: [BOARDSPECIFIC] function to enable (reset) hardware ecc generator. Must only | ||
253 | * be provided if a hardware ECC is available | ||
254 | * @erase_cmd: [INTERN] erase command write function, selectable due to AND support | ||
255 | * @scan_bbt: [REPLACEABLE] function to scan bad block table | ||
256 | * @eccmode: [BOARDSPECIFIC] mode of ecc, see defines | ||
257 | * @eccsize: [INTERN] databytes used per ecc-calculation | ||
258 | * @eccbytes: [INTERN] number of ecc bytes per ecc-calculation step | ||
259 | * @eccsteps: [INTERN] number of ecc calculation steps per page | ||
260 | * @chip_delay: [BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR) | ||
261 | * @chip_lock: [INTERN] spinlock used to protect access to this structure and the chip | ||
262 | * @wq: [INTERN] wait queue to sleep on if a NAND operation is in progress | ||
263 | * @state: [INTERN] the current state of the NAND device | ||
264 | * @page_shift: [INTERN] number of address bits in a page (column address bits) | ||
265 | * @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock | ||
266 | * @bbt_erase_shift: [INTERN] number of address bits in a bbt entry | ||
267 | * @chip_shift: [INTERN] number of address bits in one chip | ||
268 | * @data_buf: [INTERN] internal buffer for one page + oob | ||
269 | * @oob_buf: [INTERN] oob buffer for one eraseblock | ||
270 | * @oobdirty: [INTERN] indicates that oob_buf must be reinitialized | ||
271 | * @data_poi: [INTERN] pointer to a data buffer | ||
272 | * @options: [BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about | ||
273 | * special functionality. See the defines for further explanation | ||
274 | * @badblockpos: [INTERN] position of the bad block marker in the oob area | ||
275 | * @numchips: [INTERN] number of physical chips | ||
276 | * @chipsize: [INTERN] the size of one chip for multichip arrays | ||
277 | * @pagemask: [INTERN] page number mask = number of (pages / chip) - 1 | ||
278 | * @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf | ||
279 | * @autooob: [REPLACEABLE] the default (auto)placement scheme | ||
280 | * @bbt: [INTERN] bad block table pointer | ||
281 | * @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup | ||
282 | * @bbt_md: [REPLACEABLE] bad block table mirror descriptor | ||
283 | * @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan | ||
284 | * @controller: [OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices | ||
285 | * @priv: [OPTIONAL] pointer to private chip date | ||
286 | */ | ||
287 | |||
288 | struct nand_chip { | ||
289 | void __iomem *IO_ADDR_R; | ||
290 | void __iomem *IO_ADDR_W; | ||
291 | |||
292 | u_char (*read_byte)(struct mtd_info *mtd); | ||
293 | void (*write_byte)(struct mtd_info *mtd, u_char byte); | ||
294 | u16 (*read_word)(struct mtd_info *mtd); | ||
295 | void (*write_word)(struct mtd_info *mtd, u16 word); | ||
296 | |||
297 | void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len); | ||
298 | void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len); | ||
299 | int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len); | ||
300 | void (*select_chip)(struct mtd_info *mtd, int chip); | ||
301 | int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip); | ||
302 | int (*block_markbad)(struct mtd_info *mtd, loff_t ofs); | ||
303 | void (*hwcontrol)(struct mtd_info *mtd, int cmd); | ||
304 | int (*dev_ready)(struct mtd_info *mtd); | ||
305 | void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr); | ||
306 | int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state); | ||
307 | int (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); | ||
308 | int (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); | ||
309 | void (*enable_hwecc)(struct mtd_info *mtd, int mode); | ||
310 | void (*erase_cmd)(struct mtd_info *mtd, int page); | ||
311 | int (*scan_bbt)(struct mtd_info *mtd); | ||
312 | int eccmode; | ||
313 | int eccsize; | ||
314 | int eccbytes; | ||
315 | int eccsteps; | ||
316 | int chip_delay; | ||
317 | spinlock_t chip_lock; | ||
318 | wait_queue_head_t wq; | ||
319 | nand_state_t state; | ||
320 | int page_shift; | ||
321 | int phys_erase_shift; | ||
322 | int bbt_erase_shift; | ||
323 | int chip_shift; | ||
324 | u_char *data_buf; | ||
325 | u_char *oob_buf; | ||
326 | int oobdirty; | ||
327 | u_char *data_poi; | ||
328 | unsigned int options; | ||
329 | int badblockpos; | ||
330 | int numchips; | ||
331 | unsigned long chipsize; | ||
332 | int pagemask; | ||
333 | int pagebuf; | ||
334 | struct nand_oobinfo *autooob; | ||
335 | uint8_t *bbt; | ||
336 | struct nand_bbt_descr *bbt_td; | ||
337 | struct nand_bbt_descr *bbt_md; | ||
338 | struct nand_bbt_descr *badblock_pattern; | ||
339 | struct nand_hw_control *controller; | ||
340 | void *priv; | ||
341 | }; | ||
342 | |||
343 | /* | ||
344 | * NAND Flash Manufacturer ID Codes | ||
345 | */ | ||
346 | #define NAND_MFR_TOSHIBA 0x98 | ||
347 | #define NAND_MFR_SAMSUNG 0xec | ||
348 | #define NAND_MFR_FUJITSU 0x04 | ||
349 | #define NAND_MFR_NATIONAL 0x8f | ||
350 | #define NAND_MFR_RENESAS 0x07 | ||
351 | #define NAND_MFR_STMICRO 0x20 | ||
352 | |||
353 | /** | ||
354 | * struct nand_flash_dev - NAND Flash Device ID Structure | ||
355 | * | ||
356 | * @name: Identify the device type | ||
357 | * @id: device ID code | ||
358 | * @pagesize: Pagesize in bytes. Either 256 or 512 or 0 | ||
359 | * If the pagesize is 0, then the real pagesize | ||
360 | * and the eraseize are determined from the | ||
361 | * extended id bytes in the chip | ||
362 | * @erasesize: Size of an erase block in the flash device. | ||
363 | * @chipsize: Total chipsize in Mega Bytes | ||
364 | * @options: Bitfield to store chip relevant options | ||
365 | */ | ||
366 | struct nand_flash_dev { | ||
367 | char *name; | ||
368 | int id; | ||
369 | unsigned long pagesize; | ||
370 | unsigned long chipsize; | ||
371 | unsigned long erasesize; | ||
372 | unsigned long options; | ||
373 | }; | ||
374 | |||
375 | /** | ||
376 | * struct nand_manufacturers - NAND Flash Manufacturer ID Structure | ||
377 | * @name: Manufacturer name | ||
378 | * @id: manufacturer ID code of device. | ||
379 | */ | ||
380 | struct nand_manufacturers { | ||
381 | int id; | ||
382 | char * name; | ||
383 | }; | ||
384 | |||
385 | extern struct nand_flash_dev nand_flash_ids[]; | ||
386 | extern struct nand_manufacturers nand_manuf_ids[]; | ||
387 | |||
388 | /** | ||
389 | * struct nand_bbt_descr - bad block table descriptor | ||
390 | * @options: options for this descriptor | ||
391 | * @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE | ||
392 | * when bbt is searched, then we store the found bbts pages here. | ||
393 | * Its an array and supports up to 8 chips now | ||
394 | * @offs: offset of the pattern in the oob area of the page | ||
395 | * @veroffs: offset of the bbt version counter in the oob are of the page | ||
396 | * @version: version read from the bbt page during scan | ||
397 | * @len: length of the pattern, if 0 no pattern check is performed | ||
398 | * @maxblocks: maximum number of blocks to search for a bbt. This number of | ||
399 | * blocks is reserved at the end of the device where the tables are | ||
400 | * written. | ||
401 | * @reserved_block_code: if non-0, this pattern denotes a reserved (rather than | ||
402 | * bad) block in the stored bbt | ||
403 | * @pattern: pattern to identify bad block table or factory marked good / | ||
404 | * bad blocks, can be NULL, if len = 0 | ||
405 | * | ||
406 | * Descriptor for the bad block table marker and the descriptor for the | ||
407 | * pattern which identifies good and bad blocks. The assumption is made | ||
408 | * that the pattern and the version count are always located in the oob area | ||
409 | * of the first block. | ||
410 | */ | ||
411 | struct nand_bbt_descr { | ||
412 | int options; | ||
413 | int pages[NAND_MAX_CHIPS]; | ||
414 | int offs; | ||
415 | int veroffs; | ||
416 | uint8_t version[NAND_MAX_CHIPS]; | ||
417 | int len; | ||
418 | int maxblocks; | ||
419 | int reserved_block_code; | ||
420 | uint8_t *pattern; | ||
421 | }; | ||
422 | |||
423 | /* Options for the bad block table descriptors */ | ||
424 | |||
425 | /* The number of bits used per block in the bbt on the device */ | ||
426 | #define NAND_BBT_NRBITS_MSK 0x0000000F | ||
427 | #define NAND_BBT_1BIT 0x00000001 | ||
428 | #define NAND_BBT_2BIT 0x00000002 | ||
429 | #define NAND_BBT_4BIT 0x00000004 | ||
430 | #define NAND_BBT_8BIT 0x00000008 | ||
431 | /* The bad block table is in the last good block of the device */ | ||
432 | #define NAND_BBT_LASTBLOCK 0x00000010 | ||
433 | /* The bbt is at the given page, else we must scan for the bbt */ | ||
434 | #define NAND_BBT_ABSPAGE 0x00000020 | ||
435 | /* The bbt is at the given page, else we must scan for the bbt */ | ||
436 | #define NAND_BBT_SEARCH 0x00000040 | ||
437 | /* bbt is stored per chip on multichip devices */ | ||
438 | #define NAND_BBT_PERCHIP 0x00000080 | ||
439 | /* bbt has a version counter at offset veroffs */ | ||
440 | #define NAND_BBT_VERSION 0x00000100 | ||
441 | /* Create a bbt if none axists */ | ||
442 | #define NAND_BBT_CREATE 0x00000200 | ||
443 | /* Search good / bad pattern through all pages of a block */ | ||
444 | #define NAND_BBT_SCANALLPAGES 0x00000400 | ||
445 | /* Scan block empty during good / bad block scan */ | ||
446 | #define NAND_BBT_SCANEMPTY 0x00000800 | ||
447 | /* Write bbt if neccecary */ | ||
448 | #define NAND_BBT_WRITE 0x00001000 | ||
449 | /* Read and write back block contents when writing bbt */ | ||
450 | #define NAND_BBT_SAVECONTENT 0x00002000 | ||
451 | /* Search good / bad pattern on the first and the second page */ | ||
452 | #define NAND_BBT_SCAN2NDPAGE 0x00004000 | ||
453 | |||
454 | /* The maximum number of blocks to scan for a bbt */ | ||
455 | #define NAND_BBT_SCAN_MAXBLOCKS 4 | ||
456 | |||
457 | extern int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd); | ||
458 | extern int nand_update_bbt (struct mtd_info *mtd, loff_t offs); | ||
459 | extern int nand_default_bbt (struct mtd_info *mtd); | ||
460 | extern int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt); | ||
461 | extern int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt); | ||
462 | |||
463 | /* | ||
464 | * Constants for oob configuration | ||
465 | */ | ||
466 | #define NAND_SMALL_BADBLOCK_POS 5 | ||
467 | #define NAND_LARGE_BADBLOCK_POS 0 | ||
468 | |||
469 | #endif /* __LINUX_MTD_NAND_H */ | ||
diff --git a/include/linux/mtd/nand_ecc.h b/include/linux/mtd/nand_ecc.h new file mode 100644 index 000000000000..12c5bc342ead --- /dev/null +++ b/include/linux/mtd/nand_ecc.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * drivers/mtd/nand_ecc.h | ||
3 | * | ||
4 | * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com) | ||
5 | * | ||
6 | * $Id: nand_ecc.h,v 1.4 2004/06/17 02:35:02 dbrown Exp $ | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License version 2 as | ||
10 | * published by the Free Software Foundation. | ||
11 | * | ||
12 | * This file is the header for the ECC algorithm. | ||
13 | */ | ||
14 | |||
15 | #ifndef __MTD_NAND_ECC_H__ | ||
16 | #define __MTD_NAND_ECC_H__ | ||
17 | |||
18 | struct mtd_info; | ||
19 | |||
20 | /* | ||
21 | * Calculate 3 byte ECC code for 256 byte block | ||
22 | */ | ||
23 | int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code); | ||
24 | |||
25 | /* | ||
26 | * Detect and correct a 1 bit error for 256 byte block | ||
27 | */ | ||
28 | int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc); | ||
29 | |||
30 | #endif /* __MTD_NAND_ECC_H__ */ | ||
diff --git a/include/linux/mtd/nftl.h b/include/linux/mtd/nftl.h new file mode 100644 index 000000000000..d35d2c21ff3e --- /dev/null +++ b/include/linux/mtd/nftl.h | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * $Id: nftl.h,v 1.16 2004/06/30 14:49:00 dbrown Exp $ | ||
3 | * | ||
4 | * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> | ||
5 | */ | ||
6 | |||
7 | #ifndef __MTD_NFTL_H__ | ||
8 | #define __MTD_NFTL_H__ | ||
9 | |||
10 | #include <linux/mtd/mtd.h> | ||
11 | #include <linux/mtd/blktrans.h> | ||
12 | |||
13 | #include <mtd/nftl-user.h> | ||
14 | |||
15 | /* these info are used in ReplUnitTable */ | ||
16 | #define BLOCK_NIL 0xffff /* last block of a chain */ | ||
17 | #define BLOCK_FREE 0xfffe /* free block */ | ||
18 | #define BLOCK_NOTEXPLORED 0xfffd /* non explored block, only used during mounting */ | ||
19 | #define BLOCK_RESERVED 0xfffc /* bios block or bad block */ | ||
20 | |||
21 | struct NFTLrecord { | ||
22 | struct mtd_blktrans_dev mbd; | ||
23 | __u16 MediaUnit, SpareMediaUnit; | ||
24 | __u32 EraseSize; | ||
25 | struct NFTLMediaHeader MediaHdr; | ||
26 | int usecount; | ||
27 | unsigned char heads; | ||
28 | unsigned char sectors; | ||
29 | unsigned short cylinders; | ||
30 | __u16 numvunits; | ||
31 | __u16 lastEUN; /* should be suppressed */ | ||
32 | __u16 numfreeEUNs; | ||
33 | __u16 LastFreeEUN; /* To speed up finding a free EUN */ | ||
34 | int head,sect,cyl; | ||
35 | __u16 *EUNtable; /* [numvunits]: First EUN for each virtual unit */ | ||
36 | __u16 *ReplUnitTable; /* [numEUNs]: ReplUnitNumber for each */ | ||
37 | unsigned int nb_blocks; /* number of physical blocks */ | ||
38 | unsigned int nb_boot_blocks; /* number of blocks used by the bios */ | ||
39 | struct erase_info instr; | ||
40 | struct nand_oobinfo oobinfo; | ||
41 | }; | ||
42 | |||
43 | int NFTL_mount(struct NFTLrecord *s); | ||
44 | int NFTL_formatblock(struct NFTLrecord *s, int block); | ||
45 | |||
46 | #ifndef NFTL_MAJOR | ||
47 | #define NFTL_MAJOR 93 | ||
48 | #endif | ||
49 | |||
50 | #define MAX_NFTLS 16 | ||
51 | #define MAX_SECTORS_PER_UNIT 64 | ||
52 | #define NFTL_PARTN_BITS 4 | ||
53 | |||
54 | #endif /* __MTD_NFTL_H__ */ | ||
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h new file mode 100644 index 000000000000..50b2edfc8f11 --- /dev/null +++ b/include/linux/mtd/partitions.h | |||
@@ -0,0 +1,75 @@ | |||
1 | /* | ||
2 | * MTD partitioning layer definitions | ||
3 | * | ||
4 | * (C) 2000 Nicolas Pitre <nico@cam.org> | ||
5 | * | ||
6 | * This code is GPL | ||
7 | * | ||
8 | * $Id: partitions.h,v 1.16 2004/11/16 18:34:40 dwmw2 Exp $ | ||
9 | */ | ||
10 | |||
11 | #ifndef MTD_PARTITIONS_H | ||
12 | #define MTD_PARTITIONS_H | ||
13 | |||
14 | #include <linux/types.h> | ||
15 | |||
16 | |||
17 | /* | ||
18 | * Partition definition structure: | ||
19 | * | ||
20 | * An array of struct partition is passed along with a MTD object to | ||
21 | * add_mtd_partitions() to create them. | ||
22 | * | ||
23 | * For each partition, these fields are available: | ||
24 | * name: string that will be used to label the partition's MTD device. | ||
25 | * size: the partition size; if defined as MTDPART_SIZ_FULL, the partition | ||
26 | * will extend to the end of the master MTD device. | ||
27 | * offset: absolute starting position within the master MTD device; if | ||
28 | * defined as MTDPART_OFS_APPEND, the partition will start where the | ||
29 | * previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block. | ||
30 | * mask_flags: contains flags that have to be masked (removed) from the | ||
31 | * master MTD flag set for the corresponding MTD partition. | ||
32 | * For example, to force a read-only partition, simply adding | ||
33 | * MTD_WRITEABLE to the mask_flags will do the trick. | ||
34 | * | ||
35 | * Note: writeable partitions require their size and offset be | ||
36 | * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK). | ||
37 | */ | ||
38 | |||
39 | struct mtd_partition { | ||
40 | char *name; /* identifier string */ | ||
41 | u_int32_t size; /* partition size */ | ||
42 | u_int32_t offset; /* offset within the master MTD space */ | ||
43 | u_int32_t mask_flags; /* master MTD flags to mask out for this partition */ | ||
44 | struct nand_oobinfo *oobsel; /* out of band layout for this partition (NAND only)*/ | ||
45 | struct mtd_info **mtdp; /* pointer to store the MTD object */ | ||
46 | }; | ||
47 | |||
48 | #define MTDPART_OFS_NXTBLK (-2) | ||
49 | #define MTDPART_OFS_APPEND (-1) | ||
50 | #define MTDPART_SIZ_FULL (0) | ||
51 | |||
52 | |||
53 | int add_mtd_partitions(struct mtd_info *, const struct mtd_partition *, int); | ||
54 | int del_mtd_partitions(struct mtd_info *); | ||
55 | |||
56 | /* | ||
57 | * Functions dealing with the various ways of partitioning the space | ||
58 | */ | ||
59 | |||
60 | struct mtd_part_parser { | ||
61 | struct list_head list; | ||
62 | struct module *owner; | ||
63 | const char *name; | ||
64 | int (*parse_fn)(struct mtd_info *, struct mtd_partition **, unsigned long); | ||
65 | }; | ||
66 | |||
67 | extern int register_mtd_parser(struct mtd_part_parser *parser); | ||
68 | extern int deregister_mtd_parser(struct mtd_part_parser *parser); | ||
69 | extern int parse_mtd_partitions(struct mtd_info *master, const char **types, | ||
70 | struct mtd_partition **pparts, unsigned long origin); | ||
71 | |||
72 | #define put_partition_parser(p) do { module_put((p)->owner); } while(0) | ||
73 | |||
74 | #endif | ||
75 | |||
diff --git a/include/linux/mtd/physmap.h b/include/linux/mtd/physmap.h new file mode 100644 index 000000000000..05aa4970677f --- /dev/null +++ b/include/linux/mtd/physmap.h | |||
@@ -0,0 +1,61 @@ | |||
1 | /* | ||
2 | * For boards with physically mapped flash and using | ||
3 | * drivers/mtd/maps/physmap.c mapping driver. | ||
4 | * | ||
5 | * $Id: physmap.h,v 1.3 2004/07/21 00:16:15 jwboyer Exp $ | ||
6 | * | ||
7 | * Copyright (C) 2003 MontaVista Software Inc. | ||
8 | * Author: Jun Sun, jsun@mvista.com or jsun@junsun.net | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #ifndef __LINUX_MTD_PHYSMAP__ | ||
18 | |||
19 | #include <linux/config.h> | ||
20 | |||
21 | #if defined(CONFIG_MTD_PHYSMAP) | ||
22 | |||
23 | #include <linux/mtd/mtd.h> | ||
24 | #include <linux/mtd/map.h> | ||
25 | #include <linux/mtd/partitions.h> | ||
26 | |||
27 | /* | ||
28 | * The map_info for physmap. Board can override size, buswidth, phys, | ||
29 | * (*set_vpp)(), etc in their initial setup routine. | ||
30 | */ | ||
31 | extern struct map_info physmap_map; | ||
32 | |||
33 | /* | ||
34 | * Board needs to specify the exact mapping during their setup time. | ||
35 | */ | ||
36 | static inline void physmap_configure(unsigned long addr, unsigned long size, int bankwidth, void (*set_vpp)(struct map_info *, int) ) | ||
37 | { | ||
38 | physmap_map.phys = addr; | ||
39 | physmap_map.size = size; | ||
40 | physmap_map.bankwidth = bankwidth; | ||
41 | physmap_map.set_vpp = set_vpp; | ||
42 | } | ||
43 | |||
44 | #if defined(CONFIG_MTD_PARTITIONS) | ||
45 | |||
46 | /* | ||
47 | * Machines that wish to do flash partition may want to call this function in | ||
48 | * their setup routine. | ||
49 | * | ||
50 | * physmap_set_partitions(mypartitions, num_parts); | ||
51 | * | ||
52 | * Note that one can always override this hard-coded partition with | ||
53 | * command line partition (you need to enable CONFIG_MTD_CMDLINE_PARTS). | ||
54 | */ | ||
55 | void physmap_set_partitions(struct mtd_partition *parts, int num_parts); | ||
56 | |||
57 | #endif /* defined(CONFIG_MTD_PARTITIONS) */ | ||
58 | #endif /* defined(CONFIG_MTD) */ | ||
59 | |||
60 | #endif /* __LINUX_MTD_PHYSMAP__ */ | ||
61 | |||
diff --git a/include/linux/mtd/pmc551.h b/include/linux/mtd/pmc551.h new file mode 100644 index 000000000000..113e3087f68a --- /dev/null +++ b/include/linux/mtd/pmc551.h | |||
@@ -0,0 +1,79 @@ | |||
1 | /* | ||
2 | * $Id: pmc551.h,v 1.5 2003/01/24 16:49:53 dwmw2 Exp $ | ||
3 | * | ||
4 | * PMC551 PCI Mezzanine Ram Device | ||
5 | * | ||
6 | * Author: | ||
7 | * Mark Ferrell | ||
8 | * Copyright 1999,2000 Nortel Networks | ||
9 | * | ||
10 | * License: | ||
11 | * As part of this driver was derrived from the slram.c driver it falls | ||
12 | * under the same license, which is GNU General Public License v2 | ||
13 | */ | ||
14 | |||
15 | #ifndef __MTD_PMC551_H__ | ||
16 | #define __MTD_PMC551_H__ | ||
17 | |||
18 | #include <linux/mtd/mtd.h> | ||
19 | |||
20 | #define PMC551_VERSION "$Id: pmc551.h,v 1.5 2003/01/24 16:49:53 dwmw2 Exp $\n"\ | ||
21 | "Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n" | ||
22 | |||
23 | /* | ||
24 | * Our personal and private information | ||
25 | */ | ||
26 | struct mypriv { | ||
27 | struct pci_dev *dev; | ||
28 | u_char *start; | ||
29 | u32 base_map0; | ||
30 | u32 curr_map0; | ||
31 | u32 asize; | ||
32 | struct mtd_info *nextpmc551; | ||
33 | }; | ||
34 | |||
35 | /* | ||
36 | * Function Prototypes | ||
37 | */ | ||
38 | static int pmc551_erase(struct mtd_info *, struct erase_info *); | ||
39 | static void pmc551_unpoint(struct mtd_info *, u_char *, loff_t, size_t); | ||
40 | static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); | ||
41 | static int pmc551_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *); | ||
42 | static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *); | ||
43 | |||
44 | |||
45 | /* | ||
46 | * Define the PCI ID's if the kernel doesn't define them for us | ||
47 | */ | ||
48 | #ifndef PCI_VENDOR_ID_V3_SEMI | ||
49 | #define PCI_VENDOR_ID_V3_SEMI 0x11b0 | ||
50 | #endif | ||
51 | |||
52 | #ifndef PCI_DEVICE_ID_V3_SEMI_V370PDC | ||
53 | #define PCI_DEVICE_ID_V3_SEMI_V370PDC 0x0200 | ||
54 | #endif | ||
55 | |||
56 | |||
57 | #define PMC551_PCI_MEM_MAP0 0x50 | ||
58 | #define PMC551_PCI_MEM_MAP1 0x54 | ||
59 | #define PMC551_PCI_MEM_MAP_MAP_ADDR_MASK 0x3ff00000 | ||
60 | #define PMC551_PCI_MEM_MAP_APERTURE_MASK 0x000000f0 | ||
61 | #define PMC551_PCI_MEM_MAP_REG_EN 0x00000002 | ||
62 | #define PMC551_PCI_MEM_MAP_ENABLE 0x00000001 | ||
63 | |||
64 | #define PMC551_SDRAM_MA 0x60 | ||
65 | #define PMC551_SDRAM_CMD 0x62 | ||
66 | #define PMC551_DRAM_CFG 0x64 | ||
67 | #define PMC551_SYS_CTRL_REG 0x78 | ||
68 | |||
69 | #define PMC551_DRAM_BLK0 0x68 | ||
70 | #define PMC551_DRAM_BLK1 0x6c | ||
71 | #define PMC551_DRAM_BLK2 0x70 | ||
72 | #define PMC551_DRAM_BLK3 0x74 | ||
73 | #define PMC551_DRAM_BLK_GET_SIZE(x) (524288<<((x>>4)&0x0f)) | ||
74 | #define PMC551_DRAM_BLK_SET_COL_MUX(x,v) (((x) & ~0x00007000) | (((v) & 0x7) << 12)) | ||
75 | #define PMC551_DRAM_BLK_SET_ROW_MUX(x,v) (((x) & ~0x00000f00) | (((v) & 0xf) << 8)) | ||
76 | |||
77 | |||
78 | #endif /* __MTD_PMC551_H__ */ | ||
79 | |||
diff --git a/include/linux/mtd/xip.h b/include/linux/mtd/xip.h new file mode 100644 index 000000000000..fc071125cbcc --- /dev/null +++ b/include/linux/mtd/xip.h | |||
@@ -0,0 +1,107 @@ | |||
1 | /* | ||
2 | * MTD primitives for XIP support | ||
3 | * | ||
4 | * Author: Nicolas Pitre | ||
5 | * Created: Nov 2, 2004 | ||
6 | * Copyright: (C) 2004 MontaVista Software, Inc. | ||
7 | * | ||
8 | * This XIP support for MTD has been loosely inspired | ||
9 | * by an earlier patch authored by David Woodhouse. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | * | ||
15 | * $Id: xip.h,v 1.2 2004/12/01 15:49:10 nico Exp $ | ||
16 | */ | ||
17 | |||
18 | #ifndef __LINUX_MTD_XIP_H__ | ||
19 | #define __LINUX_MTD_XIP_H__ | ||
20 | |||
21 | #include <linux/config.h> | ||
22 | |||
23 | #ifdef CONFIG_MTD_XIP | ||
24 | |||
25 | /* | ||
26 | * Function that are modifying the flash state away from array mode must | ||
27 | * obviously not be running from flash. The __xipram is therefore marking | ||
28 | * those functions so they get relocated to ram. | ||
29 | */ | ||
30 | #define __xipram __attribute__ ((__section__ (".data"))) | ||
31 | |||
32 | /* | ||
33 | * We really don't want gcc to guess anything. | ||
34 | * We absolutely _need_ proper inlining. | ||
35 | */ | ||
36 | #include <linux/compiler.h> | ||
37 | |||
38 | /* | ||
39 | * Each architecture has to provide the following macros. They must access | ||
40 | * the hardware directly and not rely on any other (XIP) functions since they | ||
41 | * won't be available when used (flash not in array mode). | ||
42 | * | ||
43 | * xip_irqpending() | ||
44 | * | ||
45 | * return non zero when any hardware interrupt is pending. | ||
46 | * | ||
47 | * xip_currtime() | ||
48 | * | ||
49 | * return a platform specific time reference to be used with | ||
50 | * xip_elapsed_since(). | ||
51 | * | ||
52 | * xip_elapsed_since(x) | ||
53 | * | ||
54 | * return in usecs the elapsed timebetween now and the reference x as | ||
55 | * returned by xip_currtime(). | ||
56 | * | ||
57 | * note 1: convertion to usec can be approximated, as long as the | ||
58 | * returned value is <= the real elapsed time. | ||
59 | * note 2: this should be able to cope with a few seconds without | ||
60 | * overflowing. | ||
61 | */ | ||
62 | |||
63 | #if defined(CONFIG_ARCH_SA1100) || defined(CONFIG_ARCH_PXA) | ||
64 | |||
65 | #include <asm/hardware.h> | ||
66 | #ifdef CONFIG_ARCH_PXA | ||
67 | #include <asm/arch/pxa-regs.h> | ||
68 | #endif | ||
69 | |||
70 | #define xip_irqpending() (ICIP & ICMR) | ||
71 | |||
72 | /* we sample OSCR and convert desired delta to usec (1/4 ~= 1000000/3686400) */ | ||
73 | #define xip_currtime() (OSCR) | ||
74 | #define xip_elapsed_since(x) (signed)((OSCR - (x)) / 4) | ||
75 | |||
76 | #else | ||
77 | |||
78 | #warning "missing IRQ and timer primitives for XIP MTD support" | ||
79 | #warning "some of the XIP MTD support code will be disabled" | ||
80 | #warning "your system will therefore be unresponsive when writing or erasing flash" | ||
81 | |||
82 | #define xip_irqpending() (0) | ||
83 | #define xip_currtime() (0) | ||
84 | #define xip_elapsed_since(x) (0) | ||
85 | |||
86 | #endif | ||
87 | |||
88 | /* | ||
89 | * xip_cpu_idle() is used when waiting for a delay equal or larger than | ||
90 | * the system timer tick period. This should put the CPU into idle mode | ||
91 | * to save power and to be woken up only when some interrupts are pending. | ||
92 | * As above, this should not rely upon standard kernel code. | ||
93 | */ | ||
94 | |||
95 | #if defined(CONFIG_CPU_XSCALE) | ||
96 | #define xip_cpu_idle() asm volatile ("mcr p14, 0, %0, c7, c0, 0" :: "r" (1)) | ||
97 | #else | ||
98 | #define xip_cpu_idle() do { } while (0) | ||
99 | #endif | ||
100 | |||
101 | #else | ||
102 | |||
103 | #define __xipram | ||
104 | |||
105 | #endif /* CONFIG_MTD_XIP */ | ||
106 | |||
107 | #endif /* __LINUX_MTD_XIP_H__ */ | ||