Subject: kern/22727: support for VIA 8237 Serial ATA Controller
To: None <gnats-bugs@gnats.netbsd.org>
From: Stephen Degler <stephen@degler.net>
List: netbsd-bugs
Date: 09/08/2003 23:43:18
>Number:         22727
>Category:       kern
>Synopsis:       support for VIA 8237 Serial ATA Controller
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Sep 09 03:44:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator:     Stephen Degler
>Release:        NetBSD 1.6Z
>Organization:
	Very Little, At Best
>Environment:
	
	
System: NetBSD kashmir.degler.net 1.6Z NetBSD 1.6Z (KASHMIR) #96: Mon Sep 8 23:10:47 EDT 2003 sdegler@kashmir.degler.net:/vol1/NetBSD/kernels/KASHMIR i386
Architecture: i386
Machine: i386
>Description:
	This patch adds support to the Serial ATA Controller on the
	VIA VT8237 South Bridge.
>How-To-Repeat:
	Boot NetBSD.  See the SATA controllers not be configured.
>Fix:
	Apply included patch.  See controller configure.  Use hard 
	attached to controller.

	Also, I suggest changing product VT8237_RAID to VT8237_SATA
	just as a clarification.  This patch is against the current
	name.
	
Index: sys/dev/pci/pciide.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/pciide.c,v
retrieving revision 1.196
diff -u -r1.196 pciide.c
--- sys/dev/pci/pciide.c	2003/08/17 15:52:06	1.196
+++ sys/dev/pci/pciide.c	2003/09/09 03:31:30
@@ -175,6 +175,7 @@
 void amd7x6_setup_channel __P((struct channel_softc*));
 
 void apollo_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
+void apollo_sata_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
 void apollo_setup_channel __P((struct channel_softc*));
 
 void cmd_chip_map __P((struct pciide_softc*, struct pci_attach_args*));
@@ -444,6 +445,11 @@
 	  NULL,
 	  apollo_chip_map,
 	},
+	{ PCI_PRODUCT_VIATECH_VT8237_RAID,
+	  IDE_PCI_CLASS_OVERRIDE,
+	  NULL,
+	  apollo_sata_chip_map,
+	},
 	{ 0,
 	  0,
 	  NULL,
@@ -2539,6 +2545,83 @@
 	pciide_print_modes(cp);
 	pci_conf_write(sc->sc_pc, sc->sc_tag, APO_DATATIM, datatim_reg);
 	pci_conf_write(sc->sc_pc, sc->sc_tag, APO_UDMA, udmatim_reg);
+}
+
+void
+apollo_sata_chip_map(sc, pa)
+	struct pciide_softc *sc;
+	struct pci_attach_args *pa;
+{
+	struct pciide_channel *cp;
+	pcireg_t interface = PCI_INTERFACE(pa->pa_class);
+	int channel;
+	bus_size_t cmdsize, ctlsize;
+
+	if (pciide_chipen(sc, pa) == 0)
+		return;
+
+	if ( interface == 0 ) {
+		WDCDEBUG_PRINT(("apollo_sata_chip_map interface == 0\n"),
+			       DEBUG_PROBE);
+		interface = PCIIDE_INTERFACE_BUS_MASTER_DMA |
+			PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
+	}
+
+	aprint_normal(": VIA Technologies ");
+	switch (sc->sc_pp->ide_product) {
+
+	case PCI_PRODUCT_VIATECH_VT8237_RAID:
+		aprint_normal("VT8237 SATA Controller\n");
+		break;
+	default:
+		aprint_normal("Unknown SATA Controller\n");
+	}
+
+	aprint_normal("%s: bus-master DMA support present",
+		      sc->sc_wdcdev.sc_dev.dv_xname);
+	pciide_mapreg_dma(sc, pa);
+
+	aprint_normal("\n");
+	if (sc->sc_dma_ok) {
+		sc->sc_wdcdev.cap |= WDC_CAPABILITY_UDMA | WDC_CAPABILITY_DMA | WDC_CAPABILITY_IRQACK;
+		sc->sc_wdcdev.irqack = pciide_irqack;
+	}
+	sc->sc_wdcdev.PIO_cap = 4;
+	sc->sc_wdcdev.DMA_cap = 2;
+	sc->sc_wdcdev.UDMA_cap = 6;
+
+	sc->sc_wdcdev.channels = sc->wdc_chanarray;
+	sc->sc_wdcdev.nchannels = PCIIDE_NUM_CHANNELS;
+	sc->sc_wdcdev.cap |= WDC_CAPABILITY_DATA16 | WDC_CAPABILITY_DATA32 |
+		WDC_CAPABILITY_MODE | WDC_CAPABILITY_SINGLE_DRIVE;
+	sc->sc_wdcdev.set_modes = sata_setup_channel;
+
+	for (channel = 0; channel < sc->sc_wdcdev.nchannels; channel++) {
+		cp = &sc->pciide_channels[channel];
+		if (pciide_chansetup(sc, channel, interface) == 0)
+			continue;
+
+		if (interface & PCIIDE_INTERFACE_PCI(channel)) {
+			cp->hw_ok = pciide_mapregs_native(pa, cp, &cmdsize,
+			    &ctlsize, pciide_pci_intr);
+		} else {
+			/* When is this going to happen?? */
+			cp->hw_ok = pciide_mapregs_compat(pa, cp,
+							  channel,
+							  &cmdsize, &ctlsize);
+		}
+
+		if (cp->hw_ok == 0) {
+			continue;
+		} else {
+			pciide_map_compat_intr(pa, cp, channel, interface);
+			cp->wdc_channel.data32iot = cp->wdc_channel.cmd_iot;
+			cp->wdc_channel.data32ioh = cp->wdc_channel.cmd_ioh;
+			wdcattach(&cp->wdc_channel);
+			if (sc->sc_dma_ok)
+				sata_setup_channel(&cp->wdc_channel);
+		}
+	}
 }
 
 void

>Release-Note:
>Audit-Trail:
>Unformatted: