[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: IDE DMA on AXP & barriers



Hi Ivan,

On Fri, Dec 07, 2001 at 05:03:41PM +0300, Ivan Kokshaysky wrote:
> On Fri, Dec 07, 2001 at 01:25:05PM +0100, Kurt Garloff wrote:
> > So I  wonder where the bug actually is. Somewhere in hardware; but I wonder
> > whether the CMD646 or the 2117x (PYXIS/CIA) is to blame. The QLogicISP seems
> > to happily do BM-DMA, so I'd point to the CMD646.
> 
> Hmm, it seems to be a pyxis bug; the hardware workaround exists, but
> I guess that it might be not implemented properly on early miatas.
> This also explains why I don't have that problem on lx164 and sx164.
> >From pyxis manual:
> "A.1 Read Page Problem
>  PCI DMA reads that attempt to cross 8K page boundaries cause data corruption
>  problems. A fix has been implemented with an Altera 7032 and two Pericom
>  PI5C3400 bus switches and a diode."

Hey, where did you find that manual? I could not find one at Compaq's web
site.

I wouldn't mind to solder a diode on my board, but I don't know about the
rest ... The software workaround is even preferable, as it helps more people
than just me.

How do I recognize the broken PYXIS in software? (Except for waiting for
your hard disk to be corrupted?)

Unfortunately, I see no 21174 on my PCI bus where I could just check the
revision.
garloff@pws:~ $ /sbin/lspci 
00:03.0 Ethernet controller: Digital Equipment Corporation DECchip 21142/43 (rev 30)
00:04.0 IDE interface: CMD Technology Inc PCI0646 (rev 01)
00:07.0 Non-VGA unclassified device: Intel Corporation 82378IB [SIO ISA Bridge] (rev 43)
00:0c.0 VGA compatible controller: Matrox Graphics, Inc. MGA 2064W [Millennium] (rev 01)
00:14.0 PCI bridge: Digital Equipment Corporation DECchip 21152 (rev 02)
01:09.0 SCSI storage controller: Q Logic ISP1020 (rev 05)

Can I draw conclusions from the revision of the 21152?

Or should I just put an #ifdef CONFIG_ALPHA_PYXIS in my patch?
What about the users of generic alpha kernels?
Or a config option?

Attached is my current version of a workaround. It checks for CMD646, which
should probably be removed, because the bug is in PYXIS according to your
docs. It runs stably since a couple of hours with DMA on, now.


Could people test it? 
Please report back to me whether you have that problem on your PWS ar
another Miata(PYXIS) board.
If the workaround helps you as well, I will prepare a nice patch and submit
it to Linux/Marcelo/Alan.

Regards,
-- 
Kurt Garloff  <garloff@suse.de>                          Eindhoven, NL
GPG key: See mail header, key servers         Linux kernel development
SuSE GmbH, Nuernberg, DE                                SCSI, Security
--- linux-2.4.16.SuSE-2/drivers/ide/ide-dma.c	Mon Dec  3 01:28:08 2001
+++ linux-2.4.16.SuSE-2.axp/drivers/ide/ide-dma.c	Fri Dec  7 13:24:08 2001
@@ -379,6 +379,21 @@
 			xcount = bcount & 0xffff;
 			if (is_trm290_chipset)
 				xcount = ((xcount >> 2) - 1) << 16;
+#ifdef CONFIG_ALPHA_PYXIS
+			/* Don't cross page boundaries on PYXIS && CMD646 && write */
+			if (HWIF(drive)->chipset == ide_cmd646 && func == ide_dma_write) {
+				if (xcount ==0) 
+					xcount = 0x10000;
+				while ((cur_addr & (PAGE_SIZE-1)) + xcount > PAGE_SIZE) {
+					u32 newcnt = PAGE_SIZE - (cur_addr & (PAGE_SIZE-1));
+					if (count++ >= PRD_ENTRIES)
+						goto use_pio_instead;
+					*table++ = cpu_to_le32(newcnt);
+					*table++ = cpu_to_le32(cur_addr += newcnt);
+					xcount -= newcnt;
+				}
+			}
+#endif
 			if (xcount == 0x0000) {
 				/* 
 				 * Most chipsets correctly interpret a length
@@ -391,12 +406,14 @@
 					goto use_pio_instead;
 
 				*table++ = cpu_to_le32(0x8000);
-				*table++ = cpu_to_le32(cur_addr + 0x8000);
+				*table++ = cpu_to_le32(cur_addr += 0x8000);
 				xcount = 0x8000;
 			}
-			*table++ = cpu_to_le32(xcount);
-			cur_addr += bcount;
+			cur_addr += xcount;
 			cur_len -= bcount;
+			/* KG, 2001-12-07: Mark EOT (bit 31 in length field) */
+			// *table++ = cpu_to_le32(xcount | (cur_len? 0: 0x80000000));
+			*table++ = cpu_to_le32(xcount);
 		}
 
 		sg++;
@@ -654,6 +692,10 @@
 			reading = 1 << 3;
 		case ide_dma_write:
 			SELECT_READ_WRITE(hwif,drive,func);
+#if 0 //def __alpha__
+			if (HWIF(drive)->chipset == ide_cmd646 && func == ide_dma_write)
+				return 1; /* For now, disable DMA writing CMD64x on AXP */
+#endif
 			if (!(count = ide_build_dmatable(drive, func)))
 				return 1;	/* try PIO instead of DMA */
 			outl(hwif->dmatable_dma, dma_base + 4); /* PRD table */

Attachment: pgpKspKS2WEmH.pgp
Description: PGP signature


Reply to: