Subject: looking for VIA/NVIDIA sata testers
To: None <current-users@netbsd.org>
From: Manuel Bouyer <bouyer@antioche.eu.org>
List: current-users
Date: 10/25/2006 23:20:53
--EeQfGwPcQSOJBaQU
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi,
attached is a patch that makes viaide(4) use SATA registers do probe
drives, and also correct a few things for the VIA VT6421, and
adds the VT8237A to the table. Unfortunably I don't have any way
to test this. So if you have a Via or Nvidia system with SATA drive,
please give it a try if you can. If no drive is found please set
atadebug_mask to 0xff and send the boot messages.
There is also a distribution built with these changes, for convenience
(there are floppy and iso image here):
ftp://ftp-asim.lip6.fr/outgoing/bouyer/i386/

Thanks !

-- 
Manuel Bouyer <bouyer@antioche.eu.org>
     NetBSD: 26 ans d'experience feront toujours la difference
--

--EeQfGwPcQSOJBaQU
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="diff.viaide"

Index: pci/viaide.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/viaide.c,v
retrieving revision 1.34
diff -u -r1.34 viaide.c
--- pci/viaide.c	12 Oct 2006 01:31:33 -0000	1.34
+++ pci/viaide.c	25 Oct 2006 21:11:37 -0000
@@ -44,7 +44,17 @@
 
 static int	via_pcib_match(struct pci_attach_args *);
 static void	via_chip_map(struct pciide_softc *, struct pci_attach_args *);
+static int	via_sata_chip_map_common(struct pciide_softc *,
+		    struct pci_attach_args *);
 static void	via_sata_chip_map(struct pciide_softc *,
+		    struct pci_attach_args *, int);
+static void	via_sata_chip_map_0(struct pciide_softc *,
+		    struct pci_attach_args *);
+static void	via_sata_chip_map_6(struct pciide_softc *,
+		    struct pci_attach_args *);
+static void	via_sata_chip_map_7(struct pciide_softc *,
+		    struct pci_attach_args *);
+static void	via_sata_chip_map_new(struct pciide_softc *,
 		    struct pci_attach_args *);
 static void	via_setup_channel(struct ata_channel *);
 
