[PATCH v2 2/2] alpha: disable DAC for 32-bit PCI cards on Tsunami/Typhoon

Magnus Lindholm <[email protected]>
Newsgroups gmane.linux.ports.alpha,gmane.linux.kernel
Message-ID <[email protected]>
The Tsunami/Typhoon Pchip's DAC ("monster window") path corrupts data
when used by 32-bit PCI cards using DAC addresses above 4 GiB, even on
cards whose DAC support is otherwise solid: the same cards work
correctly with DAC on Rawhide (MCPCIA) systems, and native 64-bit PCI
cards are unaffected on Tsunami/Typhoon itself. Corruption shows up as
64-byte chunks (one 21264 cache block) of unrelated data - typically
identifiable content belonging to other processes' concurrent DMA -
substituted into the transfer; the rate varies from none to several
kilobytes per run and has not been tied to any particular alignment.

Work around this by capping affected devices to 32-bit DMA, which
routes them through the existing scatter-gather window instead of DAC.
Conventional PCI provides no status bit to distinguish a 32-bit from a
64-bit option card, so use the presence of a 64-bit memory BAR as a
practical proxy. This covers every affected card seen so far, but is
a proxy rather than a direct test: it will also needlessly restrict a
handful of 64-bit cards that only expose 32-bit BARs (e.g. QLogic
ISP1080, ISP10160). These controllers are not known to be supported by
SRM firmware and are therefore uncommon on Alpha systems, so the
trade-off is accepted.

The only driver currently known to hit this is qla1280 with an
ISP1040 card and a 64-bit DMA mask, which is a common and
SRM-supported configuration on Alpha.

Suggested-by: Maciej Rozycki <[email protected]>
Signed-off-by: Magnus Lindholm <[email protected]>
---
 arch/alpha/kernel/pci.c | 22 ++++++++++++++++++++++
 1 file changed, 22 insertions(+)

diff --git a/arch/alpha/kernel/pci.c b/arch/alpha/kernel/pci.c
index 11df411b1d18..7dbf380acd93 100644
--- a/arch/alpha/kernel/pci.c
+++ b/arch/alpha/kernel/pci.c
@@ -23,6 +23,8 @@
 #include <linux/cache.h>
 #include <linux/slab.h>
 #include <linux/syscalls.h>
+#include <linux/dma-mapping.h>
+#include <asm/hwrpb.h>
 #include <asm/machvec.h>
 
 #include "proto.h"
@@ -117,6 +119,26 @@ static void pcibios_fixup_final(struct pci_dev *dev)
 }
 DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_final);
 
+/*
+ * Tsunami/Typhoon's DAC "monster window" corrupts data on 32-bit PCI
+ * cards; cap them to 32-bit DMA by proxy of having no 64-bit BAR.
+ */
+static void tsunami_dac_quirk(struct pci_dev *pdev)
+{
+	int i;
+
+	if (hwrpb->sys_type != ST_DEC_TSUNAMI)
+		return;
+
+	for (i = 0; i <= PCI_STD_RESOURCE_END; i++)
+		if (pci_resource_flags(pdev, i) & IORESOURCE_MEM_64)
+			return;
+
+	pdev->dev.bus_dma_limit = DMA_BIT_MASK(32);
+	dev_dbg(&pdev->dev, "disabling DAC for device\n");
+}
+DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, tsunami_dac_quirk);
+
 /* Just declaring that the power-of-ten prefixes are actually the
    power-of-two ones doesn't make it true :) */
 #define KB			1024
-- 
2.53.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.