summaryrefslogtreecommitdiff
path: root/sys/arch/mac68k/dev
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/arch/mac68k/dev
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/arch/mac68k/dev')
-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/akbdmap.h431
-rw-r--r--sys/arch/mac68k/dev/akbdvar.h71
-rw-r--r--sys/arch/mac68k/dev/ams.c534
-rw-r--r--sys/arch/mac68k/dev/amsvar.h67
-rw-r--r--sys/arch/mac68k/dev/pm_direct.c3
10 files changed, 2870 insertions, 4569 deletions
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/akbdmap.h b/sys/arch/mac68k/dev/akbdmap.h
deleted file mode 100644
index 8e0c01f0523..00000000000
--- a/sys/arch/mac68k/dev/akbdmap.h
+++ /dev/null
@@ -1,431 +0,0 @@
-/* $NetBSD: akbdmap.h,v 1.7 2005/05/05 22:29:41 abs 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(52), KS_KP_Enter, /* Pretend this is alt-R ? */
- 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_Num_Lock,
- 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(96), KS_f5,
- KC(97), KS_f6,
- KC(98), KS_f7,
- KC(99), KS_f3,
- KC(100), KS_f8,
-
- KC(101), KS_f9,
-
- KC(103), KS_f11,
-
- KC(105), KS_Print_Screen,
- KC(106), KS_KP_Enter,
- KC(107), KS_Hold_Screen,
-
- KC(109), KS_f10,
-
- KC(111), KS_f12,
-
- KC(113), KS_Pause,
- KC(114), KS_Insert,
- KC(115), KS_Home,
- KC(116), KS_Prior,
- KC(117), KS_Delete,
- KC(118), KS_f4,
- KC(119), KS_End,
- KC(120), KS_f2,
- KC(121), KS_Next,
- KC(122), KS_f1,
-
- 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, 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(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(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(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(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(37), KS_l, KS_L, KS_notsign, KS_bar,
- KC(38), KS_j, KS_J, KS_Idiaeresis, KS_Igrave,
- 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(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,
- KC(45), KS_n, KS_N, KS_dead_tilde,
- KC(46), KS_comma, KS_question, KS_voidSymbol, KS_questiondown,
- KC(47), KS_colon, KS_slash, KS_division, 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 */
-};
-
-static const keysym_t akbd_keydesc_fr_nodead[] = {
- KC(18), KS_ampersand, KS_1, KS_voidSymbol, KS_acute,
- KC(33), KS_asciicircum, KS_diaeresis, KS_ocircumflex, KS_Ocircumflex,
- KC(42), KS_grave, KS_sterling, KS_at, KS_numbersign,
- KC(45), KS_n, KS_N, KS_asciitilde,
-};
-
-static const keysym_t akbd_keydesc_jp[] = {
-/* pos command normal shifted */
- KC(19), KS_2, KS_quotedbl,
- KC(22), KS_6, KS_ampersand,
- KC(24), KS_asciicircum, KS_asciitilde,
- KC(25), KS_9, KS_parenright,
- KC(26), KS_7, KS_apostrophe,
- KC(27), KS_minus, KS_equal,
- KC(28), KS_8, KS_parenleft,
- KC(29), KS_0,
- KC(30), KS_bracketleft, KS_braceleft,
- KC(33), KS_at, KS_grave,
- KC(39), KS_colon, KS_asterisk,
-
- KC(41), KS_semicolon, KS_plus,
- KC(42), KS_bracketright,KS_braceright,
- KC(93), KS_backslash, KS_bar,
- KC(94), KS_underscore,
-};
-
-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(58), 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[] = {
-/* pos normal shifted altgr shift-altgr */
- 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_es[] = {
-/* pos normal shifted altgr shift-altgr */
- KC(10), KS_degree, KS_ordfeminine, KS_backslash,
- KC(18), KS_1, KS_exclam, KS_bar,
- KC(19), KS_2, KS_quotedbl, KS_at,
- KC(20), KS_3, KS_periodcentered, KS_numbersign,
- KC(21), KS_4, KS_dollar, KS_asciitilde,
- KC(22), KS_6, KS_ampersand, KS_notsign,
- KC(23), KS_5, KS_percent,
- KC(24), KS_exclamdown, KS_questiondown,
- KC(25), KS_9, KS_parenright,
- KC(26), KS_7, KS_slash,
- KC(27), KS_apostrophe, KS_question,
- KC(28), KS_8, KS_parenleft,
- KC(29), KS_0, KS_equal,
- KC(30), KS_plus, KS_asterisk, KS_bracketright,
- KC(33), KS_dead_grave, KS_dead_circumflex, KS_bracketleft,
- KC(39), KS_dead_acute, KS_dead_diaeresis, KS_braceleft,
- KC(41), KS_ntilde,
- KC(42), KS_ccedilla, KS_Ccedilla, KS_braceright,
- 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(55), KS_Alt_L, /* Command */
- KC(58), KS_Mode_switch, KS_Multi_key, /* Option */
-};
-
-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(58), KS_Mode_switch,
- KC(81), KS_KP_Equal,
-};
-
-#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_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_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_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/arch/mac68k/dev/akbdvar.h
deleted file mode 100644
index 9688e8b421c..00000000000
--- a/sys/arch/mac68k/dev/akbdvar.h
+++ /dev/null
@@ -1,71 +0,0 @@
-/* $OpenBSD: akbdvar.h,v 1.1 2006/01/04 20:39:04 miod 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 _MAC68K_KBDVAR_H_
-#define _MAC68K_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 /* _MAC68K_KBDVAR_H_ */
diff --git a/sys/arch/mac68k/dev/ams.c b/sys/arch/mac68k/dev/ams.c
deleted file mode 100644
index a5f5e43bb0c..00000000000
--- a/sys/arch/mac68k/dev/ams.c
+++ /dev/null
@@ -1,534 +0,0 @@
-/* $OpenBSD: ams.c,v 1.4 2006/01/13 19:36:44 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 <mac68k/dev/adbvar.h>
-#include <mac68k/dev/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 = {
- 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,
-};
-
-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;
-}
-
-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.
- */
-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;
- /* 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/mac68k/dev/amsvar.h b/sys/arch/mac68k/dev/amsvar.h
deleted file mode 100644
index a4d7960cbd6..00000000000
--- a/sys/arch/mac68k/dev/amsvar.h
+++ /dev/null
@@ -1,67 +0,0 @@
-/* $OpenBSD: amsvar.h,v 1.1 2006/01/04 20:39:04 miod Exp $ */
-/* $NetBSD: amsvar.h,v 1.4 1999/06/17 06:59:05 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 _MAC68K_AMSVAR_H_
-#define _MAC68K_AMSVAR_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;
-};
-
-/* EMP device classes */
-#define MSCLASS_TABLET 0
-#define MSCLASS_MOUSE 1
-#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_ */
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>