⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mcc.c

📁 powerpc82xx mcc driver
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * 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 + -