@@ -103,7 +113,7 @@
 	{ PCI_PRODUCT_NVIDIA_NFORCE2_400_SATA,
 	  0,
 	  "NVIDIA nForce2 Ultra 400 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ PCI_PRODUCT_NVIDIA_NFORCE3_ATA133,
 	  0,
@@ -118,12 +128,12 @@
 	{ PCI_PRODUCT_NVIDIA_NFORCE3_250_SATA,
 	  0,
 	  "NVIDIA nForce3 250 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ PCI_PRODUCT_NVIDIA_NFORCE3_250_SATA2,
 	  0,
 	  "NVIDIA nForce3 250 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ PCI_PRODUCT_NVIDIA_NFORCE4_ATA133,
 	  0,
@@ -133,12 +143,12 @@
 	{ PCI_PRODUCT_NVIDIA_NFORCE4_SATA1,
 	  0,
 	  "NVIDIA nForce4 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ PCI_PRODUCT_NVIDIA_NFORCE4_SATA2,
 	  0,
 	  "NVIDIA nForce4 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ PCI_PRODUCT_NVIDIA_NFORCE430_ATA133,
 	  0,
@@ -148,12 +158,12 @@
 	{ PCI_PRODUCT_NVIDIA_NFORCE430_SATA1,
 	  0,
 	  "NVIDIA nForce430 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ PCI_PRODUCT_NVIDIA_NFORCE430_SATA2,
 	  0,
 	  "NVIDIA nForce430 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ PCI_PRODUCT_NVIDIA_MCP04_IDE,
 	  0,
@@ -163,12 +173,12 @@
 	{ PCI_PRODUCT_NVIDIA_MCP04_SATA,
 	  0,
 	  "NVIDIA MCP04 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ PCI_PRODUCT_NVIDIA_MCP04_SATA2,
 	  0,
 	  "NVIDIA MCP04 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ PCI_PRODUCT_NVIDIA_MCP55_IDE,
 	  0,
@@ -178,12 +188,12 @@
 	{ PCI_PRODUCT_NVIDIA_MCP55_SATA,
 	  0,
 	  "NVIDIA MCP55 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ PCI_PRODUCT_NVIDIA_MCP55_SATA2,
 	  0,
 	  "NVIDIA MCP55 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ PCI_PRODUCT_NVIDIA_MCP61_IDE,
 	  0,
@@ -198,37 +208,37 @@
 	{ PCI_PRODUCT_NVIDIA_MCP61_SATA,
 	  0,
 	  "NVIDIA MCP61 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ PCI_PRODUCT_NVIDIA_MCP61_SATA2,
 	  0,
 	  "NVIDIA MCP61 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ PCI_PRODUCT_NVIDIA_MCP61_SATA3,
 	  0,
 	  "NVIDIA MCP61 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ PCI_PRODUCT_NVIDIA_MCP65_SATA,
 	  0,
 	  "NVIDIA MCP65 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ PCI_PRODUCT_NVIDIA_MCP65_SATA2,
 	  0,
 	  "NVIDIA MCP65 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ PCI_PRODUCT_NVIDIA_MCP65_SATA3,
 	  0,
 	  "NVIDIA MCP65 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ PCI_PRODUCT_NVIDIA_MCP65_SATA4,
 	  0,
 	  "NVIDIA MCP65 Serial ATA Controller",
-	  via_sata_chip_map
+	  via_sata_chip_map_6
 	},
 	{ 0,
 	  0,
@@ -251,17 +261,22 @@
 	{ PCI_PRODUCT_VIATECH_VT6421_RAID,
 	  0,
 	  "VIA Technologies VT6421 Serial RAID Controller",
-	  via_sata_chip_map,
+	  via_sata_chip_map_new,
 	},
 	{ PCI_PRODUCT_VIATECH_VT8237_SATA,
 	  0,
 	  "VIA Technologies VT8237 SATA Controller",
-	  via_sata_chip_map,
+	  via_sata_chip_map_7,
+	},
+	{ PCI_PRODUCT_VIATECH_VT8237A_SATA,
+	  0,
+	  "VIA Technologies VT8237A SATA Controller",
+	  via_sata_chip_map_0,
 	},
 	{ PCI_PRODUCT_VIATECH_VT8237R_SATA,
 	  0,
 	  "VIA Technologies VT8237R SATA Controller",
-	  via_sata_chip_map,
+	  via_sata_chip_map_0,
 	},
 	{ 0,
 	  0,
@@ -632,23 +647,13 @@
 	    pci_conf_read(sc->sc_pc, sc->sc_tag, APO_UDMA(sc))), DEBUG_PROBE);
 }
 
-static void
-via_sata_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
+static int
+via_sata_chip_map_common(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;
+	bus_size_t satasize;
 
 	if (pciide_chipen(sc, pa) == 0)
-		return;
-
-	if (interface == 0) {
-		ATADEBUG_PRINT(("via_sata_chip_map interface == 0\n"),
-		    DEBUG_PROBE);
-		interface = PCIIDE_INTERFACE_BUS_MASTER_DMA |
-		    PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
-	}
+		return 0;
 
 	aprint_normal("%s: bus-master DMA support present",
 	    sc->sc_wdcdev.sc_atac.atac_dev.dv_xname);
@@ -669,13 +674,212 @@
 	sc->sc_wdcdev.sc_atac.atac_set_modes = sata_setup_channel;
 
 	wdc_allocate_regs(&sc->sc_wdcdev);
+	if (pci_mapreg_map(pa, PCI_MAPREG_START + 0x14,
+	    PCI_MAPREG_TYPE_IO, 0, &sc->sc_ba5_st, &sc->sc_ba5_sh,
+	    NULL, &satasize) != 0) {
+		if (pci_mapreg_map(pa, PCI_MAPREG_START + 0x14,
+		    PCI_MAPREG_TYPE_MEM | PCI_MAPREG_MEM_TYPE_32BIT,
+		    0, &sc->sc_ba5_st, &sc->sc_ba5_sh,
+		    NULL, &satasize) != 0) {
+			aprint_error("%s: couldn't map sata regs\n",
+			sc->sc_wdcdev.sc_atac.atac_dev.dv_xname);
+			return 0;
+		}
+	}
+	return 1;
+}
+
+static void
+via_sata_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa,
+    int satareg_shift)
+{
+	struct pciide_channel *cp;
+	struct ata_channel *wdc_cp;
+	struct wdc_regs *wdr;
+	pcireg_t interface = PCI_INTERFACE(pa->pa_class);
+	int channel;
+	bus_size_t cmdsize, ctlsize;
+
+	if (via_sata_chip_map_common(sc, pa) == 0)
+		return;
+
+	if (interface == 0) {
+		ATADEBUG_PRINT(("via_sata_chip_map interface == 0\n"),
+		    DEBUG_PROBE);
+		interface = PCIIDE_INTERFACE_BUS_MASTER_DMA |
+		    PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
+	}
 
 	for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels;
 	     channel++) {
 		cp = &sc->pciide_channels[channel];
 		if (pciide_chansetup(sc, channel, interface) == 0)
 			continue;
+		wdc_cp = &cp->ata_channel;
+		wdr = CHAN_TO_WDC_REGS(wdc_cp);
+		wdr->sata_iot = sc->sc_ba5_st;
+		wdr->sata_baseioh = sc->sc_ba5_sh;
+		if (bus_space_subregion(wdr->sata_iot, wdr->sata_baseioh,
+		    (wdc_cp->ch_channel << satareg_shift) + 0x0, 1,
+		    &wdr->sata_status) != 0) {
+			aprint_error("%s: couldn't map channel %d "
+			    "sata_status regs\n",
+			    sc->sc_wdcdev.sc_atac.atac_dev.dv_xname,
+			    wdc_cp->ch_channel);
+			continue;
+		}
+		if (bus_space_subregion(wdr->sata_iot, wdr->sata_baseioh,
+		    (wdc_cp->ch_channel << satareg_shift) + 0x4, 1,
+		    &wdr->sata_error) != 0) {
+			aprint_error("%s: couldn't map channel %d "
+			    "sata_error regs\n",
+			    sc->sc_wdcdev.sc_atac.atac_dev.dv_xname,
+			    wdc_cp->ch_channel);
+			continue;
+		}
+		if (bus_space_subregion(wdr->sata_iot, wdr->sata_baseioh,
+		    (wdc_cp->ch_channel << satareg_shift) + 0x8, 1,
+		    &wdr->sata_control) != 0) {
+			aprint_error("%s: couldn't map channel %d "
+			    "sata_control regs\n",
+			    sc->sc_wdcdev.sc_atac.atac_dev.dv_xname,
+			    wdc_cp->ch_channel);
+			continue;
+		}
+		sc->sc_wdcdev.sc_atac.atac_probe = wdc_sataprobe;
 		pciide_mapchan(pa, cp, interface, &cmdsize, &ctlsize,
 		    pciide_pci_intr);
 	}
 }
+
+static void
+via_sata_chip_map_0(struct pciide_softc *sc, struct pci_attach_args *pa)
+{
+	via_sata_chip_map(sc, pa, 0);
+}
+
+static void
+via_sata_chip_map_6(struct pciide_softc *sc, struct pci_attach_args *pa)
+{
+	via_sata_chip_map(sc, pa, 6);
+}
+
+static void
+via_sata_chip_map_7(struct pciide_softc *sc, struct pci_attach_args *pa)
+{
+	via_sata_chip_map(sc, pa, 7);
+}
+
+static void
+via_sata_chip_map_new(struct pciide_softc *sc, struct pci_attach_args *pa)
+{
+	struct pciide_channel *cp;
+	struct ata_channel *wdc_cp;
+	struct wdc_regs *wdr;
+	pcireg_t interface = PCI_INTERFACE(pa->pa_class);
+	int channel;
+	bus_size_t cmdsize;
+	pci_intr_handle_t intrhandle;
+	const char *intrstr;
+	int i;
+
+	if (via_sata_chip_map_common(sc, pa) == 0)
+		return;
+
+	if (interface == 0) {
+		ATADEBUG_PRINT(("via_sata_chip_map interface == 0\n"),
+		    DEBUG_PROBE);
+		interface = PCIIDE_INTERFACE_BUS_MASTER_DMA |
+		    PCIIDE_INTERFACE_PCI(0) | PCIIDE_INTERFACE_PCI(1);
+	}
+
+	if (pci_intr_map(pa, &intrhandle) != 0) {
+		aprint_error("%s: couldn't map native-PCI interrupt\n",
+		    sc->sc_wdcdev.sc_atac.atac_dev.dv_xname);
+		return;
+	}
+	intrstr = pci_intr_string(pa->pa_pc, intrhandle);
+	sc->sc_pci_ih = pci_intr_establish(pa->pa_pc,
+	    intrhandle, IPL_BIO, pciide_pci_intr, sc);
+	if (sc->sc_pci_ih == NULL) {
+		aprint_error(
+		    "%s: couldn't establish native-PCI interrupt",
+		    sc->sc_wdcdev.sc_atac.atac_dev.dv_xname);
+		if (intrstr != NULL)
+		    aprint_error(" at %s", intrstr);
+		aprint_error("\n");
+		return;
+	}
+	aprint_normal("%s: using %s for native-PCI interrupt\n",
+	    sc->sc_wdcdev.sc_atac.atac_dev.dv_xname,
+	    intrstr ? intrstr : "unknown interrupt");
+
+	for (channel = 0; channel < sc->sc_wdcdev.sc_atac.atac_nchannels;
+	     channel++) {
+		cp = &sc->pciide_channels[channel];
+		if (pciide_chansetup(sc, channel, interface) == 0)
+			continue;
+		cp->ata_channel.ch_ndrive = 1;
+		wdc_cp = &cp->ata_channel;
+		wdr = CHAN_TO_WDC_REGS(wdc_cp);
+
+		wdr->sata_iot = sc->sc_ba5_st;
+		wdr->sata_baseioh = sc->sc_ba5_sh;
+		if (bus_space_subregion(wdr->sata_iot, wdr->sata_baseioh,
+		    (wdc_cp->ch_channel << 6) + 0x0, 1,
+		    &wdr->sata_status) != 0) {
+			aprint_error("%s: couldn't map channel %d "
+			    "sata_status regs\n",
+			    sc->sc_wdcdev.sc_atac.atac_dev.dv_xname,
+			    wdc_cp->ch_channel);
+			continue;
+		}
+		if (bus_space_subregion(wdr->sata_iot, wdr->sata_baseioh,
+		    (wdc_cp->ch_channel << 6) + 0x4, 1,
+		    &wdr->sata_error) != 0) {
+			aprint_error("%s: couldn't map channel %d "
+			    "sata_error regs\n",
+			    sc->sc_wdcdev.sc_atac.atac_dev.dv_xname,
+			    wdc_cp->ch_channel);
+			continue;
+		}
+		if (bus_space_subregion(wdr->sata_iot, wdr->sata_baseioh,
+		    (wdc_cp->ch_channel << 6) + 0x8, 1,
+		    &wdr->sata_control) != 0) {
+			aprint_error("%s: couldn't map channel %d "
+			    "sata_control regs\n",
+			    sc->sc_wdcdev.sc_atac.atac_dev.dv_xname,
+			    wdc_cp->ch_channel);
+			continue;
+		}
+		sc->sc_wdcdev.sc_atac.atac_probe = wdc_sataprobe;
+
+		if (pci_mapreg_map(pa, (0x10 + (4 * (channel))),
+		    PCI_MAPREG_TYPE_IO, 0, &wdr->cmd_iot, &wdr->cmd_baseioh,
+		    NULL, &cmdsize) != 0) {
+			aprint_error("%s: couldn't map %s channel regs\n",
+			    sc->sc_wdcdev.sc_atac.atac_dev.dv_xname,
+			    cp->name);
+		}
+		wdr->ctl_iot = wdr->cmd_iot;
+		for (i = 0; i < WDC_NREG; i++) {
+			if (bus_space_subregion(wdr->cmd_iot,
+			    wdr->cmd_baseioh, i, i == 0 ? 4 : 1,
+			    &wdr->cmd_iohs[i]) != 0) {
+				aprint_error("%s: couldn't subregion %s "
+				    "channel cmd regs\n",
+				    sc->sc_wdcdev.sc_atac.atac_dev.dv_xname,
+				    cp->name);
+				return;
+			}
+		}
+		if (bus_space_subregion(wdr->cmd_iot, wdr->cmd_baseioh,
+		    WDC_NREG + 2, 1,  &wdr->ctl_ioh) != 0) {
+			aprint_error("%s: couldn't map channel %d ctl regs\n",
+			    sc->sc_wdcdev.sc_atac.atac_dev.dv_xname, channel);
+			return;
+		}
+		wdc_init_shadow_regs(wdc_cp);
+		wdcattach(wdc_cp);
+	}
+}

--EeQfGwPcQSOJBaQU--