libata and legacy ide pcmcia failure

Mark Lord mlord at pobox.com
Fri Jun 8 08:46:42 EDT 2007


Tejun Heo wrote:
>
>> Jun  7 21:10:29 localhost kernel: ata3.00: CFA: Memory Card Adapter,
>> 20011212, max PIO1
>> Jun  7 21:10:29 localhost kernel: ata3.00: 253696 sectors, multi 0: LBA
>> Jun  7 21:10:29 localhost kernel: ata3.00: issuing IDENTIFY
>> Jun  7 21:10:29 localhost kernel: ata3.00: IDENTIFY complete
>> Jun  7 21:10:29 localhost kernel: ata3.00: configured for PIO0
>> Jun  7 21:10:29 localhost kernel: ata3: EH complete
>> Jun  7 21:10:29 localhost kernel: scsi 3:0:0:0: Direct-Access    
>> ATA      Memory Card Adap 2001 PQ: 0 ANSI: 5
>> Jun  7 21:10:29 localhost kernel: sd 3:0:0:0: [sdd] 253696 512-byte
>> hardware sectors (130 MB)
>> Jun  7 21:10:29 localhost kernel: sd 3:0:0:0: [sdd] Write Protect is off
>> Jun  7 21:10:29 localhost kernel: sd 3:0:0:0: [sdd] Write cache:
>> disabled, read cache: enabled, doesn't support DPO or FUA
>> Jun  7 21:10:29 localhost kernel: sd 3:0:0:0: [sdd] 253696 512-byte
>> hardware sectors (130 MB)
>> Jun  7 21:10:29 localhost kernel: sd 3:0:0:0: [sdd] Write Protect is off
>> Jun  7 21:10:29 localhost kernel: sd 3:0:0:0: [sdd] Write cache:
>> disabled, read cache: enabled, doesn't support DPO or FUA
> 
> So, that made it go through detection okay.  That's a good news.
> 
>> Jun  7 21:10:59 localhost kernel:  sdd:<3>ata3.00: exception Emask 0x0
>> SAct 0x0 SErr 0x0 action 0x2 frozen
>> Jun  7 21:10:59 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  7 21:10:59 localhost kernel:          res
>> 40/00:00:00:00:00/00:00:00:00:00/00 Emask 0x4 (timeout)
> 
> But, read for partition table failed miserably and took the device
> offline completely.
> 
> Whee... Cc'ing linux-ide and Mark Lord.  The original thread is..
> 
>   http://thread.gmane.org/gmane.linux.kernel/530099
> 
> Any ideas?

I still don't see much evidence that interrupts are actually functioning here.
It would be good to see /proc/interrupts before/after libata tries to talk to it.

Let's assume for the moment that interrupts are b0rken.
The legacy IDE driver can talk to such devices completely without interrupts,
if the IDE polling patch (below) is applied.

So, Robert:  could you try again with the old IDE driver,
except apply this patch to it first?  This will give valuable info.


--- old/drivers/ide/ide-probe.c	2007-04-11 00:18:51.000000000 -0400
+++ linux/drivers/ide/ide-probe.c	2007-04-12 09:26:14.000000000 -0400
@@ -1014,6 +1014,27 @@
  * but anything else has led to problems on some machines.  We re-enable
  * interrupts as much as we can safely do in most places.
  */
+struct timer_list polling_timer;
+static void ide_polling (unsigned long data)
+{
+	ide_hwgroup_t *hwgroup = (void *)data;
+	ide_hwif_t *hwif;
+	int irq = 0;
+
+	if (hwgroup) {
+		hwif = hwgroup->hwif;
+		if (hwif)
+			irq = hwif->irq;
+	}
+
+	ide_intr(irq, hwgroup);
+	init_timer(&polling_timer);
+	polling_timer.expires = jiffies + 2;
+	polling_timer.function = &ide_polling;
+	polling_timer.data = (unsigned long) hwgroup;
+	add_timer(&polling_timer);
+}
+
 static int init_irq (ide_hwif_t *hwif)
 {
 	unsigned int index;
@@ -1110,9 +1131,12 @@
 		if (hwif->io_ports[IDE_CONTROL_OFFSET])
 			/* clear nIEN */
 			hwif->OUTB(0x08, hwif->io_ports[IDE_CONTROL_OFFSET]);
-
+#if 0
 		if (request_irq(hwif->irq,&ide_intr,sa,hwif->name,hwgroup))
 	       		goto out_unlink;
+#else
+		ide_polling((unsigned long)hwgroup);
+#endif
 	}
 
 	/*
@@ -1156,6 +1180,7 @@
 	printk("\n");
 	up(&ide_cfg_sem);
 	return 0;
+#if 0
 out_unlink:
 	spin_lock_irq(&ide_lock);
 	if (hwif->next == hwif) {
@@ -1176,6 +1201,7 @@
 		BUG_ON(hwgroup->hwif == hwif);
 	}
 	spin_unlock_irq(&ide_lock);
+#endif
 out_up:
 	up(&ide_cfg_sem);
 	return 1;
--- old/drivers/ide/ide.c	2007-04-11 00:18:51.000000000 -0400
+++ linux/drivers/ide/ide.c	2007-04-12 09:31:59.000000000 -0400
@@ -569,6 +569,8 @@
  *	This is raving bonkers.
  */
 
+extern struct timer_list polling_timer;
+
 void ide_unregister(unsigned int index)
 {
 	ide_drive_t *drive;
@@ -612,7 +614,11 @@
 		g = g->next;
 	} while (g != hwgroup->hwif);
 	if (irq_count == 1)
+#if 0
 		free_irq(hwif->irq, hwgroup);
+#else
+		del_timer(&polling_timer);
+#endif
 
 	spin_lock_irq(&ide_lock);
 	/*



More information about the linux-pcmcia mailing list