⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proc.c

📁 can bus driver code.
💻 C
字号:
/* proc.c * Linux CAN-bus device driver. * Written by Arnaud Westenberg email:arnaud@wanadoo.nl * This software is released under the GPL-License. * Version 0.7  6 Aug 2001 */ #define __NO_VERSION__#include <linux/module.h>#include <linux/autoconf.h>#if defined (CONFIG_MODVERSIONS) && !defined (MODVERSIONS)#define MODVERSIONS#endif#if defined (MODVERSIONS)#include <linux/modversions.h>#endif#include <linux/kernel.h>#include <linux/malloc.h>#include <linux/proc_fs.h>#include <linux/version.h>#include "../include/main.h"#include "../include/proc.h"#include "../include/setup.h"int add_channel_to_procdir(void);int remove_channel_from_procdir(void);int add_object_to_procdir(void);int remove_object_from_procdir(void);#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19))static int candev_readlink(struct proc_dir_entry *de, char *page);#endifstatic int bc=0; /* static counter for each hardware board */static int cc=0; /* static counter for each CAN chip */static int oc=0; /* static counter for each message object */struct canproc_t can_proc_base;struct canproc_t *base=&can_proc_base;/* The following functions are needed only for kernel version 2.2. Kernel * version 2.4 already defines them for us. */#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19))static void can_fill_inode(struct inode *inode, int fill){	if (fill)		MOD_INC_USE_COUNT;	else		MOD_DEC_USE_COUNT;}static struct proc_dir_entry * new_can_proc_entry(unsigned short inode,    const char *name, mode_t mode, nlink_t nlink, struct proc_dir_entry *parent){	struct proc_dir_entry *new_entry = NULL;	new_entry = (struct proc_dir_entry *) kmalloc(sizeof(struct 						proc_dir_entry), GFP_KERNEL);	if (new_entry == NULL)		return NULL;	memset(new_entry, 0, sizeof(struct proc_dir_entry));	new_entry->low_ino = inode;	new_entry->namelen = strlen(name);	new_entry->name = name;	new_entry->mode = mode;	new_entry->nlink = nlink;	new_entry->fill_inode = can_fill_inode;	new_entry->parent = parent;	proc_register(parent, new_entry);	return new_entry;}int can_remove_proc_entry(struct proc_dir_entry *del, struct proc_dir_entry *parent){	if (del != NULL) {		proc_unregister(parent, del->low_ino);		kfree(del);		del = NULL;		return 0;	}	else return -ENODEV;}#endif // Functions required for kernel 2.2/* can_init_procdir registers the entire CAN directory tree recursively at * the proc system. */int can_init_procdir(void){#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19))	base->can_proc_entry = new_can_proc_entry(0, "can", S_IFDIR | S_IRUGO | 					S_IXUGO, 0, &proc_root);#else	base->can_proc_entry = create_proc_entry("can", S_IFDIR | S_IRUGO | 					S_IXUGO, &proc_root);#endif	if (base->can_proc_entry == NULL)		return -ENODEV;	for (bc=0; bc<hardware_p->nr_boards; bc++) {		add_channel_to_procdir();	} 	return 0;}/* can_delete_procdir removes the entire CAN tree from the proc system */int can_delete_procdir(void){	if (remove_channel_from_procdir()) 		return -ENODEV;#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19))	if (can_remove_proc_entry(base->can_proc_entry, &proc_root)) 		return -ENODEV;#else	remove_proc_entry("can", &proc_root);#endif	return 0;}int add_channel_to_procdir(void){	int i=0;	for (i=0; i < candevices_p[bc]->nr_82527_chips + 			candevices_p[bc]->nr_sja1000_chips; i++) {		base->channel[cc] = (struct channelproc_t *)			kmalloc(sizeof(struct channelproc_t), GFP_KERNEL);		if (base->channel[cc] == NULL)			return -ENOMEM;		else if (add_mem_to_list(base->channel[cc]))			return -ENOMEM;		sprintf(base->channel[cc]->ch_name, "channel%d",cc);						#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19))		base->channel[cc]->ch_entry = new_can_proc_entry(0, 						base->channel[cc]->ch_name,						S_IFDIR | S_IRUGO | S_IXUGO, 0, 						base->can_proc_entry);#else		base->channel[cc]->ch_entry = create_proc_entry(						base->channel[cc]->ch_name,						S_IFDIR | S_IRUGO |S_IXUGO,						base->can_proc_entry);#endif		if (base->channel[cc]->ch_entry == NULL)			return -ENODEV;		add_object_to_procdir();		cc++;	} 	return 0;}int remove_channel_from_procdir(void){		while (cc != 0) {		cc--;#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19))		if (can_remove_proc_entry(base->channel[cc]->ch_entry,							base->can_proc_entry))			return -ENODEV;#else		remove_proc_entry(base->channel[cc]->ch_name,							base->can_proc_entry);#endif		if (remove_object_from_procdir())			return -ENODEV; 	}	return 0;}int add_object_to_procdir(void){	int i=0, obj=0;	if (!strcmp(chips_p[cc]->chip_type,"i82527"))		obj=15;	if (!strcmp(chips_p[cc]->chip_type,"sja1000"))		obj=1;	for (i=0; i<obj; i++) {		oc=i;		base->channel[cc]->object[i] = (struct objectproc_t *)			kmalloc(sizeof(struct objectproc_t),GFP_KERNEL);										if (base->channel[cc]->object[i] == NULL)			return -ENOMEM;		else if (add_mem_to_list( base->channel[cc]->object[i]))			return -ENOMEM;		sprintf(base->channel[cc]->object[i]->obj_name,"object%d",i);		sprintf(base->channel[cc]->object[i]->lnk_name,"dev");								#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19))		base->channel[cc]->object[i]->obj_entry=new_can_proc_entry(				0, base->channel[cc]->object[i]->obj_name,				S_IFDIR | S_IRUGO | S_IXUGO, 0, 				base->channel[cc]->ch_entry);		if (base->channel[cc]->object[i]->obj_entry == NULL)			return -ENODEV;		base->channel[cc]->object[i]->lnk = new_can_proc_entry(				0, base->channel[cc]->object[i]->lnk_name, 				S_IFLNK | S_IRUGO | S_IWUGO | S_IXUGO,				0, base->channel[cc]->object[i]->obj_entry);		if (base->channel[cc]->object[i]->lnk == NULL)			return -ENODEV;		sprintf(base->channel[cc]->object[i]->lnk_dev,"/dev/can");		base->channel[cc]->object[i]->lnk->readlink_proc =								candev_readlink;#else		base->channel[cc]->object[i]->obj_entry = create_proc_entry(				base->channel[cc]->object[i]->obj_name,				S_IFDIR | S_IRUGO | S_IXUGO,				base->channel[cc]->ch_entry);		if (base->channel[cc]->object[i]->obj_entry == NULL)			return -ENODEV;		sprintf(base->channel[cc]->object[i]->lnk_dev,"/dev/can%d",			chips_p[cc]->msgobj[i]->minor);		base->channel[cc]->object[i]->lnk = proc_symlink(				base->channel[cc]->object[i]->lnk_name,				base->channel[cc]->object[i]->obj_entry,				base->channel[cc]->object[i]->lnk_dev);		if (base->channel[cc]->object[i]->lnk == NULL)			return -ENODEV;#endif	}	return 0;} int remove_object_from_procdir(void){	int i=0, obj=0;	if (!strcmp(chips_p[cc]->chip_type,"i82527"))		obj=15;	if (!strcmp(chips_p[cc]->chip_type,"sja1000"))		obj=1;	for (i=0; i<obj; i++) {#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19))		if (can_remove_proc_entry( base->channel[cc]->object[i]->lnk,				base->channel[cc]->object[i]->obj_entry))				return -ENODEV;		if (can_remove_proc_entry(				base->channel[cc]->object[i]->obj_entry,				base->channel[cc]->ch_entry))			return -ENODEV;#else		remove_proc_entry(base->channel[cc]->object[i]->lnk_name,				base->channel[cc]->object[i]->obj_entry);		remove_proc_entry(base->channel[cc]->object[i]->obj_name,					base->channel[cc]->ch_entry);#endif			}	return 0;}#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19))static int candev_readlink(struct proc_dir_entry *de, char *page){	int i=0, nchip=0, nobj=0;	char chip[20], object[20], tmp[6];	sprintf(chip, de->parent->parent->name+7);	sprintf(object, de->parent->name+6);	for (i=0; i<MAX_TOT_CHIPS; i++) {		sprintf(tmp,"%d",i);		if (!strcmp(chip,tmp)) {			nchip=i;			break;		}		}	for (i=0; i<MAX_MSGOBJS; i++) {		sprintf(tmp,"%d",i);		if (!strcmp(object,tmp)) {			nobj=i;			break;		}	}	return sprintf(page,"/dev/can%d",chips_p[nchip]->msgobj[nobj]->minor );}#endif //End of candev_readlink for kernel 2.2

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -