diff options
author | Miod Vallat <miod@cvs.openbsd.org> | 2006-01-18 23:21:18 +0000 |
---|---|---|
committer | Miod Vallat <miod@cvs.openbsd.org> | 2006-01-18 23:21:18 +0000 |
commit | 86f7c20fe196e86a4d1c2ff666c443d883ea7744 (patch) | |
tree | 46eb3861bc677dbb3f6d3f92b54b9d4551984a84 /sys | |
parent | 692e73fadabe759f8814dda668273f20082e8cdb (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')
32 files changed, 5112 insertions, 6616 deletions
diff --git a/sys/arch/mac68k/conf/files.mac68k b/sys/arch/mac68k/conf/files.mac68k index 319d2c4d597..d31cb41db0d 100644 --- a/sys/arch/mac68k/conf/files.mac68k +++ b/sys/arch/mac68k/conf/files.mac68k @@ -1,4 +1,4 @@ -# $OpenBSD: files.mac68k,v 1.39 2006/01/13 19:36:41 miod Exp $ +# $OpenBSD: files.mac68k,v 1.40 2006/01/18 23:21:14 miod Exp $ # $NetBSD: files.mac68k,v 1.61 1997/03/01 20:22:16 scottr Exp $ # mac68k-specific configuration info @@ -22,8 +22,7 @@ file arch/mac68k/dev/nubus.c nubus device adb {} attach adb at obio file arch/mac68k/dev/adb.c adb -file arch/mac68k/dev/adb_direct.c adb -file arch/mac68k/dev/pm_direct.c +file arch/mac68k/dev/pm_direct.c adb # # "workstation console" routines @@ -35,13 +34,8 @@ include "dev/wsfont/files.wsfont" # # adb devices # -device akbd: wskbddev -attach akbd at adb -file arch/mac68k/dev/akbd.c akbd needs-flag - -device ams: wsmousedev -attach ams at adb -file arch/mac68k/dev/ams.c ams needs-flag +include "dev/adb/files.adb" +file arch/mac68k/dev/akbd_machdep.c akbd device asc attach asc at obio diff --git a/sys/arch/mac68k/dev/adb.c b/sys/arch/mac68k/dev/adb.c index aa8918ba0e7..37d361da486 100644 --- a/sys/arch/mac68k/dev/adb.c +++ b/sys/arch/mac68k/dev/adb.c @@ -1,5 +1,36 @@ -/* $OpenBSD: adb.c,v 1.18 2006/01/13 19:36:43 miod Exp $ */ +/* $OpenBSD: adb.c,v 1.19 2006/01/18 23:21:16 miod Exp $ */ /* $NetBSD: adb.c,v 1.47 2005/06/16 22:43:36 jmc Exp $ */ +/* $NetBSD: adb_direct.c,v 1.51 2005/06/16 22:43:36 jmc Exp $ */ + +/* + * Copyright (C) 1996, 1997 John P. Wittkoski + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by John P. Wittkoski. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ /* * Copyright (C) 1994 Bradley A. Grantham @@ -31,6 +62,33 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + * This code is rather messy, but I don't have time right now + * to clean it up as much as I would like. + * But it works, so I'm happy. :-) jpw + */ + +/* + * TO DO: + * - We could reduce the time spent in the adb_intr_* routines + * by having them save the incoming and outgoing data directly + * in the adbInbound and adbOutbound queues, as it would reduce + * the number of times we need to copy the data around. It + * would also make the code more readable and easier to follow. + * - (Related to above) Use the header part of adbCommand to + * reduce the number of copies we have to do of the data. + * - (Related to above) Actually implement the adbOutbound queue. + * This is fairly easy once you switch all the intr routines + * over to using adbCommand structs directly. + * - There is a bug in the state machine of adb_intr_cuda + * code that causes hangs, especially on 030 machines, probably + * because of some timing issues. Because I have been unable to + * determine the exact cause of this bug, I used the timeout function + * to check for and recover from this condition. If anyone finds + * the actual cause of this bug, the calls to timeout and the + * adb_cuda_tickle routine can be removed. + */ + #include <sys/param.h> #include <sys/device.h> #include <sys/fcntl.h> @@ -38,174 +96,2368 @@ #include <sys/selinfo.h> #include <sys/proc.h> #include <sys/signalvar.h> +#include <sys/timeout.h> #include <sys/systm.h> #include <machine/autoconf.h> #include <machine/cpu.h> +#include <machine/viareg.h> +#include <dev/adb/adb.h> #include <mac68k/dev/adbvar.h> +#define printf_intr printf + +int adb_polling; /* Are we polling? (Debugger mode) */ +#ifdef ADB_DEBUG +int adb_debug; /* Output debugging messages */ +#endif /* ADB_DEBUG */ + +/* some misc. leftovers */ +#define vPB 0x0000 +#define vPB3 0x08 +#define vPB4 0x10 +#define vPB5 0x20 +#define vSR_INT 0x04 +#define vSR_OUT 0x10 + +/* the type of ADB action that we are currently preforming */ +#define ADB_ACTION_NOTREADY 0x1 /* has not been initialized yet */ +#define ADB_ACTION_IDLE 0x2 /* the bus is currently idle */ +#define ADB_ACTION_OUT 0x3 /* sending out a command */ +#define ADB_ACTION_IN 0x4 /* receiving data */ +#define ADB_ACTION_POLLING 0x5 /* polling - II only */ + /* - * Function declarations. + * These describe the state of the ADB bus itself, although they + * don't necessarily correspond directly to ADB states. + * Note: these are not really used in the IIsi code. */ -int adbmatch(struct device *, void *, void *); -void adbattach(struct device *, struct device *, void *); -int adbprint(void *, const char *); -void adb_attach_deferred(void *); +#define ADB_BUS_UNKNOWN 0x1 /* we don't know yet - all models */ +#define ADB_BUS_IDLE 0x2 /* bus is idle - all models */ +#define ADB_BUS_CMD 0x3 /* starting a command - II models */ +#define ADB_BUS_ODD 0x4 /* the "odd" state - II models */ +#define ADB_BUS_EVEN 0x5 /* the "even" state - II models */ +#define ADB_BUS_ACTIVE 0x6 /* active state - IIsi models */ +#define ADB_BUS_ACK 0x7 /* currently ACKing - IIsi models */ + +/* + * Shortcuts for setting or testing the VIA bit states. + * Not all shortcuts are used for every type of ADB hardware. + */ +#define ADB_SET_STATE_IDLE_II() via_reg(VIA1, vBufB) |= (vPB4 | vPB5) +#define ADB_SET_STATE_IDLE_IISI() via_reg(VIA1, vBufB) &= ~(vPB4 | vPB5) +#define ADB_SET_STATE_IDLE_CUDA() via_reg(VIA1, vBufB) |= (vPB4 | vPB5) +#define ADB_SET_STATE_CMD() via_reg(VIA1, vBufB) &= ~(vPB4 | vPB5) +#define ADB_SET_STATE_EVEN() via_reg(VIA1, vBufB) = ((via_reg(VIA1, \ + vBufB) | vPB4) & ~vPB5) +#define ADB_SET_STATE_ODD() via_reg(VIA1, vBufB) = ((via_reg(VIA1, \ + vBufB) | vPB5) & ~vPB4) +#define ADB_SET_STATE_ACTIVE() via_reg(VIA1, vBufB) |= vPB5 +#define ADB_SET_STATE_INACTIVE() via_reg(VIA1, vBufB) &= ~vPB5 +#define ADB_SET_STATE_TIP() via_reg(VIA1, vBufB) &= ~vPB5 +#define ADB_CLR_STATE_TIP() via_reg(VIA1, vBufB) |= vPB5 +#define ADB_SET_STATE_ACKON() via_reg(VIA1, vBufB) |= vPB4 +#define ADB_SET_STATE_ACKOFF() via_reg(VIA1, vBufB) &= ~vPB4 +#define ADB_TOGGLE_STATE_ACK_CUDA() via_reg(VIA1, vBufB) ^= vPB4 +#define ADB_SET_STATE_ACKON_CUDA() via_reg(VIA1, vBufB) &= ~vPB4 +#define ADB_SET_STATE_ACKOFF_CUDA() via_reg(VIA1, vBufB) |= vPB4 +#define ADB_SET_SR_INPUT() via_reg(VIA1, vACR) &= ~vSR_OUT +#define ADB_SET_SR_OUTPUT() via_reg(VIA1, vACR) |= vSR_OUT +#define ADB_SR() via_reg(VIA1, vSR) +#define ADB_VIA_INTR_ENABLE() via_reg(VIA1, vIER) = 0x84 +#define ADB_VIA_INTR_DISABLE() via_reg(VIA1, vIER) = 0x04 +#define ADB_VIA_CLR_INTR() via_reg(VIA1, vIFR) = 0x04 +#define ADB_INTR_IS_OFF (vPB3 == (via_reg(VIA1, vBufB) & vPB3)) +#define ADB_INTR_IS_ON (0 == (via_reg(VIA1, vBufB) & vPB3)) +#define ADB_SR_INTR_IS_OFF (0 == (via_reg(VIA1, vIFR) & vSR_INT)) +#define ADB_SR_INTR_IS_ON (vSR_INT == (via_reg(VIA1, \ + vIFR) & vSR_INT)) -extern void adb_jadbproc(void); +/* + * This is the delay that is required (in uS) between certain + * ADB transactions. The actual timing delay for for each uS is + * calculated at boot time to account for differences in machine speed. + */ +#define ADB_DELAY 150 /* - * Global variables. + * Maximum ADB message length; includes space for data, result, and + * device code - plus a little for safety. */ -int adb_polling = 0; /* Are we polling? (Debugger mode) */ -#ifdef ADB_DEBUG -int adb_debug = 0; /* Output debugging messages */ -#endif /* ADB_DEBUG */ +#define ADB_MAX_MSG_LENGTH 16 +#define ADB_MAX_HDR_LENGTH 8 -extern struct mac68k_machine_S mac68k_machine; -extern int adbHardware; -extern char *adbHardwareDescr[]; +#define ADB_QUEUE 32 +#define ADB_TICKLE_TICKS 4 /* - * Driver definition. + * A structure for storing information about each ADB device. */ -struct cfattach adb_ca = { - sizeof(struct device), adbmatch, adbattach +struct ADBDevEntry { + void (*ServiceRtPtr)(void); + void *DataAreaAddr; + int devType; + int origAddr; + int currentAddr; }; -struct cfdriver adb_cd = { - NULL, "adb", DV_DULL + +/* + * Used to hold ADB commands that are waiting to be sent out. + */ +struct adbCmdHoldEntry { + u_char outBuf[ADB_MAX_MSG_LENGTH]; /* our message */ + u_char *saveBuf; /* buffer to know where to save result */ + u_char *compRout; /* completion routine pointer */ + u_char *data; /* completion routine data pointer */ }; -int -adbmatch(struct device *parent, void *vcf, void *aux) -{ - static int adb_matched = 0; +/* + * Eventually used for two separate queues, the queue between + * the upper and lower halves, and the outgoing packet queue. + * TO DO: adbCommand can replace all of adbCmdHoldEntry eventually + */ +struct adbCommand { + u_char header[ADB_MAX_HDR_LENGTH]; /* not used yet */ + u_char data[ADB_MAX_MSG_LENGTH]; /* packet data only */ + u_char *saveBuf; /* where to save result */ + u_char *compRout; /* completion routine pointer */ + u_char *compData; /* completion routine data pointer */ + u_int cmd; /* the original command for this data */ + u_int unsol; /* 1 if packet was unsolicited */ + u_int ack_only; /* 1 for no special processing */ +}; - /* Allow only one instance. */ - if (adb_matched) - return (0); +/* + * Text representations of each hardware class + */ +const char *adbHardwareDescr[MAX_ADB_HW + 1] = { + "unknown", + "II series", + "IIsi series", + "PowerBook", + "Cuda", +}; - adb_matched = 1; - return (1); -} +/* + * A few variables that we need and their initial values. + */ +int adbHardware = ADB_HW_UNKNOWN; +int adbActionState = ADB_ACTION_NOTREADY; +int adbBusState = ADB_BUS_UNKNOWN; +int adbWaiting = 0; /* waiting for return data from the device */ +int adbWriteDelay = 0; /* working on (or waiting to do) a write */ +int adbOutQueueHasData = 0; /* something in the queue waiting to go out */ +int adbNextEnd = 0; /* the next incoming bute is the last (II) */ +int adbSoftPower = 0; /* machine supports soft power */ + +int adbWaitingCmd = 0; /* ADB command we are waiting for */ +u_char *adbBuffer = (long)0; /* pointer to user data area */ +void *adbCompRout = (long)0; /* pointer to the completion routine */ +void *adbCompData = (long)0; /* pointer to the completion routine data */ +long adbFakeInts = 0; /* keeps track of fake ADB interrupts for + * timeouts (II) */ +int adbStarting = 1; /* doing adb_reinit so do polling differently */ +int adbSendTalk = 0; /* the intr routine is sending the talk, not + * the user (II) */ +int adbPolling = 0; /* we are polling for service request */ +int adbPollCmd = 0; /* the last poll command we sent */ + +u_char adbInputBuffer[ADB_MAX_MSG_LENGTH]; /* data input buffer */ +u_char adbOutputBuffer[ADB_MAX_MSG_LENGTH]; /* data output buffer */ +struct adbCmdHoldEntry adbOutQueue; /* our 1 entry output queue */ + +int adbSentChars = 0; /* how many characters we have sent */ +int adbLastDevice = 0; /* last ADB dev we heard from (II ONLY) */ +int adbLastDevIndex = 0; /* last ADB dev loc in dev table (II ONLY) */ +int adbLastCommand = 0; /* the last ADB command we sent (II) */ +struct ADBDevEntry ADBDevTable[16]; /* our ADB device table */ +int ADBNumDevices; /* num. of ADB devices found with adb_reinit */ + +struct adbCommand adbInbound[ADB_QUEUE]; /* incoming queue */ +volatile int adbInCount = 0; /* how many packets in in queue */ +int adbInHead = 0; /* head of in queue */ +int adbInTail = 0; /* tail of in queue */ +struct adbCommand adbOutbound[ADB_QUEUE]; /* outgoing queue - not used yet */ +int adbOutCount = 0; /* how many packets in out queue */ +int adbOutHead = 0; /* head of out queue */ +int adbOutTail = 0; /* tail of out queue */ + +int tickle_count = 0; /* how many tickles seen for this packet? */ +int tickle_serial = 0; /* the last packet tickled */ +int adb_cuda_serial = 0; /* the current packet */ + +struct timeout adb_cuda_timeout; + +void pm_setup_adb(void); +void pm_hw_setup(void); +void pm_check_adb_devices(int); +int pm_adb_op(u_char *, void *, void *, int); +void pm_init_adb_device(void); + +/* + * The following are private routines. + */ +#ifdef ADB_DEBUG +void print_single(u_char *); +#endif +int adb_intr(void *); +int adb_intr_II(void *); +int adb_intr_IIsi(void *); +int adb_intr_cuda(void *); +void adb_soft_intr(void); +int send_adb_II(u_char *, u_char *, void *, void *, int); +int send_adb_IIsi(u_char *, u_char *, void *, void *, int); +int send_adb_cuda(u_char *, u_char *, void *, void *, int); +void adb_intr_cuda_test(void); +void adb_cuda_tickle(void); +void adb_pass_up(struct adbCommand *); +void adb_op_comprout(caddr_t, caddr_t, int); +void adb_reinit(void); +int count_adbs(void); +int get_ind_adb_info(ADBDataBlock *, int); +int get_adb_info(ADBDataBlock *, int); +int set_adb_info(ADBSetInfoBlock *, int); +void adb_setup_hw_type(void); +int adb_op(Ptr, Ptr, Ptr, short); +void adb_read_II(u_char *); +void adb_hw_setup(void); +void adb_hw_setup_IIsi(u_char *); +int adb_cmd_result(u_char *); +int adb_cmd_extra(u_char *); +int adb_guess_next_device(void); +int adb_prog_switch_enable(void); +int adb_prog_switch_disable(void); +/* we should create this and it will be the public version */ +int send_adb(u_char *, void *, void *); + +#ifdef ADB_DEBUG +/* + * print_single + * Diagnostic display routine. Displays the hex values of the + * specified elements of the u_char. The length of the "string" + * is in [0]. + */ void -adbattach(struct device *parent, struct device *self, void *aux) +print_single(u_char *str) { - printf("\n"); - startuphook_establish(adb_attach_deferred, self); + int x; + + if (str == 0) { + printf_intr("no data - null pointer\n"); + return; + } + if (*str == 0) { + printf_intr("nothing returned\n"); + return; + } + if (*str > 20) { + printf_intr("ADB: ACK > 20 no way!\n"); + *str = (u_char)20; + } + printf_intr("(length=0x%x):", (u_int)*str); + for (x = 1; x <= *str; x++) + printf_intr(" 0x%02x", (u_int)*(str + x)); + printf_intr("\n"); } +#endif void -adb_attach_deferred(void *v) +adb_cuda_tickle(void) { - struct device *self = v; - ADBDataBlock adbdata; - struct adb_attach_args aa_args; - int totaladbs; - int adbindex, adbaddr; + volatile int s; - printf("%s", self->dv_xname); - adb_polling = 1; + if (adbActionState == ADB_ACTION_IN) { + if (tickle_serial == adb_cuda_serial) { + if (++tickle_count > 0) { + s = splhigh(); + adbActionState = ADB_ACTION_IDLE; + adbInputBuffer[0] = 0; + ADB_SET_STATE_IDLE_CUDA(); + splx(s); + } + } else { + tickle_serial = adb_cuda_serial; + tickle_count = 0; + } + } else { + tickle_serial = adb_cuda_serial; + tickle_count = 0; + } - ADBReInit(); - printf(": %s", adbHardwareDescr[adbHardware]); + timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS); +} + +/* + * called when when an adb interrupt happens + * + * Cuda version of adb_intr + * TO DO: do we want to add some calls to intr_dispatch() here to + * grab serial interrupts? + */ +int +adb_intr_cuda(void *arg) +{ + volatile int i, ending; + volatile unsigned int s; + struct adbCommand packet; + + s = splhigh(); /* can't be too careful - might be called */ + /* from a routine, NOT an interrupt */ + + ADB_VIA_CLR_INTR(); /* clear interrupt */ + ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */ + +switch_start: + switch (adbActionState) { + case ADB_ACTION_IDLE: + /* + * This is an unexpected packet, so grab the first (dummy) + * byte, set up the proper vars, and tell the chip we are + * starting to receive the packet by setting the TIP bit. + */ + adbInputBuffer[1] = ADB_SR(); + adb_cuda_serial++; + if (ADB_INTR_IS_OFF) /* must have been a fake start */ + break; + + ADB_SET_SR_INPUT(); + ADB_SET_STATE_TIP(); + + adbInputBuffer[0] = 1; + adbActionState = ADB_ACTION_IN; +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("idle 0x%02x ", adbInputBuffer[1]); +#endif + break; + + case ADB_ACTION_IN: + adbInputBuffer[++adbInputBuffer[0]] = ADB_SR(); + /* intr off means this is the last byte (end of frame) */ + if (ADB_INTR_IS_OFF) + ending = 1; + else + ending = 0; + + if (1 == ending) { /* end of message? */ +#ifdef ADB_DEBUG + if (adb_debug) { + printf_intr("in end 0x%02x ", + adbInputBuffer[adbInputBuffer[0]]); + print_single(adbInputBuffer); + } +#endif + + /* + * Are we waiting AND does this packet match what we + * are waiting for AND is it coming from either the + * ADB or RTC/PRAM sub-device? This section _should_ + * recognize all ADB and RTC/PRAM type commands, but + * there may be more... NOTE: commands are always at + * [4], even for RTC/PRAM commands. + */ + /* set up data for adb_pass_up */ + memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1); + + if ((adbWaiting == 1) && + (adbInputBuffer[4] == adbWaitingCmd) && + ((adbInputBuffer[2] == 0x00) || + (adbInputBuffer[2] == 0x01))) { + packet.saveBuf = adbBuffer; + packet.compRout = adbCompRout; + packet.compData = adbCompData; + packet.unsol = 0; + packet.ack_only = 0; + adb_pass_up(&packet); + + adbWaitingCmd = 0; /* reset "waiting" vars */ + adbWaiting = 0; + adbBuffer = (long)0; + adbCompRout = (long)0; + adbCompData = (long)0; + } else { + packet.unsol = 1; + packet.ack_only = 0; + adb_pass_up(&packet); + } + + + /* reset vars and signal the end of this frame */ + adbActionState = ADB_ACTION_IDLE; + adbInputBuffer[0] = 0; + ADB_SET_STATE_IDLE_CUDA(); + /*ADB_SET_SR_INPUT();*/ + + /* + * If there is something waiting to be sent out, + * the set everything up and send the first byte. + */ + if (adbWriteDelay == 1) { + delay(ADB_DELAY); /* required */ + adbSentChars = 0; + adbActionState = ADB_ACTION_OUT; + /* + * If the interrupt is on, we were too slow + * and the chip has already started to send + * something to us, so back out of the write + * and start a read cycle. + */ + if (ADB_INTR_IS_ON) { + ADB_SET_SR_INPUT(); + ADB_SET_STATE_IDLE_CUDA(); + adbSentChars = 0; + adbActionState = ADB_ACTION_IDLE; + adbInputBuffer[0] = 0; + break; + } + /* + * If we got here, it's ok to start sending + * so load the first byte and tell the chip + * we want to send. + */ + ADB_SET_STATE_TIP(); + ADB_SET_SR_OUTPUT(); + ADB_SR() = adbOutputBuffer[adbSentChars + 1]; + } + } else { + ADB_TOGGLE_STATE_ACK_CUDA(); +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("in 0x%02x ", + adbInputBuffer[adbInputBuffer[0]]); +#endif + } + break; + + case ADB_ACTION_OUT: + i = ADB_SR(); /* reset SR-intr in IFR */ +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("intr out 0x%02x ", i); +#endif + + adbSentChars++; + if (ADB_INTR_IS_ON) { /* ADB intr low during write */ +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("intr was on "); +#endif + ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ + ADB_SET_STATE_IDLE_CUDA(); + adbSentChars = 0; /* must start all over */ + adbActionState = ADB_ACTION_IDLE; /* new state */ + adbInputBuffer[0] = 0; + adbWriteDelay = 1; /* must retry when done with + * read */ + delay(ADB_DELAY); + goto switch_start; /* process next state right + * now */ + break; + } + if (adbOutputBuffer[0] == adbSentChars) { /* check for done */ + if (0 == adb_cmd_result(adbOutputBuffer)) { /* do we expect data + * back? */ + adbWaiting = 1; /* signal waiting for return */ + adbWaitingCmd = adbOutputBuffer[2]; /* save waiting command */ + } else { /* no talk, so done */ + /* set up stuff for adb_pass_up */ + memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1); + packet.saveBuf = adbBuffer; + packet.compRout = adbCompRout; + packet.compData = adbCompData; + packet.cmd = adbWaitingCmd; + packet.unsol = 0; + packet.ack_only = 1; + adb_pass_up(&packet); + + /* reset "waiting" vars, just in case */ + adbWaitingCmd = 0; + adbBuffer = (long)0; + adbCompRout = (long)0; + adbCompData = (long)0; + } + + adbWriteDelay = 0; /* done writing */ + adbActionState = ADB_ACTION_IDLE; /* signal bus is idle */ + ADB_SET_SR_INPUT(); + ADB_SET_STATE_IDLE_CUDA(); +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("write done "); +#endif + } else { + ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* send next byte */ + ADB_TOGGLE_STATE_ACK_CUDA(); /* signal byte ready to + * shift */ +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("toggle "); +#endif + } + break; + + case ADB_ACTION_NOTREADY: +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("adb: not yet initialized\n"); +#endif + break; + + default: +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("intr: unknown ADB state\n"); +#endif + break; + } + + ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */ + + splx(s); /* restore */ + + return (1); +} /* end adb_intr_cuda */ + + +int +send_adb_cuda(u_char *in, u_char *buffer, void *compRout, void *data, int + command) +{ + int s, len; #ifdef ADB_DEBUG if (adb_debug) - printf("adb: done with ADBReInit\n"); + printf_intr("SEND\n"); #endif - totaladbs = CountADBs(); + if (adbActionState == ADB_ACTION_NOTREADY) + return 1; - printf(", %d target%s\n", totaladbs, (totaladbs == 1) ? "" : "s"); + /* Don't interrupt while we are messing with the ADB */ + s = splhigh(); - /* for each ADB device */ - for (adbindex = 1; adbindex <= totaladbs; adbindex++) { - /* Get the ADB information */ - adbaddr = GetIndADB(&adbdata, adbindex); + if ((adbActionState == ADB_ACTION_IDLE) && /* ADB available? */ + (ADB_INTR_IS_OFF)) { /* and no incoming interrupt? */ + } else + if (adbWriteDelay == 0) /* it's busy, but is anything waiting? */ + adbWriteDelay = 1; /* if no, then we'll "queue" + * it up */ + else { + splx(s); + return 1; /* really busy! */ + } - aa_args.origaddr = (int)(adbdata.origADBAddr); - aa_args.adbaddr = adbaddr; - aa_args.handler_id = (int)(adbdata.devType); +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("QUEUE\n"); +#endif + if ((long)in == (long)0) { /* need to convert? */ + /* + * Don't need to use adb_cmd_extra here because this section + * will be called ONLY when it is an ADB command (no RTC or + * PRAM) + */ + if ((command & 0x0c) == 0x08) /* copy addl data ONLY if + * doing a listen! */ + len = buffer[0]; /* length of additional data */ + else + len = 0;/* no additional data */ - (void)config_found(self, &aa_args, adbprint); + adbOutputBuffer[0] = 2 + len; /* dev. type + command + addl. + * data */ + adbOutputBuffer[1] = 0x00; /* mark as an ADB command */ + adbOutputBuffer[2] = (u_char)command; /* load command */ + + /* copy additional output data, if any */ + memcpy(adbOutputBuffer + 3, buffer + 1, len); + } else + /* if data ready, just copy over */ + memcpy(adbOutputBuffer, in, in[0] + 2); + + adbSentChars = 0; /* nothing sent yet */ + adbBuffer = buffer; /* save buffer to know where to save result */ + adbCompRout = compRout; /* save completion routine pointer */ + adbCompData = data; /* save completion routine data pointer */ + adbWaitingCmd = adbOutputBuffer[2]; /* save wait command */ + + if (adbWriteDelay != 1) { /* start command now? */ +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("out start NOW"); +#endif + delay(ADB_DELAY); + adbActionState = ADB_ACTION_OUT; /* set next state */ + ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ + ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* load byte for output */ + ADB_SET_STATE_ACKOFF_CUDA(); + ADB_SET_STATE_TIP(); /* tell ADB that we want to send */ } - adb_polling = 0; -} + adbWriteDelay = 1; /* something in the write "queue" */ + + splx(s); + + if (0x0100 <= (s & 0x0700)) /* were VIA1 interrupts blocked? */ + /* poll until byte done */ + while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON) + || (adbWaiting == 1)) + if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */ + adb_intr_cuda(NULL); /* go process it */ + if (adb_polling) + adb_soft_intr(); + } + + return 0; +} /* send_adb_cuda */ int -adbprint(void *args, const char *name) +adb_intr_II(void *arg) { - struct adb_attach_args *aa_args = (struct adb_attach_args *)args; - int rv = UNCONF; + struct adbCommand packet; + int i, intr_on = 0; + int send = 0; + unsigned int s; + + s = splhigh(); /* can't be too careful - might be called */ + /* from a routine, NOT an interrupt */ + + ADB_VIA_CLR_INTR(); /* clear interrupt */ + + ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */ + + delay(ADB_DELAY); /* yuck (don't remove) */ + + (void)intr_dispatch(0x70); /* grab any serial interrupts */ - if (name) { /* no configured device matched */ - rv = UNSUPP; /* most ADB device types are unsupported */ + if (ADB_INTR_IS_ON) + intr_on = 1; /* save for later */ + +switch_start: + switch (adbActionState) { + case ADB_ACTION_POLLING: + if (!intr_on) { + if (adbOutQueueHasData) { +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("POLL-doing-out-queue. "); +#endif + ADB_SET_STATE_IDLE_II(); + delay(ADB_DELAY); - /* print out what kind of ADB device we have found */ - switch(aa_args->origaddr) { -#ifdef ADBVERBOSE - case ADBADDR_SECURE: - printf("security dongle (%d)", - aa_args->handler_id); + /* copy over data */ + memcpy(adbOutputBuffer, adbOutQueue.outBuf, + adbOutQueue.outBuf[0] + 2); + + adbBuffer = adbOutQueue.saveBuf; /* user data area */ + adbCompRout = adbOutQueue.compRout; /* completion routine */ + adbCompData = adbOutQueue.data; /* comp. rout. data */ + adbOutQueueHasData = 0; /* currently processing + * "queue" entry */ + adbSentChars = 0; /* nothing sent yet */ + adbActionState = ADB_ACTION_OUT; /* set next state */ + ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ + ADB_SR() = adbOutputBuffer[1]; /* load byte for output */ + adbBusState = ADB_BUS_CMD; /* set bus to cmd state */ + ADB_SET_STATE_CMD(); /* tell ADB that we want to send */ + break; + } else { +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("pIDLE "); +#endif + adbActionState = ADB_ACTION_IDLE; + } + } else { +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("pIN "); +#endif + adbActionState = ADB_ACTION_IN; + } + delay(ADB_DELAY); + (void)intr_dispatch(0x70); /* grab any serial interrupts */ + goto switch_start; + break; + case ADB_ACTION_IDLE: + if (!intr_on) { + i = ADB_SR(); + adbBusState = ADB_BUS_IDLE; + adbActionState = ADB_ACTION_IDLE; + ADB_SET_STATE_IDLE_II(); break; + } + adbInputBuffer[0] = 1; + adbInputBuffer[1] = ADB_SR(); /* get first byte */ +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("idle 0x%02x ", adbInputBuffer[1]); +#endif + ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ + adbActionState = ADB_ACTION_IN; /* set next state */ + ADB_SET_STATE_EVEN(); /* set bus state to even */ + adbBusState = ADB_BUS_EVEN; + break; + + case ADB_ACTION_IN: + adbInputBuffer[++adbInputBuffer[0]] = ADB_SR(); /* get byte */ +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("in 0x%02x ", + adbInputBuffer[adbInputBuffer[0]]); +#endif + ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ + + if (intr_on) { /* process last byte of packet */ + adbInputBuffer[0]--; /* minus one */ + /* + * If intr_on was true, and it's the second byte, then + * the byte we just discarded is really valid, so + * adjust the count + */ + if (adbInputBuffer[0] == 2) { + adbInputBuffer[0]++; + } + +#ifdef ADB_DEBUG + if (adb_debug & 0x80) { + printf_intr("done: "); + print_single(adbInputBuffer); + } #endif - case ADBADDR_MAP: - printf("mapped device (%d)", - aa_args->handler_id); - rv = UNCONF; + + adbLastDevice = ADB_CMDADDR(adbInputBuffer[1]); + + if (adbInputBuffer[0] == 1 && !adbWaiting) { /* SRQ!!!*/ +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr(" xSRQ! "); +#endif + adb_guess_next_device(); +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("try 0x%0x ", + adbLastDevice); +#endif + adbOutputBuffer[0] = 1; + adbOutputBuffer[1] = ADBTALK(adbLastDevice, 0); + + adbSentChars = 0; /* nothing sent yet */ + adbActionState = ADB_ACTION_POLLING; /* set next state */ + ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ + ADB_SR() = adbOutputBuffer[1]; /* load byte for output */ + adbBusState = ADB_BUS_CMD; /* set bus to cmd state */ + ADB_SET_STATE_CMD(); /* tell ADB that we want to */ + break; + } + + /* set up data for adb_pass_up */ + memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1); + + if (!adbWaiting && (adbInputBuffer[0] != 0)) { + packet.unsol = 1; + packet.ack_only = 0; + adb_pass_up(&packet); + } else { + packet.saveBuf = adbBuffer; + packet.compRout = adbCompRout; + packet.compData = adbCompData; + packet.unsol = 0; + packet.ack_only = 0; + adb_pass_up(&packet); + } + + adbWaiting = 0; + adbInputBuffer[0] = 0; + adbBuffer = (long)0; + adbCompRout = (long)0; + adbCompData = (long)0; + /* + * Since we are done, check whether there is any data + * waiting to do out. If so, start the sending the data. + */ + if (adbOutQueueHasData == 1) { +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("XXX: DOING OUT QUEUE\n"); +#endif + /* copy over data */ + memcpy(adbOutputBuffer, adbOutQueue.outBuf, + adbOutQueue.outBuf[0] + 2); + adbBuffer = adbOutQueue.saveBuf; /* user data area */ + adbCompRout = adbOutQueue.compRout; /* completion routine */ + adbCompData = adbOutQueue.data; /* comp. rout. data */ + adbOutQueueHasData = 0; /* currently processing + * "queue" entry */ + send = 1; + } else { +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("XXending "); +#endif + adb_guess_next_device(); + adbOutputBuffer[0] = 1; + adbOutputBuffer[1] = ((adbLastDevice & 0x0f) << 4) | 0x0c; + adbSentChars = 0; /* nothing sent yet */ + adbActionState = ADB_ACTION_POLLING; /* set next state */ + ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ + ADB_SR() = adbOutputBuffer[1]; /* load byte for output */ + adbBusState = ADB_BUS_CMD; /* set bus to cmd state */ + ADB_SET_STATE_CMD(); /* tell ADB that we want to */ + break; + } + } + + /* + * If send is true then something above determined that + * the message has ended and we need to start sending out + * a new message immediately. This could be because there + * is data waiting to go out or because an SRQ was seen. + */ + if (send) { + adbSentChars = 0; /* nothing sent yet */ + adbActionState = ADB_ACTION_OUT; /* set next state */ + ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ + ADB_SR() = adbOutputBuffer[1]; /* load byte for output */ + adbBusState = ADB_BUS_CMD; /* set bus to cmd state */ + ADB_SET_STATE_CMD(); /* tell ADB that we want to + * send */ + break; + } + /* We only get this far if the message hasn't ended yet. */ + switch (adbBusState) { /* set to next state */ + case ADB_BUS_EVEN: + ADB_SET_STATE_ODD(); /* set state to odd */ + adbBusState = ADB_BUS_ODD; + break; + + case ADB_BUS_ODD: + ADB_SET_STATE_EVEN(); /* set state to even */ + adbBusState = ADB_BUS_EVEN; + break; + default: + printf_intr("strange state!!!\n"); /* huh? */ break; - case ADBADDR_REL: - printf("relative positioning device (%d)", - aa_args->handler_id); - rv = UNCONF; + } + break; + + case ADB_ACTION_OUT: + i = ADB_SR(); /* clear interrupt */ + adbSentChars++; + /* + * If the outgoing data was a TALK, we must + * switch to input mode to get the result. + */ + if ((adbOutputBuffer[1] & 0x0c) == 0x0c) { + adbInputBuffer[0] = 1; + adbInputBuffer[1] = i; + adbActionState = ADB_ACTION_IN; + ADB_SET_SR_INPUT(); + adbBusState = ADB_BUS_EVEN; + ADB_SET_STATE_EVEN(); +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("talk out 0x%02x ", i); +#endif + /* we want something back */ + adbWaiting = 1; break; -#ifdef ADBVERBOSE - case ADBADDR_ABS: - switch (aa_args->handler_id) { - case ADB_ARTPAD: - printf("WACOM ArtPad II"); + } + /* + * If it's not a TALK, check whether all data has been sent. + * If so, call the completion routine and clean up. If not, + * advance to the next state. + */ +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("non-talk out 0x%0x ", i); +#endif + ADB_SET_SR_OUTPUT(); + if (adbOutputBuffer[0] == adbSentChars) { /* check for done */ +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("done \n"); +#endif + /* set up stuff for adb_pass_up */ + memcpy(packet.data, adbOutputBuffer, adbOutputBuffer[0] + 1); + packet.saveBuf = adbBuffer; + packet.compRout = adbCompRout; + packet.compData = adbCompData; + packet.cmd = adbWaitingCmd; + packet.unsol = 0; + packet.ack_only = 1; + adb_pass_up(&packet); + + /* reset "waiting" vars, just in case */ + adbBuffer = (long)0; + adbCompRout = (long)0; + adbCompData = (long)0; + if (adbOutQueueHasData == 1) { + /* copy over data */ + memcpy(adbOutputBuffer, adbOutQueue.outBuf, + adbOutQueue.outBuf[0] + 2); + adbBuffer = adbOutQueue.saveBuf; /* user data area */ + adbCompRout = adbOutQueue.compRout; /* completion routine */ + adbCompData = adbOutQueue.data; /* comp. rout. data */ + adbOutQueueHasData = 0; /* currently processing + * "queue" entry */ + adbSentChars = 0; /* nothing sent yet */ + adbActionState = ADB_ACTION_OUT; /* set next state */ + ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ + ADB_SR() = adbOutputBuffer[1]; /* load byte for output */ + adbBusState = ADB_BUS_CMD; /* set bus to cmd state */ + ADB_SET_STATE_CMD(); /* tell ADB that we want to + * send */ break; - default: - printf("absolute positioning device (%d)", - aa_args->handler_id); + } else { + /* send talk to last device instead */ + adbOutputBuffer[0] = 1; + adbOutputBuffer[1] = + ADBTALK(ADB_CMDADDR(adbOutputBuffer[1]), 0); + + adbSentChars = 0; /* nothing sent yet */ + adbActionState = ADB_ACTION_IDLE; /* set next state */ + ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ + ADB_SR() = adbOutputBuffer[1]; /* load byte for output */ + adbBusState = ADB_BUS_CMD; /* set bus to cmd state */ + ADB_SET_STATE_CMD(); /* tell ADB that we want to */ break; } + } + ADB_SR() = adbOutputBuffer[adbSentChars + 1]; + switch (adbBusState) { /* advance to next state */ + case ADB_BUS_EVEN: + ADB_SET_STATE_ODD(); /* set state to odd */ + adbBusState = ADB_BUS_ODD; break; - case ADBADDR_DATATX: - printf("data transfer device (modem?) (%d)", - aa_args->handler_id); + + case ADB_BUS_CMD: + case ADB_BUS_ODD: + ADB_SET_STATE_EVEN(); /* set state to even */ + adbBusState = ADB_BUS_EVEN; + break; + + default: +#ifdef ADB_DEBUG + if (adb_debug) { + printf_intr("strange state!!! (0x%x)\n", + adbBusState); + } +#endif break; - case ADBADDR_MISC: - switch (aa_args->handler_id) { - case ADB_POWERKEY: - printf("Sophisticated Circuits PowerKey"); + } + break; + + default: +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("adb: unknown ADB state (during intr)\n"); +#endif + break; + } + + ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */ + + splx(s); /* restore */ + + return (1); + +} + + +/* + * send_adb version for II series machines + */ +int +send_adb_II(u_char *in, u_char *buffer, void *compRout, void *data, int command) +{ + int s, len; + + if (adbActionState == ADB_ACTION_NOTREADY) /* return if ADB not + * available */ + return 1; + + /* Don't interrupt while we are messing with the ADB */ + s = splhigh(); + + if (0 != adbOutQueueHasData) { /* right now, "has data" means "full" */ + splx(s); /* sorry, try again later */ + return 1; + } + if ((long)in == (long)0) { /* need to convert? */ + /* + * Don't need to use adb_cmd_extra here because this section + * will be called ONLY when it is an ADB command (no RTC or + * PRAM), especially on II series! + */ + if ((command & 0x0c) == 0x08) /* copy addl data ONLY if + * doing a listen! */ + len = buffer[0]; /* length of additional data */ + else + len = 0;/* no additional data */ + + adbOutQueue.outBuf[0] = 1 + len; /* command + addl. data */ + adbOutQueue.outBuf[1] = (u_char)command; /* load command */ + + /* copy additional output data, if any */ + memcpy(adbOutQueue.outBuf + 2, buffer + 1, len); + } else + /* if data ready, just copy over */ + memcpy(adbOutQueue.outBuf, in, in[0] + 2); + + adbOutQueue.saveBuf = buffer; /* save buffer to know where to save + * result */ + adbOutQueue.compRout = compRout; /* save completion routine + * pointer */ + adbOutQueue.data = data;/* save completion routine data pointer */ + + if ((adbActionState == ADB_ACTION_IDLE) && /* is ADB available? */ + (ADB_INTR_IS_OFF)) { /* and no incoming interrupts? */ + /* then start command now */ + memcpy(adbOutputBuffer, adbOutQueue.outBuf, + adbOutQueue.outBuf[0] + 2); /* copy over data */ + + adbBuffer = adbOutQueue.saveBuf; /* pointer to user data + * area */ + adbCompRout = adbOutQueue.compRout; /* pointer to the + * completion routine */ + adbCompData = adbOutQueue.data; /* pointer to the completion + * routine data */ + + adbSentChars = 0; /* nothing sent yet */ + adbActionState = ADB_ACTION_OUT; /* set next state */ + adbBusState = ADB_BUS_CMD; /* set bus to cmd state */ + + ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ + + ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* load byte for output */ + ADB_SET_STATE_CMD(); /* tell ADB that we want to send */ + adbOutQueueHasData = 0; /* currently processing "queue" entry */ + } else + adbOutQueueHasData = 1; /* something in the write "queue" */ + + splx(s); + + if (0x0100 <= (s & 0x0700)) /* were VIA1 interrupts blocked? */ + /* poll until message done */ + while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON) + || (adbWaiting == 1)) + if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */ + adb_intr_II(NULL); /* go process it */ + if (adb_polling) + adb_soft_intr(); + } + + return 0; +} + + +/* + * This routine is called from the II series interrupt routine + * to determine what the "next" device is that should be polled. + */ +int +adb_guess_next_device(void) +{ + int last, i, dummy; + + if (adbStarting) { + /* + * Start polling EVERY device, since we can't be sure there is + * anything in the device table yet + */ + if (adbLastDevice < 1 || adbLastDevice > 15) + adbLastDevice = 1; + if (++adbLastDevice > 15) /* point to next one */ + adbLastDevice = 1; + } else { + /* find the next device using the device table */ + if (adbLastDevice < 1 || adbLastDevice > 15) /* let's be parinoid */ + adbLastDevice = 2; + last = 1; /* default index location */ + + for (i = 1; i < 16; i++) /* find index entry */ + if (ADBDevTable[i].currentAddr == adbLastDevice) { /* look for device */ + last = i; /* found it */ break; - default: - printf("misc. device (remote control?) (%d)", - aa_args->handler_id); + } + dummy = last; /* index to start at */ + for (;;) { /* find next device in index */ + if (++dummy > 15) /* wrap around if needed */ + dummy = 1; + if (dummy == last) { /* didn't find any other + * device! This can happen if + * there are no devices on the + * bus */ + dummy = 1; break; } + /* found the next device */ + if (ADBDevTable[dummy].devType != 0) + break; + } + adbLastDevice = ADBDevTable[dummy].currentAddr; + } + return adbLastDevice; +} + + +/* + * Called when when an adb interrupt happens. + * This routine simply transfers control over to the appropriate + * code for the machine we are running on. + */ +int +adb_intr(void *arg) +{ + switch (adbHardware) { + case ADB_HW_II: + return adb_intr_II(arg); + break; + + case ADB_HW_IISI: + return adb_intr_IIsi(arg); + break; + + case ADB_HW_PB: /* Should not come through here. */ + break; + + case ADB_HW_CUDA: + return adb_intr_cuda(arg); + break; + + case ADB_HW_UNKNOWN: + break; + } + + return (-1); +} + + +/* + * called when when an adb interrupt happens + * + * IIsi version of adb_intr + * + */ +int +adb_intr_IIsi(void *arg) +{ + struct adbCommand packet; + int i, ending; + unsigned int s; + + s = splhigh(); /* can't be too careful - might be called */ + /* from a routine, NOT an interrupt */ + + ADB_VIA_CLR_INTR(); /* clear interrupt */ + + ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */ + +switch_start: + switch (adbActionState) { + case ADB_ACTION_IDLE: + delay(ADB_DELAY); /* short delay is required before the + * first byte */ + + ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ + ADB_SET_STATE_ACTIVE(); /* signal start of data frame */ + adbInputBuffer[1] = ADB_SR(); /* get byte */ + adbInputBuffer[0] = 1; + adbActionState = ADB_ACTION_IN; /* set next state */ + + ADB_SET_STATE_ACKON(); /* start ACK to ADB chip */ + delay(ADB_DELAY); /* delay */ + ADB_SET_STATE_ACKOFF(); /* end ACK to ADB chip */ + (void)intr_dispatch(0x70); /* grab any serial interrupts */ + break; + + case ADB_ACTION_IN: + ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ + adbInputBuffer[++adbInputBuffer[0]] = ADB_SR(); /* get byte */ + if (ADB_INTR_IS_OFF) /* check for end of frame */ + ending = 1; + else + ending = 0; + + ADB_SET_STATE_ACKON(); /* start ACK to ADB chip */ + delay(ADB_DELAY); /* delay */ + ADB_SET_STATE_ACKOFF(); /* end ACK to ADB chip */ + (void)intr_dispatch(0x70); /* grab any serial interrupts */ + + if (1 == ending) { /* end of message? */ + ADB_SET_STATE_INACTIVE(); /* signal end of frame */ + /* + * This section _should_ handle all ADB and RTC/PRAM + * type commands, but there may be more... Note: + * commands are always at [4], even for rtc/pram + * commands + */ + /* set up data for adb_pass_up */ + memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1); + + if ((adbWaiting == 1) && /* are we waiting AND */ + (adbInputBuffer[4] == adbWaitingCmd) && /* the cmd we sent AND */ + ((adbInputBuffer[2] == 0x00) || /* it's from the ADB + * device OR */ + (adbInputBuffer[2] == 0x01))) { /* it's from the + * PRAM/RTC device */ + + packet.saveBuf = adbBuffer; + packet.compRout = adbCompRout; + packet.compData = adbCompData; + packet.unsol = 0; + packet.ack_only = 0; + adb_pass_up(&packet); + + adbWaitingCmd = 0; /* reset "waiting" vars */ + adbWaiting = 0; + adbBuffer = (long)0; + adbCompRout = (long)0; + adbCompData = (long)0; + } else { + packet.unsol = 1; + packet.ack_only = 0; + adb_pass_up(&packet); + } + + adbActionState = ADB_ACTION_IDLE; + adbInputBuffer[0] = 0; /* reset length */ + + if (adbWriteDelay == 1) { /* were we waiting to + * write? */ + adbSentChars = 0; /* nothing sent yet */ + adbActionState = ADB_ACTION_OUT; /* set next state */ + + delay(ADB_DELAY); /* delay */ + (void)intr_dispatch(0x70); /* grab any serial interrupts */ + + if (ADB_INTR_IS_ON) { /* ADB intr low during + * write */ + ADB_SET_STATE_IDLE_IISI(); /* reset */ + ADB_SET_SR_INPUT(); /* make sure SR is set + * to IN */ + adbSentChars = 0; /* must start all over */ + adbActionState = ADB_ACTION_IDLE; /* new state */ + adbInputBuffer[0] = 0; + /* may be able to take this out later */ + delay(ADB_DELAY); /* delay */ + break; + } + ADB_SET_STATE_ACTIVE(); /* tell ADB that we want + * to send */ + ADB_SET_STATE_ACKOFF(); /* make sure */ + ADB_SET_SR_OUTPUT(); /* set shift register + * for OUT */ + ADB_SR() = adbOutputBuffer[adbSentChars + 1]; + ADB_SET_STATE_ACKON(); /* tell ADB byte ready + * to shift */ + } + } + break; + + case ADB_ACTION_OUT: + i = ADB_SR(); /* reset SR-intr in IFR */ + ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ + + ADB_SET_STATE_ACKOFF(); /* finish ACK */ + adbSentChars++; + if (ADB_INTR_IS_ON) { /* ADB intr low during write */ + ADB_SET_STATE_IDLE_IISI(); /* reset */ + ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ + adbSentChars = 0; /* must start all over */ + adbActionState = ADB_ACTION_IDLE; /* new state */ + adbInputBuffer[0] = 0; + adbWriteDelay = 1; /* must retry when done with + * read */ + delay(ADB_DELAY); /* delay */ + (void)intr_dispatch(0x70); /* grab any serial interrupts */ + goto switch_start; /* process next state right + * now */ break; - default: - printf("unknown type %d device, (handler %d)", - aa_args->origaddr, aa_args->handler_id); + } + delay(ADB_DELAY); /* required delay */ + (void)intr_dispatch(0x70); /* grab any serial interrupts */ + + if (adbOutputBuffer[0] == adbSentChars) { /* check for done */ + if (0 == adb_cmd_result(adbOutputBuffer)) { /* do we expect data + * back? */ + adbWaiting = 1; /* signal waiting for return */ + adbWaitingCmd = adbOutputBuffer[2]; /* save waiting command */ + } else {/* no talk, so done */ + /* set up stuff for adb_pass_up */ + memcpy(packet.data, adbInputBuffer, + adbInputBuffer[0] + 1); + packet.saveBuf = adbBuffer; + packet.compRout = adbCompRout; + packet.compData = adbCompData; + packet.cmd = adbWaitingCmd; + packet.unsol = 0; + packet.ack_only = 1; + adb_pass_up(&packet); + + /* reset "waiting" vars, just in case */ + adbWaitingCmd = 0; + adbBuffer = (long)0; + adbCompRout = (long)0; + adbCompData = (long)0; + } + + adbWriteDelay = 0; /* done writing */ + adbActionState = ADB_ACTION_IDLE; /* signal bus is idle */ + ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ + ADB_SET_STATE_INACTIVE(); /* end of frame */ + } else { + ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* send next byte */ + ADB_SET_STATE_ACKON(); /* signal byte ready to shift */ + } + break; + + case ADB_ACTION_NOTREADY: +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("adb: not yet initialized\n"); +#endif + break; + + default: +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("intr: unknown ADB state\n"); +#endif + break; + } + + ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */ + + splx(s); /* restore */ + + return (1); +} /* end adb_intr_IIsi */ + + +/***************************************************************************** + * if the device is currently busy, and there is no data waiting to go out, then + * the data is "queued" in the outgoing buffer. If we are already waiting, then + * we return. + * in: if (in == 0) then the command string is built from command and buffer + * if (in != 0) then in is used as the command string + * buffer: additional data to be sent (used only if in == 0) + * this is also where return data is stored + * compRout: the completion routine that is called when then return value + * is received (if a return value is expected) + * data: a data pointer that can be used by the completion routine + * command: an ADB command to be sent (used only if in == 0) + * + */ +int +send_adb_IIsi(u_char *in, u_char *buffer, void *compRout, void *data, int + command) +{ + int s, len; + + if (adbActionState == ADB_ACTION_NOTREADY) + return 1; + + /* Don't interrupt while we are messing with the ADB */ + s = splhigh(); + + if ((adbActionState == ADB_ACTION_IDLE) && /* ADB available? */ + (ADB_INTR_IS_OFF)) {/* and no incoming interrupt? */ + + } else + if (adbWriteDelay == 0) /* it's busy, but is anything waiting? */ + adbWriteDelay = 1; /* if no, then we'll "queue" + * it up */ + else { + splx(s); + return 1; /* really busy! */ + } + + if ((long)in == (long)0) { /* need to convert? */ + /* + * Don't need to use adb_cmd_extra here because this section + * will be called ONLY when it is an ADB command (no RTC or + * PRAM) + */ + if ((command & 0x0c) == 0x08) /* copy addl data ONLY if + * doing a listen! */ + len = buffer[0]; /* length of additional data */ + else + len = 0;/* no additional data */ + + adbOutputBuffer[0] = 2 + len; /* dev. type + command + addl. + * data */ + adbOutputBuffer[1] = 0x00; /* mark as an ADB command */ + adbOutputBuffer[2] = (u_char)command; /* load command */ + + /* copy additional output data, if any */ + memcpy(adbOutputBuffer + 3, buffer + 1, len); + } else + /* if data ready, just copy over */ + memcpy(adbOutputBuffer, in, in[0] + 2); + + adbSentChars = 0; /* nothing sent yet */ + adbBuffer = buffer; /* save buffer to know where to save result */ + adbCompRout = compRout; /* save completion routine pointer */ + adbCompData = data; /* save completion routine data pointer */ + adbWaitingCmd = adbOutputBuffer[2]; /* save wait command */ + + if (adbWriteDelay != 1) { /* start command now? */ + adbActionState = ADB_ACTION_OUT; /* set next state */ + + ADB_SET_STATE_ACTIVE(); /* tell ADB that we want to send */ + ADB_SET_STATE_ACKOFF(); /* make sure */ + + ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ + + ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* load byte for output */ + + ADB_SET_STATE_ACKON(); /* tell ADB byte ready to shift */ + } + adbWriteDelay = 1; /* something in the write "queue" */ + + splx(s); + + if (0x0100 <= (s & 0x0700)) /* were VIA1 interrupts blocked? */ + /* poll until byte done */ + while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON) + || (adbWaiting == 1)) + if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */ + adb_intr_IIsi(NULL); /* go process it */ + if (adb_polling) + adb_soft_intr(); + } + + return 0; +} /* send_adb_IIsi */ + +/* + * adb_pass_up is called by the interrupt-time routines. + * It takes the raw packet data that was received from the + * device and puts it into the queue that the upper half + * processes. It then signals for a soft ADB interrupt which + * will eventually call the upper half routine (adb_soft_intr). + * + * If in->unsol is 0, then this is either the notification + * that the packet was sent (on a LISTEN, for example), or the + * response from the device (on a TALK). The completion routine + * is called only if the user specified one. + * + * If in->unsol is 1, then this packet was unsolicited and + * so we look up the device in the ADB device table to determine + * what it's default service routine is. + * + * If in->ack_only is 1, then we really only need to call + * the completion routine, so don't do any other stuff. + * + * Note that in->data contains the packet header AND data, + * while adbInbound[]->data contains ONLY data. + * + * Note: Called only at interrupt time. Assumes this. + */ +void +adb_pass_up(struct adbCommand *in) +{ + int start = 0, len = 0, cmd = 0; + ADBDataBlock block; + + /* temp for testing */ + /*u_char *buffer = 0;*/ + /*u_char *compdata = 0;*/ + /*u_char *comprout = 0;*/ + + if (adbInCount >= ADB_QUEUE) { +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("adb: ring buffer overflow\n"); +#endif + return; + } + + if (in->ack_only) { + len = in->data[0]; + cmd = in->cmd; + start = 0; + } else { + switch (adbHardware) { + case ADB_HW_II: + cmd = in->data[1]; + if (in->data[0] < 2) + len = 0; + else + len = in->data[0]-1; + start = 1; break; -#endif /* ADBVERBOSE */ + + case ADB_HW_IISI: + case ADB_HW_CUDA: + /* If it's unsolicited, accept only ADB data for now */ + if (in->unsol) + if (0 != in->data[2]) + return; + cmd = in->data[4]; + if (in->data[0] < 5) + len = 0; + else + len = in->data[0]-4; + start = 4; + break; + + case ADB_HW_PB: + cmd = in->data[1]; + if (in->data[0] < 2) + len = 0; + else + len = in->data[0]-1; + start = 1; + break; + + case ADB_HW_UNKNOWN: + return; + } + + /* Make sure there is a valid device entry for this device */ + if (in->unsol) { + /* ignore unsolicited data during adbreinit */ + if (adbStarting) + return; + /* get device's comp. routine and data area */ + if (-1 == get_adb_info(&block, ADB_CMDADDR(cmd))) + return; + } + } + + /* + * If this is an unsolicited packet, we need to fill in + * some info so adb_soft_intr can process this packet + * properly. If it's not unsolicited, then use what + * the caller sent us. + */ + if (in->unsol) { + adbInbound[adbInTail].compRout = (void *)block.dbServiceRtPtr; + adbInbound[adbInTail].compData = (void *)block.dbDataAreaAddr; + adbInbound[adbInTail].saveBuf = (void *)adbInbound[adbInTail].data; + } else { + adbInbound[adbInTail].compRout = (void *)in->compRout; + adbInbound[adbInTail].compData = (void *)in->compData; + adbInbound[adbInTail].saveBuf = (void *)in->saveBuf; + } + +#ifdef ADB_DEBUG + if (adb_debug && in->data[1] == 2) + printf_intr("adb: caught error\n"); +#endif + + /* copy the packet data over */ + /* + * TO DO: If the *_intr routines fed their incoming data + * directly into an adbCommand struct, which is passed to + * this routine, then we could eliminate this copy. + */ + memcpy(adbInbound[adbInTail].data + 1, in->data + start + 1, len); + adbInbound[adbInTail].data[0] = len; + adbInbound[adbInTail].cmd = cmd; + + adbInCount++; + if (++adbInTail >= ADB_QUEUE) + adbInTail = 0; + + /* + * If the debugger is running, call upper half manually. + * Otherwise, trigger a soft interrupt to handle the rest later. + */ + if (adb_polling) + adb_soft_intr(); + else + setsoftadb(); + + return; +} + + +/* + * Called to process the packets after they have been + * placed in the incoming queue. + * + */ +void +adb_soft_intr(void) +{ + int s; + int cmd = 0; + u_char *buffer = 0; + u_char *comprout = 0; + u_char *compdata = 0; + +/*delay(2*ADB_DELAY);*/ + + while (adbInCount) { +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("%x %x %x ", + adbInCount, adbInHead, adbInTail); +#endif + /* get the data we need from the queue */ + buffer = adbInbound[adbInHead].saveBuf; + comprout = adbInbound[adbInHead].compRout; + compdata = adbInbound[adbInHead].compData; + cmd = adbInbound[adbInHead].cmd; + + /* copy over data to data area if it's valid */ + /* + * Note that for unsol packets we don't want to copy the + * data anywhere, so buffer was already set to 0. + * For ack_only buffer was set to 0, so don't copy. + */ + if (buffer) + memcpy(buffer, adbInbound[adbInHead].data, + adbInbound[adbInHead].data[0] + 1); + +#ifdef ADB_DEBUG + if (adb_debug & 0x80) { + printf_intr("%p %p %p %x ", + buffer, comprout, compdata, (short)cmd); + printf_intr("buf: "); + print_single(adbInbound[adbInHead].data); + } +#endif + + /* call default completion routine if it's valid */ + if (comprout) { + (void)((int (*)(u_char *, u_char *, int))comprout) + (buffer, compdata, cmd); } - printf(" at %s", name); + + s = splhigh(); + adbInCount--; + if (++adbInHead >= ADB_QUEUE) + adbInHead = 0; + splx(s); + } + return; +} + + +/* + * This is my version of the ADBOp routine. It mainly just calls the + * hardware-specific routine. + * + * data : pointer to data area to be used by compRout + * compRout : completion routine + * buffer : for LISTEN: points to data to send - MAX 8 data bytes, + * byte 0 = # of bytes + * : for TALK: points to place to save return data + * command : the adb command to send + * result : 0 = success + * : -1 = could not complete + */ +int +adb_op(Ptr buffer, Ptr compRout, Ptr data, short command) +{ + int result; + + switch (adbHardware) { + case ADB_HW_II: + result = send_adb_II((u_char *)0, (u_char *)buffer, + (void *)compRout, (void *)data, (int)command); + if (result == 0) + return 0; + else + return -1; + break; + + case ADB_HW_IISI: + result = send_adb_IIsi((u_char *)0, (u_char *)buffer, + (void *)compRout, (void *)data, (int)command); + /* + * I wish I knew why this delay is needed. It usually needs to + * be here when several commands are sent in close succession, + * especially early in device probes when doing collision + * detection. It must be some race condition. Sigh. - jpw + */ + delay(100); + if (result == 0) + return 0; + else + return -1; + break; + + case ADB_HW_PB: + result = pm_adb_op((u_char *)buffer, (void *)compRout, + (void *)data, (int)command); + + if (result == 0) + return 0; + else + return -1; + break; - printf(" addr %d", aa_args->adbaddr); + case ADB_HW_CUDA: + result = send_adb_cuda((u_char *)0, (u_char *)buffer, + (void *)compRout, (void *)data, (int)command); + if (result == 0) + return 0; + else + return -1; + break; - return (rv); + case ADB_HW_UNKNOWN: + default: + return -1; + } } /* + * adb_hw_setup + * This routine sets up the possible machine specific hardware + * config (mainly VIA settings) for the various models. + */ +void +adb_hw_setup(void) +{ + volatile int i; + u_char send_string[ADB_MAX_MSG_LENGTH]; + + switch (adbHardware) { + case ADB_HW_II: + via1_register_irq(2, adb_intr_II, NULL, NULL); + + via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5: + * outputs */ + via_reg(VIA1, vDirB) &= 0xf7; /* register B bit 3: input */ + via_reg(VIA1, vACR) &= ~vSR_OUT; /* make sure SR is set + * to IN (II, IIsi) */ + adbActionState = ADB_ACTION_IDLE; /* used by all types of + * hardware (II, IIsi) */ + adbBusState = ADB_BUS_IDLE; /* this var. used in II-series + * code only */ + via_reg(VIA1, vIER) = 0x84; /* make sure VIA interrupts + * are on (II, IIsi) */ + ADB_SET_STATE_IDLE_II(); /* set ADB bus state to idle */ + + ADB_VIA_CLR_INTR(); /* clear interrupt */ + break; + + case ADB_HW_IISI: + via1_register_irq(2, adb_intr_IIsi, NULL, NULL); + via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5: + * outputs */ + via_reg(VIA1, vDirB) &= 0xf7; /* register B bit 3: input */ + via_reg(VIA1, vACR) &= ~vSR_OUT; /* make sure SR is set + * to IN (II, IIsi) */ + adbActionState = ADB_ACTION_IDLE; /* used by all types of + * hardware (II, IIsi) */ + adbBusState = ADB_BUS_IDLE; /* this var. used in II-series + * code only */ + via_reg(VIA1, vIER) = 0x84; /* make sure VIA interrupts + * are on (II, IIsi) */ + ADB_SET_STATE_IDLE_IISI(); /* set ADB bus state to idle */ + + /* get those pesky clock ticks we missed while booting */ + for (i = 0; i < 30; i++) { + delay(ADB_DELAY); + adb_hw_setup_IIsi(send_string); +#ifdef ADB_DEBUG + if (adb_debug) { + printf_intr("adb: cleanup: "); + print_single(send_string); + } +#endif + delay(ADB_DELAY); + if (ADB_INTR_IS_OFF) + break; + } + break; + + case ADB_HW_PB: + /* + * XXX - really PM_VIA_CLR_INTR - should we put it in + * pm_direct.h? + */ + pm_hw_setup(); + break; + + case ADB_HW_CUDA: + via1_register_irq(2, adb_intr_cuda, NULL, NULL); + via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5: + * outputs */ + via_reg(VIA1, vDirB) &= 0xf7; /* register B bit 3: input */ + via_reg(VIA1, vACR) &= ~vSR_OUT; /* make sure SR is set + * to IN */ + via_reg(VIA1, vACR) = (via_reg(VIA1, vACR) | 0x0c) & ~0x10; + adbActionState = ADB_ACTION_IDLE; /* used by all types of + * hardware */ + adbBusState = ADB_BUS_IDLE; /* this var. used in II-series + * code only */ + via_reg(VIA1, vIER) = 0x84; /* make sure VIA interrupts + * are on */ + ADB_SET_STATE_IDLE_CUDA(); /* set ADB bus state to idle */ + + /* sort of a device reset */ + i = ADB_SR(); /* clear interrupt */ + ADB_VIA_INTR_DISABLE(); /* no interrupts while clearing */ + ADB_SET_STATE_IDLE_CUDA(); /* reset state to idle */ + delay(ADB_DELAY); + ADB_SET_STATE_TIP(); /* signal start of frame */ + delay(ADB_DELAY); + ADB_TOGGLE_STATE_ACK_CUDA(); + delay(ADB_DELAY); + ADB_CLR_STATE_TIP(); + delay(ADB_DELAY); + ADB_SET_STATE_IDLE_CUDA(); /* back to idle state */ + i = ADB_SR(); /* clear interrupt */ + ADB_VIA_INTR_ENABLE(); /* ints ok now */ + break; + + case ADB_HW_UNKNOWN: + default: + via_reg(VIA1, vIER) = 0x04; /* turn interrupts off - TO + * DO: turn PB ints off? */ + return; + break; + } +} + + +/* + * adb_hw_setup_IIsi + * This is sort of a "read" routine that forces the adb hardware through a read cycle + * if there is something waiting. This helps "clean up" any commands that may have gotten + * stuck or stopped during the boot process. + * + */ +void +adb_hw_setup_IIsi(u_char *buffer) +{ + int i; + int dummy; + int s; + long my_time; + int endofframe; + + delay(ADB_DELAY); + + i = 1; /* skip over [0] */ + s = splhigh(); /* block ALL interrupts while we are working */ + ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ + ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */ + /* this is required, especially on faster machines */ + delay(ADB_DELAY); + + if (ADB_INTR_IS_ON) { + ADB_SET_STATE_ACTIVE(); /* signal start of data frame */ + + endofframe = 0; + while (0 == endofframe) { + /* + * Poll for ADB interrupt and watch for timeout. + * If time out, keep going in hopes of not hanging + * the ADB chip - I think + */ + my_time = ADB_DELAY * 5; + while ((ADB_SR_INTR_IS_OFF) && (my_time-- > 0)) + dummy = via_reg(VIA1, vBufB); + + buffer[i++] = ADB_SR(); /* reset interrupt flag by + * reading vSR */ + /* + * Perhaps put in a check here that ignores all data + * after the first ADB_MAX_MSG_LENGTH bytes ??? + */ + if (ADB_INTR_IS_OFF) /* check for end of frame */ + endofframe = 1; + + ADB_SET_STATE_ACKON(); /* send ACK to ADB chip */ + delay(ADB_DELAY); /* delay */ + ADB_SET_STATE_ACKOFF(); /* send ACK to ADB chip */ + } + ADB_SET_STATE_INACTIVE(); /* signal end of frame and + * delay */ + + /* probably don't need to delay this long */ + delay(ADB_DELAY); + } + buffer[0] = --i; /* [0] is length of message */ + ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */ + splx(s); /* restore interrupts */ + + return; +} /* adb_hw_setup_IIsi */ + + + +/* + * adb_reinit sets up the adb stuff + * + */ +void +adb_reinit(void) +{ + u_char send_string[ADB_MAX_MSG_LENGTH]; + ADBDataBlock data; /* temp. holder for getting device info */ + volatile int i, x; + int s; + int command; + int result; + int saveptr; /* point to next free relocation address */ + int device; + int nonewtimes; /* times thru loop w/o any new devices */ + + via1_register_irq(2, adb_intr, NULL, "adb"); + adb_setup_hw_type(); /* setup hardware type */ + + /* Make sure we are not interrupted while building the table. */ + /* ints must be on for PB & IOP (at least, for now) */ + if (adbHardware != ADB_HW_PB) + s = splhigh(); + else + s = 0; /* XXX shut the compiler up*/ + + ADBNumDevices = 0; /* no devices yet */ + + /* Let intr routines know we are running reinit */ + adbStarting = 1; + + /* + * Initialize the ADB table. For now, we'll always use the same table + * that is defined at the beginning of this file - no mallocs. + */ + for (i = 0; i < 16; i++) { + ADBDevTable[i].devType = 0; + ADBDevTable[i].origAddr = ADBDevTable[i].currentAddr = 0; + } + + adb_hw_setup(); /* init the VIA bits and hard reset ADB */ + + delay(1000); + + /* send an ADB reset first */ + (void)adb_op_sync((Ptr)0, (Ptr)0, (Ptr)0, (short)0x00); + delay(3000); + + /* + * Probe for ADB devices. Probe devices 1-15 quickly to determine + * which device addresses are in use and which are free. For each + * address that is in use, move the device at that address to a higher + * free address. Continue doing this at that address until no device + * responds at that address. Then move the last device that was moved + * back to the original address. Do this for the remaining addresses + * that we determined were in use. + * + * When finished, do this entire process over again with the updated + * list of in use addresses. Do this until no new devices have been + * found in 20 passes though the in use address list. (This probably + * seems long and complicated, but it's the best way to detect multiple + * devices at the same address - sometimes it takes a couple of tries + * before the collision is detected.) + */ + + /* initial scan through the devices */ + for (i = 1; i < 16; i++) { + command = ADBTALK(i, 3); + result = adb_op_sync((Ptr)send_string, (Ptr)0, + (Ptr)0, (short)command); + + if (result == 0 && send_string[0] != 0) { + /* found a device */ + ++ADBNumDevices; + KASSERT(ADBNumDevices < 16); + ADBDevTable[ADBNumDevices].devType = + (int)(send_string[2]); + ADBDevTable[ADBNumDevices].origAddr = i; + ADBDevTable[ADBNumDevices].currentAddr = i; + ADBDevTable[ADBNumDevices].DataAreaAddr = + (long)0; + ADBDevTable[ADBNumDevices].ServiceRtPtr = (void *)0; + pm_check_adb_devices(i); /* tell pm driver device + * is here */ + } + } + + /* find highest unused address */ + for (saveptr = 15; saveptr > 0; saveptr--) + if (-1 == get_adb_info(&data, saveptr)) + break; + +#ifdef ADB_DEBUG + if (adb_debug & 0x80) { + printf_intr("first free is: 0x%02x\n", saveptr); + printf_intr("devices: %i\n", ADBNumDevices); + } +#endif + + nonewtimes = 0; /* no loops w/o new devices */ + while (saveptr > 0 && nonewtimes++ < 11) { + for (i = 1;saveptr > 0 && i <= ADBNumDevices; i++) { + device = ADBDevTable[i].currentAddr; +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("moving device 0x%02x to 0x%02x " + "(index 0x%02x) ", device, saveptr, i); +#endif + + /* send TALK R3 to address */ + command = ADBTALK(device, 3); + (void)adb_op_sync((Ptr)send_string, (Ptr)0, + (Ptr)0, (short)command); + + /* move device to higher address */ + command = ADBLISTEN(device, 3); + send_string[0] = 2; + send_string[1] = (u_char)(saveptr | 0x60); + send_string[2] = 0xfe; + (void)adb_op_sync((Ptr)send_string, (Ptr)0, + (Ptr)0, (short)command); + delay(1000); + + /* send TALK R3 - anthing at new address? */ + command = ADBTALK(saveptr, 3); + send_string[0] = 0; + result = adb_op_sync((Ptr)send_string, (Ptr)0, + (Ptr)0, (short)command); + delay(1000); + + if (result != 0 || send_string[0] == 0) { + /* + * maybe there's a communication breakdown; + * just in case, move it back from whence it + * came, and we'll try again later + */ + command = ADBLISTEN(saveptr, 3); + send_string[0] = 2; + send_string[1] = (u_char)(device | 0x60); + send_string[2] = 0x00; + (void)adb_op_sync((Ptr)send_string, (Ptr)0, + (Ptr)0, (short)command); +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("failed, continuing\n"); +#endif + delay(1000); + continue; + } + + /* send TALK R3 - anything at old address? */ + command = ADBTALK(device, 3); + send_string[0] = 0; + result = adb_op_sync((Ptr)send_string, (Ptr)0, + (Ptr)0, (short)command); + if (result == 0 && send_string[0] != 0) { + /* new device found */ + /* update data for previously moved device */ + ADBDevTable[i].currentAddr = saveptr; +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("old device at index %i\n",i); +#endif + /* add new device in table */ +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("new device found\n"); +#endif + if (saveptr > ADBNumDevices) { + ++ADBNumDevices; + KASSERT(ADBNumDevices < 16); + } + ADBDevTable[ADBNumDevices].devType = + (int)(send_string[2]); + ADBDevTable[ADBNumDevices].origAddr = device; + ADBDevTable[ADBNumDevices].currentAddr = device; + /* These will be set correctly in adbsys.c */ + /* Until then, unsol. data will be ignored. */ + ADBDevTable[ADBNumDevices].DataAreaAddr = + (long)0; + ADBDevTable[ADBNumDevices].ServiceRtPtr = + (void *)0; + /* find next unused address */ + for (x = saveptr; x > 0; x--) { + if (-1 == get_adb_info(&data, x)) { + saveptr = x; + break; + } + } + if (x == 0) + saveptr = 0; +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("new free is 0x%02x\n", + saveptr); +#endif + nonewtimes = 0; + /* tell pm driver device is here */ + pm_check_adb_devices(device); + } else { +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("moving back...\n"); +#endif + /* move old device back */ + command = ADBLISTEN(saveptr, 3); + send_string[0] = 2; + send_string[1] = (u_char)(device | 0x60); + send_string[2] = 0xfe; + (void)adb_op_sync((Ptr)send_string, (Ptr)0, + (Ptr)0, (short)command); + delay(1000); + } + } + } + +#ifdef ADB_DEBUG + if (adb_debug) { + for (i = 1; i <= ADBNumDevices; i++) { + x = get_ind_adb_info(&data, i); + if (x != -1) + printf_intr("index 0x%x, addr 0x%x, type 0x%hx\n", + i, x, data.devType); + } + } +#endif + + /* enable the programmer's switch, if we have one */ + adb_prog_switch_enable(); + +#ifdef ADB_DEBUG + if (adb_debug) { + if (0 == ADBNumDevices) /* tell user if no devices found */ + printf_intr("adb: no devices found\n"); + } +#endif + + adbStarting = 0; /* not starting anymore */ +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("adb: adb_reinit complete\n"); +#endif + + if (adbHardware == ADB_HW_CUDA) { + timeout_set(&adb_cuda_timeout, (void *)adb_cuda_tickle, NULL); + timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS); + } + + /* ints must be on for PB & IOP (at least, for now) */ + if (adbHardware != ADB_HW_PB) + splx(s); + + return; +} + + +/* + * adb_cmd_result + * + * This routine lets the caller know whether the specified adb command string + * should expect a returned result, such as a TALK command. + * + * returns: 0 if a result should be expected + * 1 if a result should NOT be expected + */ +int +adb_cmd_result(u_char *in) +{ + switch (adbHardware) { + case ADB_HW_II: + /* was it an ADB talk command? */ + if ((in[1] & 0x0c) == 0x0c) + return 0; + return 1; + + case ADB_HW_IISI: + case ADB_HW_CUDA: + /* was it an ADB talk command? */ + if ((in[1] == 0x00) && ((in[2] & 0x0c) == 0x0c)) + return 0; + /* was it an RTC/PRAM read date/time? */ + if ((in[1] == 0x01) && (in[2] == 0x03)) + return 0; + return 1; + + case ADB_HW_PB: + return 1; + + case ADB_HW_UNKNOWN: + default: + return 1; + } +} + + +/* + * adb_cmd_extra + * + * This routine lets the caller know whether the specified adb command string + * may have extra data appended to the end of it, such as a LISTEN command. + * + * returns: 0 if extra data is allowed + * 1 if extra data is NOT allowed + */ +int +adb_cmd_extra(u_char *in) +{ + switch (adbHardware) { + case ADB_HW_II: + if ((in[1] & 0x0c) == 0x08) /* was it a listen command? */ + return 0; + return 1; + + case ADB_HW_IISI: + case ADB_HW_CUDA: + /* + * TO DO: support needs to be added to recognize RTC and PRAM + * commands + */ + if ((in[2] & 0x0c) == 0x08) /* was it a listen command? */ + return 0; + /* add others later */ + return 1; + + case ADB_HW_PB: + return 1; + + case ADB_HW_UNKNOWN: + default: + return 1; + } +} + + +void +adb_setup_hw_type(void) +{ + long response; + + response = mac68k_machine.machineid; + + /* + * Determine what type of ADB hardware we are running on. + */ + switch (response) { + case MACH_MACC610: /* Centris 610 */ + case MACH_MACC650: /* Centris 650 */ + case MACH_MACII: /* II */ + case MACH_MACIICI: /* IIci */ + case MACH_MACIICX: /* IIcx */ + case MACH_MACIIX: /* IIx */ + case MACH_MACQ610: /* Quadra 610 */ + case MACH_MACQ650: /* Quadra 650 */ + case MACH_MACQ700: /* Quadra 700 */ + case MACH_MACQ800: /* Quadra 800 */ + case MACH_MACSE30: /* SE/30 */ + adbHardware = ADB_HW_II; +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("adb: using II series hardware support\n"); +#endif + break; + + case MACH_MACCLASSICII: /* Classic II */ + case MACH_MACLCII: /* LC II, Performa 400/405/430 */ + case MACH_MACLCIII: /* LC III, Performa 450 */ + case MACH_MACIISI: /* IIsi */ + case MACH_MACIIVI: /* IIvi */ + case MACH_MACIIVX: /* IIvx */ + case MACH_MACP460: /* Performa 460/465/467 */ + case MACH_MACP600: /* Performa 600 */ + adbHardware = ADB_HW_IISI; +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("adb: using IIsi series hardware support\n"); +#endif + break; + + case MACH_MACPB140: /* PowerBook 140 */ + case MACH_MACPB145: /* PowerBook 145 */ + case MACH_MACPB160: /* PowerBook 160 */ + case MACH_MACPB165: /* PowerBook 165 */ + case MACH_MACPB165C: /* PowerBook 165c */ + case MACH_MACPB170: /* PowerBook 170 */ + case MACH_MACPB180: /* PowerBook 180 */ + case MACH_MACPB180C: /* PowerBook 180c */ + adbHardware = ADB_HW_PB; + pm_setup_adb(); +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("adb: using PowerBook 100-series hardware support\n"); +#endif + break; + + case MACH_MACPB150: /* PowerBook 150 */ + case MACH_MACPB210: /* PowerBook Duo 210 */ + case MACH_MACPB230: /* PowerBook Duo 230 */ + case MACH_MACPB250: /* PowerBook Duo 250 */ + case MACH_MACPB270: /* PowerBook Duo 270 */ + case MACH_MACPB280: /* PowerBook Duo 280 */ + case MACH_MACPB280C: /* PowerBook Duo 280c */ + case MACH_MACPB500: /* PowerBook 500 series */ + case MACH_MACPB190: /* PowerBook 190 */ + case MACH_MACPB190CS: /* PowerBook 190cs */ + adbHardware = ADB_HW_PB; + pm_setup_adb(); +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("adb: using PowerBook Duo-series and PowerBook 500-series hardware support\n"); +#endif + break; + + case MACH_MACC660AV: /* Centris 660AV */ + case MACH_MACCCLASSIC: /* Color Classic */ + case MACH_MACCCLASSICII: /* Color Classic II */ + case MACH_MACLC475: /* LC 475, Performa 475/476 */ + case MACH_MACLC475_33: /* Clock-chipped 47x */ + case MACH_MACLC520: /* LC 520 */ + case MACH_MACLC575: /* LC 575, Performa 575/577/578 */ + case MACH_MACP550: /* LC 550, Performa 550 */ + case MACH_MACTV: /* Macintosh TV */ + case MACH_MACP580: /* Performa 580/588 */ + case MACH_MACQ605: /* Quadra 605 */ + case MACH_MACQ605_33: /* Clock-chipped Quadra 605 */ + case MACH_MACQ630: /* LC 630, Performa 630, Quadra 630 */ + case MACH_MACQ840AV: /* Quadra 840AV */ + adbHardware = ADB_HW_CUDA; +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("adb: using Cuda series hardware support\n"); +#endif + break; + + default: + adbHardware = ADB_HW_UNKNOWN; +#ifdef ADB_DEBUG + if (adb_debug) { + printf_intr("adb: hardware type unknown for this machine\n"); + printf_intr("adb: ADB support is disabled\n"); + } +#endif + break; + } + + /* + * Determine whether this machine has ADB based soft power. + */ + switch (response) { + case MACH_MACCCLASSIC: /* Color Classic */ + case MACH_MACCCLASSICII: /* Color Classic II */ + case MACH_MACIISI: /* IIsi */ + case MACH_MACIIVI: /* IIvi */ + case MACH_MACIIVX: /* IIvx */ + case MACH_MACLC520: /* LC 520 */ + case MACH_MACLC575: /* LC 575, Performa 575/577/578 */ + case MACH_MACP550: /* LC 550, Performa 550 */ + case MACH_MACTV: /* Macintosh TV */ + case MACH_MACP580: /* Performa 580/588 */ + case MACH_MACP600: /* Performa 600 */ + case MACH_MACQ630: /* LC 630, Performa 630, Quadra 630 */ + case MACH_MACQ840AV: /* Quadra 840AV */ + adbSoftPower = 1; + break; + } +} + +/* * adb_op_sync * * This routine does exactly what the adb_op routine does, except that after @@ -223,7 +2475,7 @@ adb_op_sync(Ptr buffer, Ptr compRout, Ptr data, short command) int result; volatile int flag = 0; - result = ADBOp(buffer, (void *)adb_op_comprout, (Ptr)&flag, + result = adb_op(buffer, (void *)adb_op_comprout, (Ptr)&flag, command); /* send command */ if (result == 0) { /* send ok? */ /* @@ -254,7 +2506,6 @@ adb_op_sync(Ptr buffer, Ptr compRout, Ptr data, short command) return result; } - /* * adb_op_comprout * @@ -266,3 +2517,380 @@ adb_op_comprout(caddr_t buffer, caddr_t data_area, int adb_command) { *(u_short *)data_area = 0x01; /* update flag value */ } + +int +count_adbs(void) +{ + int i; + int found; + + found = 0; + + for (i = 1; i < 16; i++) + if (0 != ADBDevTable[i].currentAddr) + found++; + + return found; +} + +int +get_ind_adb_info(ADBDataBlock *info, int index) +{ + if ((index < 1) || (index > 15)) /* check range 1-15 */ + return (-1); + +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("index 0x%x devType is: 0x%x\n", index, + ADBDevTable[index].devType); +#endif + if (0 == ADBDevTable[index].devType) /* make sure it's a valid entry */ + return (-1); + + info->devType = (unsigned char)(ADBDevTable[index].devType); + info->origADBAddr = (unsigned char)(ADBDevTable[index].origAddr); + info->dbServiceRtPtr = (Ptr)ADBDevTable[index].ServiceRtPtr; + info->dbDataAreaAddr = (Ptr)ADBDevTable[index].DataAreaAddr; + + return (ADBDevTable[index].currentAddr); +} + +int +get_adb_info(ADBDataBlock *info, int adbAddr) +{ + int i; + + if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */ + return (-1); + + for (i = 1; i < 15; i++) + if (ADBDevTable[i].currentAddr == adbAddr) { + info->devType = (unsigned char)(ADBDevTable[i].devType); + info->origADBAddr = (unsigned char)(ADBDevTable[i].origAddr); + info->dbServiceRtPtr = (Ptr)ADBDevTable[i].ServiceRtPtr; + info->dbDataAreaAddr = ADBDevTable[i].DataAreaAddr; + return 0; /* found */ + } + + return (-1); /* not found */ +} + +int +set_adb_info(ADBSetInfoBlock *info, int adbAddr) +{ + int i; + + if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */ + return (-1); + + for (i = 1; i < 15; i++) + if (ADBDevTable[i].currentAddr == adbAddr) { + ADBDevTable[i].ServiceRtPtr = + (void *)(info->siServiceRtPtr); + ADBDevTable[i].DataAreaAddr = info->siDataAreaAddr; + return 0; /* found */ + } + + return (-1); /* not found */ + +} + +/* caller should really use machine-independant version: getPramTime */ +/* this version does pseudo-adb access only */ +int +adb_read_date_time(unsigned long *time) +{ + u_char output[ADB_MAX_MSG_LENGTH]; + int result; + volatile int flag = 0; + + switch (adbHardware) { + case ADB_HW_II: + return -1; + + case ADB_HW_IISI: + output[0] = 0x02; /* 2 byte message */ + output[1] = 0x01; /* to pram/rtc device */ + output[2] = 0x03; /* read date/time */ + result = send_adb_IIsi((u_char *)output, (u_char *)output, + (void *)adb_op_comprout, (void *)&flag, (int)0); + if (result != 0) /* exit if not sent */ + return -1; + + while (0 == flag) /* wait for result */ + ; + + *time = (long)(*(long *)(output + 1)); + return 0; + + case ADB_HW_PB: + return -1; + + case ADB_HW_CUDA: + output[0] = 0x02; /* 2 byte message */ + output[1] = 0x01; /* to pram/rtc device */ + output[2] = 0x03; /* read date/time */ + result = send_adb_cuda((u_char *)output, (u_char *)output, + (void *)adb_op_comprout, (void *)&flag, (int)0); + if (result != 0) /* exit if not sent */ + return -1; + + while (0 == flag) /* wait for result */ + ; + + *time = (long)(*(long *)(output + 1)); + return 0; + + case ADB_HW_UNKNOWN: + default: + return -1; + } +} + +/* caller should really use machine-independant version: setPramTime */ +/* this version does pseudo-adb access only */ +int +adb_set_date_time(unsigned long time) +{ + u_char output[ADB_MAX_MSG_LENGTH]; + int result; + volatile int flag = 0; + + switch (adbHardware) { + case ADB_HW_II: + return -1; + + case ADB_HW_IISI: + output[0] = 0x06; /* 6 byte message */ + output[1] = 0x01; /* to pram/rtc device */ + output[2] = 0x09; /* set date/time */ + output[3] = (u_char)(time >> 24); + output[4] = (u_char)(time >> 16); + output[5] = (u_char)(time >> 8); + output[6] = (u_char)(time); + result = send_adb_IIsi((u_char *)output, (u_char *)0, + (void *)adb_op_comprout, (void *)&flag, (int)0); + if (result != 0) /* exit if not sent */ + return -1; + + while (0 == flag) /* wait for send to finish */ + ; + + return 0; + + case ADB_HW_PB: + return -1; + + case ADB_HW_CUDA: + output[0] = 0x06; /* 6 byte message */ + output[1] = 0x01; /* to pram/rtc device */ + output[2] = 0x09; /* set date/time */ + output[3] = (u_char)(time >> 24); + output[4] = (u_char)(time >> 16); + output[5] = (u_char)(time >> 8); + output[6] = (u_char)(time); + result = send_adb_cuda((u_char *)output, (u_char *)0, + (void *)adb_op_comprout, (void *)&flag, (int)0); + if (result != 0) /* exit if not sent */ + return -1; + + while (0 == flag) /* wait for send to finish */ + ; + + return 0; + + case ADB_HW_UNKNOWN: + default: + return -1; + } +} + + +int +adb_poweroff(void) +{ + u_char output[ADB_MAX_MSG_LENGTH]; + int result; + + if (!adbSoftPower) + return -1; + + adb_polling = 1; + + switch (adbHardware) { + case ADB_HW_IISI: + output[0] = 0x02; /* 2 byte message */ + output[1] = 0x01; /* to pram/rtc/soft-power device */ + output[2] = 0x0a; /* set date/time */ + result = send_adb_IIsi((u_char *)output, (u_char *)0, + (void *)0, (void *)0, (int)0); + if (result != 0) /* exit if not sent */ + return -1; + + for (;;); /* wait for power off */ + + return 0; + + case ADB_HW_PB: + return -1; + + case ADB_HW_CUDA: + output[0] = 0x02; /* 2 byte message */ + output[1] = 0x01; /* to pram/rtc/soft-power device */ + output[2] = 0x0a; /* set date/time */ + result = send_adb_cuda((u_char *)output, (u_char *)0, + (void *)0, (void *)0, (int)0); + if (result != 0) /* exit if not sent */ + return -1; + + for (;;); /* wait for power off */ + + return 0; + + case ADB_HW_II: /* II models don't do ADB soft power */ + case ADB_HW_UNKNOWN: + default: + return -1; + } +} + +int +adb_prog_switch_enable(void) +{ + u_char output[ADB_MAX_MSG_LENGTH]; + int result; + volatile int flag = 0; + + switch (adbHardware) { + case ADB_HW_IISI: + output[0] = 0x03; /* 3 byte message */ + output[1] = 0x01; /* to pram/rtc/soft-power device */ + output[2] = 0x1c; /* prog. switch control */ + output[3] = 0x01; /* enable */ + result = send_adb_IIsi((u_char *)output, (u_char *)0, + (void *)adb_op_comprout, (void *)&flag, (int)0); + if (result != 0) /* exit if not sent */ + return -1; + + while (0 == flag) /* wait for send to finish */ + ; + + return 0; + + case ADB_HW_PB: + return -1; + + case ADB_HW_II: /* II models don't do prog. switch */ + case ADB_HW_CUDA: /* cuda doesn't do prog. switch TO DO: verify this */ + case ADB_HW_UNKNOWN: + default: + return -1; + } +} + +int +adb_prog_switch_disable(void) +{ + u_char output[ADB_MAX_MSG_LENGTH]; + int result; + volatile int flag = 0; + + switch (adbHardware) { + case ADB_HW_IISI: + output[0] = 0x03; /* 3 byte message */ + output[1] = 0x01; /* to pram/rtc/soft-power device */ + output[2] = 0x1c; /* prog. switch control */ + output[3] = 0x01; /* disable */ + result = send_adb_IIsi((u_char *)output, (u_char *)0, + (void *)adb_op_comprout, (void *)&flag, (int)0); + if (result != 0) /* exit if not sent */ + return -1; + + while (0 == flag) /* wait for send to finish */ + ; + + return 0; + + case ADB_HW_PB: + return -1; + + case ADB_HW_II: /* II models don't do prog. switch */ + case ADB_HW_CUDA: /* cuda doesn't do prog. switch */ + case ADB_HW_UNKNOWN: + default: + return -1; + } +} + +/* + * Function declarations. + */ +int adbmatch(struct device *, void *, void *); +void adbattach(struct device *, struct device *, void *); +void adb_attach_deferred(void *); + +/* + * Driver definition. + */ +struct cfattach adb_ca = { + sizeof(struct device), adbmatch, adbattach +}; + +int +adbmatch(struct device *parent, void *vcf, void *aux) +{ + static int adb_matched = 0; + + /* Allow only one instance. */ + if (adb_matched) + return (0); + + adb_matched = 1; + return (1); +} + +void +adbattach(struct device *parent, struct device *self, void *aux) +{ + printf("\n"); + startuphook_establish(adb_attach_deferred, self); +} + +void +adb_attach_deferred(void *v) +{ + struct device *self = v; + ADBDataBlock adbdata; + struct adb_attach_args aa_args; + int totaladbs; + int adbindex, adbaddr; + + printf("%s", self->dv_xname); + + adb_polling = 1; + adb_reinit(); + + printf(": %s", adbHardwareDescr[adbHardware]); + +#ifdef ADB_DEBUG + if (adb_debug) + printf("adb: done with adb_reinit\n"); +#endif + + totaladbs = count_adbs(); + + printf(", %d target%s\n", totaladbs, (totaladbs == 1) ? "" : "s"); + + /* for each ADB device */ + for (adbindex = 1; adbindex <= totaladbs; adbindex++) { + /* Get the ADB information */ + adbaddr = get_ind_adb_info(&adbdata, adbindex); + + aa_args.origaddr = (int)(adbdata.origADBAddr); + aa_args.adbaddr = adbaddr; + aa_args.handler_id = (int)(adbdata.devType); + + (void)config_found(self, &aa_args, adbprint); + } + adb_polling = 0; +} diff --git a/sys/arch/mac68k/dev/adb_direct.c b/sys/arch/mac68k/dev/adb_direct.c deleted file mode 100644 index a4a74300deb..00000000000 --- a/sys/arch/mac68k/dev/adb_direct.c +++ /dev/null @@ -1,2759 +0,0 @@ -/* $OpenBSD: adb_direct.c,v 1.19 2006/01/16 21:48:20 miod Exp $ */ -/* $NetBSD: adb_direct.c,v 1.51 2005/06/16 22:43:36 jmc Exp $ */ - -/* From: adb_direct.c 2.02 4/18/97 jpw */ - -/* - * Copyright (C) 1996, 1997 John P. Wittkoski - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by John P. Wittkoski. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This code is rather messy, but I don't have time right now - * to clean it up as much as I would like. - * But it works, so I'm happy. :-) jpw - */ - -/* - * TO DO: - * - We could reduce the time spent in the adb_intr_* routines - * by having them save the incoming and outgoing data directly - * in the adbInbound and adbOutbound queues, as it would reduce - * the number of times we need to copy the data around. It - * would also make the code more readable and easier to follow. - * - (Related to above) Use the header part of adbCommand to - * reduce the number of copies we have to do of the data. - * - (Related to above) Actually implement the adbOutbound queue. - * This is fairly easy once you switch all the intr routines - * over to using adbCommand structs directly. - * - There is a bug in the state machine of adb_intr_cuda - * code that causes hangs, especially on 030 machines, probably - * because of some timing issues. Because I have been unable to - * determine the exact cause of this bug, I used the timeout function - * to check for and recover from this condition. If anyone finds - * the actual cause of this bug, the calls to timeout and the - * adb_cuda_tickle routine can be removed. - */ - -#include <sys/param.h> -#include <sys/cdefs.h> -#include <sys/pool.h> -#include <sys/queue.h> -#include <sys/systm.h> -#include <sys/timeout.h> - -#include <machine/viareg.h> -#include <machine/param.h> -#include <machine/cpu.h> -#include <mac68k/dev/adbvar.h> -#define printf_intr printf - -/* some misc. leftovers */ -#define vPB 0x0000 -#define vPB3 0x08 -#define vPB4 0x10 -#define vPB5 0x20 -#define vSR_INT 0x04 -#define vSR_OUT 0x10 - -/* the type of ADB action that we are currently preforming */ -#define ADB_ACTION_NOTREADY 0x1 /* has not been initialized yet */ -#define ADB_ACTION_IDLE 0x2 /* the bus is currently idle */ -#define ADB_ACTION_OUT 0x3 /* sending out a command */ -#define ADB_ACTION_IN 0x4 /* receiving data */ -#define ADB_ACTION_POLLING 0x5 /* polling - II only */ - -/* - * These describe the state of the ADB bus itself, although they - * don't necessarily correspond directly to ADB states. - * Note: these are not really used in the IIsi code. - */ -#define ADB_BUS_UNKNOWN 0x1 /* we don't know yet - all models */ -#define ADB_BUS_IDLE 0x2 /* bus is idle - all models */ -#define ADB_BUS_CMD 0x3 /* starting a command - II models */ -#define ADB_BUS_ODD 0x4 /* the "odd" state - II models */ -#define ADB_BUS_EVEN 0x5 /* the "even" state - II models */ -#define ADB_BUS_ACTIVE 0x6 /* active state - IIsi models */ -#define ADB_BUS_ACK 0x7 /* currently ACKing - IIsi models */ - -/* - * Shortcuts for setting or testing the VIA bit states. - * Not all shortcuts are used for every type of ADB hardware. - */ -#define ADB_SET_STATE_IDLE_II() via_reg(VIA1, vBufB) |= (vPB4 | vPB5) -#define ADB_SET_STATE_IDLE_IISI() via_reg(VIA1, vBufB) &= ~(vPB4 | vPB5) -#define ADB_SET_STATE_IDLE_CUDA() via_reg(VIA1, vBufB) |= (vPB4 | vPB5) -#define ADB_SET_STATE_CMD() via_reg(VIA1, vBufB) &= ~(vPB4 | vPB5) -#define ADB_SET_STATE_EVEN() via_reg(VIA1, vBufB) = ((via_reg(VIA1, \ - vBufB) | vPB4) & ~vPB5) -#define ADB_SET_STATE_ODD() via_reg(VIA1, vBufB) = ((via_reg(VIA1, \ - vBufB) | vPB5) & ~vPB4) -#define ADB_SET_STATE_ACTIVE() via_reg(VIA1, vBufB) |= vPB5 -#define ADB_SET_STATE_INACTIVE() via_reg(VIA1, vBufB) &= ~vPB5 -#define ADB_SET_STATE_TIP() via_reg(VIA1, vBufB) &= ~vPB5 -#define ADB_CLR_STATE_TIP() via_reg(VIA1, vBufB) |= vPB5 -#define ADB_SET_STATE_ACKON() via_reg(VIA1, vBufB) |= vPB4 -#define ADB_SET_STATE_ACKOFF() via_reg(VIA1, vBufB) &= ~vPB4 -#define ADB_TOGGLE_STATE_ACK_CUDA() via_reg(VIA1, vBufB) ^= vPB4 -#define ADB_SET_STATE_ACKON_CUDA() via_reg(VIA1, vBufB) &= ~vPB4 -#define ADB_SET_STATE_ACKOFF_CUDA() via_reg(VIA1, vBufB) |= vPB4 -#define ADB_SET_SR_INPUT() via_reg(VIA1, vACR) &= ~vSR_OUT -#define ADB_SET_SR_OUTPUT() via_reg(VIA1, vACR) |= vSR_OUT -#define ADB_SR() via_reg(VIA1, vSR) -#define ADB_VIA_INTR_ENABLE() via_reg(VIA1, vIER) = 0x84 -#define ADB_VIA_INTR_DISABLE() via_reg(VIA1, vIER) = 0x04 -#define ADB_VIA_CLR_INTR() via_reg(VIA1, vIFR) = 0x04 -#define ADB_INTR_IS_OFF (vPB3 == (via_reg(VIA1, vBufB) & vPB3)) -#define ADB_INTR_IS_ON (0 == (via_reg(VIA1, vBufB) & vPB3)) -#define ADB_SR_INTR_IS_OFF (0 == (via_reg(VIA1, vIFR) & vSR_INT)) -#define ADB_SR_INTR_IS_ON (vSR_INT == (via_reg(VIA1, \ - vIFR) & vSR_INT)) - -/* - * This is the delay that is required (in uS) between certain - * ADB transactions. The actual timing delay for for each uS is - * calculated at boot time to account for differences in machine speed. - */ -#define ADB_DELAY 150 - -/* - * Maximum ADB message length; includes space for data, result, and - * device code - plus a little for safety. - */ -#define ADB_MAX_MSG_LENGTH 16 -#define ADB_MAX_HDR_LENGTH 8 - -#define ADB_QUEUE 32 -#define ADB_TICKLE_TICKS 4 - -/* - * A structure for storing information about each ADB device. - */ -struct ADBDevEntry { - void (*ServiceRtPtr)(void); - void *DataAreaAddr; - int devType; - int origAddr; - int currentAddr; -}; - -/* - * Used to hold ADB commands that are waiting to be sent out. - */ -struct adbCmdHoldEntry { - u_char outBuf[ADB_MAX_MSG_LENGTH]; /* our message */ - u_char *saveBuf; /* buffer to know where to save result */ - u_char *compRout; /* completion routine pointer */ - u_char *data; /* completion routine data pointer */ -}; - -/* - * Eventually used for two separate queues, the queue between - * the upper and lower halves, and the outgoing packet queue. - * TO DO: adbCommand can replace all of adbCmdHoldEntry eventually - */ -struct adbCommand { - u_char header[ADB_MAX_HDR_LENGTH]; /* not used yet */ - u_char data[ADB_MAX_MSG_LENGTH]; /* packet data only */ - u_char *saveBuf; /* where to save result */ - u_char *compRout; /* completion routine pointer */ - u_char *compData; /* completion routine data pointer */ - u_int cmd; /* the original command for this data */ - u_int unsol; /* 1 if packet was unsolicited */ - u_int ack_only; /* 1 for no special processing */ -}; - -/* - * Text representations of each hardware class - */ -const char *adbHardwareDescr[MAX_ADB_HW + 1] = { - "unknown", - "II series", - "IIsi series", - "PowerBook", - "Cuda", -}; - -/* - * A few variables that we need and their initial values. - */ -int adbHardware = ADB_HW_UNKNOWN; -int adbActionState = ADB_ACTION_NOTREADY; -int adbBusState = ADB_BUS_UNKNOWN; -int adbWaiting = 0; /* waiting for return data from the device */ -int adbWriteDelay = 0; /* working on (or waiting to do) a write */ -int adbOutQueueHasData = 0; /* something in the queue waiting to go out */ -int adbNextEnd = 0; /* the next incoming bute is the last (II) */ -int adbSoftPower = 0; /* machine supports soft power */ - -int adbWaitingCmd = 0; /* ADB command we are waiting for */ -u_char *adbBuffer = (long)0; /* pointer to user data area */ -void *adbCompRout = (long)0; /* pointer to the completion routine */ -void *adbCompData = (long)0; /* pointer to the completion routine data */ -long adbFakeInts = 0; /* keeps track of fake ADB interrupts for - * timeouts (II) */ -int adbStarting = 1; /* doing ADBReInit so do polling differently */ -int adbSendTalk = 0; /* the intr routine is sending the talk, not - * the user (II) */ -int adbPolling = 0; /* we are polling for service request */ -int adbPollCmd = 0; /* the last poll command we sent */ - -u_char adbInputBuffer[ADB_MAX_MSG_LENGTH]; /* data input buffer */ -u_char adbOutputBuffer[ADB_MAX_MSG_LENGTH]; /* data output buffer */ -struct adbCmdHoldEntry adbOutQueue; /* our 1 entry output queue */ - -int adbSentChars = 0; /* how many characters we have sent */ -int adbLastDevice = 0; /* last ADB dev we heard from (II ONLY) */ -int adbLastDevIndex = 0; /* last ADB dev loc in dev table (II ONLY) */ -int adbLastCommand = 0; /* the last ADB command we sent (II) */ - -struct ADBDevEntry ADBDevTable[16]; /* our ADB device table */ -int ADBNumDevices; /* num. of ADB devices found with ADBReInit */ - -struct adbCommand adbInbound[ADB_QUEUE]; /* incoming queue */ -volatile int adbInCount = 0; /* how many packets in in queue */ -int adbInHead = 0; /* head of in queue */ -int adbInTail = 0; /* tail of in queue */ -struct adbCommand adbOutbound[ADB_QUEUE]; /* outgoing queue - not used yet */ -int adbOutCount = 0; /* how many packets in out queue */ -int adbOutHead = 0; /* head of out queue */ -int adbOutTail = 0; /* tail of out queue */ - -int tickle_count = 0; /* how many tickles seen for this packet? */ -int tickle_serial = 0; /* the last packet tickled */ -int adb_cuda_serial = 0; /* the current packet */ - -struct timeout adb_cuda_timeout; - -extern struct mac68k_machine_S mac68k_machine; - -void pm_setup_adb(void); -void pm_hw_setup(void); -void pm_check_adb_devices(int); -int pm_adb_op(u_char *, void *, void *, int); -void pm_init_adb_device(void); - -/* - * The following are private routines. - */ -#ifdef ADB_DEBUG -void print_single(u_char *); -#endif -int adb_intr(void *); -int adb_intr_II(void *); -int adb_intr_IIsi(void *); -int adb_intr_cuda(void *); -void adb_soft_intr(void); -int send_adb_II(u_char *, u_char *, void *, void *, int); -int send_adb_IIsi(u_char *, u_char *, void *, void *, int); -int send_adb_cuda(u_char *, u_char *, void *, void *, int); -void adb_intr_cuda_test(void); -void adb_cuda_tickle(void); -void adb_pass_up(struct adbCommand *); -void adb_reinit(void); -int count_adbs(void); -int get_ind_adb_info(ADBDataBlock *, int); -int get_adb_info(ADBDataBlock *, int); -int set_adb_info(ADBSetInfoBlock *, int); -void adb_setup_hw_type(void); -int adb_op(Ptr, Ptr, Ptr, short); -void adb_read_II(u_char *); -void adb_hw_setup(void); -void adb_hw_setup_IIsi(u_char *); -int adb_cmd_result(u_char *); -int adb_cmd_extra(u_char *); -int adb_guess_next_device(void); -int adb_prog_switch_enable(void); -int adb_prog_switch_disable(void); -/* we should create this and it will be the public version */ -int send_adb(u_char *, void *, void *); - -#ifdef ADB_DEBUG -/* - * print_single - * Diagnostic display routine. Displays the hex values of the - * specified elements of the u_char. The length of the "string" - * is in [0]. - */ -void -print_single(u_char *str) -{ - int x; - - if (str == 0) { - printf_intr("no data - null pointer\n"); - return; - } - if (*str == 0) { - printf_intr("nothing returned\n"); - return; - } - if (*str > 20) { - printf_intr("ADB: ACK > 20 no way!\n"); - *str = (u_char)20; - } - printf_intr("(length=0x%x):", (u_int)*str); - for (x = 1; x <= *str; x++) - printf_intr(" 0x%02x", (u_int)*(str + x)); - printf_intr("\n"); -} -#endif - -void -adb_cuda_tickle(void) -{ - volatile int s; - - if (adbActionState == ADB_ACTION_IN) { - if (tickle_serial == adb_cuda_serial) { - if (++tickle_count > 0) { - s = splhigh(); - adbActionState = ADB_ACTION_IDLE; - adbInputBuffer[0] = 0; - ADB_SET_STATE_IDLE_CUDA(); - splx(s); - } - } else { - tickle_serial = adb_cuda_serial; - tickle_count = 0; - } - } else { - tickle_serial = adb_cuda_serial; - tickle_count = 0; - } - - timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS); -} - -/* - * called when when an adb interrupt happens - * - * Cuda version of adb_intr - * TO DO: do we want to add some calls to intr_dispatch() here to - * grab serial interrupts? - */ -int -adb_intr_cuda(void *arg) -{ - volatile int i, ending; - volatile unsigned int s; - struct adbCommand packet; - - s = splhigh(); /* can't be too careful - might be called */ - /* from a routine, NOT an interrupt */ - - ADB_VIA_CLR_INTR(); /* clear interrupt */ - ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */ - -switch_start: - switch (adbActionState) { - case ADB_ACTION_IDLE: - /* - * This is an unexpected packet, so grab the first (dummy) - * byte, set up the proper vars, and tell the chip we are - * starting to receive the packet by setting the TIP bit. - */ - adbInputBuffer[1] = ADB_SR(); - adb_cuda_serial++; - if (ADB_INTR_IS_OFF) /* must have been a fake start */ - break; - - ADB_SET_SR_INPUT(); - ADB_SET_STATE_TIP(); - - adbInputBuffer[0] = 1; - adbActionState = ADB_ACTION_IN; -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("idle 0x%02x ", adbInputBuffer[1]); -#endif - break; - - case ADB_ACTION_IN: - adbInputBuffer[++adbInputBuffer[0]] = ADB_SR(); - /* intr off means this is the last byte (end of frame) */ - if (ADB_INTR_IS_OFF) - ending = 1; - else - ending = 0; - - if (1 == ending) { /* end of message? */ -#ifdef ADB_DEBUG - if (adb_debug) { - printf_intr("in end 0x%02x ", - adbInputBuffer[adbInputBuffer[0]]); - print_single(adbInputBuffer); - } -#endif - - /* - * Are we waiting AND does this packet match what we - * are waiting for AND is it coming from either the - * ADB or RTC/PRAM sub-device? This section _should_ - * recognize all ADB and RTC/PRAM type commands, but - * there may be more... NOTE: commands are always at - * [4], even for RTC/PRAM commands. - */ - /* set up data for adb_pass_up */ - memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1); - - if ((adbWaiting == 1) && - (adbInputBuffer[4] == adbWaitingCmd) && - ((adbInputBuffer[2] == 0x00) || - (adbInputBuffer[2] == 0x01))) { - packet.saveBuf = adbBuffer; - packet.compRout = adbCompRout; - packet.compData = adbCompData; - packet.unsol = 0; - packet.ack_only = 0; - adb_pass_up(&packet); - - adbWaitingCmd = 0; /* reset "waiting" vars */ - adbWaiting = 0; - adbBuffer = (long)0; - adbCompRout = (long)0; - adbCompData = (long)0; - } else { - packet.unsol = 1; - packet.ack_only = 0; - adb_pass_up(&packet); - } - - - /* reset vars and signal the end of this frame */ - adbActionState = ADB_ACTION_IDLE; - adbInputBuffer[0] = 0; - ADB_SET_STATE_IDLE_CUDA(); - /*ADB_SET_SR_INPUT();*/ - - /* - * If there is something waiting to be sent out, - * the set everything up and send the first byte. - */ - if (adbWriteDelay == 1) { - delay(ADB_DELAY); /* required */ - adbSentChars = 0; - adbActionState = ADB_ACTION_OUT; - /* - * If the interrupt is on, we were too slow - * and the chip has already started to send - * something to us, so back out of the write - * and start a read cycle. - */ - if (ADB_INTR_IS_ON) { - ADB_SET_SR_INPUT(); - ADB_SET_STATE_IDLE_CUDA(); - adbSentChars = 0; - adbActionState = ADB_ACTION_IDLE; - adbInputBuffer[0] = 0; - break; - } - /* - * If we got here, it's ok to start sending - * so load the first byte and tell the chip - * we want to send. - */ - ADB_SET_STATE_TIP(); - ADB_SET_SR_OUTPUT(); - ADB_SR() = adbOutputBuffer[adbSentChars + 1]; - } - } else { - ADB_TOGGLE_STATE_ACK_CUDA(); -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("in 0x%02x ", - adbInputBuffer[adbInputBuffer[0]]); -#endif - } - break; - - case ADB_ACTION_OUT: - i = ADB_SR(); /* reset SR-intr in IFR */ -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("intr out 0x%02x ", i); -#endif - - adbSentChars++; - if (ADB_INTR_IS_ON) { /* ADB intr low during write */ -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("intr was on "); -#endif - ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ - ADB_SET_STATE_IDLE_CUDA(); - adbSentChars = 0; /* must start all over */ - adbActionState = ADB_ACTION_IDLE; /* new state */ - adbInputBuffer[0] = 0; - adbWriteDelay = 1; /* must retry when done with - * read */ - delay(ADB_DELAY); - goto switch_start; /* process next state right - * now */ - break; - } - if (adbOutputBuffer[0] == adbSentChars) { /* check for done */ - if (0 == adb_cmd_result(adbOutputBuffer)) { /* do we expect data - * back? */ - adbWaiting = 1; /* signal waiting for return */ - adbWaitingCmd = adbOutputBuffer[2]; /* save waiting command */ - } else { /* no talk, so done */ - /* set up stuff for adb_pass_up */ - memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1); - packet.saveBuf = adbBuffer; - packet.compRout = adbCompRout; - packet.compData = adbCompData; - packet.cmd = adbWaitingCmd; - packet.unsol = 0; - packet.ack_only = 1; - adb_pass_up(&packet); - - /* reset "waiting" vars, just in case */ - adbWaitingCmd = 0; - adbBuffer = (long)0; - adbCompRout = (long)0; - adbCompData = (long)0; - } - - adbWriteDelay = 0; /* done writing */ - adbActionState = ADB_ACTION_IDLE; /* signal bus is idle */ - ADB_SET_SR_INPUT(); - ADB_SET_STATE_IDLE_CUDA(); -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("write done "); -#endif - } else { - ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* send next byte */ - ADB_TOGGLE_STATE_ACK_CUDA(); /* signal byte ready to - * shift */ -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("toggle "); -#endif - } - break; - - case ADB_ACTION_NOTREADY: -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("adb: not yet initialized\n"); -#endif - break; - - default: -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("intr: unknown ADB state\n"); -#endif - break; - } - - ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */ - - splx(s); /* restore */ - - return (1); -} /* end adb_intr_cuda */ - - -int -send_adb_cuda(u_char *in, u_char *buffer, void *compRout, void *data, int - command) -{ - int s, len; - -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("SEND\n"); -#endif - - if (adbActionState == ADB_ACTION_NOTREADY) - return 1; - - /* Don't interrupt while we are messing with the ADB */ - s = splhigh(); - - if ((adbActionState == ADB_ACTION_IDLE) && /* ADB available? */ - (ADB_INTR_IS_OFF)) { /* and no incoming interrupt? */ - } else - if (adbWriteDelay == 0) /* it's busy, but is anything waiting? */ - adbWriteDelay = 1; /* if no, then we'll "queue" - * it up */ - else { - splx(s); - return 1; /* really busy! */ - } - -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("QUEUE\n"); -#endif - if ((long)in == (long)0) { /* need to convert? */ - /* - * Don't need to use adb_cmd_extra here because this section - * will be called ONLY when it is an ADB command (no RTC or - * PRAM) - */ - if ((command & 0x0c) == 0x08) /* copy addl data ONLY if - * doing a listen! */ - len = buffer[0]; /* length of additional data */ - else - len = 0;/* no additional data */ - - adbOutputBuffer[0] = 2 + len; /* dev. type + command + addl. - * data */ - adbOutputBuffer[1] = 0x00; /* mark as an ADB command */ - adbOutputBuffer[2] = (u_char)command; /* load command */ - - /* copy additional output data, if any */ - memcpy(adbOutputBuffer + 3, buffer + 1, len); - } else - /* if data ready, just copy over */ - memcpy(adbOutputBuffer, in, in[0] + 2); - - adbSentChars = 0; /* nothing sent yet */ - adbBuffer = buffer; /* save buffer to know where to save result */ - adbCompRout = compRout; /* save completion routine pointer */ - adbCompData = data; /* save completion routine data pointer */ - adbWaitingCmd = adbOutputBuffer[2]; /* save wait command */ - - if (adbWriteDelay != 1) { /* start command now? */ -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("out start NOW"); -#endif - delay(ADB_DELAY); - adbActionState = ADB_ACTION_OUT; /* set next state */ - ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ - ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* load byte for output */ - ADB_SET_STATE_ACKOFF_CUDA(); - ADB_SET_STATE_TIP(); /* tell ADB that we want to send */ - } - adbWriteDelay = 1; /* something in the write "queue" */ - - splx(s); - - if (0x0100 <= (s & 0x0700)) /* were VIA1 interrupts blocked? */ - /* poll until byte done */ - while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON) - || (adbWaiting == 1)) - if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */ - adb_intr_cuda(NULL); /* go process it */ - if (adb_polling) - adb_soft_intr(); - } - - return 0; -} /* send_adb_cuda */ - - -int -adb_intr_II(void *arg) -{ - struct adbCommand packet; - int i, intr_on = 0; - int send = 0; - unsigned int s; - - s = splhigh(); /* can't be too careful - might be called */ - /* from a routine, NOT an interrupt */ - - ADB_VIA_CLR_INTR(); /* clear interrupt */ - - ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */ - - delay(ADB_DELAY); /* yuck (don't remove) */ - - (void)intr_dispatch(0x70); /* grab any serial interrupts */ - - if (ADB_INTR_IS_ON) - intr_on = 1; /* save for later */ - -switch_start: - switch (adbActionState) { - case ADB_ACTION_POLLING: - if (!intr_on) { - if (adbOutQueueHasData) { -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("POLL-doing-out-queue. "); -#endif - ADB_SET_STATE_IDLE_II(); - delay(ADB_DELAY); - - /* copy over data */ - memcpy(adbOutputBuffer, adbOutQueue.outBuf, - adbOutQueue.outBuf[0] + 2); - - adbBuffer = adbOutQueue.saveBuf; /* user data area */ - adbCompRout = adbOutQueue.compRout; /* completion routine */ - adbCompData = adbOutQueue.data; /* comp. rout. data */ - adbOutQueueHasData = 0; /* currently processing - * "queue" entry */ - adbSentChars = 0; /* nothing sent yet */ - adbActionState = ADB_ACTION_OUT; /* set next state */ - ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ - ADB_SR() = adbOutputBuffer[1]; /* load byte for output */ - adbBusState = ADB_BUS_CMD; /* set bus to cmd state */ - ADB_SET_STATE_CMD(); /* tell ADB that we want to send */ - break; - } else { -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("pIDLE "); -#endif - adbActionState = ADB_ACTION_IDLE; - } - } else { -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("pIN "); -#endif - adbActionState = ADB_ACTION_IN; - } - delay(ADB_DELAY); - (void)intr_dispatch(0x70); /* grab any serial interrupts */ - goto switch_start; - break; - case ADB_ACTION_IDLE: - if (!intr_on) { - i = ADB_SR(); - adbBusState = ADB_BUS_IDLE; - adbActionState = ADB_ACTION_IDLE; - ADB_SET_STATE_IDLE_II(); - break; - } - adbInputBuffer[0] = 1; - adbInputBuffer[1] = ADB_SR(); /* get first byte */ -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("idle 0x%02x ", adbInputBuffer[1]); -#endif - ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ - adbActionState = ADB_ACTION_IN; /* set next state */ - ADB_SET_STATE_EVEN(); /* set bus state to even */ - adbBusState = ADB_BUS_EVEN; - break; - - case ADB_ACTION_IN: - adbInputBuffer[++adbInputBuffer[0]] = ADB_SR(); /* get byte */ -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("in 0x%02x ", - adbInputBuffer[adbInputBuffer[0]]); -#endif - ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ - - if (intr_on) { /* process last byte of packet */ - adbInputBuffer[0]--; /* minus one */ - /* - * If intr_on was true, and it's the second byte, then - * the byte we just discarded is really valid, so - * adjust the count - */ - if (adbInputBuffer[0] == 2) { - adbInputBuffer[0]++; - } - -#ifdef ADB_DEBUG - if (adb_debug & 0x80) { - printf_intr("done: "); - print_single(adbInputBuffer); - } -#endif - - adbLastDevice = ADB_CMDADDR(adbInputBuffer[1]); - - if (adbInputBuffer[0] == 1 && !adbWaiting) { /* SRQ!!!*/ -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr(" xSRQ! "); -#endif - adb_guess_next_device(); -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("try 0x%0x ", - adbLastDevice); -#endif - adbOutputBuffer[0] = 1; - adbOutputBuffer[1] = ADBTALK(adbLastDevice, 0); - - adbSentChars = 0; /* nothing sent yet */ - adbActionState = ADB_ACTION_POLLING; /* set next state */ - ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ - ADB_SR() = adbOutputBuffer[1]; /* load byte for output */ - adbBusState = ADB_BUS_CMD; /* set bus to cmd state */ - ADB_SET_STATE_CMD(); /* tell ADB that we want to */ - break; - } - - /* set up data for adb_pass_up */ - memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1); - - if (!adbWaiting && (adbInputBuffer[0] != 0)) { - packet.unsol = 1; - packet.ack_only = 0; - adb_pass_up(&packet); - } else { - packet.saveBuf = adbBuffer; - packet.compRout = adbCompRout; - packet.compData = adbCompData; - packet.unsol = 0; - packet.ack_only = 0; - adb_pass_up(&packet); - } - - adbWaiting = 0; - adbInputBuffer[0] = 0; - adbBuffer = (long)0; - adbCompRout = (long)0; - adbCompData = (long)0; - /* - * Since we are done, check whether there is any data - * waiting to do out. If so, start the sending the data. - */ - if (adbOutQueueHasData == 1) { -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("XXX: DOING OUT QUEUE\n"); -#endif - /* copy over data */ - memcpy(adbOutputBuffer, adbOutQueue.outBuf, - adbOutQueue.outBuf[0] + 2); - adbBuffer = adbOutQueue.saveBuf; /* user data area */ - adbCompRout = adbOutQueue.compRout; /* completion routine */ - adbCompData = adbOutQueue.data; /* comp. rout. data */ - adbOutQueueHasData = 0; /* currently processing - * "queue" entry */ - send = 1; - } else { -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("XXending "); -#endif - adb_guess_next_device(); - adbOutputBuffer[0] = 1; - adbOutputBuffer[1] = ((adbLastDevice & 0x0f) << 4) | 0x0c; - adbSentChars = 0; /* nothing sent yet */ - adbActionState = ADB_ACTION_POLLING; /* set next state */ - ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ - ADB_SR() = adbOutputBuffer[1]; /* load byte for output */ - adbBusState = ADB_BUS_CMD; /* set bus to cmd state */ - ADB_SET_STATE_CMD(); /* tell ADB that we want to */ - break; - } - } - - /* - * If send is true then something above determined that - * the message has ended and we need to start sending out - * a new message immediately. This could be because there - * is data waiting to go out or because an SRQ was seen. - */ - if (send) { - adbSentChars = 0; /* nothing sent yet */ - adbActionState = ADB_ACTION_OUT; /* set next state */ - ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ - ADB_SR() = adbOutputBuffer[1]; /* load byte for output */ - adbBusState = ADB_BUS_CMD; /* set bus to cmd state */ - ADB_SET_STATE_CMD(); /* tell ADB that we want to - * send */ - break; - } - /* We only get this far if the message hasn't ended yet. */ - switch (adbBusState) { /* set to next state */ - case ADB_BUS_EVEN: - ADB_SET_STATE_ODD(); /* set state to odd */ - adbBusState = ADB_BUS_ODD; - break; - - case ADB_BUS_ODD: - ADB_SET_STATE_EVEN(); /* set state to even */ - adbBusState = ADB_BUS_EVEN; - break; - default: - printf_intr("strange state!!!\n"); /* huh? */ - break; - } - break; - - case ADB_ACTION_OUT: - i = ADB_SR(); /* clear interrupt */ - adbSentChars++; - /* - * If the outgoing data was a TALK, we must - * switch to input mode to get the result. - */ - if ((adbOutputBuffer[1] & 0x0c) == 0x0c) { - adbInputBuffer[0] = 1; - adbInputBuffer[1] = i; - adbActionState = ADB_ACTION_IN; - ADB_SET_SR_INPUT(); - adbBusState = ADB_BUS_EVEN; - ADB_SET_STATE_EVEN(); -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("talk out 0x%02x ", i); -#endif - /* we want something back */ - adbWaiting = 1; - break; - } - /* - * If it's not a TALK, check whether all data has been sent. - * If so, call the completion routine and clean up. If not, - * advance to the next state. - */ -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("non-talk out 0x%0x ", i); -#endif - ADB_SET_SR_OUTPUT(); - if (adbOutputBuffer[0] == adbSentChars) { /* check for done */ -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("done \n"); -#endif - /* set up stuff for adb_pass_up */ - memcpy(packet.data, adbOutputBuffer, adbOutputBuffer[0] + 1); - packet.saveBuf = adbBuffer; - packet.compRout = adbCompRout; - packet.compData = adbCompData; - packet.cmd = adbWaitingCmd; - packet.unsol = 0; - packet.ack_only = 1; - adb_pass_up(&packet); - - /* reset "waiting" vars, just in case */ - adbBuffer = (long)0; - adbCompRout = (long)0; - adbCompData = (long)0; - if (adbOutQueueHasData == 1) { - /* copy over data */ - memcpy(adbOutputBuffer, adbOutQueue.outBuf, - adbOutQueue.outBuf[0] + 2); - adbBuffer = adbOutQueue.saveBuf; /* user data area */ - adbCompRout = adbOutQueue.compRout; /* completion routine */ - adbCompData = adbOutQueue.data; /* comp. rout. data */ - adbOutQueueHasData = 0; /* currently processing - * "queue" entry */ - adbSentChars = 0; /* nothing sent yet */ - adbActionState = ADB_ACTION_OUT; /* set next state */ - ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ - ADB_SR() = adbOutputBuffer[1]; /* load byte for output */ - adbBusState = ADB_BUS_CMD; /* set bus to cmd state */ - ADB_SET_STATE_CMD(); /* tell ADB that we want to - * send */ - break; - } else { - /* send talk to last device instead */ - adbOutputBuffer[0] = 1; - adbOutputBuffer[1] = - ADBTALK(ADB_CMDADDR(adbOutputBuffer[1]), 0); - - adbSentChars = 0; /* nothing sent yet */ - adbActionState = ADB_ACTION_IDLE; /* set next state */ - ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ - ADB_SR() = adbOutputBuffer[1]; /* load byte for output */ - adbBusState = ADB_BUS_CMD; /* set bus to cmd state */ - ADB_SET_STATE_CMD(); /* tell ADB that we want to */ - break; - } - } - ADB_SR() = adbOutputBuffer[adbSentChars + 1]; - switch (adbBusState) { /* advance to next state */ - case ADB_BUS_EVEN: - ADB_SET_STATE_ODD(); /* set state to odd */ - adbBusState = ADB_BUS_ODD; - break; - - case ADB_BUS_CMD: - case ADB_BUS_ODD: - ADB_SET_STATE_EVEN(); /* set state to even */ - adbBusState = ADB_BUS_EVEN; - break; - - default: -#ifdef ADB_DEBUG - if (adb_debug) { - printf_intr("strange state!!! (0x%x)\n", - adbBusState); - } -#endif - break; - } - break; - - default: -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("adb: unknown ADB state (during intr)\n"); -#endif - break; - } - - ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */ - - splx(s); /* restore */ - - return (1); - -} - - -/* - * send_adb version for II series machines - */ -int -send_adb_II(u_char *in, u_char *buffer, void *compRout, void *data, int command) -{ - int s, len; - - if (adbActionState == ADB_ACTION_NOTREADY) /* return if ADB not - * available */ - return 1; - - /* Don't interrupt while we are messing with the ADB */ - s = splhigh(); - - if (0 != adbOutQueueHasData) { /* right now, "has data" means "full" */ - splx(s); /* sorry, try again later */ - return 1; - } - if ((long)in == (long)0) { /* need to convert? */ - /* - * Don't need to use adb_cmd_extra here because this section - * will be called ONLY when it is an ADB command (no RTC or - * PRAM), especially on II series! - */ - if ((command & 0x0c) == 0x08) /* copy addl data ONLY if - * doing a listen! */ - len = buffer[0]; /* length of additional data */ - else - len = 0;/* no additional data */ - - adbOutQueue.outBuf[0] = 1 + len; /* command + addl. data */ - adbOutQueue.outBuf[1] = (u_char)command; /* load command */ - - /* copy additional output data, if any */ - memcpy(adbOutQueue.outBuf + 2, buffer + 1, len); - } else - /* if data ready, just copy over */ - memcpy(adbOutQueue.outBuf, in, in[0] + 2); - - adbOutQueue.saveBuf = buffer; /* save buffer to know where to save - * result */ - adbOutQueue.compRout = compRout; /* save completion routine - * pointer */ - adbOutQueue.data = data;/* save completion routine data pointer */ - - if ((adbActionState == ADB_ACTION_IDLE) && /* is ADB available? */ - (ADB_INTR_IS_OFF)) { /* and no incoming interrupts? */ - /* then start command now */ - memcpy(adbOutputBuffer, adbOutQueue.outBuf, - adbOutQueue.outBuf[0] + 2); /* copy over data */ - - adbBuffer = adbOutQueue.saveBuf; /* pointer to user data - * area */ - adbCompRout = adbOutQueue.compRout; /* pointer to the - * completion routine */ - adbCompData = adbOutQueue.data; /* pointer to the completion - * routine data */ - - adbSentChars = 0; /* nothing sent yet */ - adbActionState = ADB_ACTION_OUT; /* set next state */ - adbBusState = ADB_BUS_CMD; /* set bus to cmd state */ - - ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ - - ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* load byte for output */ - ADB_SET_STATE_CMD(); /* tell ADB that we want to send */ - adbOutQueueHasData = 0; /* currently processing "queue" entry */ - } else - adbOutQueueHasData = 1; /* something in the write "queue" */ - - splx(s); - - if (0x0100 <= (s & 0x0700)) /* were VIA1 interrupts blocked? */ - /* poll until message done */ - while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON) - || (adbWaiting == 1)) - if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */ - adb_intr_II(NULL); /* go process it */ - if (adb_polling) - adb_soft_intr(); - } - - return 0; -} - - -/* - * This routine is called from the II series interrupt routine - * to determine what the "next" device is that should be polled. - */ -int -adb_guess_next_device(void) -{ - int last, i, dummy; - - if (adbStarting) { - /* - * Start polling EVERY device, since we can't be sure there is - * anything in the device table yet - */ - if (adbLastDevice < 1 || adbLastDevice > 15) - adbLastDevice = 1; - if (++adbLastDevice > 15) /* point to next one */ - adbLastDevice = 1; - } else { - /* find the next device using the device table */ - if (adbLastDevice < 1 || adbLastDevice > 15) /* let's be parinoid */ - adbLastDevice = 2; - last = 1; /* default index location */ - - for (i = 1; i < 16; i++) /* find index entry */ - if (ADBDevTable[i].currentAddr == adbLastDevice) { /* look for device */ - last = i; /* found it */ - break; - } - dummy = last; /* index to start at */ - for (;;) { /* find next device in index */ - if (++dummy > 15) /* wrap around if needed */ - dummy = 1; - if (dummy == last) { /* didn't find any other - * device! This can happen if - * there are no devices on the - * bus */ - dummy = 1; - break; - } - /* found the next device */ - if (ADBDevTable[dummy].devType != 0) - break; - } - adbLastDevice = ADBDevTable[dummy].currentAddr; - } - return adbLastDevice; -} - - -/* - * Called when when an adb interrupt happens. - * This routine simply transfers control over to the appropriate - * code for the machine we are running on. - */ -int -adb_intr(void *arg) -{ - switch (adbHardware) { - case ADB_HW_II: - return adb_intr_II(arg); - break; - - case ADB_HW_IISI: - return adb_intr_IIsi(arg); - break; - - case ADB_HW_PB: /* Should not come through here. */ - break; - - case ADB_HW_CUDA: - return adb_intr_cuda(arg); - break; - - case ADB_HW_UNKNOWN: - break; - } - - return (-1); -} - - -/* - * called when when an adb interrupt happens - * - * IIsi version of adb_intr - * - */ -int -adb_intr_IIsi(void *arg) -{ - struct adbCommand packet; - int i, ending; - unsigned int s; - - s = splhigh(); /* can't be too careful - might be called */ - /* from a routine, NOT an interrupt */ - - ADB_VIA_CLR_INTR(); /* clear interrupt */ - - ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */ - -switch_start: - switch (adbActionState) { - case ADB_ACTION_IDLE: - delay(ADB_DELAY); /* short delay is required before the - * first byte */ - - ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ - ADB_SET_STATE_ACTIVE(); /* signal start of data frame */ - adbInputBuffer[1] = ADB_SR(); /* get byte */ - adbInputBuffer[0] = 1; - adbActionState = ADB_ACTION_IN; /* set next state */ - - ADB_SET_STATE_ACKON(); /* start ACK to ADB chip */ - delay(ADB_DELAY); /* delay */ - ADB_SET_STATE_ACKOFF(); /* end ACK to ADB chip */ - (void)intr_dispatch(0x70); /* grab any serial interrupts */ - break; - - case ADB_ACTION_IN: - ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ - adbInputBuffer[++adbInputBuffer[0]] = ADB_SR(); /* get byte */ - if (ADB_INTR_IS_OFF) /* check for end of frame */ - ending = 1; - else - ending = 0; - - ADB_SET_STATE_ACKON(); /* start ACK to ADB chip */ - delay(ADB_DELAY); /* delay */ - ADB_SET_STATE_ACKOFF(); /* end ACK to ADB chip */ - (void)intr_dispatch(0x70); /* grab any serial interrupts */ - - if (1 == ending) { /* end of message? */ - ADB_SET_STATE_INACTIVE(); /* signal end of frame */ - /* - * This section _should_ handle all ADB and RTC/PRAM - * type commands, but there may be more... Note: - * commands are always at [4], even for rtc/pram - * commands - */ - /* set up data for adb_pass_up */ - memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1); - - if ((adbWaiting == 1) && /* are we waiting AND */ - (adbInputBuffer[4] == adbWaitingCmd) && /* the cmd we sent AND */ - ((adbInputBuffer[2] == 0x00) || /* it's from the ADB - * device OR */ - (adbInputBuffer[2] == 0x01))) { /* it's from the - * PRAM/RTC device */ - - packet.saveBuf = adbBuffer; - packet.compRout = adbCompRout; - packet.compData = adbCompData; - packet.unsol = 0; - packet.ack_only = 0; - adb_pass_up(&packet); - - adbWaitingCmd = 0; /* reset "waiting" vars */ - adbWaiting = 0; - adbBuffer = (long)0; - adbCompRout = (long)0; - adbCompData = (long)0; - } else { - packet.unsol = 1; - packet.ack_only = 0; - adb_pass_up(&packet); - } - - adbActionState = ADB_ACTION_IDLE; - adbInputBuffer[0] = 0; /* reset length */ - - if (adbWriteDelay == 1) { /* were we waiting to - * write? */ - adbSentChars = 0; /* nothing sent yet */ - adbActionState = ADB_ACTION_OUT; /* set next state */ - - delay(ADB_DELAY); /* delay */ - (void)intr_dispatch(0x70); /* grab any serial interrupts */ - - if (ADB_INTR_IS_ON) { /* ADB intr low during - * write */ - ADB_SET_STATE_IDLE_IISI(); /* reset */ - ADB_SET_SR_INPUT(); /* make sure SR is set - * to IN */ - adbSentChars = 0; /* must start all over */ - adbActionState = ADB_ACTION_IDLE; /* new state */ - adbInputBuffer[0] = 0; - /* may be able to take this out later */ - delay(ADB_DELAY); /* delay */ - break; - } - ADB_SET_STATE_ACTIVE(); /* tell ADB that we want - * to send */ - ADB_SET_STATE_ACKOFF(); /* make sure */ - ADB_SET_SR_OUTPUT(); /* set shift register - * for OUT */ - ADB_SR() = adbOutputBuffer[adbSentChars + 1]; - ADB_SET_STATE_ACKON(); /* tell ADB byte ready - * to shift */ - } - } - break; - - case ADB_ACTION_OUT: - i = ADB_SR(); /* reset SR-intr in IFR */ - ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ - - ADB_SET_STATE_ACKOFF(); /* finish ACK */ - adbSentChars++; - if (ADB_INTR_IS_ON) { /* ADB intr low during write */ - ADB_SET_STATE_IDLE_IISI(); /* reset */ - ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ - adbSentChars = 0; /* must start all over */ - adbActionState = ADB_ACTION_IDLE; /* new state */ - adbInputBuffer[0] = 0; - adbWriteDelay = 1; /* must retry when done with - * read */ - delay(ADB_DELAY); /* delay */ - (void)intr_dispatch(0x70); /* grab any serial interrupts */ - goto switch_start; /* process next state right - * now */ - break; - } - delay(ADB_DELAY); /* required delay */ - (void)intr_dispatch(0x70); /* grab any serial interrupts */ - - if (adbOutputBuffer[0] == adbSentChars) { /* check for done */ - if (0 == adb_cmd_result(adbOutputBuffer)) { /* do we expect data - * back? */ - adbWaiting = 1; /* signal waiting for return */ - adbWaitingCmd = adbOutputBuffer[2]; /* save waiting command */ - } else {/* no talk, so done */ - /* set up stuff for adb_pass_up */ - memcpy(packet.data, adbInputBuffer, - adbInputBuffer[0] + 1); - packet.saveBuf = adbBuffer; - packet.compRout = adbCompRout; - packet.compData = adbCompData; - packet.cmd = adbWaitingCmd; - packet.unsol = 0; - packet.ack_only = 1; - adb_pass_up(&packet); - - /* reset "waiting" vars, just in case */ - adbWaitingCmd = 0; - adbBuffer = (long)0; - adbCompRout = (long)0; - adbCompData = (long)0; - } - - adbWriteDelay = 0; /* done writing */ - adbActionState = ADB_ACTION_IDLE; /* signal bus is idle */ - ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ - ADB_SET_STATE_INACTIVE(); /* end of frame */ - } else { - ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* send next byte */ - ADB_SET_STATE_ACKON(); /* signal byte ready to shift */ - } - break; - - case ADB_ACTION_NOTREADY: -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("adb: not yet initialized\n"); -#endif - break; - - default: -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("intr: unknown ADB state\n"); -#endif - break; - } - - ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */ - - splx(s); /* restore */ - - return (1); -} /* end adb_intr_IIsi */ - - -/***************************************************************************** - * if the device is currently busy, and there is no data waiting to go out, then - * the data is "queued" in the outgoing buffer. If we are already waiting, then - * we return. - * in: if (in == 0) then the command string is built from command and buffer - * if (in != 0) then in is used as the command string - * buffer: additional data to be sent (used only if in == 0) - * this is also where return data is stored - * compRout: the completion routine that is called when then return value - * is received (if a return value is expected) - * data: a data pointer that can be used by the completion routine - * command: an ADB command to be sent (used only if in == 0) - * - */ -int -send_adb_IIsi(u_char *in, u_char *buffer, void *compRout, void *data, int - command) -{ - int s, len; - - if (adbActionState == ADB_ACTION_NOTREADY) - return 1; - - /* Don't interrupt while we are messing with the ADB */ - s = splhigh(); - - if ((adbActionState == ADB_ACTION_IDLE) && /* ADB available? */ - (ADB_INTR_IS_OFF)) {/* and no incoming interrupt? */ - - } else - if (adbWriteDelay == 0) /* it's busy, but is anything waiting? */ - adbWriteDelay = 1; /* if no, then we'll "queue" - * it up */ - else { - splx(s); - return 1; /* really busy! */ - } - - if ((long)in == (long)0) { /* need to convert? */ - /* - * Don't need to use adb_cmd_extra here because this section - * will be called ONLY when it is an ADB command (no RTC or - * PRAM) - */ - if ((command & 0x0c) == 0x08) /* copy addl data ONLY if - * doing a listen! */ - len = buffer[0]; /* length of additional data */ - else - len = 0;/* no additional data */ - - adbOutputBuffer[0] = 2 + len; /* dev. type + command + addl. - * data */ - adbOutputBuffer[1] = 0x00; /* mark as an ADB command */ - adbOutputBuffer[2] = (u_char)command; /* load command */ - - /* copy additional output data, if any */ - memcpy(adbOutputBuffer + 3, buffer + 1, len); - } else - /* if data ready, just copy over */ - memcpy(adbOutputBuffer, in, in[0] + 2); - - adbSentChars = 0; /* nothing sent yet */ - adbBuffer = buffer; /* save buffer to know where to save result */ - adbCompRout = compRout; /* save completion routine pointer */ - adbCompData = data; /* save completion routine data pointer */ - adbWaitingCmd = adbOutputBuffer[2]; /* save wait command */ - - if (adbWriteDelay != 1) { /* start command now? */ - adbActionState = ADB_ACTION_OUT; /* set next state */ - - ADB_SET_STATE_ACTIVE(); /* tell ADB that we want to send */ - ADB_SET_STATE_ACKOFF(); /* make sure */ - - ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ - - ADB_SR() = adbOutputBuffer[adbSentChars + 1]; /* load byte for output */ - - ADB_SET_STATE_ACKON(); /* tell ADB byte ready to shift */ - } - adbWriteDelay = 1; /* something in the write "queue" */ - - splx(s); - - if (0x0100 <= (s & 0x0700)) /* were VIA1 interrupts blocked? */ - /* poll until byte done */ - while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON) - || (adbWaiting == 1)) - if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */ - adb_intr_IIsi(NULL); /* go process it */ - if (adb_polling) - adb_soft_intr(); - } - - return 0; -} /* send_adb_IIsi */ - -/* - * adb_pass_up is called by the interrupt-time routines. - * It takes the raw packet data that was received from the - * device and puts it into the queue that the upper half - * processes. It then signals for a soft ADB interrupt which - * will eventually call the upper half routine (adb_soft_intr). - * - * If in->unsol is 0, then this is either the notification - * that the packet was sent (on a LISTEN, for example), or the - * response from the device (on a TALK). The completion routine - * is called only if the user specified one. - * - * If in->unsol is 1, then this packet was unsolicited and - * so we look up the device in the ADB device table to determine - * what it's default service routine is. - * - * If in->ack_only is 1, then we really only need to call - * the completion routine, so don't do any other stuff. - * - * Note that in->data contains the packet header AND data, - * while adbInbound[]->data contains ONLY data. - * - * Note: Called only at interrupt time. Assumes this. - */ -void -adb_pass_up(struct adbCommand *in) -{ - int start = 0, len = 0, cmd = 0; - ADBDataBlock block; - - /* temp for testing */ - /*u_char *buffer = 0;*/ - /*u_char *compdata = 0;*/ - /*u_char *comprout = 0;*/ - - if (adbInCount >= ADB_QUEUE) { -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("adb: ring buffer overflow\n"); -#endif - return; - } - - if (in->ack_only) { - len = in->data[0]; - cmd = in->cmd; - start = 0; - } else { - switch (adbHardware) { - case ADB_HW_II: - cmd = in->data[1]; - if (in->data[0] < 2) - len = 0; - else - len = in->data[0]-1; - start = 1; - break; - - case ADB_HW_IISI: - case ADB_HW_CUDA: - /* If it's unsolicited, accept only ADB data for now */ - if (in->unsol) - if (0 != in->data[2]) - return; - cmd = in->data[4]; - if (in->data[0] < 5) - len = 0; - else - len = in->data[0]-4; - start = 4; - break; - - case ADB_HW_PB: - cmd = in->data[1]; - if (in->data[0] < 2) - len = 0; - else - len = in->data[0]-1; - start = 1; - break; - - case ADB_HW_UNKNOWN: - return; - } - - /* Make sure there is a valid device entry for this device */ - if (in->unsol) { - /* ignore unsolicited data during adbreinit */ - if (adbStarting) - return; - /* get device's comp. routine and data area */ - if (-1 == get_adb_info(&block, ADB_CMDADDR(cmd))) - return; - } - } - - /* - * If this is an unsolicited packet, we need to fill in - * some info so adb_soft_intr can process this packet - * properly. If it's not unsolicited, then use what - * the caller sent us. - */ - if (in->unsol) { - adbInbound[adbInTail].compRout = (void *)block.dbServiceRtPtr; - adbInbound[adbInTail].compData = (void *)block.dbDataAreaAddr; - adbInbound[adbInTail].saveBuf = (void *)adbInbound[adbInTail].data; - } else { - adbInbound[adbInTail].compRout = (void *)in->compRout; - adbInbound[adbInTail].compData = (void *)in->compData; - adbInbound[adbInTail].saveBuf = (void *)in->saveBuf; - } - -#ifdef ADB_DEBUG - if (adb_debug && in->data[1] == 2) - printf_intr("adb: caught error\n"); -#endif - - /* copy the packet data over */ - /* - * TO DO: If the *_intr routines fed their incoming data - * directly into an adbCommand struct, which is passed to - * this routine, then we could eliminate this copy. - */ - memcpy(adbInbound[adbInTail].data + 1, in->data + start + 1, len); - adbInbound[adbInTail].data[0] = len; - adbInbound[adbInTail].cmd = cmd; - - adbInCount++; - if (++adbInTail >= ADB_QUEUE) - adbInTail = 0; - - /* - * If the debugger is running, call upper half manually. - * Otherwise, trigger a soft interrupt to handle the rest later. - */ - if (adb_polling) - adb_soft_intr(); - else - setsoftadb(); - - return; -} - - -/* - * Called to process the packets after they have been - * placed in the incoming queue. - * - */ -void -adb_soft_intr(void) -{ - int s; - int cmd = 0; - u_char *buffer = 0; - u_char *comprout = 0; - u_char *compdata = 0; - -/*delay(2*ADB_DELAY);*/ - - while (adbInCount) { -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("%x %x %x ", - adbInCount, adbInHead, adbInTail); -#endif - /* get the data we need from the queue */ - buffer = adbInbound[adbInHead].saveBuf; - comprout = adbInbound[adbInHead].compRout; - compdata = adbInbound[adbInHead].compData; - cmd = adbInbound[adbInHead].cmd; - - /* copy over data to data area if it's valid */ - /* - * Note that for unsol packets we don't want to copy the - * data anywhere, so buffer was already set to 0. - * For ack_only buffer was set to 0, so don't copy. - */ - if (buffer) - memcpy(buffer, adbInbound[adbInHead].data, - adbInbound[adbInHead].data[0] + 1); - -#ifdef ADB_DEBUG - if (adb_debug & 0x80) { - printf_intr("%p %p %p %x ", - buffer, comprout, compdata, (short)cmd); - printf_intr("buf: "); - print_single(adbInbound[adbInHead].data); - } -#endif - - /* call default completion routine if it's valid */ - if (comprout) { - (void)((int (*)(u_char *, u_char *, int))comprout) - (buffer, compdata, cmd); - } - - s = splhigh(); - adbInCount--; - if (++adbInHead >= ADB_QUEUE) - adbInHead = 0; - splx(s); - - } - return; -} - - -/* - * This is my version of the ADBOp routine. It mainly just calls the - * hardware-specific routine. - * - * data : pointer to data area to be used by compRout - * compRout : completion routine - * buffer : for LISTEN: points to data to send - MAX 8 data bytes, - * byte 0 = # of bytes - * : for TALK: points to place to save return data - * command : the adb command to send - * result : 0 = success - * : -1 = could not complete - */ -int -adb_op(Ptr buffer, Ptr compRout, Ptr data, short command) -{ - int result; - - switch (adbHardware) { - case ADB_HW_II: - result = send_adb_II((u_char *)0, (u_char *)buffer, - (void *)compRout, (void *)data, (int)command); - if (result == 0) - return 0; - else - return -1; - break; - - case ADB_HW_IISI: - result = send_adb_IIsi((u_char *)0, (u_char *)buffer, - (void *)compRout, (void *)data, (int)command); - /* - * I wish I knew why this delay is needed. It usually needs to - * be here when several commands are sent in close succession, - * especially early in device probes when doing collision - * detection. It must be some race condition. Sigh. - jpw - */ - delay(100); - if (result == 0) - return 0; - else - return -1; - break; - - case ADB_HW_PB: - result = pm_adb_op((u_char *)buffer, (void *)compRout, - (void *)data, (int)command); - - if (result == 0) - return 0; - else - return -1; - break; - - case ADB_HW_CUDA: - result = send_adb_cuda((u_char *)0, (u_char *)buffer, - (void *)compRout, (void *)data, (int)command); - if (result == 0) - return 0; - else - return -1; - break; - - case ADB_HW_UNKNOWN: - default: - return -1; - } -} - - -/* - * adb_hw_setup - * This routine sets up the possible machine specific hardware - * config (mainly VIA settings) for the various models. - */ -void -adb_hw_setup(void) -{ - volatile int i; - u_char send_string[ADB_MAX_MSG_LENGTH]; - - switch (adbHardware) { - case ADB_HW_II: - via1_register_irq(2, adb_intr_II, NULL, NULL); - - via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5: - * outputs */ - via_reg(VIA1, vDirB) &= 0xf7; /* register B bit 3: input */ - via_reg(VIA1, vACR) &= ~vSR_OUT; /* make sure SR is set - * to IN (II, IIsi) */ - adbActionState = ADB_ACTION_IDLE; /* used by all types of - * hardware (II, IIsi) */ - adbBusState = ADB_BUS_IDLE; /* this var. used in II-series - * code only */ - via_reg(VIA1, vIER) = 0x84; /* make sure VIA interrupts - * are on (II, IIsi) */ - ADB_SET_STATE_IDLE_II(); /* set ADB bus state to idle */ - - ADB_VIA_CLR_INTR(); /* clear interrupt */ - break; - - case ADB_HW_IISI: - via1_register_irq(2, adb_intr_IIsi, NULL, NULL); - via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5: - * outputs */ - via_reg(VIA1, vDirB) &= 0xf7; /* register B bit 3: input */ - via_reg(VIA1, vACR) &= ~vSR_OUT; /* make sure SR is set - * to IN (II, IIsi) */ - adbActionState = ADB_ACTION_IDLE; /* used by all types of - * hardware (II, IIsi) */ - adbBusState = ADB_BUS_IDLE; /* this var. used in II-series - * code only */ - via_reg(VIA1, vIER) = 0x84; /* make sure VIA interrupts - * are on (II, IIsi) */ - ADB_SET_STATE_IDLE_IISI(); /* set ADB bus state to idle */ - - /* get those pesky clock ticks we missed while booting */ - for (i = 0; i < 30; i++) { - delay(ADB_DELAY); - adb_hw_setup_IIsi(send_string); -#ifdef ADB_DEBUG - if (adb_debug) { - printf_intr("adb: cleanup: "); - print_single(send_string); - } -#endif - delay(ADB_DELAY); - if (ADB_INTR_IS_OFF) - break; - } - break; - - case ADB_HW_PB: - /* - * XXX - really PM_VIA_CLR_INTR - should we put it in - * pm_direct.h? - */ - pm_hw_setup(); - break; - - case ADB_HW_CUDA: - via1_register_irq(2, adb_intr_cuda, NULL, NULL); - via_reg(VIA1, vDirB) |= 0x30; /* register B bits 4 and 5: - * outputs */ - via_reg(VIA1, vDirB) &= 0xf7; /* register B bit 3: input */ - via_reg(VIA1, vACR) &= ~vSR_OUT; /* make sure SR is set - * to IN */ - via_reg(VIA1, vACR) = (via_reg(VIA1, vACR) | 0x0c) & ~0x10; - adbActionState = ADB_ACTION_IDLE; /* used by all types of - * hardware */ - adbBusState = ADB_BUS_IDLE; /* this var. used in II-series - * code only */ - via_reg(VIA1, vIER) = 0x84; /* make sure VIA interrupts - * are on */ - ADB_SET_STATE_IDLE_CUDA(); /* set ADB bus state to idle */ - - /* sort of a device reset */ - i = ADB_SR(); /* clear interrupt */ - ADB_VIA_INTR_DISABLE(); /* no interrupts while clearing */ - ADB_SET_STATE_IDLE_CUDA(); /* reset state to idle */ - delay(ADB_DELAY); - ADB_SET_STATE_TIP(); /* signal start of frame */ - delay(ADB_DELAY); - ADB_TOGGLE_STATE_ACK_CUDA(); - delay(ADB_DELAY); - ADB_CLR_STATE_TIP(); - delay(ADB_DELAY); - ADB_SET_STATE_IDLE_CUDA(); /* back to idle state */ - i = ADB_SR(); /* clear interrupt */ - ADB_VIA_INTR_ENABLE(); /* ints ok now */ - break; - - case ADB_HW_UNKNOWN: - default: - via_reg(VIA1, vIER) = 0x04; /* turn interrupts off - TO - * DO: turn PB ints off? */ - return; - break; - } -} - - -/* - * adb_hw_setup_IIsi - * This is sort of a "read" routine that forces the adb hardware through a read cycle - * if there is something waiting. This helps "clean up" any commands that may have gotten - * stuck or stopped during the boot process. - * - */ -void -adb_hw_setup_IIsi(u_char *buffer) -{ - int i; - int dummy; - int s; - long my_time; - int endofframe; - - delay(ADB_DELAY); - - i = 1; /* skip over [0] */ - s = splhigh(); /* block ALL interrupts while we are working */ - ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ - ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */ - /* this is required, especially on faster machines */ - delay(ADB_DELAY); - - if (ADB_INTR_IS_ON) { - ADB_SET_STATE_ACTIVE(); /* signal start of data frame */ - - endofframe = 0; - while (0 == endofframe) { - /* - * Poll for ADB interrupt and watch for timeout. - * If time out, keep going in hopes of not hanging - * the ADB chip - I think - */ - my_time = ADB_DELAY * 5; - while ((ADB_SR_INTR_IS_OFF) && (my_time-- > 0)) - dummy = via_reg(VIA1, vBufB); - - buffer[i++] = ADB_SR(); /* reset interrupt flag by - * reading vSR */ - /* - * Perhaps put in a check here that ignores all data - * after the first ADB_MAX_MSG_LENGTH bytes ??? - */ - if (ADB_INTR_IS_OFF) /* check for end of frame */ - endofframe = 1; - - ADB_SET_STATE_ACKON(); /* send ACK to ADB chip */ - delay(ADB_DELAY); /* delay */ - ADB_SET_STATE_ACKOFF(); /* send ACK to ADB chip */ - } - ADB_SET_STATE_INACTIVE(); /* signal end of frame and - * delay */ - - /* probably don't need to delay this long */ - delay(ADB_DELAY); - } - buffer[0] = --i; /* [0] is length of message */ - ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */ - splx(s); /* restore interrupts */ - - return; -} /* adb_hw_setup_IIsi */ - - - -/* - * adb_reinit sets up the adb stuff - * - */ -void -adb_reinit(void) -{ - u_char send_string[ADB_MAX_MSG_LENGTH]; - ADBDataBlock data; /* temp. holder for getting device info */ - volatile int i, x; - int s; - int command; - int result; - int saveptr; /* point to next free relocation address */ - int device; - int nonewtimes; /* times thru loop w/o any new devices */ - - via1_register_irq(2, adb_intr, NULL, "adb"); - adb_setup_hw_type(); /* setup hardware type */ - - /* Make sure we are not interrupted while building the table. */ - /* ints must be on for PB & IOP (at least, for now) */ - if (adbHardware != ADB_HW_PB) - s = splhigh(); - else - s = 0; /* XXX shut the compiler up*/ - - ADBNumDevices = 0; /* no devices yet */ - - /* Let intr routines know we are running reinit */ - adbStarting = 1; - - /* - * Initialize the ADB table. For now, we'll always use the same table - * that is defined at the beginning of this file - no mallocs. - */ - for (i = 0; i < 16; i++) { - ADBDevTable[i].devType = 0; - ADBDevTable[i].origAddr = ADBDevTable[i].currentAddr = 0; - } - - adb_hw_setup(); /* init the VIA bits and hard reset ADB */ - - delay(1000); - - /* send an ADB reset first */ - (void)adb_op_sync((Ptr)0, (Ptr)0, (Ptr)0, (short)0x00); - delay(3000); - - /* - * Probe for ADB devices. Probe devices 1-15 quickly to determine - * which device addresses are in use and which are free. For each - * address that is in use, move the device at that address to a higher - * free address. Continue doing this at that address until no device - * responds at that address. Then move the last device that was moved - * back to the original address. Do this for the remaining addresses - * that we determined were in use. - * - * When finished, do this entire process over again with the updated - * list of in use addresses. Do this until no new devices have been - * found in 20 passes though the in use address list. (This probably - * seems long and complicated, but it's the best way to detect multiple - * devices at the same address - sometimes it takes a couple of tries - * before the collision is detected.) - */ - - /* initial scan through the devices */ - for (i = 1; i < 16; i++) { - command = ADBTALK(i, 3); - result = adb_op_sync((Ptr)send_string, (Ptr)0, - (Ptr)0, (short)command); - - if (result == 0 && send_string[0] != 0) { - /* found a device */ - ++ADBNumDevices; - KASSERT(ADBNumDevices < 16); - ADBDevTable[ADBNumDevices].devType = - (int)(send_string[2]); - ADBDevTable[ADBNumDevices].origAddr = i; - ADBDevTable[ADBNumDevices].currentAddr = i; - ADBDevTable[ADBNumDevices].DataAreaAddr = - (long)0; - ADBDevTable[ADBNumDevices].ServiceRtPtr = (void *)0; - pm_check_adb_devices(i); /* tell pm driver device - * is here */ - } - } - - /* find highest unused address */ - for (saveptr = 15; saveptr > 0; saveptr--) - if (-1 == get_adb_info(&data, saveptr)) - break; - -#ifdef ADB_DEBUG - if (adb_debug & 0x80) { - printf_intr("first free is: 0x%02x\n", saveptr); - printf_intr("devices: %i\n", ADBNumDevices); - } -#endif - - nonewtimes = 0; /* no loops w/o new devices */ - while (saveptr > 0 && nonewtimes++ < 11) { - for (i = 1;saveptr > 0 && i <= ADBNumDevices; i++) { - device = ADBDevTable[i].currentAddr; -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("moving device 0x%02x to 0x%02x " - "(index 0x%02x) ", device, saveptr, i); -#endif - - /* send TALK R3 to address */ - command = ADBTALK(device, 3); - (void)adb_op_sync((Ptr)send_string, (Ptr)0, - (Ptr)0, (short)command); - - /* move device to higher address */ - command = ADBLISTEN(device, 3); - send_string[0] = 2; - send_string[1] = (u_char)(saveptr | 0x60); - send_string[2] = 0xfe; - (void)adb_op_sync((Ptr)send_string, (Ptr)0, - (Ptr)0, (short)command); - delay(1000); - - /* send TALK R3 - anthing at new address? */ - command = ADBTALK(saveptr, 3); - send_string[0] = 0; - result = adb_op_sync((Ptr)send_string, (Ptr)0, - (Ptr)0, (short)command); - delay(1000); - - if (result != 0 || send_string[0] == 0) { - /* - * maybe there's a communication breakdown; - * just in case, move it back from whence it - * came, and we'll try again later - */ - command = ADBLISTEN(saveptr, 3); - send_string[0] = 2; - send_string[1] = (u_char)(device | 0x60); - send_string[2] = 0x00; - (void)adb_op_sync((Ptr)send_string, (Ptr)0, - (Ptr)0, (short)command); -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("failed, continuing\n"); -#endif - delay(1000); - continue; - } - - /* send TALK R3 - anything at old address? */ - command = ADBTALK(device, 3); - send_string[0] = 0; - result = adb_op_sync((Ptr)send_string, (Ptr)0, - (Ptr)0, (short)command); - if (result == 0 && send_string[0] != 0) { - /* new device found */ - /* update data for previously moved device */ - ADBDevTable[i].currentAddr = saveptr; -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("old device at index %i\n",i); -#endif - /* add new device in table */ -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("new device found\n"); -#endif - if (saveptr > ADBNumDevices) { - ++ADBNumDevices; - KASSERT(ADBNumDevices < 16); - } - ADBDevTable[ADBNumDevices].devType = - (int)(send_string[2]); - ADBDevTable[ADBNumDevices].origAddr = device; - ADBDevTable[ADBNumDevices].currentAddr = device; - /* These will be set correctly in adbsys.c */ - /* Until then, unsol. data will be ignored. */ - ADBDevTable[ADBNumDevices].DataAreaAddr = - (long)0; - ADBDevTable[ADBNumDevices].ServiceRtPtr = - (void *)0; - /* find next unused address */ - for (x = saveptr; x > 0; x--) { - if (-1 == get_adb_info(&data, x)) { - saveptr = x; - break; - } - } - if (x == 0) - saveptr = 0; -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("new free is 0x%02x\n", - saveptr); -#endif - nonewtimes = 0; - /* tell pm driver device is here */ - pm_check_adb_devices(device); - } else { -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("moving back...\n"); -#endif - /* move old device back */ - command = ADBLISTEN(saveptr, 3); - send_string[0] = 2; - send_string[1] = (u_char)(device | 0x60); - send_string[2] = 0xfe; - (void)adb_op_sync((Ptr)send_string, (Ptr)0, - (Ptr)0, (short)command); - delay(1000); - } - } - } - -#ifdef ADB_DEBUG - if (adb_debug) { - for (i = 1; i <= ADBNumDevices; i++) { - x = get_ind_adb_info(&data, i); - if (x != -1) - printf_intr("index 0x%x, addr 0x%x, type 0x%hx\n", - i, x, data.devType); - } - } -#endif - - /* enable the programmer's switch, if we have one */ - adb_prog_switch_enable(); - -#ifdef ADB_DEBUG - if (adb_debug) { - if (0 == ADBNumDevices) /* tell user if no devices found */ - printf_intr("adb: no devices found\n"); - } -#endif - - adbStarting = 0; /* not starting anymore */ -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("adb: ADBReInit complete\n"); -#endif - - if (adbHardware == ADB_HW_CUDA) { - timeout_set(&adb_cuda_timeout, (void *)adb_cuda_tickle, NULL); - timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS); - } - - /* ints must be on for PB & IOP (at least, for now) */ - if (adbHardware != ADB_HW_PB) - splx(s); - - return; -} - - -/* - * adb_cmd_result - * - * This routine lets the caller know whether the specified adb command string - * should expect a returned result, such as a TALK command. - * - * returns: 0 if a result should be expected - * 1 if a result should NOT be expected - */ -int -adb_cmd_result(u_char *in) -{ - switch (adbHardware) { - case ADB_HW_II: - /* was it an ADB talk command? */ - if ((in[1] & 0x0c) == 0x0c) - return 0; - return 1; - - case ADB_HW_IISI: - case ADB_HW_CUDA: - /* was it an ADB talk command? */ - if ((in[1] == 0x00) && ((in[2] & 0x0c) == 0x0c)) - return 0; - /* was it an RTC/PRAM read date/time? */ - if ((in[1] == 0x01) && (in[2] == 0x03)) - return 0; - return 1; - - case ADB_HW_PB: - return 1; - - case ADB_HW_UNKNOWN: - default: - return 1; - } -} - - -/* - * adb_cmd_extra - * - * This routine lets the caller know whether the specified adb command string - * may have extra data appended to the end of it, such as a LISTEN command. - * - * returns: 0 if extra data is allowed - * 1 if extra data is NOT allowed - */ -int -adb_cmd_extra(u_char *in) -{ - switch (adbHardware) { - case ADB_HW_II: - if ((in[1] & 0x0c) == 0x08) /* was it a listen command? */ - return 0; - return 1; - - case ADB_HW_IISI: - case ADB_HW_CUDA: - /* - * TO DO: support needs to be added to recognize RTC and PRAM - * commands - */ - if ((in[2] & 0x0c) == 0x08) /* was it a listen command? */ - return 0; - /* add others later */ - return 1; - - case ADB_HW_PB: - return 1; - - case ADB_HW_UNKNOWN: - default: - return 1; - } -} - - -void -adb_setup_hw_type(void) -{ - long response; - - response = mac68k_machine.machineid; - - /* - * Determine what type of ADB hardware we are running on. - */ - switch (response) { - case MACH_MACC610: /* Centris 610 */ - case MACH_MACC650: /* Centris 650 */ - case MACH_MACII: /* II */ - case MACH_MACIICI: /* IIci */ - case MACH_MACIICX: /* IIcx */ - case MACH_MACIIX: /* IIx */ - case MACH_MACQ610: /* Quadra 610 */ - case MACH_MACQ650: /* Quadra 650 */ - case MACH_MACQ700: /* Quadra 700 */ - case MACH_MACQ800: /* Quadra 800 */ - case MACH_MACSE30: /* SE/30 */ - adbHardware = ADB_HW_II; -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("adb: using II series hardware support\n"); -#endif - break; - - case MACH_MACCLASSICII: /* Classic II */ - case MACH_MACLCII: /* LC II, Performa 400/405/430 */ - case MACH_MACLCIII: /* LC III, Performa 450 */ - case MACH_MACIISI: /* IIsi */ - case MACH_MACIIVI: /* IIvi */ - case MACH_MACIIVX: /* IIvx */ - case MACH_MACP460: /* Performa 460/465/467 */ - case MACH_MACP600: /* Performa 600 */ - adbHardware = ADB_HW_IISI; -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("adb: using IIsi series hardware support\n"); -#endif - break; - - case MACH_MACPB140: /* PowerBook 140 */ - case MACH_MACPB145: /* PowerBook 145 */ - case MACH_MACPB160: /* PowerBook 160 */ - case MACH_MACPB165: /* PowerBook 165 */ - case MACH_MACPB165C: /* PowerBook 165c */ - case MACH_MACPB170: /* PowerBook 170 */ - case MACH_MACPB180: /* PowerBook 180 */ - case MACH_MACPB180C: /* PowerBook 180c */ - adbHardware = ADB_HW_PB; - pm_setup_adb(); -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("adb: using PowerBook 100-series hardware support\n"); -#endif - break; - - case MACH_MACPB150: /* PowerBook 150 */ - case MACH_MACPB210: /* PowerBook Duo 210 */ - case MACH_MACPB230: /* PowerBook Duo 230 */ - case MACH_MACPB250: /* PowerBook Duo 250 */ - case MACH_MACPB270: /* PowerBook Duo 270 */ - case MACH_MACPB280: /* PowerBook Duo 280 */ - case MACH_MACPB280C: /* PowerBook Duo 280c */ - case MACH_MACPB500: /* PowerBook 500 series */ - case MACH_MACPB190: /* PowerBook 190 */ - case MACH_MACPB190CS: /* PowerBook 190cs */ - adbHardware = ADB_HW_PB; - pm_setup_adb(); -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("adb: using PowerBook Duo-series and PowerBook 500-series hardware support\n"); -#endif - break; - - case MACH_MACC660AV: /* Centris 660AV */ - case MACH_MACCCLASSIC: /* Color Classic */ - case MACH_MACCCLASSICII: /* Color Classic II */ - case MACH_MACLC475: /* LC 475, Performa 475/476 */ - case MACH_MACLC475_33: /* Clock-chipped 47x */ - case MACH_MACLC520: /* LC 520 */ - case MACH_MACLC575: /* LC 575, Performa 575/577/578 */ - case MACH_MACP550: /* LC 550, Performa 550 */ - case MACH_MACTV: /* Macintosh TV */ - case MACH_MACP580: /* Performa 580/588 */ - case MACH_MACQ605: /* Quadra 605 */ - case MACH_MACQ605_33: /* Clock-chipped Quadra 605 */ - case MACH_MACQ630: /* LC 630, Performa 630, Quadra 630 */ - case MACH_MACQ840AV: /* Quadra 840AV */ - adbHardware = ADB_HW_CUDA; -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("adb: using Cuda series hardware support\n"); -#endif - break; - - default: - adbHardware = ADB_HW_UNKNOWN; -#ifdef ADB_DEBUG - if (adb_debug) { - printf_intr("adb: hardware type unknown for this machine\n"); - printf_intr("adb: ADB support is disabled\n"); - } -#endif - break; - } - - /* - * Determine whether this machine has ADB based soft power. - */ - switch (response) { - case MACH_MACCCLASSIC: /* Color Classic */ - case MACH_MACCCLASSICII: /* Color Classic II */ - case MACH_MACIISI: /* IIsi */ - case MACH_MACIIVI: /* IIvi */ - case MACH_MACIIVX: /* IIvx */ - case MACH_MACLC520: /* LC 520 */ - case MACH_MACLC575: /* LC 575, Performa 575/577/578 */ - case MACH_MACP550: /* LC 550, Performa 550 */ - case MACH_MACTV: /* Macintosh TV */ - case MACH_MACP580: /* Performa 580/588 */ - case MACH_MACP600: /* Performa 600 */ - case MACH_MACQ630: /* LC 630, Performa 630, Quadra 630 */ - case MACH_MACQ840AV: /* Quadra 840AV */ - adbSoftPower = 1; - break; - } -} - -int -count_adbs(void) -{ - int i; - int found; - - found = 0; - - for (i = 1; i < 16; i++) - if (0 != ADBDevTable[i].currentAddr) - found++; - - return found; -} - -int -get_ind_adb_info(ADBDataBlock *info, int index) -{ - if ((index < 1) || (index > 15)) /* check range 1-15 */ - return (-1); - -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("index 0x%x devType is: 0x%x\n", index, - ADBDevTable[index].devType); -#endif - if (0 == ADBDevTable[index].devType) /* make sure it's a valid entry */ - return (-1); - - info->devType = (unsigned char)(ADBDevTable[index].devType); - info->origADBAddr = (unsigned char)(ADBDevTable[index].origAddr); - info->dbServiceRtPtr = (Ptr)ADBDevTable[index].ServiceRtPtr; - info->dbDataAreaAddr = (Ptr)ADBDevTable[index].DataAreaAddr; - - return (ADBDevTable[index].currentAddr); -} - -int -get_adb_info(ADBDataBlock *info, int adbAddr) -{ - int i; - - if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */ - return (-1); - - for (i = 1; i < 15; i++) - if (ADBDevTable[i].currentAddr == adbAddr) { - info->devType = (unsigned char)(ADBDevTable[i].devType); - info->origADBAddr = (unsigned char)(ADBDevTable[i].origAddr); - info->dbServiceRtPtr = (Ptr)ADBDevTable[i].ServiceRtPtr; - info->dbDataAreaAddr = ADBDevTable[i].DataAreaAddr; - return 0; /* found */ - } - - return (-1); /* not found */ -} - -int -set_adb_info(ADBSetInfoBlock *info, int adbAddr) -{ - int i; - - if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */ - return (-1); - - for (i = 1; i < 15; i++) - if (ADBDevTable[i].currentAddr == adbAddr) { - ADBDevTable[i].ServiceRtPtr = - (void *)(info->siServiceRtPtr); - ADBDevTable[i].DataAreaAddr = info->siDataAreaAddr; - return 0; /* found */ - } - - return (-1); /* not found */ - -} - -/* caller should really use machine-independant version: getPramTime */ -/* this version does pseudo-adb access only */ -int -adb_read_date_time(unsigned long *time) -{ - u_char output[ADB_MAX_MSG_LENGTH]; - int result; - volatile int flag = 0; - - switch (adbHardware) { - case ADB_HW_II: - return -1; - - case ADB_HW_IISI: - output[0] = 0x02; /* 2 byte message */ - output[1] = 0x01; /* to pram/rtc device */ - output[2] = 0x03; /* read date/time */ - result = send_adb_IIsi((u_char *)output, (u_char *)output, - (void *)adb_op_comprout, (void *)&flag, (int)0); - if (result != 0) /* exit if not sent */ - return -1; - - while (0 == flag) /* wait for result */ - ; - - *time = (long)(*(long *)(output + 1)); - return 0; - - case ADB_HW_PB: - return -1; - - case ADB_HW_CUDA: - output[0] = 0x02; /* 2 byte message */ - output[1] = 0x01; /* to pram/rtc device */ - output[2] = 0x03; /* read date/time */ - result = send_adb_cuda((u_char *)output, (u_char *)output, - (void *)adb_op_comprout, (void *)&flag, (int)0); - if (result != 0) /* exit if not sent */ - return -1; - - while (0 == flag) /* wait for result */ - ; - - *time = (long)(*(long *)(output + 1)); - return 0; - - case ADB_HW_UNKNOWN: - default: - return -1; - } -} - -/* caller should really use machine-independant version: setPramTime */ -/* this version does pseudo-adb access only */ -int -adb_set_date_time(unsigned long time) -{ - u_char output[ADB_MAX_MSG_LENGTH]; - int result; - volatile int flag = 0; - - switch (adbHardware) { - case ADB_HW_II: - return -1; - - case ADB_HW_IISI: - output[0] = 0x06; /* 6 byte message */ - output[1] = 0x01; /* to pram/rtc device */ - output[2] = 0x09; /* set date/time */ - output[3] = (u_char)(time >> 24); - output[4] = (u_char)(time >> 16); - output[5] = (u_char)(time >> 8); - output[6] = (u_char)(time); - result = send_adb_IIsi((u_char *)output, (u_char *)0, - (void *)adb_op_comprout, (void *)&flag, (int)0); - if (result != 0) /* exit if not sent */ - return -1; - - while (0 == flag) /* wait for send to finish */ - ; - - return 0; - - case ADB_HW_PB: - return -1; - - case ADB_HW_CUDA: - output[0] = 0x06; /* 6 byte message */ - output[1] = 0x01; /* to pram/rtc device */ - output[2] = 0x09; /* set date/time */ - output[3] = (u_char)(time >> 24); - output[4] = (u_char)(time >> 16); - output[5] = (u_char)(time >> 8); - output[6] = (u_char)(time); - result = send_adb_cuda((u_char *)output, (u_char *)0, - (void *)adb_op_comprout, (void *)&flag, (int)0); - if (result != 0) /* exit if not sent */ - return -1; - - while (0 == flag) /* wait for send to finish */ - ; - - return 0; - - case ADB_HW_UNKNOWN: - default: - return -1; - } -} - - -int -adb_poweroff(void) -{ - u_char output[ADB_MAX_MSG_LENGTH]; - int result; - - if (!adbSoftPower) - return -1; - - adb_polling = 1; - - switch (adbHardware) { - case ADB_HW_IISI: - output[0] = 0x02; /* 2 byte message */ - output[1] = 0x01; /* to pram/rtc/soft-power device */ - output[2] = 0x0a; /* set date/time */ - result = send_adb_IIsi((u_char *)output, (u_char *)0, - (void *)0, (void *)0, (int)0); - if (result != 0) /* exit if not sent */ - return -1; - - for (;;); /* wait for power off */ - - return 0; - - case ADB_HW_PB: - return -1; - - case ADB_HW_CUDA: - output[0] = 0x02; /* 2 byte message */ - output[1] = 0x01; /* to pram/rtc/soft-power device */ - output[2] = 0x0a; /* set date/time */ - result = send_adb_cuda((u_char *)output, (u_char *)0, - (void *)0, (void *)0, (int)0); - if (result != 0) /* exit if not sent */ - return -1; - - for (;;); /* wait for power off */ - - return 0; - - case ADB_HW_II: /* II models don't do ADB soft power */ - case ADB_HW_UNKNOWN: - default: - return -1; - } -} - -int -adb_prog_switch_enable(void) -{ - u_char output[ADB_MAX_MSG_LENGTH]; - int result; - volatile int flag = 0; - - switch (adbHardware) { - case ADB_HW_IISI: - output[0] = 0x03; /* 3 byte message */ - output[1] = 0x01; /* to pram/rtc/soft-power device */ - output[2] = 0x1c; /* prog. switch control */ - output[3] = 0x01; /* enable */ - result = send_adb_IIsi((u_char *)output, (u_char *)0, - (void *)adb_op_comprout, (void *)&flag, (int)0); - if (result != 0) /* exit if not sent */ - return -1; - - while (0 == flag) /* wait for send to finish */ - ; - - return 0; - - case ADB_HW_PB: - return -1; - - case ADB_HW_II: /* II models don't do prog. switch */ - case ADB_HW_CUDA: /* cuda doesn't do prog. switch TO DO: verify this */ - case ADB_HW_UNKNOWN: - default: - return -1; - } -} - -int -adb_prog_switch_disable(void) -{ - u_char output[ADB_MAX_MSG_LENGTH]; - int result; - volatile int flag = 0; - - switch (adbHardware) { - case ADB_HW_IISI: - output[0] = 0x03; /* 3 byte message */ - output[1] = 0x01; /* to pram/rtc/soft-power device */ - output[2] = 0x1c; /* prog. switch control */ - output[3] = 0x01; /* disable */ - result = send_adb_IIsi((u_char *)output, (u_char *)0, - (void *)adb_op_comprout, (void *)&flag, (int)0); - if (result != 0) /* exit if not sent */ - return -1; - - while (0 == flag) /* wait for send to finish */ - ; - - return 0; - - case ADB_HW_PB: - return -1; - - case ADB_HW_II: /* II models don't do prog. switch */ - case ADB_HW_CUDA: /* cuda doesn't do prog. switch */ - case ADB_HW_UNKNOWN: - default: - return -1; - } -} - -int -CountADBs(void) -{ - return (count_adbs()); -} - -void -ADBReInit(void) -{ - adb_reinit(); -} - -int -GetIndADB(ADBDataBlock *info, int index) -{ - return (get_ind_adb_info(info, index)); -} - -int -GetADBInfo(ADBDataBlock *info, int adbAddr) -{ - return (get_adb_info(info, adbAddr)); -} - -int -SetADBInfo(ADBSetInfoBlock *info, int adbAddr) -{ - return (set_adb_info(info, adbAddr)); -} - -int -ADBOp(Ptr buffer, Ptr compRout, Ptr data, short commandNum) -{ - return (adb_op(buffer, compRout, data, commandNum)); -} diff --git a/sys/arch/mac68k/dev/adbvar.h b/sys/arch/mac68k/dev/adbvar.h index 60a681be10a..fb41204d969 100644 --- a/sys/arch/mac68k/dev/adbvar.h +++ b/sys/arch/mac68k/dev/adbvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: adbvar.h,v 1.11 2006/01/13 19:36:43 miod Exp $ */ +/* $OpenBSD: adbvar.h,v 1.12 2006/01/18 23:21:16 miod Exp $ */ /* $NetBSD: adbvar.h,v 1.22 2005/01/15 16:00:59 chs Exp $ */ /* @@ -31,34 +31,7 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <machine/adbsys.h> - -/* - * Arguments used to attach a device to the Apple Desktop Bus - */ -struct adb_attach_args { - int origaddr; - int adbaddr; - int handler_id; -}; - -extern int adb_polling; - -#ifdef DEBUG -#ifndef ADB_DEBUG -#define ADB_DEBUG -#endif -#endif - -#ifdef ADB_DEBUG -extern int adb_debug; -#endif - -typedef caddr_t Ptr; - -/* adb.c */ -int adb_op_sync(Ptr, Ptr, Ptr, short); -void adb_op_comprout(caddr_t, caddr_t, int); +extern int adbHardware; /* types of adb hardware that we support */ #define ADB_HW_UNKNOWN 0x0 /* don't know */ @@ -68,31 +41,6 @@ void adb_op_comprout(caddr_t, caddr_t, int); #define ADB_HW_CUDA 0x4 /* Machines with a Cuda chip */ #define MAX_ADB_HW 4 /* Number of ADB hardware types */ -#define ADB_CMDADDR(cmd) ((u_int8_t)(cmd & 0xf0) >> 4) -#define ADBFLUSH(dev) ((((u_int8_t)dev & 0x0f) << 4) | 0x01) -#define ADBLISTEN(dev, reg) ((((u_int8_t)dev & 0x0f) << 4) | 0x08 | reg) -#define ADBTALK(dev, reg) ((((u_int8_t)dev & 0x0f) << 4) | 0x0c | reg) - -/* ADB Manager */ -typedef struct { - Ptr siServiceRtPtr; - Ptr siDataAreaAddr; -} ADBSetInfoBlock; - -typedef struct { - unsigned char devType; - unsigned char origADBAddr; - Ptr dbServiceRtPtr; - Ptr dbDataAreaAddr; -} ADBDataBlock; - -/* adb_direct.c */ int adb_poweroff(void); -int CountADBs(void); -void ADBReInit(void); -int GetIndADB(ADBDataBlock *, int); -int GetADBInfo(ADBDataBlock *, int); -int SetADBInfo(ADBSetInfoBlock *, int); -int ADBOp(Ptr, Ptr, Ptr, short); int adb_read_date_time(unsigned long *); int adb_set_date_time(unsigned long); diff --git a/sys/arch/mac68k/dev/akbd.c b/sys/arch/mac68k/dev/akbd.c deleted file mode 100644 index aa778e2fd06..00000000000 --- a/sys/arch/mac68k/dev/akbd.c +++ /dev/null @@ -1,550 +0,0 @@ -/* $OpenBSD: akbd.c,v 1.6 2006/01/13 19:36:43 miod Exp $ */ -/* $NetBSD: akbd.c,v 1.17 2005/01/15 16:00:59 chs Exp $ */ - -/* - * Copyright (C) 1998 Colin Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Colin Wood. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/timeout.h> -#include <sys/kernel.h> -#include <sys/device.h> -#include <sys/fcntl.h> -#include <sys/poll.h> -#include <sys/selinfo.h> -#include <sys/proc.h> -#include <sys/signalvar.h> -#include <sys/systm.h> - -#include "wskbd.h" - -#include <dev/wscons/wsconsio.h> -#include <dev/wscons/wskbdvar.h> -#include <dev/wscons/wsksymdef.h> -#include <dev/wscons/wsksymvar.h> - -#include <machine/autoconf.h> -#include <machine/cpu.h> -#include <machine/viareg.h> - -#include <mac68k/dev/adbvar.h> -#include <mac68k/dev/akbdmap.h> -#include <mac68k/dev/akbdvar.h> - -#define KEYBOARD_ARRAY -#include <machine/keyboard.h> - -/* - * Function declarations. - */ -int akbdmatch(struct device *, void *, void *); -void akbdattach(struct device *, struct device *, void *); -void kbd_adbcomplete(caddr_t, caddr_t, int); -void kbd_processevent(adb_event_t *, struct akbd_softc *); -int akbd_is_console(void); - -/* Driver definition. */ -struct cfattach akbd_ca = { - sizeof(struct akbd_softc), akbdmatch, akbdattach -}; -struct cfdriver akbd_cd = { - NULL, "akbd", DV_DULL -}; - -int akbd_enable(void *, int); -void akbd_set_leds(void *, int); -int akbd_ioctl(void *, u_long, caddr_t, int, struct proc *); -int akbd_intr(adb_event_t *, struct akbd_softc *); -void akbd_rawrepeat(void *v); - - -struct wskbd_accessops akbd_accessops = { - akbd_enable, - akbd_set_leds, - akbd_ioctl, -}; - -struct wskbd_mapdata akbd_keymapdata = { - akbd_keydesctab, -#ifdef AKBD_LAYOUT - AKBD_LAYOUT, -#else - KB_US, -#endif -}; - -int -akbdmatch(struct device *parent, void *vcf, void *aux) -{ - struct adb_attach_args *aa_args = (struct adb_attach_args *)aux; - - if (aa_args->origaddr == ADBADDR_KBD) - return 1; - else - return 0; -} - -void -akbdattach(struct device *parent, struct device *self, void *aux) -{ - ADBSetInfoBlock adbinfo; - struct akbd_softc *sc = (struct akbd_softc *)self; - struct adb_attach_args *aa_args = (struct adb_attach_args *)aux; - int error, kbd_done; - short cmd; - u_char buffer[9]; -#if NWSKBD > 0 - struct wskbddev_attach_args a; - static int akbd_console_initted; - int wskbd_eligible; - - wskbd_eligible = 1; -#endif - - sc->origaddr = aa_args->origaddr; - sc->adbaddr = aa_args->adbaddr; - sc->handler_id = aa_args->handler_id; - - sc->sc_leds = (u_int8_t)0x00; /* initially off */ - - adbinfo.siServiceRtPtr = (Ptr)kbd_adbcomplete; - adbinfo.siDataAreaAddr = (caddr_t)sc; - - printf(": "); - switch (sc->handler_id) { - case ADB_STDKBD: - printf("standard keyboard\n"); - break; - case ADB_ISOKBD: - printf("standard keyboard (ISO layout)\n"); - break; - case ADB_EXTKBD: - cmd = ADBTALK(sc->adbaddr, 1); - kbd_done = - (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0); - - /* Ignore Logitech MouseMan/Trackman pseudo keyboard */ - if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x20) { - printf("Mouseman (non-EMP) pseudo keyboard\n"); - adbinfo.siServiceRtPtr = (Ptr)0; - adbinfo.siDataAreaAddr = (Ptr)0; -#if NWSKBD > 0 - wskbd_eligible = 0; -#endif /* NWSKBD > 0 */ - } else if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x21) { - printf("Trackman (non-EMP) pseudo keyboard\n"); - adbinfo.siServiceRtPtr = (Ptr)0; - adbinfo.siDataAreaAddr = (Ptr)0; -#if NWSKBD > 0 - wskbd_eligible = 0; -#endif /* NWSKBD > 0 */ - } else { - printf("extended keyboard\n"); -#ifdef notyet - blinkleds(sc); -#endif - } - break; - case ADB_EXTISOKBD: - printf("extended keyboard (ISO layout)\n"); -#ifdef notyet - blinkleds(sc); -#endif - break; - case ADB_KBDII: - printf("keyboard II\n"); - break; - case ADB_ISOKBDII: - printf("keyboard II (ISO layout)\n"); - break; - case ADB_PBKBD: - printf("PowerBook keyboard\n"); - break; - case ADB_PBISOKBD: - printf("PowerBook keyboard (ISO layout)\n"); - break; - case ADB_ADJKPD: - printf("adjustable keypad\n"); -#if NWSKBD > 0 - wskbd_eligible = 0; -#endif /* NWSKBD > 0 */ - break; - case ADB_ADJKBD: - printf("adjustable keyboard\n"); - break; - case ADB_ADJISOKBD: - printf("adjustable keyboard (ISO layout)\n"); - break; - case ADB_ADJJAPKBD: - printf("adjustable keyboard (Japanese layout)\n"); - break; - case ADB_PBEXTISOKBD: - printf("PowerBook extended keyboard (ISO layout)\n"); - break; - case ADB_PBEXTJAPKBD: - printf("PowerBook extended keyboard (Japanese layout)\n"); - break; - case ADB_JPKBDII: - printf("keyboard II (Japanese layout)\n"); - break; - case ADB_PBEXTKBD: - printf("PowerBook extended keyboard\n"); - break; - case ADB_DESIGNKBD: - printf("extended keyboard\n"); -#ifdef notyet - blinkleds(sc); -#endif - break; - case ADB_PBJPKBD: - printf("PowerBook keyboard (Japanese layout)\n"); - break; - case ADB_PBG3JPKBD: - printf("PowerBook G3 keyboard (Japanese layout)\n"); - break; - case ADB_PBG4KBD: - printf("PowerBook G4 keyboard (Inverted T)\n"); - break; - case ADB_IBITISOKBD: - printf("iBook keyboard with inverted T (ISO layout)\n"); - break; - default: - printf("mapped device (%d)\n", sc->handler_id); -#if NWSKBD > 0 - wskbd_eligible = 0; -#endif /* NWSKBD > 0 */ - break; - } - error = SetADBInfo(&adbinfo, sc->adbaddr); -#ifdef ADB_DEBUG - if (adb_debug) - printf("akbd: returned %d from SetADBInfo\n", error); -#endif - -#ifdef WSDISPLAY_COMPAT_RAWKBD - timeout_set(&sc->sc_rawrepeat_ch, akbd_rawrepeat, sc); -#endif - -#if NWSKBD > 0 - if (akbd_is_console() && wskbd_eligible) - a.console = (++akbd_console_initted == 1); - else - a.console = 0; - a.keymap = &akbd_keymapdata; - a.accessops = &akbd_accessops; - a.accesscookie = sc; - - sc->sc_wskbddev = config_found(self, &a, wskbddevprint); -#endif -} - - -/* - * Handle putting the keyboard data received from the ADB into - * an ADB event record. - */ -void -kbd_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command) -{ - adb_event_t event; - struct akbd_softc *ksc; - int adbaddr; -#ifdef ADB_DEBUG - int i; - - if (adb_debug) - printf("adb: transaction completion\n"); -#endif - - adbaddr = ADB_CMDADDR(adb_command); - ksc = (struct akbd_softc *)data_area; - - event.addr = adbaddr; - event.hand_id = ksc->handler_id; - event.def_addr = ksc->origaddr; - event.byte_count = buffer[0]; - memcpy(event.bytes, buffer + 1, event.byte_count); - -#ifdef ADB_DEBUG - if (adb_debug) { - printf("akbd: from %d at %d (org %d) %d:", event.addr, - event.hand_id, event.def_addr, buffer[0]); - for (i = 1; i <= buffer[0]; i++) - printf(" %x", buffer[i]); - printf("\n"); - } -#endif - - microtime(&event.timestamp); - - kbd_processevent(&event, ksc); -} - -/* - * Given a keyboard ADB event, record the keycodes and call the key - * repeat handler, optionally passing the event through the mouse - * button emulation handler first. - */ -void -kbd_processevent(adb_event_t *event, struct akbd_softc *ksc) -{ - adb_event_t new_event; - - new_event = *event; - new_event.u.k.key = event->bytes[0]; - new_event.bytes[1] = 0xff; -#if NWSKBD > 0 - if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */ - akbd_intr(&new_event, ksc); -#endif - if (event->bytes[1] != 0xff) { - new_event.u.k.key = event->bytes[1]; - new_event.bytes[0] = event->bytes[1]; - new_event.bytes[1] = 0xff; -#if NWSKBD > 0 - if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */ - akbd_intr(&new_event, ksc); -#endif - } - -} - -int -akbd_enable(void *v, int on) -{ - return 0; -} - -void -akbd_set_leds(void *v, int on) -{ -} - -int -akbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) -{ -#ifdef WSDISPLAY_COMPAT_RAWKBD - struct akbd_softc *sc = v; -#endif - - switch (cmd) { - - case WSKBDIO_GTYPE: - *(int *)data = WSKBD_TYPE_ADB; - return 0; - case WSKBDIO_SETLEDS: - return 0; - case WSKBDIO_GETLEDS: - *(int *)data = 0; - return 0; -#ifdef WSDISPLAY_COMPAT_RAWKBD - case WSKBDIO_SETMODE: - sc->sc_rawkbd = *(int *)data == WSKBD_RAW; - timeout_del(&sc->sc_rawrepeat_ch); - return (0); -#endif - case WSKBDIO_BELL: - case WSKBDIO_COMPLEXBELL: -#define d ((struct wskbd_bell_data *)data) - mac68k_ring_bell(d->pitch, d->period * hz / 1000, d->volume); -#undef d - return (0); - - default: - return (-1); - } -} - -#ifdef WSDISPLAY_COMPAT_RAWKBD -void -akbd_rawrepeat(void *v) -{ - struct akbd_softc *sc = v; - int s; - - s = spltty(); - wskbd_rawinput(sc->sc_wskbddev, sc->sc_rep, sc->sc_nrep); - splx(s); - timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAYN / 1000); -} -#endif - -int adb_polledkey; -int -akbd_intr(adb_event_t *event, struct akbd_softc *sc) -{ - int key, press, val; - int type; - static int shift; - - key = event->u.k.key; - - /* - * Caps lock is weird. The key sequence generated is: - * press: down(57) [57] (LED turns on) - * release: up(127) [255] - * press: up(127) [255] - * release: up(57) [185] (LED turns off) - */ - if (ADBK_KEYVAL(key) == ADBK_CAPSLOCK) - shift = 0; - - if (key == 255) { - if (shift == 0) { - key = ADBK_KEYUP(ADBK_CAPSLOCK); - shift = 1; - } else { - key = ADBK_KEYDOWN(ADBK_CAPSLOCK); - shift = 0; - } - } - - press = ADBK_PRESS(key); - val = ADBK_KEYVAL(key); - - type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; - - if (adb_polling) { - adb_polledkey = key; -#ifdef WSDISPLAY_COMPAT_RAWKBD - } else if (sc->sc_rawkbd) { - char cbuf[MAXKEYS *2]; - int c, j, s; - int npress; - - j = npress = 0; - - c = keyboard[val][3]; - if (c == 0) { - return 0; /* XXX */ - } - if (c & 0x80) - cbuf[j++] = 0xe0; - cbuf[j] = c & 0x7f; - if (type == WSCONS_EVENT_KEY_UP) { - cbuf[j] |= 0x80; - } else { - /* this only records last key pressed */ - if (c & 0x80) - sc->sc_rep[npress++] = 0xe0; - sc->sc_rep[npress++] = c & 0x7f; - } - j++; - s = spltty(); - wskbd_rawinput(sc->sc_wskbddev, cbuf, j); - splx(s); - timeout_del(&sc->sc_rawrepeat_ch); - sc->sc_nrep = npress; - if (npress != 0) - timeout_add(&sc->sc_rawrepeat_ch, hz * REP_DELAY1/1000); - return 0; -#endif - } else { - wskbd_input(sc->sc_wskbddev, type, val); - } - - return 0; -} - -int -akbd_is_console(void) -{ - extern struct mac68k_machine_S mac68k_machine; - - return ((mac68k_machine.serial_console & 0x03) == 0); -} - -void akbd_cnbell(void *, u_int, u_int, u_int); -void akbd_cngetc(void *, u_int *, int *); -void akbd_cnpollc(void *, int); - -struct wskbd_consops akbd_consops = { - akbd_cngetc, - akbd_cnpollc, - akbd_cnbell -}; - -int -akbd_cnattach(void) -{ - extern struct wskbd_mapdata akbd_keymapdata; - - wskbd_cnattach(&akbd_consops, NULL, &akbd_keymapdata); - - return 0; -} - -void -akbd_cngetc(void *v, u_int *type, int *data) -{ - int intbits, key, press, val; - int s; - extern int adb_polledkey; - extern int adb_intr(void *); - extern void pm_intr(void *); - - s = splhigh(); - - adb_polledkey = -1; - adb_polling = 1; - - while (adb_polledkey == -1) { - intbits = via_reg(VIA1, vIFR); - - if (intbits & V1IF_ADBRDY) { - adb_intr(NULL); - via_reg(VIA1, vIFR) = V1IF_ADBRDY; - } - if (intbits & 0x10) { - pm_intr(NULL); - via_reg(VIA1, vIFR) = 0x10; - } - } - - adb_polling = 0; - splx(s); - - key = adb_polledkey; - press = ADBK_PRESS(key); - val = ADBK_KEYVAL(key); - - *data = val; - *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; -} - -void -akbd_cnpollc(void *v, int on) -{ -} - -void -akbd_cnbell(void *v, u_int pitch, u_int period, u_int volume) -{ - mac68k_ring_bell(pitch, period * hz / 1000, volume); -} diff --git a/sys/arch/mac68k/dev/akbd_machdep.c b/sys/arch/mac68k/dev/akbd_machdep.c new file mode 100644 index 00000000000..2d8e588bbc0 --- /dev/null +++ b/sys/arch/mac68k/dev/akbd_machdep.c @@ -0,0 +1,136 @@ +/* $OpenBSD: akbd_machdep.c,v 1.1 2006/01/18 23:21:17 miod Exp $ */ +/* $NetBSD: akbd.c,v 1.17 2005/01/15 16:00:59 chs Exp $ */ + +/* + * Copyright (C) 1998 Colin Wood + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Colin Wood. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/timeout.h> +#include <sys/kernel.h> +#include <sys/device.h> +#include <sys/fcntl.h> +#include <sys/poll.h> +#include <sys/selinfo.h> +#include <sys/proc.h> +#include <sys/signalvar.h> +#include <sys/systm.h> + +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wskbdvar.h> + +#include <machine/cpu.h> +#include <machine/viareg.h> + +#include <dev/adb/adb.h> +#include <dev/adb/akbdvar.h> +#include <dev/adb/keyboard.h> + +#if 0 + case WSKBDIO_BELL: + case WSKBDIO_COMPLEXBELL: +#define d ((struct wskbd_bell_data *)data) + mac68k_ring_bell(d->pitch, d->period * hz / 1000, d->volume); +#undef d + return (0); + + default: + return (-1); +#endif + +void akbd_cnbell(void *, u_int, u_int, u_int); +void akbd_cngetc(void *, u_int *, int *); +void akbd_cnpollc(void *, int); + +struct wskbd_consops akbd_consops = { + akbd_cngetc, + akbd_cnpollc, + akbd_cnbell +}; + +int +akbd_is_console(void) +{ + return ((mac68k_machine.serial_console & 0x03) == 0); +} + +int +akbd_cnattach(void) +{ + wskbd_cnattach(&akbd_consops, NULL, &akbd_keymapdata); + return 0; +} + +void +akbd_cngetc(void *v, u_int *type, int *data) +{ + int intbits, key, press, val; + int s; + extern int adb_intr(void *); + extern void pm_intr(void *); + + s = splhigh(); + + adb_polledkey = -1; + adb_polling = 1; + + while (adb_polledkey == -1) { + intbits = via_reg(VIA1, vIFR); + + if (intbits & V1IF_ADBRDY) { + adb_intr(NULL); + via_reg(VIA1, vIFR) = V1IF_ADBRDY; + } + if (intbits & V1IF_ADBCLK) { + pm_intr(NULL); + via_reg(VIA1, vIFR) = 0x10; + } + } + + adb_polling = 0; + splx(s); + + key = adb_polledkey; + press = ADBK_PRESS(key); + val = ADBK_KEYVAL(key); + + *data = val; + *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; +} + +void +akbd_cnpollc(void *v, int on) +{ +} + +void +akbd_cnbell(void *v, u_int pitch, u_int period, u_int volume) +{ + mac68k_ring_bell(pitch, period * hz / 1000, volume); +} diff --git a/sys/arch/mac68k/dev/pm_direct.c b/sys/arch/mac68k/dev/pm_direct.c index 752200cf96a..84357747750 100644 --- a/sys/arch/mac68k/dev/pm_direct.c +++ b/sys/arch/mac68k/dev/pm_direct.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pm_direct.c,v 1.10 2006/01/13 19:36:44 miod Exp $ */ +/* $OpenBSD: pm_direct.c,v 1.11 2006/01/18 23:21:17 miod Exp $ */ /* $NetBSD: pm_direct.c,v 1.25 2005/10/28 21:54:52 christos Exp $ */ /* @@ -46,6 +46,7 @@ #include <machine/cpu.h> #include <machine/viareg.h> +#include <dev/adb/adb.h> #include <mac68k/dev/adbvar.h> #include <mac68k/dev/pm_direct.h> diff --git a/sys/arch/mac68k/include/adbsys.h b/sys/arch/mac68k/include/adbsys.h deleted file mode 100644 index 8b7b71f4ab9..00000000000 --- a/sys/arch/mac68k/include/adbsys.h +++ /dev/null @@ -1,116 +0,0 @@ -/* $OpenBSD: adbsys.h,v 1.9 2006/01/04 20:39:05 miod Exp $ */ -/* $NetBSD: adbsys.h,v 1.13 2000/02/14 07:01:48 scottr Exp $ */ - -/*- - * Copyright (C) 1993, 1994 Allen K. Briggs, Chris P. Caputo, - * Michael L. Finch, Bradley A. Grantham, and - * Lawrence A. Kesteloot - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the Alice Group. - * 4. The names of the Alice Group or any of its members may not be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _ADBSYS_MACHINE_ -#define _ADBSYS_MACHINE_ - -/* an ADB event */ -typedef struct adb_event_s { - int addr; /* device address */ - int hand_id; /* handler id */ - int def_addr; /* default address */ - int byte_count; /* number of bytes */ - unsigned char bytes[8]; /* bytes from register 0 */ - struct timeval timestamp; /* time event was acquired */ - union { - struct adb_keydata_s { - int key; /* ADB key code */ - } k; - struct adb_mousedata_s { - int dx; /* mouse delta x */ - int dy; /* mouse delta y */ - int buttons; /* buttons (down << (buttonnum)) */ - } m; - } u; /* courtesy interpretation */ -} adb_event_t; - - /* Interesting default addresses */ -#define ADBADDR_SECURE 1 /* Security dongles */ -#define ADBADDR_MAP 2 /* Mapped devices (keyboards/pads) */ -#define ADBADDR_REL 3 /* Relative positioning devices - (mice, trackballs/pads) */ -#define ADBADDR_ABS 4 /* Absolute positioning devices - (graphics tablets) */ -#define ADBADDR_DATATX 5 -#define ADBADDR_RSRVD 6 /* Reserved by Apple */ -#define ADBADDR_MISC 7 /* Miscellaneous appliances */ -#define ADBADDR_DONGLE ADBADDR_SECURE -#define ADBADDR_KBD ADBADDR_MAP -#define ADBADDR_MS ADBADDR_REL -#define ADBADDR_TABLET ADBADDR_ABS -#define ADBADDR_MODEM ADBADDR_DATATX - - - /* Interesting keyboard handler IDs */ -#define ADB_STDKBD 1 -#define ADB_EXTKBD 2 -#define ADB_ISOKBD 4 -#define ADB_EXTISOKBD 5 -#define ADB_KBDII 8 -#define ADB_ISOKBDII 9 -#define ADB_PBKBD 12 -#define ADB_PBISOKBD 13 -#define ADB_ADJKPD 14 -#define ADB_ADJKBD 16 -#define ADB_ADJISOKBD 17 -#define ADB_ADJJAPKBD 18 -#define ADB_PBEXTISOKBD 20 -#define ADB_PBEXTJAPKBD 21 -#define ADB_JPKBDII 22 -#define ADB_PBEXTKBD 24 -#define ADB_DESIGNKBD 27 /* XXX Needs to be verified XXX */ -#define ADB_PBJPKBD 30 -#define ADB_PBG4KBD 195 -#define ADB_IBITISOKBD 196 -#define ADB_PBG3JPKBD 201 - - /* Interesting mouse handler IDs */ -#define ADBMS_100DPI 1 -#define ADBMS_200DPI 2 -#define ADBMS_MSA3 3 /* Mouse Systems A3 Mouse */ -#define ADBMS_EXTENDED 4 /* Extended mouse protocol */ -#define ADBMS_USPEED 0x2f /* MicroSpeed mouse */ -#define ADBMS_UCONTOUR 0x66 /* Contour mouse */ -#define ADBMS_TURBO 50 /* Kensington Turbo Mouse */ - - /* Interesting tablet handler ID */ -#define ADB_ARTPAD 58 /* WACOM ArtPad II tablet */ - - /* Interesting miscellaneous handler ID */ -#define ADB_POWERKEY 34 /* Sophisticated Circuits PowerKey */ - /* (intelligent power tap) */ - -#endif /* _ADBSYS_MACHINE_ */ diff --git a/sys/arch/mac68k/mac68k/autoconf.c b/sys/arch/mac68k/mac68k/autoconf.c index b37052af328..3cd0121984b 100644 --- a/sys/arch/mac68k/mac68k/autoconf.c +++ b/sys/arch/mac68k/mac68k/autoconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: autoconf.c,v 1.24 2006/01/13 19:36:45 miod Exp $ */ +/* $OpenBSD: autoconf.c,v 1.25 2006/01/18 23:21:17 miod Exp $ */ /* $NetBSD: autoconf.c,v 1.38 1996/12/18 05:46:09 scottr Exp $ */ /* @@ -62,7 +62,6 @@ #include <dev/cons.h> #include <machine/autoconf.h> -#include <machine/adbsys.h> #include <machine/viareg.h> #include <scsi/scsi_all.h> @@ -92,7 +91,7 @@ static struct device fakerdrootdev = { DV_DISK, {}, NULL, 0, "rd0", NULL }; void cpu_configure() { - startrtclock(); /* start before adb_init() */ + startrtclock(); if (config_rootfound("mainbus", "mainbus") == NULL) panic("No mainbus found!"); diff --git a/sys/arch/mac68k/mac68k/pram.c b/sys/arch/mac68k/mac68k/pram.c index 71cc0d45e36..65cf35b6183 100644 --- a/sys/arch/mac68k/mac68k/pram.c +++ b/sys/arch/mac68k/mac68k/pram.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pram.c,v 1.10 2006/01/13 21:02:38 miod Exp $ */ +/* $OpenBSD: pram.c,v 1.11 2006/01/18 23:21:17 miod Exp $ */ /* $NetBSD: pram.c,v 1.11 1996/10/21 05:42:29 scottr Exp $ */ /*- @@ -40,8 +40,6 @@ #include <mac68k/mac68k/pram.h> #include <mac68k/dev/adbvar.h> -extern int adbHardware; /* from adb.c */ - /* * getPramTime * This function can be called regrardless of the machine diff --git a/sys/arch/mac68k/mac68k/wscons_machdep.c b/sys/arch/mac68k/mac68k/wscons_machdep.c index 263c1bb1ff6..1d8b442f829 100644 --- a/sys/arch/mac68k/mac68k/wscons_machdep.c +++ b/sys/arch/mac68k/mac68k/wscons_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: wscons_machdep.c,v 1.4 2006/01/10 21:19:15 miod Exp $ */ +/* $OpenBSD: wscons_machdep.c,v 1.5 2006/01/18 23:21:17 miod Exp $ */ /* $NetBSD: maccons.c,v 1.5 2005/01/15 16:00:59 chs Exp $ */ /* @@ -45,7 +45,7 @@ #include <mac68k/dev/nubus.h> #include <mac68k/dev/macfbvar.h> -#include <mac68k/dev/akbdvar.h> +#include <dev/adb/akbdvar.h> #include "wsdisplay.h" #include "wskbd.h" diff --git a/sys/arch/macppc/conf/files.macppc b/sys/arch/macppc/conf/files.macppc index b6008874578..1e4e73185e9 100644 --- a/sys/arch/macppc/conf/files.macppc +++ b/sys/arch/macppc/conf/files.macppc @@ -1,4 +1,4 @@ -# $OpenBSD: files.macppc,v 1.45 2006/01/03 17:23:19 xsa Exp $ +# $OpenBSD: files.macppc,v 1.46 2006/01/18 23:21:17 miod Exp $ # # macppc-specific configuration info @@ -156,21 +156,15 @@ file arch/macppc/dev/z8530tty.c zstty needs-flag device adb {} attach adb at macobio file arch/macppc/dev/adb.c adb needs-flag -file arch/macppc/dev/adb_direct.c adb file arch/macppc/dev/pm_direct.c adb +include "dev/adb/files.adb" +file arch/macppc/dev/akbd_machdep.c akbd + device apm attach apm at adb file arch/macppc/dev/apm.c apm needs-count -device akbd: wskbddev -attach akbd at adb -file arch/macppc/dev/akbd.c akbd needs-flag - -device ams: wsmousedev -attach ams at adb -file arch/macppc/dev/ams.c ams - device abtn attach abtn at adb file arch/macppc/dev/abtn.c abtn diff --git a/sys/arch/macppc/dev/abtn.c b/sys/arch/macppc/dev/abtn.c index 3672bfbab44..37e0c77dc70 100644 --- a/sys/arch/macppc/dev/abtn.c +++ b/sys/arch/macppc/dev/abtn.c @@ -1,4 +1,4 @@ -/* $OpenBSD: abtn.c,v 1.10 2006/01/08 17:25:05 miod Exp $ */ +/* $OpenBSD: abtn.c,v 1.11 2006/01/18 23:21:17 miod Exp $ */ /* $NetBSD: abtn.c,v 1.1 1999/07/12 17:48:26 tsubai Exp $ */ /*- @@ -37,7 +37,7 @@ #include <dev/ofw/openfirm.h> #include <macppc/macppc/ofw_machdep.h> -#include <macppc/dev/adbvar.h> +#include <dev/adb/adb.h> #define ABTN_HANDLER_ID 31 @@ -88,7 +88,7 @@ abtn_attach(struct device *parent, struct device *self, void *aux) adbinfo.siServiceRtPtr = (Ptr)abtn_adbcomplete; adbinfo.siDataAreaAddr = (caddr_t)sc; - SetADBInfo(&adbinfo, sc->adbaddr); + set_adb_info(&adbinfo, sc->adbaddr); } void diff --git a/sys/arch/macppc/dev/adb.c b/sys/arch/macppc/dev/adb.c index d006ac09f76..a192399da4b 100644 --- a/sys/arch/macppc/dev/adb.c +++ b/sys/arch/macppc/dev/adb.c @@ -1,5 +1,36 @@ -/* $OpenBSD: adb.c,v 1.17 2006/01/08 17:25:05 miod Exp $ */ +/* $OpenBSD: adb.c,v 1.18 2006/01/18 23:21:17 miod Exp $ */ /* $NetBSD: adb.c,v 1.6 1999/08/16 06:28:09 tsubai Exp $ */ +/* $NetBSD: adb_direct.c,v 1.14 2000/06/08 22:10:45 tsubai Exp $ */ + +/* + * Copyright (C) 1996, 1997 John P. Wittkoski + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by John P. Wittkoski. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ /*- * Copyright (C) 1994 Bradley A. Grantham @@ -31,6 +62,33 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +/* + * This code is rather messy, but I don't have time right now + * to clean it up as much as I would like. + * But it works, so I'm happy. :-) jpw + */ + +/* + * TO DO: + * - We could reduce the time spent in the adb_intr_* routines + * by having them save the incoming and outgoing data directly + * in the adbInbound and adbOutbound queues, as it would reduce + * the number of times we need to copy the data around. It + * would also make the code more readable and easier to follow. + * - (Related to above) Use the header part of adbCommand to + * reduce the number of copies we have to do of the data. + * - (Related to above) Actually implement the adbOutbound queue. + * This is fairly easy once you switch all the intr routines + * over to using adbCommand structs directly. + * - There is a bug in the state machine of adb_intr_cuda + * code that causes hangs, especially on 030 machines, probably + * because of some timing issues. Because I have been unable to + * determine the exact cause of this bug, I used the timeout function + * to check for and recover from this condition. If anyone finds + * the actual cause of this bug, the calls to timeout and the + * adb_cuda_tickle routine can be removed. + */ + #include <sys/param.h> #include <sys/device.h> #include <sys/fcntl.h> @@ -38,41 +96,1510 @@ #include <sys/selinfo.h> #include <sys/proc.h> #include <sys/signalvar.h> +#include <sys/timeout.h> #include <sys/systm.h> #include <machine/autoconf.h> +#include <machine/cpu.h> #include <dev/ofw/openfirm.h> +#include <dev/adb/adb.h> #include <macppc/dev/adbvar.h> -#include <macppc/dev/akbdvar.h> +#include <macppc/dev/pm_direct.h> #include <macppc/dev/viareg.h> #include "apm.h" +#define printf_intr printf + +#ifdef DEBUG +#ifndef ADB_DEBUG +#define ADB_DEBUG +#endif +#endif + +int adb_polling; /* Are we polling? (Debugger mode) */ +#ifdef ADB_DEBUG +int adb_debug; /* Output debugging messages */ +#endif /* ADB_DEBUG */ + +/* some misc. leftovers */ +#define vPB 0x0000 +#define vPB3 0x08 +#define vPB4 0x10 +#define vPB5 0x20 +#define vSR_INT 0x04 +#define vSR_OUT 0x10 + +/* the type of ADB action that we are currently performing */ +#define ADB_ACTION_NOTREADY 0x1 /* has not been initialized yet */ +#define ADB_ACTION_IDLE 0x2 /* the bus is currently idle */ +#define ADB_ACTION_OUT 0x3 /* sending out a command */ +#define ADB_ACTION_IN 0x4 /* receiving data */ + /* - * Function declarations. + * Shortcuts for setting or testing the VIA bit states. + * Not all shortcuts are used for every type of ADB hardware. */ -int adbmatch(struct device *, void *, void *); -void adbattach(struct device *, struct device *, void *); -int adbprint(void *, const char *); +#define ADB_SET_STATE_IDLE_CUDA() via_reg_or(VIA1, vBufB, (vPB4 | vPB5)) +#define ADB_SET_STATE_TIP() via_reg_and(VIA1, vBufB, ~vPB5) +#define ADB_CLR_STATE_TIP() via_reg_or(VIA1, vBufB, vPB5) +#define ADB_TOGGLE_STATE_ACK_CUDA() via_reg_xor(VIA1, vBufB, vPB4) +#define ADB_SET_STATE_ACKOFF_CUDA() via_reg_or(VIA1, vBufB, vPB4) +#define ADB_SET_SR_INPUT() via_reg_and(VIA1, vACR, ~vSR_OUT) +#define ADB_SET_SR_OUTPUT() via_reg_or(VIA1, vACR, vSR_OUT) +#define ADB_SR() read_via_reg(VIA1, vSR) +#define ADB_VIA_INTR_ENABLE() write_via_reg(VIA1, vIER, 0x84) +#define ADB_VIA_INTR_DISABLE() write_via_reg(VIA1, vIER, 0x04) +#define ADB_VIA_CLR_INTR() write_via_reg(VIA1, vIFR, 0x04) +#define ADB_INTR_IS_OFF (vPB3 == (read_via_reg(VIA1, vBufB) & vPB3)) +#define ADB_INTR_IS_ON (0 == (read_via_reg(VIA1, vBufB) & vPB3)) +#define ADB_SR_INTR_IS_ON (vSR_INT == (read_via_reg(VIA1, \ + vIFR) & vSR_INT)) /* - * Global variables. + * This is the delay that is required (in uS) between certain + * ADB transactions. The actual timing delay for for each uS is + * calculated at boot time to account for differences in machine speed. + */ +#define ADB_DELAY 150 + +/* + * Maximum ADB message length; includes space for data, result, and + * device code - plus a little for safety. + */ +#define ADB_MAX_MSG_LENGTH 16 +#define ADB_MAX_HDR_LENGTH 8 + +#define ADB_QUEUE 32 +#define ADB_TICKLE_TICKS 4 + +/* + * A structure for storing information about each ADB device. + */ +struct ADBDevEntry { + void (*ServiceRtPtr)(void); + void *DataAreaAddr; + int devType; + int origAddr; + int currentAddr; +}; + +/* + * Used to hold ADB commands that are waiting to be sent out. + */ +struct adbCmdHoldEntry { + u_char outBuf[ADB_MAX_MSG_LENGTH]; /* our message */ + u_char *saveBuf; /* buffer to know where to save result */ + u_char *compRout; /* completion routine pointer */ + u_char *data; /* completion routine data pointer */ +}; + +/* + * Eventually used for two separate queues, the queue between + * the upper and lower halves, and the outgoing packet queue. + * TO DO: adbCommand can replace all of adbCmdHoldEntry eventually + */ +struct adbCommand { + u_char header[ADB_MAX_HDR_LENGTH]; /* not used yet */ + u_char data[ADB_MAX_MSG_LENGTH]; /* packet data only */ + u_char *saveBuf; /* where to save result */ + u_char *compRout; /* completion routine pointer */ + u_char *compData; /* completion routine data pointer */ + u_int cmd; /* the original command for this data */ + u_int unsol; /* 1 if packet was unsolicited */ + u_int ack_only; /* 1 for no special processing */ +}; + +/* + * A few variables that we need and their initial values. + */ +int adbHardware = ADB_HW_UNKNOWN; +int adbActionState = ADB_ACTION_NOTREADY; +int adbWaiting = 0; /* waiting for return data from the device */ +int adbWriteDelay = 0; /* working on (or waiting to do) a write */ +int adbSoftPower = 0; /* machine supports soft power */ + +int adbWaitingCmd = 0; /* ADB command we are waiting for */ +u_char *adbBuffer = (long)0; /* pointer to user data area */ +void *adbCompRout = (long)0; /* pointer to the completion routine */ +void *adbCompData = (long)0; /* pointer to the completion routine data */ +int adbStarting = 1; /* doing adb_reinit so do polling differently */ + +u_char adbInputBuffer[ADB_MAX_MSG_LENGTH]; /* data input buffer */ +u_char adbOutputBuffer[ADB_MAX_MSG_LENGTH]; /* data output buffer */ +struct adbCmdHoldEntry adbOutQueue; /* our 1 entry output queue */ + +int adbSentChars = 0; /* how many characters we have sent */ + +struct ADBDevEntry ADBDevTable[16]; /* our ADB device table */ +int ADBNumDevices; /* num. of ADB devices found with adb_reinit */ + +struct adbCommand adbInbound[ADB_QUEUE]; /* incoming queue */ +int adbInCount = 0; /* how many packets in in queue */ +int adbInHead = 0; /* head of in queue */ +int adbInTail = 0; /* tail of in queue */ +struct adbCommand adbOutbound[ADB_QUEUE]; /* outgoing queue - not used yet */ +int adbOutCount = 0; /* how many packets in out queue */ +int adbOutHead = 0; /* head of out queue */ +int adbOutTail = 0; /* tail of out queue */ + +int tickle_count = 0; /* how many tickles seen for this packet? */ +int tickle_serial = 0; /* the last packet tickled */ +int adb_cuda_serial = 0; /* the current packet */ +struct timeout adb_cuda_timeout; +struct timeout adb_softintr_timeout; + +volatile u_char *Via1Base; + +/* + * The following are private routines. */ -int adb_polling; /* Are we polling? (Debugger mode) */ #ifdef ADB_DEBUG -int adb_debug; /* Output debugging messages */ -#endif /* ADB_DEBUG */ +void print_single(u_char *); +#endif +void adb_intr_cuda(void); +void adb_soft_intr(void); +int send_adb_cuda(u_char *, u_char *, void *, void *, int); +void adb_cuda_tickle(void); +void adb_pass_up(struct adbCommand *); +void adb_op_comprout(caddr_t, caddr_t, int); +void adb_reinit(void); +int count_adbs(void); +int get_ind_adb_info(ADBDataBlock *, int); +int get_adb_info(ADBDataBlock *, int); +int set_adb_info(ADBSetInfoBlock *, int); +void adb_setup_hw_type(void); +int adb_op(Ptr, Ptr, Ptr, short); +void adb_hw_setup(void); +int adb_cmd_result(u_char *); +void setsoftadb(void); + +int adb_intr(void *arg); +void adb_cuda_autopoll(void); + +#ifdef ADB_DEBUG +/* + * print_single + * Diagnostic display routine. Displays the hex values of the + * specified elements of the u_char. The length of the "string" + * is in [0]. + */ +void +print_single(str) + u_char *str; +{ + int x; + + if (str == 0) { + printf_intr("no data - null pointer\n"); + return; + } + if (*str == 0) { + printf_intr("nothing returned\n"); + return; + } + if (*str > 20) { + printf_intr("ADB: ACK > 20 no way!\n"); + *str = 20; + } + printf_intr("(length=0x%x):", *str); + for (x = 1; x <= *str; x++) + printf_intr(" 0x%02x", str[x]); + printf_intr("\n"); +} +#endif + +void +adb_cuda_tickle(void) +{ + volatile int s; + + if (adbActionState == ADB_ACTION_IN) { + if (tickle_serial == adb_cuda_serial) { + if (++tickle_count > 0) { + s = splhigh(); + adbActionState = ADB_ACTION_IDLE; + adbInputBuffer[0] = 0; + ADB_SET_STATE_IDLE_CUDA(); + splx(s); + } + } else { + tickle_serial = adb_cuda_serial; + tickle_count = 0; + } + } else { + tickle_serial = adb_cuda_serial; + tickle_count = 0; + } + + timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS); +} + +/* + * called when when an adb interrupt happens + * + * Cuda version of adb_intr + * TO DO: do we want to add some calls to intr_dispatch() here to + * grab serial interrupts? + */ +void +adb_intr_cuda(void) +{ + volatile int i, ending; + volatile unsigned int s; + struct adbCommand packet; + + s = splhigh(); /* can't be too careful - might be called */ + /* from a routine, NOT an interrupt */ + + ADB_VIA_CLR_INTR(); /* clear interrupt */ + ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */ + +switch_start: + switch (adbActionState) { + case ADB_ACTION_IDLE: + /* + * This is an unexpected packet, so grab the first (dummy) + * byte, set up the proper vars, and tell the chip we are + * starting to receive the packet by setting the TIP bit. + */ + adbInputBuffer[1] = ADB_SR(); + adb_cuda_serial++; + if (ADB_INTR_IS_OFF) /* must have been a fake start */ + break; + + ADB_SET_SR_INPUT(); + ADB_SET_STATE_TIP(); + + adbInputBuffer[0] = 1; + adbActionState = ADB_ACTION_IN; +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("idle 0x%02x ", adbInputBuffer[1]); +#endif + break; + + case ADB_ACTION_IN: + adbInputBuffer[++adbInputBuffer[0]] = ADB_SR(); + /* intr off means this is the last byte (end of frame) */ + if (ADB_INTR_IS_OFF) + ending = 1; + else + ending = 0; + + if (1 == ending) { /* end of message? */ +#ifdef ADB_DEBUG + if (adb_debug) { + printf_intr("in end 0x%02x ", + adbInputBuffer[adbInputBuffer[0]]); + print_single(adbInputBuffer); + } +#endif + + /* + * Are we waiting AND does this packet match what we + * are waiting for AND is it coming from either the + * ADB or RTC/PRAM sub-device? This section _should_ + * recognize all ADB and RTC/PRAM type commands, but + * there may be more... NOTE: commands are always at + * [4], even for RTC/PRAM commands. + */ + /* set up data for adb_pass_up */ + memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1); + + if ((adbWaiting == 1) && + (adbInputBuffer[4] == adbWaitingCmd) && + ((adbInputBuffer[2] == 0x00) || + (adbInputBuffer[2] == 0x01))) { + packet.saveBuf = adbBuffer; + packet.compRout = adbCompRout; + packet.compData = adbCompData; + packet.unsol = 0; + packet.ack_only = 0; + adb_pass_up(&packet); + + adbWaitingCmd = 0; /* reset "waiting" vars */ + adbWaiting = 0; + adbBuffer = (long)0; + adbCompRout = (long)0; + adbCompData = (long)0; + } else { + packet.unsol = 1; + packet.ack_only = 0; + adb_pass_up(&packet); + } + + + /* reset vars and signal the end of this frame */ + adbActionState = ADB_ACTION_IDLE; + adbInputBuffer[0] = 0; + ADB_SET_STATE_IDLE_CUDA(); + /*ADB_SET_SR_INPUT();*/ + + /* + * If there is something waiting to be sent out, + * the set everything up and send the first byte. + */ + if (adbWriteDelay == 1) { + delay(ADB_DELAY); /* required */ + adbSentChars = 0; + adbActionState = ADB_ACTION_OUT; + /* + * If the interrupt is on, we were too slow + * and the chip has already started to send + * something to us, so back out of the write + * and start a read cycle. + */ + if (ADB_INTR_IS_ON) { + ADB_SET_SR_INPUT(); + ADB_SET_STATE_IDLE_CUDA(); + adbSentChars = 0; + adbActionState = ADB_ACTION_IDLE; + adbInputBuffer[0] = 0; + break; + } + /* + * If we got here, it's ok to start sending + * so load the first byte and tell the chip + * we want to send. + */ + ADB_SET_STATE_TIP(); + ADB_SET_SR_OUTPUT(); + write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]); + } + } else { + ADB_TOGGLE_STATE_ACK_CUDA(); +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("in 0x%02x ", + adbInputBuffer[adbInputBuffer[0]]); +#endif + } + break; + + case ADB_ACTION_OUT: + i = ADB_SR(); /* reset SR-intr in IFR */ +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("intr out 0x%02x ", i); +#endif + + adbSentChars++; + if (ADB_INTR_IS_ON) { /* ADB intr low during write */ +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("intr was on "); +#endif + ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ + ADB_SET_STATE_IDLE_CUDA(); + adbSentChars = 0; /* must start all over */ + adbActionState = ADB_ACTION_IDLE; /* new state */ + adbInputBuffer[0] = 0; + adbWriteDelay = 1; /* must retry when done with + * read */ + delay(ADB_DELAY); + goto switch_start; /* process next state right + * now */ + break; + } + if (adbOutputBuffer[0] == adbSentChars) { /* check for done */ + if (0 == adb_cmd_result(adbOutputBuffer)) { /* do we expect data + * back? */ + adbWaiting = 1; /* signal waiting for return */ + adbWaitingCmd = adbOutputBuffer[2]; /* save waiting command */ + } else { /* no talk, so done */ + /* set up stuff for adb_pass_up */ + memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1); + packet.saveBuf = adbBuffer; + packet.compRout = adbCompRout; + packet.compData = adbCompData; + packet.cmd = adbWaitingCmd; + packet.unsol = 0; + packet.ack_only = 1; + adb_pass_up(&packet); + + /* reset "waiting" vars, just in case */ + adbWaitingCmd = 0; + adbBuffer = (long)0; + adbCompRout = (long)0; + adbCompData = (long)0; + } + + adbWriteDelay = 0; /* done writing */ + adbActionState = ADB_ACTION_IDLE; /* signal bus is idle */ + ADB_SET_SR_INPUT(); + ADB_SET_STATE_IDLE_CUDA(); +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("write done "); +#endif + } else { + write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]); /* send next byte */ + ADB_TOGGLE_STATE_ACK_CUDA(); /* signal byte ready to + * shift */ +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("toggle "); +#endif + } + break; + + case ADB_ACTION_NOTREADY: +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("adb: not yet initialized\n"); +#endif + break; + + default: + ; +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("intr: unknown ADB state\n"); +#endif + } + + ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */ + + splx(s); /* restore */ +} + + +int +send_adb_cuda(u_char * in, u_char * buffer, void *compRout, void *data, int + command) +{ + int s, len; + +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("SEND\n"); +#endif + + if (adbActionState == ADB_ACTION_NOTREADY) + return 1; + + /* Don't interrupt while we are messing with the ADB */ + s = splhigh(); + + if ((adbActionState == ADB_ACTION_IDLE) && /* ADB available? */ + (ADB_INTR_IS_OFF)) { /* and no incoming interrupt? */ + } else + if (adbWriteDelay == 0) /* it's busy, but is anything waiting? */ + adbWriteDelay = 1; /* if no, then we'll "queue" + * it up */ + else { + splx(s); + return 1; /* really busy! */ + } + +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("QUEUE\n"); +#endif + if ((long)in == (long)0) { /* need to convert? */ + if ((command & 0x0c) == 0x08) /* copy addl data ONLY if + * doing a listen! */ + len = buffer[0]; /* length of additional data */ + else + len = 0;/* no additional data */ + + adbOutputBuffer[0] = 2 + len; /* dev. type + command + addl. + * data */ + adbOutputBuffer[1] = 0x00; /* mark as an ADB command */ + adbOutputBuffer[2] = (u_char)command; /* load command */ + + /* copy additional output data, if any */ + memcpy(adbOutputBuffer + 3, buffer + 1, len); + } else + /* if data ready, just copy over */ + memcpy(adbOutputBuffer, in, in[0] + 2); + + adbSentChars = 0; /* nothing sent yet */ + adbBuffer = buffer; /* save buffer to know where to save result */ + adbCompRout = compRout; /* save completion routine pointer */ + adbCompData = data; /* save completion routine data pointer */ + adbWaitingCmd = adbOutputBuffer[2]; /* save wait command */ + + if (adbWriteDelay != 1) { /* start command now? */ +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("out start NOW"); +#endif + delay(ADB_DELAY); + adbActionState = ADB_ACTION_OUT; /* set next state */ + ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ + write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]); /* load byte for output */ + ADB_SET_STATE_ACKOFF_CUDA(); + ADB_SET_STATE_TIP(); /* tell ADB that we want to send */ + } + adbWriteDelay = 1; /* something in the write "queue" */ + + splx(s); + + if ((s & (1 << 18)) || adb_polling) /* XXX were VIA1 interrupts blocked ? */ + /* poll until byte done */ + while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON) + || (adbWaiting == 1)) + if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */ + adb_intr_cuda(); /* process it */ + adb_soft_intr(); + } + + return 0; +} + +/* + * Called when when an adb interrupt happens. + * This routine simply transfers control over to the appropriate + * code for the machine we are running on. + */ +int +adb_intr(void *arg) +{ + switch (adbHardware) { + case ADB_HW_PMU: + pm_intr(); + break; + + case ADB_HW_CUDA: + adb_intr_cuda(); + break; + } + return 1; +} + + +/* + * adb_pass_up is called by the interrupt-time routines. + * It takes the raw packet data that was received from the + * device and puts it into the queue that the upper half + * processes. It then signals for a soft ADB interrupt which + * will eventually call the upper half routine (adb_soft_intr). + * + * If in->unsol is 0, then this is either the notification + * that the packet was sent (on a LISTEN, for example), or the + * response from the device (on a TALK). The completion routine + * is called only if the user specified one. + * + * If in->unsol is 1, then this packet was unsolicited and + * so we look up the device in the ADB device table to determine + * what it's default service routine is. + * + * If in->ack_only is 1, then we really only need to call + * the completion routine, so don't do any other stuff. + * + * Note that in->data contains the packet header AND data, + * while adbInbound[]->data contains ONLY data. + * + * Note: Called only at interrupt time. Assumes this. + */ +void +adb_pass_up(struct adbCommand *in) +{ + int start = 0, len = 0, cmd = 0; + ADBDataBlock block; + + /* temp for testing */ + /*u_char *buffer = 0;*/ + /*u_char *compdata = 0;*/ + /*u_char *comprout = 0;*/ + + if (adbInCount >= ADB_QUEUE) { +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("adb: ring buffer overflow\n"); +#endif + return; + } + + if (in->ack_only) { + len = in->data[0]; + cmd = in->cmd; + start = 0; + } else { + switch (adbHardware) { + case ADB_HW_CUDA: + /* If it's unsolicited, accept only ADB data for now */ + if (in->unsol) + if (0 != in->data[2]) + return; + cmd = in->data[4]; + if (in->data[0] < 5) + len = 0; + else + len = in->data[0]-4; + start = 4; + break; + + case ADB_HW_PMU: + cmd = in->data[1]; + if (in->data[0] < 2) + len = 0; + else + len = in->data[0]-1; + start = 1; + break; + + case ADB_HW_UNKNOWN: + return; + } + + /* Make sure there is a valid device entry for this device */ + if (in->unsol) { + /* ignore unsolicited data during adbreinit */ + if (adbStarting) + return; + /* get device's comp. routine and data area */ + if (-1 == get_adb_info(&block, ADB_CMDADDR(cmd))) + return; + } + } + + /* + * If this is an unsolicited packet, we need to fill in + * some info so adb_soft_intr can process this packet + * properly. If it's not unsolicited, then use what + * the caller sent us. + */ + if (in->unsol) { + adbInbound[adbInTail].compRout = (void *)block.dbServiceRtPtr; + adbInbound[adbInTail].compData = (void *)block.dbDataAreaAddr; + adbInbound[adbInTail].saveBuf = (void *)adbInbound[adbInTail].data; + } else { + adbInbound[adbInTail].compRout = (void *)in->compRout; + adbInbound[adbInTail].compData = (void *)in->compData; + adbInbound[adbInTail].saveBuf = (void *)in->saveBuf; + } + +#ifdef ADB_DEBUG + if (adb_debug && in->data[1] == 2) + printf_intr("adb: caught error\n"); +#endif + + /* copy the packet data over */ + /* + * TO DO: If the *_intr routines fed their incoming data + * directly into an adbCommand struct, which is passed to + * this routine, then we could eliminate this copy. + */ + memcpy(adbInbound[adbInTail].data + 1, in->data + start + 1, len); + adbInbound[adbInTail].data[0] = len; + adbInbound[adbInTail].cmd = cmd; + + adbInCount++; + if (++adbInTail >= ADB_QUEUE) + adbInTail = 0; + + /* + * If the debugger is running, call upper half manually. + * Otherwise, trigger a soft interrupt to handle the rest later. + */ + if (adb_polling) + adb_soft_intr(); + else + setsoftadb(); +} + + +/* + * Called to process the packets after they have been + * placed in the incoming queue. + * + */ +void +adb_soft_intr(void) +{ + int s; + int cmd = 0; + u_char *buffer = 0; + u_char *comprout = 0; + u_char *compdata = 0; + +/*delay(2*ADB_DELAY);*/ + + while (adbInCount) { +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("%x %x %x ", + adbInCount, adbInHead, adbInTail); +#endif + /* get the data we need from the queue */ + buffer = adbInbound[adbInHead].saveBuf; + comprout = adbInbound[adbInHead].compRout; + compdata = adbInbound[adbInHead].compData; + cmd = adbInbound[adbInHead].cmd; + + /* copy over data to data area if it's valid */ + /* + * Note that for unsol packets we don't want to copy the + * data anywhere, so buffer was already set to 0. + * For ack_only buffer was set to 0, so don't copy. + */ + if (buffer) + memcpy(buffer, adbInbound[adbInHead].data, + adbInbound[adbInHead].data[0] + 1); + +#ifdef ADB_DEBUG + if (adb_debug & 0x80) { + printf_intr("%p %p %p %x ", + buffer, comprout, compdata, (short)cmd); + printf_intr("buf: "); + print_single(adbInbound[adbInHead].data); + } +#endif + /* + * Remove the packet from the queue before calling + * the completion routine, so that the completion + * routine can reentrantly process the queue. For + * example, this happens when polling is turned on + * by entering the debuger by keystroke. + */ + s = splhigh(); + adbInCount--; + if (++adbInHead >= ADB_QUEUE) + adbInHead = 0; + splx(s); + + /* call default completion routine if it's valid */ + if (comprout) { + ((int (*)(u_char *, u_char *, int)) comprout) + (buffer, compdata, cmd); + } + + } +} + + +/* + * This is my version of the ADBOp routine. It mainly just calls the + * hardware-specific routine. + * + * data : pointer to data area to be used by compRout + * compRout : completion routine + * buffer : for LISTEN: points to data to send - MAX 8 data bytes, + * byte 0 = # of bytes + * : for TALK: points to place to save return data + * command : the adb command to send + * result : 0 = success + * : -1 = could not complete + */ +int +adb_op(Ptr buffer, Ptr compRout, Ptr data, short command) +{ + int result; + + switch (adbHardware) { + case ADB_HW_PMU: + result = pm_adb_op((u_char *)buffer, (void *)compRout, + (void *)data, (int)command); + + if (result == 0) + return 0; + else + return -1; + break; + + case ADB_HW_CUDA: + result = send_adb_cuda((u_char *)0, (u_char *)buffer, + (void *)compRout, (void *)data, (int)command); + if (result == 0) + return 0; + else + return -1; + break; + + default: + return -1; + } +} + + +/* + * adb_hw_setup + * This routine sets up the possible machine specific hardware + * config (mainly VIA settings) for the various models. + */ +void +adb_hw_setup(void) +{ + volatile int i; + + switch (adbHardware) { + + case ADB_HW_PMU: + /* + * XXX - really PM_VIA_CLR_INTR - should we put it in + * pm_direct.h? + */ + write_via_reg(VIA1, vIFR, 0x90); /* clear interrupt */ + break; + + case ADB_HW_CUDA: + via_reg_or(VIA1, vDirB, 0x30); /* register B bits 4 and 5: + * outputs */ + via_reg_and(VIA1, vDirB, 0xf7); /* register B bit 3: input */ + via_reg_and(VIA1, vACR, ~vSR_OUT); /* make sure SR is set + * to IN */ + write_via_reg(VIA1, vACR, (read_via_reg(VIA1, vACR) | 0x0c) & ~0x10); + adbActionState = ADB_ACTION_IDLE; /* used by all types of + * hardware */ + write_via_reg(VIA1, vIER, 0x84);/* make sure VIA interrupts + * are on */ + ADB_SET_STATE_IDLE_CUDA(); /* set ADB bus state to idle */ + + /* sort of a device reset */ + i = ADB_SR(); /* clear interrupt */ + ADB_VIA_INTR_DISABLE(); /* no interrupts while clearing */ + ADB_SET_STATE_IDLE_CUDA(); /* reset state to idle */ + delay(ADB_DELAY); + ADB_SET_STATE_TIP(); /* signal start of frame */ + delay(ADB_DELAY); + ADB_TOGGLE_STATE_ACK_CUDA(); + delay(ADB_DELAY); + ADB_CLR_STATE_TIP(); + delay(ADB_DELAY); + ADB_SET_STATE_IDLE_CUDA(); /* back to idle state */ + i = ADB_SR(); /* clear interrupt */ + ADB_VIA_INTR_ENABLE(); /* ints ok now */ + break; + + case ADB_HW_UNKNOWN: + default: + write_via_reg(VIA1, vIER, 0x04);/* turn interrupts off - TO + * DO: turn PB ints off? */ + break; + } +} + +/* + * adb_reinit sets up the adb stuff + * + */ +void +adb_reinit(void) +{ + u_char send_string[ADB_MAX_MSG_LENGTH]; + ADBDataBlock data; /* temp. holder for getting device info */ + volatile int i, x; + int s; + int command; + int result; + int saveptr; /* point to next free relocation address */ + int device; + int nonewtimes; /* times thru loop w/o any new devices */ + + /* Make sure we are not interrupted while building the table. */ + if (adbHardware != ADB_HW_PMU) /* ints must be on for PB? */ + s = splhigh(); + + ADBNumDevices = 0; /* no devices yet */ + + /* Let intr routines know we are running reinit */ + adbStarting = 1; + + /* + * Initialize the ADB table. For now, we'll always use the same table + * that is defined at the beginning of this file - no mallocs. + */ + for (i = 0; i < 16; i++) + ADBDevTable[i].devType = 0; + + adb_setup_hw_type(); /* setup hardware type */ + + adb_hw_setup(); /* init the VIA bits and hard reset ADB */ + + delay(1000); + + /* send an ADB reset first */ + adb_op_sync((Ptr)0, (Ptr)0, (Ptr)0, (short)0x00); + delay(200000); + + /* + * Probe for ADB devices. Probe devices 1-15 quickly to determine + * which device addresses are in use and which are free. For each + * address that is in use, move the device at that address to a higher + * free address. Continue doing this at that address until no device + * responds at that address. Then move the last device that was moved + * back to the original address. Do this for the remaining addresses + * that we determined were in use. + * + * When finished, do this entire process over again with the updated + * list of in use addresses. Do this until no new devices have been + * found in 20 passes though the in use address list. (This probably + * seems long and complicated, but it's the best way to detect multiple + * devices at the same address - sometimes it takes a couple of tries + * before the collision is detected.) + */ + + /* initial scan through the devices */ + for (i = 1; i < 16; i++) { + send_string[0] = 0; + command = ADBTALK(i, 3); + result = adb_op_sync((Ptr)send_string, (Ptr)0, + (Ptr)0, (short)command); + + if (send_string[0] != 0) { + /* check for valid device handler */ + switch (send_string[2]) { + case 0: + case 0xfd: + case 0xfe: + case 0xff: + continue; /* invalid, skip */ + } + + /* found a device */ + ++ADBNumDevices; + KASSERT(ADBNumDevices < 16); + ADBDevTable[ADBNumDevices].devType = + (int)send_string[2]; + ADBDevTable[ADBNumDevices].origAddr = i; + ADBDevTable[ADBNumDevices].currentAddr = i; + ADBDevTable[ADBNumDevices].DataAreaAddr = + (long)0; + ADBDevTable[ADBNumDevices].ServiceRtPtr = (void *)0; + } + } + + /* find highest unused address */ + for (saveptr = 15; saveptr > 0; saveptr--) + if (-1 == get_adb_info(&data, saveptr)) + break; + +#ifdef ADB_DEBUG + if (adb_debug & 0x80) { + printf_intr("first free is: 0x%02x\n", saveptr); + printf_intr("devices: %i\n", ADBNumDevices); + } +#endif + + nonewtimes = 0; /* no loops w/o new devices */ + while (saveptr > 0 && nonewtimes++ < 11) { + for (i = 1; i <= ADBNumDevices; i++) { + device = ADBDevTable[i].currentAddr; +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("moving device 0x%02x to 0x%02x " + "(index 0x%02x) ", device, saveptr, i); +#endif + + /* send TALK R3 to address */ + command = ADBTALK(device, 3); + adb_op_sync((Ptr)send_string, (Ptr)0, + (Ptr)0, (short)command); + + /* move device to higher address */ + command = ADBLISTEN(device, 3); + send_string[0] = 2; + send_string[1] = (u_char)(saveptr | 0x60); + send_string[2] = 0xfe; + adb_op_sync((Ptr)send_string, (Ptr)0, + (Ptr)0, (short)command); + delay(500); + + /* send TALK R3 - anything at new address? */ + command = ADBTALK(saveptr, 3); + adb_op_sync((Ptr)send_string, (Ptr)0, + (Ptr)0, (short)command); + delay(500); + + if (send_string[0] == 0) { +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("failed, continuing\n"); +#endif + continue; + } + + /* send TALK R3 - anything at old address? */ + command = ADBTALK(device, 3); + result = adb_op_sync((Ptr)send_string, (Ptr)0, + (Ptr)0, (short)command); + if (send_string[0] != 0) { + /* check for valid device handler */ + switch (send_string[2]) { + case 0: + case 0xfd: + case 0xfe: + case 0xff: + continue; /* invalid, skip */ + } + + /* new device found */ + /* update data for previously moved device */ + ADBDevTable[i].currentAddr = saveptr; +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("old device at index %i\n",i); +#endif + /* add new device in table */ +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("new device found\n"); +#endif + if (saveptr > ADBNumDevices) { + ++ADBNumDevices; + KASSERT(ADBNumDevices < 16); + } + ADBDevTable[ADBNumDevices].devType = + (int)send_string[2]; + ADBDevTable[ADBNumDevices].origAddr = device; + ADBDevTable[ADBNumDevices].currentAddr = device; + /* These will be set correctly in adbsys.c */ + /* Until then, unsol. data will be ignored. */ + ADBDevTable[ADBNumDevices].DataAreaAddr = + (long)0; + ADBDevTable[ADBNumDevices].ServiceRtPtr = + (void *)0; + /* find next unused address */ + for (x = saveptr; x > 0; x--) { + if (-1 == get_adb_info(&data, x)) { + saveptr = x; + break; + } + } + if (x == 0) + saveptr = 0; +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("new free is 0x%02x\n", + saveptr); +#endif + nonewtimes = 0; + } else { +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("moving back...\n"); +#endif + /* move old device back */ + command = ADBLISTEN(saveptr, 3); + send_string[0] = 2; + send_string[1] = (u_char)(device | 0x60); + send_string[2] = 0xfe; + adb_op_sync((Ptr)send_string, (Ptr)0, + (Ptr)0, (short)command); + delay(1000); + } + } + } + +#ifdef ADB_DEBUG + if (adb_debug) { + for (i = 1; i <= ADBNumDevices; i++) { + x = get_ind_adb_info(&data, i); + if (x != -1) + printf_intr("index 0x%x, addr 0x%x, type 0x%x\n", + i, x, data.devType); + } + } +#endif + +#ifdef ADB_DEBUG + if (adb_debug) { + if (0 == ADBNumDevices) /* tell user if no devices found */ + printf_intr("adb: no devices found\n"); + } +#endif + + adbStarting = 0; /* not starting anymore */ +#ifdef ADB_DEBUG + if (adb_debug) + printf_intr("adb: adb_reinit complete\n"); +#endif + + if (adbHardware == ADB_HW_CUDA) { + timeout_set(&adb_cuda_timeout, (void *)adb_cuda_tickle, NULL); + timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS); + } + + if (adbHardware != ADB_HW_PMU) /* ints must be on for PB? */ + splx(s); +} + + +/* + * adb_cmd_result + * + * This routine lets the caller know whether the specified adb command string + * should expect a returned result, such as a TALK command. + * + * returns: 0 if a result should be expected + * 1 if a result should NOT be expected + */ +int +adb_cmd_result(u_char *in) +{ + switch (adbHardware) { + case ADB_HW_CUDA: + /* was it an ADB talk command? */ + if ((in[1] == 0x00) && ((in[2] & 0x0c) == 0x0c)) + return 0; + /* was it an RTC/PRAM read date/time? */ + if ((in[1] == 0x01) && (in[2] == 0x03)) + return 0; + return 1; + + case ADB_HW_PMU: + return 1; + + default: + return 1; + } +} + + +/* + * adb_op_sync + * + * This routine does exactly what the adb_op routine does, except that after + * the adb_op is called, it waits until the return value is present before + * returning. + * + * NOTE: The user specified compRout is ignored, since this routine specifies + * it's own to adb_op, which is why you really called this in the first place + * anyway. + */ +int +adb_op_sync(Ptr buffer, Ptr compRout, Ptr data, short command) +{ + int tmout; + int result; + volatile int flag = 0; + + result = adb_op(buffer, (void *)adb_op_comprout, + (void *)&flag, command); /* send command */ + if (result == 0) { /* send ok? */ + /* + * Total time to wait is calculated as follows: + * - Tlt (stop to start time): 260 usec + * - start bit: 100 usec + * - up to 8 data bytes: 64 * 100 usec = 6400 usec + * - stop bit (with SRQ): 140 usec + * Total: 6900 usec + * + * This is the total time allowed by the specification. Any + * device that doesn't conform to this will fail to operate + * properly on some Apple systems. In spite of this we + * double the time to wait; some Cuda-based apparently + * queues some commands and allows the main CPU to continue + * processing (radical concept, eh?). To be safe, allow + * time for two complete ADB transactions to occur. + */ + for (tmout = 13800; !flag && tmout >= 10; tmout -= 10) + delay(10); + if (!flag && tmout > 0) + delay(tmout); + + if (!flag) + result = -2; + } + + return result; +} + + +/* + * adb_op_comprout + * + * This function is used by the adb_op_sync routine so it knows when the + * function is done. + */ +void +adb_op_comprout(buffer, compdata, cmd) + caddr_t buffer, compdata; + int cmd; +{ + short *p = (short *)compdata; + + *p = 1; +} + +void +adb_setup_hw_type(void) +{ + switch (adbHardware) { + case ADB_HW_CUDA: + adbSoftPower = 1; + return; + + case ADB_HW_PMU: + adbSoftPower = 1; + pm_setup_adb(); + return; + + default: + panic("unknown adb hardware"); + } +} + +int +count_adbs(void) +{ + int i; + int found; + + found = 0; + + for (i = 1; i < 16; i++) + if (0 != ADBDevTable[i].devType) + found++; + + return found; +} + +int +get_ind_adb_info(ADBDataBlock * info, int index) +{ + if ((index < 1) || (index > 15)) /* check range 1-15 */ + return (-1); + +#ifdef ADB_DEBUG + if (adb_debug & 0x80) + printf_intr("index 0x%x devType is: 0x%x\n", index, + ADBDevTable[index].devType); +#endif + if (0 == ADBDevTable[index].devType) /* make sure it's a valid entry */ + return (-1); + + info->devType = ADBDevTable[index].devType; + info->origADBAddr = ADBDevTable[index].origAddr; + info->dbServiceRtPtr = (Ptr)ADBDevTable[index].ServiceRtPtr; + info->dbDataAreaAddr = (Ptr)ADBDevTable[index].DataAreaAddr; + + return (ADBDevTable[index].currentAddr); +} + +int +get_adb_info(ADBDataBlock * info, int adbAddr) +{ + int i; + + if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */ + return (-1); + + for (i = 1; i < 15; i++) + if (ADBDevTable[i].currentAddr == adbAddr) { + info->devType = ADBDevTable[i].devType; + info->origADBAddr = ADBDevTable[i].origAddr; + info->dbServiceRtPtr = (Ptr)ADBDevTable[i].ServiceRtPtr; + info->dbDataAreaAddr = ADBDevTable[i].DataAreaAddr; + return 0; /* found */ + } + + return (-1); /* not found */ +} + +int +set_adb_info(ADBSetInfoBlock * info, int adbAddr) +{ + int i; + + if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */ + return (-1); + + for (i = 1; i < 15; i++) + if (ADBDevTable[i].currentAddr == adbAddr) { + ADBDevTable[i].ServiceRtPtr = + (void *)(info->siServiceRtPtr); + ADBDevTable[i].DataAreaAddr = info->siDataAreaAddr; + return 0; /* found */ + } + + return (-1); /* not found */ + +} + +/* caller should really use machine-independent version: getPramTime */ +/* this version does pseudo-adb access only */ +int +adb_read_date_time(time_t *time) +{ + u_char output[ADB_MAX_MSG_LENGTH]; + int result; + int retcode; + volatile int flag = 0; + + switch (adbHardware) { + case ADB_HW_PMU: + pm_read_date_time(time); + retcode = 0; + break; + + case ADB_HW_CUDA: + output[0] = 0x02; /* 2 byte message */ + output[1] = 0x01; /* to pram/rtc device */ + output[2] = 0x03; /* read date/time */ + result = send_adb_cuda((u_char *)output, (u_char *)output, + (void *)adb_op_comprout, (void *)&flag, (int)0); + if (result != 0) { /* exit if not sent */ + retcode = -1; + break; + } + + while (0 == flag) /* wait for result */ + ; + + delay(20); /* completion occurs too soon? */ + memcpy(time, output + 1, 4); + retcode = 0; + break; + + case ADB_HW_UNKNOWN: + default: + retcode = -1; + break; + } + if (retcode == 0) { +#define DIFF19041970 2082844800 + *time -= DIFF19041970; + + } else { + *time = 0; + } + return retcode; +} + +/* caller should really use machine-independent version: setPramTime */ +/* this version does pseudo-adb access only */ +int +adb_set_date_time(time_t time) +{ + u_char output[ADB_MAX_MSG_LENGTH]; + int result; + volatile int flag = 0; + + time += DIFF19041970; + switch (adbHardware) { + + case ADB_HW_CUDA: + output[0] = 0x06; /* 6 byte message */ + output[1] = 0x01; /* to pram/rtc device */ + output[2] = 0x09; /* set date/time */ + output[3] = (u_char)(time >> 24); + output[4] = (u_char)(time >> 16); + output[5] = (u_char)(time >> 8); + output[6] = (u_char)(time); + result = send_adb_cuda((u_char *)output, (u_char *)0, + (void *)adb_op_comprout, (void *)&flag, (int)0); + if (result != 0) /* exit if not sent */ + return -1; + + while (0 == flag) /* wait for send to finish */ + ; + + return 0; + + case ADB_HW_PMU: + pm_set_date_time(time); + return 0; + + default: + return -1; + } +} + + +int +adb_poweroff(void) +{ + u_char output[ADB_MAX_MSG_LENGTH]; + int result; + + if (!adbSoftPower) + return -1; + + adb_polling = 1; + + switch (adbHardware) { + case ADB_HW_PMU: + pm_adb_poweroff(); + + for (;;); /* wait for power off */ + + return 0; + + case ADB_HW_CUDA: + output[0] = 0x02; /* 2 byte message */ + output[1] = 0x01; /* to pram/rtc/soft-power device */ + output[2] = 0x0a; /* set date/time */ + result = send_adb_cuda((u_char *)output, (u_char *)0, + (void *)0, (void *)0, (int)0); + if (result != 0) /* exit if not sent */ + return -1; + + for (;;); /* wait for power off */ + + return 0; + + default: + return -1; + } +} + +void +setsoftadb() +{ + if (!timeout_initialized(&adb_softintr_timeout)) + timeout_set(&adb_softintr_timeout, (void *)adb_soft_intr, NULL); + timeout_add(&adb_softintr_timeout, 1); +} + +void +adb_cuda_autopoll() +{ + volatile int flag = 0; + int result; + u_char output[16]; + + output[0] = 0x03; /* 3-byte message */ + output[1] = 0x01; /* to pram/rtc device */ + output[2] = 0x01; /* cuda autopoll */ + output[3] = 0x01; + result = send_adb_cuda(output, output, adb_op_comprout, + (void *)&flag, 0); + if (result != 0) /* exit if not sent */ + return; + + while (flag == 0); /* wait for result */ +} + +void +adb_restart() +{ + int result; + u_char output[16]; + + adb_polling = 1; + + switch (adbHardware) { + case ADB_HW_CUDA: + output[0] = 0x02; /* 2 byte message */ + output[1] = 0x01; /* to pram/rtc/soft-power device */ + output[2] = 0x11; /* restart */ + result = send_adb_cuda((u_char *)output, (u_char *)0, + (void *)0, (void *)0, (int)0); + if (result != 0) /* exit if not sent */ + return; + while (1); /* not return */ + + case ADB_HW_PMU: + pm_adb_restart(); + while (1); /* not return */ + } +} /* * Driver definition. */ + +int adbmatch(struct device *, void *, void *); +void adbattach(struct device *, struct device *, void *); + struct cfattach adb_ca = { sizeof(struct adb_softc), adbmatch, adbattach }; -struct cfdriver adb_cd = { - NULL, "adb", DV_DULL -}; int adbmatch(struct device *parent, void *cf, void *aux) @@ -119,7 +1646,7 @@ adbattach(struct device *parent, struct device *self, void *aux) adbHardware = ADB_HW_PMU; adb_polling = 1; - ADBReInit(); + adb_reinit(); mac_intr_establish(parent, ca->ca_intr[0], IST_LEVEL, IPL_HIGH, adb_intr, sc, "adb"); @@ -130,27 +1657,17 @@ adbattach(struct device *parent, struct device *self, void *aux) #ifdef ADB_DEBUG if (adb_debug) - printf("adb: done with ADBReInit\n"); + printf("adb: done with adb_reinit\n"); #endif - totaladbs = CountADBs(); + totaladbs = count_adbs(); - printf(" irq %d", ca->ca_intr[0]); - - switch (adbHardware) { - case ADB_HW_CUDA: - printf(": via-cuda"); - break; - case ADB_HW_PMU: - printf(": via-pmu"); - break; - } - - printf(", %d target%s\n", totaladbs, (totaladbs == 1) ? "" : "s"); + printf(" irq %d: %s, %d target%s\n", ca->ca_intr[0], ca->ca_name, + totaladbs, (totaladbs == 1) ? "" : "s"); /* for each ADB device */ for (adbindex = 1; adbindex <= totaladbs; adbindex++) { /* Get the ADB information */ - adbaddr = GetIndADB(&adbdata, adbindex); + adbaddr = get_ind_adb_info(&adbdata, adbindex); aa_args.origaddr = adbdata.origADBAddr; aa_args.adbaddr = adbaddr; @@ -183,69 +1700,3 @@ adbattach(struct device *parent, struct device *self, void *aux) } } } - -int -adbprint(void *args, const char *name) -{ - struct adb_attach_args *aa_args = (struct adb_attach_args *)args; - int rv = UNCONF; - - if (name) { /* no configured device matched */ - rv = UNSUPP; /* most ADB device types are unsupported */ - - /* print out what kind of ADB device we have found */ - switch(aa_args->origaddr) { -#ifdef ADBVERBOSE - case ADBADDR_SECURE: - printf("security dongle (%d)", aa_args->handler_id); - break; -#endif - case ADBADDR_MAP: - printf("mapped device (%d)", aa_args->handler_id); - rv = UNCONF; - break; - case ADBADDR_REL: - printf("relative positioning device (%d)", - aa_args->handler_id); - rv = UNCONF; - break; -#ifdef ADBVERBOSE - case ADBADDR_ABS: - switch (aa_args->handler_id) { - case ADB_ARTPAD: - printf("WACOM ArtPad II"); - break; - default: - printf("absolute positioning device (%d)", - aa_args->handler_id); - break; - } - break; - case ADBADDR_DATATX: - printf("data transfer device (modem?) (%d)", - aa_args->handler_id); - break; - case ADBADDR_MISC: - switch (aa_args->handler_id) { - case ADB_POWERKEY: - printf("Sophisticated Circuits PowerKey"); - break; - default: - printf("misc. device (remote control?) (%d)", - aa_args->handler_id); - break; - } - break; - default: - printf("unknown type %d device, (handler %d)", - aa_args->origaddr, aa_args->handler_id); - break; -#endif /* ADBVERBOSE */ - } - printf(" at %s", name); - } - - printf(" addr %d", aa_args->adbaddr); - - return (rv); -} diff --git a/sys/arch/macppc/dev/adb_direct.c b/sys/arch/macppc/dev/adb_direct.c deleted file mode 100644 index eab071d2c77..00000000000 --- a/sys/arch/macppc/dev/adb_direct.c +++ /dev/null @@ -1,1569 +0,0 @@ -/* $OpenBSD: adb_direct.c,v 1.14 2005/12/22 22:55:25 miod Exp $ */ -/* $NetBSD: adb_direct.c,v 1.14 2000/06/08 22:10:45 tsubai Exp $ */ - -/* - * Copyright (C) 1996, 1997 John P. Wittkoski - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by John P. Wittkoski. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -/* - * This code is rather messy, but I don't have time right now - * to clean it up as much as I would like. - * But it works, so I'm happy. :-) jpw - */ - -/* - * TO DO: - * - We could reduce the time spent in the adb_intr_* routines - * by having them save the incoming and outgoing data directly - * in the adbInbound and adbOutbound queues, as it would reduce - * the number of times we need to copy the data around. It - * would also make the code more readable and easier to follow. - * - (Related to above) Use the header part of adbCommand to - * reduce the number of copies we have to do of the data. - * - (Related to above) Actually implement the adbOutbound queue. - * This is fairly easy once you switch all the intr routines - * over to using adbCommand structs directly. - * - There is a bug in the state machine of adb_intr_cuda - * code that causes hangs, especially on 030 machines, probably - * because of some timing issues. Because I have been unable to - * determine the exact cause of this bug, I used the timeout function - * to check for and recover from this condition. If anyone finds - * the actual cause of this bug, the calls to timeout and the - * adb_cuda_tickle routine can be removed. - */ - -#include <sys/param.h> -#include <sys/cdefs.h> -#include <sys/systm.h> -#include <sys/timeout.h> -#include <sys/device.h> - -#include <machine/param.h> -#include <machine/cpu.h> -#include <machine/adbsys.h> - -#include <macppc/dev/viareg.h> -#include <macppc/dev/adbvar.h> -#include <macppc/dev/pm_direct.h> - -#define printf_intr printf - -#ifdef DEBUG -#ifndef ADB_DEBUG -#define ADB_DEBUG -#endif -#endif - -/* some misc. leftovers */ -#define vPB 0x0000 -#define vPB3 0x08 -#define vPB4 0x10 -#define vPB5 0x20 -#define vSR_INT 0x04 -#define vSR_OUT 0x10 - -/* the type of ADB action that we are currently performing */ -#define ADB_ACTION_NOTREADY 0x1 /* has not been initialized yet */ -#define ADB_ACTION_IDLE 0x2 /* the bus is currently idle */ -#define ADB_ACTION_OUT 0x3 /* sending out a command */ -#define ADB_ACTION_IN 0x4 /* receiving data */ - -/* - * Shortcuts for setting or testing the VIA bit states. - * Not all shortcuts are used for every type of ADB hardware. - */ -#define ADB_SET_STATE_IDLE_CUDA() via_reg_or(VIA1, vBufB, (vPB4 | vPB5)) -#define ADB_SET_STATE_TIP() via_reg_and(VIA1, vBufB, ~vPB5) -#define ADB_CLR_STATE_TIP() via_reg_or(VIA1, vBufB, vPB5) -#define ADB_TOGGLE_STATE_ACK_CUDA() via_reg_xor(VIA1, vBufB, vPB4) -#define ADB_SET_STATE_ACKOFF_CUDA() via_reg_or(VIA1, vBufB, vPB4) -#define ADB_SET_SR_INPUT() via_reg_and(VIA1, vACR, ~vSR_OUT) -#define ADB_SET_SR_OUTPUT() via_reg_or(VIA1, vACR, vSR_OUT) -#define ADB_SR() read_via_reg(VIA1, vSR) -#define ADB_VIA_INTR_ENABLE() write_via_reg(VIA1, vIER, 0x84) -#define ADB_VIA_INTR_DISABLE() write_via_reg(VIA1, vIER, 0x04) -#define ADB_VIA_CLR_INTR() write_via_reg(VIA1, vIFR, 0x04) -#define ADB_INTR_IS_OFF (vPB3 == (read_via_reg(VIA1, vBufB) & vPB3)) -#define ADB_INTR_IS_ON (0 == (read_via_reg(VIA1, vBufB) & vPB3)) -#define ADB_SR_INTR_IS_ON (vSR_INT == (read_via_reg(VIA1, \ - vIFR) & vSR_INT)) - -/* - * This is the delay that is required (in uS) between certain - * ADB transactions. The actual timing delay for for each uS is - * calculated at boot time to account for differences in machine speed. - */ -#define ADB_DELAY 150 - -/* - * Maximum ADB message length; includes space for data, result, and - * device code - plus a little for safety. - */ -#define ADB_MAX_MSG_LENGTH 16 -#define ADB_MAX_HDR_LENGTH 8 - -#define ADB_QUEUE 32 -#define ADB_TICKLE_TICKS 4 - -/* - * A structure for storing information about each ADB device. - */ -struct ADBDevEntry { - void (*ServiceRtPtr)(void); - void *DataAreaAddr; - int devType; - int origAddr; - int currentAddr; -}; - -/* - * Used to hold ADB commands that are waiting to be sent out. - */ -struct adbCmdHoldEntry { - u_char outBuf[ADB_MAX_MSG_LENGTH]; /* our message */ - u_char *saveBuf; /* buffer to know where to save result */ - u_char *compRout; /* completion routine pointer */ - u_char *data; /* completion routine data pointer */ -}; - -/* - * Eventually used for two separate queues, the queue between - * the upper and lower halves, and the outgoing packet queue. - * TO DO: adbCommand can replace all of adbCmdHoldEntry eventually - */ -struct adbCommand { - u_char header[ADB_MAX_HDR_LENGTH]; /* not used yet */ - u_char data[ADB_MAX_MSG_LENGTH]; /* packet data only */ - u_char *saveBuf; /* where to save result */ - u_char *compRout; /* completion routine pointer */ - u_char *compData; /* completion routine data pointer */ - u_int cmd; /* the original command for this data */ - u_int unsol; /* 1 if packet was unsolicited */ - u_int ack_only; /* 1 for no special processing */ -}; - -/* - * A few variables that we need and their initial values. - */ -int adbHardware = ADB_HW_UNKNOWN; -int adbActionState = ADB_ACTION_NOTREADY; -int adbWaiting = 0; /* waiting for return data from the device */ -int adbWriteDelay = 0; /* working on (or waiting to do) a write */ -int adbSoftPower = 0; /* machine supports soft power */ - -int adbWaitingCmd = 0; /* ADB command we are waiting for */ -u_char *adbBuffer = (long)0; /* pointer to user data area */ -void *adbCompRout = (long)0; /* pointer to the completion routine */ -void *adbCompData = (long)0; /* pointer to the completion routine data */ -int adbStarting = 1; /* doing ADBReInit so do polling differently */ - -u_char adbInputBuffer[ADB_MAX_MSG_LENGTH]; /* data input buffer */ -u_char adbOutputBuffer[ADB_MAX_MSG_LENGTH]; /* data output buffer */ -struct adbCmdHoldEntry adbOutQueue; /* our 1 entry output queue */ - -int adbSentChars = 0; /* how many characters we have sent */ - -struct ADBDevEntry ADBDevTable[16]; /* our ADB device table */ -int ADBNumDevices; /* num. of ADB devices found with ADBReInit */ - -struct adbCommand adbInbound[ADB_QUEUE]; /* incoming queue */ -int adbInCount = 0; /* how many packets in in queue */ -int adbInHead = 0; /* head of in queue */ -int adbInTail = 0; /* tail of in queue */ -struct adbCommand adbOutbound[ADB_QUEUE]; /* outgoing queue - not used yet */ -int adbOutCount = 0; /* how many packets in out queue */ -int adbOutHead = 0; /* head of out queue */ -int adbOutTail = 0; /* tail of out queue */ - -int tickle_count = 0; /* how many tickles seen for this packet? */ -int tickle_serial = 0; /* the last packet tickled */ -int adb_cuda_serial = 0; /* the current packet */ -struct timeout adb_cuda_timeout; -struct timeout adb_softintr_timeout; - -volatile u_char *Via1Base; - -/* - * The following are private routines. - */ -#ifdef ADB_DEBUG -void print_single(u_char *); -#endif -void adb_intr_cuda(void); -void adb_soft_intr(void); -int send_adb_cuda(u_char *, u_char *, void *, void *, int); -void adb_cuda_tickle(void); -void adb_pass_up(struct adbCommand *); -void adb_op_comprout(caddr_t, caddr_t, int); -void adb_reinit(void); -int count_adbs(void); -int get_ind_adb_info(ADBDataBlock *, int); -int get_adb_info(ADBDataBlock *, int); -int set_adb_info(ADBSetInfoBlock *, int); -void adb_setup_hw_type(void); -int adb_op(Ptr, Ptr, Ptr, short); -void adb_hw_setup(void); -int adb_cmd_result(u_char *); -void setsoftadb(void); - -#ifdef ADB_DEBUG -/* - * print_single - * Diagnostic display routine. Displays the hex values of the - * specified elements of the u_char. The length of the "string" - * is in [0]. - */ -void -print_single(str) - u_char *str; -{ - int x; - - if (str == 0) { - printf_intr("no data - null pointer\n"); - return; - } - if (*str == 0) { - printf_intr("nothing returned\n"); - return; - } - if (*str > 20) { - printf_intr("ADB: ACK > 20 no way!\n"); - *str = 20; - } - printf_intr("(length=0x%x):", *str); - for (x = 1; x <= *str; x++) - printf_intr(" 0x%02x", str[x]); - printf_intr("\n"); -} -#endif - -void -adb_cuda_tickle(void) -{ - volatile int s; - - if (adbActionState == ADB_ACTION_IN) { - if (tickle_serial == adb_cuda_serial) { - if (++tickle_count > 0) { - s = splhigh(); - adbActionState = ADB_ACTION_IDLE; - adbInputBuffer[0] = 0; - ADB_SET_STATE_IDLE_CUDA(); - splx(s); - } - } else { - tickle_serial = adb_cuda_serial; - tickle_count = 0; - } - } else { - tickle_serial = adb_cuda_serial; - tickle_count = 0; - } - - timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS); -} - -/* - * called when when an adb interrupt happens - * - * Cuda version of adb_intr - * TO DO: do we want to add some calls to intr_dispatch() here to - * grab serial interrupts? - */ -void -adb_intr_cuda(void) -{ - volatile int i, ending; - volatile unsigned int s; - struct adbCommand packet; - - s = splhigh(); /* can't be too careful - might be called */ - /* from a routine, NOT an interrupt */ - - ADB_VIA_CLR_INTR(); /* clear interrupt */ - ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */ - -switch_start: - switch (adbActionState) { - case ADB_ACTION_IDLE: - /* - * This is an unexpected packet, so grab the first (dummy) - * byte, set up the proper vars, and tell the chip we are - * starting to receive the packet by setting the TIP bit. - */ - adbInputBuffer[1] = ADB_SR(); - adb_cuda_serial++; - if (ADB_INTR_IS_OFF) /* must have been a fake start */ - break; - - ADB_SET_SR_INPUT(); - ADB_SET_STATE_TIP(); - - adbInputBuffer[0] = 1; - adbActionState = ADB_ACTION_IN; -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("idle 0x%02x ", adbInputBuffer[1]); -#endif - break; - - case ADB_ACTION_IN: - adbInputBuffer[++adbInputBuffer[0]] = ADB_SR(); - /* intr off means this is the last byte (end of frame) */ - if (ADB_INTR_IS_OFF) - ending = 1; - else - ending = 0; - - if (1 == ending) { /* end of message? */ -#ifdef ADB_DEBUG - if (adb_debug) { - printf_intr("in end 0x%02x ", - adbInputBuffer[adbInputBuffer[0]]); - print_single(adbInputBuffer); - } -#endif - - /* - * Are we waiting AND does this packet match what we - * are waiting for AND is it coming from either the - * ADB or RTC/PRAM sub-device? This section _should_ - * recognize all ADB and RTC/PRAM type commands, but - * there may be more... NOTE: commands are always at - * [4], even for RTC/PRAM commands. - */ - /* set up data for adb_pass_up */ - memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1); - - if ((adbWaiting == 1) && - (adbInputBuffer[4] == adbWaitingCmd) && - ((adbInputBuffer[2] == 0x00) || - (adbInputBuffer[2] == 0x01))) { - packet.saveBuf = adbBuffer; - packet.compRout = adbCompRout; - packet.compData = adbCompData; - packet.unsol = 0; - packet.ack_only = 0; - adb_pass_up(&packet); - - adbWaitingCmd = 0; /* reset "waiting" vars */ - adbWaiting = 0; - adbBuffer = (long)0; - adbCompRout = (long)0; - adbCompData = (long)0; - } else { - packet.unsol = 1; - packet.ack_only = 0; - adb_pass_up(&packet); - } - - - /* reset vars and signal the end of this frame */ - adbActionState = ADB_ACTION_IDLE; - adbInputBuffer[0] = 0; - ADB_SET_STATE_IDLE_CUDA(); - /*ADB_SET_SR_INPUT();*/ - - /* - * If there is something waiting to be sent out, - * the set everything up and send the first byte. - */ - if (adbWriteDelay == 1) { - delay(ADB_DELAY); /* required */ - adbSentChars = 0; - adbActionState = ADB_ACTION_OUT; - /* - * If the interrupt is on, we were too slow - * and the chip has already started to send - * something to us, so back out of the write - * and start a read cycle. - */ - if (ADB_INTR_IS_ON) { - ADB_SET_SR_INPUT(); - ADB_SET_STATE_IDLE_CUDA(); - adbSentChars = 0; - adbActionState = ADB_ACTION_IDLE; - adbInputBuffer[0] = 0; - break; - } - /* - * If we got here, it's ok to start sending - * so load the first byte and tell the chip - * we want to send. - */ - ADB_SET_STATE_TIP(); - ADB_SET_SR_OUTPUT(); - write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]); - } - } else { - ADB_TOGGLE_STATE_ACK_CUDA(); -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("in 0x%02x ", - adbInputBuffer[adbInputBuffer[0]]); -#endif - } - break; - - case ADB_ACTION_OUT: - i = ADB_SR(); /* reset SR-intr in IFR */ -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("intr out 0x%02x ", i); -#endif - - adbSentChars++; - if (ADB_INTR_IS_ON) { /* ADB intr low during write */ -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("intr was on "); -#endif - ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ - ADB_SET_STATE_IDLE_CUDA(); - adbSentChars = 0; /* must start all over */ - adbActionState = ADB_ACTION_IDLE; /* new state */ - adbInputBuffer[0] = 0; - adbWriteDelay = 1; /* must retry when done with - * read */ - delay(ADB_DELAY); - goto switch_start; /* process next state right - * now */ - break; - } - if (adbOutputBuffer[0] == adbSentChars) { /* check for done */ - if (0 == adb_cmd_result(adbOutputBuffer)) { /* do we expect data - * back? */ - adbWaiting = 1; /* signal waiting for return */ - adbWaitingCmd = adbOutputBuffer[2]; /* save waiting command */ - } else { /* no talk, so done */ - /* set up stuff for adb_pass_up */ - memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1); - packet.saveBuf = adbBuffer; - packet.compRout = adbCompRout; - packet.compData = adbCompData; - packet.cmd = adbWaitingCmd; - packet.unsol = 0; - packet.ack_only = 1; - adb_pass_up(&packet); - - /* reset "waiting" vars, just in case */ - adbWaitingCmd = 0; - adbBuffer = (long)0; - adbCompRout = (long)0; - adbCompData = (long)0; - } - - adbWriteDelay = 0; /* done writing */ - adbActionState = ADB_ACTION_IDLE; /* signal bus is idle */ - ADB_SET_SR_INPUT(); - ADB_SET_STATE_IDLE_CUDA(); -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("write done "); -#endif - } else { - write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]); /* send next byte */ - ADB_TOGGLE_STATE_ACK_CUDA(); /* signal byte ready to - * shift */ -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("toggle "); -#endif - } - break; - - case ADB_ACTION_NOTREADY: -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("adb: not yet initialized\n"); -#endif - break; - - default: - ; -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("intr: unknown ADB state\n"); -#endif - } - - ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */ - - splx(s); /* restore */ -} - - -int -send_adb_cuda(u_char * in, u_char * buffer, void *compRout, void *data, int - command) -{ - int s, len; - -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("SEND\n"); -#endif - - if (adbActionState == ADB_ACTION_NOTREADY) - return 1; - - /* Don't interrupt while we are messing with the ADB */ - s = splhigh(); - - if ((adbActionState == ADB_ACTION_IDLE) && /* ADB available? */ - (ADB_INTR_IS_OFF)) { /* and no incoming interrupt? */ - } else - if (adbWriteDelay == 0) /* it's busy, but is anything waiting? */ - adbWriteDelay = 1; /* if no, then we'll "queue" - * it up */ - else { - splx(s); - return 1; /* really busy! */ - } - -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("QUEUE\n"); -#endif - if ((long)in == (long)0) { /* need to convert? */ - if ((command & 0x0c) == 0x08) /* copy addl data ONLY if - * doing a listen! */ - len = buffer[0]; /* length of additional data */ - else - len = 0;/* no additional data */ - - adbOutputBuffer[0] = 2 + len; /* dev. type + command + addl. - * data */ - adbOutputBuffer[1] = 0x00; /* mark as an ADB command */ - adbOutputBuffer[2] = (u_char)command; /* load command */ - - /* copy additional output data, if any */ - memcpy(adbOutputBuffer + 3, buffer + 1, len); - } else - /* if data ready, just copy over */ - memcpy(adbOutputBuffer, in, in[0] + 2); - - adbSentChars = 0; /* nothing sent yet */ - adbBuffer = buffer; /* save buffer to know where to save result */ - adbCompRout = compRout; /* save completion routine pointer */ - adbCompData = data; /* save completion routine data pointer */ - adbWaitingCmd = adbOutputBuffer[2]; /* save wait command */ - - if (adbWriteDelay != 1) { /* start command now? */ -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("out start NOW"); -#endif - delay(ADB_DELAY); - adbActionState = ADB_ACTION_OUT; /* set next state */ - ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ - write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]); /* load byte for output */ - ADB_SET_STATE_ACKOFF_CUDA(); - ADB_SET_STATE_TIP(); /* tell ADB that we want to send */ - } - adbWriteDelay = 1; /* something in the write "queue" */ - - splx(s); - - if ((s & (1 << 18)) || adb_polling) /* XXX were VIA1 interrupts blocked ? */ - /* poll until byte done */ - while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON) - || (adbWaiting == 1)) - if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */ - adb_intr_cuda(); /* process it */ - adb_soft_intr(); - } - - return 0; -} - -/* - * Called when when an adb interrupt happens. - * This routine simply transfers control over to the appropriate - * code for the machine we are running on. - */ -int -adb_intr(void *arg) -{ - switch (adbHardware) { - case ADB_HW_PMU: - pm_intr(); - break; - - case ADB_HW_CUDA: - adb_intr_cuda(); - break; - } - return 1; -} - - -/* - * adb_pass_up is called by the interrupt-time routines. - * It takes the raw packet data that was received from the - * device and puts it into the queue that the upper half - * processes. It then signals for a soft ADB interrupt which - * will eventually call the upper half routine (adb_soft_intr). - * - * If in->unsol is 0, then this is either the notification - * that the packet was sent (on a LISTEN, for example), or the - * response from the device (on a TALK). The completion routine - * is called only if the user specified one. - * - * If in->unsol is 1, then this packet was unsolicited and - * so we look up the device in the ADB device table to determine - * what it's default service routine is. - * - * If in->ack_only is 1, then we really only need to call - * the completion routine, so don't do any other stuff. - * - * Note that in->data contains the packet header AND data, - * while adbInbound[]->data contains ONLY data. - * - * Note: Called only at interrupt time. Assumes this. - */ -void -adb_pass_up(struct adbCommand *in) -{ - int start = 0, len = 0, cmd = 0; - ADBDataBlock block; - - /* temp for testing */ - /*u_char *buffer = 0;*/ - /*u_char *compdata = 0;*/ - /*u_char *comprout = 0;*/ - - if (adbInCount >= ADB_QUEUE) { -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("adb: ring buffer overflow\n"); -#endif - return; - } - - if (in->ack_only) { - len = in->data[0]; - cmd = in->cmd; - start = 0; - } else { - switch (adbHardware) { - case ADB_HW_CUDA: - /* If it's unsolicited, accept only ADB data for now */ - if (in->unsol) - if (0 != in->data[2]) - return; - cmd = in->data[4]; - if (in->data[0] < 5) - len = 0; - else - len = in->data[0]-4; - start = 4; - break; - - case ADB_HW_PMU: - cmd = in->data[1]; - if (in->data[0] < 2) - len = 0; - else - len = in->data[0]-1; - start = 1; - break; - - case ADB_HW_UNKNOWN: - return; - } - - /* Make sure there is a valid device entry for this device */ - if (in->unsol) { - /* ignore unsolicited data during adbreinit */ - if (adbStarting) - return; - /* get device's comp. routine and data area */ - if (-1 == get_adb_info(&block, ADB_CMDADDR(cmd))) - return; - } - } - - /* - * If this is an unsolicited packet, we need to fill in - * some info so adb_soft_intr can process this packet - * properly. If it's not unsolicited, then use what - * the caller sent us. - */ - if (in->unsol) { - adbInbound[adbInTail].compRout = (void *)block.dbServiceRtPtr; - adbInbound[adbInTail].compData = (void *)block.dbDataAreaAddr; - adbInbound[adbInTail].saveBuf = (void *)adbInbound[adbInTail].data; - } else { - adbInbound[adbInTail].compRout = (void *)in->compRout; - adbInbound[adbInTail].compData = (void *)in->compData; - adbInbound[adbInTail].saveBuf = (void *)in->saveBuf; - } - -#ifdef ADB_DEBUG - if (adb_debug && in->data[1] == 2) - printf_intr("adb: caught error\n"); -#endif - - /* copy the packet data over */ - /* - * TO DO: If the *_intr routines fed their incoming data - * directly into an adbCommand struct, which is passed to - * this routine, then we could eliminate this copy. - */ - memcpy(adbInbound[adbInTail].data + 1, in->data + start + 1, len); - adbInbound[adbInTail].data[0] = len; - adbInbound[adbInTail].cmd = cmd; - - adbInCount++; - if (++adbInTail >= ADB_QUEUE) - adbInTail = 0; - - /* - * If the debugger is running, call upper half manually. - * Otherwise, trigger a soft interrupt to handle the rest later. - */ - if (adb_polling) - adb_soft_intr(); - else - setsoftadb(); -} - - -/* - * Called to process the packets after they have been - * placed in the incoming queue. - * - */ -void -adb_soft_intr(void) -{ - int s; - int cmd = 0; - u_char *buffer = 0; - u_char *comprout = 0; - u_char *compdata = 0; - -/*delay(2*ADB_DELAY);*/ - - while (adbInCount) { -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("%x %x %x ", - adbInCount, adbInHead, adbInTail); -#endif - /* get the data we need from the queue */ - buffer = adbInbound[adbInHead].saveBuf; - comprout = adbInbound[adbInHead].compRout; - compdata = adbInbound[adbInHead].compData; - cmd = adbInbound[adbInHead].cmd; - - /* copy over data to data area if it's valid */ - /* - * Note that for unsol packets we don't want to copy the - * data anywhere, so buffer was already set to 0. - * For ack_only buffer was set to 0, so don't copy. - */ - if (buffer) - memcpy(buffer, adbInbound[adbInHead].data, - adbInbound[adbInHead].data[0] + 1); - -#ifdef ADB_DEBUG - if (adb_debug & 0x80) { - printf_intr("%p %p %p %x ", - buffer, comprout, compdata, (short)cmd); - printf_intr("buf: "); - print_single(adbInbound[adbInHead].data); - } -#endif - /* - * Remove the packet from the queue before calling - * the completion routine, so that the completion - * routine can reentrantly process the queue. For - * example, this happens when polling is turned on - * by entering the debuger by keystroke. - */ - s = splhigh(); - adbInCount--; - if (++adbInHead >= ADB_QUEUE) - adbInHead = 0; - splx(s); - - /* call default completion routine if it's valid */ - if (comprout) { - ((int (*)(u_char *, u_char *, int)) comprout) - (buffer, compdata, cmd); - } - - } -} - - -/* - * This is my version of the ADBOp routine. It mainly just calls the - * hardware-specific routine. - * - * data : pointer to data area to be used by compRout - * compRout : completion routine - * buffer : for LISTEN: points to data to send - MAX 8 data bytes, - * byte 0 = # of bytes - * : for TALK: points to place to save return data - * command : the adb command to send - * result : 0 = success - * : -1 = could not complete - */ -int -adb_op(Ptr buffer, Ptr compRout, Ptr data, short command) -{ - int result; - - switch (adbHardware) { - case ADB_HW_PMU: - result = pm_adb_op((u_char *)buffer, (void *)compRout, - (void *)data, (int)command); - - if (result == 0) - return 0; - else - return -1; - break; - - case ADB_HW_CUDA: - result = send_adb_cuda((u_char *)0, (u_char *)buffer, - (void *)compRout, (void *)data, (int)command); - if (result == 0) - return 0; - else - return -1; - break; - - default: - return -1; - } -} - - -/* - * adb_hw_setup - * This routine sets up the possible machine specific hardware - * config (mainly VIA settings) for the various models. - */ -void -adb_hw_setup(void) -{ - volatile int i; - - switch (adbHardware) { - - case ADB_HW_PMU: - /* - * XXX - really PM_VIA_CLR_INTR - should we put it in - * pm_direct.h? - */ - write_via_reg(VIA1, vIFR, 0x90); /* clear interrupt */ - break; - - case ADB_HW_CUDA: - via_reg_or(VIA1, vDirB, 0x30); /* register B bits 4 and 5: - * outputs */ - via_reg_and(VIA1, vDirB, 0xf7); /* register B bit 3: input */ - via_reg_and(VIA1, vACR, ~vSR_OUT); /* make sure SR is set - * to IN */ - write_via_reg(VIA1, vACR, (read_via_reg(VIA1, vACR) | 0x0c) & ~0x10); - adbActionState = ADB_ACTION_IDLE; /* used by all types of - * hardware */ - write_via_reg(VIA1, vIER, 0x84);/* make sure VIA interrupts - * are on */ - ADB_SET_STATE_IDLE_CUDA(); /* set ADB bus state to idle */ - - /* sort of a device reset */ - i = ADB_SR(); /* clear interrupt */ - ADB_VIA_INTR_DISABLE(); /* no interrupts while clearing */ - ADB_SET_STATE_IDLE_CUDA(); /* reset state to idle */ - delay(ADB_DELAY); - ADB_SET_STATE_TIP(); /* signal start of frame */ - delay(ADB_DELAY); - ADB_TOGGLE_STATE_ACK_CUDA(); - delay(ADB_DELAY); - ADB_CLR_STATE_TIP(); - delay(ADB_DELAY); - ADB_SET_STATE_IDLE_CUDA(); /* back to idle state */ - i = ADB_SR(); /* clear interrupt */ - ADB_VIA_INTR_ENABLE(); /* ints ok now */ - break; - - case ADB_HW_UNKNOWN: - default: - write_via_reg(VIA1, vIER, 0x04);/* turn interrupts off - TO - * DO: turn PB ints off? */ - break; - } -} - -/* - * adb_reinit sets up the adb stuff - * - */ -void -adb_reinit(void) -{ - u_char send_string[ADB_MAX_MSG_LENGTH]; - ADBDataBlock data; /* temp. holder for getting device info */ - volatile int i, x; - int s; - int command; - int result; - int saveptr; /* point to next free relocation address */ - int device; - int nonewtimes; /* times thru loop w/o any new devices */ - - /* Make sure we are not interrupted while building the table. */ - if (adbHardware != ADB_HW_PMU) /* ints must be on for PB? */ - s = splhigh(); - - ADBNumDevices = 0; /* no devices yet */ - - /* Let intr routines know we are running reinit */ - adbStarting = 1; - - /* - * Initialize the ADB table. For now, we'll always use the same table - * that is defined at the beginning of this file - no mallocs. - */ - for (i = 0; i < 16; i++) - ADBDevTable[i].devType = 0; - - adb_setup_hw_type(); /* setup hardware type */ - - adb_hw_setup(); /* init the VIA bits and hard reset ADB */ - - delay(1000); - - /* send an ADB reset first */ - adb_op_sync((Ptr)0, (Ptr)0, (Ptr)0, (short)0x00); - delay(200000); - - /* - * Probe for ADB devices. Probe devices 1-15 quickly to determine - * which device addresses are in use and which are free. For each - * address that is in use, move the device at that address to a higher - * free address. Continue doing this at that address until no device - * responds at that address. Then move the last device that was moved - * back to the original address. Do this for the remaining addresses - * that we determined were in use. - * - * When finished, do this entire process over again with the updated - * list of in use addresses. Do this until no new devices have been - * found in 20 passes though the in use address list. (This probably - * seems long and complicated, but it's the best way to detect multiple - * devices at the same address - sometimes it takes a couple of tries - * before the collision is detected.) - */ - - /* initial scan through the devices */ - for (i = 1; i < 16; i++) { - send_string[0] = 0; - command = ADBTALK(i, 3); - result = adb_op_sync((Ptr)send_string, (Ptr)0, - (Ptr)0, (short)command); - - if (send_string[0] != 0) { - /* check for valid device handler */ - switch (send_string[2]) { - case 0: - case 0xfd: - case 0xfe: - case 0xff: - continue; /* invalid, skip */ - } - - /* found a device */ - ++ADBNumDevices; - KASSERT(ADBNumDevices < 16); - ADBDevTable[ADBNumDevices].devType = - (int)send_string[2]; - ADBDevTable[ADBNumDevices].origAddr = i; - ADBDevTable[ADBNumDevices].currentAddr = i; - ADBDevTable[ADBNumDevices].DataAreaAddr = - (long)0; - ADBDevTable[ADBNumDevices].ServiceRtPtr = (void *)0; - } - } - - /* find highest unused address */ - for (saveptr = 15; saveptr > 0; saveptr--) - if (-1 == get_adb_info(&data, saveptr)) - break; - -#ifdef ADB_DEBUG - if (adb_debug & 0x80) { - printf_intr("first free is: 0x%02x\n", saveptr); - printf_intr("devices: %i\n", ADBNumDevices); - } -#endif - - nonewtimes = 0; /* no loops w/o new devices */ - while (saveptr > 0 && nonewtimes++ < 11) { - for (i = 1; i <= ADBNumDevices; i++) { - device = ADBDevTable[i].currentAddr; -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("moving device 0x%02x to 0x%02x " - "(index 0x%02x) ", device, saveptr, i); -#endif - - /* send TALK R3 to address */ - command = ADBTALK(device, 3); - adb_op_sync((Ptr)send_string, (Ptr)0, - (Ptr)0, (short)command); - - /* move device to higher address */ - command = ADBLISTEN(device, 3); - send_string[0] = 2; - send_string[1] = (u_char)(saveptr | 0x60); - send_string[2] = 0xfe; - adb_op_sync((Ptr)send_string, (Ptr)0, - (Ptr)0, (short)command); - delay(500); - - /* send TALK R3 - anything at new address? */ - command = ADBTALK(saveptr, 3); - adb_op_sync((Ptr)send_string, (Ptr)0, - (Ptr)0, (short)command); - delay(500); - - if (send_string[0] == 0) { -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("failed, continuing\n"); -#endif - continue; - } - - /* send TALK R3 - anything at old address? */ - command = ADBTALK(device, 3); - result = adb_op_sync((Ptr)send_string, (Ptr)0, - (Ptr)0, (short)command); - if (send_string[0] != 0) { - /* check for valid device handler */ - switch (send_string[2]) { - case 0: - case 0xfd: - case 0xfe: - case 0xff: - continue; /* invalid, skip */ - } - - /* new device found */ - /* update data for previously moved device */ - ADBDevTable[i].currentAddr = saveptr; -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("old device at index %i\n",i); -#endif - /* add new device in table */ -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("new device found\n"); -#endif - if (saveptr > ADBNumDevices) { - ++ADBNumDevices; - KASSERT(ADBNumDevices < 16); - } - ADBDevTable[ADBNumDevices].devType = - (int)send_string[2]; - ADBDevTable[ADBNumDevices].origAddr = device; - ADBDevTable[ADBNumDevices].currentAddr = device; - /* These will be set correctly in adbsys.c */ - /* Until then, unsol. data will be ignored. */ - ADBDevTable[ADBNumDevices].DataAreaAddr = - (long)0; - ADBDevTable[ADBNumDevices].ServiceRtPtr = - (void *)0; - /* find next unused address */ - for (x = saveptr; x > 0; x--) { - if (-1 == get_adb_info(&data, x)) { - saveptr = x; - break; - } - } - if (x == 0) - saveptr = 0; -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("new free is 0x%02x\n", - saveptr); -#endif - nonewtimes = 0; - } else { -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("moving back...\n"); -#endif - /* move old device back */ - command = ADBLISTEN(saveptr, 3); - send_string[0] = 2; - send_string[1] = (u_char)(device | 0x60); - send_string[2] = 0xfe; - adb_op_sync((Ptr)send_string, (Ptr)0, - (Ptr)0, (short)command); - delay(1000); - } - } - } - -#ifdef ADB_DEBUG - if (adb_debug) { - for (i = 1; i <= ADBNumDevices; i++) { - x = get_ind_adb_info(&data, i); - if (x != -1) - printf_intr("index 0x%x, addr 0x%x, type 0x%x\n", - i, x, data.devType); - } - } -#endif - -#ifdef ADB_DEBUG - if (adb_debug) { - if (0 == ADBNumDevices) /* tell user if no devices found */ - printf_intr("adb: no devices found\n"); - } -#endif - - adbStarting = 0; /* not starting anymore */ -#ifdef ADB_DEBUG - if (adb_debug) - printf_intr("adb: ADBReInit complete\n"); -#endif - - if (adbHardware == ADB_HW_CUDA) { - timeout_set(&adb_cuda_timeout, (void *)adb_cuda_tickle, NULL); - timeout_add(&adb_cuda_timeout, ADB_TICKLE_TICKS); - } - - if (adbHardware != ADB_HW_PMU) /* ints must be on for PB? */ - splx(s); -} - - -/* - * adb_cmd_result - * - * This routine lets the caller know whether the specified adb command string - * should expect a returned result, such as a TALK command. - * - * returns: 0 if a result should be expected - * 1 if a result should NOT be expected - */ -int -adb_cmd_result(u_char *in) -{ - switch (adbHardware) { - case ADB_HW_CUDA: - /* was it an ADB talk command? */ - if ((in[1] == 0x00) && ((in[2] & 0x0c) == 0x0c)) - return 0; - /* was it an RTC/PRAM read date/time? */ - if ((in[1] == 0x01) && (in[2] == 0x03)) - return 0; - return 1; - - case ADB_HW_PMU: - return 1; - - default: - return 1; - } -} - - -/* - * adb_op_sync - * - * This routine does exactly what the adb_op routine does, except that after - * the adb_op is called, it waits until the return value is present before - * returning. - * - * NOTE: The user specified compRout is ignored, since this routine specifies - * it's own to adb_op, which is why you really called this in the first place - * anyway. - */ -int -adb_op_sync(Ptr buffer, Ptr compRout, Ptr data, short command) -{ - int tmout; - int result; - volatile int flag = 0; - - result = adb_op(buffer, (void *)adb_op_comprout, - (void *)&flag, command); /* send command */ - if (result == 0) { /* send ok? */ - /* - * Total time to wait is calculated as follows: - * - Tlt (stop to start time): 260 usec - * - start bit: 100 usec - * - up to 8 data bytes: 64 * 100 usec = 6400 usec - * - stop bit (with SRQ): 140 usec - * Total: 6900 usec - * - * This is the total time allowed by the specification. Any - * device that doesn't conform to this will fail to operate - * properly on some Apple systems. In spite of this we - * double the time to wait; some Cuda-based apparently - * queues some commands and allows the main CPU to continue - * processing (radical concept, eh?). To be safe, allow - * time for two complete ADB transactions to occur. - */ - for (tmout = 13800; !flag && tmout >= 10; tmout -= 10) - delay(10); - if (!flag && tmout > 0) - delay(tmout); - - if (!flag) - result = -2; - } - - return result; -} - - -/* - * adb_op_comprout - * - * This function is used by the adb_op_sync routine so it knows when the - * function is done. - */ -void -adb_op_comprout(buffer, compdata, cmd) - caddr_t buffer, compdata; - int cmd; -{ - short *p = (short *)compdata; - - *p = 1; -} - -void -adb_setup_hw_type(void) -{ - switch (adbHardware) { - case ADB_HW_CUDA: - adbSoftPower = 1; - return; - - case ADB_HW_PMU: - adbSoftPower = 1; - pm_setup_adb(); - return; - - default: - panic("unknown adb hardware"); - } -} - -int -count_adbs(void) -{ - int i; - int found; - - found = 0; - - for (i = 1; i < 16; i++) - if (0 != ADBDevTable[i].devType) - found++; - - return found; -} - -int -get_ind_adb_info(ADBDataBlock * info, int index) -{ - if ((index < 1) || (index > 15)) /* check range 1-15 */ - return (-1); - -#ifdef ADB_DEBUG - if (adb_debug & 0x80) - printf_intr("index 0x%x devType is: 0x%x\n", index, - ADBDevTable[index].devType); -#endif - if (0 == ADBDevTable[index].devType) /* make sure it's a valid entry */ - return (-1); - - info->devType = ADBDevTable[index].devType; - info->origADBAddr = ADBDevTable[index].origAddr; - info->dbServiceRtPtr = (Ptr)ADBDevTable[index].ServiceRtPtr; - info->dbDataAreaAddr = (Ptr)ADBDevTable[index].DataAreaAddr; - - return (ADBDevTable[index].currentAddr); -} - -int -get_adb_info(ADBDataBlock * info, int adbAddr) -{ - int i; - - if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */ - return (-1); - - for (i = 1; i < 15; i++) - if (ADBDevTable[i].currentAddr == adbAddr) { - info->devType = ADBDevTable[i].devType; - info->origADBAddr = ADBDevTable[i].origAddr; - info->dbServiceRtPtr = (Ptr)ADBDevTable[i].ServiceRtPtr; - info->dbDataAreaAddr = ADBDevTable[i].DataAreaAddr; - return 0; /* found */ - } - - return (-1); /* not found */ -} - -int -set_adb_info(ADBSetInfoBlock * info, int adbAddr) -{ - int i; - - if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */ - return (-1); - - for (i = 1; i < 15; i++) - if (ADBDevTable[i].currentAddr == adbAddr) { - ADBDevTable[i].ServiceRtPtr = - (void *)(info->siServiceRtPtr); - ADBDevTable[i].DataAreaAddr = info->siDataAreaAddr; - return 0; /* found */ - } - - return (-1); /* not found */ - -} - -/* caller should really use machine-independent version: getPramTime */ -/* this version does pseudo-adb access only */ -int -adb_read_date_time(time_t *time) -{ - u_char output[ADB_MAX_MSG_LENGTH]; - int result; - int retcode; - volatile int flag = 0; - - switch (adbHardware) { - case ADB_HW_PMU: - pm_read_date_time(time); - retcode = 0; - break; - - case ADB_HW_CUDA: - output[0] = 0x02; /* 2 byte message */ - output[1] = 0x01; /* to pram/rtc device */ - output[2] = 0x03; /* read date/time */ - result = send_adb_cuda((u_char *)output, (u_char *)output, - (void *)adb_op_comprout, (void *)&flag, (int)0); - if (result != 0) { /* exit if not sent */ - retcode = -1; - break; - } - - while (0 == flag) /* wait for result */ - ; - - delay(20); /* completion occurs too soon? */ - memcpy(time, output + 1, 4); - retcode = 0; - break; - - case ADB_HW_UNKNOWN: - default: - retcode = -1; - break; - } - if (retcode == 0) { -#define DIFF19041970 2082844800 - *time -= DIFF19041970; - - } else { - *time = 0; - } - return retcode; -} - -/* caller should really use machine-independent version: setPramTime */ -/* this version does pseudo-adb access only */ -int -adb_set_date_time(time_t time) -{ - u_char output[ADB_MAX_MSG_LENGTH]; - int result; - volatile int flag = 0; - - time += DIFF19041970; - switch (adbHardware) { - - case ADB_HW_CUDA: - output[0] = 0x06; /* 6 byte message */ - output[1] = 0x01; /* to pram/rtc device */ - output[2] = 0x09; /* set date/time */ - output[3] = (u_char)(time >> 24); - output[4] = (u_char)(time >> 16); - output[5] = (u_char)(time >> 8); - output[6] = (u_char)(time); - result = send_adb_cuda((u_char *)output, (u_char *)0, - (void *)adb_op_comprout, (void *)&flag, (int)0); - if (result != 0) /* exit if not sent */ - return -1; - - while (0 == flag) /* wait for send to finish */ - ; - - return 0; - - case ADB_HW_PMU: - pm_set_date_time(time); - return 0; - - default: - return -1; - } -} - - -int -adb_poweroff(void) -{ - u_char output[ADB_MAX_MSG_LENGTH]; - int result; - - if (!adbSoftPower) - return -1; - - adb_polling = 1; - - switch (adbHardware) { - case ADB_HW_PMU: - pm_adb_poweroff(); - - for (;;); /* wait for power off */ - - return 0; - - case ADB_HW_CUDA: - output[0] = 0x02; /* 2 byte message */ - output[1] = 0x01; /* to pram/rtc/soft-power device */ - output[2] = 0x0a; /* set date/time */ - result = send_adb_cuda((u_char *)output, (u_char *)0, - (void *)0, (void *)0, (int)0); - if (result != 0) /* exit if not sent */ - return -1; - - for (;;); /* wait for power off */ - - return 0; - - default: - return -1; - } -} - -int -CountADBs(void) -{ - return (count_adbs()); -} - -void -ADBReInit(void) -{ - adb_reinit(); -} - -int -GetIndADB(ADBDataBlock * info, int index) -{ - return (get_ind_adb_info(info, index)); -} - -int -SetADBInfo(ADBSetInfoBlock * info, int adbAddr) -{ - return (set_adb_info(info, adbAddr)); -} - -void -setsoftadb() -{ - if (!timeout_initialized(&adb_softintr_timeout)) - timeout_set(&adb_softintr_timeout, (void *)adb_soft_intr, NULL); - timeout_add(&adb_softintr_timeout, 1); -} - -void -adb_cuda_autopoll() -{ - volatile int flag = 0; - int result; - u_char output[16]; - - output[0] = 0x03; /* 3-byte message */ - output[1] = 0x01; /* to pram/rtc device */ - output[2] = 0x01; /* cuda autopoll */ - output[3] = 0x01; - result = send_adb_cuda(output, output, adb_op_comprout, - (void *)&flag, 0); - if (result != 0) /* exit if not sent */ - return; - - while (flag == 0); /* wait for result */ -} - -void -adb_restart() -{ - int result; - u_char output[16]; - - adb_polling = 1; - - switch (adbHardware) { - case ADB_HW_CUDA: - output[0] = 0x02; /* 2 byte message */ - output[1] = 0x01; /* to pram/rtc/soft-power device */ - output[2] = 0x11; /* restart */ - result = send_adb_cuda((u_char *)output, (u_char *)0, - (void *)0, (void *)0, (int)0); - if (result != 0) /* exit if not sent */ - return; - while (1); /* not return */ - - case ADB_HW_PMU: - pm_adb_restart(); - while (1); /* not return */ - } -} diff --git a/sys/arch/macppc/dev/adbvar.h b/sys/arch/macppc/dev/adbvar.h index 23fccd06e35..06b63af60e3 100644 --- a/sys/arch/macppc/dev/adbvar.h +++ b/sys/arch/macppc/dev/adbvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: adbvar.h,v 1.7 2005/12/22 22:55:25 miod Exp $ */ +/* $OpenBSD: adbvar.h,v 1.8 2006/01/18 23:21:17 miod Exp $ */ /* $NetBSD: adbvar.h,v 1.3 2000/06/08 22:10:46 tsubai Exp $ */ /*- @@ -31,67 +31,19 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#include <machine/adbsys.h> - -/* - * Arguments used to attach a device to the Apple Desktop Bus - */ -struct adb_attach_args { - int origaddr; - int adbaddr; - int handler_id; -}; - -#ifdef DEBUG -#ifndef ADB_DEBUG -#define ADB_DEBUG -#endif -#endif - -extern int adb_polling; /* Are we polling? (Debugger mode) */ -#ifdef ADB_DEBUG -extern int adb_debug; -#endif - -typedef caddr_t Ptr; - -/* ADB Manager */ -typedef struct { - Ptr siServiceRtPtr; - Ptr siDataAreaAddr; -} ADBSetInfoBlock; -typedef struct { - unsigned char devType; - unsigned char origADBAddr; - Ptr dbServiceRtPtr; - Ptr dbDataAreaAddr; -} ADBDataBlock; - struct adb_softc { struct device sc_dev; char *sc_regbase; }; -/* adb_direct.c */ extern int adbHardware; -/* types of adb hardware that we (will eventually) support */ +/* types of adb hardware that we support */ #define ADB_HW_UNKNOWN 0x01 /* don't know */ #define ADB_HW_PMU 0x04 /* PowerBook series */ #define ADB_HW_CUDA 0x05 /* Machines with a Cuda chip */ -#define ADB_CMDADDR(cmd) ((u_int8_t)((cmd) & 0xf0) >> 4) -#define ADBFLUSH(dev) ((((u_int8_t)(dev) & 0x0f) << 4) | 0x01) -#define ADBLISTEN(dev, reg) ((((u_int8_t)(dev) & 0x0f) << 4) | 0x08 | (reg)) -#define ADBTALK(dev, reg) ((((u_int8_t)(dev) & 0x0f) << 4) | 0x0c | (reg)) - int adb_poweroff(void); -int CountADBs(void); -void ADBReInit(void); -int GetIndADB(ADBDataBlock * info, int index); -int SetADBInfo(ADBSetInfoBlock * info, int adbAddr); +void adb_restart(void); int adb_read_date_time(time_t *t); int adb_set_date_time(time_t t); -int adb_intr(void *arg); -void adb_cuda_autopoll(void); -int adb_op_sync(Ptr, Ptr, Ptr, short); diff --git a/sys/arch/macppc/dev/amsvar.h b/sys/arch/macppc/dev/akbd_machdep.c index 51fe68b6671..cd963894856 100644 --- a/sys/arch/macppc/dev/amsvar.h +++ b/sys/arch/macppc/dev/akbd_machdep.c @@ -1,5 +1,5 @@ -/* $OpenBSD: amsvar.h,v 1.2 2002/03/14 01:26:36 millert Exp $ */ -/* $NetBSD: amsvar.h,v 1.4 1999/06/17 06:59:05 tsubai Exp $ */ +/* $OpenBSD: akbd_machdep.c,v 1.1 2006/01/18 23:21:17 miod Exp $ */ +/* $NetBSD: akbd.c,v 1.13 2001/01/25 14:08:55 tsubai Exp $ */ /* * Copyright (C) 1998 Colin Wood @@ -31,37 +31,77 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _MACPPC_AMSVAR_H_ -#define _MACPPC_AMSVAR_H_ +#include <sys/param.h> +#include <sys/timeout.h> +#include <sys/kernel.h> +#include <sys/device.h> +#include <sys/fcntl.h> +#include <sys/poll.h> +#include <sys/selinfo.h> +#include <sys/proc.h> +#include <sys/signalvar.h> +#include <sys/systm.h> -/* - * State info, per mouse instance. - */ -struct ams_softc { - struct device sc_dev; - - /* ADB info */ - int origaddr; /* ADB device type (ADBADDR_MS) */ - int adbaddr; /* current ADB address */ - int handler_id; /* type of mouse */ - - /* Extended Mouse Protocol info, faked for non-EMP mice */ - u_int8_t sc_class; /* mouse class (mouse, trackball) */ - u_int8_t sc_buttons; /* number of buttons */ - u_int32_t sc_res; /* mouse resolution (dpi) */ - char sc_devid[5]; /* device indentifier */ - - int sc_mb; /* current button state */ - struct device *sc_wsmousedev; +#include <dev/wscons/wsconsio.h> +#include <dev/wscons/wskbdvar.h> + +#include <dev/adb/adb.h> +#include <dev/adb/akbdvar.h> +#include <dev/adb/keyboard.h> + +void akbd_cngetc(void *, u_int *, int *); +void akbd_cnpollc(void *, int); + +struct wskbd_consops akbd_consops = { + akbd_cngetc, + akbd_cnpollc, }; -/* EMP device classes */ -#define MSCLASS_TABLET 0 -#define MSCLASS_MOUSE 1 -#define MSCLASS_TRACKBALL 2 -#define MSCLASS_TRACKPAD 3 +static int _akbd_is_console; + +int +akbd_is_console() +{ + return (_akbd_is_console); +} + +int +akbd_cnattach() +{ + _akbd_is_console = 1; + wskbd_cnattach(&akbd_consops, NULL, &akbd_keymapdata); + return 0; +} + +void +akbd_cngetc(void *v, u_int *type, int *data) +{ + int key, press, val; + int s; + extern int adb_intr(void *); + + s = splhigh(); + + adb_polledkey = -1; + adb_polling = 1; + + while (adb_polledkey == -1) { + adb_intr(NULL); /* adb does not use the argument */ + DELAY(10000); /* XXX */ + } + + adb_polling = 0; + splx(s); + + key = adb_polledkey; + press = ADBK_PRESS(key); + val = ADBK_KEYVAL(key); -void ms_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command); -void ms_handoff(adb_event_t *event, struct ams_softc *); + *data = val; + *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; +} -#endif /* _MACPPC_AMSVAR_H_ */ +void +akbd_cnpollc(void *v, int on) +{ +} diff --git a/sys/arch/macppc/dev/akbdmap.h b/sys/arch/macppc/dev/akbdmap.h deleted file mode 100644 index 3638f85fe57..00000000000 --- a/sys/arch/macppc/dev/akbdmap.h +++ /dev/null @@ -1,453 +0,0 @@ -/* $OpenBSD: akbdmap.h,v 1.12 2005/05/07 15:04:59 miod Exp $ */ -/* $NetBSD: akbdmap.h,v 1.3 2000/09/01 16:00:39 tsubai Exp $ */ - -/*- - * Copyright (c) 1997 The NetBSD Foundation, Inc. - * All rights reserved. - * - * This code is derived from software contributed to The NetBSD Foundation - * by Juergen Hannken-Illjes. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the NetBSD - * Foundation, Inc. and its contributors. - * 4. Neither the name of The NetBSD Foundation nor the names of its - * contributors may be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS - * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED - * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR - * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS - * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/* XXX This list is incomplete. */ - -#define KC(n) KS_KEYCODE(n) - -static const keysym_t akbd_keydesc_us[] = { -/* pos command normal shifted */ - KC(0), KS_a, - KC(1), KS_s, - KC(2), KS_d, - KC(3), KS_f, - KC(4), KS_h, - KC(5), KS_g, - KC(6), KS_z, - KC(7), KS_x, - KC(8), KS_c, - KC(9), KS_v, - - KC(11), KS_b, - KC(12), KS_q, - KC(13), KS_w, - KC(14), KS_e, - KC(15), KS_r, - KC(16), KS_y, - KC(17), KS_t, - KC(18), KS_1, KS_exclam, - KC(19), KS_2, KS_at, - KC(20), KS_3, KS_numbersign, - KC(21), KS_4, KS_dollar, - KC(22), KS_6, KS_asciicircum, - KC(23), KS_5, KS_percent, - KC(24), KS_equal, KS_plus, - KC(25), KS_9, KS_parenleft, - KC(26), KS_7, KS_ampersand, - KC(27), KS_minus, KS_underscore, - KC(28), KS_8, KS_asterisk, - KC(29), KS_0, KS_parenright, - KC(30), KS_bracketright, KS_braceright, - KC(31), KS_o, - KC(32), KS_u, - KC(33), KS_bracketleft, KS_braceleft, - KC(34), KS_i, - KC(35), KS_p, - KC(36), KS_Return, - KC(37), KS_l, - KC(38), KS_j, - KC(39), KS_apostrophe, KS_quotedbl, - KC(40), KS_k, - KC(41), KS_semicolon, KS_colon, - KC(42), KS_backslash, KS_bar, - KC(43), KS_comma, KS_less, - KC(44), KS_slash, KS_question, - KC(45), KS_n, - KC(46), KS_m, - KC(47), KS_period, KS_greater, - KC(48), KS_Tab, - KC(49), KS_space, - KC(50), KS_grave, KS_asciitilde, - KC(51), KS_Delete, - - KC(53), KS_Escape, - KC(54), KS_Control_L, - KC(55), KS_Cmd, /* Command */ - KC(56), KS_Shift_L, - KC(57), KS_Caps_Lock, - KC(58), KS_Cmd1, /* Option */ - KC(59), KS_Left, - KC(60), KS_Right, - KC(61), KS_Down, - KC(62), KS_Up, - - KC(65), KS_KP_Decimal, - KC(67), KS_KP_Multiply, - KC(69), KS_KP_Add, - KC(71), KS_Clear, - KC(75), KS_KP_Divide, - KC(76), KS_KP_Enter, - KC(78), KS_KP_Subtract, - - KC(81), KS_KP_Equal, - KC(82), KS_KP_0, - KC(83), KS_KP_1, - KC(84), KS_KP_2, - KC(85), KS_KP_3, - KC(86), KS_KP_4, - KC(87), KS_KP_5, - KC(88), KS_KP_6, - KC(89), KS_KP_7, - - KC(91), KS_KP_8, - KC(92), KS_KP_9, - - KC(95), KS_comma, /* XXX KS_KP_comma */ - - KC(106), KS_KP_Enter, - - KC(115), KS_KP_Home, - KC(116), KS_KP_Prior, - KC(119), KS_KP_End, - KC(121), KS_KP_Next, - - KC(127), KS_Cmd_Debugger, -}; - -static const keysym_t akbd_keydesc_fr[] = { -/* pos normal shifted altgr shift-altgr */ - KC(0), KS_q, - KC(1), KS_s, KS_S, KS_Ograve, - KC(4), KS_h, KS_H, KS_Igrave, KS_Icircumflex, - KC(6), KS_w, - KC(10), KS_at, KS_numbersign, - KC(11), KS_b, KS_B, KS_ssharp, - KC(12), KS_a, KS_A, KS_ae, KS_AE, - KC(13), KS_z, KS_Z, KS_Acircumflex, KS_Aring, - KC(14), KS_e, KS_E, KS_ecircumflex, KS_Ecircumflex, - KC(15), KS_r, KS_R, KS_registered, KS_comma, - KC(16), KS_y, KS_Y, KS_Uacute, - KC(18), KS_ampersand, KS_1, - KC(19), KS_eacute, KS_2, KS_ediaeresis, - KC(20), KS_quotedbl, KS_3, - KC(21), KS_apostrophe, KS_4, - KC(22), KS_section, KS_6, - KC(23), KS_parenleft, KS_5, KS_braceleft, KS_bracketleft, - KC(24), KS_minus, KS_underscore, - KC(25), KS_ccedilla, KS_9, KS_Ccedilla, KS_Aacute, - KC(26), KS_egrave, KS_7, KS_guillemotleft, - KS_guillemotright, - KC(27), KS_parenright, KS_degree, KS_braceright, KS_bracketright, - KC(28), KS_exclam, KS_8, KS_exclamdown, KS_Ucircumflex, - KC(29), KS_agrave, KS_0, KS_oslash, KS_Ooblique, - KC(30), KS_dollar, KS_asterisk, KS_cent, KS_yen, - KC(33), KS_dead_circumflex, KS_dead_diaeresis, - KS_ocircumflex, KS_Ocircumflex, - KC(34), KS_i, KS_I, KS_icircumflex, KS_idiaeresis, - KC(37), KS_l, KS_L, KS_voidSymbol, KS_bar, - KC(38), KS_j, KS_J, KS_Idiaeresis, KS_Iacute, - KC(39), KS_ugrave, KS_percent, KS_Ugrave, - KC(40), KS_k, KS_K, KS_Egrave, KS_Ediaeresis, - KC(41), KS_m, KS_M, KS_mu, KS_Oacute, - KC(42), KS_grave, KS_sterling, KS_at, KS_numbersign, - KC(43), KS_semicolon, KS_period, - KC(44), KS_equal, KS_plus, - KC(45), KS_n, KS_N, KS_asciitilde, - KC(46), KS_comma, KS_question, KS_voidSymbol, KS_questiondown, - KC(47), KS_colon, KS_slash, KS_voidSymbol, KS_backslash, - KC(50), KS_less, KS_greater, - KC(52), KS_Alt_R, - KC(55), KS_Meta_L, /* Command */ - KC(58), KS_Mode_switch, KS_Multi_key, /* Option */ -}; - -#if 0 -static const keysym_t akbd_keydesc_jp[] = { -/* pos command normal shifted */ - KC(42), KS_grave, KS_asciitilde, - KC(93), KS_backslash, KS_bar, -}; -#endif - -static const keysym_t akbd_keydesc_uk[] = { -/* pos normal shifted altgr shift-altgr */ - KC(10), KS_section, KS_plusminus, - KC(20), KS_3, KS_sterling, KS_numbersign, - KC(52), KS_KP_Enter, - KC(58), KS_Mode_switch, KS_Multi_key, /* Option */ -}; - -static const keysym_t akbd_keydesc_sv[] = { -/* pos normal shifted altgr shift-altgr */ - KC(10), KS_section, KS_degree, - KC(19), KS_2, KS_quotedbl, KS_at, - KC(21), KS_4, KS_dollar, - KC(22), KS_6, KS_ampersand, - KC(24), KS_dead_acute, KS_dead_grave, - KC(25), KS_9, KS_parenright, KS_bracketright, - KC(26), KS_7, KS_slash, KS_braceleft, - KC(27), KS_plus, KS_question, KS_backslash, - KC(28), KS_8, KS_parenleft, KS_bracketleft, - KC(29), KS_0, KS_equal, KS_braceright, - KC(30), KS_dead_diaeresis, KS_dead_circumflex, KS_dead_tilde, - KC(33), KS_aring, - KC(39), KS_adiaeresis, - KC(41), KS_odiaeresis, - KC(42), KS_apostrophe, KS_asterisk, - KC(43), KS_comma, KS_semicolon, - KC(44), KS_minus, KS_underscore, - KC(47), KS_period, KS_colon, - KC(50), KS_less, KS_greater, KS_bar, - KC(52), KS_Mode_switch, KS_Multi_key, -}; - -static const keysym_t akbd_keydesc_sv_nodead[] = { -/* pos normal shifted altgr shift-altgr */ - KC(24), KS_apostrophe, KS_grave, - KC(30), KS_diaeresis, KS_asciicircum, KS_asciitilde, -}; - -static const keysym_t akbd_keydesc_de[] = { -/* pos normal shifted altgr shift-altgr */ - KC(0), KS_a, KS_A, KS_aring, KS_Aring, - KC(1), KS_s, KS_S, KS_voidSymbol, KS_Iacute, - KC(3), KS_f, KS_F, KS_voidSymbol, KS_Idiaeresis, - KC(4), KS_h, KS_H, KS_ordfeminine, KS_Oacute, - KC(5), KS_g, KS_G, KS_copyright, KS_Igrave, - KC(6), KS_y, KS_Y, KS_yen, - KC(7), KS_x, KS_X, KS_voidSymbol, KS_Ugrave, - KC(8), KS_c, KS_C, KS_ccedilla, KS_Ccedilla, - KC(10), KS_dead_circumflex, KS_degree, - KC(12), KS_q, KS_Q, KS_guillemotleft, KS_guillemotright, - KC(15), KS_r, KS_R, KS_registered, KS_cedilla, - KC(16), KS_z, KS_Z, - KC(18), KS_1, KS_exclam, KS_exclamdown, KS_notsign, - KC(19), KS_2, KS_quotedbl, - KC(20), KS_3, KS_section, KS_paragraph, KS_numbersign, - KC(21), KS_4, KS_dollar, KS_cent, KS_sterling, - KC(22), KS_6, KS_ampersand, KS_bracketright,KS_dead_circumflex, - KC(23), KS_5, KS_percent, KS_bracketleft, - KC(24), KS_dead_acute, KS_dead_grave, KS_apostrophe, - KC(25), KS_9, KS_parenright, KS_braceright, KS_periodcentered, - KC(26), KS_7, KS_slash, KS_bar, KS_backslash, - KC(27), KS_ssharp, KS_question, KS_questiondown, - KC(28), KS_8, KS_parenleft, KS_braceleft, - KC(29), KS_0, KS_equal, KS_voidSymbol, KS_macron, - KC(30), KS_plus, KS_asterisk, KS_plusminus, - KC(31), KS_o, KS_O, KS_oslash, KS_Ooblique, - KC(32), KS_u, KS_U, KS_dead_diaeresis, KS_Aacute, - KC(33), KS_udiaeresis, KS_Udiaeresis, KS_voidSymbol, KS_degree, - KC(34), KS_i, KS_I, KS_voidSymbol, KS_Ucircumflex, - KC(37), KS_l, KS_L, KS_at, - KC(38), KS_j, KS_J, KS_masculine, - KC(39), KS_adiaeresis, KS_Adiaeresis, KS_ae, KS_AE, - KC(41), KS_odiaeresis, KS_Odiaeresis, - KC(42), KS_numbersign, KS_apostrophe, - KC(43), KS_comma, KS_semicolon, - KC(44), KS_minus, KS_underscore, - KC(45), KS_n, KS_N, KS_dead_tilde, - KC(46), KS_m, KS_M, KS_mu, - KC(47), KS_period, KS_colon, - KC(50), KS_less, KS_greater, - KC(52), KS_Multi_key, - KC(58), KS_Mode_switch, -}; - -static const keysym_t akbd_keydesc_de_nodead[] = { -/* pos normal shifted altgr shift-altgr */ - KC(10), KS_asciicircum, KS_degree, - KC(22), KS_6, KS_ampersand, KS_bracketright,KS_asciicircum, - KC(24), KS_acute, KS_grave, KS_apostrophe, - KC(32), KS_u, KS_U, KS_diaeresis, KS_Aacute, - KC(45), KS_n, KS_N, KS_asciitilde, -}; - -static const keysym_t akbd_keydesc_sf[] = { - KC(6), KS_y, - KC(10), KS_paragraph, KS_degree, - KC(16), KS_z, - KC(18), KS_plus, KS_1, - KC(19), KS_quotedbl, KS_2, - KC(20), KS_asterisk, KS_3, - KC(21), KS_ccedilla, KS_4, KS_Ccedilla, - KC(22), KS_ampersand, KS_6, - KC(23), KS_percent, KS_5, - KC(24), KS_dead_circumflex, KS_grave, - KC(25), KS_parenright, KS_9, - KC(26), KS_slash, KS_7, - KC(27), KS_apostrophe, KS_question, - KC(28), KS_parenleft, KS_8, - KC(29), KS_equal, KS_0, - KC(30), KS_dead_diaeresis, KS_exclam, - KC(33), KS_egrave, KS_udiaeresis, - KC(39), KS_agrave, KS_adiaeresis, - KC(41), KS_eacute, KS_odiaeresis, - KC(42), KS_dollar, KS_sterling, - KC(43), KS_period, KS_colon, - KC(46), KS_comma, KS_semicolon, - KC(47), KS_minus, KS_underscore, - KC(50), KS_less, KS_greater, -}; - -static const keysym_t akbd_keydesc_us_dvorak[] = { -/* pos command normal shifted */ - KC(1), KS_o, - KC(2), KS_e, - KC(3), KS_u, - KC(4), KS_d, - KC(5), KS_i, - KC(6), KS_semicolon, KS_colon, - KC(7), KS_q, - KC(8), KS_j, - KC(9), KS_k, - KC(11), KS_x, - KC(12), KS_apostrophe, KS_quotedbl, - KC(13), KS_comma, KS_less, - KC(14), KS_period, KS_greater, - KC(15), KS_p, - KC(16), KS_f, - KC(17), KS_y, - KC(24), KS_bracketright, KS_braceright, - KC(27), KS_bracketleft, KS_braceleft, - KC(30), KS_equal, KS_plus, - KC(31), KS_r, - KC(32), KS_g, - KC(33), KS_slash, KS_question, - KC(34), KS_c, - KC(35), KS_l, - KC(37), KS_n, - KC(38), KS_h, - KC(39), KS_minus, KS_underscore, - KC(40), KS_t, - KC(41), KS_s, - KC(43), KS_w, - KC(44), KS_z, - KC(45), KS_b, - KC(47), KS_v, -}; - -static const keysym_t akbd_keydesc_sg[] = { -/* pos normal shifted altgr shift-altgr */ - KC(0), KS_a, KS_A, KS_aring, KS_Aring, - KC(1), KS_s, KS_S, KS_ssharp, KS_voidSymbol, - KC(3), KS_f, KS_F, KS_section, KS_voidSymbol, - KC(4), KS_h, KS_H, KS_ordfeminine, KS_periodcentered, - KC(5), KS_g, KS_G, KS_at, KS_comma, - KC(6), KS_y, KS_Y, KS_yen, KS_ydiaeresis, - KC(7), KS_x, KS_X, KS_voidSymbol, KS_ydiaeresis, - KC(8), KS_c, KS_C, KS_copyright, - KC(10), KS_section, KS_degree, - KC(12), KS_q, KS_Q, - KC(15), KS_r, KS_R, KS_registered, KS_Egrave, - KC(16), KS_z, KS_Z, KS_voidSymbol, KS_Aacute, - KC(18), KS_1, KS_plus, KS_plusminus, KS_onesuperior, - KC(19), KS_2, KS_quotedbl, KS_twosuperior, - KC(20), KS_3, KS_asterisk, KS_numbersign, KS_threesuperior, - KC(21), KS_4, KS_ccedilla, KS_Ccedilla, - KC(22), KS_6, KS_ampersand, KS_bracketright, - KC(23), KS_5, KS_percent, KS_bracketleft, - KC(24), KS_dead_circumflex,KS_dead_grave,KS_dead_acute, KS_asciitilde, - KC(25), KS_9, KS_parenright, KS_braceright, KS_Ocircumflex, - KC(26), KS_7, KS_slash, KS_bar, KS_backslash, - KC(27), KS_apostrophe, KS_question, KS_questiondown, - KC(28), KS_8, KS_parenleft, KS_braceleft, KS_Ograve, - KC(29), KS_0, KS_equal, KS_voidSymbol, KS_Uacute, - KC(30), KS_dead_diaeresis,KS_exclam, KS_bracketright, - KC(31), KS_o, KS_O, KS_oslash, - KC(32), KS_u, KS_U, KS_degree, KS_Ugrave, - KC(33), KS_udiaeresis, KS_egrave, KS_bracketleft, - KC(34), KS_i, KS_I, KS_exclamdown, - KC(37), KS_l, KS_L, KS_notsign, - KC(38), KS_j, KS_J, KS_masculine, - KC(39), KS_adiaeresis, KS_agrave, KS_ae, KS_AE, - KC(41), KS_odiaeresis, KS_eacute, KS_cent, - KC(42), KS_dollar, KS_sterling, KS_paragraph, - KC(43), KS_comma, KS_semicolon, KS_guillemotleft,KS_guillemotright, - KC(44), KS_minus, KS_underscore, - KC(45), KS_n, KS_N, KS_dead_tilde, - KC(46), KS_m, KS_M, KS_mu, - KC(47), KS_period, KS_colon, KS_voidSymbol, KS_division, - KC(50), KS_less, KS_greater, - KC(52), KS_Multi_key, - KC(58), KS_Mode_switch, -}; - -static const keysym_t akbd_keydesc_sg_nodead[] = { -/* pos normal shifted altgr shift-altgr */ - KC(24), KS_asciicircum, KS_grave, KS_acute, KS_asciitilde, - KC(30), KS_diaeresis, KS_exclam, KS_bracketright,KS_braceright, - KC(45), KS_n, KS_N, KS_asciitilde, -}; - -static const keysym_t akbd_keydesc_pt[] = { -/* pos normal shifted altgr shift-altgr */ - KC(7), KS_x, KS_X, KS_guillemotleft, KS_guillemotright, - KC(10), KS_section, KS_plusminus, - KC(19), KS_2, KS_quotedbl, KS_at, - KC(20), KS_3, KS_numbersign, KS_sterling, - KC(22), KS_6, KS_ampersand, - KC(24), KS_plus, KS_asterisk, - KC(25), KS_9, KS_parenright, KS_bracketright, KS_braceright, - KC(26), KS_7, KS_slash, - KC(27), KS_apostrophe, KS_question, - KC(28), KS_8, KS_parenleft, KS_bracketleft, KS_braceleft, - KC(29), KS_0, KS_equal, - KC(30), KS_dead_acute, KS_dead_grave, - KC(33), KS_masculine, KS_ordfeminine, - KC(39), KS_dead_tilde, KS_dead_circumflex, - KC(41), KS_ccedilla, KS_Ccedilla, - KC(43), KS_comma, KS_semicolon, - KC(44), KS_minus, KS_underscore, - KC(47), KS_period, KS_colon, - KC(50), KS_less, KS_greater, - KC(52), KS_Multi_key, - KC(58), KS_Mode_switch, -}; - -#define KBD_MAP(name, base, map) \ - { name, base, sizeof(map)/sizeof(keysym_t), map } - -const struct wscons_keydesc akbd_keydesctab[] = { - KBD_MAP(KB_US, 0, akbd_keydesc_us), - KBD_MAP(KB_US | KB_DVORAK, KB_US, akbd_keydesc_us_dvorak), - KBD_MAP(KB_FR, KB_US, akbd_keydesc_fr), - KBD_MAP(KB_SF, KB_US, akbd_keydesc_sf), - KBD_MAP(KB_SV, KB_US, akbd_keydesc_sv), - KBD_MAP(KB_SV | KB_NODEAD, KB_SV, akbd_keydesc_sv_nodead), - KBD_MAP(KB_DE, KB_US, akbd_keydesc_de), - KBD_MAP(KB_DE | KB_NODEAD, KB_DE, akbd_keydesc_de_nodead), - KBD_MAP(KB_SG, KB_US, akbd_keydesc_sg), - KBD_MAP(KB_SG | KB_NODEAD, KB_SG, akbd_keydesc_sg_nodead), - KBD_MAP(KB_UK, KB_US, akbd_keydesc_uk), - KBD_MAP(KB_PT, KB_US, akbd_keydesc_pt), - {0, 0, 0, 0} -}; - -#undef KBD_MAP -#undef KC diff --git a/sys/arch/macppc/dev/akbdvar.h b/sys/arch/macppc/dev/akbdvar.h deleted file mode 100644 index 2689d719931..00000000000 --- a/sys/arch/macppc/dev/akbdvar.h +++ /dev/null @@ -1,71 +0,0 @@ -/* $OpenBSD: akbdvar.h,v 1.3 2002/03/27 21:48:12 drahn Exp $ */ -/* $NetBSD: akbdvar.h,v 1.4 1999/02/17 14:56:56 tsubai Exp $ */ - -/* - * Copyright (C) 1998 Colin Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Colin Wood. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef _MACPPC_KBDVAR_H_ -#define _MACPPC_KBDVAR_H_ - -#include <machine/adbsys.h> - -/* - * State info, per keyboard instance. - */ -struct akbd_softc { - struct device sc_dev; - - /* ADB info */ - int origaddr; /* ADB device type (ADBADDR_KBD) */ - int adbaddr; /* current ADB address */ - int handler_id; /* type of keyboard */ - - u_int8_t sc_leds; /* current LED state */ - struct device *sc_wskbddev; -#ifdef WSDISPLAY_COMPAT_RAWKBD -#define MAXKEYS 20 -#define REP_DELAY1 400 -#define REP_DELAYN 100 - int sc_rawkbd; - int sc_nrep; - char sc_rep[MAXKEYS]; - struct timeout sc_rawrepeat_ch; -#endif /* defined(WSDISPLAY_COMPAT_RAWKBD) */ -}; - -/* LED register bits, inverse of actual register value */ -#define LED_NUMLOCK 0x1 -#define LED_CAPSLOCK 0x2 -#define LED_SCROLL_LOCK 0x4 - -void kbd_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command); -int akbd_cnattach(void); - -#endif /* _MACPPC_KBDVAR_H_ */ diff --git a/sys/arch/macppc/dev/ams.c b/sys/arch/macppc/dev/ams.c deleted file mode 100644 index 3787b509193..00000000000 --- a/sys/arch/macppc/dev/ams.c +++ /dev/null @@ -1,535 +0,0 @@ -/* $OpenBSD: ams.c,v 1.13 2006/01/08 17:25:06 miod Exp $ */ -/* $NetBSD: ams.c,v 1.11 2000/12/19 03:13:40 tsubai Exp $ */ - -/* - * Copyright (C) 1998 Colin Wood - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by Colin Wood. - * 4. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE - * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include <sys/param.h> -#include <sys/device.h> -#include <sys/fcntl.h> -#include <sys/poll.h> -#include <sys/selinfo.h> -#include <sys/proc.h> -#include <sys/signalvar.h> -#include <sys/systm.h> - -#include <machine/autoconf.h> - -#include <dev/wscons/wsconsio.h> -#include <dev/wscons/wsmousevar.h> - -#include <macppc/dev/adbvar.h> -#include <macppc/dev/amsvar.h> - -/* - * Function declarations. - */ -static int amsmatch(struct device *, void *, void *); -static void amsattach(struct device *, struct device *, void *); -static void ems_init(struct ams_softc *); -static void ms_processevent(adb_event_t *event, struct ams_softc *); - -/* Driver definition. */ -struct cfattach ams_ca = { - sizeof(struct ams_softc), amsmatch, amsattach -}; -/* Driver definition. */ -struct cfdriver ams_cd = { - NULL, "ams", DV_DULL -}; - - -int ams_enable(void *); -int ams_ioctl(void *, u_long, caddr_t, int, struct proc *); -void ams_disable(void *); - -const struct wsmouse_accessops ams_accessops = { - ams_enable, - ams_ioctl, - ams_disable, -}; - -static int -amsmatch(struct device *parent, void *cf, void *aux) -{ - struct adb_attach_args *aa_args = aux; - - if (aa_args->origaddr == ADBADDR_MS) - return 1; - else - return 0; -} - -static void -amsattach(struct device *parent, struct device *self, void *aux) -{ - ADBSetInfoBlock adbinfo; - struct ams_softc *sc = (struct ams_softc *)self; - struct adb_attach_args *aa_args = aux; - int error; - struct wsmousedev_attach_args a; - - sc->origaddr = aa_args->origaddr; - sc->adbaddr = aa_args->adbaddr; - sc->handler_id = aa_args->handler_id; - - sc->sc_class = MSCLASS_MOUSE; - sc->sc_buttons = 1; - sc->sc_res = 100; - sc->sc_devid[0] = 0; - sc->sc_devid[4] = 0; - - adbinfo.siServiceRtPtr = (Ptr)ms_adbcomplete; - adbinfo.siDataAreaAddr = (caddr_t)sc; - - ems_init(sc); - - /* print out the type of mouse we have */ - printf(": "); - switch (sc->handler_id) { - case ADBMS_200DPI: - sc->sc_res = 200; - /* FALLTHROUGH */ - case ADBMS_100DPI: - printf("%d-button, %d dpi mouse\n", sc->sc_buttons, - (int)(sc->sc_res)); - break; - case ADBMS_MSA3: - printf("Mouse Systems A3 mouse, %d-button, %d dpi\n", - sc->sc_buttons, (int)(sc->sc_res)); - break; - case ADBMS_USPEED: - printf("MicroSpeed mouse, default parameters\n"); - break; - case ADBMS_UCONTOUR: - printf("Contour mouse, default parameters\n"); - break; - case ADBMS_TURBO: - printf("Kensington Turbo Mouse\n"); - break; - case ADBMS_EXTENDED: - if (sc->sc_devid[0] == '\0') { - printf("Logitech "); - switch (sc->sc_class) { - case MSCLASS_MOUSE: - printf("MouseMan (non-EMP) mouse"); - break; - case MSCLASS_TRACKBALL: - printf("TrackMan (non-EMP) trackball"); - break; - default: - printf("non-EMP relative positioning device"); - break; - } - printf("\n"); - } else { - printf("EMP "); - switch (sc->sc_class) { - case MSCLASS_TABLET: - printf("tablet"); - break; - case MSCLASS_MOUSE: - printf("mouse"); - break; - case MSCLASS_TRACKBALL: - printf("trackball"); - break; - case MSCLASS_TRACKPAD: - printf("trackpad"); - break; - default: - printf("unknown device"); - break; - } - printf(" <%s> %d-button, %d dpi\n", sc->sc_devid, - sc->sc_buttons, (int)(sc->sc_res)); - } - break; - default: - printf("relative positioning device (mouse?) (%d)\n", - sc->handler_id); - break; - } - error = SetADBInfo(&adbinfo, sc->adbaddr); -#ifdef ADB_DEBUG - if (adb_debug) - printf("ams: returned %d from SetADBInfo\n", error); -#endif - - a.accessops = &ams_accessops; - a.accesscookie = sc; - sc->sc_wsmousedev = config_found(self, &a, wsmousedevprint); -} - - -/* - * Initialize extended mouse support -- probes devices as described - * in Inside Macintosh: Devices, Chapter 5 "ADB Manager". - * - * Extended Mouse Protocol is documented in TechNote HW1: - * "ADB - The Untold Story: Space Aliens Ate My Mouse" - * - * Supports: Extended Mouse Protocol, MicroSpeed Mouse Deluxe, - * Mouse Systems A^3 Mouse, Logitech non-EMP MouseMan - */ -void -ems_init(struct ams_softc *sc) -{ - int adbaddr; - short cmd; - u_char buffer[9]; - - adbaddr = sc->adbaddr; - if (sc->origaddr != ADBADDR_MS) - return; - if (sc->handler_id == ADBMS_USPEED || - sc->handler_id == ADBMS_UCONTOUR) { - /* Found MicroSpeed Mouse Deluxe Mac or Contour Mouse */ - cmd = ADBLISTEN(adbaddr, 1); - - /* - * To setup the MicroSpeed or the Contour, it appears - * that we can send the following command to the mouse - * and then expect data back in the form: - * buffer[0] = 4 (bytes) - * buffer[1], buffer[2] as std. mouse - * buffer[3] = buffer[4] = 0xff when no buttons - * are down. When button N down, bit N is clear. - * buffer[4]'s locking mask enables a - * click to toggle the button down state--sort of - * like the "Easy Access" shift/control/etc. keys. - * buffer[3]'s alternative speed mask enables using - * different speed when the corr. button is down - */ - buffer[0] = 4; - buffer[1] = 0x00; /* Alternative speed */ - buffer[2] = 0x00; /* speed = maximum */ - buffer[3] = 0x10; /* enable extended protocol, - * lower bits = alt. speed mask - * = 0000b - */ - buffer[4] = 0x07; /* Locking mask = 0000b, - * enable buttons = 0111b - */ - adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd); - - sc->sc_buttons = 3; - sc->sc_res = 200; - return; - } - if (sc->handler_id == ADBMS_TURBO) { - /* Found Kensington Turbo Mouse */ - static u_char data1[] = - { 8, 0xe7, 0x8c, 0, 0, 0, 0xff, 0xff, 0x94 }; - static u_char data2[] = - { 8, 0xa5, 0x14, 0, 0, 0x69, 0xff, 0xff, 0x27 }; - - buffer[0] = 0; - adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, ADBFLUSH(adbaddr)); - - adb_op_sync((Ptr)data1, (Ptr)0, (Ptr)0, ADBLISTEN(adbaddr, 2)); - - buffer[0] = 0; - adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, ADBFLUSH(adbaddr)); - - adb_op_sync((Ptr)data2, (Ptr)0, (Ptr)0, ADBLISTEN(adbaddr, 2)); - return; - } - if ((sc->handler_id == ADBMS_100DPI) || - (sc->handler_id == ADBMS_200DPI)) { - /* found a mouse */ - cmd = ADBTALK(adbaddr, 3); - if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd)) { -#ifdef ADB_DEBUG - if (adb_debug) - printf("adb: ems_init timed out\n"); -#endif - return; - } - - /* Attempt to initialize Extended Mouse Protocol */ - buffer[2] = 4; /* make handler ID 4 */ - cmd = ADBLISTEN(adbaddr, 3); - if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd)) { -#ifdef ADB_DEBUG - if (adb_debug) - printf("adb: ems_init timed out\n"); -#endif - return; - } - - /* - * Check to see if successful, if not - * try to initialize it as other types - */ - cmd = ADBTALK(adbaddr, 3); - if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0 && - buffer[2] == ADBMS_EXTENDED) { - sc->handler_id = ADBMS_EXTENDED; - cmd = ADBTALK(adbaddr, 1); - if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd)) { -#ifdef ADB_DEBUG - if (adb_debug) - printf("adb: ems_init timed out\n"); -#endif - } else if (buffer[0] == 8) { - /* we have a true EMP device */ - sc->sc_class = buffer[7]; - sc->sc_buttons = buffer[8]; - sc->sc_res = (int)*(short *)&buffer[5]; - bcopy(&(buffer[1]), sc->sc_devid, 4); - } else if (buffer[1] == 0x9a && - ((buffer[2] == 0x20) || (buffer[2] == 0x21))) { - /* - * Set up non-EMP Mouseman/Trackman to put - * button bits in 3rd byte instead of sending - * via pseudo keyboard device. - */ - cmd = ADBLISTEN(adbaddr, 1); - buffer[0]=2; - buffer[1]=0x00; - buffer[2]=0x81; - adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd); - - cmd = ADBLISTEN(adbaddr, 1); - buffer[0]=2; - buffer[1]=0x01; - buffer[2]=0x81; - adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd); - - cmd = ADBLISTEN(adbaddr, 1); - buffer[0]=2; - buffer[1]=0x02; - buffer[2]=0x81; - adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd); - - cmd = ADBLISTEN(adbaddr, 1); - buffer[0]=2; - buffer[1]=0x03; - buffer[2]=0x38; - adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd); - - sc->sc_buttons = 3; - sc->sc_res = 400; - if (buffer[2] == 0x21) - sc->sc_class = MSCLASS_TRACKBALL; - else - sc->sc_class = MSCLASS_MOUSE; - } else - /* unknown device? */; - } else { - /* Attempt to initialize as an A3 mouse */ - buffer[2] = 0x03; /* make handler ID 3 */ - cmd = ADBLISTEN(adbaddr, 3); - if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd)) { -#ifdef ADB_DEBUG - if (adb_debug) - printf("adb: ems_init timed out\n"); -#endif - return; - } - - /* - * Check to see if successful, if not - * try to initialize it as other types - */ - cmd = ADBTALK(adbaddr, 3); - if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0 - && buffer[2] == ADBMS_MSA3) { - sc->handler_id = ADBMS_MSA3; - /* Initialize as above */ - cmd = ADBLISTEN(adbaddr, 2); - /* listen 2 */ - buffer[0] = 3; - buffer[1] = 0x00; - /* Irrelevant, buffer has 0x77 */ - buffer[2] = 0x07; - /* - * enable 3 button mode = 0111b, - * speed = normal - */ - adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd); - sc->sc_buttons = 3; - sc->sc_res = 300; - } else { - /* No special support for this mouse */ - } - } - } -} - -/* - * Handle putting the mouse data received from the ADB into - * an ADB event record. - */ -void -ms_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command) -{ - adb_event_t event; - struct ams_softc *sc; - int adbaddr; -#ifdef ADB_DEBUG - int i; - - if (adb_debug) - printf("adb: transaction completion\n"); -#endif - - adbaddr = ADB_CMDADDR(adb_command); - sc = (struct ams_softc *)data_area; - - if ((sc->handler_id == ADBMS_EXTENDED) && (sc->sc_devid[0] == 0)) { - /* massage the data to look like EMP data */ - if ((buffer[3] & 0x04) == 0x04) - buffer[1] &= 0x7f; - else - buffer[1] |= 0x80; - if ((buffer[3] & 0x02) == 0x02) - buffer[2] &= 0x7f; - else - buffer[2] |= 0x80; - if ((buffer[3] & 0x01) == 0x01) - buffer[3] = 0x00; - else - buffer[3] = 0x80; - } - - event.addr = adbaddr; - event.hand_id = sc->handler_id; - event.def_addr = sc->origaddr; - event.byte_count = buffer[0]; - memcpy(event.bytes, buffer + 1, event.byte_count); - -#ifdef ADB_DEBUG - if (adb_debug) { - printf("ams: from %d at %d (org %d) %d:", event.addr, - event.hand_id, event.def_addr, buffer[0]); - for (i = 1; i <= buffer[0]; i++) - printf(" %x", buffer[i]); - printf("\n"); - } -#endif - - microtime(&event.timestamp); - - ms_processevent(&event, sc); -} - -/* - * Given a mouse ADB event, record the button settings, calculate the - * x- and y-axis motion, and handoff the event to the appropriate subsystem. - */ -static void -ms_processevent(adb_event_t *event, struct ams_softc *sc) -{ - adb_event_t new_event; - int i, button_bit, max_byte, mask, buttons; - - new_event = *event; - buttons = 0; - - /* - * This should handle both plain ol' Apple mice and mice - * that claim to support the Extended Apple Mouse Protocol. - */ - max_byte = event->byte_count; - button_bit = 1; - switch (event->hand_id) { - case ADBMS_USPEED: - case ADBMS_UCONTOUR: - /* MicroSpeed mouse and Contour mouse */ - if (max_byte == 4) - buttons = (~event->bytes[2]) & 0xff; - else - buttons = (event->bytes[0] & 0x80) ? 0 : 1; - break; - case ADBMS_MSA3: - /* Mouse Systems A3 mouse */ - if (max_byte == 3) - buttons = (~event->bytes[2]) & 0x07; - else - buttons = (event->bytes[0] & 0x80) ? 0 : 1; - break; - default: - /* Classic Mouse Protocol (up to 2 buttons) */ - for (i = 0; i < 2; i++, button_bit <<= 1) - /* 0 when button down */ - if (!(event->bytes[i] & 0x80)) - buttons |= button_bit; - else - buttons &= ~button_bit; - if (sc->sc_class == MSCLASS_MOUSE) - /* Extended Protocol (up to 6 more buttons) */ - for (mask = 0x80; i < max_byte; - i += (mask == 0x80), button_bit <<= 1) { - /* 0 when button down */ - if (!(event->bytes[i] & mask)) - buttons |= button_bit; - else - buttons &= ~button_bit; - mask = ((mask >> 4) & 0xf) - | ((mask & 0xf) << 4); - } - break; - } - new_event.u.m.buttons = sc->sc_mb | buttons; - new_event.u.m.dx = ((signed int) (event->bytes[1] & 0x3f)) - - ((event->bytes[1] & 0x40) ? 64 : 0); - new_event.u.m.dy = ((signed int) (event->bytes[0] & 0x3f)) - - ((event->bytes[0] & 0x40) ? 64 : 0); - - if (sc->sc_wsmousedev) - wsmouse_input(sc->sc_wsmousedev, new_event.u.m.buttons, - new_event.u.m.dx, -new_event.u.m.dy, 0, - WSMOUSE_INPUT_DELTA); -} - -int -ams_enable(void *v) -{ - return 0; -} - -int -ams_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) -{ - switch (cmd) { - case WSMOUSEIO_GTYPE: - *(u_int *)data = WSMOUSE_TYPE_ADB; - return (0); - } - - return -1; -} - -void -ams_disable(void *v) -{ -} diff --git a/sys/arch/macppc/dev/apm.c b/sys/arch/macppc/dev/apm.c index 41d90969592..a49f1f89d68 100644 --- a/sys/arch/macppc/dev/apm.c +++ b/sys/arch/macppc/dev/apm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: apm.c,v 1.11 2005/10/15 15:01:23 martin Exp $ */ +/* $OpenBSD: apm.c,v 1.12 2006/01/18 23:21:17 miod Exp $ */ /*- * Copyright (c) 2001 Alexander Guy. All rights reserved. @@ -54,6 +54,7 @@ #include <machine/cpu.h> #include <machine/apmvar.h> +#include <dev/adb/adb.h> #include <macppc/dev/adbvar.h> #include <macppc/dev/pm_direct.h> diff --git a/sys/arch/macppc/dev/pm_direct.c b/sys/arch/macppc/dev/pm_direct.c index fc22ea56242..7a5c80b6305 100644 --- a/sys/arch/macppc/dev/pm_direct.c +++ b/sys/arch/macppc/dev/pm_direct.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pm_direct.c,v 1.17 2005/12/22 22:55:25 miod Exp $ */ +/* $OpenBSD: pm_direct.c,v 1.18 2006/01/18 23:21:17 miod Exp $ */ /* $NetBSD: pm_direct.c,v 1.9 2000/06/08 22:10:46 tsubai Exp $ */ /* @@ -44,9 +44,9 @@ #include <sys/device.h> #include <sys/systm.h> -#include <machine/adbsys.h> #include <machine/cpu.h> +#include <dev/adb/adb.h> #include <macppc/dev/adbvar.h> #include <macppc/dev/pm_direct.h> #include <macppc/dev/viareg.h> diff --git a/sys/arch/macppc/macppc/ofw_machdep.c b/sys/arch/macppc/macppc/ofw_machdep.c index 7ace6b09192..b6489d81a48 100644 --- a/sys/arch/macppc/macppc/ofw_machdep.c +++ b/sys/arch/macppc/macppc/ofw_machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ofw_machdep.c,v 1.28 2006/01/01 11:59:39 miod Exp $ */ +/* $OpenBSD: ofw_machdep.c,v 1.29 2006/01/18 23:21:17 miod Exp $ */ /* $NetBSD: ofw_machdep.c,v 1.1 1996/09/30 16:34:50 ws Exp $ */ /* @@ -52,11 +52,11 @@ #include <macppc/macppc/ofw_machdep.h> -#include <ukbd.h> -#include <akbd.h> -#include <zstty.h> +#include "ukbd.h" +#include "akbd.h" +#include "zstty.h" #include <dev/usb/ukbdvar.h> -#include <macppc/dev/akbdvar.h> +#include <dev/adb/akbdvar.h> /* XXX, called from asm */ int save_ofw_mapping(void); diff --git a/sys/arch/macppc/include/adbsys.h b/sys/dev/adb/adb.h index e39f2606090..e18e61cc0ea 100644 --- a/sys/arch/macppc/include/adbsys.h +++ b/sys/dev/adb/adb.h @@ -1,4 +1,4 @@ -/* $OpenBSD: adbsys.h,v 1.5 2006/01/04 21:03:49 miod Exp $ */ +/* $OpenBSD: adb.h,v 1.1 2006/01/18 23:21:17 miod Exp $ */ /* $NetBSD: adbsys.h,v 1.4 2000/12/19 02:59:24 tsubai Exp $ */ /*- @@ -34,11 +34,27 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _ADBSYS_MACHINE_ -#define _ADBSYS_MACHINE_ +#ifndef _ADB_H_ +#define _ADB_H_ + +#ifdef _KERNEL #include <sys/time.h> /* timeval stuff */ +/* + * Arguments used to attach a device to the Apple Desktop Bus + */ +struct adb_attach_args { + int origaddr; + int adbaddr; + int handler_id; +}; + +#define ADB_CMDADDR(cmd) ((u_int8_t)(cmd & 0xf0) >> 4) +#define ADBFLUSH(dev) ((((u_int8_t)dev & 0x0f) << 4) | 0x01) +#define ADBLISTEN(dev, reg) ((((u_int8_t)dev & 0x0f) << 4) | 0x08 | reg) +#define ADBTALK(dev, reg) ((((u_int8_t)dev & 0x0f) << 4) | 0x0c | reg) + /* an ADB event */ typedef struct adb_event_s { int addr; /* device address */ @@ -48,10 +64,10 @@ typedef struct adb_event_s { unsigned char bytes[8]; /* bytes from register 0 */ struct timeval timestamp; /* time event was acquired */ union { - struct adb_keydata_s{ + struct adb_keydata_s { int key; /* ADB key code */ } k; - struct adb_mousedata_s{ + struct adb_mousedata_s { int dx; /* mouse delta x */ int dy; /* mouse delta y */ int buttons; /* buttons (down << (buttonnum)) */ @@ -59,15 +75,6 @@ typedef struct adb_event_s { } u; /* courtesy interpretation */ } adb_event_t; - -/* a device on the ADB */ -typedef struct adb_dev_s{ - int addr; /* current address */ - int default_addr; /* startup address */ - int handler_id; /* handler ID */ -} adb_dev_t; - - /* Interesting default addresses */ #define ADBADDR_SECURE 1 /* Security dongles */ #define ADBADDR_MAP 2 /* Mapped devices (keyboards/pads) */ @@ -126,12 +133,31 @@ typedef struct adb_dev_s{ #define ADB_POWERKEY 34 /* Sophisticated Circuits PowerKey */ /* (intelligent power tap) */ -#ifdef _KERNEL -int adb_poweroff(void); -void adb_restart(void); -int CountADBs(void); -void ADBReInit(void); -int adb_read_date_time(time_t *); +extern int adb_polling; +#ifdef ADB_DEBUG +extern int adb_debug; #endif -#endif /* _ADBSYS_MACHINE_ */ +/* ADB Manager */ + +typedef caddr_t Ptr; + +typedef struct { + Ptr siServiceRtPtr; + Ptr siDataAreaAddr; +} ADBSetInfoBlock; + +typedef struct { + unsigned char devType; + unsigned char origADBAddr; + Ptr dbServiceRtPtr; + Ptr dbDataAreaAddr; +} ADBDataBlock; + +int adbprint(void *, const char *); +int adb_op_sync(Ptr, Ptr, Ptr, short); +int set_adb_info(ADBSetInfoBlock *, int); + +#endif /* _KERNEL */ + +#endif /* _ADB_H_ */ diff --git a/sys/dev/adb/adb_subr.c b/sys/dev/adb/adb_subr.c new file mode 100644 index 00000000000..839f2aa6878 --- /dev/null +++ b/sys/dev/adb/adb_subr.c @@ -0,0 +1,108 @@ +/* $OpenBSD: adb_subr.c,v 1.1 2006/01/18 23:21:17 miod Exp $ */ +/* $NetBSD: adb.c,v 1.6 1999/08/16 06:28:09 tsubai Exp $ */ + +/*- + * Copyright (C) 1994 Bradley A. Grantham + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Bradley A. Grantham. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/device.h> + +#include <dev/adb/adb.h> + +struct cfdriver adb_cd = { + NULL, "adb", DV_DULL +}; + +int +adbprint(void *args, const char *name) +{ + struct adb_attach_args *aa_args = (struct adb_attach_args *)args; + int rv = UNCONF; + + if (name) { /* no configured device matched */ + rv = UNSUPP; /* most ADB device types are unsupported */ + + /* print out what kind of ADB device we have found */ + switch(aa_args->origaddr) { +#ifdef ADBVERBOSE + case ADBADDR_SECURE: + printf("security dongle (%d)", aa_args->handler_id); + break; +#endif + case ADBADDR_MAP: + printf("mapped device (%d)", aa_args->handler_id); + rv = UNCONF; + break; + case ADBADDR_REL: + printf("relative positioning device (%d)", + aa_args->handler_id); + rv = UNCONF; + break; +#ifdef ADBVERBOSE + case ADBADDR_ABS: + switch (aa_args->handler_id) { + case ADB_ARTPAD: + printf("WACOM ArtPad II"); + break; + default: + printf("absolute positioning device (%d)", + aa_args->handler_id); + break; + } + break; + case ADBADDR_DATATX: + printf("data transfer device (modem?) (%d)", + aa_args->handler_id); + break; + case ADBADDR_MISC: + switch (aa_args->handler_id) { + case ADB_POWERKEY: + printf("Sophisticated Circuits PowerKey"); + break; + default: + printf("misc. device (remote control?) (%d)", + aa_args->handler_id); + break; + } + break; + default: + printf("unknown type %d device, (handler %d)", + aa_args->origaddr, aa_args->handler_id); + break; +#endif /* ADBVERBOSE */ + } + printf(" at %s", name); + } + + printf(" addr %d", aa_args->adbaddr); + + return (rv); +} diff --git a/sys/arch/macppc/dev/akbd.c b/sys/dev/adb/akbd.c index 651bf454c52..18d8434415e 100644 --- a/sys/arch/macppc/dev/akbd.c +++ b/sys/dev/adb/akbd.c @@ -1,5 +1,5 @@ -/* $OpenBSD: akbd.c,v 1.20 2006/01/08 17:25:05 miod Exp $ */ -/* $NetBSD: akbd.c,v 1.13 2001/01/25 14:08:55 tsubai Exp $ */ +/* $OpenBSD: akbd.c,v 1.1 2006/01/18 23:21:17 miod Exp $ */ +/* $NetBSD: akbd.c,v 1.17 2005/01/15 16:00:59 chs Exp $ */ /* * Copyright (C) 1998 Colin Wood @@ -48,25 +48,26 @@ #include <dev/wscons/wsksymvar.h> #include <machine/autoconf.h> -#define KEYBOARD_ARRAY +#include <machine/cpu.h> + +#include <dev/adb/adb.h> +#include <dev/adb/akbdmap.h> +#include <dev/adb/akbdvar.h> -#include <macppc/dev/keyboard.h> -#include <macppc/dev/adbvar.h> -#include <macppc/dev/akbdmap.h> -#include <macppc/dev/akbdvar.h> -#include <macppc/dev/amsvar.h> +#define KEYBOARD_ARRAY +#include <dev/adb/keyboard.h> /* * Function declarations. */ -static int akbdmatch(struct device *, void *, void *); -static void akbdattach(struct device *, struct device *, void *); -void kbd_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command); -static void kbd_processevent(adb_event_t *event, struct akbd_softc *); +int akbdmatch(struct device *, void *, void *); +void akbdattach(struct device *, struct device *, void *); +void kbd_adbcomplete(caddr_t, caddr_t, int); +void kbd_processevent(adb_event_t *, struct akbd_softc *); #ifdef notyet -static u_char getleds(int); -static int setleds(struct akbd_softc *, u_char); -static void blinkleds(struct akbd_softc *); +u_char getleds(int); +int setleds(struct akbd_softc *, u_char); +void blinkleds(struct akbd_softc *); #endif /* Driver definition. */ @@ -77,11 +78,10 @@ struct cfdriver akbd_cd = { NULL, "akbd", DV_DULL }; - int akbd_enable(void *, int); void akbd_set_leds(void *, int); int akbd_ioctl(void *, u_long, caddr_t, int, struct proc *); -int akbd_intr(adb_event_t *event); +int akbd_intr(adb_event_t *, struct akbd_softc *); void akbd_rawrepeat(void *v); @@ -91,14 +91,6 @@ struct wskbd_accessops akbd_accessops = { akbd_ioctl, }; -void akbd_cngetc(void *, u_int *, int *); -void akbd_cnpollc(void *, int); - -struct wskbd_consops akbd_consops = { - akbd_cngetc, - akbd_cnpollc, -}; - struct wskbd_mapdata akbd_keymapdata = { akbd_keydesctab, #ifdef AKBD_LAYOUT @@ -108,12 +100,10 @@ struct wskbd_mapdata akbd_keymapdata = { #endif }; -static int akbd_is_console; - -static int -akbdmatch(struct device *parent, void *cf, void *aux) +int +akbdmatch(struct device *parent, void *vcf, void *aux) { - struct adb_attach_args *aa_args = aux; + struct adb_attach_args *aa_args = (struct adb_attach_args *)aux; if (aa_args->origaddr == ADBADDR_KBD) return 1; @@ -121,16 +111,18 @@ akbdmatch(struct device *parent, void *cf, void *aux) return 0; } -static void +void akbdattach(struct device *parent, struct device *self, void *aux) { ADBSetInfoBlock adbinfo; struct akbd_softc *sc = (struct akbd_softc *)self; - struct adb_attach_args *aa_args = aux; + struct adb_attach_args *aa_args = (struct adb_attach_args *)aux; int error, kbd_done; short cmd; u_char buffer[9]; struct wskbddev_attach_args a; + static int akbd_console_initted; + int wskbd_eligible = 1; sc->origaddr = aa_args->origaddr; sc->adbaddr = aa_args->adbaddr; @@ -159,10 +151,12 @@ akbdattach(struct device *parent, struct device *self, void *aux) printf("Mouseman (non-EMP) pseudo keyboard\n"); adbinfo.siServiceRtPtr = (Ptr)0; adbinfo.siDataAreaAddr = (Ptr)0; + wskbd_eligible = 0; } else if (kbd_done && buffer[1] == 0x9a && buffer[2] == 0x21) { printf("Trackman (non-EMP) pseudo keyboard\n"); adbinfo.siServiceRtPtr = (Ptr)0; adbinfo.siDataAreaAddr = (Ptr)0; + wskbd_eligible = 0; } else { printf("extended keyboard\n"); #ifdef notyet @@ -190,6 +184,7 @@ akbdattach(struct device *parent, struct device *self, void *aux) break; case ADB_ADJKPD: printf("adjustable keypad\n"); + wskbd_eligible = 0; break; case ADB_ADJKBD: printf("adjustable keyboard\n"); @@ -232,20 +227,23 @@ akbdattach(struct device *parent, struct device *self, void *aux) break; default: printf("mapped device (%d)\n", sc->handler_id); + wskbd_eligible = 0; break; } - error = SetADBInfo(&adbinfo, sc->adbaddr); + error = set_adb_info(&adbinfo, sc->adbaddr); #ifdef ADB_DEBUG if (adb_debug) - printf("akbd: returned %d from SetADBInfo\n", error); + printf("akbd: returned %d from set_adb_info\n", error); #endif #ifdef WSDISPLAY_COMPAT_RAWKBD timeout_set(&sc->sc_rawrepeat_ch, akbd_rawrepeat, sc); #endif - - a.console = akbd_is_console; + if (akbd_is_console() && wskbd_eligible) + a.console = (++akbd_console_initted == 1); + else + a.console = 0; a.keymap = &akbd_keymapdata; a.accessops = &akbd_accessops; a.accesscookie = sc; @@ -300,7 +298,7 @@ kbd_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command) * repeat handler, optionally passing the event through the mouse * button emulation handler first. */ -static void +void kbd_processevent(adb_event_t *event, struct akbd_softc *ksc) { adb_event_t new_event; @@ -308,12 +306,14 @@ kbd_processevent(adb_event_t *event, struct akbd_softc *ksc) new_event = *event; new_event.u.k.key = event->bytes[0]; new_event.bytes[1] = 0xff; - akbd_intr(&new_event); + if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */ + akbd_intr(&new_event, ksc); if (event->bytes[1] != 0xff) { new_event.u.k.key = event->bytes[1]; new_event.bytes[0] = event->bytes[1]; new_event.bytes[1] = 0xff; - akbd_intr(&new_event); + if (ksc->sc_wskbddev != NULL) /* wskbd is attached? */ + akbd_intr(&new_event, ksc); } } @@ -322,7 +322,7 @@ kbd_processevent(adb_event_t *event, struct akbd_softc *ksc) /* * Get the actual hardware LED state and convert it to softc format. */ -static u_char +u_char getleds(int addr) { short cmd; @@ -331,7 +331,6 @@ getleds(int addr) leds = 0x00; /* all off */ buffer[0] = 0; - /* talk R2 */ cmd = ADBTALK(addr, 2); if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) == 0 && buffer[0] > 0) @@ -346,7 +345,7 @@ getleds(int addr) * Automatically translates from ioctl/softc format to the * actual keyboard register format */ -static int +int setleds(struct akbd_softc *ksc, u_char leds) { int addr; @@ -370,6 +369,7 @@ setleds(struct akbd_softc *ksc, u_char leds) cmd = ADBLISTEN(addr, 2); adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd); + /* talk R2 */ cmd = ADBTALK(addr, 2); if (adb_op_sync((Ptr)buffer, (Ptr)0, (Ptr)0, cmd) || buffer[0] == 0) return (EIO); @@ -385,7 +385,7 @@ setleds(struct akbd_softc *ksc, u_char leds) /* * Toggle all of the LED's on and off, just for show. */ -static void +void blinkleds(struct akbd_softc *ksc) { int addr, i; @@ -445,10 +445,18 @@ akbd_ioctl(void *v, u_long cmd, caddr_t data, int flag, struct proc *p) return (0); #endif - } - /* kbdioctl(...); */ +#ifdef mac68k /* XXX not worth creating akbd_machdep_ioctl() */ + case WSKBDIO_BELL: + case WSKBDIO_COMPLEXBELL: +#define d ((struct wskbd_bell_data *)data) + mac68k_ring_bell(d->pitch, d->period * hz / 1000, d->volume); +#undef d + return (0); +#endif - return -1; + default: + return (-1); + } } #ifdef WSDISPLAY_COMPAT_RAWKBD @@ -465,18 +473,14 @@ akbd_rawrepeat(void *v) } #endif - -static int polledkey; - +int adb_polledkey; int -akbd_intr(adb_event_t *event) +akbd_intr(adb_event_t *event, struct akbd_softc *sc) { int key, press, val; int type; static int shift; - struct akbd_softc *sc = akbd_cd.cd_devs[0]; - key = event->u.k.key; /* @@ -504,20 +508,8 @@ akbd_intr(adb_event_t *event) type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; - switch (val) { -#if 0 - /* not supported... */ - case ADBK_KEYVAL(245): - pm_eject_pcmcia(0); - break; - case ADBK_KEYVAL(244): - pm_eject_pcmcia(1); - break; -#endif - } - if (adb_polling) { - polledkey = key; + adb_polledkey = key; #ifdef WSDISPLAY_COMPAT_RAWKBD } else if (sc->sc_rawkbd) { char cbuf[MAXKEYS *2]; @@ -557,44 +549,3 @@ akbd_intr(adb_event_t *event) return 0; } - -int -akbd_cnattach() -{ - - akbd_is_console = 1; - wskbd_cnattach(&akbd_consops, NULL, &akbd_keymapdata); - return 0; -} - -void -akbd_cngetc(void *v, u_int *type, int *data) -{ - int key, press, val; - int s; - - s = splhigh(); - - polledkey = -1; - adb_polling = 1; - - while (polledkey == -1) { - adb_intr(NULL); /* adb does not use the argument */ - DELAY(10000); /* XXX */ - } - - adb_polling = 0; - splx(s); - - key = polledkey; - press = ADBK_PRESS(key); - val = ADBK_KEYVAL(key); - - *data = val; - *type = press ? WSCONS_EVENT_KEY_DOWN : WSCONS_EVENT_KEY_UP; -} - -void -akbd_cnpollc(void *v, int on) -{ -} diff --git a/sys/arch/mac68k/dev/akbdmap.h b/sys/dev/adb/akbdmap.h index 8e0c01f0523..f91444ed71a 100644 --- a/sys/arch/mac68k/dev/akbdmap.h +++ b/sys/dev/adb/akbdmap.h @@ -1,3 +1,4 @@ +/* $OpenBSD: akbdmap.h,v 1.1 2006/01/18 23:21:17 miod Exp $ */ /* $NetBSD: akbdmap.h,v 1.7 2005/05/05 22:29:41 abs Exp $ */ /*- @@ -94,7 +95,7 @@ static const keysym_t akbd_keydesc_us[] = { KC(49), KS_space, KC(50), KS_grave, KS_asciitilde, KC(51), KS_Delete, - KC(52), KS_KP_Enter, /* Pretend this is alt-R ? */ + KC(52), KS_KP_Enter, KC(53), KS_Escape, KC(54), KS_Control_L, KC(55), KS_Cmd, /* Command */ @@ -109,25 +110,25 @@ static const keysym_t akbd_keydesc_us[] = { KC(65), KS_KP_Decimal, KC(67), KS_KP_Multiply, KC(69), KS_KP_Add, - KC(71), KS_Num_Lock, + KC(71), KS_Num_Lock, KS_Clear, KC(75), KS_KP_Divide, KC(76), KS_KP_Enter, KC(78), KS_KP_Subtract, KC(81), KS_KP_Equal, - KC(82), KS_KP_Insert, KS_KP_0, - KC(83), KS_KP_End, KS_KP_1, - KC(84), KS_KP_Down, KS_KP_2, - KC(85), KS_KP_Next, KS_KP_3, - KC(86), KS_KP_Left, KS_KP_4, - KC(87), KS_KP_Begin, KS_KP_5, - KC(88), KS_KP_Right, KS_KP_6, - KC(89), KS_KP_Home, KS_KP_7, - - KC(91), KS_KP_Up, KS_KP_8, - KC(92), KS_KP_Prior, KS_KP_9, - - KC(95), KS_KP_Delete, KS_KP_Decimal, + KC(82), KS_KP_0, KS_KP_Insert, + KC(83), KS_KP_1, KS_KP_End, + KC(84), KS_KP_2, KS_KP_Down, + KC(85), KS_KP_3, KS_KP_Next, + KC(86), KS_KP_4, KS_KP_Left, + KC(87), KS_KP_5, KS_KP_Begin, + KC(88), KS_KP_6, KS_KP_Right, + KC(89), KS_KP_7, KS_KP_Home, + + KC(91), KS_KP_8, KS_KP_Up, + KC(92), KS_KP_9, KS_KP_Prior, + + KC(95), KS_KP_Decimal, KS_KP_Delete, KC(96), KS_f5, KC(97), KS_f6, KC(98), KS_f7, @@ -138,15 +139,15 @@ static const keysym_t akbd_keydesc_us[] = { KC(103), KS_f11, - KC(105), KS_Print_Screen, + KC(105), KS_f13, KS_Print_Screen, KC(106), KS_KP_Enter, - KC(107), KS_Hold_Screen, + KC(107), KS_f14, KS_Hold_Screen, KC(109), KS_f10, KC(111), KS_f12, - KC(113), KS_Pause, + KC(113), KS_f15, KS_Pause, KC(114), KS_Insert, KC(115), KS_Home, KC(116), KS_Prior, @@ -168,32 +169,34 @@ static const keysym_t akbd_keydesc_fr[] = { KC(6), KS_w, KS_W, KS_less, KS_greater, KC(8), KS_c, KS_C, KS_copyright, KS_cent, KC(10), KS_at, KS_numbersign, - KC(11), KS_b, KS_B, KS_ssharp, + KC(11), KS_b, KS_B, KS_ssharp, KC(12), KS_a, KS_A, KS_ae, KS_AE, KC(13), KS_z, KS_Z, KS_Acircumflex, KS_Aring, KC(14), KS_e, KS_E, KS_ecircumflex, KS_Ecircumflex, - KC(15), KS_r, KS_R, KS_registered, /* Euro */ + KC(15), KS_r, KS_R, KS_registered, KS_comma, KC(16), KS_y, KS_Y, KS_Uacute, KC(18), KS_ampersand, KS_1, KS_voidSymbol, KS_dead_acute, KC(19), KS_eacute, KS_2, KS_ediaeresis, KC(20), KS_quotedbl, KS_3, KC(21), KS_apostrophe, KS_4, KS_braceleft, KS_bracketleft, - KC(22), KS_section, KS_6, KS_paragraph, + KC(22), KS_section, KS_6, KS_paragraph, KS_aring, KC(23), KS_parenleft, KS_5, KS_braceleft, KS_bracketleft, KC(24), KS_minus, KS_underscore, KS_braceright, - KC(25), KS_ccedilla, KS_9, KS_Ccedilla, KS_Agrave, - KC(26), KS_egrave, KS_7, KS_guillemotleft,KS_guillemotright, + KC(25), KS_ccedilla, KS_9, KS_Ccedilla, KS_Aacute, + KC(26), KS_egrave, KS_7, KS_guillemotleft, + KS_guillemotright, KC(27), KS_parenright, KS_degree, KS_braceright, KS_bracketright, KC(28), KS_exclam, KS_8, KS_exclamdown, KS_Ucircumflex, - KC(29), KS_agrave, KS_0, KS_oslash, - KC(30), KS_dollar, KS_asterisk, KS_comma, KS_yen, - KC(33), KS_dead_circumflex, KS_dead_diaeresis,KS_ocircumflex,KS_Ocircumflex, - KC(34), KS_i, KS_I, KS_icircumflex, KS_Icircumflex, + KC(29), KS_agrave, KS_0, KS_oslash, KS_Ooblique, + KC(30), KS_dollar, KS_asterisk, KS_cent, KS_yen, + KC(33), KS_dead_circumflex, KS_dead_diaeresis, + KS_ocircumflex, KS_Ocircumflex, + KC(34), KS_i, KS_I, KS_icircumflex, KS_idiaeresis, KC(37), KS_l, KS_L, KS_notsign, KS_bar, - KC(38), KS_j, KS_J, KS_Idiaeresis, KS_Igrave, + KC(38), KS_j, KS_J, KS_Idiaeresis, KS_Iacute, KC(39), KS_ugrave, KS_percent, KS_Ugrave, KC(40), KS_k, KS_K, KS_Egrave, KS_Ediaeresis, - KC(41), KS_m, KS_M, KS_mu, KS_Ograve, + KC(41), KS_m, KS_M, KS_mu, KS_Oacute, KC(42), KS_dead_grave, KS_sterling, KS_at, KS_numbersign, KC(43), KS_semicolon, KS_period, KC(44), KS_equal, KS_plus, KS_voidSymbol, KS_plusminus, @@ -403,29 +406,120 @@ static const keysym_t akbd_keydesc_pt[] = { KC(44), KS_minus, KS_underscore, KC(47), KS_period, KS_colon, KC(50), KS_less, KS_greater, + KC(58), KS_Mode_switch, KS_Multi_key, /* Option */ +}; + +static const keysym_t akbd_keydesc_us_dvorak[] = { +/* pos command normal shifted */ + KC(1), KS_o, + KC(2), KS_e, + KC(3), KS_u, + KC(4), KS_d, + KC(5), KS_i, + KC(6), KS_semicolon, KS_colon, + KC(7), KS_q, + KC(8), KS_j, + KC(9), KS_k, + KC(11), KS_x, + KC(12), KS_apostrophe, KS_quotedbl, + KC(13), KS_comma, KS_less, + KC(14), KS_period, KS_greater, + KC(15), KS_p, + KC(16), KS_f, + KC(17), KS_y, + KC(24), KS_bracketright, KS_braceright, + KC(27), KS_bracketleft, KS_braceleft, + KC(30), KS_equal, KS_plus, + KC(31), KS_r, + KC(32), KS_g, + KC(33), KS_slash, KS_question, + KC(34), KS_c, + KC(35), KS_l, + KC(37), KS_n, + KC(38), KS_h, + KC(39), KS_minus, KS_underscore, + KC(40), KS_t, + KC(41), KS_s, + KC(43), KS_w, + KC(44), KS_z, + KC(45), KS_b, + KC(47), KS_v, +}; + +static const keysym_t akbd_keydesc_sg[] = { +/* pos normal shifted altgr shift-altgr */ + KC(0), KS_a, KS_A, KS_aring, KS_Aring, + KC(1), KS_s, KS_S, KS_ssharp, KS_voidSymbol, + KC(3), KS_f, KS_F, KS_section, KS_voidSymbol, + KC(4), KS_h, KS_H, KS_ordfeminine, KS_periodcentered, + KC(5), KS_g, KS_G, KS_at, KS_comma, + KC(6), KS_y, KS_Y, KS_yen, KS_ydiaeresis, + KC(7), KS_x, KS_X, KS_voidSymbol, KS_ydiaeresis, + KC(8), KS_c, KS_C, KS_copyright, + KC(10), KS_section, KS_degree, + KC(12), KS_q, KS_Q, + KC(15), KS_r, KS_R, KS_registered, KS_Egrave, + KC(16), KS_z, KS_Z, KS_voidSymbol, KS_Aacute, + KC(18), KS_1, KS_plus, KS_plusminus, KS_onesuperior, + KC(19), KS_2, KS_quotedbl, KS_twosuperior, + KC(20), KS_3, KS_asterisk, KS_numbersign, KS_threesuperior, + KC(21), KS_4, KS_ccedilla, KS_Ccedilla, + KC(22), KS_6, KS_ampersand, KS_bracketright, + KC(23), KS_5, KS_percent, KS_bracketleft, + KC(24), KS_dead_circumflex,KS_dead_grave,KS_dead_acute, KS_asciitilde, + KC(25), KS_9, KS_parenright, KS_braceright, KS_Ocircumflex, + KC(26), KS_7, KS_slash, KS_bar, KS_backslash, + KC(27), KS_apostrophe, KS_question, KS_questiondown, + KC(28), KS_8, KS_parenleft, KS_braceleft, KS_Ograve, + KC(29), KS_0, KS_equal, KS_voidSymbol, KS_Uacute, + KC(30), KS_dead_diaeresis,KS_exclam, KS_bracketright, + KC(31), KS_o, KS_O, KS_oslash, + KC(32), KS_u, KS_U, KS_degree, KS_Ugrave, + KC(33), KS_udiaeresis, KS_egrave, KS_bracketleft, + KC(34), KS_i, KS_I, KS_exclamdown, + KC(37), KS_l, KS_L, KS_notsign, + KC(38), KS_j, KS_J, KS_masculine, + KC(39), KS_adiaeresis, KS_agrave, KS_ae, KS_AE, + KC(41), KS_odiaeresis, KS_eacute, KS_cent, + KC(42), KS_dollar, KS_sterling, KS_paragraph, + KC(43), KS_comma, KS_semicolon, KS_guillemotleft,KS_guillemotright, + KC(44), KS_minus, KS_underscore, + KC(45), KS_n, KS_N, KS_dead_tilde, + KC(46), KS_m, KS_M, KS_mu, + KC(47), KS_period, KS_colon, KS_voidSymbol, KS_division, + KC(50), KS_less, KS_greater, + KC(52), KS_Multi_key, KC(58), KS_Mode_switch, - KC(81), KS_KP_Equal, }; +static const keysym_t akbd_keydesc_sg_nodead[] = { +/* pos normal shifted altgr shift-altgr */ + KC(24), KS_asciicircum, KS_grave, KS_acute, KS_asciitilde, + KC(30), KS_diaeresis, KS_exclam, KS_bracketright,KS_braceright, + KC(45), KS_n, KS_N, KS_asciitilde, +}; + #define KBD_MAP(name, base, map) \ { name, base, sizeof(map)/sizeof(keysym_t), map } static const struct wscons_keydesc akbd_keydesctab[] = { KBD_MAP(KB_US, 0, akbd_keydesc_us), + KBD_MAP(KB_US | KB_DVORAK, KB_US, akbd_keydesc_us_dvorak), + KBD_MAP(KB_DE, KB_US, akbd_keydesc_de), + KBD_MAP(KB_DE | KB_NODEAD, KB_DE, akbd_keydesc_de_nodead), + KBD_MAP(KB_ES, KB_US, akbd_keydesc_es), KBD_MAP(KB_FR, KB_US, akbd_keydesc_fr), - KBD_MAP(KB_JP, KB_US, akbd_keydesc_jp), KBD_MAP(KB_FR | KB_NODEAD, KB_FR, akbd_keydesc_fr_nodead), + KBD_MAP(KB_JP, KB_US, akbd_keydesc_jp), + KBD_MAP(KB_PT, KB_US, akbd_keydesc_pt), KBD_MAP(KB_SF, KB_US, akbd_keydesc_sf), + KBD_MAP(KB_SG, KB_US, akbd_keydesc_sg), + KBD_MAP(KB_SG | KB_NODEAD, KB_SG, akbd_keydesc_sg_nodead), KBD_MAP(KB_SV, KB_US, akbd_keydesc_sv), KBD_MAP(KB_SV | KB_NODEAD, KB_SV, akbd_keydesc_sv_nodead), - KBD_MAP(KB_DE, KB_US, akbd_keydesc_de), - KBD_MAP(KB_DE | KB_NODEAD, KB_DE, akbd_keydesc_de_nodead), KBD_MAP(KB_UK, KB_US, akbd_keydesc_uk), - KBD_MAP(KB_ES, KB_US, akbd_keydesc_es), - KBD_MAP(KB_PT, KB_US, akbd_keydesc_pt), {0, 0, 0, 0} }; #undef KBD_MAP #undef KC - diff --git a/sys/arch/mac68k/dev/akbdvar.h b/sys/dev/adb/akbdvar.h index 9688e8b421c..d3c2db3bb2b 100644 --- a/sys/arch/mac68k/dev/akbdvar.h +++ b/sys/dev/adb/akbdvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: akbdvar.h,v 1.1 2006/01/04 20:39:04 miod Exp $ */ +/* $OpenBSD: akbdvar.h,v 1.1 2006/01/18 23:21:17 miod Exp $ */ /* $NetBSD: akbdvar.h,v 1.4 1999/02/17 14:56:56 tsubai Exp $ */ /* @@ -31,10 +31,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _MAC68K_KBDVAR_H_ -#define _MAC68K_KBDVAR_H_ - -#include <machine/adbsys.h> +#ifndef _ADB_AKBDVAR_H_ +#define _ADB_AKBDVAR_H_ /* * State info, per keyboard instance. @@ -65,7 +63,10 @@ struct akbd_softc { #define LED_CAPSLOCK 0x2 #define LED_SCROLL_LOCK 0x4 -void kbd_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command); -int akbd_cnattach(void); +int akbd_cnattach(void); +int akbd_is_console(void); + +extern struct wskbd_mapdata akbd_keymapdata; +extern int adb_polledkey; -#endif /* _MAC68K_KBDVAR_H_ */ +#endif /* _ADB_AKBDVAR_H_ */ diff --git a/sys/arch/mac68k/dev/ams.c b/sys/dev/adb/ams.c index a5f5e43bb0c..97edff1b7a5 100644 --- a/sys/arch/mac68k/dev/ams.c +++ b/sys/dev/adb/ams.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ams.c,v 1.4 2006/01/13 19:36:44 miod Exp $ */ +/* $OpenBSD: ams.c,v 1.1 2006/01/18 23:21:17 miod Exp $ */ /* $NetBSD: ams.c,v 1.11 2000/12/19 03:13:40 tsubai Exp $ */ /* @@ -45,16 +45,14 @@ #include <dev/wscons/wsconsio.h> #include <dev/wscons/wsmousevar.h> -#include <mac68k/dev/adbvar.h> -#include <mac68k/dev/amsvar.h> +#include <dev/adb/adb.h> +#include <dev/adb/amsvar.h> /* * Function declarations. */ int amsmatch(struct device *, void *, void *); void amsattach(struct device *, struct device *, void *); -void ems_init(struct ams_softc *); -void ms_processevent(adb_event_t *event, struct ams_softc *); /* Driver definition. */ struct cfattach ams_ca = { @@ -65,10 +63,9 @@ struct cfdriver ams_cd = { NULL, "ams", DV_DULL }; - -int ams_enable(void *); -int ams_ioctl(void *, u_long, caddr_t, int, struct proc *); -void ams_disable(void *); +int ams_enable(void *); +int ams_ioctl(void *, u_long, caddr_t, int, struct proc *); +void ams_disable(void *); const struct wsmouse_accessops ams_accessops = { ams_enable, @@ -76,6 +73,11 @@ const struct wsmouse_accessops ams_accessops = { ams_disable, }; +void ems_init(struct ams_softc *); +void ms_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command); +void ms_handoff(adb_event_t *event, struct ams_softc *); +void ms_processevent(adb_event_t *event, struct ams_softc *); + int amsmatch(struct device *parent, void *cf, void *aux) { @@ -177,10 +179,10 @@ amsattach(struct device *parent, struct device *self, void *aux) sc->handler_id); break; } - error = SetADBInfo(&adbinfo, sc->adbaddr); + error = set_adb_info(&adbinfo, sc->adbaddr); #ifdef ADB_DEBUG if (adb_debug) - printf("ams: returned %d from SetADBInfo\n", error); + printf("ams: returned %d from set_adb_info\n", error); #endif a.accessops = &ams_accessops; diff --git a/sys/arch/mac68k/dev/amsvar.h b/sys/dev/adb/amsvar.h index a4d7960cbd6..e121af61fcd 100644 --- a/sys/arch/mac68k/dev/amsvar.h +++ b/sys/dev/adb/amsvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: amsvar.h,v 1.1 2006/01/04 20:39:04 miod Exp $ */ +/* $OpenBSD: amsvar.h,v 1.1 2006/01/18 23:21:17 miod Exp $ */ /* $NetBSD: amsvar.h,v 1.4 1999/06/17 06:59:05 tsubai Exp $ */ /* @@ -31,8 +31,8 @@ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -#ifndef _MAC68K_AMSVAR_H_ -#define _MAC68K_AMSVAR_H_ +#ifndef _ADB_AMSVAR_H_ +#define _ADB_AMSVAR_H_ /* * State info, per mouse instance. @@ -49,7 +49,7 @@ struct ams_softc { u_int8_t sc_class; /* mouse class (mouse, trackball) */ u_int8_t sc_buttons; /* number of buttons */ u_int32_t sc_res; /* mouse resolution (dpi) */ - char sc_devid[5]; /* device indentifier */ + char sc_devid[5]; /* device identifier */ int sc_mb; /* current button state */ struct device *sc_wsmousedev; @@ -61,7 +61,4 @@ struct ams_softc { #define MSCLASS_TRACKBALL 2 #define MSCLASS_TRACKPAD 3 -void ms_adbcomplete(caddr_t buffer, caddr_t data_area, int adb_command); -void ms_handoff(adb_event_t *event, struct ams_softc *); - -#endif /* _MAC68K_AMSVAR_H_ */ +#endif /* _ADB_AMSVAR_H_ */ diff --git a/sys/dev/adb/files.adb b/sys/dev/adb/files.adb new file mode 100644 index 00000000000..7061d8ef0dc --- /dev/null +++ b/sys/dev/adb/files.adb @@ -0,0 +1,11 @@ +# $OpenBSD: files.adb,v 1.1 2006/01/18 23:21:17 miod Exp $ + +file dev/adb/adb_subr.c adb + +device akbd: wskbddev +attach akbd at adb +file dev/adb/akbd.c akbd needs-flag + +device ams: wsmousedev +attach ams at adb +file dev/adb/ams.c ams needs-flag diff --git a/sys/dev/adb/keyboard.h b/sys/dev/adb/keyboard.h new file mode 100644 index 00000000000..ae158f92b63 --- /dev/null +++ b/sys/dev/adb/keyboard.h @@ -0,0 +1,217 @@ +/* $OpenBSD: keyboard.h,v 1.1 2006/01/18 23:21:17 miod Exp $ */ +/* $NetBSD: keyboard.h,v 1.1 1998/05/15 10:15:54 tsubai Exp $ */ + +/*- + * Copyright (C) 1993 Allen K. Briggs, Chris P. Caputo, + * Michael L. Finch, Bradley A. Grantham, and + * Lawrence A. Kesteloot + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the Alice Group. + * 4. The names of the Alice Group or any of its members may not be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define ADBK_LEFT 0x3B +#define ADBK_RIGHT 0x3C +#define ADBK_UP 0x3E +#define ADBK_DOWN 0x3D +#define ADBK_PGUP 0x74 +#define ADBK_PGDN 0x79 +#define ADBK_HOME 0x73 +#define ADBK_END 0x77 +#define ADBK_CONTROL 0x36 +#define ADBK_FLOWER 0x37 +#define ADBK_SHIFT 0x38 +#define ADBK_CAPSLOCK 0x39 +#define ADBK_OPTION 0x3A +#define ADBK_F 0x03 +#define ADBK_O 0x1F +#define ADBK_P 0x23 +#define ADBK_Q 0x0C +#define ADBK_V 0x09 +#define ADBK_1 0x12 +#define ADBK_2 0x13 +#define ADBK_3 0x14 +#define ADBK_4 0x15 +#define ADBK_5 0x17 +#define ADBK_6 0x16 +#define ADBK_7 0x1A +#define ADBK_8 0x1C +#define ADBK_9 0x19 +#define ADBK_0 0x1D + +#define ADBK_KEYVAL(key) ((key) & 0x7f) +#define ADBK_PRESS(key) (((key) & 0x80) == 0) +#define ADBK_KEYDOWN(key) (key) +#define ADBK_KEYUP(key) ((key) | 0x80) +#define ADBK_MODIFIER(key) ((((key) & 0x7f) == ADBK_SHIFT) || \ + (((key) & 0x7f) == ADBK_CONTROL) || \ + (((key) & 0x7f) == ADBK_FLOWER) || \ + (((key) & 0x7f) == ADBK_OPTION)) + +#ifndef KEYBOARD_ARRAY +extern unsigned char keyboard[128][4]; +#else +unsigned char keyboard[128][4] = { + /* Scan code Normal Shifted Controlled XT */ + { /* 0x00, */ 'a', 'A', 0x01, 30 }, + { /* 0x01, */ 's', 'S', 0x13, 31 }, + { /* 0x02, */ 'd', 'D', 0x04, 32 }, + { /* 0x03, */ 'f', 'F', 0x06, 33 }, + { /* 0x04, */ 'h', 'H', 0x08, 35 }, + { /* 0x05, */ 'g', 'G', 0x07, 34 }, + { /* 0x06, */ 'z', 'Z', 0x1A, 44 }, + { /* 0x07, */ 'x', 'X', 0x18, 45 }, + { /* 0x08, */ 'c', 'C', 0x03, 46 }, + { /* 0x09, */ 'v', 'V', 0x16, 47 }, +#ifdef FIX_SV_X_KBDBUG + { /* 0x0A, */ 0x00, 0x00, 0x00, 41 }, +#else + { /* 0x0A, */ 0x00, 0x00, 0x00, 86 }, +#endif + { /* 0x0B, */ 'b', 'B', 0x02, 48 }, + { /* 0x0C, */ 'q', 'Q', 0x11, 16 }, + { /* 0x0D, */ 'w', 'W', 0x17, 17 }, + { /* 0x0E, */ 'e', 'E', 0x05, 18 }, + { /* 0x0F, */ 'r', 'R', 0x12, 19 }, + { /* 0x10, */ 'y', 'Y', 0x19, 21 }, + { /* 0x11, */ 't', 'T', 0x14, 20 }, + { /* 0x12, */ '1', '!', 0x00, 2 }, + { /* 0x13, */ '2', '@', 0x00, 3 }, + { /* 0x14, */ '3', '#', 0x00, 4 }, + { /* 0x15, */ '4', '$', 0x00, 5 }, + { /* 0x16, */ '6', '^', 0x1E, 7 }, + { /* 0x17, */ '5', '%', 0x00, 6 }, + { /* 0x18, */ '=', '+', 0x00, 13 }, + { /* 0x19, */ '9', '(', 0x00, 10 }, + { /* 0x1A, */ '7', '&', 0x00, 8 }, + { /* 0x1B, */ '-', '_', 0x1F, 12 }, + { /* 0x1C, */ '8', '*', 0x00, 9 }, + { /* 0x1D, */ '0', ')', 0x00, 11 }, + { /* 0x1E, */ ']', '}', 0x1D, 27 }, + { /* 0x1F, */ 'o', 'O', 0x0F, 24 }, + { /* 0x20, */ 'u', 'U', 0x15, 22 }, + { /* 0x21, */ '[', '{', 0x1B, 26 }, + { /* 0x22, */ 'i', 'I', 0x09, 23 }, + { /* 0x23, */ 'p', 'P', 0x10, 25 }, + { /* 0x24, */ 0x0D, 0x0D, 0x0D, 28 }, + { /* 0x25, */ 'l', 'L', 0x0C, 38 }, + { /* 0x26, */ 'j', 'J', 0x0A, 36 }, + { /* 0x27, */ '\'', '"', 0x00, 40 }, + { /* 0x28, */ 'k', 'K', 0x0B, 37 }, + { /* 0x29, */ ';', ':', 0x00, 39 }, + { /* 0x2A, */ '\\', '|', 0x1C, 43 }, + { /* 0x2B, */ ',', '<', 0x00, 51 }, + { /* 0x2C, */ '/', '?', 0x00, 53 }, + { /* 0x2D, */ 'n', 'N', 0x0E, 49 }, + { /* 0x2E, */ 'm', 'M', 0x0D, 50 }, + { /* 0x2F, */ '.', '>', 0x00, 52 }, + { /* 0x30, */ 0x09, 0x09, 0x09, 15 }, + { /* 0x31, */ ' ', ' ', 0x00, 57 }, +#ifdef FIX_SV_X_KBDBUG + { /* 0x32, */ '`', '~', 0x00, 86 }, +#else + { /* 0x32, */ '`', '~', 0x00, 41 }, +#endif + { /* 0x33, */ 0x7F, 0x7F, 0x7F, 211 }, /* Delete */ + { /* 0x34, */ 0x00, 0x00, 0x00, 105 }, /* MODE/KP_Enter */ + { /* 0x35, */ 0x1B, 0x1B, 0x1B, 1 }, + { /* 0x36, */ 0x00, 0x00, 0x00, 29 }, + { /* 0x37, */ 0x00, 0x00, 0x00, 219 }, + { /* 0x38, */ 0x00, 0x00, 0x00, 42 }, + { /* 0x39, */ 0x00, 0x00, 0x00, 58 }, + { /* 0x3A, */ 0x00, 0x00, 0x00, 56 }, /* L Alt */ + { /* 0x3B, */ 'h', 0x00, 0x00, 203 }, /* Left */ + { /* 0x3C, */ 'l', 0x00, 0x00, 205 }, /* Right */ + { /* 0x3D, */ 'j', 0x00, 0x00, 208 }, /* Down */ + { /* 0x3E, */ 'k', 0x00, 0x00, 200 }, /* Up */ + { /* 0x3F, */ 0x00, 0x00, 0x00, 0 }, /* Fn */ + { /* 0x40, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x41, */ '.', '.', 0x00, 83 }, + { /* 0x42, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x43, */ '*', '*', 0x00, 55 }, + { /* 0x44, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x45, */ '+', '+', 0x00, 78 }, + { /* 0x46, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x47, */ 0x00, 0x00, 0x00, 69 }, + { /* 0x48, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x49, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x4A, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x4B, */ '/', '/', 0x00, 181 }, + { /* 0x4C, */ 0x0D, 0x0D, 0x0D, 156 }, + { /* 0x4D, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x4E, */ '-', '-', 0x00, 74 }, + { /* 0x4F, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x50, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x51, */ '=', '=', 0x00, 118 }, + { /* 0x52, */ '0', '0', 0x00, 82 }, + { /* 0x53, */ '1', '1', 0x00, 79 }, + { /* 0x54, */ '2', '2', 0x00, 80 }, + { /* 0x55, */ '3', '3', 0x00, 81 }, + { /* 0x56, */ '4', '4', 0x00, 75 }, + { /* 0x57, */ '5', '5', 0x00, 76 }, + { /* 0x58, */ '6', '6', 0x00, 77 }, + { /* 0x59, */ '7', '7', 0x00, 71 }, + { /* 0x5A, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x5B, */ '8', '8', 0x00, 72 }, + { /* 0x5C, */ '9', '9', 0x00, 73 }, + { /* 0x5D, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x5E, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x5F, */ 0x00, 0x00, 0x00, 51 }, + { /* 0x60, */ 0x00, 0x00, 0x00, 63 }, /* F5 */ + { /* 0x61, */ 0x00, 0x00, 0x00, 64 }, /* F6 */ + { /* 0x62, */ 0x00, 0x00, 0x00, 65 }, /* F7 */ + { /* 0x63, */ 0x00, 0x00, 0x00, 61 }, /* F3 */ + { /* 0x64, */ 0x00, 0x00, 0x00, 66 }, /* F8 */ + { /* 0x65, */ 0x00, 0x00, 0x00, 67 }, /* F9 */ + { /* 0x66, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x67, */ 0x00, 0x00, 0x00, 87 }, /* F11 */ + { /* 0x68, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x69, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x6A, */ 0x00, 0x00, 0x00, 156 }, + { /* 0x6B, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x6C, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x6D, */ 0x00, 0x00, 0x00, 68 }, /* F10 */ + { /* 0x6E, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x6F, */ 0x00, 0x00, 0x00, 88 }, /* F12 */ + { /* 0x70, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x71, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x72, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x73, */ 0x00, 0x00, 0x00, 199 }, + { /* 0x74, */ 0x00, 0x00, 0x00, 201 }, + { /* 0x75, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x76, */ 0x00, 0x00, 0x00, 62 }, /* F4 */ + { /* 0x77, */ 0x00, 0x00, 0x00, 207 }, + { /* 0x78, */ 0x00, 0x00, 0x00, 60 }, /* F2 */ + { /* 0x79, */ 0x00, 0x00, 0x00, 209 }, + { /* 0x7A, */ 0x00, 0x00, 0x00, 59 }, /* F1 */ + { /* 0x7B, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x7C, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x7D, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x7E, */ 0x00, 0x00, 0x00, 0 }, + { /* 0x7F, */ 0x00, 0x00, 0x00, 0 } /* pwr */ +}; +#endif /* KEYBOARD_ARRAY */ |