summaryrefslogtreecommitdiff
path: root/include/linux
diff options
context:
space:
mode:
authorDavid Woodhouse <dwmw2@infradead.org>2003-05-28 18:03:33 +0100
committerDavid Woodhouse <dwmw2@infradead.org>2003-05-28 18:03:33 +0100
commit5af017c0de780cb463b784ef909406ce397332ee (patch)
treeecfae73f9c51082ebe4cbe6d228adcba21ca524d /include/linux
parent015498d534572f8a9c3bf5f1dfc02bd02bfb2c9d (diff)
MTD and JFFS2 update.
- JFFS2 bugfixes and performance improvements - Support for 64-bit flash arrangements - Optimise for linear mappings of flash, without out-of-line access functions - New map drivers - Updated NAND flash support, new board drivers - Support for DiskOnChip Millennium Plus and INFTL translation layer - Clean up all translation layers with a single blkdev helper library. - Fix races in MTD device registration/deregistration - Add support for new flash chips - Clean up partition parsing code More detailed comments in per-file changelogs.
Diffstat (limited to 'include/linux')
-rw-r--r--include/linux/jffs2.h25
-rw-r--r--include/linux/jffs2_fs_sb.h5
-rw-r--r--include/linux/mtd/blktrans.h75
-rw-r--r--include/linux/mtd/cfi.h143
-rw-r--r--include/linux/mtd/cfi_endian.h8
-rw-r--r--include/linux/mtd/compatmac.h199
-rw-r--r--include/linux/mtd/doc2000.h48
-rw-r--r--include/linux/mtd/flashchip.h8
-rw-r--r--include/linux/mtd/inftl.h129
-rw-r--r--include/linux/mtd/jedec.h3
-rw-r--r--include/linux/mtd/map.h137
-rw-r--r--include/linux/mtd/mtd.h71
-rw-r--r--include/linux/mtd/nand.h156
-rw-r--r--include/linux/mtd/nand_ecc.h4
-rw-r--r--include/linux/mtd/nand_ids.h52
-rw-r--r--include/linux/mtd/nftl.h20
-rw-r--r--include/linux/mtd/partitions.h34
-rw-r--r--include/linux/mtd/pmc551.h6
18 files changed, 728 insertions, 395 deletions
diff --git a/include/linux/jffs2.h b/include/linux/jffs2.h
index 958cab16d8a7..2e9a2c8e4fdd 100644
--- a/include/linux/jffs2.h
+++ b/include/linux/jffs2.h
@@ -8,19 +8,23 @@
* For licensing information, see the file 'LICENCE' in the
* jffs2 directory.
*
- * $Id: jffs2.h,v 1.25 2002/08/20 21:37:27 dwmw2 Exp $
+ * $Id: jffs2.h,v 1.30 2003/02/15 00:15:22 dwmw2 Exp $
*
*/
#ifndef __LINUX_JFFS2_H__
#define __LINUX_JFFS2_H__
+/* You must include something which defines the C99 uintXX_t types.
+ We don't do it from here because this file is used in too many
+ different environments. */
+
#define JFFS2_SUPER_MAGIC 0x72b6
/* Values we may expect to find in the 'magic' field */
#define JFFS2_OLD_MAGIC_BITMASK 0x1984
#define JFFS2_MAGIC_BITMASK 0x1985
-#define KSAMTIB_CIGAM_2SFFJ 0x5981 /* For detecting wrong-endian fs */
+#define KSAMTIB_CIGAM_2SFFJ 0x8519 /* For detecting wrong-endian fs */
#define JFFS2_EMPTY_BITMASK 0xffff
#define JFFS2_DIRTY_BITMASK 0x0000
@@ -76,29 +80,42 @@ typedef struct {
} __attribute__((packed)) jint32_t;
typedef struct {
+ uint32_t m;
+} __attribute__((packed)) jmode_t;
+
+typedef struct {
uint16_t v16;
} __attribute__((packed)) jint16_t;
#define JFFS2_NATIVE_ENDIAN
+/* Note we handle mode bits conversion from JFFS2 (i.e. Linux) to/from
+ whatever OS we're actually running on here too. */
+
#if defined(JFFS2_NATIVE_ENDIAN)
#define cpu_to_je16(x) ((jint16_t){x})
#define cpu_to_je32(x) ((jint32_t){x})
+#define cpu_to_jemode(x) ((jmode_t){os_to_jffs2_mode(x)})
#define je16_to_cpu(x) ((x).v16)
#define je32_to_cpu(x) ((x).v32)
+#define jemode_to_cpu(x) (jffs2_to_os_mode((x).m))
#elif defined(JFFS2_BIG_ENDIAN)
#define cpu_to_je16(x) ((jint16_t){cpu_to_be16(x)})
#define cpu_to_je32(x) ((jint32_t){cpu_to_be32(x)})
+#define cpu_to_jemode(x) ((jmode_t){cpu_to_be32(os_to_jffs2_mode(x))})
#define je16_to_cpu(x) (be16_to_cpu(x.v16))
#define je32_to_cpu(x) (be32_to_cpu(x.v32))
+#define jemode_to_cpu(x) (be32_to_cpu(jffs2_to_os_mode((x).m)))
#elif defined(JFFS2_LITTLE_ENDIAN)
#define cpu_to_je16(x) ((jint16_t){cpu_to_le16(x)})
#define cpu_to_je32(x) ((jint32_t){cpu_to_le32(x)})
+#define cpu_to_jemode(x) ((jmode_t){cpu_to_le32(os_to_jffs2_mode(x))})
#define je16_to_cpu(x) (le16_to_cpu(x.v16))
#define je32_to_cpu(x) (le32_to_cpu(x.v32))
+#define jemode_to_cpu(x) (le32_to_cpu(jffs2_to_os_mode((x).m)))
#else
#error wibble
#endif
@@ -144,7 +161,7 @@ struct jffs2_raw_inode
jint32_t hdr_crc;
jint32_t ino; /* Inode number. */
jint32_t version; /* Version number. */
- jint32_t mode; /* The file's type or mode. */
+ jmode_t mode; /* The file's type or mode. */
jint16_t uid; /* The file's owner. */
jint16_t gid; /* The file's group. */
jint32_t isize; /* Total resultant size of this inode (used for truncations) */
@@ -159,7 +176,7 @@ struct jffs2_raw_inode
jint16_t flags; /* See JFFS2_INO_FLAG_* */
jint32_t data_crc; /* CRC for the (compressed) data. */
jint32_t node_crc; /* CRC for the raw inode (excluding data) */
-// uint8_t data[dsize];
+ uint8_t data[0];
} __attribute__((packed));
union jffs2_node_union {
diff --git a/include/linux/jffs2_fs_sb.h b/include/linux/jffs2_fs_sb.h
index 7cfabbd614cb..246ff237325c 100644
--- a/include/linux/jffs2_fs_sb.h
+++ b/include/linux/jffs2_fs_sb.h
@@ -1,4 +1,4 @@
-/* $Id: jffs2_fs_sb.h,v 1.35 2002/11/12 09:42:18 dwmw2 Exp $ */
+/* $Id: jffs2_fs_sb.h,v 1.37 2003/01/17 16:04:44 dwmw2 Exp $ */
#ifndef _JFFS2_FS_SB
#define _JFFS2_FS_SB
@@ -8,6 +8,8 @@
#include <linux/workqueue.h>
#include <linux/completion.h>
#include <asm/semaphore.h>
+#include <linux/timer.h>
+#include <linux/wait.h>
#include <linux/list.h>
#define JFFS2_SB_FLAG_RO 1
@@ -73,6 +75,7 @@ struct jffs2_sb_info {
against erase completion handler */
wait_queue_head_t erase_wait; /* For waiting for erases to complete */
+ wait_queue_head_t inocache_wq;
struct jffs2_inode_cache **inocache_list;
spinlock_t inocache_lock;
diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h
new file mode 100644
index 000000000000..ab9639b36e25
--- /dev/null
+++ b/include/linux/mtd/blktrans.h
@@ -0,0 +1,75 @@
+/*
+ * $Id: blktrans.h,v 1.4 2003/05/21 01:01:32 dwmw2 Exp $
+ *
+ * (C) 2003 David Woodhouse <dwmw2@infradead.org>
+ *
+ * Interface to Linux block layer for MTD 'translation layers'.
+ *
+ */
+
+#ifndef __MTD_TRANS_H__
+#define __MTD_TRANS_H__
+
+#include <asm/semaphore.h>
+
+struct mtd_info;
+struct mtd_blktrans_ops;
+struct file;
+struct inode;
+
+struct mtd_blktrans_dev {
+ struct mtd_blktrans_ops *tr;
+ struct list_head list;
+ struct mtd_info *mtd;
+ struct semaphore sem;
+ int devnum;
+ int blksize;
+ unsigned long size;
+ int readonly;
+ void *blkcore_priv; /* gendisk in 2.5, devfs_handle in 2.4 */
+};
+
+struct blkcore_priv; /* Differs for 2.4 and 2.5 kernels; private */
+
+struct mtd_blktrans_ops {
+ char *name;
+ int major;
+ int part_bits;
+
+ /* Access functions */
+ int (*readsect)(struct mtd_blktrans_dev *dev,
+ unsigned long block, char *buffer);
+ int (*writesect)(struct mtd_blktrans_dev *dev,
+ unsigned long block, char *buffer);
+
+ /* HDIO_GETGEO and HDIO_GETGEO_BIG are the only non-private
+ ioctls which are expected to be passed through */
+ int (*ioctl)(struct mtd_blktrans_dev *dev,
+ struct inode * inode, struct file * file,
+ unsigned int cmd, unsigned long arg);
+
+ /* Called with mtd_table_mutex held; no race with add/remove */
+ int (*open)(struct mtd_blktrans_dev *dev,
+ struct inode *i, struct file *f);
+ int (*release)(struct mtd_blktrans_dev *dev,
+ struct inode *i, struct file *f);
+
+ /* Called on {de,}registration and on subsequent addition/removal
+ of devices, with mtd_table_mutex held. */
+ void (*add_mtd)(struct mtd_blktrans_ops *tr, struct mtd_info *mtd);
+ void (*remove_dev)(struct mtd_blktrans_dev *dev);
+
+ struct list_head devs;
+ struct list_head list;
+ struct module *owner;
+
+ struct mtd_blkcore_priv *blkcore_priv;
+};
+
+extern int register_mtd_blktrans(struct mtd_blktrans_ops *tr);
+extern int deregister_mtd_blktrans(struct mtd_blktrans_ops *tr);
+extern int add_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
+extern int del_mtd_blktrans_dev(struct mtd_blktrans_dev *dev);
+
+
+#endif /* __MTD_TRANS_H__ */
diff --git a/include/linux/mtd/cfi.h b/include/linux/mtd/cfi.h
index 0ad3d186597d..c72e6c789b82 100644
--- a/include/linux/mtd/cfi.h
+++ b/include/linux/mtd/cfi.h
@@ -1,7 +1,7 @@
/* Common Flash Interface structures
* See http://support.intel.com/design/flash/technote/index.htm
- * $Id: cfi.h,v 1.25 2001/09/04 07:06:21 dwmw2 Exp $
+ * $Id: cfi.h,v 1.34 2003/05/16 18:55:44 dwmw2 Exp $
*/
#ifndef __MTD_CFI_H__
@@ -18,13 +18,16 @@
* You can optimize the code size and performance by defining only
* the geometry(ies) available on your hardware.
* CFIDEV_INTERLEAVE_n, where represents the interleave (number of chips to fill the bus width)
- * CFIDEV_BUSWIDTH_n, where n is the bus width in bytes (1, 2 or 4 bytes)
+ * CFIDEV_BUSWIDTH_n, where n is the bus width in bytes (1, 2, 4 or 8 bytes)
*
* By default, all (known) geometries are supported.
*/
#ifndef CONFIG_MTD_CFI_GEOMETRY
+/* The default case - support all but 64-bit, which has
+ a performance penalty */
+
#define CFIDEV_INTERLEAVE_1 (1)
#define CFIDEV_INTERLEAVE_2 (2)
#define CFIDEV_INTERLEAVE_4 (4)
@@ -33,8 +36,12 @@
#define CFIDEV_BUSWIDTH_2 (2)
#define CFIDEV_BUSWIDTH_4 (4)
+typedef __u32 cfi_word;
+
#else
+/* Explicitly configured buswidth/interleave support */
+
#ifdef CONFIG_MTD_CFI_I1
#define CFIDEV_INTERLEAVE_1 (1)
#endif
@@ -44,6 +51,9 @@
#ifdef CONFIG_MTD_CFI_I4
#define CFIDEV_INTERLEAVE_4 (4)
#endif
+#ifdef CONFIG_MTD_CFI_I8
+#define CFIDEV_INTERLEAVE_8 (8)
+#endif
#ifdef CONFIG_MTD_CFI_B1
#define CFIDEV_BUSWIDTH_1 (1)
@@ -54,6 +64,27 @@
#ifdef CONFIG_MTD_CFI_B4
#define CFIDEV_BUSWIDTH_4 (4)
#endif
+#ifdef CONFIG_MTD_CFI_B8
+#define CFIDEV_BUSWIDTH_8 (8)
+#endif
+
+/* pick the largest necessary */
+#ifdef CONFIG_MTD_CFI_B8
+typedef __u64 cfi_word;
+
+/* This only works if asm/io.h is included first */
+#ifndef __raw_readll
+#define __raw_readll(addr) (*(volatile __u64 *)(addr))
+#endif
+#ifndef __raw_writell
+#define __raw_writell(v, addr) (*(volatile __u64 *)(addr) = (v))
+#endif
+#define CFI_WORD_64
+#else /* CONFIG_MTD_CFI_B8 */
+/* All others can use 32-bits. It's probably more efficient than
+ the smaller types anyway */
+typedef __u32 cfi_word;
+#endif /* CONFIG_MTD_CFI_B8 */
#endif
@@ -61,12 +92,15 @@
* The following macros are used to select the code to execute:
* cfi_buswidth_is_*()
* cfi_interleave_is_*()
- * [where * is either 1, 2 or 4]
+ * [where * is either 1, 2, 4, or 8]
* Those macros should be used with 'if' statements. If only one of few
* geometry arrangements are selected, they expand to constants thus allowing
* the compiler (most of them being 0) to optimize away all the unneeded code,
* while still validating the syntax (which is not possible with embedded
* #if ... #endif constructs).
+ * The exception to this is the 64-bit versions, which need an extension
+ * to the cfi_word type, and cause compiler warnings about shifts being
+ * out of range.
*/
#ifdef CFIDEV_INTERLEAVE_1
@@ -105,6 +139,18 @@
# define cfi_interleave_is_4() (0)
#endif
+#ifdef CFIDEV_INTERLEAVE_8
+# ifdef CFIDEV_INTERLEAVE
+# undef CFIDEV_INTERLEAVE
+# define CFIDEV_INTERLEAVE (cfi->interleave)
+# else
+# define CFIDEV_INTERLEAVE CFIDEV_INTERLEAVE_8
+# endif
+# define cfi_interleave_is_8() (CFIDEV_INTERLEAVE == CFIDEV_INTERLEAVE_8)
+#else
+# define cfi_interleave_is_8() (0)
+#endif
+
#ifndef CFIDEV_INTERLEAVE
#error You must define at least one interleave to support!
#endif
@@ -145,6 +191,18 @@
# define cfi_buswidth_is_4() (0)
#endif
+#ifdef CFIDEV_BUSWIDTH_8
+# ifdef CFIDEV_BUSWIDTH
+# undef CFIDEV_BUSWIDTH
+# define CFIDEV_BUSWIDTH (map->buswidth)
+# else
+# define CFIDEV_BUSWIDTH CFIDEV_BUSWIDTH_8
+# endif
+# define cfi_buswidth_is_8() (CFIDEV_BUSWIDTH == CFIDEV_BUSWIDTH_8)
+#else
+# define cfi_buswidth_is_8() (0)
+#endif
+
#ifndef CFIDEV_BUSWIDTH
#error You must define at least one bus width to support!
#endif
@@ -156,6 +214,7 @@
#define CFI_DEVICETYPE_X8 (8 / 8)
#define CFI_DEVICETYPE_X16 (16 / 8)
#define CFI_DEVICETYPE_X32 (32 / 8)
+#define CFI_DEVICETYPE_X64 (64 / 8)
/* NB: We keep these structures in memory in HOST byteorder, except
* where individually noted.
@@ -206,6 +265,10 @@ struct cfi_pri_intelext {
__u16 BlkStatusRegMask;
__u8 VccOptimal;
__u8 VppOptimal;
+ __u8 NumProtectionFields;
+ __u16 ProtRegAddr;
+ __u8 FactProtRegSize;
+ __u8 UserProtRegSize;
} __attribute__((packed));
struct cfi_pri_query {
@@ -229,8 +292,8 @@ struct cfi_bri_query {
#define P_ID_RESERVED 65535
-#define CFI_MODE_CFI 0
-#define CFI_MODE_JEDEC 1
+#define CFI_MODE_CFI 1
+#define CFI_MODE_JEDEC 0
struct cfi_private {
__u16 cmdset;
@@ -264,9 +327,9 @@ static inline __u32 cfi_build_cmd_addr(__u32 cmd_ofs, int interleave, int type)
/*
* Transforms the CFI command for the given geometry (bus width & interleave.
*/
-static inline __u32 cfi_build_cmd(u_char cmd, struct map_info *map, struct cfi_private *cfi)
+static inline cfi_word cfi_build_cmd(u_char cmd, struct map_info *map, struct cfi_private *cfi)
{
- __u32 val = 0;
+ cfi_word val = 0;
if (cfi_buswidth_is_1()) {
/* 1 x8 device */
@@ -291,6 +354,27 @@ static inline __u32 cfi_build_cmd(u_char cmd, struct map_info *map, struct cfi_p
val = (cmd << 16) | cmd;
val = cpu_to_cfi32((val << 8) | val);
}
+#ifdef CFI_WORD_64
+ } else if (cfi_buswidth_is_8()) {
+ if (cfi_interleave_is_1()) {
+ /* 1 x64 device in x64 mode */
+ val = cpu_to_cfi64(cmd);
+ } else if (cfi_interleave_is_2()) {
+ /* 2 x32 device in x32 mode */
+ val = cmd;
+ val = cpu_to_cfi64((val << 32) | val);
+ } else if (cfi_interleave_is_4()) {
+ /* 4 (x16, x32 or x64) devices in x16 mode */
+ val = (cmd << 16) | cmd;
+ val = cpu_to_cfi64((val << 32) | val);
+ } else if (cfi_interleave_is_8()) {
+ /* 8 (x8, x16 or x32) devices in x8 mode */
+ val = (cmd << 8) | cmd;
+ val = (val << 16) | val;
+ val = (val << 32) | val;
+ val = cpu_to_cfi64(val);
+ }
+#endif /* CFI_WORD_64 */
}
return val;
}
@@ -300,14 +384,16 @@ static inline __u32 cfi_build_cmd(u_char cmd, struct map_info *map, struct cfi_p
* Read a value according to the bus width.
*/
-static inline __u32 cfi_read(struct map_info *map, __u32 addr)
+static inline cfi_word cfi_read(struct map_info *map, __u32 addr)
{
if (cfi_buswidth_is_1()) {
- return map->read8(map, addr);
+ return map_read8(map, addr);
} else if (cfi_buswidth_is_2()) {
- return map->read16(map, addr);
+ return map_read16(map, addr);
} else if (cfi_buswidth_is_4()) {
- return map->read32(map, addr);
+ return map_read32(map, addr);
+ } else if (cfi_buswidth_is_8()) {
+ return map_read64(map, addr);
} else {
return 0;
}
@@ -317,14 +403,16 @@ static inline __u32 cfi_read(struct map_info *map, __u32 addr)
* Write a value according to the bus width.
*/
-static inline void cfi_write(struct map_info *map, __u32 val, __u32 addr)
+static inline void cfi_write(struct map_info *map, cfi_word val, __u32 addr)
{
if (cfi_buswidth_is_1()) {
- map->write8(map, val, addr);
+ map_write8(map, val, addr);
} else if (cfi_buswidth_is_2()) {
- map->write16(map, val, addr);
+ map_write16(map, val, addr);
} else if (cfi_buswidth_is_4()) {
- map->write32(map, val, addr);
+ map_write32(map, val, addr);
+ } else if (cfi_buswidth_is_8()) {
+ map_write64(map, val, addr);
}
}
@@ -337,9 +425,9 @@ static inline void cfi_write(struct map_info *map, __u32 val, __u32 addr)
*/
static inline __u32 cfi_send_gen_cmd(u_char cmd, __u32 cmd_addr, __u32 base,
struct map_info *map, struct cfi_private *cfi,
- int type, __u32 *prev_val)
+ int type, cfi_word *prev_val)
{
- __u32 val;
+ cfi_word val;
__u32 addr = base + cfi_build_cmd_addr(cmd_addr, CFIDEV_INTERLEAVE, type);
val = cfi_build_cmd(cmd, map, cfi);
@@ -355,11 +443,13 @@ static inline __u32 cfi_send_gen_cmd(u_char cmd, __u32 cmd_addr, __u32 base,
static inline __u8 cfi_read_query(struct map_info *map, __u32 addr)
{
if (cfi_buswidth_is_1()) {
- return map->read8(map, addr);
+ return map_read8(map, addr);
} else if (cfi_buswidth_is_2()) {
- return cfi16_to_cpu(map->read16(map, addr));
+ return cfi16_to_cpu(map_read16(map, addr));
} else if (cfi_buswidth_is_4()) {
- return cfi32_to_cpu(map->read32(map, addr));
+ return cfi32_to_cpu(map_read32(map, addr));
+ } else if (cfi_buswidth_is_8()) {
+ return cfi64_to_cpu(map_read64(map, addr));
} else {
return 0;
}
@@ -368,17 +458,17 @@ static inline __u8 cfi_read_query(struct map_info *map, __u32 addr)
static inline void cfi_udelay(int us)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0)
- if (need_resched()) {
- unsigned long t = us * HZ / 1000000;
- if (t < 1)
- t = 1;
+ unsigned long t = us * HZ / 1000000;
+ if (t) {
set_current_state(TASK_UNINTERRUPTIBLE);
schedule_timeout(t);
+ return;
}
- else
#endif
- udelay(us);
+ udelay(us);
+ cond_resched();
}
+
static inline void cfi_spin_lock(spinlock_t *mutex)
{
spin_lock_bh(mutex);
@@ -389,5 +479,4 @@ static inline void cfi_spin_unlock(spinlock_t *mutex)
spin_unlock_bh(mutex);
}
-
#endif /* __MTD_CFI_H__ */
diff --git a/include/linux/mtd/cfi_endian.h b/include/linux/mtd/cfi_endian.h
index 9f3b041c4092..25724f7d3867 100644
--- a/include/linux/mtd/cfi_endian.h
+++ b/include/linux/mtd/cfi_endian.h
@@ -1,5 +1,5 @@
/*
- * $Id: cfi_endian.h,v 1.10 2001/06/18 11:00:46 abz Exp $
+ * $Id: cfi_endian.h,v 1.11 2002/01/30 23:20:48 awozniak Exp $
*
*/
@@ -30,22 +30,28 @@
#define cfi8_to_cpu(x) (x)
#define cpu_to_cfi16(x) cpu_to_le16(x)
#define cpu_to_cfi32(x) cpu_to_le32(x)
+#define cpu_to_cfi64(x) cpu_to_le64(x)
#define cfi16_to_cpu(x) le16_to_cpu(x)
#define cfi32_to_cpu(x) le32_to_cpu(x)
+#define cfi64_to_cpu(x) le64_to_cpu(x)
#elif defined (CFI_BIG_ENDIAN)
#define cpu_to_cfi8(x) (x)
#define cfi8_to_cpu(x) (x)
#define cpu_to_cfi16(x) cpu_to_be16(x)
#define cpu_to_cfi32(x) cpu_to_be32(x)
+#define cpu_to_cfi64(x) cpu_to_be64(x)
#define cfi16_to_cpu(x) be16_to_cpu(x)
#define cfi32_to_cpu(x) be32_to_cpu(x)
+#define cfi64_to_cpu(x) be64_to_cpu(x)
#elif defined (CFI_HOST_ENDIAN)
#define cpu_to_cfi8(x) (x)
#define cfi8_to_cpu(x) (x)
#define cpu_to_cfi16(x) (x)
#define cpu_to_cfi32(x) (x)
+#define cpu_to_cfi64(x) (x)
#define cfi16_to_cpu(x) (x)
#define cfi32_to_cpu(x) (x)
+#define cfi64_to_cpu(x) (x)
#else
#error No CFI endianness defined
#endif
diff --git a/include/linux/mtd/compatmac.h b/include/linux/mtd/compatmac.h
index 8b243674cf22..7d1300d9bd51 100644
--- a/include/linux/mtd/compatmac.h
+++ b/include/linux/mtd/compatmac.h
@@ -1,201 +1,10 @@
-/*
- * mtd/include/compatmac.h
- *
- * $Id: compatmac.h,v 1.4 2000/07/03 10:01:38 dwmw2 Exp $
- *
- * Extensions and omissions from the normal 'linux/compatmac.h'
- * files. hopefully this will end up empty as the 'real' one
- * becomes fully-featured.
- */
-
-
-/* First, include the parts which the kernel is good enough to provide
- * to us
- */
-
#ifndef __LINUX_MTD_COMPATMAC_H__
#define __LINUX_MTD_COMPATMAC_H__
-#include <linux/types.h> /* used later in this header */
-#include <linux/module.h>
-#ifndef LINUX_VERSION_CODE
-#include <linux/version.h>
-#endif
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
-#include <linux/vmalloc.h>
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,0,0)
-# error "This kernel is too old: not supported by this file"
-#endif
-
-/* Modularization issues */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,18)
-# define __USE_OLD_SYMTAB__
-# define EXPORT_NO_SYMBOLS register_symtab(NULL);
-# define REGISTER_SYMTAB(tab) register_symtab(tab)
-#else
-# define REGISTER_SYMTAB(tab) /* nothing */
-#endif
-
-#ifdef __USE_OLD_SYMTAB__
-# define __MODULE_STRING(s) /* nothing */
-# define MODULE_PARM(v,t) /* nothing */
-# define MODULE_PARM_DESC(v,t) /* nothing */
-# define MODULE_AUTHOR(n) /* nothing */
-# define MODULE_DESCRIPTION(d) /* nothing */
-# define MODULE_SUPPORTED_DEVICE(n) /* nothing */
-#endif
-
-/*
- * "select" changed in 2.1.23. The implementation is twin, but this
- * header is new
- */
-#if LINUX_VERSION_CODE > KERNEL_VERSION(2,1,22)
-# include <linux/poll.h>
-#else
-# define __USE_OLD_SELECT__
-#endif
-
-/* Other change in the fops are solved using pseudo-types */
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0)
-# define lseek_t long long
-# define lseek_off_t long long
-#else
-# define lseek_t int
-# define lseek_off_t off_t
-#endif
-
-/* changed the prototype of read/write */
-
-#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,1,0) || defined(__alpha__)
-# define count_t unsigned long
-# define read_write_t long
-#else
-# define count_t int
-# define read_write_t int
-#endif
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,1,31)
-# define release_t void
-# define release_return(x) return
-#else
-# define release_t int
-# define release_return(x) return (x)
-#endif
-
-#if LINUX_VERSION_CODE < 0x20300
-#define __exit
-#endif
-#if LINUX_VERSION_CODE < 0x20200
-#define __init
-#else
-#include <linux/init.h>
-#endif
-
-#if LINUX_VERSION_CODE < 0x20300
-#define init_MUTEX(x) do {*(x) = MUTEX;} while (0)
-#define RQFUNC_ARG void
-#define blkdev_dequeue_request(req) do {CURRENT = req->next;} while (0)
-#else
-#define RQFUNC_ARG request_queue_t *q
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,2,0)
-#define __MOD_INC_USE_COUNT(mod) \
- (atomic_inc(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED|MOD_USED_ONCE)
-#define __MOD_DEC_USE_COUNT(mod) \
- (atomic_dec(&(mod)->uc.usecount), (mod)->flags |= MOD_VISITED)
-#endif
-
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
-
-#define DECLARE_WAIT_QUEUE_HEAD(x) struct wait_queue *x = NULL
-#define init_waitqueue_head init_waitqueue
-
-static inline int try_inc_mod_count(struct module *mod)
-{
- if (mod)
- __MOD_INC_USE_COUNT(mod);
- return 1;
-}
-#endif
-
-
-/* Yes, I'm aware that it's a fairly ugly hack.
- Until the __constant_* macros appear in Linus' own kernels, this is
- the way it has to be done.
- DW 19/1/00
- */
-
-#include <asm/byteorder.h>
-
-#ifndef __constant_cpu_to_le16
-
-#ifdef __BIG_ENDIAN
-#define __constant_cpu_to_le64(x) ___swab64((x))
-#define __constant_le64_to_cpu(x) ___swab64((x))
-#define __constant_cpu_to_le32(x) ___swab32((x))
-#define __constant_le32_to_cpu(x) ___swab32((x))
-#define __constant_cpu_to_le16(x) ___swab16((x))
-#define __constant_le16_to_cpu(x) ___swab16((x))
-#define __constant_cpu_to_be64(x) ((__u64)(x))
-#define __constant_be64_to_cpu(x) ((__u64)(x))
-#define __constant_cpu_to_be32(x) ((__u32)(x))
-#define __constant_be32_to_cpu(x) ((__u32)(x))
-#define __constant_cpu_to_be16(x) ((__u16)(x))
-#define __constant_be16_to_cpu(x) ((__u16)(x))
-#else
-#ifdef __LITTLE_ENDIAN
-#define __constant_cpu_to_le64(x) ((__u64)(x))
-#define __constant_le64_to_cpu(x) ((__u64)(x))
-#define __constant_cpu_to_le32(x) ((__u32)(x))
-#define __constant_le32_to_cpu(x) ((__u32)(x))
-#define __constant_cpu_to_le16(x) ((__u16)(x))
-#define __constant_le16_to_cpu(x) ((__u16)(x))
-#define __constant_cpu_to_be64(x) ___swab64((x))
-#define __constant_be64_to_cpu(x) ___swab64((x))
-#define __constant_cpu_to_be32(x) ___swab32((x))
-#define __constant_be32_to_cpu(x) ___swab32((x))
-#define __constant_cpu_to_be16(x) ___swab16((x))
-#define __constant_be16_to_cpu(x) ___swab16((x))
-#else
-#error No (recognised) endianness defined (unless it,s PDP)
-#endif /* __LITTLE_ENDIAN */
-#endif /* __BIG_ENDIAN */
-
-#endif /* ifndef __constant_cpu_to_le16 */
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,3,0)
- #define mod_init_t int __init
- #define mod_exit_t void
-#else
- #define mod_init_t static int __init
- #define mod_exit_t static void __exit
-#endif
-
-#ifndef THIS_MODULE
-#ifdef MODULE
-#define THIS_MODULE (&__this_module)
-#else
-#define THIS_MODULE (NULL)
-#endif
-#endif
-
-#if LINUX_VERSION_CODE < 0x20300
-#include <linux/interrupt.h>
-#define spin_lock_bh(lock) do {start_bh_atomic();spin_lock(lock);} while(0)
-#define spin_unlock_bh(lock) do {spin_unlock(lock);end_bh_atomic();} while(0)
-#else
-#include <linux/interrupt.h>
-#include <linux/spinlock.h>
-#endif
+/* Nothing to see here. We write 2.5-compatible code and this
+ file makes it all OK in older kernels, but it's empty in _current_
+ kernels. Include guard just to make GCC ignore it in future inclusions
+ anyway... */
#endif /* __LINUX_MTD_COMPATMAC_H__ */
-
-
diff --git a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h
index 6161f2c0ed3b..c224985990b9 100644
--- a/include/linux/mtd/doc2000.h
+++ b/include/linux/mtd/doc2000.h
@@ -2,7 +2,7 @@
/* Linux driver for Disk-On-Chip 2000 */
/* (c) 1999 Machine Vision Holdings, Inc. */
/* Author: David Woodhouse <dwmw2@mvhi.com> */
-/* $Id: doc2000.h,v 1.15 2001/09/19 00:22:15 dwmw2 Exp $ */
+/* $Id: doc2000.h,v 1.16 2003/05/23 11:29:33 dwmw2 Exp $ */
#ifndef __MTD_DOC2000_H__
#define __MTD_DOC2000_H__
@@ -38,6 +38,35 @@
#define DoC_Mil_CDSN_IO 0x0800
#define DoC_2k_CDSN_IO 0x1800
+#define DoC_Mplus_NOP 0x1002
+#define DoC_Mplus_AliasResolution 0x1004
+#define DoC_Mplus_DOCControl 0x1006
+#define DoC_Mplus_AccessStatus 0x1008
+#define DoC_Mplus_DeviceSelect 0x1008
+#define DoC_Mplus_Configuration 0x100a
+#define DoC_Mplus_OutputControl 0x1002
+#define DoC_Mplus_FlashControl 0x1020
+#define DoC_Mplus_FlashSelect 0x1022
+#define DoC_Mplus_FlashCmd 0x1024
+#define DoC_Mplus_FlashAddress 0x1026
+#define DoC_Mplus_FlashData0 0x1028
+#define DoC_Mplus_FlashData1 0x1029
+#define DoC_Mplus_ReadPipeInit 0x102a
+#define DoC_Mplus_LastDataRead 0x102c
+#define DoC_Mplus_LastDataRead1 0x102d
+#define DoC_Mplus_WritePipeTerm 0x102e
+#define DoC_Mplus_ECCSyndrome0 0x1040
+#define DoC_Mplus_ECCSyndrome1 0x1041
+#define DoC_Mplus_ECCSyndrome2 0x1042
+#define DoC_Mplus_ECCSyndrome3 0x1043
+#define DoC_Mplus_ECCSyndrome4 0x1044
+#define DoC_Mplus_ECCSyndrome5 0x1045
+#define DoC_Mplus_ECCConf 0x1046
+#define DoC_Mplus_Toggle 0x1046
+#define DoC_Mplus_DownloadStatus 0x1074
+#define DoC_Mplus_CtrlConfirm 0x1076
+#define DoC_Mplus_Power 0x1fff
+
/* How to access the device?
* On ARM, it'll be mmap'd directly with 32-bit wide accesses.
* On PPC, it's mmap'd and 16-bit wide.
@@ -71,13 +100,20 @@
#define DOC_MODE_RESERVED1 2
#define DOC_MODE_RESERVED2 3
-#define DOC_MODE_MDWREN 4
#define DOC_MODE_CLR_ERR 0x80
+#define DOC_MODE_RST_LAT 0x10
+#define DOC_MODE_BDECT 0x08
+#define DOC_MODE_MDWREN 0x04
#define DOC_ChipID_Doc2k 0x20
#define DOC_ChipID_DocMil 0x30
+#define DOC_ChipID_DocMilPlus32 0x40
+#define DOC_ChipID_DocMilPlus16 0x41
#define CDSN_CTRL_FR_B 0x80
+#define CDSN_CTRL_FR_B0 0x40
+#define CDSN_CTRL_FR_B1 0x80
+
#define CDSN_CTRL_ECC_IO 0x20
#define CDSN_CTRL_FLASH_IO 0x10
#define CDSN_CTRL_WP 0x08
@@ -93,6 +129,10 @@
#define DOC_ECC_RESV 0x02
#define DOC_ECC_IGNORE 0x01
+#define DOC_FLASH_CE 0x80
+#define DOC_FLASH_WP 0x40
+#define DOC_FLASH_BANK 0x02
+
/* We have to also set the reserved bit 1 for enable */
#define DOC_ECC_EN (DOC_ECC__EN | DOC_ECC_RESV)
#define DOC_ECC_DIS (DOC_ECC_RESV)
@@ -110,6 +150,9 @@ struct Nand {
#define MAX_FLOORS_MIL 4
#define MAX_CHIPS_MIL 1
+#define MAX_FLOORS_MPLUS 1
+#define MAX_CHIPS_MPLUS 1
+
#define ADDR_COLUMN 1
#define ADDR_PAGE 2
#define ADDR_COLUMN_PAGE 3
@@ -126,6 +169,7 @@ struct DiskOnChip {
int chipshift;
char page256;
char pageadrlen;
+ char interleave; /* Internal interleaving - Millennium Plus style */
unsigned long erasesize;
int curfloor;
diff --git a/include/linux/mtd/flashchip.h b/include/linux/mtd/flashchip.h
index 4cdccad20abe..7e042bf5fd0b 100644
--- a/include/linux/mtd/flashchip.h
+++ b/include/linux/mtd/flashchip.h
@@ -6,7 +6,7 @@
*
* (C) 2000 Red Hat. GPLd.
*
- * $Id: flashchip.h,v 1.7 2001/01/18 03:52:36 nico Exp $
+ * $Id: flashchip.h,v 1.9 2003/04/30 11:15:22 dwmw2 Exp $
*
*/
@@ -36,6 +36,7 @@ typedef enum {
FL_UNLOADING,
FL_LOCKING,
FL_UNLOCKING,
+ FL_POINT,
FL_UNKNOWN
} flstate_t;
@@ -54,8 +55,13 @@ struct flchip {
a given offset, and we'll want to add the per-chip length field
back in.
*/
+ int ref_point_counter;
flstate_t state;
flstate_t oldstate;
+
+ int write_suspended:1;
+ int erase_suspended:1;
+
spinlock_t *mutex;
spinlock_t _spinlock; /* We do it like this because sometimes they'll be shared. */
wait_queue_head_t wq; /* Wait on here when we're waiting for the chip
diff --git a/include/linux/mtd/inftl.h b/include/linux/mtd/inftl.h
new file mode 100644
index 000000000000..5cc052da9597
--- /dev/null
+++ b/include/linux/mtd/inftl.h
@@ -0,0 +1,129 @@
+/*
+ * inftl.h -- defines to support the Inverse NAND Flash Translation Layer
+ *
+ * (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
+ *
+ * $Id: inftl.h,v 1.3 2003/05/23 11:35:34 dwmw2 Exp $
+ */
+
+#ifndef __MTD_INFTL_H__
+#define __MTD_INFTL_H__
+
+#include <linux/mtd/blktrans.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/nftl.h>
+
+#define OSAK_VERSION 0x5120
+#define PERCENTUSED 98
+
+#define SECTORSIZE 512
+
+#ifndef INFTL_MAJOR
+#define INFTL_MAJOR 93 /* FIXME */
+#endif
+#define INFTL_PARTN_BITS 4
+
+/* Block Control Information */
+
+struct inftl_bci {
+ __u8 ECCsig[6];
+ __u8 Status;
+ __u8 Status1;
+} __attribute__((packed));
+
+struct inftl_unithead1 {
+ __u16 virtualUnitNo;
+ __u16 prevUnitNo;
+ __u8 ANAC;
+ __u8 NACs;
+ __u8 parityPerField;
+ __u8 discarded;
+} __attribute__((packed));
+
+struct inftl_unithead2 {
+ __u8 parityPerField;
+ __u8 ANAC;
+ __u16 prevUnitNo;
+ __u16 virtualUnitNo;
+ __u8 NACs;
+ __u8 discarded;
+} __attribute__((packed));
+
+struct inftl_unittail {
+ __u8 Reserved[4];
+ __u16 EraseMark;
+ __u16 EraseMark1;
+} __attribute__((packed));
+
+union inftl_uci {
+ struct inftl_unithead1 a;
+ struct inftl_unithead2 b;
+ struct inftl_unittail c;
+};
+
+struct inftl_oob {
+ struct inftl_bci b;
+ union inftl_uci u;
+};
+
+
+/* INFTL Media Header */
+
+struct INFTLPartition {
+ __u32 virtualUnits;
+ __u32 firstUnit;
+ __u32 lastUnit;
+ __u32 flags;
+ __u32 spareUnits;
+ __u32 Reserved0;
+ __u32 Reserved1;
+} __attribute__((packed));
+
+struct INFTLMediaHeader {
+ char bootRecordID[8];
+ __u32 NoOfBootImageBlocks;
+ __u32 NoOfBinaryPartitions;
+ __u32 NoOfBDTLPartitions;
+ __u32 BlockMultiplierBits;
+ __u32 FormatFlags;
+ __u32 OsakVersion;
+ __u32 PercentUsed;
+ struct INFTLPartition Partitions[4];
+} __attribute__((packed));
+
+/* Partition flag types */
+#define INFTL_BINARY 0x20000000
+#define INFTL_BDTL 0x40000000
+#define INFTL_LAST 0x80000000
+
+
+#ifdef __KERNEL__
+
+struct INFTLrecord {
+ struct mtd_blktrans_dev mbd;
+ __u16 MediaUnit, SpareMediaUnit;
+ __u32 EraseSize;
+ struct INFTLMediaHeader MediaHdr;
+ int usecount;
+ unsigned char heads;
+ unsigned char sectors;
+ unsigned short cylinders;
+ __u16 numvunits;
+ __u16 firstEUN;
+ __u16 lastEUN;
+ __u16 numfreeEUNs;
+ __u16 LastFreeEUN; /* To speed up finding a free EUN */
+ int head,sect,cyl;
+ __u16 *PUtable; /* Physical Unit Table */
+ __u16 *VUtable; /* Virtual Unit Table */
+ unsigned int nb_blocks; /* number of physical blocks */
+ unsigned int nb_boot_blocks; /* number of blocks used by the bios */
+ struct erase_info instr;
+};
+
+int INFTL_mount(struct INFTLrecord *s);
+int INFTL_formatblock(struct INFTLrecord *s, int block);
+
+#endif /* __KERNEL__ */
+
+#endif /* __MTD_INFTL_H__ */
diff --git a/include/linux/mtd/jedec.h b/include/linux/mtd/jedec.h
index 75271b8a70ba..2ba0f700ddbc 100644
--- a/include/linux/mtd/jedec.h
+++ b/include/linux/mtd/jedec.h
@@ -7,14 +7,13 @@
*
* See the AMD flash databook for information on how to operate the interface.
*
- * $Id: jedec.h,v 1.2 2001/11/06 14:37:36 dwmw2 Exp $
+ * $Id: jedec.h,v 1.3 2003/05/21 11:51:01 dwmw2 Exp $
*/
#ifndef __LINUX_MTD_JEDEC_H__
#define __LINUX_MTD_JEDEC_H__
#include <linux/types.h>
-#include <linux/mtd/map.h>
#define MAX_JEDEC_CHIPS 16
diff --git a/include/linux/mtd/map.h b/include/linux/mtd/map.h
index ad8dfcbda17d..0c933f9bf1fe 100644
--- a/include/linux/mtd/map.h
+++ b/include/linux/mtd/map.h
@@ -1,14 +1,15 @@
/* Overhauled routines for dealing with different mmap regions of flash */
-/* $Id: map.h,v 1.25 2001/09/09 15:04:17 dwmw2 Exp $ */
+/* $Id: map.h,v 1.34 2003/05/28 12:42:22 dwmw2 Exp $ */
#ifndef __LINUX_MTD_MAP_H__
#define __LINUX_MTD_MAP_H__
#include <linux/config.h>
#include <linux/types.h>
-#include <linux/mtd/mtd.h>
-#include <linux/slab.h>
+#include <linux/list.h>
+#include <asm/system.h>
+#include <asm/io.h>
/* The map stuff is very simple. You fill in your struct map_info with
a handful of routines for accessing the device, making sure they handle
@@ -29,34 +30,44 @@
struct map_info {
char *name;
unsigned long size;
+ unsigned long phys;
+#define NO_XIP (-1UL)
+
+ unsigned long virt;
+ void *cached;
+
int buswidth; /* in octets */
- __u8 (*read8)(struct map_info *, unsigned long);
- __u16 (*read16)(struct map_info *, unsigned long);
- __u32 (*read32)(struct map_info *, unsigned long);
+
+#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
+ u8 (*read8)(struct map_info *, unsigned long);
+ u16 (*read16)(struct map_info *, unsigned long);
+ u32 (*read32)(struct map_info *, unsigned long);
+ u64 (*read64)(struct map_info *, unsigned long);
/* If it returned a 'long' I'd call it readl.
* It doesn't.
* I won't.
* dwmw2 */
void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t);
- void (*write8)(struct map_info *, __u8, unsigned long);
- void (*write16)(struct map_info *, __u16, unsigned long);
- void (*write32)(struct map_info *, __u32, unsigned long);
+ void (*write8)(struct map_info *, u8, unsigned long);
+ void (*write16)(struct map_info *, u16, unsigned long);
+ void (*write32)(struct map_info *, u32, unsigned long);
+ void (*write64)(struct map_info *, u64, unsigned long);
void (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t);
+ /* We can perhaps put in 'point' and 'unpoint' methods, if we really
+ want to enable XIP for non-linear mappings. Not yet though. */
+#endif
+ /* set_vpp() must handle being reentered -- enable, enable, disable
+ must leave it enabled. */
void (*set_vpp)(struct map_info *, int);
- /* We put these two here rather than a single void *map_priv,
- because we want mappers to be able to have quickly-accessible
- cache for the 'currently-mapped page' without the _extra_
- redirection that would be necessary. If you need more than
- two longs, turn the second into a pointer. dwmw2 */
+
unsigned long map_priv_1;
unsigned long map_priv_2;
void *fldrv_priv;
struct mtd_chip_driver *fldrv;
};
-
struct mtd_chip_driver {
struct mtd_info *(*probe)(struct map_info *map);
void (*destroy)(struct mtd_info *);
@@ -68,24 +79,94 @@ struct mtd_chip_driver {
void register_mtd_chip_driver(struct mtd_chip_driver *);
void unregister_mtd_chip_driver(struct mtd_chip_driver *);
-struct mtd_info *do_map_probe(char *name, struct map_info *map);
+struct mtd_info *do_map_probe(const char *name, struct map_info *map);
+void map_destroy(struct mtd_info *mtd);
+#define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0)
+#define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0)
+
+#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
+#define map_read8(map, ofs) (map)->read8(map, ofs)
+#define map_read16(map, ofs) (map)->read16(map, ofs)
+#define map_read32(map, ofs) (map)->read32(map, ofs)
+#define map_read64(map, ofs) (map)->read64(map, ofs)
+#define map_copy_from(map, to, from, len) (map)->copy_from(map, to, from, len)
+#define map_write8(map, datum, ofs) (map)->write8(map, datum, ofs)
+#define map_write16(map, datum, ofs) (map)->write16(map, datum, ofs)
+#define map_write32(map, datum, ofs) (map)->write32(map, datum, ofs)
+#define map_write64(map, datum, ofs) (map)->write64(map, datum, ofs)
+#define map_copy_to(map, to, from, len) (map)->copy_to(map, to, from, len)
-/*
- * Destroy an MTD device which was created for a map device.
- * Make sure the MTD device is already unregistered before calling this
- */
-static inline void map_destroy(struct mtd_info *mtd)
+extern void simple_map_init(struct map_info *);
+#define map_is_linear(map) (map->phys != NO_XIP)
+
+#else
+static inline u8 map_read8(struct map_info *map, unsigned long ofs)
{
- struct map_info *map = mtd->priv;
+ return __raw_readb(map->virt + ofs);
+}
- if (map->fldrv->destroy)
- map->fldrv->destroy(mtd);
- module_put(map->fldrv->module);
- kfree(mtd);
+static inline u16 map_read16(struct map_info *map, unsigned long ofs)
+{
+ return __raw_readw(map->virt + ofs);
}
-#define ENABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 1); } while(0)
-#define DISABLE_VPP(map) do { if(map->set_vpp) map->set_vpp(map, 0); } while(0)
+static inline u32 map_read32(struct map_info *map, unsigned long ofs)
+{
+ return __raw_readl(map->virt + ofs);
+}
+
+static inline u64 map_read64(struct map_info *map, unsigned long ofs)
+{
+#ifndef CONFIG_MTD_CFI_B8 /* 64-bit mappings */
+ BUG();
+ return 0;
+#else
+ return __raw_readll(map->virt + ofs);
+#endif
+}
+
+static inline void map_write8(struct map_info *map, u8 datum, unsigned long ofs)
+{
+ __raw_writeb(datum, map->virt + ofs);
+ mb();
+}
+
+static inline void map_write16(struct map_info *map, u16 datum, unsigned long ofs)
+{
+ __raw_writew(datum, map->virt + ofs);
+ mb();
+}
+
+static inline void map_write32(struct map_info *map, u32 datum, unsigned long ofs)
+{
+ __raw_writel(datum, map->virt + ofs);
+ mb();
+}
+
+static inline void map_write64(struct map_info *map, u64 datum, unsigned long ofs)
+{
+#ifndef CONFIG_MTD_CFI_B8 /* 64-bit mappings */
+ BUG();
+#else
+ __raw_writell(datum, map->virt + ofs);
+ mb();
+#endif /* CFI_B8 */
+}
+
+static inline void map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
+{
+ memcpy_fromio(to, map->virt + from, len);
+}
+
+static inline void map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
+{
+ memcpy_toio(map->virt + to, from, len);
+}
+
+#define simple_map_init(map) do { } while (0)
+#define map_is_linear(map) (1)
+
+#endif /* !CONFIG_MTD_COMPLEX_MAPPINGS */
#endif /* __LINUX_MTD_MAP_H__ */
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h
index 6a57af9f46a3..9ac94aaabd3f 100644
--- a/include/linux/mtd/mtd.h
+++ b/include/linux/mtd/mtd.h
@@ -1,5 +1,5 @@
-/* $Id: mtd.h,v 1.33 2001/06/09 00:08:59 dwmw2 Exp $ */
+/* $Id: mtd.h,v 1.45 2003/05/20 21:56:40 dwmw2 Exp $ */
#ifndef __MTD_MTD_H__
#define __MTD_MTD_H__
@@ -9,7 +9,6 @@
#include <linux/config.h>
#include <linux/version.h>
#include <linux/types.h>
-#include <linux/mtd/compatmac.h>
#include <linux/module.h>
#include <linux/uio.h>
@@ -26,7 +25,6 @@ struct mtd_oob_buf {
unsigned char *ptr;
};
-
#define MTD_CHAR_MAJOR 90
#define MTD_BLOCK_MAJOR 31
#define MAX_MTD_DEVICES 16
@@ -93,16 +91,23 @@ struct region_info_user {
#define MEMUNLOCK _IOW('M', 6, struct erase_info_user)
#define MEMGETREGIONCOUNT _IOR('M', 7, int)
#define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user)
+#define MEMSETOOBSEL _IOW('M', 9, struct nand_oobinfo)
+
+struct nand_oobinfo {
+ int useecc;
+ int eccpos[6];
+};
+
#ifndef __KERNEL__
typedef struct mtd_info_user mtd_info_t;
typedef struct erase_info_user erase_info_t;
typedef struct region_info_user region_info_t;
+typedef struct nand_oobinfo nand_oobinfo_t;
/* User-space ioctl definitions */
-
#else /* __KERNEL__ */
@@ -147,11 +152,15 @@ struct mtd_info {
u_int32_t oobsize; // Amount of OOB data per block (e.g. 16)
u_int32_t ecctype;
u_int32_t eccsize;
+
// Kernel-only stuff starts here.
char *name;
int index;
+ // oobinfo is a nand_oobinfo structure, which can be set by iotcl (MEMSETOOBINFO)
+ struct nand_oobinfo oobinfo;
+
/* Data for variable erase regions. If numeraseregions is zero,
* it means that the whole device has erasesize as given above.
*/
@@ -161,32 +170,47 @@ struct mtd_info {
/* This really shouldn't be here. It can go away in 2.5 */
u_int32_t bank_size;
- struct module *module;
int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
/* This stuff for eXecute-In-Place */
int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);
/* We probably shouldn't allow XIP if the unpoint isn't a NULL */
- void (*unpoint) (struct mtd_info *mtd, u_char * addr);
+ void (*unpoint) (struct mtd_info *mtd, u_char * addr, loff_t from, size_t len);
int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
- int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf);
- int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf);
+ int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
+ int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf);
+ /*
+ * Methods to access the protection register area, present in some
+ * flash devices. The user data is one time programmable but the
+ * factory data is read only.
+ */
+ int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
+
+ int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
+
+ /* This function is not yet implemented */
+ int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);
+
/* iovec-based read/write methods. We need these especially for NAND flash,
with its limited number of write cycles per erase.
NB: The 'count' parameter is the number of _vectors_, each of
which contains an (ofs, len) tuple.
*/
int (*readv) (struct mtd_info *mtd, struct iovec *vecs, unsigned long count, loff_t from, size_t *retlen);
+ int (*readv_ecc) (struct mtd_info *mtd, struct iovec *vecs, unsigned long count, loff_t from,
+ size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
int (*writev) (struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen);
+ int (*writev_ecc) (struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to,
+ size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
/* Sync */
void (*sync) (struct mtd_info *mtd);
@@ -200,6 +224,9 @@ struct mtd_info {
void (*resume) (struct mtd_info *mtd);
void *priv;
+
+ struct module *owner;
+ int usecount;
};
@@ -208,35 +235,27 @@ struct mtd_info {
extern int add_mtd_device(struct mtd_info *mtd);
extern int del_mtd_device (struct mtd_info *mtd);
-extern struct mtd_info *__get_mtd_device(struct mtd_info *mtd, int num);
+extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num);
-static inline struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num)
-{
- struct mtd_info *ret;
-
- ret = __get_mtd_device(mtd, num);
- if (ret && !try_module_get(ret->module))
- return NULL;
- return ret;
-}
+extern void put_mtd_device(struct mtd_info *mtd);
-static inline void put_mtd_device(struct mtd_info *mtd)
-{
- module_put(mtd->module);
-}
struct mtd_notifier {
void (*add)(struct mtd_info *mtd);
void (*remove)(struct mtd_info *mtd);
- struct mtd_notifier *next;
+ struct list_head list;
};
extern void register_mtd_user (struct mtd_notifier *new);
extern int unregister_mtd_user (struct mtd_notifier *old);
+int default_mtd_writev(struct mtd_info *mtd, const struct iovec *vecs,
+ unsigned long count, loff_t to, size_t *retlen);
+
+int default_mtd_readv(struct mtd_info *mtd, struct iovec *vecs,
+ unsigned long count, loff_t from, size_t *retlen);
-#ifndef MTDC
#define MTD_ERASE(mtd, args...) (*(mtd->erase))(mtd, args)
#define MTD_POINT(mtd, a,b,c,d) (*(mtd->point))(mtd, a,b,c, (u_char **)(d))
#define MTD_UNPOINT(mtd, arg) (*(mtd->unpoint))(mtd, (u_char *)arg)
@@ -249,7 +268,6 @@ extern int unregister_mtd_user (struct mtd_notifier *old);
#define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args)
#define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args)
#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0)
-#endif /* MTDC */
/*
* Debugging macro and defines
@@ -266,7 +284,8 @@ extern int unregister_mtd_user (struct mtd_notifier *old);
printk(KERN_INFO args); \
} while(0)
#else /* CONFIG_MTD_DEBUG */
-#define DEBUG(n, args...)
+#define DEBUG(n, args...) do { } while(0)
+
#endif /* CONFIG_MTD_DEBUG */
#endif /* __KERNEL__ */
diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h
index 8c678ab9761a..88d48a26bf75 100644
--- a/include/linux/mtd/nand.h
+++ b/include/linux/mtd/nand.h
@@ -2,9 +2,10 @@
* linux/include/linux/mtd/nand.h
*
* Copyright (c) 2000 David Woodhouse <dwmw2@mvhi.com>
- * Steven J. Hill <sjhill@cotw.com>
+ * Steven J. Hill <sjhill@realitydiluted.com>
+ * Thomas Gleixner <tglx@linutronix.de>
*
- * $Id: nand.h,v 1.8 2000/10/30 17:16:17 sjhill Exp $
+ * $Id: nand.h,v 1.25 2003/05/21 15:15:02 dwmw2 Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
@@ -23,19 +24,51 @@
* bat later if I did something naughty.
* 10-11-2000 SJH Added private NAND flash structure for driver
* 10-24-2000 SJH Added prototype for 'nand_scan' function
+ * 10-29-2001 TG changed nand_chip structure to support
+ * hardwarespecific function for accessing control lines
+ * 02-21-2002 TG added support for different read/write adress and
+ * ready/busy line access function
+ * 02-26-2002 TG added chip_delay to nand_chip structure to optimize
+ * command delay times for different chips
+ * 04-28-2002 TG OOB config defines moved from nand.c to avoid duplicate
+ * defines in jffs2/wbuf.c
+ * 08-07-2002 TG forced bad block location to byte 5 of OOB, even if
+ * CONFIG_MTD_NAND_ECC_JFFS2 is not set
+ * 08-10-2002 TG extensions to nand_chip structure to support HW-ECC
+ *
+ * 08-29-2002 tglx nand_chip structure: data_poi for selecting
+ * internal / fs-driver buffer
+ * support for 6byte/512byte hardware ECC
+ * read_ecc, write_ecc extended for different oob-layout
+ * oob layout selections: NAND_NONE_OOB, NAND_JFFS2_OOB,
+ * NAND_YAFFS_OOB
+ * 11-25-2002 tglx Added Manufacturer code FUJITSU, NATIONAL
+ * Split manufacturer and device ID structures
*/
#ifndef __LINUX_MTD_NAND_H
#define __LINUX_MTD_NAND_H
#include <linux/config.h>
-#include <linux/sched.h>
+#include <linux/wait.h>
+#include <linux/spinlock.h>
+struct mtd_info;
/*
* Searches for a NAND device
*/
extern int nand_scan (struct mtd_info *mtd);
/*
+ * Constants for hardware specific CLE/ALE/NCE function
+*/
+#define NAND_CTL_SETNCE 1
+#define NAND_CTL_CLRNCE 2
+#define NAND_CTL_SETCLE 3
+#define NAND_CTL_CLRCLE 4
+#define NAND_CTL_SETALE 5
+#define NAND_CTL_CLRALE 6
+
+/*
* Standard NAND flash commands
*/
#define NAND_CMD_READ0 0
@@ -49,6 +82,29 @@ extern int nand_scan (struct mtd_info *mtd);
#define NAND_CMD_ERASE2 0xd0
#define NAND_CMD_RESET 0xff
+/*
+ * Constants for ECC_MODES
+ *
+ * NONE: No ECC
+ * SOFT: Software ECC 3 byte ECC per 256 Byte data
+ * HW3_256: Hardware ECC 3 byte ECC per 256 Byte data
+ * HW3_512: Hardware ECC 3 byte ECC per 512 Byte data
+ *
+ *
+*/
+#define NAND_ECC_NONE 0
+#define NAND_ECC_SOFT 1
+#define NAND_ECC_HW3_256 2
+#define NAND_ECC_HW3_512 3
+#define NAND_ECC_HW6_512 4
+#define NAND_ECC_DISKONCHIP 5
+
+/*
+ * Constants for Hardware ECC
+*/
+#define NAND_ECC_READ 0
+#define NAND_ECC_WRITE 1
+
/*
* Enumeration for NAND flash chip state
*/
@@ -60,20 +116,33 @@ typedef enum {
FL_SYNCING
} nand_state_t;
+
/*
* NAND Private Flash Chip Data
*
* Structure overview:
*
- * IO_ADDR - address to access the 8 I/O lines to the flash device
+ * IO_ADDR_R - address to read the 8 I/O lines of the flash device
+ *
+ * IO_ADDR_W - address to write the 8 I/O lines of the flash device
*
- * CTRL_ADDR - address where ALE, CLE and CE control bits are accessed
+ * hwcontrol - hardwarespecific function for accesing control-lines
*
- * CLE - location in control word for Command Latch Enable bit
+ * dev_ready - hardwarespecific function for accesing device ready/busy line
*
- * ALE - location in control word for Address Latch Enable bit
+ * waitfunc - hardwarespecific function for wait on ready
*
- * NCE - location in control word for nChip Enable bit
+ * calculate_ecc - function for ecc calculation or readback from ecc hardware
+ *
+ * correct_data - function for ecc correction, matching to ecc generator (sw/hw)
+ *
+ * enable_hwecc - function to enable (reset) hardware ecc generator
+ *
+ * eccmod - mode of ecc: see constants
+ *
+ * eccsize - databytes used per ecc-calculation
+ *
+ * chip_delay - chip dependent delay for transfering data from array to read regs (tR)
*
* chip_lock - spinlock used to protect access to this structure
*
@@ -85,27 +154,30 @@ typedef enum {
*
* data_buf - data buffer passed to/from MTD user modules
*
- * ecc_code_buf - used only for holding calculated or read ECCs for
- * a page read or written when ECC is in use
+ * data_cache - data cache for redundant page access and shadow for
+ * ECC failure
*
- * reserved - padding to make structure fall on word boundary if
- * when ECC is in use
+ * cache_page - number of last valid page in page_cache
*/
struct nand_chip {
- unsigned long IO_ADDR;
- unsigned long CTRL_ADDR;
- unsigned int CLE;
- unsigned int ALE;
- unsigned int NCE;
- spinlock_t chip_lock;
+ unsigned long IO_ADDR_R;
+ unsigned long IO_ADDR_W;
+ void (*hwcontrol)(int cmd);
+ int (*dev_ready)(void);
+ void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);
+ int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state);
+ void (*calculate_ecc)(const u_char *dat, u_char *ecc_code);
+ int (*correct_data)(u_char *dat, u_char *read_ecc, u_char *calc_ecc);
+ void (*enable_hwecc)(int mode);
+ int eccmode;
+ int eccsize;
+ int chip_delay;
+ spinlock_t chip_lock;
wait_queue_head_t wq;
- nand_state_t state;
- int page_shift;
- u_char *data_buf;
-#ifdef CONFIG_MTD_NAND_ECC
- u_char ecc_code_buf[6];
- u_char reserved[2];
-#endif
+ nand_state_t state;
+ int page_shift;
+ u_char *data_buf;
+ u_char *data_poi;
};
/*
@@ -113,17 +185,17 @@ struct nand_chip {
*/
#define NAND_MFR_TOSHIBA 0x98
#define NAND_MFR_SAMSUNG 0xec
+#define NAND_MFR_FUJITSU 0x04
+#define NAND_MFR_NATIONAL 0x8f
/*
* NAND Flash Device ID Structure
*
* Structure overview:
*
- * name - Complete name of device
- *
- * manufacture_id - manufacturer ID code of device.
+ * name - Identify the device type
*
- * model_id - model ID code of device.
+ * id - device ID code
*
* chipshift - total number of address bits for the device which
* is used to calculate address offsets and the total
@@ -143,12 +215,30 @@ struct nand_chip {
*/
struct nand_flash_dev {
char * name;
- int manufacture_id;
- int model_id;
+ int id;
int chipshift;
- char page256;
- char pageadrlen;
unsigned long erasesize;
+ char page256;
};
+/*
+ * NAND Flash Manufacturer ID Structure
+ *
+ * name - Manufacturer name
+ *
+ * id - manufacturer ID code of device.
+*/
+struct nand_manufacturers {
+ int id;
+ char * name;
+};
+
+extern struct nand_flash_dev nand_flash_ids[];
+extern struct nand_manufacturers nand_manuf_ids[];
+
+/*
+* Constants for oob configuration
+*/
+#define NAND_BADBLOCK_POS 5
+
#endif /* __LINUX_MTD_NAND_H */
diff --git a/include/linux/mtd/nand_ecc.h b/include/linux/mtd/nand_ecc.h
index f3f1d7e0f6aa..c3b493c99b05 100644
--- a/include/linux/mtd/nand_ecc.h
+++ b/include/linux/mtd/nand_ecc.h
@@ -1,9 +1,9 @@
/*
* drivers/mtd/nand_ecc.h
*
- * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com)
+ * Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
*
- * $Id: nand_ecc.h,v 1.1 2000/10/12 00:57:15 sjhill Exp $
+ * $Id: nand_ecc.h,v 1.2 2003/02/20 13:34:20 sjhill Exp $
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
diff --git a/include/linux/mtd/nand_ids.h b/include/linux/mtd/nand_ids.h
deleted file mode 100644
index 0918b8c1e92d..000000000000
--- a/include/linux/mtd/nand_ids.h
+++ /dev/null
@@ -1,52 +0,0 @@
-/*
- * linux/include/linux/mtd/nand_ids.h
- *
- * Copyright (c) 2000 David Woodhouse <dwmw2@mvhi.com>
- * Steven J. Hill <sjhill@cotw.com>
- *
- * $Id: nand_ids.h,v 1.1 2000/10/13 16:16:26 mdeans Exp $
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 as
- * published by the Free Software Foundation.
- *
- * Info:
- * Contains standard defines and IDs for NAND flash devices
- *
- * Changelog:
- * 01-31-2000 DMW Created
- * 09-18-2000 SJH Moved structure out of the Disk-On-Chip drivers
- * so it can be used by other NAND flash device
- * drivers. I also changed the copyright since none
- * of the original contents of this file are specific
- * to DoC devices. David can whack me with a baseball
- * bat later if I did something naughty.
- * 10-11-2000 SJH Added private NAND flash structure for driver
- * 2000-10-13 BE Moved out of 'nand.h' - avoids duplication.
- */
-
-#ifndef __LINUX_MTD_NAND_IDS_H
-#define __LINUX_MTD_NAND_IDS_H
-
-static struct nand_flash_dev nand_flash_ids[] = {
- {"Toshiba TC5816BDC", NAND_MFR_TOSHIBA, 0x64, 21, 1, 2, 0x1000},
- {"Toshiba TC5832DC", NAND_MFR_TOSHIBA, 0x6b, 22, 0, 2, 0x2000},
- {"Toshiba TH58V128DC", NAND_MFR_TOSHIBA, 0x73, 24, 0, 2, 0x4000},
- {"Toshiba TC58256FT/DC", NAND_MFR_TOSHIBA, 0x75, 25, 0, 2, 0x4000},
- {"Toshiba TH58512FT", NAND_MFR_TOSHIBA, 0x76, 26, 0, 3, 0x4000},
- {"Toshiba TC58V32DC", NAND_MFR_TOSHIBA, 0xe5, 22, 0, 2, 0x2000},
- {"Toshiba TC58V64AFT/DC", NAND_MFR_TOSHIBA, 0xe6, 23, 0, 2, 0x2000},
- {"Toshiba TC58V16BDC", NAND_MFR_TOSHIBA, 0xea, 21, 1, 2, 0x1000},
- {"Samsung KM29N16000", NAND_MFR_SAMSUNG, 0x64, 21, 1, 2, 0x1000},
- {"Samsung unknown 4Mb", NAND_MFR_SAMSUNG, 0x6b, 22, 0, 2, 0x2000},
- {"Samsung KM29U128T", NAND_MFR_SAMSUNG, 0x73, 24, 0, 2, 0x4000},
- {"Samsung KM29U256T", NAND_MFR_SAMSUNG, 0x75, 25, 0, 2, 0x4000},
- {"Samsung unknown 64Mb", NAND_MFR_SAMSUNG, 0x76, 26, 0, 3, 0x4000},
- {"Samsung KM29W32000", NAND_MFR_SAMSUNG, 0xe3, 22, 0, 2, 0x2000},
- {"Samsung unknown 4Mb", NAND_MFR_SAMSUNG, 0xe5, 22, 0, 2, 0x2000},
- {"Samsung KM29U64000", NAND_MFR_SAMSUNG, 0xe6, 23, 0, 2, 0x2000},
- {"Samsung KM29W16000", NAND_MFR_SAMSUNG, 0xea, 21, 1, 2, 0x1000},
- {NULL,}
-};
-
-#endif /* __LINUX_MTD_NAND_IDS_H */
diff --git a/include/linux/mtd/nftl.h b/include/linux/mtd/nftl.h
index 55778a673b5d..fd57ffddd69a 100644
--- a/include/linux/mtd/nftl.h
+++ b/include/linux/mtd/nftl.h
@@ -1,15 +1,14 @@
-
-/* Defines for NAND Flash Translation Layer */
-/* (c) 1999 Machine Vision Holdings, Inc. */
-/* Author: David Woodhouse <dwmw2@mvhi.com> */
-/* $Id: nftl.h,v 1.10 2000/12/29 00:25:38 dwmw2 Exp $ */
+/*
+ * $Id: nftl.h,v 1.13 2003/05/23 11:25:02 dwmw2 Exp $
+ *
+ * (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
+ */
#ifndef __MTD_NFTL_H__
#define __MTD_NFTL_H__
-#ifndef __BOOT__
#include <linux/mtd/mtd.h>
-#endif
+#include <linux/mtd/blktrans.h>
/* Block Control Information */
@@ -84,8 +83,7 @@ struct NFTLMediaHeader {
#define BLOCK_RESERVED 0xfffc /* bios block or bad block */
struct NFTLrecord {
- struct mtd_info *mtd;
- struct semaphore mutex;
+ struct mtd_blktrans_dev mbd;
__u16 MediaUnit, SpareMediaUnit;
__u32 EraseSize;
struct NFTLMediaHeader MediaHdr;
@@ -97,14 +95,12 @@ struct NFTLrecord {
__u16 lastEUN; /* should be suppressed */
__u16 numfreeEUNs;
__u16 LastFreeEUN; /* To speed up finding a free EUN */
- __u32 long nr_sects;
int head,sect,cyl;
__u16 *EUNtable; /* [numvunits]: First EUN for each virtual unit */
__u16 *ReplUnitTable; /* [numEUNs]: ReplUnitNumber for each */
unsigned int nb_blocks; /* number of physical blocks */
unsigned int nb_boot_blocks; /* number of blocks used by the bios */
struct erase_info instr;
- struct gendisk *disk;
};
int NFTL_mount(struct NFTLrecord *s);
@@ -115,7 +111,7 @@ int NFTL_formatblock(struct NFTLrecord *s, int block);
#endif
#define MAX_NFTLS 16
-#define MAX_SECTORS_PER_UNIT 32
+#define MAX_SECTORS_PER_UNIT 64
#define NFTL_PARTN_BITS 4
#endif /* __KERNEL__ */
diff --git a/include/linux/mtd/partitions.h b/include/linux/mtd/partitions.h
index 1d3351cc1eca..5c5f8770b86d 100644
--- a/include/linux/mtd/partitions.h
+++ b/include/linux/mtd/partitions.h
@@ -5,7 +5,7 @@
*
* This code is GPL
*
- * $Id: partitions.h,v 1.6 2001/03/17 17:10:21 dwmw2 Exp $
+ * $Id: partitions.h,v 1.14 2003/05/20 21:56:29 dwmw2 Exp $
*/
#ifndef MTD_PARTITIONS_H
@@ -26,23 +26,26 @@
* will extend to the end of the master MTD device.
* offset: absolute starting position within the master MTD device; if
* defined as MTDPART_OFS_APPEND, the partition will start where the
- * previous one ended.
+ * previous one ended; if MTDPART_OFS_NXTBLK, at the next erase block.
* mask_flags: contains flags that have to be masked (removed) from the
* master MTD flag set for the corresponding MTD partition.
* For example, to force a read-only partition, simply adding
* MTD_WRITEABLE to the mask_flags will do the trick.
*
* Note: writeable partitions require their size and offset be
- * erasesize aligned.
+ * erasesize aligned (e.g. use MTDPART_OFS_NEXTBLK).
*/
struct mtd_partition {
- char *name; /* identifier string */
- u_int32_t size; /* partition size */
+ char *name; /* identifier string */
+ u_int32_t size; /* partition size */
u_int32_t offset; /* offset within the master MTD space */
- u_int32_t mask_flags; /* master MTD flags to mask out for this partition */
+ u_int32_t mask_flags; /* master MTD flags to mask out for this partition */
+ struct nand_oobinfo *oobsel; /* out of band layout for this partition (NAND only)*/
+ struct mtd_info **mtdp; /* pointer to store the MTD object */
};
+#define MTDPART_OFS_NXTBLK (-2)
#define MTDPART_OFS_APPEND (-1)
#define MTDPART_SIZ_FULL (0)
@@ -50,5 +53,24 @@ struct mtd_partition {
int add_mtd_partitions(struct mtd_info *, struct mtd_partition *, int);
int del_mtd_partitions(struct mtd_info *);
+/*
+ * Functions dealing with the various ways of partitioning the space
+ */
+
+struct mtd_part_parser {
+ struct list_head list;
+ struct module *owner;
+ const char *name;
+ int (*parse_fn)(struct mtd_info *, struct mtd_partition **, unsigned long);
+};
+
+extern struct mtd_part_parser *get_partition_parser(const char *name);
+extern int register_mtd_parser(struct mtd_part_parser *parser);
+extern int deregister_mtd_parser(struct mtd_part_parser *parser);
+extern int parse_mtd_partitions(struct mtd_info *master, const char **types,
+ struct mtd_partition **pparts, unsigned long origin);
+
+#define put_partition_parser(p) do { module_put((p)->owner); } while(0)
+
#endif
diff --git a/include/linux/mtd/pmc551.h b/include/linux/mtd/pmc551.h
index 640d3ebbc2ce..113e3087f68a 100644
--- a/include/linux/mtd/pmc551.h
+++ b/include/linux/mtd/pmc551.h
@@ -1,5 +1,5 @@
/*
- * $Id: pmc551.h,v 1.4 2001/06/12 16:19:38 major Exp $
+ * $Id: pmc551.h,v 1.5 2003/01/24 16:49:53 dwmw2 Exp $
*
* PMC551 PCI Mezzanine Ram Device
*
@@ -17,7 +17,7 @@
#include <linux/mtd/mtd.h>
-#define PMC551_VERSION "$Id: pmc551.h,v 1.4 2001/06/12 16:19:38 major Exp $\n"\
+#define PMC551_VERSION "$Id: pmc551.h,v 1.5 2003/01/24 16:49:53 dwmw2 Exp $\n"\
"Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n"
/*
@@ -36,7 +36,7 @@ struct mypriv {
* Function Prototypes
*/
static int pmc551_erase(struct mtd_info *, struct erase_info *);
-static void pmc551_unpoint(struct mtd_info *, u_char *);
+static void pmc551_unpoint(struct mtd_info *, u_char *, loff_t, size_t);
static int pmc551_point (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);
static int pmc551_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
static int pmc551_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);