- device_driver include/linux/device.h struct device_driver {
const char * name; /* 驱动名称 */
struct bus_type * bus; /* 总线类型 */
struct completion unloaded; /* 卸载事件通知机制 */ struct kobject kobj; /* sys 中的对象 */
struct klist klist_devices; /* 设备列表 */ struct klist_node knode_bus; /* 总线结点列表 */
struct module * owner;/* 所有者 */
/* 设备驱动通用方法 */
int (*probe) (struct device * dev); /* 探测设备 */ int (*remove) (struct device * dev); /* 移除设备 */ void (*shutdown) (struct device * dev); /* 关闭设备 */
/* 挂起设备 */
int (*suspend) (struct device * dev, pm_message_t state, u32 level); int (*resume) (struct device * dev, u32 level); /* 恢复 */
};
- platform_device include/linux/device.h struct platform_device {
const char * name; /* 名称 */
u32 id; /* 设备编号, -1 表示不支持同类多个设备 */ struct device dev; /* 设备 */
u32 num_resources; /* 资源数 */ struct resource * resource; /* 资源列表 */
};
3. resource struct resource {
const char name; /* 资源名称 */
unsigned long start, end; /* 开始位置和结束位置 */ unsigned long flags; /* 资源类型 */
/* 资源在资源树中的父亲,兄弟和孩子 */ struct resource *parent, *sibling, *child;
};
4. device include/linux/device.h struct device {
struct klist klist_children; /* 在设备列表中的孩子列表 */ struct klist_node knode_parent; /* 兄弟结点 */
struct klist_node knode_driver; /* 驱动结点 */ struct klist_node knode_bus; /* 总线结点 */ struct device parent; /* 父亲 */
struct kobject kobj; /* sys结点 */ char bus_id[BUS_ID_SIZE];
struct semaphore sem; /* 同步驱动的信号量 */
struct bus_type * bus; /* 总线类型 */ struct device_driver *driver; /* 设备驱动 */ void *driver_data; /* 驱动的私有数据 */
void *platform_data; /* 平台指定的数据,为 device 核心驱动保留 */ void *firmware_data; /* 固件指定的数据,为 device 核心驱动保留 */ struct dev_pm_info power; /* 设备电源管理信息 */
u64 *dma_mask; /* DMA掩码 */
u64 coherent_dma_mask;
struct list_head dma_pools; /* DMA缓冲池 */
struct dma_coherent_mem *dma_mem; /* 连续 DMA 内存的起始位置 */
void (*release)(struct device * dev); /* 释放设置方法 */
};
- nand_hw_control include/linux/mtd/nand.h struct nand_hw_control {
spinlock_t lock; /* 自旋锁,用于硬件控制 */ struct nand_chip *active; /* 正在处理 MTD 设备 */ wait_queue_head_t wq; /* 等待队列 */
};
- nand_chip include/linux/mtd/nand.h struct nand_chip {
void iomem *IO_ADDR_R; /* 读地址 */ void iomem *IO_ADDR_W; /* 写地址 */
/* 字节操作 */
u_char (*read_byte)(struct mtd_info *mtd); /* 读一个字节 */
void (*write_byte)(struct mtd_info *mtd, u_char byte); /* 写一个字节 */
/* 双字节操作 */
u16 (*read_word)(struct mtd_info mtd); /* 读一个字 */
void (*write_word)(struct mtd_info *mtd, u16 word); /* 写一个字 */
/* buffer 操作 */
void (*write_buf)(struct mtd_info *mtd, const u_char *buf, int len); void (*read_buf)(struct mtd_info *mtd, u_char *buf, int len);
int (*verify_buf)(struct mtd_info *mtd, const u_char *buf, int len);
/* 选择一个操作芯片 */
void (*select_chip)(struct mtd_info *mtd, int chip);
/* 坏块检查操作 */
int (*block_bad)(struct mtd_info *mtd, loff_t ofs, int getchip);
/* 坏块标记操作 */
int (*block_markbad)(struct mtd_info *mtd, loff_t ofs);
/* 硬件控制操作 */
void (*hwcontrol)(struct mtd_info *mtd, int cmd);
/* 设备准备操作 */
int (*dev_ready)(struct mtd_info *mtd);
/* 命令发送操作 */
void (*cmdfunc)(struct mtd_info *mtd, unsigned command, int column, int page_addr);
/* 等待命令完成 */
int (*waitfunc)(struct mtd_info *mtd, struct nand_chip *this, int state);
/* 计算 ECC 码操作 */
int (*calculate_ecc)(struct mtd_info *mtd, const u_char *dat, u_char
*ecc_code);
/* 数据纠错操作 */
int (*correct_data)(struct mtd_info *mtd, u_char *dat, u_char *read_ecc, u_char *calc_ecc);
/* 开启硬件 ECC */
void (*enable_hwecc)(struct mtd_info *mtd, int mode);
/* 擦除操作 */
void (*erase_cmd)(struct mtd_info *mtd, int page);
/* 检查坏块表 */
int (*scan_bbt)(struct mtd_info *mtd);
int eccmode; /* ECC 模式 */
int eccsize; /* ECC 计算时使用的字节数 */
int eccbytes; /* ECC 码的字节数 */
int eccsteps; /* ECC 码计算的步骤数 */
int chip_delay; /* 芯片的延迟时间 */ spinlock_t chip_lock; /* 芯片访问的自旋锁 */ wait_queue_head_t wq; /* 芯片访问的等待队列 */ nand_state_t state; /* Nand Flash 状态 */
int page_shift; /* 页右移的位数,即 column 地址位数 */
int phys_erase_shift; /* 块右移的位数, 即 column 和页一共的地址位数 */ int bbt_erase_shift; /* 坏块页表的位数 */
int chip_shift; /* 该芯片总共的地址位数 */
u_char *data_buf; /* 数据缓冲区 */
u_char *oob_buf; /* oob 缓冲区 */
int oobdirty; /* oob 缓冲区是否需要重新初始化 */
u_char *data_poi; /* 数据缓冲区指针 */ unsigned int options; /* 芯片专有选项 */
int badblockpos;/* 坏块标示字节在 OOB 中的位置 */
int numchips; /* 芯片的个数 */
unsigned |
long |
chipsize; |
/* 在多个芯片组中, 一个芯片的大小 */ |
int |
pagemask; |
/* 每个芯片页数的屏蔽字, 通过它取出每个芯片包含多少个页 */ |
|
int |
pagebuf; |
/* 在页缓冲区中的页号 */ |
struct nand_oobinfo *autooob; /* oob 信息 */ uint8_t *bbt; /* 坏块页表 */ struct nand_bbt_descr *bbt_td; /* 坏块表描述 */
struct nand_bbt_descr *bbt_md; /* 坏块表镜像描述 */
struct nand_bbt_descr *badblock_pattern; /* 坏块检测模板 */ struct nand_hw_control *controller; /* 硬件控制 */
void *priv; /* 私有数据结构 */
/* 进行附加错误检查 */
int (*errstat)(struct mtd_info *mtd, struct nand_chip *this, int state, int status, int page);
};
- mtd_info include/linux/mtd/mtd.h struct mtd_info {
u_char type; /* 设备类型 */ u_int32_t flags; /* 设备标志位组 */ u_int32_t size; /* 总共设备的大小 */ u_int32_t erasesize; /* 擦除块的大小 */
u_int32_t oobblock; /* OOB 块的大小,如:512 个字节有一个 OOB */ u_int32_t oobsize; /* OOB数据的大小,如:一个 OOB 块有 16 个字节 */ u_int32_t ecctype; /* ECC 校验的类型 */
u_int32_t eccsize; /* ECC 码的大小 */
char *name; /* 设备名称 */
int index; /* 设备编号 */
/* oobinfo 信息,它可以通过 MEMSETOOBINFO ioctl 命令来设置 */ struct nand_oobinfo oobinfo;
u_int32_t oobavail; /* OOB区的有效字节数,为文件系统提供 */
/* 数据擦除边界信息 */ int numeraseregions;
struct mtd_erase_region_info *eraseregions;
u_int32_t bank_size; /* 保留 */
/* 擦除操作 */
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, u_char **mtdbuf);
/* 取消指向 */
void (*unpoint) (struct mtd_info *mtd, u_char * addr, 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);
/* 带 ECC 码的读/写操作 */
int (*read_ecc) (struct mtd_info *mtd, loff_t from, size_t len, size_t *retlen, u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
int (*write_ecc) (struct mtd_info *mtd, loff_t to, size_t len, size_t *retlen, const u_char *buf, u_char *eccbuf, struct nand_oobinfo *oobsel);
/* 带 OOB 码的读/写操作 */
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);
/* 提供访问保护寄存器区的方法 */
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);
/* 提供 readv 和 writev 方法 */
int (*readv) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen);
int (*readv_ecc) (struct mtd_info *mtd, struct kvec *vecs, unsigned long count, loff_t from, size_t *retlen, u_char *eccbuf,
struct nand_oobinfo *oobsel);
int (*writev) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen);
int (*writev_ecc) (struct mtd_info *mtd, const struct kvec *vecs, unsigned long count, loff_t to, size_t *retlen, u_char *eccbuf, struct nand_oobinfo *oobsel);
/* 同步操作 */
void (*sync) (struct mtd_info *mtd);
/* 芯片级支持的加/解锁操作 */
int (*lock) (struct mtd_info *mtd, loff_t ofs, size_t len); int (*unlock) (struct mtd_info *mtd, loff_t ofs, size_t len);
/* 电源管理操作 */
int (*suspend) (struct mtd_info *mtd); void (*resume) (struct mtd_info *mtd);
/* 坏块管理操作 */
int (*block_isbad) (struct mtd_info *mtd, loff_t ofs); int (*block_markbad) (struct mtd_info *mtd, loff_t ofs);
/* 重启前的通知事件 */
struct notifier_block reboot_notifier; void *priv; /* 私有数据结构 */
struct module *owner; /* 模块所有者 */ int usecount; /* 使用次数 */
};