Subject: More info about WDC/ATA PCMCIA and CardBus problems using flash (i.e., not with microdrive)
To: None <tech-kern@netbsd.org>
From: Tad Hunt <tad@entrisphere.com>
List: tech-kern
Date: 03/27/2002 14:19:20
I just had one of our hardware engineers change the PCMCIA interface
on our MPC8260 board so I can demultiplex the pcmcia interrupts
from the other interrupts on the same irq line (aren't PALs great!).
Anyway, the problem described in PR kern/15841 still exists when
using the flash ATA PC Card.

As before the jammed interrupt problem never occurs with the IBM
Microdrive (side note: believe it or not, the microdrive is faster
for both reading and writing than the flash disk!).

In summary, the problem is that the flash disk is asserting the
interrupt request, but the WDCF_IRQ_WAIT bit is not set in the
"channel_softc", so the interrupt is never serviced.

I see the same problem on the "stock" NetBSD-1.5 i386 port (a Dell
with a cardbus card in a PCI slot) as I do on our MPC8260 port,
which leads me to believe that it is a general problem.

I see the same behavior with both of the following flash disk parts
(the only ones I have been able to test with so far):

1) SMART Modular Technologies ATA PC Card (model SM9FLAPC512M1)

   NetBSD identifies this as follows:

	wdc0 at pcmcia0 function 0 port 0x15000000-0x1500000f
	wd0 at wdc0 channel 0 drive 0: <SMART ATA FLASH>
	wd0: drive supports 1-sector PIO transfers, LBA addressing
	wd0: 489 MB, 994 cyl, 16 head, 63 sec, 512 bytes/sect x 1001952 sectors
	wd0: drive supports PIO mode 4

2) AVL Compact Flash Card 128MB (unknown model number)

   NetBSD identifies this as follows:

	wdc0 at pcmcia0 function 0 port 0x15000000-0x1500000f
	wd0 at wdc0 channel 0 drive 0: <Ritek Corporation>
	wd0: drive supports 1-sector PIO transfers, LBA addressing
	wd0: 122 MB, 978 cyl, 8 head, 32 sec, 512 bytes/sect x 250368 sectors

Now that I can de-multiplex the pcmcia interrupts, I can move the
hack described in PR15841 out of the toplevel interrupt handler,
and into the wdc interrupt handler.  However, this is still
far from an optimum solution.

	wdcintr(...)
	{
		...
		if((chp->ch_flags & WDCF_IRQ_WAIT) == 0) {
			if(irq_for_this_channel_is_pending)
				wdcfix(chp);
			WDCDEBUG_PRINT(("wdcintr: inactive controller\n"),
				DEBUG_INTR);
			return (0);
		}
		...
	}

-Tad