diff options
| author | bouyer <bouyer@NetBSD.org> | 2006-03-06 18:35:24 +0000 |
|---|---|---|
| committer | bouyer <bouyer@NetBSD.org> | 2006-03-06 18:35:24 +0000 |
| commit | f656fa41eb4a793d30bdd41614deebad9ce3e277 (patch) | |
| tree | 9e38d3a7ec1c47f7e9b04ccbcfbae73068f66e35 | |
| parent | 21d185683caf39527978cf219b0dc6b9ef66cde1 (diff) | |
Add svwsata(4), a driver for Serverworks K2 SATA controllers. From
OpenBSD via Joerg Sonnenberger.
| -rw-r--r-- | doc/CHANGES | 4 | ||||
| -rw-r--r-- | share/man/man4/Makefile | 5 | ||||
| -rw-r--r-- | share/man/man4/pciide.4 | 5 | ||||
| -rw-r--r-- | share/man/man4/svwsata.4 | 59 | ||||
| -rw-r--r-- | sys/arch/i386/conf/GENERIC | 5 | ||||
| -rw-r--r-- | sys/arch/i386/conf/INSTALL | 3 | ||||
| -rw-r--r-- | sys/arch/i386/conf/XEN0 | 3 | ||||
| -rw-r--r-- | sys/dev/pci/files.pci | 7 | ||||
| -rw-r--r-- | sys/dev/pci/pcidevs | 3 | ||||
| -rw-r--r-- | sys/dev/pci/pciide_svwsata_reg.h | 40 | ||||
| -rw-r--r-- | sys/dev/pci/pciidevar.h | 7 | ||||
| -rw-r--r-- | sys/dev/pci/svwsata.c | 366 |
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); + } +} |
