Re: libata and legacy ide pcmcia failure

From: Mark Lord
Date: Fri Jun 22 2007 - 09:33:15 EST


Robert de Rooy wrote:

I did another try with libata pcmcia support using 2.6.22-rc5 which already includes the nodata polling fix, in combination with disable-dev_init_param-and-setxfermode-for-CFA.patch and the timing-debug.patch
...
Jun 22 13:19:44 localhost kernel: ata3.00: issuing IDENTIFY
Jun 22 13:19:45 localhost kernel: ata3.00: IDENTIFY complete
Jun 22 13:19:45 localhost kernel: ata3.00: CFA: Memory Card Adapter, 20011212, max PIO1
Jun 22 13:19:45 localhost kernel: ata3.00: 253696 sectors, multi 0: LBA
Jun 22 13:19:45 localhost kernel: ata3.00: issuing IDENTIFY
Jun 22 13:19:45 localhost kernel: ata3.00: IDENTIFY complete
Jun 22 13:19:45 localhost kernel: ata3.00: configured for PIO0
Jun 22 13:19:45 localhost kernel: ata3: EH complete
Jun 22 13:19:45 localhost kernel: scsi 2:0:0:0: Direct-Access ATA Memory Card Adap 2001 PQ: 0 ANSI: 5
Jun 22 13:19:45 localhost kernel: sd 2:0:0:0: [sdb] 253696 512-byte hardware sectors (130 MB)
Jun 22 13:19:45 localhost kernel: sd 2:0:0:0: [sdb] Write Protect is off
Jun 22 13:19:45 localhost kernel: sd 2:0:0:0: [sdb] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
Jun 22 13:19:45 localhost kernel: sd 2:0:0:0: [sdb] 253696 512-byte hardware sectors (130 MB)
Jun 22 13:19:45 localhost kernel: sd 2:0:0:0: [sdb] Write Protect is off
Jun 22 13:19:45 localhost kernel: sd 2:0:0:0: [sdb] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
Jun 22 13:20:15 localhost kernel: sdb:<3>ata3.00: exception Emask 0x0 SAct 0x0 SErr 0x0 action 0x2 frozen
Jun 22 13:20:15 localhost kernel: ata3.00: cmd 20/00:08:00:00:00/00:00:00:00:00/e0 tag 0 cdb 0x0 data 4096 in
Jun 22 13:20:15 localhost kernel: res 40/00:00:00:00:00/00:00:00:00:00/00 Emask 0x4 (timeout)
Jun 22 13:20:15 localhost kernel: ata3: soft resetting port
Jun 22 13:20:15 localhost kernel: ata3: reset complete
Jun 22 13:20:15 localhost kernel: ATA: abnormal status 0x80 on port 0x00014107
Jun 22 13:20:15 localhost kernel: ATA: abnormal status 0x80 on port 0x00014107
Jun 22 13:20:15 localhost kernel: ATA: abnormal status 0x58 on port 0x00014107
Jun 22 13:20:15 localhost kernel: ata3.00: issuing IDENTIFY
Jun 22 13:20:15 localhost kernel: ATA: abnormal status 0x58 on port 0x00014107
...

Mmm.. I don't know about the first failure there,
but after that it gets into the "stuck DRQ" state
which libata makes no attempt to handle at present.

Here is an additional patch, which hopefully will apply to your kernel
to handle the stuck DRQ. You may need to hand tweak it, though,
as I'm not entirely certain as to where to place the new call
to ata_drain_fifo(). It's currently on an error recovery path
which works for DMA, but your device is using PIO. It may still get
hit as-is, but.. Give it a try.


--- linux/drivers/ata/libata-sff.c.orig 2007-04-26 12:02:46.000000000 -0400
+++ linux/drivers/ata/libata-sff.c 2007-04-29 08:29:27.000000000 -0400
@@ -413,6 +413,24 @@
ap->ops->irq_on(ap);
}

+static void ata_drain_fifo (struct ata_port *ap, struct ata_queued_cmd *qc)
+{
+ u8 stat = ata_chk_status(ap);
+ /*
+ * Try to clear stuck DRQ if necessary.
+ */
+ if ((stat & ATA_DRQ) && (!qc || qc->dma_dir != DMA_TO_DEVICE)) {
+ unsigned int i, limit = 512;
+ printk("Draining up to %u words from data FIFO.\n", limit);
+ for (i = 0; i < limit ; ++i) {
+ ioread16(ap->ioaddr.data_addr);
+ if (!(ata_chk_status(ap) & ATA_DRQ))
+ break;
+ }
+ printk("Drained %u/%u words.\n", i, limit);
+ }
+}
+
/**
* ata_bmdma_drive_eh - Perform EH with given methods for BMDMA controller
* @ap: port to handle error for
@@ -469,7 +487,7 @@
}

ata_altstatus(ap);
- ata_chk_status(ap);
+ ata_drain_fifo(ap, qc);
ap->ops->irq_clear(ap);

spin_unlock_irqrestore(ap->lock, flags);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/