diff options
| author | David Woodhouse <dwmw2@infradead.org> | 2003-05-28 18:03:33 +0100 |
|---|---|---|
| committer | David Woodhouse <dwmw2@infradead.org> | 2003-05-28 18:03:33 +0100 |
| commit | 5af017c0de780cb463b784ef909406ce397332ee (patch) | |
| tree | ecfae73f9c51082ebe4cbe6d228adcba21ca524d /include/linux | |
| parent | 015498d534572f8a9c3bf5f1dfc02bd02bfb2c9d (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.h | 25 | ||||
| -rw-r--r-- | include/linux/jffs2_fs_sb.h | 5 | ||||
| -rw-r--r-- | include/linux/mtd/blktrans.h | 75 | ||||
| -rw-r--r-- | include/linux/mtd/cfi.h | 143 | ||||
| -rw-r--r-- | include/linux/mtd/cfi_endian.h | 8 | ||||
| -rw-r--r-- | include/linux/mtd/compatmac.h | 199 | ||||
| -rw-r--r-- | include/linux/mtd/doc2000.h | 48 | ||||
| -rw-r--r-- | include/linux/mtd/flashchip.h | 8 | ||||
| -rw-r--r-- | include/linux/mtd/inftl.h | 129 | ||||
| -rw-r--r-- | include/linux/mtd/jedec.h | 3 | ||||
| -rw-r--r-- | include/linux/mtd/map.h | 137 | ||||
| -rw-r--r-- | include/linux/mtd/mtd.h | 71 | ||||
| -rw-r--r-- | include/linux/mtd/nand.h | 156 | ||||
| -rw-r--r-- | include/linux/mtd/nand_ecc.h | 4 | ||||
| -rw-r--r-- | include/linux/mtd/nand_ids.h | 52 | ||||
| -rw-r--r-- | include/linux/mtd/nftl.h | 20 | ||||
| -rw-r--r-- | include/linux/mtd/partitions.h | 34 | ||||
| -rw-r--r-- | include/linux/mtd/pmc551.h | 6 |
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 *); |
