From 4c7c634330bc4fecbf7c203a6c3f4e3e2324893e Mon Sep 17 00:00:00 2001 From: is Date: Mon, 20 Aug 2007 07:40:29 +0000 Subject: [PATCH] wdc frontent for the buddha and catweazle Z2 hardware. From an old prototype by me which was never committed due to lack of testers, adopted to 4.99 and fixed by Frank Wille. --- sys/arch/amiga/conf/GENERIC.in | 6 +- sys/arch/amiga/conf/files.amiga | 6 +- sys/arch/amiga/dev/wdc_buddha.c | 215 ++++++++++++++++++++++++++++++++ 3 files changed, 224 insertions(+), 3 deletions(-) create mode 100644 sys/arch/amiga/dev/wdc_buddha.c diff --git a/sys/arch/amiga/conf/GENERIC.in b/sys/arch/amiga/conf/GENERIC.in index f8bbad27fef0..67a6fd839831 100644 --- a/sys/arch/amiga/conf/GENERIC.in +++ b/sys/arch/amiga/conf/GENERIC.in @@ -1,4 +1,4 @@ -# $NetBSD: GENERIC.in,v 1.61 2007/08/06 21:26:54 adrianp Exp $ +# $NetBSD: GENERIC.in,v 1.62 2007/08/20 07:40:29 is Exp $ # # GENERIC machine description file # @@ -56,7 +56,7 @@ include "arch/amiga/conf/std.amiga" options INCLUDE_CONFIG_FILE # embed config file in kernel binary -#ident "GENERIC-$Revision: 1.61 $" +#ident "GENERIC-$Revision: 1.62 $" m4_ifdef(`INSTALL_CONFIGURATION', `m4_dnl makeoptions COPTS="-Os" @@ -528,6 +528,8 @@ empsc0 at zbus0 # Emplant scsi scsibus* at empsc0 wdc0 at mainbus0 # A4000 & A1200 IDE bus +wdc* at zbus0 # Buddha / Catweasel + atabus* at wdc? channel ? # ATA bus wd* at atabus? drive ? # + drives atapibus* at atabus? # ATAPI bus diff --git a/sys/arch/amiga/conf/files.amiga b/sys/arch/amiga/conf/files.amiga index 7421e53bad5a..1355cad44196 100644 --- a/sys/arch/amiga/conf/files.amiga +++ b/sys/arch/amiga/conf/files.amiga @@ -1,4 +1,4 @@ -# $NetBSD: files.amiga,v 1.137 2007/06/09 16:31:08 mhitch Exp $ +# $NetBSD: files.amiga,v 1.138 2007/08/20 07:40:29 is Exp $ # maxpartitions must be first item in files.${ARCH}.newconf maxpartitions 16 # NOTE THAT AMIGA IS SPECIAL! @@ -465,6 +465,10 @@ include "dev/ata/files.ata" attach wdc at mainbus with wdc_amiga: gayle file arch/amiga/dev/wdc_amiga.c wdc_amiga +# Buddha wdc +attach wdc at zbus with wdc_buddha +file arch/amiga/dev/wdc_buddha.c wdc_buddha + # Compatibility modules # NetBSD m68k a.out Binary Compatibility (COMPAT_AOUT_M68K) diff --git a/sys/arch/amiga/dev/wdc_buddha.c b/sys/arch/amiga/dev/wdc_buddha.c new file mode 100644 index 000000000000..962189aef07d --- /dev/null +++ b/sys/arch/amiga/dev/wdc_buddha.c @@ -0,0 +1,215 @@ +/* $NetBSD: wdc_buddha.c,v 1.1 2007/08/20 07:40:29 is Exp $ */ + +/*- + * Copyright (c) 2000 The NetBSD Foundation, Inc. + * All rights reserved. + * + * This code is derived from software contributed to The NetBSD Foundation + * by Michael L. Hitch and Ignatios Souvatzis. + * + * 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 the NetBSD + * Foundation, Inc. and its contributors. + * 4. Neither the name of The NetBSD Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS + * ``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 FOUNDATION OR CONTRIBUTORS + * 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. + */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include + +#include +#include + +#define BUDDHA_MAX_CHANNELS 3 + +struct wdc_buddha_softc { + struct wdc_softc sc_wdcdev; + struct ata_channel *wdc_chanarray[BUDDHA_MAX_CHANNELS]; + struct ata_channel channels[BUDDHA_MAX_CHANNELS]; + struct bus_space_tag sc_iot; + struct isr sc_isr; + volatile char *ba; +}; + +int wdc_buddha_probe(struct device *, struct cfdata *, void *); +void wdc_buddha_attach(struct device *, struct device *, void *); +int wdc_buddha_intr(void *); + +CFATTACH_DECL(wdc_buddha, sizeof(struct wdc_buddha_softc), + wdc_buddha_probe, wdc_buddha_attach, NULL, NULL); + +int +wdc_buddha_probe(struct device *parent, struct cfdata *cfp, void *aux) +{ + struct zbus_args *zap; + + zap = aux; + + if (zap->manid != 4626) + return 0; + + if ((zap->prodid != 0) && /* Buddha */ + (zap->prodid != 42)) /* Catweasel */ + return 0; + + return 1; +} + +void +wdc_buddha_attach(struct device *parent, struct device *self, void *aux) +{ + struct wdc_buddha_softc *sc; + struct zbus_args *zap; + int nchannels; + int ch; + + sc = (void *)self; + zap = aux; + + sc->ba = zap->va; + + sc->sc_iot.base = (bus_addr_t)sc->ba; + sc->sc_iot.absm = &amiga_bus_stride_4swap; + + nchannels = 2; + if (zap->prodid == 42) { + printf(": Catweasel Z2\n"); + nchannels = 3; + } else if (zap->serno == 0) + printf(": Buddha\n"); + else + printf(": Buddha Flash\n"); + + /* XXX pio mode setting not implemented yet. */ + sc->sc_wdcdev.sc_atac.atac_cap = ATAC_CAP_DATA16; + sc->sc_wdcdev.sc_atac.atac_pio_cap = 0; + sc->sc_wdcdev.sc_atac.atac_channels = sc->wdc_chanarray; + sc->sc_wdcdev.sc_atac.atac_nchannels = nchannels; + + wdc_allocate_regs(&sc->sc_wdcdev); + + for (ch = 0; ch < nchannels; ch++) { + struct ata_channel *cp; + struct wdc_regs *wdr; + int i; + + cp = &sc->channels[ch]; + sc->wdc_chanarray[ch] = cp; + + cp->ch_channel = ch; + cp->ch_atac = &sc->sc_wdcdev.sc_atac; + cp->ch_queue = + malloc(sizeof(struct ata_queue), M_DEVBUF, M_NOWAIT); + if (cp->ch_queue == NULL) { + printf("%s: can't allocate memory for command queue\n", + sc->sc_wdcdev.sc_atac.atac_dev.dv_xname); + return; + } + cp->ch_ndrive = 2; + + /* + * XXX According to the Buddha docs, we should use a method + * array that adds 0x40 to the address for byte accesses, to + * get the slow timing for command accesses, and the 0x00 + * offset for the word (fast) accesses. This will be + * reconsidered when implementing setting the timing. + * + * XXX We also could consider to abuse the 32bit capability, or + * 32bit accesses to the words (which will read in two words) + * for better performance. + * -is + */ + wdr = CHAN_TO_WDC_REGS(cp); + + wdr->cmd_iot = &sc->sc_iot; + if (bus_space_map(wdr->cmd_iot, 0x210+ch*0x80, 8, 0, + &wdr->cmd_baseioh)) { + printf("%s: couldn't map cmd registers\n", + sc->sc_wdcdev.sc_atac.atac_dev.dv_xname); + return; + } + + wdr->ctl_iot = &sc->sc_iot; + if (bus_space_map(wdr->ctl_iot, 0x250+ch*0x80, 2, 0, + &wdr->ctl_ioh)) { + bus_space_unmap(wdr->cmd_iot, wdr->cmd_baseioh, 8); + printf("%s: couldn't map ctl registers\n", + sc->sc_wdcdev.sc_atac.atac_dev.dv_xname); + return; + } + + 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) { + printf("%s: couldn't subregion cmd regs\n", + sc->sc_wdcdev.sc_atac.atac_dev.dv_xname); + return; + } + } + + wdc_init_shadow_regs(cp); + wdcattach(cp); + } + + sc->sc_isr.isr_intr = wdc_buddha_intr; + sc->sc_isr.isr_arg = sc; + sc->sc_isr.isr_ipl = 2; + add_isr (&sc->sc_isr); + sc->ba[0xfc0] = 0; /* enable interrupts */ +} + +int +wdc_buddha_intr(void *arg) +{ + struct wdc_buddha_softc *sc = (struct wdc_buddha_softc *)arg; + int nchannels, i, ret; + volatile char *p; + + ret = 0; + nchannels = sc->sc_wdcdev.sc_atac.atac_nchannels; + p = sc->ba; + + for (i=0; ichannels[i]); + ret = 1; + } + } + + return ret; +}