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

Re: filesystem corruption



"David S. Miller" <davem@redhat.com> writes:

>> On 16 Feb 2004 15:47:00 -0500
>> Marc Horowitz <marc@mit.edu> wrote:
>> 
>> > I went back to my source, and he told me I was incorrect in my earlier
>> > description.  The register which is modified is pci config register
>> > 0x58 on the PCI-ISA bridge, not the ide controller.
>> 
>> That makes a ton more sense.  We are talking about bits 2 and 3
>> in PCI config 0x58 in the PCI-ISA bridge.  These two bits do
>> the same thing, bit 2 for the primary IDE bus and bit 3 for
>> the secondary IDE bus.
>> 
>> If cleared, the bit tri-states the bus channel pins.  If set, the bit
>> makes the bus channel pins get controlled by the IDE controller.

I wrote up a patch of my own, which I've appended.  It doesn't make
anything worse, but it doesn't seem to make anything better, either.
As you can see from the patch, I toggle the necessary bits when the
chipset gets initialized, and whenever one of the ide ports is reset.
So the question I'm still struggling with is when to do this hack.

I'm still trying to get more info about when the vendor os performs
this operation.  It's possible I'll want to move the calls to
ali15x3_tune_chipset or ali15x3_config_drive_for_dma.

>> Something like this ought to implement said workaround.  (not even
>> compile tested, beware :-)
>> 
>> ChangeSet@1.1718, 2004-02-16 22:45:02-08:00, yoshfuji@linux-ipv6.org
>>   [NETFILTER]: Fix signedness overflow in ip{,6}_tables.c
>> diff -Nru a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
>> diff -Nru a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c

Why don't I believe this changeset is going to affect an IDE DMA
problem?  :-)

                Marc

--- kernel-source-2.4.21/drivers/ide/pci/alim15x3.c	2003-05-31 23:06:25.000000000 -0400
+++ /usr/src/kernel-source-2.4.21/drivers/ide/pci/alim15x3.c	2004-02-17 00:12:32.000000000 -0500
@@ -43,6 +43,10 @@
 #include "ide_modes.h"
 #include "alim15x3.h"
 
+#ifdef CONFIG_SPARC64
+#define CHIPSET_BUG_WORKAROUND
+#endif
+
 /*
  *	ALi devices are not plug in. Otherwise these static values would
  *	need to go. They ought to go away anyway
@@ -483,7 +487,6 @@
 	return (ide_config_drive_speed(drive, speed));
 }
 
-
 /**
  *	config_chipset_for_dma	-	set up DMA mode
  *	@drive: drive to configure for
@@ -576,6 +579,46 @@
 	return __ide_dma_write(drive);
 }
 
+#ifdef CHIPSET_BUG_WORKAROUND
+static void ali15x3_sparc64_chipset_fix1(u8 channel, char *name)
+{
+    u8 magic_register;
+    u8 mask;
+
+    if (isa_dev == 0)
+	    return;
+
+    if (channel == 0)
+	    mask = 0x04;
+    else if (channel == 1)
+	    mask = 0x08;
+    else
+	    return;
+
+    pci_read_config_byte(isa_dev, 0x58, &magic_register);
+    pci_write_config_byte(isa_dev, 0x58, magic_register & (~mask));
+    udelay(1000);
+    pci_write_config_byte(isa_dev, 0x58, magic_register);
+
+    printk(KERN_NOTICE "Chipset bug workaround for %s (pci %s) done.\n",
+	   name, isa_dev->name);
+}
+
+/**
+ *	ali15x3_sparc64_chipset_fix	-      Work around a bug in the chipset
+ *	@hwif: IDE interface
+ *
+ *	This fix, adopted from the vendor OS, works around a bug in
+ *	the chipset which causes DMA transfers to be occasionally
+ *	corrupted.
+ */
+
+static void ali15x3_sparc64_chipset_fix(ide_drive_t *drive)
+{
+    ali15x3_sparc64_chipset_fix1(HWIF(drive)->channel, HWIF(drive)->name);
+}
+#endif
+
 /**
  *	init_chipset_ali15x3	-	Initialise an ALi IDE controller
  *	@dev: PCI device
@@ -641,6 +684,21 @@
 	 * 0:0.0 so if we didn't find one we know what is cooking.
 	 */
 	if (north && north->vendor != PCI_VENDOR_ID_AL) {
+#ifdef CHIPSET_BUG_WORKAROUND
+		/* 
+		 * this does the magic reset logic for both channels,
+		 * even though I don't know if there are any devices
+		 * out there yet.
+		 * 
+		 * I don't know if this is truly correct.  The right
+		 * thing would be for the loop at the end of
+		 * probe_hwif() to call hwif->resetproc() on each
+		 * drive.
+		 */
+
+		ali15x3_sparc64_chipset_fix1((u8) 0, "ide0");
+		ali15x3_sparc64_chipset_fix1((u8) 1, "ide1");
+#endif
 		local_irq_restore(flags);
 	        return 0;
 	}
@@ -664,6 +722,7 @@
 			pci_write_config_byte(isa_dev, 0x79, tmpbyte | 0x02);
 		}
 	}
+
 	local_irq_restore(flags);
 	return 0;
 }
@@ -756,6 +814,9 @@
 	hwif->autodma = 0;
 	hwif->tuneproc = &ali15x3_tune_drive;
 	hwif->speedproc = &ali15x3_tune_chipset;
+#ifdef CHIPSET_BUG_WORKAROUND
+	hwif->resetproc = &ali15x3_sparc64_chipset_fix;
+#endif
 
 	/* Don't use LBA48 on ALi devices before rev 0xC5 */
 	hwif->addressing = (m5229_revision <= 0xC4) ? 1 : 0;



Reply to: