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

📄 ca91c042.c

📁 linux下vme总线驱动代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        if (timeout == 100000)          printk("<<ca91c042 DMA Timed out>>\n");        if (! (val & 0x00000800)) {  // An Error Happened          count -= readl(baseaddr+DTBC);            }        image_ptr[minor] += count;        // Copy pages to User Memory        __copy_to_user(temp,DMA_Buffer+dma_align,count);        free_pages((unsigned long)DMA_Buffer,order);      }           // end of MODE_DMA    }             // end of OKtoWrite  }    *ppos += count;  return(count);}//----------------------------------------------------------------------------////  uni_write()////----------------------------------------------------------------------------static ssize_t uni_write(struct file *file, const char *buf, size_t count, loff_t *ppos){  int x,p;  unsigned int numt,remain,tmp;  char *temp = (char *)buf;  unsigned int minor = MINOR(file->f_dentry->d_inode->i_rdev);  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,    pci       = 0,    vme       = 0,    okcount   = 0;  writes++;  if (minor == CONTROL_MINOR) {    __copy_from_user(&vl,temp,4);    p = (int)image_ptr[minor];    writel(vl,baseaddr+p);  } else {    if (OkToWrite[minor]) {      if (mode[minor] == MODE_PROGRAMMED) {        // Calc the number of longs we need        numt = count;        remain = count;        numt = count / 4;        remain = count % 4;        for (x=0;x<numt;x++) {          __copy_from_user(&vl,temp,4);          writel(vl,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;          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++) {          __copy_from_user(&vs,temp,2);          writew(vs,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;          image_ptr[minor]+=2;          temp+=2;        }          for (x=0;x<remain;x++) {          __copy_from_user(&vc,temp,1);          writeb(vc,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;          image_ptr[minor]+=1;          temp+=1;        }          // Lets Check for a Bus Error        tmp = readl(baseaddr+PCI_CSR);        if (tmp & 0x08000000) {  // S_TA is Set          writel(0x08000000,baseaddr+PCI_CSR);          count = 0;        }      } else if (mode[minor] == MODE_DMA) {        // ------------------------------------------------------------------        //        // ------------------------------------------------------------------              // Wait for DMA to finish, This needs to be changed        val = readl(baseaddr+DGCS);        while ((val & 0x00008000) && (timeout++ < 100000))          val = readl(baseaddr+DGCS);        // Setup DMA Buffer to write data into        // VME Address						              vme = image_va[minor] + (image_ptr[minor] - (unsigned int)image_ba[minor]);          dma_align = vme % 8;          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);          // Copy User Memory into buffer        __copy_from_user(DMA_Buffer + dma_align,temp,count);        // PCI Address        pci = virt_to_bus(DMA_Buffer) + dma_align;        // Setup DMA regs        writel(DMA[minor]|0x80000000,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);        if (timeout == 100000)          printk("<<ca91c042 DMA Timed out>>\n");        if (! (val & 0x00000800)) {  // An Error Happened          // The Universe Seems to return an invalid value in DTBC on          // Bus Errors during DMA, so invalidate the count          count = 0;        }        image_ptr[minor] += count;        free_pages((unsigned long)DMA_Buffer,order);      }           // end of MODE_DMA    }  //OKtoWrite  }    *ppos += count;  return(count);}//----------------------------------------------------------------------------//  uni_ioctl()//----------------------------------------------------------------------------static int uni_ioctl(struct inode *inode,struct file *file,unsigned int cmd, unsigned long arg){  unsigned int minor = MINOR(inode->i_rdev);  unsigned int sizetomap = 0, to = 0, bs = 0;  ioctls++;  switch (cmd) {  case IOCTL_SET_CTL:    writel(arg,baseaddr+aCTL[minor]);    // Lets compute and save the DMA CTL Register    DMA[minor] = arg & 0x00FFFF00;    break;  case IOCTL_SET_MODE:    mode[minor] = arg;    break;            // Lets Map the VME Bus to the PCI Bus    //    // << NOTE >> BD Must already be set before you call this!!!!    //    //  case IOCTL_SET_BS:    writel(arg,baseaddr+aBS[minor]);    if (image_ba[minor])      iounmap(image_ba[minor]);    // This uses the BD Register to Find the size of the Image Mapping		    sizetomap = readl(baseaddr+aBD[minor]);    sizetomap -= arg;    image_ba[minor] = (char *)ioremap(arg,sizetomap);    if (!image_ba[minor]) {      OkToWrite[minor] = 0;           return -1;    }    image_ptr[minor] = (int)image_ba[minor];    OkToWrite[minor] = 1;    // Calculate the VME Address    bs = readl(baseaddr+aBS[minor]);    to = readl(baseaddr+aTO[minor]);    image_va[minor]  = bs + to;    break;  case IOCTL_SET_BD:    writel(arg,baseaddr+aBD[minor]);    break;    case IOCTL_SET_TO:    writel(arg,baseaddr+aTO[minor]);    // Calculate the VME Address    bs = readl(baseaddr+aBS[minor]);    to = readl(baseaddr+aTO[minor]);    image_va[minor]  = bs + to;    break;    default:    if (cmd < 0x1000) {  // This is a Register value so write to it.      writel(arg,baseaddr+cmd);    }    break;    }  return(0);}//-----------------------------------------------------------------------------// Function   : PrintCmdPacketList// Inputs     : TDMA_Cmd_Packet* cpl (PCI Phys Address)// Outputs    : void// Description: // Remarks    : // History    : //-----------------------------------------------------------------------------void PrintCmdPacketList(TDMA_Cmd_Packet* cpl){  TDMA_Cmd_Packet *p = bus_to_virt((int)cpl);  char buff[100];  int x = 0;  int done = 0;  while (!done && (x < 10)) {    x++;    sprintf(buff,"<ca91c042> (%i) dctl=%08X, dtbc=%08X\n",x,p->dctl,p->dtbc);    printk(buff);    sprintf(buff,"<ca91c042> dlv=%08X, dva=%08X\n",p->dlv,p->dva);    printk(buff);    sprintf(buff,"<ca91c042> dcpp=%08X\n",p->dcpp);    printk(buff);    done = (p->dcpp & 0x00000001);    p = bus_to_virt((int)(TDMA_Cmd_Packet*)(p->dcpp & 0xFFFFFFF8));  // Next in Line Please  }}//-----------------------------------------------------------------------------// Function   : void DMA_status// Inputs     : unsigned long __data// Outputs    : static// Description: // Remarks    : // History    : //-----------------------------------------------------------------------------static void DMA_status(unsigned long __data){  printk("<<ca91c042>> DMA Timed out\n");  if (DMACallBackFunc)    DMACallBackFunc(1);  DMACallBackFunc = NULL;}//-----------------------------------------------------------------------------// Function   : DMA_irq_handler// Inputs     : void// Outputs    : void// Description: // Remarks    : // History    : //-----------------------------------------------------------------------------void DMA_irq_handler(void){  int val;  int cbv=0;  char buf[100];  TDMA_Cmd_Packet *cpl;  del_timer(&DMA_timer);  // Cancel DMA Time Out  val = readl(baseaddr+DGCS);  if (!(val & 0x00000800)) {    sprintf(buf,"<<ca91c042>> DMA Error in DMA_irq_handler DGCS=%08X\n",val);      printk(buf);    val = readl(baseaddr+DCPP);    sprintf(buf,"<<ca91c042>> DCPP=%08X\n",val);      printk(buf);    val = readl(baseaddr+DCTL);    sprintf(buf,"<<ca91c042>> DCTL=%08X\n",val);      printk(buf);    val = readl(baseaddr+DTBC);    sprintf(buf,"<<ca91c042>> DTBC=%08X\n",val);      printk(buf);    val = readl(baseaddr+DLA);    sprintf(buf,"<<ca91c042>> DLA=%08X\n",val);      printk(buf);    val = readl(baseaddr+DVA);    sprintf(buf,"<<ca91c042>> DVA=%08X\n",val);      printk(buf);    if (DMAType == DMATYPE_LLIST) {      printk("<<ca91c042>> CmdPacketList sent to DMARead\n");      PrintCmdPacketList(debugptr);      printk("<<ca91c042>> CmdPacketList as seen by DCPP\n");      cpl = (TDMA_Cmd_Packet*)readl(baseaddr+DCPP);   // Command Packet Pointer      cpl = (TDMA_Cmd_Packet*)((int)cpl & ~0x03);      PrintCmdPacketList(cpl);    }    cbv = 1;  // Call Back value is set to 1 to show error condition  }  if (DMACallBackFunc)    DMACallBackFunc(cbv);  // We are done with the Call Back so clear it  DMACallBackFunc = NULL;}//-----------------------------------------------------------------------------// Function   : LERR_irq_handler// Inputs     : void// Outputs    : void// Description: // Remarks    : // History    : //-----------------------------------------------------------------------------void LERR_irq_handler(void){  int val;  char buf[100];  TDMA_Cmd_Packet *cpl;  del_timer(&DMA_timer);  // Cancel DMA Time Out  val = readl(baseaddr+DGCS);  if (!(val & 0x00000800)) {    sprintf(buf,"<<ca91c042>> LERR_irq_handler DMA Read Error DGCS=%08X\n",val);      printk(buf);    if (DMAType == DMATYPE_LLIST) {      cpl = (TDMA_Cmd_Packet*)readl(baseaddr+DCPP);   // Command Packet Pointer      cpl = (TDMA_Cmd_Packet*)((int)cpl & ~0x03);      PrintCmdPacketList(cpl);      sprintf(buf,"<<ca91c042>> DMAReadCallBack Request of cmdpack=0x%08X\n",(int)cpl);      printk(buf);    }  }  if (DMACallBackFunc)    DMACallBackFunc(1);  DMACallBackFunc = NULL;}//-----------------------------------------------------------------------------// Function   : VERR_irq_handler// Inputs     : void// Outputs    : void// Description: // Remarks    : // History    : //-----------------------------------------------------------------------------void VERR_irq_handler(void){  int val;  char buf[100];  TDMA_Cmd_Packet *cpl;  del_timer(&DMA_timer);  // Cancel DMA Time Out  val = readl(baseaddr+DGCS);  if (!(val & 0x00000800)) {    sprintf(buf,"<<ca91c042>> VERR_irq_handler DMA Read Error DGCS=%08X\n",val);      printk(buf);    if (DMAType == DMATYPE_LLIST) {      cpl = (TDMA_Cmd_Packet*)readl(baseaddr+DCPP);   // Command Packet Pointer      cpl = (TDMA_Cmd_Packet*)((int)cpl & ~0x03);      PrintCmdPacketList(cpl);      sprintf(buf,"<<ca91c042>> DMAReadCallBack Request of cmdpack=0x%08X\n",(int)cpl);      printk(buf);    }  }  if (DMACallBackFunc)    DMACallBackFunc(1);  DMACallBackFunc = NULL;}

⌨️ 快捷键说明

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