Module Name:    src
Committed By:   rkujawa
Date:           Thu Oct 27 22:12:24 UTC 2011

Modified Files:
        src/distrib/sets/lists/man: mi
        src/share/man/man4/man4.amiga: Makefile
        src/sys/arch/amiga/conf: GENERIC.in files.amiga
Added Files:
        src/share/man/man4/man4.amiga: efa.4
        src/sys/arch/amiga/dev: efa.c efareg.h efavar.h

Log Message:
Add driver for ELBOX FastATA 1200 Mk-III/Mk-IV (and the man page).


To generate a diff of this commit:
cvs rdiff -u -r1.1350 -r1.1351 src/distrib/sets/lists/man/mi
cvs rdiff -u -r1.20 -r1.21 src/share/man/man4/man4.amiga/Makefile
cvs rdiff -u -r0 -r1.1 src/share/man/man4/man4.amiga/efa.4
cvs rdiff -u -r1.84 -r1.85 src/sys/arch/amiga/conf/GENERIC.in
cvs rdiff -u -r1.148 -r1.149 src/sys/arch/amiga/conf/files.amiga
cvs rdiff -u -r0 -r1.1 src/sys/arch/amiga/dev/efa.c \
    src/sys/arch/amiga/dev/efareg.h src/sys/arch/amiga/dev/efavar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/distrib/sets/lists/man/mi
diff -u src/distrib/sets/lists/man/mi:1.1350 src/distrib/sets/lists/man/mi:1.1351
--- src/distrib/sets/lists/man/mi:1.1350	Tue Oct 18 10:19:11 2011
+++ src/distrib/sets/lists/man/mi	Thu Oct 27 22:12:24 2011
@@ -1,4 +1,4 @@
-# $NetBSD: mi,v 1.1350 2011/10/18 10:19:11 wiz Exp $
+# $NetBSD: mi,v 1.1351 2011/10/27 22:12:24 rkujawa Exp $
 #
 # Note: don't delete entries from here - mark them as "obsolete" instead.
 #
@@ -728,6 +728,7 @@
 ./usr/share/man/cat4/amiga/bppcsc.0		man-sys-catman		.cat
 ./usr/share/man/cat4/amiga/console.0		man-sys-catman		.cat
 ./usr/share/man/cat4/amiga/ed.0			man-sys-catman		.cat
+./usr/share/man/cat4/amiga/efa.0		man-sys-catman		.cat
 ./usr/share/man/cat4/amiga/es.0			man-sys-catman		.cat
 ./usr/share/man/cat4/amiga/fdc.0		man-sys-catman		.cat
 ./usr/share/man/cat4/amiga/grf.0		man-sys-catman		.cat
@@ -3604,6 +3605,7 @@
 ./usr/share/man/html4/amiga/bppcsc.html		man-sys-htmlman		html
 ./usr/share/man/html4/amiga/console.html	man-sys-htmlman		html
 ./usr/share/man/html4/amiga/ed.html		man-sys-htmlman		html
+./usr/share/man/html4/amiga/efa.html		man-sys-htmlman		html
 ./usr/share/man/html4/amiga/es.html		man-sys-htmlman		html
 ./usr/share/man/html4/amiga/fdc.html		man-sys-htmlman		html
 ./usr/share/man/html4/amiga/grf.html		man-sys-htmlman		html
@@ -6177,6 +6179,7 @@
 ./usr/share/man/man4/amiga/bppcsc.4		man-sys-man		.man
 ./usr/share/man/man4/amiga/console.4		man-sys-man		.man
 ./usr/share/man/man4/amiga/ed.4			man-sys-man		.man
+./usr/share/man/man4/amiga/efa.4		man-sys-man		.man
 ./usr/share/man/man4/amiga/es.4			man-sys-man		.man
 ./usr/share/man/man4/amiga/fdc.4		man-sys-man		.man
 ./usr/share/man/man4/amiga/grf.4		man-sys-man		.man

Index: src/share/man/man4/man4.amiga/Makefile
diff -u src/share/man/man4/man4.amiga/Makefile:1.20 src/share/man/man4/man4.amiga/Makefile:1.21
--- src/share/man/man4/man4.amiga/Makefile:1.20	Sat Sep 17 17:04:22 2011
+++ src/share/man/man4/man4.amiga/Makefile	Thu Oct 27 22:12:24 2011
@@ -1,8 +1,8 @@
 # 	from: @(#)Makefile	8.2 (Berkeley) 2/16/94
-#	$NetBSD: Makefile,v 1.20 2011/09/17 17:04:22 rkujawa Exp $
+#	$NetBSD: Makefile,v 1.21 2011/10/27 22:12:24 rkujawa Exp $
 
 MAN=	afsc.4 ahsc.4 amidisplaycc.4 atzsc.4 autoconf.4 console.4 bah.4 \
