1 2/* $Id: mtd.h,v 1.1.1.1 2008/10/15 03:29:28 james26_jang Exp $ */ 3 4#ifndef __MTD_MTD_H__ 5#define __MTD_MTD_H__ 6 7#ifdef __KERNEL__ 8 9#include <linux/config.h> 10#include <linux/version.h> 11#include <linux/types.h> 12#include <linux/mtd/compatmac.h> 13#include <linux/module.h> 14#include <linux/uio.h> 15 16#endif /* __KERNEL__ */ 17 18struct erase_info_user { 19 u_int32_t start; 20 u_int32_t length; 21}; 22 23struct mtd_oob_buf { 24 u_int32_t start; 25 u_int32_t length; 26 unsigned char *ptr; 27}; 28 29 30#define MTD_CHAR_MAJOR 90 31#define MTD_BLOCK_MAJOR 31 32#define MAX_MTD_DEVICES 16 33 34 35 36#define MTD_ABSENT 0 37#define MTD_RAM 1 38#define MTD_ROM 2 39#define MTD_NORFLASH 3 40#define MTD_NANDFLASH 4 41#define MTD_PEROM 5 42#define MTD_OTHER 14 43#define MTD_UNKNOWN 15 44 45 46 47#define MTD_CLEAR_BITS 1 // Bits can be cleared (flash) 48#define MTD_SET_BITS 2 // Bits can be set 49#define MTD_ERASEABLE 4 // Has an erase function 50#define MTD_WRITEB_WRITEABLE 8 // Direct IO is possible 51#define MTD_VOLATILE 16 // Set for RAMs 52#define MTD_XIP 32 // eXecute-In-Place possible 53#define MTD_OOB 64 // Out-of-band data (NAND flash) 54#define MTD_ECC 128 // Device capable of automatic ECC 55 56// Some common devices / combinations of capabilities 57#define MTD_CAP_ROM 0 58#define MTD_CAP_RAM (MTD_CLEAR_BITS|MTD_SET_BITS|MTD_WRITEB_WRITEABLE) 59#define MTD_CAP_NORFLASH (MTD_CLEAR_BITS|MTD_ERASEABLE) 60#define MTD_CAP_NANDFLASH (MTD_CLEAR_BITS|MTD_ERASEABLE|MTD_OOB) 61#define MTD_WRITEABLE (MTD_CLEAR_BITS|MTD_SET_BITS) 62 63 64// Types of automatic ECC/Checksum available 65#define MTD_ECC_NONE 0 // No automatic ECC available 66#define MTD_ECC_RS_DiskOnChip 1 // Automatic ECC on DiskOnChip 67#define MTD_ECC_SW 2 // SW ECC for Toshiba & Samsung devices 68 69struct mtd_info_user { 70 u_char type; 71 u_int32_t flags; 72 u_int32_t size; // Total size of the MTD 73 u_int32_t erasesize; 74 u_int32_t oobblock; // Size of OOB blocks (e.g. 512) 75 u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) 76 u_int32_t ecctype; 77 u_int32_t eccsize; 78}; 79 80struct region_info_user { 81 u_int32_t offset; /* At which this region starts, 82 * from the beginning of the MTD */ 83 u_int32_t erasesize; /* For this region */ 84 u_int32_t numblocks; /* Number of blocks in this region */ 85 u_int32_t regionindex; 86}; 87 88#define MEMGETINFO _IOR('M', 1, struct mtd_info_user) 89#define MEMERASE _IOW('M', 2, struct erase_info_user) 90#define MEMWRITEOOB _IOWR('M', 3, struct mtd_oob_buf) 91#define MEMREADOOB _IOWR('M', 4, struct mtd_oob_buf) 92#define MEMLOCK _IOW('M', 5, struct erase_info_user) 93#define MEMUNLOCK _IOW('M', 6, struct erase_info_user) 94#define MEMGETREGIONCOUNT _IOR('M', 7, int) 95#define MEMGETREGIONINFO _IOWR('M', 8, struct region_info_user) 96 97#ifndef __KERNEL__ 98 99typedef struct mtd_info_user mtd_info_t; 100typedef struct erase_info_user erase_info_t; 101typedef struct region_info_user region_info_t; 102 103 /* User-space ioctl definitions */ 104 105 106#else /* __KERNEL__ */ 107 108 109#define MTD_ERASE_PENDING 0x01 110#define MTD_ERASING 0x02 111#define MTD_ERASE_SUSPEND 0x04 112#define MTD_ERASE_DONE 0x08 113#define MTD_ERASE_FAILED 0x10 114 115struct erase_info { 116 struct mtd_info *mtd; 117 u_int32_t addr; 118 u_int32_t len; 119 u_long time; 120 u_long retries; 121 u_int dev; 122 u_int cell; 123 void (*callback) (struct erase_info *self); 124 u_long priv; 125 u_char state; 126 struct erase_info *next; 127}; 128 129struct mtd_erase_region_info { 130 u_int32_t offset; /* At which this region starts, from the beginning of the MTD */ 131 u_int32_t erasesize; /* For this region */ 132 u_int32_t numblocks; /* Number of blocks of erasesize in this region */ 133}; 134 135struct mtd_info { 136 u_char type; 137 u_int32_t flags; 138 u_int32_t size; // Total size of the MTD 139 140 /* "Major" erase size for the device. Na�ve users may take this 141 * to be the only erase size available, or may use the more detailed 142 * information below if they desire 143 */ 144 u_int32_t erasesize; 145 146 u_int32_t oobblock; // Size of OOB blocks (e.g. 512) 147 u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) 148 u_int32_t ecctype; 149 u_int32_t eccsize; 150 151 // Kernel-only stuff starts here. 152 char *name; 153 int index; 154 155 /* Data for variable erase regions. If numeraseregions is zero, 156 * it means that the whole device has erasesize as given above. 157 */ 158 int numeraseregions; 159 struct mtd_erase_region_info *eraseregions; 160 161 /* This really shouldn't be here. It can go away in 2.5 */ 162 u_int32_t bank_size; 163 164 struct module *module; 165 int (*erase) (struct mtd_info *mtd, struct erase_info *instr); 166 167 /* This stuff for eXecute-In-Place */ 168 int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf); 169 170 /* We probably shouldn't allow XIP if the unpoint isn't a NULL */ 171 void (*unpoint) (struct mtd_info *mtd, u_char * addr); 172 173 174 int (*read) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 175 int (*write) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); 176 177 int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf); 178 int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf); 179 180 int (*read_oob) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf); 181 int (*write_oob) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf); 182 183 /* iovec-based read/write methods. We need these especially for NAND flash, 184 with its limited number of write cycles per erase. 185 NB: The 'count' parameter is the number of _vectors_, each of 186 which contains an (ofs, len) tuple. 187 */ 188 int (*readv) (struct mtd_info *mtd, struct iovec *vecs, unsigned long count, loff_t from, size_t *retlen); 189 int (*writev) (struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen); 190 191 /* Sync */ 192 void (*sync) (struct mtd_info *mtd); 193 194 /* Chip-supported device locking */ 195 int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len); 196 int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len); 197 198 /* Power Management functions */ 199 int (*suspend) (struct mtd_info *mtd); 200 void (*resume) (struct mtd_info *mtd); 201 202 void *priv; 203}; 204 205 206 /* Kernel-side ioctl definitions */ 207 208extern int add_mtd_device(struct mtd_info *mtd); 209extern int del_mtd_device (struct mtd_info *mtd); 210 211extern struct mtd_info *__get_mtd_device(struct mtd_info *mtd, int num); 212 213static inline struct mtd_info *get_mtd_device(struct mtd_info *mtd, int num) 214{ 215 struct mtd_info *ret; 216 217 ret = __get_mtd_device(mtd, num); 218 219 if (ret && ret->module && !try_inc_mod_count(ret->module)) 220 return NULL; 221 222 return ret; 223} 224 225static inline void put_mtd_device(struct mtd_info *mtd) 226{ 227 if (mtd->module) 228 __MOD_DEC_USE_COUNT(mtd->module); 229} 230 231 232struct mtd_notifier { 233 void (*add)(struct mtd_info *mtd); 234 void (*remove)(struct mtd_info *mtd); 235 struct mtd_notifier *next; 236}; 237 238 239extern void register_mtd_user (struct mtd_notifier *new); 240extern int unregister_mtd_user (struct mtd_notifier *old); 241 242 243#ifndef MTDC 244#define MTD_ERASE(mtd, args...) (*(mtd->erase))(mtd, args) 245#define MTD_POINT(mtd, a,b,c,d) (*(mtd->point))(mtd, a,b,c, (u_char **)(d)) 246#define MTD_UNPOINT(mtd, arg) (*(mtd->unpoint))(mtd, (u_char *)arg) 247#define MTD_READ(mtd, args...) (*(mtd->read))(mtd, args) 248#define MTD_WRITE(mtd, args...) (*(mtd->write))(mtd, args) 249#define MTD_READV(mtd, args...) (*(mtd->readv))(mtd, args) 250#define MTD_WRITEV(mtd, args...) (*(mtd->writev))(mtd, args) 251#define MTD_READECC(mtd, args...) (*(mtd->read_ecc))(mtd, args) 252#define MTD_WRITEECC(mtd, args...) (*(mtd->write_ecc))(mtd, args) 253#define MTD_READOOB(mtd, args...) (*(mtd->read_oob))(mtd, args) 254#define MTD_WRITEOOB(mtd, args...) (*(mtd->write_oob))(mtd, args) 255#define MTD_SYNC(mtd) do { if (mtd->sync) (*(mtd->sync))(mtd); } while (0) 256#endif /* MTDC */ 257 258/* 259 * Debugging macro and defines 260 */ 261#define MTD_DEBUG_LEVEL0 (0) /* Quiet */ 262#define MTD_DEBUG_LEVEL1 (1) /* Audible */ 263#define MTD_DEBUG_LEVEL2 (2) /* Loud */ 264#define MTD_DEBUG_LEVEL3 (3) /* Noisy */ 265 266#ifdef CONFIG_MTD_DEBUG 267#define DEBUG(n, args...) \ 268 if (n <= CONFIG_MTD_DEBUG_VERBOSE) { \ 269 printk(KERN_INFO args); \ 270 } 271#else /* CONFIG_MTD_DEBUG */ 272#define DEBUG(n, args...) 273#endif /* CONFIG_MTD_DEBUG */ 274 275#endif /* __KERNEL__ */ 276 277#endif /* __MTD_MTD_H__ */ 278