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

📄 ca91c042.c

📁 linux下vme总线驱动代码
💻 C
📖 第 1 页 / 共 3 页
字号:
//------------------------------------------------------------------------------  //title: Tundra Universe PCI-VME Kernel Driver//version: Linux 1.1//date: March 1999                                                                //designer: Michael Wyrick                                                      //programmer: Michael Wyrick                                                    //platform: Linux 2.4.x//language: GCC 2.95 and 3.0//module: ca91c042//------------------------------------------------------------------------------  //  Purpose: Provide a Kernel Driver to Linux for the Universe I and II //           Universe model number ca91c042//  Docs:                                  //    This driver supports both the Universe and Universe II chips                                     //------------------------------------------------------------------------------  // RCS:// $Id: ca91c042.c,v 1.5 2001/10/27 03:50:07 jhuggins Exp $// $Log: ca91c042.c,v $// Revision 1.5  2001/10/27 03:50:07  jhuggins// These changes add support for the extra images offered by the Universe II.// CVS : ----------------------------------------------------------------------//// Revision 1.6  2001/10/16 15:16:53  wyrick// Minor Cleanup of Comments//////-----------------------------------------------------------------------------#define MODULEstatic char Version[] = "1.2 2001Oct17";#include <linux/config.h>#include <linux/version.h>#ifdef CONFIG_MODVERSIONS  #define MODVERSIONS  #include <linux/modversions.h>#endif#include <linux/module.h>#include <linux/types.h>#include <linux/errno.h>#include <linux/proc_fs.h>#include <linux/pci.h>#include <linux/poll.h>#include <asm/io.h>#include <asm/uaccess.h>#include "ca91c042.h"//----------------------------------------------------------------------------// Prototypes//----------------------------------------------------------------------------static int uni_open(struct inode *, struct file *);static int uni_release(struct inode *, struct file *);static ssize_t uni_read(struct file *,char *, size_t, loff_t *);static ssize_t uni_write(struct file *,const char *, size_t, loff_t *);static unsigned int uni_poll(struct file *, poll_table *);static int uni_ioctl(struct inode *, struct file *, unsigned int, unsigned long);static long long uni_llseek(struct file *,loff_t,int);//static int uni_mmap(struct inode *inode,struct file *file,struct vm_area_struct *vma);//static int uni_select(struct inode *inode,struct file *file,int mode, select_table *table);static int uni_procinfo(char *, char **, off_t, int, int *,void *);//----------------------------------------------------------------------------// Types//----------------------------------------------------------------------------static struct proc_dir_entry *uni_procdir;static struct file_operations uni_fops = {  llseek:   uni_llseek,  read:     uni_read,  write:    uni_write,  poll:     uni_poll,     // uni_poll     ioctl:    uni_ioctl,  open:     uni_open,  release:  uni_release };static int aCTL[] = {LSI0_CTL, LSI1_CTL, LSI2_CTL, LSI3_CTL,                     LSI4_CTL, LSI5_CTL, LSI6_CTL, LSI7_CTL};                     static int aBS[]  = {LSI0_BS,  LSI1_BS,  LSI2_BS,  LSI3_BS,                     LSI4_BS,  LSI5_BS,  LSI6_BS,  LSI7_BS};                      static int aBD[]  = {LSI0_BD,  LSI1_BD,  LSI2_BD,  LSI3_BD,                     LSI4_BD,  LSI5_BD,  LSI6_BD,  LSI7_BD}; static int aTO[]  = {LSI0_TO,  LSI1_TO,  LSI2_TO,  LSI3_TO,                     LSI4_TO,  LSI5_TO,  LSI6_TO,  LSI7_TO}; //----------------------------------------------------------------------------// Vars and Defines//----------------------------------------------------------------------------#define UNI_MAJOR      221#define MAX_MINOR 	    8#define CONTROL_MINOR   8#define MODE_UNDEFINED  0#define MODE_PROGRAMMED 1#define MODE_DMA 	      2#define DMATYPE_SINGLE  1#define DMATYPE_LLIST   2static int OkToWrite[MAX_MINOR + 1];        // Can I write to the Hardwarestatic int opened[MAX_MINOR + 1];static int mode[MAX_MINOR + 1];             // DMA or Programmed I/Ostatic unsigned long DMA[MAX_MINOR + 1];    // DMA Control Regstatic int status;static int DMAType = 0;static int irq = 0;static char *baseaddr  = 0;static char *image_ba[MAX_MINOR+1];         // Base PCI Addressstatic unsigned int image_ptr[MAX_MINOR+1];static unsigned int image_va[MAX_MINOR+1];// Hold the VME Irq Handlersstatic TirqHandler vmeirqs[7] = {NULL,NULL,NULL,NULL,NULL,NULL,NULL};static short vmeirqbit[7]     = {IRQ_VIRQ1, IRQ_VIRQ2, IRQ_VIRQ3, IRQ_VIRQ4,                                 IRQ_VIRQ5, IRQ_VIRQ6, IRQ_VIRQ7};               static int vmevec[7]          = {V1_STATID, V2_STATID, V3_STATID, V4_STATID,                                 V5_STATID, V6_STATID, V7_STATID};// Status Varsstatic unsigned int reads  = 0;static unsigned int writes = 0;static unsigned int ioctls = 0;static TDMAcallback DMACallBackFunc = NULL;static void *debugptr = NULL;// Timersstruct timer_list DMA_timer;                // This is a timer for returning status//----------------------------------------------------------------------------//  uni_procinfo()//----------------------------------------------------------------------------static int uni_procinfo(char *buf, char **start, off_t fpos, int lenght, int *eof, void *data){  char *p;  unsigned int temp1,temp2,x;  p = buf;  p += sprintf(p,"Universe driver %s\n",Version);  p += sprintf(p,"  baseaddr = %08X\n",(int)baseaddr);  p += sprintf(p,"  Stats  reads = %i  writes = %i  ioctls = %i\n",                 reads,writes,ioctls);  for (x=0;x<8;x+=2) {    temp1 = readl(baseaddr+aCTL[x]);    temp2 = readl(baseaddr+aCTL[x+1]);    p += sprintf(p,"  LSI%i_CTL = %08X    LSI%i_CTL = %08X\n",x,temp1,x+1,temp2);    temp1 = readl(baseaddr+aBS[x]);    temp2 = readl(baseaddr+aBS[x+1]);    p += sprintf(p,"  LSI%i_BS  = %08X    LSI%i_BS  = %08X\n",x,temp1,x+1,temp2);    temp1 = readl(baseaddr+aBD[x]);    temp2 = readl(baseaddr+aBD[x+1]);    p += sprintf(p,"  LSI%i_BD  = %08X    LSI%i_BD  = %08X\n",x,temp1,x+1,temp2);    temp1 = readl(baseaddr+aTO[x]);    temp2 = readl(baseaddr+aTO[x+1]);    p += sprintf(p,"  LSI%i_TO  = %08X    LSI%i_TO  = %08X\n",x,temp1,x+1,temp2);  }    for (x=0;x<8;x+=2)    p += sprintf(p,"  image_va%i   = %08X     image_va%i   = %08X\n",                 x,image_va[x],x+1,image_va[x+1]);   p += sprintf(p,"\nDriver Program Status:\n");    for (x=0;x<8;x+=2)    p += sprintf(p,"  DMACTL %i    = %08lX DMACTL %i    = %08lX\n",                 x,DMA[x],x+1,DMA[x+1]);          for (x=0;x<8;x+=2)    p += sprintf(p,"  OkToWrite %i = %1X        OkToWrite %i = %1X\n",                 x,OkToWrite[x],x+1,OkToWrite[x+1]);   for (x=0;x<8;x+=2)    p += sprintf(p,"  Mode %i      = %1X        Mode %i      = %1X\n",                 x,mode[x],x+1,mode[x+1]);   p += sprintf(p,"\n");    temp1 = 0;  p += sprintf(p, "VMEIrqs Assigned: ");  for (x=0;x<7;x++) {    if (vmeirqs[x] != NULL) {      p += sprintf(p, "%i ",x+1);      temp1++;    }  }  if (temp1 == 0)    p += sprintf(p, "none\n");  else    p += sprintf(p,"\n");    *eof = 1;  return p - buf;}//----------------------------------------------------------------------------//  register_proc()//----------------------------------------------------------------------------static void register_proc(){  uni_procdir = create_proc_entry("ca91c042", S_IFREG | S_IRUGO, 0);  uni_procdir->read_proc = uni_procinfo;}//----------------------------------------------------------------------------//  unregister_proc()//----------------------------------------------------------------------------static void unregister_proc(){  remove_proc_entry("ca91c042",0);}//----------------------------------------------------------------------------////  uni_poll()////----------------------------------------------------------------------------static unsigned int uni_poll(struct file* file, poll_table* wait){  return 0;}//----------------------------------------------------------------------------////  uni_open()////----------------------------------------------------------------------------static int uni_open(struct inode *inode,struct file *file){  unsigned int minor = MINOR(inode->i_rdev);  if (minor > MAX_MINOR) {    return(-ENODEV);  }  if (minor == CONTROL_MINOR) {    opened[minor]++;    return(0);  }  if (!opened[minor]) {    opened[minor] = 1;    return(0);  } else    return(-EBUSY);}//----------------------------------------------------------------------------////  uni_release()////----------------------------------------------------------------------------static int uni_release(struct inode *inode,struct file *file){  unsigned int minor = MINOR(inode->i_rdev);  opened[minor]--;  return 0;}//----------------------------------------------------------------------------////  uni_lseek()////----------------------------------------------------------------------------static long long uni_llseek(struct file *file,loff_t offset,int whence){  unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);  unsigned int toffset,base,paddr;  if (whence == SEEK_SET) {    if (minor == CONTROL_MINOR) {      image_ptr[minor] = offset;    } else {      toffset = readl(baseaddr+aTO[minor]);          base    = readl(baseaddr+aBS[minor]);          paddr   = offset-toffset;      image_ptr[minor] = (int)(image_ba[minor]+(paddr-base));    }      return 0;  } else if (whence == SEEK_CUR) {    image_ptr[minor] += offset;    return 0;  } else    return -1;  }//----------------------------------------------------------------------------////  uni_read()////----------------------------------------------------------------------------static ssize_t uni_read(struct file *file, char *buf, size_t count, loff_t *ppos){  int x = 0;  unsigned int v,numt,remain,tmp;  char *temp = buf;  unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);    int p;   unsigned char  vc;  unsigned short vs;  unsigned int   vl;  char *DMA_Buffer;  unsigned int DMA_Buffer_Size = 0,     order     = 0,    a_size    = 0,    dma_align = 0,    timeout   = 0;                       int val     = 0,    pci       = 0,    vme       = 0,    okcount   = 0;  if (minor == CONTROL_MINOR) {    p = (int)image_ptr[minor];    v = readl(baseaddr+p);        __copy_to_user(temp,&v,4);  } else {    reads++;                    if (OkToWrite[minor]) {      if (mode[minor] == MODE_PROGRAMMED) {        numt = count;        remain = count;        // Calc the number of longs we need        numt = count / 4;        remain = count % 4;        for (x=0;x<numt;x++) {          vl = readl(image_ptr[minor]);              // Lets Check for a Bus Error          tmp = readl(baseaddr+PCI_CSR);          if (tmp & 0x08000000) {            writel(tmp,baseaddr+PCI_CSR);            return(okcount);          } else            okcount += 4;          __copy_to_user(temp,&vl,4);          image_ptr[minor]+=4;          temp+=4;        }          // Calc the number of Words we need        numt = remain / 2;        remain = remain % 2;        for (x=0;x<numt;x++) {          vs = readw(image_ptr[minor]);              // Lets Check for a Bus Error          tmp = readl(baseaddr+PCI_CSR);          if (tmp & 0x08000000) {            writel(tmp,baseaddr+PCI_CSR);            return(okcount);          } else            okcount += 2;          __copy_to_user(temp,&vs,2);          image_ptr[minor]+=2;          temp+=2;        }          for (x=0;x<remain;x++) {          vc = readb(image_ptr[minor]);              // Lets Check for a Bus Error          tmp = readl(baseaddr+PCI_CSR);          if (tmp & 0x08000000) {            writel(tmp,baseaddr+PCI_CSR);            return(okcount);          } else            okcount++;          __copy_to_user(temp,&vc,1);          image_ptr[minor]+=1;          temp+=1;        }        } else if (mode[minor] == MODE_DMA) {        // ------------------------------------------------------------------        //        // ------------------------------------------------------------------              // Wait for DMA to finish, This needs to be changed        val = readl(baseaddr+DGCS);        while ((val & 0x00008000) && (timeout++ < 1000000))          val = readl(baseaddr+DGCS);        // VME Address						              vme = image_va[minor] + (image_ptr[minor] - (unsigned int)image_ba[minor]);          dma_align = vme % 8;          // Setup DMA Buffer to read data into        DMA_Buffer_Size = count + ((int)image_ptr % 8) + dma_align;                 a_size = PAGE_SIZE;        while (a_size < DMA_Buffer_Size) {          order++;          a_size <<= 1;        }        DMA_Buffer = (char *)__get_dma_pages(GFP_KERNEL,order);          // PCI Address        pci = virt_to_bus(DMA_Buffer) + dma_align;        // Setup DMA regs        writel(DMA[minor],baseaddr+DCTL);       // Setup Control Reg        writel(count,baseaddr+DTBC);            // Count	            writel(pci,baseaddr+DLA);               // PCI Address        writel(vme,baseaddr+DVA);               // VME Address        // Start DMA        writel(0x80006F00,baseaddr+DGCS);       // GO        // Wait for DMA to finish, This needs to be changed        val = readl(baseaddr+DGCS);        while ((val & 0x00008000) && (timeout++ < 100000))          val = readl(baseaddr+DGCS);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -