diff options
Diffstat (limited to 'include/linux/mtd/mtd.h')
| -rw-r--r-- | include/linux/mtd/mtd.h | 304 | 
1 files changed, 84 insertions, 220 deletions
diff --git a/include/linux/mtd/mtd.h b/include/linux/mtd/mtd.h index d43dc25af82..cf5ea8cdcf8 100644 --- a/include/linux/mtd/mtd.h +++ b/include/linux/mtd/mtd.h @@ -164,6 +164,9 @@ struct mtd_info {  	/* ECC layout structure pointer - read only! */  	struct nand_ecclayout *ecclayout; +	/* max number of correctible bit errors per writesize */ +	unsigned int ecc_strength; +  	/* Data for variable erase regions. If numeraseregions is zero,  	 * it means that the whole device has erasesize as given above.  	 */ @@ -174,52 +177,52 @@ struct mtd_info {  	 * Do not call via these pointers, use corresponding mtd_*()  	 * wrappers instead.  	 */ -	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, resource_size_t *phys); -	void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len); -	unsigned long (*get_unmapped_area) (struct mtd_info *mtd, -					    unsigned long len, -					    unsigned long offset, -					    unsigned long flags); -	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 (*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, -			 struct mtd_oob_ops *ops); -	int (*write_oob) (struct mtd_info *mtd, loff_t to, +	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, resource_size_t *phys); +	int (*_unpoint) (struct mtd_info *mtd, loff_t from, size_t len); +	unsigned long (*_get_unmapped_area) (struct mtd_info *mtd, +					     unsigned long len, +					     unsigned long offset, +					     unsigned long flags); +	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 (*_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,  			  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); -	int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, +	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); +	int (*_writev) (struct mtd_info *mtd, const struct kvec *vecs,  			unsigned long count, loff_t to, size_t *retlen); -	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 (*is_locked) (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); -	int (*suspend) (struct mtd_info *mtd); -	void (*resume) (struct mtd_info *mtd); +	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 (*_is_locked) (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); +	int (*_suspend) (struct mtd_info *mtd); +	void (*_resume) (struct mtd_info *mtd);  	/*  	 * 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_device) (struct mtd_info *mtd); -	void (*put_device) (struct mtd_info *mtd); +	int (*_get_device) (struct mtd_info *mtd); +	void (*_put_device) (struct mtd_info *mtd);  	/* Backing device capabilities for this device  	 * - provides mmap capabilities @@ -240,214 +243,75 @@ struct mtd_info {  	int usecount;  }; -/* - * 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. - */ -static inline int mtd_erase(struct mtd_info *mtd, struct erase_info *instr) -{ -	return mtd->erase(mtd, instr); -} - -/* - * This stuff for eXecute-In-Place. phys is optional and may be set to NULL. - */ -static inline int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, -			    size_t *retlen, void **virt, resource_size_t *phys) -{ -	*retlen = 0; -	if (!mtd->point) -		return -EOPNOTSUPP; -	return mtd->point(mtd, from, len, retlen, virt, phys); -} - -/* We probably shouldn't allow XIP if the unpoint isn't a NULL */ -static inline void mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len) -{ -	return mtd->unpoint(mtd, from, len); -} - -/* - * Allow NOMMU mmap() to directly map the device (if not NULL) - * - return the address to which the offset maps - * - return -ENOSYS to indicate refusal to do the mapping - */ -static inline unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, -						  unsigned long len, -						  unsigned long offset, -						  unsigned long flags) -{ -	if (!mtd->get_unmapped_area) -		return -EOPNOTSUPP; -	return mtd->get_unmapped_area(mtd, len, offset, flags); -} - -static inline int mtd_read(struct mtd_info *mtd, loff_t from, size_t len, -			   size_t *retlen, u_char *buf) -{ -	return mtd->read(mtd, from, len, retlen, buf); -} - -static inline int mtd_write(struct mtd_info *mtd, loff_t to, size_t len, -			    size_t *retlen, const u_char *buf) -{ -	*retlen = 0; -	if (!mtd->write) -		return -EROFS; -	return mtd->write(mtd, to, len, retlen, buf); -} - -/* - * In blackbox flight recorder like scenarios we want to make successful writes - * in interrupt context. panic_write() is only intended to be called when its - * known the kernel is about to panic and we need the write to succeed. Since - * the kernel is not going to be running for much longer, this function can - * break locks and delay to ensure the write succeeds (but not sleep). - */ -static inline int mtd_panic_write(struct mtd_info *mtd, loff_t to, size_t len, -				  size_t *retlen, const u_char *buf) -{ -	*retlen = 0; -	if (!mtd->panic_write) -		return -EOPNOTSUPP; -	return mtd->panic_write(mtd, to, len, retlen, buf); -} +int mtd_erase(struct mtd_info *mtd, struct erase_info *instr); +int mtd_point(struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, +	      void **virt, resource_size_t *phys); +int mtd_unpoint(struct mtd_info *mtd, loff_t from, size_t len); +unsigned long mtd_get_unmapped_area(struct mtd_info *mtd, unsigned long len, +				    unsigned long offset, unsigned long flags); +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);  static inline int mtd_read_oob(struct mtd_info *mtd, loff_t from,  			       struct mtd_oob_ops *ops)  {  	ops->retlen = ops->oobretlen = 0; -	if (!mtd->read_oob) +	if (!mtd->_read_oob)  		return -EOPNOTSUPP; -	return mtd->read_oob(mtd, from, ops); +	return mtd->_read_oob(mtd, from, 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; -	return mtd->write_oob(mtd, to, ops); -} - -/* - * Method 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. - */ -static inline int mtd_get_fact_prot_info(struct mtd_info *mtd, -					 struct otp_info *buf, size_t len) -{ -	if (!mtd->get_fact_prot_info) +	if (!mtd->_write_oob)  		return -EOPNOTSUPP; -	return mtd->get_fact_prot_info(mtd, buf, len); -} - -static inline int mtd_read_fact_prot_reg(struct mtd_info *mtd, loff_t from, -					 size_t len, size_t *retlen, -					 u_char *buf) -{ -	*retlen = 0; -	if (!mtd->read_fact_prot_reg) -		return -EOPNOTSUPP; -	return mtd->read_fact_prot_reg(mtd, from, len, retlen, buf); -} - -static inline int mtd_get_user_prot_info(struct mtd_info *mtd, -					 struct otp_info *buf, -					 size_t len) -{ -	if (!mtd->get_user_prot_info) -		return -EOPNOTSUPP; -	return mtd->get_user_prot_info(mtd, buf, len); -} - -static inline int mtd_read_user_prot_reg(struct mtd_info *mtd, loff_t from, -					 size_t len, size_t *retlen, -					 u_char *buf) -{ -	*retlen = 0; -	if (!mtd->read_user_prot_reg) -		return -EOPNOTSUPP; -	return mtd->read_user_prot_reg(mtd, from, len, retlen, buf); -} - -static inline int mtd_write_user_prot_reg(struct mtd_info *mtd, loff_t to, -					  size_t len, size_t *retlen, -					  u_char *buf) -{ -	*retlen = 0; -	if (!mtd->write_user_prot_reg) -		return -EOPNOTSUPP; -	return mtd->write_user_prot_reg(mtd, to, len, retlen, buf); +	if (!(mtd->flags & MTD_WRITEABLE)) +		return -EROFS; +	return mtd->_write_oob(mtd, to, ops);  } -static inline int mtd_lock_user_prot_reg(struct mtd_info *mtd, loff_t from, -					 size_t len) -{ -	if (!mtd->lock_user_prot_reg) -		return -EOPNOTSUPP; -	return mtd->lock_user_prot_reg(mtd, from, len); -} +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);  int mtd_writev(struct mtd_info *mtd, const struct kvec *vecs,  	       unsigned long count, loff_t to, size_t *retlen);  static inline void mtd_sync(struct mtd_info *mtd)  { -	if (mtd->sync) -		mtd->sync(mtd); -} - -/* Chip-supported device locking */ -static inline int mtd_lock(struct mtd_info *mtd, loff_t ofs, uint64_t len) -{ -	if (!mtd->lock) -		return -EOPNOTSUPP; -	return mtd->lock(mtd, ofs, len); +	if (mtd->_sync) +		mtd->_sync(mtd);  } -static inline int mtd_unlock(struct mtd_info *mtd, loff_t ofs, uint64_t len) -{ -	if (!mtd->unlock) -		return -EOPNOTSUPP; -	return mtd->unlock(mtd, ofs, len); -} - -static inline int mtd_is_locked(struct mtd_info *mtd, loff_t ofs, uint64_t len) -{ -	if (!mtd->is_locked) -		return -EOPNOTSUPP; -	return mtd->is_locked(mtd, ofs, len); -} +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 int mtd_suspend(struct mtd_info *mtd)  { -	return mtd->suspend ? mtd->suspend(mtd) : 0; +	return mtd->_suspend ? mtd->_suspend(mtd) : 0;  }  static inline void mtd_resume(struct mtd_info *mtd)  { -	if (mtd->resume) -		mtd->resume(mtd); -} - -static inline int mtd_block_isbad(struct mtd_info *mtd, loff_t ofs) -{ -	if (!mtd->block_isbad) -		return 0; -	return mtd->block_isbad(mtd, ofs); -} - -static inline int mtd_block_markbad(struct mtd_info *mtd, loff_t ofs) -{ -	if (!mtd->block_markbad) -		return -EOPNOTSUPP; -	return mtd->block_markbad(mtd, ofs); +	if (mtd->_resume) +		mtd->_resume(mtd);  }  static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd) @@ -482,12 +346,12 @@ static inline uint32_t mtd_mod_by_ws(uint64_t sz, struct mtd_info *mtd)  static inline int mtd_has_oob(const struct mtd_info *mtd)  { -	return mtd->read_oob && mtd->write_oob; +	return mtd->_read_oob && mtd->_write_oob;  }  static inline int mtd_can_have_bb(const struct mtd_info *mtd)  { -	return !!mtd->block_isbad; +	return !!mtd->_block_isbad;  }  	/* Kernel-side ioctl definitions */  |