diff options
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/err.h | 45 | ||||
| -rw-r--r-- | include/linux/mtd/blktrans.h | 81 | ||||
| -rw-r--r-- | include/linux/mtd/compat.h | 7 | ||||
| -rw-r--r-- | include/linux/mtd/doc2000.h | 215 | ||||
| -rw-r--r-- | include/linux/mtd/inftl-user.h | 91 | ||||
| -rw-r--r-- | include/linux/mtd/jffs2-user.h | 35 | ||||
| -rw-r--r-- | include/linux/mtd/mtd-abi.h | 135 | ||||
| -rw-r--r-- | include/linux/mtd/mtd.h | 150 | ||||
| -rw-r--r-- | include/linux/mtd/nand.h | 450 | ||||
| -rw-r--r-- | include/linux/mtd/nftl-user.h | 76 | ||||
| -rw-r--r-- | include/linux/mtd/nftl.h | 93 | ||||
| -rw-r--r-- | include/linux/mtd/ubi-header.h | 360 | ||||
| -rw-r--r-- | include/linux/mtd/ubi-user.h | 161 | 
13 files changed, 1482 insertions, 417 deletions
| diff --git a/include/linux/err.h b/include/linux/err.h new file mode 100644 index 000000000..4e08c4fe6 --- /dev/null +++ b/include/linux/err.h @@ -0,0 +1,45 @@ +#ifndef _LINUX_ERR_H +#define _LINUX_ERR_H + +/* XXX U-BOOT XXX */ +#if 0 +#include <linux/compiler.h> +#else +#include <linux/mtd/compat.h> +#endif + +#include <asm/errno.h> + + +/* + * Kernel pointers have redundant information, so we can use a + * scheme where we can return either an error code or a dentry + * pointer with the same return value. + * + * This should be a per-architecture thing, to allow different + * error and pointer decisions. + */ +#define MAX_ERRNO	4095 + +#ifndef __ASSEMBLY__ + +#define IS_ERR_VALUE(x) unlikely((x) >= (unsigned long)-MAX_ERRNO) + +static inline void *ERR_PTR(long error) +{ +	return (void *) error; +} + +static inline long PTR_ERR(const void *ptr) +{ +	return (long) ptr; +} + +static inline long IS_ERR(const void *ptr) +{ +	return IS_ERR_VALUE((unsigned long)ptr); +} + +#endif + +#endif /* _LINUX_ERR_H */ diff --git a/include/linux/mtd/blktrans.h b/include/linux/mtd/blktrans.h new file mode 100644 index 000000000..d1ded51d7 --- /dev/null +++ b/include/linux/mtd/blktrans.h @@ -0,0 +1,81 @@ +/* + * $Id: blktrans.h,v 1.6 2005/11/07 11:14:54 gleixner 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__ + +/* XXX U-BOOT XXX */ +#if 0 +#include <linux/mutex.h> +#else +#include <linux/list.h> +#endif + +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; +/* XXX U-BOOT XXX */ +#if 0 +	struct mutex lock; +#endif +	int devnum; +	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; +	int blksize; +	int blkshift; + +	/* 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__ */ diff --git a/include/linux/mtd/compat.h b/include/linux/mtd/compat.h index fe55087ea..86a6e43ca 100644 --- a/include/linux/mtd/compat.h +++ b/include/linux/mtd/compat.h @@ -18,7 +18,12 @@  #define KERN_DEBUG  #define kmalloc(size, flags)	malloc(size) -#define kfree(ptr)		free(ptr) +#define kzalloc(size, flags)    calloc(size, 1) +#define vmalloc(size)			malloc(size) +#define kfree(ptr)		        free(ptr) +#define vfree(ptr)              free(ptr) + +#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))  /*   * ..and if you can't take the strict diff --git a/include/linux/mtd/doc2000.h b/include/linux/mtd/doc2000.h index 29f676786..12de2845a 100644 --- a/include/linux/mtd/doc2000.h +++ b/include/linux/mtd/doc2000.h @@ -1,15 +1,23 @@ - -/* Linux driver for Disk-On-Chip 2000       */ -/* (c) 1999 Machine Vision Holdings, Inc.   */ -/* Author: David Woodhouse <dwmw2@mvhi.com> */ -/* $Id: doc2000.h,v 1.15 2001/09/19 00:22:15 dwmw2 Exp $ */ +/* + * 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.25 2005/11/07 11:14:54 gleixner Exp $ + * + * Released under GPL + */  #ifndef __MTD_DOC2000_H__  #define __MTD_DOC2000_H__ -struct DiskOnChip; - -#include <linux/mtd/nftl.h> +#include <linux/mtd/mtd.h> +#if 0 +#include <linux/mutex.h> +#endif  #define DoC_Sig1 0  #define DoC_Sig2 1 @@ -40,10 +48,58 @@ struct DiskOnChip;  #define DoC_Mil_CDSN_IO		0x0800  #define DoC_2k_CDSN_IO		0x1800 -#define ReadDOC_(adr, reg)      ((volatile unsigned char)(*(volatile __u8 *)(((unsigned long)adr)+((reg))))) -#define WriteDOC_(d, adr, reg)  do{ *(volatile __u8 *)(((unsigned long)adr)+((reg))) = (__u8)d; eieio();} while(0) +#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 -#define DOC_IOREMAP_LEN		0x4000 +/* 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) @@ -54,14 +110,21 @@ struct DiskOnChip;  #define DOC_MODE_RESERVED1	2  #define DOC_MODE_RESERVED2	3 -#define DOC_MODE_MDWREN		4  #define DOC_MODE_CLR_ERR	0x80 +#define	DOC_MODE_RST_LAT	0x10 +#define	DOC_MODE_BDECT		0x08 +#define DOC_MODE_MDWREN	0x04 -#define DOC_ChipID_UNKNOWN	0x00  #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 @@ -77,41 +140,47 @@ struct DiskOnChip;  #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 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 Nand { -	char floor, chip; -	unsigned long curadr; -	unsigned char curmode; -	/* Also some erase/write/pipeline info when we get that far */ -}; -  struct DiskOnChip {  	unsigned long physadr; -	unsigned long virtadr; +	void __iomem *virtadr;  	unsigned long totlen; -	char* name; -	char ChipID; /* Type of DiskOnChip */ +	unsigned char ChipID; /* Type of DiskOnChip */  	int ioreg; -	char* chips_name;  	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; @@ -119,98 +188,22 @@ struct DiskOnChip {  	int numchips;  	struct Nand *chips; - -	int nftl_found; -	struct NFTLrecord nftl; +	struct mtd_info *nextdoc; +/* XXX U-BOOT XXX */ +#if 0 +	struct mutex lock; +#endif  }; -#define SECTORSIZE 512 - -/* Return codes from doc_write(), doc_read(), and doc_erase(). - */ -#define DOC_OK		0 -#define DOC_EIO		1 -#define DOC_EINVAL	2 -#define DOC_EECC	3 -#define DOC_ETIMEOUT	4 - -/* - * Function Prototypes - */  int doc_decode_ecc(unsigned char sector[512], unsigned char ecc1[6]); -int doc_rw(struct DiskOnChip* this, int cmd, loff_t from, size_t len, -	   size_t *retlen, u_char *buf); -int doc_read_ecc(struct DiskOnChip* this, loff_t from, size_t len, -		 size_t *retlen, u_char *buf, u_char *eccbuf); -int doc_write_ecc(struct DiskOnChip* this, loff_t to, size_t len, -		  size_t *retlen, const u_char *buf, u_char *eccbuf); -int doc_read_oob(struct DiskOnChip* this, loff_t ofs, size_t len, -		 size_t *retlen, u_char *buf); -int doc_write_oob(struct DiskOnChip* this, loff_t ofs, size_t len, -		  size_t *retlen, const u_char *buf); -int doc_erase (struct DiskOnChip* this, loff_t ofs, size_t len); - -void doc_probe(unsigned long physadr); - -void doc_print(struct DiskOnChip*); - -/* - * Standard NAND flash commands - */ -#define NAND_CMD_READ0		0 -#define NAND_CMD_READ1		1 -#define NAND_CMD_PAGEPROG	0x10 -#define NAND_CMD_READOOB	0x50 -#define NAND_CMD_ERASE1		0x60 -#define NAND_CMD_STATUS		0x70 -#define NAND_CMD_SEQIN		0x80 -#define NAND_CMD_READID		0x90 -#define NAND_CMD_ERASE2		0xd0 -#define NAND_CMD_RESET		0xff - +/* XXX U-BOOT XXX */ +#if 1  /*   * NAND Flash Manufacturer ID Codes   */ -#define NAND_MFR_TOSHIBA	0x98 -#define NAND_MFR_SAMSUNG	0xec - -/* - * NAND Flash Device ID Structure - * - * Structure overview: - * - *  name - Complete name of device - * - *  manufacture_id - manufacturer ID code of device. - * - *  model_id - model ID code of device. - * - *  chipshift - total number of address bits for the device which - *              is used to calculate address offsets and the total - *              number of bytes the device is capable of. - * - *  page256 - denotes if flash device has 256 byte pages or not. - * - *  pageadrlen - number of bytes minus one needed to hold the - *               complete address into the flash array. Keep in - *               mind that when a read or write is done to a - *               specific address, the address is input serially - *               8 bits at a time. This structure member is used - *               by the read/write routines as a loop index for - *               shifting the address out 8 bits at a time. - * - *  erasesize - size of an erase block in the flash device. - */ -struct nand_flash_dev { -	char * name; -	int manufacture_id; -	int model_id; -	int chipshift; -	char page256; -	char pageadrlen; -	unsigned long erasesize; -	int bus16; -}; +#define NAND_MFR_TOSHIBA   0x98 +#define NAND_MFR_SAMSUNG   0xec +#endif  #endif /* __MTD_DOC2000_H__ */ diff --git a/include/linux/mtd/inftl-user.h b/include/linux/mtd/inftl-user.h new file mode 100644 index 000000000..9b1e2526b --- /dev/null +++ b/include/linux/mtd/inftl-user.h @@ -0,0 +1,91 @@ +/* + * $Id: inftl-user.h,v 1.2 2005/11/07 11:14:56 gleixner Exp $ + * + * Parts of INFTL headers shared with userspace + * + */ + +#ifndef __MTD_INFTL_USER_H__ +#define __MTD_INFTL_USER_H__ + +#define	OSAK_VERSION	0x5120 +#define	PERCENTUSED	98 + +#define	SECTORSIZE	512 + +/* Block Control Information */ + +struct inftl_bci { +	uint8_t ECCsig[6]; +	uint8_t Status; +	uint8_t Status1; +} __attribute__((packed)); + +struct inftl_unithead1 { +	uint16_t virtualUnitNo; +	uint16_t prevUnitNo; +	uint8_t ANAC; +	uint8_t NACs; +	uint8_t parityPerField; +	uint8_t discarded; +} __attribute__((packed)); + +struct inftl_unithead2 { +	uint8_t parityPerField; +	uint8_t ANAC; +	uint16_t prevUnitNo; +	uint16_t virtualUnitNo; +	uint8_t NACs; +	uint8_t discarded; +} __attribute__((packed)); + +struct inftl_unittail { +	uint8_t Reserved[4]; +	uint16_t EraseMark; +	uint16_t EraseMark1; +} __attribute__((packed)); + +union inftl_uci { +	struct inftl_unithead1 a; +	struct inftl_unithead2 b; +	struct inftl_unittail c; +}; + +struct inftl_oob { +	struct inftl_bci b; +	union inftl_uci u; +}; + + +/* INFTL Media Header */ + +struct INFTLPartition { +	__u32 virtualUnits; +	__u32 firstUnit; +	__u32 lastUnit; +	__u32 flags; +	__u32 spareUnits; +	__u32 Reserved0; +	__u32 Reserved1; +} __attribute__((packed)); + +struct INFTLMediaHeader { +	char bootRecordID[8]; +	__u32 NoOfBootImageBlocks; +	__u32 NoOfBinaryPartitions; +	__u32 NoOfBDTLPartitions; +	__u32 BlockMultiplierBits; +	__u32 FormatFlags; +	__u32 OsakVersion; +	__u32 PercentUsed; +	struct INFTLPartition Partitions[4]; +} __attribute__((packed)); + +/* Partition flag types */ +#define	INFTL_BINARY	0x20000000 +#define	INFTL_BDTL	0x40000000 +#define	INFTL_LAST	0x80000000 + +#endif /* __MTD_INFTL_USER_H__ */ + + diff --git a/include/linux/mtd/jffs2-user.h b/include/linux/mtd/jffs2-user.h new file mode 100644 index 000000000..d508ef0ae --- /dev/null +++ b/include/linux/mtd/jffs2-user.h @@ -0,0 +1,35 @@ +/* + * $Id: jffs2-user.h,v 1.1 2004/05/05 11:57:54 dwmw2 Exp $ + * + * JFFS2 definitions for use in user space only + */ + +#ifndef __JFFS2_USER_H__ +#define __JFFS2_USER_H__ + +/* This file is blessed for inclusion by userspace */ +#include <linux/jffs2.h> +#include <endian.h> +#include <byteswap.h> + +#undef cpu_to_je16 +#undef cpu_to_je32 +#undef cpu_to_jemode +#undef je16_to_cpu +#undef je32_to_cpu +#undef jemode_to_cpu + +extern int target_endian; + +#define t16(x) ({ uint16_t __b = (x); (target_endian==__BYTE_ORDER)?__b:bswap_16(__b); }) +#define t32(x) ({ uint32_t __b = (x); (target_endian==__BYTE_ORDER)?__b:bswap_32(__b); }) + +#define cpu_to_je16(x) ((jint16_t){t16(x)}) +#define cpu_to_je32(x) ((jint32_t){t32(x)}) +#define cpu_to_jemode(x) ((jmode_t){t32(x)}) + +#define je16_to_cpu(x) (t16((x).v16)) +#define je32_to_cpu(x) (t32((x).v32)) +#define jemode_to_cpu(x) (t32((x).m)) + +#endif /* __JFFS2_USER_H__ */ diff --git a/include/linux/mtd/mtd-abi.h b/include/linux/mtd/mtd-abi.h index 4cebea959..0ce2099d6 100644 --- a/include/linux/mtd/mtd-abi.h +++ b/include/linux/mtd/mtd-abi.h @@ -1,5 +1,5 @@  /* - * $Id: mtd-abi.h,v 1.7 2004/11/23 15:37:32 gleixner Exp $ + * $Id: mtd-abi.h,v 1.13 2005/11/07 11:14:56 gleixner Exp $   *   * Portions of MTD ABI definition which are shared by kernel and user space   */ @@ -7,6 +7,10 @@  #ifndef __MTD_ABI_H__  #define __MTD_ABI_H__ +#if 1 +#include <linux/mtd/compat.h> +#endif +  struct erase_info_user {  	uint32_t start;  	uint32_t length; @@ -15,7 +19,7 @@ struct erase_info_user {  struct mtd_oob_buf {  	uint32_t start;  	uint32_t length; -	unsigned char *ptr; +	unsigned char __user *ptr;  };  #define MTD_ABSENT		0 @@ -23,47 +27,41 @@ struct mtd_oob_buf {  #define MTD_ROM			2  #define MTD_NORFLASH		3  #define MTD_NANDFLASH		4 -#define MTD_PEROM		5 -#define MTD_OTHER		14 -#define MTD_UNKNOWN		15 +#define MTD_DATAFLASH		6 +#define MTD_UBIVOLUME		7 -#define MTD_CLEAR_BITS		1       /* Bits can be cleared (flash) */ -#define MTD_SET_BITS		2       /* Bits can be set */ -#define MTD_ERASEABLE		4       /* Has an erase function */ -#define MTD_WRITEB_WRITEABLE	8       /* Direct IO is possible */ -#define MTD_VOLATILE		16      /* Set for RAMs */ -#define MTD_XIP			32	/* eXecute-In-Place possible */ -#define MTD_OOB			64	/* Out-of-band data (NAND flash) */ -#define MTD_ECC			128	/* Device capable of automatic ECC */ -#define MTD_NO_VIRTBLOCKS	256	/* Virtual blocks not allowed */ +#define MTD_WRITEABLE		0x400	/* Device is writeable */ +#define MTD_BIT_WRITEABLE	0x800	/* Single bits can be flipped */ +#define MTD_NO_ERASE		0x1000	/* No erase necessary */ +#define MTD_STUPID_LOCK		0x2000	/* Always locked after reset */ -/* Some common devices / combinations of capabilities */ +// Some common devices / combinations of capabilities  #define MTD_CAP_ROM		0 -#define MTD_CAP_RAM		(MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEB_WRITEABLE) -#define MTD_CAP_NORFLASH        (MTD_CLEAR_BITS|MTD_ERASEABLE) -#define MTD_CAP_NANDFLASH       (MTD_CLEAR_BITS|MTD_ERASEABLE|MTD_OOB) -#define MTD_WRITEABLE		(MTD_CLEAR_BITS|MTD_SET_BITS) - - -/* Types of automatic ECC/Checksum available */ -#define MTD_ECC_NONE		0	/* No automatic ECC available */ -#define MTD_ECC_RS_DiskOnChip	1	/* Automatic ECC on DiskOnChip */ -#define MTD_ECC_SW		2	/* SW ECC for Toshiba & Samsung devices */ +#define MTD_CAP_RAM		(MTD_WRITEABLE | MTD_BIT_WRITEABLE | MTD_NO_ERASE) +#define MTD_CAP_NORFLASH	(MTD_WRITEABLE | MTD_BIT_WRITEABLE) +#define MTD_CAP_NANDFLASH	(MTD_WRITEABLE)  /* ECC byte placement */ -#define MTD_NANDECC_OFF		0	/* Switch off ECC (Not recommended) */ -#define MTD_NANDECC_PLACE	1	/* Use the given placement in the structure (YAFFS1 legacy mode) */ -#define MTD_NANDECC_AUTOPLACE	2	/* Use the default placement scheme */ -#define MTD_NANDECC_PLACEONLY	3	/* Use the given placement in the structure (Do not store ecc result on read) */ -#define MTD_NANDECC_AUTOPL_USR	4	/* Use the given autoplacement scheme rather than using the default */ +#define MTD_NANDECC_OFF		0	// Switch off ECC (Not recommended) +#define MTD_NANDECC_PLACE	1	// Use the given placement in the structure (YAFFS1 legacy mode) +#define MTD_NANDECC_AUTOPLACE	2	// Use the default placement scheme +#define MTD_NANDECC_PLACEONLY	3	// Use the given placement in the structure (Do not store ecc result on read) +#define MTD_NANDECC_AUTOPL_USR	4	// Use the given autoplacement scheme rather than using the default + +/* OTP mode selection */ +#define MTD_OTP_OFF		0 +#define MTD_OTP_FACTORY		1 +#define MTD_OTP_USER		2  struct mtd_info_user {  	uint8_t type;  	uint32_t flags; -	uint32_t size;	 /* Total size of the MTD */ +	uint32_t size;	 // Total size of the MTD  	uint32_t erasesize; -	uint32_t oobblock;  /* Size of OOB blocks (e.g. 512) */ -	uint32_t oobsize;   /* Amount of OOB data per block (e.g. 16) */ +	uint32_t writesize; +	uint32_t oobsize;   // Amount of OOB data per block (e.g. 16) +	/* The below two fields are obsolete and broken, do not use them +	 * (TODO: remove at some point) */  	uint32_t ecctype;  	uint32_t eccsize;  }; @@ -76,19 +74,36 @@ struct region_info_user {  	uint32_t regionindex;  }; -#define MEMGETINFO              _IOR('M', 1, struct mtd_info_user) -#define MEMERASE                _IOW('M', 2, struct erase_info_user) -#define MEMWRITEOOB             _IOWR('M', 3, struct mtd_oob_buf) -#define MEMREADOOB              _IOWR('M', 4, struct mtd_oob_buf) -#define MEMLOCK                 _IOW('M', 5, struct erase_info_user) -#define MEMUNLOCK               _IOW('M', 6, struct erase_info_user) +struct otp_info { +	uint32_t start; +	uint32_t length; +	uint32_t locked; +}; + +#define MEMGETINFO		_IOR('M', 1, struct mtd_info_user) +#define MEMERASE		_IOW('M', 2, struct erase_info_user) +#define MEMWRITEOOB		_IOWR('M', 3, struct mtd_oob_buf) +#define MEMREADOOB		_IOWR('M', 4, struct mtd_oob_buf) +#define MEMLOCK			_IOW('M', 5, struct erase_info_user) +#define MEMUNLOCK		_IOW('M', 6, struct erase_info_user)  #define MEMGETREGIONCOUNT	_IOR('M', 7, int)  #define MEMGETREGIONINFO	_IOWR('M', 8, struct region_info_user)  #define MEMSETOOBSEL		_IOW('M', 9, struct nand_oobinfo)  #define MEMGETOOBSEL		_IOR('M', 10, struct nand_oobinfo)  #define MEMGETBADBLOCK		_IOW('M', 11, loff_t)  #define MEMSETBADBLOCK		_IOW('M', 12, loff_t) +#define OTPSELECT		_IOR('M', 13, int) +#define OTPGETREGIONCOUNT	_IOW('M', 14, int) +#define OTPGETREGIONINFO	_IOW('M', 15, struct otp_info) +#define OTPLOCK			_IOR('M', 16, struct otp_info) +#define ECCGETLAYOUT		_IOR('M', 17, struct nand_ecclayout) +#define ECCGETSTATS		_IOR('M', 18, struct mtd_ecc_stats) +#define MTDFILEMODE		_IO('M', 19) +/* + * Obsolete legacy interface. Keep it in order not to break userspace + * interfaces + */  struct nand_oobinfo {  	uint32_t useecc;  	uint32_t eccbytes; @@ -96,4 +111,46 @@ struct nand_oobinfo {  	uint32_t eccpos[48];  }; +struct nand_oobfree { +	uint32_t offset; +	uint32_t length; +}; + +#define MTD_MAX_OOBFREE_ENTRIES	8 +/* + * ECC layout control structure. Exported to userspace for + * diagnosis and to allow creation of raw images + */ +struct nand_ecclayout { +	uint32_t eccbytes; +	uint32_t eccpos[64]; +	uint32_t oobavail; +	struct nand_oobfree oobfree[MTD_MAX_OOBFREE_ENTRIES]; +}; + +/** + * struct mtd_ecc_stats - error correction stats + * + * @corrected:	number of corrected bits + * @failed:	number of uncorrectable errors + * @badblocks:	number of bad blocks in this partition + * @bbtblocks:	number of blocks reserved for bad block tables + */ +struct mtd_ecc_stats { +	uint32_t corrected; +	uint32_t failed; +	uint32_t badblocks; +	uint32_t bbtblocks; +}; + +/* + * Read/write file modes for access to MTD + */ +enum mtd_file_modes { +	MTD_MODE_NORMAL = MTD_OTP_OFF, +	MTD_MODE_OTP_FACTORY = MTD_OTP_FACTORY, +	MTD_MODE_OTP_USER = MTD_OTP_USER, +	MTD_MODE_RAW, +}; +  #endif /* __MTD_ABI_H__ */ diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 05ba375a8..8e0dc00f7 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -1,5 +1,5 @@  /* - * $Id: mtd.h,v 1.56 2004/08/09 18:46:04 dmarlin Exp $ + * $Id: mtd.h,v 1.61 2005/11/07 11:14:54 gleixner Exp $   *   * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al.   * @@ -8,10 +8,13 @@  #ifndef __MTD_MTD_H__  #define __MTD_MTD_H__ +  #include <linux/types.h>  #include <linux/mtd/mtd-abi.h> -#define MAX_MTD_DEVICES 16 +#define MTD_CHAR_MAJOR 90 +#define MTD_BLOCK_MAJOR 31 +#define MAX_MTD_DEVICES 32  #define MTD_ERASE_PENDING	0x01  #define MTD_ERASING		0x02 @@ -41,32 +44,83 @@ 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 */ +	unsigned long *lockmap;		/* If keeping bitmap of locks */ +}; + +/* + * oob operation modes + * + * MTD_OOB_PLACE:	oob data are placed at the given offset + * MTD_OOB_AUTO:	oob data are automatically placed at the free areas + *			which are defined by the ecclayout + * MTD_OOB_RAW:		mode to read raw data+oob in one chunk. The oob data + *			is inserted into the data. Thats a raw image of the + *			flash contents. + */ +typedef enum { +	MTD_OOB_PLACE, +	MTD_OOB_AUTO, +	MTD_OOB_RAW, +} mtd_oob_mode_t; + +/** + * struct mtd_oob_ops - oob operation operands + * @mode:	operation mode + * + * @len:	number of data bytes to write/read + * + * @retlen:	number of data bytes written/read + * + * @ooblen:	number of oob bytes to write/read + * @oobretlen:	number of oob bytes written/read + * @ooboffs:	offset of oob data in the oob area (only relevant when + *		mode = MTD_OOB_PLACE) + * @datbuf:	data buffer - if NULL only oob data are read/written + * @oobbuf:	oob data buffer + * + * Note, it is allowed to read more then one OOB area at one go, but not write. + * The interface assumes that the OOB write requests program only one page's + * OOB area. + */ +struct mtd_oob_ops { +	mtd_oob_mode_t	mode; +	size_t		len; +	size_t		retlen; +	size_t		ooblen; +	size_t		oobretlen; +	uint32_t	ooboffs; +	uint8_t		*datbuf; +	uint8_t		*oobbuf;  };  struct mtd_info {  	u_char type;  	u_int32_t flags; -	u_int32_t size;	 /* Total size of the MTD */ +	u_int32_t size;	 // Total size of the MTD -	/* "Major" erase size for the device. Naοve users may take this +	/* "Major" erase size for the device. NaΓ―ve users may take this  	 * to be the only erase size available, or may use the more detailed  	 * information below if they desire  	 */  	u_int32_t erasesize; +	/* Minimal writable flash unit size. In case of NOR flash it is 1 (even +	 * though individual bits can be cleared), in case of NAND flash it is +	 * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR +	 * it is of ECC block size, etc. It is illegal to have writesize = 0. +	 * Any driver registering a struct mtd_info must ensure a writesize of +	 * 1 or larger. +	 */ +	u_int32_t writesize; -	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; - +	u_int32_t oobsize;   // Amount of OOB data per block (e.g. 16) +	u_int32_t oobavail;  // Available OOB bytes per block -	/* Kernel-only stuff starts here. */ +	// 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; +	/* ecc layout structure pointer - read only ! */ +	struct nand_ecclayout *ecclayout;  	/* Data for variable erase regions. If numeraseregions is zero,  	 * it means that the whole device has erasesize as given above. @@ -74,9 +128,6 @@ struct mtd_info {  	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 */ @@ -89,39 +140,35 @@ struct mtd_info {  	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); +	int (*read_oob) (struct mtd_info *mtd, loff_t from, +			 struct mtd_oob_ops *ops); +	int (*write_oob) (struct mtd_info *mtd, loff_t to, +			 struct mtd_oob_ops *ops);  	/*  	 * 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 (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len);  	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 (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len); +	int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf);  	int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); +	int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len); + +/* XXX U-BOOT XXX */  #if 0 -	/* kvec-based read/write methods. We need these especially for NAND flash, -	   with its limited number of write cycles per erase. +	/* kvec-based read/write methods.  	   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);  #endif +  	/* Sync */  	void (*sync) (struct mtd_info *mtd); -#if 0 +  	/* 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); @@ -129,15 +176,32 @@ struct mtd_info {  	/* Power Management functions */  	int (*suspend) (struct mtd_info *mtd);  	void (*resume) (struct mtd_info *mtd); -#endif +  	/* Bad block management functions */  	int (*block_isbad) (struct mtd_info *mtd, loff_t ofs);  	int (*block_markbad) (struct mtd_info *mtd, loff_t ofs); +/* XXX U-BOOT XXX */ +#if 0 +	struct notifier_block reboot_notifier;  /* default mode before reboot */ +#endif + +	/* ECC status information */ +	struct mtd_ecc_stats ecc_stats; +	/* Subpage shift (NAND) */ +	int subpage_sft; +  	void *priv;  	struct module *owner;  	int usecount; + +	/* If the driver is something smart, like UBI, it may need to maintain +	 * its own reference counting. The below functions are only for driver. +	 * The driver may register its callbacks. These callbacks are not +	 * supposed to be called by MTD users */ +	int (*get_device) (struct mtd_info *mtd); +	void (*put_device) (struct mtd_info *mtd);  }; @@ -147,9 +211,11 @@ extern int add_mtd_device(struct mtd_info *mtd);  extern int del_mtd_device (struct mtd_info *mtd);  extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num); +extern struct mtd_info *get_mtd_device_nm(const char *name);  extern void put_mtd_device(struct mtd_info *mtd); +/* XXX U-BOOT XXX */  #if 0  struct mtd_notifier {  	void (*add)(struct mtd_info *mtd); @@ -157,7 +223,6 @@ struct mtd_notifier {  	struct list_head list;  }; -  extern void register_mtd_user (struct mtd_notifier *new);  extern int unregister_mtd_user (struct mtd_notifier *old); @@ -168,20 +233,6 @@ int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs,  		      unsigned long count, loff_t from, size_t *retlen);  #endif -#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 @@ -208,7 +259,6 @@ static inline void mtd_erase_callback(struct erase_info *instr)  	} while(0)  #else /* CONFIG_MTD_DEBUG */  #define MTDDEBUG(n, args...) do { } while(0) -  #endif /* CONFIG_MTD_DEBUG */  #endif /* __MTD_MTD_H__ */ diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index e2a25a60d..db8bd7ba2 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -2,114 +2,123 @@   *  linux/include/linux/mtd/nand.h   *   *  Copyright (c) 2000 David Woodhouse <dwmw2@mvhi.com> - *		       Steven J. Hill <sjhill@realitydiluted.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 $ + * $Id: nand.h,v 1.74 2005/09/15 13:58:50 vwool 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 + * 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 + * Changelog: + *	See git changelog.   */  #ifndef __LINUX_MTD_NAND_H  #define __LINUX_MTD_NAND_H -#include <linux/mtd/compat.h> +/* XXX U-BOOT XXX */ +#if 0 +#include <linux/wait.h> +#include <linux/spinlock.h>  #include <linux/mtd/mtd.h> +#endif + +#include "config.h" + +#include "linux/mtd/compat.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); +/* Separate phases of nand_scan(), allowing board driver to intervene + * and override command or ECC setup according to flash type */ +extern int nand_scan_ident(struct mtd_info *mtd, int max_chips); +extern int nand_scan_tail(struct mtd_info *mtd); +  /* 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); +/* Internal helper for board drivers which need to override command function */ +extern void nand_wait_ready(struct mtd_info *mtd); +/* The maximum number of NAND chips in an array */ +#ifndef NAND_MAX_CHIPS +#define NAND_MAX_CHIPS		8 +#endif  /* 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 +#define NAND_MAX_OOBSIZE	128 +#define NAND_MAX_PAGESIZE	4096  /*   * Constants for hardware specific CLE/ALE/NCE function -*/ + * + * These are bits which can be or'ed to set/clear multiple + * bits in one go. + */  /* 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 +#define NAND_NCE		0x01  /* 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 +#define NAND_CLE		0x02  /* 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 +#define NAND_ALE		0x04 + +#define NAND_CTRL_CLE		(NAND_NCE | NAND_CLE) +#define NAND_CTRL_ALE		(NAND_NCE | NAND_ALE) +#define NAND_CTRL_CHANGE	0x80  /*   * Standard NAND flash commands   */  #define NAND_CMD_READ0		0  #define NAND_CMD_READ1		1 +#define NAND_CMD_RNDOUT		5  #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_RNDIN		0x85  #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_RNDOUTSTART	0xE0  #define NAND_CMD_CACHEDPROG	0x15 +/* Extended commands for AG-AND device */ +/* + * Note: the command for NAND_CMD_DEPLETE1 is really 0x00 but + *       there is no way to distinguish that from NAND_CMD_READ0 + *       until the remaining sequence of commands has been completed + *       so add a high order bit and mask it off in the command. + */ +#define NAND_CMD_DEPLETE1	0x100 +#define NAND_CMD_DEPLETE2	0x38 +#define NAND_CMD_STATUS_MULTI	0x71 +#define NAND_CMD_STATUS_ERROR	0x72 +/* multi-bank error status (banks 0-3) */ +#define NAND_CMD_STATUS_ERROR0	0x73 +#define NAND_CMD_STATUS_ERROR1	0x74 +#define NAND_CMD_STATUS_ERROR2	0x75 +#define NAND_CMD_STATUS_ERROR3	0x76 +#define NAND_CMD_STATUS_RESET	0x7f +#define NAND_CMD_STATUS_CLEAR	0xff + +#define NAND_CMD_NONE		-1 +  /* Status bits */  #define NAND_STATUS_FAIL	0x01  #define NAND_STATUS_FAIL_N1	0x02 @@ -120,25 +129,16 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_  /*   * 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 6 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 +typedef enum { +	NAND_ECC_NONE, +	NAND_ECC_SOFT, +	NAND_ECC_HW, +	NAND_ECC_HW_SYNDROME, +} nand_ecc_modes_t;  /*   * Constants for Hardware ECC -*/ + */  /* Reset Hardware ECC for read */  #define NAND_ECC_READ		0  /* Reset Hardware ECC for write */ @@ -146,6 +146,10 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_  /* Enable Hardware ECC before syndrom is read back from flash */  #define NAND_ECC_READSYN	2 +/* Bit mask for flags passed to do_nand_read_ecc */ +#define NAND_GET_DEVICE		0x80 + +  /* Option constants for bizarre disfunctionality and real  *  features  */ @@ -165,6 +169,17 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_  /* Chip has a array of 4 pages which can be read without   * additional ready /busy waits */  #define NAND_4PAGE_ARRAY	0x00000040 +/* Chip requires that BBT is periodically rewritten to prevent + * bits from adjacent blocks from 'leaking' in altering data. + * This happens with the Renesas AG-AND chips, possibly others.  */ +#define BBT_AUTO_REFRESH	0x00000080 +/* Chip does not require ready check on read. True + * for all large page devices, as they do not support + * autoincrement.*/ +#define NAND_NO_READRDY		0x00000100 +/* Chip does not allow subpage writes */ +#define NAND_NO_SUBPAGE_WRITE	0x00000200 +  /* Options valid for Samsung large page devices */  #define NAND_SAMSUNG_LP_OPTIONS \ @@ -183,18 +198,18 @@ extern int nand_read_raw (struct mtd_info *mtd, uint8_t *buf, loff_t from, size_  /* 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 - - +/* This option skips the bbt scan during initialization. */ +#define NAND_SKIP_BBTSCAN	0x00020000 +/* This option is defined if the board driver allocates its own buffers +   (e.g. because it needs them DMA-coherent */ +#define NAND_OWN_BUFFERS	0x00040000  /* 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 scan has allocated controller struct */ +#define NAND_CONTROLLER_ALLOC	0x80000000 +/* Cell info constants */ +#define NAND_CI_CHIPNR_MSK	0x03 +#define NAND_CI_CELLTYPE_MSK	0x0C  /*   * nand_state_t - chip states @@ -207,135 +222,216 @@ typedef enum {  	FL_ERASING,  	FL_SYNCING,  	FL_CACHEDPRG, +	FL_PM_SUSPENDED,  } nand_state_t;  /* Keep gcc happy */  struct nand_chip; -#if 0  /** - * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independend devices - * @lock:		protection lock + * struct nand_hw_control - Control structure for hardware controller (e.g ECC generator) shared among independent devices + * @lock:               protection lock   * @active:		the mtd device which holds the controller currently + * @wq:			wait queue to sleep on if a NAND operation is in progress + *                      used instead of the per chip wait queue when a hw controller is available   */  struct nand_hw_control { -	spinlock_t	 lock; -	struct nand_chip *active; -}; +#if 0 +    spinlock_t	 lock; +    wait_queue_head_t wq;  #endif +    struct nand_chip *active; +}; + +/** + * struct nand_ecc_ctrl - Control structure for ecc + * @mode:	ecc mode + * @steps:	number of ecc steps per page + * @size:	data bytes per ecc step + * @bytes:	ecc bytes per step + * @total:	total number of ecc bytes per page + * @prepad:	padding information for syndrome based ecc generators + * @postpad:	padding information for syndrome based ecc generators + * @layout:	ECC layout control struct pointer + * @hwctl:	function to control hardware ecc generator. Must only + *		be provided if an hardware ECC is available + * @calculate:	function for ecc calculation or readback from ecc hardware + * @correct:	function for ecc correction, matching to ecc generator (sw/hw) + * @read_page_raw:	function to read a raw page without ECC + * @write_page_raw:	function to write a raw page without ECC + * @read_page:	function to read a page according to the ecc generator requirements + * @write_page:	function to write a page according to the ecc generator requirements + * @read_oob:	function to read chip OOB data + * @write_oob:	function to write chip OOB data + */ +struct nand_ecc_ctrl { +	nand_ecc_modes_t	mode; +	int			steps; +	int			size; +	int			bytes; +	int			total; +	int			prepad; +	int			postpad; +	struct nand_ecclayout	*layout; +	void			(*hwctl)(struct mtd_info *mtd, int mode); +	int			(*calculate)(struct mtd_info *mtd, +					     const uint8_t *dat, +					     uint8_t *ecc_code); +	int			(*correct)(struct mtd_info *mtd, uint8_t *dat, +					   uint8_t *read_ecc, +					   uint8_t *calc_ecc); +	int			(*read_page_raw)(struct mtd_info *mtd, +						 struct nand_chip *chip, +						 uint8_t *buf); +	void			(*write_page_raw)(struct mtd_info *mtd, +						  struct nand_chip *chip, +						  const uint8_t *buf); +	int			(*read_page)(struct mtd_info *mtd, +					     struct nand_chip *chip, +					     uint8_t *buf); +	void			(*write_page)(struct mtd_info *mtd, +					      struct nand_chip *chip, +					      const uint8_t *buf); +	int			(*read_oob)(struct mtd_info *mtd, +					    struct nand_chip *chip, +					    int page, +					    int sndcmd); +	int			(*write_oob)(struct mtd_info *mtd, +					     struct nand_chip *chip, +					     int page); +}; + +/** + * struct nand_buffers - buffer structure for read/write + * @ecccalc:	buffer for calculated ecc + * @ecccode:	buffer for ecc read from flash + * @databuf:	buffer for data - dynamically sized + * + * Do not change the order of buffers. databuf and oobrbuf must be in + * consecutive order. + */ +struct nand_buffers { +	uint8_t	ecccalc[NAND_MAX_OOBSIZE]; +	uint8_t	ecccode[NAND_MAX_OOBSIZE]; +	uint8_t databuf[NAND_MAX_PAGESIZE + NAND_MAX_OOBSIZE]; +};  /**   * 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 + * @cmd_ctrl:		[BOARDSPECIFIC] hardwarespecific funtion for controlling + *			ALE/CLE/nCE. Also used to write command and address   * @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 + * @ecc:		[BOARDSPECIFIC] ecc control ctructure + * @buffers:		buffer structure for read/write + * @hwcontrol:		platform-specific hardware control structure + * @ops:		oob operation operands   * @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 + * @oob_poi:		poison value buffer   * @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 + * @datbuf:		[INTERN] internal buffer for one page + oob + * @oobbuf:		[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 + * @cellinfo:		[INTERN] MLC/multichip data from chip ident   * @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 + * @subpagesize:	[INTERN] holds the subpagesize + * @ecclayout:		[REPLACEABLE] the default ecc 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 + * @controller:		[REPLACEABLE] a pointer to a hardware controller structure + *			which is shared among multiple independend devices   * @priv:		[OPTIONAL] pointer to private chip date + * @errstat:		[OPTIONAL] hardware specific function to perform additional error status checks + *			(determine if errors are correctable) + * @write_page:		[REPLACEABLE] High-level page write function   */  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); +	uint8_t		(*read_byte)(struct mtd_info *mtd);  	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		(*write_buf)(struct mtd_info *mtd, const uint8_t *buf, int len); +	void		(*read_buf)(struct mtd_info *mtd, uint8_t *buf, int len); +	int		(*verify_buf)(struct mtd_info *mtd, const uint8_t *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); +	void		(*cmd_ctrl)(struct mtd_info *mtd, int dat, +				    unsigned int ctrl);  	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); +	int		(*waitfunc)(struct mtd_info *mtd, struct nand_chip *this);  	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		(*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page); +	int		(*write_page)(struct mtd_info *mtd, struct nand_chip *chip, +				      const uint8_t *buf, int page, int cached, int raw); +  	int		chip_delay; -#if 0 -	spinlock_t	chip_lock; -	wait_queue_head_t wq; -	nand_state_t	state; -#endif +	unsigned int	options; +  	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; +	int		subpagesize; +	uint8_t		cellinfo; +	int		badblockpos; + +	nand_state_t	state; + +	uint8_t		*oob_poi; +	struct nand_hw_control  *controller; +	struct nand_ecclayout	*ecclayout; + +	struct nand_ecc_ctrl ecc; +	struct nand_buffers *buffers; +	 +	struct nand_hw_control hwcontrol; + +	struct mtd_oob_ops ops; +  	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;  }; @@ -348,11 +444,11 @@ struct nand_chip {  #define NAND_MFR_NATIONAL	0x8f  #define NAND_MFR_RENESAS	0x07  #define NAND_MFR_STMICRO	0x20 +#define NAND_MFR_HYNIX		0xad  #define NAND_MFR_MICRON		0x2c  /**   * 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 @@ -403,7 +499,7 @@ extern struct nand_manufacturers nand_manuf_ids[];   *		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 + *              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   * @@ -417,11 +513,11 @@ struct nand_bbt_descr {  	int	pages[NAND_MAX_CHIPS];  	int	offs;  	int	veroffs; -	uint8_t version[NAND_MAX_CHIPS]; +	uint8_t	version[NAND_MAX_CHIPS];  	int	len;  	int	maxblocks;  	int	reserved_block_code; -	uint8_t *pattern; +	uint8_t	*pattern;  };  /* Options for the bad block table descriptors */ @@ -433,7 +529,7 @@ struct nand_bbt_descr {  #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 +#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 */ @@ -456,13 +552,16 @@ struct nand_bbt_descr {  #define NAND_BBT_SCAN2NDPAGE	0x00004000  /* The maximum number of blocks to scan for a bbt */ -#define NAND_BBT_SCAN_MAXBLOCKS 4 +#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); +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); +extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len, +			size_t * retlen, uint8_t * buf);  /*  * Constants for oob configuration @@ -470,4 +569,67 @@ extern int nand_erase_nand (struct mtd_info *mtd, struct erase_info *instr, int  #define NAND_SMALL_BADBLOCK_POS		5  #define NAND_LARGE_BADBLOCK_POS		0 +/** + * struct platform_nand_chip - chip level device structure + * @nr_chips:		max. number of chips to scan for + * @chip_offset:	chip number offset + * @nr_partitions:	number of partitions pointed to by partitions (or zero) + * @partitions:		mtd partition list + * @chip_delay:		R/B delay value in us + * @options:		Option flags, e.g. 16bit buswidth + * @ecclayout:		ecc layout info structure + * @part_probe_types:	NULL-terminated array of probe types + * @priv:		hardware controller specific settings + */ +struct platform_nand_chip { +	int			nr_chips; +	int			chip_offset; +	int			nr_partitions; +	struct mtd_partition	*partitions; +	struct nand_ecclayout	*ecclayout; +	int			chip_delay; +	unsigned int		options; +	const char		**part_probe_types; +	void			*priv; +}; + +/** + * struct platform_nand_ctrl - controller level device structure + * @hwcontrol:		platform specific hardware control structure + * @dev_ready:		platform specific function to read ready/busy pin + * @select_chip:	platform specific chip select function + * @cmd_ctrl:		platform specific function for controlling + *			ALE/CLE/nCE. Also used to write command and address + * @priv:		private data to transport driver specific settings + * + * All fields are optional and depend on the hardware driver requirements + */ +struct platform_nand_ctrl { +	void		(*hwcontrol)(struct mtd_info *mtd, int cmd); +	int		(*dev_ready)(struct mtd_info *mtd); +	void		(*select_chip)(struct mtd_info *mtd, int chip); +	void		(*cmd_ctrl)(struct mtd_info *mtd, int dat, +				    unsigned int ctrl); +	void		*priv; +}; + +/** + * struct platform_nand_data - container structure for platform-specific data + * @chip:		chip level chip structure + * @ctrl:		controller level device structure + */ +struct platform_nand_data { +	struct platform_nand_chip	chip; +	struct platform_nand_ctrl	ctrl; +}; + +/* Some helpers to access the data structures */ +static inline +struct platform_nand_chip *get_platform_nandchip(struct mtd_info *mtd) +{ +	struct nand_chip *chip = mtd->priv; + +	return chip->priv; +} +  #endif /* __LINUX_MTD_NAND_H */ diff --git a/include/linux/mtd/nftl-user.h b/include/linux/mtd/nftl-user.h new file mode 100644 index 000000000..b2bca18e7 --- /dev/null +++ b/include/linux/mtd/nftl-user.h @@ -0,0 +1,76 @@ +/* + * $Id: nftl-user.h,v 1.2 2005/11/07 11:14:56 gleixner Exp $ + * + * Parts of NFTL headers shared with userspace + * + */ + +#ifndef __MTD_NFTL_USER_H__ +#define __MTD_NFTL_USER_H__ + +/* Block Control Information */ + +struct nftl_bci { +	unsigned char ECCSig[6]; +	uint8_t Status; +	uint8_t Status1; +}__attribute__((packed)); + +/* Unit Control Information */ + +struct nftl_uci0 { +	uint16_t VirtUnitNum; +	uint16_t ReplUnitNum; +	uint16_t SpareVirtUnitNum; +	uint16_t SpareReplUnitNum; +} __attribute__((packed)); + +struct nftl_uci1 { +	uint32_t WearInfo; +	uint16_t EraseMark; +	uint16_t EraseMark1; +} __attribute__((packed)); + +struct nftl_uci2 { +        uint16_t FoldMark; +        uint16_t FoldMark1; +	uint32_t unused; +} __attribute__((packed)); + +union nftl_uci { +	struct nftl_uci0 a; +	struct nftl_uci1 b; +	struct nftl_uci2 c; +}; + +struct nftl_oob { +	struct nftl_bci b; +	union nftl_uci u; +}; + +/* NFTL Media Header */ + +struct NFTLMediaHeader { +	char DataOrgID[6]; +	uint16_t NumEraseUnits; +	uint16_t FirstPhysicalEUN; +	uint32_t FormattedSize; +	unsigned char UnitSizeFactor; +} __attribute__((packed)); + +#define MAX_ERASE_ZONES (8192 - 512) + +#define ERASE_MARK 0x3c69 +#define SECTOR_FREE 0xff +#define SECTOR_USED 0x55 +#define SECTOR_IGNORE 0x11 +#define SECTOR_DELETED 0x00 + +#define FOLD_MARK_IN_PROGRESS 0x5555 + +#define ZONE_GOOD 0xff +#define ZONE_BAD_ORIGINAL 0 +#define ZONE_BAD_MARKED 7 + + +#endif /* __MTD_NFTL_USER_H__ */ diff --git a/include/linux/mtd/nftl.h b/include/linux/mtd/nftl.h index b0337c340..04963a52e 100644 --- a/include/linux/mtd/nftl.h +++ b/include/linux/mtd/nftl.h @@ -1,75 +1,16 @@ - -/* Defines for NAND Flash Translation Layer  */ -/* (c) 1999 Machine Vision Holdings, Inc.    */ -/* Author: David Woodhouse <dwmw2@mvhi.com>  */ -/* $Id: nftl.h,v 1.10 2000/12/29 00:25:38 dwmw2 Exp $ */ +/* + * $Id: nftl.h,v 1.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__ -/* Block Control Information */ - -struct nftl_bci { -	unsigned char ECCSig[6]; -	__u8 Status; -	__u8 Status1; -}__attribute__((packed)); - -/* Unit Control Information */ - -struct nftl_uci0 { -	__u16 VirtUnitNum; -	__u16 ReplUnitNum; -	__u16 SpareVirtUnitNum; -	__u16 SpareReplUnitNum; -} __attribute__((packed)); - -struct nftl_uci1 { -	__u32 WearInfo; -	__u16 EraseMark; -	__u16 EraseMark1; -} __attribute__((packed)); +#include <linux/mtd/mtd.h> +#include <linux/mtd/blktrans.h> -struct nftl_uci2 { -	__u16 FoldMark; -	__u16 FoldMark1; -	__u32 unused; -} __attribute__((packed)); - -union nftl_uci { -	struct nftl_uci0 a; -	struct nftl_uci1 b; -	struct nftl_uci2 c; -}; - -struct nftl_oob { -	struct nftl_bci b; -	union nftl_uci u; -}; - -/* NFTL Media Header */ - -struct NFTLMediaHeader { -	char DataOrgID[6]; -	__u16 NumEraseUnits; -	__u16 FirstPhysicalEUN; -	__u32 FormattedSize; -	unsigned char UnitSizeFactor; -} __attribute__((packed)); - -#define MAX_ERASE_ZONES (8192 - 512) - -#define ERASE_MARK 0x3c69 -#define SECTOR_FREE 0xff -#define SECTOR_USED 0x55 -#define SECTOR_IGNORE 0x11 -#define SECTOR_DELETED 0x00 - -#define FOLD_MARK_IN_PROGRESS 0x5555 - -#define ZONE_GOOD 0xff -#define ZONE_BAD_ORIGINAL 0 -#define ZONE_BAD_MARKED 7 +#include <linux/mtd/nftl-user.h>  /* these info are used in ReplUnitTable */  #define BLOCK_NIL          0xffff /* last block of a chain */ @@ -78,7 +19,7 @@ struct NFTLMediaHeader {  #define BLOCK_RESERVED     0xfffc /* bios block or bad block */  struct NFTLrecord { -	struct DiskOnChip *mtd; +	struct mtd_blktrans_dev mbd;  	__u16 MediaUnit, SpareMediaUnit;  	__u32 EraseSize;  	struct NFTLMediaHeader MediaHdr; @@ -90,16 +31,24 @@ struct NFTLrecord {  	__u16 lastEUN;                  /* should be suppressed */  	__u16 numfreeEUNs;  	__u16 LastFreeEUN;		/* To speed up finding a free EUN */ -	__u32 nr_sects;  	int head,sect,cyl;  	__u16 *EUNtable;		/* [numvunits]: First EUN for each virtual unit  */  	__u16 *ReplUnitTable;		/* [numEUNs]: ReplUnitNumber for each */ -	unsigned int nb_blocks;		/* number of physical blocks */ -	unsigned int nb_boot_blocks;	/* number of blocks used by the bios */ +        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_ecclayout 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 32 +#define MAX_SECTORS_PER_UNIT 64  #define NFTL_PARTN_BITS 4  #endif /* __MTD_NFTL_H__ */ diff --git a/include/linux/mtd/ubi-header.h b/include/linux/mtd/ubi-header.h new file mode 100644 index 000000000..fa479c71a --- /dev/null +++ b/include/linux/mtd/ubi-header.h @@ -0,0 +1,360 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Authors: Artem Bityutskiy (ΠΠΈΡΡΡΠΊΠΈΠΉ ΠΡΡΡΠΌ) + *          Thomas Gleixner + *          Frank Haverkamp + *          Oliver Lohmann + *          Andreas Arnez + */ + +/* + * This file defines the layout of UBI headers and all the other UBI on-flash + * data structures. May be included by user-space. + */ + +#ifndef __UBI_HEADER_H__ +#define __UBI_HEADER_H__ + +#include <asm/byteorder.h> + +/* The version of UBI images supported by this implementation */ +#define UBI_VERSION 1 + +/* The highest erase counter value supported by this implementation */ +#define UBI_MAX_ERASECOUNTER 0x7FFFFFFF + +/* The initial CRC32 value used when calculating CRC checksums */ +#define UBI_CRC32_INIT 0xFFFFFFFFU + +/* Erase counter header magic number (ASCII "UBI#") */ +#define UBI_EC_HDR_MAGIC  0x55424923 +/* Volume identifier header magic number (ASCII "UBI!") */ +#define UBI_VID_HDR_MAGIC 0x55424921 + +/* + * Volume type constants used in the volume identifier header. + * + * @UBI_VID_DYNAMIC: dynamic volume + * @UBI_VID_STATIC: static volume + */ +enum { +	UBI_VID_DYNAMIC = 1, +	UBI_VID_STATIC  = 2 +}; + +/* + * Compatibility constants used by internal volumes. + * + * @UBI_COMPAT_DELETE: delete this internal volume before anything is written + * to the flash + * @UBI_COMPAT_RO: attach this device in read-only mode + * @UBI_COMPAT_PRESERVE: preserve this internal volume - do not touch its + * physical eraseblocks, don't allow the wear-leveling unit to move them + * @UBI_COMPAT_REJECT: reject this UBI image + */ +enum { +	UBI_COMPAT_DELETE   = 1, +	UBI_COMPAT_RO       = 2, +	UBI_COMPAT_PRESERVE = 4, +	UBI_COMPAT_REJECT   = 5 +}; + +/* + * ubi16_t/ubi32_t/ubi64_t - 16, 32, and 64-bit integers used in UBI on-flash + * data structures. + */ +typedef struct { +	uint16_t int16; +} __attribute__ ((packed)) ubi16_t; + +typedef struct { +	uint32_t int32; +} __attribute__ ((packed)) ubi32_t; + +typedef struct { +	uint64_t int64; +} __attribute__ ((packed)) ubi64_t; + +/* + * In this implementation of UBI uses the big-endian format for on-flash + * integers. The below are the corresponding conversion macros. + */ +#define cpu_to_ubi16(x) ((ubi16_t){__cpu_to_be16(x)}) +#define ubi16_to_cpu(x) ((uint16_t)__be16_to_cpu((x).int16)) + +#define cpu_to_ubi32(x) ((ubi32_t){__cpu_to_be32(x)}) +#define ubi32_to_cpu(x) ((uint32_t)__be32_to_cpu((x).int32)) + +#define cpu_to_ubi64(x) ((ubi64_t){__cpu_to_be64(x)}) +#define ubi64_to_cpu(x) ((uint64_t)__be64_to_cpu((x).int64)) + +/* Sizes of UBI headers */ +#define UBI_EC_HDR_SIZE  sizeof(struct ubi_ec_hdr) +#define UBI_VID_HDR_SIZE sizeof(struct ubi_vid_hdr) + +/* Sizes of UBI headers without the ending CRC */ +#define UBI_EC_HDR_SIZE_CRC  (UBI_EC_HDR_SIZE  - sizeof(ubi32_t)) +#define UBI_VID_HDR_SIZE_CRC (UBI_VID_HDR_SIZE - sizeof(ubi32_t)) + +/** + * struct ubi_ec_hdr - UBI erase counter header. + * @magic: erase counter header magic number (%UBI_EC_HDR_MAGIC) + * @version: version of UBI implementation which is supposed to accept this + * UBI image + * @padding1: reserved for future, zeroes + * @ec: the erase counter + * @vid_hdr_offset: where the VID header starts + * @data_offset: where the user data start + * @padding2: reserved for future, zeroes + * @hdr_crc: erase counter header CRC checksum + * + * The erase counter header takes 64 bytes and has a plenty of unused space for + * future usage. The unused fields are zeroed. The @version field is used to + * indicate the version of UBI implementation which is supposed to be able to + * work with this UBI image. If @version is greater then the current UBI + * version, the image is rejected. This may be useful in future if something + * is changed radically. This field is duplicated in the volume identifier + * header. + * + * The @vid_hdr_offset and @data_offset fields contain the offset of the the + * volume identifier header and user data, relative to the beginning of the + * physical eraseblock. These values have to be the same for all physical + * eraseblocks. + */ +struct ubi_ec_hdr { +	ubi32_t magic; +	uint8_t version; +	uint8_t padding1[3]; +	ubi64_t ec; /* Warning: the current limit is 31-bit anyway! */ +	ubi32_t vid_hdr_offset; +	ubi32_t data_offset; +	uint8_t padding2[36]; +	ubi32_t hdr_crc; +} __attribute__ ((packed)); + +/** + * struct ubi_vid_hdr - on-flash UBI volume identifier header. + * @magic: volume identifier header magic number (%UBI_VID_HDR_MAGIC) + * @version: UBI implementation version which is supposed to accept this UBI + * image (%UBI_VERSION) + * @vol_type: volume type (%UBI_VID_DYNAMIC or %UBI_VID_STATIC) + * @copy_flag: if this logical eraseblock was copied from another physical + * eraseblock (for wear-leveling reasons) + * @compat: compatibility of this volume (%0, %UBI_COMPAT_DELETE, + * %UBI_COMPAT_IGNORE, %UBI_COMPAT_PRESERVE, or %UBI_COMPAT_REJECT) + * @vol_id: ID of this volume + * @lnum: logical eraseblock number + * @leb_ver: version of this logical eraseblock (IMPORTANT: obsolete, to be + * removed, kept only for not breaking older UBI users) + * @data_size: how many bytes of data this logical eraseblock contains + * @used_ebs: total number of used logical eraseblocks in this volume + * @data_pad: how many bytes at the end of this physical eraseblock are not + * used + * @data_crc: CRC checksum of the data stored in this logical eraseblock + * @padding1: reserved for future, zeroes + * @sqnum: sequence number + * @padding2: reserved for future, zeroes + * @hdr_crc: volume identifier header CRC checksum + * + * The @sqnum is the value of the global sequence counter at the time when this + * VID header was created. The global sequence counter is incremented each time + * UBI writes a new VID header to the flash, i.e. when it maps a logical + * eraseblock to a new physical eraseblock. The global sequence counter is an + * unsigned 64-bit integer and we assume it never overflows. The @sqnum + * (sequence number) is used to distinguish between older and newer versions of + * logical eraseblocks. + * + * There are 2 situations when there may be more then one physical eraseblock + * corresponding to the same logical eraseblock, i.e., having the same @vol_id + * and @lnum values in the volume identifier header. Suppose we have a logical + * eraseblock L and it is mapped to the physical eraseblock P. + * + * 1. Because UBI may erase physical eraseblocks asynchronously, the following + * situation is possible: L is asynchronously erased, so P is scheduled for + * erasure, then L is written to,i.e. mapped to another physical eraseblock P1, + * so P1 is written to, then an unclean reboot happens. Result - there are 2 + * physical eraseblocks P and P1 corresponding to the same logical eraseblock + * L. But P1 has greater sequence number, so UBI picks P1 when it attaches the + * flash. + * + * 2. From time to time UBI moves logical eraseblocks to other physical + * eraseblocks for wear-leveling reasons. If, for example, UBI moves L from P + * to P1, and an unclean reboot happens before P is physically erased, there + * are two physical eraseblocks P and P1 corresponding to L and UBI has to + * select one of them when the flash is attached. The @sqnum field says which + * PEB is the original (obviously P will have lower @sqnum) and the copy. But + * it is not enough to select the physical eraseblock with the higher sequence + * number, because the unclean reboot could have happen in the middle of the + * copying process, so the data in P is corrupted. It is also not enough to + * just select the physical eraseblock with lower sequence number, because the + * data there may be old (consider a case if more data was added to P1 after + * the copying). Moreover, the unclean reboot may happen when the erasure of P + * was just started, so it result in unstable P, which is "mostly" OK, but + * still has unstable bits. + * + * UBI uses the @copy_flag field to indicate that this logical eraseblock is a + * copy. UBI also calculates data CRC when the data is moved and stores it at + * the @data_crc field of the copy (P1). So when UBI needs to pick one physical + * eraseblock of two (P or P1), the @copy_flag of the newer one (P1) is + * examined. If it is cleared, the situation* is simple and the newer one is + * picked. If it is set, the data CRC of the copy (P1) is examined. If the CRC + * checksum is correct, this physical eraseblock is selected (P1). Otherwise + * the older one (P) is selected. + * + * Note, there is an obsolete @leb_ver field which was used instead of @sqnum + * in the past. But it is not used anymore and we keep it in order to be able + * to deal with old UBI images. It will be removed at some point. + * + * There are 2 sorts of volumes in UBI: user volumes and internal volumes. + * Internal volumes are not seen from outside and are used for various internal + * UBI purposes. In this implementation there is only one internal volume - the + * layout volume. Internal volumes are the main mechanism of UBI extensions. + * For example, in future one may introduce a journal internal volume. Internal + * volumes have their own reserved range of IDs. + * + * The @compat field is only used for internal volumes and contains the "degree + * of their compatibility". It is always zero for user volumes. This field + * provides a mechanism to introduce UBI extensions and to be still compatible + * with older UBI binaries. For example, if someone introduced a journal in + * future, he would probably use %UBI_COMPAT_DELETE compatibility for the + * journal volume.  And in this case, older UBI binaries, which know nothing + * about the journal volume, would just delete this volume and work perfectly + * fine. This is similar to what Ext2fs does when it is fed by an Ext3fs image + * - it just ignores the Ext3fs journal. + * + * The @data_crc field contains the CRC checksum of the contents of the logical + * eraseblock if this is a static volume. In case of dynamic volumes, it does + * not contain the CRC checksum as a rule. The only exception is when the + * data of the physical eraseblock was moved by the wear-leveling unit, then + * the wear-leveling unit calculates the data CRC and stores it in the + * @data_crc field. And of course, the @copy_flag is %in this case. + * + * The @data_size field is used only for static volumes because UBI has to know + * how many bytes of data are stored in this eraseblock. For dynamic volumes, + * this field usually contains zero. The only exception is when the data of the + * physical eraseblock was moved to another physical eraseblock for + * wear-leveling reasons. In this case, UBI calculates CRC checksum of the + * contents and uses both @data_crc and @data_size fields. In this case, the + * @data_size field contains data size. + * + * The @used_ebs field is used only for static volumes and indicates how many + * eraseblocks the data of the volume takes. For dynamic volumes this field is + * not used and always contains zero. + * + * The @data_pad is calculated when volumes are created using the alignment + * parameter. So, effectively, the @data_pad field reduces the size of logical + * eraseblocks of this volume. This is very handy when one uses block-oriented + * software (say, cramfs) on top of the UBI volume. + */ +struct ubi_vid_hdr { +	ubi32_t magic; +	uint8_t version; +	uint8_t vol_type; +	uint8_t copy_flag; +	uint8_t compat; +	ubi32_t vol_id; +	ubi32_t lnum; +	ubi32_t leb_ver; /* obsolete, to be removed, don't use */ +	ubi32_t data_size; +	ubi32_t used_ebs; +	ubi32_t data_pad; +	ubi32_t data_crc; +	uint8_t padding1[4]; +	ubi64_t sqnum; +	uint8_t padding2[12]; +	ubi32_t hdr_crc; +} __attribute__ ((packed)); + +/* Internal UBI volumes count */ +#define UBI_INT_VOL_COUNT 1 + +/* + * Starting ID of internal volumes. There is reserved room for 4096 internal + * volumes. + */ +#define UBI_INTERNAL_VOL_START (0x7FFFFFFF - 4096) + +/* The layout volume contains the volume table */ + +#define UBI_LAYOUT_VOL_ID        UBI_INTERNAL_VOL_START +#define UBI_LAYOUT_VOLUME_EBS    2 +#define UBI_LAYOUT_VOLUME_NAME   "layout volume" +#define UBI_LAYOUT_VOLUME_COMPAT UBI_COMPAT_REJECT + +/* The maximum number of volumes per one UBI device */ +#define UBI_MAX_VOLUMES 128 + +/* The maximum volume name length */ +#define UBI_VOL_NAME_MAX 127 + +/* Size of the volume table record */ +#define UBI_VTBL_RECORD_SIZE sizeof(struct ubi_vtbl_record) + +/* Size of the volume table record without the ending CRC */ +#define UBI_VTBL_RECORD_SIZE_CRC (UBI_VTBL_RECORD_SIZE - sizeof(ubi32_t)) + +/** + * struct ubi_vtbl_record - a record in the volume table. + * @reserved_pebs: how many physical eraseblocks are reserved for this volume + * @alignment: volume alignment + * @data_pad: how many bytes are unused at the end of the each physical + * eraseblock to satisfy the requested alignment + * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @upd_marker: if volume update was started but not finished + * @name_len: volume name length + * @name: the volume name + * @padding2: reserved, zeroes + * @crc: a CRC32 checksum of the record + * + * The volume table records are stored in the volume table, which is stored in + * the layout volume. The layout volume consists of 2 logical eraseblock, each + * of which contains a copy of the volume table (i.e., the volume table is + * duplicated). The volume table is an array of &struct ubi_vtbl_record + * objects indexed by the volume ID. + * + * If the size of the logical eraseblock is large enough to fit + * %UBI_MAX_VOLUMES records, the volume table contains %UBI_MAX_VOLUMES + * records. Otherwise, it contains as many records as it can fit (i.e., size of + * logical eraseblock divided by sizeof(struct ubi_vtbl_record)). + * + * The @upd_marker flag is used to implement volume update. It is set to %1 + * before update and set to %0 after the update. So if the update operation was + * interrupted, UBI knows that the volume is corrupted. + * + * The @alignment field is specified when the volume is created and cannot be + * later changed. It may be useful, for example, when a block-oriented file + * system works on top of UBI. The @data_pad field is calculated using the + * logical eraseblock size and @alignment. The alignment must be multiple to the + * minimal flash I/O unit. If @alignment is 1, all the available space of + * the physical eraseblocks is used. + * + * Empty records contain all zeroes and the CRC checksum of those zeroes. + */ +struct ubi_vtbl_record { +	ubi32_t reserved_pebs; +	ubi32_t alignment; +	ubi32_t data_pad; +	uint8_t vol_type; +	uint8_t upd_marker; +	ubi16_t name_len; +	uint8_t name[UBI_VOL_NAME_MAX+1]; +	uint8_t padding2[24]; +	ubi32_t crc; +} __attribute__ ((packed)); + +#endif /* !__UBI_HEADER_H__ */ diff --git a/include/linux/mtd/ubi-user.h b/include/linux/mtd/ubi-user.h new file mode 100644 index 000000000..fe06ded0e --- /dev/null +++ b/include/linux/mtd/ubi-user.h @@ -0,0 +1,161 @@ +/* + * Copyright (c) International Business Machines Corp., 2006 + * + * 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. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See + * the GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Author: Artem Bityutskiy (ΠΠΈΡΡΡΠΊΠΈΠΉ ΠΡΡΡΠΌ) + */ + +#ifndef __UBI_USER_H__ +#define __UBI_USER_H__ + +/* + * UBI volume creation + * ~~~~~~~~~~~~~~~~~~~ + * + * UBI volumes are created via the %UBI_IOCMKVOL IOCTL command of UBI character + * device. A &struct ubi_mkvol_req object has to be properly filled and a + * pointer to it has to be passed to the IOCTL. + * + * UBI volume deletion + * ~~~~~~~~~~~~~~~~~~~ + * + * To delete a volume, the %UBI_IOCRMVOL IOCTL command of the UBI character + * device should be used. A pointer to the 32-bit volume ID hast to be passed + * to the IOCTL. + * + * UBI volume re-size + * ~~~~~~~~~~~~~~~~~~ + * + * To re-size a volume, the %UBI_IOCRSVOL IOCTL command of the UBI character + * device should be used. A &struct ubi_rsvol_req object has to be properly + * filled and a pointer to it has to be passed to the IOCTL. + * + * UBI volume update + * ~~~~~~~~~~~~~~~~~ + * + * Volume update should be done via the %UBI_IOCVOLUP IOCTL command of the + * corresponding UBI volume character device. A pointer to a 64-bit update + * size should be passed to the IOCTL. After then, UBI expects user to write + * this number of bytes to the volume character device. The update is finished + * when the claimed number of bytes is passed. So, the volume update sequence + * is something like: + * + * fd = open("/dev/my_volume"); + * ioctl(fd, UBI_IOCVOLUP, &image_size); + * write(fd, buf, image_size); + * close(fd); + */ + +/* + * When a new volume is created, users may either specify the volume number they + * want to create or to let UBI automatically assign a volume number using this + * constant. + */ +#define UBI_VOL_NUM_AUTO (-1) + +/* Maximum volume name length */ +#define UBI_MAX_VOLUME_NAME 127 + +/* IOCTL commands of UBI character devices */ + +#define UBI_IOC_MAGIC 'o' + +/* Create an UBI volume */ +#define UBI_IOCMKVOL _IOW(UBI_IOC_MAGIC, 0, struct ubi_mkvol_req) +/* Remove an UBI volume */ +#define UBI_IOCRMVOL _IOW(UBI_IOC_MAGIC, 1, int32_t) +/* Re-size an UBI volume */ +#define UBI_IOCRSVOL _IOW(UBI_IOC_MAGIC, 2, struct ubi_rsvol_req) + +/* IOCTL commands of UBI volume character devices */ + +#define UBI_VOL_IOC_MAGIC 'O' + +/* Start UBI volume update */ +#define UBI_IOCVOLUP _IOW(UBI_VOL_IOC_MAGIC, 0, int64_t) +/* An eraseblock erasure command, used for debugging, disabled by default */ +#define UBI_IOCEBER _IOW(UBI_VOL_IOC_MAGIC, 1, int32_t) + +/* + * UBI volume type constants. + * + * @UBI_DYNAMIC_VOLUME: dynamic volume + * @UBI_STATIC_VOLUME:  static volume + */ +enum { +	UBI_DYNAMIC_VOLUME = 3, +	UBI_STATIC_VOLUME = 4 +}; + +/** + * struct ubi_mkvol_req - volume description data structure used in + * volume creation requests. + * @vol_id: volume number + * @alignment: volume alignment + * @bytes: volume size in bytes + * @vol_type: volume type (%UBI_DYNAMIC_VOLUME or %UBI_STATIC_VOLUME) + * @padding1: reserved for future, not used + * @name_len: volume name length + * @padding2: reserved for future, not used + * @name: volume name + * + * This structure is used by userspace programs when creating new volumes. The + * @used_bytes field is only necessary when creating static volumes. + * + * The @alignment field specifies the required alignment of the volume logical + * eraseblock. This means, that the size of logical eraseblocks will be aligned + * to this number, i.e., + *	(UBI device logical eraseblock size) mod (@alignment) = 0. + * + * To put it differently, the logical eraseblock of this volume may be slightly + * shortened in order to make it properly aligned. The alignment has to be + * multiple of the flash minimal input/output unit, or %1 to utilize the entire + * available space of logical eraseblocks. + * + * The @alignment field may be useful, for example, when one wants to maintain + * a block device on top of an UBI volume. In this case, it is desirable to fit + * an integer number of blocks in logical eraseblocks of this UBI volume. With + * alignment it is possible to update this volume using plane UBI volume image + * BLOBs, without caring about how to properly align them. + */ +struct ubi_mkvol_req { +	int32_t vol_id; +	int32_t alignment; +	int64_t bytes; +	int8_t vol_type; +	int8_t padding1; +	int16_t name_len; +	int8_t padding2[4]; +	char name[UBI_MAX_VOLUME_NAME+1]; +} __attribute__ ((packed)); + +/** + * struct ubi_rsvol_req - a data structure used in volume re-size requests. + * @vol_id: ID of the volume to re-size + * @bytes: new size of the volume in bytes + * + * Re-sizing is possible for both dynamic and static volumes. But while dynamic + * volumes may be re-sized arbitrarily, static volumes cannot be made to be + * smaller then the number of bytes they bear. To arbitrarily shrink a static + * volume, it must be wiped out first (by means of volume update operation with + * zero number of bytes). + */ +struct ubi_rsvol_req { +	int64_t bytes; +	int32_t vol_id; +} __attribute__ ((packed)); + +#endif /* __UBI_USER_H__ */ |