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

📄 main.c

📁 PCM9880是一块PC/104界面的双端口隔离CAN总线通讯卡
💻 C
字号:
/* main.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 EXPORT_SYMTAB#include <linux/autoconf.h>#if defined (CONFIG_MODVERSIONS) && !defined (MODVERSIONS)#define MODVERSIONS#endif#include <linux/module.h>#if defined (MODVERSIONS)#include <linux/modversions.h>#endif#include <linux/kernel.h>#include <linux/fs.h>#include <linux/wrapper.h>#include <linux/sched.h>#include <linux/version.h>#include <linux/autoconf.h>#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19))#include <asm/spinlock.h>#else#include <linux/spinlock.h>#endif#if !defined (__GENKSYMS__) #if (defined (MODVERSIONS) && !defined(NOVER))#include <linux/modversions.h>#include "../include/main.ver"#endif#endif#include "../include/main.h"#include "../include/modparms.h"#include "../include/setup.h"#include "../include/proc.h"#include "../include/open.h"#include "../include/close.h"#include "../include/read.h"#include "../include/irq.h"#include "../include/ioctl.h"#include "../include/write.h"#define EXPORT_SYMTAB/* Module parameters, some must be supplied at module loading time */int major=CAN_MAJOR;MODULE_PARM(major,"1i");int minor[MAX_TOT_CHIPS]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};MODULE_PARM(minor, "1-" __MODULE_STRING(MAX_TOT_CHIPS)"i");int extended=0;MODULE_PARM(extended,"1i");int pelican=0;MODULE_PARM(pelican,"1i");int baudrate=0;MODULE_PARM(baudrate,"1i");char *hw[MAX_HW_CARDS]={NULL,};MODULE_PARM(hw, "1-" __MODULE_STRING(MAX_HW_CARDS)"s");int irq[MAX_IRQ]={-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1};MODULE_PARM(irq, "1-" __MODULE_STRING(MAX_IRQ)"i");unsigned long io[MAX_HW_CARDS]={-1,-1,-1,-1,-1,-1,-1,-1};MODULE_PARM(io, "1-" __MODULE_STRING(MAX_HW_CARDS)"i");int stdmask=0;MODULE_PARM(stdmask, "1i");int extmask=0;MODULE_PARM(extmask, "1i");int mo15mask=0;MODULE_PARM(mo15mask, "1i");/* Global structures, used to describe the installed hardware. */struct canhardware_t canhardware;struct canhardware_t *hardware_p=&canhardware;struct candevice_t *candevices_p[MAX_HW_CARDS];struct chip_t *chips_p[MAX_TOT_CHIPS];struct msgobj_t *objects_p[MAX_TOT_MSGOBJS];/* Pointers to dynamically allocated memory are maintained in a linked list * to ease memory deallocation. */struct mem_addr *mem_head=NULL;#if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19))struct file_operations can_fops={	NULL,				/* llseek */	read:		can_read,	write:		can_write,	NULL,				/* readdir */	NULL, 				/* poll */	ioctl:		can_ioctl,	NULL,				/* mmap */	open:		can_open,	NULL,				/* flush */	release:	can_close,	NULL,				/* fsync */}; #else struct file_operations can_fops={	owner:		THIS_MODULE,		read:		can_read,	write:		can_write,	ioctl:		can_ioctl,	open:		can_open,	release:	can_close,};#endifEXPORT_SYMBOL(can_fops);int init_module(void){	int res=0,i=0;	if (parse_mod_parms())		return -EINVAL;	if (init_hw_struct())		return -ENODEV;	#ifdef CAN_DEBUG		list_hw();	#endif	res=register_chrdev(major,DEVICE_NAME, &can_fops);	if (res<0) {		CANMSG("Error registering driver.\n");		return -ENODEV;	}	for (i=0; i<hardware_p->nr_boards; i++) {		if (candevices_p[i]->hwspecops->request_io(candevices_p[i]->io_addr)) 		goto memory_error;	}	for (i=0; i<hardware_p->nr_boards; i++) {		if (candevices_p[i]->hwspecops->reset(i)) 			goto reset_error;	}	i=0;	while ( (chips_p[i] != NULL) && (i < MAX_TOT_CHIPS) ) {		if (!strcmp(chips_p[i]->chip_type,"i82527")) {			if (request_irq(chips_p[i]->chip_irq,i82527_irq_handler,SA_SHIRQ,DEVICE_NAME,chips_p[i]))  				goto interrupt_error;			else				DEBUGMSG("Registered interrupt %d\n",chips_p[i]->chip_irq);		}		if (!strcmp(chips_p[i]->chip_type,"sja1000p") ||  				!strcmp(chips_p[i]->chip_type,"sja1000")) {			if (request_irq(chips_p[i]->chip_irq,	chips_p[i]->chipspecops->irq_handler,SA_SHIRQ,DEVICE_NAME,chips_p[i]))				goto interrupt_error;			else				DEBUGMSG("Registered interrupt %d\n",chips_p[i]->chip_irq);		}		i++;	}	for (i=0; i<hardware_p->nr_boards; i++) {		if (candevices_p[i]->flags & PROGRAMMABLE_IRQ)			if (candevices_p[i]->hwspecops->program_irq(i))				goto interrupt_error;	}	spin_lock_init(&hardware_p->rtr_lock);	hardware_p->rtr_queue=NULL;#ifdef CONFIG_PROC_FS	if (can_init_procdir())		goto proc_error;#endif	return 0;#ifdef CONFIG_PROC_FS	proc_error: ;		CANMSG("Error registering /proc entry.\n");		goto memory_error; #endif	interrupt_error: ;		CANMSG("Error registering interrupt line.\n");		goto memory_error;	reset_error: ;		goto memory_error;	memory_error: ;		for (i=0; i<hardware_p->nr_boards; i++)			candevices_p[i]->hwspecops->release_io(candevices_p[i]->io_addr);		goto register_error;	register_error: ;		res=unregister_chrdev(major,DEVICE_NAME);		if (res<0)			CANMSG("Error unloading CAN driver, error: %d\n",res);		else			CANMSG("Successfully unloaded CAN driver.\n");		return -ENODEV;}void cleanup_module(void){	int res=0,i=0;#ifdef CONFIG_PROC_FS	if (can_delete_procdir())		CANMSG("Error unregistering /proc/can entry.\n"); #endif	while ( (chips_p[i] != NULL) & (i < MAX_TOT_CHIPS) ) {		free_irq(chips_p[i]->chip_irq, chips_p[i]);		i++;	}	for (i=0; i<hardware_p->nr_boards; i++) 		candevices_p[i]->hwspecops->release_io(candevices_p[i]->io_addr);	if ( del_mem_list() ) 		CANMSG("Error deallocating memory\n");	res=unregister_chrdev(major,DEVICE_NAME);	if (res<0)		CANMSG("Error unregistering CAN driver, error: %d\n",res);}

⌨️ 快捷键说明

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