Subject: kern/37519: satalink: patch for 3114
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: None <kanaoka@ann.hi-ho.ne.jp>
List: netbsd-bugs
Date: 12/11/2007 13:50:00
>Number: 37519
>Category: kern
>Synopsis: satalink: patch for 3114
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: kern-bug-people
>State: open
>Class: support
>Submitter-Id: net
>Arrival-Date: Tue Dec 11 13:50:00 +0000 2007
>Originator: Masanori Kanaoka
>Release: NetBSD 4.99.41/i386
>Organization:
>Environment:
NetBSD lab.k.vnop.net 4.99.41 NetBSD 4.99.41 (GENERIC.MP) #0: Mon Dec 10 23:32:36 JST 2007 root@lab.k.vnop.net:/usr/obj/sys/arch/i386/compile/GENERIC.MP i386
>Description:
satalink have problem cacheline but sii_fixup_cacheline() fixup
for 3112.
sii_fixup_cacheline() do fixup channel0(0x40) and channel1(0x44).
3114 have channel2(0x240) and channel3(0x244) but does not fixup.
>How-To-Repeat:
use channel2, channel3 with silcon image 3114.
>Fix:
I attached a patch, not test.
--- satalink.c.orig 2007-12-11 21:08:14.000000000 +0900
+++ satalink.c 2007-12-11 21:09:02.000000000 +0900
@@ -414,6 +414,39 @@
ba5_write_4(sc, 0x44, (reg44 & ~0x07) | cls);
}
+
+static void
+sii3114_fixup_cacheline(struct pciide_softc *sc, struct pci_attach_args *pa)
+{
+ pcireg_t cls, reg40, reg44, reg240, reg244;
+
+ 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);
+ reg240 = ba5_read_4(sc, 0x240);
+ reg244 = ba5_read_4(sc, 0x244);
+ if ((reg40 & 0x7) < cls)
+ ba5_write_4(sc, 0x40, (reg40 & ~0x07) | cls);
+ if ((reg44 & 0x7) < cls)
+ ba5_write_4(sc, 0x44, (reg44 & ~0x07) | cls);
+ if ((reg240 & 0x7) < cls)
+ ba5_write_4(sc, 0x240, (reg240 & ~0x07) | cls);
+ if ((reg244 & 0x7) < cls)
+ ba5_write_4(sc, 0x244, (reg244 & ~0x07) | cls);
+}
+
static void
sii3112_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
{
@@ -725,7 +758,7 @@
sii3114_mapreg_dma(sc, pa);
aprint_verbose("\n");
- sii_fixup_cacheline(sc, pa);
+ sii3114_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;