-	bppcsc.4 ed.4 es.4 fdc.4 grf.4 \
+	bppcsc.4 ed.4 efa.4 es.4 fdc.4 grf.4 \
 	grfcl.4 grfcv.4 grfcv3d.4 grfet.4 grfrh.4 grfrt.4 grful.4 \
 	gtsc.4 intro.4 ite.4 mem.4 mfcs.4 mgnsc.4 mppb.4 p5pb.4 \
 	qn.4 ser.4 wesc.4 zssc.4

Index: src/sys/arch/amiga/conf/GENERIC.in
diff -u src/sys/arch/amiga/conf/GENERIC.in:1.84 src/sys/arch/amiga/conf/GENERIC.in:1.85
--- src/sys/arch/amiga/conf/GENERIC.in:1.84	Mon Sep 19 19:15:29 2011
+++ src/sys/arch/amiga/conf/GENERIC.in	Thu Oct 27 22:12:23 2011
@@ -1,4 +1,4 @@
-# $NetBSD: GENERIC.in,v 1.84 2011/09/19 19:15:29 rkujawa Exp $
+# $NetBSD: GENERIC.in,v 1.85 2011/10/27 22:12:23 rkujawa Exp $
 #
 ##
 # GENERIC machine description file
@@ -57,7 +57,7 @@ include "arch/amiga/conf/std.amiga"
 
 options 	INCLUDE_CONFIG_FILE	# embed config file in kernel binary
 
-#ident 		"GENERIC-$Revision: 1.84 $"
+#ident 		"GENERIC-$Revision: 1.85 $"
 
 m4_ifdef(`INSTALL_CONFIGURATION', `m4_dnl
 makeoptions	COPTS="-Os"
@@ -528,8 +528,10 @@ scsibus*	at empsc0
 
 wdc0		at mainbus0		# A4000 & A1200 IDE bus
 wdc*		at zbus0		# Buddha / Catweasel
+#efa0		at mainbus0		# ELBOX FastATA 1200 Mk-III/Mk-IV 
 
 atabus* 	at wdc? channel ?	# ATA bus
+#atabus*		at efa? channel ?	# ATA bus 
 wd*		at atabus? drive ?	#  + drives
 atapibus*	at atabus?		# ATAPI bus
 cd*		at atapibus? drive ?	# ATAPI CD-ROM drives

Index: src/sys/arch/amiga/conf/files.amiga
diff -u src/sys/arch/amiga/conf/files.amiga:1.148 src/sys/arch/amiga/conf/files.amiga:1.149
--- src/sys/arch/amiga/conf/files.amiga:1.148	Mon Sep 19 19:15:29 2011
+++ src/sys/arch/amiga/conf/files.amiga	Thu Oct 27 22:12:23 2011
@@ -1,4 +1,4 @@
-#	$NetBSD: files.amiga,v 1.148 2011/09/19 19:15:29 rkujawa Exp $
+#	$NetBSD: files.amiga,v 1.149 2011/10/27 22:12:23 rkujawa Exp $
 
 # maxpartitions must be first item in files.${ARCH}.newconf
 maxpartitions 16			# NOTE THAT AMIGA IS SPECIAL!
@@ -470,6 +470,11 @@ file	arch/amiga/dev/wdc_amiga.c	wdc_amig
 attach	wdc at zbus with wdc_buddha
 file	arch/amiga/dev/wdc_buddha.c	wdc_buddha
 
+# FastATA 
+device  efa: ata,wdc_common
+attach  efa at mainbus
+file    arch/amiga/dev/efa.c		efa
+
 # Compatibility modules
 
 # NetBSD m68k a.out Binary Compatibility (COMPAT_AOUT_M68K)

Added files:

Index: src/share/man/man4/man4.amiga/efa.4
diff -u /dev/null src/share/man/man4/man4.amiga/efa.4:1.1
--- /dev/null	Thu Oct 27 22:12:25 2011
+++ src/share/man/man4/man4.amiga/efa.4	Thu Oct 27 22:12:24 2011
@@ -0,0 +1,110 @@
+.\" $NetBSD: efa.4,v 1.1 2011/10/27 22:12:24 rkujawa Exp $
+.\"
+.\" Copyright (c) 2011 The NetBSD Foundation, Inc.
+.\" All rights reserved.
+.\"
+.\" This code is derived from software contributed to The NetBSD Foundation
+.\" by Radoslaw Kujawa.
+.\"
+.\" 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.
+.\"
+.\" 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.
+.\"
+.Dd October 25, 2011
+.Dt EFA 4 amiga
+.Os
+.Sh NAME
+.Nm efa
+.Nd ELBOX FastATA 1200 IDE disk controller driver
+.Sh SYNOPSIS
+.Cd "efa0 at mainbus0"
+.\".Cd "options EFA_32BIT_IO"
+.\".Cd "options EFA_NO_INTR"
+.Sh DESCRIPTION
+The
+.Nm
+driver provides support for the FastATA 1200 family of IDE controllers and
+provides the interface with the hardware for the
+.Xr ata 4
+driver. PIO modes 0, 3, 4 and 5 are supported.
+.\".Pp
+.\"The following kernel configuration options are available:
+.\".Bl -ohang
+.\".It Cd options EFA_32BIT_IO
+.\"Use 32-bit data port. 
+.\".It Cd options EFA_GAYLE_COMPAT
+.\"Drive FastATA in Gayle IDE compatibility mode. Use if the driver does not 
+.\"work correctly in native (default) mode. Limits operation to PIO0 mode.
+.\".El
+.Sh HARDWARE
+The
+.Nm
+driver supports the following hardware:
+.Bl -tag -width "ELBOX FastATA 1200 Mk-IV" -offset indent
+.It Em ELBOX FastATA 1200 Mk-III 
+.It Em ELBOX FastATA 1200 Mk-IV 
+.El
+.Sh SEE ALSO
+.Xr ata 4 ,
+.Xr wdc 4 
+.Sh HISTORY
+The
+.Nm
+device first appeared in
+.Nx 6.0 .
+.Sh AUTHORS
+.An -nosplit
+The
+.Nm
+driver was written by
+.An Radoslaw Kujawa Aq [email protected] .
+.Sh CAVEATS
+Older versions of FastATA 1200 are NOT supported:
+.Bl -tag -width "ELBOX FastATA 1200 Mk-II" -offset indent
+.It Em ELBOX FastATA 1200 Mk-I
+.It Em ELBOX FastATA 1200 Lite
+.It Em ELBOX FastATA 1200 GOLD
+.It Em ELBOX FastATA 1200 Mk-II
+.El
+.Pp
+These devices do not generate hardware interrupts and need to be driven in
+non-standard polling mode. Code needed to support it is present in driver
+but does not work correctly.
+.Pp
+Some of the above devices were also marketed under PowerFlyer and Winner brands.
+.Pp
+The
+.Nm
+driver can not coexist with 
+.Xr wdc 4
+driver attached to
+.Xr mainbus 4 , 
+because FastATA 1200 hardware uses portions of the on-board Gayle IDE 
+controller. These 
+drivers should not be enabled in the same kernel.
+.Pp
+DMA modes are not supported, this is a hardware limitation.
+.Sh BUGS
+Performance is worse than with official AmigaOS driver from ELBOX.
+.Pp
+Disks paritioned in split mode, which is specific to official AmigaOS FastATA
+driver, are not recognized in NetBSD.
+.Pp
+Improved probe procedure should be written.

Index: src/sys/arch/amiga/dev/efa.c
diff -u /dev/null src/sys/arch/amiga/dev/efa.c:1.1
--- /dev/null	Thu Oct 27 22:12:25 2011
+++ src/sys/arch/amiga/dev/efa.c	Thu Oct 27 22:12:23 2011
@@ -0,0 +1,558 @@
+/*	$NetBSD: efa.c,v 1.1 2011/10/27 22:12:23 rkujawa Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Radoslaw Kujawa.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+/* 
+ * Driver for FastATA 1200 EIDE controller, manufactured by ELBOX Computer. 
+ *
+ * Gayle-related stuff inspired by wdc_amiga.c written by Michael L. Hitch
+ * and Aymeric Vincent. 
+ */
+
+#include <sys/cdefs.h>
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/device.h>
+#include <sys/bus.h>
+#include <sys/proc.h>
+#include <sys/kernel.h>
+#include <sys/kthread.h>
+
+#include <machine/cpu.h>
+#include <machine/intr.h>
+#include <sys/bswap.h>
+
+#include <amiga/amiga/cia.h>
+#include <amiga/amiga/custom.h>
+#include <amiga/amiga/device.h>
+#include <amiga/amiga/gayle.h>
+#include <amiga/dev/zbusvar.h>
+
+#include <dev/ata/atavar.h>
+#include <dev/ic/wdcvar.h>
+
+#include <amiga/dev/efareg.h>
+#include <amiga/dev/efavar.h>
+
+/* #define EFA_32BIT_IO 1 */
+/* #define EFA_NO_INTR 1 */
+/* #define EFA_DEBUG 1 */
+
+int		efa_probe(device_t, cfdata_t, void *);
+void		efa_attach(device_t, device_t, void *);
+int		efa_intr(void *);
+int		efa_intr_soft(void *arg);
+static void	efa_set_opts(struct efa_softc *sc);
+static bool	efa_mapbase(struct efa_softc *sc);
+static bool	efa_mapreg_gayle(struct efa_softc *sc);
+static bool	efa_mapreg_native(struct efa_softc *sc);
+static void	efa_fata_subregion_pio0(struct wdc_regs *wdr_fata);
+static void	efa_fata_subregion_pion(struct wdc_regs *wdr_fata, bool data32);
+static void	efa_setup_channel(struct ata_channel *chp);
+static void	efa_attach_channel(struct efa_softc *sc, int i);
+static void	efa_select_regset(struct efa_softc *sc, int chnum, 
+		    uint8_t piomode);
+static void	efa_poll_kthread(void *arg);
+#ifdef EFA_DEBUG
+static void	efa_debug_print_regmapping(struct wdc_regs *wdr_fata);
+#endif /* EFA_DEBUG */
+
+CFATTACH_DECL_NEW(efa, sizeof(struct efa_softc),
+    efa_probe, efa_attach, NULL, NULL);
+
+#define PIO_NSUPP		0xFFFFFFFF
+
+static const bus_addr_t		pio_offsets[] = 
+    { FATA1_PIO0_OFF, PIO_NSUPP, PIO_NSUPP, FATA1_PIO3_OFF, FATA1_PIO4_OFF, 
+      FATA1_PIO5_OFF };
+static const unsigned int	wdr_offsets_pio0[] = 
+    { FATA1_PIO0_OFF_DATA, FATA1_PIO0_OFF_ERROR, FATA1_PIO0_OFF_SECCNT,
+      FATA1_PIO0_OFF_SECTOR, FATA1_PIO0_OFF_CYL_LO, FATA1_PIO0_OFF_CYL_HI,
+      FATA1_PIO0_OFF_SDH, FATA1_PIO0_OFF_COMMAND };
+static const unsigned int	wdr_offsets_pion[] =
+    { FATA1_PION_OFF_DATA, FATA1_PION_OFF_ERROR, FATA1_PION_OFF_SECCNT,
+      FATA1_PION_OFF_SECTOR, FATA1_PION_OFF_CYL_LO, FATA1_PION_OFF_CYL_HI,
+      FATA1_PION_OFF_SDH, FATA1_PION_OFF_COMMAND };
+static const unsigned int	wdr_offsets_pion32[] =
+    { FATA1_PION_OFF_DATA32, FATA1_PION_OFF_ERROR, FATA1_PION_OFF_SECCNT,
+      FATA1_PION_OFF_SECTOR, FATA1_PION_OFF_CYL_LO, FATA1_PION_OFF_CYL_HI,
+      FATA1_PION_OFF_SDH, FATA1_PION_OFF_COMMAND };
+
+int
+efa_probe(device_t parent, cfdata_t cfp, void *aux)
+{
+	/* FastATA 1200 uses portions of Gayle IDE interface, and efa driver 
+	 * can't coexist with wdc_amiga. Match "wdc" on an A1200, because 
+         * FastATA 1200 does not autoconfigure. */
+	if( !matchname(aux, "wdc") || !is_a1200() )
+		return(0);
+
+	return 100;
+}
+
+void
+efa_attach(device_t parent, device_t self, void *aux)
+{
+	int i; 
+	struct efa_softc *sc = device_private(self);
+
+	aprint_normal(": ELBOX FastATA 1200\n");
+
+	gayle_init();
+
+	sc->sc_dev = self;
+
+	efa_set_opts(sc);
+
+	if(!efa_mapbase(sc)) {
+		aprint_error_dev(self, "couldn't map base addresses\n");
+		return;
+	}
+	if(!efa_mapreg_gayle(sc)) {
+		aprint_error_dev(self, "couldn't map Gayle registers\n");
+		return;
+	}
+	if(!efa_mapreg_native(sc)) {
+		aprint_error_dev(self, "couldn't map FastATA regsters\n");
+		return;
+	}
+
+	sc->sc_wdcdev.sc_atac.atac_pio_cap = 5; 
+	sc->sc_wdcdev.sc_atac.atac_nchannels = FATA1_CHANNELS;
+	sc->sc_wdcdev.sc_atac.atac_set_modes = efa_setup_channel;
+	sc->sc_wdcdev.sc_atac.atac_dev = self;
+	sc->sc_wdcdev.sc_atac.atac_channels = sc->sc_chanlist;
+
+	if(sc->sc_32bit_io)
+		sc->sc_wdcdev.sc_atac.atac_cap = ATAC_CAP_DATA32;
+	else	
+		sc->sc_wdcdev.sc_atac.atac_cap = ATAC_CAP_DATA16;
+	/*
+	 * The following should work for polling mode, but it does not.
+	 * if(sc->sc_no_intr) 
+	 *	sc->sc_wdcdev.sc_atac.atac_cap |= ATAC_CAP_NOIRQ;
+	 */
+
+	wdc_allocate_regs(&sc->sc_wdcdev);
+
+	sc->sc_intreg = &gayle.intreq;
+
+	for(i = 0; i < FATA1_CHANNELS; i++) {
+		efa_attach_channel(sc, i);
+	}
+
+	if(sc->sc_no_intr) {
+		sc->sc_fata_softintr = softint_establish(SOFTINT_BIO,
+		    (void (*)(void *))efa_intr_soft, sc);
+		if (sc->sc_fata_softintr == NULL) {
+			aprint_error_dev(self, "couldn't create soft intr\n");
+			return;
+		}
+		if (kthread_create(PRI_NONE, 0, NULL, efa_poll_kthread, sc,
+		    NULL, "efa")) {
+			aprint_error_dev(self, "couldn't create kthread\n");
+			return;
+		}
+	} else {
+		sc->sc_isr.isr_intr = efa_intr;
+		sc->sc_isr.isr_arg = sc;
+		sc->sc_isr.isr_ipl = 2;
+		add_isr (&sc->sc_isr);
+		gayle.intena |= GAYLE_INT_IDE;
+	}
+
+}
+
+static void
+efa_attach_channel(struct efa_softc *sc, int chnum) 
+{
+	sc->sc_chanlist[chnum] = &sc->sc_ports[chnum].chan;
+
+	sc->sc_ports[chnum].chan.ch_channel = chnum;
+	sc->sc_ports[chnum].chan.ch_atac = &sc->sc_wdcdev.sc_atac;
+	sc->sc_ports[chnum].chan.ch_queue = &sc->sc_ports[chnum].queue;
+	sc->sc_ports[chnum].chan.ch_ndrive = 2;
+
+	if(!sc->sc_32bit_io)
+		efa_select_regset(sc, chnum, 0); /* Start in PIO0. */
+	else
+		efa_select_regset(sc, chnum, 3); 
+
+	wdc_init_shadow_regs(&sc->sc_ports[chnum].chan);
+
+	wdcattach(&sc->sc_ports[chnum].chan);	
+
+#ifdef EFA_DEBUG
+	aprint_normal_dev(sc->sc_dev, "done init for channel %d\n", chnum);
+#endif
+
+}
+
+/* TODO: convert to callout(9) */ 
+static void
+efa_poll_kthread(void *arg)
+{
+	struct efa_softc *sc = arg;
+
+	for(;;) {
+		/* TODO: actually check if interrupt status register is set */
+		softint_schedule(sc->sc_fata_softintr);
+		/* TODO: convert to kpause */
+		tsleep(arg, PWAIT, "efa_poll", hz);
+	}
+}
+
+static void
+efa_set_opts(struct efa_softc *sc)
+{
+#ifdef EFA_32BIT_IO 
+	sc->sc_32bit_io = true;		/* XXX: bus_space_read_multi_stream_4 */
+#else
+	sc->sc_32bit_io = false;
+#endif /* EFA_32BIT_IO */
+
+#ifdef EFA_NO_INTR
+	sc->sc_no_intr = true;		/* XXX: not yet! */
+#else
+	sc->sc_no_intr = false;
+#endif /* EFA_NO_INTR */
+
+	if(sc->sc_no_intr)
+		aprint_verbose_dev(sc->sc_dev, "hardware interrupt disabled\n");
+
+	if(sc->sc_32bit_io)
+		aprint_verbose_dev(sc->sc_dev, "32-bit I/O enabled\n");
+}
+
+int
+efa_intr_soft(void *arg) 
+{
+	int ret = 0;
+	struct efa_softc *sc = (struct efa_softc *)arg;
+
+	/* TODO: check which channel needs servicing */
+	/* 
+	uint8_t fataintreq;
+	fataintreq = bus_space_read_1(sc->sc_ports[0].wdr[piom].cmd_iot, 
+	sc->sc_ports[chnum].intst[piom], 0);
+	*/
+
+	ret = wdcintr(&sc->sc_ports[0].chan);
+	ret = wdcintr(&sc->sc_ports[1].chan);
+
+	return ret;
+}
+
+int
+efa_intr(void *arg)
+{
+	struct efa_softc *sc = (struct efa_softc *)arg;
+	int r1, r2;
+
+	u_char intreq = *sc->sc_intreg;
+	int ret = 0;
+
+	if (intreq & GAYLE_INT_IDE) {
+		gayle.intreq = 0x7c | (intreq & 0x03);
+		/* How to check which channel caused interrupt?
+		 * Interrupt status register is not very useful here. */
+		r1 = wdcintr(&sc->sc_ports[0].chan);
+		r2 = wdcintr(&sc->sc_ports[1].chan);
+		ret = r1 | r2;
+	}
+
+	return ret;
+}
+
+static bool
+efa_mapbase(struct efa_softc *sc) 
+{
+	int i, j;
+	static struct bus_space_tag fata_cmd_iot;
+	static struct bus_space_tag gayle_cmd_iot;
+	
+	gayle_cmd_iot.base = (bus_addr_t) ztwomap(GAYLE_IDE_BASE + 2);
+	gayle_cmd_iot.absm = &amiga_bus_stride_4swap;
+	fata_cmd_iot.base = (bus_addr_t) ztwomap(FATA1_BASE);
+	fata_cmd_iot.absm = &amiga_bus_stride_4swap;
+
+#ifdef EFA_DEBUG
+	aprint_normal_dev(sc->sc_dev, "Gayle %x -> %x, FastATA %x -> %x\n",
+	    GAYLE_IDE_BASE, gayle_cmd_iot.base, FATA1_BASE, fata_cmd_iot.base);
+#endif
+
+	if(!gayle_cmd_iot.base)
+		return false;
+	if(!fata_cmd_iot.base)
+		return false;
+
+	sc->sc_gayle_wdc_regs.cmd_iot = &gayle_cmd_iot;
+	sc->sc_gayle_wdc_regs.ctl_iot = &gayle_cmd_iot;
+
+	for(i = 0; i < FATA1_CHANNELS; i++) {
+		for(j = 0; j < PIO_COUNT; j++) {
+			sc->sc_ports[i].wdr[j].cmd_iot = &fata_cmd_iot;
+			sc->sc_ports[i].wdr[j].ctl_iot = &gayle_cmd_iot;
+		}
+	}
+
+	return true;
+}
+
+
+/* Gayle IDE register mapping, we need it anyway. */
+static bool 
+efa_mapreg_gayle(struct efa_softc *sc)
+{
+	int i;
+
+	struct wdc_regs *wdr = &sc->sc_gayle_wdc_regs;
+
+	if (bus_space_map(wdr->cmd_iot, 0, 0x40, 0,
+			  &wdr->cmd_baseioh)) {
+		return false;
+	}
+
+	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) {
+
+			bus_space_unmap(wdr->cmd_iot,
+			    wdr->cmd_baseioh, 0x40);
+			return false;
+		}
+	}
+
+	if (bus_space_subregion(wdr->cmd_iot,
+	    wdr->cmd_baseioh, 0x406, 1, &wdr->ctl_ioh))
+		return false;
+
+	return true;
+}
+
+/* Native FastATA register mapping, suitable for PIO modes 0 to 5. */
+static bool
+efa_mapreg_native(struct efa_softc *sc) {
+	int i,j;
+	struct wdc_regs *wdr_gayle = &sc->sc_gayle_wdc_regs;
+	struct wdc_regs *wdr_fata;
+
+	for(i = 0; i < FATA1_CHANNELS; i++) {
+
+		for(j = 0; j < PIO_COUNT; j++) {
+
+			wdr_fata = &sc->sc_ports[i].wdr[j];
+			sc->sc_ports[i].mode_ok[j] = false;
+
+			if(pio_offsets[j] == PIO_NSUPP) {
+#ifdef EFA_DEBUG
+				aprint_normal_dev(sc->sc_dev, 
+				    "Skipping mapping for PIO mode %x\n", j);
+#endif
+				continue;
+			}
+
+			if(bus_space_map(wdr_fata->cmd_iot, 
+			    pio_offsets[j] + FATA1_CHAN_SIZE * i, 
+			    FATA1_CHAN_SIZE, 0, &wdr_fata->cmd_baseioh)) {
+			    return false;
+			}
+#ifdef EFA_DEBUG
+			aprint_normal_dev(sc->sc_dev, 
+			    "Chan %x PIO mode %x mapped %x -> %x\n",
+			    i, j, (bus_addr_t) kvtop((void*) 
+			    wdr_fata->cmd_baseioh), (unsigned int) 
+			    wdr_fata->cmd_baseioh);
+#endif
+
+			sc->sc_ports[i].mode_ok[j] = true;
+
+			if(j == 0)
+				efa_fata_subregion_pio0(wdr_fata);
+			else {
+				if(sc->sc_32bit_io) 
+					efa_fata_subregion_pion(wdr_fata, 
+					    true);
+				else 
+					efa_fata_subregion_pion(wdr_fata, 
+					    false);
+
+				bus_space_subregion(wdr_fata->cmd_iot,
+				    wdr_fata->cmd_baseioh, FATA1_PION_OFF_INTST,
+				    1, &sc->sc_ports[i].intst[j]);
+			}
+
+			/* No 32-bit register for PIO0 ... */
+			if(j == 0 && sc->sc_32bit_io)
+				sc->sc_ports[i].mode_ok[j] = false;
+			
+			wdr_fata->ctl_ioh = wdr_gayle->ctl_ioh; 
+		};
+	}
+	return true;
+}
+
+
+static void
+efa_fata_subregion_pio0(struct wdc_regs *wdr_fata) 
+{
+
+	bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 
+	    FATA1_PIO0_OFF_DATA, 4, &wdr_fata->cmd_iohs[wd_data]);
+	bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 
+	    FATA1_PIO0_OFF_ERROR, 1, &wdr_fata->cmd_iohs[wd_error]);
+	bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 
+	    FATA1_PIO0_OFF_SECCNT, 1, &wdr_fata->cmd_iohs[wd_seccnt]);
+	bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 
+	    FATA1_PIO0_OFF_SECTOR, 1, &wdr_fata->cmd_iohs[wd_sector]);
+	bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 
+	    FATA1_PIO0_OFF_CYL_LO, 1, &wdr_fata->cmd_iohs[wd_cyl_lo]);
+	bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 
+	    FATA1_PIO0_OFF_CYL_HI, 1, &wdr_fata->cmd_iohs[wd_cyl_hi]);
+	bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 
+	    FATA1_PIO0_OFF_SDH, 1, &wdr_fata->cmd_iohs[wd_sdh]);
+	bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 
+	    FATA1_PIO0_OFF_COMMAND, 1, &wdr_fata->cmd_iohs[wd_command]);
+}
+
+static void
+efa_fata_subregion_pion(struct wdc_regs *wdr_fata, bool data32) 
+{
+	if(data32)
+		bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 
+		    FATA1_PION_OFF_DATA32, 8, &wdr_fata->cmd_iohs[wd_data]);
+	else
+		bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 
+	    	    FATA1_PION_OFF_DATA, 4, &wdr_fata->cmd_iohs[wd_data]);
+
+	bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 
+	    FATA1_PION_OFF_ERROR, 1, &wdr_fata->cmd_iohs[wd_error]);
+	bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 
+	    FATA1_PION_OFF_SECCNT, 1, &wdr_fata->cmd_iohs[wd_seccnt]);
+	bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 
+	    FATA1_PION_OFF_SECTOR, 1, &wdr_fata->cmd_iohs[wd_sector]);
+	bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 
+	    FATA1_PION_OFF_CYL_LO, 1, &wdr_fata->cmd_iohs[wd_cyl_lo]);
+	bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 
+	    FATA1_PION_OFF_CYL_HI, 1, &wdr_fata->cmd_iohs[wd_cyl_hi]);
+	bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 
+	    FATA1_PION_OFF_SDH, 1, &wdr_fata->cmd_iohs[wd_sdh]);
+	bus_space_subregion(wdr_fata->cmd_iot, wdr_fata->cmd_baseioh, 
+	    FATA1_PION_OFF_COMMAND, 1, &wdr_fata->cmd_iohs[wd_command]);
+}
+
+static void
+efa_setup_channel(struct ata_channel *chp)
+{
+	int drive, chnum;
+	uint8_t mode; 
+	struct atac_softc *atac; 
+	struct ata_drive_datas *drvp;
+	struct efa_softc *sc;
+	int ipl;
+
+	chnum = chp->ch_channel;
+	atac = chp->ch_atac;
+	sc = device_private(atac->atac_dev);
+
+	mode = 5; /* start with fastest possible setting */
+
+#ifdef EFA_DEBUG
+	aprint_normal_dev(sc->sc_dev, "efa_setup_channel for ch %d\n",
+	    chnum);
+#endif /* EFA_DEBUG */
+
+	/* We might be in the middle of something... so raise IPL. */
+	ipl = splvm();
+
+	for (drive = 0; drive < 2; drive++) {
+		drvp = &chp->ch_drive[drive];
+
+		if ((drvp->drive_flags & DRIVE) == 0)
+			continue; /* nothing to see here */
+
+		if(drvp->PIO_cap < mode);
+			mode = drvp->PIO_cap;
+
+		/* TODO: check if sc_ports->mode_ok */
+
+#ifdef EFA_DEBUG
+		aprint_normal_dev(sc->sc_dev, "drive %d supports %d\n",
+		    drive, drvp->PIO_cap);
+#endif /* EFA_DEBUG */
+
+		drvp->PIO_mode = mode; 
+	}
+
+	/* Change FastATA register set. */
+	efa_select_regset(sc, chnum, mode);
+	/* re-init shadow regs */
+	wdc_init_shadow_regs(&sc->sc_ports[chnum].chan);
+
+	splx(ipl);
+}
+
+static void 
+efa_select_regset(struct efa_softc *sc, int chnum, uint8_t piomode) 
+{
+	struct wdc_softc *wdc;
+
+	wdc = CHAN_TO_WDC(&sc->sc_ports[chnum].chan);	
+	wdc->regs[chnum] = sc->sc_ports[chnum].wdr[piomode]; 
+
+#ifdef EFA_DEBUG
+	aprint_normal_dev(sc->sc_dev, "switched ch %d to PIO %d\n",
+	    chnum, piomode);
+
+	efa_debug_print_regmapping(&wdc->regs[chnum]);
+#endif /* EFA_DEBUG */
+}
+
+#ifdef EFA_DEBUG
+static void 
+efa_debug_print_regmapping(struct wdc_regs *wdr_fata) 
+{ 
+	int i;
+	aprint_normal("base %x->%x", 
+	    (bus_addr_t) kvtop((void*) wdr_fata->cmd_baseioh),
+	    (bus_addr_t) wdr_fata->cmd_baseioh);
+	for (i = 0; i < WDC_NREG; i++) {
+		aprint_normal("reg %x, %x->%x, ", i, 
+		    (bus_addr_t) kvtop((void*) wdr_fata->cmd_iohs[i]),
+		    (bus_addr_t) wdr_fata->cmd_iohs[i]);
+	}
+	aprint_normal("\n");
+}
+#endif /* EFA_DEBUG */
+
Index: src/sys/arch/amiga/dev/efareg.h
diff -u /dev/null src/sys/arch/amiga/dev/efareg.h:1.1
--- /dev/null	Thu Oct 27 22:12:25 2011
+++ src/sys/arch/amiga/dev/efareg.h	Thu Oct 27 22:12:23 2011
@@ -0,0 +1,74 @@
+/*	$NetBSD: efareg.h,v 1.1 2011/10/27 22:12:23 rkujawa Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Radoslaw Kujawa.
+ *
+ * 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.
+ *
+ * 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.
+ */
+
+#ifndef _AMIGA_EFAREG_H_
+
+#define GAYLE_IDE_BASE		0xDA0000
+#define FATA1_BASE		0xDA2000
+
+/* Offsets. Stride of 4 is used, so multiply any offset by 4. */
+#define FATA1_PIO0_OFF		0x0 // XXX 0
+#define FATA1_PIO3_OFF		0x4000
+#define FATA1_PIO4_OFF		0x5000
+#define FATA1_PIO5_OFF		0x4800
+
+#define FATA1_CHAN_SIZE		0x400
+#define FATA1_REGS_SIZE		0x4BC0
+
+/* PIO0 */
+#define FATA1_PIO0_OFF_DATA	0x0
+#define FATA1_PIO0_OFF_ERROR	0x1
+#define FATA1_PIO0_OFF_SECCNT	0x2
+#define FATA1_PIO0_OFF_SECTOR	0x3
+#define FATA1_PIO0_OFF_CYL_LO	0x4
+#define FATA1_PIO0_OFF_CYL_HI	0x5
+#define FATA1_PIO0_OFF_SDH	0x6
+#define FATA1_PIO0_OFF_COMMAND	0x7
+
+/* PIO3-5 */
+#define FATA1_PION_OFF_DATA	0x82	/* 16-bit data port */
+#define FATA1_PION_OFF_DATA32	0x0	/* 32-bit data port, 2 cycles to HD */
+#define FATA1_PION_OFF_ERROR	0x80
+#define FATA1_PION_OFF_SECCNT	0x100
+#define FATA1_PION_OFF_SECTOR	0x180
+#define FATA1_PION_OFF_CYL_LO	0x200
+#define FATA1_PION_OFF_CYL_HI	0x280
+#define FATA1_PION_OFF_SDH	0x300
+#define FATA1_PION_OFF_COMMAND	0x380
+
+#define FATA1_PION_OFF_INTST	0x140	/* FastATA interrupt status */
+
+#define FATA1_INT_ANY		0x80
+#define FATA1_INT_DRIVE0	0x40
+#define FATA1_INT_DRIVE1	0x20
+
+#endif /* _AMIGA_EFAREG_H_ */
+
Index: src/sys/arch/amiga/dev/efavar.h
diff -u /dev/null src/sys/arch/amiga/dev/efavar.h:1.1
--- /dev/null	Thu Oct 27 22:12:25 2011
+++ src/sys/arch/amiga/dev/efavar.h	Thu Oct 27 22:12:23 2011
@@ -0,0 +1,70 @@
+/*	$NetBSD: efavar.h,v 1.1 2011/10/27 22:12:23 rkujawa Exp $ */
+
+/*-
+ * Copyright (c) 2011 The NetBSD Foundation, Inc.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to The NetBSD Foundation
+ * by Radoslaw Kujawa.
+ *
+ * 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.
+ *
+ * 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 <dev/ata/atavar.h>
+#include <dev/ic/wdcvar.h>
+
+#define FATA1_CHANNELS		2
+#define PIO_COUNT		6
+
+struct efa_port {
+
+	struct ata_channel	chan;
+	struct ata_queue	queue;
+
+	uint8_t			mode;		/* currently set mode */
+
+	struct wdc_regs		wdr[6];		/* PIO0-5 */
+	bus_space_handle_t	intst[6];	/* interrupt status register */
+	bool			mode_ok[6];	/* is this PIO mode usable? */
+};
+
+struct efa_softc {
+	device_t		sc_dev;
+
+	struct wdc_softc	sc_wdcdev;
+	struct ata_channel	*sc_chanlist[FATA1_CHANNELS];
+
+	struct efa_port		sc_ports[FATA1_CHANNELS];
+
+	/* Force 32-bit data port, otherwise always use 16-bit */
+	bool			sc_32bit_io;
+	/* Disable hw interrupt support (for FastATA 1200 older than Mk-III) */
+	bool			sc_no_intr;
+
+	struct isr		sc_isr;
+	volatile u_char		*sc_intreg;
+
+	void			*sc_fata_softintr;	
+
+	struct wdc_regs		sc_gayle_wdc_regs;
+};
+

Reply via email to