Linux CF卡驱动经验小结

 

(2.6.34内核, 使用cf卡的IDE模式,PIO传输方式)

设备选择协议
============

设备选择协议请参考: http://wenku.baidu.com/view/40f58020aaea998fcc220e2e.html

在写设备寄存器之前需要确定BSY和DRQ这两位为0:
        /* yll
  * 根据设备选择协议,在往device寄存器中写入以前必须等待BSY和DRQ为0
  */
 if (valid & IDE_VALID_DEVICE) {
  for(i=10000; i; --i) {
   tmp = ide_inb(io_ports->status_addr);
   if (!( tmp & (1<<7 | 1<<3) )) //wait for BUSY==0,DRQ==0
    break;
  }
  tf_outb(tf->device, io_ports->device_addr);
        }
经过测试,如果没有等待BSY和DRQ这两位为0,则16G(133X)的金士顿CF卡和1G的工业卡无法正常挂载,虽然其扇区数等ID信息是可以被读出的.

 

 

忽略意外中断
============

 

采取措施
-------------
在driver/ide/ide-io.c的函数ide_intr中,将处理意外中断的函数unexpected_intr注释掉:
        if (handler == NULL || hwif->polling) {
  /*
   * Not expecting an interrupt from this drive.
   * That means this could be:
   * (1) an interrupt from another PCI device
   * sharing the same PCI INT# as us.
   * or (2) a drive just entered sleep or standby mode,
   * and is interrupting to let us know.
   * or (3) a spurious interrupt of unknown origin.
   *
   * For PCI, we cannot tell the difference,
   * so in that case we just ignore it and hope it goes away.
   */
  if ((host->irq_flags & IRQF_SHARED) == 0) {
   /*
    * Probably not a shared PCI interrupt,
    * so we can safely try to do something about it:
    */
   
       #if 0//yll: do nothing  ##########  Look Here  ################ 
   unexpected_intr(irq, hwif);
       #endif
  } else {
   /*
    * Whack the status register, just in case
    * we have a leftover pending IRQ.
    */
   (void)hwif->tp_ops->read_status(hwif);
  }
  goto out;
 }


错误信息和现象
---------------------
CF卡有时会产生一些意外的中断,如果不将unexpected_intr注释掉,会产生以下类似的错误:

ide0: unexpected interrupt, status=0x51, count=4
hda: task_pio_intr: status=0x51 { DriveReady SeekComplete Error }
hda: task_pio_intr: error=0x10 { SectorIdNotFound }, CHS=2/0/221, sector=733
hda: possibly failed opcode: 0x20
ide0: unexpected interrupt, status=0x51, count=16
 
或者:
--------
ide0: unexpected interrupt, status=0x51, count=3
ide0: unexpected interrupt, status=0x51, count=4
ide0: unexpected interrupt, status=0x51, count=5
ide0: unexpected interrupt, status=0x51, count=6
ide0: unexpected interrupt, status=0x51, count=7
ide0: unexpected interrupt, status=0x51, count=8
ide0: unexpected interrupt, status=0xd1, count=9
hda: status error: status=0x59 { DriveReady SeekComplete DataRequest Error }
hda: status error: error=0x00 { }
hda: possibly failed opcode: 0x30
hda: no DRQ after issuing WRITE
ide0: reset: master: ECC circuitry error
ide0: unexpected interrupt, status=0x51, count=11
ide0: unexpected interrupt, status=0x51, count=12
cp: write error: No space left on device

这些错误可能会引起读写操作的意外停止,或者使CF卡变成只读的,还可能破坏CF卡上的文件系统,损坏数据,让CF卡的可用空间变小,一些文件无法读写。

 

原因
-----------
ide_intr是中断上下文,如果调用了unexpected_intr,unexpected_intr会调用printk函数打印信息。
注释掉unexpected_intr之后测试表明,数据传输并不会出错(md5码验证),也不再有恼人的错误信息。

你可能感兴趣的:(linux,IO,测试,null,ide)