Source-Changes-HG archive

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

[src/trunk]: src/sys/dev/pci The read/read multiple cacheline problem may als...



details:   https://anonhg.NetBSD.org/src/rev/05be8243498f
branches:  trunk
changeset: 581386:05be8243498f
user:      ragge <ragge%NetBSD.org@localhost>
date:      Wed Jun 01 10:00:35 2005 +0000

description:
The read/read multiple cacheline problem may also appear on the 3114
controller, so apply the cacheline fix to it as well.

diffstat:

 sys/dev/pci/satalink.c |  72 ++++++++++++++++++++++++++++---------------------
 1 files changed, 41 insertions(+), 31 deletions(-)

diffs (106 lines):

diff -r 9b98ff1bf6e0 -r 05be8243498f sys/dev/pci/satalink.c
--- a/sys/dev/pci/satalink.c    Wed Jun 01 09:45:15 2005 +0000
+++ b/sys/dev/pci/satalink.c    Wed Jun 01 10:00:35 2005 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: satalink.c,v 1.24 2005/02/27 00:27:34 perry Exp $      */
+/*     $NetBSD: satalink.c,v 1.25 2005/06/01 10:00:35 ragge Exp $      */
 
 /*-
  * Copyright (c) 2003 The NetBSD Foundation, Inc.
@@ -373,13 +373,49 @@
 #define        BA5_WRITE_4(sc, chan, reg, val)                                 \
        ba5_write_4((sc), satalink_ba5_regmap[(chan)].reg, (val))
 
+/*
+ * When the Silicon Image 3112 retries a PCI memory read command,
+ * it may retry it as a memory read multiple command under some
+ * circumstances.  This can totally confuse some PCI controllers,
+ * so ensure that it will never do this by making sure that the
+ * Read Threshold (FIFO Read Request Control) field of the FIFO
+ * Valid Byte Count and Control registers for both channels (BA5
+ * offset 0x40 and 0x44) are set to be at least as large as the
+ * cacheline size register.
+ * This may also happen on the 3114 (ragge 050527)
+ */
+static void
+sii_fixup_cacheline(struct pciide_softc *sc, struct pci_attach_args *pa)
+{
+       pcireg_t cls, reg40, reg44;
+
+       cls = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
+       cls = (cls >> PCI_CACHELINE_SHIFT) & PCI_CACHELINE_MASK;
+       cls *= 4;
+       if (cls > 224) {
+               cls = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
+               cls &= ~(PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT);
+               cls |= ((224/4) << PCI_CACHELINE_SHIFT);
+               pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, cls);
+               cls = 224;
+       }
+       if (cls < 32)
+               cls = 32;
+       cls = (cls + 31) / 32;
+       reg40 = ba5_read_4(sc, 0x40);
+       reg44 = ba5_read_4(sc, 0x44);
+       if ((reg40 & 0x7) < cls)
+               ba5_write_4(sc, 0x40, (reg40 & ~0x07) | cls);
+       if ((reg44 & 0x7) < cls)
+               ba5_write_4(sc, 0x44, (reg44 & ~0x07) | cls);
+}
+
 static void
 sii3112_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
 {
        struct pciide_channel *cp;
        bus_size_t cmdsize, ctlsize;
        pcireg_t interface, scs_cmd, cfgctl;
-       pcireg_t cls, reg40, reg44;
        int channel;
 
        if (pciide_chipen(sc, pa) == 0)
@@ -439,35 +475,7 @@
                sc->sc_dma_boundary = 8192;
        }
 
-       /*
-        * When the Silicon Image 3112 retries a PCI memory read command,
-        * it may retry it as a memory read multiple command under some
-        * circumstances.  This can totally confuse some PCI controllers,
-        * so ensure that it will never do this by making sure that the
-        * Read Threshold (FIFO Read Request Control) field of the FIFO
-        * Valid Byte Count and Control registers for both channels (BA5
-        * offset 0x40 and 0x44) are set to be at least as large as the
-        * cacheline size register.
-        */
-       cls = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
-       cls = (cls >> PCI_CACHELINE_SHIFT) & PCI_CACHELINE_MASK;
-       cls *= 4;
-       if (cls > 224) {
-               cls = pci_conf_read(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG);
-               cls &= ~(PCI_CACHELINE_MASK << PCI_CACHELINE_SHIFT);
-               cls |= ((224/4) << PCI_CACHELINE_SHIFT);
-               pci_conf_write(pa->pa_pc, pa->pa_tag, PCI_BHLC_REG, cls);
-               cls = 224;
-       }
-       if (cls < 32)
-               cls = 32;
-       cls = (cls + 31) / 32;
-       reg40 = ba5_read_4(sc, 0x40);
-       reg44 = ba5_read_4(sc, 0x44);
-       if ((reg40 & 0x7) < cls)
-               ba5_write_4(sc, 0x40, (reg40 & ~0x07) | cls);
-       if ((reg44 & 0x7) < cls)
-               ba5_write_4(sc, 0x44, (reg44 & ~0x07) | cls);
+       sii_fixup_cacheline(sc, pa);
 
        sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16 | ATAC_CAP_DATA32;
        sc->sc_wdcdev.sc_atac.atac_pio_cap = 4;
@@ -712,6 +720,8 @@
        sii3114_mapreg_dma(sc, pa);
        aprint_normal("\n");
 
+       sii_fixup_cacheline(sc, pa);
+
        sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DATA16 | ATAC_CAP_DATA32;
        sc->sc_wdcdev.sc_atac.atac_pio_cap = 4;
        if (sc->sc_dma_ok) {



Home | Main Index | Thread Index | Old Index