阅读:1341回复:5
PCI驱动的移植
最近在将一视频卡的LINUX下的PCI驱动程序从X86的PC机上移植(用交叉编译的方式)到一MIPS的嵌入式系统平台上出现了一些问题,具体是这样:在PC上运行一切正常播放,但移到MIPS平台上时播放有时正常,但不能长时间播放(一般只有几分钟正常,然后就死机,死机发生是随机的)。这是否与PCI驱动的DMA或中断时序有关(因为我在中断处理程序中加入PRINTK()函数,情况就有改善,但仍然不能根本解决,而这只不过是相当于加入一个很短的延时)?或是移植时有与硬件相关的驱动部分的源程序需要修改?有哪位专家对这类移植有经验的能否帮忙?事情很急,谢谢了!
|
|
沙发#
发布于:2003-05-18 01:10
跟我的情况非常相似。伤脑筋...
|
|
板凳#
发布于:2003-05-22 14:47
Mips我做过一年,什么问题,贴出来看看
|
|
|
地板#
发布于:2003-05-22 14:49
我做的MIPS时,主要是由于芯片温度太高,经常TLB Miss
|
|
|
地下室#
发布于:2003-05-26 21:14
首先要感谢您的关注。
实际情况如下: 这是驱动程序中的中断服务程序: // // Note: This can share the interrupt line with other PCI device drivers. // static void vw2010_isr(int irq, void * dev_id, struct pt_regs * regs) { PDEVICE_EXTENSION pdx; U32 instance, HIUCMD, index; U16 output, ack; Addr2Mem Handle; VWKdPrint(printk(KERN_INFO \"vw2010_isr\\n\")); pdx = (PDEVICE_EXTENSION) dev_id; if(pdx == NULL) { printk(KERN_WARNING \"\\nVweb ISR Done NULL dev\\n\"); return; } // // Service the interrupt. The driver should do whatever necessary to the device // for servicing the interrupt. This is device specific. // instance = pdx->INST; VWKdPrint(printk(KERN_INFO \"(%d): entering\\n\", instance)); if (!pdx->intr_enabled) { VWKdPrint(printk(KERN_INFO \"vw2010_isr(%d): Intr disabled!\\n\", instance)); return; } HIUCMD = HIUCTLCODE(RD_VW_REG, REG_INTS); output = READ_REGISTER_USHORT((pdx->PtrKernelBar[0] + HIUCMD)); /×读出卡上的中断标自 // output = *((U16 *) (pdx->PtrKernelBar[0] + HIUCMD)); if ( (output & (U16)BIT9) == 0 ) { VWKdPrint(printk(KERN_INFO \"vw2010_isr(%d): Faulty Intr!\\n\", instance)); return; } file://clear interrupts --To reset the chip\'s pci interrupt***colin HIUCMD = HIUCTLCODE(WR_VW_REG, REG_INTR); WRITE_REGISTER_USHORT((pdx->PtrKernelBar[0] + HIUCMD), BIT9); file://get the handle HIUCMD = HIUCTLCODE(WR_DRAM, REG_MEM1); WRITE_REGISTER_USHORT((pdx->PtrKernelBar[0] + HIUCMD), SM_VW2PC_HND_LO); HIUCMD = HIUCTLCODE(WR_DRAM, REG_MEM2); WRITE_REGISTER_USHORT((pdx->PtrKernelBar[0] + HIUCMD), SM_VW2PC_HND_HI); HIUCMD = HIUCTLCODE(RD_DRAM, REG_MEM3); Handle._16.Low = READ_REGISTER_USHORT((pdx->PtrKernelBar[0] + HIUCMD)); HIUCMD = HIUCTLCODE(RD_DRAM, REG_MEM4); Handle._16.High = READ_REGISTER_USHORT((pdx->PtrKernelBar[0] + HIUCMD)); file://check if it has been acked HIUCMD = HIUCTLCODE(WR_DRAM, REG_MEM1); WRITE_REGISTER_USHORT((pdx->PtrKernelBar[0] + HIUCMD), SM_VW2PC_CMD_LO); HIUCMD = HIUCTLCODE(WR_DRAM, REG_MEM2); WRITE_REGISTER_USHORT((pdx->PtrKernelBar[0] + HIUCMD), SM_VW2PC_CMD_HI); HIUCMD = HIUCTLCODE(RD_DRAM, REG_MEM4); READ_REGISTER_USHORT((pdx->PtrKernelBar[0] + HIUCMD)); HIUCMD = HIUCTLCODE(RD_DRAM, REG_MEM3); ack = READ_REGISTER_USHORT((pdx->PtrKernelBar[0] + HIUCMD)); if ( (ack&0xff00) == NACK) { file://command failed! switch (ack&0xff) { case ReadCmd: VWKdPrint(printk(KERN_INFO \"vw2010_isr(%d): ReadCmd failed!\\n\", instance)); index = FindIndex(pdx, Handle._32); if (index == 0xffff) { printk(KERN_WARNING \"vw2010(%d): [ISR] Wrong Handle.\\n\", pdx->INST); return ; } pdx->StreamCmdCode[index] = ReadCmd; pdx->StreamIsACK[index] = FALSE; #ifdef VW_DUMP_MEM ack = 0; VWDumpSharedMem(pdx, &ack); #endif vw2010_wakeup(&pdx->wq[index]); break; case IoctlCmd: VWKdPrint(printk(KERN_INFO \"vw2010_isr(%d): IoctlCmd failed!\\n\", instance)); index = FindIndex(pdx, Handle._32); if (index == 0xffff) { printk(KERN_WARNING \"vw2010(%d): [ISR] Wrong Handle.\\n\", pdx->INST); return; } pdx->StreamCmdCode[index] = IoctlCmd; pdx->StreamIsACK[index] = FALSE; vw2010_wakeup(&pdx->wq[index]); break; case WriteCmd: VWKdPrint(printk(KERN_INFO \"vw2010_isr(%d): WriteCmd failed!\\n\", instance)); index = FindIndex(pdx, Handle._32); if (index == 0xffff) { printk(KERN_WARNING \"vw2010(%d): [ISR] Wrong Handle.\\n\", pdx->INST); return; } pdx->StreamCmdCode[index] = WriteCmd; pdx->StreamIsACK[index] = FALSE; vw2010_wakeup(&pdx->wq[index]); break; case MallocCmd: VWKdPrint(printk(KERN_INFO \"vw2010_isr(%d): MallocCmd failed!\\n\", instance)); index = FindIndex(pdx, vWeB); if (index == 0xffff) { printk(KERN_WARNING \"vw2010(%d): [ISR] Wrong Handle.\\n\", pdx->INST); return; } pdx->StreamCmdCode[index] = MallocCmd; pdx->StreamIsACK[index] = FALSE; pdx->StreamHandle[index] = Handle._32; vw2010_wakeup(&pdx->wq[index]); break; case FreeCmd: VWKdPrint(printk(KERN_INFO \"vw2010_isr(%d): FreeCmd failed!\\n\", instance)); index = FindIndex(pdx, Handle._32); if (index == 0xffff) { printk(KERN_WARNING \"vw2010(%d): [ISR] Wrong Handle.\\n\", pdx->INST); return; } pdx->StreamCmdCode[index] = FreeCmd; pdx->StreamIsACK[index] = FALSE; // vw_dev_tbl[pdx->INST]->vw_index_inst = ( ((index<<16) & 0xffff0000) | (instance & 0xffff) ); // tasklet_schedule(&vw_polling_tasklet); break; default: VWKdPrint(printk(KERN_INFO \"Unknown:0x%x failed!\\n\", (ack&0xff00))); break; } file://end of switch VWKdPrint(printk(KERN_INFO \"vw2010_isr(%d): leaving...\\n\", instance)); return; } // // OK, here we assume MIPS has acked the last command...正确地响应了中断 // switch (ack&0xff) { case ReadCmd: { printk(KERN_INFO \"vw2010_isr(%d): ReadCmd recvd with Handle=0x%x\\n\", instance, Handle._32); index = FindIndex(pdx, Handle._32); if (index == 0xffff) { printk(KERN_WARNING \"vw2010(%d): [ISR/ReadCmd] Wrong Handle.\\n\", pdx->INST); return; } pdx->StreamCmdCode[index] = ReadCmd; pdx->StreamIsACK[index] = TRUE; vw2010_wakeup(&pdx->wq[index]); VWKdPrint(printk(KERN_INFO \"vw2010(%d) - [ISR/ReadCmd]Index= 0x%x\\n\", instance, index)); break; } case IoctlCmd: { printk(\"vw2010_isr[%d]: IoctlCmd recvd with Handle=0x%x\\n\", instance, Handle._32); index = FindIndex(pdx, Handle._32); if (index == 0xffff) { printk(KERN_WARNING \"vw2010(%d): [ISR/IoctlCmd] Wrong Handle.\\n\", pdx->INST); return; } pdx->StreamCmdCode[index] = IoctlCmd; pdx->StreamIsACK[index] = TRUE; vw2010_wakeup(&pdx->wq[index]); VWKdPrint(printk(KERN_INFO \"vw2010(%d) - [ISR/IoctlCmd]Index= 0x%x\\n\", instance, index)); break; } case WriteCmd: { printk(\"vw2010_isr[%d]: WriteCmd recvd with Handle=0x%x\\n\", instance, Handle._32); index = FindIndex(pdx, Handle._32); if (index == 0xffff) { printk(KERN_WARNING \"vw2010(%d): [ISR/WriteCmd] Wrong Handle.\\n\", pdx->INST); return; } pdx->StreamCmdCode[index] = WriteCmd; pdx->StreamIsACK[index] = TRUE; vw2010_wakeup(&pdx->wq[index]); VWKdPrint(printk(KERN_INFO \"vw2010(%d) - [ISR/WriteCmd]Index= 0x%x\\n\", instance, index)); break; } case MallocCmd: { printk(KERN_INFO \"vw2010_isr(%d): MallocCmd recvd!\\n\", instance); index = FindIndex(pdx, vWeB); if (index == 0xffff) { printk(KERN_WARNING \"vw2010(%d): [ISR] Wrong Handle.\\n\", pdx->INST); return; } pdx->StreamCmdCode[index] = MallocCmd; pdx->StreamIsACK[index] = TRUE; pdx->StreamHandle[index] = Handle._32; vw2010_wakeup(&pdx->wq[index]); VWKdPrint(printk(KERN_INFO \"[MalloCmd]Index= 0x%x\\tHandle= 0x%x\\n\", index, Handle._32)); break; } case FreeCmd: { printk(KERN_INFO \"vw2010_isr[%d]: CmdTestInt recvd!\\n\", instance); index = FindIndex(pdx, Handle._32); if (index == 0xffff) { printk(KERN_WARNING \"vw2010(%d): [ISR] Wrong Handle.\\n\", pdx->INST); return; } pdx->StreamCmdCode[index] = FreeCmd; pdx->StreamIsACK[index] = TRUE; VWKdPrint(printk(KERN_INFO \"vw2010(%d) - [FreeCmd]Index= 0x%x\\n\", instance, index)); // vw_dev_tbl[pdx->INST]->vw_index_inst = ( ((index<<16) & 0xffff0000) | (instance & 0xffff) ); // tasklet_schedule(&vw_polling_tasklet); break; } default: VWKdPrint(printk(KERN_INFO \"Unknown:0x%x recvd!\\n\", (ack&0xff00))); break; } VWKdPrint(printk(KERN_INFO \"vw2010_isr(%d): leaving...\\n\", instance)); return; } 程序中每个case下的第一个printk是我加入的,我只不过是加入了那些调试信息,最多也就是引入一点延迟,情况就得到改善,可以播的出来了,但是还是会死机,再在这几个地方加入udelay()的延迟也无济于事,不知道是何原因? 我想可能是中断丢失或mips系统对中断的路由出了问题,不知道有没有这种可能,再不就是硬件的问题了。 |
|
5楼#
发布于:2003-06-03 16:32
在读写寄存器的时候稍微延时一下
|
|
|