📄 mcc.c
字号:
/* * mcc.c - mcc linux device driver * * (C) Copyright 2002 * Gianfranco Morandi, Eurostudio s.r.l., gianfranco.morandi@euro-studio.it * See file CREDITS for list of people who contributed to this * project. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2 of * the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA * * configurated for 64 chns 64..95 to TDM1C and 96..127 to TDM1D * clock routing and I/O routing supposed done in fec001a_setup.c. * Only 60x bus transations are configurated. * Trasmission interrupt not allowed, rx interrupt routed on RXINT0 queue only for * 32nd chn (on TDM1C). * * Tx scheme sends WriteBuffer data if it is valid or notone byte, 0xD5 (0x7E for 1st chn), instead * Rx fills ReadBuffer every RxBD recieved. Handshaking is done with writeNow, redNow and valid global * variables. * writeNow = 1 : WriteBuffer trasferred by cpm * readNow = 1 : ReadBuffer filled by cpm * valid = 1 : WriteBuffder is valid * * * WriteBuffer, ReadBuffer : buffer for read & write system call. * RxTxBDs : Rx and Tx BDs ring. NUM_TXBDS Tx BD and NUM_RXBDS RxBD for chn * BufferPool : Tx and Rx MCC buffer * txIntCQ, rxIntCQ : tx and rx interrupt queue. * * ioctl : MCC_IOC_TXBDS reads and returns TxBDs status * : MCC_IOC_RXBDS reads and returns RxBDs status * : SIXRAM_IOC_REGS reads and returns SI register and ram entries * : TXRX_IOC_BUFF reads and return Tx and Rx MCC buffer * : MCC_FASYNC_IOC_DEAMON allow fasync notification * * Rev 1.00 - 20/09/2002 * Rev 1.01 - 29/10/2002 : add ioctl command. * Rev 1.02 - 30/10/2002 : non static definition of the function getFrame,sendFrame,restoreBDs. * Rev 1.03 - 04/11/2002 : irq handler locked with spin_lock_irq _irq macro. * Rev 1.04 - 05/11/2002 : new versions of mcc_ISR, getFrame, sendFrame and restoreBDs functions. * Rev 1.05 - 06/11/2002 : all MCC interrupt abled to discover FIFO's underun exception * Rev 1.06 - 11/11/2002 : fsync notification during underrun interrupt error * * */#ifndef __KERNEL__# define __KERNEL__#endif#ifndef MODULE# define MODULE#endif#define MCC_DEBUG#undef MCC_DEBUG#define MCC_WRITE#undef MCC_WRITE#include <linux/param.h>#include <asm/system.h>#include <linux/config.h>#include <linux/module.h>#include <linux/sched.h>#include <linux/wait.h>//#include <linux/types.h>#include <linux/kernel.h>#include <linux/fs.h>#include <linux/errno.h>#include <linux/delay.h>#include <linux/malloc.h>#include <linux/mm.h>#include <linux/ioport.h>#include <linux/interrupt.h>#include <linux/tqueue.h>#include <linux/ioctl.h>#include <asm/irq.h>#include <asm/io.h>#include <asm/semaphore.h>#include <asm/immap_8260.h>#include <asm/pgtable.h>#include <asm/mpc8260.h>#include <asm/bitops.h>#include <asm/uaccess.h>#include <asm/cpm_8260.h>#include "mcc.h"#include "sysdep.h"#include "mccIOC.h"#include "device.h"/*------------------------------------------------------------------------------- * Defines *-------------------------------------------------------------------------------- */#define NUM(dev) (MINOR(dev) & 0xf)#define min(A, B) ((A<B)?A:B)#define MCC_IRQ SIU_INT_MCC1#define MCC_MAJOR 0 /* 40 *//*------------------------------------------------------------------------------- * Module parameters *-------------------------------------------------------------------------------- */static int mcc_major = MCC_MAJOR;/* major number*///MODULE_PARM(mcc_major,"i");MODULE_AUTHOR ("Eurostudio");/*--------------------------------------------------------------------------------- * Function prototypes *--------------------------------------------------------------------------------- */#ifdef LINUX_20int mcc_read(struct inode *,struct file *,char *,int);#elsessize_t mcc_read(struct file *,char *,size_t,loff_t *);#endifssize_t do_mcc_read(struct inode *,struct file *,char *,size_t,loff_t *);#ifdef LINUX_20int mcc_write(struct inode *,struct file *,char *,int );#elsessize_t mcc_write(struct file *,const char *,size_t,loff_t *);#endifssize_t do_mcc_write(struct inode *,struct file *,const char *,size_t,loff_t *);int mcc_ioctl(struct inode *,struct file *,unsigned int ,unsigned long );int mcc_open(struct inode *,struct file *);#ifdef LINUX_20void mcc_release(struct inode *,struct file *);#elseint mcc_release(struct inode *,struct file *);#endifint mcc_fasync(fasync_file ,struct file *,int );void mccFasync(void);/*--------------------------------------------------------------------------------- * Global variables *--------------------------------------------------------------------------------- *//* read & write Handshaking */int writeNow[BUFFER_SIZE];int valid[BUFFER_SIZE];int readNow[BUFFER_SIZE];/* IO register external status variable ### */extern unsigned int reg0data; /* read and write data buffer */FrameBuffer *ReadBuffer, *WriteBuffer;static struct file_operations mcc_fops= { read: mcc_read, write: mcc_write, ioctl: mcc_ioctl, open: mcc_open, release: mcc_release, fasync: mcc_fasync, };volatile immap_t *immap;/* TxRx data buffer */unsigned char *BufferPool;struct fasync_struct *async_queue;/* buffer descriptors base pointer */BDRINGS *RxTxBD;/* TxRx interrupt queue */unsigned int *txIntCQ;unsigned int *rxIntCQ;/* spin lock */spinlock_t lock;/* fasync notification */int fasyncActive = FALSE;/*--------------------------------------------------------------------------------- * Function *--------------------------------------------------------------------------------- *//* * Name: * mcc_cleanup * Description: * unload mcc driver */void mcc_cleanup (void){ stopTxRx(); free_irq( MCC_IRQ,NULL); kfree(BufferPool); kfree(RxTxBD); kfree(txIntCQ); kfree(rxIntCQ); kfree(WriteBuffer); kfree(ReadBuffer); unregister_chrdev(mcc_major,"mcc");}/* * Name : * mcc_init * Input Parameter: * None * Description: * load the driver */ int mcc_init(void){ int mcc_result = 0;#ifdef MCC_DEBUG unsigned int *BoardIO = ioremap(0xF1000000,0x32);#endif int i; /* pointer to internal register */ immap = (immap_t *)IMAP_ADDR;#ifdef MCC_DEBUG *BoardIO = 0x30000000 | reg0data; reg0data |= 0x30000000;#endif /* memory allocation for TxRx BD data buffer */ BufferPool = (unsigned char *) kmalloc ((sizeof(unsigned char )*NUMBER_OF_CHANNELS*(NUM_RXBDS+NUM_TXBDS )*BUFFER_SIZE),GFP_KERNEL); if (BufferPool == NULL) return -ENOMEM; for(i=0; i < BUFFER_SIZE; i++){ readNow[i] = 0; writeNow[i] = 0; valid[i] = 1; } /* spin lock declaration */ spin_lock_init(&lock); #ifdef MCC_DEBUG printk("MCC:Data Buffer at %xH\n",(unsigned int )BufferPool);#endif /* clear buffer */ memset(BufferPool, NULL_PATTERN, NUMBER_OF_CHANNELS*(NUM_RXBDS+NUM_TXBDS )*BUFFER_SIZE); memset(BufferPool, SILENCE_PATTERN, NUMBER_OF_CHANNELS*NUM_TXBDS*BUFFER_SIZE);#ifdef MCC_DEBUG memset(BufferPool, SYNC_PATTERN, NUM_TXBDS*BUFFER_SIZE); /* fixed pattern for 1st channel */#endif #ifdef MCC_DEBUG printk("MCC:Data Buffer cleared\n");#endif /* memory allocation for TxRxBDs*/ RxTxBD = (BDRINGS *) kmalloc ((sizeof(BDRINGS )),GFP_KERNEL); if (RxTxBD == NULL) return -ENOMEM; #ifdef MCC_DEBUG printk("RxTxBD = %xH\n",(unsigned int ) RxTxBD); printk("MCC:BDs memory allocated.. %xH bytes\n",sizeof(BDRINGS));#endif /* memory allocation for txIntCQ */ txIntCQ = (unsigned int *) kmalloc ((sizeof(unsigned int )*NUM_CHN_INT*NUM_TXBDS),GFP_KERNEL); if (txIntCQ == NULL) return -ENOMEM; /* memory allocation for rxIntCQ */ rxIntCQ = (unsigned int *) kmalloc ((sizeof(unsigned int )*NUM_CHN_INT*NUM_RXBDS),GFP_KERNEL); if (rxIntCQ == NULL) return -ENOMEM; /* txIntCQ and rxIntCQ initialization */ memset((unsigned char *)txIntCQ, 0,NUM_CHN_INT*NUM_TXBDS*4); /* clear interrupt queue areas */ memset((unsigned char *)rxIntCQ, 0,NUM_CHN_INT*NUM_RXBDS*4); *((unsigned int *)txIntCQ + NUM_CHN_INT*NUM_TXBDS - 1) = 0x40000000; /* set wrap bit at end of TX intcq */ *((unsigned int *)rxIntCQ + NUM_CHN_INT*NUM_RXBDS - 1) = 0x40000000; /* set wrap bit at end of RX intcq */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -