Subject: Re: WDC/ATA PCMCIA and CardBus problems only with flash (i.e., not w/ microdrive)
To: None <tech-kern@netbsd.org>
From: Tad Hunt <tad@entrisphere.com>
List: tech-kern
Date: 03/11/2002 12:18:07
In message <20020309184608.371597E03@beowulf.gw.com>, christos said:
;
;Ick... Is there another way this can be handled? Inside the wdc irq handler?
;
;christos

The first thing I tried was counting the number of times wdcintr() was
called in a row without WDCF_IRQ_WAIT being set, and if that was greater
than some constant, reading the status register

	wdcintr(...)
	{
		static int nowait;
		...

		if ((chp->ch_flags & WDCF_IRQ_WAIT) == 0) {

			nowait++;
			if(nowait > MAX_NO_WAIT)
				wdcfix(chp);

			WDCDEBUG_PRINT(("wdcintr: inactive controller\n"), DEBUG_INTR);
			return (0);
		}
		nowait = 0;
		...
	}

While this works, it really isn't the correct solution. If the disk
is idle, and one of the other devices is active on the shared irq
line is busy, we'll still call wdcfix() when we don't need to.

Another problem is that you want MAX_NO_WAIT to be big enough that
wdcfix() doesn't get called very frequently, which means that when
the problem does occur, it effectively busy-waits until it counts
to MAX_NO_WAIT.

The solution I came up with is only correct when you have a single
device on a shared irq line causing the spurious interrupts.  With
this solution there is no busy waiting, and it will only call
wdcfix() more frequently than necessary when there is more than
one device causing spurious interrupts on the shared irq line.

All of this really begs the question of why I'm seeing the spurious
interrupt in the first place though.

-Tad