input输入子系统源码部分函数分析

/*
 *	源文件目录:
 *			/drivers/input/input.c
 */

入口函数:
		static int __init input_init(void)
1、		err = class_register(&input_class);				/* class设备节点生成 */
2、             err = input_proc_init();			/* 为添加到proc文件系统的设备节点文件做一些初始化工作 */
3、	        err = register_chrdev(INPUT_MAJOR, "input", &input_fops);	/* 注册为字符型驱动 */


/*
 * input_fops结构体分析
 */
 static const struct file_operations input_fops = {
	.owner = THIS_MODULE,								/* 模块所属者 */
	.open = input_open_file,						/* 打开操作函数 */
	.llseek = noop_llseek,							/* 绕过llseek操作 */
};

/*
 * input_open_file函数分析 
 */
static int input_open_file(struct inode *inode, struct file *file)
		1. struct input_handler *handler;			/* handler声明 */
/*
 * input_hanler结构体:
 * struct input_handler {

		void *private;

		void (*event)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
		bool (*filter)(struct input_handle *handle, unsigned int type, unsigned int code, int value);
		bool (*match)(struct input_handler *handler, struct input_dev *dev);
		int (*connect)(struct input_handler *handler, struct input_dev *dev, const struct input_device_id *id);
		void (*disconnect)(struct input_handle *handle);
		void (*start)(struct input_handle *handle);

		const struct file_operations *fops;
		int minor;
		const char *name;

		const struct input_device_id *id_table;
	
 *	struct list_head	h_list;
 *	struct list_head	node;
 *	};
 */
 		2. const struct file_operations *old_fops, *new_fops = NULL;		/* file_operations结构体声明 */
 		3. err = mutex_lock_interruptible(&input_mutex);			/* 上互斥锁操作 */
 		4. handler = input_table[iminor(inode) >> 5];				/* input_table链表中第iminor(inode) >> 5节点的handler */
 		5. if (handler)								/* 是否存在此handler */		
		new_fops = fops_get(handler->fops);			/* 存在内容则取出此handler的fops结构体赋予new_fops */
 		6. mutex_unlock(&input_mutex);					/* 解除互斥锁 */ 
 		7. 	old_fops = file->f_op;
				file->f_op = new_fops;				/* 交换file_operation,使input设备可使用相应的操作函数 */
		8. err = new_fops->open(inode, file);				/* 使用对于的打开函数 */
		9. fops_put(old_fops);							/* 释放old_fops */
		
/*
 *  input_register_device函数分析
 */
int input_register_device(struct input_dev *dev);
		1. static atomic_t input_no = ATOMIC_INIT(0);				/* 原子变量初始化 */
		2. struct input_handler *handler;					/* 新handler声明 */
		3. /* Every input device generates EV_SYN/SYN_REPORT events. */		/* 设置dev结构体 */
			 __set_bit(EV_SYN, dev->evbit);
			 /* KEY_RESERVED is not supposed to be transmitted to userspace. */
			 __clear_bit(KEY_RESERVED, dev->keybit);
			 /* Make sure that bitmasks not mentioned in dev->evbit are clean. */
			 input_cleanse_bitmasks(dev);
		4. init_timer(&dev->timer);					/* 初始化一个定时器 */
		5. error = device_add(&dev->dev);					/* 添加设备 */
			/*
			 *	device_add函数分析
			 */
			int device_add(struct device *dev)
				 	1. dev = get_device(dev);																								/* 获取dev的kobj */
				 	struct device *get_device(struct device *dev);
				 			\--->return dev ? to_dev(kobject_get(&dev->kobj)) : NULL;
				 	2. parent = get_device(dev->parent);		/* 获取父类驱动的kobj */
							 setup_parent(dev, parent);			/* 启动父类驱动 */
					3. error = kobject_add(&dev->kobj, dev->kobj.parent, NULL);/* 将dev->kobj, dev->kobj.parent添加至内核中 */
						 
		6. error = mutex_lock_interruptible(&input_mutex);						/* 上互斥锁 */
		7. list_add_tail(&dev->node, &input_dev_list);							/* 添加到input_dev_list队列中 */
		8. list_for_each_entry(handler, &input_handler_list, node)
			input_attach_handler(dev, handler);		/* 遍历每个节点 */
		9. input_wakeup_procfs_readers();					/* 唤醒procfs_readers */
