libata and legacy ide pcmcia failure

Mark Lord liml at rtr.ca
Fri Jun 22 09:32:54 EDT 2007


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);



More information about the linux-pcmcia mailing list