📄 ca91c042.c
字号:
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 + -