10. mutex_unlock(&input_mutex);								/* 解除互斥锁 */
	 
/*
 * input_register_handler函数分析 
 */	
int input_register_handler(struct input_handler *handler);
		1. struct input_dev *dev;							/* input_dev结构体指针声明 */
		2. retval = mutex_lock_interruptible(&input_mutex);					/* 上互斥锁 */
		3. INIT_LIST_HEAD(&handler->h_list);							/* 初始化list的前级与后继指针都指向list */
		4. if (handler->fops != NULL) {								/* 判断是否有值handler->fops */
			if (input_table[handler->minor >> 5]) {					/* 判断input_table[handler->minor >> 5]节点是否有值 */
				retval = -EBUSY;
				goto out;
			}
			input_table[handler->minor >> 5] = handler;			/* 将handler添加到input_table[handler->minor >> 5]节点上 */
		}
		5. list_add_tail(&handler->node, &input_handler_list);			/* 将handler->node放入到队列中 */
		6. list_for_each_entry(dev, &input_dev_list, node)
				input_attach_handler(dev, handler);			/* 遍历每个节点 */
		7. input_wakeup_procfs_readers();					/* 唤醒procfs_readers */

/*
 * input_allocate_device函数分析 
 */
struct input_dev *input_allocate_device(void);
 		1. struct input_dev *dev;						/* input_dev结构体声明 */
 		2. dev = kzalloc(sizeof(struct input_dev), GFP_KERNEL);			/* input_dev结构体空间分配 */
 			 /* 
 			  * 分析kzalloc函数
 			  */
 			  static inline void *kzalloc(size_t size, gfp_t flags)
 			  					\-->return kmalloc(size, flags | __GFP_ZERO);
 		3. if (dev) {								/* 初始化dev的成员变量 */	
				dev->dev.type = &input_dev_type;
				dev->dev.class = &input_class;
				device_initialize(&dev->dev);
				/*
				 * device_initialize函数
				 */
				 void device_initialize(struct device *dev)
					{
						dev->kobj.kset = devices_kset;
						kobject_init(&dev->kobj, &device_ktype);
						INIT_LIST_HEAD(&dev->dma_pools);
						mutex_init(&dev->mutex);
						lockdep_set_novalidate_class(&dev->mutex);
						spin_lock_init(&dev->devres_lock);
						INIT_LIST_HEAD(&dev->devres_head);
						device_pm_init(dev);
						set_dev_node(dev, -1);
					}
				/*
				 * 互斥锁初始化 
				 */
				mutex_init(&dev->mutex);
				/*
				 * 自旋锁初始化
				 */
				spin_lock_init(&dev->event_lock);
				INIT_LIST_HEAD(&dev->h_list);
				INIT_LIST_HEAD(&dev->node);
		
				__module_get(THIS_MODULE);
			}

/*
 * input_attach_handler函数分析 
 */
static int input_attach_handler(struct input_dev *dev, struct input_handler *handler);
		1. id = input_match_device(handler, dev);					/* 比较handler与dev的id */
		2. error = handler->connect(handler, dev, id);					/* 调用相应handler的connet函数 */
		
/*
 * input_register_handle函数分析 
 */
int input_register_handle(struct input_handle *handle)
		1. error = mutex_lock_interruptible(&dev->mutex);				/* 上互斥锁 */
		2. if (handler->filter)								/* 使dev->h_list指向handle->d_node */
			list_add_rcu(&handle->d_node, &dev->h_list);
		   else
				list_add_tail_rcu(&handle->d_node, &dev->h_list);
		3. mutex_unlock(&dev->mutex);						/* 解除互斥锁 */1
		4. list_add_tail_rcu(&handle->h_node, &handler->h_list);	/* 使handler->h_list指向handle->h_node */	

你可能感兴趣的:(linux,源代码,驱动)