📄 mcc.c
字号:
#ifdef MCC_DEBUG printk("MCC:Init interrupt queue done\n");#endif /* memory allocation for read buffer */ ReadBuffer = (FrameBuffer *) kmalloc ( sizeof(FrameBuffer)*NUMBER_OF_CHANNELS, GFP_KERNEL); if (ReadBuffer == NULL) return -ENOMEM; /* memory allocation for read buffer */ WriteBuffer = (FrameBuffer *) kmalloc ( sizeof(FrameBuffer)*NUMBER_OF_CHANNELS, GFP_KERNEL); if (WriteBuffer == NULL) return -ENOMEM; #ifdef MCC_DEBUG printk("MCC:Data WriteBuffer pointer= %xH\n" ,(unsigned int )WriteBuffer); printk("MCC:Data ReadBuffer pointer= %xH\n" ,(unsigned int )ReadBuffer);#endif /* main MCC and SI init */ mainInitMCC( (unsigned int ) immap);#ifdef MCC_DEBUG printk("MCC:MCC and SI RAM configurated\n");#endif /* Regist del driver */ mcc_result = register_chrdev(mcc_major, "mcc", &mcc_fops); if ( mcc_result < 0 ) { printk(KERN_INFO "MCC:Can't get major %d.\n", mcc_major); kfree(BufferPool); return mcc_result; } if ( mcc_major == 0) mcc_major = mcc_result; // register mcc interrupt if (request_8xxirq(MCC_IRQ,mcc_ISR,0,"mcc",NULL)) { printk("MCC: Could not register interrupt %d.\n", MCC_IRQ); return -EBUSY; } /* startup TDM */ startTxRx(); printk("MCC:driver loaded\n"); return 0; }/* * Name: * mcc_open * Description: * open system call * */int mcc_open(struct inode *inode,struct file *filp){ if(MINOR(inode->i_rdev)>=NUMBER_OF_CHANNELS) return -ENODEV;#ifdef SINGLE_USER if(MOD_IN_USE) return -EBUSY;#endif MOD_INC_USE_COUNT; readNow[MINOR(inode->i_rdev)] = 0; writeNow[MINOR(inode->i_rdev)] = 0; valid[MINOR(inode->i_rdev)] = 0; return 0;}/* mcc_open *//* * Name: * mcc_release * Description: * close system call * */#ifdef LINUX_20void mcc_release(struct inode *inode,struct file *filp){ MOD_DEC_USE_COUNT; mcc_fasync(-1, filp, 0); readNow[MINOR(inode->i_rdev)] = 0; writeNow[MINOR(inode->i_rdev)] = 0; valid[MINOR(inode->i_rdev)] = 0; return;}#elseint mcc_release(struct inode *inode,struct file *filp){ MOD_DEC_USE_COUNT; mcc_fasync(-1, filp, 0); readNow[MINOR(inode->i_rdev)] = 0; writeNow[MINOR(inode->i_rdev)] = 0; valid[MINOR(inode->i_rdev)] = 0; return 0;}#endif#ifdef LINUX_20int mcc_read(struct inode *inode,struct file *filp,char *buf,int count){ return do_mcc_read(inode,filp,buf,count,&filp->f_pos);}#elsessize_t mcc_read(struct file *filp,char *buf,size_t count,loff_t *f_pos){ return do_mcc_read(filp->f_dentry->d_inode,filp,buf,count,f_pos);}#endif/* * Name: * do_mcc_read * Description: * char driver read function * */ssize_t do_mcc_read(struct inode *inode,struct file *filp,char *buffer,size_t size,loff_t *f_pos) { int count = 0; int device = MINOR(inode->i_rdev); FrameBuffer *read = (FrameBuffer *) ( (unsigned int ) ReadBuffer + (sizeof(FrameBuffer))*device); if(readNow[device] == 1){ for(count = 0; count < BUFFER_SIZE; count++){ put_user(read->data[count], buffer++); } readNow[device] = 0; return BUFFER_SIZE; } return 0;} /* do_mcc_read */#ifdef LINUX_20int mcc_write(struct inode *inode,struct file *filp,const char *buf,int count){ return do_mcc_write(inode,filp,buf,count,&filp->f_pos);}#elsessize_t mcc_write(struct file *filp,const char *buf,size_t count,loff_t *f_pos){ return do_mcc_write(filp->f_dentry->d_inode,filp,buf,count,f_pos);}#endif/* * Name: * do_mcc_write * Description: * char driver write function * */ssize_t do_mcc_write(struct inode *inode,struct file *filp,const char *buf,size_t size,loff_t *f_pos) { int device = MINOR(inode->i_rdev); int count = 0; FrameBuffer *write = (FrameBuffer *) ( (unsigned int ) WriteBuffer + (sizeof(FrameBuffer))*device);#ifdef MCC_WRITE unsigned int *BoardIO = ioremap(0xF1000000,0x32); *BoardIO =~( 0x20000000) & reg0data; *BoardIO = 0x20000000 | reg0data;#endif if ( writeNow[device] == 0){ return 0; } while (count < BUFFER_SIZE) { get_user(write->data[count] ,buf++); count++; } valid[device] = 1; writeNow[device] = 0; return BUFFER_SIZE;}/*end of do_mcc_write *//* * Name: * mcc_ioctl * Description: * char driver ioctl function * */int mcc_ioctl(struct inode *inode,struct file *filp,unsigned int cmd,unsigned long arg){ int err=0; if(_IOC_TYPE(cmd)!=MCC_IOC_MAGIC) return -ENOTTY; if(_IOC_NR(cmd)>MCC_IOC_MAXNR) return -ENOTTY;#ifdef LINUX_20 if(_IOC_DIR(cmd)&_IOC_READ) err=verify_area(VERIFY_WRITE,(void *)arg,_IOC_SIZE(cmd)); else if(_IOC_DIR(cmd)&_IOC_WRITE) err=verify_area(VERIFY_READ,(void *)arg,_IOC_SIZE(cmd)); if(err) return err;#else if(_IOC_DIR(cmd)&_IOC_READ) err=!access_ok(VERIFY_WRITE,(void *)arg,_IOC_SIZE(cmd)); else if(_IOC_DIR(cmd)&_IOC_WRITE) err=!access_ok(VERIFY_READ,(void *)arg,_IOC_SIZE(cmd)); if(err) return -EFAULT;#endif switch(cmd) { case MCC_IOC_TXBDS: { BDS_IOC *TxBdsIOCTL; TxBdsIOCTL = (BDS_IOC *) arg; BDsStatus(TX,NUM_TXBDS*TxBdsIOCTL->chn,&TxBdsIOCTL->bd_cstatus[0],&TxBdsIOCTL->bd_length[0],&TxBdsIOCTL->bd_addr[0]); } break; case MCC_IOC_RXBDS: { BDS_IOC *RxBdsIOCTL; RxBdsIOCTL = (BDS_IOC *) arg; BDsStatus(RX,NUM_RXBDS*RxBdsIOCTL->chn,&RxBdsIOCTL->bd_cstatus[0],&RxBdsIOCTL->bd_length[0],&RxBdsIOCTL->bd_addr[0]); } break; case SIXRAM_IOC_REGS: { SI_REGS_IOC *SiRegsIOCTL; SiRegsIOCTL = (SI_REGS_IOC *) arg; SiRamStatus(SiRegsIOCTL->chn,&SiRegsIOCTL->sigmr,&SiRegsIOCTL->sicmdr,&SiRegsIOCTL->sistr, &SiRegsIOCTL->sirsr,&SiRegsIOCTL->mcce,&SiRegsIOCTL->mccm,&SiRegsIOCTL->mccr, &SiRegsIOCTL->sixmr,&SiRegsIOCTL->tx_siram,&SiRegsIOCTL->rx_siram); } break; case CPM_IOC_REGS: { CPM_STATUS_IOC *CpmStatusRegisterIOCTL; CpmStatusRegisterIOCTL=(CPM_STATUS_IOC *) arg; CpmReadRegisters(CpmStatusRegisterIOCTL); } break; case TXRX_IOC_BUFF: { unsigned char offset; unsigned char index; unsigned char *txBuffer; unsigned char *rxBuffer; int count = 0; TXRX_BUFF_IOC *TxRxBufferIOCTL; TxRxBufferIOCTL=(TXRX_BUFF_IOC *) arg; offset = TxRxBufferIOCTL->offset; index = TxRxBufferIOCTL->index; rxBuffer = (unsigned char * )BufferPool + BUFFER_SIZE*NUMBER_OF_CHANNELS*NUM_TXBDS + (offset+index)*BUFFER_SIZE; txBuffer = (unsigned char * ) BufferPool+(offset+index)*BUFFER_SIZE; for(count = 0; count < BUFFER_SIZE; count++){ put_user(txBuffer[count],&TxRxBufferIOCTL->TxBuff[count]); put_user(rxBuffer[count],&TxRxBufferIOCTL->RxBuff[count]); } } break; case MCC_FASYNC_IOC_DEAMON: { fasyncActive = TRUE; } break; case MCC_RESTART_CMD: { RestartServiceRoutine(); } break; default: return -ENOTTY; } return err;} /* mcc_ioctl *//* * Name: * mccFasync * Description: * call MCC fasync method from interrupt hadler. */void mccFasync(void){ if((async_queue) && (fasyncActive == TRUE) ){ kill_fasync(&async_queue,SIGIO,POLL_IN); } }/* * Name: * mcc_fasync * Description: * MCC fasync method */int mcc_fasync(fasync_file fd,struct file *filp,int mode){ return fasync_helper(fd,filp,mode,&async_queue);}/* * Name: * mcc_ISR * Description: * MCC Interrupt handler * void mcc_ISR(int irq, void *dev_id, struct pt_regs *regs) { do_mcc_ISR(); }*//* * linux interface * */module_init(mcc_init);module_exit(mcc_cleanup);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -