summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMiod Vallat <miod@cvs.openbsd.org>2006-01-18 23:21:18 +0000
committerMiod Vallat <miod@cvs.openbsd.org>2006-01-18 23:21:18 +0000
commit86f7c20fe196e86a4d1c2ff666c443d883ea7744 (patch)
tree46eb3861bc677dbb3f6d3f92b54b9d4551984a84 /sys
parent692e73fadabe759f8814dda668273f20082e8cdb (diff)
Factorize akbd and ams drivers between mac68k and macppc; while there, start
moving out common adb code as well, and merge adb_direct.c into adb.c to simplify external header files. No functional change; more cleanups to come.
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/mac68k/conf/files.mac68k14
-rw-r--r--sys/arch/mac68k/dev/adb.c2832
-rw-r--r--sys/arch/mac68k/dev/adb_direct.c2759
-rw-r--r--sys/arch/mac68k/dev/adbvar.h56
-rw-r--r--sys/arch/mac68k/dev/akbd.c550
-rw-r--r--sys/arch/mac68k/dev/akbd_machdep.c136
-rw-r--r--sys/arch/mac68k/dev/pm_direct.c3
-rw-r--r--sys/arch/mac68k/include/adbsys.h116
-rw-r--r--sys/arch/mac68k/mac68k/autoconf.c5
-rw-r--r--sys/arch/mac68k/mac68k/pram.c4
-rw-r--r--sys/arch/mac68k/mac68k/wscons_machdep.c4
-rw-r--r--sys/arch/macppc/conf/files.macppc14
-rw-r--r--sys/arch/macppc/dev/abtn.c6
-rw-r--r--sys/arch/macppc/dev/adb.c1641
-rw-r--r--sys/arch/macppc/dev/adb_direct.c1569
-rw-r--r--sys/arch/macppc/dev/adbvar.h54
-rw-r--r--sys/arch/macppc/dev/akbd_machdep.c (renamed from sys/arch/macppc/dev/amsvar.h)102
-rw-r--r--sys/arch/macppc/dev/akbdmap.h453
-rw-r--r--sys/arch/macppc/dev/akbdvar.h71
-rw-r--r--sys/arch/macppc/dev/ams.c535
-rw-r--r--sys/arch/macppc/dev/apm.c3
-rw-r--r--sys/arch/macppc/dev/pm_direct.c4
-rw-r--r--sys/arch/macppc/macppc/ofw_machdep.c10
-rw-r--r--sys/dev/adb/adb.h (renamed from sys/arch/macppc/include/adbsys.h)68
-rw-r--r--sys/dev/adb/adb_subr.c108
-rw-r--r--sys/dev/adb/akbd.c (renamed from sys/arch/macppc/dev/akbd.c)163
-rw-r--r--sys/dev/adb/akbdmap.h (renamed from sys/arch/mac68k/dev/akbdmap.h)166
-rw-r--r--sys/dev/adb/akbdvar.h (renamed from sys/arch/mac68k/dev/akbdvar.h)17
-rw-r--r--sys/dev/adb/ams.c (renamed from sys/arch/mac68k/dev/ams.c)24
-rw-r--r--sys/dev/adb/amsvar.h (renamed from sys/arch/mac68k/dev/amsvar.h)13
-rw-r--r--sys/dev/adb/files.adb11
-rw-r--r--sys/dev/adb/keyboard.h217
32 files changed, 5112 insertions, 6616 deletions
diff --git a/sys/arch/mac68k/conf/files.mac68k b/sys/arch/mac68k/conf/files.mac68k
index 319d2c4d597..d31cb41db0d 100644
--- a/sys/arch/mac68k/conf/files.mac68k
+++ b/sys/arch/mac68k/conf/files.mac68k
@@ -1,4 +1,4 @@
-# $OpenBSD: files.mac68k,v 1.39 2006/01/13 19:36:41 miod Exp $
+# $OpenBSD: files.mac68k,v 1.40 2006/01/18 23:21:14 miod Exp $
# $NetBSD: files.mac68k,v 1.61 1997/03/01 20:22:16 scottr Exp $
# mac68k-specific configuration info
@@ -22,8 +22,7 @@ file arch/mac68k/dev/nubus.c nubus
device adb {}
attach adb at obio
file arch/mac68k/dev/adb.c adb
-file arch/mac68k/dev/adb_direct.c adb
-file arch/mac68k/dev/pm_direct.c
+file arch/mac68k/dev/pm_direct.c adb
#
# "workstation console" routines
@@ -35,13 +34,8 @@ include "dev/wsfont/files.wsfont"
#
# adb devices
#
-device akbd: wskbddev
-attach akbd at adb
-file arch/mac68k/dev/akbd.c akbd needs-flag
-
-device ams: wsmousedev
-attach ams at adb
-file arch/mac68k/dev/ams.c ams needs-flag
+include "dev/adb/files.adb"
+file arch/mac68k/dev/akbd_machdep.c akbd
device asc
attach asc at obio
diff --git a/sys/arch/mac68k/dev/adb.c b/sys/arch/mac68k/dev/adb.c
index aa8918ba0e7..37d361da486 100644
--- a/sys/arch/mac68k/dev/adb.c
+++ b/sys/arch/mac68k/dev/adb.c
@@ -1,5 +1,36 @@
-/* $OpenBSD: adb.c,v 1.18 2006/01/13 19:36:43 miod Exp $ */
+/* $OpenBSD: adb.c,v 1.19 2006/01/18 23:21:16 miod Exp $ */
/* $NetBSD: adb.c,v 1.47 2005/06/16 22:43:36 jmc Exp $ */
+/* $NetBSD: adb_direct.c,v 1.51 2005/06/16 22:43:36 jmc Exp $ */
+
+/*
+ * Copyright (C) 1996, 1997 John P. Wittkoski
+ * All rights reserved.
+ *
+ * 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 John P. Wittkoski.
+ * 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.
+ */
/*
* Copyright (C) 1994 Bradley A. Grantham
@@ -31,6 +62,33 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * This code is rather messy, but I don't have time right now
+ * to clean it up as much as I would like.
+ * But it works, so I'm happy. :-) jpw
+ */
+
+/*
+ * TO DO:
+ * - We could reduce the time spent in the adb_intr_* routines
+ * by having them save the incoming and outgoing data directly
+ * in the adbInbound and adbOutbound queues, as it would reduce
+ * the number of times we need to copy the data around. It
+ * would also make the code more readable and easier to follow.
+ * - (Related to above) Use the header part of adbCommand to
+ * reduce the number of copies we have to do of the data.
+ * - (Related to above) Actually implement the adbOutbound queue.
+ * This is fairly easy once you switch all the intr routines
+ * over to using adbCommand structs directly.
+ * - There is a bug in the state machine of adb_intr_cuda
+ * code that causes hangs, especially on 030 machines, probably
+ * because of some timing issues. Because I have been unable to
+ * determine the exact cause of this bug, I used the timeout function
+ * to check for and recover from this condition. If anyone finds
+ * the actual cause of this bug, the calls to timeout and the
+ * adb_cuda_tickle routine can be removed.
+ */
+
#include <sys/param.h>
#include <sys/device.h>
#include <sys/fcntl.h>
@@ -38,174 +96,2368 @@
#include <sys/selinfo.h>
#include <sys/proc.h>
#include <sys/signalvar.h>
+#include <sys/timeout.h>
#include <sys/systm.h>
#include <machine/autoconf.h>
#include <machine/cpu.h>
+#include <machine/viareg.h>
+#include <dev/adb/adb.h>
#include <mac68k/dev/adbvar.h>
+#define printf_intr printf
+
+int adb_polling; /* Are we polling? (Debugger mode) */
+#ifdef ADB_DEBUG
+int adb_debug; /* Output debugging messages */
+#endif /* ADB_DEBUG */
+
+/* some misc. leftovers */
+#define vPB 0x0000
+#define vPB3 0x08
+#define vPB4 0x10
+#define vPB5 0x20
+#define vSR_INT 0x04
+#define vSR_OUT 0x10
+
+/* the type of ADB action that we are currently preforming */
+#define ADB_ACTION_NOTREADY 0x1 /* has not been initialized yet */
+#define ADB_ACTION_IDLE 0x2 /* the bus is currently idle */
+#define ADB_ACTION_OUT 0x3 /* sending out a command */
+#define ADB_ACTION_IN 0x4 /* receiving data */
+#define ADB_ACTION_POLLING 0x5 /* polling - II only */
+
/*
- * Function declarations.
+ * These describe the state of the ADB bus itself, although they
+ * don't necessarily correspond directly to ADB states.
+ * Note: these are not really used in the IIsi code.
*/
-int adbmatch(struct device *, void *, void *);
-void adbattach(struct device *, struct device *, void *);
-int adbprint(void *, const char *);
-void adb_attach_deferred(void *);
+#define ADB_BUS_UNKNOWN 0x1 /* we don't know yet - all models */
+#define ADB_BUS_IDLE 0x2 /* bus is idle - all models */
+#define ADB_BUS_CMD 0x3 /* starting a command - II models */
+#define ADB_BUS_ODD 0x4 /* the "odd" state - II models */
+#define ADB_BUS_EVEN 0x5 /* the "even" state - II models */
+#define ADB_BUS_ACTIVE 0x6 /* active state - IIsi models */
+#define ADB_BUS_ACK 0x7 /* currently ACKing - IIsi models */
+
+/*
+ * Shortcuts for setting or testing the VIA bit states.
+ * Not all shortcuts are used for every type of ADB hardware.
+ */
+#define ADB_SET_STATE_IDLE_II() via_reg(VIA1, vBufB) |= (vPB4 | vPB5)
+#define ADB_SET_STATE_IDLE_IISI() via_reg(VIA1, vBufB) &= ~(vPB4 | vPB5)
+#define ADB_SET_STATE_IDLE_CUDA() via_reg(VIA1, vBufB) |= (vPB4 | vPB5)
+#define ADB_SET_STATE_CMD() via_reg(VIA1, vBufB) &= ~(vPB4 | vPB5)
+#define ADB_SET_STATE_EVEN() via_reg(VIA1, vBufB) = ((via_reg(VIA1, \
+ vBufB) | vPB4) & ~vPB5)
+#define ADB_SET_STATE_ODD() via_reg(VIA1, vBufB) = ((via_reg(VIA1, \
+ vBufB) | vPB5) & ~vPB4)
+#define ADB_SET_STATE_ACTIVE() via_reg(VIA1, vBufB) |= vPB5
+#define ADB_SET_STATE_INACTIVE() via_reg(VIA1, vBufB) &= ~vPB5
+#define ADB_SET_STATE_TIP() via_reg(VIA1, vBufB) &= ~vPB5
+#define ADB_CLR_STATE_TIP() via_reg(VIA1, vBufB) |= vPB5
+#define ADB_SET_STATE_ACKON() via_reg(VIA1, vBufB) |= vPB4
+#define ADB_SET_STATE_ACKOFF() via_reg(VIA1, vBufB) &= ~vPB4
+#define ADB_TOGGLE_STATE_ACK_CUDA() via_reg(VIA1, vBufB) ^= vPB4
+#define ADB_SET_STATE_ACKON_CUDA() via_reg(VIA1, vBufB) &= ~vPB4
+#define ADB_SET_STATE_ACKOFF_CUDA() via_reg(VIA1, vBufB) |= vPB4
+#define ADB_SET_SR_INPUT() via_reg(VIA1, vACR) &= ~vSR_OUT
+#define ADB_SET_SR_OUTPUT() via_reg(VIA1, vACR) |= vSR_OUT
+#define ADB_SR() via_reg(VIA1, vSR)
+#define ADB_VIA_INTR_ENABLE() via_reg(VIA1, vIER) = 0x84
+#define ADB_VIA_INTR_DISABLE() via_reg(VIA1, vIER) = 0x04
+#define ADB_VIA_CLR_INTR() via_reg(VIA1, vIFR) = 0x04
+#define ADB_INTR_IS_OFF (vPB3 == (via_reg(VIA1, vBufB) & vPB3))
+#define ADB_INTR_IS_ON (0 == (via_reg(VIA1, vBufB) & vPB3))
+#define ADB_SR_INTR_IS_OFF (0 == (via_reg(VIA1, vIFR) & vSR_INT))
+#define ADB_SR_INTR_IS_ON (vSR_INT == (via_reg(VIA1, \
+ vIFR) & vSR_INT))
-extern void adb_jadbproc(void);
+/*
+ * This is the delay that is required (in uS) between certain
+ * ADB transactions. The actual timing delay for for each uS is
+ * calculated at boot time to account for differences in machine speed.
+ */
+#define ADB_DELAY 150
/*
- * Global variables.
+ * Maximum ADB message length; includes space for data, result, and
+ * device code - plus a little for safety.
*/
-int adb_polling = 0; /* Are we polling? (Debugger mode) */
-#ifdef ADB_DEBUG
-int adb_debug = 0; /* Output debugging messages */
-#endif /* ADB_DEBUG */
+#define ADB_MAX_MSG_LENGTH 16
+#define ADB_MAX_HDR_LENGTH 8
-extern struct mac68k_machine_S mac68k_machine;
-extern int adbHardware;
-extern char *adbHardwareDescr[];
+#define ADB_QUEUE 32
+#define ADB_TICKLE_TICKS 4
/*
- * Driver definition.
+ * A structure for storing information about each ADB device.
*/
-struct cfattach adb_ca = {
- sizeof(struct device), adbmatch, adbattach
+struct ADBDevEntry {
+ void (*ServiceRtPtr)(void);
+ void *DataAreaAddr;
+ int devType;
+ int origAddr;
+ int currentAddr;
};
-struct cfdriver adb_cd = {
- NULL, "adb", DV_DULL
+
+/*
+ * Used to hold ADB commands that are waiting to be sent out.
+ */
+struct adbCmdHoldEntry {
+ u_char outBuf[ADB_MAX_MSG_LENGTH]; /* our message */
+ u_char *saveBuf; /* buffer to know where to save result */
+ u_char *compRout; /* completion routine pointer */
+ u_char *data; /* completion routine data pointer */
};
-int
-adbmatch(struct device *parent, void *vcf, void *aux)
-{
- static int adb_matched = 0;
+/*
+ * Eventually used for two separate queues, the queue between
+ * the upper and lower halves, and the outgoing packet queue.
+ * TO DO: adbCommand can replace all of adbCmdHoldEntry eventually
+ */
+struct adbCommand {
+ u_char header[ADB_MAX_HDR_LENGTH]; /* not used yet */
+ u_char data[ADB_MAX_MSG_LENGTH]; /* packet data only */
+ u_char *saveBuf; /* where to save result */
+ u_char *compRout; /* completion routine pointer */
+ u_char *compData; /* completion routine data pointer */
+ u_int cmd; /* the original command for this data */
+ u_int unsol; /* 1 if packet was unsolicited */
+ u_int ack_only; /* 1 for no special processing */
+};
- /* Allow only one instance. */
- if (adb_matched)
- return (0);
+/*
+ * Text representations of each hardware class
+ */
+const char *adbHardwareDescr[MAX_ADB_HW + 1] = {
+ "unknown",
+ "II series",
+ "IIsi series",
+ "PowerBook",
+ "Cuda",
+};
- adb_matched = 1;
- return (1);
-}
+/*
+ * A few variables that we need and their initial values.
+ */
+int adbHardware = ADB_HW_UNKNOWN;
+int adbActionState = ADB_ACTION_NOTREADY;
+int adbBusState = ADB_BUS_UNKNOWN;
+int adbWaiting = 0; /* waiting for return data from the device */
+int adbWriteDelay = 0; /* working on (or waiting to do) a write */
+int adbOutQueueHasData = 0; /* something in the queue waiting to go out */
+int adbNextEnd = 0; /* the next incoming bute is the last (II) */
+int adbSoftPower = 0; /* machine supports soft power */
+
+int adbWaitingCmd = 0; /* ADB command we are waiting for */
+u_char *adbBuffer = (long)0; /* pointer to user data area */
+void *adbCompRout = (long)0; /* pointer to the completion routine */
+void *adbCompData = (long)0; /* pointer to the completion routine data */
+long adbFakeInts = 0; /* keeps track of fake ADB interrupts for
+ * timeouts (II) */
+int adbStarting = 1; /* doing adb_reinit so do polling differently */
+int adbSendTalk = 0; /* the intr routine is sending the talk, not
+ * the user (II) */
+int adbPolling = 0; /* we are polling for service request */
+int adbPollCmd = 0; /* the last poll command we sent */
+
+u_char adbInputBuffer[ADB_MAX_MSG_LENGTH]; /* data input buffer */
+u_char adbOutputBuffer[ADB_MAX_MSG_LENGTH]; /* data output buffer */
+struct adbCmdHoldEntry adbOutQueue; /* our 1 entry output queue */
+
+int adbSentChars = 0; /* how many characters we have sent */
+int adbLastDevice = 0; /* last ADB dev we heard from (II ONLY) */
+int adbLastDevIndex = 0; /* last ADB dev loc in dev table (II ONLY) */
+int adbLastCommand = 0; /* the last ADB command we sent (II) */
+struct ADBDevEntry ADBDevTable[16]; /* our ADB device table */
+int ADBNumDevices; /* num. of ADB devices found with adb_reinit */
+
+struct adbCommand adbInbound[ADB_QUEUE]; /* incoming queue */
+volatile int adbInCount = 0; /* how many packets in in queue */
+int adbInHead = 0; /* head of in queue */
+int adbInTail = 0; /* tail of in queue */
+struct adbCommand adbOutbound[ADB_QUEUE]; /* outgoing queue - not used yet */
+int adbOutCount = 0; /* how many packets in out queue */
+int adbOutHead = 0; /* head of out queue */
+int adbOutTail = 0; /* tail of out queue */
+
+int tickle_count = 0; /* how many tickles seen for this packet? */
+int tickle_serial = 0; /* the last packet tickled */
+int adb_cuda_serial = 0; /* the current packet */
+
+struct timeout adb_cuda_timeout;
+
+void pm_setup_adb(void);
+void pm_hw_setup(void);
+void pm_check_adb_devices(int);
+int pm_adb_op(u_char *, void *, void *, int);
+void pm_init_adb_device(void);
+
+/*
+ * The following are private routines.
+ */
+#ifdef ADB_DEBUG
+void print_single(u_char *);
+#endif
+int adb_intr(void *);
+int adb_intr_II(void *);
+int adb_intr_IIsi(void *);
+int adb_intr_cuda(void *);
+void adb_soft_intr(void);
+int send_adb_II(u_char *, u_char *, void *, void *, int);
+int send_adb_IIsi(u_char *, u_char *, void *, void *, int);
+int send_adb_cuda(u_char *, u_char *, void *, void *, int);
+void adb_intr_cuda_test(void);
+void adb_cuda_tickle(void);
+void adb_pass_up(struct adbCommand *);
+void adb_op_comprout(caddr_t, caddr_t, int);
+void adb_reinit(void);
+int count_adbs(void);
+int get_ind_adb_info(ADBDataBlock *, int);
+int get_adb_info(ADBDataBlock *, int);
+int set_adb_info(ADBSetInfoBlock *, int);
+void adb_setup_hw_type(void);
+int adb_op(Ptr, Ptr, Ptr, short);
+void adb_read_II(u_char *);
+void adb_hw_setup(void);
+void adb_hw_setup_IIsi(u_char *);
+int adb_cmd_result(u_char *);
+int adb_cmd_extra(u_char *);
+int adb_guess_next_device(void);
+int adb_prog_switch_enable(void);
+int adb_prog_switch_disable(void);
+/* we should create this and it will be the public version */
+int send_adb(u_char *, void *, void *);
+
+#ifdef ADB_DEBUG
+/*
+ * print_single
+ * Diagnostic display routine. Displays the hex values of the
+ * specified elements of the u_char. The length of the "string"
+ * is in [0].
+ */
void
-adbattach(struct device *parent, struct device *self, void *aux)
+print_single(u_char *str)
{
- printf("\n");
- startuphook_establish(adb_attach_deferred, self);
+ int x;
+
+ if (str == 0) {
+ printf_intr("no data - null pointer\n");
+ return;
+ }
+ if (*str == 0) {
+ printf_intr("nothing returned\n");
+ return;
+ }
+ if (*str > 20) {
+ printf_intr("ADB: ACK > 20 no way!\n");
+ *str = (u_char)20;
+ }
+ printf_intr("(length=0x%x):", (u_int)*str);
+ for (x = 1; x <= *str; x++)
+ printf_intr(" 0x%02x", (u_int)*(str + x));
+ printf_intr("\n");
}
+#endif
void
-adb_attach_deferred(void *v)
+adb_cuda_tickle(void)
{
- struct device *self = v;
- ADBDataBlock adbdata;
- struct adb_attach_args aa_args;
- int totaladbs;
- int adbindex, adbaddr;
+ volatile int s;
- printf("%s", self->dv_xname);
- adb_polling = 1;
+ if (adbActionState == ADB_ACTION_IN) {
+ if (tickle_serial == adb_cuda_serial) {
+ if (++tickle_count > 0) {
+ s = splhigh();
+ adbActionState = ADB_ACTION_IDLE;
+ adbInputBuffer[0] = 0;
+ ADB_SET_STATE_IDLE_CUDA();
+ splx(s);
+ }
+ } else {
+ tickle_serial = adb_cuda_serial;
+ tickle_count = 0;
+ }
+ } else {
+ tickle_serial = adb_cuda_serial;
+ tickle_count = 0;
+ }
- ADBReInit();
- printf(": %s", adbHardwareDescr[adbHardware]);
+ timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS);
+}
+
+/*
+ * called when when an adb interrupt happens
+ *
+ * Cuda version of adb_intr
+ * TO DO: do we want to add some calls to intr_dispatch() here to
+ * grab serial interrupts?
+ */
+int
+adb_intr_cuda(void *arg)
+{
+ volatile int i, ending;
+ volatile unsigned int s;
+ struct adbCommand packet;
+
+ s = splhigh(); /* can't be too careful - might be called */
+ /* from a routine, NOT an interrupt */
+
+ ADB_VIA_CLR_INTR(); /* clear interrupt */
+ ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */
+
+switch_start:
+ switch (adbActionState) {
+ case ADB_ACTION_IDLE:
+ /*
+ * This is an unexpected packet, so grab the first (dummy)
+ * byte, set up the proper vars, and tell the chip we are
+ * starting to receive the packet by setting the TIP bit.
+ */
+ adbInputBuffer[1] = ADB_SR();
+ adb_cuda_serial++;
+ if (ADB_INTR_IS_OFF) /* must have been a fake start */
+ break;
+
+ ADB_SET_SR_INPUT();
+ ADB_SET_STATE_TIP();
+
+ adbInputBuffer[0] = 1;
+ adbActionState = ADB_ACTION_IN;
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("idle 0x%02x ", adbInputBuffer[1]);
+#endif
+ break;
+
+ case ADB_ACTION_IN:
+ adbInputBuffer[++adbInputBuffer[0]] = ADB_SR();
+ /* intr off means this is the last byte (end of frame) */
+ if (ADB_INTR_IS_OFF)
+ ending = 1;
+ else
+ ending = 0;
+
+ if (1 == ending) { /* end of message? */
+#ifdef ADB_DEBUG
+ if (adb_debug) {
+ printf_intr("in end 0x%02x ",
+ adbInputBuffer[adbInputBuffer[0]]);
+ print_single(adbInputBuffer);
+ }
+#endif
+
+ /*
+ * Are we waiting AND does this packet match what we
+ * are waiting for AND is it coming from either the
+ * ADB or RTC/PRAM sub-device? This section _should_
+ * recognize all ADB and RTC/PRAM type commands, but
+ * there may be more... NOTE: commands are always at
+ * [4], even for RTC/PRAM commands.
+ */
+ /* set up data for adb_pass_up */
+ memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
+
+ if ((adbWaiting == 1) &&
+ (adbInputBuffer[4] == adbWaitingCmd) &&
+ ((adbInputBuffer[2] == 0x00) ||
+ (adbInputBuffer[2] == 0x01))) {
+ packet.saveBuf = adbBuffer;
+ packet.compRout = adbCompRout;
+ packet.compData = adbCompData;
+ packet.unsol = 0;
+ packet.ack_only = 0;
+ adb_pass_up(&packet);
+
+ adbWaitingCmd = 0; /* reset "waiting" vars */
+ adbWaiting = 0;
+ adbBuffer = (long)0;
+ adbCompRout = (long)0;
+ adbCompData = (long)0;
+ } else {
+ packet.unsol = 1;
+ packet.ack_only = 0;
+ adb_pass_up(&packet);
+ }
+
+
+ /* reset vars and signal the end of this frame */
+ adbActionState = ADB_ACTION_IDLE;
+ adbInputBuffer[0] = 0;
+ ADB_SET_STATE_IDLE_CUDA();
+ /*ADB_SET_SR_INPUT();*/
+
+ /*
+ * If there is something waiting to be sent out,
+ * the set everything up and send the first byte.
+ */
+ if (adbWriteDelay == 1) {
+ delay(ADB_DELAY); /* required */
+ adbSentChars = 0;
+ adbActionState = ADB_ACTION_OUT;
+ /*
+ * If the interrupt is on, we were too slow
+ * and the chip has already started to send
+ * something to us, so back out of the write
+ * and start a read cycle.
+ */
+ if (ADB_INTR_IS_ON) {
+ ADB_SET_SR_INPUT();
+ ADB_SET_STATE_IDLE_CUDA();
+ adbSentChars = 0;
+ adbActionState = ADB_ACTION_IDLE;
+ adbInputBuffer[0] = 0;
+ break;
+ }
+ /*
+ * If we got here, it's ok to start sending
+ * so load the first byte and tell the chip
+ * we want to send.
+ */
+ ADB_SET_STATE_TIP();
+ ADB_SET_SR_OUTPUT();
+ ADB_SR() = adbOutputBuffer[adbSentChars + 1];
+ }
+ } else {
+ ADB_TOGGLE_STATE_ACK_CUDA();
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("in 0x%02x ",
+ adbInputBuffer[adbInputBuffer[0]]);
+#endif
+ }
+ break;
+
+ case ADB_ACTION_OUT:
+ i = ADB_SR(); /* reset SR-intr in IFR */
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("intr out 0x%02x ", i);
+#endif
+
+ adbSentChars++;
+ if (ADB_INTR_IS_ON) { /* ADB intr low during write */
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("intr was on ");
+#endif
+ ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
+ ADB_SET_STATE_IDLE_CUDA();
+ adbSentChars = 0; /* must start all over */
+ adbActionState = ADB_ACTION_IDLE; /* new state */
+ adbInputBuffer[0] = 0;
+ adbWriteDelay = 1; /* must retry when done with
+ * read */
+ delay(ADB_DELAY);
+ goto switch_start; /* process next state right
+ * now */
+ break;
+ }
+ if (adbOutputBuffer[0] == adbSentChars) { /* check for done */
+ if (0 == adb_cmd_result(adbOutputBuffer)) { /* do we expect data
+ * back? */
+ adbWaiting = 1; /* signal waiting for return */
+ adbWaitingCmd = adbOutputBuffer[2]; /* save waiting command */
+ } else { /* no talk, so done */
+ /* set up stuff for adb_pass_up */
+ memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
+ packet.saveBuf = adbBuffer;
+ packet.compRout = adbCompRout;
+ packet.compData = adbCompData;
+ packet.cmd = adbWaitingCmd;
+ packet.unsol = 0;
+ packet.ack_only = 1;
+ adb_pass_up(&packet);
+
+ /* reset "waiting" vars, just in case */
+ adbWaitingCmd = 0;
+ adbBuffer = (long)0;
+ adbCompRout = (long)0;
+ adbCompData = (long)0;
+ }
+
+ adbWriteDelay = 0; /* done writing */
+ adbActionState = ADB_ACTION_IDLE; /* signal bus is idle */
+ ADB_SET_SR_INPUT();
+ ADB_SET_STATE_IDLE_CUDA();
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("write done ");
+#endif
+ } else {
+ ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* send next byte */
+ ADB_TOGGLE_STATE_ACK_CUDA(); /* signal byte ready to
+ * shift */
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("toggle ");
+#endif
+ }
+ break;
+
+ case ADB_ACTION_NOTREADY:
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("adb: not yet initialized\n");
+#endif
+ break;
+
+ default:
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("intr: unknown ADB state\n");
+#endif
+ break;
+ }
+
+ ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */
+
+ splx(s); /* restore */
+
+ return (1);
+} /* end adb_intr_cuda */
+
+
+int
+send_adb_cuda(u_char *in, u_char *buffer, void *compRout, void *data, int
+ command)
+{
+ int s, len;
#ifdef ADB_DEBUG
if (adb_debug)
- printf("adb: done with ADBReInit\n");
+ printf_intr("SEND\n");
#endif
- totaladbs = CountADBs();
+ if (adbActionState == ADB_ACTION_NOTREADY)
+ return 1;
- printf(", %d target%s\n", totaladbs, (totaladbs == 1) ? "" : "s");
+ /* Don't interrupt while we are messing with the ADB */
+ s = splhigh();
- /* for each ADB device */
- for (adbindex = 1; adbindex <= totaladbs; adbindex++) {
- /* Get the ADB information */
- adbaddr = GetIndADB(&adbdata, adbindex);
+ if ((adbActionState == ADB_ACTION_IDLE) && /* ADB available? */
+ (ADB_INTR_IS_OFF)) { /* and no incoming interrupt? */
+ } else
+ if (adbWriteDelay == 0) /* it's busy, but is anything waiting? */
+ adbWriteDelay = 1; /* if no, then we'll "queue"
+ * it up */
+ else {
+ splx(s);
+ return 1; /* really busy! */
+ }
- aa_args.origaddr = (int)(adbdata.origADBAddr);
- aa_args.adbaddr = adbaddr;
- aa_args.handler_id = (int)(adbdata.devType);
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("QUEUE\n");
+#endif
+ if ((long)in == (long)0) { /* need to convert? */
+ /*
+ * Don't need to use adb_cmd_extra here because this section
+ * will be called ONLY when it is an ADB command (no RTC or
+ * PRAM)
+ */
+ if ((command & 0x0c) == 0x08) /* copy addl data ONLY if
+ * doing a listen! */
+ len = buffer[0]; /* length of additional data */
+ else
+ len = 0;/* no additional data */
- (void)config_found(self, &aa_args, adbprint);
+ adbOutputBuffer[0] = 2 + len; /* dev. type + command + addl.
+ * data */
+ adbOutputBuffer[1] = 0x00; /* mark as an ADB command */
+ adbOutputBuffer[2] = (u_char)command; /* load command */
+
+ /* copy additional output data, if any */
+ memcpy(adbOutputBuffer + 3, buffer + 1, len);
+ } else
+ /* if data ready, just copy over */
+ memcpy(adbOutputBuffer, in, in[0] + 2);
+
+ adbSentChars = 0; /* nothing sent yet */
+ adbBuffer = buffer; /* save buffer to know where to save result */
+ adbCompRout = compRout; /* save completion routine pointer */
+ adbCompData = data; /* save completion routine data pointer */
+ adbWaitingCmd = adbOutputBuffer[2]; /* save wait command */
+
+ if (adbWriteDelay != 1) { /* start command now? */
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("out start NOW");
+#endif
+ delay(ADB_DELAY);
+ adbActionState = ADB_ACTION_OUT; /* set next state */
+ ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
+ ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* load byte for output */
+ ADB_SET_STATE_ACKOFF_CUDA();
+ ADB_SET_STATE_TIP(); /* tell ADB that we want to send */
}
- adb_polling = 0;
-}
+ adbWriteDelay = 1; /* something in the write "queue" */
+
+ splx(s);
+
+ if (0x0100 <= (s & 0x0700)) /* were VIA1 interrupts blocked? */
+ /* poll until byte done */
+ while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
+ || (adbWaiting == 1))
+ if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
+ adb_intr_cuda(NULL); /* go process it */
+ if (adb_polling)
+ adb_soft_intr();
+ }
+
+ return 0;
+} /* send_adb_cuda */
int
-adbprint(void *args, const char *name)
+adb_intr_II(void *arg)
{
- struct adb_attach_args *aa_args = (struct adb_attach_args *)args;
- int rv = UNCONF;
+ struct adbCommand packet;
+ int i, intr_on = 0;
+ int send = 0;
+ unsigned int s;
+
+ s = splhigh(); /* can't be too careful - might be called */
+ /* from a routine, NOT an interrupt */
+
+ ADB_VIA_CLR_INTR(); /* clear interrupt */
+
+ ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */
+
+ delay(ADB_DELAY); /* yuck (don't remove) */
+
+ (void)intr_dispatch(0x70); /* grab any serial interrupts */
- if (name) { /* no configured device matched */
- rv = UNSUPP; /* most ADB device types are unsupported */
+ if (ADB_INTR_IS_ON)
+ intr_on = 1; /* save for later */
+
+switch_start:
+ switch (adbActionState) {
+ case ADB_ACTION_POLLING:
+ if (!intr_on) {
+ if (adbOutQueueHasData) {
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("POLL-doing-out-queue. ");
+#endif
+ ADB_SET_STATE_IDLE_II();
+ delay(ADB_DELAY);
- /* print out what kind of ADB device we have found */
- switch(aa_args->origaddr) {
-#ifdef ADBVERBOSE
- case ADBADDR_SECURE:
- printf("security dongle (%d)",
- aa_args->handler_id);
+ /* copy over data */
+ memcpy(adbOutputBuffer, adbOutQueue.outBuf,
+ adbOutQueue.outBuf[0] + 2);
+
+ adbBuffer = adbOutQueue.saveBuf; /* user data area */
+ adbCompRout = adbOutQueue.compRout; /* completion routine */
+ adbCompData = adbOutQueue.data; /* comp. rout. data */
+ adbOutQueueHasData = 0; /* currently processing
+ * "queue" entry */
+ adbSentChars = 0; /* nothing sent yet */
+ adbActionState = ADB_ACTION_OUT; /* set next state */
+ ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
+ ADB_SR() = adbOutputBuffer[1]; /* load byte for output */
+ adbBusState = ADB_BUS_CMD; /* set bus to cmd state */
+ ADB_SET_STATE_CMD(); /* tell ADB that we want to send */
+ break;
+ } else {
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("pIDLE ");
+#endif
+ adbActionState = ADB_ACTION_IDLE;
+ }
+ } else {
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("pIN ");
+#endif
+ adbActionState = ADB_ACTION_IN;
+ }
+ delay(ADB_DELAY);
+ (void)intr_dispatch(0x70); /* grab any serial interrupts */
+ goto switch_start;
+ break;
+ case ADB_ACTION_IDLE:
+ if (!intr_on) {
+ i = ADB_SR();
+ adbBusState = ADB_BUS_IDLE;
+ adbActionState = ADB_ACTION_IDLE;
+ ADB_SET_STATE_IDLE_II();
break;
+ }
+ adbInputBuffer[0] = 1;
+ adbInputBuffer[1] = ADB_SR(); /* get first byte */
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("idle 0x%02x ", adbInputBuffer[1]);
+#endif
+ ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
+ adbActionState = ADB_ACTION_IN; /* set next state */
+ ADB_SET_STATE_EVEN(); /* set bus state to even */
+ adbBusState = ADB_BUS_EVEN;
+ break;
+
+ case ADB_ACTION_IN:
+ adbInputBuffer[++adbInputBuffer[0]] = ADB_SR(); /* get byte */
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("in 0x%02x ",
+ adbInputBuffer[adbInputBuffer[0]]);
+#endif
+ ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
+
+ if (intr_on) { /* process last byte of packet */
+ adbInputBuffer[0]--; /* minus one */
+ /*
+ * If intr_on was true, and it's the second byte, then
+ * the byte we just discarded is really valid, so
+ * adjust the count
+ */
+ if (adbInputBuffer[0] == 2) {
+ adbInputBuffer[0]++;
+ }
+
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80) {
+ printf_intr("done: ");
+ print_single(adbInputBuffer);
+ }
#endif
- case ADBADDR_MAP:
- printf("mapped device (%d)",
- aa_args->handler_id);
- rv = UNCONF;
+
+ adbLastDevice = ADB_CMDADDR(adbInputBuffer[1]);
+
+ if (adbInputBuffer[0] == 1 && !adbWaiting) { /* SRQ!!!*/
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr(" xSRQ! ");
+#endif
+ adb_guess_next_device();
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("try 0x%0x ",
+ adbLastDevice);
+#endif
+ adbOutputBuffer[0] = 1;
+ adbOutputBuffer[1] = ADBTALK(adbLastDevice, 0);
+
+ adbSentChars = 0; /* nothing sent yet */
+ adbActionState = ADB_ACTION_POLLING; /* set next state */
+ ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
+ ADB_SR() = adbOutputBuffer[1]; /* load byte for output */
+ adbBusState = ADB_BUS_CMD; /* set bus to cmd state */
+ ADB_SET_STATE_CMD(); /* tell ADB that we want to */
+ break;
+ }
+
+ /* set up data for adb_pass_up */
+ memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
+
+ if (!adbWaiting && (adbInputBuffer[0] != 0)) {
+ packet.unsol = 1;
+ packet.ack_only = 0;
+ adb_pass_up(&packet);
+ } else {
+ packet.saveBuf = adbBuffer;
+ packet.compRout = adbCompRout;
+ packet.compData = adbCompData;
+ packet.unsol = 0;
+ packet.ack_only = 0;
+ adb_pass_up(&packet);
+ }
+
+ adbWaiting = 0;
+ adbInputBuffer[0] = 0;
+ adbBuffer = (long)0;
+ adbCompRout = (long)0;
+ adbCompData = (long)0;
+ /*
+ * Since we are done, check whether there is any data
+ * waiting to do out. If so, start the sending the data.
+ */
+ if (adbOutQueueHasData == 1) {
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("XXX: DOING OUT QUEUE\n");
+#endif
+ /* copy over data */
+ memcpy(adbOutputBuffer, adbOutQueue.outBuf,
+ adbOutQueue.outBuf[0] + 2);
+ adbBuffer = adbOutQueue.saveBuf; /* user data area */
+ adbCompRout = adbOutQueue.compRout; /* completion routine */
+ adbCompData = adbOutQueue.data; /* comp. rout. data */
+ adbOutQueueHasData = 0; /* currently processing
+ * "queue" entry */
+ send = 1;
+ } else {
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("XXending ");
+#endif
+ adb_guess_next_device();
+ adbOutputBuffer[0] = 1;
+ adbOutputBuffer[1] = ((adbLastDevice & 0x0f) << 4) | 0x0c;
+ adbSentChars = 0; /* nothing sent yet */
+ adbActionState = ADB_ACTION_POLLING; /* set next state */
+ ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
+ ADB_SR() = adbOutputBuffer[1]; /* load byte for output */
+ adbBusState = ADB_BUS_CMD; /* set bus to cmd state */
+ ADB_SET_STATE_CMD(); /* tell ADB that we want to */
+ break;
+ }
+ }
+
+ /*
+ * If send is true then something above determined that
+ * the message has ended and we need to start sending out
+ * a new message immediately. This could be because there
+ * is data waiting to go out or because an SRQ was seen.
+ */
+ if (send) {
+ adbSentChars = 0; /* nothing sent yet */
+ adbActionState = ADB_ACTION_OUT; /* set next state */
+ ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
+ ADB_SR() = adbOutputBuffer[1]; /* load byte for output */
+ adbBusState = ADB_BUS_CMD; /* set bus to cmd state */
+ ADB_SET_STATE_CMD(); /* tell ADB that we want to
+ * send */
+ break;
+ }
+ /* We only get this far if the message hasn't ended yet. */
+ switch (adbBusState) { /* set to next state */
+ case ADB_BUS_EVEN:
+ ADB_SET_STATE_ODD(); /* set state to odd */
+ adbBusState = ADB_BUS_ODD;
+ break;
+
+ case ADB_BUS_ODD:
+ ADB_SET_STATE_EVEN(); /* set state to even */
+ adbBusState = ADB_BUS_EVEN;
+ break;
+ default:
+ printf_intr("strange state!!!\n"); /* huh? */
break;
- case ADBADDR_REL:
- printf("relative positioning device (%d)",
- aa_args->handler_id);
- rv = UNCONF;
+ }
+ break;
+
+ case ADB_ACTION_OUT:
+ i = ADB_SR(); /* clear interrupt */
+ adbSentChars++;
+ /*
+ * If the outgoing data was a TALK, we must
+ * switch to input mode to get the result.
+ */
+ if ((adbOutputBuffer[1] & 0x0c) == 0x0c) {
+ adbInputBuffer[0] = 1;
+ adbInputBuffer[1] = i;
+ adbActionState = ADB_ACTION_IN;
+ ADB_SET_SR_INPUT();
+ adbBusState = ADB_BUS_EVEN;
+ ADB_SET_STATE_EVEN();
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("talk out 0x%02x ", i);
+#endif
+ /* we want something back */
+ adbWaiting = 1;
break;
-#ifdef ADBVERBOSE
- case ADBADDR_ABS:
- switch (aa_args->handler_id) {
- case ADB_ARTPAD:
- printf("WACOM ArtPad II");
+ }
+ /*
+ * If it's not a TALK, check whether all data has been sent.
+ * If so, call the completion routine and clean up. If not,
+ * advance to the next state.
+ */
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("non-talk out 0x%0x ", i);
+#endif
+ ADB_SET_SR_OUTPUT();
+ if (adbOutputBuffer[0] == adbSentChars) { /* check for done */
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("done \n");
+#endif
+ /* set up stuff for adb_pass_up */
+ memcpy(packet.data, adbOutputBuffer, adbOutputBuffer[0] + 1);
+ packet.saveBuf = adbBuffer;
+ packet.compRout = adbCompRout;
+ packet.compData = adbCompData;
+ packet.cmd = adbWaitingCmd;
+ packet.unsol = 0;
+ packet.ack_only = 1;
+ adb_pass_up(&packet);
+
+ /* reset "waiting" vars, just in case */
+ adbBuffer = (long)0;
+ adbCompRout = (long)0;
+ adbCompData = (long)0;
+ if (adbOutQueueHasData == 1) {
+ /* copy over data */
+ memcpy(adbOutputBuffer, adbOutQueue.outBuf,
+ adbOutQueue.outBuf[0] + 2);
+ adbBuffer = adbOutQueue.saveBuf; /* user data area */
+ adbCompRout = adbOutQueue.compRout; /* completion routine */
+ adbCompData = adbOutQueue.data; /* comp. rout. data */
+ adbOutQueueHasData = 0; /* currently processing
+ * "queue" entry */
+ adbSentChars = 0; /* nothing sent yet */
+ adbActionState = ADB_ACTION_OUT; /* set next state */
+ ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
+ ADB_SR() = adbOutputBuffer[1]; /* load byte for output */
+ adbBusState = ADB_BUS_CMD; /* set bus to cmd state */
+ ADB_SET_STATE_CMD(); /* tell ADB that we want to
+ * send */
break;
- default:
- printf("absolute positioning device (%d)",
- aa_args->handler_id);
+ } else {
+ /* send talk to last device instead */
+ adbOutputBuffer[0] = 1;
+ adbOutputBuffer[1] =
+ ADBTALK(ADB_CMDADDR(adbOutputBuffer[1]), 0);
+
+ adbSentChars = 0; /* nothing sent yet */
+ adbActionState = ADB_ACTION_IDLE; /* set next state */
+ ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
+ ADB_SR() = adbOutputBuffer[1]; /* load byte for output */
+ adbBusState = ADB_BUS_CMD; /* set bus to cmd state */
+ ADB_SET_STATE_CMD(); /* tell ADB that we want to */
break;
}
+ }
+ ADB_SR() = adbOutputBuffer[adbSentChars + 1];
+ switch (adbBusState) { /* advance to next state */
+ case ADB_BUS_EVEN:
+ ADB_SET_STATE_ODD(); /* set state to odd */
+ adbBusState = ADB_BUS_ODD;
break;
- case ADBADDR_DATATX:
- printf("data transfer device (modem?) (%d)",
- aa_args->handler_id);
+
+ case ADB_BUS_CMD:
+ case ADB_BUS_ODD:
+ ADB_SET_STATE_EVEN(); /* set state to even */
+ adbBusState = ADB_BUS_EVEN;
+ break;
+
+ default:
+#ifdef ADB_DEBUG
+ if (adb_debug) {
+ printf_intr("strange state!!! (0x%x)\n",
+ adbBusState);
+ }
+#endif
break;
- case ADBADDR_MISC:
- switch (aa_args->handler_id) {
- case ADB_POWERKEY:
- printf("Sophisticated Circuits PowerKey");
+ }
+ break;
+
+ default:
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("adb: unknown ADB state (during intr)\n");
+#endif
+ break;
+ }
+
+ ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */
+
+ splx(s); /* restore */
+
+ return (1);
+
+}
+
+
+/*
+ * send_adb version for II series machines
+ */
+int
+send_adb_II(u_char *in, u_char *buffer, void *compRout, void *data, int command)
+{
+ int s, len;
+
+ if (adbActionState == ADB_ACTION_NOTREADY) /* return if ADB not
+ * available */
+ return 1;
+
+ /* Don't interrupt while we are messing with the ADB */
+ s = splhigh();
+
+ if (0 != adbOutQueueHasData) { /* right now, "has data" means "full" */
+ splx(s); /* sorry, try again later */
+ return 1;
+ }
+ if ((long)in == (long)0) { /* need to convert? */
+ /*
+ * Don't need to use adb_cmd_extra here because this section
+ * will be called ONLY when it is an ADB command (no RTC or
+ * PRAM), especially on II series!
+ */
+ if ((command & 0x0c) == 0x08) /* copy addl data ONLY if
+ * doing a listen! */
+ len = buffer[0]; /* length of additional data */
+ else
+ len = 0;/* no additional data */
+
+ adbOutQueue.outBuf[0] = 1 + len; /* command + addl. data */
+ adbOutQueue.outBuf[1] = (u_char)command; /* load command */
+
+ /* copy additional output data, if any */
+ memcpy(adbOutQueue.outBuf + 2, buffer + 1, len);
+ } else
+ /* if data ready, just copy over */
+ memcpy(adbOutQueue.outBuf, in, in[0] + 2);
+
+ adbOutQueue.saveBuf = buffer; /* save buffer to know where to save
+ * result */
+ adbOutQueue.compRout = compRout; /* save completion routine
+ * pointer */
+ adbOutQueue.data = data;/* save completion routine data pointer */
+
+ if ((adbActionState == ADB_ACTION_IDLE) && /* is ADB available? */
+ (ADB_INTR_IS_OFF)) { /* and no incoming interrupts? */
+ /* then start command now */
+ memcpy(adbOutputBuffer, adbOutQueue.outBuf,
+ adbOutQueue.outBuf[0] + 2); /* copy over data */
+
+ adbBuffer = adbOutQueue.saveBuf; /* pointer to user data
+ * area */
+ adbCompRout = adbOutQueue.compRout; /* pointer to the
+ * completion routine */
+ adbCompData = adbOutQueue.data; /* pointer to the completion
+ * routine data */
+
+ adbSentChars = 0; /* nothing sent yet */
+ adbActionState = ADB_ACTION_OUT; /* set next state */
+ adbBusState = ADB_BUS_CMD; /* set bus to cmd state */
+
+ ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
+
+ ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* load byte for output */
+ ADB_SET_STATE_CMD(); /* tell ADB that we want to send */
+ adbOutQueueHasData = 0; /* currently processing "queue" entry */
+ } else
+ adbOutQueueHasData = 1; /* something in the write "queue" */
+
+ splx(s);
+
+ if (0x0100 <= (s & 0x0700)) /* were VIA1 interrupts blocked? */
+ /* poll until message done */
+ while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
+ || (adbWaiting == 1))
+ if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
+ adb_intr_II(NULL); /* go process it */
+ if (adb_polling)
+ adb_soft_intr();
+ }
+
+ return 0;
+}
+
+
+/*
+ * This routine is called from the II series interrupt routine
+ * to determine what the "next" device is that should be polled.
+ */
+int
+adb_guess_next_device(void)
+{
+ int last, i, dummy;
+
+ if (adbStarting) {
+ /*
+ * Start polling EVERY device, since we can't be sure there is
+ * anything in the device table yet
+ */
+ if (adbLastDevice < 1 || adbLastDevice > 15)
+ adbLastDevice = 1;
+ if (++adbLastDevice > 15) /* point to next one */
+ adbLastDevice = 1;
+ } else {
+ /* find the next device using the device table */
+ if (adbLastDevice < 1 || adbLastDevice > 15) /* let's be parinoid */
+ adbLastDevice = 2;
+ last = 1; /* default index location */
+
+ for (i = 1; i < 16; i++) /* find index entry */
+ if (ADBDevTable[i].currentAddr == adbLastDevice) { /* look for device */
+ last = i; /* found it */
break;
- default:
- printf("misc. device (remote control?) (%d)",
- aa_args->handler_id);
+ }
+ dummy = last; /* index to start at */
+ for (;;) { /* find next device in index */
+ if (++dummy > 15) /* wrap around if needed */
+ dummy = 1;
+ if (dummy == last) { /* didn't find any other
+ * device! This can happen if
+ * there are no devices on the
+ * bus */
+ dummy = 1;
break;
}
+ /* found the next device */
+ if (ADBDevTable[dummy].devType != 0)
+ break;
+ }
+ adbLastDevice = ADBDevTable[dummy].currentAddr;
+ }
+ return adbLastDevice;
+}
+
+
+/*
+ * Called when when an adb interrupt happens.
+ * This routine simply transfers control over to the appropriate
+ * code for the machine we are running on.
+ */
+int
+adb_intr(void *arg)
+{
+ switch (adbHardware) {
+ case ADB_HW_II:
+ return adb_intr_II(arg);
+ break;
+
+ case ADB_HW_IISI:
+ return adb_intr_IIsi(arg);
+ break;
+
+ case ADB_HW_PB: /* Should not come through here. */
+ break;
+
+ case ADB_HW_CUDA:
+ return adb_intr_cuda(arg);
+ break;
+
+ case ADB_HW_UNKNOWN:
+ break;
+ }
+
+ return (-1);
+}
+
+
+/*
+ * called when when an adb interrupt happens
+ *
+ * IIsi version of adb_intr
+ *
+ */
+int
+adb_intr_IIsi(void *arg)
+{
+ struct adbCommand packet;
+ int i, ending;
+ unsigned int s;
+
+ s = splhigh(); /* can't be too careful - might be called */
+ /* from a routine, NOT an interrupt */
+
+ ADB_VIA_CLR_INTR(); /* clear interrupt */
+
+ ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */
+
+switch_start:
+ switch (adbActionState) {
+ case ADB_ACTION_IDLE:
+ delay(ADB_DELAY); /* short delay is required before the
+ * first byte */
+
+ ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
+ ADB_SET_STATE_ACTIVE(); /* signal start of data frame */
+ adbInputBuffer[1] = ADB_SR(); /* get byte */
+ adbInputBuffer[0] = 1;
+ adbActionState = ADB_ACTION_IN; /* set next state */
+
+ ADB_SET_STATE_ACKON(); /* start ACK to ADB chip */
+ delay(ADB_DELAY); /* delay */
+ ADB_SET_STATE_ACKOFF(); /* end ACK to ADB chip */
+ (void)intr_dispatch(0x70); /* grab any serial interrupts */
+ break;
+
+ case ADB_ACTION_IN:
+ ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
+ adbInputBuffer[++adbInputBuffer[0]] = ADB_SR(); /* get byte */
+ if (ADB_INTR_IS_OFF) /* check for end of frame */
+ ending = 1;
+ else
+ ending = 0;
+
+ ADB_SET_STATE_ACKON(); /* start ACK to ADB chip */
+ delay(ADB_DELAY); /* delay */
+ ADB_SET_STATE_ACKOFF(); /* end ACK to ADB chip */
+ (void)intr_dispatch(0x70); /* grab any serial interrupts */
+
+ if (1 == ending) { /* end of message? */
+ ADB_SET_STATE_INACTIVE(); /* signal end of frame */
+ /*
+ * This section _should_ handle all ADB and RTC/PRAM
+ * type commands, but there may be more... Note:
+ * commands are always at [4], even for rtc/pram
+ * commands
+ */
+ /* set up data for adb_pass_up */
+ memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
+
+ if ((adbWaiting == 1) && /* are we waiting AND */
+ (adbInputBuffer[4] == adbWaitingCmd) && /* the cmd we sent AND */
+ ((adbInputBuffer[2] == 0x00) || /* it's from the ADB
+ * device OR */
+ (adbInputBuffer[2] == 0x01))) { /* it's from the
+ * PRAM/RTC device */
+
+ packet.saveBuf = adbBuffer;
+ packet.compRout = adbCompRout;
+ packet.compData = adbCompData;
+ packet.unsol = 0;
+ packet.ack_only = 0;
+ adb_pass_up(&packet);
+
+ adbWaitingCmd = 0; /* reset "waiting" vars */
+ adbWaiting = 0;
+ adbBuffer = (long)0;
+ adbCompRout = (long)0;
+ adbCompData = (long)0;
+ } else {
+ packet.unsol = 1;
+ packet.ack_only = 0;
+ adb_pass_up(&packet);
+ }
+
+ adbActionState = ADB_ACTION_IDLE;
+ adbInputBuffer[0] = 0; /* reset length */
+
+ if (adbWriteDelay == 1) { /* were we waiting to
+ * write? */
+ adbSentChars = 0; /* nothing sent yet */
+ adbActionState = ADB_ACTION_OUT; /* set next state */
+
+ delay(ADB_DELAY); /* delay */
+ (void)intr_dispatch(0x70); /* grab any serial interrupts */
+
+ if (ADB_INTR_IS_ON) { /* ADB intr low during
+ * write */
+ ADB_SET_STATE_IDLE_IISI(); /* reset */
+ ADB_SET_SR_INPUT(); /* make sure SR is set
+ * to IN */
+ adbSentChars = 0; /* must start all over */
+ adbActionState = ADB_ACTION_IDLE; /* new state */
+ adbInputBuffer[0] = 0;
+ /* may be able to take this out later */
+ delay(ADB_DELAY); /* delay */
+ break;
+ }
+ ADB_SET_STATE_ACTIVE(); /* tell ADB that we want
+ * to send */
+ ADB_SET_STATE_ACKOFF(); /* make sure */
+ ADB_SET_SR_OUTPUT(); /* set shift register
+ * for OUT */
+ ADB_SR() = adbOutputBuffer[adbSentChars + 1];
+ ADB_SET_STATE_ACKON(); /* tell ADB byte ready
+ * to shift */
+ }
+ }
+ break;
+
+ case ADB_ACTION_OUT:
+ i = ADB_SR(); /* reset SR-intr in IFR */
+ ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
+
+ ADB_SET_STATE_ACKOFF(); /* finish ACK */
+ adbSentChars++;
+ if (ADB_INTR_IS_ON) { /* ADB intr low during write */
+ ADB_SET_STATE_IDLE_IISI(); /* reset */
+ ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
+ adbSentChars = 0; /* must start all over */
+ adbActionState = ADB_ACTION_IDLE; /* new state */
+ adbInputBuffer[0] = 0;
+ adbWriteDelay = 1; /* must retry when done with
+ * read */
+ delay(ADB_DELAY); /* delay */
+ (void)intr_dispatch(0x70); /* grab any serial interrupts */
+ goto switch_start; /* process next state right
+ * now */
break;
- default:
- printf("unknown type %d device, (handler %d)",
- aa_args->origaddr, aa_args->handler_id);
+ }
+ delay(ADB_DELAY); /* required delay */
+ (void)intr_dispatch(0x70); /* grab any serial interrupts */
+
+ if (adbOutputBuffer[0] == adbSentChars) { /* check for done */
+ if (0 == adb_cmd_result(adbOutputBuffer)) { /* do we expect data
+ * back? */
+ adbWaiting = 1; /* signal waiting for return */
+ adbWaitingCmd = adbOutputBuffer[2]; /* save waiting command */
+ } else {/* no talk, so done */
+ /* set up stuff for adb_pass_up */
+ memcpy(packet.data, adbInputBuffer,
+ adbInputBuffer[0] + 1);
+ packet.saveBuf = adbBuffer;
+ packet.compRout = adbCompRout;
+ packet.compData = adbCompData;
+ packet.cmd = adbWaitingCmd;
+ packet.unsol = 0;
+ packet.ack_only = 1;
+ adb_pass_up(&packet);
+
+ /* reset "waiting" vars, just in case */
+ adbWaitingCmd = 0;
+ adbBuffer = (long)0;
+ adbCompRout = (long)0;
+ adbCompData = (long)0;
+ }
+
+ adbWriteDelay = 0; /* done writing */
+ adbActionState = ADB_ACTION_IDLE; /* signal bus is idle */
+ ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
+ ADB_SET_STATE_INACTIVE(); /* end of frame */
+ } else {
+ ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* send next byte */
+ ADB_SET_STATE_ACKON(); /* signal byte ready to shift */
+ }
+ break;
+
+ case ADB_ACTION_NOTREADY:
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("adb: not yet initialized\n");
+#endif
+ break;
+
+ default:
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("intr: unknown ADB state\n");
+#endif
+ break;
+ }
+
+ ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */
+
+ splx(s); /* restore */
+
+ return (1);
+} /* end adb_intr_IIsi */
+
+
+/*****************************************************************************
+ * if the device is currently busy, and there is no data waiting to go out, then
+ * the data is "queued" in the outgoing buffer. If we are already waiting, then
+ * we return.
+ * in: if (in == 0) then the command string is built from command and buffer
+ * if (in != 0) then in is used as the command string
+ * buffer: additional data to be sent (used only if in == 0)
+ * this is also where return data is stored
+ * compRout: the completion routine that is called when then return value
+ * is received (if a return value is expected)
+ * data: a data pointer that can be used by the completion routine
+ * command: an ADB command to be sent (used only if in == 0)
+ *
+ */
+int
+send_adb_IIsi(u_char *in, u_char *buffer, void *compRout, void *data, int
+ command)
+{
+ int s, len;
+
+ if (adbActionState == ADB_ACTION_NOTREADY)
+ return 1;
+
+ /* Don't interrupt while we are messing with the ADB */
+ s = splhigh();
+
+ if ((adbActionState == ADB_ACTION_IDLE) && /* ADB available? */
+ (ADB_INTR_IS_OFF)) {/* and no incoming interrupt? */
+
+ } else
+ if (adbWriteDelay == 0) /* it's busy, but is anything waiting? */
+ adbWriteDelay = 1; /* if no, then we'll "queue"
+ * it up */
+ else {
+ splx(s);
+ return 1; /* really busy! */
+ }
+
+ if ((long)in == (long)0) { /* need to convert? */
+ /*
+ * Don't need to use adb_cmd_extra here because this section
+ * will be called ONLY when it is an ADB command (no RTC or
+ * PRAM)
+ */
+ if ((command & 0x0c) == 0x08) /* copy addl data ONLY if
+ * doing a listen! */
+ len = buffer[0]; /* length of additional data */
+ else
+ len = 0;/* no additional data */
+
+ adbOutputBuffer[0] = 2 + len; /* dev. type + command + addl.
+ * data */
+ adbOutputBuffer[1] = 0x00; /* mark as an ADB command */
+ adbOutputBuffer[2] = (u_char)command; /* load command */
+
+ /* copy additional output data, if any */
+ memcpy(adbOutputBuffer + 3, buffer + 1, len);
+ } else
+ /* if data ready, just copy over */
+ memcpy(adbOutputBuffer, in, in[0] + 2);
+
+ adbSentChars = 0; /* nothing sent yet */
+ adbBuffer = buffer; /* save buffer to know where to save result */
+ adbCompRout = compRout; /* save completion routine pointer */
+ adbCompData = data; /* save completion routine data pointer */
+ adbWaitingCmd = adbOutputBuffer[2]; /* save wait command */
+
+ if (adbWriteDelay != 1) { /* start command now? */
+ adbActionState = ADB_ACTION_OUT; /* set next state */
+
+ ADB_SET_STATE_ACTIVE(); /* tell ADB that we want to send */
+ ADB_SET_STATE_ACKOFF(); /* make sure */
+
+ ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
+
+ ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* load byte for output */
+
+ ADB_SET_STATE_ACKON(); /* tell ADB byte ready to shift */
+ }
+ adbWriteDelay = 1; /* something in the write "queue" */
+
+ splx(s);
+
+ if (0x0100 <= (s & 0x0700)) /* were VIA1 interrupts blocked? */
+ /* poll until byte done */
+ while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
+ || (adbWaiting == 1))
+ if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
+ adb_intr_IIsi(NULL); /* go process it */
+ if (adb_polling)
+ adb_soft_intr();
+ }
+
+ return 0;
+} /* send_adb_IIsi */
+
+/*
+ * adb_pass_up is called by the interrupt-time routines.
+ * It takes the raw packet data that was received from the
+ * device and puts it into the queue that the upper half
+ * processes. It then signals for a soft ADB interrupt which
+ * will eventually call the upper half routine (adb_soft_intr).
+ *
+ * If in->unsol is 0, then this is either the notification
+ * that the packet was sent (on a LISTEN, for example), or the
+ * response from the device (on a TALK). The completion routine
+ * is called only if the user specified one.
+ *
+ * If in->unsol is 1, then this packet was unsolicited and
+ * so we look up the device in the ADB device table to determine
+ * what it's default service routine is.
+ *
+ * If in->ack_only is 1, then we really only need to call
+ * the completion routine, so don't do any other stuff.
+ *
+ * Note that in->data contains the packet header AND data,
+ * while adbInbound[]->data contains ONLY data.
+ *
+ * Note: Called only at interrupt time. Assumes this.
+ */
+void
+adb_pass_up(struct adbCommand *in)
+{
+ int start = 0, len = 0, cmd = 0;
+ ADBDataBlock block;
+
+ /* temp for testing */
+ /*u_char *buffer = 0;*/
+ /*u_char *compdata = 0;*/
+ /*u_char *comprout = 0;*/
+
+ if (adbInCount >= ADB_QUEUE) {
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("adb: ring buffer overflow\n");
+#endif
+ return;
+ }
+
+ if (in->ack_only) {
+ len = in->data[0];
+ cmd = in->cmd;
+ start = 0;
+ } else {
+ switch (adbHardware) {
+ case ADB_HW_II:
+ cmd = in->data[1];
+ if (in->data[0] < 2)
+ len = 0;
+ else
+ len = in->data[0]-1;
+ start = 1;
break;
-#endif /* ADBVERBOSE */
+
+ case ADB_HW_IISI:
+ case ADB_HW_CUDA:
+ /* If it's unsolicited, accept only ADB data for now */
+ if (in->unsol)
+ if (0 != in->data[2])
+ return;
+ cmd = in->data[4];
+ if (in->data[0] < 5)
+ len = 0;
+ else
+ len = in->data[0]-4;
+ start = 4;
+ break;
+
+ case ADB_HW_PB:
+ cmd = in->data[1];
+ if (in->data[0] < 2)
+ len = 0;
+ else
+ len = in->data[0]-1;
+ start = 1;
+ break;
+
+ case ADB_HW_UNKNOWN:
+ return;
+ }
+
+ /* Make sure there is a valid device entry for this device */
+ if (in->unsol) {
+ /* ignore unsolicited data during adbreinit */
+ if (adbStarting)
+ return;
+ /* get device's comp. routine and data area */
+ if (-1 == get_adb_info(&block, ADB_CMDADDR(cmd)))
+ return;
+ }
+ }
+
+ /*
+ * If this is an unsolicited packet, we need to fill in
+ * some info so adb_soft_intr can process this packet
+ * properly. If it's not unsolicited, then use what
+ * the caller sent us.
+ */
+ if (in->unsol) {
+ adbInbound[adbInTail].compRout = (void *)block.dbServiceRtPtr;
+ adbInbound[adbInTail].compData = (void *)block.dbDataAreaAddr;
+ adbInbound[adbInTail].saveBuf = (void *)adbInbound[adbInTail].data;
+ } else {
+ adbInbound[adbInTail].compRout = (void *)in->compRout;
+ adbInbound[adbInTail].compData = (void *)in->compData;
+ adbInbound[adbInTail].saveBuf = (void *)in->saveBuf;
+ }
+
+#ifdef ADB_DEBUG
+ if (adb_debug && in->data[1] == 2)
+ printf_intr("adb: caught error\n");
+#endif
+
+ /* copy the packet data over */
+ /*
+ * TO DO: If the *_intr routines fed their incoming data
+ * directly into an adbCommand struct, which is passed to
+ * this routine, then we could eliminate this copy.
+ */
+ memcpy(adbInbound[adbInTail].data + 1, in->data + start + 1, len);
+ adbInbound[adbInTail].data[0] = len;
+ adbInbound[adbInTail].cmd = cmd;
+
+ adbInCount++;
+ if (++adbInTail >= ADB_QUEUE)
+ adbInTail = 0;
+
+ /*
+ * If the debugger is running, call upper half manually.
+ * Otherwise, trigger a soft interrupt to handle the rest later.
+ */
+ if (adb_polling)
+ adb_soft_intr();
+ else
+ setsoftadb();
+
+ return;
+}
+
+
+/*
+ * Called to process the packets after they have been
+ * placed in the incoming queue.
+ *
+ */
+void
+adb_soft_intr(void)
+{
+ int s;
+ int cmd = 0;
+ u_char *buffer = 0;
+ u_char *comprout = 0;
+ u_char *compdata = 0;
+
+/*delay(2*ADB_DELAY);*/
+
+ while (adbInCount) {
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("%x %x %x ",
+ adbInCount, adbInHead, adbInTail);
+#endif
+ /* get the data we need from the queue */
+ buffer = adbInbound[adbInHead].saveBuf;
+ comprout = adbInbound[adbInHead].compRout;
+ compdata = adbInbound[adbInHead].compData;
+ cmd = adbInbound[adbInHead].cmd;
+
+ /* copy over data to data area if it's valid */
+ /*
+ * Note that for unsol packets we don't want to copy the
+ * data anywhere, so buffer was already set to 0.
+ * For ack_only buffer was set to 0, so don't copy.
+ */
+ if (buffer)
+ memcpy(buffer, adbInbound[adbInHead].data,
+ adbInbound[adbInHead].data[0] + 1);
+
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80) {
+ printf_intr("%p %p %p %x ",
+ buffer, comprout, compdata, (short)cmd);
+ printf_intr("buf: ");
+ print_single(adbInbound[adbInHead].data);
+ }
+#endif
+
+ /* call default completion routine if it's valid */
+ if (comprout) {
+ (void)((int (*)(u_char *, u_char *, int))comprout)
+ (buffer, compdata, cmd);
}
- printf(" at %s", name);
+
+ s = splhigh();
+ adbInCount--;
+ if (++adbInHead >= ADB_QUEUE)
+ adbInHead = 0;
+ splx(s);
+
}
+ return;
+}
+
+
+/*
+ * This is my version of the ADBOp routine. It mainly just calls the
+ * hardware-specific routine.
+ *
+ * data : pointer to data area to be used by compRout
+ * compRout : completion routine
+ * buffer : for LISTEN: points to data to send - MAX 8 data bytes,
+ * byte 0 = # of bytes
+ * : for TALK: points to place to save return data
+ * command : the adb command to send
+ * result : 0 = success
+ * : -1 = could not complete
+ */
+int
+adb_op(Ptr buffer, Ptr compRout, Ptr data, short command)
+{
+ int result;
+
+ switch (adbHardware) {
+ case ADB_HW_II:
+ result = send_adb_II((u_char *)0, (u_char *)buffer,
+ (void *)compRout, (void *)data, (int)command);
+ if (result == 0)
+ return 0;
+ else
+ return -1;
+ break;
+
+ case ADB_HW_IISI:
+ result = send_adb_IIsi((u_char *)0, (u_char *)buffer,
+ (void *)compRout, (void *)data, (int)command);
+ /*
+ * I wish I knew why this delay is needed. It usually needs to
+ * be here when several commands are sent in close succession,
+ * especially early in device probes when doing collision
+ * detection. It must be some race condition. Sigh. - jpw
+ */
+ delay(100);
+ if (result == 0)
+ return 0;
+ else
+ return -1;
+ break;
+
+ case ADB_HW_PB:
+ result = pm_adb_op((u_char *)buffer, (void *)compRout,
+ (void *)data, (int)command);
+
+ if (result == 0)
+ return 0;
+ else
+ return -1;
+ break;
- printf(" addr %d", aa_args->adbaddr);
+ case ADB_HW_CUDA:
+ result = send_adb_cuda((u_char *)0, (u_char *)buffer,
+ (void *)compRout, (void *)data, (int)command);
+ if (result == 0)
+ return 0;
+ else
+ return -1;
+ break;
- return (rv);
+ case ADB_HW_UNKNOWN:
+ default:
+ return -1;
+ }
}
/*
+ * adb_hw_setup
+ * This routine sets up the possible machine specific hardware
+ * config (mainly VIA settings) for the various models.
+ */
+void
+adb_hw_setup(void)
+{
+ volatile int i;
+ u_char send_string[ADB_MAX_MSG_LENGTH];
+
+ switch (adbHardware) {
+ case ADB_HW_II:
+ via1_register_irq(2, adb_intr_II, NULL, NULL);
+
+ via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5:
+ * outputs */
+ via_reg(VIA1, vDirB) &= 0xf7; /* register B bit 3: input */
+ via_reg(VIA1, vACR) &= ~vSR_OUT; /* make sure SR is set
+ * to IN (II, IIsi) */
+ adbActionState = ADB_ACTION_IDLE; /* used by all types of
+ * hardware (II, IIsi) */
+ adbBusState = ADB_BUS_IDLE; /* this var. used in II-series
+ * code only */
+ via_reg(VIA1, vIER) = 0x84; /* make sure VIA interrupts
+ * are on (II, IIsi) */
+ ADB_SET_STATE_IDLE_II(); /* set ADB bus state to idle */
+
+ ADB_VIA_CLR_INTR(); /* clear interrupt */
+ break;
+
+ case ADB_HW_IISI:
+ via1_register_irq(2, adb_intr_IIsi, NULL, NULL);
+ via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5:
+ * outputs */
+ via_reg(VIA1, vDirB) &= 0xf7; /* register B bit 3: input */
+ via_reg(VIA1, vACR) &= ~vSR_OUT; /* make sure SR is set
+ * to IN (II, IIsi) */
+ adbActionState = ADB_ACTION_IDLE; /* used by all types of
+ * hardware (II, IIsi) */
+ adbBusState = ADB_BUS_IDLE; /* this var. used in II-series
+ * code only */
+ via_reg(VIA1, vIER) = 0x84; /* make sure VIA interrupts
+ * are on (II, IIsi) */
+ ADB_SET_STATE_IDLE_IISI(); /* set ADB bus state to idle */
+
+ /* get those pesky clock ticks we missed while booting */
+ for (i = 0; i < 30; i++) {
+ delay(ADB_DELAY);
+ adb_hw_setup_IIsi(send_string);
+#ifdef ADB_DEBUG
+ if (adb_debug) {
+ printf_intr("adb: cleanup: ");
+ print_single(send_string);
+ }
+#endif
+ delay(ADB_DELAY);
+ if (ADB_INTR_IS_OFF)
+ break;
+ }
+ break;
+
+ case ADB_HW_PB:
+ /*
+ * XXX - really PM_VIA_CLR_INTR - should we put it in
+ * pm_direct.h?
+ */
+ pm_hw_setup();
+ break;
+
+ case ADB_HW_CUDA:
+ via1_register_irq(2, adb_intr_cuda, NULL, NULL);
+ via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5:
+ * outputs */
+ via_reg(VIA1, vDirB) &= 0xf7; /* register B bit 3: input */
+ via_reg(VIA1, vACR) &= ~vSR_OUT; /* make sure SR is set
+ * to IN */
+ via_reg(VIA1, vACR) = (via_reg(VIA1, vACR) | 0x0c) & ~0x10;
+ adbActionState = ADB_ACTION_IDLE; /* used by all types of
+ * hardware */
+ adbBusState = ADB_BUS_IDLE; /* this var. used in II-series
+ * code only */
+ via_reg(VIA1, vIER) = 0x84; /* make sure VIA interrupts
+ * are on */
+ ADB_SET_STATE_IDLE_CUDA(); /* set ADB bus state to idle */
+
+ /* sort of a device reset */
+ i = ADB_SR(); /* clear interrupt */
+ ADB_VIA_INTR_DISABLE(); /* no interrupts while clearing */
+ ADB_SET_STATE_IDLE_CUDA(); /* reset state to idle */
+ delay(ADB_DELAY);
+ ADB_SET_STATE_TIP(); /* signal start of frame */
+ delay(ADB_DELAY);
+ ADB_TOGGLE_STATE_ACK_CUDA();
+ delay(ADB_DELAY);
+ ADB_CLR_STATE_TIP();
+ delay(ADB_DELAY);
+ ADB_SET_STATE_IDLE_CUDA(); /* back to idle state */
+ i = ADB_SR(); /* clear interrupt */
+ ADB_VIA_INTR_ENABLE(); /* ints ok now */
+ break;
+
+ case ADB_HW_UNKNOWN:
+ default:
+ via_reg(VIA1, vIER) = 0x04; /* turn interrupts off - TO
+ * DO: turn PB ints off? */
+ return;
+ break;
+ }
+}
+
+
+/*
+ * adb_hw_setup_IIsi
+ * This is sort of a "read" routine that forces the adb hardware through a read cycle
+ * if there is something waiting. This helps "clean up" any commands that may have gotten
+ * stuck or stopped during the boot process.
+ *
+ */
+void
+adb_hw_setup_IIsi(u_char *buffer)
+{
+ int i;
+ int dummy;
+ int s;
+ long my_time;
+ int endofframe;
+
+ delay(ADB_DELAY);
+
+ i = 1; /* skip over [0] */
+ s = splhigh(); /* block ALL interrupts while we are working */
+ ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
+ ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */
+ /* this is required, especially on faster machines */
+ delay(ADB_DELAY);
+
+ if (ADB_INTR_IS_ON) {
+ ADB_SET_STATE_ACTIVE(); /* signal start of data frame */
+
+ endofframe = 0;
+ while (0 == endofframe) {
+ /*
+ * Poll for ADB interrupt and watch for timeout.
+ * If time out, keep going in hopes of not hanging
+ * the ADB chip - I think
+ */
+ my_time = ADB_DELAY * 5;
+ while ((ADB_SR_INTR_IS_OFF) && (my_time-- > 0))
+ dummy = via_reg(VIA1, vBufB);
+
+ buffer[i++] = ADB_SR(); /* reset interrupt flag by
+ * reading vSR */
+ /*
+ * Perhaps put in a check here that ignores all data
+ * after the first ADB_MAX_MSG_LENGTH bytes ???
+ */
+ if (ADB_INTR_IS_OFF) /* check for end of frame */
+ endofframe = 1;
+
+ ADB_SET_STATE_ACKON(); /* send ACK to ADB chip */
+ delay(ADB_DELAY); /* delay */
+ ADB_SET_STATE_ACKOFF(); /* send ACK to ADB chip */
+ }
+ ADB_SET_STATE_INACTIVE(); /* signal end of frame and
+ * delay */
+
+ /* probably don't need to delay this long */
+ delay(ADB_DELAY);
+ }
+ buffer[0] = --i; /* [0] is length of message */
+ ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */
+ splx(s); /* restore interrupts */
+
+ return;
+} /* adb_hw_setup_IIsi */
+
+
+
+/*
+ * adb_reinit sets up the adb stuff
+ *
+ */
+void
+adb_reinit(void)
+{
+ u_char send_string[ADB_MAX_MSG_LENGTH];
+ ADBDataBlock data; /* temp. holder for getting device info */
+ volatile int i, x;
+ int s;
+ int command;
+ int result;
+ int saveptr; /* point to next free relocation address */
+ int device;
+ int nonewtimes; /* times thru loop w/o any new devices */
+
+ via1_register_irq(2, adb_intr, NULL, "adb");
+ adb_setup_hw_type(); /* setup hardware type */
+
+ /* Make sure we are not interrupted while building the table. */
+ /* ints must be on for PB & IOP (at least, for now) */
+ if (adbHardware != ADB_HW_PB)
+ s = splhigh();
+ else
+ s = 0; /* XXX shut the compiler up*/
+
+ ADBNumDevices = 0; /* no devices yet */
+
+ /* Let intr routines know we are running reinit */
+ adbStarting = 1;
+
+ /*
+ * Initialize the ADB table. For now, we'll always use the same table
+ * that is defined at the beginning of this file - no mallocs.
+ */
+ for (i = 0; i < 16; i++) {
+ ADBDevTable[i].devType = 0;
+ ADBDevTable[i].origAddr = ADBDevTable[i].currentAddr = 0;
+ }
+
+ adb_hw_setup(); /* init the VIA bits and hard reset ADB */
+
+ delay(1000);
+
+ /* send an ADB reset first */
+ (void)adb_op_sync((Ptr)0, (Ptr)0, (Ptr)0, (short)0x00);
+ delay(3000);
+
+ /*
+ * Probe for ADB devices. Probe devices 1-15 quickly to determine
+ * which device addresses are in use and which are free. For each
+ * address that is in use, move the device at that address to a higher
+ * free address. Continue doing this at that address until no device
+ * responds at that address. Then move the last device that was moved
+ * back to the original address. Do this for the remaining addresses
+ * that we determined were in use.
+ *
+ * When finished, do this entire process over again with the updated
+ * list of in use addresses. Do this until no new devices have been
+ * found in 20 passes though the in use address list. (This probably
+ * seems long and complicated, but it's the best way to detect multiple
+ * devices at the same address - sometimes it takes a couple of tries
+ * before the collision is detected.)
+ */
+
+ /* initial scan through the devices */
+ for (i = 1; i < 16; i++) {
+ command = ADBTALK(i, 3);
+ result = adb_op_sync((Ptr)send_string, (Ptr)0,
+ (Ptr)0, (short)command);
+
+ if (result == 0 && send_string[0] != 0) {
+ /* found a device */
+ ++ADBNumDevices;
+ KASSERT(ADBNumDevices < 16);
+ ADBDevTable[ADBNumDevices].devType =
+ (int)(send_string[2]);
+ ADBDevTable[ADBNumDevices].origAddr = i;
+ ADBDevTable[ADBNumDevices].currentAddr = i;
+ ADBDevTable[ADBNumDevices].DataAreaAddr =
+ (long)0;
+ ADBDevTable[ADBNumDevices].ServiceRtPtr = (void *)0;
+ pm_check_adb_devices(i); /* tell pm driver device
+ * is here */
+ }
+ }
+
+ /* find highest unused address */
+ for (saveptr = 15; saveptr > 0; saveptr--)
+ if (-1 == get_adb_info(&data, saveptr))
+ break;
+
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80) {
+ printf_intr("first free is: 0x%02x\n", saveptr);
+ printf_intr("devices: %i\n", ADBNumDevices);
+ }
+#endif
+
+ nonewtimes = 0; /* no loops w/o new devices */
+ while (saveptr > 0 && nonewtimes++ < 11) {
+ for (i = 1;saveptr > 0 && i <= ADBNumDevices; i++) {
+ device = ADBDevTable[i].currentAddr;
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("moving device 0x%02x to 0x%02x "
+ "(index 0x%02x) ", device, saveptr, i);
+#endif
+
+ /* send TALK R3 to address */
+ command = ADBTALK(device, 3);
+ (void)adb_op_sync((Ptr)send_string, (Ptr)0,
+ (Ptr)0, (short)command);
+
+ /* move device to higher address */
+ command = ADBLISTEN(device, 3);
+ send_string[0] = 2;
+ send_string[1] = (u_char)(saveptr | 0x60);
+ send_string[2] = 0xfe;
+ (void)adb_op_sync((Ptr)send_string, (Ptr)0,
+ (Ptr)0, (short)command);
+ delay(1000);
+
+ /* send TALK R3 - anthing at new address? */
+ command = ADBTALK(saveptr, 3);
+ send_string[0] = 0;
+ result = adb_op_sync((Ptr)send_string, (Ptr)0,
+ (Ptr)0, (short)command);
+ delay(1000);
+
+ if (result != 0 || send_string[0] == 0) {
+ /*
+ * maybe there's a communication breakdown;
+ * just in case, move it back from whence it
+ * came, and we'll try again later
+ */
+ command = ADBLISTEN(saveptr, 3);
+ send_string[0] = 2;
+ send_string[1] = (u_char)(device | 0x60);
+ send_string[2] = 0x00;
+ (void)adb_op_sync((Ptr)send_string, (Ptr)0,
+ (Ptr)0, (short)command);
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("failed, continuing\n");
+#endif
+ delay(1000);
+ continue;
+ }
+
+ /* send TALK R3 - anything at old address? */
+ command = ADBTALK(device, 3);
+ send_string[0] = 0;
+ result = adb_op_sync((Ptr)send_string, (Ptr)0,
+ (Ptr)0, (short)command);
+ if (result == 0 && send_string[0] != 0) {
+ /* new device found */
+ /* update data for previously moved device */
+ ADBDevTable[i].currentAddr = saveptr;
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("old device at index %i\n",i);
+#endif
+ /* add new device in table */
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("new device found\n");
+#endif
+ if (saveptr > ADBNumDevices) {
+ ++ADBNumDevices;
+ KASSERT(ADBNumDevices < 16);
+ }
+ ADBDevTable[ADBNumDevices].devType =
+ (int)(send_string[2]);
+ ADBDevTable[ADBNumDevices].origAddr = device;
+ ADBDevTable[ADBNumDevices].currentAddr = device;
+ /* These will be set correctly in adbsys.c */
+ /* Until then, unsol. data will be ignored. */
+ ADBDevTable[ADBNumDevices].DataAreaAddr =
+ (long)0;
+ ADBDevTable[ADBNumDevices].ServiceRtPtr =
+ (void *)0;
+ /* find next unused address */
+ for (x = saveptr; x > 0; x--) {
+ if (-1 == get_adb_info(&data, x)) {
+ saveptr = x;
+ break;
+ }
+ }
+ if (x == 0)
+ saveptr = 0;
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("new free is 0x%02x\n",
+ saveptr);
+#endif
+ nonewtimes = 0;
+ /* tell pm driver device is here */
+ pm_check_adb_devices(device);
+ } else {
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("moving back...\n");
+#endif
+ /* move old device back */
+ command = ADBLISTEN(saveptr, 3);
+ send_string[0] = 2;
+ send_string[1] = (u_char)(device | 0x60);
+ send_string[2] = 0xfe;
+ (void)adb_op_sync((Ptr)send_string, (Ptr)0,
+ (Ptr)0, (short)command);
+ delay(1000);
+ }
+ }
+ }
+
+#ifdef ADB_DEBUG
+ if (adb_debug) {
+ for (i = 1; i <= ADBNumDevices; i++) {
+ x = get_ind_adb_info(&data, i);
+ if (x != -1)
+ printf_intr("index 0x%x, addr 0x%x, type 0x%hx\n",
+ i, x, data.devType);
+ }
+ }
+#endif
+
+ /* enable the programmer's switch, if we have one */
+ adb_prog_switch_enable();
+
+#ifdef ADB_DEBUG
+ if (adb_debug) {
+ if (0 == ADBNumDevices) /* tell user if no devices found */
+ printf_intr("adb: no devices found\n");
+ }
+#endif
+
+ adbStarting = 0; /* not starting anymore */
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("adb: adb_reinit complete\n");
+#endif
+
+ if (adbHardware == ADB_HW_CUDA) {
+ timeout_set(&adb_cuda_timeout, (void *)adb_cuda_tickle, NULL);
+ timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS);
+ }
+
+ /* ints must be on for PB & IOP (at least, for now) */
+ if (adbHardware != ADB_HW_PB)
+ splx(s);
+
+ return;
+}
+
+
+/*
+ * adb_cmd_result
+ *
+ * This routine lets the caller know whether the specified adb command string
+ * should expect a returned result, such as a TALK command.
+ *
+ * returns: 0 if a result should be expected
+ * 1 if a result should NOT be expected
+ */
+int
+adb_cmd_result(u_char *in)
+{
+ switch (adbHardware) {
+ case ADB_HW_II:
+ /* was it an ADB talk command? */
+ if ((in[1] & 0x0c) == 0x0c)
+ return 0;
+ return 1;
+
+ case ADB_HW_IISI:
+ case ADB_HW_CUDA:
+ /* was it an ADB talk command? */
+ if ((in[1] == 0x00) && ((in[2] & 0x0c) == 0x0c))
+ return 0;
+ /* was it an RTC/PRAM read date/time? */
+ if ((in[1] == 0x01) && (in[2] == 0x03))
+ return 0;
+ return 1;
+
+ case ADB_HW_PB:
+ return 1;
+
+ case ADB_HW_UNKNOWN:
+ default:
+ return 1;
+ }
+}
+
+
+/*
+ * adb_cmd_extra
+ *
+ * This routine lets the caller know whether the specified adb command string
+ * may have extra data appended to the end of it, such as a LISTEN command.
+ *
+ * returns: 0 if extra data is allowed
+ * 1 if extra data is NOT allowed
+ */
+int
+adb_cmd_extra(u_char *in)
+{
+ switch (adbHardware) {
+ case ADB_HW_II:
+ if ((in[1] & 0x0c) == 0x08) /* was it a listen command? */
+ return 0;
+ return 1;
+
+ case ADB_HW_IISI:
+ case ADB_HW_CUDA:
+ /*
+ * TO DO: support needs to be added to recognize RTC and PRAM
+ * commands
+ */
+ if ((in[2] & 0x0c) == 0x08) /* was it a listen command? */
+ return 0;
+ /* add others later */
+ return 1;
+
+ case ADB_HW_PB:
+ return 1;
+
+ case ADB_HW_UNKNOWN:
+ default:
+ return 1;
+ }
+}
+
+
+void
+adb_setup_hw_type(void)
+{
+ long response;
+
+ response = mac68k_machine.machineid;
+
+ /*
+ * Determine what type of ADB hardware we are running on.
+ */
+ switch (response) {
+ case MACH_MACC610: /* Centris 610 */
+ case MACH_MACC650: /* Centris 650 */
+ case MACH_MACII: /* II */
+ case MACH_MACIICI: /* IIci */
+ case MACH_MACIICX: /* IIcx */
+ case MACH_MACIIX: /* IIx */
+ case MACH_MACQ610: /* Quadra 610 */
+ case MACH_MACQ650: /* Quadra 650 */
+ case MACH_MACQ700: /* Quadra 700 */
+ case MACH_MACQ800: /* Quadra 800 */
+ case MACH_MACSE30: /* SE/30 */
+ adbHardware = ADB_HW_II;
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("adb: using II series hardware support\n");
+#endif
+ break;
+
+ case MACH_MACCLASSICII: /* Classic II */
+ case MACH_MACLCII: /* LC II, Performa 400/405/430 */
+ case MACH_MACLCIII: /* LC III, Performa 450 */
+ case MACH_MACIISI: /* IIsi */
+ case MACH_MACIIVI: /* IIvi */
+ case MACH_MACIIVX: /* IIvx */
+ case MACH_MACP460: /* Performa 460/465/467 */
+ case MACH_MACP600: /* Performa 600 */
+ adbHardware = ADB_HW_IISI;
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("adb: using IIsi series hardware support\n");
+#endif
+ break;
+
+ case MACH_MACPB140: /* PowerBook 140 */
+ case MACH_MACPB145: /* PowerBook 145 */
+ case MACH_MACPB160: /* PowerBook 160 */
+ case MACH_MACPB165: /* PowerBook 165 */
+ case MACH_MACPB165C: /* PowerBook 165c */
+ case MACH_MACPB170: /* PowerBook 170 */
+ case MACH_MACPB180: /* PowerBook 180 */
+ case MACH_MACPB180C: /* PowerBook 180c */
+ adbHardware = ADB_HW_PB;
+ pm_setup_adb();
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("adb: using PowerBook 100-series hardware support\n");
+#endif
+ break;
+
+ case MACH_MACPB150: /* PowerBook 150 */
+ case MACH_MACPB210: /* PowerBook Duo 210 */
+ case MACH_MACPB230: /* PowerBook Duo 230 */
+ case MACH_MACPB250: /* PowerBook Duo 250 */
+ case MACH_MACPB270: /* PowerBook Duo 270 */
+ case MACH_MACPB280: /* PowerBook Duo 280 */
+ case MACH_MACPB280C: /* PowerBook Duo 280c */
+ case MACH_MACPB500: /* PowerBook 500 series */
+ case MACH_MACPB190: /* PowerBook 190 */
+ case MACH_MACPB190CS: /* PowerBook 190cs */
+ adbHardware = ADB_HW_PB;
+ pm_setup_adb();
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("adb: using PowerBook Duo-series and PowerBook 500-series hardware support\n");
+#endif
+ break;
+
+ case MACH_MACC660AV: /* Centris 660AV */
+ case MACH_MACCCLASSIC: /* Color Classic */
+ case MACH_MACCCLASSICII: /* Color Classic II */
+ case MACH_MACLC475: /* LC 475, Performa 475/476 */
+ case MACH_MACLC475_33: /* Clock-chipped 47x */
+ case MACH_MACLC520: /* LC 520 */
+ case MACH_MACLC575: /* LC 575, Performa 575/577/578 */
+ case MACH_MACP550: /* LC 550, Performa 550 */
+ case MACH_MACTV: /* Macintosh TV */
+ case MACH_MACP580: /* Performa 580/588 */
+ case MACH_MACQ605: /* Quadra 605 */
+ case MACH_MACQ605_33: /* Clock-chipped Quadra 605 */
+ case MACH_MACQ630: /* LC 630, Performa 630, Quadra 630 */
+ case MACH_MACQ840AV: /* Quadra 840AV */
+ adbHardware = ADB_HW_CUDA;
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("adb: using Cuda series hardware support\n");
+#endif
+ break;
+
+ default:
+ adbHardware = ADB_HW_UNKNOWN;
+#ifdef ADB_DEBUG
+ if (adb_debug) {
+ printf_intr("adb: hardware type unknown for this machine\n");
+ printf_intr("adb: ADB support is disabled\n");
+ }
+#endif
+ break;
+ }
+
+ /*
+ * Determine whether this machine has ADB based soft power.
+ */
+ switch (response) {
+ case MACH_MACCCLASSIC: /* Color Classic */
+ case MACH_MACCCLASSICII: /* Color Classic II */
+ case MACH_MACIISI: /* IIsi */
+ case MACH_MACIIVI: /* IIvi */
+ case MACH_MACIIVX: /* IIvx */
+ case MACH_MACLC520: /* LC 520 */
+ case MACH_MACLC575: /* LC 575, Performa 575/577/578 */
+ case MACH_MACP550: /* LC 550, Performa 550 */
+ case MACH_MACTV: /* Macintosh TV */
+ case MACH_MACP580: /* Performa 580/588 */
+ case MACH_MACP600: /* Performa 600 */
+ case MACH_MACQ630: /* LC 630, Performa 630, Quadra 630 */
+ case MACH_MACQ840AV: /* Quadra 840AV */
+ adbSoftPower = 1;
+ break;
+ }
+}
+
+/*
* adb_op_sync
*
* This routine does exactly what the adb_op routine does, except that after
@@ -223,7 +2475,7 @@ adb_op_sync(Ptr buffer, Ptr compRout, Ptr data, short command)
int result;
volatile int flag = 0;
- result = ADBOp(buffer, (void *)adb_op_comprout, (Ptr)&flag,
+ result = adb_op(buffer, (void *)adb_op_comprout, (Ptr)&flag,
command); /* send command */
if (result == 0) { /* send ok? */
/*
@@ -254,7 +2506,6 @@ adb_op_sync(Ptr buffer, Ptr compRout, Ptr data, short command)
return result;
}
-
/*
* adb_op_comprout
*
@@ -266,3 +2517,380 @@ adb_op_comprout(caddr_t buffer, caddr_t data_area, int adb_command)
{
*(u_short *)data_area = 0x01; /* update flag value */
}
+
+int
+count_adbs(void)
+{
+ int i;
+ int found;
+
+ found = 0;
+
+ for (i = 1; i < 16; i++)
+ if (0 != ADBDevTable[i].currentAddr)
+ found++;
+
+ return found;
+}
+
+int
+get_ind_adb_info(ADBDataBlock *info, int index)
+{
+ if ((index < 1) || (index > 15)) /* check range 1-15 */
+ return (-1);
+
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("index 0x%x devType is: 0x%x\n", index,
+ ADBDevTable[index].devType);
+#endif
+ if (0 == ADBDevTable[index].devType) /* make sure it's a valid entry */
+ return (-1);
+
+ info->devType = (unsigned char)(ADBDevTable[index].devType);
+ info->origADBAddr = (unsigned char)(ADBDevTable[index].origAddr);
+ info->dbServiceRtPtr = (Ptr)ADBDevTable[index].ServiceRtPtr;
+ info->dbDataAreaAddr = (Ptr)ADBDevTable[index].DataAreaAddr;
+
+ return (ADBDevTable[index].currentAddr);
+}
+
+int
+get_adb_info(ADBDataBlock *info, int adbAddr)
+{
+ int i;
+
+ if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */
+ return (-1);
+
+ for (i = 1; i < 15; i++)
+ if (ADBDevTable[i].currentAddr == adbAddr) {
+ info->devType = (unsigned char)(ADBDevTable[i].devType);
+ info->origADBAddr = (unsigned char)(ADBDevTable[i].origAddr);
+ info->dbServiceRtPtr = (Ptr)ADBDevTable[i].ServiceRtPtr;
+ info->dbDataAreaAddr = ADBDevTable[i].DataAreaAddr;
+ return 0; /* found */
+ }
+
+ return (-1); /* not found */
+}
+
+int
+set_adb_info(ADBSetInfoBlock *info, int adbAddr)
+{
+ int i;
+
+ if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */
+ return (-1);
+
+ for (i = 1; i < 15; i++)
+ if (ADBDevTable[i].currentAddr == adbAddr) {
+ ADBDevTable[i].ServiceRtPtr =
+ (void *)(info->siServiceRtPtr);
+ ADBDevTable[i].DataAreaAddr = info->siDataAreaAddr;
+ return 0; /* found */
+ }
+
+ return (-1); /* not found */
+
+}
+
+/* caller should really use machine-independant version: getPramTime */
+/* this version does pseudo-adb access only */
+int
+adb_read_date_time(unsigned long *time)
+{
+ u_char output[ADB_MAX_MSG_LENGTH];
+ int result;
+ volatile int flag = 0;
+
+ switch (adbHardware) {
+ case ADB_HW_II:
+ return -1;
+
+ case ADB_HW_IISI:
+ output[0] = 0x02; /* 2 byte message */
+ output[1] = 0x01; /* to pram/rtc device */
+ output[2] = 0x03; /* read date/time */
+ result = send_adb_IIsi((u_char *)output, (u_char *)output,
+ (void *)adb_op_comprout, (void *)&flag, (int)0);
+ if (result != 0) /* exit if not sent */
+ return -1;
+
+ while (0 == flag) /* wait for result */
+ ;
+
+ *time = (long)(*(long *)(output + 1));
+ return 0;
+
+ case ADB_HW_PB:
+ return -1;
+
+ case ADB_HW_CUDA:
+ output[0] = 0x02; /* 2 byte message */
+ output[1] = 0x01; /* to pram/rtc device */
+ output[2] = 0x03; /* read date/time */
+ result = send_adb_cuda((u_char *)output, (u_char *)output,
+ (void *)adb_op_comprout, (void *)&flag, (int)0);
+ if (result != 0) /* exit if not sent */
+ return -1;
+
+ while (0 == flag) /* wait for result */
+ ;
+
+ *time = (long)(*(long *)(output + 1));
+ return 0;
+
+ case ADB_HW_UNKNOWN:
+ default:
+ return -1;
+ }
+}
+
+/* caller should really use machine-independant version: setPramTime */
+/* this version does pseudo-adb access only */
+int
+adb_set_date_time(unsigned long time)
+{
+ u_char output[ADB_MAX_MSG_LENGTH];
+ int result;
+ volatile int flag = 0;
+
+ switch (adbHardware) {
+ case ADB_HW_II:
+ return -1;
+
+ case ADB_HW_IISI:
+ output[0] = 0x06; /* 6 byte message */
+ output[1] = 0x01; /* to pram/rtc device */
+ output[2] = 0x09; /* set date/time */
+ output[3] = (u_char)(time >> 24);
+ output[4] = (u_char)(time >> 16);
+ output[5] = (u_char)(time >> 8);
+ output[6] = (u_char)(time);
+ result = send_adb_IIsi((u_char *)output, (u_char *)0,
+ (void *)adb_op_comprout, (void *)&flag, (int)0);
+ if (result != 0) /* exit if not sent */
+ return -1;
+
+ while (0 == flag) /* wait for send to finish */
+ ;
+
+ return 0;
+
+ case ADB_HW_PB:
+ return -1;
+
+ case ADB_HW_CUDA:
+ output[0] = 0x06; /* 6 byte message */
+ output[1] = 0x01; /* to pram/rtc device */
+ output[2] = 0x09; /* set date/time */
+ output[3] = (u_char)(time >> 24);
+ output[4] = (u_char)(time >> 16);
+ output[5] = (u_char)(time >> 8);
+ output[6] = (u_char)(time);
+ result = send_adb_cuda((u_char *)output, (u_char *)0,
+ (void *)adb_op_comprout, (void *)&flag, (int)0);
+ if (result != 0) /* exit if not sent */
+ return -1;
+
+ while (0 == flag) /* wait for send to finish */
+ ;
+
+ return 0;
+
+ case ADB_HW_UNKNOWN:
+ default:
+ return -1;
+ }
+}
+
+
+int
+adb_poweroff(void)
+{
+ u_char output[ADB_MAX_MSG_LENGTH];
+ int result;
+
+ if (!adbSoftPower)
+ return -1;
+
+ adb_polling = 1;
+
+ switch (adbHardware) {
+ case ADB_HW_IISI:
+ output[0] = 0x02; /* 2 byte message */
+ output[1] = 0x01; /* to pram/rtc/soft-power device */
+ output[2] = 0x0a; /* set date/time */
+ result = send_adb_IIsi((u_char *)output, (u_char *)0,
+ (void *)0, (void *)0, (int)0);
+ if (result != 0) /* exit if not sent */
+ return -1;
+
+ for (;;); /* wait for power off */
+
+ return 0;
+
+ case ADB_HW_PB:
+ return -1;
+
+ case ADB_HW_CUDA:
+ output[0] = 0x02; /* 2 byte message */
+ output[1] = 0x01; /* to pram/rtc/soft-power device */
+ output[2] = 0x0a; /* set date/time */
+ result = send_adb_cuda((u_char *)output, (u_char *)0,
+ (void *)0, (void *)0, (int)0);
+ if (result != 0) /* exit if not sent */
+ return -1;
+
+ for (;;); /* wait for power off */
+
+ return 0;
+
+ case ADB_HW_II: /* II models don't do ADB soft power */
+ case ADB_HW_UNKNOWN:
+ default:
+ return -1;
+ }
+}
+
+int
+adb_prog_switch_enable(void)
+{
+ u_char output[ADB_MAX_MSG_LENGTH];
+ int result;
+ volatile int flag = 0;
+
+ switch (adbHardware) {
+ case ADB_HW_IISI:
+ output[0] = 0x03; /* 3 byte message */
+ output[1] = 0x01; /* to pram/rtc/soft-power device */
+ output[2] = 0x1c; /* prog. switch control */
+ output[3] = 0x01; /* enable */
+ result = send_adb_IIsi((u_char *)output, (u_char *)0,
+ (void *)adb_op_comprout, (void *)&flag, (int)0);
+ if (result != 0) /* exit if not sent */
+ return -1;
+
+ while (0 == flag) /* wait for send to finish */
+ ;
+
+ return 0;
+
+ case ADB_HW_PB:
+ return -1;
+
+ case ADB_HW_II: /* II models don't do prog. switch */
+ case ADB_HW_CUDA: /* cuda doesn't do prog. switch TO DO: verify this */
+ case ADB_HW_UNKNOWN:
+ default:
+ return -1;
+ }
+}
+
+int
+adb_prog_switch_disable(void)
+{
+ u_char output[ADB_MAX_MSG_LENGTH];
+ int result;
+ volatile int flag = 0;
+
+ switch (adbHardware) {
+ case ADB_HW_IISI:
+ output[0] = 0x03; /* 3 byte message */
+ output[1] = 0x01; /* to pram/rtc/soft-power device */
+ output[2] = 0x1c; /* prog. switch control */
+ output[3] = 0x01; /* disable */
+ result = send_adb_IIsi((u_char *)output, (u_char *)0,
+ (void *)adb_op_comprout, (void *)&flag, (int)0);
+ if (result != 0) /* exit if not sent */
+ return -1;
+
+ while (0 == flag) /* wait for send to finish */
+ ;
+
+ return 0;
+
+ case ADB_HW_PB:
+ return -1;
+
+ case ADB_HW_II: /* II models don't do prog. switch */
+ case ADB_HW_CUDA: /* cuda doesn't do prog. switch */
+ case ADB_HW_UNKNOWN:
+ default:
+ return -1;
+ }
+}
+
+/*
+ * Function declarations.
+ */
+int adbmatch(struct device *, void *, void *);
+void adbattach(struct device *, struct device *, void *);
+void adb_attach_deferred(void *);
+
+/*
+ * Driver definition.
+ */
+struct cfattach adb_ca = {
+ sizeof(struct device), adbmatch, adbattach
+};
+
+int
+adbmatch(struct device *parent, void *vcf, void *aux)
+{
+ static int adb_matched = 0;
+
+ /* Allow only one instance. */
+ if (adb_matched)
+ return (0);
+
+ adb_matched = 1;
+ return (1);
+}
+
+void
+adbattach(struct device *parent, struct device *self, void *aux)
+{
+ printf("\n");
+ startuphook_establish(adb_attach_deferred, self);
+}
+
+void
+adb_attach_deferred(void *v)
+{
+ struct device *self = v;
+ ADBDataBlock adbdata;
+ struct adb_attach_args aa_args;
+ int totaladbs;
+ int adbindex, adbaddr;
+
+ printf("%s", self->dv_xname);
+
+ adb_polling = 1;
+ adb_reinit();
+
+ printf(": %s", adbHardwareDescr[adbHardware]);
+
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf("adb: done with adb_reinit\n");
+#endif
+
+ totaladbs = count_adbs();
+
+ printf(", %d target%s\n", totaladbs, (totaladbs == 1) ? "" : "s");
+
+ /* for each ADB device */
+ for (adbindex = 1; adbindex <= totaladbs; adbindex++) {
+ /* Get the ADB information */
+ adbaddr = get_ind_adb_info(&adbdata, adbindex);
+
+ aa_args.origaddr = (int)(adbdata.origADBAddr);
+ aa_args.adbaddr = adbaddr;
+ aa_args.handler_id = (int)(adbdata.devType);
+
+ (void)config_found(self, &aa_args, adbprint);
+ }
+ adb_polling = 0;
+}
diff --git a/sys/arch/mac68k/dev/adb_direct.c b/sys/arch/mac68k/dev/adb_direct.c
deleted file mode 100644
index a4a74300deb..00000000000
--- a/sys/arch/mac68k/dev/adb_direct.c
+++ /dev/null
@@ -1,2759 +0,0 @@
-/* $OpenBSD: adb_direct.c,v 1.19 2006/01/16 21:48:20 miod Exp $ */
-/* $NetBSD: adb_direct.c,v 1.51 2005/06/16 22:43:36 jmc Exp $ */
-
-/* From: adb_direct.c 2.02 4/18/97 jpw */
-
-/*
- * Copyright (C) 1996, 1997 John P. Wittkoski
- * All rights reserved.
- *
- * 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 John P. Wittkoski.
- * 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.
- */
-
-/*
- * This code is rather messy, but I don't have time right now
- * to clean it up as much as I would like.
- * But it works, so I'm happy. :-) jpw
- */
-
-/*
- * TO DO:
- * - We could reduce the time spent in the adb_intr_* routines
- * by having them save the incoming and outgoing data directly
- * in the adbInbound and adbOutbound queues, as it would reduce
- * the number of times we need to copy the data around. It
- * would also make the code more readable and easier to follow.
- * - (Related to above) Use the header part of adbCommand to
- * reduce the number of copies we have to do of the data.
- * - (Related to above) Actually implement the adbOutbound queue.
- * This is fairly easy once you switch all the intr routines
- * over to using adbCommand structs directly.
- * - There is a bug in the state machine of adb_intr_cuda
- * code that causes hangs, especially on 030 machines, probably
- * because of some timing issues. Because I have been unable to
- * determine the exact cause of this bug, I used the timeout function
- * to check for and recover from this condition. If anyone finds
- * the actual cause of this bug, the calls to timeout and the
- * adb_cuda_tickle routine can be removed.
- */
-
-#include <sys/param.h>
-#include <sys/cdefs.h>
-#include <sys/pool.h>
-#include <sys/queue.h>
-#include <sys/systm.h>
-#include <sys/timeout.h>
-
-#include <machine/viareg.h>
-#include <machine/param.h>
-#include <machine/cpu.h>
-#include <mac68k/dev/adbvar.h>
-#define printf_intr printf
-
-/* some misc. leftovers */
-#define vPB 0x0000
-#define vPB3 0x08
-#define vPB4 0x10
-#define vPB5 0x20
-#define vSR_INT 0x04
-#define vSR_OUT 0x10
-
-/* the type of ADB action that we are currently preforming */
-#define ADB_ACTION_NOTREADY 0x1 /* has not been initialized yet */
-#define ADB_ACTION_IDLE 0x2 /* the bus is currently idle */
-#define ADB_ACTION_OUT 0x3 /* sending out a command */
-#define ADB_ACTION_IN 0x4 /* receiving data */
-#define ADB_ACTION_POLLING 0x5 /* polling - II only */
-
-/*
- * These describe the state of the ADB bus itself, although they
- * don't necessarily correspond directly to ADB states.
- * Note: these are not really used in the IIsi code.
- */
-#define ADB_BUS_UNKNOWN 0x1 /* we don't know yet - all models */
-#define ADB_BUS_IDLE 0x2 /* bus is idle - all models */
-#define ADB_BUS_CMD 0x3 /* starting a command - II models */
-#define ADB_BUS_ODD 0x4 /* the "odd" state - II models */
-#define ADB_BUS_EVEN 0x5 /* the "even" state - II models */
-#define ADB_BUS_ACTIVE 0x6 /* active state - IIsi models */
-#define ADB_BUS_ACK 0x7 /* currently ACKing - IIsi models */
-
-/*
- * Shortcuts for setting or testing the VIA bit states.
- * Not all shortcuts are used for every type of ADB hardware.
- */
-#define ADB_SET_STATE_IDLE_II() via_reg(VIA1, vBufB) |= (vPB4 | vPB5)
-#define ADB_SET_STATE_IDLE_IISI() via_reg(VIA1, vBufB) &= ~(vPB4 | vPB5)
-#define ADB_SET_STATE_IDLE_CUDA() via_reg(VIA1, vBufB) |= (vPB4 | vPB5)
-#define ADB_SET_STATE_CMD() via_reg(VIA1, vBufB) &= ~(vPB4 | vPB5)
-#define ADB_SET_STATE_EVEN() via_reg(VIA1, vBufB) = ((via_reg(VIA1, \
- vBufB) | vPB4) & ~vPB5)
-#define ADB_SET_STATE_ODD() via_reg(VIA1, vBufB) = ((via_reg(VIA1, \
- vBufB) | vPB5) & ~vPB4)
-#define ADB_SET_STATE_ACTIVE() via_reg(VIA1, vBufB) |= vPB5
-#define ADB_SET_STATE_INACTIVE() via_reg(VIA1, vBufB) &= ~vPB5
-#define ADB_SET_STATE_TIP() via_reg(VIA1, vBufB) &= ~vPB5
-#define ADB_CLR_STATE_TIP() via_reg(VIA1, vBufB) |= vPB5
-#define ADB_SET_STATE_ACKON() via_reg(VIA1, vBufB) |= vPB4
-#define ADB_SET_STATE_ACKOFF() via_reg(VIA1, vBufB) &= ~vPB4
-#define ADB_TOGGLE_STATE_ACK_CUDA() via_reg(VIA1, vBufB) ^= vPB4
-#define ADB_SET_STATE_ACKON_CUDA() via_reg(VIA1, vBufB) &= ~vPB4
-#define ADB_SET_STATE_ACKOFF_CUDA() via_reg(VIA1, vBufB) |= vPB4
-#define ADB_SET_SR_INPUT() via_reg(VIA1, vACR) &= ~vSR_OUT
-#define ADB_SET_SR_OUTPUT() via_reg(VIA1, vACR) |= vSR_OUT
-#define ADB_SR() via_reg(VIA1, vSR)
-#define ADB_VIA_INTR_ENABLE() via_reg(VIA1, vIER) = 0x84
-#define ADB_VIA_INTR_DISABLE() via_reg(VIA1, vIER) = 0x04
-#define ADB_VIA_CLR_INTR() via_reg(VIA1, vIFR) = 0x04
-#define ADB_INTR_IS_OFF (vPB3 == (via_reg(VIA1, vBufB) & vPB3))
-#define ADB_INTR_IS_ON (0 == (via_reg(VIA1, vBufB) & vPB3))
-#define ADB_SR_INTR_IS_OFF (0 == (via_reg(VIA1, vIFR) & vSR_INT))
-#define ADB_SR_INTR_IS_ON (vSR_INT == (via_reg(VIA1, \
- vIFR) & vSR_INT))
-
-/*
- * This is the delay that is required (in uS) between certain
- * ADB transactions. The actual timing delay for for each uS is
- * calculated at boot time to account for differences in machine speed.
- */
-#define ADB_DELAY 150
-
-/*
- * Maximum ADB message length; includes space for data, result, and
- * device code - plus a little for safety.
- */
-#define ADB_MAX_MSG_LENGTH 16
-#define ADB_MAX_HDR_LENGTH 8
-
-#define ADB_QUEUE 32
-#define ADB_TICKLE_TICKS 4
-
-/*
- * A structure for storing information about each ADB device.
- */
-struct ADBDevEntry {
- void (*ServiceRtPtr)(void);
- void *DataAreaAddr;
- int devType;
- int origAddr;
- int currentAddr;
-};
-
-/*
- * Used to hold ADB commands that are waiting to be sent out.
- */
-struct adbCmdHoldEntry {
- u_char outBuf[ADB_MAX_MSG_LENGTH]; /* our message */
- u_char *saveBuf; /* buffer to know where to save result */
- u_char *compRout; /* completion routine pointer */
- u_char *data; /* completion routine data pointer */
-};
-
-/*
- * Eventually used for two separate queues, the queue between
- * the upper and lower halves, and the outgoing packet queue.
- * TO DO: adbCommand can replace all of adbCmdHoldEntry eventually
- */
-struct adbCommand {
- u_char header[ADB_MAX_HDR_LENGTH]; /* not used yet */
- u_char data[ADB_MAX_MSG_LENGTH]; /* packet data only */
- u_char *saveBuf; /* where to save result */
- u_char *compRout; /* completion routine pointer */
- u_char *compData; /* completion routine data pointer */
- u_int cmd; /* the original command for this data */
- u_int unsol; /* 1 if packet was unsolicited */
- u_int ack_only; /* 1 for no special processing */
-};
-
-/*
- * Text representations of each hardware class
- */
-const char *adbHardwareDescr[MAX_ADB_HW + 1] = {
- "unknown",
- "II series",
- "IIsi series",
- "PowerBook",
- "Cuda",
-};
-
-/*
- * A few variables that we need and their initial values.
- */
-int adbHardware = ADB_HW_UNKNOWN;
-int adbActionState = ADB_ACTION_NOTREADY;
-int adbBusState = ADB_BUS_UNKNOWN;
-int adbWaiting = 0; /* waiting for return data from the device */
-int adbWriteDelay = 0; /* working on (or waiting to do) a write */
-int adbOutQueueHasData = 0; /* something in the queue waiting to go out */
-int adbNextEnd = 0; /* the next incoming bute is the last (II) */
-int adbSoftPower = 0; /* machine supports soft power */
-
-int adbWaitingCmd = 0; /* ADB command we are waiting for */
-u_char *adbBuffer = (long)0; /* pointer to user data area */
-void *adbCompRout = (long)0; /* pointer to the completion routine */
-void *adbCompData = (long)0; /* pointer to the completion routine data */
-long adbFakeInts = 0; /* keeps track of fake ADB interrupts for
- * timeouts (II) */
-int adbStarting = 1; /* doing ADBReInit so do polling differently */
-int adbSendTalk = 0; /* the intr routine is sending the talk, not
- * the user (II) */
-int adbPolling = 0; /* we are polling for service request */
-int adbPollCmd = 0; /* the last poll command we sent */
-
-u_char adbInputBuffer[ADB_MAX_MSG_LENGTH]; /* data input buffer */
-u_char adbOutputBuffer[ADB_MAX_MSG_LENGTH]; /* data output buffer */
-struct adbCmdHoldEntry adbOutQueue; /* our 1 entry output queue */
-
-int adbSentChars = 0; /* how many characters we have sent */
-int adbLastDevice = 0; /* last ADB dev we heard from (II ONLY) */
-int adbLastDevIndex = 0; /* last ADB dev loc in dev table (II ONLY) */
-int adbLastCommand = 0; /* the last ADB command we sent (II) */
-
-struct ADBDevEntry ADBDevTable[16]; /* our ADB device table */
-int ADBNumDevices; /* num. of ADB devices found with ADBReInit */
-
-struct adbCommand adbInbound[ADB_QUEUE]; /* incoming queue */
-volatile int adbInCount = 0; /* how many packets in in queue */
-int adbInHead = 0; /* head of in queue */
-int adbInTail = 0; /* tail of in queue */
-struct adbCommand adbOutbound[ADB_QUEUE]; /* outgoing queue - not used yet */
-int adbOutCount = 0; /* how many packets in out queue */
-int adbOutHead = 0; /* head of out queue */
-int adbOutTail = 0; /* tail of out queue */
-
-int tickle_count = 0; /* how many tickles seen for this packet? */
-int tickle_serial = 0; /* the last packet tickled */
-int adb_cuda_serial = 0; /* the current packet */
-
-struct timeout adb_cuda_timeout;
-
-extern struct mac68k_machine_S mac68k_machine;
-
-void pm_setup_adb(void);
-void pm_hw_setup(void);
-void pm_check_adb_devices(int);
-int pm_adb_op(u_char *, void *, void *, int);
-void pm_init_adb_device(void);
-
-/*
- * The following are private routines.
- */
-#ifdef ADB_DEBUG
-void print_single(u_char *);
-#endif
-int adb_intr(void *);
-int adb_intr_II(void *);
-int adb_intr_IIsi(void *);
-int adb_intr_cuda(void *);
-void adb_soft_intr(void);
-int send_adb_II(u_char *, u_char *, void *, void *, int);
-int send_adb_IIsi(u_char *, u_char *, void *, void *, int);
-int send_adb_cuda(u_char *, u_char *, void *, void *, int);
-void adb_intr_cuda_test(void);
-void adb_cuda_tickle(void);
-void adb_pass_up(struct adbCommand *);
-void adb_reinit(void);
-int count_adbs(void);
-int get_ind_adb_info(ADBDataBlock *, int);
-int get_adb_info(ADBDataBlock *, int);
-int set_adb_info(ADBSetInfoBlock *, int);
-void adb_setup_hw_type(void);
-int adb_op(Ptr, Ptr, Ptr, short);
-void adb_read_II(u_char *);
-void adb_hw_setup(void);
-void adb_hw_setup_IIsi(u_char *);
-int adb_cmd_result(u_char *);
-int adb_cmd_extra(u_char *);
-int adb_guess_next_device(void);
-int adb_prog_switch_enable(void);
-int adb_prog_switch_disable(void);
-/* we should create this and it will be the public version */
-int send_adb(u_char *, void *, void *);
-
-#ifdef ADB_DEBUG
-/*
- * print_single
- * Diagnostic display routine. Displays the hex values of the
- * specified elements of the u_char. The length of the "string"
- * is in [0].
- */
-void
-print_single(u_char *str)
-{
- int x;
-
- if (str == 0) {
- printf_intr("no data - null pointer\n");
- return;
- }
- if (*str == 0) {
- printf_intr("nothing returned\n");
- return;
- }
- if (*str > 20) {
- printf_intr("ADB: ACK > 20 no way!\n");
- *str = (u_char)20;
- }
- printf_intr("(length=0x%x):", (u_int)*str);
- for (x = 1; x <= *str; x++)
- printf_intr(" 0x%02x", (u_int)*(str + x));
- printf_intr("\n");
-}
-#endif
-
-void
-adb_cuda_tickle(void)
-{
- volatile int s;
-
- if (adbActionState == ADB_ACTION_IN) {
- if (tickle_serial == adb_cuda_serial) {
- if (++tickle_count > 0) {
- s = splhigh();
- adbActionState = ADB_ACTION_IDLE;
- adbInputBuffer[0] = 0;
- ADB_SET_STATE_IDLE_CUDA();
- splx(s);
- }
- } else {
- tickle_serial = adb_cuda_serial;
- tickle_count = 0;
- }
- } else {
- tickle_serial = adb_cuda_serial;
- tickle_count = 0;
- }
-
- timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS);
-}
-
-/*
- * called when when an adb interrupt happens
- *
- * Cuda version of adb_intr
- * TO DO: do we want to add some calls to intr_dispatch() here to
- * grab serial interrupts?
- */
-int
-adb_intr_cuda(void *arg)
-{
- volatile int i, ending;
- volatile unsigned int s;
- struct adbCommand packet;
-
- s = splhigh(); /* can't be too careful - might be called */
- /* from a routine, NOT an interrupt */
-
- ADB_VIA_CLR_INTR(); /* clear interrupt */
- ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */
-
-switch_start:
- switch (adbActionState) {
- case ADB_ACTION_IDLE:
- /*
- * This is an unexpected packet, so grab the first (dummy)
- * byte, set up the proper vars, and tell the chip we are
- * starting to receive the packet by setting the TIP bit.
- */
- adbInputBuffer[1] = ADB_SR();
- adb_cuda_serial++;
- if (ADB_INTR_IS_OFF) /* must have been a fake start */
- break;
-
- ADB_SET_SR_INPUT();
- ADB_SET_STATE_TIP();
-
- adbInputBuffer[0] = 1;
- adbActionState = ADB_ACTION_IN;
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("idle 0x%02x ", adbInputBuffer[1]);
-#endif
- break;
-
- case ADB_ACTION_IN:
- adbInputBuffer[++adbInputBuffer[0]] = ADB_SR();
- /* intr off means this is the last byte (end of frame) */
- if (ADB_INTR_IS_OFF)
- ending = 1;
- else
- ending = 0;
-
- if (1 == ending) { /* end of message? */
-#ifdef ADB_DEBUG
- if (adb_debug) {
- printf_intr("in end 0x%02x ",
- adbInputBuffer[adbInputBuffer[0]]);
- print_single(adbInputBuffer);
- }
-#endif
-
- /*
- * Are we waiting AND does this packet match what we
- * are waiting for AND is it coming from either the
- * ADB or RTC/PRAM sub-device? This section _should_
- * recognize all ADB and RTC/PRAM type commands, but
- * there may be more... NOTE: commands are always at
- * [4], even for RTC/PRAM commands.
- */
- /* set up data for adb_pass_up */
- memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
-
- if ((adbWaiting == 1) &&
- (adbInputBuffer[4] == adbWaitingCmd) &&
- ((adbInputBuffer[2] == 0x00) ||
- (adbInputBuffer[2] == 0x01))) {
- packet.saveBuf = adbBuffer;
- packet.compRout = adbCompRout;
- packet.compData = adbCompData;
- packet.unsol = 0;
- packet.ack_only = 0;
- adb_pass_up(&packet);
-
- adbWaitingCmd = 0; /* reset "waiting" vars */
- adbWaiting = 0;
- adbBuffer = (long)0;
- adbCompRout = (long)0;
- adbCompData = (long)0;
- } else {
- packet.unsol = 1;
- packet.ack_only = 0;
- adb_pass_up(&packet);
- }
-
-
- /* reset vars and signal the end of this frame */
- adbActionState = ADB_ACTION_IDLE;
- adbInputBuffer[0] = 0;
- ADB_SET_STATE_IDLE_CUDA();
- /*ADB_SET_SR_INPUT();*/
-
- /*
- * If there is something waiting to be sent out,
- * the set everything up and send the first byte.
- */
- if (adbWriteDelay == 1) {
- delay(ADB_DELAY); /* required */
- adbSentChars = 0;
- adbActionState = ADB_ACTION_OUT;
- /*
- * If the interrupt is on, we were too slow
- * and the chip has already started to send
- * something to us, so back out of the write
- * and start a read cycle.
- */
- if (ADB_INTR_IS_ON) {
- ADB_SET_SR_INPUT();
- ADB_SET_STATE_IDLE_CUDA();
- adbSentChars = 0;
- adbActionState = ADB_ACTION_IDLE;
- adbInputBuffer[0] = 0;
- break;
- }
- /*
- * If we got here, it's ok to start sending
- * so load the first byte and tell the chip
- * we want to send.
- */
- ADB_SET_STATE_TIP();
- ADB_SET_SR_OUTPUT();
- ADB_SR() = adbOutputBuffer[adbSentChars + 1];
- }
- } else {
- ADB_TOGGLE_STATE_ACK_CUDA();
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("in 0x%02x ",
- adbInputBuffer[adbInputBuffer[0]]);
-#endif
- }
- break;
-
- case ADB_ACTION_OUT:
- i = ADB_SR(); /* reset SR-intr in IFR */
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("intr out 0x%02x ", i);
-#endif
-
- adbSentChars++;
- if (ADB_INTR_IS_ON) { /* ADB intr low during write */
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("intr was on ");
-#endif
- ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
- ADB_SET_STATE_IDLE_CUDA();
- adbSentChars = 0; /* must start all over */
- adbActionState = ADB_ACTION_IDLE; /* new state */
- adbInputBuffer[0] = 0;
- adbWriteDelay = 1; /* must retry when done with
- * read */
- delay(ADB_DELAY);
- goto switch_start; /* process next state right
- * now */
- break;
- }
- if (adbOutputBuffer[0] == adbSentChars) { /* check for done */
- if (0 == adb_cmd_result(adbOutputBuffer)) { /* do we expect data
- * back? */
- adbWaiting = 1; /* signal waiting for return */
- adbWaitingCmd = adbOutputBuffer[2]; /* save waiting command */
- } else { /* no talk, so done */
- /* set up stuff for adb_pass_up */
- memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
- packet.saveBuf = adbBuffer;
- packet.compRout = adbCompRout;
- packet.compData = adbCompData;
- packet.cmd = adbWaitingCmd;
- packet.unsol = 0;
- packet.ack_only = 1;
- adb_pass_up(&packet);
-
- /* reset "waiting" vars, just in case */
- adbWaitingCmd = 0;
- adbBuffer = (long)0;
- adbCompRout = (long)0;
- adbCompData = (long)0;
- }
-
- adbWriteDelay = 0; /* done writing */
- adbActionState = ADB_ACTION_IDLE; /* signal bus is idle */
- ADB_SET_SR_INPUT();
- ADB_SET_STATE_IDLE_CUDA();
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("write done ");
-#endif
- } else {
- ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* send next byte */
- ADB_TOGGLE_STATE_ACK_CUDA(); /* signal byte ready to
- * shift */
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("toggle ");
-#endif
- }
- break;
-
- case ADB_ACTION_NOTREADY:
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("adb: not yet initialized\n");
-#endif
- break;
-
- default:
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("intr: unknown ADB state\n");
-#endif
- break;
- }
-
- ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */
-
- splx(s); /* restore */
-
- return (1);
-} /* end adb_intr_cuda */
-
-
-int
-send_adb_cuda(u_char *in, u_char *buffer, void *compRout, void *data, int
- command)
-{
- int s, len;
-
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("SEND\n");
-#endif
-
- if (adbActionState == ADB_ACTION_NOTREADY)
- return 1;
-
- /* Don't interrupt while we are messing with the ADB */
- s = splhigh();
-
- if ((adbActionState == ADB_ACTION_IDLE) && /* ADB available? */
- (ADB_INTR_IS_OFF)) { /* and no incoming interrupt? */
- } else
- if (adbWriteDelay == 0) /* it's busy, but is anything waiting? */
- adbWriteDelay = 1; /* if no, then we'll "queue"
- * it up */
- else {
- splx(s);
- return 1; /* really busy! */
- }
-
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("QUEUE\n");
-#endif
- if ((long)in == (long)0) { /* need to convert? */
- /*
- * Don't need to use adb_cmd_extra here because this section
- * will be called ONLY when it is an ADB command (no RTC or
- * PRAM)
- */
- if ((command & 0x0c) == 0x08) /* copy addl data ONLY if
- * doing a listen! */
- len = buffer[0]; /* length of additional data */
- else
- len = 0;/* no additional data */
-
- adbOutputBuffer[0] = 2 + len; /* dev. type + command + addl.
- * data */
- adbOutputBuffer[1] = 0x00; /* mark as an ADB command */
- adbOutputBuffer[2] = (u_char)command; /* load command */
-
- /* copy additional output data, if any */
- memcpy(adbOutputBuffer + 3, buffer + 1, len);
- } else
- /* if data ready, just copy over */
- memcpy(adbOutputBuffer, in, in[0] + 2);
-
- adbSentChars = 0; /* nothing sent yet */
- adbBuffer = buffer; /* save buffer to know where to save result */
- adbCompRout = compRout; /* save completion routine pointer */
- adbCompData = data; /* save completion routine data pointer */
- adbWaitingCmd = adbOutputBuffer[2]; /* save wait command */
-
- if (adbWriteDelay != 1) { /* start command now? */
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("out start NOW");
-#endif
- delay(ADB_DELAY);
- adbActionState = ADB_ACTION_OUT; /* set next state */
- ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
- ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* load byte for output */
- ADB_SET_STATE_ACKOFF_CUDA();
- ADB_SET_STATE_TIP(); /* tell ADB that we want to send */
- }
- adbWriteDelay = 1; /* something in the write "queue" */
-
- splx(s);
-
- if (0x0100 <= (s & 0x0700)) /* were VIA1 interrupts blocked? */
- /* poll until byte done */
- while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
- || (adbWaiting == 1))
- if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
- adb_intr_cuda(NULL); /* go process it */
- if (adb_polling)
- adb_soft_intr();
- }
-
- return 0;
-} /* send_adb_cuda */
-
-
-int
-adb_intr_II(void *arg)
-{
- struct adbCommand packet;
- int i, intr_on = 0;
- int send = 0;
- unsigned int s;
-
- s = splhigh(); /* can't be too careful - might be called */
- /* from a routine, NOT an interrupt */
-
- ADB_VIA_CLR_INTR(); /* clear interrupt */
-
- ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */
-
- delay(ADB_DELAY); /* yuck (don't remove) */
-
- (void)intr_dispatch(0x70); /* grab any serial interrupts */
-
- if (ADB_INTR_IS_ON)
- intr_on = 1; /* save for later */
-
-switch_start:
- switch (adbActionState) {
- case ADB_ACTION_POLLING:
- if (!intr_on) {
- if (adbOutQueueHasData) {
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("POLL-doing-out-queue. ");
-#endif
- ADB_SET_STATE_IDLE_II();
- delay(ADB_DELAY);
-
- /* copy over data */
- memcpy(adbOutputBuffer, adbOutQueue.outBuf,
- adbOutQueue.outBuf[0] + 2);
-
- adbBuffer = adbOutQueue.saveBuf; /* user data area */
- adbCompRout = adbOutQueue.compRout; /* completion routine */
- adbCompData = adbOutQueue.data; /* comp. rout. data */
- adbOutQueueHasData = 0; /* currently processing
- * "queue" entry */
- adbSentChars = 0; /* nothing sent yet */
- adbActionState = ADB_ACTION_OUT; /* set next state */
- ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
- ADB_SR() = adbOutputBuffer[1]; /* load byte for output */
- adbBusState = ADB_BUS_CMD; /* set bus to cmd state */
- ADB_SET_STATE_CMD(); /* tell ADB that we want to send */
- break;
- } else {
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("pIDLE ");
-#endif
- adbActionState = ADB_ACTION_IDLE;
- }
- } else {
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("pIN ");
-#endif
- adbActionState = ADB_ACTION_IN;
- }
- delay(ADB_DELAY);
- (void)intr_dispatch(0x70); /* grab any serial interrupts */
- goto switch_start;
- break;
- case ADB_ACTION_IDLE:
- if (!intr_on) {
- i = ADB_SR();
- adbBusState = ADB_BUS_IDLE;
- adbActionState = ADB_ACTION_IDLE;
- ADB_SET_STATE_IDLE_II();
- break;
- }
- adbInputBuffer[0] = 1;
- adbInputBuffer[1] = ADB_SR(); /* get first byte */
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("idle 0x%02x ", adbInputBuffer[1]);
-#endif
- ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
- adbActionState = ADB_ACTION_IN; /* set next state */
- ADB_SET_STATE_EVEN(); /* set bus state to even */
- adbBusState = ADB_BUS_EVEN;
- break;
-
- case ADB_ACTION_IN:
- adbInputBuffer[++adbInputBuffer[0]] = ADB_SR(); /* get byte */
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("in 0x%02x ",
- adbInputBuffer[adbInputBuffer[0]]);
-#endif
- ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
-
- if (intr_on) { /* process last byte of packet */
- adbInputBuffer[0]--; /* minus one */
- /*
- * If intr_on was true, and it's the second byte, then
- * the byte we just discarded is really valid, so
- * adjust the count
- */
- if (adbInputBuffer[0] == 2) {
- adbInputBuffer[0]++;
- }
-
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80) {
- printf_intr("done: ");
- print_single(adbInputBuffer);
- }
-#endif
-
- adbLastDevice = ADB_CMDADDR(adbInputBuffer[1]);
-
- if (adbInputBuffer[0] == 1 && !adbWaiting) { /* SRQ!!!*/
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr(" xSRQ! ");
-#endif
- adb_guess_next_device();
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("try 0x%0x ",
- adbLastDevice);
-#endif
- adbOutputBuffer[0] = 1;
- adbOutputBuffer[1] = ADBTALK(adbLastDevice, 0);
-
- adbSentChars = 0; /* nothing sent yet */
- adbActionState = ADB_ACTION_POLLING; /* set next state */
- ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
- ADB_SR() = adbOutputBuffer[1]; /* load byte for output */
- adbBusState = ADB_BUS_CMD; /* set bus to cmd state */
- ADB_SET_STATE_CMD(); /* tell ADB that we want to */
- break;
- }
-
- /* set up data for adb_pass_up */
- memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
-
- if (!adbWaiting && (adbInputBuffer[0] != 0)) {
- packet.unsol = 1;
- packet.ack_only = 0;
- adb_pass_up(&packet);
- } else {
- packet.saveBuf = adbBuffer;
- packet.compRout = adbCompRout;
- packet.compData = adbCompData;
- packet.unsol = 0;
- packet.ack_only = 0;
- adb_pass_up(&packet);
- }
-
- adbWaiting = 0;
- adbInputBuffer[0] = 0;
- adbBuffer = (long)0;
- adbCompRout = (long)0;
- adbCompData = (long)0;
- /*
- * Since we are done, check whether there is any data
- * waiting to do out. If so, start the sending the data.
- */
- if (adbOutQueueHasData == 1) {
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("XXX: DOING OUT QUEUE\n");
-#endif
- /* copy over data */
- memcpy(adbOutputBuffer, adbOutQueue.outBuf,
- adbOutQueue.outBuf[0] + 2);
- adbBuffer = adbOutQueue.saveBuf; /* user data area */
- adbCompRout = adbOutQueue.compRout; /* completion routine */
- adbCompData = adbOutQueue.data; /* comp. rout. data */
- adbOutQueueHasData = 0; /* currently processing
- * "queue" entry */
- send = 1;
- } else {
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("XXending ");
-#endif
- adb_guess_next_device();
- adbOutputBuffer[0] = 1;
- adbOutputBuffer[1] = ((adbLastDevice & 0x0f) << 4) | 0x0c;
- adbSentChars = 0; /* nothing sent yet */
- adbActionState = ADB_ACTION_POLLING; /* set next state */
- ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
- ADB_SR() = adbOutputBuffer[1]; /* load byte for output */
- adbBusState = ADB_BUS_CMD; /* set bus to cmd state */
- ADB_SET_STATE_CMD(); /* tell ADB that we want to */
- break;
- }
- }
-
- /*
- * If send is true then something above determined that
- * the message has ended and we need to start sending out
- * a new message immediately. This could be because there
- * is data waiting to go out or because an SRQ was seen.
- */
- if (send) {
- adbSentChars = 0; /* nothing sent yet */
- adbActionState = ADB_ACTION_OUT; /* set next state */
- ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
- ADB_SR() = adbOutputBuffer[1]; /* load byte for output */
- adbBusState = ADB_BUS_CMD; /* set bus to cmd state */
- ADB_SET_STATE_CMD(); /* tell ADB that we want to
- * send */
- break;
- }
- /* We only get this far if the message hasn't ended yet. */
- switch (adbBusState) { /* set to next state */
- case ADB_BUS_EVEN:
- ADB_SET_STATE_ODD(); /* set state to odd */
- adbBusState = ADB_BUS_ODD;
- break;
-
- case ADB_BUS_ODD:
- ADB_SET_STATE_EVEN(); /* set state to even */
- adbBusState = ADB_BUS_EVEN;
- break;
- default:
- printf_intr("strange state!!!\n"); /* huh? */
- break;
- }
- break;
-
- case ADB_ACTION_OUT:
- i = ADB_SR(); /* clear interrupt */
- adbSentChars++;
- /*
- * If the outgoing data was a TALK, we must
- * switch to input mode to get the result.
- */
- if ((adbOutputBuffer[1] & 0x0c) == 0x0c) {
- adbInputBuffer[0] = 1;
- adbInputBuffer[1] = i;
- adbActionState = ADB_ACTION_IN;
- ADB_SET_SR_INPUT();
- adbBusState = ADB_BUS_EVEN;
- ADB_SET_STATE_EVEN();
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("talk out 0x%02x ", i);
-#endif
- /* we want something back */
- adbWaiting = 1;
- break;
- }
- /*
- * If it's not a TALK, check whether all data has been sent.
- * If so, call the completion routine and clean up. If not,
- * advance to the next state.
- */
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("non-talk out 0x%0x ", i);
-#endif
- ADB_SET_SR_OUTPUT();
- if (adbOutputBuffer[0] == adbSentChars) { /* check for done */
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("done \n");
-#endif
- /* set up stuff for adb_pass_up */
- memcpy(packet.data, adbOutputBuffer, adbOutputBuffer[0] + 1);
- packet.saveBuf = adbBuffer;
- packet.compRout = adbCompRout;
- packet.compData = adbCompData;
- packet.cmd = adbWaitingCmd;
- packet.unsol = 0;
- packet.ack_only = 1;
- adb_pass_up(&packet);
-
- /* reset "waiting" vars, just in case */
- adbBuffer = (long)0;
- adbCompRout = (long)0;
- adbCompData = (long)0;
- if (adbOutQueueHasData == 1) {
- /* copy over data */
- memcpy(adbOutputBuffer, adbOutQueue.outBuf,
- adbOutQueue.outBuf[0] + 2);
- adbBuffer = adbOutQueue.saveBuf; /* user data area */
- adbCompRout = adbOutQueue.compRout; /* completion routine */
- adbCompData = adbOutQueue.data; /* comp. rout. data */
- adbOutQueueHasData = 0; /* currently processing
- * "queue" entry */
- adbSentChars = 0; /* nothing sent yet */
- adbActionState = ADB_ACTION_OUT; /* set next state */
- ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
- ADB_SR() = adbOutputBuffer[1]; /* load byte for output */
- adbBusState = ADB_BUS_CMD; /* set bus to cmd state */
- ADB_SET_STATE_CMD(); /* tell ADB that we want to
- * send */
- break;
- } else {
- /* send talk to last device instead */
- adbOutputBuffer[0] = 1;
- adbOutputBuffer[1] =
- ADBTALK(ADB_CMDADDR(adbOutputBuffer[1]), 0);
-
- adbSentChars = 0; /* nothing sent yet */
- adbActionState = ADB_ACTION_IDLE; /* set next state */
- ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
- ADB_SR() = adbOutputBuffer[1]; /* load byte for output */
- adbBusState = ADB_BUS_CMD; /* set bus to cmd state */
- ADB_SET_STATE_CMD(); /* tell ADB that we want to */
- break;
- }
- }
- ADB_SR() = adbOutputBuffer[adbSentChars + 1];
- switch (adbBusState) { /* advance to next state */
- case ADB_BUS_EVEN:
- ADB_SET_STATE_ODD(); /* set state to odd */
- adbBusState = ADB_BUS_ODD;
- break;
-
- case ADB_BUS_CMD:
- case ADB_BUS_ODD:
- ADB_SET_STATE_EVEN(); /* set state to even */
- adbBusState = ADB_BUS_EVEN;
- break;
-
- default:
-#ifdef ADB_DEBUG
- if (adb_debug) {
- printf_intr("strange state!!! (0x%x)\n",
- adbBusState);
- }
-#endif
- break;
- }
- break;
-
- default:
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("adb: unknown ADB state (during intr)\n");
-#endif
- break;
- }
-
- ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */
-
- splx(s); /* restore */
-
- return (1);
-
-}
-
-
-/*
- * send_adb version for II series machines
- */
-int
-send_adb_II(u_char *in, u_char *buffer, void *compRout, void *data, int command)
-{
- int s, len;
-
- if (adbActionState == ADB_ACTION_NOTREADY) /* return if ADB not
- * available */
- return 1;
-
- /* Don't interrupt while we are messing with the ADB */
- s = splhigh();
-
- if (0 != adbOutQueueHasData) { /* right now, "has data" means "full" */
- splx(s); /* sorry, try again later */
- return 1;
- }
- if ((long)in == (long)0) { /* need to convert? */
- /*
- * Don't need to use adb_cmd_extra here because this section
- * will be called ONLY when it is an ADB command (no RTC or
- * PRAM), especially on II series!
- */
- if ((command & 0x0c) == 0x08) /* copy addl data ONLY if
- * doing a listen! */
- len = buffer[0]; /* length of additional data */
- else
- len = 0;/* no additional data */
-
- adbOutQueue.outBuf[0] = 1 + len; /* command + addl. data */
- adbOutQueue.outBuf[1] = (u_char)command; /* load command */
-
- /* copy additional output data, if any */
- memcpy(adbOutQueue.outBuf + 2, buffer + 1, len);
- } else
- /* if data ready, just copy over */
- memcpy(adbOutQueue.outBuf, in, in[0] + 2);
-
- adbOutQueue.saveBuf = buffer; /* save buffer to know where to save
- * result */
- adbOutQueue.compRout = compRout; /* save completion routine
- * pointer */
- adbOutQueue.data = data;/* save completion routine data pointer */
-
- if ((adbActionState == ADB_ACTION_IDLE) && /* is ADB available? */
- (ADB_INTR_IS_OFF)) { /* and no incoming interrupts? */
- /* then start command now */
- memcpy(adbOutputBuffer, adbOutQueue.outBuf,
- adbOutQueue.outBuf[0] + 2); /* copy over data */
-
- adbBuffer = adbOutQueue.saveBuf; /* pointer to user data
- * area */
- adbCompRout = adbOutQueue.compRout; /* pointer to the
- * completion routine */
- adbCompData = adbOutQueue.data; /* pointer to the completion
- * routine data */
-
- adbSentChars = 0; /* nothing sent yet */
- adbActionState = ADB_ACTION_OUT; /* set next state */
- adbBusState = ADB_BUS_CMD; /* set bus to cmd state */
-
- ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
-
- ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* load byte for output */
- ADB_SET_STATE_CMD(); /* tell ADB that we want to send */
- adbOutQueueHasData = 0; /* currently processing "queue" entry */
- } else
- adbOutQueueHasData = 1; /* something in the write "queue" */
-
- splx(s);
-
- if (0x0100 <= (s & 0x0700)) /* were VIA1 interrupts blocked? */
- /* poll until message done */
- while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
- || (adbWaiting == 1))
- if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
- adb_intr_II(NULL); /* go process it */
- if (adb_polling)
- adb_soft_intr();
- }
-
- return 0;
-}
-
-
-/*
- * This routine is called from the II series interrupt routine
- * to determine what the "next" device is that should be polled.
- */
-int
-adb_guess_next_device(void)
-{
- int last, i, dummy;
-
- if (adbStarting) {
- /*
- * Start polling EVERY device, since we can't be sure there is
- * anything in the device table yet
- */
- if (adbLastDevice < 1 || adbLastDevice > 15)
- adbLastDevice = 1;
- if (++adbLastDevice > 15) /* point to next one */
- adbLastDevice = 1;
- } else {
- /* find the next device using the device table */
- if (adbLastDevice < 1 || adbLastDevice > 15) /* let's be parinoid */
- adbLastDevice = 2;
- last = 1; /* default index location */
-
- for (i = 1; i < 16; i++) /* find index entry */
- if (ADBDevTable[i].currentAddr == adbLastDevice) { /* look for device */
- last = i; /* found it */
- break;
- }
- dummy = last; /* index to start at */
- for (;;) { /* find next device in index */
- if (++dummy > 15) /* wrap around if needed */
- dummy = 1;
- if (dummy == last) { /* didn't find any other
- * device! This can happen if
- * there are no devices on the
- * bus */
- dummy = 1;
- break;
- }
- /* found the next device */
- if (ADBDevTable[dummy].devType != 0)
- break;
- }
- adbLastDevice = ADBDevTable[dummy].currentAddr;
- }
- return adbLastDevice;
-}
-
-
-/*
- * Called when when an adb interrupt happens.
- * This routine simply transfers control over to the appropriate
- * code for the machine we are running on.
- */
-int
-adb_intr(void *arg)
-{
- switch (adbHardware) {
- case ADB_HW_II:
- return adb_intr_II(arg);
- break;
-
- case ADB_HW_IISI:
- return adb_intr_IIsi(arg);
- break;
-
- case ADB_HW_PB: /* Should not come through here. */
- break;
-
- case ADB_HW_CUDA:
- return adb_intr_cuda(arg);
- break;
-
- case ADB_HW_UNKNOWN:
- break;
- }
-
- return (-1);
-}
-
-
-/*
- * called when when an adb interrupt happens
- *
- * IIsi version of adb_intr
- *
- */
-int
-adb_intr_IIsi(void *arg)
-{
- struct adbCommand packet;
- int i, ending;
- unsigned int s;
-
- s = splhigh(); /* can't be too careful - might be called */
- /* from a routine, NOT an interrupt */
-
- ADB_VIA_CLR_INTR(); /* clear interrupt */
-
- ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */
-
-switch_start:
- switch (adbActionState) {
- case ADB_ACTION_IDLE:
- delay(ADB_DELAY); /* short delay is required before the
- * first byte */
-
- ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
- ADB_SET_STATE_ACTIVE(); /* signal start of data frame */
- adbInputBuffer[1] = ADB_SR(); /* get byte */
- adbInputBuffer[0] = 1;
- adbActionState = ADB_ACTION_IN; /* set next state */
-
- ADB_SET_STATE_ACKON(); /* start ACK to ADB chip */
- delay(ADB_DELAY); /* delay */
- ADB_SET_STATE_ACKOFF(); /* end ACK to ADB chip */
- (void)intr_dispatch(0x70); /* grab any serial interrupts */
- break;
-
- case ADB_ACTION_IN:
- ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
- adbInputBuffer[++adbInputBuffer[0]] = ADB_SR(); /* get byte */
- if (ADB_INTR_IS_OFF) /* check for end of frame */
- ending = 1;
- else
- ending = 0;
-
- ADB_SET_STATE_ACKON(); /* start ACK to ADB chip */
- delay(ADB_DELAY); /* delay */
- ADB_SET_STATE_ACKOFF(); /* end ACK to ADB chip */
- (void)intr_dispatch(0x70); /* grab any serial interrupts */
-
- if (1 == ending) { /* end of message? */
- ADB_SET_STATE_INACTIVE(); /* signal end of frame */
- /*
- * This section _should_ handle all ADB and RTC/PRAM
- * type commands, but there may be more... Note:
- * commands are always at [4], even for rtc/pram
- * commands
- */
- /* set up data for adb_pass_up */
- memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
-
- if ((adbWaiting == 1) && /* are we waiting AND */
- (adbInputBuffer[4] == adbWaitingCmd) && /* the cmd we sent AND */
- ((adbInputBuffer[2] == 0x00) || /* it's from the ADB
- * device OR */
- (adbInputBuffer[2] == 0x01))) { /* it's from the
- * PRAM/RTC device */
-
- packet.saveBuf = adbBuffer;
- packet.compRout = adbCompRout;
- packet.compData = adbCompData;
- packet.unsol = 0;
- packet.ack_only = 0;
- adb_pass_up(&packet);
-
- adbWaitingCmd = 0; /* reset "waiting" vars */
- adbWaiting = 0;
- adbBuffer = (long)0;
- adbCompRout = (long)0;
- adbCompData = (long)0;
- } else {
- packet.unsol = 1;
- packet.ack_only = 0;
- adb_pass_up(&packet);
- }
-
- adbActionState = ADB_ACTION_IDLE;
- adbInputBuffer[0] = 0; /* reset length */
-
- if (adbWriteDelay == 1) { /* were we waiting to
- * write? */
- adbSentChars = 0; /* nothing sent yet */
- adbActionState = ADB_ACTION_OUT; /* set next state */
-
- delay(ADB_DELAY); /* delay */
- (void)intr_dispatch(0x70); /* grab any serial interrupts */
-
- if (ADB_INTR_IS_ON) { /* ADB intr low during
- * write */
- ADB_SET_STATE_IDLE_IISI(); /* reset */
- ADB_SET_SR_INPUT(); /* make sure SR is set
- * to IN */
- adbSentChars = 0; /* must start all over */
- adbActionState = ADB_ACTION_IDLE; /* new state */
- adbInputBuffer[0] = 0;
- /* may be able to take this out later */
- delay(ADB_DELAY); /* delay */
- break;
- }
- ADB_SET_STATE_ACTIVE(); /* tell ADB that we want
- * to send */
- ADB_SET_STATE_ACKOFF(); /* make sure */
- ADB_SET_SR_OUTPUT(); /* set shift register
- * for OUT */
- ADB_SR() = adbOutputBuffer[adbSentChars + 1];
- ADB_SET_STATE_ACKON(); /* tell ADB byte ready
- * to shift */
- }
- }
- break;
-
- case ADB_ACTION_OUT:
- i = ADB_SR(); /* reset SR-intr in IFR */
- ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
-
- ADB_SET_STATE_ACKOFF(); /* finish ACK */
- adbSentChars++;
- if (ADB_INTR_IS_ON) { /* ADB intr low during write */
- ADB_SET_STATE_IDLE_IISI(); /* reset */
- ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
- adbSentChars = 0; /* must start all over */
- adbActionState = ADB_ACTION_IDLE; /* new state */
- adbInputBuffer[0] = 0;
- adbWriteDelay = 1; /* must retry when done with
- * read */
- delay(ADB_DELAY); /* delay */
- (void)intr_dispatch(0x70); /* grab any serial interrupts */
- goto switch_start; /* process next state right
- * now */
- break;
- }
- delay(ADB_DELAY); /* required delay */
- (void)intr_dispatch(0x70); /* grab any serial interrupts */
-
- if (adbOutputBuffer[0] == adbSentChars) { /* check for done */
- if (0 == adb_cmd_result(adbOutputBuffer)) { /* do we expect data
- * back? */
- adbWaiting = 1; /* signal waiting for return */
- adbWaitingCmd = adbOutputBuffer[2]; /* save waiting command */
- } else {/* no talk, so done */
- /* set up stuff for adb_pass_up */
- memcpy(packet.data, adbInputBuffer,
- adbInputBuffer[0] + 1);
- packet.saveBuf = adbBuffer;
- packet.compRout = adbCompRout;
- packet.compData = adbCompData;
- packet.cmd = adbWaitingCmd;
- packet.unsol = 0;
- packet.ack_only = 1;
- adb_pass_up(&packet);
-
- /* reset "waiting" vars, just in case */
- adbWaitingCmd = 0;
- adbBuffer = (long)0;
- adbCompRout = (long)0;
- adbCompData = (long)0;
- }
-
- adbWriteDelay = 0; /* done writing */
- adbActionState = ADB_ACTION_IDLE; /* signal bus is idle */
- ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
- ADB_SET_STATE_INACTIVE(); /* end of frame */
- } else {
- ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* send next byte */
- ADB_SET_STATE_ACKON(); /* signal byte ready to shift */
- }
- break;
-
- case ADB_ACTION_NOTREADY:
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("adb: not yet initialized\n");
-#endif
- break;
-
- default:
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("intr: unknown ADB state\n");
-#endif
- break;
- }
-
- ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */
-
- splx(s); /* restore */
-
- return (1);
-} /* end adb_intr_IIsi */
-
-
-/*****************************************************************************
- * if the device is currently busy, and there is no data waiting to go out, then
- * the data is "queued" in the outgoing buffer. If we are already waiting, then
- * we return.
- * in: if (in == 0) then the command string is built from command and buffer
- * if (in != 0) then in is used as the command string
- * buffer: additional data to be sent (used only if in == 0)
- * this is also where return data is stored
- * compRout: the completion routine that is called when then return value
- * is received (if a return value is expected)
- * data: a data pointer that can be used by the completion routine
- * command: an ADB command to be sent (used only if in == 0)
- *
- */
-int
-send_adb_IIsi(u_char *in, u_char *buffer, void *compRout, void *data, int
- command)
-{
- int s, len;
-
- if (adbActionState == ADB_ACTION_NOTREADY)
- return 1;
-
- /* Don't interrupt while we are messing with the ADB */
- s = splhigh();
-
- if ((adbActionState == ADB_ACTION_IDLE) && /* ADB available? */
- (ADB_INTR_IS_OFF)) {/* and no incoming interrupt? */
-
- } else
- if (adbWriteDelay == 0) /* it's busy, but is anything waiting? */
- adbWriteDelay = 1; /* if no, then we'll "queue"
- * it up */
- else {
- splx(s);
- return 1; /* really busy! */
- }
-
- if ((long)in == (long)0) { /* need to convert? */
- /*
- * Don't need to use adb_cmd_extra here because this section
- * will be called ONLY when it is an ADB command (no RTC or
- * PRAM)
- */
- if ((command & 0x0c) == 0x08) /* copy addl data ONLY if
- * doing a listen! */
- len = buffer[0]; /* length of additional data */
- else
- len = 0;/* no additional data */
-
- adbOutputBuffer[0] = 2 + len; /* dev. type + command + addl.
- * data */
- adbOutputBuffer[1] = 0x00; /* mark as an ADB command */
- adbOutputBuffer[2] = (u_char)command; /* load command */
-
- /* copy additional output data, if any */
- memcpy(adbOutputBuffer + 3, buffer + 1, len);
- } else
- /* if data ready, just copy over */
- memcpy(adbOutputBuffer, in, in[0] + 2);
-
- adbSentChars = 0; /* nothing sent yet */
- adbBuffer = buffer; /* save buffer to know where to save result */
- adbCompRout = compRout; /* save completion routine pointer */
- adbCompData = data; /* save completion routine data pointer */
- adbWaitingCmd = adbOutputBuffer[2]; /* save wait command */
-
- if (adbWriteDelay != 1) { /* start command now? */
- adbActionState = ADB_ACTION_OUT; /* set next state */
-
- ADB_SET_STATE_ACTIVE(); /* tell ADB that we want to send */
- ADB_SET_STATE_ACKOFF(); /* make sure */
-
- ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
-
- ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* load byte for output */
-
- ADB_SET_STATE_ACKON(); /* tell ADB byte ready to shift */
- }
- adbWriteDelay = 1; /* something in the write "queue" */
-
- splx(s);
-
- if (0x0100 <= (s & 0x0700)) /* were VIA1 interrupts blocked? */
- /* poll until byte done */
- while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
- || (adbWaiting == 1))
- if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
- adb_intr_IIsi(NULL); /* go process it */
- if (adb_polling)
- adb_soft_intr();
- }
-
- return 0;
-} /* send_adb_IIsi */
-
-/*
- * adb_pass_up is called by the interrupt-time routines.
- * It takes the raw packet data that was received from the
- * device and puts it into the queue that the upper half
- * processes. It then signals for a soft ADB interrupt which
- * will eventually call the upper half routine (adb_soft_intr).
- *
- * If in->unsol is 0, then this is either the notification
- * that the packet was sent (on a LISTEN, for example), or the
- * response from the device (on a TALK). The completion routine
- * is called only if the user specified one.
- *
- * If in->unsol is 1, then this packet was unsolicited and
- * so we look up the device in the ADB device table to determine
- * what it's default service routine is.
- *
- * If in->ack_only is 1, then we really only need to call
- * the completion routine, so don't do any other stuff.
- *
- * Note that in->data contains the packet header AND data,
- * while adbInbound[]->data contains ONLY data.
- *
- * Note: Called only at interrupt time. Assumes this.
- */
-void
-adb_pass_up(struct adbCommand *in)
-{
- int start = 0, len = 0, cmd = 0;
- ADBDataBlock block;
-
- /* temp for testing */
- /*u_char *buffer = 0;*/
- /*u_char *compdata = 0;*/
- /*u_char *comprout = 0;*/
-
- if (adbInCount >= ADB_QUEUE) {
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("adb: ring buffer overflow\n");
-#endif
- return;
- }
-
- if (in->ack_only) {
- len = in->data[0];
- cmd = in->cmd;
- start = 0;
- } else {
- switch (adbHardware) {
- case ADB_HW_II:
- cmd = in->data[1];
- if (in->data[0] < 2)
- len = 0;
- else
- len = in->data[0]-1;
- start = 1;
- break;
-
- case ADB_HW_IISI:
- case ADB_HW_CUDA:
- /* If it's unsolicited, accept only ADB data for now */
- if (in->unsol)
- if (0 != in->data[2])
- return;
- cmd = in->data[4];
- if (in->data[0] < 5)
- len = 0;
- else
- len = in->data[0]-4;
- start = 4;
- break;
-
- case ADB_HW_PB:
- cmd = in->data[1];
- if (in->data[0] < 2)
- len = 0;
- else
- len = in->data[0]-1;
- start = 1;
- break;
-
- case ADB_HW_UNKNOWN:
- return;
- }
-
- /* Make sure there is a valid device entry for this device */
- if (in->unsol) {
- /* ignore unsolicited data during adbreinit */
- if (adbStarting)
- return;
- /* get device's comp. routine and data area */
- if (-1 == get_adb_info(&block, ADB_CMDADDR(cmd)))
- return;
- }
- }
-
- /*
- * If this is an unsolicited packet, we need to fill in
- * some info so adb_soft_intr can process this packet
- * properly. If it's not unsolicited, then use what
- * the caller sent us.
- */
- if (in->unsol) {
- adbInbound[adbInTail].compRout = (void *)block.dbServiceRtPtr;
- adbInbound[adbInTail].compData = (void *)block.dbDataAreaAddr;
- adbInbound[adbInTail].saveBuf = (void *)adbInbound[adbInTail].data;
- } else {
- adbInbound[adbInTail].compRout = (void *)in->compRout;
- adbInbound[adbInTail].compData = (void *)in->compData;
- adbInbound[adbInTail].saveBuf = (void *)in->saveBuf;
- }
-
-#ifdef ADB_DEBUG
- if (adb_debug && in->data[1] == 2)
- printf_intr("adb: caught error\n");
-#endif
-
- /* copy the packet data over */
- /*
- * TO DO: If the *_intr routines fed their incoming data
- * directly into an adbCommand struct, which is passed to
- * this routine, then we could eliminate this copy.
- */
- memcpy(adbInbound[adbInTail].data + 1, in->data + start + 1, len);
- adbInbound[adbInTail].data[0] = len;
- adbInbound[adbInTail].cmd = cmd;
-
- adbInCount++;
- if (++adbInTail >= ADB_QUEUE)
- adbInTail = 0;
-
- /*
- * If the debugger is running, call upper half manually.
- * Otherwise, trigger a soft interrupt to handle the rest later.
- */
- if (adb_polling)
- adb_soft_intr();
- else
- setsoftadb();
-
- return;
-}
-
-
-/*
- * Called to process the packets after they have been
- * placed in the incoming queue.
- *
- */
-void
-adb_soft_intr(void)
-{
- int s;
- int cmd = 0;
- u_char *buffer = 0;
- u_char *comprout = 0;
- u_char *compdata = 0;
-
-/*delay(2*ADB_DELAY);*/
-
- while (adbInCount) {
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("%x %x %x ",
- adbInCount, adbInHead, adbInTail);
-#endif
- /* get the data we need from the queue */
- buffer = adbInbound[adbInHead].saveBuf;
- comprout = adbInbound[adbInHead].compRout;
- compdata = adbInbound[adbInHead].compData;
- cmd = adbInbound[adbInHead].cmd;
-
- /* copy over data to data area if it's valid */
- /*
- * Note that for unsol packets we don't want to copy the
- * data anywhere, so buffer was already set to 0.
- * For ack_only buffer was set to 0, so don't copy.
- */
- if (buffer)
- memcpy(buffer, adbInbound[adbInHead].data,
- adbInbound[adbInHead].data[0] + 1);
-
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80) {
- printf_intr("%p %p %p %x ",
- buffer, comprout, compdata, (short)cmd);
- printf_intr("buf: ");
- print_single(adbInbound[adbInHead].data);
- }
-#endif
-
- /* call default completion routine if it's valid */
- if (comprout) {
- (void)((int (*)(u_char *, u_char *, int))comprout)
- (buffer, compdata, cmd);
- }
-
- s = splhigh();
- adbInCount--;
- if (++adbInHead >= ADB_QUEUE)
- adbInHead = 0;
- splx(s);
-
- }
- return;
-}
-
-
-/*
- * This is my version of the ADBOp routine. It mainly just calls the
- * hardware-specific routine.
- *
- * data : pointer to data area to be used by compRout
- * compRout : completion routine
- * buffer : for LISTEN: points to data to send - MAX 8 data bytes,
- * byte 0 = # of bytes
- * : for TALK: points to place to save return data
- * command : the adb command to send
- * result : 0 = success
- * : -1 = could not complete
- */
-int
-adb_op(Ptr buffer, Ptr compRout, Ptr data, short command)
-{
- int result;
-
- switch (adbHardware) {
- case ADB_HW_II:
- result = send_adb_II((u_char *)0, (u_char *)buffer,
- (void *)compRout, (void *)data, (int)command);
- if (result == 0)
- return 0;
- else
- return -1;
- break;
-
- case ADB_HW_IISI:
- result = send_adb_IIsi((u_char *)0, (u_char *)buffer,
- (void *)compRout, (void *)data, (int)command);
- /*
- * I wish I knew why this delay is needed. It usually needs to
- * be here when several commands are sent in close succession,
- * especially early in device probes when doing collision
- * detection. It must be some race condition. Sigh. - jpw
- */
- delay(100);
- if (result == 0)
- return 0;
- else
- return -1;
- break;
-
- case ADB_HW_PB:
- result = pm_adb_op((u_char *)buffer, (void *)compRout,
- (void *)data, (int)command);
-
- if (result == 0)
- return 0;
- else
- return -1;
- break;
-
- case ADB_HW_CUDA:
- result = send_adb_cuda((u_char *)0, (u_char *)buffer,
- (void *)compRout, (void *)data, (int)command);
- if (result == 0)
- return 0;
- else
- return -1;
- break;
-
- case ADB_HW_UNKNOWN:
- default:
- return -1;
- }
-}
-
-
-/*
- * adb_hw_setup
- * This routine sets up the possible machine specific hardware
- * config (mainly VIA settings) for the various models.
- */
-void
-adb_hw_setup(void)
-{
- volatile int i;
- u_char send_string[ADB_MAX_MSG_LENGTH];
-
- switch (adbHardware) {
- case ADB_HW_II:
- via1_register_irq(2, adb_intr_II, NULL, NULL);
-
- via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5:
- * outputs */
- via_reg(VIA1, vDirB) &= 0xf7; /* register B bit 3: input */
- via_reg(VIA1, vACR) &= ~vSR_OUT; /* make sure SR is set
- * to IN (II, IIsi) */
- adbActionState = ADB_ACTION_IDLE; /* used by all types of
- * hardware (II, IIsi) */
- adbBusState = ADB_BUS_IDLE; /* this var. used in II-series
- * code only */
- via_reg(VIA1, vIER) = 0x84; /* make sure VIA interrupts
- * are on (II, IIsi) */
- ADB_SET_STATE_IDLE_II(); /* set ADB bus state to idle */
-
- ADB_VIA_CLR_INTR(); /* clear interrupt */
- break;
-
- case ADB_HW_IISI:
- via1_register_irq(2, adb_intr_IIsi, NULL, NULL);
- via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5:
- * outputs */
- via_reg(VIA1, vDirB) &= 0xf7; /* register B bit 3: input */
- via_reg(VIA1, vACR) &= ~vSR_OUT; /* make sure SR is set
- * to IN (II, IIsi) */
- adbActionState = ADB_ACTION_IDLE; /* used by all types of
- * hardware (II, IIsi) */
- adbBusState = ADB_BUS_IDLE; /* this var. used in II-series
- * code only */
- via_reg(VIA1, vIER) = 0x84; /* make sure VIA interrupts
- * are on (II, IIsi) */
- ADB_SET_STATE_IDLE_IISI(); /* set ADB bus state to idle */
-
- /* get those pesky clock ticks we missed while booting */
- for (i = 0; i < 30; i++) {
- delay(ADB_DELAY);
- adb_hw_setup_IIsi(send_string);
-#ifdef ADB_DEBUG
- if (adb_debug) {
- printf_intr("adb: cleanup: ");
- print_single(send_string);
- }
-#endif
- delay(ADB_DELAY);
- if (ADB_INTR_IS_OFF)
- break;
- }
- break;
-
- case ADB_HW_PB:
- /*
- * XXX - really PM_VIA_CLR_INTR - should we put it in
- * pm_direct.h?
- */
- pm_hw_setup();
- break;
-
- case ADB_HW_CUDA:
- via1_register_irq(2, adb_intr_cuda, NULL, NULL);
- via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5:
- * outputs */
- via_reg(VIA1, vDirB) &= 0xf7; /* register B bit 3: input */
- via_reg(VIA1, vACR) &= ~vSR_OUT; /* make sure SR is set
- * to IN */
- via_reg(VIA1, vACR) = (via_reg(VIA1, vACR) | 0x0c) & ~0x10;
- adbActionState = ADB_ACTION_IDLE; /* used by all types of
- * hardware */
- adbBusState = ADB_BUS_IDLE; /* this var. used in II-series
- * code only */
- via_reg(VIA1, vIER) = 0x84; /* make sure VIA interrupts
- * are on */
- ADB_SET_STATE_IDLE_CUDA(); /* set ADB bus state to idle */
-
- /* sort of a device reset */
- i = ADB_SR(); /* clear interrupt */
- ADB_VIA_INTR_DISABLE(); /* no interrupts while clearing */
- ADB_SET_STATE_IDLE_CUDA(); /* reset state to idle */
- delay(ADB_DELAY);
- ADB_SET_STATE_TIP(); /* signal start of frame */
- delay(ADB_DELAY);
- ADB_TOGGLE_STATE_ACK_CUDA();
- delay(ADB_DELAY);
- ADB_CLR_STATE_TIP();
- delay(ADB_DELAY);
- ADB_SET_STATE_IDLE_CUDA(); /* back to idle state */
- i = ADB_SR(); /* clear interrupt */
- ADB_VIA_INTR_ENABLE(); /* ints ok now */
- break;
-
- case ADB_HW_UNKNOWN:
- default:
- via_reg(VIA1, vIER) = 0x04; /* turn interrupts off - TO
- * DO: turn PB ints off? */
- return;
- break;
- }
-}
-
-
-/*
- * adb_hw_setup_IIsi
- * This is sort of a "read" routine that forces the adb hardware through a read cycle
- * if there is something waiting. This helps "clean up" any commands that may have gotten
- * stuck or stopped during the boot process.
- *
- */
-void
-adb_hw_setup_IIsi(u_char *buffer)
-{
- int i;
- int dummy;
- int s;
- long my_time;
- int endofframe;
-
- delay(ADB_DELAY);
-
- i = 1; /* skip over [0] */
- s = splhigh(); /* block ALL interrupts while we are working */
- ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
- ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */
- /* this is required, especially on faster machines */
- delay(ADB_DELAY);
-
- if (ADB_INTR_IS_ON) {
- ADB_SET_STATE_ACTIVE(); /* signal start of data frame */
-
- endofframe = 0;
- while (0 == endofframe) {
- /*
- * Poll for ADB interrupt and watch for timeout.
- * If time out, keep going in hopes of not hanging
- * the ADB chip - I think
- */
- my_time = ADB_DELAY * 5;
- while ((ADB_SR_INTR_IS_OFF) && (my_time-- > 0))
- dummy = via_reg(VIA1, vBufB);
-
- buffer[i++] = ADB_SR(); /* reset interrupt flag by
- * reading vSR */
- /*
- * Perhaps put in a check here that ignores all data
- * after the first ADB_MAX_MSG_LENGTH bytes ???
- */
- if (ADB_INTR_IS_OFF) /* check for end of frame */
- endofframe = 1;
-
- ADB_SET_STATE_ACKON(); /* send ACK to ADB chip */
- delay(ADB_DELAY); /* delay */
- ADB_SET_STATE_ACKOFF(); /* send ACK to ADB chip */
- }
- ADB_SET_STATE_INACTIVE(); /* signal end of frame and
- * delay */
-
- /* probably don't need to delay this long */
- delay(ADB_DELAY);
- }
- buffer[0] = --i; /* [0] is length of message */
- ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */
- splx(s); /* restore interrupts */
-
- return;
-} /* adb_hw_setup_IIsi */
-
-
-
-/*
- * adb_reinit sets up the adb stuff
- *
- */
-void
-adb_reinit(void)
-{
- u_char send_string[ADB_MAX_MSG_LENGTH];
- ADBDataBlock data; /* temp. holder for getting device info */
- volatile int i, x;
- int s;
- int command;
- int result;
- int saveptr; /* point to next free relocation address */
- int device;
- int nonewtimes; /* times thru loop w/o any new devices */
-
- via1_register_irq(2, adb_intr, NULL, "adb");
- adb_setup_hw_type(); /* setup hardware type */
-
- /* Make sure we are not interrupted while building the table. */
- /* ints must be on for PB & IOP (at least, for now) */
- if (adbHardware != ADB_HW_PB)
- s = splhigh();
- else
- s = 0; /* XXX shut the compiler up*/
-
- ADBNumDevices = 0; /* no devices yet */
-
- /* Let intr routines know we are running reinit */
- adbStarting = 1;
-
- /*
- * Initialize the ADB table. For now, we'll always use the same table
- * that is defined at the beginning of this file - no mallocs.
- */
- for (i = 0; i < 16; i++) {
- ADBDevTable[i].devType = 0;
- ADBDevTable[i].origAddr = ADBDevTable[i].currentAddr = 0;
- }
-
- adb_hw_setup(); /* init the VIA bits and hard reset ADB */
-
- delay(1000);
-
- /* send an ADB reset first */
- (void)adb_op_sync((Ptr)0, (Ptr)0, (Ptr)0, (short)0x00);
- delay(3000);
-
- /*
- * Probe for ADB devices. Probe devices 1-15 quickly to determine
- * which device addresses are in use and which are free. For each
- * address that is in use, move the device at that address to a higher
- * free address. Continue doing this at that address until no device
- * responds at that address. Then move the last device that was moved
- * back to the original address. Do this for the remaining addresses
- * that we determined were in use.
- *
- * When finished, do this entire process over again with the updated
- * list of in use addresses. Do this until no new devices have been
- * found in 20 passes though the in use address list. (This probably
- * seems long and complicated, but it's the best way to detect multiple
- * devices at the same address - sometimes it takes a couple of tries
- * before the collision is detected.)
- */
-
- /* initial scan through the devices */
- for (i = 1; i < 16; i++) {
- command = ADBTALK(i, 3);
- result = adb_op_sync((Ptr)send_string, (Ptr)0,
- (Ptr)0, (short)command);
-
- if (result == 0 && send_string[0] != 0) {
- /* found a device */
- ++ADBNumDevices;
- KASSERT(ADBNumDevices < 16);
- ADBDevTable[ADBNumDevices].devType =
- (int)(send_string[2]);
- ADBDevTable[ADBNumDevices].origAddr = i;
- ADBDevTable[ADBNumDevices].currentAddr = i;
- ADBDevTable[ADBNumDevices].DataAreaAddr =
- (long)0;
- ADBDevTable[ADBNumDevices].ServiceRtPtr = (void *)0;
- pm_check_adb_devices(i); /* tell pm driver device
- * is here */
- }
- }
-
- /* find highest unused address */
- for (saveptr = 15; saveptr > 0; saveptr--)
- if (-1 == get_adb_info(&data, saveptr))
- break;
-
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80) {
- printf_intr("first free is: 0x%02x\n", saveptr);
- printf_intr("devices: %i\n", ADBNumDevices);
- }
-#endif
-
- nonewtimes = 0; /* no loops w/o new devices */
- while (saveptr > 0 && nonewtimes++ < 11) {
- for (i = 1;saveptr > 0 && i <= ADBNumDevices; i++) {
- device = ADBDevTable[i].currentAddr;
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("moving device 0x%02x to 0x%02x "
- "(index 0x%02x) ", device, saveptr, i);
-#endif
-
- /* send TALK R3 to address */
- command = ADBTALK(device, 3);
- (void)adb_op_sync((Ptr)send_string, (Ptr)0,
- (Ptr)0, (short)command);
-
- /* move device to higher address */
- command = ADBLISTEN(device, 3);
- send_string[0] = 2;
- send_string[1] = (u_char)(saveptr | 0x60);
- send_string[2] = 0xfe;
- (void)adb_op_sync((Ptr)send_string, (Ptr)0,
- (Ptr)0, (short)command);
- delay(1000);
-
- /* send TALK R3 - anthing at new address? */
- command = ADBTALK(saveptr, 3);
- send_string[0] = 0;
- result = adb_op_sync((Ptr)send_string, (Ptr)0,
- (Ptr)0, (short)command);
- delay(1000);
-
- if (result != 0 || send_string[0] == 0) {
- /*
- * maybe there's a communication breakdown;
- * just in case, move it back from whence it
- * came, and we'll try again later
- */
- command = ADBLISTEN(saveptr, 3);
- send_string[0] = 2;
- send_string[1] = (u_char)(device | 0x60);
- send_string[2] = 0x00;
- (void)adb_op_sync((Ptr)send_string, (Ptr)0,
- (Ptr)0, (short)command);
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("failed, continuing\n");
-#endif
- delay(1000);
- continue;
- }
-
- /* send TALK R3 - anything at old address? */
- command = ADBTALK(device, 3);
- send_string[0] = 0;
- result = adb_op_sync((Ptr)send_string, (Ptr)0,
- (Ptr)0, (short)command);
- if (result == 0 && send_string[0] != 0) {
- /* new device found */
- /* update data for previously moved device */
- ADBDevTable[i].currentAddr = saveptr;
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("old device at index %i\n",i);
-#endif
- /* add new device in table */
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("new device found\n");
-#endif
- if (saveptr > ADBNumDevices) {
- ++ADBNumDevices;
- KASSERT(ADBNumDevices < 16);
- }
- ADBDevTable[ADBNumDevices].devType =
- (int)(send_string[2]);
- ADBDevTable[ADBNumDevices].origAddr = device;
- ADBDevTable[ADBNumDevices].currentAddr = device;
- /* These will be set correctly in adbsys.c */
- /* Until then, unsol. data will be ignored. */
- ADBDevTable[ADBNumDevices].DataAreaAddr =
- (long)0;
- ADBDevTable[ADBNumDevices].ServiceRtPtr =
- (void *)0;
- /* find next unused address */
- for (x = saveptr; x > 0; x--) {
- if (-1 == get_adb_info(&data, x)) {
- saveptr = x;
- break;
- }
- }
- if (x == 0)
- saveptr = 0;
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("new free is 0x%02x\n",
- saveptr);
-#endif
- nonewtimes = 0;
- /* tell pm driver device is here */
- pm_check_adb_devices(device);
- } else {
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("moving back...\n");
-#endif
- /* move old device back */
- command = ADBLISTEN(saveptr, 3);
- send_string[0] = 2;
- send_string[1] = (u_char)(device | 0x60);
- send_string[2] = 0xfe;
- (void)adb_op_sync((Ptr)send_string, (Ptr)0,
- (Ptr)0, (short)command);
- delay(1000);
- }
- }
- }
-
-#ifdef ADB_DEBUG
- if (adb_debug) {
- for (i = 1; i <= ADBNumDevices; i++) {
- x = get_ind_adb_info(&data, i);
- if (x != -1)
- printf_intr("index 0x%x, addr 0x%x, type 0x%hx\n",
- i, x, data.devType);
- }
- }
-#endif
-
- /* enable the programmer's switch, if we have one */
- adb_prog_switch_enable();
-
-#ifdef ADB_DEBUG
- if (adb_debug) {
- if (0 == ADBNumDevices) /* tell user if no devices found */
- printf_intr("adb: no devices found\n");
- }
-#endif
-
- adbStarting = 0; /* not starting anymore */
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("adb: ADBReInit complete\n");
-#endif
-
- if (adbHardware == ADB_HW_CUDA) {
- timeout_set(&adb_cuda_timeout, (void *)adb_cuda_tickle, NULL);
- timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS);
- }
-
- /* ints must be on for PB & IOP (at least, for now) */
- if (adbHardware != ADB_HW_PB)
- splx(s);
-
- return;
-}
-
-
-/*
- * adb_cmd_result
- *
- * This routine lets the caller know whether the specified adb command string
- * should expect a returned result, such as a TALK command.
- *
- * returns: 0 if a result should be expected
- * 1 if a result should NOT be expected
- */
-int
-adb_cmd_result(u_char *in)
-{
- switch (adbHardware) {
- case ADB_HW_II:
- /* was it an ADB talk command? */
- if ((in[1] & 0x0c) == 0x0c)
- return 0;
- return 1;
-
- case ADB_HW_IISI:
- case ADB_HW_CUDA:
- /* was it an ADB talk command? */
- if ((in[1] == 0x00) && ((in[2] & 0x0c) == 0x0c))
- return 0;
- /* was it an RTC/PRAM read date/time? */
- if ((in[1] == 0x01) && (in[2] == 0x03))
- return 0;
- return 1;
-
- case ADB_HW_PB:
- return 1;
-
- case ADB_HW_UNKNOWN:
- default:
- return 1;
- }
-}
-
-
-/*
- * adb_cmd_extra
- *
- * This routine lets the caller know whether the specified adb command string
- * may have extra data appended to the end of it, such as a LISTEN command.
- *
- * returns: 0 if extra data is allowed
- * 1 if extra data is NOT allowed
- */
-int
-adb_cmd_extra(u_char *in)
-{
- switch (adbHardware) {
- case ADB_HW_II:
- if ((in[1] & 0x0c) == 0x08) /* was it a listen command? */
- return 0;
- return 1;
-
- case ADB_HW_IISI:
- case ADB_HW_CUDA:
- /*
- * TO DO: support needs to be added to recognize RTC and PRAM
- * commands
- */
- if ((in[2] & 0x0c) == 0x08) /* was it a listen command? */
- return 0;
- /* add others later */
- return 1;
-
- case ADB_HW_PB:
- return 1;
-
- case ADB_HW_UNKNOWN:
- default:
- return 1;
- }
-}
-
-
-void
-adb_setup_hw_type(void)
-{
- long response;
-
- response = mac68k_machine.machineid;
-
- /*
- * Determine what type of ADB hardware we are running on.
- */
- switch (response) {
- case MACH_MACC610: /* Centris 610 */
- case MACH_MACC650: /* Centris 650 */
- case MACH_MACII: /* II */
- case MACH_MACIICI: /* IIci */
- case MACH_MACIICX: /* IIcx */
- case MACH_MACIIX: /* IIx */
- case MACH_MACQ610: /* Quadra 610 */
- case MACH_MACQ650: /* Quadra 650 */
- case MACH_MACQ700: /* Quadra 700 */
- case MACH_MACQ800: /* Quadra 800 */
- case MACH_MACSE30: /* SE/30 */
- adbHardware = ADB_HW_II;
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("adb: using II series hardware support\n");
-#endif
- break;
-
- case MACH_MACCLASSICII: /* Classic II */
- case MACH_MACLCII: /* LC II, Performa 400/405/430 */
- case MACH_MACLCIII: /* LC III, Performa 450 */
- case MACH_MACIISI: /* IIsi */
- case MACH_MACIIVI: /* IIvi */
- case MACH_MACIIVX: /* IIvx */
- case MACH_MACP460: /* Performa 460/465/467 */
- case MACH_MACP600: /* Performa 600 */
- adbHardware = ADB_HW_IISI;
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("adb: using IIsi series hardware support\n");
-#endif
- break;
-
- case MACH_MACPB140: /* PowerBook 140 */
- case MACH_MACPB145: /* PowerBook 145 */
- case MACH_MACPB160: /* PowerBook 160 */
- case MACH_MACPB165: /* PowerBook 165 */
- case MACH_MACPB165C: /* PowerBook 165c */
- case MACH_MACPB170: /* PowerBook 170 */
- case MACH_MACPB180: /* PowerBook 180 */
- case MACH_MACPB180C: /* PowerBook 180c */
- adbHardware = ADB_HW_PB;
- pm_setup_adb();
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("adb: using PowerBook 100-series hardware support\n");
-#endif
- break;
-
- case MACH_MACPB150: /* PowerBook 150 */
- case MACH_MACPB210: /* PowerBook Duo 210 */
- case MACH_MACPB230: /* PowerBook Duo 230 */
- case MACH_MACPB250: /* PowerBook Duo 250 */
- case MACH_MACPB270: /* PowerBook Duo 270 */
- case MACH_MACPB280: /* PowerBook Duo 280 */
- case MACH_MACPB280C: /* PowerBook Duo 280c */
- case MACH_MACPB500: /* PowerBook 500 series */
- case MACH_MACPB190: /* PowerBook 190 */
- case MACH_MACPB190CS: /* PowerBook 190cs */
- adbHardware = ADB_HW_PB;
- pm_setup_adb();
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("adb: using PowerBook Duo-series and PowerBook 500-series hardware support\n");
-#endif
- break;
-
- case MACH_MACC660AV: /* Centris 660AV */
- case MACH_MACCCLASSIC: /* Color Classic */
- case MACH_MACCCLASSICII: /* Color Classic II */
- case MACH_MACLC475: /* LC 475, Performa 475/476 */
- case MACH_MACLC475_33: /* Clock-chipped 47x */
- case MACH_MACLC520: /* LC 520 */
- case MACH_MACLC575: /* LC 575, Performa 575/577/578 */
- case MACH_MACP550: /* LC 550, Performa 550 */
- case MACH_MACTV: /* Macintosh TV */
- case MACH_MACP580: /* Performa 580/588 */
- case MACH_MACQ605: /* Quadra 605 */
- case MACH_MACQ605_33: /* Clock-chipped Quadra 605 */
- case MACH_MACQ630: /* LC 630, Performa 630, Quadra 630 */
- case MACH_MACQ840AV: /* Quadra 840AV */
- adbHardware = ADB_HW_CUDA;
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("adb: using Cuda series hardware support\n");
-#endif
- break;
-
- default:
- adbHardware = ADB_HW_UNKNOWN;
-#ifdef ADB_DEBUG
- if (adb_debug) {
- printf_intr("adb: hardware type unknown for this machine\n");
- printf_intr("adb: ADB support is disabled\n");
- }
-#endif
- break;
- }
-
- /*
- * Determine whether this machine has ADB based soft power.
- */
- switch (response) {
- case MACH_MACCCLASSIC: /* Color Classic */
- case MACH_MACCCLASSICII: /* Color Classic II */
- case MACH_MACIISI: /* IIsi */
- case MACH_MACIIVI: /* IIvi */
- case MACH_MACIIVX: /* IIvx */
- case MACH_MACLC520: /* LC 520 */
- case MACH_MACLC575: /* LC 575, Performa 575/577/578 */
- case MACH_MACP550: /* LC 550, Performa 550 */
- case MACH_MACTV: /* Macintosh TV */
- case MACH_MACP580: /* Performa 580/588 */
- case MACH_MACP600: /* Performa 600 */
- case MACH_MACQ630: /* LC 630, Performa 630, Quadra 630 */
- case MACH_MACQ840AV: /* Quadra 840AV */
- adbSoftPower = 1;
- break;
- }
-}
-
-int
-count_adbs(void)
-{
- int i;
- int found;
-
- found = 0;
-
- for (i = 1; i < 16; i++)
- if (0 != ADBDevTable[i].currentAddr)
- found++;
-
- return found;
-}
-
-int
-get_ind_adb_info(ADBDataBlock *info, int index)
-{
- if ((index < 1) || (index > 15)) /* check range 1-15 */
- return (-1);
-
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("index 0x%x devType is: 0x%x\n", index,
- ADBDevTable[index].devType);
-#endif
- if (0 == ADBDevTable[index].devType) /* make sure it's a valid entry */
- return (-1);
-
- info->devType = (unsigned char)(ADBDevTable[index].devType);
- info->origADBAddr = (unsigned char)(ADBDevTable[index].origAddr);
- info->dbServiceRtPtr = (Ptr)ADBDevTable[index].ServiceRtPtr;
- info->dbDataAreaAddr = (Ptr)ADBDevTable[index].DataAreaAddr;
-
- return (ADBDevTable[index].currentAddr);
-}
-
-int
-get_adb_info(ADBDataBlock *info, int adbAddr)
-{
- int i;
-
- if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */
- return (-1);
-
- for (i = 1; i < 15; i++)
- if (ADBDevTable[i].currentAddr == adbAddr) {
- info->devType = (unsigned char)(ADBDevTable[i].devType);
- info->origADBAddr = (unsigned char)(ADBDevTable[i].origAddr);
- info->dbServiceRtPtr = (Ptr)ADBDevTable[i].ServiceRtPtr;
- info->dbDataAreaAddr = ADBDevTable[i].DataAreaAddr;
- return 0; /* found */
- }
-
- return (-1); /* not found */
-}
-
-int
-set_adb_info(ADBSetInfoBlock *info, int adbAddr)
-{
- int i;
-
- if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */
- return (-1);
-
- for (i = 1; i < 15; i++)
- if (ADBDevTable[i].currentAddr == adbAddr) {
- ADBDevTable[i].ServiceRtPtr =
- (void *)(info->siServiceRtPtr);
- ADBDevTable[i].DataAreaAddr = info->siDataAreaAddr;
- return 0; /* found */
- }
-
- return (-1); /* not found */
-
-}
-
-/* caller should really use machine-independant version: getPramTime */
-/* this version does pseudo-adb access only */
-int
-adb_read_date_time(unsigned long *time)
-{
- u_char output[ADB_MAX_MSG_LENGTH];
- int result;
- volatile int flag = 0;
-
- switch (adbHardware) {
- case ADB_HW_II:
- return -1;
-
- case ADB_HW_IISI:
- output[0] = 0x02; /* 2 byte message */
- output[1] = 0x01; /* to pram/rtc device */
- output[2] = 0x03; /* read date/time */
- result = send_adb_IIsi((u_char *)output, (u_char *)output,
- (void *)adb_op_comprout, (void *)&flag, (int)0);
- if (result != 0) /* exit if not sent */
- return -1;
-
- while (0 == flag) /* wait for result */
- ;
-
- *time = (long)(*(long *)(output + 1));
- return 0;
-
- case ADB_HW_PB:
- return -1;
-
- case ADB_HW_CUDA:
- output[0] = 0x02; /* 2 byte message */
- output[1] = 0x01; /* to pram/rtc device */
- output[2] = 0x03; /* read date/time */
- result = send_adb_cuda((u_char *)output, (u_char *)output,
- (void *)adb_op_comprout, (void *)&flag, (int)0);
- if (result != 0) /* exit if not sent */
- return -1;
-
- while (0 == flag) /* wait for result */
- ;
-
- *time = (long)(*(long *)(output + 1));
- return 0;
-
- case ADB_HW_UNKNOWN:
- default:
- return -1;
- }
-}
-
-/* caller should really use machine-independant version: setPramTime */
-/* this version does pseudo-adb access only */
-int
-adb_set_date_time(unsigned long time)
-{
- u_char output[ADB_MAX_MSG_LENGTH];
- int result;
- volatile int flag = 0;
-
- switch (adbHardware) {
- case ADB_HW_II:
- return -1;
-
- case ADB_HW_IISI:
- output[0] = 0x06; /* 6 byte message */
- output[1] = 0x01; /* to pram/rtc device */
- output[2] = 0x09; /* set date/time */
- output[3] = (u_char)(time >> 24);
- output[4] = (u_char)(time >> 16);
- output[5] = (u_char)(time >> 8);
- output[6] = (u_char)(time);
- result = send_adb_IIsi((u_char *)output, (u_char *)0,
- (void *)adb_op_comprout, (void *)&flag, (int)0);
- if (result != 0) /* exit if not sent */
- return -1;
-
- while (0 == flag) /* wait for send to finish */
- ;
-
- return 0;
-
- case ADB_HW_PB:
- return -1;
-
- case ADB_HW_CUDA:
- output[0] = 0x06; /* 6 byte message */
- output[1] = 0x01; /* to pram/rtc device */
- output[2] = 0x09; /* set date/time */
- output[3] = (u_char)(time >> 24);
- output[4] = (u_char)(time >> 16);
- output[5] = (u_char)(time >> 8);
- output[6] = (u_char)(time);
- result = send_adb_cuda((u_char *)output, (u_char *)0,
- (void *)adb_op_comprout, (void *)&flag, (int)0);
- if (result != 0) /* exit if not sent */
- return -1;
-
- while (0 == flag) /* wait for send to finish */
- ;
-
- return 0;
-
- case ADB_HW_UNKNOWN:
- default:
- return -1;
- }
-}
-
-
-int
-adb_poweroff(void)
-{
- u_char output[ADB_MAX_MSG_LENGTH];
- int result;
-
- if (!adbSoftPower)
- return -1;
-
- adb_polling = 1;
-
- switch (adbHardware) {
- case ADB_HW_IISI:
- output[0] = 0x02; /* 2 byte message */
- output[1] = 0x01; /* to pram/rtc/soft-power device */
- output[2] = 0x0a; /* set date/time */
- result = send_adb_IIsi((u_char *)output, (u_char *)0,
- (void *)0, (void *)0, (int)0);
- if (result != 0) /* exit if not sent */
- return -1;
-
- for (;;); /* wait for power off */
-
- return 0;
-
- case ADB_HW_PB:
- return -1;
-
- case ADB_HW_CUDA:
- output[0] = 0x02; /* 2 byte message */
- output[1] = 0x01; /* to pram/rtc/soft-power device */
- output[2] = 0x0a; /* set date/time */
- result = send_adb_cuda((u_char *)output, (u_char *)0,
- (void *)0, (void *)0, (int)0);
- if (result != 0) /* exit if not sent */
- return -1;
-
- for (;;); /* wait for power off */
-
- return 0;
-
- case ADB_HW_II: /* II models don't do ADB soft power */
- case ADB_HW_UNKNOWN:
- default:
- return -1;
- }
-}
-
-int
-adb_prog_switch_enable(void)
-{
- u_char output[ADB_MAX_MSG_LENGTH];
- int result;
- volatile int flag = 0;
-
- switch (adbHardware) {
- case ADB_HW_IISI:
- output[0] = 0x03; /* 3 byte message */
- output[1] = 0x01; /* to pram/rtc/soft-power device */
- output[2] = 0x1c; /* prog. switch control */
- output[3] = 0x01; /* enable */
- result = send_adb_IIsi((u_char *)output, (u_char *)0,
- (void *)adb_op_comprout, (void *)&flag, (int)0);
- if (result != 0) /* exit if not sent */
- return -1;
-
- while (0 == flag) /* wait for send to finish */
- ;
-
- return 0;
-
- case ADB_HW_PB:
- return -1;
-
- case ADB_HW_II: /* II models don't do prog. switch */
- case ADB_HW_CUDA: /* cuda doesn't do prog. switch TO DO: verify this */
- case ADB_HW_UNKNOWN:
- default:
- return -1;
- }
-}
-
-int
-adb_prog_switch_disable(void)
-{
- u_char output[ADB_MAX_MSG_LENGTH];
- int result;
- volatile int flag = 0;
-
- switch (adbHardware) {
- case ADB_HW_IISI:
- output[0] = 0x03; /* 3 byte message */
- output[1] = 0x01; /* to pram/rtc/soft-power device */
- output[2] = 0x1c; /* prog. switch control */
- output[3] = 0x01; /* disable */
- result = send_adb_IIsi((u_char *)output, (u_char *)0,
- (void *)adb_op_comprout, (void *)&flag, (int)0);
- if (result != 0) /* exit if not sent */
- return -1;
-
- while (0 == flag) /* wait for send to finish */
- ;
-
- return 0;
-
- case ADB_HW_PB:
- return -1;
-
- case ADB_HW_II: /* II models don't do prog. switch */
- case ADB_HW_CUDA: /* cuda doesn't do prog. switch */
- case ADB_HW_UNKNOWN:
- default:
- return -1;
- }
-}
-
-int
-CountADBs(void)
-{
- return (count_adbs());
-}
-
-void
-ADBReInit(void)
-{
- adb_reinit();
-}
-
-int
-GetIndADB(ADBDataBlock *info, int index)
-{
- return (get_ind_adb_info(info, index));
-}
-
-int
-GetADBInfo(ADBDataBlock *info, int adbAddr)
-{
- return (get_adb_info(info, adbAddr));
-}
-
-int
-SetADBInfo(ADBSetInfoBlock *info, int adbAddr)
-{
- return (set_adb_info(info, adbAddr));
-}
-
-int
-ADBOp(Ptr buffer, Ptr compRout, Ptr data, short commandNum)
-{
- return (adb_op(buffer, compRout, data, commandNum));
-}
diff --git a/sys/arch/mac68k/dev/adbvar.h b/sys/arch/mac68k/dev/adbvar.h
index 60a681be10a..fb41204d969 100644
--- a/sys/arch/mac68k/dev/adbvar.h
+++ b/sys/arch/mac68k/dev/adbvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: adbvar.h,v 1.11 2006/01/13 19:36:43 miod Exp $ */
+/* $OpenBSD: adbvar.h,v 1.12 2006/01/18 23:21:16 miod Exp $ */
/* $NetBSD: adbvar.h,v 1.22 2005/01/15 16:00:59 chs Exp $ */
/*
@@ -31,34 +31,7 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <machine/adbsys.h>
-
-/*
- * Arguments used to attach a device to the Apple Desktop Bus
- */
-struct adb_attach_args {
- int origaddr;
- int adbaddr;
- int handler_id;
-};
-
-extern int adb_polling;
-
-#ifdef DEBUG
-#ifndef ADB_DEBUG
-#define ADB_DEBUG
-#endif
-#endif
-
-#ifdef ADB_DEBUG
-extern int adb_debug;
-#endif
-
-typedef caddr_t Ptr;
-
-/* adb.c */
-int adb_op_sync(Ptr, Ptr, Ptr, short);
-void adb_op_comprout(caddr_t, caddr_t, int);
+extern int adbHardware;
/* types of adb hardware that we support */
#define ADB_HW_UNKNOWN 0x0 /* don't know */
@@ -68,31 +41,6 @@ void adb_op_comprout(caddr_t, caddr_t, int);
#define ADB_HW_CUDA 0x4 /* Machines with a Cuda chip */
#define MAX_ADB_HW 4 /* Number of ADB hardware types */
-#define ADB_CMDADDR(cmd) ((u_int8_t)(cmd & 0xf0) >> 4)
-#define ADBFLUSH(dev) ((((u_int8_t)dev & 0x0f) << 4) | 0x01)
-#define ADBLISTEN(dev, reg) ((((u_int8_t)dev & 0x0f) << 4) | 0x08 | reg)
-#define ADBTALK(dev, reg) ((((u_int8_t)dev & 0x0f) << 4) | 0x0c | reg)
-
-/* ADB Manager */
-typedef struct {
- Ptr siServiceRtPtr;
- Ptr siDataAreaAddr;
-} ADBSetInfoBlock;
-
-typedef struct {
- unsigned char devType;
- unsigned char origADBAddr;
- Ptr dbServiceRtPtr;
- Ptr dbDataAreaAddr;
-} ADBDataBlock;
-
-/* adb_direct.c */
int adb_poweroff(void);
-int CountADBs(void);
-void ADBReInit(void);
-int GetIndADB(ADBDataBlock *, int);
-int GetADBInfo(ADBDataBlock *, int);
-int SetADBInfo(ADBSetInfoBlock *, int);
-int ADBOp(Ptr, Ptr, Ptr, short);
int adb_read_date_time(unsigned long *);
int adb_set_date_time(unsigned long);
diff --git a/sys/arch/mac68k/dev/akbd.c b/sys/arch/mac68k/dev/akbd.c
deleted file mode 100644
index aa778e2fd06..00000000000
--- a/sys/arch/mac68k/dev/akbd.c
+++ /dev/null
@@ -1,550 +0,0 @@
-/* $OpenBSD: akbd.c,v 1.6 2006/01/13 19:36:43 miod Exp $ */
-/* $NetBSD: akbd.c,v 1.17 2005/01/15 16:00:59 chs Exp $ */
-
-/*
- * Copyright (C) 1998 Colin Wood
- * All rights reserved.
- *
- * 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 Colin Wood.
- * 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.
- */
-
-#include <sys/param.h>
-#include <sys/timeout.h>
-#include <sys/kernel.h>
-#include <sys/device.h>
-#include <sys/fcntl.h>
-#include <sys/poll.h>
-#include <sys/selinfo.h>
-#include <sys/proc.h>
-#include <sys/signalvar.h>
-#include <sys/systm.h>
-
-#include "wskbd.h"
-
-#include <dev/wscons/wsconsio.h>
-#include <dev/wscons/wskbdvar.h>
-#include <dev/wscons/wsksymdef.h>
-#include <dev/wscons/wsksymvar.h>
-
-#include <machine/autoconf.h>
-#include <machine/cpu.h>
-#include <machine/viareg.h>
-
-#include <mac68k/dev/adbvar.h>
-#include <mac68k/dev/akbdmap.h>
-#include <mac68k/dev/akbdvar.h>
-
-#define KEYBOARD_ARRAY
-#include <machine/keyboard.h>
-
-/*
- * Function declarations.
- */
-int akbdmatch(struct device *, void *, void *);
-void akbdattach(struct device *, struct device *, void *);
-void kbd_adbcomplete(caddr_t, caddr_t, int);
-void kbd_processevent(adb_event_t *, struct akbd_softc *);
-int akbd_is_console(void);
-
-/* Driver definition. */
-struct cfattach akbd_ca = {
- sizeof(struct akbd_softc), akbdmatch, akbdattach
-};
-struct cfdriver akbd_cd = {
- NULL, "akbd", DV_DULL
-};
-
-int akbd_enable(void *, int);
-void akbd_set_leds(void *, int);
-int akbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
-int akbd_intr(adb_event_t *, struct akbd_softc *);
-void akbd_rawrepeat(void *v);
-
-
-struct wskbd_accessops akbd_accessops = {
- akbd_enable,
- akbd_set_leds,
- akbd_ioctl,
-};
-
-struct wskbd_mapdata akbd_keymapdata = {
- akbd_keydesctab,
-#ifdef AKBD_LAYOUT
- AKBD_LAYOUT,
-#else
- KB_US,
-#endif
-};
-
-int
-akbdmatch(struct device *parent, void *vcf, void *aux)
-{
- struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
-
- if (aa_args->origaddr == ADBADDR_KBD)
- return 1;
- else
- return 0;
-}
-
-void
-akbdattach(struct device *parent, struct device *self, void *aux)
-{
- ADBSetInfoBlock adbinfo;
- struct akbd_softc *sc = (struct akbd_softc *)self;
- struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
- int error, kbd_done;
- short cmd;
- u_char buffer[9];
-#if NWSKBD > 0
- struct wskbddev_attach_args a;
- static int akbd_console_initted;
- int wskbd_eligible;
-
- wskbd_eligible = 1;
-#endif
-
- sc->origaddr = aa_args->origaddr;
- sc->adbaddr = aa_args->adbaddr;
- sc->handler_id = aa_args->handler_id;
-
- sc->sc_leds = (u_int8_t)0x00; /* initially off */
-
- adbinfo.siServiceRtPtr = (Ptr)kbd_adbcomplete;
- adbinfo.siDataAreaAddr = (caddr_t)sc;
-
- printf(": ");
- switch (sc->handler_id) {
- case ADB_STDKBD:
- printf("standard keyboard\n");
- break;
- case ADB_ISOKBD:
- printf("standard keyboard (ISO layout)\n");
- break;
- case ADB_EXTKBD:
- cmd = ADBTALK(sc->adbaddr, 1);
- kbd_done =
- (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0);
-
- /* Ignore Logitech MouseMan/Trackman pseudo keyboard */
- if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x20) {
- printf("Mouseman (non-EMP) pseudo keyboard\n");
- adbinfo.siServiceRtPtr = (Ptr)0;
- adbinfo.siDataAreaAddr = (Ptr)0;
-#if NWSKBD > 0
- wskbd_eligible = 0;
-#endif /* NWSKBD > 0 */
- } else if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x21) {
- printf("Trackman (non-EMP) pseudo keyboard\n");
- adbinfo.siServiceRtPtr = (Ptr)0;
- adbinfo.siDataAreaAddr = (Ptr)0;
-#if NWSKBD > 0
- wskbd_eligible = 0;
-#endif /* NWSKBD > 0 */
- } else {
- printf("extended keyboard\n");
-#ifdef notyet
- blinkleds(sc);
-#endif
- }
- break;
- case ADB_EXTISOKBD:
- printf("extended keyboard (ISO layout)\n");
-#ifdef notyet
- blinkleds(sc);
-#endif
- break;
- case ADB_KBDII:
- printf("keyboard II\n");
- break;
- case ADB_ISOKBDII:
- printf("keyboard II (ISO layout)\n");
- break;
- case ADB_PBKBD:
- printf("PowerBook keyboard\n");
- break;
- case ADB_PBISOKBD:
- printf("PowerBook keyboard (ISO layout)\n");
- break;
- case ADB_ADJKPD:
- printf("adjustable keypad\n");
-#if NWSKBD > 0
- wskbd_eligible = 0;
-#endif /* NWSKBD > 0 */
- break;
- case ADB_ADJKBD:
- printf("adjustable keyboard\n");
- break;
- case ADB_ADJISOKBD:
- printf("adjustable keyboard (ISO layout)\n");
- break;
- case ADB_ADJJAPKBD:
- printf("adjustable keyboard (Japanese layout)\n");
- break;
- case ADB_PBEXTISOKBD:
- printf("PowerBook extended keyboard (ISO layout)\n");
- break;
- case ADB_PBEXTJAPKBD:
- printf("PowerBook extended keyboard (Japanese layout)\n");
- break;
- case ADB_JPKBDII:
- printf("keyboard II (Japanese layout)\n");
- break;
- case ADB_PBEXTKBD:
- printf("PowerBook extended keyboard\n");
- break;
- case ADB_DESIGNKBD:
- printf("extended keyboard\n");
-#ifdef notyet
- blinkleds(sc);
-#endif
- break;
- case ADB_PBJPKBD:
- printf("PowerBook keyboard (Japanese layout)\n");
- break;
- case ADB_PBG3JPKBD:
- printf("PowerBook G3 keyboard (Japanese layout)\n");
- break;
- case ADB_PBG4KBD:
- printf("PowerBook G4 keyboard (Inverted T)\n");
- break;
- case ADB_IBITISOKBD:
- printf("iBook keyboard with inverted T (ISO layout)\n");
- break;
- default:
- printf("mapped device (%d)\n", sc->handler_id);
-#if NWSKBD > 0
- wskbd_eligible = 0;
-#endif /* NWSKBD > 0 */
- break;
- }
- error = SetADBInfo(&adbinfo, sc->adbaddr);
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf("akbd: returned %d from SetADBInfo\n", error);
-#endif
-
-#ifdef WSDISPLAY_COMPAT_RAWKBD
- timeout_set(&sc->sc_rawrepeat_ch, akbd_rawrepeat, sc);
-#endif
-
-#if NWSKBD > 0
- if (akbd_is_console() && wskbd_eligible)
- a.console = (++akbd_console_initted == 1);
- else
- a.console = 0;
- a.keymap = &akbd_keymapdata;
- a.accessops = &akbd_accessops;
- a.accesscookie = sc;
-
- sc->sc_wskbddev = config_found(self, &a, wskbddevprint);
-#endif
-}
-
-
-/*
- * Handle putting the keyboard data received from the ADB into
- * an ADB event record.
- */
-void
-kbd_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command)
-{
- adb_event_t event;
- struct akbd_softc *ksc;
- int adbaddr;
-#ifdef ADB_DEBUG
- int i;
-
- if (adb_debug)
- printf("adb: transaction completion\n");
-#endif
-
- adbaddr = ADB_CMDADDR(adb_command);
- ksc = (struct akbd_softc *)data_area;
-
- event.addr = adbaddr;
- event.hand_id = ksc->handler_id;
- event.def_addr = ksc->origaddr;
- event.byte_count = buffer[0];
- memcpy(event.bytes, buffer + 1, event.byte_count);
-
-#ifdef ADB_DEBUG
- if (adb_debug) {
- printf("akbd: from %d at %d (org %d) %d:", event.addr,
- event.hand_id, event.def_addr, buffer[0]);
- for (i = 1; i <= buffer[0]; i++)
- printf(" %x", buffer[i]);
- printf("\n");
- }
-#endif
-
- microtime(&event.timestamp);
-
- kbd_processevent(&event, ksc);
-}
-
-/*
- * Given a keyboard ADB event, record the keycodes and call the key
- * repeat handler, optionally passing the event through the mouse
- * button emulation handler first.
- */
-void
-kbd_processevent(adb_event_t *event, struct akbd_softc *ksc)
-{
- adb_event_t new_event;
-
- new_event = *event;
- new_event.u.k.key = event->bytes[0];
- new_event.bytes[1] = 0xff;
-#if NWSKBD > 0
- if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */
- akbd_intr(&new_event, ksc);
-#endif
- if (event->bytes[1] != 0xff) {
- new_event.u.k.key = event->bytes[1];
- new_event.bytes[0] = event->bytes[1];
- new_event.bytes[1] = 0xff;
-#if NWSKBD > 0
- if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */
- akbd_intr(&new_event, ksc);
-#endif
- }
-
-}
-
-int
-akbd_enable(void *v, int on)
-{
- return 0;
-}
-
-void
-akbd_set_leds(void *v, int on)
-{
-}
-
-int
-akbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
-{
-#ifdef WSDISPLAY_COMPAT_RAWKBD
- struct akbd_softc *sc = v;
-#endif
-
- switch (cmd) {
-
- case WSKBDIO_GTYPE:
- *(int *)data = WSKBD_TYPE_ADB;
- return 0;
- case WSKBDIO_SETLEDS:
- return 0;
- case WSKBDIO_GETLEDS:
- *(int *)data = 0;
- return 0;
-#ifdef WSDISPLAY_COMPAT_RAWKBD
- case WSKBDIO_SETMODE:
- sc->sc_rawkbd = *(int *)data == WSKBD_RAW;
- timeout_del(&sc->sc_rawrepeat_ch);
- return (0);
-#endif
- case WSKBDIO_BELL:
- case WSKBDIO_COMPLEXBELL:
-#define d ((struct wskbd_bell_data *)data)
- mac68k_ring_bell(d->pitch, d->period * hz / 1000, d->volume);
-#undef d
- return (0);
-
- default:
- return (-1);
- }
-}
-
-#ifdef WSDISPLAY_COMPAT_RAWKBD
-void
-akbd_rawrepeat(void *v)
-{
- struct akbd_softc *sc = v;
- int s;
-
- s = spltty();
- wskbd_rawinput(sc->sc_wskbddev, sc->sc_rep, sc->sc_nrep);
- splx(s);
- timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAYN / 1000);
-}
-#endif
-
-int adb_polledkey;
-int
-akbd_intr(adb_event_t *event, struct akbd_softc *sc)
-{
- int key, press, val;
- int type;
- static int shift;
-
- key = event->u.k.key;
-
- /*
- * Caps lock is weird. The key sequence generated is:
- * press: down(57) [57] (LED turns on)
- * release: up(127) [255]
- * press: up(127) [255]
- * release: up(57) [185] (LED turns off)
- */
- if (ADBK_KEYVAL(key) == ADBK_CAPSLOCK)
- shift = 0;
-
- if (key == 255) {
- if (shift == 0) {
- key = ADBK_KEYUP(ADBK_CAPSLOCK);
- shift = 1;
- } else {
- key = ADBK_KEYDOWN(ADBK_CAPSLOCK);
- shift = 0;
- }
- }
-
- press = ADBK_PRESS(key);
- val = ADBK_KEYVAL(key);
-
- type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
-
- if (adb_polling) {
- adb_polledkey = key;
-#ifdef WSDISPLAY_COMPAT_RAWKBD
- } else if (sc->sc_rawkbd) {
- char cbuf[MAXKEYS *2];
- int c, j, s;
- int npress;
-
- j = npress = 0;
-
- c = keyboard[val][3];
- if (c == 0) {
- return 0; /* XXX */
- }
- if (c & 0x80)
- cbuf[j++] = 0xe0;
- cbuf[j] = c & 0x7f;
- if (type == WSCONS_EVENT_KEY_UP) {
- cbuf[j] |= 0x80;
- } else {
- /* this only records last key pressed */
- if (c & 0x80)
- sc->sc_rep[npress++] = 0xe0;
- sc->sc_rep[npress++] = c & 0x7f;
- }
- j++;
- s = spltty();
- wskbd_rawinput(sc->sc_wskbddev, cbuf, j);
- splx(s);
- timeout_del(&sc->sc_rawrepeat_ch);
- sc->sc_nrep = npress;
- if (npress != 0)
- timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAY1/1000);
- return 0;
-#endif
- } else {
- wskbd_input(sc->sc_wskbddev, type, val);
- }
-
- return 0;
-}
-
-int
-akbd_is_console(void)
-{
- extern struct mac68k_machine_S mac68k_machine;
-
- return ((mac68k_machine.serial_console & 0x03) == 0);
-}
-
-void akbd_cnbell(void *, u_int, u_int, u_int);
-void akbd_cngetc(void *, u_int *, int *);
-void akbd_cnpollc(void *, int);
-
-struct wskbd_consops akbd_consops = {
- akbd_cngetc,
- akbd_cnpollc,
- akbd_cnbell
-};
-
-int
-akbd_cnattach(void)
-{
- extern struct wskbd_mapdata akbd_keymapdata;
-
- wskbd_cnattach(&akbd_consops, NULL, &akbd_keymapdata);
-
- return 0;
-}
-
-void
-akbd_cngetc(void *v, u_int *type, int *data)
-{
- int intbits, key, press, val;
- int s;
- extern int adb_polledkey;
- extern int adb_intr(void *);
- extern void pm_intr(void *);
-
- s = splhigh();
-
- adb_polledkey = -1;
- adb_polling = 1;
-
- while (adb_polledkey == -1) {
- intbits = via_reg(VIA1, vIFR);
-
- if (intbits & V1IF_ADBRDY) {
- adb_intr(NULL);
- via_reg(VIA1, vIFR) = V1IF_ADBRDY;
- }
- if (intbits & 0x10) {
- pm_intr(NULL);
- via_reg(VIA1, vIFR) = 0x10;
- }
- }
-
- adb_polling = 0;
- splx(s);
-
- key = adb_polledkey;
- press = ADBK_PRESS(key);
- val = ADBK_KEYVAL(key);
-
- *data = val;
- *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
-}
-
-void
-akbd_cnpollc(void *v, int on)
-{
-}
-
-void
-akbd_cnbell(void *v, u_int pitch, u_int period, u_int volume)
-{
- mac68k_ring_bell(pitch, period * hz / 1000, volume);
-}
diff --git a/sys/arch/mac68k/dev/akbd_machdep.c b/sys/arch/mac68k/dev/akbd_machdep.c
new file mode 100644
index 00000000000..2d8e588bbc0
--- /dev/null
+++ b/sys/arch/mac68k/dev/akbd_machdep.c
@@ -0,0 +1,136 @@
+/* $OpenBSD: akbd_machdep.c,v 1.1 2006/01/18 23:21:17 miod Exp $ */
+/* $NetBSD: akbd.c,v 1.17 2005/01/15 16:00:59 chs Exp $ */
+
+/*
+ * Copyright (C) 1998 Colin Wood
+ * All rights reserved.
+ *
+ * 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 Colin Wood.
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <sys/timeout.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/fcntl.h>
+#include <sys/poll.h>
+#include <sys/selinfo.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/systm.h>
+
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wskbdvar.h>
+
+#include <machine/cpu.h>
+#include <machine/viareg.h>
+
+#include <dev/adb/adb.h>
+#include <dev/adb/akbdvar.h>
+#include <dev/adb/keyboard.h>
+
+#if 0
+ case WSKBDIO_BELL:
+ case WSKBDIO_COMPLEXBELL:
+#define d ((struct wskbd_bell_data *)data)
+ mac68k_ring_bell(d->pitch, d->period * hz / 1000, d->volume);
+#undef d
+ return (0);
+
+ default:
+ return (-1);
+#endif
+
+void akbd_cnbell(void *, u_int, u_int, u_int);
+void akbd_cngetc(void *, u_int *, int *);
+void akbd_cnpollc(void *, int);
+
+struct wskbd_consops akbd_consops = {
+ akbd_cngetc,
+ akbd_cnpollc,
+ akbd_cnbell
+};
+
+int
+akbd_is_console(void)
+{
+ return ((mac68k_machine.serial_console & 0x03) == 0);
+}
+
+int
+akbd_cnattach(void)
+{
+ wskbd_cnattach(&akbd_consops, NULL, &akbd_keymapdata);
+ return 0;
+}
+
+void
+akbd_cngetc(void *v, u_int *type, int *data)
+{
+ int intbits, key, press, val;
+ int s;
+ extern int adb_intr(void *);
+ extern void pm_intr(void *);
+
+ s = splhigh();
+
+ adb_polledkey = -1;
+ adb_polling = 1;
+
+ while (adb_polledkey == -1) {
+ intbits = via_reg(VIA1, vIFR);
+
+ if (intbits & V1IF_ADBRDY) {
+ adb_intr(NULL);
+ via_reg(VIA1, vIFR) = V1IF_ADBRDY;
+ }
+ if (intbits & V1IF_ADBCLK) {
+ pm_intr(NULL);
+ via_reg(VIA1, vIFR) = 0x10;
+ }
+ }
+
+ adb_polling = 0;
+ splx(s);
+
+ key = adb_polledkey;
+ press = ADBK_PRESS(key);
+ val = ADBK_KEYVAL(key);
+
+ *data = val;
+ *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
+}
+
+void
+akbd_cnpollc(void *v, int on)
+{
+}
+
+void
+akbd_cnbell(void *v, u_int pitch, u_int period, u_int volume)
+{
+ mac68k_ring_bell(pitch, period * hz / 1000, volume);
+}
diff --git a/sys/arch/mac68k/dev/pm_direct.c b/sys/arch/mac68k/dev/pm_direct.c
index 752200cf96a..84357747750 100644
--- a/sys/arch/mac68k/dev/pm_direct.c
+++ b/sys/arch/mac68k/dev/pm_direct.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pm_direct.c,v 1.10 2006/01/13 19:36:44 miod Exp $ */
+/* $OpenBSD: pm_direct.c,v 1.11 2006/01/18 23:21:17 miod Exp $ */
/* $NetBSD: pm_direct.c,v 1.25 2005/10/28 21:54:52 christos Exp $ */
/*
@@ -46,6 +46,7 @@
#include <machine/cpu.h>
#include <machine/viareg.h>
+#include <dev/adb/adb.h>
#include <mac68k/dev/adbvar.h>
#include <mac68k/dev/pm_direct.h>
diff --git a/sys/arch/mac68k/include/adbsys.h b/sys/arch/mac68k/include/adbsys.h
deleted file mode 100644
index 8b7b71f4ab9..00000000000
--- a/sys/arch/mac68k/include/adbsys.h
+++ /dev/null
@@ -1,116 +0,0 @@
-/* $OpenBSD: adbsys.h,v 1.9 2006/01/04 20:39:05 miod Exp $ */
-/* $NetBSD: adbsys.h,v 1.13 2000/02/14 07:01:48 scottr Exp $ */
-
-/*-
- * Copyright (C) 1993, 1994 Allen K. Briggs, Chris P. Caputo,
- * Michael L. Finch, Bradley A. Grantham, and
- * Lawrence A. Kesteloot
- * All rights reserved.
- *
- * 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 Alice Group.
- * 4. The names of the Alice Group or any of its members may not be used
- * to endorse or promote products derived from this software without
- * specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``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 ALICE GROUP 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 _ADBSYS_MACHINE_
-#define _ADBSYS_MACHINE_
-
-/* an ADB event */
-typedef struct adb_event_s {
- int addr; /* device address */
- int hand_id; /* handler id */
- int def_addr; /* default address */
- int byte_count; /* number of bytes */
- unsigned char bytes[8]; /* bytes from register 0 */
- struct timeval timestamp; /* time event was acquired */
- union {
- struct adb_keydata_s {
- int key; /* ADB key code */
- } k;
- struct adb_mousedata_s {
- int dx; /* mouse delta x */
- int dy; /* mouse delta y */
- int buttons; /* buttons (down << (buttonnum)) */
- } m;
- } u; /* courtesy interpretation */
-} adb_event_t;
-
- /* Interesting default addresses */
-#define ADBADDR_SECURE 1 /* Security dongles */
-#define ADBADDR_MAP 2 /* Mapped devices (keyboards/pads) */
-#define ADBADDR_REL 3 /* Relative positioning devices
- (mice, trackballs/pads) */
-#define ADBADDR_ABS 4 /* Absolute positioning devices
- (graphics tablets) */
-#define ADBADDR_DATATX 5
-#define ADBADDR_RSRVD 6 /* Reserved by Apple */
-#define ADBADDR_MISC 7 /* Miscellaneous appliances */
-#define ADBADDR_DONGLE ADBADDR_SECURE
-#define ADBADDR_KBD ADBADDR_MAP
-#define ADBADDR_MS ADBADDR_REL
-#define ADBADDR_TABLET ADBADDR_ABS
-#define ADBADDR_MODEM ADBADDR_DATATX
-
-
- /* Interesting keyboard handler IDs */
-#define ADB_STDKBD 1
-#define ADB_EXTKBD 2
-#define ADB_ISOKBD 4
-#define ADB_EXTISOKBD 5
-#define ADB_KBDII 8
-#define ADB_ISOKBDII 9
-#define ADB_PBKBD 12
-#define ADB_PBISOKBD 13
-#define ADB_ADJKPD 14
-#define ADB_ADJKBD 16
-#define ADB_ADJISOKBD 17
-#define ADB_ADJJAPKBD 18
-#define ADB_PBEXTISOKBD 20
-#define ADB_PBEXTJAPKBD 21
-#define ADB_JPKBDII 22
-#define ADB_PBEXTKBD 24
-#define ADB_DESIGNKBD 27 /* XXX Needs to be verified XXX */
-#define ADB_PBJPKBD 30
-#define ADB_PBG4KBD 195
-#define ADB_IBITISOKBD 196
-#define ADB_PBG3JPKBD 201
-
- /* Interesting mouse handler IDs */
-#define ADBMS_100DPI 1
-#define ADBMS_200DPI 2
-#define ADBMS_MSA3 3 /* Mouse Systems A3 Mouse */
-#define ADBMS_EXTENDED 4 /* Extended mouse protocol */
-#define ADBMS_USPEED 0x2f /* MicroSpeed mouse */
-#define ADBMS_UCONTOUR 0x66 /* Contour mouse */
-#define ADBMS_TURBO 50 /* Kensington Turbo Mouse */
-
- /* Interesting tablet handler ID */
-#define ADB_ARTPAD 58 /* WACOM ArtPad II tablet */
-
- /* Interesting miscellaneous handler ID */
-#define ADB_POWERKEY 34 /* Sophisticated Circuits PowerKey */
- /* (intelligent power tap) */
-
-#endif /* _ADBSYS_MACHINE_ */
diff --git a/sys/arch/mac68k/mac68k/autoconf.c b/sys/arch/mac68k/mac68k/autoconf.c
index b37052af328..3cd0121984b 100644
--- a/sys/arch/mac68k/mac68k/autoconf.c
+++ b/sys/arch/mac68k/mac68k/autoconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: autoconf.c,v 1.24 2006/01/13 19:36:45 miod Exp $ */
+/* $OpenBSD: autoconf.c,v 1.25 2006/01/18 23:21:17 miod Exp $ */
/* $NetBSD: autoconf.c,v 1.38 1996/12/18 05:46:09 scottr Exp $ */
/*
@@ -62,7 +62,6 @@
#include <dev/cons.h>
#include <machine/autoconf.h>
-#include <machine/adbsys.h>
#include <machine/viareg.h>
#include <scsi/scsi_all.h>
@@ -92,7 +91,7 @@ static struct device fakerdrootdev = { DV_DISK, {}, NULL, 0, "rd0", NULL };
void
cpu_configure()
{
- startrtclock(); /* start before adb_init() */
+ startrtclock();
if (config_rootfound("mainbus", "mainbus") == NULL)
panic("No mainbus found!");
diff --git a/sys/arch/mac68k/mac68k/pram.c b/sys/arch/mac68k/mac68k/pram.c
index 71cc0d45e36..65cf35b6183 100644
--- a/sys/arch/mac68k/mac68k/pram.c
+++ b/sys/arch/mac68k/mac68k/pram.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pram.c,v 1.10 2006/01/13 21:02:38 miod Exp $ */
+/* $OpenBSD: pram.c,v 1.11 2006/01/18 23:21:17 miod Exp $ */
/* $NetBSD: pram.c,v 1.11 1996/10/21 05:42:29 scottr Exp $ */
/*-
@@ -40,8 +40,6 @@
#include <mac68k/mac68k/pram.h>
#include <mac68k/dev/adbvar.h>
-extern int adbHardware; /* from adb.c */
-
/*
* getPramTime
* This function can be called regrardless of the machine
diff --git a/sys/arch/mac68k/mac68k/wscons_machdep.c b/sys/arch/mac68k/mac68k/wscons_machdep.c
index 263c1bb1ff6..1d8b442f829 100644
--- a/sys/arch/mac68k/mac68k/wscons_machdep.c
+++ b/sys/arch/mac68k/mac68k/wscons_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: wscons_machdep.c,v 1.4 2006/01/10 21:19:15 miod Exp $ */
+/* $OpenBSD: wscons_machdep.c,v 1.5 2006/01/18 23:21:17 miod Exp $ */
/* $NetBSD: maccons.c,v 1.5 2005/01/15 16:00:59 chs Exp $ */
/*
@@ -45,7 +45,7 @@
#include <mac68k/dev/nubus.h>
#include <mac68k/dev/macfbvar.h>
-#include <mac68k/dev/akbdvar.h>
+#include <dev/adb/akbdvar.h>
#include "wsdisplay.h"
#include "wskbd.h"
diff --git a/sys/arch/macppc/conf/files.macppc b/sys/arch/macppc/conf/files.macppc
index b6008874578..1e4e73185e9 100644
--- a/sys/arch/macppc/conf/files.macppc
+++ b/sys/arch/macppc/conf/files.macppc
@@ -1,4 +1,4 @@
-# $OpenBSD: files.macppc,v 1.45 2006/01/03 17:23:19 xsa Exp $
+# $OpenBSD: files.macppc,v 1.46 2006/01/18 23:21:17 miod Exp $
#
# macppc-specific configuration info
@@ -156,21 +156,15 @@ file arch/macppc/dev/z8530tty.c zstty needs-flag
device adb {}
attach adb at macobio
file arch/macppc/dev/adb.c adb needs-flag
-file arch/macppc/dev/adb_direct.c adb
file arch/macppc/dev/pm_direct.c adb
+include "dev/adb/files.adb"
+file arch/macppc/dev/akbd_machdep.c akbd
+
device apm
attach apm at adb
file arch/macppc/dev/apm.c apm needs-count
-device akbd: wskbddev
-attach akbd at adb
-file arch/macppc/dev/akbd.c akbd needs-flag
-
-device ams: wsmousedev
-attach ams at adb
-file arch/macppc/dev/ams.c ams
-
device abtn
attach abtn at adb
file arch/macppc/dev/abtn.c abtn
diff --git a/sys/arch/macppc/dev/abtn.c b/sys/arch/macppc/dev/abtn.c
index 3672bfbab44..37e0c77dc70 100644
--- a/sys/arch/macppc/dev/abtn.c
+++ b/sys/arch/macppc/dev/abtn.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: abtn.c,v 1.10 2006/01/08 17:25:05 miod Exp $ */
+/* $OpenBSD: abtn.c,v 1.11 2006/01/18 23:21:17 miod Exp $ */
/* $NetBSD: abtn.c,v 1.1 1999/07/12 17:48:26 tsubai Exp $ */
/*-
@@ -37,7 +37,7 @@
#include <dev/ofw/openfirm.h>
#include <macppc/macppc/ofw_machdep.h>
-#include <macppc/dev/adbvar.h>
+#include <dev/adb/adb.h>
#define ABTN_HANDLER_ID 31
@@ -88,7 +88,7 @@ abtn_attach(struct device *parent, struct device *self, void *aux)
adbinfo.siServiceRtPtr = (Ptr)abtn_adbcomplete;
adbinfo.siDataAreaAddr = (caddr_t)sc;
- SetADBInfo(&adbinfo, sc->adbaddr);
+ set_adb_info(&adbinfo, sc->adbaddr);
}
void
diff --git a/sys/arch/macppc/dev/adb.c b/sys/arch/macppc/dev/adb.c
index d006ac09f76..a192399da4b 100644
--- a/sys/arch/macppc/dev/adb.c
+++ b/sys/arch/macppc/dev/adb.c
@@ -1,5 +1,36 @@
-/* $OpenBSD: adb.c,v 1.17 2006/01/08 17:25:05 miod Exp $ */
+/* $OpenBSD: adb.c,v 1.18 2006/01/18 23:21:17 miod Exp $ */
/* $NetBSD: adb.c,v 1.6 1999/08/16 06:28:09 tsubai Exp $ */
+/* $NetBSD: adb_direct.c,v 1.14 2000/06/08 22:10:45 tsubai Exp $ */
+
+/*
+ * Copyright (C) 1996, 1997 John P. Wittkoski
+ * All rights reserved.
+ *
+ * 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 John P. Wittkoski.
+ * 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.
+ */
/*-
* Copyright (C) 1994 Bradley A. Grantham
@@ -31,6 +62,33 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
+/*
+ * This code is rather messy, but I don't have time right now
+ * to clean it up as much as I would like.
+ * But it works, so I'm happy. :-) jpw
+ */
+
+/*
+ * TO DO:
+ * - We could reduce the time spent in the adb_intr_* routines
+ * by having them save the incoming and outgoing data directly
+ * in the adbInbound and adbOutbound queues, as it would reduce
+ * the number of times we need to copy the data around. It
+ * would also make the code more readable and easier to follow.
+ * - (Related to above) Use the header part of adbCommand to
+ * reduce the number of copies we have to do of the data.
+ * - (Related to above) Actually implement the adbOutbound queue.
+ * This is fairly easy once you switch all the intr routines
+ * over to using adbCommand structs directly.
+ * - There is a bug in the state machine of adb_intr_cuda
+ * code that causes hangs, especially on 030 machines, probably
+ * because of some timing issues. Because I have been unable to
+ * determine the exact cause of this bug, I used the timeout function
+ * to check for and recover from this condition. If anyone finds
+ * the actual cause of this bug, the calls to timeout and the
+ * adb_cuda_tickle routine can be removed.
+ */
+
#include <sys/param.h>
#include <sys/device.h>
#include <sys/fcntl.h>
@@ -38,41 +96,1510 @@
#include <sys/selinfo.h>
#include <sys/proc.h>
#include <sys/signalvar.h>
+#include <sys/timeout.h>
#include <sys/systm.h>
#include <machine/autoconf.h>
+#include <machine/cpu.h>
#include <dev/ofw/openfirm.h>
+#include <dev/adb/adb.h>
#include <macppc/dev/adbvar.h>
-#include <macppc/dev/akbdvar.h>
+#include <macppc/dev/pm_direct.h>
#include <macppc/dev/viareg.h>
#include "apm.h"
+#define printf_intr printf
+
+#ifdef DEBUG
+#ifndef ADB_DEBUG
+#define ADB_DEBUG
+#endif
+#endif
+
+int adb_polling; /* Are we polling? (Debugger mode) */
+#ifdef ADB_DEBUG
+int adb_debug; /* Output debugging messages */
+#endif /* ADB_DEBUG */
+
+/* some misc. leftovers */
+#define vPB 0x0000
+#define vPB3 0x08
+#define vPB4 0x10
+#define vPB5 0x20
+#define vSR_INT 0x04
+#define vSR_OUT 0x10
+
+/* the type of ADB action that we are currently performing */
+#define ADB_ACTION_NOTREADY 0x1 /* has not been initialized yet */
+#define ADB_ACTION_IDLE 0x2 /* the bus is currently idle */
+#define ADB_ACTION_OUT 0x3 /* sending out a command */
+#define ADB_ACTION_IN 0x4 /* receiving data */
+
/*
- * Function declarations.
+ * Shortcuts for setting or testing the VIA bit states.
+ * Not all shortcuts are used for every type of ADB hardware.
*/
-int adbmatch(struct device *, void *, void *);
-void adbattach(struct device *, struct device *, void *);
-int adbprint(void *, const char *);
+#define ADB_SET_STATE_IDLE_CUDA() via_reg_or(VIA1, vBufB, (vPB4 | vPB5))
+#define ADB_SET_STATE_TIP() via_reg_and(VIA1, vBufB, ~vPB5)
+#define ADB_CLR_STATE_TIP() via_reg_or(VIA1, vBufB, vPB5)
+#define ADB_TOGGLE_STATE_ACK_CUDA() via_reg_xor(VIA1, vBufB, vPB4)
+#define ADB_SET_STATE_ACKOFF_CUDA() via_reg_or(VIA1, vBufB, vPB4)
+#define ADB_SET_SR_INPUT() via_reg_and(VIA1, vACR, ~vSR_OUT)
+#define ADB_SET_SR_OUTPUT() via_reg_or(VIA1, vACR, vSR_OUT)
+#define ADB_SR() read_via_reg(VIA1, vSR)
+#define ADB_VIA_INTR_ENABLE() write_via_reg(VIA1, vIER, 0x84)
+#define ADB_VIA_INTR_DISABLE() write_via_reg(VIA1, vIER, 0x04)
+#define ADB_VIA_CLR_INTR() write_via_reg(VIA1, vIFR, 0x04)
+#define ADB_INTR_IS_OFF (vPB3 == (read_via_reg(VIA1, vBufB) & vPB3))
+#define ADB_INTR_IS_ON (0 == (read_via_reg(VIA1, vBufB) & vPB3))
+#define ADB_SR_INTR_IS_ON (vSR_INT == (read_via_reg(VIA1, \
+ vIFR) & vSR_INT))
/*
- * Global variables.
+ * This is the delay that is required (in uS) between certain
+ * ADB transactions. The actual timing delay for for each uS is
+ * calculated at boot time to account for differences in machine speed.
+ */
+#define ADB_DELAY 150
+
+/*
+ * Maximum ADB message length; includes space for data, result, and
+ * device code - plus a little for safety.
+ */
+#define ADB_MAX_MSG_LENGTH 16
+#define ADB_MAX_HDR_LENGTH 8
+
+#define ADB_QUEUE 32
+#define ADB_TICKLE_TICKS 4
+
+/*
+ * A structure for storing information about each ADB device.
+ */
+struct ADBDevEntry {
+ void (*ServiceRtPtr)(void);
+ void *DataAreaAddr;
+ int devType;
+ int origAddr;
+ int currentAddr;
+};
+
+/*
+ * Used to hold ADB commands that are waiting to be sent out.
+ */
+struct adbCmdHoldEntry {
+ u_char outBuf[ADB_MAX_MSG_LENGTH]; /* our message */
+ u_char *saveBuf; /* buffer to know where to save result */
+ u_char *compRout; /* completion routine pointer */
+ u_char *data; /* completion routine data pointer */
+};
+
+/*
+ * Eventually used for two separate queues, the queue between
+ * the upper and lower halves, and the outgoing packet queue.
+ * TO DO: adbCommand can replace all of adbCmdHoldEntry eventually
+ */
+struct adbCommand {
+ u_char header[ADB_MAX_HDR_LENGTH]; /* not used yet */
+ u_char data[ADB_MAX_MSG_LENGTH]; /* packet data only */
+ u_char *saveBuf; /* where to save result */
+ u_char *compRout; /* completion routine pointer */
+ u_char *compData; /* completion routine data pointer */
+ u_int cmd; /* the original command for this data */
+ u_int unsol; /* 1 if packet was unsolicited */
+ u_int ack_only; /* 1 for no special processing */
+};
+
+/*
+ * A few variables that we need and their initial values.
+ */
+int adbHardware = ADB_HW_UNKNOWN;
+int adbActionState = ADB_ACTION_NOTREADY;
+int adbWaiting = 0; /* waiting for return data from the device */
+int adbWriteDelay = 0; /* working on (or waiting to do) a write */
+int adbSoftPower = 0; /* machine supports soft power */
+
+int adbWaitingCmd = 0; /* ADB command we are waiting for */
+u_char *adbBuffer = (long)0; /* pointer to user data area */
+void *adbCompRout = (long)0; /* pointer to the completion routine */
+void *adbCompData = (long)0; /* pointer to the completion routine data */
+int adbStarting = 1; /* doing adb_reinit so do polling differently */
+
+u_char adbInputBuffer[ADB_MAX_MSG_LENGTH]; /* data input buffer */
+u_char adbOutputBuffer[ADB_MAX_MSG_LENGTH]; /* data output buffer */
+struct adbCmdHoldEntry adbOutQueue; /* our 1 entry output queue */
+
+int adbSentChars = 0; /* how many characters we have sent */
+
+struct ADBDevEntry ADBDevTable[16]; /* our ADB device table */
+int ADBNumDevices; /* num. of ADB devices found with adb_reinit */
+
+struct adbCommand adbInbound[ADB_QUEUE]; /* incoming queue */
+int adbInCount = 0; /* how many packets in in queue */
+int adbInHead = 0; /* head of in queue */
+int adbInTail = 0; /* tail of in queue */
+struct adbCommand adbOutbound[ADB_QUEUE]; /* outgoing queue - not used yet */
+int adbOutCount = 0; /* how many packets in out queue */
+int adbOutHead = 0; /* head of out queue */
+int adbOutTail = 0; /* tail of out queue */
+
+int tickle_count = 0; /* how many tickles seen for this packet? */
+int tickle_serial = 0; /* the last packet tickled */
+int adb_cuda_serial = 0; /* the current packet */
+struct timeout adb_cuda_timeout;
+struct timeout adb_softintr_timeout;
+
+volatile u_char *Via1Base;
+
+/*
+ * The following are private routines.
*/
-int adb_polling; /* Are we polling? (Debugger mode) */
#ifdef ADB_DEBUG
-int adb_debug; /* Output debugging messages */
-#endif /* ADB_DEBUG */
+void print_single(u_char *);
+#endif
+void adb_intr_cuda(void);
+void adb_soft_intr(void);
+int send_adb_cuda(u_char *, u_char *, void *, void *, int);
+void adb_cuda_tickle(void);
+void adb_pass_up(struct adbCommand *);
+void adb_op_comprout(caddr_t, caddr_t, int);
+void adb_reinit(void);
+int count_adbs(void);
+int get_ind_adb_info(ADBDataBlock *, int);
+int get_adb_info(ADBDataBlock *, int);
+int set_adb_info(ADBSetInfoBlock *, int);
+void adb_setup_hw_type(void);
+int adb_op(Ptr, Ptr, Ptr, short);
+void adb_hw_setup(void);
+int adb_cmd_result(u_char *);
+void setsoftadb(void);
+
+int adb_intr(void *arg);
+void adb_cuda_autopoll(void);
+
+#ifdef ADB_DEBUG
+/*
+ * print_single
+ * Diagnostic display routine. Displays the hex values of the
+ * specified elements of the u_char. The length of the "string"
+ * is in [0].
+ */
+void
+print_single(str)
+ u_char *str;
+{
+ int x;
+
+ if (str == 0) {
+ printf_intr("no data - null pointer\n");
+ return;
+ }
+ if (*str == 0) {
+ printf_intr("nothing returned\n");
+ return;
+ }
+ if (*str > 20) {
+ printf_intr("ADB: ACK > 20 no way!\n");
+ *str = 20;
+ }
+ printf_intr("(length=0x%x):", *str);
+ for (x = 1; x <= *str; x++)
+ printf_intr(" 0x%02x", str[x]);
+ printf_intr("\n");
+}
+#endif
+
+void
+adb_cuda_tickle(void)
+{
+ volatile int s;
+
+ if (adbActionState == ADB_ACTION_IN) {
+ if (tickle_serial == adb_cuda_serial) {
+ if (++tickle_count > 0) {
+ s = splhigh();
+ adbActionState = ADB_ACTION_IDLE;
+ adbInputBuffer[0] = 0;
+ ADB_SET_STATE_IDLE_CUDA();
+ splx(s);
+ }
+ } else {
+ tickle_serial = adb_cuda_serial;
+ tickle_count = 0;
+ }
+ } else {
+ tickle_serial = adb_cuda_serial;
+ tickle_count = 0;
+ }
+
+ timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS);
+}
+
+/*
+ * called when when an adb interrupt happens
+ *
+ * Cuda version of adb_intr
+ * TO DO: do we want to add some calls to intr_dispatch() here to
+ * grab serial interrupts?
+ */
+void
+adb_intr_cuda(void)
+{
+ volatile int i, ending;
+ volatile unsigned int s;
+ struct adbCommand packet;
+
+ s = splhigh(); /* can't be too careful - might be called */
+ /* from a routine, NOT an interrupt */
+
+ ADB_VIA_CLR_INTR(); /* clear interrupt */
+ ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */
+
+switch_start:
+ switch (adbActionState) {
+ case ADB_ACTION_IDLE:
+ /*
+ * This is an unexpected packet, so grab the first (dummy)
+ * byte, set up the proper vars, and tell the chip we are
+ * starting to receive the packet by setting the TIP bit.
+ */
+ adbInputBuffer[1] = ADB_SR();
+ adb_cuda_serial++;
+ if (ADB_INTR_IS_OFF) /* must have been a fake start */
+ break;
+
+ ADB_SET_SR_INPUT();
+ ADB_SET_STATE_TIP();
+
+ adbInputBuffer[0] = 1;
+ adbActionState = ADB_ACTION_IN;
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("idle 0x%02x ", adbInputBuffer[1]);
+#endif
+ break;
+
+ case ADB_ACTION_IN:
+ adbInputBuffer[++adbInputBuffer[0]] = ADB_SR();
+ /* intr off means this is the last byte (end of frame) */
+ if (ADB_INTR_IS_OFF)
+ ending = 1;
+ else
+ ending = 0;
+
+ if (1 == ending) { /* end of message? */
+#ifdef ADB_DEBUG
+ if (adb_debug) {
+ printf_intr("in end 0x%02x ",
+ adbInputBuffer[adbInputBuffer[0]]);
+ print_single(adbInputBuffer);
+ }
+#endif
+
+ /*
+ * Are we waiting AND does this packet match what we
+ * are waiting for AND is it coming from either the
+ * ADB or RTC/PRAM sub-device? This section _should_
+ * recognize all ADB and RTC/PRAM type commands, but
+ * there may be more... NOTE: commands are always at
+ * [4], even for RTC/PRAM commands.
+ */
+ /* set up data for adb_pass_up */
+ memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
+
+ if ((adbWaiting == 1) &&
+ (adbInputBuffer[4] == adbWaitingCmd) &&
+ ((adbInputBuffer[2] == 0x00) ||
+ (adbInputBuffer[2] == 0x01))) {
+ packet.saveBuf = adbBuffer;
+ packet.compRout = adbCompRout;
+ packet.compData = adbCompData;
+ packet.unsol = 0;
+ packet.ack_only = 0;
+ adb_pass_up(&packet);
+
+ adbWaitingCmd = 0; /* reset "waiting" vars */
+ adbWaiting = 0;
+ adbBuffer = (long)0;
+ adbCompRout = (long)0;
+ adbCompData = (long)0;
+ } else {
+ packet.unsol = 1;
+ packet.ack_only = 0;
+ adb_pass_up(&packet);
+ }
+
+
+ /* reset vars and signal the end of this frame */
+ adbActionState = ADB_ACTION_IDLE;
+ adbInputBuffer[0] = 0;
+ ADB_SET_STATE_IDLE_CUDA();
+ /*ADB_SET_SR_INPUT();*/
+
+ /*
+ * If there is something waiting to be sent out,
+ * the set everything up and send the first byte.
+ */
+ if (adbWriteDelay == 1) {
+ delay(ADB_DELAY); /* required */
+ adbSentChars = 0;
+ adbActionState = ADB_ACTION_OUT;
+ /*
+ * If the interrupt is on, we were too slow
+ * and the chip has already started to send
+ * something to us, so back out of the write
+ * and start a read cycle.
+ */
+ if (ADB_INTR_IS_ON) {
+ ADB_SET_SR_INPUT();
+ ADB_SET_STATE_IDLE_CUDA();
+ adbSentChars = 0;
+ adbActionState = ADB_ACTION_IDLE;
+ adbInputBuffer[0] = 0;
+ break;
+ }
+ /*
+ * If we got here, it's ok to start sending
+ * so load the first byte and tell the chip
+ * we want to send.
+ */
+ ADB_SET_STATE_TIP();
+ ADB_SET_SR_OUTPUT();
+ write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]);
+ }
+ } else {
+ ADB_TOGGLE_STATE_ACK_CUDA();
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("in 0x%02x ",
+ adbInputBuffer[adbInputBuffer[0]]);
+#endif
+ }
+ break;
+
+ case ADB_ACTION_OUT:
+ i = ADB_SR(); /* reset SR-intr in IFR */
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("intr out 0x%02x ", i);
+#endif
+
+ adbSentChars++;
+ if (ADB_INTR_IS_ON) { /* ADB intr low during write */
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("intr was on ");
+#endif
+ ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
+ ADB_SET_STATE_IDLE_CUDA();
+ adbSentChars = 0; /* must start all over */
+ adbActionState = ADB_ACTION_IDLE; /* new state */
+ adbInputBuffer[0] = 0;
+ adbWriteDelay = 1; /* must retry when done with
+ * read */
+ delay(ADB_DELAY);
+ goto switch_start; /* process next state right
+ * now */
+ break;
+ }
+ if (adbOutputBuffer[0] == adbSentChars) { /* check for done */
+ if (0 == adb_cmd_result(adbOutputBuffer)) { /* do we expect data
+ * back? */
+ adbWaiting = 1; /* signal waiting for return */
+ adbWaitingCmd = adbOutputBuffer[2]; /* save waiting command */
+ } else { /* no talk, so done */
+ /* set up stuff for adb_pass_up */
+ memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
+ packet.saveBuf = adbBuffer;
+ packet.compRout = adbCompRout;
+ packet.compData = adbCompData;
+ packet.cmd = adbWaitingCmd;
+ packet.unsol = 0;
+ packet.ack_only = 1;
+ adb_pass_up(&packet);
+
+ /* reset "waiting" vars, just in case */
+ adbWaitingCmd = 0;
+ adbBuffer = (long)0;
+ adbCompRout = (long)0;
+ adbCompData = (long)0;
+ }
+
+ adbWriteDelay = 0; /* done writing */
+ adbActionState = ADB_ACTION_IDLE; /* signal bus is idle */
+ ADB_SET_SR_INPUT();
+ ADB_SET_STATE_IDLE_CUDA();
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("write done ");
+#endif
+ } else {
+ write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]); /* send next byte */
+ ADB_TOGGLE_STATE_ACK_CUDA(); /* signal byte ready to
+ * shift */
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("toggle ");
+#endif
+ }
+ break;
+
+ case ADB_ACTION_NOTREADY:
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("adb: not yet initialized\n");
+#endif
+ break;
+
+ default:
+ ;
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("intr: unknown ADB state\n");
+#endif
+ }
+
+ ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */
+
+ splx(s); /* restore */
+}
+
+
+int
+send_adb_cuda(u_char * in, u_char * buffer, void *compRout, void *data, int
+ command)
+{
+ int s, len;
+
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("SEND\n");
+#endif
+
+ if (adbActionState == ADB_ACTION_NOTREADY)
+ return 1;
+
+ /* Don't interrupt while we are messing with the ADB */
+ s = splhigh();
+
+ if ((adbActionState == ADB_ACTION_IDLE) && /* ADB available? */
+ (ADB_INTR_IS_OFF)) { /* and no incoming interrupt? */
+ } else
+ if (adbWriteDelay == 0) /* it's busy, but is anything waiting? */
+ adbWriteDelay = 1; /* if no, then we'll "queue"
+ * it up */
+ else {
+ splx(s);
+ return 1; /* really busy! */
+ }
+
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("QUEUE\n");
+#endif
+ if ((long)in == (long)0) { /* need to convert? */
+ if ((command & 0x0c) == 0x08) /* copy addl data ONLY if
+ * doing a listen! */
+ len = buffer[0]; /* length of additional data */
+ else
+ len = 0;/* no additional data */
+
+ adbOutputBuffer[0] = 2 + len; /* dev. type + command + addl.
+ * data */
+ adbOutputBuffer[1] = 0x00; /* mark as an ADB command */
+ adbOutputBuffer[2] = (u_char)command; /* load command */
+
+ /* copy additional output data, if any */
+ memcpy(adbOutputBuffer + 3, buffer + 1, len);
+ } else
+ /* if data ready, just copy over */
+ memcpy(adbOutputBuffer, in, in[0] + 2);
+
+ adbSentChars = 0; /* nothing sent yet */
+ adbBuffer = buffer; /* save buffer to know where to save result */
+ adbCompRout = compRout; /* save completion routine pointer */
+ adbCompData = data; /* save completion routine data pointer */
+ adbWaitingCmd = adbOutputBuffer[2]; /* save wait command */
+
+ if (adbWriteDelay != 1) { /* start command now? */
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("out start NOW");
+#endif
+ delay(ADB_DELAY);
+ adbActionState = ADB_ACTION_OUT; /* set next state */
+ ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
+ write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]); /* load byte for output */
+ ADB_SET_STATE_ACKOFF_CUDA();
+ ADB_SET_STATE_TIP(); /* tell ADB that we want to send */
+ }
+ adbWriteDelay = 1; /* something in the write "queue" */
+
+ splx(s);
+
+ if ((s & (1 << 18)) || adb_polling) /* XXX were VIA1 interrupts blocked ? */
+ /* poll until byte done */
+ while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
+ || (adbWaiting == 1))
+ if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
+ adb_intr_cuda(); /* process it */
+ adb_soft_intr();
+ }
+
+ return 0;
+}
+
+/*
+ * Called when when an adb interrupt happens.
+ * This routine simply transfers control over to the appropriate
+ * code for the machine we are running on.
+ */
+int
+adb_intr(void *arg)
+{
+ switch (adbHardware) {
+ case ADB_HW_PMU:
+ pm_intr();
+ break;
+
+ case ADB_HW_CUDA:
+ adb_intr_cuda();
+ break;
+ }
+ return 1;
+}
+
+
+/*
+ * adb_pass_up is called by the interrupt-time routines.
+ * It takes the raw packet data that was received from the
+ * device and puts it into the queue that the upper half
+ * processes. It then signals for a soft ADB interrupt which
+ * will eventually call the upper half routine (adb_soft_intr).
+ *
+ * If in->unsol is 0, then this is either the notification
+ * that the packet was sent (on a LISTEN, for example), or the
+ * response from the device (on a TALK). The completion routine
+ * is called only if the user specified one.
+ *
+ * If in->unsol is 1, then this packet was unsolicited and
+ * so we look up the device in the ADB device table to determine
+ * what it's default service routine is.
+ *
+ * If in->ack_only is 1, then we really only need to call
+ * the completion routine, so don't do any other stuff.
+ *
+ * Note that in->data contains the packet header AND data,
+ * while adbInbound[]->data contains ONLY data.
+ *
+ * Note: Called only at interrupt time. Assumes this.
+ */
+void
+adb_pass_up(struct adbCommand *in)
+{
+ int start = 0, len = 0, cmd = 0;
+ ADBDataBlock block;
+
+ /* temp for testing */
+ /*u_char *buffer = 0;*/
+ /*u_char *compdata = 0;*/
+ /*u_char *comprout = 0;*/
+
+ if (adbInCount >= ADB_QUEUE) {
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("adb: ring buffer overflow\n");
+#endif
+ return;
+ }
+
+ if (in->ack_only) {
+ len = in->data[0];
+ cmd = in->cmd;
+ start = 0;
+ } else {
+ switch (adbHardware) {
+ case ADB_HW_CUDA:
+ /* If it's unsolicited, accept only ADB data for now */
+ if (in->unsol)
+ if (0 != in->data[2])
+ return;
+ cmd = in->data[4];
+ if (in->data[0] < 5)
+ len = 0;
+ else
+ len = in->data[0]-4;
+ start = 4;
+ break;
+
+ case ADB_HW_PMU:
+ cmd = in->data[1];
+ if (in->data[0] < 2)
+ len = 0;
+ else
+ len = in->data[0]-1;
+ start = 1;
+ break;
+
+ case ADB_HW_UNKNOWN:
+ return;
+ }
+
+ /* Make sure there is a valid device entry for this device */
+ if (in->unsol) {
+ /* ignore unsolicited data during adbreinit */
+ if (adbStarting)
+ return;
+ /* get device's comp. routine and data area */
+ if (-1 == get_adb_info(&block, ADB_CMDADDR(cmd)))
+ return;
+ }
+ }
+
+ /*
+ * If this is an unsolicited packet, we need to fill in
+ * some info so adb_soft_intr can process this packet
+ * properly. If it's not unsolicited, then use what
+ * the caller sent us.
+ */
+ if (in->unsol) {
+ adbInbound[adbInTail].compRout = (void *)block.dbServiceRtPtr;
+ adbInbound[adbInTail].compData = (void *)block.dbDataAreaAddr;
+ adbInbound[adbInTail].saveBuf = (void *)adbInbound[adbInTail].data;
+ } else {
+ adbInbound[adbInTail].compRout = (void *)in->compRout;
+ adbInbound[adbInTail].compData = (void *)in->compData;
+ adbInbound[adbInTail].saveBuf = (void *)in->saveBuf;
+ }
+
+#ifdef ADB_DEBUG
+ if (adb_debug && in->data[1] == 2)
+ printf_intr("adb: caught error\n");
+#endif
+
+ /* copy the packet data over */
+ /*
+ * TO DO: If the *_intr routines fed their incoming data
+ * directly into an adbCommand struct, which is passed to
+ * this routine, then we could eliminate this copy.
+ */
+ memcpy(adbInbound[adbInTail].data + 1, in->data + start + 1, len);
+ adbInbound[adbInTail].data[0] = len;
+ adbInbound[adbInTail].cmd = cmd;
+
+ adbInCount++;
+ if (++adbInTail >= ADB_QUEUE)
+ adbInTail = 0;
+
+ /*
+ * If the debugger is running, call upper half manually.
+ * Otherwise, trigger a soft interrupt to handle the rest later.
+ */
+ if (adb_polling)
+ adb_soft_intr();
+ else
+ setsoftadb();
+}
+
+
+/*
+ * Called to process the packets after they have been
+ * placed in the incoming queue.
+ *
+ */
+void
+adb_soft_intr(void)
+{
+ int s;
+ int cmd = 0;
+ u_char *buffer = 0;
+ u_char *comprout = 0;
+ u_char *compdata = 0;
+
+/*delay(2*ADB_DELAY);*/
+
+ while (adbInCount) {
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("%x %x %x ",
+ adbInCount, adbInHead, adbInTail);
+#endif
+ /* get the data we need from the queue */
+ buffer = adbInbound[adbInHead].saveBuf;
+ comprout = adbInbound[adbInHead].compRout;
+ compdata = adbInbound[adbInHead].compData;
+ cmd = adbInbound[adbInHead].cmd;
+
+ /* copy over data to data area if it's valid */
+ /*
+ * Note that for unsol packets we don't want to copy the
+ * data anywhere, so buffer was already set to 0.
+ * For ack_only buffer was set to 0, so don't copy.
+ */
+ if (buffer)
+ memcpy(buffer, adbInbound[adbInHead].data,
+ adbInbound[adbInHead].data[0] + 1);
+
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80) {
+ printf_intr("%p %p %p %x ",
+ buffer, comprout, compdata, (short)cmd);
+ printf_intr("buf: ");
+ print_single(adbInbound[adbInHead].data);
+ }
+#endif
+ /*
+ * Remove the packet from the queue before calling
+ * the completion routine, so that the completion
+ * routine can reentrantly process the queue. For
+ * example, this happens when polling is turned on
+ * by entering the debuger by keystroke.
+ */
+ s = splhigh();
+ adbInCount--;
+ if (++adbInHead >= ADB_QUEUE)
+ adbInHead = 0;
+ splx(s);
+
+ /* call default completion routine if it's valid */
+ if (comprout) {
+ ((int (*)(u_char *, u_char *, int)) comprout)
+ (buffer, compdata, cmd);
+ }
+
+ }
+}
+
+
+/*
+ * This is my version of the ADBOp routine. It mainly just calls the
+ * hardware-specific routine.
+ *
+ * data : pointer to data area to be used by compRout
+ * compRout : completion routine
+ * buffer : for LISTEN: points to data to send - MAX 8 data bytes,
+ * byte 0 = # of bytes
+ * : for TALK: points to place to save return data
+ * command : the adb command to send
+ * result : 0 = success
+ * : -1 = could not complete
+ */
+int
+adb_op(Ptr buffer, Ptr compRout, Ptr data, short command)
+{
+ int result;
+
+ switch (adbHardware) {
+ case ADB_HW_PMU:
+ result = pm_adb_op((u_char *)buffer, (void *)compRout,
+ (void *)data, (int)command);
+
+ if (result == 0)
+ return 0;
+ else
+ return -1;
+ break;
+
+ case ADB_HW_CUDA:
+ result = send_adb_cuda((u_char *)0, (u_char *)buffer,
+ (void *)compRout, (void *)data, (int)command);
+ if (result == 0)
+ return 0;
+ else
+ return -1;
+ break;
+
+ default:
+ return -1;
+ }
+}
+
+
+/*
+ * adb_hw_setup
+ * This routine sets up the possible machine specific hardware
+ * config (mainly VIA settings) for the various models.
+ */
+void
+adb_hw_setup(void)
+{
+ volatile int i;
+
+ switch (adbHardware) {
+
+ case ADB_HW_PMU:
+ /*
+ * XXX - really PM_VIA_CLR_INTR - should we put it in
+ * pm_direct.h?
+ */
+ write_via_reg(VIA1, vIFR, 0x90); /* clear interrupt */
+ break;
+
+ case ADB_HW_CUDA:
+ via_reg_or(VIA1, vDirB, 0x30); /* register B bits 4 and 5:
+ * outputs */
+ via_reg_and(VIA1, vDirB, 0xf7); /* register B bit 3: input */
+ via_reg_and(VIA1, vACR, ~vSR_OUT); /* make sure SR is set
+ * to IN */
+ write_via_reg(VIA1, vACR, (read_via_reg(VIA1, vACR) | 0x0c) & ~0x10);
+ adbActionState = ADB_ACTION_IDLE; /* used by all types of
+ * hardware */
+ write_via_reg(VIA1, vIER, 0x84);/* make sure VIA interrupts
+ * are on */
+ ADB_SET_STATE_IDLE_CUDA(); /* set ADB bus state to idle */
+
+ /* sort of a device reset */
+ i = ADB_SR(); /* clear interrupt */
+ ADB_VIA_INTR_DISABLE(); /* no interrupts while clearing */
+ ADB_SET_STATE_IDLE_CUDA(); /* reset state to idle */
+ delay(ADB_DELAY);
+ ADB_SET_STATE_TIP(); /* signal start of frame */
+ delay(ADB_DELAY);
+ ADB_TOGGLE_STATE_ACK_CUDA();
+ delay(ADB_DELAY);
+ ADB_CLR_STATE_TIP();
+ delay(ADB_DELAY);
+ ADB_SET_STATE_IDLE_CUDA(); /* back to idle state */
+ i = ADB_SR(); /* clear interrupt */
+ ADB_VIA_INTR_ENABLE(); /* ints ok now */
+ break;
+
+ case ADB_HW_UNKNOWN:
+ default:
+ write_via_reg(VIA1, vIER, 0x04);/* turn interrupts off - TO
+ * DO: turn PB ints off? */
+ break;
+ }
+}
+
+/*
+ * adb_reinit sets up the adb stuff
+ *
+ */
+void
+adb_reinit(void)
+{
+ u_char send_string[ADB_MAX_MSG_LENGTH];
+ ADBDataBlock data; /* temp. holder for getting device info */
+ volatile int i, x;
+ int s;
+ int command;
+ int result;
+ int saveptr; /* point to next free relocation address */
+ int device;
+ int nonewtimes; /* times thru loop w/o any new devices */
+
+ /* Make sure we are not interrupted while building the table. */
+ if (adbHardware != ADB_HW_PMU) /* ints must be on for PB? */
+ s = splhigh();
+
+ ADBNumDevices = 0; /* no devices yet */
+
+ /* Let intr routines know we are running reinit */
+ adbStarting = 1;
+
+ /*
+ * Initialize the ADB table. For now, we'll always use the same table
+ * that is defined at the beginning of this file - no mallocs.
+ */
+ for (i = 0; i < 16; i++)
+ ADBDevTable[i].devType = 0;
+
+ adb_setup_hw_type(); /* setup hardware type */
+
+ adb_hw_setup(); /* init the VIA bits and hard reset ADB */
+
+ delay(1000);
+
+ /* send an ADB reset first */
+ adb_op_sync((Ptr)0, (Ptr)0, (Ptr)0, (short)0x00);
+ delay(200000);
+
+ /*
+ * Probe for ADB devices. Probe devices 1-15 quickly to determine
+ * which device addresses are in use and which are free. For each
+ * address that is in use, move the device at that address to a higher
+ * free address. Continue doing this at that address until no device
+ * responds at that address. Then move the last device that was moved
+ * back to the original address. Do this for the remaining addresses
+ * that we determined were in use.
+ *
+ * When finished, do this entire process over again with the updated
+ * list of in use addresses. Do this until no new devices have been
+ * found in 20 passes though the in use address list. (This probably
+ * seems long and complicated, but it's the best way to detect multiple
+ * devices at the same address - sometimes it takes a couple of tries
+ * before the collision is detected.)
+ */
+
+ /* initial scan through the devices */
+ for (i = 1; i < 16; i++) {
+ send_string[0] = 0;
+ command = ADBTALK(i, 3);
+ result = adb_op_sync((Ptr)send_string, (Ptr)0,
+ (Ptr)0, (short)command);
+
+ if (send_string[0] != 0) {
+ /* check for valid device handler */
+ switch (send_string[2]) {
+ case 0:
+ case 0xfd:
+ case 0xfe:
+ case 0xff:
+ continue; /* invalid, skip */
+ }
+
+ /* found a device */
+ ++ADBNumDevices;
+ KASSERT(ADBNumDevices < 16);
+ ADBDevTable[ADBNumDevices].devType =
+ (int)send_string[2];
+ ADBDevTable[ADBNumDevices].origAddr = i;
+ ADBDevTable[ADBNumDevices].currentAddr = i;
+ ADBDevTable[ADBNumDevices].DataAreaAddr =
+ (long)0;
+ ADBDevTable[ADBNumDevices].ServiceRtPtr = (void *)0;
+ }
+ }
+
+ /* find highest unused address */
+ for (saveptr = 15; saveptr > 0; saveptr--)
+ if (-1 == get_adb_info(&data, saveptr))
+ break;
+
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80) {
+ printf_intr("first free is: 0x%02x\n", saveptr);
+ printf_intr("devices: %i\n", ADBNumDevices);
+ }
+#endif
+
+ nonewtimes = 0; /* no loops w/o new devices */
+ while (saveptr > 0 && nonewtimes++ < 11) {
+ for (i = 1; i <= ADBNumDevices; i++) {
+ device = ADBDevTable[i].currentAddr;
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("moving device 0x%02x to 0x%02x "
+ "(index 0x%02x) ", device, saveptr, i);
+#endif
+
+ /* send TALK R3 to address */
+ command = ADBTALK(device, 3);
+ adb_op_sync((Ptr)send_string, (Ptr)0,
+ (Ptr)0, (short)command);
+
+ /* move device to higher address */
+ command = ADBLISTEN(device, 3);
+ send_string[0] = 2;
+ send_string[1] = (u_char)(saveptr | 0x60);
+ send_string[2] = 0xfe;
+ adb_op_sync((Ptr)send_string, (Ptr)0,
+ (Ptr)0, (short)command);
+ delay(500);
+
+ /* send TALK R3 - anything at new address? */
+ command = ADBTALK(saveptr, 3);
+ adb_op_sync((Ptr)send_string, (Ptr)0,
+ (Ptr)0, (short)command);
+ delay(500);
+
+ if (send_string[0] == 0) {
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("failed, continuing\n");
+#endif
+ continue;
+ }
+
+ /* send TALK R3 - anything at old address? */
+ command = ADBTALK(device, 3);
+ result = adb_op_sync((Ptr)send_string, (Ptr)0,
+ (Ptr)0, (short)command);
+ if (send_string[0] != 0) {
+ /* check for valid device handler */
+ switch (send_string[2]) {
+ case 0:
+ case 0xfd:
+ case 0xfe:
+ case 0xff:
+ continue; /* invalid, skip */
+ }
+
+ /* new device found */
+ /* update data for previously moved device */
+ ADBDevTable[i].currentAddr = saveptr;
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("old device at index %i\n",i);
+#endif
+ /* add new device in table */
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("new device found\n");
+#endif
+ if (saveptr > ADBNumDevices) {
+ ++ADBNumDevices;
+ KASSERT(ADBNumDevices < 16);
+ }
+ ADBDevTable[ADBNumDevices].devType =
+ (int)send_string[2];
+ ADBDevTable[ADBNumDevices].origAddr = device;
+ ADBDevTable[ADBNumDevices].currentAddr = device;
+ /* These will be set correctly in adbsys.c */
+ /* Until then, unsol. data will be ignored. */
+ ADBDevTable[ADBNumDevices].DataAreaAddr =
+ (long)0;
+ ADBDevTable[ADBNumDevices].ServiceRtPtr =
+ (void *)0;
+ /* find next unused address */
+ for (x = saveptr; x > 0; x--) {
+ if (-1 == get_adb_info(&data, x)) {
+ saveptr = x;
+ break;
+ }
+ }
+ if (x == 0)
+ saveptr = 0;
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("new free is 0x%02x\n",
+ saveptr);
+#endif
+ nonewtimes = 0;
+ } else {
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("moving back...\n");
+#endif
+ /* move old device back */
+ command = ADBLISTEN(saveptr, 3);
+ send_string[0] = 2;
+ send_string[1] = (u_char)(device | 0x60);
+ send_string[2] = 0xfe;
+ adb_op_sync((Ptr)send_string, (Ptr)0,
+ (Ptr)0, (short)command);
+ delay(1000);
+ }
+ }
+ }
+
+#ifdef ADB_DEBUG
+ if (adb_debug) {
+ for (i = 1; i <= ADBNumDevices; i++) {
+ x = get_ind_adb_info(&data, i);
+ if (x != -1)
+ printf_intr("index 0x%x, addr 0x%x, type 0x%x\n",
+ i, x, data.devType);
+ }
+ }
+#endif
+
+#ifdef ADB_DEBUG
+ if (adb_debug) {
+ if (0 == ADBNumDevices) /* tell user if no devices found */
+ printf_intr("adb: no devices found\n");
+ }
+#endif
+
+ adbStarting = 0; /* not starting anymore */
+#ifdef ADB_DEBUG
+ if (adb_debug)
+ printf_intr("adb: adb_reinit complete\n");
+#endif
+
+ if (adbHardware == ADB_HW_CUDA) {
+ timeout_set(&adb_cuda_timeout, (void *)adb_cuda_tickle, NULL);
+ timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS);
+ }
+
+ if (adbHardware != ADB_HW_PMU) /* ints must be on for PB? */
+ splx(s);
+}
+
+
+/*
+ * adb_cmd_result
+ *
+ * This routine lets the caller know whether the specified adb command string
+ * should expect a returned result, such as a TALK command.
+ *
+ * returns: 0 if a result should be expected
+ * 1 if a result should NOT be expected
+ */
+int
+adb_cmd_result(u_char *in)
+{
+ switch (adbHardware) {
+ case ADB_HW_CUDA:
+ /* was it an ADB talk command? */
+ if ((in[1] == 0x00) && ((in[2] & 0x0c) == 0x0c))
+ return 0;
+ /* was it an RTC/PRAM read date/time? */
+ if ((in[1] == 0x01) && (in[2] == 0x03))
+ return 0;
+ return 1;
+
+ case ADB_HW_PMU:
+ return 1;
+
+ default:
+ return 1;
+ }
+}
+
+
+/*
+ * adb_op_sync
+ *
+ * This routine does exactly what the adb_op routine does, except that after
+ * the adb_op is called, it waits until the return value is present before
+ * returning.
+ *
+ * NOTE: The user specified compRout is ignored, since this routine specifies
+ * it's own to adb_op, which is why you really called this in the first place
+ * anyway.
+ */
+int
+adb_op_sync(Ptr buffer, Ptr compRout, Ptr data, short command)
+{
+ int tmout;
+ int result;
+ volatile int flag = 0;
+
+ result = adb_op(buffer, (void *)adb_op_comprout,
+ (void *)&flag, command); /* send command */
+ if (result == 0) { /* send ok? */
+ /*
+ * Total time to wait is calculated as follows:
+ * - Tlt (stop to start time): 260 usec
+ * - start bit: 100 usec
+ * - up to 8 data bytes: 64 * 100 usec = 6400 usec
+ * - stop bit (with SRQ): 140 usec
+ * Total: 6900 usec
+ *
+ * This is the total time allowed by the specification. Any
+ * device that doesn't conform to this will fail to operate
+ * properly on some Apple systems. In spite of this we
+ * double the time to wait; some Cuda-based apparently
+ * queues some commands and allows the main CPU to continue
+ * processing (radical concept, eh?). To be safe, allow
+ * time for two complete ADB transactions to occur.
+ */
+ for (tmout = 13800; !flag && tmout >= 10; tmout -= 10)
+ delay(10);
+ if (!flag && tmout > 0)
+ delay(tmout);
+
+ if (!flag)
+ result = -2;
+ }
+
+ return result;
+}
+
+
+/*
+ * adb_op_comprout
+ *
+ * This function is used by the adb_op_sync routine so it knows when the
+ * function is done.
+ */
+void
+adb_op_comprout(buffer, compdata, cmd)
+ caddr_t buffer, compdata;
+ int cmd;
+{
+ short *p = (short *)compdata;
+
+ *p = 1;
+}
+
+void
+adb_setup_hw_type(void)
+{
+ switch (adbHardware) {
+ case ADB_HW_CUDA:
+ adbSoftPower = 1;
+ return;
+
+ case ADB_HW_PMU:
+ adbSoftPower = 1;
+ pm_setup_adb();
+ return;
+
+ default:
+ panic("unknown adb hardware");
+ }
+}
+
+int
+count_adbs(void)
+{
+ int i;
+ int found;
+
+ found = 0;
+
+ for (i = 1; i < 16; i++)
+ if (0 != ADBDevTable[i].devType)
+ found++;
+
+ return found;
+}
+
+int
+get_ind_adb_info(ADBDataBlock * info, int index)
+{
+ if ((index < 1) || (index > 15)) /* check range 1-15 */
+ return (-1);
+
+#ifdef ADB_DEBUG
+ if (adb_debug & 0x80)
+ printf_intr("index 0x%x devType is: 0x%x\n", index,
+ ADBDevTable[index].devType);
+#endif
+ if (0 == ADBDevTable[index].devType) /* make sure it's a valid entry */
+ return (-1);
+
+ info->devType = ADBDevTable[index].devType;
+ info->origADBAddr = ADBDevTable[index].origAddr;
+ info->dbServiceRtPtr = (Ptr)ADBDevTable[index].ServiceRtPtr;
+ info->dbDataAreaAddr = (Ptr)ADBDevTable[index].DataAreaAddr;
+
+ return (ADBDevTable[index].currentAddr);
+}
+
+int
+get_adb_info(ADBDataBlock * info, int adbAddr)
+{
+ int i;
+
+ if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */
+ return (-1);
+
+ for (i = 1; i < 15; i++)
+ if (ADBDevTable[i].currentAddr == adbAddr) {
+ info->devType = ADBDevTable[i].devType;
+ info->origADBAddr = ADBDevTable[i].origAddr;
+ info->dbServiceRtPtr = (Ptr)ADBDevTable[i].ServiceRtPtr;
+ info->dbDataAreaAddr = ADBDevTable[i].DataAreaAddr;
+ return 0; /* found */
+ }
+
+ return (-1); /* not found */
+}
+
+int
+set_adb_info(ADBSetInfoBlock * info, int adbAddr)
+{
+ int i;
+
+ if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */
+ return (-1);
+
+ for (i = 1; i < 15; i++)
+ if (ADBDevTable[i].currentAddr == adbAddr) {
+ ADBDevTable[i].ServiceRtPtr =
+ (void *)(info->siServiceRtPtr);
+ ADBDevTable[i].DataAreaAddr = info->siDataAreaAddr;
+ return 0; /* found */
+ }
+
+ return (-1); /* not found */
+
+}
+
+/* caller should really use machine-independent version: getPramTime */
+/* this version does pseudo-adb access only */
+int
+adb_read_date_time(time_t *time)
+{
+ u_char output[ADB_MAX_MSG_LENGTH];
+ int result;
+ int retcode;
+ volatile int flag = 0;
+
+ switch (adbHardware) {
+ case ADB_HW_PMU:
+ pm_read_date_time(time);
+ retcode = 0;
+ break;
+
+ case ADB_HW_CUDA:
+ output[0] = 0x02; /* 2 byte message */
+ output[1] = 0x01; /* to pram/rtc device */
+ output[2] = 0x03; /* read date/time */
+ result = send_adb_cuda((u_char *)output, (u_char *)output,
+ (void *)adb_op_comprout, (void *)&flag, (int)0);
+ if (result != 0) { /* exit if not sent */
+ retcode = -1;
+ break;
+ }
+
+ while (0 == flag) /* wait for result */
+ ;
+
+ delay(20); /* completion occurs too soon? */
+ memcpy(time, output + 1, 4);
+ retcode = 0;
+ break;
+
+ case ADB_HW_UNKNOWN:
+ default:
+ retcode = -1;
+ break;
+ }
+ if (retcode == 0) {
+#define DIFF19041970 2082844800
+ *time -= DIFF19041970;
+
+ } else {
+ *time = 0;
+ }
+ return retcode;
+}
+
+/* caller should really use machine-independent version: setPramTime */
+/* this version does pseudo-adb access only */
+int
+adb_set_date_time(time_t time)
+{
+ u_char output[ADB_MAX_MSG_LENGTH];
+ int result;
+ volatile int flag = 0;
+
+ time += DIFF19041970;
+ switch (adbHardware) {
+
+ case ADB_HW_CUDA:
+ output[0] = 0x06; /* 6 byte message */
+ output[1] = 0x01; /* to pram/rtc device */
+ output[2] = 0x09; /* set date/time */
+ output[3] = (u_char)(time >> 24);
+ output[4] = (u_char)(time >> 16);
+ output[5] = (u_char)(time >> 8);
+ output[6] = (u_char)(time);
+ result = send_adb_cuda((u_char *)output, (u_char *)0,
+ (void *)adb_op_comprout, (void *)&flag, (int)0);
+ if (result != 0) /* exit if not sent */
+ return -1;
+
+ while (0 == flag) /* wait for send to finish */
+ ;
+
+ return 0;
+
+ case ADB_HW_PMU:
+ pm_set_date_time(time);
+ return 0;
+
+ default:
+ return -1;
+ }
+}
+
+
+int
+adb_poweroff(void)
+{
+ u_char output[ADB_MAX_MSG_LENGTH];
+ int result;
+
+ if (!adbSoftPower)
+ return -1;
+
+ adb_polling = 1;
+
+ switch (adbHardware) {
+ case ADB_HW_PMU:
+ pm_adb_poweroff();
+
+ for (;;); /* wait for power off */
+
+ return 0;
+
+ case ADB_HW_CUDA:
+ output[0] = 0x02; /* 2 byte message */
+ output[1] = 0x01; /* to pram/rtc/soft-power device */
+ output[2] = 0x0a; /* set date/time */
+ result = send_adb_cuda((u_char *)output, (u_char *)0,
+ (void *)0, (void *)0, (int)0);
+ if (result != 0) /* exit if not sent */
+ return -1;
+
+ for (;;); /* wait for power off */
+
+ return 0;
+
+ default:
+ return -1;
+ }
+}
+
+void
+setsoftadb()
+{
+ if (!timeout_initialized(&adb_softintr_timeout))
+ timeout_set(&adb_softintr_timeout, (void *)adb_soft_intr, NULL);
+ timeout_add(&adb_softintr_timeout, 1);
+}
+
+void
+adb_cuda_autopoll()
+{
+ volatile int flag = 0;
+ int result;
+ u_char output[16];
+
+ output[0] = 0x03; /* 3-byte message */
+ output[1] = 0x01; /* to pram/rtc device */
+ output[2] = 0x01; /* cuda autopoll */
+ output[3] = 0x01;
+ result = send_adb_cuda(output, output, adb_op_comprout,
+ (void *)&flag, 0);
+ if (result != 0) /* exit if not sent */
+ return;
+
+ while (flag == 0); /* wait for result */
+}
+
+void
+adb_restart()
+{
+ int result;
+ u_char output[16];
+
+ adb_polling = 1;
+
+ switch (adbHardware) {
+ case ADB_HW_CUDA:
+ output[0] = 0x02; /* 2 byte message */
+ output[1] = 0x01; /* to pram/rtc/soft-power device */
+ output[2] = 0x11; /* restart */
+ result = send_adb_cuda((u_char *)output, (u_char *)0,
+ (void *)0, (void *)0, (int)0);
+ if (result != 0) /* exit if not sent */
+ return;
+ while (1); /* not return */
+
+ case ADB_HW_PMU:
+ pm_adb_restart();
+ while (1); /* not return */
+ }
+}
/*
* Driver definition.
*/
+
+int adbmatch(struct device *, void *, void *);
+void adbattach(struct device *, struct device *, void *);
+
struct cfattach adb_ca = {
sizeof(struct adb_softc), adbmatch, adbattach
};
-struct cfdriver adb_cd = {
- NULL, "adb", DV_DULL
-};
int
adbmatch(struct device *parent, void *cf, void *aux)
@@ -119,7 +1646,7 @@ adbattach(struct device *parent, struct device *self, void *aux)
adbHardware = ADB_HW_PMU;
adb_polling = 1;
- ADBReInit();
+ adb_reinit();
mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_HIGH,
adb_intr, sc, "adb");
@@ -130,27 +1657,17 @@ adbattach(struct device *parent, struct device *self, void *aux)
#ifdef ADB_DEBUG
if (adb_debug)
- printf("adb: done with ADBReInit\n");
+ printf("adb: done with adb_reinit\n");
#endif
- totaladbs = CountADBs();
+ totaladbs = count_adbs();
- printf(" irq %d", ca->ca_intr[0]);
-
- switch (adbHardware) {
- case ADB_HW_CUDA:
- printf(": via-cuda");
- break;
- case ADB_HW_PMU:
- printf(": via-pmu");
- break;
- }
-
- printf(", %d target%s\n", totaladbs, (totaladbs == 1) ? "" : "s");
+ printf(" irq %d: %s, %d target%s\n", ca->ca_intr[0], ca->ca_name,
+ totaladbs, (totaladbs == 1) ? "" : "s");
/* for each ADB device */
for (adbindex = 1; adbindex <= totaladbs; adbindex++) {
/* Get the ADB information */
- adbaddr = GetIndADB(&adbdata, adbindex);
+ adbaddr = get_ind_adb_info(&adbdata, adbindex);
aa_args.origaddr = adbdata.origADBAddr;
aa_args.adbaddr = adbaddr;
@@ -183,69 +1700,3 @@ adbattach(struct device *parent, struct device *self, void *aux)
}
}
}
-
-int
-adbprint(void *args, const char *name)
-{
- struct adb_attach_args *aa_args = (struct adb_attach_args *)args;
- int rv = UNCONF;
-
- if (name) { /* no configured device matched */
- rv = UNSUPP; /* most ADB device types are unsupported */
-
- /* print out what kind of ADB device we have found */
- switch(aa_args->origaddr) {
-#ifdef ADBVERBOSE
- case ADBADDR_SECURE:
- printf("security dongle (%d)", aa_args->handler_id);
- break;
-#endif
- case ADBADDR_MAP:
- printf("mapped device (%d)", aa_args->handler_id);
- rv = UNCONF;
- break;
- case ADBADDR_REL:
- printf("relative positioning device (%d)",
- aa_args->handler_id);
- rv = UNCONF;
- break;
-#ifdef ADBVERBOSE
- case ADBADDR_ABS:
- switch (aa_args->handler_id) {
- case ADB_ARTPAD:
- printf("WACOM ArtPad II");
- break;
- default:
- printf("absolute positioning device (%d)",
- aa_args->handler_id);
- break;
- }
- break;
- case ADBADDR_DATATX:
- printf("data transfer device (modem?) (%d)",
- aa_args->handler_id);
- break;
- case ADBADDR_MISC:
- switch (aa_args->handler_id) {
- case ADB_POWERKEY:
- printf("Sophisticated Circuits PowerKey");
- break;
- default:
- printf("misc. device (remote control?) (%d)",
- aa_args->handler_id);
- break;
- }
- break;
- default:
- printf("unknown type %d device, (handler %d)",
- aa_args->origaddr, aa_args->handler_id);
- break;
-#endif /* ADBVERBOSE */
- }
- printf(" at %s", name);
- }
-
- printf(" addr %d", aa_args->adbaddr);
-
- return (rv);
-}
diff --git a/sys/arch/macppc/dev/adb_direct.c b/sys/arch/macppc/dev/adb_direct.c
deleted file mode 100644
index eab071d2c77..00000000000
--- a/sys/arch/macppc/dev/adb_direct.c
+++ /dev/null
@@ -1,1569 +0,0 @@
-/* $OpenBSD: adb_direct.c,v 1.14 2005/12/22 22:55:25 miod Exp $ */
-/* $NetBSD: adb_direct.c,v 1.14 2000/06/08 22:10:45 tsubai Exp $ */
-
-/*
- * Copyright (C) 1996, 1997 John P. Wittkoski
- * All rights reserved.
- *
- * 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 John P. Wittkoski.
- * 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.
- */
-
-/*
- * This code is rather messy, but I don't have time right now
- * to clean it up as much as I would like.
- * But it works, so I'm happy. :-) jpw
- */
-
-/*
- * TO DO:
- * - We could reduce the time spent in the adb_intr_* routines
- * by having them save the incoming and outgoing data directly
- * in the adbInbound and adbOutbound queues, as it would reduce
- * the number of times we need to copy the data around. It
- * would also make the code more readable and easier to follow.
- * - (Related to above) Use the header part of adbCommand to
- * reduce the number of copies we have to do of the data.
- * - (Related to above) Actually implement the adbOutbound queue.
- * This is fairly easy once you switch all the intr routines
- * over to using adbCommand structs directly.
- * - There is a bug in the state machine of adb_intr_cuda
- * code that causes hangs, especially on 030 machines, probably
- * because of some timing issues. Because I have been unable to
- * determine the exact cause of this bug, I used the timeout function
- * to check for and recover from this condition. If anyone finds
- * the actual cause of this bug, the calls to timeout and the
- * adb_cuda_tickle routine can be removed.
- */
-
-#include <sys/param.h>
-#include <sys/cdefs.h>
-#include <sys/systm.h>
-#include <sys/timeout.h>
-#include <sys/device.h>
-
-#include <machine/param.h>
-#include <machine/cpu.h>
-#include <machine/adbsys.h>
-
-#include <macppc/dev/viareg.h>
-#include <macppc/dev/adbvar.h>
-#include <macppc/dev/pm_direct.h>
-
-#define printf_intr printf
-
-#ifdef DEBUG
-#ifndef ADB_DEBUG
-#define ADB_DEBUG
-#endif
-#endif
-
-/* some misc. leftovers */
-#define vPB 0x0000
-#define vPB3 0x08
-#define vPB4 0x10
-#define vPB5 0x20
-#define vSR_INT 0x04
-#define vSR_OUT 0x10
-
-/* the type of ADB action that we are currently performing */
-#define ADB_ACTION_NOTREADY 0x1 /* has not been initialized yet */
-#define ADB_ACTION_IDLE 0x2 /* the bus is currently idle */
-#define ADB_ACTION_OUT 0x3 /* sending out a command */
-#define ADB_ACTION_IN 0x4 /* receiving data */
-
-/*
- * Shortcuts for setting or testing the VIA bit states.
- * Not all shortcuts are used for every type of ADB hardware.
- */
-#define ADB_SET_STATE_IDLE_CUDA() via_reg_or(VIA1, vBufB, (vPB4 | vPB5))
-#define ADB_SET_STATE_TIP() via_reg_and(VIA1, vBufB, ~vPB5)
-#define ADB_CLR_STATE_TIP() via_reg_or(VIA1, vBufB, vPB5)
-#define ADB_TOGGLE_STATE_ACK_CUDA() via_reg_xor(VIA1, vBufB, vPB4)
-#define ADB_SET_STATE_ACKOFF_CUDA() via_reg_or(VIA1, vBufB, vPB4)
-#define ADB_SET_SR_INPUT() via_reg_and(VIA1, vACR, ~vSR_OUT)
-#define ADB_SET_SR_OUTPUT() via_reg_or(VIA1, vACR, vSR_OUT)
-#define ADB_SR() read_via_reg(VIA1, vSR)
-#define ADB_VIA_INTR_ENABLE() write_via_reg(VIA1, vIER, 0x84)
-#define ADB_VIA_INTR_DISABLE() write_via_reg(VIA1, vIER, 0x04)
-#define ADB_VIA_CLR_INTR() write_via_reg(VIA1, vIFR, 0x04)
-#define ADB_INTR_IS_OFF (vPB3 == (read_via_reg(VIA1, vBufB) & vPB3))
-#define ADB_INTR_IS_ON (0 == (read_via_reg(VIA1, vBufB) & vPB3))
-#define ADB_SR_INTR_IS_ON (vSR_INT == (read_via_reg(VIA1, \
- vIFR) & vSR_INT))
-
-/*
- * This is the delay that is required (in uS) between certain
- * ADB transactions. The actual timing delay for for each uS is
- * calculated at boot time to account for differences in machine speed.
- */
-#define ADB_DELAY 150
-
-/*
- * Maximum ADB message length; includes space for data, result, and
- * device code - plus a little for safety.
- */
-#define ADB_MAX_MSG_LENGTH 16
-#define ADB_MAX_HDR_LENGTH 8
-
-#define ADB_QUEUE 32
-#define ADB_TICKLE_TICKS 4
-
-/*
- * A structure for storing information about each ADB device.
- */
-struct ADBDevEntry {
- void (*ServiceRtPtr)(void);
- void *DataAreaAddr;
- int devType;
- int origAddr;
- int currentAddr;
-};
-
-/*
- * Used to hold ADB commands that are waiting to be sent out.
- */
-struct adbCmdHoldEntry {
- u_char outBuf[ADB_MAX_MSG_LENGTH]; /* our message */
- u_char *saveBuf; /* buffer to know where to save result */
- u_char *compRout; /* completion routine pointer */
- u_char *data; /* completion routine data pointer */
-};
-
-/*
- * Eventually used for two separate queues, the queue between
- * the upper and lower halves, and the outgoing packet queue.
- * TO DO: adbCommand can replace all of adbCmdHoldEntry eventually
- */
-struct adbCommand {
- u_char header[ADB_MAX_HDR_LENGTH]; /* not used yet */
- u_char data[ADB_MAX_MSG_LENGTH]; /* packet data only */
- u_char *saveBuf; /* where to save result */
- u_char *compRout; /* completion routine pointer */
- u_char *compData; /* completion routine data pointer */
- u_int cmd; /* the original command for this data */
- u_int unsol; /* 1 if packet was unsolicited */
- u_int ack_only; /* 1 for no special processing */
-};
-
-/*
- * A few variables that we need and their initial values.
- */
-int adbHardware = ADB_HW_UNKNOWN;
-int adbActionState = ADB_ACTION_NOTREADY;
-int adbWaiting = 0; /* waiting for return data from the device */
-int adbWriteDelay = 0; /* working on (or waiting to do) a write */
-int adbSoftPower = 0; /* machine supports soft power */
-
-int adbWaitingCmd = 0; /* ADB command we are waiting for */
-u_char *adbBuffer = (long)0; /* pointer to user data area */
-void *adbCompRout = (long)0; /* pointer to the completion routine */
-void *adbCompData = (long)0; /* pointer to the completion routine data */
-int adbStarting = 1; /* doing ADBReInit so do polling differently */
-
-u_char adbInputBuffer[ADB_MAX_MSG_LENGTH]; /* data input buffer */
-u_char adbOutputBuffer[ADB_MAX_MSG_LENGTH]; /* data output buffer */
-struct adbCmdHoldEntry adbOutQueue; /* our 1 entry output queue */
-
-int adbSentChars = 0; /* how many characters we have sent */
-
-struct ADBDevEntry ADBDevTable[16]; /* our ADB device table */
-int ADBNumDevices; /* num. of ADB devices found with ADBReInit */
-
-struct adbCommand adbInbound[ADB_QUEUE]; /* incoming queue */
-int adbInCount = 0; /* how many packets in in queue */
-int adbInHead = 0; /* head of in queue */
-int adbInTail = 0; /* tail of in queue */
-struct adbCommand adbOutbound[ADB_QUEUE]; /* outgoing queue - not used yet */
-int adbOutCount = 0; /* how many packets in out queue */
-int adbOutHead = 0; /* head of out queue */
-int adbOutTail = 0; /* tail of out queue */
-
-int tickle_count = 0; /* how many tickles seen for this packet? */
-int tickle_serial = 0; /* the last packet tickled */
-int adb_cuda_serial = 0; /* the current packet */
-struct timeout adb_cuda_timeout;
-struct timeout adb_softintr_timeout;
-
-volatile u_char *Via1Base;
-
-/*
- * The following are private routines.
- */
-#ifdef ADB_DEBUG
-void print_single(u_char *);
-#endif
-void adb_intr_cuda(void);
-void adb_soft_intr(void);
-int send_adb_cuda(u_char *, u_char *, void *, void *, int);
-void adb_cuda_tickle(void);
-void adb_pass_up(struct adbCommand *);
-void adb_op_comprout(caddr_t, caddr_t, int);
-void adb_reinit(void);
-int count_adbs(void);
-int get_ind_adb_info(ADBDataBlock *, int);
-int get_adb_info(ADBDataBlock *, int);
-int set_adb_info(ADBSetInfoBlock *, int);
-void adb_setup_hw_type(void);
-int adb_op(Ptr, Ptr, Ptr, short);
-void adb_hw_setup(void);
-int adb_cmd_result(u_char *);
-void setsoftadb(void);
-
-#ifdef ADB_DEBUG
-/*
- * print_single
- * Diagnostic display routine. Displays the hex values of the
- * specified elements of the u_char. The length of the "string"
- * is in [0].
- */
-void
-print_single(str)
- u_char *str;
-{
- int x;
-
- if (str == 0) {
- printf_intr("no data - null pointer\n");
- return;
- }
- if (*str == 0) {
- printf_intr("nothing returned\n");
- return;
- }
- if (*str > 20) {
- printf_intr("ADB: ACK > 20 no way!\n");
- *str = 20;
- }
- printf_intr("(length=0x%x):", *str);
- for (x = 1; x <= *str; x++)
- printf_intr(" 0x%02x", str[x]);
- printf_intr("\n");
-}
-#endif
-
-void
-adb_cuda_tickle(void)
-{
- volatile int s;
-
- if (adbActionState == ADB_ACTION_IN) {
- if (tickle_serial == adb_cuda_serial) {
- if (++tickle_count > 0) {
- s = splhigh();
- adbActionState = ADB_ACTION_IDLE;
- adbInputBuffer[0] = 0;
- ADB_SET_STATE_IDLE_CUDA();
- splx(s);
- }
- } else {
- tickle_serial = adb_cuda_serial;
- tickle_count = 0;
- }
- } else {
- tickle_serial = adb_cuda_serial;
- tickle_count = 0;
- }
-
- timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS);
-}
-
-/*
- * called when when an adb interrupt happens
- *
- * Cuda version of adb_intr
- * TO DO: do we want to add some calls to intr_dispatch() here to
- * grab serial interrupts?
- */
-void
-adb_intr_cuda(void)
-{
- volatile int i, ending;
- volatile unsigned int s;
- struct adbCommand packet;
-
- s = splhigh(); /* can't be too careful - might be called */
- /* from a routine, NOT an interrupt */
-
- ADB_VIA_CLR_INTR(); /* clear interrupt */
- ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */
-
-switch_start:
- switch (adbActionState) {
- case ADB_ACTION_IDLE:
- /*
- * This is an unexpected packet, so grab the first (dummy)
- * byte, set up the proper vars, and tell the chip we are
- * starting to receive the packet by setting the TIP bit.
- */
- adbInputBuffer[1] = ADB_SR();
- adb_cuda_serial++;
- if (ADB_INTR_IS_OFF) /* must have been a fake start */
- break;
-
- ADB_SET_SR_INPUT();
- ADB_SET_STATE_TIP();
-
- adbInputBuffer[0] = 1;
- adbActionState = ADB_ACTION_IN;
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("idle 0x%02x ", adbInputBuffer[1]);
-#endif
- break;
-
- case ADB_ACTION_IN:
- adbInputBuffer[++adbInputBuffer[0]] = ADB_SR();
- /* intr off means this is the last byte (end of frame) */
- if (ADB_INTR_IS_OFF)
- ending = 1;
- else
- ending = 0;
-
- if (1 == ending) { /* end of message? */
-#ifdef ADB_DEBUG
- if (adb_debug) {
- printf_intr("in end 0x%02x ",
- adbInputBuffer[adbInputBuffer[0]]);
- print_single(adbInputBuffer);
- }
-#endif
-
- /*
- * Are we waiting AND does this packet match what we
- * are waiting for AND is it coming from either the
- * ADB or RTC/PRAM sub-device? This section _should_
- * recognize all ADB and RTC/PRAM type commands, but
- * there may be more... NOTE: commands are always at
- * [4], even for RTC/PRAM commands.
- */
- /* set up data for adb_pass_up */
- memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
-
- if ((adbWaiting == 1) &&
- (adbInputBuffer[4] == adbWaitingCmd) &&
- ((adbInputBuffer[2] == 0x00) ||
- (adbInputBuffer[2] == 0x01))) {
- packet.saveBuf = adbBuffer;
- packet.compRout = adbCompRout;
- packet.compData = adbCompData;
- packet.unsol = 0;
- packet.ack_only = 0;
- adb_pass_up(&packet);
-
- adbWaitingCmd = 0; /* reset "waiting" vars */
- adbWaiting = 0;
- adbBuffer = (long)0;
- adbCompRout = (long)0;
- adbCompData = (long)0;
- } else {
- packet.unsol = 1;
- packet.ack_only = 0;
- adb_pass_up(&packet);
- }
-
-
- /* reset vars and signal the end of this frame */
- adbActionState = ADB_ACTION_IDLE;
- adbInputBuffer[0] = 0;
- ADB_SET_STATE_IDLE_CUDA();
- /*ADB_SET_SR_INPUT();*/
-
- /*
- * If there is something waiting to be sent out,
- * the set everything up and send the first byte.
- */
- if (adbWriteDelay == 1) {
- delay(ADB_DELAY); /* required */
- adbSentChars = 0;
- adbActionState = ADB_ACTION_OUT;
- /*
- * If the interrupt is on, we were too slow
- * and the chip has already started to send
- * something to us, so back out of the write
- * and start a read cycle.
- */
- if (ADB_INTR_IS_ON) {
- ADB_SET_SR_INPUT();
- ADB_SET_STATE_IDLE_CUDA();
- adbSentChars = 0;
- adbActionState = ADB_ACTION_IDLE;
- adbInputBuffer[0] = 0;
- break;
- }
- /*
- * If we got here, it's ok to start sending
- * so load the first byte and tell the chip
- * we want to send.
- */
- ADB_SET_STATE_TIP();
- ADB_SET_SR_OUTPUT();
- write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]);
- }
- } else {
- ADB_TOGGLE_STATE_ACK_CUDA();
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("in 0x%02x ",
- adbInputBuffer[adbInputBuffer[0]]);
-#endif
- }
- break;
-
- case ADB_ACTION_OUT:
- i = ADB_SR(); /* reset SR-intr in IFR */
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("intr out 0x%02x ", i);
-#endif
-
- adbSentChars++;
- if (ADB_INTR_IS_ON) { /* ADB intr low during write */
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("intr was on ");
-#endif
- ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
- ADB_SET_STATE_IDLE_CUDA();
- adbSentChars = 0; /* must start all over */
- adbActionState = ADB_ACTION_IDLE; /* new state */
- adbInputBuffer[0] = 0;
- adbWriteDelay = 1; /* must retry when done with
- * read */
- delay(ADB_DELAY);
- goto switch_start; /* process next state right
- * now */
- break;
- }
- if (adbOutputBuffer[0] == adbSentChars) { /* check for done */
- if (0 == adb_cmd_result(adbOutputBuffer)) { /* do we expect data
- * back? */
- adbWaiting = 1; /* signal waiting for return */
- adbWaitingCmd = adbOutputBuffer[2]; /* save waiting command */
- } else { /* no talk, so done */
- /* set up stuff for adb_pass_up */
- memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
- packet.saveBuf = adbBuffer;
- packet.compRout = adbCompRout;
- packet.compData = adbCompData;
- packet.cmd = adbWaitingCmd;
- packet.unsol = 0;
- packet.ack_only = 1;
- adb_pass_up(&packet);
-
- /* reset "waiting" vars, just in case */
- adbWaitingCmd = 0;
- adbBuffer = (long)0;
- adbCompRout = (long)0;
- adbCompData = (long)0;
- }
-
- adbWriteDelay = 0; /* done writing */
- adbActionState = ADB_ACTION_IDLE; /* signal bus is idle */
- ADB_SET_SR_INPUT();
- ADB_SET_STATE_IDLE_CUDA();
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("write done ");
-#endif
- } else {
- write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]); /* send next byte */
- ADB_TOGGLE_STATE_ACK_CUDA(); /* signal byte ready to
- * shift */
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("toggle ");
-#endif
- }
- break;
-
- case ADB_ACTION_NOTREADY:
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("adb: not yet initialized\n");
-#endif
- break;
-
- default:
- ;
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("intr: unknown ADB state\n");
-#endif
- }
-
- ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */
-
- splx(s); /* restore */
-}
-
-
-int
-send_adb_cuda(u_char * in, u_char * buffer, void *compRout, void *data, int
- command)
-{
- int s, len;
-
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("SEND\n");
-#endif
-
- if (adbActionState == ADB_ACTION_NOTREADY)
- return 1;
-
- /* Don't interrupt while we are messing with the ADB */
- s = splhigh();
-
- if ((adbActionState == ADB_ACTION_IDLE) && /* ADB available? */
- (ADB_INTR_IS_OFF)) { /* and no incoming interrupt? */
- } else
- if (adbWriteDelay == 0) /* it's busy, but is anything waiting? */
- adbWriteDelay = 1; /* if no, then we'll "queue"
- * it up */
- else {
- splx(s);
- return 1; /* really busy! */
- }
-
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("QUEUE\n");
-#endif
- if ((long)in == (long)0) { /* need to convert? */
- if ((command & 0x0c) == 0x08) /* copy addl data ONLY if
- * doing a listen! */
- len = buffer[0]; /* length of additional data */
- else
- len = 0;/* no additional data */
-
- adbOutputBuffer[0] = 2 + len; /* dev. type + command + addl.
- * data */
- adbOutputBuffer[1] = 0x00; /* mark as an ADB command */
- adbOutputBuffer[2] = (u_char)command; /* load command */
-
- /* copy additional output data, if any */
- memcpy(adbOutputBuffer + 3, buffer + 1, len);
- } else
- /* if data ready, just copy over */
- memcpy(adbOutputBuffer, in, in[0] + 2);
-
- adbSentChars = 0; /* nothing sent yet */
- adbBuffer = buffer; /* save buffer to know where to save result */
- adbCompRout = compRout; /* save completion routine pointer */
- adbCompData = data; /* save completion routine data pointer */
- adbWaitingCmd = adbOutputBuffer[2]; /* save wait command */
-
- if (adbWriteDelay != 1) { /* start command now? */
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("out start NOW");
-#endif
- delay(ADB_DELAY);
- adbActionState = ADB_ACTION_OUT; /* set next state */
- ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
- write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]); /* load byte for output */
- ADB_SET_STATE_ACKOFF_CUDA();
- ADB_SET_STATE_TIP(); /* tell ADB that we want to send */
- }
- adbWriteDelay = 1; /* something in the write "queue" */
-
- splx(s);
-
- if ((s & (1 << 18)) || adb_polling) /* XXX were VIA1 interrupts blocked ? */
- /* poll until byte done */
- while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
- || (adbWaiting == 1))
- if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
- adb_intr_cuda(); /* process it */
- adb_soft_intr();
- }
-
- return 0;
-}
-
-/*
- * Called when when an adb interrupt happens.
- * This routine simply transfers control over to the appropriate
- * code for the machine we are running on.
- */
-int
-adb_intr(void *arg)
-{
- switch (adbHardware) {
- case ADB_HW_PMU:
- pm_intr();
- break;
-
- case ADB_HW_CUDA:
- adb_intr_cuda();
- break;
- }
- return 1;
-}
-
-
-/*
- * adb_pass_up is called by the interrupt-time routines.
- * It takes the raw packet data that was received from the
- * device and puts it into the queue that the upper half
- * processes. It then signals for a soft ADB interrupt which
- * will eventually call the upper half routine (adb_soft_intr).
- *
- * If in->unsol is 0, then this is either the notification
- * that the packet was sent (on a LISTEN, for example), or the
- * response from the device (on a TALK). The completion routine
- * is called only if the user specified one.
- *
- * If in->unsol is 1, then this packet was unsolicited and
- * so we look up the device in the ADB device table to determine
- * what it's default service routine is.
- *
- * If in->ack_only is 1, then we really only need to call
- * the completion routine, so don't do any other stuff.
- *
- * Note that in->data contains the packet header AND data,
- * while adbInbound[]->data contains ONLY data.
- *
- * Note: Called only at interrupt time. Assumes this.
- */
-void
-adb_pass_up(struct adbCommand *in)
-{
- int start = 0, len = 0, cmd = 0;
- ADBDataBlock block;
-
- /* temp for testing */
- /*u_char *buffer = 0;*/
- /*u_char *compdata = 0;*/
- /*u_char *comprout = 0;*/
-
- if (adbInCount >= ADB_QUEUE) {
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("adb: ring buffer overflow\n");
-#endif
- return;
- }
-
- if (in->ack_only) {
- len = in->data[0];
- cmd = in->cmd;
- start = 0;
- } else {
- switch (adbHardware) {
- case ADB_HW_CUDA:
- /* If it's unsolicited, accept only ADB data for now */
- if (in->unsol)
- if (0 != in->data[2])
- return;
- cmd = in->data[4];
- if (in->data[0] < 5)
- len = 0;
- else
- len = in->data[0]-4;
- start = 4;
- break;
-
- case ADB_HW_PMU:
- cmd = in->data[1];
- if (in->data[0] < 2)
- len = 0;
- else
- len = in->data[0]-1;
- start = 1;
- break;
-
- case ADB_HW_UNKNOWN:
- return;
- }
-
- /* Make sure there is a valid device entry for this device */
- if (in->unsol) {
- /* ignore unsolicited data during adbreinit */
- if (adbStarting)
- return;
- /* get device's comp. routine and data area */
- if (-1 == get_adb_info(&block, ADB_CMDADDR(cmd)))
- return;
- }
- }
-
- /*
- * If this is an unsolicited packet, we need to fill in
- * some info so adb_soft_intr can process this packet
- * properly. If it's not unsolicited, then use what
- * the caller sent us.
- */
- if (in->unsol) {
- adbInbound[adbInTail].compRout = (void *)block.dbServiceRtPtr;
- adbInbound[adbInTail].compData = (void *)block.dbDataAreaAddr;
- adbInbound[adbInTail].saveBuf = (void *)adbInbound[adbInTail].data;
- } else {
- adbInbound[adbInTail].compRout = (void *)in->compRout;
- adbInbound[adbInTail].compData = (void *)in->compData;
- adbInbound[adbInTail].saveBuf = (void *)in->saveBuf;
- }
-
-#ifdef ADB_DEBUG
- if (adb_debug && in->data[1] == 2)
- printf_intr("adb: caught error\n");
-#endif
-
- /* copy the packet data over */
- /*
- * TO DO: If the *_intr routines fed their incoming data
- * directly into an adbCommand struct, which is passed to
- * this routine, then we could eliminate this copy.
- */
- memcpy(adbInbound[adbInTail].data + 1, in->data + start + 1, len);
- adbInbound[adbInTail].data[0] = len;
- adbInbound[adbInTail].cmd = cmd;
-
- adbInCount++;
- if (++adbInTail >= ADB_QUEUE)
- adbInTail = 0;
-
- /*
- * If the debugger is running, call upper half manually.
- * Otherwise, trigger a soft interrupt to handle the rest later.
- */
- if (adb_polling)
- adb_soft_intr();
- else
- setsoftadb();
-}
-
-
-/*
- * Called to process the packets after they have been
- * placed in the incoming queue.
- *
- */
-void
-adb_soft_intr(void)
-{
- int s;
- int cmd = 0;
- u_char *buffer = 0;
- u_char *comprout = 0;
- u_char *compdata = 0;
-
-/*delay(2*ADB_DELAY);*/
-
- while (adbInCount) {
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("%x %x %x ",
- adbInCount, adbInHead, adbInTail);
-#endif
- /* get the data we need from the queue */
- buffer = adbInbound[adbInHead].saveBuf;
- comprout = adbInbound[adbInHead].compRout;
- compdata = adbInbound[adbInHead].compData;
- cmd = adbInbound[adbInHead].cmd;
-
- /* copy over data to data area if it's valid */
- /*
- * Note that for unsol packets we don't want to copy the
- * data anywhere, so buffer was already set to 0.
- * For ack_only buffer was set to 0, so don't copy.
- */
- if (buffer)
- memcpy(buffer, adbInbound[adbInHead].data,
- adbInbound[adbInHead].data[0] + 1);
-
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80) {
- printf_intr("%p %p %p %x ",
- buffer, comprout, compdata, (short)cmd);
- printf_intr("buf: ");
- print_single(adbInbound[adbInHead].data);
- }
-#endif
- /*
- * Remove the packet from the queue before calling
- * the completion routine, so that the completion
- * routine can reentrantly process the queue. For
- * example, this happens when polling is turned on
- * by entering the debuger by keystroke.
- */
- s = splhigh();
- adbInCount--;
- if (++adbInHead >= ADB_QUEUE)
- adbInHead = 0;
- splx(s);
-
- /* call default completion routine if it's valid */
- if (comprout) {
- ((int (*)(u_char *, u_char *, int)) comprout)
- (buffer, compdata, cmd);
- }
-
- }
-}
-
-
-/*
- * This is my version of the ADBOp routine. It mainly just calls the
- * hardware-specific routine.
- *
- * data : pointer to data area to be used by compRout
- * compRout : completion routine
- * buffer : for LISTEN: points to data to send - MAX 8 data bytes,
- * byte 0 = # of bytes
- * : for TALK: points to place to save return data
- * command : the adb command to send
- * result : 0 = success
- * : -1 = could not complete
- */
-int
-adb_op(Ptr buffer, Ptr compRout, Ptr data, short command)
-{
- int result;
-
- switch (adbHardware) {
- case ADB_HW_PMU:
- result = pm_adb_op((u_char *)buffer, (void *)compRout,
- (void *)data, (int)command);
-
- if (result == 0)
- return 0;
- else
- return -1;
- break;
-
- case ADB_HW_CUDA:
- result = send_adb_cuda((u_char *)0, (u_char *)buffer,
- (void *)compRout, (void *)data, (int)command);
- if (result == 0)
- return 0;
- else
- return -1;
- break;
-
- default:
- return -1;
- }
-}
-
-
-/*
- * adb_hw_setup
- * This routine sets up the possible machine specific hardware
- * config (mainly VIA settings) for the various models.
- */
-void
-adb_hw_setup(void)
-{
- volatile int i;
-
- switch (adbHardware) {
-
- case ADB_HW_PMU:
- /*
- * XXX - really PM_VIA_CLR_INTR - should we put it in
- * pm_direct.h?
- */
- write_via_reg(VIA1, vIFR, 0x90); /* clear interrupt */
- break;
-
- case ADB_HW_CUDA:
- via_reg_or(VIA1, vDirB, 0x30); /* register B bits 4 and 5:
- * outputs */
- via_reg_and(VIA1, vDirB, 0xf7); /* register B bit 3: input */
- via_reg_and(VIA1, vACR, ~vSR_OUT); /* make sure SR is set
- * to IN */
- write_via_reg(VIA1, vACR, (read_via_reg(VIA1, vACR) | 0x0c) & ~0x10);
- adbActionState = ADB_ACTION_IDLE; /* used by all types of
- * hardware */
- write_via_reg(VIA1, vIER, 0x84);/* make sure VIA interrupts
- * are on */
- ADB_SET_STATE_IDLE_CUDA(); /* set ADB bus state to idle */
-
- /* sort of a device reset */
- i = ADB_SR(); /* clear interrupt */
- ADB_VIA_INTR_DISABLE(); /* no interrupts while clearing */
- ADB_SET_STATE_IDLE_CUDA(); /* reset state to idle */
- delay(ADB_DELAY);
- ADB_SET_STATE_TIP(); /* signal start of frame */
- delay(ADB_DELAY);
- ADB_TOGGLE_STATE_ACK_CUDA();
- delay(ADB_DELAY);
- ADB_CLR_STATE_TIP();
- delay(ADB_DELAY);
- ADB_SET_STATE_IDLE_CUDA(); /* back to idle state */
- i = ADB_SR(); /* clear interrupt */
- ADB_VIA_INTR_ENABLE(); /* ints ok now */
- break;
-
- case ADB_HW_UNKNOWN:
- default:
- write_via_reg(VIA1, vIER, 0x04);/* turn interrupts off - TO
- * DO: turn PB ints off? */
- break;
- }
-}
-
-/*
- * adb_reinit sets up the adb stuff
- *
- */
-void
-adb_reinit(void)
-{
- u_char send_string[ADB_MAX_MSG_LENGTH];
- ADBDataBlock data; /* temp. holder for getting device info */
- volatile int i, x;
- int s;
- int command;
- int result;
- int saveptr; /* point to next free relocation address */
- int device;
- int nonewtimes; /* times thru loop w/o any new devices */
-
- /* Make sure we are not interrupted while building the table. */
- if (adbHardware != ADB_HW_PMU) /* ints must be on for PB? */
- s = splhigh();
-
- ADBNumDevices = 0; /* no devices yet */
-
- /* Let intr routines know we are running reinit */
- adbStarting = 1;
-
- /*
- * Initialize the ADB table. For now, we'll always use the same table
- * that is defined at the beginning of this file - no mallocs.
- */
- for (i = 0; i < 16; i++)
- ADBDevTable[i].devType = 0;
-
- adb_setup_hw_type(); /* setup hardware type */
-
- adb_hw_setup(); /* init the VIA bits and hard reset ADB */
-
- delay(1000);
-
- /* send an ADB reset first */
- adb_op_sync((Ptr)0, (Ptr)0, (Ptr)0, (short)0x00);
- delay(200000);
-
- /*
- * Probe for ADB devices. Probe devices 1-15 quickly to determine
- * which device addresses are in use and which are free. For each
- * address that is in use, move the device at that address to a higher
- * free address. Continue doing this at that address until no device
- * responds at that address. Then move the last device that was moved
- * back to the original address. Do this for the remaining addresses
- * that we determined were in use.
- *
- * When finished, do this entire process over again with the updated
- * list of in use addresses. Do this until no new devices have been
- * found in 20 passes though the in use address list. (This probably
- * seems long and complicated, but it's the best way to detect multiple
- * devices at the same address - sometimes it takes a couple of tries
- * before the collision is detected.)
- */
-
- /* initial scan through the devices */
- for (i = 1; i < 16; i++) {
- send_string[0] = 0;
- command = ADBTALK(i, 3);
- result = adb_op_sync((Ptr)send_string, (Ptr)0,
- (Ptr)0, (short)command);
-
- if (send_string[0] != 0) {
- /* check for valid device handler */
- switch (send_string[2]) {
- case 0:
- case 0xfd:
- case 0xfe:
- case 0xff:
- continue; /* invalid, skip */
- }
-
- /* found a device */
- ++ADBNumDevices;
- KASSERT(ADBNumDevices < 16);
- ADBDevTable[ADBNumDevices].devType =
- (int)send_string[2];
- ADBDevTable[ADBNumDevices].origAddr = i;
- ADBDevTable[ADBNumDevices].currentAddr = i;
- ADBDevTable[ADBNumDevices].DataAreaAddr =
- (long)0;
- ADBDevTable[ADBNumDevices].ServiceRtPtr = (void *)0;
- }
- }
-
- /* find highest unused address */
- for (saveptr = 15; saveptr > 0; saveptr--)
- if (-1 == get_adb_info(&data, saveptr))
- break;
-
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80) {
- printf_intr("first free is: 0x%02x\n", saveptr);
- printf_intr("devices: %i\n", ADBNumDevices);
- }
-#endif
-
- nonewtimes = 0; /* no loops w/o new devices */
- while (saveptr > 0 && nonewtimes++ < 11) {
- for (i = 1; i <= ADBNumDevices; i++) {
- device = ADBDevTable[i].currentAddr;
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("moving device 0x%02x to 0x%02x "
- "(index 0x%02x) ", device, saveptr, i);
-#endif
-
- /* send TALK R3 to address */
- command = ADBTALK(device, 3);
- adb_op_sync((Ptr)send_string, (Ptr)0,
- (Ptr)0, (short)command);
-
- /* move device to higher address */
- command = ADBLISTEN(device, 3);
- send_string[0] = 2;
- send_string[1] = (u_char)(saveptr | 0x60);
- send_string[2] = 0xfe;
- adb_op_sync((Ptr)send_string, (Ptr)0,
- (Ptr)0, (short)command);
- delay(500);
-
- /* send TALK R3 - anything at new address? */
- command = ADBTALK(saveptr, 3);
- adb_op_sync((Ptr)send_string, (Ptr)0,
- (Ptr)0, (short)command);
- delay(500);
-
- if (send_string[0] == 0) {
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("failed, continuing\n");
-#endif
- continue;
- }
-
- /* send TALK R3 - anything at old address? */
- command = ADBTALK(device, 3);
- result = adb_op_sync((Ptr)send_string, (Ptr)0,
- (Ptr)0, (short)command);
- if (send_string[0] != 0) {
- /* check for valid device handler */
- switch (send_string[2]) {
- case 0:
- case 0xfd:
- case 0xfe:
- case 0xff:
- continue; /* invalid, skip */
- }
-
- /* new device found */
- /* update data for previously moved device */
- ADBDevTable[i].currentAddr = saveptr;
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("old device at index %i\n",i);
-#endif
- /* add new device in table */
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("new device found\n");
-#endif
- if (saveptr > ADBNumDevices) {
- ++ADBNumDevices;
- KASSERT(ADBNumDevices < 16);
- }
- ADBDevTable[ADBNumDevices].devType =
- (int)send_string[2];
- ADBDevTable[ADBNumDevices].origAddr = device;
- ADBDevTable[ADBNumDevices].currentAddr = device;
- /* These will be set correctly in adbsys.c */
- /* Until then, unsol. data will be ignored. */
- ADBDevTable[ADBNumDevices].DataAreaAddr =
- (long)0;
- ADBDevTable[ADBNumDevices].ServiceRtPtr =
- (void *)0;
- /* find next unused address */
- for (x = saveptr; x > 0; x--) {
- if (-1 == get_adb_info(&data, x)) {
- saveptr = x;
- break;
- }
- }
- if (x == 0)
- saveptr = 0;
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("new free is 0x%02x\n",
- saveptr);
-#endif
- nonewtimes = 0;
- } else {
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("moving back...\n");
-#endif
- /* move old device back */
- command = ADBLISTEN(saveptr, 3);
- send_string[0] = 2;
- send_string[1] = (u_char)(device | 0x60);
- send_string[2] = 0xfe;
- adb_op_sync((Ptr)send_string, (Ptr)0,
- (Ptr)0, (short)command);
- delay(1000);
- }
- }
- }
-
-#ifdef ADB_DEBUG
- if (adb_debug) {
- for (i = 1; i <= ADBNumDevices; i++) {
- x = get_ind_adb_info(&data, i);
- if (x != -1)
- printf_intr("index 0x%x, addr 0x%x, type 0x%x\n",
- i, x, data.devType);
- }
- }
-#endif
-
-#ifdef ADB_DEBUG
- if (adb_debug) {
- if (0 == ADBNumDevices) /* tell user if no devices found */
- printf_intr("adb: no devices found\n");
- }
-#endif
-
- adbStarting = 0; /* not starting anymore */
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf_intr("adb: ADBReInit complete\n");
-#endif
-
- if (adbHardware == ADB_HW_CUDA) {
- timeout_set(&adb_cuda_timeout, (void *)adb_cuda_tickle, NULL);
- timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS);
- }
-
- if (adbHardware != ADB_HW_PMU) /* ints must be on for PB? */
- splx(s);
-}
-
-
-/*
- * adb_cmd_result
- *
- * This routine lets the caller know whether the specified adb command string
- * should expect a returned result, such as a TALK command.
- *
- * returns: 0 if a result should be expected
- * 1 if a result should NOT be expected
- */
-int
-adb_cmd_result(u_char *in)
-{
- switch (adbHardware) {
- case ADB_HW_CUDA:
- /* was it an ADB talk command? */
- if ((in[1] == 0x00) && ((in[2] & 0x0c) == 0x0c))
- return 0;
- /* was it an RTC/PRAM read date/time? */
- if ((in[1] == 0x01) && (in[2] == 0x03))
- return 0;
- return 1;
-
- case ADB_HW_PMU:
- return 1;
-
- default:
- return 1;
- }
-}
-
-
-/*
- * adb_op_sync
- *
- * This routine does exactly what the adb_op routine does, except that after
- * the adb_op is called, it waits until the return value is present before
- * returning.
- *
- * NOTE: The user specified compRout is ignored, since this routine specifies
- * it's own to adb_op, which is why you really called this in the first place
- * anyway.
- */
-int
-adb_op_sync(Ptr buffer, Ptr compRout, Ptr data, short command)
-{
- int tmout;
- int result;
- volatile int flag = 0;
-
- result = adb_op(buffer, (void *)adb_op_comprout,
- (void *)&flag, command); /* send command */
- if (result == 0) { /* send ok? */
- /*
- * Total time to wait is calculated as follows:
- * - Tlt (stop to start time): 260 usec
- * - start bit: 100 usec
- * - up to 8 data bytes: 64 * 100 usec = 6400 usec
- * - stop bit (with SRQ): 140 usec
- * Total: 6900 usec
- *
- * This is the total time allowed by the specification. Any
- * device that doesn't conform to this will fail to operate
- * properly on some Apple systems. In spite of this we
- * double the time to wait; some Cuda-based apparently
- * queues some commands and allows the main CPU to continue
- * processing (radical concept, eh?). To be safe, allow
- * time for two complete ADB transactions to occur.
- */
- for (tmout = 13800; !flag && tmout >= 10; tmout -= 10)
- delay(10);
- if (!flag && tmout > 0)
- delay(tmout);
-
- if (!flag)
- result = -2;
- }
-
- return result;
-}
-
-
-/*
- * adb_op_comprout
- *
- * This function is used by the adb_op_sync routine so it knows when the
- * function is done.
- */
-void
-adb_op_comprout(buffer, compdata, cmd)
- caddr_t buffer, compdata;
- int cmd;
-{
- short *p = (short *)compdata;
-
- *p = 1;
-}
-
-void
-adb_setup_hw_type(void)
-{
- switch (adbHardware) {
- case ADB_HW_CUDA:
- adbSoftPower = 1;
- return;
-
- case ADB_HW_PMU:
- adbSoftPower = 1;
- pm_setup_adb();
- return;
-
- default:
- panic("unknown adb hardware");
- }
-}
-
-int
-count_adbs(void)
-{
- int i;
- int found;
-
- found = 0;
-
- for (i = 1; i < 16; i++)
- if (0 != ADBDevTable[i].devType)
- found++;
-
- return found;
-}
-
-int
-get_ind_adb_info(ADBDataBlock * info, int index)
-{
- if ((index < 1) || (index > 15)) /* check range 1-15 */
- return (-1);
-
-#ifdef ADB_DEBUG
- if (adb_debug & 0x80)
- printf_intr("index 0x%x devType is: 0x%x\n", index,
- ADBDevTable[index].devType);
-#endif
- if (0 == ADBDevTable[index].devType) /* make sure it's a valid entry */
- return (-1);
-
- info->devType = ADBDevTable[index].devType;
- info->origADBAddr = ADBDevTable[index].origAddr;
- info->dbServiceRtPtr = (Ptr)ADBDevTable[index].ServiceRtPtr;
- info->dbDataAreaAddr = (Ptr)ADBDevTable[index].DataAreaAddr;
-
- return (ADBDevTable[index].currentAddr);
-}
-
-int
-get_adb_info(ADBDataBlock * info, int adbAddr)
-{
- int i;
-
- if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */
- return (-1);
-
- for (i = 1; i < 15; i++)
- if (ADBDevTable[i].currentAddr == adbAddr) {
- info->devType = ADBDevTable[i].devType;
- info->origADBAddr = ADBDevTable[i].origAddr;
- info->dbServiceRtPtr = (Ptr)ADBDevTable[i].ServiceRtPtr;
- info->dbDataAreaAddr = ADBDevTable[i].DataAreaAddr;
- return 0; /* found */
- }
-
- return (-1); /* not found */
-}
-
-int
-set_adb_info(ADBSetInfoBlock * info, int adbAddr)
-{
- int i;
-
- if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */
- return (-1);
-
- for (i = 1; i < 15; i++)
- if (ADBDevTable[i].currentAddr == adbAddr) {
- ADBDevTable[i].ServiceRtPtr =
- (void *)(info->siServiceRtPtr);
- ADBDevTable[i].DataAreaAddr = info->siDataAreaAddr;
- return 0; /* found */
- }
-
- return (-1); /* not found */
-
-}
-
-/* caller should really use machine-independent version: getPramTime */
-/* this version does pseudo-adb access only */
-int
-adb_read_date_time(time_t *time)
-{
- u_char output[ADB_MAX_MSG_LENGTH];
- int result;
- int retcode;
- volatile int flag = 0;
-
- switch (adbHardware) {
- case ADB_HW_PMU:
- pm_read_date_time(time);
- retcode = 0;
- break;
-
- case ADB_HW_CUDA:
- output[0] = 0x02; /* 2 byte message */
- output[1] = 0x01; /* to pram/rtc device */
- output[2] = 0x03; /* read date/time */
- result = send_adb_cuda((u_char *)output, (u_char *)output,
- (void *)adb_op_comprout, (void *)&flag, (int)0);
- if (result != 0) { /* exit if not sent */
- retcode = -1;
- break;
- }
-
- while (0 == flag) /* wait for result */
- ;
-
- delay(20); /* completion occurs too soon? */
- memcpy(time, output + 1, 4);
- retcode = 0;
- break;
-
- case ADB_HW_UNKNOWN:
- default:
- retcode = -1;
- break;
- }
- if (retcode == 0) {
-#define DIFF19041970 2082844800
- *time -= DIFF19041970;
-
- } else {
- *time = 0;
- }
- return retcode;
-}
-
-/* caller should really use machine-independent version: setPramTime */
-/* this version does pseudo-adb access only */
-int
-adb_set_date_time(time_t time)
-{
- u_char output[ADB_MAX_MSG_LENGTH];
- int result;
- volatile int flag = 0;
-
- time += DIFF19041970;
- switch (adbHardware) {
-
- case ADB_HW_CUDA:
- output[0] = 0x06; /* 6 byte message */
- output[1] = 0x01; /* to pram/rtc device */
- output[2] = 0x09; /* set date/time */
- output[3] = (u_char)(time >> 24);
- output[4] = (u_char)(time >> 16);
- output[5] = (u_char)(time >> 8);
- output[6] = (u_char)(time);
- result = send_adb_cuda((u_char *)output, (u_char *)0,
- (void *)adb_op_comprout, (void *)&flag, (int)0);
- if (result != 0) /* exit if not sent */
- return -1;
-
- while (0 == flag) /* wait for send to finish */
- ;
-
- return 0;
-
- case ADB_HW_PMU:
- pm_set_date_time(time);
- return 0;
-
- default:
- return -1;
- }
-}
-
-
-int
-adb_poweroff(void)
-{
- u_char output[ADB_MAX_MSG_LENGTH];
- int result;
-
- if (!adbSoftPower)
- return -1;
-
- adb_polling = 1;
-
- switch (adbHardware) {
- case ADB_HW_PMU:
- pm_adb_poweroff();
-
- for (;;); /* wait for power off */
-
- return 0;
-
- case ADB_HW_CUDA:
- output[0] = 0x02; /* 2 byte message */
- output[1] = 0x01; /* to pram/rtc/soft-power device */
- output[2] = 0x0a; /* set date/time */
- result = send_adb_cuda((u_char *)output, (u_char *)0,
- (void *)0, (void *)0, (int)0);
- if (result != 0) /* exit if not sent */
- return -1;
-
- for (;;); /* wait for power off */
-
- return 0;
-
- default:
- return -1;
- }
-}
-
-int
-CountADBs(void)
-{
- return (count_adbs());
-}
-
-void
-ADBReInit(void)
-{
- adb_reinit();
-}
-
-int
-GetIndADB(ADBDataBlock * info, int index)
-{
- return (get_ind_adb_info(info, index));
-}
-
-int
-SetADBInfo(ADBSetInfoBlock * info, int adbAddr)
-{
- return (set_adb_info(info, adbAddr));
-}
-
-void
-setsoftadb()
-{
- if (!timeout_initialized(&adb_softintr_timeout))
- timeout_set(&adb_softintr_timeout, (void *)adb_soft_intr, NULL);
- timeout_add(&adb_softintr_timeout, 1);
-}
-
-void
-adb_cuda_autopoll()
-{
- volatile int flag = 0;
- int result;
- u_char output[16];
-
- output[0] = 0x03; /* 3-byte message */
- output[1] = 0x01; /* to pram/rtc device */
- output[2] = 0x01; /* cuda autopoll */
- output[3] = 0x01;
- result = send_adb_cuda(output, output, adb_op_comprout,
- (void *)&flag, 0);
- if (result != 0) /* exit if not sent */
- return;
-
- while (flag == 0); /* wait for result */
-}
-
-void
-adb_restart()
-{
- int result;
- u_char output[16];
-
- adb_polling = 1;
-
- switch (adbHardware) {
- case ADB_HW_CUDA:
- output[0] = 0x02; /* 2 byte message */
- output[1] = 0x01; /* to pram/rtc/soft-power device */
- output[2] = 0x11; /* restart */
- result = send_adb_cuda((u_char *)output, (u_char *)0,
- (void *)0, (void *)0, (int)0);
- if (result != 0) /* exit if not sent */
- return;
- while (1); /* not return */
-
- case ADB_HW_PMU:
- pm_adb_restart();
- while (1); /* not return */
- }
-}
diff --git a/sys/arch/macppc/dev/adbvar.h b/sys/arch/macppc/dev/adbvar.h
index 23fccd06e35..06b63af60e3 100644
--- a/sys/arch/macppc/dev/adbvar.h
+++ b/sys/arch/macppc/dev/adbvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: adbvar.h,v 1.7 2005/12/22 22:55:25 miod Exp $ */
+/* $OpenBSD: adbvar.h,v 1.8 2006/01/18 23:21:17 miod Exp $ */
/* $NetBSD: adbvar.h,v 1.3 2000/06/08 22:10:46 tsubai Exp $ */
/*-
@@ -31,67 +31,19 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#include <machine/adbsys.h>
-
-/*
- * Arguments used to attach a device to the Apple Desktop Bus
- */
-struct adb_attach_args {
- int origaddr;
- int adbaddr;
- int handler_id;
-};
-
-#ifdef DEBUG
-#ifndef ADB_DEBUG
-#define ADB_DEBUG
-#endif
-#endif
-
-extern int adb_polling; /* Are we polling? (Debugger mode) */
-#ifdef ADB_DEBUG
-extern int adb_debug;
-#endif
-
-typedef caddr_t Ptr;
-
-/* ADB Manager */
-typedef struct {
- Ptr siServiceRtPtr;
- Ptr siDataAreaAddr;
-} ADBSetInfoBlock;
-typedef struct {
- unsigned char devType;
- unsigned char origADBAddr;
- Ptr dbServiceRtPtr;
- Ptr dbDataAreaAddr;
-} ADBDataBlock;
-
struct adb_softc {
struct device sc_dev;
char *sc_regbase;
};
-/* adb_direct.c */
extern int adbHardware;
-/* types of adb hardware that we (will eventually) support */
+/* types of adb hardware that we support */
#define ADB_HW_UNKNOWN 0x01 /* don't know */
#define ADB_HW_PMU 0x04 /* PowerBook series */
#define ADB_HW_CUDA 0x05 /* Machines with a Cuda chip */
-#define ADB_CMDADDR(cmd) ((u_int8_t)((cmd) & 0xf0) >> 4)
-#define ADBFLUSH(dev) ((((u_int8_t)(dev) & 0x0f) << 4) | 0x01)
-#define ADBLISTEN(dev, reg) ((((u_int8_t)(dev) & 0x0f) << 4) | 0x08 | (reg))
-#define ADBTALK(dev, reg) ((((u_int8_t)(dev) & 0x0f) << 4) | 0x0c | (reg))
-
int adb_poweroff(void);
-int CountADBs(void);
-void ADBReInit(void);
-int GetIndADB(ADBDataBlock * info, int index);
-int SetADBInfo(ADBSetInfoBlock * info, int adbAddr);
+void adb_restart(void);
int adb_read_date_time(time_t *t);
int adb_set_date_time(time_t t);
-int adb_intr(void *arg);
-void adb_cuda_autopoll(void);
-int adb_op_sync(Ptr, Ptr, Ptr, short);
diff --git a/sys/arch/macppc/dev/amsvar.h b/sys/arch/macppc/dev/akbd_machdep.c
index 51fe68b6671..cd963894856 100644
--- a/sys/arch/macppc/dev/amsvar.h
+++ b/sys/arch/macppc/dev/akbd_machdep.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: amsvar.h,v 1.2 2002/03/14 01:26:36 millert Exp $ */
-/* $NetBSD: amsvar.h,v 1.4 1999/06/17 06:59:05 tsubai Exp $ */
+/* $OpenBSD: akbd_machdep.c,v 1.1 2006/01/18 23:21:17 miod Exp $ */
+/* $NetBSD: akbd.c,v 1.13 2001/01/25 14:08:55 tsubai Exp $ */
/*
* Copyright (C) 1998 Colin Wood
@@ -31,37 +31,77 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _MACPPC_AMSVAR_H_
-#define _MACPPC_AMSVAR_H_
+#include <sys/param.h>
+#include <sys/timeout.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/fcntl.h>
+#include <sys/poll.h>
+#include <sys/selinfo.h>
+#include <sys/proc.h>
+#include <sys/signalvar.h>
+#include <sys/systm.h>
-/*
- * State info, per mouse instance.
- */
-struct ams_softc {
- struct device sc_dev;
-
- /* ADB info */
- int origaddr; /* ADB device type (ADBADDR_MS) */
- int adbaddr; /* current ADB address */
- int handler_id; /* type of mouse */
-
- /* Extended Mouse Protocol info, faked for non-EMP mice */
- u_int8_t sc_class; /* mouse class (mouse, trackball) */
- u_int8_t sc_buttons; /* number of buttons */
- u_int32_t sc_res; /* mouse resolution (dpi) */
- char sc_devid[5]; /* device indentifier */
-
- int sc_mb; /* current button state */
- struct device *sc_wsmousedev;
+#include <dev/wscons/wsconsio.h>
+#include <dev/wscons/wskbdvar.h>
+
+#include <dev/adb/adb.h>
+#include <dev/adb/akbdvar.h>
+#include <dev/adb/keyboard.h>
+
+void akbd_cngetc(void *, u_int *, int *);
+void akbd_cnpollc(void *, int);
+
+struct wskbd_consops akbd_consops = {
+ akbd_cngetc,
+ akbd_cnpollc,
};
-/* EMP device classes */
-#define MSCLASS_TABLET 0
-#define MSCLASS_MOUSE 1
-#define MSCLASS_TRACKBALL 2
-#define MSCLASS_TRACKPAD 3
+static int _akbd_is_console;
+
+int
+akbd_is_console()
+{
+ return (_akbd_is_console);
+}
+
+int
+akbd_cnattach()
+{
+ _akbd_is_console = 1;
+ wskbd_cnattach(&akbd_consops, NULL, &akbd_keymapdata);
+ return 0;
+}
+
+void
+akbd_cngetc(void *v, u_int *type, int *data)
+{
+ int key, press, val;
+ int s;
+ extern int adb_intr(void *);
+
+ s = splhigh();
+
+ adb_polledkey = -1;
+ adb_polling = 1;
+
+ while (adb_polledkey == -1) {
+ adb_intr(NULL); /* adb does not use the argument */
+ DELAY(10000); /* XXX */
+ }
+
+ adb_polling = 0;
+ splx(s);
+
+ key = adb_polledkey;
+ press = ADBK_PRESS(key);
+ val = ADBK_KEYVAL(key);
-void ms_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command);
-void ms_handoff(adb_event_t *event, struct ams_softc *);
+ *data = val;
+ *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
+}
-#endif /* _MACPPC_AMSVAR_H_ */
+void
+akbd_cnpollc(void *v, int on)
+{
+}
diff --git a/sys/arch/macppc/dev/akbdmap.h b/sys/arch/macppc/dev/akbdmap.h
deleted file mode 100644
index 3638f85fe57..00000000000
--- a/sys/arch/macppc/dev/akbdmap.h
+++ /dev/null
@@ -1,453 +0,0 @@
-/* $OpenBSD: akbdmap.h,v 1.12 2005/05/07 15:04:59 miod Exp $ */
-/* $NetBSD: akbdmap.h,v 1.3 2000/09/01 16:00:39 tsubai Exp $ */
-
-/*-
- * Copyright (c) 1997 The NetBSD Foundation, Inc.
- * All rights reserved.
- *
- * This code is derived from software contributed to The NetBSD Foundation
- * by Juergen Hannken-Illjes.
- *
- * 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.
- */
-
-/* XXX This list is incomplete. */
-
-#define KC(n) KS_KEYCODE(n)
-
-static const keysym_t akbd_keydesc_us[] = {
-/* pos command normal shifted */
- KC(0), KS_a,
- KC(1), KS_s,
- KC(2), KS_d,
- KC(3), KS_f,
- KC(4), KS_h,
- KC(5), KS_g,
- KC(6), KS_z,
- KC(7), KS_x,
- KC(8), KS_c,
- KC(9), KS_v,
-
- KC(11), KS_b,
- KC(12), KS_q,
- KC(13), KS_w,
- KC(14), KS_e,
- KC(15), KS_r,
- KC(16), KS_y,
- KC(17), KS_t,
- KC(18), KS_1, KS_exclam,
- KC(19), KS_2, KS_at,
- KC(20), KS_3, KS_numbersign,
- KC(21), KS_4, KS_dollar,
- KC(22), KS_6, KS_asciicircum,
- KC(23), KS_5, KS_percent,
- KC(24), KS_equal, KS_plus,
- KC(25), KS_9, KS_parenleft,
- KC(26), KS_7, KS_ampersand,
- KC(27), KS_minus, KS_underscore,
- KC(28), KS_8, KS_asterisk,
- KC(29), KS_0, KS_parenright,
- KC(30), KS_bracketright, KS_braceright,
- KC(31), KS_o,
- KC(32), KS_u,
- KC(33), KS_bracketleft, KS_braceleft,
- KC(34), KS_i,
- KC(35), KS_p,
- KC(36), KS_Return,
- KC(37), KS_l,
- KC(38), KS_j,
- KC(39), KS_apostrophe, KS_quotedbl,
- KC(40), KS_k,
- KC(41), KS_semicolon, KS_colon,
- KC(42), KS_backslash, KS_bar,
- KC(43), KS_comma, KS_less,
- KC(44), KS_slash, KS_question,
- KC(45), KS_n,
- KC(46), KS_m,
- KC(47), KS_period, KS_greater,
- KC(48), KS_Tab,
- KC(49), KS_space,
- KC(50), KS_grave, KS_asciitilde,
- KC(51), KS_Delete,
-
- KC(53), KS_Escape,
- KC(54), KS_Control_L,
- KC(55), KS_Cmd, /* Command */
- KC(56), KS_Shift_L,
- KC(57), KS_Caps_Lock,
- KC(58), KS_Cmd1, /* Option */
- KC(59), KS_Left,
- KC(60), KS_Right,
- KC(61), KS_Down,
- KC(62), KS_Up,
-
- KC(65), KS_KP_Decimal,
- KC(67), KS_KP_Multiply,
- KC(69), KS_KP_Add,
- KC(71), KS_Clear,
- KC(75), KS_KP_Divide,
- KC(76), KS_KP_Enter,
- KC(78), KS_KP_Subtract,
-
- KC(81), KS_KP_Equal,
- KC(82), KS_KP_0,
- KC(83), KS_KP_1,
- KC(84), KS_KP_2,
- KC(85), KS_KP_3,
- KC(86), KS_KP_4,
- KC(87), KS_KP_5,
- KC(88), KS_KP_6,
- KC(89), KS_KP_7,
-
- KC(91), KS_KP_8,
- KC(92), KS_KP_9,
-
- KC(95), KS_comma, /* XXX KS_KP_comma */
-
- KC(106), KS_KP_Enter,
-
- KC(115), KS_KP_Home,
- KC(116), KS_KP_Prior,
- KC(119), KS_KP_End,
- KC(121), KS_KP_Next,
-
- KC(127), KS_Cmd_Debugger,
-};
-
-static const keysym_t akbd_keydesc_fr[] = {
-/* pos normal shifted altgr shift-altgr */
- KC(0), KS_q,
- KC(1), KS_s, KS_S, KS_Ograve,
- KC(4), KS_h, KS_H, KS_Igrave, KS_Icircumflex,
- KC(6), KS_w,
- KC(10), KS_at, KS_numbersign,
- KC(11), KS_b, KS_B, KS_ssharp,
- KC(12), KS_a, KS_A, KS_ae, KS_AE,
- KC(13), KS_z, KS_Z, KS_Acircumflex, KS_Aring,
- KC(14), KS_e, KS_E, KS_ecircumflex, KS_Ecircumflex,
- KC(15), KS_r, KS_R, KS_registered, KS_comma,
- KC(16), KS_y, KS_Y, KS_Uacute,
- KC(18), KS_ampersand, KS_1,
- KC(19), KS_eacute, KS_2, KS_ediaeresis,
- KC(20), KS_quotedbl, KS_3,
- KC(21), KS_apostrophe, KS_4,
- KC(22), KS_section, KS_6,
- KC(23), KS_parenleft, KS_5, KS_braceleft, KS_bracketleft,
- KC(24), KS_minus, KS_underscore,
- KC(25), KS_ccedilla, KS_9, KS_Ccedilla, KS_Aacute,
- KC(26), KS_egrave, KS_7, KS_guillemotleft,
- KS_guillemotright,
- KC(27), KS_parenright, KS_degree, KS_braceright, KS_bracketright,
- KC(28), KS_exclam, KS_8, KS_exclamdown, KS_Ucircumflex,
- KC(29), KS_agrave, KS_0, KS_oslash, KS_Ooblique,
- KC(30), KS_dollar, KS_asterisk, KS_cent, KS_yen,
- KC(33), KS_dead_circumflex, KS_dead_diaeresis,
- KS_ocircumflex, KS_Ocircumflex,
- KC(34), KS_i, KS_I, KS_icircumflex, KS_idiaeresis,
- KC(37), KS_l, KS_L, KS_voidSymbol, KS_bar,
- KC(38), KS_j, KS_J, KS_Idiaeresis, KS_Iacute,
- KC(39), KS_ugrave, KS_percent, KS_Ugrave,
- KC(40), KS_k, KS_K, KS_Egrave, KS_Ediaeresis,
- KC(41), KS_m, KS_M, KS_mu, KS_Oacute,
- KC(42), KS_grave, KS_sterling, KS_at, KS_numbersign,
- KC(43), KS_semicolon, KS_period,
- KC(44), KS_equal, KS_plus,
- KC(45), KS_n, KS_N, KS_asciitilde,
- KC(46), KS_comma, KS_question, KS_voidSymbol, KS_questiondown,
- KC(47), KS_colon, KS_slash, KS_voidSymbol, KS_backslash,
- KC(50), KS_less, KS_greater,
- KC(52), KS_Alt_R,
- KC(55), KS_Meta_L, /* Command */
- KC(58), KS_Mode_switch, KS_Multi_key, /* Option */
-};
-
-#if 0
-static const keysym_t akbd_keydesc_jp[] = {
-/* pos command normal shifted */
- KC(42), KS_grave, KS_asciitilde,
- KC(93), KS_backslash, KS_bar,
-};
-#endif
-
-static const keysym_t akbd_keydesc_uk[] = {
-/* pos normal shifted altgr shift-altgr */
- KC(10), KS_section, KS_plusminus,
- KC(20), KS_3, KS_sterling, KS_numbersign,
- KC(52), KS_KP_Enter,
- KC(58), KS_Mode_switch, KS_Multi_key, /* Option */
-};
-
-static const keysym_t akbd_keydesc_sv[] = {
-/* pos normal shifted altgr shift-altgr */
- KC(10), KS_section, KS_degree,
- KC(19), KS_2, KS_quotedbl, KS_at,
- KC(21), KS_4, KS_dollar,
- KC(22), KS_6, KS_ampersand,
- KC(24), KS_dead_acute, KS_dead_grave,
- KC(25), KS_9, KS_parenright, KS_bracketright,
- KC(26), KS_7, KS_slash, KS_braceleft,
- KC(27), KS_plus, KS_question, KS_backslash,
- KC(28), KS_8, KS_parenleft, KS_bracketleft,
- KC(29), KS_0, KS_equal, KS_braceright,
- KC(30), KS_dead_diaeresis, KS_dead_circumflex, KS_dead_tilde,
- KC(33), KS_aring,
- KC(39), KS_adiaeresis,
- KC(41), KS_odiaeresis,
- KC(42), KS_apostrophe, KS_asterisk,
- KC(43), KS_comma, KS_semicolon,
- KC(44), KS_minus, KS_underscore,
- KC(47), KS_period, KS_colon,
- KC(50), KS_less, KS_greater, KS_bar,
- KC(52), KS_Mode_switch, KS_Multi_key,
-};
-
-static const keysym_t akbd_keydesc_sv_nodead[] = {
-/* pos normal shifted altgr shift-altgr */
- KC(24), KS_apostrophe, KS_grave,
- KC(30), KS_diaeresis, KS_asciicircum, KS_asciitilde,
-};
-
-static const keysym_t akbd_keydesc_de[] = {
-/* pos normal shifted altgr shift-altgr */
- KC(0), KS_a, KS_A, KS_aring, KS_Aring,
- KC(1), KS_s, KS_S, KS_voidSymbol, KS_Iacute,
- KC(3), KS_f, KS_F, KS_voidSymbol, KS_Idiaeresis,
- KC(4), KS_h, KS_H, KS_ordfeminine, KS_Oacute,
- KC(5), KS_g, KS_G, KS_copyright, KS_Igrave,
- KC(6), KS_y, KS_Y, KS_yen,
- KC(7), KS_x, KS_X, KS_voidSymbol, KS_Ugrave,
- KC(8), KS_c, KS_C, KS_ccedilla, KS_Ccedilla,
- KC(10), KS_dead_circumflex, KS_degree,
- KC(12), KS_q, KS_Q, KS_guillemotleft, KS_guillemotright,
- KC(15), KS_r, KS_R, KS_registered, KS_cedilla,
- KC(16), KS_z, KS_Z,
- KC(18), KS_1, KS_exclam, KS_exclamdown, KS_notsign,
- KC(19), KS_2, KS_quotedbl,
- KC(20), KS_3, KS_section, KS_paragraph, KS_numbersign,
- KC(21), KS_4, KS_dollar, KS_cent, KS_sterling,
- KC(22), KS_6, KS_ampersand, KS_bracketright,KS_dead_circumflex,
- KC(23), KS_5, KS_percent, KS_bracketleft,
- KC(24), KS_dead_acute, KS_dead_grave, KS_apostrophe,
- KC(25), KS_9, KS_parenright, KS_braceright, KS_periodcentered,
- KC(26), KS_7, KS_slash, KS_bar, KS_backslash,
- KC(27), KS_ssharp, KS_question, KS_questiondown,
- KC(28), KS_8, KS_parenleft, KS_braceleft,
- KC(29), KS_0, KS_equal, KS_voidSymbol, KS_macron,
- KC(30), KS_plus, KS_asterisk, KS_plusminus,
- KC(31), KS_o, KS_O, KS_oslash, KS_Ooblique,
- KC(32), KS_u, KS_U, KS_dead_diaeresis, KS_Aacute,
- KC(33), KS_udiaeresis, KS_Udiaeresis, KS_voidSymbol, KS_degree,
- KC(34), KS_i, KS_I, KS_voidSymbol, KS_Ucircumflex,
- KC(37), KS_l, KS_L, KS_at,
- KC(38), KS_j, KS_J, KS_masculine,
- KC(39), KS_adiaeresis, KS_Adiaeresis, KS_ae, KS_AE,
- KC(41), KS_odiaeresis, KS_Odiaeresis,
- KC(42), KS_numbersign, KS_apostrophe,
- KC(43), KS_comma, KS_semicolon,
- KC(44), KS_minus, KS_underscore,
- KC(45), KS_n, KS_N, KS_dead_tilde,
- KC(46), KS_m, KS_M, KS_mu,
- KC(47), KS_period, KS_colon,
- KC(50), KS_less, KS_greater,
- KC(52), KS_Multi_key,
- KC(58), KS_Mode_switch,
-};
-
-static const keysym_t akbd_keydesc_de_nodead[] = {
-/* pos normal shifted altgr shift-altgr */
- KC(10), KS_asciicircum, KS_degree,
- KC(22), KS_6, KS_ampersand, KS_bracketright,KS_asciicircum,
- KC(24), KS_acute, KS_grave, KS_apostrophe,
- KC(32), KS_u, KS_U, KS_diaeresis, KS_Aacute,
- KC(45), KS_n, KS_N, KS_asciitilde,
-};
-
-static const keysym_t akbd_keydesc_sf[] = {
- KC(6), KS_y,
- KC(10), KS_paragraph, KS_degree,
- KC(16), KS_z,
- KC(18), KS_plus, KS_1,
- KC(19), KS_quotedbl, KS_2,
- KC(20), KS_asterisk, KS_3,
- KC(21), KS_ccedilla, KS_4, KS_Ccedilla,
- KC(22), KS_ampersand, KS_6,
- KC(23), KS_percent, KS_5,
- KC(24), KS_dead_circumflex, KS_grave,
- KC(25), KS_parenright, KS_9,
- KC(26), KS_slash, KS_7,
- KC(27), KS_apostrophe, KS_question,
- KC(28), KS_parenleft, KS_8,
- KC(29), KS_equal, KS_0,
- KC(30), KS_dead_diaeresis, KS_exclam,
- KC(33), KS_egrave, KS_udiaeresis,
- KC(39), KS_agrave, KS_adiaeresis,
- KC(41), KS_eacute, KS_odiaeresis,
- KC(42), KS_dollar, KS_sterling,
- KC(43), KS_period, KS_colon,
- KC(46), KS_comma, KS_semicolon,
- KC(47), KS_minus, KS_underscore,
- KC(50), KS_less, KS_greater,
-};
-
-static const keysym_t akbd_keydesc_us_dvorak[] = {
-/* pos command normal shifted */
- KC(1), KS_o,
- KC(2), KS_e,
- KC(3), KS_u,
- KC(4), KS_d,
- KC(5), KS_i,
- KC(6), KS_semicolon, KS_colon,
- KC(7), KS_q,
- KC(8), KS_j,
- KC(9), KS_k,
- KC(11), KS_x,
- KC(12), KS_apostrophe, KS_quotedbl,
- KC(13), KS_comma, KS_less,
- KC(14), KS_period, KS_greater,
- KC(15), KS_p,
- KC(16), KS_f,
- KC(17), KS_y,
- KC(24), KS_bracketright, KS_braceright,
- KC(27), KS_bracketleft, KS_braceleft,
- KC(30), KS_equal, KS_plus,
- KC(31), KS_r,
- KC(32), KS_g,
- KC(33), KS_slash, KS_question,
- KC(34), KS_c,
- KC(35), KS_l,
- KC(37), KS_n,
- KC(38), KS_h,
- KC(39), KS_minus, KS_underscore,
- KC(40), KS_t,
- KC(41), KS_s,
- KC(43), KS_w,
- KC(44), KS_z,
- KC(45), KS_b,
- KC(47), KS_v,
-};
-
-static const keysym_t akbd_keydesc_sg[] = {
-/* pos normal shifted altgr shift-altgr */
- KC(0), KS_a, KS_A, KS_aring, KS_Aring,
- KC(1), KS_s, KS_S, KS_ssharp, KS_voidSymbol,
- KC(3), KS_f, KS_F, KS_section, KS_voidSymbol,
- KC(4), KS_h, KS_H, KS_ordfeminine, KS_periodcentered,
- KC(5), KS_g, KS_G, KS_at, KS_comma,
- KC(6), KS_y, KS_Y, KS_yen, KS_ydiaeresis,
- KC(7), KS_x, KS_X, KS_voidSymbol, KS_ydiaeresis,
- KC(8), KS_c, KS_C, KS_copyright,
- KC(10), KS_section, KS_degree,
- KC(12), KS_q, KS_Q,
- KC(15), KS_r, KS_R, KS_registered, KS_Egrave,
- KC(16), KS_z, KS_Z, KS_voidSymbol, KS_Aacute,
- KC(18), KS_1, KS_plus, KS_plusminus, KS_onesuperior,
- KC(19), KS_2, KS_quotedbl, KS_twosuperior,
- KC(20), KS_3, KS_asterisk, KS_numbersign, KS_threesuperior,
- KC(21), KS_4, KS_ccedilla, KS_Ccedilla,
- KC(22), KS_6, KS_ampersand, KS_bracketright,
- KC(23), KS_5, KS_percent, KS_bracketleft,
- KC(24), KS_dead_circumflex,KS_dead_grave,KS_dead_acute, KS_asciitilde,
- KC(25), KS_9, KS_parenright, KS_braceright, KS_Ocircumflex,
- KC(26), KS_7, KS_slash, KS_bar, KS_backslash,
- KC(27), KS_apostrophe, KS_question, KS_questiondown,
- KC(28), KS_8, KS_parenleft, KS_braceleft, KS_Ograve,
- KC(29), KS_0, KS_equal, KS_voidSymbol, KS_Uacute,
- KC(30), KS_dead_diaeresis,KS_exclam, KS_bracketright,
- KC(31), KS_o, KS_O, KS_oslash,
- KC(32), KS_u, KS_U, KS_degree, KS_Ugrave,
- KC(33), KS_udiaeresis, KS_egrave, KS_bracketleft,
- KC(34), KS_i, KS_I, KS_exclamdown,
- KC(37), KS_l, KS_L, KS_notsign,
- KC(38), KS_j, KS_J, KS_masculine,
- KC(39), KS_adiaeresis, KS_agrave, KS_ae, KS_AE,
- KC(41), KS_odiaeresis, KS_eacute, KS_cent,
- KC(42), KS_dollar, KS_sterling, KS_paragraph,
- KC(43), KS_comma, KS_semicolon, KS_guillemotleft,KS_guillemotright,
- KC(44), KS_minus, KS_underscore,
- KC(45), KS_n, KS_N, KS_dead_tilde,
- KC(46), KS_m, KS_M, KS_mu,
- KC(47), KS_period, KS_colon, KS_voidSymbol, KS_division,
- KC(50), KS_less, KS_greater,
- KC(52), KS_Multi_key,
- KC(58), KS_Mode_switch,
-};
-
-static const keysym_t akbd_keydesc_sg_nodead[] = {
-/* pos normal shifted altgr shift-altgr */
- KC(24), KS_asciicircum, KS_grave, KS_acute, KS_asciitilde,
- KC(30), KS_diaeresis, KS_exclam, KS_bracketright,KS_braceright,
- KC(45), KS_n, KS_N, KS_asciitilde,
-};
-
-static const keysym_t akbd_keydesc_pt[] = {
-/* pos normal shifted altgr shift-altgr */
- KC(7), KS_x, KS_X, KS_guillemotleft, KS_guillemotright,
- KC(10), KS_section, KS_plusminus,
- KC(19), KS_2, KS_quotedbl, KS_at,
- KC(20), KS_3, KS_numbersign, KS_sterling,
- KC(22), KS_6, KS_ampersand,
- KC(24), KS_plus, KS_asterisk,
- KC(25), KS_9, KS_parenright, KS_bracketright, KS_braceright,
- KC(26), KS_7, KS_slash,
- KC(27), KS_apostrophe, KS_question,
- KC(28), KS_8, KS_parenleft, KS_bracketleft, KS_braceleft,
- KC(29), KS_0, KS_equal,
- KC(30), KS_dead_acute, KS_dead_grave,
- KC(33), KS_masculine, KS_ordfeminine,
- KC(39), KS_dead_tilde, KS_dead_circumflex,
- KC(41), KS_ccedilla, KS_Ccedilla,
- KC(43), KS_comma, KS_semicolon,
- KC(44), KS_minus, KS_underscore,
- KC(47), KS_period, KS_colon,
- KC(50), KS_less, KS_greater,
- KC(52), KS_Multi_key,
- KC(58), KS_Mode_switch,
-};
-
-#define KBD_MAP(name, base, map) \
- { name, base, sizeof(map)/sizeof(keysym_t), map }
-
-const struct wscons_keydesc akbd_keydesctab[] = {
- KBD_MAP(KB_US, 0, akbd_keydesc_us),
- KBD_MAP(KB_US | KB_DVORAK, KB_US, akbd_keydesc_us_dvorak),
- KBD_MAP(KB_FR, KB_US, akbd_keydesc_fr),
- KBD_MAP(KB_SF, KB_US, akbd_keydesc_sf),
- KBD_MAP(KB_SV, KB_US, akbd_keydesc_sv),
- KBD_MAP(KB_SV | KB_NODEAD, KB_SV, akbd_keydesc_sv_nodead),
- KBD_MAP(KB_DE, KB_US, akbd_keydesc_de),
- KBD_MAP(KB_DE | KB_NODEAD, KB_DE, akbd_keydesc_de_nodead),
- KBD_MAP(KB_SG, KB_US, akbd_keydesc_sg),
- KBD_MAP(KB_SG | KB_NODEAD, KB_SG, akbd_keydesc_sg_nodead),
- KBD_MAP(KB_UK, KB_US, akbd_keydesc_uk),
- KBD_MAP(KB_PT, KB_US, akbd_keydesc_pt),
- {0, 0, 0, 0}
-};
-
-#undef KBD_MAP
-#undef KC
diff --git a/sys/arch/macppc/dev/akbdvar.h b/sys/arch/macppc/dev/akbdvar.h
deleted file mode 100644
index 2689d719931..00000000000
--- a/sys/arch/macppc/dev/akbdvar.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* $OpenBSD: akbdvar.h,v 1.3 2002/03/27 21:48:12 drahn Exp $ */
-/* $NetBSD: akbdvar.h,v 1.4 1999/02/17 14:56:56 tsubai Exp $ */
-
-/*
- * Copyright (C) 1998 Colin Wood
- * All rights reserved.
- *
- * 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 Colin Wood.
- * 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.
- */
-
-#ifndef _MACPPC_KBDVAR_H_
-#define _MACPPC_KBDVAR_H_
-
-#include <machine/adbsys.h>
-
-/*
- * State info, per keyboard instance.
- */
-struct akbd_softc {
- struct device sc_dev;
-
- /* ADB info */
- int origaddr; /* ADB device type (ADBADDR_KBD) */
- int adbaddr; /* current ADB address */
- int handler_id; /* type of keyboard */
-
- u_int8_t sc_leds; /* current LED state */
- struct device *sc_wskbddev;
-#ifdef WSDISPLAY_COMPAT_RAWKBD
-#define MAXKEYS 20
-#define REP_DELAY1 400
-#define REP_DELAYN 100
- int sc_rawkbd;
- int sc_nrep;
- char sc_rep[MAXKEYS];
- struct timeout sc_rawrepeat_ch;
-#endif /* defined(WSDISPLAY_COMPAT_RAWKBD) */
-};
-
-/* LED register bits, inverse of actual register value */
-#define LED_NUMLOCK 0x1
-#define LED_CAPSLOCK 0x2
-#define LED_SCROLL_LOCK 0x4
-
-void kbd_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command);
-int akbd_cnattach(void);
-
-#endif /* _MACPPC_KBDVAR_H_ */
diff --git a/sys/arch/macppc/dev/ams.c b/sys/arch/macppc/dev/ams.c
deleted file mode 100644
index 3787b509193..00000000000
--- a/sys/arch/macppc/dev/ams.c
+++ /dev/null
@@ -1,535 +0,0 @@
-/* $OpenBSD: ams.c,v 1.13 2006/01/08 17:25:06 miod Exp $ */
-/* $NetBSD: ams.c,v 1.11 2000/12/19 03:13:40 tsubai Exp $ */
-
-/*
- * Copyright (C) 1998 Colin Wood
- * All rights reserved.
- *
- * 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 Colin Wood.
- * 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.
- */
-
-#include <sys/param.h>
-#include <sys/device.h>
-#include <sys/fcntl.h>
-#include <sys/poll.h>
-#include <sys/selinfo.h>
-#include <sys/proc.h>
-#include <sys/signalvar.h>
-#include <sys/systm.h>
-
-#include <machine/autoconf.h>
-
-#include <dev/wscons/wsconsio.h>
-#include <dev/wscons/wsmousevar.h>
-
-#include <macppc/dev/adbvar.h>
-#include <macppc/dev/amsvar.h>
-
-/*
- * Function declarations.
- */
-static int amsmatch(struct device *, void *, void *);
-static void amsattach(struct device *, struct device *, void *);
-static void ems_init(struct ams_softc *);
-static void ms_processevent(adb_event_t *event, struct ams_softc *);
-
-/* Driver definition. */
-struct cfattach ams_ca = {
- sizeof(struct ams_softc), amsmatch, amsattach
-};
-/* Driver definition. */
-struct cfdriver ams_cd = {
- NULL, "ams", DV_DULL
-};
-
-
-int ams_enable(void *);
-int ams_ioctl(void *, u_long, caddr_t, int, struct proc *);
-void ams_disable(void *);
-
-const struct wsmouse_accessops ams_accessops = {
- ams_enable,
- ams_ioctl,
- ams_disable,
-};
-
-static int
-amsmatch(struct device *parent, void *cf, void *aux)
-{
- struct adb_attach_args *aa_args = aux;
-
- if (aa_args->origaddr == ADBADDR_MS)
- return 1;
- else
- return 0;
-}
-
-static void
-amsattach(struct device *parent, struct device *self, void *aux)
-{
- ADBSetInfoBlock adbinfo;
- struct ams_softc *sc = (struct ams_softc *)self;
- struct adb_attach_args *aa_args = aux;
- int error;
- struct wsmousedev_attach_args a;
-
- sc->origaddr = aa_args->origaddr;
- sc->adbaddr = aa_args->adbaddr;
- sc->handler_id = aa_args->handler_id;
-
- sc->sc_class = MSCLASS_MOUSE;
- sc->sc_buttons = 1;
- sc->sc_res = 100;
- sc->sc_devid[0] = 0;
- sc->sc_devid[4] = 0;
-
- adbinfo.siServiceRtPtr = (Ptr)ms_adbcomplete;
- adbinfo.siDataAreaAddr = (caddr_t)sc;
-
- ems_init(sc);
-
- /* print out the type of mouse we have */
- printf(": ");
- switch (sc->handler_id) {
- case ADBMS_200DPI:
- sc->sc_res = 200;
- /* FALLTHROUGH */
- case ADBMS_100DPI:
- printf("%d-button, %d dpi mouse\n", sc->sc_buttons,
- (int)(sc->sc_res));
- break;
- case ADBMS_MSA3:
- printf("Mouse Systems A3 mouse, %d-button, %d dpi\n",
- sc->sc_buttons, (int)(sc->sc_res));
- break;
- case ADBMS_USPEED:
- printf("MicroSpeed mouse, default parameters\n");
- break;
- case ADBMS_UCONTOUR:
- printf("Contour mouse, default parameters\n");
- break;
- case ADBMS_TURBO:
- printf("Kensington Turbo Mouse\n");
- break;
- case ADBMS_EXTENDED:
- if (sc->sc_devid[0] == '\0') {
- printf("Logitech ");
- switch (sc->sc_class) {
- case MSCLASS_MOUSE:
- printf("MouseMan (non-EMP) mouse");
- break;
- case MSCLASS_TRACKBALL:
- printf("TrackMan (non-EMP) trackball");
- break;
- default:
- printf("non-EMP relative positioning device");
- break;
- }
- printf("\n");
- } else {
- printf("EMP ");
- switch (sc->sc_class) {
- case MSCLASS_TABLET:
- printf("tablet");
- break;
- case MSCLASS_MOUSE:
- printf("mouse");
- break;
- case MSCLASS_TRACKBALL:
- printf("trackball");
- break;
- case MSCLASS_TRACKPAD:
- printf("trackpad");
- break;
- default:
- printf("unknown device");
- break;
- }
- printf(" <%s> %d-button, %d dpi\n", sc->sc_devid,
- sc->sc_buttons, (int)(sc->sc_res));
- }
- break;
- default:
- printf("relative positioning device (mouse?) (%d)\n",
- sc->handler_id);
- break;
- }
- error = SetADBInfo(&adbinfo, sc->adbaddr);
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf("ams: returned %d from SetADBInfo\n", error);
-#endif
-
- a.accessops = &ams_accessops;
- a.accesscookie = sc;
- sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint);
-}
-
-
-/*
- * Initialize extended mouse support -- probes devices as described
- * in Inside Macintosh: Devices, Chapter 5 "ADB Manager".
- *
- * Extended Mouse Protocol is documented in TechNote HW1:
- * "ADB - The Untold Story: Space Aliens Ate My Mouse"
- *
- * Supports: Extended Mouse Protocol, MicroSpeed Mouse Deluxe,
- * Mouse Systems A^3 Mouse, Logitech non-EMP MouseMan
- */
-void
-ems_init(struct ams_softc *sc)
-{
- int adbaddr;
- short cmd;
- u_char buffer[9];
-
- adbaddr = sc->adbaddr;
- if (sc->origaddr != ADBADDR_MS)
- return;
- if (sc->handler_id == ADBMS_USPEED ||
- sc->handler_id == ADBMS_UCONTOUR) {
- /* Found MicroSpeed Mouse Deluxe Mac or Contour Mouse */
- cmd = ADBLISTEN(adbaddr, 1);
-
- /*
- * To setup the MicroSpeed or the Contour, it appears
- * that we can send the following command to the mouse
- * and then expect data back in the form:
- * buffer[0] = 4 (bytes)
- * buffer[1], buffer[2] as std. mouse
- * buffer[3] = buffer[4] = 0xff when no buttons
- * are down. When button N down, bit N is clear.
- * buffer[4]'s locking mask enables a
- * click to toggle the button down state--sort of
- * like the "Easy Access" shift/control/etc. keys.
- * buffer[3]'s alternative speed mask enables using
- * different speed when the corr. button is down
- */
- buffer[0] = 4;
- buffer[1] = 0x00; /* Alternative speed */
- buffer[2] = 0x00; /* speed = maximum */
- buffer[3] = 0x10; /* enable extended protocol,
- * lower bits = alt. speed mask
- * = 0000b
- */
- buffer[4] = 0x07; /* Locking mask = 0000b,
- * enable buttons = 0111b
- */
- adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd);
-
- sc->sc_buttons = 3;
- sc->sc_res = 200;
- return;
- }
- if (sc->handler_id == ADBMS_TURBO) {
- /* Found Kensington Turbo Mouse */
- static u_char data1[] =
- { 8, 0xe7, 0x8c, 0, 0, 0, 0xff, 0xff, 0x94 };
- static u_char data2[] =
- { 8, 0xa5, 0x14, 0, 0, 0x69, 0xff, 0xff, 0x27 };
-
- buffer[0] = 0;
- adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, ADBFLUSH(adbaddr));
-
- adb_op_sync((Ptr)data1, (Ptr)0, (Ptr)0, ADBLISTEN(adbaddr, 2));
-
- buffer[0] = 0;
- adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, ADBFLUSH(adbaddr));
-
- adb_op_sync((Ptr)data2, (Ptr)0, (Ptr)0, ADBLISTEN(adbaddr, 2));
- return;
- }
- if ((sc->handler_id == ADBMS_100DPI) ||
- (sc->handler_id == ADBMS_200DPI)) {
- /* found a mouse */
- cmd = ADBTALK(adbaddr, 3);
- if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd)) {
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf("adb: ems_init timed out\n");
-#endif
- return;
- }
-
- /* Attempt to initialize Extended Mouse Protocol */
- buffer[2] = 4; /* make handler ID 4 */
- cmd = ADBLISTEN(adbaddr, 3);
- if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd)) {
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf("adb: ems_init timed out\n");
-#endif
- return;
- }
-
- /*
- * Check to see if successful, if not
- * try to initialize it as other types
- */
- cmd = ADBTALK(adbaddr, 3);
- if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0 &&
- buffer[2] == ADBMS_EXTENDED) {
- sc->handler_id = ADBMS_EXTENDED;
- cmd = ADBTALK(adbaddr, 1);
- if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd)) {
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf("adb: ems_init timed out\n");
-#endif
- } else if (buffer[0] == 8) {
- /* we have a true EMP device */
- sc->sc_class = buffer[7];
- sc->sc_buttons = buffer[8];
- sc->sc_res = (int)*(short *)&buffer[5];
- bcopy(&(buffer[1]), sc->sc_devid, 4);
- } else if (buffer[1] == 0x9a &&
- ((buffer[2] == 0x20) || (buffer[2] == 0x21))) {
- /*
- * Set up non-EMP Mouseman/Trackman to put
- * button bits in 3rd byte instead of sending
- * via pseudo keyboard device.
- */
- cmd = ADBLISTEN(adbaddr, 1);
- buffer[0]=2;
- buffer[1]=0x00;
- buffer[2]=0x81;
- adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd);
-
- cmd = ADBLISTEN(adbaddr, 1);
- buffer[0]=2;
- buffer[1]=0x01;
- buffer[2]=0x81;
- adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd);
-
- cmd = ADBLISTEN(adbaddr, 1);
- buffer[0]=2;
- buffer[1]=0x02;
- buffer[2]=0x81;
- adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd);
-
- cmd = ADBLISTEN(adbaddr, 1);
- buffer[0]=2;
- buffer[1]=0x03;
- buffer[2]=0x38;
- adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd);
-
- sc->sc_buttons = 3;
- sc->sc_res = 400;
- if (buffer[2] == 0x21)
- sc->sc_class = MSCLASS_TRACKBALL;
- else
- sc->sc_class = MSCLASS_MOUSE;
- } else
- /* unknown device? */;
- } else {
- /* Attempt to initialize as an A3 mouse */
- buffer[2] = 0x03; /* make handler ID 3 */
- cmd = ADBLISTEN(adbaddr, 3);
- if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd)) {
-#ifdef ADB_DEBUG
- if (adb_debug)
- printf("adb: ems_init timed out\n");
-#endif
- return;
- }
-
- /*
- * Check to see if successful, if not
- * try to initialize it as other types
- */
- cmd = ADBTALK(adbaddr, 3);
- if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0
- && buffer[2] == ADBMS_MSA3) {
- sc->handler_id = ADBMS_MSA3;
- /* Initialize as above */
- cmd = ADBLISTEN(adbaddr, 2);
- /* listen 2 */
- buffer[0] = 3;
- buffer[1] = 0x00;
- /* Irrelevant, buffer has 0x77 */
- buffer[2] = 0x07;
- /*
- * enable 3 button mode = 0111b,
- * speed = normal
- */
- adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd);
- sc->sc_buttons = 3;
- sc->sc_res = 300;
- } else {
- /* No special support for this mouse */
- }
- }
- }
-}
-
-/*
- * Handle putting the mouse data received from the ADB into
- * an ADB event record.
- */
-void
-ms_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command)
-{
- adb_event_t event;
- struct ams_softc *sc;
- int adbaddr;
-#ifdef ADB_DEBUG
- int i;
-
- if (adb_debug)
- printf("adb: transaction completion\n");
-#endif
-
- adbaddr = ADB_CMDADDR(adb_command);
- sc = (struct ams_softc *)data_area;
-
- if ((sc->handler_id == ADBMS_EXTENDED) && (sc->sc_devid[0] == 0)) {
- /* massage the data to look like EMP data */
- if ((buffer[3] & 0x04) == 0x04)
- buffer[1] &= 0x7f;
- else
- buffer[1] |= 0x80;
- if ((buffer[3] & 0x02) == 0x02)
- buffer[2] &= 0x7f;
- else
- buffer[2] |= 0x80;
- if ((buffer[3] & 0x01) == 0x01)
- buffer[3] = 0x00;
- else
- buffer[3] = 0x80;
- }
-
- event.addr = adbaddr;
- event.hand_id = sc->handler_id;
- event.def_addr = sc->origaddr;
- event.byte_count = buffer[0];
- memcpy(event.bytes, buffer + 1, event.byte_count);
-
-#ifdef ADB_DEBUG
- if (adb_debug) {
- printf("ams: from %d at %d (org %d) %d:", event.addr,
- event.hand_id, event.def_addr, buffer[0]);
- for (i = 1; i <= buffer[0]; i++)
- printf(" %x", buffer[i]);
- printf("\n");
- }
-#endif
-
- microtime(&event.timestamp);
-
- ms_processevent(&event, sc);
-}
-
-/*
- * Given a mouse ADB event, record the button settings, calculate the
- * x- and y-axis motion, and handoff the event to the appropriate subsystem.
- */
-static void
-ms_processevent(adb_event_t *event, struct ams_softc *sc)
-{
- adb_event_t new_event;
- int i, button_bit, max_byte, mask, buttons;
-
- new_event = *event;
- buttons = 0;
-
- /*
- * This should handle both plain ol' Apple mice and mice
- * that claim to support the Extended Apple Mouse Protocol.
- */
- max_byte = event->byte_count;
- button_bit = 1;
- switch (event->hand_id) {
- case ADBMS_USPEED:
- case ADBMS_UCONTOUR:
- /* MicroSpeed mouse and Contour mouse */
- if (max_byte == 4)
- buttons = (~event->bytes[2]) & 0xff;
- else
- buttons = (event->bytes[0] & 0x80) ? 0 : 1;
- break;
- case ADBMS_MSA3:
- /* Mouse Systems A3 mouse */
- if (max_byte == 3)
- buttons = (~event->bytes[2]) & 0x07;
- else
- buttons = (event->bytes[0] & 0x80) ? 0 : 1;
- break;
- default:
- /* Classic Mouse Protocol (up to 2 buttons) */
- for (i = 0; i < 2; i++, button_bit <<= 1)
- /* 0 when button down */
- if (!(event->bytes[i] & 0x80))
- buttons |= button_bit;
- else
- buttons &= ~button_bit;
- if (sc->sc_class == MSCLASS_MOUSE)
- /* Extended Protocol (up to 6 more buttons) */
- for (mask = 0x80; i < max_byte;
- i += (mask == 0x80), button_bit <<= 1) {
- /* 0 when button down */
- if (!(event->bytes[i] & mask))
- buttons |= button_bit;
- else
- buttons &= ~button_bit;
- mask = ((mask >> 4) & 0xf)
- | ((mask & 0xf) << 4);
- }
- break;
- }
- new_event.u.m.buttons = sc->sc_mb | buttons;
- new_event.u.m.dx = ((signed int) (event->bytes[1] & 0x3f)) -
- ((event->bytes[1] & 0x40) ? 64 : 0);
- new_event.u.m.dy = ((signed int) (event->bytes[0] & 0x3f)) -
- ((event->bytes[0] & 0x40) ? 64 : 0);
-
- if (sc->sc_wsmousedev)
- wsmouse_input(sc->sc_wsmousedev, new_event.u.m.buttons,
- new_event.u.m.dx, -new_event.u.m.dy, 0,
- WSMOUSE_INPUT_DELTA);
-}
-
-int
-ams_enable(void *v)
-{
- return 0;
-}
-
-int
-ams_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
-{
- switch (cmd) {
- case WSMOUSEIO_GTYPE:
- *(u_int *)data = WSMOUSE_TYPE_ADB;
- return (0);
- }
-
- return -1;
-}
-
-void
-ams_disable(void *v)
-{
-}
diff --git a/sys/arch/macppc/dev/apm.c b/sys/arch/macppc/dev/apm.c
index 41d90969592..a49f1f89d68 100644
--- a/sys/arch/macppc/dev/apm.c
+++ b/sys/arch/macppc/dev/apm.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: apm.c,v 1.11 2005/10/15 15:01:23 martin Exp $ */
+/* $OpenBSD: apm.c,v 1.12 2006/01/18 23:21:17 miod Exp $ */
/*-
* Copyright (c) 2001 Alexander Guy. All rights reserved.
@@ -54,6 +54,7 @@
#include <machine/cpu.h>
#include <machine/apmvar.h>
+#include <dev/adb/adb.h>
#include <macppc/dev/adbvar.h>
#include <macppc/dev/pm_direct.h>
diff --git a/sys/arch/macppc/dev/pm_direct.c b/sys/arch/macppc/dev/pm_direct.c
index fc22ea56242..7a5c80b6305 100644
--- a/sys/arch/macppc/dev/pm_direct.c
+++ b/sys/arch/macppc/dev/pm_direct.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pm_direct.c,v 1.17 2005/12/22 22:55:25 miod Exp $ */
+/* $OpenBSD: pm_direct.c,v 1.18 2006/01/18 23:21:17 miod Exp $ */
/* $NetBSD: pm_direct.c,v 1.9 2000/06/08 22:10:46 tsubai Exp $ */
/*
@@ -44,9 +44,9 @@
#include <sys/device.h>
#include <sys/systm.h>
-#include <machine/adbsys.h>
#include <machine/cpu.h>
+#include <dev/adb/adb.h>
#include <macppc/dev/adbvar.h>
#include <macppc/dev/pm_direct.h>
#include <macppc/dev/viareg.h>
diff --git a/sys/arch/macppc/macppc/ofw_machdep.c b/sys/arch/macppc/macppc/ofw_machdep.c
index 7ace6b09192..b6489d81a48 100644
--- a/sys/arch/macppc/macppc/ofw_machdep.c
+++ b/sys/arch/macppc/macppc/ofw_machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ofw_machdep.c,v 1.28 2006/01/01 11:59:39 miod Exp $ */
+/* $OpenBSD: ofw_machdep.c,v 1.29 2006/01/18 23:21:17 miod Exp $ */
/* $NetBSD: ofw_machdep.c,v 1.1 1996/09/30 16:34:50 ws Exp $ */
/*
@@ -52,11 +52,11 @@
#include <macppc/macppc/ofw_machdep.h>
-#include <ukbd.h>
-#include <akbd.h>
-#include <zstty.h>
+#include "ukbd.h"
+#include "akbd.h"
+#include "zstty.h"
#include <dev/usb/ukbdvar.h>
-#include <macppc/dev/akbdvar.h>
+#include <dev/adb/akbdvar.h>
/* XXX, called from asm */
int save_ofw_mapping(void);
diff --git a/sys/arch/macppc/include/adbsys.h b/sys/dev/adb/adb.h
index e39f2606090..e18e61cc0ea 100644
--- a/sys/arch/macppc/include/adbsys.h
+++ b/sys/dev/adb/adb.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: adbsys.h,v 1.5 2006/01/04 21:03:49 miod Exp $ */
+/* $OpenBSD: adb.h,v 1.1 2006/01/18 23:21:17 miod Exp $ */
/* $NetBSD: adbsys.h,v 1.4 2000/12/19 02:59:24 tsubai Exp $ */
/*-
@@ -34,11 +34,27 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _ADBSYS_MACHINE_
-#define _ADBSYS_MACHINE_
+#ifndef _ADB_H_
+#define _ADB_H_
+
+#ifdef _KERNEL
#include <sys/time.h> /* timeval stuff */
+/*
+ * Arguments used to attach a device to the Apple Desktop Bus
+ */
+struct adb_attach_args {
+ int origaddr;
+ int adbaddr;
+ int handler_id;
+};
+
+#define ADB_CMDADDR(cmd) ((u_int8_t)(cmd & 0xf0) >> 4)
+#define ADBFLUSH(dev) ((((u_int8_t)dev & 0x0f) << 4) | 0x01)
+#define ADBLISTEN(dev, reg) ((((u_int8_t)dev & 0x0f) << 4) | 0x08 | reg)
+#define ADBTALK(dev, reg) ((((u_int8_t)dev & 0x0f) << 4) | 0x0c | reg)
+
/* an ADB event */
typedef struct adb_event_s {
int addr; /* device address */
@@ -48,10 +64,10 @@ typedef struct adb_event_s {
unsigned char bytes[8]; /* bytes from register 0 */
struct timeval timestamp; /* time event was acquired */
union {
- struct adb_keydata_s{
+ struct adb_keydata_s {
int key; /* ADB key code */
} k;
- struct adb_mousedata_s{
+ struct adb_mousedata_s {
int dx; /* mouse delta x */
int dy; /* mouse delta y */
int buttons; /* buttons (down << (buttonnum)) */
@@ -59,15 +75,6 @@ typedef struct adb_event_s {
} u; /* courtesy interpretation */
} adb_event_t;
-
-/* a device on the ADB */
-typedef struct adb_dev_s{
- int addr; /* current address */
- int default_addr; /* startup address */
- int handler_id; /* handler ID */
-} adb_dev_t;
-
-
/* Interesting default addresses */
#define ADBADDR_SECURE 1 /* Security dongles */
#define ADBADDR_MAP 2 /* Mapped devices (keyboards/pads) */
@@ -126,12 +133,31 @@ typedef struct adb_dev_s{
#define ADB_POWERKEY 34 /* Sophisticated Circuits PowerKey */
/* (intelligent power tap) */
-#ifdef _KERNEL
-int adb_poweroff(void);
-void adb_restart(void);
-int CountADBs(void);
-void ADBReInit(void);
-int adb_read_date_time(time_t *);
+extern int adb_polling;
+#ifdef ADB_DEBUG
+extern int adb_debug;
#endif
-#endif /* _ADBSYS_MACHINE_ */
+/* ADB Manager */
+
+typedef caddr_t Ptr;
+
+typedef struct {
+ Ptr siServiceRtPtr;
+ Ptr siDataAreaAddr;
+} ADBSetInfoBlock;
+
+typedef struct {
+ unsigned char devType;
+ unsigned char origADBAddr;
+ Ptr dbServiceRtPtr;
+ Ptr dbDataAreaAddr;
+} ADBDataBlock;
+
+int adbprint(void *, const char *);
+int adb_op_sync(Ptr, Ptr, Ptr, short);
+int set_adb_info(ADBSetInfoBlock *, int);
+
+#endif /* _KERNEL */
+
+#endif /* _ADB_H_ */
diff --git a/sys/dev/adb/adb_subr.c b/sys/dev/adb/adb_subr.c
new file mode 100644
index 00000000000..839f2aa6878
--- /dev/null
+++ b/sys/dev/adb/adb_subr.c
@@ -0,0 +1,108 @@
+/* $OpenBSD: adb_subr.c,v 1.1 2006/01/18 23:21:17 miod Exp $ */
+/* $NetBSD: adb.c,v 1.6 1999/08/16 06:28:09 tsubai Exp $ */
+
+/*-
+ * Copyright (C) 1994 Bradley A. Grantham
+ * All rights reserved.
+ *
+ * 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 Bradley A. Grantham.
+ * 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.
+ */
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <dev/adb/adb.h>
+
+struct cfdriver adb_cd = {
+ NULL, "adb", DV_DULL
+};
+
+int
+adbprint(void *args, const char *name)
+{
+ struct adb_attach_args *aa_args = (struct adb_attach_args *)args;
+ int rv = UNCONF;
+
+ if (name) { /* no configured device matched */
+ rv = UNSUPP; /* most ADB device types are unsupported */
+
+ /* print out what kind of ADB device we have found */
+ switch(aa_args->origaddr) {
+#ifdef ADBVERBOSE
+ case ADBADDR_SECURE:
+ printf("security dongle (%d)", aa_args->handler_id);
+ break;
+#endif
+ case ADBADDR_MAP:
+ printf("mapped device (%d)", aa_args->handler_id);
+ rv = UNCONF;
+ break;
+ case ADBADDR_REL:
+ printf("relative positioning device (%d)",
+ aa_args->handler_id);
+ rv = UNCONF;
+ break;
+#ifdef ADBVERBOSE
+ case ADBADDR_ABS:
+ switch (aa_args->handler_id) {
+ case ADB_ARTPAD:
+ printf("WACOM ArtPad II");
+ break;
+ default:
+ printf("absolute positioning device (%d)",
+ aa_args->handler_id);
+ break;
+ }
+ break;
+ case ADBADDR_DATATX:
+ printf("data transfer device (modem?) (%d)",
+ aa_args->handler_id);
+ break;
+ case ADBADDR_MISC:
+ switch (aa_args->handler_id) {
+ case ADB_POWERKEY:
+ printf("Sophisticated Circuits PowerKey");
+ break;
+ default:
+ printf("misc. device (remote control?) (%d)",
+ aa_args->handler_id);
+ break;
+ }
+ break;
+ default:
+ printf("unknown type %d device, (handler %d)",
+ aa_args->origaddr, aa_args->handler_id);
+ break;
+#endif /* ADBVERBOSE */
+ }
+ printf(" at %s", name);
+ }
+
+ printf(" addr %d", aa_args->adbaddr);
+
+ return (rv);
+}
diff --git a/sys/arch/macppc/dev/akbd.c b/sys/dev/adb/akbd.c
index 651bf454c52..18d8434415e 100644
--- a/sys/arch/macppc/dev/akbd.c
+++ b/sys/dev/adb/akbd.c
@@ -1,5 +1,5 @@
-/* $OpenBSD: akbd.c,v 1.20 2006/01/08 17:25:05 miod Exp $ */
-/* $NetBSD: akbd.c,v 1.13 2001/01/25 14:08:55 tsubai Exp $ */
+/* $OpenBSD: akbd.c,v 1.1 2006/01/18 23:21:17 miod Exp $ */
+/* $NetBSD: akbd.c,v 1.17 2005/01/15 16:00:59 chs Exp $ */
/*
* Copyright (C) 1998 Colin Wood
@@ -48,25 +48,26 @@
#include <dev/wscons/wsksymvar.h>
#include <machine/autoconf.h>
-#define KEYBOARD_ARRAY
+#include <machine/cpu.h>
+
+#include <dev/adb/adb.h>
+#include <dev/adb/akbdmap.h>
+#include <dev/adb/akbdvar.h>
-#include <macppc/dev/keyboard.h>
-#include <macppc/dev/adbvar.h>
-#include <macppc/dev/akbdmap.h>
-#include <macppc/dev/akbdvar.h>
-#include <macppc/dev/amsvar.h>
+#define KEYBOARD_ARRAY
+#include <dev/adb/keyboard.h>
/*
* Function declarations.
*/
-static int akbdmatch(struct device *, void *, void *);
-static void akbdattach(struct device *, struct device *, void *);
-void kbd_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command);
-static void kbd_processevent(adb_event_t *event, struct akbd_softc *);
+int akbdmatch(struct device *, void *, void *);
+void akbdattach(struct device *, struct device *, void *);
+void kbd_adbcomplete(caddr_t, caddr_t, int);
+void kbd_processevent(adb_event_t *, struct akbd_softc *);
#ifdef notyet
-static u_char getleds(int);
-static int setleds(struct akbd_softc *, u_char);
-static void blinkleds(struct akbd_softc *);
+u_char getleds(int);
+int setleds(struct akbd_softc *, u_char);
+void blinkleds(struct akbd_softc *);
#endif
/* Driver definition. */
@@ -77,11 +78,10 @@ struct cfdriver akbd_cd = {
NULL, "akbd", DV_DULL
};
-
int akbd_enable(void *, int);
void akbd_set_leds(void *, int);
int akbd_ioctl(void *, u_long, caddr_t, int, struct proc *);
-int akbd_intr(adb_event_t *event);
+int akbd_intr(adb_event_t *, struct akbd_softc *);
void akbd_rawrepeat(void *v);
@@ -91,14 +91,6 @@ struct wskbd_accessops akbd_accessops = {
akbd_ioctl,
};
-void akbd_cngetc(void *, u_int *, int *);
-void akbd_cnpollc(void *, int);
-
-struct wskbd_consops akbd_consops = {
- akbd_cngetc,
- akbd_cnpollc,
-};
-
struct wskbd_mapdata akbd_keymapdata = {
akbd_keydesctab,
#ifdef AKBD_LAYOUT
@@ -108,12 +100,10 @@ struct wskbd_mapdata akbd_keymapdata = {
#endif
};
-static int akbd_is_console;
-
-static int
-akbdmatch(struct device *parent, void *cf, void *aux)
+int
+akbdmatch(struct device *parent, void *vcf, void *aux)
{
- struct adb_attach_args *aa_args = aux;
+ struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
if (aa_args->origaddr == ADBADDR_KBD)
return 1;
@@ -121,16 +111,18 @@ akbdmatch(struct device *parent, void *cf, void *aux)
return 0;
}
-static void
+void
akbdattach(struct device *parent, struct device *self, void *aux)
{
ADBSetInfoBlock adbinfo;
struct akbd_softc *sc = (struct akbd_softc *)self;
- struct adb_attach_args *aa_args = aux;
+ struct adb_attach_args *aa_args = (struct adb_attach_args *)aux;
int error, kbd_done;
short cmd;
u_char buffer[9];
struct wskbddev_attach_args a;
+ static int akbd_console_initted;
+ int wskbd_eligible = 1;
sc->origaddr = aa_args->origaddr;
sc->adbaddr = aa_args->adbaddr;
@@ -159,10 +151,12 @@ akbdattach(struct device *parent, struct device *self, void *aux)
printf("Mouseman (non-EMP) pseudo keyboard\n");
adbinfo.siServiceRtPtr = (Ptr)0;
adbinfo.siDataAreaAddr = (Ptr)0;
+ wskbd_eligible = 0;
} else if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x21) {
printf("Trackman (non-EMP) pseudo keyboard\n");
adbinfo.siServiceRtPtr = (Ptr)0;
adbinfo.siDataAreaAddr = (Ptr)0;
+ wskbd_eligible = 0;
} else {
printf("extended keyboard\n");
#ifdef notyet
@@ -190,6 +184,7 @@ akbdattach(struct device *parent, struct device *self, void *aux)
break;
case ADB_ADJKPD:
printf("adjustable keypad\n");
+ wskbd_eligible = 0;
break;
case ADB_ADJKBD:
printf("adjustable keyboard\n");
@@ -232,20 +227,23 @@ akbdattach(struct device *parent, struct device *self, void *aux)
break;
default:
printf("mapped device (%d)\n", sc->handler_id);
+ wskbd_eligible = 0;
break;
}
- error = SetADBInfo(&adbinfo, sc->adbaddr);
+ error = set_adb_info(&adbinfo, sc->adbaddr);
#ifdef ADB_DEBUG
if (adb_debug)
- printf("akbd: returned %d from SetADBInfo\n", error);
+ printf("akbd: returned %d from set_adb_info\n", error);
#endif
#ifdef WSDISPLAY_COMPAT_RAWKBD
timeout_set(&sc->sc_rawrepeat_ch, akbd_rawrepeat, sc);
#endif
-
- a.console = akbd_is_console;
+ if (akbd_is_console() && wskbd_eligible)
+ a.console = (++akbd_console_initted == 1);
+ else
+ a.console = 0;
a.keymap = &akbd_keymapdata;
a.accessops = &akbd_accessops;
a.accesscookie = sc;
@@ -300,7 +298,7 @@ kbd_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command)
* repeat handler, optionally passing the event through the mouse
* button emulation handler first.
*/
-static void
+void
kbd_processevent(adb_event_t *event, struct akbd_softc *ksc)
{
adb_event_t new_event;
@@ -308,12 +306,14 @@ kbd_processevent(adb_event_t *event, struct akbd_softc *ksc)
new_event = *event;
new_event.u.k.key = event->bytes[0];
new_event.bytes[1] = 0xff;
- akbd_intr(&new_event);
+ if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */
+ akbd_intr(&new_event, ksc);
if (event->bytes[1] != 0xff) {
new_event.u.k.key = event->bytes[1];
new_event.bytes[0] = event->bytes[1];
new_event.bytes[1] = 0xff;
- akbd_intr(&new_event);
+ if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */
+ akbd_intr(&new_event, ksc);
}
}
@@ -322,7 +322,7 @@ kbd_processevent(adb_event_t *event, struct akbd_softc *ksc)
/*
* Get the actual hardware LED state and convert it to softc format.
*/
-static u_char
+u_char
getleds(int addr)
{
short cmd;
@@ -331,7 +331,6 @@ getleds(int addr)
leds = 0x00; /* all off */
buffer[0] = 0;
- /* talk R2 */
cmd = ADBTALK(addr, 2);
if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0 &&
buffer[0] > 0)
@@ -346,7 +345,7 @@ getleds(int addr)
* Automatically translates from ioctl/softc format to the
* actual keyboard register format
*/
-static int
+int
setleds(struct akbd_softc *ksc, u_char leds)
{
int addr;
@@ -370,6 +369,7 @@ setleds(struct akbd_softc *ksc, u_char leds)
cmd = ADBLISTEN(addr, 2);
adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd);
+ /* talk R2 */
cmd = ADBTALK(addr, 2);
if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) || buffer[0] == 0)
return (EIO);
@@ -385,7 +385,7 @@ setleds(struct akbd_softc *ksc, u_char leds)
/*
* Toggle all of the LED's on and off, just for show.
*/
-static void
+void
blinkleds(struct akbd_softc *ksc)
{
int addr, i;
@@ -445,10 +445,18 @@ akbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p)
return (0);
#endif
- }
- /* kbdioctl(...); */
+#ifdef mac68k /* XXX not worth creating akbd_machdep_ioctl() */
+ case WSKBDIO_BELL:
+ case WSKBDIO_COMPLEXBELL:
+#define d ((struct wskbd_bell_data *)data)
+ mac68k_ring_bell(d->pitch, d->period * hz / 1000, d->volume);
+#undef d
+ return (0);
+#endif
- return -1;
+ default:
+ return (-1);
+ }
}
#ifdef WSDISPLAY_COMPAT_RAWKBD
@@ -465,18 +473,14 @@ akbd_rawrepeat(void *v)
}
#endif
-
-static int polledkey;
-
+int adb_polledkey;
int
-akbd_intr(adb_event_t *event)
+akbd_intr(adb_event_t *event, struct akbd_softc *sc)
{
int key, press, val;
int type;
static int shift;
- struct akbd_softc *sc = akbd_cd.cd_devs[0];
-
key = event->u.k.key;
/*
@@ -504,20 +508,8 @@ akbd_intr(adb_event_t *event)
type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
- switch (val) {
-#if 0
- /* not supported... */
- case ADBK_KEYVAL(245):
- pm_eject_pcmcia(0);
- break;
- case ADBK_KEYVAL(244):
- pm_eject_pcmcia(1);
- break;
-#endif
- }
-
if (adb_polling) {
- polledkey = key;
+ adb_polledkey = key;
#ifdef WSDISPLAY_COMPAT_RAWKBD
} else if (sc->sc_rawkbd) {
char cbuf[MAXKEYS *2];
@@ -557,44 +549,3 @@ akbd_intr(adb_event_t *event)
return 0;
}
-
-int
-akbd_cnattach()
-{
-
- akbd_is_console = 1;
- wskbd_cnattach(&akbd_consops, NULL, &akbd_keymapdata);
- return 0;
-}
-
-void
-akbd_cngetc(void *v, u_int *type, int *data)
-{
- int key, press, val;
- int s;
-
- s = splhigh();
-
- polledkey = -1;
- adb_polling = 1;
-
- while (polledkey == -1) {
- adb_intr(NULL); /* adb does not use the argument */
- DELAY(10000); /* XXX */
- }
-
- adb_polling = 0;
- splx(s);
-
- key = polledkey;
- press = ADBK_PRESS(key);
- val = ADBK_KEYVAL(key);
-
- *data = val;
- *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP;
-}
-
-void
-akbd_cnpollc(void *v, int on)
-{
-}
diff --git a/sys/arch/mac68k/dev/akbdmap.h b/sys/dev/adb/akbdmap.h
index 8e0c01f0523..f91444ed71a 100644
--- a/sys/arch/mac68k/dev/akbdmap.h
+++ b/sys/dev/adb/akbdmap.h
@@ -1,3 +1,4 @@
+/* $OpenBSD: akbdmap.h,v 1.1 2006/01/18 23:21:17 miod Exp $ */
/* $NetBSD: akbdmap.h,v 1.7 2005/05/05 22:29:41 abs Exp $ */
/*-
@@ -94,7 +95,7 @@ static const keysym_t akbd_keydesc_us[] = {
KC(49), KS_space,
KC(50), KS_grave, KS_asciitilde,
KC(51), KS_Delete,
- KC(52), KS_KP_Enter, /* Pretend this is alt-R ? */
+ KC(52), KS_KP_Enter,
KC(53), KS_Escape,
KC(54), KS_Control_L,
KC(55), KS_Cmd, /* Command */
@@ -109,25 +110,25 @@ static const keysym_t akbd_keydesc_us[] = {
KC(65), KS_KP_Decimal,
KC(67), KS_KP_Multiply,
KC(69), KS_KP_Add,
- KC(71), KS_Num_Lock,
+ KC(71), KS_Num_Lock, KS_Clear,
KC(75), KS_KP_Divide,
KC(76), KS_KP_Enter,
KC(78), KS_KP_Subtract,
KC(81), KS_KP_Equal,
- KC(82), KS_KP_Insert, KS_KP_0,
- KC(83), KS_KP_End, KS_KP_1,
- KC(84), KS_KP_Down, KS_KP_2,
- KC(85), KS_KP_Next, KS_KP_3,
- KC(86), KS_KP_Left, KS_KP_4,
- KC(87), KS_KP_Begin, KS_KP_5,
- KC(88), KS_KP_Right, KS_KP_6,
- KC(89), KS_KP_Home, KS_KP_7,
-
- KC(91), KS_KP_Up, KS_KP_8,
- KC(92), KS_KP_Prior, KS_KP_9,
-
- KC(95), KS_KP_Delete, KS_KP_Decimal,
+ KC(82), KS_KP_0, KS_KP_Insert,
+ KC(83), KS_KP_1, KS_KP_End,
+ KC(84), KS_KP_2, KS_KP_Down,
+ KC(85), KS_KP_3, KS_KP_Next,
+ KC(86), KS_KP_4, KS_KP_Left,
+ KC(87), KS_KP_5, KS_KP_Begin,
+ KC(88), KS_KP_6, KS_KP_Right,
+ KC(89), KS_KP_7, KS_KP_Home,
+
+ KC(91), KS_KP_8, KS_KP_Up,
+ KC(92), KS_KP_9, KS_KP_Prior,
+
+ KC(95), KS_KP_Decimal, KS_KP_Delete,
KC(96), KS_f5,
KC(97), KS_f6,
KC(98), KS_f7,
@@ -138,15 +139,15 @@ static const keysym_t akbd_keydesc_us[] = {
KC(103), KS_f11,
- KC(105), KS_Print_Screen,
+ KC(105), KS_f13, KS_Print_Screen,
KC(106), KS_KP_Enter,
- KC(107), KS_Hold_Screen,
+ KC(107), KS_f14, KS_Hold_Screen,
KC(109), KS_f10,
KC(111), KS_f12,
- KC(113), KS_Pause,
+ KC(113), KS_f15, KS_Pause,
KC(114), KS_Insert,
KC(115), KS_Home,
KC(116), KS_Prior,
@@ -168,32 +169,34 @@ static const keysym_t akbd_keydesc_fr[] = {
KC(6), KS_w, KS_W, KS_less, KS_greater,
KC(8), KS_c, KS_C, KS_copyright, KS_cent,
KC(10), KS_at, KS_numbersign,
- KC(11), KS_b, KS_B, KS_ssharp,
+ KC(11), KS_b, KS_B, KS_ssharp,
KC(12), KS_a, KS_A, KS_ae, KS_AE,
KC(13), KS_z, KS_Z, KS_Acircumflex, KS_Aring,
KC(14), KS_e, KS_E, KS_ecircumflex, KS_Ecircumflex,
- KC(15), KS_r, KS_R, KS_registered, /* Euro */
+ KC(15), KS_r, KS_R, KS_registered, KS_comma,
KC(16), KS_y, KS_Y, KS_Uacute,
KC(18), KS_ampersand, KS_1, KS_voidSymbol, KS_dead_acute,
KC(19), KS_eacute, KS_2, KS_ediaeresis,
KC(20), KS_quotedbl, KS_3,
KC(21), KS_apostrophe, KS_4, KS_braceleft, KS_bracketleft,
- KC(22), KS_section, KS_6, KS_paragraph,
+ KC(22), KS_section, KS_6, KS_paragraph, KS_aring,
KC(23), KS_parenleft, KS_5, KS_braceleft, KS_bracketleft,
KC(24), KS_minus, KS_underscore, KS_braceright,
- KC(25), KS_ccedilla, KS_9, KS_Ccedilla, KS_Agrave,
- KC(26), KS_egrave, KS_7, KS_guillemotleft,KS_guillemotright,
+ KC(25), KS_ccedilla, KS_9, KS_Ccedilla, KS_Aacute,
+ KC(26), KS_egrave, KS_7, KS_guillemotleft,
+ KS_guillemotright,
KC(27), KS_parenright, KS_degree, KS_braceright, KS_bracketright,
KC(28), KS_exclam, KS_8, KS_exclamdown, KS_Ucircumflex,
- KC(29), KS_agrave, KS_0, KS_oslash,
- KC(30), KS_dollar, KS_asterisk, KS_comma, KS_yen,
- KC(33), KS_dead_circumflex, KS_dead_diaeresis,KS_ocircumflex,KS_Ocircumflex,
- KC(34), KS_i, KS_I, KS_icircumflex, KS_Icircumflex,
+ KC(29), KS_agrave, KS_0, KS_oslash, KS_Ooblique,
+ KC(30), KS_dollar, KS_asterisk, KS_cent, KS_yen,
+ KC(33), KS_dead_circumflex, KS_dead_diaeresis,
+ KS_ocircumflex, KS_Ocircumflex,
+ KC(34), KS_i, KS_I, KS_icircumflex, KS_idiaeresis,
KC(37), KS_l, KS_L, KS_notsign, KS_bar,
- KC(38), KS_j, KS_J, KS_Idiaeresis, KS_Igrave,
+ KC(38), KS_j, KS_J, KS_Idiaeresis, KS_Iacute,
KC(39), KS_ugrave, KS_percent, KS_Ugrave,
KC(40), KS_k, KS_K, KS_Egrave, KS_Ediaeresis,
- KC(41), KS_m, KS_M, KS_mu, KS_Ograve,
+ KC(41), KS_m, KS_M, KS_mu, KS_Oacute,
KC(42), KS_dead_grave, KS_sterling, KS_at, KS_numbersign,
KC(43), KS_semicolon, KS_period,
KC(44), KS_equal, KS_plus, KS_voidSymbol, KS_plusminus,
@@ -403,29 +406,120 @@ static const keysym_t akbd_keydesc_pt[] = {
KC(44), KS_minus, KS_underscore,
KC(47), KS_period, KS_colon,
KC(50), KS_less, KS_greater,
+ KC(58), KS_Mode_switch, KS_Multi_key, /* Option */
+};
+
+static const keysym_t akbd_keydesc_us_dvorak[] = {
+/* pos command normal shifted */
+ KC(1), KS_o,
+ KC(2), KS_e,
+ KC(3), KS_u,
+ KC(4), KS_d,
+ KC(5), KS_i,
+ KC(6), KS_semicolon, KS_colon,
+ KC(7), KS_q,
+ KC(8), KS_j,
+ KC(9), KS_k,
+ KC(11), KS_x,
+ KC(12), KS_apostrophe, KS_quotedbl,
+ KC(13), KS_comma, KS_less,
+ KC(14), KS_period, KS_greater,
+ KC(15), KS_p,
+ KC(16), KS_f,
+ KC(17), KS_y,
+ KC(24), KS_bracketright, KS_braceright,
+ KC(27), KS_bracketleft, KS_braceleft,
+ KC(30), KS_equal, KS_plus,
+ KC(31), KS_r,
+ KC(32), KS_g,
+ KC(33), KS_slash, KS_question,
+ KC(34), KS_c,
+ KC(35), KS_l,
+ KC(37), KS_n,
+ KC(38), KS_h,
+ KC(39), KS_minus, KS_underscore,
+ KC(40), KS_t,
+ KC(41), KS_s,
+ KC(43), KS_w,
+ KC(44), KS_z,
+ KC(45), KS_b,
+ KC(47), KS_v,
+};
+
+static const keysym_t akbd_keydesc_sg[] = {
+/* pos normal shifted altgr shift-altgr */
+ KC(0), KS_a, KS_A, KS_aring, KS_Aring,
+ KC(1), KS_s, KS_S, KS_ssharp, KS_voidSymbol,
+ KC(3), KS_f, KS_F, KS_section, KS_voidSymbol,
+ KC(4), KS_h, KS_H, KS_ordfeminine, KS_periodcentered,
+ KC(5), KS_g, KS_G, KS_at, KS_comma,
+ KC(6), KS_y, KS_Y, KS_yen, KS_ydiaeresis,
+ KC(7), KS_x, KS_X, KS_voidSymbol, KS_ydiaeresis,
+ KC(8), KS_c, KS_C, KS_copyright,
+ KC(10), KS_section, KS_degree,
+ KC(12), KS_q, KS_Q,
+ KC(15), KS_r, KS_R, KS_registered, KS_Egrave,
+ KC(16), KS_z, KS_Z, KS_voidSymbol, KS_Aacute,
+ KC(18), KS_1, KS_plus, KS_plusminus, KS_onesuperior,
+ KC(19), KS_2, KS_quotedbl, KS_twosuperior,
+ KC(20), KS_3, KS_asterisk, KS_numbersign, KS_threesuperior,
+ KC(21), KS_4, KS_ccedilla, KS_Ccedilla,
+ KC(22), KS_6, KS_ampersand, KS_bracketright,
+ KC(23), KS_5, KS_percent, KS_bracketleft,
+ KC(24), KS_dead_circumflex,KS_dead_grave,KS_dead_acute, KS_asciitilde,
+ KC(25), KS_9, KS_parenright, KS_braceright, KS_Ocircumflex,
+ KC(26), KS_7, KS_slash, KS_bar, KS_backslash,
+ KC(27), KS_apostrophe, KS_question, KS_questiondown,
+ KC(28), KS_8, KS_parenleft, KS_braceleft, KS_Ograve,
+ KC(29), KS_0, KS_equal, KS_voidSymbol, KS_Uacute,
+ KC(30), KS_dead_diaeresis,KS_exclam, KS_bracketright,
+ KC(31), KS_o, KS_O, KS_oslash,
+ KC(32), KS_u, KS_U, KS_degree, KS_Ugrave,
+ KC(33), KS_udiaeresis, KS_egrave, KS_bracketleft,
+ KC(34), KS_i, KS_I, KS_exclamdown,
+ KC(37), KS_l, KS_L, KS_notsign,
+ KC(38), KS_j, KS_J, KS_masculine,
+ KC(39), KS_adiaeresis, KS_agrave, KS_ae, KS_AE,
+ KC(41), KS_odiaeresis, KS_eacute, KS_cent,
+ KC(42), KS_dollar, KS_sterling, KS_paragraph,
+ KC(43), KS_comma, KS_semicolon, KS_guillemotleft,KS_guillemotright,
+ KC(44), KS_minus, KS_underscore,
+ KC(45), KS_n, KS_N, KS_dead_tilde,
+ KC(46), KS_m, KS_M, KS_mu,
+ KC(47), KS_period, KS_colon, KS_voidSymbol, KS_division,
+ KC(50), KS_less, KS_greater,
+ KC(52), KS_Multi_key,
KC(58), KS_Mode_switch,
- KC(81), KS_KP_Equal,
};
+static const keysym_t akbd_keydesc_sg_nodead[] = {
+/* pos normal shifted altgr shift-altgr */
+ KC(24), KS_asciicircum, KS_grave, KS_acute, KS_asciitilde,
+ KC(30), KS_diaeresis, KS_exclam, KS_bracketright,KS_braceright,
+ KC(45), KS_n, KS_N, KS_asciitilde,
+};
+
#define KBD_MAP(name, base, map) \
{ name, base, sizeof(map)/sizeof(keysym_t), map }
static const struct wscons_keydesc akbd_keydesctab[] = {
KBD_MAP(KB_US, 0, akbd_keydesc_us),
+ KBD_MAP(KB_US | KB_DVORAK, KB_US, akbd_keydesc_us_dvorak),
+ KBD_MAP(KB_DE, KB_US, akbd_keydesc_de),
+ KBD_MAP(KB_DE | KB_NODEAD, KB_DE, akbd_keydesc_de_nodead),
+ KBD_MAP(KB_ES, KB_US, akbd_keydesc_es),
KBD_MAP(KB_FR, KB_US, akbd_keydesc_fr),
- KBD_MAP(KB_JP, KB_US, akbd_keydesc_jp),
KBD_MAP(KB_FR | KB_NODEAD, KB_FR, akbd_keydesc_fr_nodead),
+ KBD_MAP(KB_JP, KB_US, akbd_keydesc_jp),
+ KBD_MAP(KB_PT, KB_US, akbd_keydesc_pt),
KBD_MAP(KB_SF, KB_US, akbd_keydesc_sf),
+ KBD_MAP(KB_SG, KB_US, akbd_keydesc_sg),
+ KBD_MAP(KB_SG | KB_NODEAD, KB_SG, akbd_keydesc_sg_nodead),
KBD_MAP(KB_SV, KB_US, akbd_keydesc_sv),
KBD_MAP(KB_SV | KB_NODEAD, KB_SV, akbd_keydesc_sv_nodead),
- KBD_MAP(KB_DE, KB_US, akbd_keydesc_de),
- KBD_MAP(KB_DE | KB_NODEAD, KB_DE, akbd_keydesc_de_nodead),
KBD_MAP(KB_UK, KB_US, akbd_keydesc_uk),
- KBD_MAP(KB_ES, KB_US, akbd_keydesc_es),
- KBD_MAP(KB_PT, KB_US, akbd_keydesc_pt),
{0, 0, 0, 0}
};
#undef KBD_MAP
#undef KC
-
diff --git a/sys/arch/mac68k/dev/akbdvar.h b/sys/dev/adb/akbdvar.h
index 9688e8b421c..d3c2db3bb2b 100644
--- a/sys/arch/mac68k/dev/akbdvar.h
+++ b/sys/dev/adb/akbdvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: akbdvar.h,v 1.1 2006/01/04 20:39:04 miod Exp $ */
+/* $OpenBSD: akbdvar.h,v 1.1 2006/01/18 23:21:17 miod Exp $ */
/* $NetBSD: akbdvar.h,v 1.4 1999/02/17 14:56:56 tsubai Exp $ */
/*
@@ -31,10 +31,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _MAC68K_KBDVAR_H_
-#define _MAC68K_KBDVAR_H_
-
-#include <machine/adbsys.h>
+#ifndef _ADB_AKBDVAR_H_
+#define _ADB_AKBDVAR_H_
/*
* State info, per keyboard instance.
@@ -65,7 +63,10 @@ struct akbd_softc {
#define LED_CAPSLOCK 0x2
#define LED_SCROLL_LOCK 0x4
-void kbd_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command);
-int akbd_cnattach(void);
+int akbd_cnattach(void);
+int akbd_is_console(void);
+
+extern struct wskbd_mapdata akbd_keymapdata;
+extern int adb_polledkey;
-#endif /* _MAC68K_KBDVAR_H_ */
+#endif /* _ADB_AKBDVAR_H_ */
diff --git a/sys/arch/mac68k/dev/ams.c b/sys/dev/adb/ams.c
index a5f5e43bb0c..97edff1b7a5 100644
--- a/sys/arch/mac68k/dev/ams.c
+++ b/sys/dev/adb/ams.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: ams.c,v 1.4 2006/01/13 19:36:44 miod Exp $ */
+/* $OpenBSD: ams.c,v 1.1 2006/01/18 23:21:17 miod Exp $ */
/* $NetBSD: ams.c,v 1.11 2000/12/19 03:13:40 tsubai Exp $ */
/*
@@ -45,16 +45,14 @@
#include <dev/wscons/wsconsio.h>
#include <dev/wscons/wsmousevar.h>
-#include <mac68k/dev/adbvar.h>
-#include <mac68k/dev/amsvar.h>
+#include <dev/adb/adb.h>
+#include <dev/adb/amsvar.h>
/*
* Function declarations.
*/
int amsmatch(struct device *, void *, void *);
void amsattach(struct device *, struct device *, void *);
-void ems_init(struct ams_softc *);
-void ms_processevent(adb_event_t *event, struct ams_softc *);
/* Driver definition. */
struct cfattach ams_ca = {
@@ -65,10 +63,9 @@ struct cfdriver ams_cd = {
NULL, "ams", DV_DULL
};
-
-int ams_enable(void *);
-int ams_ioctl(void *, u_long, caddr_t, int, struct proc *);
-void ams_disable(void *);
+int ams_enable(void *);
+int ams_ioctl(void *, u_long, caddr_t, int, struct proc *);
+void ams_disable(void *);
const struct wsmouse_accessops ams_accessops = {
ams_enable,
@@ -76,6 +73,11 @@ const struct wsmouse_accessops ams_accessops = {
ams_disable,
};
+void ems_init(struct ams_softc *);
+void ms_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command);
+void ms_handoff(adb_event_t *event, struct ams_softc *);
+void ms_processevent(adb_event_t *event, struct ams_softc *);
+
int
amsmatch(struct device *parent, void *cf, void *aux)
{
@@ -177,10 +179,10 @@ amsattach(struct device *parent, struct device *self, void *aux)
sc->handler_id);
break;
}
- error = SetADBInfo(&adbinfo, sc->adbaddr);
+ error = set_adb_info(&adbinfo, sc->adbaddr);
#ifdef ADB_DEBUG
if (adb_debug)
- printf("ams: returned %d from SetADBInfo\n", error);
+ printf("ams: returned %d from set_adb_info\n", error);
#endif
a.accessops = &ams_accessops;
diff --git a/sys/arch/mac68k/dev/amsvar.h b/sys/dev/adb/amsvar.h
index a4d7960cbd6..e121af61fcd 100644
--- a/sys/arch/mac68k/dev/amsvar.h
+++ b/sys/dev/adb/amsvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: amsvar.h,v 1.1 2006/01/04 20:39:04 miod Exp $ */
+/* $OpenBSD: amsvar.h,v 1.1 2006/01/18 23:21:17 miod Exp $ */
/* $NetBSD: amsvar.h,v 1.4 1999/06/17 06:59:05 tsubai Exp $ */
/*
@@ -31,8 +31,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _MAC68K_AMSVAR_H_
-#define _MAC68K_AMSVAR_H_
+#ifndef _ADB_AMSVAR_H_
+#define _ADB_AMSVAR_H_
/*
* State info, per mouse instance.
@@ -49,7 +49,7 @@ struct ams_softc {
u_int8_t sc_class; /* mouse class (mouse, trackball) */
u_int8_t sc_buttons; /* number of buttons */
u_int32_t sc_res; /* mouse resolution (dpi) */
- char sc_devid[5]; /* device indentifier */
+ char sc_devid[5]; /* device identifier */
int sc_mb; /* current button state */
struct device *sc_wsmousedev;
@@ -61,7 +61,4 @@ struct ams_softc {
#define MSCLASS_TRACKBALL 2
#define MSCLASS_TRACKPAD 3
-void ms_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command);
-void ms_handoff(adb_event_t *event, struct ams_softc *);
-
-#endif /* _MAC68K_AMSVAR_H_ */
+#endif /* _ADB_AMSVAR_H_ */
diff --git a/sys/dev/adb/files.adb b/sys/dev/adb/files.adb
new file mode 100644
index 00000000000..7061d8ef0dc
--- /dev/null
+++ b/sys/dev/adb/files.adb
@@ -0,0 +1,11 @@
+# $OpenBSD: files.adb,v 1.1 2006/01/18 23:21:17 miod Exp $
+
+file dev/adb/adb_subr.c adb
+
+device akbd: wskbddev
+attach akbd at adb
+file dev/adb/akbd.c akbd needs-flag
+
+device ams: wsmousedev
+attach ams at adb
+file dev/adb/ams.c ams needs-flag
diff --git a/sys/dev/adb/keyboard.h b/sys/dev/adb/keyboard.h
new file mode 100644
index 00000000000..ae158f92b63
--- /dev/null
+++ b/sys/dev/adb/keyboard.h
@@ -0,0 +1,217 @@
+/* $OpenBSD: keyboard.h,v 1.1 2006/01/18 23:21:17 miod Exp $ */
+/* $NetBSD: keyboard.h,v 1.1 1998/05/15 10:15:54 tsubai Exp $ */
+
+/*-
+ * Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo,
+ * Michael L. Finch, Bradley A. Grantham, and
+ * Lawrence A. Kesteloot
+ * All rights reserved.
+ *
+ * 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 Alice Group.
+ * 4. The names of the Alice Group or any of its members may not be used
+ * to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``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 ALICE GROUP 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.
+ */
+
+#define ADBK_LEFT 0x3B
+#define ADBK_RIGHT 0x3C
+#define ADBK_UP 0x3E
+#define ADBK_DOWN 0x3D
+#define ADBK_PGUP 0x74
+#define ADBK_PGDN 0x79
+#define ADBK_HOME 0x73
+#define ADBK_END 0x77
+#define ADBK_CONTROL 0x36
+#define ADBK_FLOWER 0x37
+#define ADBK_SHIFT 0x38
+#define ADBK_CAPSLOCK 0x39
+#define ADBK_OPTION 0x3A
+#define ADBK_F 0x03
+#define ADBK_O 0x1F
+#define ADBK_P 0x23
+#define ADBK_Q 0x0C
+#define ADBK_V 0x09
+#define ADBK_1 0x12
+#define ADBK_2 0x13
+#define ADBK_3 0x14
+#define ADBK_4 0x15
+#define ADBK_5 0x17
+#define ADBK_6 0x16
+#define ADBK_7 0x1A
+#define ADBK_8 0x1C
+#define ADBK_9 0x19
+#define ADBK_0 0x1D
+
+#define ADBK_KEYVAL(key) ((key) & 0x7f)
+#define ADBK_PRESS(key) (((key) & 0x80) == 0)
+#define ADBK_KEYDOWN(key) (key)
+#define ADBK_KEYUP(key) ((key) | 0x80)
+#define ADBK_MODIFIER(key) ((((key) & 0x7f) == ADBK_SHIFT) || \
+ (((key) & 0x7f) == ADBK_CONTROL) || \
+ (((key) & 0x7f) == ADBK_FLOWER) || \
+ (((key) & 0x7f) == ADBK_OPTION))
+
+#ifndef KEYBOARD_ARRAY
+extern unsigned char keyboard[128][4];
+#else
+unsigned char keyboard[128][4] = {
+ /* Scan code Normal Shifted Controlled XT */
+ { /* 0x00, */ 'a', 'A', 0x01, 30 },
+ { /* 0x01, */ 's', 'S', 0x13, 31 },
+ { /* 0x02, */ 'd', 'D', 0x04, 32 },
+ { /* 0x03, */ 'f', 'F', 0x06, 33 },
+ { /* 0x04, */ 'h', 'H', 0x08, 35 },
+ { /* 0x05, */ 'g', 'G', 0x07, 34 },
+ { /* 0x06, */ 'z', 'Z', 0x1A, 44 },
+ { /* 0x07, */ 'x', 'X', 0x18, 45 },
+ { /* 0x08, */ 'c', 'C', 0x03, 46 },
+ { /* 0x09, */ 'v', 'V', 0x16, 47 },
+#ifdef FIX_SV_X_KBDBUG
+ { /* 0x0A, */ 0x00, 0x00, 0x00, 41 },
+#else
+ { /* 0x0A, */ 0x00, 0x00, 0x00, 86 },
+#endif
+ { /* 0x0B, */ 'b', 'B', 0x02, 48 },
+ { /* 0x0C, */ 'q', 'Q', 0x11, 16 },
+ { /* 0x0D, */ 'w', 'W', 0x17, 17 },
+ { /* 0x0E, */ 'e', 'E', 0x05, 18 },
+ { /* 0x0F, */ 'r', 'R', 0x12, 19 },
+ { /* 0x10, */ 'y', 'Y', 0x19, 21 },
+ { /* 0x11, */ 't', 'T', 0x14, 20 },
+ { /* 0x12, */ '1', '!', 0x00, 2 },
+ { /* 0x13, */ '2', '@', 0x00, 3 },
+ { /* 0x14, */ '3', '#', 0x00, 4 },
+ { /* 0x15, */ '4', '$', 0x00, 5 },
+ { /* 0x16, */ '6', '^', 0x1E, 7 },
+ { /* 0x17, */ '5', '%', 0x00, 6 },
+ { /* 0x18, */ '=', '+', 0x00, 13 },
+ { /* 0x19, */ '9', '(', 0x00, 10 },
+ { /* 0x1A, */ '7', '&', 0x00, 8 },
+ { /* 0x1B, */ '-', '_', 0x1F, 12 },
+ { /* 0x1C, */ '8', '*', 0x00, 9 },
+ { /* 0x1D, */ '0', ')', 0x00, 11 },
+ { /* 0x1E, */ ']', '}', 0x1D, 27 },
+ { /* 0x1F, */ 'o', 'O', 0x0F, 24 },
+ { /* 0x20, */ 'u', 'U', 0x15, 22 },
+ { /* 0x21, */ '[', '{', 0x1B, 26 },
+ { /* 0x22, */ 'i', 'I', 0x09, 23 },
+ { /* 0x23, */ 'p', 'P', 0x10, 25 },
+ { /* 0x24, */ 0x0D, 0x0D, 0x0D, 28 },
+ { /* 0x25, */ 'l', 'L', 0x0C, 38 },
+ { /* 0x26, */ 'j', 'J', 0x0A, 36 },
+ { /* 0x27, */ '\'', '"', 0x00, 40 },
+ { /* 0x28, */ 'k', 'K', 0x0B, 37 },
+ { /* 0x29, */ ';', ':', 0x00, 39 },
+ { /* 0x2A, */ '\\', '|', 0x1C, 43 },
+ { /* 0x2B, */ ',', '<', 0x00, 51 },
+ { /* 0x2C, */ '/', '?', 0x00, 53 },
+ { /* 0x2D, */ 'n', 'N', 0x0E, 49 },
+ { /* 0x2E, */ 'm', 'M', 0x0D, 50 },
+ { /* 0x2F, */ '.', '>', 0x00, 52 },
+ { /* 0x30, */ 0x09, 0x09, 0x09, 15 },
+ { /* 0x31, */ ' ', ' ', 0x00, 57 },
+#ifdef FIX_SV_X_KBDBUG
+ { /* 0x32, */ '`', '~', 0x00, 86 },
+#else
+ { /* 0x32, */ '`', '~', 0x00, 41 },
+#endif
+ { /* 0x33, */ 0x7F, 0x7F, 0x7F, 211 }, /* Delete */
+ { /* 0x34, */ 0x00, 0x00, 0x00, 105 }, /* MODE/KP_Enter */
+ { /* 0x35, */ 0x1B, 0x1B, 0x1B, 1 },
+ { /* 0x36, */ 0x00, 0x00, 0x00, 29 },
+ { /* 0x37, */ 0x00, 0x00, 0x00, 219 },
+ { /* 0x38, */ 0x00, 0x00, 0x00, 42 },
+ { /* 0x39, */ 0x00, 0x00, 0x00, 58 },
+ { /* 0x3A, */ 0x00, 0x00, 0x00, 56 }, /* L Alt */
+ { /* 0x3B, */ 'h', 0x00, 0x00, 203 }, /* Left */
+ { /* 0x3C, */ 'l', 0x00, 0x00, 205 }, /* Right */
+ { /* 0x3D, */ 'j', 0x00, 0x00, 208 }, /* Down */
+ { /* 0x3E, */ 'k', 0x00, 0x00, 200 }, /* Up */
+ { /* 0x3F, */ 0x00, 0x00, 0x00, 0 }, /* Fn */
+ { /* 0x40, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x41, */ '.', '.', 0x00, 83 },
+ { /* 0x42, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x43, */ '*', '*', 0x00, 55 },
+ { /* 0x44, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x45, */ '+', '+', 0x00, 78 },
+ { /* 0x46, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x47, */ 0x00, 0x00, 0x00, 69 },
+ { /* 0x48, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x49, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x4A, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x4B, */ '/', '/', 0x00, 181 },
+ { /* 0x4C, */ 0x0D, 0x0D, 0x0D, 156 },
+ { /* 0x4D, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x4E, */ '-', '-', 0x00, 74 },
+ { /* 0x4F, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x50, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x51, */ '=', '=', 0x00, 118 },
+ { /* 0x52, */ '0', '0', 0x00, 82 },
+ { /* 0x53, */ '1', '1', 0x00, 79 },
+ { /* 0x54, */ '2', '2', 0x00, 80 },
+ { /* 0x55, */ '3', '3', 0x00, 81 },
+ { /* 0x56, */ '4', '4', 0x00, 75 },
+ { /* 0x57, */ '5', '5', 0x00, 76 },
+ { /* 0x58, */ '6', '6', 0x00, 77 },
+ { /* 0x59, */ '7', '7', 0x00, 71 },
+ { /* 0x5A, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x5B, */ '8', '8', 0x00, 72 },
+ { /* 0x5C, */ '9', '9', 0x00, 73 },
+ { /* 0x5D, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x5E, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x5F, */ 0x00, 0x00, 0x00, 51 },
+ { /* 0x60, */ 0x00, 0x00, 0x00, 63 }, /* F5 */
+ { /* 0x61, */ 0x00, 0x00, 0x00, 64 }, /* F6 */
+ { /* 0x62, */ 0x00, 0x00, 0x00, 65 }, /* F7 */
+ { /* 0x63, */ 0x00, 0x00, 0x00, 61 }, /* F3 */
+ { /* 0x64, */ 0x00, 0x00, 0x00, 66 }, /* F8 */
+ { /* 0x65, */ 0x00, 0x00, 0x00, 67 }, /* F9 */
+ { /* 0x66, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x67, */ 0x00, 0x00, 0x00, 87 }, /* F11 */
+ { /* 0x68, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x69, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x6A, */ 0x00, 0x00, 0x00, 156 },
+ { /* 0x6B, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x6C, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x6D, */ 0x00, 0x00, 0x00, 68 }, /* F10 */
+ { /* 0x6E, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x6F, */ 0x00, 0x00, 0x00, 88 }, /* F12 */
+ { /* 0x70, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x71, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x72, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x73, */ 0x00, 0x00, 0x00, 199 },
+ { /* 0x74, */ 0x00, 0x00, 0x00, 201 },
+ { /* 0x75, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x76, */ 0x00, 0x00, 0x00, 62 }, /* F4 */
+ { /* 0x77, */ 0x00, 0x00, 0x00, 207 },
+ { /* 0x78, */ 0x00, 0x00, 0x00, 60 }, /* F2 */
+ { /* 0x79, */ 0x00, 0x00, 0x00, 209 },
+ { /* 0x7A, */ 0x00, 0x00, 0x00, 59 }, /* F1 */
+ { /* 0x7B, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x7C, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x7D, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x7E, */ 0x00, 0x00, 0x00, 0 },
+ { /* 0x7F, */ 0x00, 0x00, 0x00, 0 } /* pwr */
+};
+#endif /* KEYBOARD_ARRAY */