1932394acSWolfgang Denk /* 2932394acSWolfgang Denk * Copyright (C) 1999-2003 David Woodhouse <dwmw2@infradead.org> et al. 3932394acSWolfgang Denk * 4932394acSWolfgang Denk * Released under GPL 5932394acSWolfgang Denk */ 6932394acSWolfgang Denk 7932394acSWolfgang Denk #ifndef __MTD_MTD_H__ 8932394acSWolfgang Denk #define __MTD_MTD_H__ 9cfa460adSWilliam Juul 10932394acSWolfgang Denk #include <linux/types.h> 118d2effeaSStefan Roese #include <div64.h> 12932394acSWolfgang Denk #include <linux/mtd/mtd-abi.h> 13932394acSWolfgang Denk 14cfa460adSWilliam Juul #define MTD_CHAR_MAJOR 90 15cfa460adSWilliam Juul #define MTD_BLOCK_MAJOR 31 16cfa460adSWilliam Juul #define MAX_MTD_DEVICES 32 17932394acSWolfgang Denk 18932394acSWolfgang Denk #define MTD_ERASE_PENDING 0x01 19932394acSWolfgang Denk #define MTD_ERASING 0x02 20932394acSWolfgang Denk #define MTD_ERASE_SUSPEND 0x04 21932394acSWolfgang Denk #define MTD_ERASE_DONE 0x08 22932394acSWolfgang Denk #define MTD_ERASE_FAILED 0x10 23932394acSWolfgang Denk 248d2effeaSStefan Roese #define MTD_FAIL_ADDR_UNKNOWN -1LL 258d2effeaSStefan Roese 26d438d508SKyungmin Park /* 27d438d508SKyungmin Park * Enumeration for NAND/OneNAND flash chip state 28d438d508SKyungmin Park */ 29d438d508SKyungmin Park enum { 30d438d508SKyungmin Park FL_READY, 31d438d508SKyungmin Park FL_READING, 32d438d508SKyungmin Park FL_WRITING, 33d438d508SKyungmin Park FL_ERASING, 34d438d508SKyungmin Park FL_SYNCING, 35d438d508SKyungmin Park FL_CACHEDPRG, 36d438d508SKyungmin Park FL_RESETING, 37d438d508SKyungmin Park FL_UNLOCKING, 38d438d508SKyungmin Park FL_LOCKING, 39d438d508SKyungmin Park FL_PM_SUSPENDED, 40d438d508SKyungmin Park }; 41d438d508SKyungmin Park 42932394acSWolfgang Denk /* If the erase fails, fail_addr might indicate exactly which block failed. If 438d2effeaSStefan Roese fail_addr = MTD_FAIL_ADDR_UNKNOWN, the failure was not at the device level or was not 44932394acSWolfgang Denk specific to any particular block. */ 45932394acSWolfgang Denk struct erase_info { 46932394acSWolfgang Denk struct mtd_info *mtd; 478d2effeaSStefan Roese uint64_t addr; 488d2effeaSStefan Roese uint64_t len; 498d2effeaSStefan Roese uint64_t fail_addr; 50932394acSWolfgang Denk u_long time; 51932394acSWolfgang Denk u_long retries; 52932394acSWolfgang Denk u_int dev; 53932394acSWolfgang Denk u_int cell; 54932394acSWolfgang Denk void (*callback) (struct erase_info *self); 55932394acSWolfgang Denk u_long priv; 56932394acSWolfgang Denk u_char state; 57932394acSWolfgang Denk struct erase_info *next; 58*6d41419fSMarek Vasut int scrub; 59932394acSWolfgang Denk }; 60932394acSWolfgang Denk 61932394acSWolfgang Denk struct mtd_erase_region_info { 628d2effeaSStefan Roese uint64_t offset; /* At which this region starts, from the beginning of the MTD */ 63932394acSWolfgang Denk u_int32_t erasesize; /* For this region */ 64932394acSWolfgang Denk u_int32_t numblocks; /* Number of blocks of erasesize in this region */ 65cfa460adSWilliam Juul unsigned long *lockmap; /* If keeping bitmap of locks */ 66cfa460adSWilliam Juul }; 67cfa460adSWilliam Juul 68cfa460adSWilliam Juul /* 69cfa460adSWilliam Juul * oob operation modes 70cfa460adSWilliam Juul * 71cfa460adSWilliam Juul * MTD_OOB_PLACE: oob data are placed at the given offset 72cfa460adSWilliam Juul * MTD_OOB_AUTO: oob data are automatically placed at the free areas 73cfa460adSWilliam Juul * which are defined by the ecclayout 74cfa460adSWilliam Juul * MTD_OOB_RAW: mode to read raw data+oob in one chunk. The oob data 75cfa460adSWilliam Juul * is inserted into the data. Thats a raw image of the 76cfa460adSWilliam Juul * flash contents. 77cfa460adSWilliam Juul */ 78cfa460adSWilliam Juul typedef enum { 79cfa460adSWilliam Juul MTD_OOB_PLACE, 80cfa460adSWilliam Juul MTD_OOB_AUTO, 81cfa460adSWilliam Juul MTD_OOB_RAW, 82cfa460adSWilliam Juul } mtd_oob_mode_t; 83cfa460adSWilliam Juul 84cfa460adSWilliam Juul /** 85cfa460adSWilliam Juul * struct mtd_oob_ops - oob operation operands 86cfa460adSWilliam Juul * @mode: operation mode 87cfa460adSWilliam Juul * 88cfa460adSWilliam Juul * @len: number of data bytes to write/read 89cfa460adSWilliam Juul * 90cfa460adSWilliam Juul * @retlen: number of data bytes written/read 91cfa460adSWilliam Juul * 92cfa460adSWilliam Juul * @ooblen: number of oob bytes to write/read 93cfa460adSWilliam Juul * @oobretlen: number of oob bytes written/read 94cfa460adSWilliam Juul * @ooboffs: offset of oob data in the oob area (only relevant when 95cfa460adSWilliam Juul * mode = MTD_OOB_PLACE) 96cfa460adSWilliam Juul * @datbuf: data buffer - if NULL only oob data are read/written 97cfa460adSWilliam Juul * @oobbuf: oob data buffer 98cfa460adSWilliam Juul * 99cfa460adSWilliam Juul * Note, it is allowed to read more then one OOB area at one go, but not write. 100cfa460adSWilliam Juul * The interface assumes that the OOB write requests program only one page's 101cfa460adSWilliam Juul * OOB area. 102cfa460adSWilliam Juul */ 103cfa460adSWilliam Juul struct mtd_oob_ops { 104cfa460adSWilliam Juul mtd_oob_mode_t mode; 105cfa460adSWilliam Juul size_t len; 106cfa460adSWilliam Juul size_t retlen; 107cfa460adSWilliam Juul size_t ooblen; 108cfa460adSWilliam Juul size_t oobretlen; 109cfa460adSWilliam Juul uint32_t ooboffs; 110cfa460adSWilliam Juul uint8_t *datbuf; 111cfa460adSWilliam Juul uint8_t *oobbuf; 112932394acSWolfgang Denk }; 113932394acSWolfgang Denk 114932394acSWolfgang Denk struct mtd_info { 115932394acSWolfgang Denk u_char type; 116932394acSWolfgang Denk u_int32_t flags; 1178e5e9b94SWolfgang Denk uint64_t size; /* Total size of the MTD */ 118932394acSWolfgang Denk 119fa82f871SAlbert ARIBAUD /* "Major" erase size for the device. Naïve users may take this 120932394acSWolfgang Denk * to be the only erase size available, or may use the more detailed 121932394acSWolfgang Denk * information below if they desire 122932394acSWolfgang Denk */ 123932394acSWolfgang Denk u_int32_t erasesize; 124cfa460adSWilliam Juul /* Minimal writable flash unit size. In case of NOR flash it is 1 (even 125cfa460adSWilliam Juul * though individual bits can be cleared), in case of NAND flash it is 126cfa460adSWilliam Juul * one NAND page (or half, or one-fourths of it), in case of ECC-ed NOR 127cfa460adSWilliam Juul * it is of ECC block size, etc. It is illegal to have writesize = 0. 128cfa460adSWilliam Juul * Any driver registering a struct mtd_info must ensure a writesize of 129cfa460adSWilliam Juul * 1 or larger. 130cfa460adSWilliam Juul */ 131cfa460adSWilliam Juul u_int32_t writesize; 132932394acSWolfgang Denk 1334b070809SWolfgang Denk u_int32_t oobsize; /* Amount of OOB data per block (e.g. 16) */ 1344b070809SWolfgang Denk u_int32_t oobavail; /* Available OOB bytes per block */ 135932394acSWolfgang Denk 1364b070809SWolfgang Denk /* Kernel-only stuff starts here. */ 137c45912d8SScott Wood const char *name; 138932394acSWolfgang Denk int index; 139932394acSWolfgang Denk 140cfa460adSWilliam Juul /* ecc layout structure pointer - read only ! */ 141cfa460adSWilliam Juul struct nand_ecclayout *ecclayout; 142932394acSWolfgang Denk 143932394acSWolfgang Denk /* Data for variable erase regions. If numeraseregions is zero, 144932394acSWolfgang Denk * it means that the whole device has erasesize as given above. 145932394acSWolfgang Denk */ 146932394acSWolfgang Denk int numeraseregions; 147932394acSWolfgang Denk struct mtd_erase_region_info *eraseregions; 148932394acSWolfgang Denk 149c45912d8SScott Wood /* 150c45912d8SScott Wood * Erase is an asynchronous operation. Device drivers are supposed 151c45912d8SScott Wood * to call instr->callback() whenever the operation completes, even 152c45912d8SScott Wood * if it completes with a failure. 153c45912d8SScott Wood * Callers are supposed to pass a callback function and wait for it 154c45912d8SScott Wood * to be called before writing to the block. 155c45912d8SScott Wood */ 156932394acSWolfgang Denk int (*erase) (struct mtd_info *mtd, struct erase_info *instr); 157932394acSWolfgang Denk 158932394acSWolfgang Denk /* This stuff for eXecute-In-Place */ 159c45912d8SScott Wood /* phys is optional and may be set to NULL */ 160c45912d8SScott Wood int (*point) (struct mtd_info *mtd, loff_t from, size_t len, 161c45912d8SScott Wood size_t *retlen, void **virt, phys_addr_t *phys); 162932394acSWolfgang Denk 163932394acSWolfgang Denk /* We probably shouldn't allow XIP if the unpoint isn't a NULL */ 164c45912d8SScott Wood void (*unpoint) (struct mtd_info *mtd, loff_t from, size_t len); 165932394acSWolfgang Denk 166932394acSWolfgang Denk 167932394acSWolfgang Denk int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 168932394acSWolfgang Denk int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); 169932394acSWolfgang Denk 170c45912d8SScott Wood /* In blackbox flight recorder like scenarios we want to make successful 171c45912d8SScott Wood writes in interrupt context. panic_write() is only intended to be 172c45912d8SScott Wood called when its known the kernel is about to panic and we need the 173c45912d8SScott Wood write to succeed. Since the kernel is not going to be running for much 174c45912d8SScott Wood longer, this function can break locks and delay to ensure the write 175c45912d8SScott Wood succeeds (but not sleep). */ 176c45912d8SScott Wood 177c45912d8SScott Wood int (*panic_write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); 178c45912d8SScott Wood 179cfa460adSWilliam Juul int (*read_oob) (struct mtd_info *mtd, loff_t from, 180cfa460adSWilliam Juul struct mtd_oob_ops *ops); 181cfa460adSWilliam Juul int (*write_oob) (struct mtd_info *mtd, loff_t to, 182cfa460adSWilliam Juul struct mtd_oob_ops *ops); 183932394acSWolfgang Denk 184932394acSWolfgang Denk /* 185932394acSWolfgang Denk * Methods to access the protection register area, present in some 186932394acSWolfgang Denk * flash devices. The user data is one time programmable but the 187932394acSWolfgang Denk * factory data is read only. 188932394acSWolfgang Denk */ 189cfa460adSWilliam Juul int (*get_fact_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len); 190932394acSWolfgang Denk int (*read_fact_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 191cfa460adSWilliam Juul int (*get_user_prot_info) (struct mtd_info *mtd, struct otp_info *buf, size_t len); 192cfa460adSWilliam Juul int (*read_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 193932394acSWolfgang Denk int (*write_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 194cfa460adSWilliam Juul int (*lock_user_prot_reg) (struct mtd_info *mtd, loff_t from, size_t len); 195cfa460adSWilliam Juul 196cfa460adSWilliam Juul /* XXX U-BOOT XXX */ 197932394acSWolfgang Denk #if 0 198cfa460adSWilliam Juul /* kvec-based read/write methods. 199932394acSWolfgang Denk NB: The 'count' parameter is the number of _vectors_, each of 200932394acSWolfgang Denk which contains an (ofs, len) tuple. 201932394acSWolfgang Denk */ 202932394acSWolfgang Denk int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen); 203932394acSWolfgang Denk #endif 204cfa460adSWilliam Juul 205932394acSWolfgang Denk /* Sync */ 206932394acSWolfgang Denk void (*sync) (struct mtd_info *mtd); 207cfa460adSWilliam Juul 208932394acSWolfgang Denk /* Chip-supported device locking */ 2098d2effeaSStefan Roese int (*lock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); 2108d2effeaSStefan Roese int (*unlock) (struct mtd_info *mtd, loff_t ofs, uint64_t len); 211932394acSWolfgang Denk 212932394acSWolfgang Denk /* Bad block management functions */ 213932394acSWolfgang Denk int (*block_isbad) (struct mtd_info *mtd, loff_t ofs); 214932394acSWolfgang Denk int (*block_markbad) (struct mtd_info *mtd, loff_t ofs); 215932394acSWolfgang Denk 216cfa460adSWilliam Juul /* XXX U-BOOT XXX */ 217cfa460adSWilliam Juul #if 0 218cfa460adSWilliam Juul struct notifier_block reboot_notifier; /* default mode before reboot */ 219cfa460adSWilliam Juul #endif 220cfa460adSWilliam Juul 221cfa460adSWilliam Juul /* ECC status information */ 222cfa460adSWilliam Juul struct mtd_ecc_stats ecc_stats; 223cfa460adSWilliam Juul /* Subpage shift (NAND) */ 224cfa460adSWilliam Juul int subpage_sft; 225cfa460adSWilliam Juul 226932394acSWolfgang Denk void *priv; 227932394acSWolfgang Denk 228932394acSWolfgang Denk struct module *owner; 229932394acSWolfgang Denk int usecount; 230cfa460adSWilliam Juul 231cfa460adSWilliam Juul /* If the driver is something smart, like UBI, it may need to maintain 232cfa460adSWilliam Juul * its own reference counting. The below functions are only for driver. 233cfa460adSWilliam Juul * The driver may register its callbacks. These callbacks are not 234cfa460adSWilliam Juul * supposed to be called by MTD users */ 235cfa460adSWilliam Juul int (*get_device) (struct mtd_info *mtd); 236cfa460adSWilliam Juul void (*put_device) (struct mtd_info *mtd); 237932394acSWolfgang Denk }; 238932394acSWolfgang Denk 2398d2effeaSStefan Roese static inline uint32_t mtd_div_by_eb(uint64_t sz, struct mtd_info *mtd) 2408d2effeaSStefan Roese { 2418d2effeaSStefan Roese do_div(sz, mtd->erasesize); 2428d2effeaSStefan Roese return sz; 2438d2effeaSStefan Roese } 2448d2effeaSStefan Roese 2458d2effeaSStefan Roese static inline uint32_t mtd_mod_by_eb(uint64_t sz, struct mtd_info *mtd) 2468d2effeaSStefan Roese { 2478d2effeaSStefan Roese return do_div(sz, mtd->erasesize); 2488d2effeaSStefan Roese } 249932394acSWolfgang Denk 250932394acSWolfgang Denk /* Kernel-side ioctl definitions */ 251932394acSWolfgang Denk 252932394acSWolfgang Denk extern int add_mtd_device(struct mtd_info *mtd); 253932394acSWolfgang Denk extern int del_mtd_device (struct mtd_info *mtd); 254932394acSWolfgang Denk 255932394acSWolfgang Denk extern struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num); 256cfa460adSWilliam Juul extern struct mtd_info *get_mtd_device_nm(const char *name); 257932394acSWolfgang Denk 258932394acSWolfgang Denk extern void put_mtd_device(struct mtd_info *mtd); 2594ba692fbSBen Gardiner extern void mtd_get_len_incl_bad(struct mtd_info *mtd, uint64_t offset, 2604ba692fbSBen Gardiner const uint64_t length, uint64_t *len_incl_bad, 2614ba692fbSBen Gardiner int *truncated); 262cfa460adSWilliam Juul /* XXX U-BOOT XXX */ 263932394acSWolfgang Denk #if 0 264932394acSWolfgang Denk struct mtd_notifier { 265932394acSWolfgang Denk void (*add)(struct mtd_info *mtd); 266932394acSWolfgang Denk void (*remove)(struct mtd_info *mtd); 267932394acSWolfgang Denk struct list_head list; 268932394acSWolfgang Denk }; 269932394acSWolfgang Denk 270932394acSWolfgang Denk extern void register_mtd_user (struct mtd_notifier *new); 271932394acSWolfgang Denk extern int unregister_mtd_user (struct mtd_notifier *old); 272932394acSWolfgang Denk 273932394acSWolfgang Denk int default_mtd_writev(struct mtd_info *mtd, const struct kvec *vecs, 274932394acSWolfgang Denk unsigned long count, loff_t to, size_t *retlen); 275932394acSWolfgang Denk 276932394acSWolfgang Denk int default_mtd_readv(struct mtd_info *mtd, struct kvec *vecs, 277932394acSWolfgang Denk unsigned long count, loff_t from, size_t *retlen); 278932394acSWolfgang Denk #endif 279932394acSWolfgang Denk 280932394acSWolfgang Denk #ifdef CONFIG_MTD_PARTITIONS 281932394acSWolfgang Denk void mtd_erase_callback(struct erase_info *instr); 282932394acSWolfgang Denk #else 283932394acSWolfgang Denk static inline void mtd_erase_callback(struct erase_info *instr) 284932394acSWolfgang Denk { 285932394acSWolfgang Denk if (instr->callback) 286932394acSWolfgang Denk instr->callback(instr); 287932394acSWolfgang Denk } 288932394acSWolfgang Denk #endif 289932394acSWolfgang Denk 290932394acSWolfgang Denk /* 291932394acSWolfgang Denk * Debugging macro and defines 292932394acSWolfgang Denk */ 293932394acSWolfgang Denk #define MTD_DEBUG_LEVEL0 (0) /* Quiet */ 294932394acSWolfgang Denk #define MTD_DEBUG_LEVEL1 (1) /* Audible */ 295932394acSWolfgang Denk #define MTD_DEBUG_LEVEL2 (2) /* Loud */ 296932394acSWolfgang Denk #define MTD_DEBUG_LEVEL3 (3) /* Noisy */ 297932394acSWolfgang Denk 298932394acSWolfgang Denk #ifdef CONFIG_MTD_DEBUG 2993167c538SScott Wood #define MTDDEBUG(n, args...) \ 300932394acSWolfgang Denk do { \ 301932394acSWolfgang Denk if (n <= CONFIG_MTD_DEBUG_VERBOSE) \ 302932394acSWolfgang Denk printk(KERN_INFO args); \ 303932394acSWolfgang Denk } while(0) 304932394acSWolfgang Denk #else /* CONFIG_MTD_DEBUG */ 305c45912d8SScott Wood #define MTDDEBUG(n, args...) \ 306c45912d8SScott Wood do { \ 307c45912d8SScott Wood if (0) \ 308c45912d8SScott Wood printk(KERN_INFO args); \ 309c45912d8SScott Wood } while(0) 310932394acSWolfgang Denk #endif /* CONFIG_MTD_DEBUG */ 311932394acSWolfgang Denk 312932394acSWolfgang Denk #endif /* __MTD_MTD_H__ */ 313