diff options
Diffstat (limited to 'include')
| -rw-r--r-- | include/configs/P1022DS.h | 2 | ||||
| -rw-r--r-- | include/linux/mtd/bbm.h | 49 | ||||
| -rw-r--r-- | include/linux/mtd/mtd.h | 203 | ||||
| -rw-r--r-- | include/linux/mtd/nand.h | 173 | ||||
| -rw-r--r-- | include/linux/string.h | 3 | ||||
| -rw-r--r-- | include/mtd/mtd-abi.h (renamed from include/linux/mtd/mtd-abi.h) | 53 | ||||
| -rw-r--r-- | include/nand.h | 8 | 
7 files changed, 327 insertions, 164 deletions
| diff --git a/include/configs/P1022DS.h b/include/configs/P1022DS.h index 8b13b107e..69412e461 100644 --- a/include/configs/P1022DS.h +++ b/include/configs/P1022DS.h @@ -316,7 +316,6 @@  #define CONFIG_SYS_HUSH_PARSER  /* Video */ -#define CONFIG_FSL_DIU_FB  #ifdef CONFIG_FSL_DIU_FB  #define CONFIG_SYS_DIU_ADDR	(CONFIG_SYS_CCSRBAR + 0x10000) @@ -336,7 +335,6 @@  #endif  #ifndef CONFIG_FSL_DIU_FB -#define CONFIG_ATI  #endif  #ifdef CONFIG_ATI diff --git a/include/linux/mtd/bbm.h b/include/linux/mtd/bbm.h index 8cbcdae11..71292b1a8 100644 --- a/include/linux/mtd/bbm.h +++ b/include/linux/mtd/bbm.h @@ -81,32 +81,53 @@ struct nand_bbt_descr {  #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 exists */  #define NAND_BBT_CREATE		0x00000200 +/* + * Create an empty BBT with no vendor information. Vendor's information may be + * unavailable, for example, if the NAND controller has a different data and OOB + * layout or if this information is already purged. Must be used in conjunction + * with NAND_BBT_CREATE. + */ +#define NAND_BBT_CREATE_EMPTY	0x00000400  /* Search good / bad pattern through all pages of a block */ -#define NAND_BBT_SCANALLPAGES	0x00000400 +#define NAND_BBT_SCANALLPAGES	0x00000800  /* Scan block empty during good / bad block scan */ -#define NAND_BBT_SCANEMPTY	0x00000800 +#define NAND_BBT_SCANEMPTY	0x00001000  /* Write bbt if neccecary */ -#define NAND_BBT_WRITE		0x00001000 +#define NAND_BBT_WRITE		0x00002000  /* Read and write back block contents when writing bbt */ -#define NAND_BBT_SAVECONTENT	0x00002000 +#define NAND_BBT_SAVECONTENT	0x00004000  /* Search good / bad pattern on the first and the second page */ -#define NAND_BBT_SCAN2NDPAGE	0x00004000 +#define NAND_BBT_SCAN2NDPAGE	0x00008000  /* Search good / bad pattern on the last page of the eraseblock */ -#define NAND_BBT_SCANLASTPAGE	0x00008000 -/* Chip stores bad block marker on BOTH 1st and 6th bytes of OOB */ -#define NAND_BBT_SCANBYTE1AND6 0x00100000 -/* The nand_bbt_descr was created dynamicaly and must be freed */ -#define NAND_BBT_DYNAMICSTRUCT 0x00200000 -/* The bad block table does not OOB for marker */ -#define NAND_BBT_NO_OOB		0x00400000 +#define NAND_BBT_SCANLASTPAGE	0x00010000 +/* + * Use a flash based bad block table. By default, OOB identifier is saved in + * OOB area. This option is passed to the default bad block table function. + */ +#define NAND_BBT_USE_FLASH	0x00020000 +/* + * Do not store flash based bad block table marker in the OOB area; store it + * in-band. + */ +#define NAND_BBT_NO_OOB		0x00040000 +/* + * Do not write new bad block markers to OOB; useful, e.g., when ECC covers + * entire spare area. Must be used with NAND_BBT_USE_FLASH. + */ +#define NAND_BBT_NO_OOB_BBM	0x00080000 + +/* + * Flag set by nand_create_default_bbt_descr(), marking that the nand_bbt_descr + * was allocated dynamicaly and must be freed in nand_release(). Has no meaning + * in nand_chip.bbt_options. + */ +#define NAND_BBT_DYNAMICSTRUCT	0x80000000  /* The maximum number of blocks to scan for a bbt */  #define NAND_BBT_SCAN_MAXBLOCKS	4 diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index 141c96024..6f44abdc1 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -9,7 +9,8 @@  #include <linux/types.h>  #include <div64.h> -#include <linux/mtd/mtd-abi.h> +#include <mtd/mtd-abi.h> +#include <asm/errno.h>  #define MTD_CHAR_MAJOR 90  #define MTD_BLOCK_MAJOR 31 @@ -65,22 +66,6 @@ struct mtd_erase_region_info {  	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 @@ -92,7 +77,7 @@ typedef enum {   * @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) + *		mode = MTD_OPS_PLACE_OOB or MTD_OPS_RAW)   * @datbuf:	data buffer - if NULL only oob data are read/written   * @oobbuf:	oob data buffer   * @@ -101,7 +86,7 @@ typedef enum {   * OOB area.   */  struct mtd_oob_ops { -	mtd_oob_mode_t	mode; +	unsigned int	mode;  	size_t		len;  	size_t		retlen;  	size_t		ooblen; @@ -133,13 +118,25 @@ struct mtd_info {  	u_int32_t oobsize;   /* Amount of OOB data per block (e.g. 16) */  	u_int32_t oobavail;  /* Available OOB bytes per block */ +	/* +	 * read ops return -EUCLEAN if max number of bitflips corrected on any +	 * one region comprising an ecc step equals or exceeds this value. +	 * Settable by driver, else defaults to ecc_strength.  User can override +	 * in sysfs.  N.B. The meaning of the -EUCLEAN return code has changed; +	 * see Documentation/ABI/testing/sysfs-class-mtd for more detail. +	 */ +	unsigned int bitflip_threshold; +  	/* Kernel-only stuff starts here. */  	const char *name;  	int index; -	/* ecc layout structure pointer - read only ! */ +	/* ECC layout structure pointer - read only! */  	struct nand_ecclayout *ecclayout; +	/* max number of correctible bit errors per ecc step */ +	unsigned int ecc_strength; +  	/* Data for variable erase regions. If numeraseregions is zero,  	 * it means that the whole device has erasesize as given above.  	 */ @@ -147,25 +144,17 @@ struct mtd_info {  	struct mtd_erase_region_info *eraseregions;  	/* -	 * Erase is an asynchronous operation.  Device drivers are supposed -	 * to call instr->callback() whenever the operation completes, even -	 * if it completes with a failure. -	 * Callers are supposed to pass a callback function and wait for it -	 * to be called before writing to the block. +	 * Do not call via these pointers, use corresponding mtd_*() +	 * wrappers instead.  	 */ -	int (*erase) (struct mtd_info *mtd, struct erase_info *instr); - -	/* This stuff for eXecute-In-Place */ -	/* phys is optional and may be set to NULL */ -	int (*point) (struct mtd_info *mtd, loff_t from, size_t len, +	int (*_erase) (struct mtd_info *mtd, struct erase_info *instr); +	int (*_point) (struct mtd_info *mtd, loff_t from, size_t len,  			size_t *retlen, void **virt, phys_addr_t *phys); - -	/* We probably shouldn't allow XIP if the unpoint isn't a NULL */ -	void (*unpoint) (struct mtd_info *mtd, 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); +	void (*_unpoint) (struct mtd_info *mtd, 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);  	/* In blackbox flight recorder like scenarios we want to make successful  	   writes in interrupt context. panic_write() is only intended to be @@ -174,24 +163,35 @@ struct mtd_info {  	   longer, this function can break locks and delay to ensure the write  	   succeeds (but not sleep). */ -	int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); +	int (*_panic_write) (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, +	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, +	int (*_write_oob) (struct mtd_info *mtd, loff_t to,  			 struct mtd_oob_ops *ops); - +	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); +	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 to, size_t len, +				    size_t *retlen, u_char *buf); +	int (*_lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, +				   size_t len); +	void (*_sync) (struct mtd_info *mtd); +	int (*_lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); +	int (*_unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); +	int (*_block_isbad) (struct mtd_info *mtd, loff_t ofs); +	int (*_block_markbad) (struct mtd_info *mtd, loff_t ofs);  	/* -	 * 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. +	 * If the driver is something smart, like UBI, it may need to maintain +	 * its own reference counting. The below functions are only for driver.  	 */ -	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); -	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); +	int (*_get_device) (struct mtd_info *mtd); +	void (*_put_device) (struct mtd_info *mtd);  /* XXX U-BOOT XXX */  #if 0 @@ -201,18 +201,6 @@ struct mtd_info {  	*/  	int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);  #endif - -	/* Sync */ -	void (*sync) (struct mtd_info *mtd); - -	/* Chip-supported device locking */ -	int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); -	int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); - -	/* 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 */ @@ -227,15 +215,59 @@ struct mtd_info {  	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);  }; +int mtd_erase(struct mtd_info *mtd, struct erase_info *instr); +int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, +	     u_char *buf); +int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, +	      const u_char *buf); +int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, +		    const u_char *buf); + +int mtd_read_oob(struct mtd_info *mtd, loff_t from, struct mtd_oob_ops *ops); + +static inline int mtd_write_oob(struct mtd_info *mtd, loff_t to, +				struct mtd_oob_ops *ops) +{ +	ops->retlen = ops->oobretlen = 0; +	if (!mtd->_write_oob) +		return -EOPNOTSUPP; +	if (!(mtd->flags & MTD_WRITEABLE)) +		return -EROFS; +	return mtd->_write_oob(mtd, to, ops); +} + +int mtd_get_fact_prot_info(struct mtd_info *mtd, struct otp_info *buf, +			   size_t len); +int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, size_t len, +			   size_t *retlen, u_char *buf); +int mtd_get_user_prot_info(struct mtd_info *mtd, struct otp_info *buf, +			   size_t len); +int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len, +			   size_t *retlen, u_char *buf); +int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, size_t len, +			    size_t *retlen, u_char *buf); +int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, size_t len); + +/* XXX U-BOOT XXX */ +#if 0 +int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, +	       unsigned long count, loff_t to, size_t *retlen); +#endif + +static inline void mtd_sync(struct mtd_info *mtd) +{ +	if (mtd->_sync) +		mtd->_sync(mtd); +} + +int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len); +int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len); +int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len); +int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs); +int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs); +  static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd)  {  	do_div(sz, mtd->erasesize); @@ -247,6 +279,16 @@ static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd)  	return do_div(sz, mtd->erasesize);  } +static inline int mtd_has_oob(const struct mtd_info *mtd) +{ +	return mtd->_read_oob && mtd->_write_oob; +} + +static inline int mtd_can_have_bb(const struct mtd_info *mtd) +{ +	return !!mtd->_block_isbad; +} +  	/* Kernel-side ioctl definitions */  extern int add_mtd_device(struct mtd_info *mtd); @@ -269,12 +311,6 @@ struct mtd_notifier {  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);  #endif  #ifdef CONFIG_MTD_PARTITIONS @@ -296,17 +332,34 @@ static inline void mtd_erase_callback(struct erase_info *instr)  #define MTD_DEBUG_LEVEL3	(3)	/* Noisy   */  #ifdef CONFIG_MTD_DEBUG +#define pr_debug(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args)  #define MTDDEBUG(n, args...)				\  	do {						\  		if (n <= CONFIG_MTD_DEBUG_VERBOSE)	\  			printk(KERN_INFO args);		\  	} while(0)  #else /* CONFIG_MTD_DEBUG */ +#define pr_debug(args...)  #define MTDDEBUG(n, args...)				\  	do {						\  		if (0)					\  			printk(KERN_INFO args);		\  	} while(0)  #endif /* CONFIG_MTD_DEBUG */ +#define pr_info(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args) +#define pr_warn(args...)	MTDDEBUG(MTD_DEBUG_LEVEL0, args) +#define pr_err(args...)		MTDDEBUG(MTD_DEBUG_LEVEL0, args) + +static inline int mtd_is_bitflip(int err) { +	return err == -EUCLEAN; +} + +static inline int mtd_is_eccerr(int err) { +	return err == -EBADMSG; +} + +static inline int mtd_is_bitflip_or_eccerr(int err) { +	return mtd_is_bitflip(err) || mtd_is_eccerr(err); +}  #endif /* __MTD_MTD_H__ */ diff --git a/include/linux/mtd/nand.h b/include/linux/mtd/nand.h index 98bf255bb..205558437 100644 --- a/include/linux/mtd/nand.h +++ b/include/linux/mtd/nand.h @@ -46,7 +46,7 @@ extern void nand_wait_ready(struct mtd_info *mtd);   * is supported now. If you add a chip with bigger oobsize/page   * adjust this accordingly.   */ -#define NAND_MAX_OOBSIZE	576 +#define NAND_MAX_OOBSIZE	640  #define NAND_MAX_PAGESIZE	8192  /* @@ -82,6 +82,8 @@ extern void nand_wait_ready(struct mtd_info *mtd);  #define NAND_CMD_READID		0x90  #define NAND_CMD_ERASE2		0xd0  #define NAND_CMD_PARAM		0xec +#define NAND_CMD_GET_FEATURES	0xee +#define NAND_CMD_SET_FEATURES	0xef  #define NAND_CMD_RESET		0xff  #define NAND_CMD_LOCK		0x2a @@ -142,7 +144,7 @@ typedef enum {  #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 */ +/* Enable Hardware ECC before syndrome is read back from flash */  #define NAND_ECC_READSYN	2  /* Bit mask for flags passed to do_nand_read_ecc */ @@ -153,9 +155,7 @@ typedef enum {   * Option constants for bizarre disfunctionality and real   * features.   */ -/* Chip can not auto increment pages */ -#define NAND_NO_AUTOINCR	0x00000001 -/* Buswitdh is 16 bit */ +/* Buswidth is 16 bit */  #define NAND_BUSWIDTH_16	0x00000002  /* Device supports partial programming without padding */  #define NAND_NO_PADDING		0x00000004 @@ -179,12 +179,6 @@ typedef enum {   * 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 @@ -202,34 +196,21 @@ typedef enum {  	(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))  #define NAND_HAS_SUBPAGE_READ(chip) ((chip->options & NAND_SUBPAGE_READ))  /* Non chip related options */ -/* - * Use a flash based bad block table. OOB identifier is saved in OOB area. - * This option is passed to the default bad block table function. - */ -#define NAND_USE_FLASH_BBT	0x00010000  /* This option skips the bbt scan during initialization. */ -#define NAND_SKIP_BBTSCAN	0x00020000 +#define NAND_SKIP_BBTSCAN	0x00010000  /*   * 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 +#define NAND_OWN_BUFFERS	0x00020000  /* Chip may not exist, so silence any errors in scan */ -#define NAND_SCAN_SILENT_NODEV	0x00080000 -/* - * If passed additionally to NAND_USE_FLASH_BBT then BBT code will not touch - * the OOB area. - */ -#define NAND_USE_FLASH_BBT_NO_OOB	0x00800000 -/* Create an empty BBT with no vendor information if the BBT is available */ -#define NAND_CREATE_EMPTY_BBT		0x01000000 +#define NAND_SCAN_SILENT_NODEV	0x00040000  /* Options set by nand scan */  /* bbt has already been read */ @@ -244,6 +225,21 @@ typedef enum {  /* Keep gcc happy */  struct nand_chip; +/* ONFI timing mode, used in both asynchronous and synchronous mode */ +#define ONFI_TIMING_MODE_0		(1 << 0) +#define ONFI_TIMING_MODE_1		(1 << 1) +#define ONFI_TIMING_MODE_2		(1 << 2) +#define ONFI_TIMING_MODE_3		(1 << 3) +#define ONFI_TIMING_MODE_4		(1 << 4) +#define ONFI_TIMING_MODE_5		(1 << 5) +#define ONFI_TIMING_MODE_UNKNOWN	(1 << 6) + +/* ONFI feature address */ +#define ONFI_FEATURE_ADDR_TIMING_MODE	0x1 + +/* ONFI subfeature parameters length */ +#define ONFI_SUBFEATURE_PARAM_LEN	4 +  struct nand_onfi_params {  	/* rev info and features block */  	/* 'O' 'N' 'F' 'I'  */ @@ -326,27 +322,32 @@ struct nand_hw_control {  };  /** - * 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 + * 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 + * @strength:	max number of correctible bits per ECC 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 - * @priv:	pointer to private ecc control data - * @hwctl:	function to control hardware ecc generator. Must only + * @priv:	pointer to private ECC control data + * @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) + * @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. - * @read_subpage:	function to read parts of the page covered by ECC. - * @write_page:	function to write a page according to the ecc generator + * @read_page:	function to read a page according to the ECC generator + *		requirements; returns maximum number of bitflips corrected in + *		any single ECC step, 0 if bitflips uncorrectable, -EIO hw error + * @read_subpage:	function to read parts of the page covered by ECC; + *			returns same as read_page() + * @write_page:	function to write a page according to the ECC generator   *		requirements. + * @write_oob_raw:	function to write chip OOB data without ECC + * @read_oob_raw:	function to read chip OOB data without ECC   * @read_oob:	function to read chip OOB data   * @write_oob:	function to write chip OOB data   */ @@ -356,6 +357,7 @@ struct nand_ecc_ctrl {  	int size;  	int bytes;  	int total; +	int strength;  	int prepad;  	int postpad;  	struct nand_ecclayout	*layout; @@ -366,25 +368,28 @@ struct nand_ecc_ctrl {  	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, int page); -	void (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip, -			const uint8_t *buf); +			uint8_t *buf, int oob_required, int page); +	int (*write_page_raw)(struct mtd_info *mtd, struct nand_chip *chip, +			const uint8_t *buf, int oob_required);  	int (*read_page)(struct mtd_info *mtd, struct nand_chip *chip, -			uint8_t *buf, int page); +			uint8_t *buf, int oob_required, int page);  	int (*read_subpage)(struct mtd_info *mtd, struct nand_chip *chip,  			uint32_t offs, uint32_t len, 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_page)(struct mtd_info *mtd, struct nand_chip *chip, +			const uint8_t *buf, int oob_required); +	int (*write_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip, +			int page); +	int (*read_oob_raw)(struct mtd_info *mtd, struct nand_chip *chip, +			int page); +	int (*read_oob)(struct mtd_info *mtd, struct nand_chip *chip, int page);  	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 + * @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 @@ -418,7 +423,7 @@ struct nand_buffers {   *			mtd->oobsize, mtd->writesize and so on.   *			@id_data contains the 8 bytes values of NAND_CMD_READID.   *			Return with the bus width. - * @dev_ready:		[BOARDSPECIFIC] hardwarespecific function for accesing + * @dev_ready:		[BOARDSPECIFIC] hardwarespecific function for accessing   *			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. @@ -426,17 +431,17 @@ struct nand_buffers {   *			commands to the chip.   * @waitfunc:		[REPLACEABLE] hardwarespecific function for wait on   *			ready. - * @ecc:		[BOARDSPECIFIC] ecc control ctructure + * @ecc:		[BOARDSPECIFIC] ECC control structure   * @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   * @chip_delay:		[BOARDSPECIFIC] chip dependent delay for transferring   *			data from array to read regs (tR).   * @state:		[INTERN] the current state of the NAND device - * @oob_poi:		poison value buffer + * @oob_poi:		"poison value buffer," used for laying out OOB data + *			before writing   * @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 @@ -445,10 +450,14 @@ struct nand_buffers {   * @options:		[BOARDSPECIFIC] various chip options. They can partly   *			be set to inform nand_scan about special functionality.   *			See the defines for further explanation. + * @bbt_options:	[INTERN] bad block specific options. All options used + *			here must come from bbm.h. By default, these options + *			will be copied to the appropriate nand_bbt_descr's.   * @badblockpos:	[INTERN] position of the bad block marker in the oob   *			area. - * @badblockbits:	[INTERN] number of bits to left-shift the bad block - *			number + * @badblockbits:	[INTERN] minimum number of set bits in a good block's + *			bad block marker position; i.e., BBM == 11110111b is + *			not bad when badblockbits == 7   * @cellinfo:		[INTERN] MLC/multichip data from chip ident   * @numchips:		[INTERN] number of physical chips   * @chipsize:		[INTERN] the size of one chip for multichip arrays @@ -460,7 +469,9 @@ struct nand_buffers {   *			non 0 if ONFI supported.   * @onfi_params:	[INTERN] holds the ONFI page parameter when ONFI is   *			supported, 0 otherwise. - * @ecclayout:		[REPLACEABLE] the default ecc placement scheme + * @onfi_set_features	[REPLACEABLE] set the features for ONFI nand + * @onfi_get_features	[REPLACEABLE] get the features for ONFI nand + * @ecclayout:		[REPLACEABLE] the default ECC placement scheme   * @bbt:		[INTERN] bad block table pointer   * @bbt_td:		[REPLACEABLE] bad block table descriptor for flash   *			lookup. @@ -468,9 +479,9 @@ struct nand_buffers {   * @badblock_pattern:	[REPLACEABLE] bad block scan pattern used for initial   *			bad block scan.   * @controller:		[REPLACEABLE] a pointer to a hardware controller - *			structure which is shared among multiple independend + *			structure which is shared among multiple independent   *			devices. - * @priv:		[OPTIONAL] pointer to private chip date + * @priv:		[OPTIONAL] pointer to private chip data   * @errstat:		[OPTIONAL] hardware specific function to perform   *			additional error status checks (determine if errors are   *			correctable). @@ -501,10 +512,16 @@ struct nand_chip {  	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); +			const uint8_t *buf, int oob_required, int page, +			int cached, int raw); +	int (*onfi_set_features)(struct mtd_info *mtd, struct nand_chip *chip, +			int feature_addr, uint8_t *subfeature_para); +	int (*onfi_get_features)(struct mtd_info *mtd, struct nand_chip *chip, +			int feature_addr, uint8_t *subfeature_para);  	int chip_delay;  	unsigned int options; +	unsigned int bbt_options;  	int page_shift;  	int phys_erase_shift; @@ -534,8 +551,6 @@ struct nand_chip {  	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; @@ -557,6 +572,8 @@ struct nand_chip {  #define NAND_MFR_HYNIX		0xad  #define NAND_MFR_MICRON		0x2c  #define NAND_MFR_AMD		0x01 +#define NAND_MFR_MACRONIX	0xc2 +#define NAND_MFR_EON		0x92  /**   * struct nand_flash_dev - NAND Flash Device ID Structure @@ -615,9 +632,9 @@ extern int nand_do_read(struct mtd_info *mtd, loff_t from, size_t len,   * @partitions:		mtd partition list   * @chip_delay:		R/B delay value in us   * @options:		Option flags, e.g. 16bit buswidth - * @ecclayout:		ecc layout info structure + * @bbt_options:	BBT option flags, e.g. NAND_BBT_USE_FLASH + * @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; @@ -627,8 +644,8 @@ struct platform_nand_chip {  	struct nand_ecclayout *ecclayout;  	int chip_delay;  	unsigned int options; +	unsigned int bbt_options;  	const char **part_probe_types; -	void *priv;  };  /* Keep gcc happy */ @@ -650,6 +667,7 @@ struct platform_nand_ctrl {  	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); +	unsigned char (*read_byte)(struct mtd_info *mtd);  	void *priv;  }; @@ -679,4 +697,23 @@ void nand_read_buf(struct mtd_info *mtd, uint8_t *buf, int len);  void nand_read_buf16(struct mtd_info *mtd, uint8_t *buf, int len);  uint8_t nand_read_byte(struct mtd_info *mtd); +/* return the supported asynchronous timing mode. */ + +#ifdef CONFIG_SYS_NAND_ONFI_DETECTION +static inline int onfi_get_async_timing_mode(struct nand_chip *chip) +{ +	if (!chip->onfi_version) +		return ONFI_TIMING_MODE_UNKNOWN; +	return le16_to_cpu(chip->onfi_params.async_timing_mode); +} + +/* return the supported synchronous timing mode. */ +static inline int onfi_get_sync_timing_mode(struct nand_chip *chip) +{ +	if (!chip->onfi_version) +		return ONFI_TIMING_MODE_UNKNOWN; +	return le16_to_cpu(chip->onfi_params.src_sync_timing_mode); +} +#endif +  #endif /* __LINUX_MTD_NAND_H */ diff --git a/include/linux/string.h b/include/linux/string.h index e9b134d14..8e4485571 100644 --- a/include/linux/string.h +++ b/include/linux/string.h @@ -85,6 +85,9 @@ extern int memcmp(const void *,const void *,__kernel_size_t);  #ifndef __HAVE_ARCH_MEMCHR  extern void * memchr(const void *,int,__kernel_size_t);  #endif +#ifndef __HAVE_ARCH_MEMCHR_INV +void *memchr_inv(const void *, int, size_t); +#endif  #ifdef __cplusplus  } diff --git a/include/linux/mtd/mtd-abi.h b/include/mtd/mtd-abi.h index 8bdd23112..d51c1abd1 100644 --- a/include/linux/mtd/mtd-abi.h +++ b/include/mtd/mtd-abi.h @@ -24,6 +24,25 @@ struct mtd_oob_buf {  	unsigned char __user *ptr;  }; +/* + * MTD operation modes + * + * @MTD_OPS_PLACE_OOB:	OOB data are placed at the given offset (default) + * @MTD_OPS_AUTO_OOB:	OOB data are automatically placed at the free areas + *			which are defined by the internal ecclayout + * @MTD_OPS_RAW:	data are transferred as-is, with no error correction; + *			this mode implies %MTD_OPS_PLACE_OOB + * + * These modes can be passed to ioctl(MEMWRITE) and are also used internally. + * See notes on "MTD file modes" for discussion on %MTD_OPS_RAW vs. + * %MTD_FILE_MODE_RAW. + */ +enum { +	MTD_OPS_PLACE_OOB = 0, +	MTD_OPS_AUTO_OOB = 1, +	MTD_OPS_RAW = 2, +}; +  #define MTD_ABSENT		0  #define MTD_RAM			1  #define MTD_ROM			2 @@ -82,24 +101,42 @@ struct otp_info {  	uint32_t locked;  }; +/* Get basic MTD characteristics info (better to use sysfs) */  #define MEMGETINFO		_IOR('M', 1, struct mtd_info_user) +/* Erase segment of MTD */  #define MEMERASE		_IOW('M', 2, struct erase_info_user) +/* Write out-of-band data from MTD */  #define MEMWRITEOOB		_IOWR('M', 3, struct mtd_oob_buf) +/* Read out-of-band data from MTD */  #define MEMREADOOB		_IOWR('M', 4, struct mtd_oob_buf) +/* Lock a chip (for MTD that supports it) */  #define MEMLOCK			_IOW('M', 5, struct erase_info_user) +/* Unlock a chip (for MTD that supports it) */  #define MEMUNLOCK		_IOW('M', 6, struct erase_info_user) +/* Get the number of different erase regions */  #define MEMGETREGIONCOUNT	_IOR('M', 7, int) +/* Get information about the erase region for a specific index */  #define MEMGETREGIONINFO	_IOWR('M', 8, struct region_info_user) +/* Get info about OOB modes (e.g., RAW, PLACE, AUTO) - legacy interface */  #define MEMSETOOBSEL		_IOW('M', 9, struct nand_oobinfo)  #define MEMGETOOBSEL		_IOR('M', 10, struct nand_oobinfo) +/* Check if an eraseblock is bad */  #define MEMGETBADBLOCK		_IOW('M', 11, loff_t) +/* Mark an eraseblock as bad */  #define MEMSETBADBLOCK		_IOW('M', 12, loff_t) +/* Set OTP (One-Time Programmable) mode (factory vs. user) */  #define OTPSELECT		_IOR('M', 13, int) +/* Get number of OTP (One-Time Programmable) regions */  #define OTPGETREGIONCOUNT	_IOW('M', 14, int) +/* Get all OTP (One-Time Programmable) info about MTD */  #define OTPGETREGIONINFO	_IOW('M', 15, struct otp_info) +/* Lock a given range of user data (must be in mode %MTD_FILE_MODE_OTP_USER) */  #define OTPLOCK			_IOR('M', 16, struct otp_info) +/* Get ECC layout (deprecated) */  #define ECCGETLAYOUT		_IOR('M', 17, struct nand_ecclayout) +/* Get statistics about corrected/uncorrected errors */  #define ECCGETSTATS		_IOR('M', 18, struct mtd_ecc_stats) +/* Set MTD mode on a per-file-descriptor basis (see "MTD file modes") */  #define MTDFILEMODE		_IO('M', 19)  /* @@ -146,7 +183,21 @@ struct mtd_ecc_stats {  };  /* - * Read/write file modes for access to MTD + * MTD file modes - for read/write access to MTD + * + * @MTD_FILE_MODE_NORMAL:	OTP disabled, ECC enabled + * @MTD_FILE_MODE_OTP_FACTORY:	OTP enabled in factory mode + * @MTD_FILE_MODE_OTP_USER:	OTP enabled in user mode + * @MTD_FILE_MODE_RAW:		OTP disabled, ECC disabled + * + * These modes can be set via ioctl(MTDFILEMODE). The mode mode will be retained + * separately for each open file descriptor. + * + * Note: %MTD_FILE_MODE_RAW provides the same functionality as %MTD_OPS_RAW - + * raw access to the flash, without error correction or autoplacement schemes. + * Wherever possible, the MTD_OPS_* mode will override the MTD_FILE_MODE_* mode + * (e.g., when using ioctl(MEMWRITE)), but in some cases, the MTD_FILE_MODE is + * used out of necessity (e.g., `write()', ioctl(MEMWRITEOOB64)).   */  enum mtd_file_modes {  	MTD_MODE_NORMAL = MTD_OTP_OFF, diff --git a/include/nand.h b/include/nand.h index 4f965235b..26190e413 100644 --- a/include/nand.h +++ b/include/nand.h @@ -56,17 +56,17 @@ extern nand_info_t nand_info[];  static inline int nand_read(nand_info_t *info, loff_t ofs, size_t *len, u_char *buf)  { -	return info->read(info, ofs, *len, (size_t *)len, buf); +	return mtd_read(info, ofs, *len, (size_t *)len, buf);  }  static inline int nand_write(nand_info_t *info, loff_t ofs, size_t *len, u_char *buf)  { -	return info->write(info, ofs, *len, (size_t *)len, buf); +	return mtd_write(info, ofs, *len, (size_t *)len, buf);  }  static inline int nand_block_isbad(nand_info_t *info, loff_t ofs)  { -	return info->block_isbad(info, ofs); +	return mtd_block_isbad(info, ofs);  }  static inline int nand_erase(nand_info_t *info, loff_t off, size_t size) @@ -78,7 +78,7 @@ static inline int nand_erase(nand_info_t *info, loff_t off, size_t size)  	instr.len = size;  	instr.callback = 0; -	return info->erase(info, &instr); +	return mtd_erase(info, &instr);  } |