Subject: wdc_buddha works
To: None <port-amiga@NetBSD.org>
From: Frank Wille <frank@phoenix.owl.de>
List: port-amiga
Date: 08/18/2007 00:41:08
Warning: This is a message in MIME format. Your mail reader does not
support MIME. Some parts of this message will be readable as plain text.
To see the rest, you will need to upgrade your mail reader. Following are
some URLs where you can find MIME-capable mail programs for common platforms:

  Amiga............: YAM          http://www.yam.ch/
  Unix.............: Metamail     ftp://thumper.bellcore.com/pub/nsb/
  Windows/Macintosh: Eudora       http://www.eudora.com/

General info about MIME can be found at:

http://www.faqs.org/faqs/mail/mime-faq/


--BOUNDARY.549844656.5
Content-Type: text/plain

Ok, after porting the source from NetBSD 1.5 to current and fixing minor
bugs it seems to work:

wdc1 at zbus0 pa 0xea0000 man/pro 4626/42: Catweasel Z2
atabus1 at wdc1 channel 0
atabus2 at wdc1 channel 1
atabus3 at wdc1 channel 2
cbiiisc at zbus0: pa 0xf0102c man/pro 8512/100 not configured
4 views configured
wd0 at atabus1 drive 0: <QUANTUM FIREBALL_TM3200A>
wd0: drive supports 16-sector PIO transfers, LBA addressing
wd0: 3067 MB, 6232 cyl, 16 head, 63 sec, 512 bytes/sect x 6281856 sectors
wd0: drive supports PIO mode 4, DMA mode 2
wd1 at atabus1 drive 1: <FUJITSU MPC3032AT>
wd1: drive supports 16-sector PIO transfers, LBA addressing
wd1: 3093 MB, 6704 cyl, 15 head, 63 sec, 512 bytes/sect x 6335280 sectors
wd1: drive supports PIO mode 4, DMA mode 2, Ultra-DMA mode 2 (Ultra/33)
root on wd0a dumps on wd0b
root file system type: ffs

Currently it runs in slowest PIO-mode 0. But that's as fast as A4000-IDE.

I did some tests on an A4000 and even an A2500(68020), and in both cases the
driver looks quite stable to me.

The modified wdc_buddha.c and the diffs for files.amiga and the GENERIC
config file are attached. When somebody else confirms that it works, maybe
Ignatios considers to commit it? ;)

-- 
    _  Frank Wille (frank@phoenix.owl.de)
 _ //  http://sun.hasenbraten.de/~frank/
 \X/   Phx @ #AmigaGer

--BOUNDARY.549844656.5
Content-Type: text/plain; name="wdc_buddha.c"
Content-Disposition: attachment; filename="wdc_buddha.c"

/*	$NetBSD: wdc_amiga.c,v 1.5 2000/02/21 18:27:49 aymeric 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 <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/malloc.h>
#include <sys/device.h>

#include <machine/cpu.h>
#include <machine/bus.h>
#include <machine/intr.h>
#include <machine/bswap.h>

#include <amiga/amiga/cia.h>
#include <amiga/amiga/custom.h>
#include <amiga/amiga/device.h>
#include <amiga/dev/zbusvar.h>

#include <dev/ata/atavar.h>
#include <dev/ic/wdcvar.h>

#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; i<nchannels; i++) {
		if (p[0xf00 + 0x40*i] & 0x80) {
			wdcintr(&sc->channels[i]);
			ret = 1;
		}
	}

	return ret;
}

--BOUNDARY.549844656.5
Content-Type: text/plain; name="files.amiga.diff"
Content-Disposition: attachment; filename="files.amiga.diff"

--- files.amiga.orig	2007-08-14 18:53:55.000000000 +0200
+++ files.amiga	2007-08-14 18:55:51.000000000 +0200
@@ -463,6 +463,10 @@
 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)

--BOUNDARY.549844656.5
Content-Type: text/plain; name="GENERIC.diff"
Content-Disposition: attachment; filename="GENERIC.diff"

--- GENERIC.orig	2007-08-17 22:12:42.000000000 +0200
+++ GENERIC	2007-08-17 22:13:27.000000000 +0200
@@ -426,6 +426,7 @@
 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

--BOUNDARY.549844656.5--