www.pudn.com > 422.rar > main.c
/* main.c * Linux serial-bus device driver. * Written by wang song yue--bupt email:wsy5228@sina.com * This software is released under the GPL-License. * Version 0.1 28 october 2005 */ #define EXPORT_SYMTAB #include#if defined (CONFIG_MODVERSIONS) && !defined (MODVERSIONS) #define MODVERSIONS #endif #include #if defined (MODVERSIONS) #include #endif #include #include #include #include #include #include #if (LINUX_VERSION_CODE <= KERNEL_VERSION(2,2,19)) #include #else #include #endif #if !defined (__GENKSYMS__) #if (defined (MODVERSIONS) && !defined(NOVER)) #include #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=TTS_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]={"aim104","aim104","aim104","aim104",NULL}; MODULE_PARM(hw, "1-" __MODULE_STRING(MAX_HW_CARDS)"s"); int irq[MAX_IRQ]={59,59,59,59,-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]={0xffd00000,0xffd00008,0xffd00010,0xffd00018,-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: serial_read, write: serial_write, NULL, /* readdir */ NULL, /* poll */ ioctl: serial_ioctl, NULL, /* mmap */ open: serial_open, NULL, /* flush */ release: serial_close, NULL, /* fsync */ }; #else struct file_operations can_fops= { owner: THIS_MODULE, read: serial_read, write: serial_write, ioctl: serial_ioctl, open: serial_open, release: serial_close, }; #endif EXPORT_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 while(hw[i]!=NULL) { res=register_chrdev(major,DEVICE_NAME, &can_fops); if (res<0) { CANMSG("Error registering driver.\n"); return -ENODEV; } i++; } for (i=0; i nr_boards; i++) { // printk("i===%d\n",i); // printk("io_addr===========0x%lx\n",candevices_p[i]->io_addr); if (candevices_p[i]->hwspecops->request_io(candevices_p[i]->io_addr)) goto memory_error; } for (i=0; i nr_boards; i++) { if (candevices_p[i]->hwspecops->reset(i)) goto reset_error; } //printk("main reset(i) 1111111111\n"); i=0; while ( (chips_p[i] != NULL) && (i < MAX_TOT_CHIPS) ) { if (!strcmp(chips_p[i]->chip_type,"16c554")) { 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 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 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 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 TTS driver, error: %d\n",res); }