mtd.h
#define MTD_CHAR_MAJOR 90 MTD字符设备的主设备号
#define MTD_BLOCK_MAJOR 31 MTD块设备的主设备号
#define MAX_MTD_DEVICES 16 最大MTD原始设备数
表示MTD原始设备的结构,每个分区也被实现为一个mtd_info,如果有两个MTD原始设备,每个上有三个分区,在系统中就一共有6个mtd_info结构,这些mtd_info的指针被存放在名为mtd_table的数组里。
struct mtd_info {
u_char type; 内存技术的类型
u_int32_t flags; 标志位
u_int32_t size; // Total size of the MTD mtd设备的大小
/* "Major" erase size for the device. Na飗e 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;“主要的”erasesize(同一个mtd设备可能有数种不同的erasesize)
u_int32_t oobblock; // Size of OOB blocks (e.g. 512) oob块大小
u_int32_t oobsize; // Amount of OOB data per block (e.g. 16) oob特别数据大小
u_int32_t ecctype; ecc类型
u_int32_t eccsize; 自动ecc可以工作的范围
// Kernel-only stuff starts here.
char *name;
int index;
/* Data for variable erase regions. If numeraseregions is zero,
* it means that the whole device has erasesize as given above.
*/不同的erasesize的区域
int numeraseregions; 不同erasesize的区域的数目(通常是1)
struct mtd_erase_region_info *eraseregions;
/* This really shouldn't be here. It can go away in 2.5 */
u_int32_t bank_size;
struct module *module;
int (*erase) (struct mtd_info *mtd, struct erase_info *instr);
此routine用于将一个erase_info加入erase queue
/* This stuff for eXecute-In-Place */
int (*point) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char **mtdbuf);
/* We probably shouldn't allow XIP if the unpoint isn't a NULL */
void (*unpoint) (struct mtd_info *mtd, u_char * addr);
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);
int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf);
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);
/* iovec-based read/write methods. We need these especially for NAND flash,
with its limited number of write cycles per erase.
NB: The 'count' parameter is the number of _vectors_, each of
which contains an (ofs, len) tuple.
*/
int (*readv) (struct mtd_info *mtd, struct iovec *vecs, unsigned long count, loff_t from, size_t *retlen);
int (*writev) (struct mtd_info *mtd, const struct iovec *vecs, unsigned long count, loff_t to, size_t *retlen);
/* Sync */
void (*sync) (struct mtd_info *mtd);
/* 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);
/* Power Management functions */
int (*suspend) (struct mtd_info *mtd);
void (*resume) (struct mtd_info *mtd);
void *priv; //指向map_info结构
}
#define MTD_ABSENT 0
#define MTD_RAM 1
#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_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
// 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)
#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
表示erase动作的结构,由设备层调用mtd_info->erase函数传递给原始设备层
struct erase_info {
struct mtd_info *mtd; 被操作的MTD原始设备
u_int32_t addr; 被操作的地址(byte)
u_int32_t len; 长度
u_long time;
u_long retries;
u_int dev;
u_int cell;
void (*callback) (struct erase_info *self);
callback函数指针,当erase结束后该函数被调用
u_long priv; user模块提供的private数据
u_char state; 当前状态
struct erase_info *next; erase队列中的下一个erase_info
};
#define MTD_ERASE_PENDING 0x01
#define MTD_ERASING 0x02
#define MTD_ERASE_SUSPEND 0x04
#define MTD_ERASE_DONE 0x08
#define MTD_ERASE_FAILED 0x10
驱动模块在erase要求进入erase 队列时将state设置为MTD_ERASE_PENDING,当callback被调用时设置为MTD_ERASE_DONE或MTD_ERASE_FAILED。
MTD通知器(这个名字很古怪,但我找不到更好的词来翻译),加入/删除MTD设备和原始设备时调用的函数,在设备层,当MTD字符设备或块设备注册时,如果定义了CONFIG_DEVFS_FS,则会将一个mtd_notifier加入MTD原始设备层的mtd_notifiers链表,其中的函数会在两种情况下被调用,一是加入/删除新的MTD字符/块设备时,此时调用该MTD字符/块设备的notifier对下层所有的MTD原始设备操作一遍,二是加入/删除新的MTD原始设备时,此时调用所有的notifier对该原始设备执行一遍。
struct mtd_notifier {
void (*add)(struct mtd_info *mtd); 加入时调用
void (*remove)(struct mtd_info *mtd); 删除时调用
struct mtd_notifier *next; 指向mtd_notifiers队列中的下一个mtd_notifier
};