📄 main.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 + -