ARM-Linux驱动--MTD驱动分析(二)
硬件平台:FL2440(S3C2440)with linux kernel 2.6.35
1、mtd_notifier结构体
- //MTD设备通知结构体
- structmtd_notifier{
- void(*add)(structmtd_info*mtd);//加入MTD原始/字符/块设备时执行
- void(*remove)(structmtd_info*mtd);//移除MTD原始/字符/块设备时执行
- structlist_headlist;//list是双向链表,定义在include/linux/list.h
- };
INIT_LIST_HEAD(ptr) 初始化ptr节点为表头,将前趋与后继都指向自己。
LIST_HEAD(name) 声明并初始化双向循环链表name。
static inline void __list_add(struct list_head *new, struct list_head *prev, struct list_head *next)
向链表中在prev与next之间插入元素new
static inline void list_add(struct list_head *new, struct list_head *head)
在链表中头节点后插入元素new,调用__list_add()实现。
static inline void list_add_tail(struct list_head *new, struct list_head *head)
在链表末尾插入元素new,调用__list_add()实现。
static inline void __list_del(struct list_head * prev, struct list_head * next)
删除链表中prev与next之间的元素。
static inline void list_del(struct list_head *entry)
删除链表中的元素entry。
static inline void list_del_init(struct list_head *entry)
从链表中删除元素entry,并将其初始化为新的链表。
static inline void list_move(struct list_head *list, struct list_head *head)
从链表中删除list元素,并将其加入head链表。
static inline void list_move_tail(struct list_head *list, struct list_head *head)
把list移动到链表末尾。
static inline int list_empty(const struct list_head *head)
测试链表是否为空。
static inline void __list_splice(struct list_head *list, struct list_head *head)
将链表list与head合并。
static inline void list_splice(struct list_head *list, struct list_head *head)
在list不为空的情况下,调用__list_splice()实现list与head的合并。
static inline void list_splice_init(struct list_head *list, struct list_head *head)
将两链表合并,并将list初始化。
list_entry(ptr, type, member)
list_entry的定义是怎么回事?
a. list_entry的定义在内核源文件include/linux/list.h中:
#define list_entry(ptr, type, member)
((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
b. 其功能是根据list_head型指针ptr换算成其宿主结构的起始地址,该宿主结构是type型的,而ptr在其宿主结构中定义为member成员。
2、add_mtd_device函数
- /**
- *add_mtd_device-registeranMTDdevice
- *@mtd:pointertonewMTDdeviceinfostructure
- *
- *AddadevicetothelistofMTDdevicespresentinthesystem,and
- *notifyeachcurrentlyactiveMTDuserofitsarrival.Returns
- *zeroonsuccessor1onfailure,whichcurrentlywillonlyhappen
- *ifthereisinsufficientmemoryorasysfserror.
- */
- //添加MTD设备函数,将MTD设备加入MTD设备链表,并通知所有的MTDuser该MTD设备。返回0表示成功,返回1表示出错(内存不足或文件系统错误)
- intadd_mtd_device(structmtd_info*mtd)
- {
- structmtd_notifier*not;//定义一个MTD设备通知器
- inti,error;
- //下面是设置mtd_info结构体信息
- if(!mtd->backing_dev_info){
- switch(mtd->type){
- caseMTD_RAM://MTD_RAM定义在include/mtd/mtd-abi.h
- mtd->backing_dev_info=&mtd_bdi_rw_mappable;
- break;
- caseMTD_ROM:
- mtd->backing_dev_info=&mtd_bdi_ro_mappable;
- break;
- default:
- mtd->backing_dev_info=&mtd_bdi_unmappable;
- break;
- }
- }
- BUG_ON(mtd->writesize==0);
- mutex_lock(&mtd_table_mutex);//给操作mtd_table加锁
- do{
- if(!idr_pre_get(&mtd_idr,GFP_KERNEL))//为mtd_idr分配内存
- gotofail_locked;
- error=idr_get_new(&mtd_idr,mtd,&i);//将id号和mtd_idr关联
- }while(error==-EAGAIN);
- if(error)
- gotofail_locked;
- mtd->index=i;
- mtd->usecount=0;
- if(is_power_of_2(mtd->erasesize))
- mtd->erasesize_shift=ffs(mtd->erasesize)-1;
- else
- mtd->erasesize_shift=0;
- if(is_power_of_2(mtd->writesize))
- mtd->writesize_shift=ffs(mtd->writesize)-1;
- else
- mtd->writesize_shift=0;
- mtd->erasesize_mask=(1
erasesize_shift)-1; - mtd->writesize_mask=(1
writesize_shift)-1; - /*Some
ARM-Linux驱动MTD驱动分 相关文章:
- ARM-Linux驱动--MTD驱动分析(一)(11-20)
- ARM-Linux驱动--MTD驱动分析(三)(11-20)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)