colinjjj
驱动牛犊
驱动牛犊
  • 注册日期2003-02-28
  • 最后登录2003-07-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1341回复:5

PCI驱动的移植

楼主#
更多 发布于:2003-05-17 22:31
最近在将一视频卡的LINUX下的PCI驱动程序从X86的PC机上移植(用交叉编译的方式)到一MIPS的嵌入式系统平台上出现了一些问题,具体是这样:在PC上运行一切正常播放,但移到MIPS平台上时播放有时正常,但不能长时间播放(一般只有几分钟正常,然后就死机,死机发生是随机的)。这是否与PCI驱动的DMA或中断时序有关(因为我在中断处理程序中加入PRINTK()函数,情况就有改善,但仍然不能根本解决,而这只不过是相当于加入一个很短的延时)?或是移植时有与硬件相关的驱动部分的源程序需要修改?有哪位专家对这类移植有经验的能否帮忙?事情很急,谢谢了!
dos
dos
驱动小牛
驱动小牛
  • 注册日期2001-06-13
  • 最后登录2010-02-24
  • 粉丝0
  • 关注0
  • 积分90分
  • 威望9点
  • 贡献值0点
  • 好评度9点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2003-05-18 01:10
跟我的情况非常相似。伤脑筋...
raul.wang
驱动小牛
驱动小牛
  • 注册日期2002-07-30
  • 最后登录2004-11-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2003-05-22 14:47
Mips我做过一年,什么问题,贴出来看看
同饮一壶酒
raul.wang
驱动小牛
驱动小牛
  • 注册日期2002-07-30
  • 最后登录2004-11-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地板#
发布于:2003-05-22 14:49
我做的MIPS时,主要是由于芯片温度太高,经常TLB Miss
同饮一壶酒
colinjjj
驱动牛犊
驱动牛犊
  • 注册日期2003-02-28
  • 最后登录2003-07-15
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于: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系统对中断的路由出了问题,不知道有没有这种可能,再不就是硬件的问题了。
        
    

        
raul.wang
驱动小牛
驱动小牛
  • 注册日期2002-07-30
  • 最后登录2004-11-13
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2003-06-03 16:32
在读写寄存器的时候稍微延时一下
同饮一壶酒
游客

返回顶部