Re: MTRR patch causes system lockups

David Wragg (dpw@doc.ic.ac.uk)
Sat, 17 Jan 1998 18:37:32 GMT


mj@atrey.karlin.mff.cuni.cz
In-Reply-To: <199801152226.RAA04236@bucky.physics.ncsu.edu>
X-Mailer: VM 6.22 under 19.15 XEmacs Lucid

Emil Briggs <briggs@bucky.physics.ncsu.edu> writes:
> The MTRR setting patch can cause a system lockup for certain
> motherboards/bioses using the Natoma chipset. I've tested this
> under two P6 motherboards so far and obtained the same results.
> Heres the conditions under which the lockup occurs.
>
>
> 1. write combining to the linear frame buffer is enabled
> 2. passive release is not enabled in the PIIX3 (bit 1 offset 82h)
> 3. access to the floppy drive at the same time as large transfers
> to the LFB are occuring.
>

Here's a kernel patch that should fix the problem (for 2.1.75 onwards)

Putting PCI-related code in with MTRR code is a little ugly, so I've
put the fix in drivers/pci/quirks.c instead (it is a PCI quirk, after
all).

You'll need to say yes to CONFIG_PCI_OPTIMIZE.

(CONFIG_PCI_OPTIMIZE is really a misnomer in 2.1.75 onwards. What do
people think of CONFIG_PCI_QUIRKS, or having a CONFIG option for each
quirk?).

Please let me know whether it does the trick.

Dave Wragg

--- linux-2.1.78/drivers/pci/quirks.c Sat Jan 17 17:49:55 1998
+++ linux/drivers/pci/quirks.c Sat Jan 17 17:53:36 1998
@@ -104,11 +104,41 @@
}
}

+
+/* Deal with broken BIOS'es that neglect to enable passive release,
+ which can cause problems in combination with the 82441FX/PPro MTRRs */
+__initfunc(static void quirk_passive_release(struct pci_dev *dev, int arg))
+{
+ struct pci_dev *piix3;
+ unsigned char dlc;
+
+ /* We need to make sure a particular bit is set in the PIIX3
+ ISA bridge, so we have to go out and find it. */
+ for (piix3 = pci_devices; ; piix3 = piix3->next) {
+ if (!piix3)
+ return;
+
+ if (piix3->vendor == PCI_VENDOR_ID_INTEL
+ && piix3->device == PCI_DEVICE_ID_INTEL_82371SB_0)
+ break;
+ }
+
+ pcibios_read_config_byte(piix3->bus->number, piix3->devfn, 0x82, &dlc);
+
+ if (!(dlc & 1<<1)) {
+ printk("PIIX3: Enabling Passive Release\n");
+ dlc |= 1<<1;
+ pcibios_write_config_byte(piix3->bus->number, piix3->devfn,
+ 0x82, dlc);
+ }
+}
+
/*
* Table of quirk handler functions
*/

#define Q_BRIDGE 0
+#define Q_PASSIVE_RELEASE 1

struct quirk_type {
void (*handler)(struct pci_dev *, int);
@@ -117,6 +147,7 @@

static struct quirk_type quirk_types[] __initdata = {
{ quirk_bridge, "Bridge optimization" },
+ { quirk_passive_release, "Passive release enable" },
};

/*
@@ -132,7 +163,8 @@
{ PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_BRD, Q_BRIDGE, 0x00 },
{ PCI_VENDOR_ID_UMC, PCI_DEVICE_ID_UMC_UM8891A, Q_BRIDGE, 0x01 },
{ PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82424, Q_BRIDGE, 0x00 },
- { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82434, Q_BRIDGE, 0x00 }
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82434, Q_BRIDGE, 0x00 },
+ { PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82441, Q_PASSIVE_RELEASE, 0x00 },
};

__initfunc(void pci_quirks_init(void))