diff options
author | Andreas Baumann <mail@andreasbaumann.cc> | 2015-01-03 12:04:58 +0100 |
---|---|---|
committer | Andreas Baumann <mail@andreasbaumann.cc> | 2015-01-03 12:04:58 +0100 |
commit | 008d0be72b2f160382c6e880765e96b64a050c65 (patch) | |
tree | 36f48a98a3815a408e2ce1693dd182af90f80305 /release/src/linux/linux/include/linux/mtd | |
parent | 611becfb8726c60cb060368541ad98191d4532f5 (diff) | |
download | tomato-008d0be72b2f160382c6e880765e96b64a050c65.tar.gz tomato-008d0be72b2f160382c6e880765e96b64a050c65.tar.bz2 |
imported original firmware WRT54GL_v4.30.11_11_US
Diffstat (limited to 'release/src/linux/linux/include/linux/mtd')
18 files changed, 2007 insertions, 0 deletions
diff --git a/release/src/linux/linux/include/linux/mtd/cfi.h b/release/src/linux/linux/include/linux/mtd/cfi.h new file mode 100644 index 00000000..d61ee9d2 --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/cfi.h @@ -0,0 +1,393 @@ + +/* Common Flash Interface structures + * See http://support.intel.com/design/flash/technote/index.htm + * $Id: cfi.h,v 1.1.1.4 2003/10/14 08:09:27 sparq Exp $ + */ + +#ifndef __MTD_CFI_H__ +#define __MTD_CFI_H__ + +#include <linux/config.h> +#include <linux/delay.h> +#include <linux/types.h> +#include <linux/interrupt.h> +#include <linux/mtd/flashchip.h> +#include <linux/mtd/cfi_endian.h> + +/* + * 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) + * + * By default, all (known) geometries are supported. + */ + +#ifndef CONFIG_MTD_CFI_GEOMETRY + +#define CFIDEV_INTERLEAVE_1 (1) +#define CFIDEV_INTERLEAVE_2 (2) +#define CFIDEV_INTERLEAVE_4 (4) + +#define CFIDEV_BUSWIDTH_1 (1) +#define CFIDEV_BUSWIDTH_2 (2) +#define CFIDEV_BUSWIDTH_4 (4) + +#else + +#ifdef CONFIG_MTD_CFI_I1 +#define CFIDEV_INTERLEAVE_1 (1) +#endif +#ifdef CONFIG_MTD_CFI_I2 +#define CFIDEV_INTERLEAVE_2 (2) +#endif +#ifdef CONFIG_MTD_CFI_I4 +#define CFIDEV_INTERLEAVE_4 (4) +#endif + +#ifdef CONFIG_MTD_CFI_B1 +#define CFIDEV_BUSWIDTH_1 (1) +#endif +#ifdef CONFIG_MTD_CFI_B2 +#define CFIDEV_BUSWIDTH_2 (2) +#endif +#ifdef CONFIG_MTD_CFI_B4 +#define CFIDEV_BUSWIDTH_4 (4) +#endif + +#endif + +/* + * The following macros are used to select the code to execute: + * cfi_buswidth_is_*() + * cfi_interleave_is_*() + * [where * is either 1, 2 or 4] + * 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). + */ + +#ifdef CFIDEV_INTERLEAVE_1 +# ifdef CFIDEV_INTERLEAVE +# undef CFIDEV_INTERLEAVE +# define CFIDEV_INTERLEAVE (cfi->interleave) +# else +# define CFIDEV_INTERLEAVE CFIDEV_INTERLEAVE_1 +# endif +# define cfi_interleave_is_1() (CFIDEV_INTERLEAVE == CFIDEV_INTERLEAVE_1) +#else +# define cfi_interleave_is_1() (0) +#endif + +#ifdef CFIDEV_INTERLEAVE_2 +# ifdef CFIDEV_INTERLEAVE +# undef CFIDEV_INTERLEAVE +# define CFIDEV_INTERLEAVE (cfi->interleave) +# else +# define CFIDEV_INTERLEAVE CFIDEV_INTERLEAVE_2 +# endif +# define cfi_interleave_is_2() (CFIDEV_INTERLEAVE == CFIDEV_INTERLEAVE_2) +#else +# define cfi_interleave_is_2() (0) +#endif + +#ifdef CFIDEV_INTERLEAVE_4 +# ifdef CFIDEV_INTERLEAVE +# undef CFIDEV_INTERLEAVE +# define CFIDEV_INTERLEAVE (cfi->interleave) +# else +# define CFIDEV_INTERLEAVE CFIDEV_INTERLEAVE_4 +# endif +# define cfi_interleave_is_4() (CFIDEV_INTERLEAVE == CFIDEV_INTERLEAVE_4) +#else +# define cfi_interleave_is_4() (0) +#endif + +#ifndef CFIDEV_INTERLEAVE +#error You must define at least one interleave to support! +#endif + +#ifdef CFIDEV_BUSWIDTH_1 +# ifdef CFIDEV_BUSWIDTH +# undef CFIDEV_BUSWIDTH +# define CFIDEV_BUSWIDTH (map->buswidth) +# else +# define CFIDEV_BUSWIDTH CFIDEV_BUSWIDTH_1 +# endif +# define cfi_buswidth_is_1() (CFIDEV_BUSWIDTH == CFIDEV_BUSWIDTH_1) +#else +# define cfi_buswidth_is_1() (0) +#endif + +#ifdef CFIDEV_BUSWIDTH_2 +# ifdef CFIDEV_BUSWIDTH +# undef CFIDEV_BUSWIDTH +# define CFIDEV_BUSWIDTH (map->buswidth) +# else +# define CFIDEV_BUSWIDTH CFIDEV_BUSWIDTH_2 +# endif +# define cfi_buswidth_is_2() (CFIDEV_BUSWIDTH == CFIDEV_BUSWIDTH_2) +#else +# define cfi_buswidth_is_2() (0) +#endif + +#ifdef CFIDEV_BUSWIDTH_4 +# ifdef CFIDEV_BUSWIDTH +# undef CFIDEV_BUSWIDTH +# define CFIDEV_BUSWIDTH (map->buswidth) +# else +# define CFIDEV_BUSWIDTH CFIDEV_BUSWIDTH_4 +# endif +# define cfi_buswidth_is_4() (CFIDEV_BUSWIDTH == CFIDEV_BUSWIDTH_4) +#else +# define cfi_buswidth_is_4() (0) +#endif + +#ifndef CFIDEV_BUSWIDTH +#error You must define at least one bus width to support! +#endif + +/* NB: these values must represents the number of bytes needed to meet the + * device type (x8, x16, x32). Eg. a 32 bit device is 4 x 8 bytes. + * These numbers are used in calculations. + */ +#define CFI_DEVICETYPE_X8 (8 / 8) +#define CFI_DEVICETYPE_X16 (16 / 8) +#define CFI_DEVICETYPE_X32 (32 / 8) + +/* NB: We keep these structures in memory in HOST byteorder, except + * where individually noted. + */ + +/* Basic Query Structure */ +struct cfi_ident { + __u8 qry[3]; + __u16 P_ID; + __u16 P_ADR; + __u16 A_ID; + __u16 A_ADR; + __u8 VccMin; + __u8 VccMax; + __u8 VppMin; + __u8 VppMax; + __u8 WordWriteTimeoutTyp; + __u8 BufWriteTimeoutTyp; + __u8 BlockEraseTimeoutTyp; + __u8 ChipEraseTimeoutTyp; + __u8 WordWriteTimeoutMax; + __u8 BufWriteTimeoutMax; + __u8 BlockEraseTimeoutMax; + __u8 ChipEraseTimeoutMax; + __u8 DevSize; + __u16 InterfaceDesc; + __u16 MaxBufWriteSize; + __u8 NumEraseRegions; + __u32 EraseRegionInfo[0]; /* Not host ordered */ +} __attribute__((packed)); + +/* Extended Query Structure for both PRI and ALT */ + +struct cfi_extquery { + __u8 pri[3]; + __u8 MajorVersion; + __u8 MinorVersion; +} __attribute__((packed)); + +/* Vendor-Specific PRI for Intel/Sharp Extended Command Set (0x0001) */ + +struct cfi_pri_intelext { + __u8 pri[3]; + __u8 MajorVersion; + __u8 MinorVersion; + __u32 FeatureSupport; + __u8 SuspendCmdSupport; + __u16 BlkStatusRegMask; + __u8 VccOptimal; + __u8 VppOptimal; +} __attribute__((packed)); + +struct cfi_pri_query { + __u8 NumFields; + __u32 ProtField[1]; /* Not host ordered */ +} __attribute__((packed)); + +struct cfi_bri_query { + __u8 PageModeReadCap; + __u8 NumFields; + __u32 ConfField[1]; /* Not host ordered */ +} __attribute__((packed)); + +#define P_ID_NONE 0 +#define P_ID_INTEL_EXT 1 +#define P_ID_AMD_STD 2 +#define P_ID_INTEL_STD 3 +#define P_ID_AMD_EXT 4 +#define P_ID_MITSUBISHI_STD 256 +#define P_ID_MITSUBISHI_EXT 257 +#define P_ID_RESERVED 65535 + + +#define CFI_MODE_CFI 0 +#define CFI_MODE_JEDEC 1 + +struct cfi_private { + __u16 cmdset; + void *cmdset_priv; + int interleave; + int device_type; + int cfi_mode; /* Are we a JEDEC device pretending to be CFI? */ + int addr_unlock1; + int addr_unlock2; + int fast_prog; + struct mtd_info *(*cmdset_setup)(struct map_info *); + struct cfi_ident *cfiq; /* For now only one. We insist that all devs + must be of the same type. */ + int mfr, id; + int numchips; + unsigned long chipshift; /* Because they're of the same type */ + const char *im_name; /* inter_module name for cmdset_setup */ + struct flchip chips[0]; /* per-chip data structure for each chip */ +}; + +#define MAX_CFI_CHIPS 8 /* Entirely arbitrary to avoid realloc() */ + +/* + * Returns the command address according to the given geometry. + */ +static inline __u32 cfi_build_cmd_addr(__u32 cmd_ofs, int interleave, int type) +{ + return (cmd_ofs * type) * interleave; +} + +/* + * 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) +{ + __u32 val = 0; + + if (cfi_buswidth_is_1()) { + /* 1 x8 device */ + val = cmd; + } else if (cfi_buswidth_is_2()) { + if (cfi_interleave_is_1()) { + /* 1 x16 device in x16 mode */ + val = cpu_to_cfi16(cmd); + } else if (cfi_interleave_is_2()) { + /* 2 (x8, x16 or x32) devices in x8 mode */ + val = cpu_to_cfi16((cmd << 8) | cmd); + } + } else if (cfi_buswidth_is_4()) { + if (cfi_interleave_is_1()) { + /* 1 x32 device in x32 mode */ + val = cpu_to_cfi32(cmd); + } else if (cfi_interleave_is_2()) { + /* 2 x16 device in x16 mode */ + val = cpu_to_cfi32((cmd << 16) | cmd); + } else if (cfi_interleave_is_4()) { + /* 4 (x8, x16 or x32) devices in x8 mode */ + val = (cmd << 16) | cmd; + val = cpu_to_cfi32((val << 8) | val); + } + } + return val; +} +#define CMD(x) cfi_build_cmd((x), map, cfi) + +/* + * Read a value according to the bus width. + */ + +static inline __u32 cfi_read(struct map_info *map, __u32 addr) +{ + if (cfi_buswidth_is_1()) { + return map->read8(map, addr); + } else if (cfi_buswidth_is_2()) { + return map->read16(map, addr); + } else if (cfi_buswidth_is_4()) { + return map->read32(map, addr); + } else { + return 0; + } +} + +/* + * Write a value according to the bus width. + */ + +static inline void cfi_write(struct map_info *map, __u32 val, __u32 addr) +{ + if (cfi_buswidth_is_1()) { + map->write8(map, val, addr); + } else if (cfi_buswidth_is_2()) { + map->write16(map, val, addr); + } else if (cfi_buswidth_is_4()) { + map->write32(map, val, addr); + } +} + +/* + * Sends a CFI command to a bank of flash for the given geometry. + * + * Returns the offset in flash where the command was written. + * If prev_val is non-null, it will be set to the value at the command address, + * before the command was written. + */ +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) +{ + __u32 val; + __u32 addr = base + cfi_build_cmd_addr(cmd_addr, CFIDEV_INTERLEAVE, type); + + val = cfi_build_cmd(cmd, map, cfi); + + if (prev_val) + *prev_val = cfi_read(map, addr); + + cfi_write(map, val, addr); + + return addr - base; +} + +static inline __u8 cfi_read_query(struct map_info *map, __u32 addr) +{ + if (cfi_buswidth_is_1()) { + return map->read8(map, addr); + } else if (cfi_buswidth_is_2()) { + return cfi16_to_cpu(map->read16(map, addr)); + } else if (cfi_buswidth_is_4()) { + return cfi32_to_cpu(map->read32(map, addr)); + } else { + return 0; + } +} + +static inline void cfi_udelay(int us) +{ +#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,2,0) + if (current->need_resched) { + unsigned long t = us * HZ / 1000000; + if (t < 1) + t = 1; + set_current_state(TASK_UNINTERRUPTIBLE); + schedule_timeout(t); + } + else +#endif + udelay(us); +} +static inline void cfi_spin_lock(spinlock_t *mutex) +{ + spin_lock_bh(mutex); +} + +static inline void cfi_spin_unlock(spinlock_t *mutex) +{ + spin_unlock_bh(mutex); +} + + +#endif /* __MTD_CFI_H__ */ diff --git a/release/src/linux/linux/include/linux/mtd/cfi_endian.h b/release/src/linux/linux/include/linux/mtd/cfi_endian.h new file mode 100644 index 00000000..e6dc67af --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/cfi_endian.h @@ -0,0 +1,51 @@ +/* + * $Id: cfi_endian.h,v 1.1.1.4 2003/10/14 08:09:27 sparq Exp $ + * + */ + +#include <asm/byteorder.h> + +#ifndef CONFIG_MTD_CFI_ADV_OPTIONS + +#define CFI_HOST_ENDIAN + +#else + +#ifdef CONFIG_MTD_CFI_NOSWAP +#define CFI_HOST_ENDIAN +#endif + +#ifdef CONFIG_MTD_CFI_LE_BYTE_SWAP +#define CFI_LITTLE_ENDIAN +#endif + +#ifdef CONFIG_MTD_CFI_BE_BYTE_SWAP +#define CFI_BIG_ENDIAN +#endif + +#endif + +#if defined(CFI_LITTLE_ENDIAN) +#define cpu_to_cfi8(x) (x) +#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 cfi16_to_cpu(x) le16_to_cpu(x) +#define cfi32_to_cpu(x) le32_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 cfi16_to_cpu(x) be16_to_cpu(x) +#define cfi32_to_cpu(x) be32_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 cfi16_to_cpu(x) (x) +#define cfi32_to_cpu(x) (x) +#else +#error No CFI endianness defined +#endif diff --git a/release/src/linux/linux/include/linux/mtd/compatmac.h b/release/src/linux/linux/include/linux/mtd/compatmac.h new file mode 100644 index 00000000..3951b3cd --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/compatmac.h @@ -0,0 +1,202 @@ + +/* + * mtd/include/compatmac.h + * + * $Id: compatmac.h,v 1.1.1.4 2003/10/14 08:09:27 sparq 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/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 <asm/softirq.h> +#include <linux/spinlock.h> +#endif + +#endif /* __LINUX_MTD_COMPATMAC_H__ */ + + diff --git a/release/src/linux/linux/include/linux/mtd/concat.h b/release/src/linux/linux/include/linux/mtd/concat.h new file mode 100644 index 00000000..a63147f9 --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/concat.h @@ -0,0 +1,23 @@ +/* + * MTD device concatenation layer definitions + * + * (C) 2002 Robert Kaiser <rkaiser@sysgo.de> + * + * This code is GPL + * + * $Id: concat.h,v 1.1.1.4 2003/10/14 08:09:27 sparq Exp $ + */ + +#ifndef MTD_CONCAT_H +#define MTD_CONCAT_H + + +struct mtd_info *mtd_concat_create( + struct mtd_info *subdev[], /* subdevices to concatenate */ + int num_devs, /* number of subdevices */ + char *name); /* name for the new device */ + +void mtd_concat_destroy(struct mtd_info *mtd); + +#endif + diff --git a/release/src/linux/linux/include/linux/mtd/doc2000.h b/release/src/linux/linux/include/linux/mtd/doc2000.h new file mode 100644 index 00000000..f07545e9 --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/doc2000.h @@ -0,0 +1,142 @@ + +/* Linux driver for Disk-On-Chip 2000 */ +/* (c) 1999 Machine Vision Holdings, Inc. */ +/* Author: David Woodhouse <dwmw2@mvhi.com> */ +/* $Id: doc2000.h,v 1.1.1.4 2003/10/14 08:09:27 sparq Exp $ */ + +#ifndef __MTD_DOC2000_H__ +#define __MTD_DOC2000_H__ + +#include <linux/mtd/mtd.h> + +#define DoC_Sig1 0 +#define DoC_Sig2 1 + +#define DoC_ChipID 0x1000 +#define DoC_DOCStatus 0x1001 +#define DoC_DOCControl 0x1002 +#define DoC_FloorSelect 0x1003 +#define DoC_CDSNControl 0x1004 +#define DoC_CDSNDeviceSelect 0x1005 +#define DoC_ECCConf 0x1006 +#define DoC_2k_ECCStatus 0x1007 + +#define DoC_CDSNSlowIO 0x100d +#define DoC_ECCSyndrome0 0x1010 +#define DoC_ECCSyndrome1 0x1011 +#define DoC_ECCSyndrome2 0x1012 +#define DoC_ECCSyndrome3 0x1013 +#define DoC_ECCSyndrome4 0x1014 +#define DoC_ECCSyndrome5 0x1015 +#define DoC_AliasResolution 0x101b +#define DoC_ConfigInput 0x101c +#define DoC_ReadPipeInit 0x101d +#define DoC_WritePipeTerm 0x101e +#define DoC_LastDataRead 0x101f +#define DoC_NOP 0x1020 + +#define DoC_Mil_CDSN_IO 0x0800 +#define DoC_2k_CDSN_IO 0x1800 + +/* 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. + * Others use readb/writeb + */ +#if defined(__arm__) +#define ReadDOC_(adr, reg) ((unsigned char)(*(__u32 *)(((unsigned long)adr)+((reg)<<2)))) +#define WriteDOC_(d, adr, reg) do{ *(__u32 *)(((unsigned long)adr)+((reg)<<2)) = (__u32)d; wmb();} while(0) +#define DOC_IOREMAP_LEN 0x8000 +#elif defined(__ppc__) +#define ReadDOC_(adr, reg) ((unsigned char)(*(__u16 *)(((unsigned long)adr)+((reg)<<1)))) +#define WriteDOC_(d, adr, reg) do{ *(__u16 *)(((unsigned long)adr)+((reg)<<1)) = (__u16)d; wmb();} while(0) +#define DOC_IOREMAP_LEN 0x4000 +#else +#define ReadDOC_(adr, reg) readb(((unsigned long)adr) + (reg)) +#define WriteDOC_(d, adr, reg) writeb(d, ((unsigned long)adr) + (reg)) +#define DOC_IOREMAP_LEN 0x2000 + +#endif + +#if defined(__i386__) || defined(__x86_64__) +#define USE_MEMCPY +#endif + +/* These are provided to directly use the DoC_xxx defines */ +#define ReadDOC(adr, reg) ReadDOC_(adr,DoC_##reg) +#define WriteDOC(d, adr, reg) WriteDOC_(d,adr,DoC_##reg) + +#define DOC_MODE_RESET 0 +#define DOC_MODE_NORMAL 1 +#define DOC_MODE_RESERVED1 2 +#define DOC_MODE_RESERVED2 3 + +#define DOC_MODE_MDWREN 4 +#define DOC_MODE_CLR_ERR 0x80 + +#define DOC_ChipID_Doc2k 0x20 +#define DOC_ChipID_DocMil 0x30 + +#define CDSN_CTRL_FR_B 0x80 +#define CDSN_CTRL_ECC_IO 0x20 +#define CDSN_CTRL_FLASH_IO 0x10 +#define CDSN_CTRL_WP 0x08 +#define CDSN_CTRL_ALE 0x04 +#define CDSN_CTRL_CLE 0x02 +#define CDSN_CTRL_CE 0x01 + +#define DOC_ECC_RESET 0 +#define DOC_ECC_ERROR 0x80 +#define DOC_ECC_RW 0x20 +#define DOC_ECC__EN 0x08 +#define DOC_TOGGLE_BIT 0x04 +#define DOC_ECC_RESV 0x02 +#define DOC_ECC_IGNORE 0x01 + +/* 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) + +struct Nand { + char floor, chip; + unsigned long curadr; + unsigned char curmode; + /* Also some erase/write/pipeline info when we get that far */ +}; + +#define MAX_FLOORS 4 +#define MAX_CHIPS 4 + +#define MAX_FLOORS_MIL 4 +#define MAX_CHIPS_MIL 1 + +#define ADDR_COLUMN 1 +#define ADDR_PAGE 2 +#define ADDR_COLUMN_PAGE 3 + +struct DiskOnChip { + unsigned long physadr; + unsigned long virtadr; + unsigned long totlen; + char ChipID; /* Type of DiskOnChip */ + int ioreg; + + unsigned long mfr; /* Flash IDs - only one type of flash per device */ + unsigned long id; + int chipshift; + char page256; + char pageadrlen; + unsigned long erasesize; + + int curfloor; + int curchip; + + int numchips; + struct Nand *chips; + struct mtd_info *nextdoc; + struct semaphore lock; +}; + +int doc_decode_ecc(unsigned char sector[512], unsigned char ecc1[6]); + +#endif /* __MTD_DOC2000_H__ */ diff --git a/release/src/linux/linux/include/linux/mtd/flashchip.h b/release/src/linux/linux/include/linux/mtd/flashchip.h new file mode 100644 index 00000000..1d7738ad --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/flashchip.h @@ -0,0 +1,70 @@ + +/* + * struct flchip definition + * + * Contains information about the location and state of a given flash device + * + * (C) 2000 Red Hat. GPLd. + * + * $Id: flashchip.h,v 1.1.1.4 2003/10/14 08:09:27 sparq Exp $ + * + */ + +#ifndef __MTD_FLASHCHIP_H__ +#define __MTD_FLASHCHIP_H__ + +/* For spinlocks. sched.h includes spinlock.h from whichever directory it + * happens to be in - so we don't have to care whether we're on 2.2, which + * has asm/spinlock.h, or 2.4, which has linux/spinlock.h + */ +#include <linux/sched.h> + +typedef enum { + FL_READY, + FL_STATUS, + FL_CFI_QUERY, + FL_JEDEC_QUERY, + FL_ERASING, + FL_ERASE_SUSPENDING, + FL_ERASE_SUSPENDED, + FL_WRITING, + FL_WRITING_TO_BUFFER, + FL_WRITE_SUSPENDING, + FL_WRITE_SUSPENDED, + FL_PM_SUSPENDED, + FL_SYNCING, + FL_UNLOADING, + FL_LOCKING, + FL_UNLOCKING, + FL_UNKNOWN +} flstate_t; + + + +/* NOTE: confusingly, this can be used to refer to more than one chip at a time, + if they're interleaved. */ + +struct flchip { + unsigned long start; /* Offset within the map */ + // unsigned long len; + /* We omit len for now, because when we group them together + we insist that they're all of the same size, and the chip size + is held in the next level up. If we get more versatile later, + it'll make it a damn sight harder to find which chip we want from + a given offset, and we'll want to add the per-chip length field + back in. + */ + flstate_t state; + flstate_t oldstate; + 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 + to be ready */ + int word_write_time; + int buffer_write_time; + int erase_time; +}; + + + +#endif /* __MTD_FLASHCHIP_H__ */ diff --git a/release/src/linux/linux/include/linux/mtd/ftl.h b/release/src/linux/linux/include/linux/mtd/ftl.h new file mode 100644 index 00000000..702b26eb --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/ftl.h @@ -0,0 +1,76 @@ +/* + * $Id: ftl.h,v 1.1.1.4 2003/10/14 08:09:27 sparq Exp $ + * + * Derived from (and probably identical to): + * ftl.h 1.7 1999/10/25 20:23:17 + * + * The contents of this file are subject to the Mozilla Public License + * Version 1.1 (the "License"); you may not use this file except in + * compliance with the License. You may obtain a copy of the License + * at http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" + * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See + * the License for the specific language governing rights and + * limitations under the License. + * + * The initial developer of the original code is David A. Hinds + * <dahinds@users.sourceforge.net>. Portions created by David A. Hinds + * are Copyright (C) 1999 David A. Hinds. All Rights Reserved. + * + * Alternatively, the contents of this file may be used under the + * terms of the GNU General Public License version 2 (the "GPL"), in + * which case the provisions of the GPL are applicable instead of the + * above. If you wish to allow the use of your version of this file + * only under the terms of the GPL and not to allow others to use + * your version of this file under the MPL, indicate your decision by + * deleting the provisions above and replace them with the notice and + * other provisions required by the GPL. If you do not delete the + * provisions above, a recipient may use your version of this file + * under either the MPL or the GPL. + */ + +#ifndef _LINUX_FTL_H +#define _LINUX_FTL_H + +typedef struct erase_unit_header_t { + u_int8_t LinkTargetTuple[5]; + u_int8_t DataOrgTuple[10]; + u_int8_t NumTransferUnits; + u_int32_t EraseCount; + u_int16_t LogicalEUN; + u_int8_t BlockSize; + u_int8_t EraseUnitSize; + u_int16_t FirstPhysicalEUN; + u_int16_t NumEraseUnits; + u_int32_t FormattedSize; + u_int32_t FirstVMAddress; + u_int16_t NumVMPages; + u_int8_t Flags; + u_int8_t Code; + u_int32_t SerialNumber; + u_int32_t AltEUHOffset; + u_int32_t BAMOffset; + u_int8_t Reserved[12]; + u_int8_t EndTuple[2]; +} erase_unit_header_t; + +/* Flags in erase_unit_header_t */ +#define HIDDEN_AREA 0x01 +#define REVERSE_POLARITY 0x02 +#define DOUBLE_BAI 0x04 + +/* Definitions for block allocation information */ + +#define BLOCK_FREE(b) ((b) == 0xffffffff) +#define BLOCK_DELETED(b) (((b) == 0) || ((b) == 0xfffffffe)) + +#define BLOCK_TYPE(b) ((b) & 0x7f) +#define BLOCK_ADDRESS(b) ((b) & ~0x7f) +#define BLOCK_NUMBER(b) ((b) >> 9) +#define BLOCK_CONTROL 0x30 +#define BLOCK_DATA 0x40 +#define BLOCK_REPLACEMENT 0x60 +#define BLOCK_BAD 0x70 + +#endif /* _LINUX_FTL_H */ diff --git a/release/src/linux/linux/include/linux/mtd/gen_probe.h b/release/src/linux/linux/include/linux/mtd/gen_probe.h new file mode 100644 index 00000000..33e6f861 --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/gen_probe.h @@ -0,0 +1,23 @@ +/* + * (C) 2001, 2001 Red Hat, Inc. + * GPL'd + * $Id: gen_probe.h,v 1.1.1.4 2003/10/14 08:09:27 sparq Exp $ + */ + +#ifndef __LINUX_MTD_GEN_PROBE_H__ +#define __LINUX_MTD_GEN_PROBE_H__ + +#include <linux/mtd/flashchip.h> +#include <linux/mtd/map.h> +#include <linux/mtd/cfi.h> + +struct chip_probe { + char *name; + int (*probe_chip)(struct map_info *map, __u32 base, + struct flchip *chips, struct cfi_private *cfi); + +}; + +struct mtd_info *mtd_do_chip_probe(struct map_info *map, struct chip_probe *cp); + +#endif /* __LINUX_MTD_GEN_PROBE_H__ */ diff --git a/release/src/linux/linux/include/linux/mtd/iflash.h b/release/src/linux/linux/include/linux/mtd/iflash.h new file mode 100644 index 00000000..bf058ac7 --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/iflash.h @@ -0,0 +1,98 @@ +/* $Id: iflash.h,v 1.1.1.4 2003/10/14 08:09:27 sparq Exp $ */ + +#ifndef __MTD_IFLASH_H__ +#define __MTD_IFLASH_H__ + +/* Extended CIS registers for Series 2 and 2+ cards */ +/* The registers are all offsets from 0x4000 */ +#define CISREG_CSR 0x0100 +#define CISREG_WP 0x0104 +#define CISREG_RDYBSY 0x0140 + +/* Extended CIS registers for Series 2 cards */ +#define CISREG_SLEEP 0x0118 +#define CISREG_RDY_MASK 0x0120 +#define CISREG_RDY_STATUS 0x0130 + +/* Extended CIS registers for Series 2+ cards */ +#define CISREG_VCR 0x010c + +/* Card Status Register */ +#define CSR_SRESET 0x20 /* Soft reset */ +#define CSR_CMWP 0x10 /* Common memory write protect */ +#define CSR_PWRDOWN 0x08 /* Power down status */ +#define CSR_CISWP 0x04 /* Common memory CIS WP */ +#define CSR_WP 0x02 /* Mechanical write protect */ +#define CSR_READY 0x01 /* Ready/busy status */ + +/* Write Protection Register */ +#define WP_BLKEN 0x04 /* Enable block locking */ +#define WP_CMWP 0x02 /* Common memory write protect */ +#define WP_CISWP 0x01 /* Common memory CIS WP */ + +/* Voltage Control Register */ +#define VCR_VCC_LEVEL 0x80 /* 0 = 5V, 1 = 3.3V */ +#define VCR_VPP_VALID 0x02 /* Vpp Valid */ +#define VCR_VPP_GEN 0x01 /* Integrated Vpp generator */ + +/* Ready/Busy Mode Register */ +#define RDYBSY_RACK 0x02 /* Ready acknowledge */ +#define RDYBSY_MODE 0x01 /* 1 = high performance */ + +#define LOW(x) ((x) & 0xff) + +/* 28F008SA-Compatible Command Set */ +#define IF_READ_ARRAY 0xffff +#define IF_INTEL_ID 0x9090 +#define IF_READ_CSR 0x7070 +#define IF_CLEAR_CSR 0x5050 +#define IF_WRITE 0x4040 +#define IF_BLOCK_ERASE 0x2020 +#define IF_ERASE_SUSPEND 0xb0b0 +#define IF_CONFIRM 0xd0d0 + +/* 28F016SA Performance Enhancement Commands */ +#define IF_READ_PAGE 0x7575 +#define IF_PAGE_SWAP 0x7272 +#define IF_SINGLE_LOAD 0x7474 +#define IF_SEQ_LOAD 0xe0e0 +#define IF_PAGE_WRITE 0x0c0c +#define IF_RDY_MODE 0x9696 +#define IF_RDY_LEVEL 0x0101 +#define IF_RDY_PULSE_WRITE 0x0202 +#define IF_RDY_PULSE_ERASE 0x0303 +#define IF_RDY_DISABLE 0x0404 +#define IF_LOCK_BLOCK 0x7777 +#define IF_UPLOAD_STATUS 0x9797 +#define IF_READ_ESR 0x7171 +#define IF_ERASE_UNLOCKED 0xa7a7 +#define IF_SLEEP 0xf0f0 +#define IF_ABORT 0x8080 +#define IF_UPLOAD_DEVINFO 0x9999 + +/* Definitions for Compatible Status Register */ +#define CSR_WR_READY 0x8080 /* Write state machine status */ +#define CSR_ERA_SUSPEND 0x4040 /* Erase suspend status */ +#define CSR_ERA_ERR 0x2020 /* Erase status */ +#define CSR_WR_ERR 0x1010 /* Data write status */ +#define CSR_VPP_LOW 0x0808 /* Vpp status */ + +/* Definitions for Global Status Register */ +#define GSR_WR_READY 0x8080 /* Write state machine status */ +#define GSR_OP_SUSPEND 0x4040 /* Operation suspend status */ +#define GSR_OP_ERR 0x2020 /* Device operation status */ +#define GSR_SLEEP 0x1010 /* Device sleep status */ +#define GSR_QUEUE_FULL 0x0808 /* Queue status */ +#define GSR_PAGE_AVAIL 0x0404 /* Page buffer available status */ +#define GSR_PAGE_READY 0x0202 /* Page buffer status */ +#define GSR_PAGE_SELECT 0x0101 /* Page buffer select status */ + +/* Definitions for Block Status Register */ +#define BSR_READY 0x8080 /* Block status */ +#define BSR_UNLOCK 0x4040 /* Block lock status */ +#define BSR_FAILED 0x2020 /* Block operation status */ +#define BSR_ABORTED 0x1010 /* Operation abort status */ +#define BSR_QUEUE_FULL 0x0808 /* Queue status */ +#define BSR_VPP_LOW 0x0404 /* Vpp status */ + +#endif /* __MTD_IFLASH_H__ */ diff --git a/release/src/linux/linux/include/linux/mtd/jedec.h b/release/src/linux/linux/include/linux/mtd/jedec.h new file mode 100644 index 00000000..71bb6540 --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/jedec.h @@ -0,0 +1,67 @@ + +/* JEDEC Flash Interface. + * This is an older type of interface for self programming flash. It is + * commonly use in older AMD chips and is obsolete compared with CFI. + * It is called JEDEC because the JEDEC association distributes the ID codes + * for the chips. + * + * See the AMD flash databook for information on how to operate the interface. + * + * $Id: jedec.h,v 1.1.1.4 2003/10/14 08:09:27 sparq 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 + +// Listing of all supported chips and their information +struct JEDECTable +{ + __u16 jedec; + char *name; + unsigned long size; + unsigned long sectorsize; + __u32 capabilities; +}; + +// JEDEC being 0 is the end of the chip array +struct jedec_flash_chip +{ + __u16 jedec; + unsigned long size; + unsigned long sectorsize; + + // *(__u8*)(base + (adder << addrshift)) = data << datashift + // Address size = size << addrshift + unsigned long base; // Byte 0 of the flash, will be unaligned + unsigned int datashift; // Useful for 32bit/16bit accesses + unsigned int addrshift; + unsigned long offset; // linerized start. base==offset for unbanked, uninterleaved flash + + __u32 capabilities; + + // These markers are filled in by the flash_chip_scan function + unsigned long start; + unsigned long length; +}; + +struct jedec_private +{ + unsigned long size; // Total size of all the devices + + /* Bank handling. If sum(bank_fill) == size then this is linear flash. + Otherwise the mapping has holes in it. bank_fill may be used to + find the holes, but in the common symetric case + bank_fill[0] == bank_fill[*], thus addresses may be computed + mathmatically. bank_fill must be powers of two */ + unsigned is_banked; + unsigned long bank_fill[MAX_JEDEC_CHIPS]; + + struct jedec_flash_chip chips[MAX_JEDEC_CHIPS]; +}; + +#endif diff --git a/release/src/linux/linux/include/linux/mtd/map.h b/release/src/linux/linux/include/linux/mtd/map.h new file mode 100644 index 00000000..1d95d670 --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/map.h @@ -0,0 +1,94 @@ + +/* Overhauled routines for dealing with different mmap regions of flash */ +/* $Id: map.h,v 1.1.1.4 2003/10/14 08:09:27 sparq 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> + +/* 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 + paging etc. correctly if your device needs it. Then you pass it off + to a chip driver which deals with a mapped device - generally either + do_cfi_probe() or do_ram_probe(), either of which will return a + struct mtd_info if they liked what they saw. At which point, you + fill in the mtd->module with your own module address, and register + it. + + The mtd->priv field will point to the struct map_info, and any further + private data required by the chip driver is linked from the + mtd->priv->fldrv_priv field. This allows the map driver to get at + the destructor function map->fldrv_destroy() when it's tired + of living. +*/ + +struct map_info { + char *name; + unsigned long size; + 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); + /* 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 (*copy_to)(struct map_info *, unsigned long, const void *, ssize_t); + + 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 *); + struct module *module; + char *name; + struct list_head list; +}; + +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); + + +/* + * 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) +{ + struct map_info *map = mtd->priv; + + if (map->fldrv->destroy) + map->fldrv->destroy(mtd); +#ifdef CONFIG_MODULES + if (map->fldrv->module) + __MOD_DEC_USE_COUNT(map->fldrv->module); +#endif + kfree(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) + +#endif /* __LINUX_MTD_MAP_H__ */ diff --git a/release/src/linux/linux/include/linux/mtd/mtd.h b/release/src/linux/linux/include/linux/mtd/mtd.h new file mode 100644 index 00000000..dcf86b4e --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/mtd.h @@ -0,0 +1,277 @@ + +/* $Id: mtd.h,v 1.1.1.4 2003/10/14 08:09:27 sparq Exp $ */ + +#ifndef __MTD_MTD_H__ +#define __MTD_MTD_H__ + +#ifdef __KERNEL__ + +#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> + +#endif /* __KERNEL__ */ + +struct erase_info_user { + u_int32_t start; + u_int32_t length; +}; + +struct mtd_oob_buf { + u_int32_t start; + u_int32_t length; + unsigned char *ptr; +}; + + +#define MTD_CHAR_MAJOR 90 +#define MTD_BLOCK_MAJOR 31 +#define MAX_MTD_DEVICES 16 + + + +#define MTD_ABSENT 0 +#define MTD_RAM 1 +#define MTD_ROM 2 +#define MTD_NORFLASH 3 +#define MTD_NANDFLASH 4 +#define MTD_PEROM 5 +#define MTD_OTHER 14 +#define MTD_UNKNOWN 15 + + + +#define MTD_CLEAR_BITS 1 // Bits can be cleared (flash) +#define MTD_SET_BITS 2 // Bits can be set +#define MTD_ERASEABLE 4 // Has an erase function +#define MTD_WRITEB_WRITEABLE 8 // Direct IO is possible +#define MTD_VOLATILE 16 // Set for RAMs +#define MTD_XIP 32 // eXecute-In-Place possible +#define MTD_OOB 64 // Out-of-band data (NAND flash) +#define MTD_ECC 128 // Device capable of automatic ECC + +// Some common devices / combinations of capabilities +#define MTD_CAP_ROM 0 +#define MTD_CAP_RAM (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEB_WRITEABLE) +#define MTD_CAP_NORFLASH (MTD_CLEAR_BITS|MTD_ERASEABLE) +#define MTD_CAP_NANDFLASH (MTD_CLEAR_BITS|MTD_ERASEABLE|MTD_OOB) +#define MTD_WRITEABLE (MTD_CLEAR_BITS|MTD_SET_BITS) + + +// Types of automatic ECC/Checksum available +#define MTD_ECC_NONE 0 // No automatic ECC available +#define MTD_ECC_RS_DiskOnChip 1 // Automatic ECC on DiskOnChip +#define MTD_ECC_SW 2 // SW ECC for Toshiba & Samsung devices + +struct mtd_info_user { + u_char type; + u_int32_t flags; + u_int32_t size; // Total size of the MTD + u_int32_t erasesize; + u_int32_t oobblock; // Size of OOB blocks (e.g. 512) + u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) + u_int32_t ecctype; + u_int32_t eccsize; +}; + +struct region_info_user { + u_int32_t offset; /* At which this region starts, + * from the beginning of the MTD */ + u_int32_t erasesize; /* For this region */ + u_int32_t numblocks; /* Number of blocks in this region */ + u_int32_t regionindex; +}; + +#define MEMGETINFO _IOR('M', 1, struct mtd_info_user) +#define MEMERASE _IOW('M', 2, struct erase_info_user) +#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf) +#define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf) +#define MEMLOCK _IOW('M', 5, struct erase_info_user) +#define MEMUNLOCK _IOW('M', 6, struct erase_info_user) +#define MEMGETREGIONCOUNT _IOR('M', 7, int) +#define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user) + +#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; + + /* User-space ioctl definitions */ + + +#else /* __KERNEL__ */ + + +#define MTD_ERASE_PENDING 0x01 +#define MTD_ERASING 0x02 +#define MTD_ERASE_SUSPEND 0x04 +#define MTD_ERASE_DONE 0x08 +#define MTD_ERASE_FAILED 0x10 + +struct erase_info { + struct mtd_info *mtd; + u_int32_t addr; + u_int32_t len; + u_long time; + u_long retries; + u_int dev; + u_int cell; + void (*callback) (struct erase_info *self); + u_long priv; + u_char state; + struct erase_info *next; +}; + +struct mtd_erase_region_info { + u_int32_t offset; /* At which this region starts, from the beginning of the MTD */ + u_int32_t erasesize; /* For this region */ + u_int32_t numblocks; /* Number of blocks of erasesize in this region */ +}; + +struct mtd_info { + u_char type; + u_int32_t flags; + u_int32_t size; // Total size of the MTD + + /* "Major" erase size for the device. Naïve users may take this + * to be the only erase size available, or may use the more detailed + * information below if they desire + */ + u_int32_t erasesize; + + u_int32_t oobblock; // Size of OOB blocks (e.g. 512) + u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) + u_int32_t ecctype; + u_int32_t eccsize; + + // Kernel-only stuff starts here. + char *name; + int index; + + /* Data for variable erase regions. If numeraseregions is zero, + * it means that the whole device has erasesize as given above. + */ + int numeraseregions; + struct mtd_erase_region_info *eraseregions; + + /* This really shouldn't be here. It can go away in 2.5 */ + u_int32_t bank_size; + + 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); + + + 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_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); + + /* 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 (*writev) (struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen); + + /* Sync */ + void (*sync) (struct mtd_info *mtd); + + /* Chip-supported device locking */ + int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len); + int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len); + + /* Power Management functions */ + int (*suspend) (struct mtd_info *mtd); + void (*resume) (struct mtd_info *mtd); + + void *priv; +}; + + + /* Kernel-side ioctl definitions */ + +extern int add_mtd_device(struct mtd_info *mtd); +extern int del_mtd_device (struct mtd_info *mtd); + +extern struct mtd_info *__get_mtd_device(struct mtd_info *mtd, int num); + +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 && ret->module && !try_inc_mod_count(ret->module)) + return NULL; + + return ret; +} + +static inline void put_mtd_device(struct mtd_info *mtd) +{ + if (mtd->module) + __MOD_DEC_USE_COUNT(mtd->module); +} + + +struct mtd_notifier { + void (*add)(struct mtd_info *mtd); + void (*remove)(struct mtd_info *mtd); + struct mtd_notifier *next; +}; + + +extern void register_mtd_user (struct mtd_notifier *new); +extern int unregister_mtd_user (struct mtd_notifier *old); + + +#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) +#define MTD_READ(mtd, args...) (*(mtd->read))(mtd, args) +#define MTD_WRITE(mtd, args...) (*(mtd->write))(mtd, args) +#define MTD_READV(mtd, args...) (*(mtd->readv))(mtd, args) +#define MTD_WRITEV(mtd, args...) (*(mtd->writev))(mtd, args) +#define MTD_READECC(mtd, args...) (*(mtd->read_ecc))(mtd, args) +#define MTD_WRITEECC(mtd, args...) (*(mtd->write_ecc))(mtd, args) +#define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args) +#define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args) +#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0) +#endif /* MTDC */ + +/* + * Debugging macro and defines + */ +#define MTD_DEBUG_LEVEL0 (0) /* Quiet */ +#define MTD_DEBUG_LEVEL1 (1) /* Audible */ +#define MTD_DEBUG_LEVEL2 (2) /* Loud */ +#define MTD_DEBUG_LEVEL3 (3) /* Noisy */ + +#ifdef CONFIG_MTD_DEBUG +#define DEBUG(n, args...) \ + if (n <= CONFIG_MTD_DEBUG_VERBOSE) { \ + printk(KERN_INFO args); \ + } +#else /* CONFIG_MTD_DEBUG */ +#define DEBUG(n, args...) +#endif /* CONFIG_MTD_DEBUG */ + +#endif /* __KERNEL__ */ + +#endif /* __MTD_MTD_H__ */ diff --git a/release/src/linux/linux/include/linux/mtd/nand.h b/release/src/linux/linux/include/linux/mtd/nand.h new file mode 100644 index 00000000..3b8d95c0 --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/nand.h @@ -0,0 +1,154 @@ +/* + * linux/include/linux/mtd/nand.h + * + * Copyright (c) 2000 David Woodhouse <dwmw2@mvhi.com> + * Steven J. Hill <sjhill@cotw.com> + * + * $Id: nand.h,v 1.1.1.4 2003/10/14 08:09:27 sparq 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 + * 10-24-2000 SJH Added prototype for 'nand_scan' function + */ +#ifndef __LINUX_MTD_NAND_H +#define __LINUX_MTD_NAND_H + +#include <linux/config.h> +#include <linux/sched.h> + +/* + * Searches for a NAND device + */ +extern int nand_scan (struct mtd_info *mtd); + +/* + * Standard NAND flash commands + */ +#define NAND_CMD_READ0 0 +#define NAND_CMD_READ1 1 +#define NAND_CMD_PAGEPROG 0x10 +#define NAND_CMD_READOOB 0x50 +#define NAND_CMD_ERASE1 0x60 +#define NAND_CMD_STATUS 0x70 +#define NAND_CMD_SEQIN 0x80 +#define NAND_CMD_READID 0x90 +#define NAND_CMD_ERASE2 0xd0 +#define NAND_CMD_RESET 0xff + +/* + * Enumeration for NAND flash chip state + */ +typedef enum { + FL_READY, + FL_READING, + FL_WRITING, + FL_ERASING, + 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 + * + * CTRL_ADDR - address where ALE, CLE and CE control bits are accessed + * + * CLE - location in control word for Command Latch Enable bit + * + * ALE - location in control word for Address Latch Enable bit + * + * NCE - location in control word for nChip Enable bit + * + * chip_lock - spinlock used to protect access to this structure + * + * wq - wait queue to sleep on if a NAND operation is in progress + * + * state - give the current state of the NAND device + * + * page_shift - number of address bits in a page (column address bits) + * + * 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 + * + * reserved - padding to make structure fall on word boundary if + * when ECC is in use + */ +struct nand_chip { + unsigned long IO_ADDR; + unsigned long CTRL_ADDR; + unsigned int CLE; + unsigned int ALE; + unsigned int NCE; + 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 Flash Manufacturer ID Codes + */ +#define NAND_MFR_TOSHIBA 0x98 +#define NAND_MFR_SAMSUNG 0xec + +/* + * NAND Flash Device ID Structure + * + * Structure overview: + * + * name - Complete name of device + * + * manufacture_id - manufacturer ID code of device. + * + * model_id - model ID code of device. + * + * chipshift - total number of address bits for the device which + * is used to calculate address offsets and the total + * number of bytes the device is capable of. + * + * page256 - denotes if flash device has 256 byte pages or not. + * + * pageadrlen - number of bytes minus one needed to hold the + * complete address into the flash array. Keep in + * mind that when a read or write is done to a + * specific address, the address is input serially + * 8 bits at a time. This structure member is used + * by the read/write routines as a loop index for + * shifting the address out 8 bits at a time. + * + * erasesize - size of an erase block in the flash device. + */ +struct nand_flash_dev { + char * name; + int manufacture_id; + int model_id; + int chipshift; + char page256; + char pageadrlen; + unsigned long erasesize; +}; + +#endif /* __LINUX_MTD_NAND_H */ diff --git a/release/src/linux/linux/include/linux/mtd/nand_ecc.h b/release/src/linux/linux/include/linux/mtd/nand_ecc.h new file mode 100644 index 00000000..2392e6f6 --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/nand_ecc.h @@ -0,0 +1,28 @@ +/* + * drivers/mtd/nand_ecc.h + * + * Copyright (C) 2000 Steven J. Hill (sjhill@cotw.com) + * + * $Id: nand_ecc.h,v 1.1.1.4 2003/10/14 08:09:27 sparq Exp $ + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This file is the header for the ECC algorithm. + */ + +/* + * Creates non-inverted ECC code from line parity + */ +void nand_trans_result(u_char reg2, u_char reg3, u_char *ecc_code); + +/* + * Calculate 3 byte ECC code for 256 byte block + */ +void nand_calculate_ecc (const u_char *dat, u_char *ecc_code); + +/* + * Detect and correct a 1 bit error for 256 byte block + */ +int nand_correct_data (u_char *dat, u_char *read_ecc, u_char *calc_ecc); diff --git a/release/src/linux/linux/include/linux/mtd/nand_ids.h b/release/src/linux/linux/include/linux/mtd/nand_ids.h new file mode 100644 index 00000000..87caee01 --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/nand_ids.h @@ -0,0 +1,52 @@ +/* + * 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.1.4 2003/10/14 08:09:27 sparq 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/release/src/linux/linux/include/linux/mtd/nftl.h b/release/src/linux/linux/include/linux/mtd/nftl.h new file mode 100644 index 00000000..80c8d89b --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/nftl.h @@ -0,0 +1,122 @@ + +/* Defines for NAND Flash Translation Layer */ +/* (c) 1999 Machine Vision Holdings, Inc. */ +/* Author: David Woodhouse <dwmw2@mvhi.com> */ +/* $Id: nftl.h,v 1.1.1.4 2003/10/14 08:09:27 sparq Exp $ */ + +#ifndef __MTD_NFTL_H__ +#define __MTD_NFTL_H__ + +#ifndef __BOOT__ +#include <linux/mtd/mtd.h> +#endif + +/* Block Control Information */ + +struct nftl_bci { + unsigned char ECCSig[6]; + __u8 Status; + __u8 Status1; +}__attribute__((packed)); + +/* Unit Control Information */ + +struct nftl_uci0 { + __u16 VirtUnitNum; + __u16 ReplUnitNum; + __u16 SpareVirtUnitNum; + __u16 SpareReplUnitNum; +} __attribute__((packed)); + +struct nftl_uci1 { + __u32 WearInfo; + __u16 EraseMark; + __u16 EraseMark1; +} __attribute__((packed)); + +struct nftl_uci2 { + __u16 FoldMark; + __u16 FoldMark1; + __u32 unused; +} __attribute__((packed)); + +union nftl_uci { + struct nftl_uci0 a; + struct nftl_uci1 b; + struct nftl_uci2 c; +}; + +struct nftl_oob { + struct nftl_bci b; + union nftl_uci u; +}; + +/* NFTL Media Header */ + +struct NFTLMediaHeader { + char DataOrgID[6]; + __u16 NumEraseUnits; + __u16 FirstPhysicalEUN; + __u32 FormattedSize; + unsigned char UnitSizeFactor; +} __attribute__((packed)); + +#define MAX_ERASE_ZONES (8192 - 512) + +#define ERASE_MARK 0x3c69 +#define SECTOR_FREE 0xff +#define SECTOR_USED 0x55 +#define SECTOR_IGNORE 0x11 +#define SECTOR_DELETED 0x00 + +#define FOLD_MARK_IN_PROGRESS 0x5555 + +#define ZONE_GOOD 0xff +#define ZONE_BAD_ORIGINAL 0 +#define ZONE_BAD_MARKED 7 + +#ifdef __KERNEL__ + +/* these info are used in ReplUnitTable */ +#define BLOCK_NIL 0xffff /* last block of a chain */ +#define BLOCK_FREE 0xfffe /* free block */ +#define BLOCK_NOTEXPLORED 0xfffd /* non explored block, only used during mounting */ +#define BLOCK_RESERVED 0xfffc /* bios block or bad block */ + +struct NFTLrecord { + struct mtd_info *mtd; + struct semaphore mutex; + __u16 MediaUnit, SpareMediaUnit; + __u32 EraseSize; + struct NFTLMediaHeader MediaHdr; + int usecount; + unsigned char heads; + unsigned char sectors; + unsigned short cylinders; + __u16 numvunits; + __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; +}; + +int NFTL_mount(struct NFTLrecord *s); +int NFTL_formatblock(struct NFTLrecord *s, int block); + +#ifndef NFTL_MAJOR +#define NFTL_MAJOR 93 +#endif + +#define MAX_NFTLS 16 +#define MAX_SECTORS_PER_UNIT 32 +#define NFTL_PARTN_BITS 4 + +#endif /* __KERNEL__ */ + +#endif /* __MTD_NFTL_H__ */ diff --git a/release/src/linux/linux/include/linux/mtd/partitions.h b/release/src/linux/linux/include/linux/mtd/partitions.h new file mode 100644 index 00000000..7c3671d7 --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/partitions.h @@ -0,0 +1,56 @@ +/* + * MTD partitioning layer definitions + * + * (C) 2000 Nicolas Pitre <nico@cam.org> + * + * This code is GPL + * + * $Id: partitions.h,v 1.1.1.4 2003/10/14 08:09:27 sparq Exp $ + */ + +#ifndef MTD_PARTITIONS_H +#define MTD_PARTITIONS_H + +#include <linux/types.h> + + +/* + * Partition definition structure: + * + * An array of struct partition is passed along with a MTD object to + * add_mtd_partitions() to create them. + * + * For each partition, these fields are available: + * name: string that will be used to label the partition's MTD device. + * size: the partition size; if defined as MTDPART_SIZ_FULL, the partition + * 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; 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 (e.g. use MTDPART_OFS_NEXTBLK). + */ + +struct mtd_partition { + 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 */ + 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) + + +int add_mtd_partitions(struct mtd_info *, struct mtd_partition *, int); +int del_mtd_partitions(struct mtd_info *); + +#endif + diff --git a/release/src/linux/linux/include/linux/mtd/pmc551.h b/release/src/linux/linux/include/linux/mtd/pmc551.h new file mode 100644 index 00000000..6b60f3e3 --- /dev/null +++ b/release/src/linux/linux/include/linux/mtd/pmc551.h @@ -0,0 +1,79 @@ +/* + * $Id: pmc551.h,v 1.1.1.4 2003/10/14 08:09:27 sparq Exp $ + * + * PMC551 PCI Mezzanine Ram Device + * + * Author: + * Mark Ferrell + * Copyright 1999,2000 Nortel Networks + * + * License: + * As part of this driver was derrived from the slram.c driver it falls + * under the same license, which is GNU General Public License v2 + */ + +#ifndef __MTD_PMC551_H__ +#define __MTD_PMC551_H__ + +#include <linux/mtd/mtd.h> + +#define PMC551_VERSION "$Id: pmc551.h,v 1.1.1.4 2003/10/14 08:09:27 sparq Exp $\n"\ + "Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n" + +/* + * Our personal and private information + */ +struct mypriv { + struct pci_dev *dev; + u_char *start; + u32 base_map0; + u32 curr_map0; + u32 asize; + struct mtd_info *nextpmc551; +}; + +/* + * Function Prototypes + */ +static int pmc551_erase(struct mtd_info *, struct erase_info *); +static void pmc551_unpoint(struct mtd_info *, u_char *); +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 *); + + +/* + * Define the PCI ID's if the kernel doesn't define them for us + */ +#ifndef PCI_VENDOR_ID_V3_SEMI +#define PCI_VENDOR_ID_V3_SEMI 0x11b0 +#endif + +#ifndef PCI_DEVICE_ID_V3_SEMI_V370PDC +#define PCI_DEVICE_ID_V3_SEMI_V370PDC 0x0200 +#endif + + +#define PMC551_PCI_MEM_MAP0 0x50 +#define PMC551_PCI_MEM_MAP1 0x54 +#define PMC551_PCI_MEM_MAP_MAP_ADDR_MASK 0x3ff00000 +#define PMC551_PCI_MEM_MAP_APERTURE_MASK 0x000000f0 +#define PMC551_PCI_MEM_MAP_REG_EN 0x00000002 +#define PMC551_PCI_MEM_MAP_ENABLE 0x00000001 + +#define PMC551_SDRAM_MA 0x60 +#define PMC551_SDRAM_CMD 0x62 +#define PMC551_DRAM_CFG 0x64 +#define PMC551_SYS_CTRL_REG 0x78 + +#define PMC551_DRAM_BLK0 0x68 +#define PMC551_DRAM_BLK1 0x6c +#define PMC551_DRAM_BLK2 0x70 +#define PMC551_DRAM_BLK3 0x74 +#define PMC551_DRAM_BLK_GET_SIZE(x) (524288<<((x>>4)&0x0f)) +#define PMC551_DRAM_BLK_SET_COL_MUX(x,v) (((x) & ~0x00007000) | (((v) & 0x7) << 12)) +#define PMC551_DRAM_BLK_SET_ROW_MUX(x,v) (((x) & ~0x00000f00) | (((v) & 0xf) << 8)) + + +#endif /* __MTD_PMC551_H__ */ + |