Linux-2.6.12-rc2
Initial git repository build. I'm not bothering with the full history, even though we have it. We can create a separate "historical" git archive of that later if we want to, and in the meantime it's about 3.2GB when imported into git - space that would just make the early git days unnecessarily complicated, when we don't have a lot of good infrastructure for it. Let it rip!
This commit is contained in:
72
include/linux/mtd/blktrans.h
Normal file
72
include/linux/mtd/blktrans.h
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* $Id: blktrans.h,v 1.5 2003/06/23 12:00:08 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 hd_geometry;
|
||||
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);
|
||||
|
||||
/* Block layer ioctls */
|
||||
int (*getgeo)(struct mtd_blktrans_dev *dev, struct hd_geometry *geo);
|
||||
int (*flush)(struct mtd_blktrans_dev *dev);
|
||||
|
||||
/* Called with mtd_table_mutex held; no race with add/remove */
|
||||
int (*open)(struct mtd_blktrans_dev *dev);
|
||||
int (*release)(struct mtd_blktrans_dev *dev);
|
||||
|
||||
/* 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__ */
|
394
include/linux/mtd/cfi.h
Normal file
394
include/linux/mtd/cfi.h
Normal file
@@ -0,0 +1,394 @@
|
||||
|
||||
/* Common Flash Interface structures
|
||||
* See http://support.intel.com/design/flash/technote/index.htm
|
||||
* $Id: cfi.h,v 1.50 2004/11/20 12:46:51 dwmw2 Exp $
|
||||
*/
|
||||
|
||||
#ifndef __MTD_CFI_H__
|
||||
#define __MTD_CFI_H__
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/mtd/flashchip.h>
|
||||
#include <linux/mtd/map.h>
|
||||
#include <linux/mtd/cfi_endian.h>
|
||||
|
||||
#ifdef CONFIG_MTD_CFI_I1
|
||||
#define cfi_interleave(cfi) 1
|
||||
#define cfi_interleave_is_1(cfi) (cfi_interleave(cfi) == 1)
|
||||
#else
|
||||
#define cfi_interleave_is_1(cfi) (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MTD_CFI_I2
|
||||
# ifdef cfi_interleave
|
||||
# undef cfi_interleave
|
||||
# define cfi_interleave(cfi) ((cfi)->interleave)
|
||||
# else
|
||||
# define cfi_interleave(cfi) 2
|
||||
# endif
|
||||
#define cfi_interleave_is_2(cfi) (cfi_interleave(cfi) == 2)
|
||||
#else
|
||||
#define cfi_interleave_is_2(cfi) (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MTD_CFI_I4
|
||||
# ifdef cfi_interleave
|
||||
# undef cfi_interleave
|
||||
# define cfi_interleave(cfi) ((cfi)->interleave)
|
||||
# else
|
||||
# define cfi_interleave(cfi) 4
|
||||
# endif
|
||||
#define cfi_interleave_is_4(cfi) (cfi_interleave(cfi) == 4)
|
||||
#else
|
||||
#define cfi_interleave_is_4(cfi) (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MTD_CFI_I8
|
||||
# ifdef cfi_interleave
|
||||
# undef cfi_interleave
|
||||
# define cfi_interleave(cfi) ((cfi)->interleave)
|
||||
# else
|
||||
# define cfi_interleave(cfi) 8
|
||||
# endif
|
||||
#define cfi_interleave_is_8(cfi) (cfi_interleave(cfi) == 8)
|
||||
#else
|
||||
#define cfi_interleave_is_8(cfi) (0)
|
||||
#endif
|
||||
|
||||
static inline int cfi_interleave_supported(int i)
|
||||
{
|
||||
switch (i) {
|
||||
#ifdef CONFIG_MTD_CFI_I1
|
||||
case 1:
|
||||
#endif
|
||||
#ifdef CONFIG_MTD_CFI_I2
|
||||
case 2:
|
||||
#endif
|
||||
#ifdef CONFIG_MTD_CFI_I4
|
||||
case 4:
|
||||
#endif
|
||||
#ifdef CONFIG_MTD_CFI_I8
|
||||
case 8:
|
||||
#endif
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* 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)
|
||||
#define CFI_DEVICETYPE_X64 (64 / 8)
|
||||
|
||||
/* NB: We keep these structures in memory in HOST byteorder, except
|
||||
* where individually noted.
|
||||
*/
|
||||
|
||||
/* Basic Query Structure */
|
||||
struct cfi_ident {
|
||||
uint8_t qry[3];
|
||||
uint16_t P_ID;
|
||||
uint16_t P_ADR;
|
||||
uint16_t A_ID;
|
||||
uint16_t A_ADR;
|
||||
uint8_t VccMin;
|
||||
uint8_t VccMax;
|
||||
uint8_t VppMin;
|
||||
uint8_t VppMax;
|
||||
uint8_t WordWriteTimeoutTyp;
|
||||
uint8_t BufWriteTimeoutTyp;
|
||||
uint8_t BlockEraseTimeoutTyp;
|
||||
uint8_t ChipEraseTimeoutTyp;
|
||||
uint8_t WordWriteTimeoutMax;
|
||||
uint8_t BufWriteTimeoutMax;
|
||||
uint8_t BlockEraseTimeoutMax;
|
||||
uint8_t ChipEraseTimeoutMax;
|
||||
uint8_t DevSize;
|
||||
uint16_t InterfaceDesc;
|
||||
uint16_t MaxBufWriteSize;
|
||||
uint8_t NumEraseRegions;
|
||||
uint32_t EraseRegionInfo[0]; /* Not host ordered */
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Extended Query Structure for both PRI and ALT */
|
||||
|
||||
struct cfi_extquery {
|
||||
uint8_t pri[3];
|
||||
uint8_t MajorVersion;
|
||||
uint8_t MinorVersion;
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Vendor-Specific PRI for Intel/Sharp Extended Command Set (0x0001) */
|
||||
|
||||
struct cfi_pri_intelext {
|
||||
uint8_t pri[3];
|
||||
uint8_t MajorVersion;
|
||||
uint8_t MinorVersion;
|
||||
uint32_t FeatureSupport; /* if bit 31 is set then an additional uint32_t feature
|
||||
block follows - FIXME - not currently supported */
|
||||
uint8_t SuspendCmdSupport;
|
||||
uint16_t BlkStatusRegMask;
|
||||
uint8_t VccOptimal;
|
||||
uint8_t VppOptimal;
|
||||
uint8_t NumProtectionFields;
|
||||
uint16_t ProtRegAddr;
|
||||
uint8_t FactProtRegSize;
|
||||
uint8_t UserProtRegSize;
|
||||
uint8_t extra[0];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct cfi_intelext_blockinfo {
|
||||
uint16_t NumIdentBlocks;
|
||||
uint16_t BlockSize;
|
||||
uint16_t MinBlockEraseCycles;
|
||||
uint8_t BitsPerCell;
|
||||
uint8_t BlockCap;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct cfi_intelext_regioninfo {
|
||||
uint16_t NumIdentPartitions;
|
||||
uint8_t NumOpAllowed;
|
||||
uint8_t NumOpAllowedSimProgMode;
|
||||
uint8_t NumOpAllowedSimEraMode;
|
||||
uint8_t NumBlockTypes;
|
||||
struct cfi_intelext_blockinfo BlockTypes[1];
|
||||
} __attribute__((packed));
|
||||
|
||||
/* Vendor-Specific PRI for AMD/Fujitsu Extended Command Set (0x0002) */
|
||||
|
||||
struct cfi_pri_amdstd {
|
||||
uint8_t pri[3];
|
||||
uint8_t MajorVersion;
|
||||
uint8_t MinorVersion;
|
||||
uint8_t SiliconRevision; /* bits 1-0: Address Sensitive Unlock */
|
||||
uint8_t EraseSuspend;
|
||||
uint8_t BlkProt;
|
||||
uint8_t TmpBlkUnprotect;
|
||||
uint8_t BlkProtUnprot;
|
||||
uint8_t SimultaneousOps;
|
||||
uint8_t BurstMode;
|
||||
uint8_t PageMode;
|
||||
uint8_t VppMin;
|
||||
uint8_t VppMax;
|
||||
uint8_t TopBottom;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct cfi_pri_query {
|
||||
uint8_t NumFields;
|
||||
uint32_t ProtField[1]; /* Not host ordered */
|
||||
} __attribute__((packed));
|
||||
|
||||
struct cfi_bri_query {
|
||||
uint8_t PageModeReadCap;
|
||||
uint8_t NumFields;
|
||||
uint32_t ConfField[1]; /* Not host ordered */
|
||||
} __attribute__((packed));
|
||||
|
||||
#define P_ID_NONE 0x0000
|
||||
#define P_ID_INTEL_EXT 0x0001
|
||||
#define P_ID_AMD_STD 0x0002
|
||||
#define P_ID_INTEL_STD 0x0003
|
||||
#define P_ID_AMD_EXT 0x0004
|
||||
#define P_ID_WINBOND 0x0006
|
||||
#define P_ID_ST_ADV 0x0020
|
||||
#define P_ID_MITSUBISHI_STD 0x0100
|
||||
#define P_ID_MITSUBISHI_EXT 0x0101
|
||||
#define P_ID_SST_PAGE 0x0102
|
||||
#define P_ID_INTEL_PERFORMANCE 0x0200
|
||||
#define P_ID_INTEL_DATA 0x0210
|
||||
#define P_ID_RESERVED 0xffff
|
||||
|
||||
|
||||
#define CFI_MODE_CFI 1
|
||||
#define CFI_MODE_JEDEC 0
|
||||
|
||||
struct cfi_private {
|
||||
uint16_t 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;
|
||||
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 */
|
||||
};
|
||||
|
||||
/*
|
||||
* Returns the command address according to the given geometry.
|
||||
*/
|
||||
static inline uint32_t cfi_build_cmd_addr(uint32_t cmd_ofs, int interleave, int type)
|
||||
{
|
||||
return (cmd_ofs * type) * interleave;
|
||||
}
|
||||
|
||||
/*
|
||||
* Transforms the CFI command for the given geometry (bus width & interleave).
|
||||
* It looks too long to be inline, but in the common case it should almost all
|
||||
* get optimised away.
|
||||
*/
|
||||
static inline map_word cfi_build_cmd(u_char cmd, struct map_info *map, struct cfi_private *cfi)
|
||||
{
|
||||
map_word val = { {0} };
|
||||
int wordwidth, words_per_bus, chip_mode, chips_per_word;
|
||||
unsigned long onecmd;
|
||||
int i;
|
||||
|
||||
/* We do it this way to give the compiler a fighting chance
|
||||
of optimising away all the crap for 'bankwidth' larger than
|
||||
an unsigned long, in the common case where that support is
|
||||
disabled */
|
||||
if (map_bankwidth_is_large(map)) {
|
||||
wordwidth = sizeof(unsigned long);
|
||||
words_per_bus = (map_bankwidth(map)) / wordwidth; // i.e. normally 1
|
||||
} else {
|
||||
wordwidth = map_bankwidth(map);
|
||||
words_per_bus = 1;
|
||||
}
|
||||
|
||||
chip_mode = map_bankwidth(map) / cfi_interleave(cfi);
|
||||
chips_per_word = wordwidth * cfi_interleave(cfi) / map_bankwidth(map);
|
||||
|
||||
/* First, determine what the bit-pattern should be for a single
|
||||
device, according to chip mode and endianness... */
|
||||
switch (chip_mode) {
|
||||
default: BUG();
|
||||
case 1:
|
||||
onecmd = cmd;
|
||||
break;
|
||||
case 2:
|
||||
onecmd = cpu_to_cfi16(cmd);
|
||||
break;
|
||||
case 4:
|
||||
onecmd = cpu_to_cfi32(cmd);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Now replicate it across the size of an unsigned long, or
|
||||
just to the bus width as appropriate */
|
||||
switch (chips_per_word) {
|
||||
default: BUG();
|
||||
#if BITS_PER_LONG >= 64
|
||||
case 8:
|
||||
onecmd |= (onecmd << (chip_mode * 32));
|
||||
#endif
|
||||
case 4:
|
||||
onecmd |= (onecmd << (chip_mode * 16));
|
||||
case 2:
|
||||
onecmd |= (onecmd << (chip_mode * 8));
|
||||
case 1:
|
||||
;
|
||||
}
|
||||
|
||||
/* And finally, for the multi-word case, replicate it
|
||||
in all words in the structure */
|
||||
for (i=0; i < words_per_bus; i++) {
|
||||
val.x[i] = onecmd;
|
||||
}
|
||||
|
||||
return val;
|
||||
}
|
||||
#define CMD(x) cfi_build_cmd((x), map, cfi)
|
||||
|
||||
/*
|
||||
* 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 uint32_t cfi_send_gen_cmd(u_char cmd, uint32_t cmd_addr, uint32_t base,
|
||||
struct map_info *map, struct cfi_private *cfi,
|
||||
int type, map_word *prev_val)
|
||||
{
|
||||
map_word val;
|
||||
uint32_t addr = base + cfi_build_cmd_addr(cmd_addr, cfi_interleave(cfi), type);
|
||||
|
||||
val = cfi_build_cmd(cmd, map, cfi);
|
||||
|
||||
if (prev_val)
|
||||
*prev_val = map_read(map, addr);
|
||||
|
||||
map_write(map, val, addr);
|
||||
|
||||
return addr - base;
|
||||
}
|
||||
|
||||
static inline uint8_t cfi_read_query(struct map_info *map, uint32_t addr)
|
||||
{
|
||||
map_word val = map_read(map, addr);
|
||||
|
||||
if (map_bankwidth_is_1(map)) {
|
||||
return val.x[0];
|
||||
} else if (map_bankwidth_is_2(map)) {
|
||||
return cfi16_to_cpu(val.x[0]);
|
||||
} else {
|
||||
/* No point in a 64-bit byteswap since that would just be
|
||||
swapping the responses from different chips, and we are
|
||||
only interested in one chip (a representative sample) */
|
||||
return cfi32_to_cpu(val.x[0]);
|
||||
}
|
||||
}
|
||||
|
||||
static inline void cfi_udelay(int us)
|
||||
{
|
||||
if (us >= 1000) {
|
||||
msleep((us+999)/1000);
|
||||
} else {
|
||||
udelay(us);
|
||||
cond_resched();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
struct cfi_extquery *cfi_read_pri(struct map_info *map, uint16_t adr, uint16_t size,
|
||||
const char* name);
|
||||
struct cfi_fixup {
|
||||
uint16_t mfr;
|
||||
uint16_t id;
|
||||
void (*fixup)(struct mtd_info *mtd, void* param);
|
||||
void* param;
|
||||
};
|
||||
|
||||
#define CFI_MFR_ANY 0xffff
|
||||
#define CFI_ID_ANY 0xffff
|
||||
|
||||
#define CFI_MFR_AMD 0x0001
|
||||
#define CFI_MFR_ST 0x0020 /* STMicroelectronics */
|
||||
|
||||
void cfi_fixup(struct mtd_info *mtd, struct cfi_fixup* fixups);
|
||||
|
||||
typedef int (*varsize_frob_t)(struct map_info *map, struct flchip *chip,
|
||||
unsigned long adr, int len, void *thunk);
|
||||
|
||||
int cfi_varsize_frob(struct mtd_info *mtd, varsize_frob_t frob,
|
||||
loff_t ofs, size_t len, void *thunk);
|
||||
|
||||
|
||||
#endif /* __MTD_CFI_H__ */
|
57
include/linux/mtd/cfi_endian.h
Normal file
57
include/linux/mtd/cfi_endian.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* $Id: cfi_endian.h,v 1.11 2002/01/30 23:20:48 awozniak 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 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
|
10
include/linux/mtd/compatmac.h
Normal file
10
include/linux/mtd/compatmac.h
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
#ifndef __LINUX_MTD_COMPATMAC_H__
|
||||
#define __LINUX_MTD_COMPATMAC_H__
|
||||
|
||||
/* 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__ */
|
23
include/linux/mtd/concat.h
Normal file
23
include/linux/mtd/concat.h
Normal file
@@ -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 2002/03/08 16:34:36 rkaiser 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
|
||||
|
195
include/linux/mtd/doc2000.h
Normal file
195
include/linux/mtd/doc2000.h
Normal file
@@ -0,0 +1,195 @@
|
||||
/*
|
||||
* Linux driver for Disk-On-Chip devices
|
||||
*
|
||||
* Copyright (C) 1999 Machine Vision Holdings, Inc.
|
||||
* Copyright (C) 2001-2003 David Woodhouse <dwmw2@infradead.org>
|
||||
* Copyright (C) 2002-2003 Greg Ungerer <gerg@snapgear.com>
|
||||
* Copyright (C) 2002-2003 SnapGear Inc
|
||||
*
|
||||
* $Id: doc2000.h,v 1.24 2005/01/05 12:40:38 dwmw2 Exp $
|
||||
*
|
||||
* Released under GPL
|
||||
*/
|
||||
|
||||
#ifndef __MTD_DOC2000_H__
|
||||
#define __MTD_DOC2000_H__
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <asm/semaphore.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
|
||||
|
||||
#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 0x100c
|
||||
#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.
|
||||
* Others use readb/writeb
|
||||
*/
|
||||
#if defined(__arm__)
|
||||
#define ReadDOC_(adr, reg) ((unsigned char)(*(volatile __u32 *)(((unsigned long)adr)+((reg)<<2))))
|
||||
#define WriteDOC_(d, adr, reg) do{ *(volatile __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)(*(volatile __u16 *)(((unsigned long)adr)+((reg)<<1))))
|
||||
#define WriteDOC_(d, adr, reg) do{ *(volatile __u16 *)(((unsigned long)adr)+((reg)<<1)) = (__u16)d; wmb();} while(0)
|
||||
#define DOC_IOREMAP_LEN 0x4000
|
||||
#else
|
||||
#define ReadDOC_(adr, reg) readb((void __iomem *)(adr) + (reg))
|
||||
#define WriteDOC_(d, adr, reg) writeb(d, (void __iomem *)(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_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_Doc2kTSOP 0x21 /* internal number for MTD */
|
||||
#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
|
||||
#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
|
||||
|
||||
#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)
|
||||
|
||||
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 1
|
||||
#define MAX_CHIPS_MIL 1
|
||||
|
||||
#define MAX_FLOORS_MPLUS 2
|
||||
#define MAX_CHIPS_MPLUS 1
|
||||
|
||||
#define ADDR_COLUMN 1
|
||||
#define ADDR_PAGE 2
|
||||
#define ADDR_COLUMN_PAGE 3
|
||||
|
||||
struct DiskOnChip {
|
||||
unsigned long physadr;
|
||||
void __iomem *virtadr;
|
||||
unsigned long totlen;
|
||||
unsigned 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;
|
||||
char interleave; /* Internal interleaving - Millennium Plus style */
|
||||
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__ */
|
89
include/linux/mtd/flashchip.h
Normal file
89
include/linux/mtd/flashchip.h
Normal file
@@ -0,0 +1,89 @@
|
||||
|
||||
/*
|
||||
* 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.15 2004/11/05 22:41:06 nico 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_POINT,
|
||||
FL_XIP_WHILE_ERASING,
|
||||
FL_XIP_WHILE_WRITING,
|
||||
FL_UNKNOWN
|
||||
} flstate_t;
|
||||
|
||||
|
||||
|
||||
/* NOTE: confusingly, this can be used to refer to more than one chip at a time,
|
||||
if they're interleaved. This can even refer to individual partitions on
|
||||
the same physical chip when present. */
|
||||
|
||||
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.
|
||||
*/
|
||||
int ref_point_counter;
|
||||
flstate_t state;
|
||||
flstate_t oldstate;
|
||||
|
||||
int write_suspended:1;
|
||||
int erase_suspended:1;
|
||||
unsigned long in_progress_block_addr;
|
||||
|
||||
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;
|
||||
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/* This is used to handle contention on write/erase operations
|
||||
between partitions of the same physical chip. */
|
||||
struct flchip_shared {
|
||||
spinlock_t lock;
|
||||
struct flchip *writing;
|
||||
struct flchip *erasing;
|
||||
};
|
||||
|
||||
|
||||
#endif /* __MTD_FLASHCHIP_H__ */
|
76
include/linux/mtd/ftl.h
Normal file
76
include/linux/mtd/ftl.h
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* $Id: ftl.h,v 1.6 2003/01/24 13:20:04 dwmw2 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 */
|
23
include/linux/mtd/gen_probe.h
Normal file
23
include/linux/mtd/gen_probe.h
Normal file
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* (C) 2001, 2001 Red Hat, Inc.
|
||||
* GPL'd
|
||||
* $Id: gen_probe.h,v 1.3 2004/10/20 22:10:33 dwmw2 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>
|
||||
#include <linux/bitops.h>
|
||||
|
||||
struct chip_probe {
|
||||
char *name;
|
||||
int (*probe_chip)(struct map_info *map, __u32 base,
|
||||
unsigned long *chip_map, 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__ */
|
98
include/linux/mtd/iflash.h
Normal file
98
include/linux/mtd/iflash.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/* $Id: iflash.h,v 1.2 2000/11/13 18:01:54 dwmw2 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__ */
|
57
include/linux/mtd/inftl.h
Normal file
57
include/linux/mtd/inftl.h
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* inftl.h -- defines to support the Inverse NAND Flash Translation Layer
|
||||
*
|
||||
* (C) Copyright 2002, Greg Ungerer (gerg@snapgear.com)
|
||||
*
|
||||
* $Id: inftl.h,v 1.6 2004/06/30 14:49:00 dbrown Exp $
|
||||
*/
|
||||
|
||||
#ifndef __MTD_INFTL_H__
|
||||
#define __MTD_INFTL_H__
|
||||
|
||||
#ifndef __KERNEL__
|
||||
#error This is a kernel header. Perhaps include nftl-user.h instead?
|
||||
#endif
|
||||
|
||||
#include <linux/mtd/blktrans.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/nftl.h>
|
||||
|
||||
#include <mtd/inftl-user.h>
|
||||
|
||||
#ifndef INFTL_MAJOR
|
||||
#define INFTL_MAJOR 94
|
||||
#endif
|
||||
#define INFTL_PARTN_BITS 4
|
||||
|
||||
#ifdef __KERNEL__
|
||||
|
||||
struct INFTLrecord {
|
||||
struct mtd_blktrans_dev mbd;
|
||||
__u16 MediaUnit;
|
||||
__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;
|
||||
struct nand_oobinfo oobinfo;
|
||||
};
|
||||
|
||||
int INFTL_mount(struct INFTLrecord *s);
|
||||
int INFTL_formatblock(struct INFTLrecord *s, int block);
|
||||
|
||||
#endif /* __KERNEL__ */
|
||||
|
||||
#endif /* __MTD_INFTL_H__ */
|
66
include/linux/mtd/jedec.h
Normal file
66
include/linux/mtd/jedec.h
Normal file
@@ -0,0 +1,66 @@
|
||||
|
||||
/* 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.3 2003/05/21 11:51:01 dwmw2 Exp $
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MTD_JEDEC_H__
|
||||
#define __LINUX_MTD_JEDEC_H__
|
||||
|
||||
#include <linux/types.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
|
412
include/linux/mtd/map.h
Normal file
412
include/linux/mtd/map.h
Normal file
@@ -0,0 +1,412 @@
|
||||
|
||||
/* Overhauled routines for dealing with different mmap regions of flash */
|
||||
/* $Id: map.h,v 1.46 2005/01/05 17:09:44 dwmw2 Exp $ */
|
||||
|
||||
#ifndef __LINUX_MTD_MAP_H__
|
||||
#define __LINUX_MTD_MAP_H__
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/mtd/compatmac.h>
|
||||
#include <asm/unaligned.h>
|
||||
#include <asm/system.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/bug.h>
|
||||
|
||||
#ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
|
||||
#define map_bankwidth(map) 1
|
||||
#define map_bankwidth_is_1(map) (map_bankwidth(map) == 1)
|
||||
#define map_bankwidth_is_large(map) (0)
|
||||
#define map_words(map) (1)
|
||||
#define MAX_MAP_BANKWIDTH 1
|
||||
#else
|
||||
#define map_bankwidth_is_1(map) (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MTD_MAP_BANK_WIDTH_2
|
||||
# ifdef map_bankwidth
|
||||
# undef map_bankwidth
|
||||
# define map_bankwidth(map) ((map)->bankwidth)
|
||||
# else
|
||||
# define map_bankwidth(map) 2
|
||||
# define map_bankwidth_is_large(map) (0)
|
||||
# define map_words(map) (1)
|
||||
# endif
|
||||
#define map_bankwidth_is_2(map) (map_bankwidth(map) == 2)
|
||||
#undef MAX_MAP_BANKWIDTH
|
||||
#define MAX_MAP_BANKWIDTH 2
|
||||
#else
|
||||
#define map_bankwidth_is_2(map) (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MTD_MAP_BANK_WIDTH_4
|
||||
# ifdef map_bankwidth
|
||||
# undef map_bankwidth
|
||||
# define map_bankwidth(map) ((map)->bankwidth)
|
||||
# else
|
||||
# define map_bankwidth(map) 4
|
||||
# define map_bankwidth_is_large(map) (0)
|
||||
# define map_words(map) (1)
|
||||
# endif
|
||||
#define map_bankwidth_is_4(map) (map_bankwidth(map) == 4)
|
||||
#undef MAX_MAP_BANKWIDTH
|
||||
#define MAX_MAP_BANKWIDTH 4
|
||||
#else
|
||||
#define map_bankwidth_is_4(map) (0)
|
||||
#endif
|
||||
|
||||
/* ensure we never evaluate anything shorted than an unsigned long
|
||||
* to zero, and ensure we'll never miss the end of an comparison (bjd) */
|
||||
|
||||
#define map_calc_words(map) ((map_bankwidth(map) + (sizeof(unsigned long)-1))/ sizeof(unsigned long))
|
||||
|
||||
#ifdef CONFIG_MTD_MAP_BANK_WIDTH_8
|
||||
# ifdef map_bankwidth
|
||||
# undef map_bankwidth
|
||||
# define map_bankwidth(map) ((map)->bankwidth)
|
||||
# if BITS_PER_LONG < 64
|
||||
# undef map_bankwidth_is_large
|
||||
# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
|
||||
# undef map_words
|
||||
# define map_words(map) map_calc_words(map)
|
||||
# endif
|
||||
# else
|
||||
# define map_bankwidth(map) 8
|
||||
# define map_bankwidth_is_large(map) (BITS_PER_LONG < 64)
|
||||
# define map_words(map) map_calc_words(map)
|
||||
# endif
|
||||
#define map_bankwidth_is_8(map) (map_bankwidth(map) == 8)
|
||||
#undef MAX_MAP_BANKWIDTH
|
||||
#define MAX_MAP_BANKWIDTH 8
|
||||
#else
|
||||
#define map_bankwidth_is_8(map) (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MTD_MAP_BANK_WIDTH_16
|
||||
# ifdef map_bankwidth
|
||||
# undef map_bankwidth
|
||||
# define map_bankwidth(map) ((map)->bankwidth)
|
||||
# undef map_bankwidth_is_large
|
||||
# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
|
||||
# undef map_words
|
||||
# define map_words(map) map_calc_words(map)
|
||||
# else
|
||||
# define map_bankwidth(map) 16
|
||||
# define map_bankwidth_is_large(map) (1)
|
||||
# define map_words(map) map_calc_words(map)
|
||||
# endif
|
||||
#define map_bankwidth_is_16(map) (map_bankwidth(map) == 16)
|
||||
#undef MAX_MAP_BANKWIDTH
|
||||
#define MAX_MAP_BANKWIDTH 16
|
||||
#else
|
||||
#define map_bankwidth_is_16(map) (0)
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_MTD_MAP_BANK_WIDTH_32
|
||||
# ifdef map_bankwidth
|
||||
# undef map_bankwidth
|
||||
# define map_bankwidth(map) ((map)->bankwidth)
|
||||
# undef map_bankwidth_is_large
|
||||
# define map_bankwidth_is_large(map) (map_bankwidth(map) > BITS_PER_LONG/8)
|
||||
# undef map_words
|
||||
# define map_words(map) map_calc_words(map)
|
||||
# else
|
||||
# define map_bankwidth(map) 32
|
||||
# define map_bankwidth_is_large(map) (1)
|
||||
# define map_words(map) map_calc_words(map)
|
||||
# endif
|
||||
#define map_bankwidth_is_32(map) (map_bankwidth(map) == 32)
|
||||
#undef MAX_MAP_BANKWIDTH
|
||||
#define MAX_MAP_BANKWIDTH 32
|
||||
#else
|
||||
#define map_bankwidth_is_32(map) (0)
|
||||
#endif
|
||||
|
||||
#ifndef map_bankwidth
|
||||
#error "No bus width supported. What's the point?"
|
||||
#endif
|
||||
|
||||
static inline int map_bankwidth_supported(int w)
|
||||
{
|
||||
switch (w) {
|
||||
#ifdef CONFIG_MTD_MAP_BANK_WIDTH_1
|
||||
case 1:
|
||||
#endif
|
||||
#ifdef CONFIG_MTD_MAP_BANK_WIDTH_2
|
||||
case 2:
|
||||
#endif
|
||||
#ifdef CONFIG_MTD_MAP_BANK_WIDTH_4
|
||||
case 4:
|
||||
#endif
|
||||
#ifdef CONFIG_MTD_MAP_BANK_WIDTH_8
|
||||
case 8:
|
||||
#endif
|
||||
#ifdef CONFIG_MTD_MAP_BANK_WIDTH_16
|
||||
case 16:
|
||||
#endif
|
||||
#ifdef CONFIG_MTD_MAP_BANK_WIDTH_32
|
||||
case 32:
|
||||
#endif
|
||||
return 1;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
#define MAX_MAP_LONGS ( ((MAX_MAP_BANKWIDTH*8) + BITS_PER_LONG - 1) / BITS_PER_LONG )
|
||||
|
||||
typedef union {
|
||||
unsigned long x[MAX_MAP_LONGS];
|
||||
} map_word;
|
||||
|
||||
/* 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 probe routine -- either JEDEC or CFI probe or both -- via
|
||||
do_map_probe(). If a chip is recognised, the probe code will invoke the
|
||||
appropriate chip driver (if present) and return a struct mtd_info.
|
||||
At which point, you fill in the mtd->module with your own module
|
||||
address, and register it with the MTD core code. Or you could partition
|
||||
it and register the partitions instead, or keep it for your own private
|
||||
use; whatever.
|
||||
|
||||
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;
|
||||
unsigned long phys;
|
||||
#define NO_XIP (-1UL)
|
||||
|
||||
void __iomem *virt;
|
||||
void *cached;
|
||||
|
||||
int bankwidth; /* in octets. This isn't necessarily the width
|
||||
of actual bus cycles -- it's the repeat interval
|
||||
in bytes, before you are talking to the first chip again.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
|
||||
map_word (*read)(struct map_info *, unsigned long);
|
||||
void (*copy_from)(struct map_info *, void *, unsigned long, ssize_t);
|
||||
|
||||
void (*write)(struct map_info *, const map_word, 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
|
||||
/* It's possible for the map driver to use cached memory in its
|
||||
copy_from implementation (and _only_ with copy_from). However,
|
||||
when the chip driver knows some flash area has changed contents,
|
||||
it will signal it to the map driver through this routine to let
|
||||
the map driver invalidate the corresponding cache as needed.
|
||||
If there is no cache to care about this can be set to NULL. */
|
||||
void (*inval_cache)(struct map_info *, unsigned long, ssize_t);
|
||||
|
||||
/* set_vpp() must handle being reentered -- enable, enable, disable
|
||||
must leave it enabled. */
|
||||
void (*set_vpp)(struct map_info *, int);
|
||||
|
||||
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(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)
|
||||
|
||||
#define INVALIDATE_CACHED_RANGE(map, from, size) \
|
||||
do { if(map->inval_cache) map->inval_cache(map, from, size); } while(0)
|
||||
|
||||
|
||||
static inline int map_word_equal(struct map_info *map, map_word val1, map_word val2)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<map_words(map); i++) {
|
||||
if (val1.x[i] != val2.x[i])
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static inline map_word map_word_and(struct map_info *map, map_word val1, map_word val2)
|
||||
{
|
||||
map_word r;
|
||||
int i;
|
||||
|
||||
for (i=0; i<map_words(map); i++) {
|
||||
r.x[i] = val1.x[i] & val2.x[i];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline map_word map_word_or(struct map_info *map, map_word val1, map_word val2)
|
||||
{
|
||||
map_word r;
|
||||
int i;
|
||||
|
||||
for (i=0; i<map_words(map); i++) {
|
||||
r.x[i] = val1.x[i] | val2.x[i];
|
||||
}
|
||||
return r;
|
||||
}
|
||||
#define map_word_andequal(m, a, b, z) map_word_equal(m, z, map_word_and(m, a, b))
|
||||
|
||||
static inline int map_word_bitsset(struct map_info *map, map_word val1, map_word val2)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i=0; i<map_words(map); i++) {
|
||||
if (val1.x[i] & val2.x[i])
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline map_word map_word_load(struct map_info *map, const void *ptr)
|
||||
{
|
||||
map_word r;
|
||||
|
||||
if (map_bankwidth_is_1(map))
|
||||
r.x[0] = *(unsigned char *)ptr;
|
||||
else if (map_bankwidth_is_2(map))
|
||||
r.x[0] = get_unaligned((uint16_t *)ptr);
|
||||
else if (map_bankwidth_is_4(map))
|
||||
r.x[0] = get_unaligned((uint32_t *)ptr);
|
||||
#if BITS_PER_LONG >= 64
|
||||
else if (map_bankwidth_is_8(map))
|
||||
r.x[0] = get_unaligned((uint64_t *)ptr);
|
||||
#endif
|
||||
else if (map_bankwidth_is_large(map))
|
||||
memcpy(r.x, ptr, map->bankwidth);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline map_word map_word_load_partial(struct map_info *map, map_word orig, const unsigned char *buf, int start, int len)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (map_bankwidth_is_large(map)) {
|
||||
char *dest = (char *)&orig;
|
||||
memcpy(dest+start, buf, len);
|
||||
} else {
|
||||
for (i=start; i < start+len; i++) {
|
||||
int bitpos;
|
||||
#ifdef __LITTLE_ENDIAN
|
||||
bitpos = i*8;
|
||||
#else /* __BIG_ENDIAN */
|
||||
bitpos = (map_bankwidth(map)-1-i)*8;
|
||||
#endif
|
||||
orig.x[0] &= ~(0xff << bitpos);
|
||||
orig.x[0] |= buf[i-start] << bitpos;
|
||||
}
|
||||
}
|
||||
return orig;
|
||||
}
|
||||
|
||||
static inline map_word map_word_ff(struct map_info *map)
|
||||
{
|
||||
map_word r;
|
||||
int i;
|
||||
|
||||
for (i=0; i<map_words(map); i++) {
|
||||
r.x[i] = ~0UL;
|
||||
}
|
||||
return r;
|
||||
}
|
||||
static inline map_word inline_map_read(struct map_info *map, unsigned long ofs)
|
||||
{
|
||||
map_word r;
|
||||
|
||||
if (map_bankwidth_is_1(map))
|
||||
r.x[0] = __raw_readb(map->virt + ofs);
|
||||
else if (map_bankwidth_is_2(map))
|
||||
r.x[0] = __raw_readw(map->virt + ofs);
|
||||
else if (map_bankwidth_is_4(map))
|
||||
r.x[0] = __raw_readl(map->virt + ofs);
|
||||
#if BITS_PER_LONG >= 64
|
||||
else if (map_bankwidth_is_8(map))
|
||||
r.x[0] = __raw_readq(map->virt + ofs);
|
||||
#endif
|
||||
else if (map_bankwidth_is_large(map))
|
||||
memcpy_fromio(r.x, map->virt+ofs, map->bankwidth);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
static inline void inline_map_write(struct map_info *map, const map_word datum, unsigned long ofs)
|
||||
{
|
||||
if (map_bankwidth_is_1(map))
|
||||
__raw_writeb(datum.x[0], map->virt + ofs);
|
||||
else if (map_bankwidth_is_2(map))
|
||||
__raw_writew(datum.x[0], map->virt + ofs);
|
||||
else if (map_bankwidth_is_4(map))
|
||||
__raw_writel(datum.x[0], map->virt + ofs);
|
||||
#if BITS_PER_LONG >= 64
|
||||
else if (map_bankwidth_is_8(map))
|
||||
__raw_writeq(datum.x[0], map->virt + ofs);
|
||||
#endif
|
||||
else if (map_bankwidth_is_large(map))
|
||||
memcpy_toio(map->virt+ofs, datum.x, map->bankwidth);
|
||||
mb();
|
||||
}
|
||||
|
||||
static inline void inline_map_copy_from(struct map_info *map, void *to, unsigned long from, ssize_t len)
|
||||
{
|
||||
if (map->cached)
|
||||
memcpy(to, (char *)map->cached + from, len);
|
||||
else
|
||||
memcpy_fromio(to, map->virt + from, len);
|
||||
}
|
||||
|
||||
static inline void inline_map_copy_to(struct map_info *map, unsigned long to, const void *from, ssize_t len)
|
||||
{
|
||||
memcpy_toio(map->virt + to, from, len);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MTD_COMPLEX_MAPPINGS
|
||||
#define map_read(map, ofs) (map)->read(map, ofs)
|
||||
#define map_copy_from(map, to, from, len) (map)->copy_from(map, to, from, len)
|
||||
#define map_write(map, datum, ofs) (map)->write(map, datum, ofs)
|
||||
#define map_copy_to(map, to, from, len) (map)->copy_to(map, to, from, len)
|
||||
|
||||
extern void simple_map_init(struct map_info *);
|
||||
#define map_is_linear(map) (map->phys != NO_XIP)
|
||||
|
||||
#else
|
||||
#define map_read(map, ofs) inline_map_read(map, ofs)
|
||||
#define map_copy_from(map, to, from, len) inline_map_copy_from(map, to, from, len)
|
||||
#define map_write(map, datum, ofs) inline_map_write(map, datum, ofs)
|
||||
#define map_copy_to(map, to, from, len) inline_map_copy_to(map, to, from, len)
|
||||
|
||||
|
||||
#define simple_map_init(map) BUG_ON(!map_bankwidth_supported((map)->bankwidth))
|
||||
#define map_is_linear(map) (1)
|
||||
|
||||
#endif /* !CONFIG_MTD_COMPLEX_MAPPINGS */
|
||||
|
||||
#endif /* __LINUX_MTD_MAP_H__ */
|
226
include/linux/mtd/mtd.h
Normal file
226
include/linux/mtd/mtd.h
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* $Id: mtd.h,v 1.56 2004/08/09 18:46:04 dmarlin Exp $
|
||||
*
|
||||
* Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al.
|
||||
*
|
||||
* Released under GPL
|
||||
*/
|
||||
|
||||
#ifndef __MTD_MTD_H__
|
||||
#define __MTD_MTD_H__
|
||||
|
||||
#ifndef __KERNEL__
|
||||
#error This is a kernel header. Perhaps include mtd-user.h instead?
|
||||
#endif
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/version.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/uio.h>
|
||||
|
||||
#include <linux/mtd/compatmac.h>
|
||||
#include <mtd/mtd-abi.h>
|
||||
|
||||
#define MTD_CHAR_MAJOR 90
|
||||
#define MTD_BLOCK_MAJOR 31
|
||||
#define MAX_MTD_DEVICES 16
|
||||
|
||||
#define MTD_ERASE_PENDING 0x01
|
||||
#define MTD_ERASING 0x02
|
||||
#define MTD_ERASE_SUSPEND 0x04
|
||||
#define MTD_ERASE_DONE 0x08
|
||||
#define MTD_ERASE_FAILED 0x10
|
||||
|
||||
/* If the erase fails, fail_addr might indicate exactly which block failed. If
|
||||
fail_addr = 0xffffffff, the failure was not at the device level or was not
|
||||
specific to any particular block. */
|
||||
struct erase_info {
|
||||
struct mtd_info *mtd;
|
||||
u_int32_t addr;
|
||||
u_int32_t len;
|
||||
u_int32_t fail_addr;
|
||||
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<4E>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 oobavail; // Number of bytes in OOB area available for fs
|
||||
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.
|
||||
*/
|
||||
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;
|
||||
|
||||
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, 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, 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);
|
||||
|
||||
/* kvec-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 kvec *vecs, unsigned long count, loff_t from, size_t *retlen);
|
||||
int (*readv_ecc) (struct mtd_info *mtd, struct kvec *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 kvec *vecs, unsigned long count, loff_t to, size_t *retlen);
|
||||
int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to,
|
||||
size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Bad block management functions */
|
||||
int (*block_isbad) (struct mtd_info *mtd, loff_t ofs);
|
||||
int (*block_markbad) (struct mtd_info *mtd, loff_t ofs);
|
||||
|
||||
void *priv;
|
||||
|
||||
struct module *owner;
|
||||
int usecount;
|
||||
};
|
||||
|
||||
|
||||
/* 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);
|
||||
|
||||
extern void put_mtd_device(struct mtd_info *mtd);
|
||||
|
||||
|
||||
struct mtd_notifier {
|
||||
void (*add)(struct mtd_info *mtd);
|
||||
void (*remove)(struct mtd_info *mtd);
|
||||
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 kvec *vecs,
|
||||
unsigned long count, loff_t to, size_t *retlen);
|
||||
|
||||
int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs,
|
||||
unsigned long count, loff_t from, size_t *retlen);
|
||||
|
||||
#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)
|
||||
|
||||
|
||||
#ifdef CONFIG_MTD_PARTITIONS
|
||||
void mtd_erase_callback(struct erase_info *instr);
|
||||
#else
|
||||
static inline void mtd_erase_callback(struct erase_info *instr)
|
||||
{
|
||||
if (instr->callback)
|
||||
instr->callback(instr);
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* 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...) \
|
||||
do { \
|
||||
if (n <= CONFIG_MTD_DEBUG_VERBOSE) \
|
||||
printk(KERN_INFO args); \
|
||||
} while(0)
|
||||
#else /* CONFIG_MTD_DEBUG */
|
||||
#define DEBUG(n, args...) do { } while(0)
|
||||
|
||||
#endif /* CONFIG_MTD_DEBUG */
|
||||
|
||||
#endif /* __MTD_MTD_H__ */
|
469
include/linux/mtd/nand.h
Normal file
469
include/linux/mtd/nand.h
Normal file
@@ -0,0 +1,469 @@
|
||||
/*
|
||||
* linux/include/linux/mtd/nand.h
|
||||
*
|
||||
* Copyright (c) 2000 David Woodhouse <dwmw2@mvhi.com>
|
||||
* Steven J. Hill <sjhill@realitydiluted.com>
|
||||
* Thomas Gleixner <tglx@linutronix.de>
|
||||
*
|
||||
* $Id: nand.h,v 1.68 2004/11/12 10:40:37 gleixner 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
|
||||
* 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
|
||||
*
|
||||
* 02-08-2004 tglx added option field to nand structure for chip anomalities
|
||||
* 05-25-2004 tglx added bad block table support, ST-MICRO manufacturer id
|
||||
* update of nand_chip structure description
|
||||
*/
|
||||
#ifndef __LINUX_MTD_NAND_H
|
||||
#define __LINUX_MTD_NAND_H
|
||||
|
||||
#include <linux/config.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/mtd/mtd.h>
|
||||
|
||||
struct mtd_info;
|
||||
/* Scan and identify a NAND device */
|
||||
extern int nand_scan (struct mtd_info *mtd, int max_chips);
|
||||
/* Free resources held by the NAND device */
|
||||
extern void nand_release (struct mtd_info *mtd);
|
||||
|
||||
/* Read raw data from the device without ECC */
|
||||
extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_t len, size_t ooblen);
|
||||
|
||||
|
||||
/* The maximum number of NAND chips in an array */
|
||||
#define NAND_MAX_CHIPS 8
|
||||
|
||||
/* This constant declares the max. oobsize / page, which
|
||||
* is supported now. If you add a chip with bigger oobsize/page
|
||||
* adjust this accordingly.
|
||||
*/
|
||||
#define NAND_MAX_OOBSIZE 64
|
||||
|
||||
/*
|
||||
* Constants for hardware specific CLE/ALE/NCE function
|
||||
*/
|
||||
/* Select the chip by setting nCE to low */
|
||||
#define NAND_CTL_SETNCE 1
|
||||
/* Deselect the chip by setting nCE to high */
|
||||
#define NAND_CTL_CLRNCE 2
|
||||
/* Select the command latch by setting CLE to high */
|
||||
#define NAND_CTL_SETCLE 3
|
||||
/* Deselect the command latch by setting CLE to low */
|
||||
#define NAND_CTL_CLRCLE 4
|
||||
/* Select the address latch by setting ALE to high */
|
||||
#define NAND_CTL_SETALE 5
|
||||
/* Deselect the address latch by setting ALE to low */
|
||||
#define NAND_CTL_CLRALE 6
|
||||
/* Set write protection by setting WP to high. Not used! */
|
||||
#define NAND_CTL_SETWP 7
|
||||
/* Clear write protection by setting WP to low. Not used! */
|
||||
#define NAND_CTL_CLRWP 8
|
||||
|
||||
/*
|
||||
* 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_STATUS_MULTI 0x71
|
||||
#define NAND_CMD_SEQIN 0x80
|
||||
#define NAND_CMD_READID 0x90
|
||||
#define NAND_CMD_ERASE2 0xd0
|
||||
#define NAND_CMD_RESET 0xff
|
||||
|
||||
/* Extended commands for large page devices */
|
||||
#define NAND_CMD_READSTART 0x30
|
||||
#define NAND_CMD_CACHEDPROG 0x15
|
||||
|
||||
/* Status bits */
|
||||
#define NAND_STATUS_FAIL 0x01
|
||||
#define NAND_STATUS_FAIL_N1 0x02
|
||||
#define NAND_STATUS_TRUE_READY 0x20
|
||||
#define NAND_STATUS_READY 0x40
|
||||
#define NAND_STATUS_WP 0x80
|
||||
|
||||
/*
|
||||
* Constants for ECC_MODES
|
||||
*/
|
||||
|
||||
/* No ECC. Usage is not recommended ! */
|
||||
#define NAND_ECC_NONE 0
|
||||
/* Software ECC 3 byte ECC per 256 Byte data */
|
||||
#define NAND_ECC_SOFT 1
|
||||
/* Hardware ECC 3 byte ECC per 256 Byte data */
|
||||
#define NAND_ECC_HW3_256 2
|
||||
/* Hardware ECC 3 byte ECC per 512 Byte data */
|
||||
#define NAND_ECC_HW3_512 3
|
||||
/* Hardware ECC 3 byte ECC per 512 Byte data */
|
||||
#define NAND_ECC_HW6_512 4
|
||||
/* Hardware ECC 8 byte ECC per 512 Byte data */
|
||||
#define NAND_ECC_HW8_512 6
|
||||
/* Hardware ECC 12 byte ECC per 2048 Byte data */
|
||||
#define NAND_ECC_HW12_2048 7
|
||||
|
||||
/*
|
||||
* Constants for Hardware ECC
|
||||
*/
|
||||
/* Reset Hardware ECC for read */
|
||||
#define NAND_ECC_READ 0
|
||||
/* Reset Hardware ECC for write */
|
||||
#define NAND_ECC_WRITE 1
|
||||
/* Enable Hardware ECC before syndrom is read back from flash */
|
||||
#define NAND_ECC_READSYN 2
|
||||
|
||||
/* Option constants for bizarre disfunctionality and real
|
||||
* features
|
||||
*/
|
||||
/* Chip can not auto increment pages */
|
||||
#define NAND_NO_AUTOINCR 0x00000001
|
||||
/* Buswitdh is 16 bit */
|
||||
#define NAND_BUSWIDTH_16 0x00000002
|
||||
/* Device supports partial programming without padding */
|
||||
#define NAND_NO_PADDING 0x00000004
|
||||
/* Chip has cache program function */
|
||||
#define NAND_CACHEPRG 0x00000008
|
||||
/* Chip has copy back function */
|
||||
#define NAND_COPYBACK 0x00000010
|
||||
/* AND Chip which has 4 banks and a confusing page / block
|
||||
* assignment. See Renesas datasheet for further information */
|
||||
#define NAND_IS_AND 0x00000020
|
||||
/* Chip has a array of 4 pages which can be read without
|
||||
* additional ready /busy waits */
|
||||
#define NAND_4PAGE_ARRAY 0x00000040
|
||||
|
||||
/* Options valid for Samsung large page devices */
|
||||
#define NAND_SAMSUNG_LP_OPTIONS \
|
||||
(NAND_NO_PADDING | NAND_CACHEPRG | NAND_COPYBACK)
|
||||
|
||||
/* Macros to identify the above */
|
||||
#define NAND_CANAUTOINCR(chip) (!(chip->options & NAND_NO_AUTOINCR))
|
||||
#define NAND_MUST_PAD(chip) (!(chip->options & NAND_NO_PADDING))
|
||||
#define NAND_HAS_CACHEPROG(chip) ((chip->options & NAND_CACHEPRG))
|
||||
#define NAND_HAS_COPYBACK(chip) ((chip->options & NAND_COPYBACK))
|
||||
|
||||
/* Mask to zero out the chip options, which come from the id table */
|
||||
#define NAND_CHIPOPTIONS_MSK (0x0000ffff & ~NAND_NO_AUTOINCR)
|
||||
|
||||
/* Non chip related options */
|
||||
/* Use a flash based bad block table. This option is passed to the
|
||||
* default bad block table function. */
|
||||
#define NAND_USE_FLASH_BBT 0x00010000
|
||||
/* The hw ecc generator provides a syndrome instead a ecc value on read
|
||||
* This can only work if we have the ecc bytes directly behind the
|
||||
* data bytes. Applies for DOC and AG-AND Renesas HW Reed Solomon generators */
|
||||
#define NAND_HWECC_SYNDROME 0x00020000
|
||||
|
||||
|
||||
/* Options set by nand scan */
|
||||
/* Nand scan has allocated oob_buf */
|
||||
#define NAND_OOBBUF_ALLOC 0x40000000
|
||||
/* Nand scan has allocated data_buf */
|
||||
#define NAND_DATABUF_ALLOC 0x80000000
|
||||
|
||||
|
||||
/*
|
||||
* nand_state_t - chip states
|
||||
* Enumeration for NAND flash chip state
|
||||
*/
|
||||
typedef enum {
|
||||
FL_READY,
|
||||
FL_READING,
|
||||
FL_WRITING,
|
||||
FL_ERASING,
|
||||
FL_SYNCING,
|
||||
FL_CACHEDPRG,
|
||||
} nand_state_t;
|
||||
|
||||
/* Keep gcc happy */
|
||||
struct nand_chip;
|
||||
|
||||
/**
|
||||
* struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices
|
||||
* @lock: protection lock
|
||||
* @active: the mtd device which holds the controller currently
|
||||
*/
|
||||
struct nand_hw_control {
|
||||
spinlock_t lock;
|
||||
struct nand_chip *active;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nand_chip - NAND Private Flash Chip Data
|
||||
* @IO_ADDR_R: [BOARDSPECIFIC] address to read the 8 I/O lines of the flash device
|
||||
* @IO_ADDR_W: [BOARDSPECIFIC] address to write the 8 I/O lines of the flash device
|
||||
* @read_byte: [REPLACEABLE] read one byte from the chip
|
||||
* @write_byte: [REPLACEABLE] write one byte to the chip
|
||||
* @read_word: [REPLACEABLE] read one word from the chip
|
||||
* @write_word: [REPLACEABLE] write one word to the chip
|
||||
* @write_buf: [REPLACEABLE] write data from the buffer to the chip
|
||||
* @read_buf: [REPLACEABLE] read data from the chip into the buffer
|
||||
* @verify_buf: [REPLACEABLE] verify buffer contents against the chip data
|
||||
* @select_chip: [REPLACEABLE] select chip nr
|
||||
* @block_bad: [REPLACEABLE] check, if the block is bad
|
||||
* @block_markbad: [REPLACEABLE] mark the block bad
|
||||
* @hwcontrol: [BOARDSPECIFIC] hardwarespecific function for accesing control-lines
|
||||
* @dev_ready: [BOARDSPECIFIC] hardwarespecific function for accesing device ready/busy line
|
||||
* If set to NULL no access to ready/busy is available and the ready/busy information
|
||||
* is read from the chip status register
|
||||
* @cmdfunc: [REPLACEABLE] hardwarespecific function for writing commands to the chip
|
||||
* @waitfunc: [REPLACEABLE] hardwarespecific function for wait on ready
|
||||
* @calculate_ecc: [REPLACEABLE] function for ecc calculation or readback from ecc hardware
|
||||
* @correct_data: [REPLACEABLE] function for ecc correction, matching to ecc generator (sw/hw)
|
||||
* @enable_hwecc: [BOARDSPECIFIC] function to enable (reset) hardware ecc generator. Must only
|
||||
* be provided if a hardware ECC is available
|
||||
* @erase_cmd: [INTERN] erase command write function, selectable due to AND support
|
||||
* @scan_bbt: [REPLACEABLE] function to scan bad block table
|
||||
* @eccmode: [BOARDSPECIFIC] mode of ecc, see defines
|
||||
* @eccsize: [INTERN] databytes used per ecc-calculation
|
||||
* @eccbytes: [INTERN] number of ecc bytes per ecc-calculation step
|
||||
* @eccsteps: [INTERN] number of ecc calculation steps per page
|
||||
* @chip_delay: [BOARDSPECIFIC] chip dependent delay for transfering data from array to read regs (tR)
|
||||
* @chip_lock: [INTERN] spinlock used to protect access to this structure and the chip
|
||||
* @wq: [INTERN] wait queue to sleep on if a NAND operation is in progress
|
||||
* @state: [INTERN] the current state of the NAND device
|
||||
* @page_shift: [INTERN] number of address bits in a page (column address bits)
|
||||
* @phys_erase_shift: [INTERN] number of address bits in a physical eraseblock
|
||||
* @bbt_erase_shift: [INTERN] number of address bits in a bbt entry
|
||||
* @chip_shift: [INTERN] number of address bits in one chip
|
||||
* @data_buf: [INTERN] internal buffer for one page + oob
|
||||
* @oob_buf: [INTERN] oob buffer for one eraseblock
|
||||
* @oobdirty: [INTERN] indicates that oob_buf must be reinitialized
|
||||
* @data_poi: [INTERN] pointer to a data buffer
|
||||
* @options: [BOARDSPECIFIC] various chip options. They can partly be set to inform nand_scan about
|
||||
* special functionality. See the defines for further explanation
|
||||
* @badblockpos: [INTERN] position of the bad block marker in the oob area
|
||||
* @numchips: [INTERN] number of physical chips
|
||||
* @chipsize: [INTERN] the size of one chip for multichip arrays
|
||||
* @pagemask: [INTERN] page number mask = number of (pages / chip) - 1
|
||||
* @pagebuf: [INTERN] holds the pagenumber which is currently in data_buf
|
||||
* @autooob: [REPLACEABLE] the default (auto)placement scheme
|
||||
* @bbt: [INTERN] bad block table pointer
|
||||
* @bbt_td: [REPLACEABLE] bad block table descriptor for flash lookup
|
||||
* @bbt_md: [REPLACEABLE] bad block table mirror descriptor
|
||||
* @badblock_pattern: [REPLACEABLE] bad block scan pattern used for initial bad block scan
|
||||
* @controller: [OPTIONAL] a pointer to a hardware controller structure which is shared among multiple independend devices
|
||||
* @priv: [OPTIONAL] pointer to private chip date
|
||||
*/
|
||||
|
||||
struct nand_chip {
|
||||
void __iomem *IO_ADDR_R;
|
||||
void __iomem *IO_ADDR_W;
|
||||
|
||||
u_char (*read_byte)(struct mtd_info *mtd);
|
||||
void (*write_byte)(struct mtd_info *mtd, u_char byte);
|
||||
u16 (*read_word)(struct mtd_info *mtd);
|
||||
void (*write_word)(struct mtd_info *mtd, u16 word);
|
||||
|
||||
void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len);
|
||||
void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len);
|
||||
int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len);
|
||||
void (*select_chip)(struct mtd_info *mtd, int chip);
|
||||
int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);
|
||||
int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
|
||||
void (*hwcontrol)(struct mtd_info *mtd, int cmd);
|
||||
int (*dev_ready)(struct mtd_info *mtd);
|
||||
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);
|
||||
int (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code);
|
||||
int (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
|
||||
void (*enable_hwecc)(struct mtd_info *mtd, int mode);
|
||||
void (*erase_cmd)(struct mtd_info *mtd, int page);
|
||||
int (*scan_bbt)(struct mtd_info *mtd);
|
||||
int eccmode;
|
||||
int eccsize;
|
||||
int eccbytes;
|
||||
int eccsteps;
|
||||
int chip_delay;
|
||||
spinlock_t chip_lock;
|
||||
wait_queue_head_t wq;
|
||||
nand_state_t state;
|
||||
int page_shift;
|
||||
int phys_erase_shift;
|
||||
int bbt_erase_shift;
|
||||
int chip_shift;
|
||||
u_char *data_buf;
|
||||
u_char *oob_buf;
|
||||
int oobdirty;
|
||||
u_char *data_poi;
|
||||
unsigned int options;
|
||||
int badblockpos;
|
||||
int numchips;
|
||||
unsigned long chipsize;
|
||||
int pagemask;
|
||||
int pagebuf;
|
||||
struct nand_oobinfo *autooob;
|
||||
uint8_t *bbt;
|
||||
struct nand_bbt_descr *bbt_td;
|
||||
struct nand_bbt_descr *bbt_md;
|
||||
struct nand_bbt_descr *badblock_pattern;
|
||||
struct nand_hw_control *controller;
|
||||
void *priv;
|
||||
};
|
||||
|
||||
/*
|
||||
* NAND Flash Manufacturer ID Codes
|
||||
*/
|
||||
#define NAND_MFR_TOSHIBA 0x98
|
||||
#define NAND_MFR_SAMSUNG 0xec
|
||||
#define NAND_MFR_FUJITSU 0x04
|
||||
#define NAND_MFR_NATIONAL 0x8f
|
||||
#define NAND_MFR_RENESAS 0x07
|
||||
#define NAND_MFR_STMICRO 0x20
|
||||
|
||||
/**
|
||||
* struct nand_flash_dev - NAND Flash Device ID Structure
|
||||
*
|
||||
* @name: Identify the device type
|
||||
* @id: device ID code
|
||||
* @pagesize: Pagesize in bytes. Either 256 or 512 or 0
|
||||
* If the pagesize is 0, then the real pagesize
|
||||
* and the eraseize are determined from the
|
||||
* extended id bytes in the chip
|
||||
* @erasesize: Size of an erase block in the flash device.
|
||||
* @chipsize: Total chipsize in Mega Bytes
|
||||
* @options: Bitfield to store chip relevant options
|
||||
*/
|
||||
struct nand_flash_dev {
|
||||
char *name;
|
||||
int id;
|
||||
unsigned long pagesize;
|
||||
unsigned long chipsize;
|
||||
unsigned long erasesize;
|
||||
unsigned long options;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nand_manufacturers - 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[];
|
||||
|
||||
/**
|
||||
* struct nand_bbt_descr - bad block table descriptor
|
||||
* @options: options for this descriptor
|
||||
* @pages: the page(s) where we find the bbt, used with option BBT_ABSPAGE
|
||||
* when bbt is searched, then we store the found bbts pages here.
|
||||
* Its an array and supports up to 8 chips now
|
||||
* @offs: offset of the pattern in the oob area of the page
|
||||
* @veroffs: offset of the bbt version counter in the oob are of the page
|
||||
* @version: version read from the bbt page during scan
|
||||
* @len: length of the pattern, if 0 no pattern check is performed
|
||||
* @maxblocks: maximum number of blocks to search for a bbt. This number of
|
||||
* blocks is reserved at the end of the device where the tables are
|
||||
* written.
|
||||
* @reserved_block_code: if non-0, this pattern denotes a reserved (rather than
|
||||
* bad) block in the stored bbt
|
||||
* @pattern: pattern to identify bad block table or factory marked good /
|
||||
* bad blocks, can be NULL, if len = 0
|
||||
*
|
||||
* Descriptor for the bad block table marker and the descriptor for the
|
||||
* pattern which identifies good and bad blocks. The assumption is made
|
||||
* that the pattern and the version count are always located in the oob area
|
||||
* of the first block.
|
||||
*/
|
||||
struct nand_bbt_descr {
|
||||
int options;
|
||||
int pages[NAND_MAX_CHIPS];
|
||||
int offs;
|
||||
int veroffs;
|
||||
uint8_t version[NAND_MAX_CHIPS];
|
||||
int len;
|
||||
int maxblocks;
|
||||
int reserved_block_code;
|
||||
uint8_t *pattern;
|
||||
};
|
||||
|
||||
/* Options for the bad block table descriptors */
|
||||
|
||||
/* The number of bits used per block in the bbt on the device */
|
||||
#define NAND_BBT_NRBITS_MSK 0x0000000F
|
||||
#define NAND_BBT_1BIT 0x00000001
|
||||
#define NAND_BBT_2BIT 0x00000002
|
||||
#define NAND_BBT_4BIT 0x00000004
|
||||
#define NAND_BBT_8BIT 0x00000008
|
||||
/* The bad block table is in the last good block of the device */
|
||||
#define NAND_BBT_LASTBLOCK 0x00000010
|
||||
/* The bbt is at the given page, else we must scan for the bbt */
|
||||
#define NAND_BBT_ABSPAGE 0x00000020
|
||||
/* The bbt is at the given page, else we must scan for the bbt */
|
||||
#define NAND_BBT_SEARCH 0x00000040
|
||||
/* bbt is stored per chip on multichip devices */
|
||||
#define NAND_BBT_PERCHIP 0x00000080
|
||||
/* bbt has a version counter at offset veroffs */
|
||||
#define NAND_BBT_VERSION 0x00000100
|
||||
/* Create a bbt if none axists */
|
||||
#define NAND_BBT_CREATE 0x00000200
|
||||
/* Search good / bad pattern through all pages of a block */
|
||||
#define NAND_BBT_SCANALLPAGES 0x00000400
|
||||
/* Scan block empty during good / bad block scan */
|
||||
#define NAND_BBT_SCANEMPTY 0x00000800
|
||||
/* Write bbt if neccecary */
|
||||
#define NAND_BBT_WRITE 0x00001000
|
||||
/* Read and write back block contents when writing bbt */
|
||||
#define NAND_BBT_SAVECONTENT 0x00002000
|
||||
/* Search good / bad pattern on the first and the second page */
|
||||
#define NAND_BBT_SCAN2NDPAGE 0x00004000
|
||||
|
||||
/* The maximum number of blocks to scan for a bbt */
|
||||
#define NAND_BBT_SCAN_MAXBLOCKS 4
|
||||
|
||||
extern int nand_scan_bbt (struct mtd_info *mtd, struct nand_bbt_descr *bd);
|
||||
extern int nand_update_bbt (struct mtd_info *mtd, loff_t offs);
|
||||
extern int nand_default_bbt (struct mtd_info *mtd);
|
||||
extern int nand_isbad_bbt (struct mtd_info *mtd, loff_t offs, int allowbbt);
|
||||
extern int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int allowbbt);
|
||||
|
||||
/*
|
||||
* Constants for oob configuration
|
||||
*/
|
||||
#define NAND_SMALL_BADBLOCK_POS 5
|
||||
#define NAND_LARGE_BADBLOCK_POS 0
|
||||
|
||||
#endif /* __LINUX_MTD_NAND_H */
|
30
include/linux/mtd/nand_ecc.h
Normal file
30
include/linux/mtd/nand_ecc.h
Normal file
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* drivers/mtd/nand_ecc.h
|
||||
*
|
||||
* Copyright (C) 2000 Steven J. Hill (sjhill@realitydiluted.com)
|
||||
*
|
||||
* $Id: nand_ecc.h,v 1.4 2004/06/17 02:35:02 dbrown 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.
|
||||
*/
|
||||
|
||||
#ifndef __MTD_NAND_ECC_H__
|
||||
#define __MTD_NAND_ECC_H__
|
||||
|
||||
struct mtd_info;
|
||||
|
||||
/*
|
||||
* Calculate 3 byte ECC code for 256 byte block
|
||||
*/
|
||||
int nand_calculate_ecc(struct mtd_info *mtd, const u_char *dat, u_char *ecc_code);
|
||||
|
||||
/*
|
||||
* Detect and correct a 1 bit error for 256 byte block
|
||||
*/
|
||||
int nand_correct_data(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
|
||||
|
||||
#endif /* __MTD_NAND_ECC_H__ */
|
54
include/linux/mtd/nftl.h
Normal file
54
include/linux/mtd/nftl.h
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* $Id: nftl.h,v 1.16 2004/06/30 14:49:00 dbrown Exp $
|
||||
*
|
||||
* (C) 1999-2003 David Woodhouse <dwmw2@infradead.org>
|
||||
*/
|
||||
|
||||
#ifndef __MTD_NFTL_H__
|
||||
#define __MTD_NFTL_H__
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/blktrans.h>
|
||||
|
||||
#include <mtd/nftl-user.h>
|
||||
|
||||
/* 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_blktrans_dev mbd;
|
||||
__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 */
|
||||
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 nand_oobinfo oobinfo;
|
||||
};
|
||||
|
||||
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 64
|
||||
#define NFTL_PARTN_BITS 4
|
||||
|
||||
#endif /* __MTD_NFTL_H__ */
|
75
include/linux/mtd/partitions.h
Normal file
75
include/linux/mtd/partitions.h
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* MTD partitioning layer definitions
|
||||
*
|
||||
* (C) 2000 Nicolas Pitre <nico@cam.org>
|
||||
*
|
||||
* This code is GPL
|
||||
*
|
||||
* $Id: partitions.h,v 1.16 2004/11/16 18:34:40 dwmw2 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 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)
|
||||
|
||||
|
||||
int add_mtd_partitions(struct mtd_info *, const 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 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
|
||||
|
61
include/linux/mtd/physmap.h
Normal file
61
include/linux/mtd/physmap.h
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* For boards with physically mapped flash and using
|
||||
* drivers/mtd/maps/physmap.c mapping driver.
|
||||
*
|
||||
* $Id: physmap.h,v 1.3 2004/07/21 00:16:15 jwboyer Exp $
|
||||
*
|
||||
* Copyright (C) 2003 MontaVista Software Inc.
|
||||
* Author: Jun Sun, jsun@mvista.com or jsun@junsun.net
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation; either version 2 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MTD_PHYSMAP__
|
||||
|
||||
#include <linux/config.h>
|
||||
|
||||
#if defined(CONFIG_MTD_PHYSMAP)
|
||||
|
||||
#include <linux/mtd/mtd.h>
|
||||
#include <linux/mtd/map.h>
|
||||
#include <linux/mtd/partitions.h>
|
||||
|
||||
/*
|
||||
* The map_info for physmap. Board can override size, buswidth, phys,
|
||||
* (*set_vpp)(), etc in their initial setup routine.
|
||||
*/
|
||||
extern struct map_info physmap_map;
|
||||
|
||||
/*
|
||||
* Board needs to specify the exact mapping during their setup time.
|
||||
*/
|
||||
static inline void physmap_configure(unsigned long addr, unsigned long size, int bankwidth, void (*set_vpp)(struct map_info *, int) )
|
||||
{
|
||||
physmap_map.phys = addr;
|
||||
physmap_map.size = size;
|
||||
physmap_map.bankwidth = bankwidth;
|
||||
physmap_map.set_vpp = set_vpp;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_MTD_PARTITIONS)
|
||||
|
||||
/*
|
||||
* Machines that wish to do flash partition may want to call this function in
|
||||
* their setup routine.
|
||||
*
|
||||
* physmap_set_partitions(mypartitions, num_parts);
|
||||
*
|
||||
* Note that one can always override this hard-coded partition with
|
||||
* command line partition (you need to enable CONFIG_MTD_CMDLINE_PARTS).
|
||||
*/
|
||||
void physmap_set_partitions(struct mtd_partition *parts, int num_parts);
|
||||
|
||||
#endif /* defined(CONFIG_MTD_PARTITIONS) */
|
||||
#endif /* defined(CONFIG_MTD) */
|
||||
|
||||
#endif /* __LINUX_MTD_PHYSMAP__ */
|
||||
|
79
include/linux/mtd/pmc551.h
Normal file
79
include/linux/mtd/pmc551.h
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* $Id: pmc551.h,v 1.5 2003/01/24 16:49:53 dwmw2 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.5 2003/01/24 16:49:53 dwmw2 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 *, 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 *);
|
||||
|
||||
|
||||
/*
|
||||
* 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__ */
|
||||
|
107
include/linux/mtd/xip.h
Normal file
107
include/linux/mtd/xip.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* MTD primitives for XIP support
|
||||
*
|
||||
* Author: Nicolas Pitre
|
||||
* Created: Nov 2, 2004
|
||||
* Copyright: (C) 2004 MontaVista Software, Inc.
|
||||
*
|
||||
* This XIP support for MTD has been loosely inspired
|
||||
* by an earlier patch authored by David Woodhouse.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* $Id: xip.h,v 1.2 2004/12/01 15:49:10 nico Exp $
|
||||
*/
|
||||
|
||||
#ifndef __LINUX_MTD_XIP_H__
|
||||
#define __LINUX_MTD_XIP_H__
|
||||
|
||||
#include <linux/config.h>
|
||||
|
||||
#ifdef CONFIG_MTD_XIP
|
||||
|
||||
/*
|
||||
* Function that are modifying the flash state away from array mode must
|
||||
* obviously not be running from flash. The __xipram is therefore marking
|
||||
* those functions so they get relocated to ram.
|
||||
*/
|
||||
#define __xipram __attribute__ ((__section__ (".data")))
|
||||
|
||||
/*
|
||||
* We really don't want gcc to guess anything.
|
||||
* We absolutely _need_ proper inlining.
|
||||
*/
|
||||
#include <linux/compiler.h>
|
||||
|
||||
/*
|
||||
* Each architecture has to provide the following macros. They must access
|
||||
* the hardware directly and not rely on any other (XIP) functions since they
|
||||
* won't be available when used (flash not in array mode).
|
||||
*
|
||||
* xip_irqpending()
|
||||
*
|
||||
* return non zero when any hardware interrupt is pending.
|
||||
*
|
||||
* xip_currtime()
|
||||
*
|
||||
* return a platform specific time reference to be used with
|
||||
* xip_elapsed_since().
|
||||
*
|
||||
* xip_elapsed_since(x)
|
||||
*
|
||||
* return in usecs the elapsed timebetween now and the reference x as
|
||||
* returned by xip_currtime().
|
||||
*
|
||||
* note 1: convertion to usec can be approximated, as long as the
|
||||
* returned value is <= the real elapsed time.
|
||||
* note 2: this should be able to cope with a few seconds without
|
||||
* overflowing.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_ARCH_SA1100) || defined(CONFIG_ARCH_PXA)
|
||||
|
||||
#include <asm/hardware.h>
|
||||
#ifdef CONFIG_ARCH_PXA
|
||||
#include <asm/arch/pxa-regs.h>
|
||||
#endif
|
||||
|
||||
#define xip_irqpending() (ICIP & ICMR)
|
||||
|
||||
/* we sample OSCR and convert desired delta to usec (1/4 ~= 1000000/3686400) */
|
||||
#define xip_currtime() (OSCR)
|
||||
#define xip_elapsed_since(x) (signed)((OSCR - (x)) / 4)
|
||||
|
||||
#else
|
||||
|
||||
#warning "missing IRQ and timer primitives for XIP MTD support"
|
||||
#warning "some of the XIP MTD support code will be disabled"
|
||||
#warning "your system will therefore be unresponsive when writing or erasing flash"
|
||||
|
||||
#define xip_irqpending() (0)
|
||||
#define xip_currtime() (0)
|
||||
#define xip_elapsed_since(x) (0)
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
* xip_cpu_idle() is used when waiting for a delay equal or larger than
|
||||
* the system timer tick period. This should put the CPU into idle mode
|
||||
* to save power and to be woken up only when some interrupts are pending.
|
||||
* As above, this should not rely upon standard kernel code.
|
||||
*/
|
||||
|
||||
#if defined(CONFIG_CPU_XSCALE)
|
||||
#define xip_cpu_idle() asm volatile ("mcr p14, 0, %0, c7, c0, 0" :: "r" (1))
|
||||
#else
|
||||
#define xip_cpu_idle() do { } while (0)
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#define __xipram
|
||||
|
||||
#endif /* CONFIG_MTD_XIP */
|
||||
|
||||
#endif /* __LINUX_MTD_XIP_H__ */
|
Reference in New Issue
Block a user