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;