📄 arbracan.c
字号:
if(CAN_TX_BUFF_FREE(bus_nb)){ /* && CAN_TX_FREE(bus_nb)*/ if(!Get_From_x(Tx, bus_nb, &m)){ CAN_PUT(bus_nb, &m); Wake_Up(bus_nb, Tx); } } Bus_Unlock(bus_nb, Tx); MSGK("Fin Update_Board_Tx(%d)\n",bus_nb); }}//// The read function (non blocking)//static int canboard_read(int bus_nb, Message *m){ MSGK("CANBOARD_READ (%d)\n",bus_nb); Update_Board_Rx(bus_nb); if(Get_From_x_Lock(Rx, bus_nb, m)){ return -EFAULT; // No more seat left } return 0;}//// The read function (blocking)//static int canboard_read_block(int bus_nb, Message *m){ MSGK("CANBOARD_READ_BLOCK (%d)\n",bus_nb); // Warning loop undefinitely when it can not get lock while(Get_From_x_Lock(Rx, bus_nb, m)){ MSGK("CANBOARD_READ_BLOCK (%d) -- dodo\n",bus_nb); Wait_For_Event(bus_nb, Rx, Message_Pending(Rx, bus_nb)); MSGK("CANBOARD_READ_BLOCK (%d) -- reveil\n",bus_nb); if(Caught_Signal) return -EFAULT; Update_Board_Rx(bus_nb); } return 0;}//// The write function (non blocking)//static int canboard_write(int bus_nb, Message *m){ MSGK("CANBOARD_WRITE (%d)\n",bus_nb); if(Put_In_x_Lock(Tx, bus_nb, m) < 0){ return -EFAULT; } Update_Board_Tx(bus_nb); return 0;}//// The write function (blocking)//static int canboard_write_block(int bus_nb, Message *m){ int place; int prio; MSGK("CANBOARD_WRITE_BLOCK (%d)\n",bus_nb); prio = GET_PRIO(*m); while(((place = Put_In_x_Lock(Tx, bus_nb, m)) <0)){ MSGK("CANBOARD_WRITE_BLOCK (%d) -- dodo\n",bus_nb); // block if no seat left in FIFO Wait_For_Event(bus_nb, Tx, Seat_Left_In_x(Tx, bus_nb, prio)); MSGK("CANBOARD_WRITE_BLOCK (%d) -- reveil\n",bus_nb); if(Caught_Signal) return -EFAULT; Update_Board_Tx(bus_nb); } Update_Board_Tx(bus_nb); // block while not send MSGK("CANBOARD_WRITE_BLOCK (%d) -- dodo (wait to be sent)\n", bus_nb); Wait_For_Event(bus_nb, Tx, Is_Out_Of_x(Tx, bus_nb, prio, place)); MSGK("CANBOARD_WRITE_BLOCK (%d) -- reveil\n",bus_nb); return 0;}//// The status function// (if someone want to use it...)//static int canboard_status(int bus_nb){ return CAN_STATUS(bus_nb);}//// The open function//static int canboard_open(int bus_nb){ MSGK("canboard_open\n"); /* increment usage count */ MOD_INC_USE_COUNT; if((1 << bus_nb) & can_silent){ CAN_INIT_SILENT(bus_nb, can_rate); } else { CAN_INIT(bus_nb, can_rate); } return 0;}//// The close function//static int canboard_close(int bus_nb){ MSGK("canboard_close\n"); MOD_DEC_USE_COUNT; openner[bus_nb]=NOT_OPENED; CAN_UNINIT(bus_nb); return 0;}//// Linux POSIX registered functions//// IOCTLstatic int canboard_ioctl_linux(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg){ int bus_nb = MINOR(inode->i_rdev); Message m; if(bus_nb >= CAN_BUS_COUNT) return -ENOTTY; /* make sure that the command is really one of canboard's */ if (_IOC_TYPE(cmd) != CANBOARD_IOCTL_BASE) return -ENOTTY; switch (cmd) { case CANBOARD_READ_BLOCK: { int res = canboard_read_block(bus_nb, &m); copy_to_user((void*) arg, &m, sizeof(Message)); return res; } case CANBOARD_READ: { int res = canboard_read(bus_nb, &m); copy_to_user((void*) arg, &m, sizeof(Message)); return res; } case CANBOARD_WRITE_BLOCK: { copy_from_user(&m,(void *)arg, sizeof(Message)); m.cob_id.w &= 0x07ff; //Filter for crazy users return canboard_write_block(bus_nb, &m); } case CANBOARD_WRITE: { copy_from_user(&m,(void *)arg, sizeof(Message)); m.cob_id.w &= 0x07ff; //Filter for crazy users return canboard_write(bus_nb, &m); } case CANBOARD_STATUS: { int status = canboard_status(bus_nb); put_user((void *)arg, &status); return 0; } default: { return -ENOTTY; } } /* to keep gcc happy */ return 0;}// OPENstatic int canboard_open_linux(struct inode *inode, struct file *file){ int bus_nb = MINOR(inode->i_rdev); // Because of the new syntax of kernel // we have to declare an init a wait queue. // and copy it to our wait table. if(openner[bus_nb]==NOT_OPENED) { init_waitqueue_head(&can_wq[bus_nb][Rx].l); init_waitqueue_head(&can_wq[bus_nb][Tx].l); openner[bus_nb]=OPENED_USER; return canboard_open(bus_nb); } return -EFAULT;}// CLOSEstatic int canboard_close_linux(struct inode *inode, struct file *file){ int bus_nb = MINOR(inode->i_rdev); return canboard_close(bus_nb);}// FOPS struct for registrationstatic struct file_operations canboard_fops = { ioctl: canboard_ioctl_linux, open: canboard_open_linux, release: canboard_close_linux};#ifdef __RTL__ /* Rtlinux version of the driver*///// RTLinux POSIX registered functions//// IOCTLstatic int canboard_ioctl_rtl(struct rtl_file *rtfile, unsigned int cmd, unsigned long arg){ int bus_nb = rtfile->f_minor; Message m; if(bus_nb >= CAN_BUS_COUNT) return -ENOTTY; /* make sure that the command is really one of canboard's */ if (_IOC_TYPE(cmd) != CANBOARD_IOCTL_BASE) return -ENOTTY; switch (cmd) { case CANBOARD_READ_BLOCK: { int res = canboard_read_block(bus_nb, &m); memcpy((void*) arg, &m, sizeof(Message)); return res; } case CANBOARD_READ: { int res = canboard_read(bus_nb, &m); memcpy((void*) arg, &m, sizeof(Message)); return res; } case CANBOARD_WRITE_BLOCK: { memcpy(&m,(void *)arg, sizeof(Message)); m.cob_id.w &= 0x07ff; //Filter for crazy users return canboard_write_block(bus_nb, &m); } case CANBOARD_WRITE: { memcpy(&m,(void *)arg, sizeof(Message)); m.cob_id.w &= 0x07ff; //Filter for crazy users return canboard_write(bus_nb, &m); } case CANBOARD_STATUS: { int status = canboard_status(bus_nb); (int)arg = status; return 0; } default: { return -ENOTTY; } } /* to keep gcc happy */ return 0;}// OPENstatic int canboard_open_rtl(struct rtl_file *rtfile){ int bus_nb = rtfile->f_minor; if(openner[bus_nb]==NOT_OPENED) { rtl_wait_init(&can_wq[bus_nb][Rx].rt); rtl_wait_init(&can_wq[bus_nb][Tx].rt); openner[bus_nb] = OPENED_RTL; return canboard_open(bus_nb); } return -EFAULT;}// CLOSEstatic int canboard_close_rtl(struct rtl_file *rtfile){ int bus_nb = rtfile->f_minor; return canboard_close(bus_nb);}// FOPS struct for registrationstruct rtl_file_operations canboard_rtl_fops = { ioctl: canboard_ioctl_rtl, open: canboard_open_rtl, release: canboard_close_rtl};#endif//// The IRQ Handler//#ifdef __RTL__void canboard_interrupt(int sig)#elsestatic void canboard_interrupt(int irq, void *dev_id, struct pt_regs *regs)#endif{ int bus_nb; char it; for(bus_nb=0;bus_nb<CAN_BUS_COUNT;bus_nb++){ it = CAN_IR(bus_nb); if(openner[bus_nb]!=NOT_OPENED){ MSGK("Entering interrupt for (%d)\n", bus_nb); MSGK("(%d)IR: %x\n", bus_nb,it); if(it & RECEIVE_IT) Update_Board_Rx(bus_nb); if(it & TRANSMIT_IT) Update_Board_Tx(bus_nb); MSGK("Exiting interrupt\n"); } } OS_enable_irq(can_irq); #ifdef __RTL__ pthread_kill(pthread_linux(), RTL_LINUX_MIN_SIGNAL+can_irq); #endif}//// Module Initialisation//#undef Debug_Cond#define Debug_Cond (can_debug != 0)int init_module(void){ int res; struct pci_dev *dev=NULL; if((dev=pci_find_device(CAN_PCI_VENDOR_ID, CAN_PCI_DEVICE_ID, dev))) { MSGK("Carte trouv閑\n"); MSGK("Name : %s\n", dev->name); MSGK("Slot_Name : %s\n", dev->slot_name); MSGK("IRQ : %d\n", dev->irq); // enable I/O area if not enabled#if LINUX_VERSION_CODE > KERNEL_VERSION(2,3,13) if((res=pci_enable_device(dev))) { MSGK("Couldn't enable pci dev"); return res; }#else { short tmp; pci_read_config_word(dev,PCI_COMMAND,&tmp); if (tmp & PCI_COMMAND_IO) { tmp |= PCI_COMMAND_IO; pci_write_config_word(dev,PCI_COMMAND,tmp); } }#endif if((res = CAN_BOARD_INIT(dev))) return res; } else { MSGK("No can card found !\n"); return -ENODEV; } /* If no name have been given set it to default */ if (canboard_name == NULL) canboard_name = "can"; /* Get the IRQ */ can_irq = dev->irq; /* Check parameters in request_irq for shared IRQ*/ /* in case of linux-only driver */ if(can_irq == 0 || OS_request_irq(can_irq, &canboard_interrupt, SA_INTERRUPT | SA_SHIRQ, canboard_name, &can_irq)){//we use pointer to can_irq as a cookie MSGK("Bad IRQ (%d)\n", can_irq); CAN_BOARD_CLOSE(); return -EFAULT; } /* register device with kernel */#ifdef __RTL__ if ((res=rtl_register_chrdev(SCHAR_MAJOR, canboard_name, &canboard_rtl_fops))) { MSGK("can't register device with kernel\n"); CAN_BOARD_CLOSE(); return res; }#endif if ((res=register_chrdev(SCHAR_MAJOR, canboard_name, &canboard_fops))) { MSGK("can't register device with kernel\n"); CAN_BOARD_CLOSE(); return res; } MSGK("module loaded\n"); return 0;}//// Module Cleanup//void cleanup_module(void) { unregister_chrdev(SCHAR_MAJOR,canboard_name);#ifdef __RTL__ rtl_unregister_chrdev(SCHAR_MAJOR,canboard_name);#endif OS_free_irq(can_irq,&can_irq); //we use pointer to can_irq as a cookie CAN_BOARD_CLOSE(); MSGK("CAN driver unloaded\n"); return;}#undef Debug_Cond#undef ArbraCan_C
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -