summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorbouyer <bouyer@NetBSD.org>2006-03-06 18:35:24 +0000
committerbouyer <bouyer@NetBSD.org>2006-03-06 18:35:24 +0000
commitf656fa41eb4a793d30bdd41614deebad9ce3e277 (patch)
tree9e38d3a7ec1c47f7e9b04ccbcfbae73068f66e35
parent21d185683caf39527978cf219b0dc6b9ef66cde1 (diff)
Add svwsata(4), a driver for Serverworks K2 SATA controllers. From
OpenBSD via Joerg Sonnenberger.
-rw-r--r--doc/CHANGES4
-rw-r--r--share/man/man4/Makefile5
-rw-r--r--share/man/man4/pciide.45
-rw-r--r--share/man/man4/svwsata.459
-rw-r--r--sys/arch/i386/conf/GENERIC5
-rw-r--r--sys/arch/i386/conf/INSTALL3
-rw-r--r--sys/arch/i386/conf/XEN03
-rw-r--r--sys/dev/pci/files.pci7
-rw-r--r--sys/dev/pci/pcidevs3
-rw-r--r--sys/dev/pci/pciide_svwsata_reg.h40
-rw-r--r--sys/dev/pci/pciidevar.h7
-rw-r--r--sys/dev/pci/svwsata.c366
12 files changed, 495 insertions, 12 deletions
diff --git a/doc/CHANGES b/doc/CHANGES
index eb12d8d93c6..a842f07a0aa 100644
--- a/doc/CHANGES
+++ b/doc/CHANGES
@@ -1,4 +1,4 @@
-LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.593 $>
+LIST OF CHANGES FROM LAST RELEASE: <$Revision: 1.594 $>
[Note: This file does not mention every change made to the NetBSD source tree.
@@ -220,3 +220,5 @@ Changes from NetBSD 3.0 to NetBSD 4.0:
kernel: Add support for PT_SYSCALL, a ptrace call that allows processes
to stop on syscall entry and exit. Used by tools like
strace/truss [christos 20060305]
+ svwsata(4): Driver for Serverworks K2 SATA controllers. From
+ OpenBSD via Joerg Sonnenberger [bouyer 20060306]
diff --git a/share/man/man4/Makefile b/share/man/man4/Makefile
index 7259d49aaf4..e73791da07f 100644
--- a/share/man/man4/Makefile
+++ b/share/man/man4/Makefile
@@ -1,4 +1,4 @@
-# $NetBSD: Makefile,v 1.375 2006/02/25 01:58:03 christos Exp $
+# $NetBSD: Makefile,v 1.376 2006/03/06 18:35:24 bouyer Exp $
# @(#)Makefile 8.1 (Berkeley) 6/18/93
MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 adc.4 adt7467c.4 adv.4 \
@@ -37,7 +37,8 @@ MAN= aac.4 ac97.4 acardide.4 aceride.4 acphy.4 adc.4 adt7467c.4 adv.4 \
satalink.4 sbus.4 scc.4 scsi.4 sd.4 se.4 sem.4 ses.4 sf.4 sfb.4 shb.4 \
shpcic.4 siop.4 sip.4 siside.4 sk.4 sl.4 slide.4 \
sm.4 spc.4 speaker.4 spif.4 spp.4 sqphy.4 ss.4 \
- st.4 ste.4 stge.4 sti.4 stpcide.4 sv.4 strip.4 swwdog.4 systrace.4 \
+ st.4 ste.4 stge.4 sti.4 stpcide.4 sv.4 strip.4 \
+ svwsata.4 swwdog.4 systrace.4 \
tap.4 tc.4 tcds.4 tcp.4 termios.4 tfb.4 ti.4 \
tl.4 tlp.4 tlphy.4 tp.4 tr.4 tra.4 trm.4 tty.4 tun.4 \
tqphy.4 twe.4 txp.4 ubsec.4 udp.4 uep.4 uha.4 uk.4 ukphy.4 \
diff --git a/share/man/man4/pciide.4 b/share/man/man4/pciide.4
index 01a601c2aa0..dad951e6aa1 100644
--- a/share/man/man4/pciide.4
+++ b/share/man/man4/pciide.4
@@ -1,4 +1,4 @@
-.\" $NetBSD: pciide.4,v 1.59 2005/03/08 10:50:09 wiz Exp $
+.\" $NetBSD: pciide.4,v 1.60 2006/03/06 18:35:24 bouyer Exp $
.\"
.\" Copyright (c) 1998,2003 Manuel Bouyer.
.\"
@@ -90,6 +90,9 @@ PDC20268 (Ultra/100TX2 and Ultra/100TX2v2), Ultra/133, Ultra/133TX2 and
Ultra/133TX2v2 PCI IDE controllers:
.Xr pdcide 4
.It
+Serverworks K2 SATA controllers:
+.Xr svwsata 4
+.It
Silicon Image 0680 IDE controller:
.Xr cmdide 4
.It
diff --git a/share/man/man4/svwsata.4 b/share/man/man4/svwsata.4
new file mode 100644
index 00000000000..711796c166b
--- /dev/null
+++ b/share/man/man4/svwsata.4
@@ -0,0 +1,59 @@
+.\" $NetBSD: svwsata.4,v 1.1 2006/03/06 18:36:29 bouyer Exp $
+.\"
+.\" Copyright (c) 2006 Manuel Bouyer.
+.\"
+.\" Redistribution and use in source and binary forms, with or without
+.\" modification, are permitted provided that the following conditions
+.\" are met:
+.\" 1. Redistributions of source code must retain the above copyright
+.\" notice, this list of conditions and the following disclaimer.
+.\" 2. Redistributions in binary form must reproduce the above copyright
+.\" notice, this list of conditions and the following disclaimer in the
+.\" documentation and/or other materials provided with the distribution.
+.\" 3. All advertising materials mentioning features or use of this software
+.\" must display the following acknowledgement:
+.\" This product includes software developed by Manuel Bouyer.
+.\" 4. The name of the author may not be used to endorse or promote products
+.\" derived from this software without specific prior written permission.
+.\"
+.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+.\" IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+.\" OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+.\" IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+.\" INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+.\" NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+.\" DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+.\" THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+.\" INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+.\"
+.Dd March 6, 2006
+.Dt SVWSATA 4
+.Os
+.Sh NAME
+.Nm svwsata
+.Nd Serverworks K2 Serial ATA disk controller driver
+.Sh SYNOPSIS
+.Cd "svwsata* at pci? dev ? function ? flags 0x0000"
+.Sh DESCRIPTION
+The
+.Nm
+driver supports the Serverworks K2 Serial ATA and controllers,
+and provides the interface with the hardware for the
+.Xr ata 4
+driver.
+.Pp
+The 0x0002 flag forces the
+.Nm
+driver to disable DMA on chipsets for which DMA would normally be
+enabled.
+This can be used as a debugging aid, or to work around
+problems where the SATA controller is wired up to the system incorrectly.
+.Sh SEE ALSO
+.Xr ata 4 ,
+.Xr atapi 4 ,
+.Xr intro 4 ,
+.Xr pci 4 ,
+.Xr pciide 4 ,
+.Xr wd 4 ,
+.Xr wdc 4
diff --git a/sys/arch/i386/conf/GENERIC b/sys/arch/i386/conf/GENERIC
index e9590b7a681..4610ee05503 100644
--- a/sys/arch/i386/conf/GENERIC
+++ b/sys/arch/i386/conf/GENERIC
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC,v 1.731 2006/02/25 01:33:15 christos Exp $
+# $NetBSD: GENERIC,v 1.732 2006/03/06 18:35:24 bouyer Exp $
#
# GENERIC machine description file
#
@@ -22,7 +22,7 @@ include "arch/i386/conf/std.i386"
options INCLUDE_CONFIG_FILE # embed config file in kernel binary
-#ident "GENERIC-$Revision: 1.731 $"
+#ident "GENERIC-$Revision: 1.732 $"
maxusers 32 # estimated number of users
@@ -723,6 +723,7 @@ rccide* at pci? dev ? function ? # ServerWorks IDE controllers
satalink* at pci? dev ? function ? # SiI SATALink controllers
siside* at pci? dev ? function ? # SiS IDE controllers
slide* at pci? dev ? function ? # Symphony Labs IDE controllers
+svwsata* at pci? dev ? function ? # ServerWorks SATA controllers
stpcide* at pci? dev ? function ? # STMicro STPC IDE controllers
viaide* at pci? dev ? function ? # VIA/AMD/Nvidia IDE controllers
diff --git a/sys/arch/i386/conf/INSTALL b/sys/arch/i386/conf/INSTALL
index 15e6ed3853c..3afa9677c75 100644
--- a/sys/arch/i386/conf/INSTALL
+++ b/sys/arch/i386/conf/INSTALL
@@ -1,4 +1,4 @@
-# $NetBSD: INSTALL,v 1.280 2006/02/05 05:01:55 cube Exp $
+# $NetBSD: INSTALL,v 1.281 2006/03/06 18:35:24 bouyer Exp $
#
# INSTALL - Installation kernel.
#
@@ -435,6 +435,7 @@ rccide* at pci? dev ? function ? # ServerWorks IDE controllers
satalink* at pci? dev ? function ? # SiI SATALink controllers
siside* at pci? dev ? function ? # SiS IDE controllers
slide* at pci? dev ? function ? # Symphony Labs IDE controllers
+svwsata* at pci? dev ? function ? # ServerWorks SATA controllers
viaide* at pci? dev ? function ? # VIA/AMD/Nvidia IDE controllers
stpcide* at pci? dev ? function ? # STMicro STPC IDE controllers
diff --git a/sys/arch/i386/conf/XEN0 b/sys/arch/i386/conf/XEN0
index 236a03c1694..0c3135cdf23 100644
--- a/sys/arch/i386/conf/XEN0
+++ b/sys/arch/i386/conf/XEN0
@@ -1,4 +1,4 @@
-# $NetBSD: XEN0,v 1.33 2006/02/25 01:33:15 christos Exp $
+# $NetBSD: XEN0,v 1.34 2006/03/06 18:35:24 bouyer Exp $
include "arch/xen/conf/std.xen"
@@ -356,6 +356,7 @@ rccide* at pci? dev ? function ? # ServerWorks IDE controllers
satalink* at pci? dev ? function ? # SiI SATALink controllers
siside* at pci? dev ? function ? # SiS IDE controllers
slide* at pci? dev ? function ? # Symphony Labs IDE controllers
+svwsata* at pci? dev ? function ? # ServerWorks SATA controllers
stpcide* at pci? dev ? function ? # STMicro STPC IDE controllers
viaide* at pci? dev ? function ? # VIA/AMD/Nvidia IDE controllers
diff --git a/sys/dev/pci/files.pci b/sys/dev/pci/files.pci
index 072d9601c1d..417c4a09465 100644
--- a/sys/dev/pci/files.pci
+++ b/sys/dev/pci/files.pci
@@ -1,4 +1,4 @@
-# $NetBSD: files.pci,v 1.242 2006/02/19 02:24:20 tls Exp $
+# $NetBSD: files.pci,v 1.243 2006/03/06 18:35:24 bouyer Exp $
#
# Config file and device description for machine-independent PCI code.
# Included by ports that need it. Requires that the SCSI files be
@@ -267,6 +267,11 @@ device rccide: ata, pciide_common, wdc_common
attach rccide at pci
file dev/pci/rccide.c rccide
+# ServerWorks SATA controllers
+device svwsata: ata, pciide_common, wdc_common, sata
+attach svwsata at pci
+file dev/pci/svwsata.c svwsata
+
# Silicon Image SATALink controllers
device satalink: ata, pciide_common, wdc_common, sata
attach satalink at pci
diff --git a/sys/dev/pci/pcidevs b/sys/dev/pci/pcidevs
index c7e8f826e66..d40eb952eed 100644
--- a/sys/dev/pci/pcidevs
+++ b/sys/dev/pci/pcidevs
@@ -1,4 +1,4 @@
-$NetBSD: pcidevs,v 1.770 2006/03/06 08:23:00 martin Exp $
+$NetBSD: pcidevs,v 1.771 2006/03/06 18:35:24 bouyer Exp $
/*
* Copyright (c) 1995, 1996 Christopher G. Demetriou
@@ -2660,6 +2660,7 @@ product SERVERWORKS OSB4_USB 0x0220 OSB4/CSB5 USB Host Controller
product SERVERWORKS CSB6_USB 0x0221 CSB6 USB Host Controller
product SERVERWORKS CSB5_LPC 0x0225 CSB5 ISA/LPC bridge
product SERVERWORKS CSB6_LPC 0x0227 CSB6 ISA/LPC bridge
+product SERVERWORKS K2_SATA 0x0240 K2 SATA
product SERVERWORKS BCM5714 0x0103 bcm5714/bcm5715 integral PCI-E to PCI-X bridge
/* SGI products */
diff --git a/sys/dev/pci/pciide_svwsata_reg.h b/sys/dev/pci/pciide_svwsata_reg.h
new file mode 100644
index 00000000000..627cb4b7569
--- /dev/null
+++ b/sys/dev/pci/pciide_svwsata_reg.h
@@ -0,0 +1,40 @@
+/* $OpenBSD: pciide_svwsata_reg.h,v 1.4 2006/02/10 21:45:41 kettenis Exp $ */
+
+/*
+ * Copyright (c) 2005 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _DEV_PCI_PCIIDE_SVWSATA_REG_H_
+#define _DEV_PCI_PCIIDE_SVWSATA_REG_H_
+
+struct pciide_svwsata {
+ bus_space_tag_t ba5_st;
+ bus_space_handle_t ba5_sh;
+};
+
+#define SVWSATA_TF0 0x00
+#define SVWSATA_TF8 0x20
+
+#define SVWSATA_DMA 0x30
+
+#define SVWSATA_SSTATUS 0x40
+#define SVWSATA_SERROR 0x44
+#define SVWSATA_SCONTROL 0x48
+
+#define SVWSATA_SICR1 0x80
+#define SVWSATA_SICR2 0x84
+#define SVWSATA_SIM 0x88
+
+#endif /* !_DEV_PCI_PCIIDE_SVWSATA_REG_H_ */
diff --git a/sys/dev/pci/pciidevar.h b/sys/dev/pci/pciidevar.h
index bf41c080f8c..23df808364a 100644
--- a/sys/dev/pci/pciidevar.h
+++ b/sys/dev/pci/pciidevar.h
@@ -1,4 +1,4 @@
-/* $NetBSD: pciidevar.h,v 1.32 2005/12/24 20:27:42 perry Exp $ */
+/* $NetBSD: pciidevar.h,v 1.33 2006/03/06 18:35:24 bouyer Exp $ */
/*
* Copyright (c) 1998 Christopher G. Demetriou. All rights reserved.
@@ -108,7 +108,10 @@ struct pciide_softc {
/* for SiS */
u_int8_t sis_type;
- /* For Silicon Image SATALink, Artisea SATA and Promise SATA */
+ /*
+ * For Silicon Image SATALink, Serverworks SATA, Artisea SATA
+ * and Promise SATA
+ */
bus_space_tag_t sc_ba5_st;
bus_space_handle_t sc_ba5_sh;
int sc_ba5_en;
diff --git a/sys/dev/pci/svwsata.c b/sys/dev/pci/svwsata.c
new file mode 100644
index 00000000000..b31c393981c
--- /dev/null
+++ b/sys/dev/pci/svwsata.c
@@ -0,0 +1,366 @@
+/* $NetBSD: svwsata.c,v 1.1 2006/03/06 18:35:24 bouyer Exp $ */
+
+/*
+ * Copyright (c) 2005 Mark Kettenis
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: svwsata.c,v 1.1 2006/03/06 18:35:24 bouyer Exp $");
+
+#include <sys/param.h>
+#include <sys/systm.h>
+
+#include <dev/ata/atareg.h>
+#include <dev/ata/satareg.h>
+#include <dev/ata/satavar.h>
+#include <dev/pci/pcivar.h>
+#include <dev/pci/pcidevs.h>
+#include <dev/pci/pciidereg.h>
+#include <dev/pci/pciidevar.h>
+#include <dev/pci/pciide_svwsata_reg.h>
+
+static int svwsata_match(struct device *, struct cfdata *, void *);
+static void svwsata_attach(struct device *, struct device *, void *);
+
+static void svwsata_chip_map(struct pciide_softc *, struct pci_attach_args *) __unused;
+static void svwsata_mapreg_dma(struct pciide_softc *, struct pci_attach_args *);
+static void svwsata_mapchan(struct pciide_channel *);
+static void svwsata_drv_probe(struct ata_channel *chp);
+
+CFATTACH_DECL(svwsata, sizeof(struct pciide_softc),
+ svwsata_match, svwsata_attach, NULL, NULL);
+
+static const struct pciide_product_desc pciide_svwsata_products[] = {
+ { PCI_PRODUCT_SERVERWORKS_K2_SATA,
+ 0,
+ "ServerWorks K2 SATA Controller",
+ svwsata_chip_map
+ },
+ { 0,
+ 0,
+ NULL,
+ NULL,
+ }
+};
+
+static int
+svwsata_match(struct device *parent, struct cfdata *match, void *aux)
+{
+ struct pci_attach_args *pa = aux;
+
+ if (PCI_VENDOR(pa->pa_id) == PCI_VENDOR_SERVERWORKS) {
+ if (pciide_lookup_product(pa->pa_id,
+ pciide_svwsata_products))
+ return (2);
+ }
+ return (0);
+}
+
+static void
+svwsata_attach(struct device *parent, struct device *self, void *aux)
+{
+ struct pci_attach_args *pa = aux;
+ struct pciide_softc *sc = (void *)self;
+
+ pciide_common_attach(sc, pa,
+ pciide_lookup_product(pa->pa_id, pciide_svwsata_products));
+}
+
+static void
+svwsata_chip_map(struct pciide_softc *sc, struct pci_attach_args *pa)
+{
+ struct pciide_channel *cp;
+ pci_intr_handle_t intrhandle;
+ pcireg_t interface;
+ const char *intrstr;
+ int channel;
+
+ if (pciide_chipen(sc, pa) == 0)
+ return;
+
+ 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, NULL) != 0) {
+ aprint_error(": unable to map BA5 register space\n");
+ return;
+ }
+
+ aprint_normal(": DMA");
+ svwsata_mapreg_dma(sc, pa);
+ aprint_normal("\n");
+
+ 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) {
+ sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_DMA | ATAC_CAP_UDMA;
+ sc->sc_wdcdev.irqack = pciide_irqack;
+ sc->sc_wdcdev.sc_atac.atac_dma_cap = 2;
+ sc->sc_wdcdev.sc_atac.atac_udma_cap = 6;
+ }
+
+ sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray;
+ sc->sc_wdcdev.sc_atac.atac_nchannels = 4;
+ sc->sc_wdcdev.sc_atac.atac_set_modes = sata_setup_channel;
+
+ /* We can use SControl and SStatus to probe for drives. */
+ sc->sc_wdcdev.sc_atac.atac_probe = svwsata_drv_probe;
+
+ wdc_allocate_regs(&sc->sc_wdcdev);
+
+ /* Map and establish the interrupt handler. */
+ 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_normal("%s: using %s for native-PCI interrupt\n",
+ sc->sc_wdcdev.sc_atac.atac_dev.dv_xname,
+ intrstr ? intrstr : "unknown interrupt");
+ } else {
+ aprint_error("%s: couldn't establish native-PCI interrupt",
+ sc->sc_wdcdev.sc_atac.atac_dev.dv_xname);
+ if (intrstr != NULL)
+ aprint_normal(" at %s", intrstr);
+ aprint_normal("\n");
+ return;
+ }
+
+ 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;
+ svwsata_mapchan(cp);
+ }
+}
+
+static void
+svwsata_mapreg_dma(struct pciide_softc *sc, struct pci_attach_args *pa)
+{
+ struct pciide_channel *pc;
+ int chan, reg;
+ bus_size_t size;
+
+ sc->sc_wdcdev.dma_arg = sc;
+ sc->sc_wdcdev.dma_init = pciide_dma_init;
+ sc->sc_wdcdev.dma_start = pciide_dma_start;
+ sc->sc_wdcdev.dma_finish = pciide_dma_finish;
+
+ if (sc->sc_wdcdev.sc_atac.atac_dev.dv_cfdata->cf_flags &
+ PCIIDE_OPTIONS_NODMA) {
+ aprint_normal(
+ ", but unused (forced off by config file)");
+ sc->sc_dma_ok = 0;
+ return;
+ }
+
+ /*
+ * Slice off a subregion of BA5 for each of the channel's DMA
+ * registers.
+ */
+
+ sc->sc_dma_iot = sc->sc_ba5_st;
+ for (chan = 0; chan < 4; chan++) {
+ pc = &sc->pciide_channels[chan];
+ for (reg = 0; reg < IDEDMA_NREGS; reg++) {
+ size = 4;
+ if (size > (IDEDMA_SCH_OFFSET - reg))
+ size = IDEDMA_SCH_OFFSET - reg;
+ if (bus_space_subregion(sc->sc_ba5_st,
+ sc->sc_ba5_sh,
+ (chan << 8) + SVWSATA_DMA + reg,
+ size, &pc->dma_iohs[reg]) != 0) {
+ sc->sc_dma_ok = 0;
+ aprint_normal(", but can't subregion offset "
+ "%lu size %lu",
+ (u_long) (chan << 8) + SVWSATA_DMA + reg,
+ (u_long) size);
+ return;
+ }
+ }
+ }
+
+ /* DMA registers all set up! */
+ sc->sc_dmat = pa->pa_dmat;
+ sc->sc_dma_ok = 1;
+}
+
+static void
+svwsata_mapchan(struct pciide_channel *cp)
+{
+ struct ata_channel *wdc_cp = &cp->ata_channel;
+ struct pciide_softc *sc = CHAN_TO_PCIIDE(wdc_cp);
+ struct wdc_regs *wdr = CHAN_TO_WDC_REGS(wdc_cp);
+ int i;
+
+ cp->compat = 0;
+ cp->ih = sc->sc_pci_ih;
+
+ wdr->cmd_iot = sc->sc_ba5_st;
+ if (bus_space_subregion(sc->sc_ba5_st, sc->sc_ba5_sh,
+ (wdc_cp->ch_channel << 8) + SVWSATA_TF0,
+ SVWSATA_TF8 - SVWSATA_TF0, &wdr->cmd_baseioh) != 0) {
+ aprint_error("%s: couldn't map %s cmd regs\n",
+ sc->sc_wdcdev.sc_atac.atac_dev.dv_xname, cp->name);
+ goto bad;
+ }
+
+ wdr->ctl_iot = sc->sc_ba5_st;
+ if (bus_space_subregion(sc->sc_ba5_st, sc->sc_ba5_sh,
+ (wdc_cp->ch_channel << 8) + SVWSATA_TF8, 4,
+ &cp->ctl_baseioh) != 0) {
+ aprint_error("%s: couldn't map %s ctl regs\n",
+ sc->sc_wdcdev.sc_atac.atac_dev.dv_xname, cp->name);
+ goto bad;
+ }
+ wdr->ctl_ioh = cp->ctl_baseioh;
+
+ for (i = 0; i < WDC_NREG; i++) {
+ if (bus_space_subregion(wdr->cmd_iot, wdr->cmd_baseioh,
+ i << 2, 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);
+ goto bad;
+ }
+ }
+ wdc_init_shadow_regs(wdc_cp);
+ wdr->data32iot = wdr->cmd_iot;
+ wdr->data32ioh = wdr->cmd_iohs[0];
+
+ wdcattach(wdc_cp);
+ return;
+
+ bad:
+ cp->ata_channel.ch_flags |= ATACH_DISABLED;
+}
+
+static void
+svwsata_drv_probe(struct ata_channel *chp)
+{
+ struct pciide_softc *sc = CHAN_TO_PCIIDE(chp);
+ struct wdc_regs *wdr = CHAN_TO_WDC_REGS(chp);
+ int channel = chp->ch_channel;
+ uint32_t scontrol, sstatus;
+ uint8_t scnt, sn, cl, ch;
+ int i, s;
+
+ /* XXX This should be done by other code. */
+ for (i = 0; i < 2; i++) {
+ chp->ch_drive[i].chnl_softc = chp;
+ chp->ch_drive[i].drive = i;
+ }
+
+ /*
+ * Request communication initialization sequence, any speed.
+ * Performing this is the equivalent of an ATA Reset.
+ */
+ scontrol = SControl_DET_INIT | SControl_SPD_ANY;
+
+ /*
+ * XXX We don't yet support SATA power management; disable all
+ * power management state transitions.
+ */
+ scontrol |= SControl_IPM_NONE;
+
+ bus_space_write_4(sc->sc_ba5_st, sc->sc_ba5_sh,
+ (channel << 8) + SVWSATA_SCONTROL, scontrol);
+ delay(50 * 1000);
+ scontrol &= ~SControl_DET_INIT;
+ bus_space_write_4(sc->sc_ba5_st, sc->sc_ba5_sh,
+ (channel << 8) + SVWSATA_SCONTROL, scontrol);
+ delay(50 * 1000);
+
+ sstatus = bus_space_read_4(sc->sc_ba5_st, sc->sc_ba5_sh,
+ (channel << 8) + SVWSATA_SSTATUS);
+#if 0
+ printf("%s: port %d: SStatus=0x%08x, SControl=0x%08x\n",
+ sc->sc_wdcdev.sc_atac.atac_dev.dv_xname, chp->ch_channel, sstatus,
+ bus_space_read_4(sc->sc_ba5_st, sc->sc_ba5_sh,
+ (channel << 8) + SVWSATA_SSTATUS));
+#endif
+ switch (sstatus & SStatus_DET_mask) {
+ case SStatus_DET_NODEV:
+ /* No device; be silent. */
+ break;
+
+ case SStatus_DET_DEV_NE:
+ aprint_error("%s: port %d: device connected, but "
+ "communication not established\n",
+ sc->sc_wdcdev.sc_atac.atac_dev.dv_xname, chp->ch_channel);
+ break;
+
+ case SStatus_DET_OFFLINE:
+ aprint_error("%s: port %d: PHY offline\n",
+ sc->sc_wdcdev.sc_atac.atac_dev.dv_xname, chp->ch_channel);
+ break;
+
+ case SStatus_DET_DEV:
+ /*
+ * XXX ATAPI detection doesn't currently work. Don't
+ * XXX know why. But, it's not like the standard method
+ * XXX can detect an ATAPI device connected via a SATA/PATA
+ * XXX bridge, so at least this is no worse. --thorpej
+ */
+ bus_space_write_1(wdr->cmd_iot, wdr->cmd_iohs[wd_sdh], 0,
+ WDSD_IBM | (0 << 4));
+ delay(10); /* 400ns delay */
+ /* Save register contents. */
+ scnt = bus_space_read_1(wdr->cmd_iot,
+ wdr->cmd_iohs[wd_seccnt], 0);
+ sn = bus_space_read_1(wdr->cmd_iot,
+ wdr->cmd_iohs[wd_sector], 0);
+ cl = bus_space_read_1(wdr->cmd_iot,
+ wdr->cmd_iohs[wd_cyl_lo], 0);
+ ch = bus_space_read_1(wdr->cmd_iot,
+ wdr->cmd_iohs[wd_cyl_hi], 0);
+#if 0
+ printf("%s: port %d: scnt=0x%x sn=0x%x cl=0x%x ch=0x%x\n",
+ sc->sc_wdcdev.sc_atac.atac_dev.dv_xname, chp->ch_channel,
+ scnt, sn, cl, ch);
+#endif
+ /*
+ * scnt and sn are supposed to be 0x1 for ATAPI, but in some
+ * cases we get wrong values here, so ignore it.
+ */
+ s = splbio();
+ if (cl == 0x14 && ch == 0xeb)
+ chp->ch_drive[0].drive_flags |= DRIVE_ATAPI;
+ else
+ chp->ch_drive[0].drive_flags |= DRIVE_ATA;
+ splx(s);
+
+ aprint_normal("%s: port %d: device present, speed: %s\n",
+ sc->sc_wdcdev.sc_atac.atac_dev.dv_xname, chp->ch_channel,
+ sata_speed(sstatus));
+ break;
+
+ default:
+ aprint_error("%s: port %d: unknown SStatus: 0x%08x\n",
+ sc->sc_wdcdev.sc_atac.atac_dev.dv_xname, chp->ch_channel, sstatus);
+ }
+}