Home | History | Annotate | Line # | Download | only in dev
adb_direct.c revision 1.7
      1  1.7  briggs /*	$NetBSD: adb_direct.c,v 1.7 1997/11/04 04:00:18 briggs Exp $	*/
      2  1.5  scottr 
      3  1.5  scottr /*  From: adb_direct.c 2.02 4/18/97 jpw */
      4  1.1  scottr 
      5  1.1  scottr /*
      6  1.1  scottr  * Copyright (C) 1996, 1997 John P. Wittkoski
      7  1.1  scottr  * All rights reserved.
      8  1.1  scottr  *
      9  1.1  scottr  * Redistribution and use in source and binary forms, with or without
     10  1.1  scottr  * modification, are permitted provided that the following conditions
     11  1.1  scottr  * are met:
     12  1.1  scottr  * 1. Redistributions of source code must retain the above copyright
     13  1.1  scottr  *    notice, this list of conditions and the following disclaimer.
     14  1.1  scottr  * 2. Redistributions in binary form must reproduce the above copyright
     15  1.1  scottr  *    notice, this list of conditions and the following disclaimer in the
     16  1.1  scottr  *    documentation and/or other materials provided with the distribution.
     17  1.1  scottr  * 3. All advertising materials mentioning features or use of this software
     18  1.1  scottr  *    must display the following acknowledgement:
     19  1.1  scottr  *  This product includes software developed by John P. Wittkoski.
     20  1.1  scottr  * 4. The name of the author may not be used to endorse or promote products
     21  1.1  scottr  *    derived from this software without specific prior written permission.
     22  1.1  scottr  *
     23  1.1  scottr  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     24  1.1  scottr  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     25  1.1  scottr  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     26  1.1  scottr  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     27  1.1  scottr  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     28  1.1  scottr  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     29  1.1  scottr  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     30  1.1  scottr  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     31  1.1  scottr  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     32  1.1  scottr  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     33  1.1  scottr  */
     34  1.1  scottr 
     35  1.1  scottr /* This code is rather messy, but I don't have time right now
     36  1.1  scottr  * to clean it up as much as I would like.
     37  1.1  scottr  * But it works, so I'm happy. :-) jpw */
     38  1.1  scottr 
     39  1.1  scottr #ifdef __NetBSD__
     40  1.3  scottr #include "opt_mrg_adb.h"
     41  1.3  scottr 
     42  1.1  scottr #include <sys/param.h>
     43  1.1  scottr #include <sys/cdefs.h>
     44  1.1  scottr #include <sys/systm.h>
     45  1.1  scottr 
     46  1.1  scottr #include <machine/viareg.h>
     47  1.1  scottr #include <machine/param.h>
     48  1.1  scottr #include <machine/cpu.h>
     49  1.1  scottr #include <machine/adbsys.h>			/* required for adbvar.h */
     50  1.1  scottr 
     51  1.6  scottr #include <mac68k/mac68k/macrom.h>
     52  1.6  scottr #include <mac68k/dev/adb_direct.h>
     53  1.6  scottr #include <mac68k/dev/adbvar.h>
     54  1.1  scottr #define printf_intr printf
     55  1.1  scottr #else
     56  1.1  scottr #include "via.h"				/* for macos based testing */
     57  1.4  scottr typedef unsigned char	u_char;
     58  1.1  scottr #endif
     59  1.1  scottr 
     60  1.1  scottr /* more verbose for testing */
     61  1.1  scottr /*#define DEBUG*/
     62  1.1  scottr 
     63  1.1  scottr /* some misc. leftovers */
     64  1.1  scottr #define vPB		0x0000
     65  1.1  scottr #define vPB3		0x08
     66  1.1  scottr #define vPB4		0x10
     67  1.1  scottr #define vPB5		0x20
     68  1.1  scottr #define vSR_INT		0x04
     69  1.1  scottr #define vSR_OUT		0x10
     70  1.1  scottr 
     71  1.1  scottr /* types of adb hardware that we (will eventually) support */
     72  1.1  scottr #define ADB_HW_UNKNOWN		0x01	/* don't know */
     73  1.1  scottr #define ADB_HW_II		0x02	/* Mac II series */
     74  1.1  scottr #define ADB_HW_IISI		0x03	/* Mac IIsi series */
     75  1.1  scottr #define ADB_HW_PB		0x04	/* PowerBook series */
     76  1.1  scottr #define ADB_HW_CUDA		0x05	/* Machines with a Cuda chip */
     77  1.1  scottr 
     78  1.1  scottr /* the type of ADB action that we are currently preforming */
     79  1.1  scottr #define ADB_ACTION_NOTREADY	0x01	/* has not been initialized yet */
     80  1.1  scottr #define ADB_ACTION_IDLE		0x02	/* the bus is currently idle */
     81  1.1  scottr #define ADB_ACTION_OUT		0x03	/* sending out a command */
     82  1.1  scottr #define ADB_ACTION_IN		0x04	/* receiving data */
     83  1.1  scottr 
     84  1.1  scottr /*
     85  1.1  scottr  * These describe the state of the ADB bus itself, although they
     86  1.1  scottr  * don't necessarily correspond directly to ADB states.
     87  1.1  scottr  * Note: these are not really used in the IIsi code.
     88  1.1  scottr  */
     89  1.1  scottr #define ADB_BUS_UNKNOWN		0x01	/* we don't know yet - all models */
     90  1.1  scottr #define ADB_BUS_IDLE		0x02	/* bus is idle - all models */
     91  1.1  scottr #define ADB_BUS_CMD		0x03	/* starting a command - II models */
     92  1.1  scottr #define ADB_BUS_ODD		0x04	/* the "odd" state - II models */
     93  1.1  scottr #define ADB_BUS_EVEN		0x05	/* the "even" state - II models */
     94  1.1  scottr #define ADB_BUS_ACTIVE		0x06	/* active state - IIsi models */
     95  1.1  scottr #define ADB_BUS_ACK		0x07	/* currently ACKing - IIsi models */
     96  1.1  scottr 
     97  1.1  scottr /*
     98  1.1  scottr  * Shortcuts for setting or testing the VIA bit states.
     99  1.1  scottr  * Not all shortcuts are used for every type of ADB hardware.
    100  1.1  scottr  */
    101  1.1  scottr #define ADB_SET_STATE_IDLE_II()		via_reg(VIA1, vBufB) |= (vPB4 | vPB5)
    102  1.1  scottr #define ADB_SET_STATE_IDLE_IISI()	via_reg(VIA1, vBufB) &= ~(vPB4 | vPB5)
    103  1.1  scottr #define ADB_SET_STATE_IDLE_CUDA()	via_reg(VIA1, vBufB) |= (vPB4 | vPB5)
    104  1.1  scottr #define ADB_SET_STATE_CMD()		via_reg(VIA1, vBufB) &= ~(vPB4 | vPB5)
    105  1.5  scottr #define ADB_SET_STATE_EVEN()		via_reg(VIA1, vBufB) = ((via_reg(VIA1, \
    106  1.5  scottr 						vBufB) | vPB4) & ~vPB5)
    107  1.5  scottr #define ADB_SET_STATE_ODD()		via_reg(VIA1, vBufB) = ((via_reg(VIA1, \
    108  1.1  scottr 						vBufB) | vPB5) & ~vPB4 )
    109  1.1  scottr #define ADB_SET_STATE_ACTIVE() 		via_reg(VIA1, vBufB) |= vPB5
    110  1.1  scottr #define ADB_SET_STATE_INACTIVE()	via_reg(VIA1, vBufB) &= ~vPB5
    111  1.1  scottr #define ADB_SET_STATE_TIP()		via_reg(VIA1, vBufB) &= ~vPB5
    112  1.1  scottr #define ADB_CLR_STATE_TIP() 		via_reg(VIA1, vBufB) |= vPB5
    113  1.1  scottr #define ADB_SET_STATE_ACKON()		via_reg(VIA1, vBufB) |= vPB4
    114  1.1  scottr #define ADB_SET_STATE_ACKOFF()		via_reg(VIA1, vBufB) &= ~vPB4
    115  1.1  scottr #define ADB_TOGGLE_STATE_ACK_CUDA()	via_reg(VIA1, vBufB) ^= vPB4
    116  1.1  scottr #define ADB_SET_STATE_ACKON_CUDA()	via_reg(VIA1, vBufB) &= ~vPB4
    117  1.1  scottr #define ADB_SET_STATE_ACKOFF_CUDA()	via_reg(VIA1, vBufB) |= vPB4
    118  1.1  scottr #define ADB_SET_SR_INPUT()		via_reg(VIA1, vACR) &= ~vSR_OUT
    119  1.1  scottr #define ADB_SET_SR_OUTPUT()		via_reg(VIA1, vACR) |= vSR_OUT
    120  1.1  scottr #define ADB_SR()			via_reg(VIA1, vSR)
    121  1.1  scottr #define ADB_VIA_INTR_ENABLE()		via_reg(VIA1, vIER) = 0x84
    122  1.1  scottr #define ADB_VIA_INTR_DISABLE()		via_reg(VIA1, vIER) = 0x04
    123  1.1  scottr #define ADB_VIA_CLR_INTR()		via_reg(VIA1, vIFR) = 0x04
    124  1.5  scottr #define ADB_INTR_IS_OFF			(vPB3 == (via_reg(VIA1, vBufB) & vPB3))
    125  1.5  scottr #define ADB_INTR_IS_ON			(0 == (via_reg(VIA1, vBufB) & vPB3))
    126  1.5  scottr #define ADB_SR_INTR_IS_OFF		(0 == (via_reg(VIA1, vIFR) & vSR_INT))
    127  1.5  scottr #define ADB_SR_INTR_IS_ON		(vSR_INT == (via_reg(VIA1, \
    128  1.5  scottr 						vIFR) & vSR_INT))
    129  1.1  scottr 
    130  1.5  scottr /*
    131  1.1  scottr  * This is the delay that is required (in uS) between certain
    132  1.1  scottr  * ADB transactions. The actual timing delay for for each uS is
    133  1.1  scottr  * calculated at boot time to account for differences in machine speed.
    134  1.1  scottr  */
    135  1.5  scottr #define ADB_DELAY	150
    136  1.1  scottr 
    137  1.1  scottr /*
    138  1.1  scottr  * Maximum ADB message length; includes space for data, result, and
    139  1.1  scottr  * device code - plus a little for safety.
    140  1.1  scottr  */
    141  1.1  scottr #define MAX_ADB_MSG_LENGTH	20
    142  1.1  scottr 
    143  1.1  scottr /*
    144  1.1  scottr  * A structure for storing information about each ADB device.
    145  1.1  scottr  */
    146  1.5  scottr struct ADBDevEntry {
    147  1.1  scottr 	void	(*ServiceRtPtr) __P((void));
    148  1.1  scottr 	void	*DataAreaAddr;
    149  1.1  scottr 	char	devType;
    150  1.1  scottr 	char	origAddr;
    151  1.1  scottr 	char	currentAddr;
    152  1.1  scottr };
    153  1.1  scottr 
    154  1.1  scottr /*
    155  1.1  scottr  * Used to hold ADB commands that are waiting to be sent out.
    156  1.1  scottr  */
    157  1.1  scottr struct adbCmdHoldEntry {
    158  1.4  scottr 	u_char	outBuf[MAX_ADB_MSG_LENGTH];	/* our message */
    159  1.4  scottr 	u_char	*saveBuf;	/* buffer to know where to save result */
    160  1.4  scottr 	u_char	*compRout;	/* completion routine pointer */
    161  1.4  scottr 	u_char	*data;		/* completion routine data pointer */
    162  1.1  scottr };
    163  1.1  scottr 
    164  1.1  scottr /*
    165  1.1  scottr  * A few variables that we need and their initial values.
    166  1.1  scottr  */
    167  1.1  scottr int	adbHardware = ADB_HW_UNKNOWN;
    168  1.1  scottr int	adbActionState = ADB_ACTION_NOTREADY;
    169  1.1  scottr int	adbBusState = ADB_BUS_UNKNOWN;
    170  1.1  scottr int	adbWaiting = 0;		/* waiting for return data from the device */
    171  1.1  scottr int	adbWriteDelay = 0;	/* working on (or waiting to do) a write */
    172  1.5  scottr int	adbOutQueueHasData = 0;	/* something in the queue waiting to go out */
    173  1.1  scottr int	adbNextEnd = 0;		/* the next incoming bute is the last (II) */
    174  1.1  scottr 
    175  1.1  scottr int	adbWaitingCmd = 0;	/* ADB command we are waiting for */
    176  1.1  scottr u_char	*adbBuffer = (long) 0;	/* pointer to user data area */
    177  1.5  scottr void	*adbCompRout = (long) 0;	/* pointer to the completion routine */
    178  1.5  scottr void	*adbCompData = (long) 0;	/* pointer to the completion routine data */
    179  1.1  scottr long	adbFakeInts = 0;	/* keeps track of fake ADB interrupts for
    180  1.1  scottr 				 * timeouts (II) */
    181  1.5  scottr int	adbStarting = 1;	/* doing ADBReInit so do polling differently */
    182  1.1  scottr int	adbSendTalk = 0;	/* the intr routine is sending the talk, not
    183  1.1  scottr 				 * the user (II) */
    184  1.1  scottr int	adbPolling = 0;		/* we are polling for service request */
    185  1.1  scottr int	adbPollCmd = 0;		/* the last poll command we sent */
    186  1.1  scottr 
    187  1.5  scottr u_char	adbInputBuffer[MAX_ADB_MSG_LENGTH];	/* data input buffer */
    188  1.5  scottr u_char	adbOutputBuffer[MAX_ADB_MSG_LENGTH];	/* data output buffer */
    189  1.5  scottr struct	adbCmdHoldEntry adbOutQueue;		/* our 1 entry output queue */
    190  1.1  scottr 
    191  1.1  scottr int	adbSentChars = 0;	/* how many characters we have sent */
    192  1.5  scottr int	adbLastDevice = 0;	/* last ADB dev we heard from (II ONLY) */
    193  1.5  scottr int	adbLastDevIndex = 0;	/* last ADB dev loc in dev table (II ONLY) */
    194  1.1  scottr int	adbLastCommand = 0;	/* the last ADB command we sent (II) */
    195  1.1  scottr 
    196  1.1  scottr struct ADBDevEntry ADBDevTable[16];	/* our ADB device table */
    197  1.5  scottr int	ADBNumDevices;		/* num. of ADB devices found with ADBReInit */
    198  1.1  scottr 
    199  1.1  scottr extern struct mac68k_machine_S mac68k_machine;
    200  1.1  scottr 
    201  1.4  scottr int	zshard __P((int));
    202  1.1  scottr 
    203  1.4  scottr void	pm_setup_adb __P((void));
    204  1.4  scottr void	pm_check_adb_devices __P((int));
    205  1.4  scottr void	pm_intr __P((void));
    206  1.4  scottr int	pm_adb_op __P((u_char *, void *, void *, int));
    207  1.4  scottr void	pm_init_adb_device __P((void));
    208  1.1  scottr 
    209  1.1  scottr /*
    210  1.1  scottr  * The following are private routines.
    211  1.1  scottr  */
    212  1.4  scottr void	print_single __P((u_char *));
    213  1.4  scottr void	adb_intr __P((void));
    214  1.4  scottr void	adb_intr_II __P((void));
    215  1.4  scottr void	adb_intr_IIsi __P((void));
    216  1.4  scottr void	adb_intr_cuda __P((void));
    217  1.4  scottr int	send_adb_II __P((u_char *, u_char *, void *, void *, int));
    218  1.4  scottr int	send_adb_IIsi __P((u_char *, u_char *, void *, void *, int));
    219  1.4  scottr int	send_adb_cuda __P((u_char *, u_char *, void *, void *, int));
    220  1.4  scottr void	adb_intr_cuda_test __P((void));
    221  1.4  scottr void	adb_handle_unsol __P((u_char *));
    222  1.4  scottr void	adb_op_comprout __P((void));
    223  1.4  scottr void	adb_reinit __P((void));
    224  1.4  scottr int	count_adbs __P((void));
    225  1.4  scottr int	get_ind_adb_info __P((ADBDataBlock *, int));
    226  1.4  scottr int	get_adb_info __P((ADBDataBlock *, int));
    227  1.4  scottr int	set_adb_info __P((ADBSetInfoBlock *, int));
    228  1.4  scottr void	adb_setup_hw_type __P((void));
    229  1.4  scottr int	adb_op __P((Ptr, Ptr, Ptr, short));
    230  1.4  scottr void	adb_handle_unsol __P((u_char *));
    231  1.4  scottr int	adb_op_sync __P((Ptr, Ptr, Ptr, short));
    232  1.4  scottr void	adb_read_II __P((u_char *));
    233  1.4  scottr void	adb_cleanup __P((u_char *));
    234  1.4  scottr void	adb_cleanup_IIsi __P((u_char *));
    235  1.4  scottr void	adb_comp_exec __P((void));
    236  1.4  scottr int	adb_cmd_result __P((u_char *));
    237  1.4  scottr int	adb_cmd_extra __P((u_char *));
    238  1.4  scottr int	adb_guess_next_device __P((void));
    239  1.4  scottr int	adb_prog_switch_enable __P((void));
    240  1.4  scottr int	adb_prog_switch_disable __P((void));
    241  1.1  scottr /* we should create this and it will be the public version */
    242  1.4  scottr int	send_adb __P((u_char *, void *, void *));
    243  1.1  scottr 
    244  1.1  scottr /*
    245  1.1  scottr  * print_single
    246  1.1  scottr  * Diagnostic display routine. Displays the hex values of the
    247  1.1  scottr  * specified elements of the u_char. The length of the "string"
    248  1.1  scottr  * is in [0].
    249  1.1  scottr  */
    250  1.5  scottr void
    251  1.1  scottr print_single(thestring)
    252  1.1  scottr 	u_char *thestring;
    253  1.1  scottr {
    254  1.1  scottr 	int x;
    255  1.1  scottr 
    256  1.5  scottr 	if ((int) (thestring[0]) == 0) {
    257  1.5  scottr 		printf_intr("nothing returned\n");
    258  1.5  scottr 		return;
    259  1.5  scottr 	}
    260  1.1  scottr 	if (thestring == 0) {
    261  1.1  scottr 		printf_intr("no data - null pointer\n");
    262  1.1  scottr 		return;
    263  1.1  scottr 	}
    264  1.1  scottr 	if (thestring[0] > 20) {
    265  1.1  scottr 		printf_intr("ADB: ACK > 20 no way!\n");
    266  1.1  scottr 		thestring[0] = 20;
    267  1.1  scottr 	}
    268  1.1  scottr 	printf_intr("(length=0x%x):", thestring[0]);
    269  1.1  scottr 	for (x = 0; x < thestring[0]; x++)
    270  1.1  scottr 		printf_intr("  0x%02x", thestring[x + 1]);
    271  1.1  scottr 	printf_intr("\n");
    272  1.1  scottr }
    273  1.1  scottr 
    274  1.1  scottr 
    275  1.5  scottr /*
    276  1.5  scottr  * called when when an adb interrupt happens
    277  1.1  scottr  *
    278  1.1  scottr  * Cuda version of adb_intr
    279  1.5  scottr  * TO DO: do we want to add some zshard calls in here?
    280  1.1  scottr  */
    281  1.5  scottr void
    282  1.1  scottr adb_intr_cuda(void)
    283  1.1  scottr {
    284  1.1  scottr 	int i, ending, len;
    285  1.1  scottr 	unsigned int s;
    286  1.1  scottr 
    287  1.1  scottr 	s = splhigh();		/* can't be too careful - might be called */
    288  1.5  scottr 	/* from a routine, NOT an interrupt */
    289  1.1  scottr 
    290  1.1  scottr 	ADB_VIA_CLR_INTR();	/* clear interrupt */
    291  1.1  scottr 
    292  1.1  scottr 	ADB_VIA_INTR_DISABLE();	/* disable ADB interrupt on IIs. */
    293  1.1  scottr 
    294  1.1  scottr switch_start:
    295  1.1  scottr 	switch (adbActionState) {
    296  1.1  scottr 	case ADB_ACTION_IDLE:
    297  1.5  scottr 		/* This is an unexpected packet, so grab the first (dummy)
    298  1.5  scottr 		 * byte, set up the proper vars, and tell the chip we are
    299  1.5  scottr 		 * starting to receive the packet by setting the TIP bit. */
    300  1.5  scottr 		adbInputBuffer[1] = ADB_SR();
    301  1.5  scottr 		ADB_SET_STATE_TIP();
    302  1.5  scottr 		ADB_SET_SR_INPUT();
    303  1.5  scottr 		delay(ADB_DELAY);	/* required delay */
    304  1.5  scottr #ifdef DEBUG
    305  1.5  scottr 		printf_intr("idle 0x%02x ", adbInputBuffer[1]);
    306  1.5  scottr #endif
    307  1.5  scottr 		adbInputBuffer[0] = 1;
    308  1.5  scottr 		adbActionState = ADB_ACTION_IN;
    309  1.5  scottr 		break;
    310  1.5  scottr 
    311  1.5  scottr 	case ADB_ACTION_IN:
    312  1.5  scottr 		adbInputBuffer[++adbInputBuffer[0]] = ADB_SR();
    313  1.5  scottr 		/* intr off means this is the last byte (end of frame) */
    314  1.5  scottr 		if (ADB_INTR_IS_OFF)
    315  1.5  scottr 			ending = 1;
    316  1.5  scottr 		else
    317  1.5  scottr 			ending = 0;
    318  1.5  scottr 
    319  1.5  scottr 		/* if the second byte is 0xff, it's a "dummy" packet */
    320  1.5  scottr 		if (adbInputBuffer[2] == 0xff)
    321  1.5  scottr 			ending = 1;
    322  1.5  scottr 
    323  1.5  scottr 		if (1 == ending) {	/* end of message? */
    324  1.5  scottr #ifdef DEBUG
    325  1.5  scottr 			printf_intr("in end 0x%02x ",
    326  1.5  scottr 			    adbInputBuffer[adbInputBuffer[0]]);
    327  1.5  scottr 			print_single(adbInputBuffer);
    328  1.5  scottr #endif
    329  1.5  scottr 
    330  1.5  scottr 			/* Are we waiting AND does this packet match what we
    331  1.5  scottr 			 * are waiting for AND is it coming from either the
    332  1.5  scottr 			 * ADB or RTC/PRAM sub-device? This section _should_
    333  1.5  scottr 			 * recognize all ADB and RTC/PRAM type commands, but
    334  1.5  scottr 			 * there may be more... NOTE: commands are always at
    335  1.5  scottr 			 * [4], even for RTC/PRAM commands. */
    336  1.5  scottr 			if ((adbWaiting == 1) &&
    337  1.5  scottr 			    (adbInputBuffer[4] == adbWaitingCmd) &&
    338  1.5  scottr 			    ((adbInputBuffer[2] == 0x00) ||
    339  1.5  scottr 			    (adbInputBuffer[2] == 0x01))) {
    340  1.5  scottr 
    341  1.5  scottr 				if (adbBuffer != (long) 0) {
    342  1.5  scottr 					/* if valid return data pointer */
    343  1.1  scottr 					/* get return length minus extras */
    344  1.5  scottr 					len = adbInputBuffer[0] - 4;
    345  1.5  scottr 					/*
    346  1.5  scottr 					 * If adb_op is ever made to be called
    347  1.5  scottr 					 * from a user routine, we should use
    348  1.5  scottr 					 * a copyout or copyin here to be sure
    349  1.5  scottr 					 * we're in the correct context
    350  1.5  scottr 					 */
    351  1.5  scottr 					for (i = 1; i <= len; i++)
    352  1.5  scottr 						adbBuffer[i] = adbInputBuffer[4 + i];
    353  1.5  scottr 					if (len < 0)
    354  1.5  scottr 						len = 0;
    355  1.5  scottr 					adbBuffer[0] = len;
    356  1.5  scottr 				}
    357  1.5  scottr 				/* call completion routine and clean up */
    358  1.5  scottr 				adb_comp_exec();
    359  1.5  scottr 				adbWaitingCmd = 0;
    360  1.5  scottr 				adbWaiting = 0;
    361  1.5  scottr 				adbBuffer = (long) 0;
    362  1.5  scottr 				adbCompRout = (long) 0;
    363  1.5  scottr 				adbCompData = (long) 0;
    364  1.5  scottr 			} else {
    365  1.5  scottr 				/*
    366  1.5  scottr 				 * This was an unsolicited packet, so
    367  1.5  scottr 				 * pass the data off to the handler for
    368  1.5  scottr 				 * this device if we are NOT doing this
    369  1.5  scottr 				 * during a ADBReInit.
    370  1.5  scottr 				 * This section IGNORES all data that is not
    371  1.5  scottr 				 * from the ADB sub-device. That is, not from
    372  1.5  scottr 				 * RTC or PRAM. Maybe we should fix later,
    373  1.5  scottr 				 * but do the other devices every send things
    374  1.5  scottr 				 * without being asked?
    375  1.5  scottr 				 */
    376  1.5  scottr 				if (adbStarting == 0)
    377  1.5  scottr 					if (adbInputBuffer[2] == 0x00)
    378  1.5  scottr 						adb_handle_unsol(adbInputBuffer);
    379  1.5  scottr 			}
    380  1.1  scottr 
    381  1.5  scottr 			/* reset vars and signal the end of this frame */
    382  1.5  scottr 			adbActionState = ADB_ACTION_IDLE;
    383  1.5  scottr 			adbInputBuffer[0] = 0;
    384  1.5  scottr 			ADB_SET_STATE_IDLE_CUDA();
    385  1.5  scottr 
    386  1.5  scottr 			/*
    387  1.5  scottr 			 * If there is something waiting to be sent out,
    388  1.5  scottr 			 * the set everything up and send the first byte.
    389  1.5  scottr 			 */
    390  1.5  scottr 			if (adbWriteDelay == 1) {
    391  1.5  scottr 				delay(ADB_DELAY);	/* required */
    392  1.5  scottr 				adbSentChars = 0;
    393  1.5  scottr 				adbActionState = ADB_ACTION_OUT;
    394  1.5  scottr 
    395  1.5  scottr /* TO DO: don't we need to set up adbWaiting vars here??? */
    396  1.5  scottr 
    397  1.5  scottr 				/*
    398  1.5  scottr 				 * If the interrupt is on, we were too slow
    399  1.5  scottr 				 * and the chip has already started to send
    400  1.5  scottr 				 * something to us, so back out of the write
    401  1.5  scottr 				 * and start a read cycle.
    402  1.5  scottr 				 */
    403  1.5  scottr 				if (ADB_INTR_IS_ON) {
    404  1.5  scottr 					ADB_SET_STATE_IDLE_CUDA();
    405  1.5  scottr 					ADB_SET_SR_INPUT();
    406  1.5  scottr 					adbSentChars = 0;
    407  1.5  scottr 					adbActionState = ADB_ACTION_IDLE;
    408  1.5  scottr 					adbInputBuffer[0] = 0;
    409  1.5  scottr 					break;
    410  1.5  scottr 				}
    411  1.5  scottr 				/*
    412  1.5  scottr 				 * If we got here, it's ok to start sending
    413  1.5  scottr 				 * so load the first byte and tell the chip
    414  1.5  scottr 				 * we want to send.
    415  1.5  scottr 				 */
    416  1.5  scottr 				ADB_SET_SR_OUTPUT();
    417  1.5  scottr 				ADB_SR() = adbOutputBuffer[adbSentChars + 1];
    418  1.5  scottr 				ADB_SET_STATE_TIP();
    419  1.5  scottr 			}
    420  1.5  scottr 		} else {
    421  1.5  scottr 			ADB_TOGGLE_STATE_ACK_CUDA();
    422  1.5  scottr #ifdef DEBUG
    423  1.5  scottr 			printf_intr("in 0x%02x ",
    424  1.5  scottr 			    adbInputBuffer[adbInputBuffer[0]]);
    425  1.5  scottr #endif
    426  1.5  scottr 		}
    427  1.5  scottr 		break;
    428  1.1  scottr 
    429  1.5  scottr 	case ADB_ACTION_OUT:
    430  1.5  scottr 		i = ADB_SR();	/* reset SR-intr in IFR */
    431  1.5  scottr #ifdef DEBUG
    432  1.5  scottr 		printf_intr("intr out 0x%02x ", i);
    433  1.5  scottr #endif
    434  1.5  scottr 		ADB_SET_SR_OUTPUT();	/* set shift register for OUT */
    435  1.1  scottr 
    436  1.5  scottr 		adbSentChars++;
    437  1.5  scottr 		if (ADB_INTR_IS_ON) {	/* ADB intr low during write */
    438  1.5  scottr #ifdef DEBUG
    439  1.5  scottr 			printf_intr("intr was on ");
    440  1.5  scottr #endif
    441  1.5  scottr 			ADB_SET_STATE_IDLE_CUDA();
    442  1.5  scottr 			ADB_SET_SR_INPUT();	/* make sure SR is set to IN */
    443  1.5  scottr 			adbSentChars = 0;	/* must start all over */
    444  1.5  scottr 			adbActionState = ADB_ACTION_IDLE;	/* new state */
    445  1.5  scottr 			adbInputBuffer[0] = 0;
    446  1.5  scottr 			adbWriteDelay = 1;	/* must retry when done with
    447  1.5  scottr 						 * read */
    448  1.5  scottr 			delay(ADB_DELAY);
    449  1.5  scottr 			goto switch_start;	/* process next state right
    450  1.5  scottr 						 * now */
    451  1.5  scottr 			break;
    452  1.5  scottr 		}
    453  1.5  scottr 		if (adbOutputBuffer[0] == adbSentChars) {	/* check for done */
    454  1.5  scottr 			if (0 == adb_cmd_result(adbOutputBuffer)) {	/* do we expect data
    455  1.5  scottr 									 * back? */
    456  1.5  scottr 				adbWaiting = 1;	/* signal waiting for return */
    457  1.5  scottr 				adbWaitingCmd = adbOutputBuffer[2];	/* save waiting command */
    458  1.5  scottr 			} else {/* no talk, so done */
    459  1.5  scottr 				adb_comp_exec();	/* call completion
    460  1.5  scottr 							 * routine */
    461  1.5  scottr 				adbWaitingCmd = 0;	/* reset "waiting" vars,
    462  1.5  scottr 							 * just in case */
    463  1.5  scottr 				adbBuffer = (long) 0;
    464  1.5  scottr 				adbCompRout = (long) 0;
    465  1.5  scottr 				adbCompData = (long) 0;
    466  1.5  scottr 			}
    467  1.1  scottr 
    468  1.5  scottr 			adbWriteDelay = 0;	/* done writing */
    469  1.5  scottr 			adbActionState = ADB_ACTION_IDLE;	/* signal bus is idle */
    470  1.5  scottr 			ADB_SET_STATE_IDLE_CUDA();
    471  1.5  scottr #ifdef DEBUG
    472  1.5  scottr 			printf_intr("write done ");
    473  1.5  scottr #endif
    474  1.5  scottr 		} else {
    475  1.5  scottr 			ADB_SR() = adbOutputBuffer[adbSentChars + 1];	/* send next byte */
    476  1.5  scottr 			ADB_TOGGLE_STATE_ACK_CUDA();	/* signal byte ready to
    477  1.5  scottr 							 * shift */
    478  1.5  scottr #ifdef DEBUG
    479  1.5  scottr 			printf_intr("toggle ");
    480  1.5  scottr #endif
    481  1.5  scottr 		}
    482  1.5  scottr 		break;
    483  1.1  scottr 
    484  1.5  scottr 	case ADB_ACTION_NOTREADY:
    485  1.5  scottr 		printf_intr("adb: not yet initialized\n");
    486  1.5  scottr 		break;
    487  1.1  scottr 
    488  1.5  scottr 	default:
    489  1.5  scottr 		printf_intr("intr: unknown ADB state\n");
    490  1.5  scottr 	}
    491  1.1  scottr 
    492  1.5  scottr 	ADB_VIA_INTR_ENABLE();	/* enable ADB interrupt on IIs. */
    493  1.1  scottr 
    494  1.5  scottr 	splx(s);		/* restore */
    495  1.1  scottr 
    496  1.5  scottr 	return;
    497  1.5  scottr }				/* end adb_intr_IIsi */
    498  1.1  scottr 
    499  1.1  scottr 
    500  1.5  scottr int
    501  1.5  scottr send_adb_cuda(u_char * in, u_char * buffer, void *compRout, void *data, int
    502  1.5  scottr 	command)
    503  1.5  scottr {
    504  1.5  scottr 	int i, s, len;
    505  1.1  scottr 
    506  1.5  scottr #ifdef DEBUG
    507  1.5  scottr 	printf_intr("SEND\n");
    508  1.5  scottr #endif
    509  1.1  scottr 
    510  1.5  scottr 	if (adbActionState == ADB_ACTION_NOTREADY)
    511  1.5  scottr 		return 1;
    512  1.1  scottr 
    513  1.5  scottr 	s = splhigh();		/* don't interrupt while we are messing with
    514  1.5  scottr 				 * the ADB */
    515  1.1  scottr 
    516  1.5  scottr 	if ((adbActionState == ADB_ACTION_IDLE) &&	/* ADB available? */
    517  1.5  scottr 	    (ADB_INTR_IS_OFF)) {	/* and no incoming interrupt? */
    518  1.5  scottr 	} else
    519  1.5  scottr 		if (adbWriteDelay == 0)	/* it's busy, but is anything waiting? */
    520  1.5  scottr 			adbWriteDelay = 1;	/* if no, then we'll "queue"
    521  1.5  scottr 						 * it up */
    522  1.5  scottr 		else {
    523  1.5  scottr 			splx(s);
    524  1.5  scottr 			return 1;	/* really busy! */
    525  1.5  scottr 		}
    526  1.1  scottr 
    527  1.5  scottr #ifdef DEBUG
    528  1.5  scottr 	printf_intr("QUEUE\n");
    529  1.1  scottr #endif
    530  1.5  scottr 	if ((long) in == (long) 0) {	/* need to convert? */
    531  1.5  scottr 		/* don't need to use adb_cmd_extra here because this section
    532  1.5  scottr 		 * will be called */
    533  1.5  scottr 		/* ONLY when it is an ADB command (no RTC or PRAM) */
    534  1.5  scottr 		if ((command & 0x0c) == 0x08)	/* copy addl data ONLY if
    535  1.5  scottr 						 * doing a listen! */
    536  1.5  scottr 			len = buffer[0];	/* length of additional data */
    537  1.5  scottr 		else
    538  1.5  scottr 			len = 0;/* no additional data */
    539  1.1  scottr 
    540  1.5  scottr 		adbOutputBuffer[0] = 2 + len;	/* dev. type + command + addl.
    541  1.5  scottr 						 * data */
    542  1.5  scottr 		adbOutputBuffer[1] = 0x00;	/* mark as an ADB command */
    543  1.5  scottr 		adbOutputBuffer[2] = (u_char) command;	/* load command */
    544  1.5  scottr 
    545  1.5  scottr 		for (i = 1; i <= len; i++)	/* copy additional output
    546  1.5  scottr 						 * data, if any */
    547  1.5  scottr 			adbOutputBuffer[2 + i] = buffer[i];
    548  1.5  scottr 	} else
    549  1.5  scottr 		for (i = 0; i <= (adbOutputBuffer[0] + 1); i++)
    550  1.5  scottr 			adbOutputBuffer[i] = in[i];
    551  1.5  scottr 
    552  1.5  scottr 	adbSentChars = 0;	/* nothing sent yet */
    553  1.5  scottr 	adbBuffer = buffer;	/* save buffer to know where to save result */
    554  1.5  scottr 	adbCompRout = compRout;	/* save completion routine pointer */
    555  1.5  scottr 	adbCompData = data;	/* save completion routine data pointer */
    556  1.5  scottr 	adbWaitingCmd = adbOutputBuffer[2];	/* save wait command */
    557  1.5  scottr 
    558  1.5  scottr 	if (adbWriteDelay != 1) {	/* start command now? */
    559  1.5  scottr #ifdef DEBUG
    560  1.5  scottr 		printf_intr("out start NOW");
    561  1.5  scottr #endif
    562  1.5  scottr 		delay(ADB_DELAY);
    563  1.5  scottr 		adbActionState = ADB_ACTION_OUT;	/* set next state */
    564  1.5  scottr 		ADB_SET_SR_OUTPUT();	/* set shift register for OUT */
    565  1.5  scottr 		ADB_SR() = adbOutputBuffer[adbSentChars + 1];	/* load byte for output */
    566  1.5  scottr 		ADB_SET_STATE_ACKOFF_CUDA();
    567  1.5  scottr 		ADB_SET_STATE_TIP();	/* tell ADB that we want to send */
    568  1.5  scottr 	}
    569  1.5  scottr 	adbWriteDelay = 1;	/* something in the write "queue" */
    570  1.1  scottr 
    571  1.5  scottr 	splx(s);
    572  1.1  scottr 
    573  1.5  scottr 	if (0x0100 <= (s & 0x0700))	/* were VIA1 interrupts blocked ? */
    574  1.5  scottr 		/* poll until byte done */
    575  1.5  scottr 		while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
    576  1.5  scottr 		    || (adbWaiting == 1))
    577  1.5  scottr 			if (ADB_SR_INTR_IS_ON)	/* wait for "interrupt" */
    578  1.5  scottr 				adb_intr_cuda();	/* go process
    579  1.5  scottr 							 * "interrupt" */
    580  1.1  scottr 
    581  1.5  scottr 	return 0;
    582  1.5  scottr }				/* send_adb_cuda */
    583  1.1  scottr 
    584  1.1  scottr 
    585  1.1  scottr /* TO DO: add one or two zshard calls in here */
    586  1.1  scottr void
    587  1.1  scottr adb_intr_II(void)
    588  1.1  scottr {
    589  1.5  scottr 	int i, len, intr_on = 0;
    590  1.5  scottr 	int send = 0, do_srq = 0;
    591  1.5  scottr 	unsigned int s;
    592  1.1  scottr 
    593  1.5  scottr 	s = splhigh();		/* can't be too careful - might be called */
    594  1.5  scottr 	/* from a routine, NOT an interrupt */
    595  1.1  scottr 
    596  1.5  scottr 	ADB_VIA_CLR_INTR();	/* clear interrupt */
    597  1.1  scottr 
    598  1.5  scottr 	ADB_VIA_INTR_DISABLE();	/* disable ADB interrupt on IIs. */
    599  1.1  scottr 
    600  1.1  scottr /*if (ADB_INTR_IS_ON)*/
    601  1.1  scottr /*	printf_intr("INTR ON ");*/
    602  1.5  scottr 	if (ADB_INTR_IS_ON)
    603  1.5  scottr 		intr_on = 1;	/* save for later */
    604  1.5  scottr 
    605  1.5  scottr 	switch (adbActionState) {
    606  1.5  scottr 	case ADB_ACTION_IDLE:
    607  1.5  scottr 		if (!intr_on) {
    608  1.5  scottr 			/* printf_intr("FAKE DROPPED \n"); */
    609  1.5  scottr 			/* printf_intr(" XX "); */
    610  1.5  scottr 			i = ADB_SR();
    611  1.5  scottr 			break;
    612  1.5  scottr 		}
    613  1.5  scottr 		adbNextEnd = 0;
    614  1.5  scottr 		/* printf_intr("idle "); */
    615  1.5  scottr 		adbInputBuffer[0] = 1;
    616  1.5  scottr 		adbInputBuffer[1] = ADB_SR();	/* get first byte */
    617  1.5  scottr 		/* printf_intr("0x%02x ", adbInputBuffer[1]); */
    618  1.5  scottr 		ADB_SET_SR_INPUT();	/* make sure SR is set to IN */
    619  1.5  scottr 		adbActionState = ADB_ACTION_IN;	/* set next state */
    620  1.5  scottr 		ADB_SET_STATE_EVEN();	/* set bus state to even */
    621  1.5  scottr 		adbBusState = ADB_BUS_EVEN;
    622  1.5  scottr 		break;
    623  1.5  scottr 
    624  1.5  scottr 	case ADB_ACTION_IN:
    625  1.5  scottr 		adbInputBuffer[++adbInputBuffer[0]] = ADB_SR();	/* get byte */
    626  1.5  scottr 		/* printf_intr("in 0x%02x ",
    627  1.5  scottr 		 * adbInputBuffer[adbInputBuffer[0]]); */
    628  1.5  scottr 		ADB_SET_SR_INPUT();	/* make sure SR is set to IN */
    629  1.1  scottr 
    630  1.5  scottr 		/*
    631  1.5  scottr 		 * Check for an unsolicited Service Request (SRQ).
    632  1.5  scottr 		 * An empty SRQ packet NEVER ends, so we must manually
    633  1.5  scottr 		 * check for the following condition.
    634  1.5  scottr 		 */
    635  1.5  scottr 		if (adbInputBuffer[0] == 4 && adbInputBuffer[2] == 0xff &&
    636  1.5  scottr 		    adbInputBuffer[3] == 0xff && adbInputBuffer[4] == 0xff &&
    637  1.5  scottr 		    intr_on && !adbNextEnd)
    638  1.5  scottr 			do_srq = 1;
    639  1.5  scottr 
    640  1.5  scottr 		if (adbNextEnd == 1) {	/* process last byte of packet */
    641  1.5  scottr 			adbNextEnd = 0;
    642  1.5  scottr 			/* printf_intr("done: "); */
    643  1.5  scottr 
    644  1.5  scottr 			/* If the following conditions are true (4 byte
    645  1.5  scottr 			 * message, last 3 bytes are 0xff) then we basically
    646  1.5  scottr 			 * got a "no response" from the ADB chip, so change
    647  1.5  scottr 			 * the message to an empty one. We also clear intr_on
    648  1.5  scottr 			 * to stop the SRQ send later on because these packets
    649  1.5  scottr 			 * normally have the SRQ bit set even when there is
    650  1.5  scottr 			 * NOT a pending SRQ. */
    651  1.5  scottr 			if (adbInputBuffer[0] == 4 && adbInputBuffer[2] == 0xff &&
    652  1.5  scottr 			    adbInputBuffer[3] == 0xff && adbInputBuffer[4] == 0xff) {
    653  1.5  scottr 				/* printf_intr("NO RESP "); */
    654  1.5  scottr 				intr_on = 0;
    655  1.5  scottr 				adbInputBuffer[0] = 0;
    656  1.5  scottr 			}
    657  1.5  scottr 			adbLastDevice = (adbInputBuffer[1] & 0xf0) >> 4;
    658  1.5  scottr 
    659  1.5  scottr 			if ((!adbWaiting || adbPolling)
    660  1.5  scottr 			    && (adbInputBuffer[0] != 0)) {
    661  1.5  scottr 				/* unsolicided - ignore if starting */
    662  1.5  scottr 				if (!adbStarting)
    663  1.5  scottr 					adb_handle_unsol(adbInputBuffer);
    664  1.5  scottr 			} else
    665  1.5  scottr 				if (!adbPolling) {	/* someone asked for it */
    666  1.5  scottr 					/* printf_intr("SOL: "); */
    667  1.5  scottr 					/* print_single(adbInputBuffer); */
    668  1.5  scottr 					if (adbBuffer != (long) 0) {	/* if valid return data
    669  1.5  scottr 									 * pointer */
    670  1.5  scottr 						/* get return length minus
    671  1.5  scottr 						 * extras */
    672  1.5  scottr 						len = adbInputBuffer[0] - 1;
    673  1.5  scottr 
    674  1.5  scottr 						/* if adb_op is ever made to
    675  1.5  scottr 						 * be called from a user
    676  1.5  scottr 						 * routine, we should use a
    677  1.5  scottr 						 * copyout or copyin here to
    678  1.5  scottr 						 * be sure we're in the
    679  1.5  scottr 						 * correct context. */
    680  1.5  scottr 						for (i = 1; i <= len; i++)
    681  1.5  scottr 							adbBuffer[i] = adbInputBuffer[i + 1];
    682  1.5  scottr 						if (len < 0)
    683  1.5  scottr 							len = 0;
    684  1.5  scottr 						adbBuffer[0] = len;
    685  1.5  scottr 					}
    686  1.5  scottr 					adb_comp_exec();
    687  1.5  scottr 				}
    688  1.5  scottr 			adbWaiting = 0;
    689  1.5  scottr 			adbPolling = 0;
    690  1.5  scottr 			adbInputBuffer[0] = 0;
    691  1.5  scottr 			adbBuffer = (long) 0;
    692  1.5  scottr 			adbCompRout = (long) 0;
    693  1.5  scottr 			adbCompData = (long) 0;
    694  1.5  scottr 			/*
    695  1.5  scottr 			 * Since we are done, check whether there is any data
    696  1.5  scottr 			 * waiting to do out. If so, start the sending the data.
    697  1.5  scottr 			 */
    698  1.5  scottr 			if (adbOutQueueHasData == 1) {
    699  1.5  scottr 				/* printf_intr("XXX: DOING OUT QUEUE\n"); */
    700  1.5  scottr 				/* copy over data */
    701  1.5  scottr 				for (i = 0; i <= (adbOutQueue.outBuf[0] + 1); i++)
    702  1.5  scottr 					adbOutputBuffer[i] = adbOutQueue.outBuf[i];
    703  1.5  scottr 				adbBuffer = adbOutQueue.saveBuf;	/* user data area */
    704  1.5  scottr 				adbCompRout = adbOutQueue.compRout;	/* completion routine */
    705  1.5  scottr 				adbCompData = adbOutQueue.data;	/* comp. rout. data */
    706  1.5  scottr 				adbOutQueueHasData = 0;	/* currently processing
    707  1.5  scottr 							 * "queue" entry */
    708  1.5  scottr 				adbPolling = 0;
    709  1.5  scottr 				send = 1;
    710  1.5  scottr 				/* if intr_on is true, then it's a SRQ so poll
    711  1.5  scottr 				 * other devices. */
    712  1.5  scottr 			} else
    713  1.5  scottr 				if (intr_on) {
    714  1.5  scottr 					/* printf_intr("starting POLL "); */
    715  1.5  scottr 					do_srq = 1;
    716  1.5  scottr 					adbPolling = 1;
    717  1.5  scottr 				} else
    718  1.5  scottr 					if ((adbInputBuffer[1] & 0x0f) != 0x0c) {
    719  1.5  scottr 						/* printf_intr("xC HACK "); */
    720  1.5  scottr 						adbPolling = 1;
    721  1.5  scottr 						send = 1;
    722  1.5  scottr 						adbOutputBuffer[0] = 1;
    723  1.5  scottr 						adbOutputBuffer[1] = (adbInputBuffer[1] & 0xf0) | 0x0c;
    724  1.5  scottr 					} else {
    725  1.5  scottr 						/* printf_intr("ending "); */
    726  1.5  scottr 						adbBusState = ADB_BUS_IDLE;
    727  1.5  scottr 						adbActionState = ADB_ACTION_IDLE;
    728  1.5  scottr 						ADB_SET_STATE_IDLE_II();
    729  1.5  scottr 						break;
    730  1.5  scottr 					}
    731  1.5  scottr 		}
    732  1.5  scottr 		/*
    733  1.5  scottr 		 * If do_srq is true then something above determined that
    734  1.5  scottr 		 * the message has ended and some device is sending a
    735  1.5  scottr 		 * service request. So we need to determine the next device
    736  1.5  scottr 		 * and send a poll to it. (If the device we send to isn't the
    737  1.5  scottr 		 * one that sent the SRQ, that ok as it will be caught
    738  1.5  scottr 		 * the next time though.)
    739  1.5  scottr 		 */
    740  1.5  scottr 		if (do_srq) {
    741  1.5  scottr 			/* printf_intr("SRQ! "); */
    742  1.5  scottr 			adbPolling = 1;
    743  1.5  scottr 			adb_guess_next_device();
    744  1.5  scottr 			adbOutputBuffer[0] = 1;
    745  1.5  scottr 			adbOutputBuffer[1] = ((adbLastDevice & 0x0f) << 4) | 0x0c;
    746  1.5  scottr 			send = 1;
    747  1.5  scottr 		}
    748  1.5  scottr 		/*
    749  1.5  scottr 		 * If send is true then something above determined that
    750  1.5  scottr 		 * the message has ended and we need to start sending out
    751  1.5  scottr 		 * a new message immediately. This could be because there
    752  1.5  scottr 		 * is data waiting to go out or because an SRQ was seen.
    753  1.1  scottr 		 */
    754  1.5  scottr 		if (send) {
    755  1.5  scottr 			adbNextEnd = 0;
    756  1.5  scottr 			adbSentChars = 0;	/* nothing sent yet */
    757  1.5  scottr 			adbActionState = ADB_ACTION_OUT;	/* set next state */
    758  1.5  scottr 			ADB_SET_SR_OUTPUT();	/* set shift register for OUT */
    759  1.5  scottr 			ADB_SR() = adbOutputBuffer[1];	/* load byte for output */
    760  1.5  scottr 			adbBusState = ADB_BUS_CMD;	/* set bus to cmd state */
    761  1.5  scottr 			ADB_SET_STATE_CMD();	/* tell ADB that we want to
    762  1.5  scottr 						 * send */
    763  1.5  scottr 			break;
    764  1.5  scottr 		}
    765  1.5  scottr 		/* We only get this far if the message hasn't ended yet. */
    766  1.5  scottr 		if (!intr_on)	/* if adb intr. on then the */
    767  1.5  scottr 			adbNextEnd = 1;	/* NEXT byte is the last */
    768  1.5  scottr 
    769  1.5  scottr 		switch (adbBusState) {	/* set to next state */
    770  1.5  scottr 		case ADB_BUS_EVEN:
    771  1.5  scottr 			ADB_SET_STATE_ODD();	/* set state to odd */
    772  1.1  scottr 			adbBusState = ADB_BUS_ODD;
    773  1.5  scottr 			break;
    774  1.1  scottr 
    775  1.1  scottr 		case ADB_BUS_ODD:
    776  1.5  scottr 			ADB_SET_STATE_EVEN();	/* set state to even */
    777  1.5  scottr 			adbBusState = ADB_BUS_EVEN;
    778  1.5  scottr 			break;
    779  1.5  scottr 		default:
    780  1.5  scottr 			printf_intr("strange state!!!\n");	/* huh? */
    781  1.5  scottr 			break;
    782  1.5  scottr 		}
    783  1.5  scottr 		break;
    784  1.5  scottr 
    785  1.5  scottr 	case ADB_ACTION_OUT:
    786  1.5  scottr 		adbNextEnd = 0;
    787  1.5  scottr 		if (!adbPolling)
    788  1.5  scottr 			adbWaiting = 1;	/* not unsolicited */
    789  1.5  scottr 		i = ADB_SR();	/* clear interrupt */
    790  1.5  scottr 		adbSentChars++;
    791  1.5  scottr 		/*
    792  1.5  scottr 		 * If the outgoing data was a TALK, we must
    793  1.5  scottr 		 * switch to input mode to get the result.
    794  1.5  scottr 		 */
    795  1.5  scottr 		if ((adbOutputBuffer[1] & 0x0c) == 0x0c) {
    796  1.5  scottr 			adbInputBuffer[0] = 1;
    797  1.5  scottr 			adbInputBuffer[1] = i;
    798  1.5  scottr 			adbActionState = ADB_ACTION_IN;
    799  1.5  scottr 			ADB_SET_SR_INPUT();
    800  1.5  scottr 			adbBusState = ADB_BUS_EVEN;
    801  1.5  scottr 			ADB_SET_STATE_EVEN();
    802  1.5  scottr 			/* printf_intr("talk out 0x%02x ", i); */
    803  1.5  scottr 			break;
    804  1.5  scottr 		}
    805  1.5  scottr 		/* If it's not a TALK, check whether all data has been sent.
    806  1.5  scottr 		 * If so, call the completion routine and clean up. If not,
    807  1.5  scottr 		 * advance to the next state. */
    808  1.5  scottr 		/* printf_intr("non-talk out 0x%0x ", i); */
    809  1.5  scottr 		ADB_SET_SR_OUTPUT();
    810  1.5  scottr 		if (adbOutputBuffer[0] == adbSentChars) {	/* check for done */
    811  1.5  scottr 			/* printf_intr("done \n"); */
    812  1.1  scottr 			adb_comp_exec();
    813  1.5  scottr 			adbBuffer = (long) 0;
    814  1.5  scottr 			adbCompRout = (long) 0;
    815  1.5  scottr 			adbCompData = (long) 0;
    816  1.5  scottr 			if (adbOutQueueHasData == 1) {
    817  1.5  scottr 				/* copy over data */
    818  1.5  scottr 				for (i = 0; i <= (adbOutQueue.outBuf[0] + 1); i++)
    819  1.5  scottr 					adbOutputBuffer[i] = adbOutQueue.outBuf[i];
    820  1.5  scottr 				adbBuffer = adbOutQueue.saveBuf;	/* user data area */
    821  1.5  scottr 				adbCompRout = adbOutQueue.compRout;	/* completion routine */
    822  1.5  scottr 				adbCompData = adbOutQueue.data;	/* comp. rout. data */
    823  1.5  scottr 				adbOutQueueHasData = 0;	/* currently processing
    824  1.5  scottr 							 * "queue" entry */
    825  1.5  scottr 				adbPolling = 0;
    826  1.5  scottr 			} else {
    827  1.5  scottr 				adbOutputBuffer[0] = 1;
    828  1.5  scottr 				adbOutputBuffer[1] = (adbOutputBuffer[1] & 0xf0) | 0x0c;
    829  1.5  scottr 				adbPolling = 1;	/* non-user poll */
    830  1.5  scottr 			}
    831  1.5  scottr 			adbNextEnd = 0;
    832  1.5  scottr 			adbSentChars = 0;	/* nothing sent yet */
    833  1.5  scottr 			adbActionState = ADB_ACTION_OUT;	/* set next state */
    834  1.5  scottr 			ADB_SET_SR_OUTPUT();	/* set shift register for OUT */
    835  1.5  scottr 			ADB_SR() = adbOutputBuffer[1];	/* load byte for output */
    836  1.5  scottr 			adbBusState = ADB_BUS_CMD;	/* set bus to cmd state */
    837  1.5  scottr 			ADB_SET_STATE_CMD();	/* tell ADB that we want to
    838  1.5  scottr 						 * send */
    839  1.5  scottr 			break;
    840  1.5  scottr 		}
    841  1.5  scottr 		ADB_SR() = adbOutputBuffer[adbSentChars + 1];
    842  1.5  scottr 		switch (adbBusState) {	/* advance to next state */
    843  1.5  scottr 		case ADB_BUS_EVEN:
    844  1.5  scottr 			ADB_SET_STATE_ODD();	/* set state to odd */
    845  1.5  scottr 			adbBusState = ADB_BUS_ODD;
    846  1.5  scottr 			break;
    847  1.5  scottr 
    848  1.5  scottr 		case ADB_BUS_CMD:
    849  1.5  scottr 		case ADB_BUS_ODD:
    850  1.5  scottr 			ADB_SET_STATE_EVEN();	/* set state to even */
    851  1.5  scottr 			adbBusState = ADB_BUS_EVEN;
    852  1.5  scottr 			break;
    853  1.5  scottr 
    854  1.5  scottr 		default:
    855  1.5  scottr 			printf_intr("strange state!!! (0x%x)\n", adbBusState);
    856  1.5  scottr 			break;
    857  1.5  scottr 		}
    858  1.5  scottr 		break;
    859  1.5  scottr 
    860  1.5  scottr 	default:
    861  1.5  scottr 		printf_intr("adb: unknown ADB state (during intr)\n");
    862  1.5  scottr 	}
    863  1.5  scottr 
    864  1.5  scottr 	ADB_VIA_INTR_ENABLE();	/* enable ADB interrupt on IIs. */
    865  1.1  scottr 
    866  1.5  scottr 	splx(s);		/* restore */
    867  1.1  scottr 
    868  1.5  scottr 	return;
    869  1.1  scottr 
    870  1.1  scottr }
    871  1.1  scottr 
    872  1.1  scottr 
    873  1.5  scottr /*
    874  1.5  scottr  * send_adb version for II series machines
    875  1.1  scottr  */
    876  1.1  scottr int
    877  1.5  scottr send_adb_II(u_char * in, u_char * buffer, void *compRout, void *data, int command)
    878  1.1  scottr {
    879  1.5  scottr 	int i, s, len;
    880  1.5  scottr 
    881  1.5  scottr 	if (adbActionState == ADB_ACTION_NOTREADY)	/* return if ADB not
    882  1.5  scottr 							 * available */
    883  1.5  scottr 		return 1;
    884  1.5  scottr 
    885  1.5  scottr 	s = splhigh();		/* don't interrupt while we are messing with
    886  1.5  scottr 				 * the ADB */
    887  1.1  scottr 
    888  1.5  scottr 	if (0 != adbOutQueueHasData) {	/* right now, "has data" means "full" */
    889  1.5  scottr 		splx(s);	/* sorry, try again later */
    890  1.5  scottr 		return 1;
    891  1.5  scottr 	}
    892  1.5  scottr 	if ((long) in == (long) 0) {	/* need to convert? */
    893  1.5  scottr 		/*
    894  1.5  scottr 		 * Don't need to use adb_cmd_extra here because this section
    895  1.5  scottr 		 * will be called ONLY when it is an ADB command (no RTC or
    896  1.5  scottr 		 * PRAM), especially on II series!
    897  1.5  scottr 		 */
    898  1.5  scottr 		if ((command & 0x0c) == 0x08)	/* copy addl data ONLY if
    899  1.5  scottr 						 * doing a listen! */
    900  1.5  scottr 			len = buffer[0];	/* length of additional data */
    901  1.5  scottr 		else
    902  1.5  scottr 			len = 0;/* no additional data */
    903  1.1  scottr 
    904  1.5  scottr 		adbOutQueue.outBuf[0] = 1 + len;	/* command + addl. data */
    905  1.5  scottr 		adbOutQueue.outBuf[1] = (u_char) command;	/* load command */
    906  1.1  scottr 
    907  1.5  scottr 		for (i = 1; i <= len; i++)	/* copy additional output
    908  1.5  scottr 						 * data, if any */
    909  1.5  scottr 			adbOutQueue.outBuf[1 + i] = buffer[i];
    910  1.5  scottr 	} else
    911  1.5  scottr 		/* if data ready, just copy over */
    912  1.5  scottr 		for (i = 0; i <= (adbOutQueue.outBuf[0] + 1); i++)
    913  1.5  scottr 			adbOutQueue.outBuf[i] = in[i];
    914  1.5  scottr 
    915  1.5  scottr 	adbOutQueue.saveBuf = buffer;	/* save buffer to know where to save
    916  1.5  scottr 					 * result */
    917  1.5  scottr 	adbOutQueue.compRout = compRout;	/* save completion routine
    918  1.5  scottr 						 * pointer */
    919  1.5  scottr 	adbOutQueue.data = data;/* save completion routine data pointer */
    920  1.5  scottr 
    921  1.5  scottr 	if ((adbActionState == ADB_ACTION_IDLE) &&	/* is ADB available? */
    922  1.5  scottr 	    (ADB_INTR_IS_OFF) &&/* and no incoming interrupts? */
    923  1.5  scottr 	    (adbPolling == 0)) {/* and we are not currently polling */
    924  1.5  scottr 		/* then start command now */
    925  1.5  scottr 		for (i = 0; i <= (adbOutQueue.outBuf[0] + 1); i++)	/* copy over data */
    926  1.5  scottr 			adbOutputBuffer[i] = adbOutQueue.outBuf[i];
    927  1.5  scottr 
    928  1.5  scottr 		adbBuffer = adbOutQueue.saveBuf;	/* pointer to user data
    929  1.5  scottr 							 * area */
    930  1.5  scottr 		adbCompRout = adbOutQueue.compRout;	/* pointer to the
    931  1.5  scottr 							 * completion routine */
    932  1.5  scottr 		adbCompData = adbOutQueue.data;	/* pointer to the completion
    933  1.5  scottr 						 * routine data */
    934  1.5  scottr 
    935  1.5  scottr 		adbSentChars = 0;	/* nothing sent yet */
    936  1.5  scottr 		adbActionState = ADB_ACTION_OUT;	/* set next state */
    937  1.5  scottr 		adbBusState = ADB_BUS_CMD;	/* set bus to cmd state */
    938  1.5  scottr 
    939  1.5  scottr 		ADB_SET_SR_OUTPUT();	/* set shift register for OUT */
    940  1.5  scottr 
    941  1.5  scottr 		ADB_SR() = adbOutputBuffer[adbSentChars + 1];	/* load byte for output */
    942  1.5  scottr 		ADB_SET_STATE_CMD();	/* tell ADB that we want to send */
    943  1.5  scottr 		adbOutQueueHasData = 0;	/* currently processing "queue" entry */
    944  1.5  scottr 	} else
    945  1.5  scottr 		adbOutQueueHasData = 1;	/* something in the write "queue" */
    946  1.5  scottr 
    947  1.5  scottr 	splx(s);
    948  1.5  scottr 
    949  1.5  scottr 	if (0x0100 <= (s & 0x0700))	/* were VIA1 interrupts blocked ? */
    950  1.5  scottr 		/* poll until message done */
    951  1.5  scottr 		while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
    952  1.5  scottr 		    || (adbWaiting == 1) || (adbPolling == 1))
    953  1.5  scottr 			if (ADB_SR_INTR_IS_ON)	/* wait for "interrupt" */
    954  1.5  scottr 				adb_intr_II();	/* go process "interrupt" */
    955  1.1  scottr 
    956  1.5  scottr 	return 0;
    957  1.1  scottr }
    958  1.1  scottr 
    959  1.1  scottr 
    960  1.1  scottr /*
    961  1.1  scottr  * This routine is called from the II series interrupt routine
    962  1.1  scottr  * to determine what the "next" device is that should be polled.
    963  1.1  scottr  */
    964  1.1  scottr int
    965  1.1  scottr adb_guess_next_device(void)
    966  1.1  scottr {
    967  1.5  scottr 	int last, i, dummy;
    968  1.1  scottr 
    969  1.1  scottr 	if (adbStarting) {
    970  1.5  scottr 		/* start polling EVERY device, since we can't be sure there is
    971  1.5  scottr 		 * anything in the device table yet */
    972  1.5  scottr 		if (adbLastDevice < 1 || adbLastDevice > 15)
    973  1.1  scottr 			adbLastDevice = 1;
    974  1.5  scottr 		if (++adbLastDevice > 15)	/* point to next one */
    975  1.1  scottr 			adbLastDevice = 1;
    976  1.1  scottr 	} else {
    977  1.1  scottr 		/* find the next device using the device table */
    978  1.5  scottr 		if (adbLastDevice < 1 || adbLastDevice > 15)	/* let's be parinoid */
    979  1.1  scottr 			adbLastDevice = 2;
    980  1.5  scottr 		last = 1;	/* default index location */
    981  1.5  scottr 
    982  1.1  scottr 		for (i = 1; i < 16; i++)	/* find index entry */
    983  1.5  scottr 			if (ADBDevTable[i].currentAddr == adbLastDevice) {	/* look for device */
    984  1.5  scottr 				last = i;	/* found it */
    985  1.1  scottr 				break;
    986  1.1  scottr 			}
    987  1.5  scottr 		dummy = last;	/* index to start at */
    988  1.5  scottr 		for (;;) {	/* find next device in index */
    989  1.5  scottr 			if (++dummy > 15)	/* wrap around if needed */
    990  1.1  scottr 				dummy = 1;
    991  1.5  scottr 			if (dummy == last) {	/* didn't find any other
    992  1.5  scottr 						 * device! This can happen if
    993  1.5  scottr 						 * there are no devices on the
    994  1.5  scottr 						 * bus */
    995  1.5  scottr 				dummy = 2;
    996  1.1  scottr 				break;
    997  1.1  scottr 			}
    998  1.1  scottr 			/* found the next device */
    999  1.5  scottr 			if (ADBDevTable[dummy].devType != 0)
   1000  1.1  scottr 				break;
   1001  1.1  scottr 		}
   1002  1.5  scottr 		adbLastDevice = ADBDevTable[dummy].currentAddr;
   1003  1.1  scottr 	}
   1004  1.1  scottr 	return adbLastDevice;
   1005  1.1  scottr }
   1006  1.5  scottr /*
   1007  1.1  scottr  * Called when when an adb interrupt happens.
   1008  1.1  scottr  * This routine simply transfers control over to the appropriate
   1009  1.1  scottr  * code for the machine we are running on.
   1010  1.1  scottr  */
   1011  1.5  scottr void
   1012  1.1  scottr adb_intr(void)
   1013  1.1  scottr {
   1014  1.5  scottr 	switch (adbHardware) {
   1015  1.5  scottr 		case ADB_HW_II:
   1016  1.5  scottr 		adb_intr_II();
   1017  1.5  scottr 		break;
   1018  1.1  scottr 
   1019  1.5  scottr 	case ADB_HW_IISI:
   1020  1.5  scottr 		adb_intr_IIsi();
   1021  1.5  scottr 		break;
   1022  1.5  scottr 
   1023  1.5  scottr 	case ADB_HW_PB:
   1024  1.5  scottr 		break;
   1025  1.1  scottr 
   1026  1.1  scottr 	case ADB_HW_CUDA:
   1027  1.1  scottr 		adb_intr_cuda();
   1028  1.1  scottr 		break;
   1029  1.5  scottr 
   1030  1.5  scottr 	case ADB_HW_UNKNOWN:
   1031  1.5  scottr 		break;
   1032  1.5  scottr 	}
   1033  1.1  scottr }
   1034  1.1  scottr 
   1035  1.1  scottr 
   1036  1.5  scottr /*
   1037  1.5  scottr  * called when when an adb interrupt happens
   1038  1.1  scottr  *
   1039  1.1  scottr  * IIsi version of adb_intr
   1040  1.1  scottr  *
   1041  1.1  scottr  */
   1042  1.5  scottr void
   1043  1.1  scottr adb_intr_IIsi(void)
   1044  1.1  scottr {
   1045  1.5  scottr 	int i, ending, len;
   1046  1.5  scottr 	unsigned int s;
   1047  1.1  scottr 
   1048  1.5  scottr 	s = splhigh();		/* can't be too careful - might be called */
   1049  1.5  scottr 	/* from a routine, NOT an interrupt */
   1050  1.1  scottr 
   1051  1.5  scottr 	ADB_VIA_CLR_INTR();	/* clear interrupt */
   1052  1.1  scottr 
   1053  1.5  scottr 	ADB_VIA_INTR_DISABLE();	/* disable ADB interrupt on IIs. */
   1054  1.1  scottr 
   1055  1.1  scottr switch_start:
   1056  1.5  scottr 	switch (adbActionState) {
   1057  1.5  scottr 	case ADB_ACTION_IDLE:
   1058  1.5  scottr 		delay(ADB_DELAY);	/* short delay is required before the
   1059  1.5  scottr 					 * first byte */
   1060  1.5  scottr 
   1061  1.5  scottr 		ADB_SET_SR_INPUT();	/* make sure SR is set to IN */
   1062  1.5  scottr 		ADB_SET_STATE_ACTIVE();	/* signal start of data frame */
   1063  1.5  scottr 		adbInputBuffer[1] = ADB_SR();	/* get byte */
   1064  1.5  scottr 		adbInputBuffer[0] = 1;
   1065  1.5  scottr 		adbActionState = ADB_ACTION_IN;	/* set next state */
   1066  1.5  scottr 
   1067  1.5  scottr 		ADB_SET_STATE_ACKON();	/* start ACK to ADB chip */
   1068  1.5  scottr 		delay(ADB_DELAY);	/* delay */
   1069  1.5  scottr 		ADB_SET_STATE_ACKOFF();	/* end ACK to ADB chip */
   1070  1.5  scottr 		zshard(0);	/* grab any serial interrupts */
   1071  1.5  scottr 		break;
   1072  1.5  scottr 
   1073  1.5  scottr 	case ADB_ACTION_IN:
   1074  1.5  scottr 		ADB_SET_SR_INPUT();	/* make sure SR is set to IN */
   1075  1.5  scottr 		adbInputBuffer[++adbInputBuffer[0]] = ADB_SR();	/* get byte */
   1076  1.5  scottr 		if (ADB_INTR_IS_OFF)	/* check for end of frame */
   1077  1.5  scottr 			ending = 1;
   1078  1.5  scottr 		else
   1079  1.5  scottr 			ending = 0;
   1080  1.5  scottr 
   1081  1.5  scottr 		ADB_SET_STATE_ACKON();	/* start ACK to ADB chip */
   1082  1.5  scottr 		delay(ADB_DELAY);	/* delay */
   1083  1.5  scottr 		ADB_SET_STATE_ACKOFF();	/* end ACK to ADB chip */
   1084  1.5  scottr 		zshard(0);	/* grab any serial interrupts */
   1085  1.5  scottr 
   1086  1.5  scottr 		if (1 == ending) {	/* end of message? */
   1087  1.5  scottr 			ADB_SET_STATE_INACTIVE();	/* signal end of frame */
   1088  1.5  scottr 			/* this section _should_ handle all ADB and RTC/PRAM
   1089  1.5  scottr 			 * type commands, */
   1090  1.5  scottr 			/* but there may be more... */
   1091  1.5  scottr 			/* note: commands are always at [4], even for rtc/pram
   1092  1.5  scottr 			 * commands */
   1093  1.5  scottr 			if ((adbWaiting == 1) &&	/* are we waiting AND */
   1094  1.5  scottr 			    (adbInputBuffer[4] == adbWaitingCmd) &&	/* the cmd we sent AND */
   1095  1.5  scottr 			    ((adbInputBuffer[2] == 0x00) ||	/* it's from the ADB
   1096  1.5  scottr 								 * device OR */
   1097  1.5  scottr 				(adbInputBuffer[2] == 0x01))) {	/* it's from the
   1098  1.5  scottr 								 * PRAM/RTC device */
   1099  1.5  scottr 
   1100  1.5  scottr 				/* is this data we are waiting for? */
   1101  1.5  scottr 				if (adbBuffer != (long) 0) {	/* if valid return data
   1102  1.5  scottr 								 * pointer */
   1103  1.1  scottr 					/* get return length minus extras */
   1104  1.5  scottr 					len = adbInputBuffer[0] - 4;
   1105  1.5  scottr 					/* if adb_op is ever made to be called
   1106  1.5  scottr 					 * from a user routine, we should use
   1107  1.5  scottr 					 * a copyout or copyin here to be sure
   1108  1.5  scottr 					 * we're in the correct context */
   1109  1.5  scottr 					for (i = 1; i <= len; i++)
   1110  1.5  scottr 						adbBuffer[i] = adbInputBuffer[4 + i];
   1111  1.5  scottr 					if (len < 0)
   1112  1.5  scottr 						len = 0;
   1113  1.5  scottr 					adbBuffer[0] = len;
   1114  1.5  scottr 				}
   1115  1.5  scottr 				adb_comp_exec();	/* call completion
   1116  1.5  scottr 							 * routine */
   1117  1.5  scottr 
   1118  1.5  scottr 				adbWaitingCmd = 0;	/* reset "waiting" vars */
   1119  1.5  scottr 				adbWaiting = 0;
   1120  1.5  scottr 				adbBuffer = (long) 0;
   1121  1.5  scottr 				adbCompRout = (long) 0;
   1122  1.5  scottr 				adbCompData = (long) 0;
   1123  1.5  scottr 			} else {
   1124  1.5  scottr 				/* pass the data off to the handler */
   1125  1.5  scottr 				/* This section IGNORES all data that is not
   1126  1.5  scottr 				 * from the ADB sub-device. That is, not from
   1127  1.5  scottr 				 * rtc or pram. Maybe we should fix later,
   1128  1.5  scottr 				 * but do the other devices every send things
   1129  1.5  scottr 				 * without being asked? */
   1130  1.5  scottr 				if (adbStarting == 0)	/* ignore if during
   1131  1.5  scottr 							 * adbreinit */
   1132  1.5  scottr 					if (adbInputBuffer[2] == 0x00)
   1133  1.5  scottr 						adb_handle_unsol(adbInputBuffer);
   1134  1.5  scottr 			}
   1135  1.5  scottr 
   1136  1.5  scottr 			adbActionState = ADB_ACTION_IDLE;
   1137  1.5  scottr 			adbInputBuffer[0] = 0;	/* reset length */
   1138  1.5  scottr 
   1139  1.5  scottr 			if (adbWriteDelay == 1) {	/* were we waiting to
   1140  1.5  scottr 							 * write? */
   1141  1.5  scottr 				adbSentChars = 0;	/* nothing sent yet */
   1142  1.5  scottr 				adbActionState = ADB_ACTION_OUT;	/* set next state */
   1143  1.5  scottr 
   1144  1.5  scottr 				delay(ADB_DELAY);	/* delay */
   1145  1.5  scottr 				zshard(0);	/* grab any serial interrupts */
   1146  1.5  scottr 
   1147  1.5  scottr 				if (ADB_INTR_IS_ON) {	/* ADB intr low during
   1148  1.5  scottr 							 * write */
   1149  1.5  scottr 					ADB_SET_STATE_IDLE_IISI();	/* reset */
   1150  1.5  scottr 					ADB_SET_SR_INPUT();	/* make sure SR is set
   1151  1.5  scottr 								 * to IN */
   1152  1.5  scottr 					adbSentChars = 0;	/* must start all over */
   1153  1.5  scottr 					adbActionState = ADB_ACTION_IDLE;	/* new state */
   1154  1.5  scottr 					adbInputBuffer[0] = 0;
   1155  1.5  scottr 					/* may be able to take this out later */
   1156  1.5  scottr 					delay(ADB_DELAY);	/* delay */
   1157  1.5  scottr 					break;
   1158  1.5  scottr 				}
   1159  1.5  scottr 				ADB_SET_STATE_ACTIVE();	/* tell ADB that we want
   1160  1.5  scottr 							 * to send */
   1161  1.5  scottr 				ADB_SET_STATE_ACKOFF();	/* make sure */
   1162  1.5  scottr 				ADB_SET_SR_OUTPUT();	/* set shift register
   1163  1.5  scottr 							 * for OUT */
   1164  1.5  scottr 				ADB_SR() = adbOutputBuffer[adbSentChars + 1];
   1165  1.5  scottr 				ADB_SET_STATE_ACKON();	/* tell ADB byte ready
   1166  1.5  scottr 							 * to shift */
   1167  1.5  scottr 			}
   1168  1.5  scottr 		}
   1169  1.5  scottr 		break;
   1170  1.5  scottr 
   1171  1.5  scottr 	case ADB_ACTION_OUT:
   1172  1.5  scottr 		i = ADB_SR();	/* reset SR-intr in IFR */
   1173  1.5  scottr 		ADB_SET_SR_OUTPUT();	/* set shift register for OUT */
   1174  1.5  scottr 
   1175  1.5  scottr 		ADB_SET_STATE_ACKOFF();	/* finish ACK */
   1176  1.5  scottr 		adbSentChars++;
   1177  1.5  scottr 		if (ADB_INTR_IS_ON) {	/* ADB intr low during write */
   1178  1.5  scottr 			ADB_SET_STATE_IDLE_IISI();	/* reset */
   1179  1.5  scottr 			ADB_SET_SR_INPUT();	/* make sure SR is set to IN */
   1180  1.5  scottr 			adbSentChars = 0;	/* must start all over */
   1181  1.5  scottr 			adbActionState = ADB_ACTION_IDLE;	/* new state */
   1182  1.5  scottr 			adbInputBuffer[0] = 0;
   1183  1.5  scottr 			adbWriteDelay = 1;	/* must retry when done with
   1184  1.5  scottr 						 * read */
   1185  1.5  scottr 			delay(ADB_DELAY);	/* delay */
   1186  1.5  scottr 			zshard(0);		/* grab any serial interrupts */
   1187  1.5  scottr 			goto switch_start;	/* process next state right
   1188  1.5  scottr 						 * now */
   1189  1.5  scottr 			break;
   1190  1.5  scottr 		}
   1191  1.5  scottr 		delay(ADB_DELAY);	/* required delay */
   1192  1.5  scottr 		zshard(0);	/* grab any serial interrupts */
   1193  1.5  scottr 
   1194  1.5  scottr 		if (adbOutputBuffer[0] == adbSentChars) {	/* check for done */
   1195  1.5  scottr 			if (0 == adb_cmd_result(adbOutputBuffer)) {	/* do we expect data
   1196  1.5  scottr 									 * back? */
   1197  1.5  scottr 				adbWaiting = 1;	/* signal waiting for return */
   1198  1.5  scottr 				adbWaitingCmd = adbOutputBuffer[2];	/* save waiting command */
   1199  1.5  scottr 			} else {/* no talk, so done */
   1200  1.5  scottr 				adb_comp_exec();	/* call completion
   1201  1.5  scottr 							 * routine */
   1202  1.5  scottr 				adbWaitingCmd = 0;	/* reset "waiting" vars,
   1203  1.5  scottr 							 * just in case */
   1204  1.5  scottr 				adbBuffer = (long) 0;
   1205  1.5  scottr 				adbCompRout = (long) 0;
   1206  1.5  scottr 				adbCompData = (long) 0;
   1207  1.5  scottr 			}
   1208  1.5  scottr 
   1209  1.5  scottr 			adbWriteDelay = 0;	/* done writing */
   1210  1.5  scottr 			adbActionState = ADB_ACTION_IDLE;	/* signal bus is idle */
   1211  1.5  scottr 			ADB_SET_SR_INPUT();	/* make sure SR is set to IN */
   1212  1.5  scottr 			ADB_SET_STATE_INACTIVE();	/* end of frame */
   1213  1.5  scottr 		} else {
   1214  1.5  scottr 			ADB_SR() = adbOutputBuffer[adbSentChars + 1];	/* send next byte */
   1215  1.5  scottr 			ADB_SET_STATE_ACKON();	/* signal byte ready to shift */
   1216  1.5  scottr 		}
   1217  1.5  scottr 		break;
   1218  1.1  scottr 
   1219  1.5  scottr 	case ADB_ACTION_NOTREADY:
   1220  1.5  scottr 		printf_intr("adb: not yet initialized\n");
   1221  1.5  scottr 		break;
   1222  1.5  scottr 
   1223  1.5  scottr 	default:
   1224  1.5  scottr 		printf_intr("intr: unknown ADB state\n");
   1225  1.5  scottr 	}
   1226  1.5  scottr 
   1227  1.5  scottr 	ADB_VIA_INTR_ENABLE();	/* enable ADB interrupt on IIs. */
   1228  1.1  scottr 
   1229  1.5  scottr 	splx(s);		/* restore */
   1230  1.1  scottr 
   1231  1.5  scottr 	return;
   1232  1.5  scottr }				/* end adb_intr_IIsi */
   1233  1.1  scottr 
   1234  1.1  scottr 
   1235  1.1  scottr /*****************************************************************************
   1236  1.1  scottr  * if the device is currently busy, and there is no data waiting to go out, then
   1237  1.1  scottr  * the data is "queued" in the outgoing buffer. If we are already waiting, then
   1238  1.1  scottr  * we return.
   1239  1.1  scottr  * in: if (in==0) then the command string is built from command and buffer
   1240  1.1  scottr  *     if (in!=0) then in is used as the command string
   1241  1.1  scottr  * buffer: additional data to be sent (used only if in==0)
   1242  1.1  scottr  *         this is also where return data is stored
   1243  1.5  scottr  * compRout: the completion routine that is called when then return value
   1244  1.1  scottr  *	     is received (if a return value is expected)
   1245  1.1  scottr  * data: a data pointer that can be used by the completion routine
   1246  1.1  scottr  * command: an ADB command to be sent (used only if in==0)
   1247  1.5  scottr  *
   1248  1.1  scottr  */
   1249  1.5  scottr int
   1250  1.5  scottr send_adb_IIsi(u_char * in, u_char * buffer, void *compRout, void *data, int
   1251  1.5  scottr 	command)
   1252  1.1  scottr {
   1253  1.5  scottr 	int i, s, len;
   1254  1.1  scottr 
   1255  1.5  scottr 	if (adbActionState == ADB_ACTION_NOTREADY)
   1256  1.5  scottr 		return 1;
   1257  1.1  scottr 
   1258  1.5  scottr 	s = splhigh();		/* don't interrupt while we are messing with
   1259  1.5  scottr 				 * the ADB */
   1260  1.5  scottr 
   1261  1.5  scottr 	if ((adbActionState == ADB_ACTION_IDLE) &&	/* ADB available? */
   1262  1.5  scottr 	    (ADB_INTR_IS_OFF)) {/* and no incoming interrupt? */
   1263  1.5  scottr 
   1264  1.5  scottr 	} else
   1265  1.5  scottr 		if (adbWriteDelay == 0)	/* it's busy, but is anything waiting? */
   1266  1.5  scottr 			adbWriteDelay = 1;	/* if no, then we'll "queue"
   1267  1.5  scottr 						 * it up */
   1268  1.5  scottr 		else {
   1269  1.5  scottr 			splx(s);
   1270  1.5  scottr 			return 1;	/* really busy! */
   1271  1.5  scottr 		}
   1272  1.1  scottr 
   1273  1.5  scottr 	if ((long) in == (long) 0) {	/* need to convert? */
   1274  1.5  scottr 		/* don't need to use adb_cmd_extra here because this section
   1275  1.5  scottr 		 * will be called */
   1276  1.5  scottr 		/* ONLY when it is an ADB command (no RTC or PRAM) */
   1277  1.5  scottr 		if ((command & 0x0c) == 0x08)	/* copy addl data ONLY if
   1278  1.5  scottr 						 * doing a listen! */
   1279  1.5  scottr 			len = buffer[0];	/* length of additional data */
   1280  1.5  scottr 		else
   1281  1.5  scottr 			len = 0;/* no additional data */
   1282  1.1  scottr 
   1283  1.5  scottr 		adbOutputBuffer[0] = 2 + len;	/* dev. type + command + addl.
   1284  1.5  scottr 						 * data */
   1285  1.5  scottr 		adbOutputBuffer[1] = 0x00;	/* mark as an ADB command */
   1286  1.5  scottr 		adbOutputBuffer[2] = (u_char) command;	/* load command */
   1287  1.1  scottr 
   1288  1.5  scottr 		for (i = 1; i <= len; i++)	/* copy additional output
   1289  1.5  scottr 						 * data, if any */
   1290  1.5  scottr 			adbOutputBuffer[2 + i] = buffer[i];
   1291  1.5  scottr 	} else
   1292  1.5  scottr 		for (i = 0; i <= (adbOutputBuffer[0] + 1); i++)
   1293  1.5  scottr 			adbOutputBuffer[i] = in[i];
   1294  1.1  scottr 
   1295  1.5  scottr 	adbSentChars = 0;	/* nothing sent yet */
   1296  1.5  scottr 	adbBuffer = buffer;	/* save buffer to know where to save result */
   1297  1.5  scottr 	adbCompRout = compRout;	/* save completion routine pointer */
   1298  1.5  scottr 	adbCompData = data;	/* save completion routine data pointer */
   1299  1.5  scottr 	adbWaitingCmd = adbOutputBuffer[2];	/* save wait command */
   1300  1.1  scottr 
   1301  1.5  scottr 	if (adbWriteDelay != 1) {	/* start command now? */
   1302  1.5  scottr 		adbActionState = ADB_ACTION_OUT;	/* set next state */
   1303  1.1  scottr 
   1304  1.5  scottr 		ADB_SET_STATE_ACTIVE();	/* tell ADB that we want to send */
   1305  1.5  scottr 		ADB_SET_STATE_ACKOFF();	/* make sure */
   1306  1.1  scottr 
   1307  1.5  scottr 		ADB_SET_SR_OUTPUT();	/* set shift register for OUT */
   1308  1.1  scottr 
   1309  1.5  scottr 		ADB_SR() = adbOutputBuffer[adbSentChars + 1];	/* load byte for output */
   1310  1.1  scottr 
   1311  1.5  scottr 		ADB_SET_STATE_ACKON();	/* tell ADB byte ready to shift */
   1312  1.5  scottr 	}
   1313  1.5  scottr 	adbWriteDelay = 1;	/* something in the write "queue" */
   1314  1.1  scottr 
   1315  1.5  scottr 	splx(s);
   1316  1.1  scottr 
   1317  1.5  scottr 	if (0x0100 <= (s & 0x0700))	/* were VIA1 interrupts blocked ? */
   1318  1.5  scottr 		/* poll until byte done */
   1319  1.5  scottr 		while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
   1320  1.5  scottr 		    || (adbWaiting == 1))
   1321  1.5  scottr 			if (ADB_SR_INTR_IS_ON)	/* wait for "interrupt" */
   1322  1.5  scottr 				adb_intr_IIsi();	/* go process
   1323  1.5  scottr 							 * "interrupt" */
   1324  1.1  scottr 
   1325  1.5  scottr 	return 0;
   1326  1.5  scottr }				/* send_adb_IIsi */
   1327  1.1  scottr 
   1328  1.1  scottr 
   1329  1.5  scottr /*
   1330  1.1  scottr  * adb_comp_exec
   1331  1.1  scottr  * This is a general routine that calls the completion routine if there is one.
   1332  1.1  scottr  */
   1333  1.5  scottr void
   1334  1.5  scottr adb_comp_exec(void)
   1335  1.1  scottr {
   1336  1.5  scottr 	if ((long) 0 != adbCompRout)	/* don't call if empty return location */
   1337  1.5  scottr #ifdef __NetBSD__
   1338  1.5  scottr 		asm("
   1339  1.5  scottr 		    movml #0xffff, sp@-		| save all registers
   1340  1.5  scottr 		    movl %0, a2 		| adbCompData
   1341  1.5  scottr 		    movl %1, a1 		| adbCompRout
   1342  1.5  scottr 		    movl %2, a0 		| adbBuffer
   1343  1.5  scottr 		    movl %3, d0 		| adbWaitingCmd
   1344  1.5  scottr 		    jbsr a1@ 			| go call the routine
   1345  1.5  scottr 		    movml sp@+, #0xffff		| restore all registers"
   1346  1.5  scottr 		    :
   1347  1.5  scottr 		    :"g"(adbCompData), "g"(adbCompRout),
   1348  1.5  scottr 		     "g"(adbBuffer), "g"(adbWaitingCmd)
   1349  1.5  scottr 		    :"d0", "a0", "a1", "a2");
   1350  1.5  scottr #else					/* for macos based testing */
   1351  1.5  scottr 		asm {
   1352  1.5  scottr 			movem.l a0/a1/a2/d0, -(a7)
   1353  1.5  scottr 			move.l adbCompData, a2
   1354  1.5  scottr 			move.l adbCompRout, a1
   1355  1.5  scottr 			move.l adbBuffer, a0
   1356  1.5  scottr 			move.w adbWaitingCmd, d0
   1357  1.5  scottr 			jsr(a1)
   1358  1.5  scottr 			movem.l(a7) +, d0/a2/a1/a0
   1359  1.5  scottr 		}
   1360  1.5  scottr #endif
   1361  1.1  scottr }
   1362  1.5  scottr 
   1363  1.1  scottr 
   1364  1.1  scottr /*
   1365  1.5  scottr  * This routine handles what needs to be done after an unsolicited
   1366  1.5  scottr  * message is read from the ADB device.  'in' points to the raw
   1367  1.5  scottr  * data received from the device, including device number
   1368  1.5  scottr  * (on IIsi) and result code.
   1369  1.5  scottr  *
   1370  1.5  scottr  * Note that the service (completion) routine for an unsolicited
   1371  1.5  scottr  * message is whatever is set in the ADB device table. This is
   1372  1.5  scottr  * different than for a device responding to a specific request,
   1373  1.5  scottr  * where the completion routine is defined by the caller.
   1374  1.1  scottr  */
   1375  1.5  scottr void
   1376  1.5  scottr adb_handle_unsol(u_char * in)
   1377  1.1  scottr {
   1378  1.5  scottr 	int i, cmd = 0;
   1379  1.5  scottr 	u_char data[MAX_ADB_MSG_LENGTH];
   1380  1.5  scottr 	u_char *buffer = 0;
   1381  1.5  scottr 	ADBDataBlock block;
   1382  1.5  scottr 
   1383  1.5  scottr 	/* make local copy so we don't destroy the real one - it may be needed
   1384  1.5  scottr 	 * later. */
   1385  1.5  scottr 	for (i = 0; i <= (in[0] + 1); i++)
   1386  1.5  scottr 		data[i] = in[i];
   1387  1.5  scottr 
   1388  1.5  scottr 	switch (adbHardware) {
   1389  1.5  scottr 	case ADB_HW_II:
   1390  1.5  scottr 		/* adjust the "length" byte */
   1391  1.5  scottr 		cmd = data[1];
   1392  1.5  scottr 		if (data[0] < 2)
   1393  1.5  scottr 			data[1] = 0;
   1394  1.5  scottr 		else
   1395  1.5  scottr 			data[1] = data[0] - 1;
   1396  1.5  scottr 
   1397  1.5  scottr 		buffer = (data + 1);
   1398  1.5  scottr 		break;
   1399  1.5  scottr 
   1400  1.5  scottr 	case ADB_HW_IISI:
   1401  1.5  scottr 	case ADB_HW_CUDA:
   1402  1.5  scottr 		/* only handles ADB for now */
   1403  1.5  scottr 		if (0 != *(data + 2))
   1404  1.5  scottr 			return;
   1405  1.5  scottr 
   1406  1.5  scottr 		/* adjust the "length" byte */
   1407  1.5  scottr 		cmd = data[4];
   1408  1.5  scottr 		if (data[0] < 5)
   1409  1.5  scottr 			data[4] = 0;
   1410  1.5  scottr 		else
   1411  1.5  scottr 			data[4] = data[0] - 4;
   1412  1.5  scottr 
   1413  1.5  scottr 		buffer = (data + 4);
   1414  1.5  scottr 		break;
   1415  1.1  scottr 
   1416  1.5  scottr 	case ADB_HW_PB:
   1417  1.1  scottr 		return;		/* how does PM handle "unsolicited" messages? */
   1418  1.4  scottr 
   1419  1.5  scottr 	case ADB_HW_UNKNOWN:
   1420  1.5  scottr 		return;
   1421  1.5  scottr 	}
   1422  1.5  scottr 
   1423  1.5  scottr 	if (-1 == get_adb_info(&block, ((cmd & 0xf0) >> 4)))
   1424  1.5  scottr 		return;
   1425  1.5  scottr 
   1426  1.5  scottr 	/* call default completion routine if it's valid */
   1427  1.5  scottr 	/* TO DO: This section of code is somewhat redundant with
   1428  1.5  scottr 	 * adb_comp_exec (above). Some day we may want to generalize it and
   1429  1.5  scottr 	 * make it a single function. */
   1430  1.5  scottr 	if ((long) 0 != (long) block.dbServiceRtPtr) {
   1431  1.5  scottr #ifdef __NetBSD__
   1432  1.5  scottr 		asm("
   1433  1.5  scottr 		    movml #0xffff, sp@-		| save all registers
   1434  1.5  scottr 		    movl %0, a2 		| block.dbDataAreaAddr
   1435  1.5  scottr 		    movl %1, a1 		| block.dbServiceRtPtr
   1436  1.5  scottr 		    movl %2, a0 		| buffer
   1437  1.5  scottr 		    movl %3, d0 		| cmd
   1438  1.5  scottr 		    jbsr a1@ 			| go call the routine
   1439  1.5  scottr 		    movml sp@+, #0xffff		| restore all registers"
   1440  1.5  scottr 		    :
   1441  1.5  scottr 		    : "g"(block.dbDataAreaAddr),
   1442  1.5  scottr 		      "g"(block.dbServiceRtPtr), "g"(buffer), "g"(cmd)
   1443  1.5  scottr 		    : "d0", "a0", "a1", "a2");
   1444  1.5  scottr #else					/* for macos based testing */
   1445  1.5  scottr 		asm
   1446  1.5  scottr 		{
   1447  1.5  scottr 			movem.l a0/a1/a2/d0, -(a7)
   1448  1.5  scottr 			move.l block.dbDataAreaAddr, a2
   1449  1.5  scottr 			move.l block.dbServiceRtPtr, a1
   1450  1.5  scottr 			move.l buffer, a0
   1451  1.5  scottr 			move.w cmd, d0
   1452  1.5  scottr 			jsr(a1)
   1453  1.5  scottr 			movem.l(a7) +, d0/a2/a1/a0
   1454  1.5  scottr 		}
   1455  1.1  scottr #endif
   1456  1.5  scottr 	}
   1457  1.5  scottr 	return;
   1458  1.1  scottr }
   1459  1.1  scottr 
   1460  1.1  scottr 
   1461  1.1  scottr /*
   1462  1.1  scottr  * This is my version of the ADBOp routine. It mainly just calls the hardware-specific
   1463  1.1  scottr  * routine.
   1464  1.1  scottr  *
   1465  1.5  scottr  *   data 	: pointer to data area to be used by compRout
   1466  1.1  scottr  *   compRout	: completion routine
   1467  1.5  scottr  *   buffer	: for LISTEN: points to data to send - MAX 8 data bytes,
   1468  1.5  scottr  *		  byte 0 = # of bytes
   1469  1.5  scottr  *		: for TALK: points to place to save return data
   1470  1.1  scottr  *   command	: the adb command to send
   1471  1.1  scottr  *   result     : 0 = success
   1472  1.1  scottr  *              : -1 = could not complete
   1473  1.1  scottr  */
   1474  1.5  scottr int
   1475  1.1  scottr adb_op(Ptr buffer, Ptr compRout, Ptr data, short command)
   1476  1.1  scottr {
   1477  1.5  scottr 	int result;
   1478  1.5  scottr 
   1479  1.5  scottr 	switch (adbHardware) {
   1480  1.5  scottr 	case ADB_HW_II:
   1481  1.5  scottr 		result = send_adb_II((u_char *) 0,
   1482  1.5  scottr 		    (u_char *) buffer, (void *) compRout,
   1483  1.5  scottr 		    (void *) data, (int) command);
   1484  1.5  scottr 		if (result == 0)
   1485  1.5  scottr 			return 0;
   1486  1.5  scottr 		else
   1487  1.5  scottr 			return -1;
   1488  1.5  scottr 		break;
   1489  1.1  scottr 
   1490  1.5  scottr 	case ADB_HW_IISI:
   1491  1.5  scottr 		result = send_adb_IIsi((u_char *) 0,
   1492  1.5  scottr 		    (u_char *) buffer, (void *) compRout,
   1493  1.5  scottr 		    (void *) data, (int) command);
   1494  1.1  scottr 		/*
   1495  1.1  scottr 		 * I wish I knew why this delay is needed. It usually needs to
   1496  1.5  scottr 		 * be here when several commands are sent in close succession,
   1497  1.1  scottr 		 * especially early in device probes when doing collision
   1498  1.1  scottr 		 * detection. It must be some race condition. Sigh. - jpw
   1499  1.1  scottr 		 */
   1500  1.1  scottr 		delay(100);
   1501  1.5  scottr 		if (result == 0)
   1502  1.5  scottr 			return 0;
   1503  1.5  scottr 		else
   1504  1.5  scottr 			return -1;
   1505  1.1  scottr 		break;
   1506  1.1  scottr 
   1507  1.5  scottr 	case ADB_HW_PB:
   1508  1.4  scottr 		result = pm_adb_op((u_char *)buffer, (void *)compRout,
   1509  1.4  scottr 		    (void *)data, (int)command);
   1510  1.5  scottr 
   1511  1.4  scottr 		if (result == 0)
   1512  1.4  scottr 			return 0;
   1513  1.4  scottr 		else
   1514  1.4  scottr 			return -1;
   1515  1.5  scottr 		break;
   1516  1.1  scottr 
   1517  1.5  scottr 	case ADB_HW_CUDA:
   1518  1.5  scottr 		result = send_adb_cuda((u_char *) 0,
   1519  1.5  scottr 		    (u_char *) buffer, (void *) compRout,
   1520  1.5  scottr 		    (void *) data, (int) command);
   1521  1.5  scottr 		if (result == 0)
   1522  1.5  scottr 			return 0;
   1523  1.5  scottr 		else
   1524  1.5  scottr 			return -1;
   1525  1.1  scottr 		break;
   1526  1.1  scottr 
   1527  1.5  scottr 	case ADB_HW_UNKNOWN:
   1528  1.1  scottr 	default:
   1529  1.5  scottr 		return -1;
   1530  1.5  scottr 	}
   1531  1.1  scottr }
   1532  1.1  scottr 
   1533  1.1  scottr 
   1534  1.1  scottr /*
   1535  1.1  scottr  * adb_cleanup
   1536  1.1  scottr  * This routine simply calls the appropriate version of the adb_cleanup routine.
   1537  1.1  scottr  */
   1538  1.5  scottr void
   1539  1.5  scottr adb_cleanup(u_char * in)
   1540  1.1  scottr {
   1541  1.5  scottr 	volatile int i;
   1542  1.5  scottr 
   1543  1.5  scottr 	switch (adbHardware) {
   1544  1.5  scottr 	case ADB_HW_II:
   1545  1.5  scottr 		ADB_VIA_CLR_INTR();	/* clear interrupt */
   1546  1.5  scottr 		break;
   1547  1.5  scottr 
   1548  1.5  scottr 	case ADB_HW_IISI:
   1549  1.5  scottr 		/* get those pesky clock ticks we missed while booting */
   1550  1.5  scottr 		adb_cleanup_IIsi(in);
   1551  1.5  scottr 		break;
   1552  1.5  scottr 
   1553  1.5  scottr 	case ADB_HW_PB:
   1554  1.5  scottr 		/*
   1555  1.5  scottr 		 * XXX -  really PM_VIA_CLR_INTR - should we put it in
   1556  1.5  scottr 		 * pm_direct.h?
   1557  1.5  scottr 		 */
   1558  1.5  scottr 		via_reg(VIA1, vIFR) = 0x90;	/* clear interrupt */
   1559  1.5  scottr 		break;
   1560  1.5  scottr 
   1561  1.5  scottr 	case ADB_HW_CUDA:
   1562  1.5  scottr 		i = ADB_SR();	/* clear interrupt */
   1563  1.5  scottr 		ADB_VIA_INTR_DISABLE();	/* no interrupts while clearing */
   1564  1.5  scottr 		ADB_SET_STATE_IDLE_CUDA();	/* reset state to idle */
   1565  1.5  scottr 		delay(ADB_DELAY);
   1566  1.5  scottr 		ADB_SET_STATE_TIP();	/* signal start of frame */
   1567  1.5  scottr 		delay(ADB_DELAY);
   1568  1.5  scottr 		ADB_TOGGLE_STATE_ACK_CUDA();
   1569  1.5  scottr 		delay(ADB_DELAY);
   1570  1.5  scottr 		ADB_CLR_STATE_TIP();
   1571  1.5  scottr 		delay(ADB_DELAY);
   1572  1.5  scottr 		ADB_SET_STATE_IDLE_CUDA();	/* back to idle state */
   1573  1.5  scottr 		i = ADB_SR();	/* clear interrupt */
   1574  1.5  scottr 		ADB_VIA_INTR_ENABLE();	/* ints ok now */
   1575  1.5  scottr 		break;
   1576  1.5  scottr 
   1577  1.5  scottr 	case ADB_HW_UNKNOWN:
   1578  1.5  scottr 		return;
   1579  1.5  scottr 	}
   1580  1.1  scottr }
   1581  1.5  scottr 
   1582  1.5  scottr 
   1583  1.5  scottr /*
   1584  1.1  scottr  * adb_cleanup_IIsi
   1585  1.1  scottr  * This is sort of a "read" routine that forces the adb hardware through a read cycle
   1586  1.1  scottr  * if there is something waiting. This helps "clean up" any commands that may have gotten
   1587  1.1  scottr  * stuck or stopped during the boot process.
   1588  1.1  scottr  *
   1589  1.1  scottr  */
   1590  1.5  scottr void
   1591  1.5  scottr adb_cleanup_IIsi(u_char * buffer)
   1592  1.1  scottr {
   1593  1.5  scottr 	int i;
   1594  1.5  scottr 	int dummy;
   1595  1.5  scottr 	int s;
   1596  1.5  scottr 	long my_time;
   1597  1.5  scottr 	int endofframe;
   1598  1.5  scottr 
   1599  1.5  scottr 	delay(ADB_DELAY);
   1600  1.5  scottr 
   1601  1.5  scottr 	i = 1;			/* skip over [0] */
   1602  1.5  scottr 	s = splhigh();		/* block ALL interrupts while we are working */
   1603  1.5  scottr 	ADB_SET_SR_INPUT();	/* make sure SR is set to IN */
   1604  1.5  scottr 	ADB_VIA_INTR_DISABLE();	/* disable ADB interrupt on IIs. */
   1605  1.5  scottr 	/* this is required, especially on faster machines */
   1606  1.5  scottr 	delay(ADB_DELAY);
   1607  1.5  scottr 
   1608  1.5  scottr 	if (ADB_INTR_IS_ON) {
   1609  1.5  scottr 		ADB_SET_STATE_ACTIVE();	/* signal start of data frame */
   1610  1.5  scottr 
   1611  1.5  scottr 		endofframe = 0;
   1612  1.5  scottr 		while (0 == endofframe) {
   1613  1.5  scottr 			/* poll for ADB interrupt and watch for timeout */
   1614  1.5  scottr 			/* if time out, keep going in hopes of not hanging the
   1615  1.5  scottr 			 * ADB chip - I think */
   1616  1.5  scottr 			my_time = ADB_DELAY * 5;
   1617  1.5  scottr 			while ((ADB_SR_INTR_IS_OFF) && (my_time-- > 0))
   1618  1.5  scottr 				dummy = via_reg(VIA1, vBufB);
   1619  1.5  scottr 
   1620  1.5  scottr 			buffer[i++] = ADB_SR();	/* reset interrupt flag by
   1621  1.5  scottr 						 * reading vSR */
   1622  1.5  scottr 			/* perhaps put in a check here that ignores all data
   1623  1.5  scottr 			 * after the first MAX_ADB_MSG_LENGTH bytes ??? */
   1624  1.5  scottr 			if (ADB_INTR_IS_OFF)	/* check for end of frame */
   1625  1.5  scottr 				endofframe = 1;
   1626  1.5  scottr 
   1627  1.5  scottr 			ADB_SET_STATE_ACKON();	/* send ACK to ADB chip */
   1628  1.5  scottr 			delay(ADB_DELAY);	/* delay */
   1629  1.5  scottr 			ADB_SET_STATE_ACKOFF();	/* send ACK to ADB chip */
   1630  1.5  scottr 		}
   1631  1.5  scottr 		ADB_SET_STATE_INACTIVE();	/* signal end of frame and
   1632  1.5  scottr 						 * delay */
   1633  1.5  scottr 
   1634  1.5  scottr 		/* probably don't need to delay this long */
   1635  1.5  scottr 		delay(ADB_DELAY);
   1636  1.5  scottr 	}
   1637  1.5  scottr 	buffer[0] = --i;	/* [0] is length of message */
   1638  1.5  scottr 	ADB_VIA_INTR_ENABLE();	/* enable ADB interrupt on IIs. */
   1639  1.5  scottr 	splx(s);		/* restore interrupts */
   1640  1.5  scottr 
   1641  1.5  scottr 	return;
   1642  1.5  scottr }				/* adb_cleanup_IIsi */
   1643  1.1  scottr 
   1644  1.1  scottr 
   1645  1.1  scottr 
   1646  1.1  scottr /*
   1647  1.1  scottr  * adb_reinit sets up the adb stuff
   1648  1.1  scottr  *
   1649  1.1  scottr  */
   1650  1.5  scottr void
   1651  1.1  scottr adb_reinit(void)
   1652  1.1  scottr {
   1653  1.5  scottr 	u_char send_string[MAX_ADB_MSG_LENGTH];
   1654  1.5  scottr 	int s = 0;
   1655  1.5  scottr 	volatile int i, x;
   1656  1.5  scottr 	int command;
   1657  1.5  scottr 	int result;
   1658  1.5  scottr 	int saveptr;		/* point to next free relocation address */
   1659  1.5  scottr 	int device;
   1660  1.5  scottr 	int nonewtimes;		/* times thru loop w/o any new devices */
   1661  1.1  scottr 	ADBDataBlock data;	/* temp. holder for getting device info */
   1662  1.1  scottr 
   1663  1.4  scottr 	(void)(&s);		/* work around lame GCC bug */
   1664  1.4  scottr 
   1665  1.5  scottr 	/* Make sure we are not interrupted while building the table. */
   1666  1.5  scottr 	if (adbHardware != ADB_HW_PB)	/* ints must be on for PB? */
   1667  1.5  scottr 		s = splhigh();
   1668  1.5  scottr 
   1669  1.5  scottr 	ADBNumDevices = 0;	/* no devices yet */
   1670  1.5  scottr 
   1671  1.5  scottr 	/* Let intr routines know we are running reinit */
   1672  1.5  scottr 	adbStarting = 1;
   1673  1.5  scottr 
   1674  1.5  scottr 	/* Initialize the ADB table.  For now, we'll always use the same table
   1675  1.5  scottr 	 * that is defined at the beginning of this file - no mallocs. */
   1676  1.5  scottr 	for (i = 0; i < 16; i++)
   1677  1.5  scottr 		ADBDevTable[i].devType = 0;
   1678  1.5  scottr 
   1679  1.5  scottr 	adb_setup_hw_type();	/* setup hardware type */
   1680  1.5  scottr 
   1681  1.5  scottr 	/* Set up all the VIA bits we need to do the ADB stuff. */
   1682  1.5  scottr 	switch (adbHardware) {
   1683  1.5  scottr 	case ADB_HW_II:
   1684  1.5  scottr 		via_reg(VIA1, vDirB) |= 0x30;	/* register B bits 4 and 5:
   1685  1.5  scottr 						 * outputs */
   1686  1.5  scottr 		via_reg(VIA1, vDirB) &= 0xf7;	/* register B bit 3: input */
   1687  1.5  scottr 		via_reg(VIA1, vACR) &= ~vSR_OUT;	/* make sure SR is set
   1688  1.5  scottr 							 * to IN (II, IIsi) */
   1689  1.5  scottr 		adbActionState = ADB_ACTION_IDLE;	/* used by all types of
   1690  1.5  scottr 							 * hardware (II, IIsi) */
   1691  1.5  scottr 		adbBusState = ADB_BUS_IDLE;	/* this var. used in II-series
   1692  1.5  scottr 						 * code only */
   1693  1.5  scottr 		via_reg(VIA1, vIER) = 0x84;	/* make sure VIA interrupts
   1694  1.5  scottr 						 * are on (II, IIsi) */
   1695  1.5  scottr 		ADB_SET_STATE_IDLE_II();	/* set ADB bus state to idle */
   1696  1.5  scottr 		break;
   1697  1.5  scottr 
   1698  1.5  scottr 	case ADB_HW_IISI:
   1699  1.5  scottr 		via_reg(VIA1, vDirB) |= 0x30;	/* register B bits 4 and 5:
   1700  1.5  scottr 						 * outputs */
   1701  1.5  scottr 		via_reg(VIA1, vDirB) &= 0xf7;	/* register B bit 3: input */
   1702  1.5  scottr 		via_reg(VIA1, vACR) &= ~vSR_OUT;	/* make sure SR is set
   1703  1.5  scottr 							 * to IN (II, IIsi) */
   1704  1.5  scottr 		adbActionState = ADB_ACTION_IDLE;	/* used by all types of
   1705  1.5  scottr 							 * hardware (II, IIsi) */
   1706  1.5  scottr 		adbBusState = ADB_BUS_IDLE;	/* this var. used in II-series
   1707  1.5  scottr 						 * code only */
   1708  1.5  scottr 		via_reg(VIA1, vIER) = 0x84;	/* make sure VIA interrupts
   1709  1.5  scottr 						 * are on (II, IIsi) */
   1710  1.5  scottr 		ADB_SET_STATE_IDLE_IISI();	/* set ADB bus state to idle */
   1711  1.5  scottr 		break;
   1712  1.5  scottr 
   1713  1.5  scottr 	case ADB_HW_PB:
   1714  1.5  scottr 		break;		/* there has to be more than this? */
   1715  1.5  scottr 
   1716  1.5  scottr 	case ADB_HW_CUDA:
   1717  1.5  scottr 		via_reg(VIA1, vDirB) |= 0x30;	/* register B bits 4 and 5:
   1718  1.5  scottr 						 * outputs */
   1719  1.5  scottr 		via_reg(VIA1, vDirB) &= 0xf7;	/* register B bit 3: input */
   1720  1.5  scottr 		via_reg(VIA1, vACR) &= ~vSR_OUT;	/* make sure SR is set
   1721  1.5  scottr 							 * to IN */
   1722  1.5  scottr 		via_reg(VIA1, vACR) = (via_reg(VIA1, vACR) | 0x0c) & ~0x10;
   1723  1.5  scottr 		adbActionState = ADB_ACTION_IDLE;	/* used by all types of
   1724  1.5  scottr 							 * hardware */
   1725  1.5  scottr 		adbBusState = ADB_BUS_IDLE;	/* this var. used in II-series
   1726  1.5  scottr 						 * code only */
   1727  1.5  scottr 		via_reg(VIA1, vIER) = 0x84;	/* make sure VIA interrupts
   1728  1.5  scottr 						 * are on */
   1729  1.5  scottr 		ADB_SET_STATE_IDLE_CUDA();	/* set ADB bus state to idle */
   1730  1.5  scottr 		break;
   1731  1.5  scottr 
   1732  1.5  scottr 	case ADB_HW_UNKNOWN:	/* if type unknown then skip out */
   1733  1.1  scottr 	default:
   1734  1.5  scottr 		via_reg(VIA1, vIER) = 0x04;	/* turn interrupts off - TO
   1735  1.5  scottr 						 * DO: turn PB ints off? */
   1736  1.5  scottr 		return;
   1737  1.1  scottr 		break;
   1738  1.5  scottr 	}
   1739  1.1  scottr 
   1740  1.5  scottr 	/*
   1741  1.5  scottr 	 * Clear out any "leftover" commands.  Remember that up until this
   1742  1.5  scottr 	 * point, the interrupt routine will be either off or it should be
   1743  1.5  scottr 	 * able to ignore inputs until the device table is built.
   1744  1.1  scottr 	 */
   1745  1.5  scottr 	for (i = 0; i < 30; i++) {
   1746  1.5  scottr 		delay(ADB_DELAY);
   1747  1.5  scottr 		adb_cleanup(send_string);
   1748  1.5  scottr 		printf_intr("adb: cleanup: ");
   1749  1.5  scottr 		print_single(send_string);
   1750  1.5  scottr 		delay(ADB_DELAY);
   1751  1.5  scottr 		if (ADB_INTR_IS_OFF)
   1752  1.5  scottr 			break;
   1753  1.5  scottr 	}
   1754  1.5  scottr 
   1755  1.5  scottr 	/* send an ADB reset first */
   1756  1.5  scottr 	adb_op_sync((Ptr) 0, (Ptr) 0, (Ptr) 0, (short) 0x00);
   1757  1.5  scottr 
   1758  1.5  scottr 	/* Probe for ADB devices. Probe devices 1-15 quickly to determine
   1759  1.5  scottr 	 * which device addresses are in use and which are free. For each
   1760  1.5  scottr 	 * address that is in use, move the device at that address to a higher
   1761  1.5  scottr 	 * free address. Continue doing this at that address until no device
   1762  1.5  scottr 	 * responds at that address. Then move the last device that was moved
   1763  1.5  scottr 	 * back to the original address. Do this for the remaining addresses
   1764  1.5  scottr 	 * that we determined were in use.
   1765  1.5  scottr 	 *
   1766  1.5  scottr 	 * When finished, do this entire process over again with the updated list
   1767  1.5  scottr 	 * of in use addresses. Do this until no new devices have been found
   1768  1.5  scottr 	 * in 20 passes though the in use address list. (This probably seems
   1769  1.5  scottr 	 * long and complicated, but it's the best way to detect multiple
   1770  1.5  scottr 	 * devices at the same address - sometimes it takes a couple of tries
   1771  1.5  scottr 	 * before the collision is detected.) */
   1772  1.5  scottr 
   1773  1.1  scottr 	/* initial scan through the devices */
   1774  1.5  scottr 	for (i = 1; i < 16; i++) {
   1775  1.1  scottr 		command = (int) (0x0f | ((int) (i & 0x000f) << 4));	/* talk R3 */
   1776  1.1  scottr 		result = adb_op_sync((Ptr) send_string, (Ptr) 0, (Ptr) 0, (short) command);
   1777  1.5  scottr 		if (0x00 != send_string[0]) {	/* anything come back ?? */
   1778  1.1  scottr 			ADBDevTable[++ADBNumDevices].devType = (u_char) send_string[2];
   1779  1.1  scottr 			ADBDevTable[ADBNumDevices].origAddr = i;
   1780  1.1  scottr 			ADBDevTable[ADBNumDevices].currentAddr = i;
   1781  1.1  scottr 			ADBDevTable[ADBNumDevices].DataAreaAddr = (long) 0;
   1782  1.5  scottr 			ADBDevTable[ADBNumDevices].ServiceRtPtr = (void *) 0;
   1783  1.5  scottr 			/* printf_intr("initial device found (at index %i)\n",
   1784  1.5  scottr 			 * ADBNumDevices); */
   1785  1.5  scottr 			pm_check_adb_devices(i);	/* tell pm driver device
   1786  1.5  scottr 							 * is here */
   1787  1.1  scottr 		}
   1788  1.1  scottr 	}
   1789  1.5  scottr 
   1790  1.1  scottr 	/* find highest unused address */
   1791  1.5  scottr 	for (saveptr = 15; saveptr > 0; saveptr--)
   1792  1.5  scottr 		if (-1 == get_adb_info(&data, saveptr))
   1793  1.1  scottr 			break;
   1794  1.5  scottr 
   1795  1.5  scottr 	if (saveptr == 0)	/* no free addresses??? */
   1796  1.5  scottr 		saveptr = 15;
   1797  1.5  scottr 
   1798  1.5  scottr 	/* printf_intr("first free is: 0x%02x\n", saveptr); */
   1799  1.5  scottr 	/* printf_intr("devices: %i\n", ADBNumDevices); */
   1800  1.5  scottr 
   1801  1.5  scottr 	nonewtimes = 0;		/* no loops w/o new devices */
   1802  1.5  scottr 	while (nonewtimes++ < 11) {
   1803  1.5  scottr 		for (i = 1; i <= ADBNumDevices; i++) {
   1804  1.5  scottr 			device = ADBDevTable[i].currentAddr;
   1805  1.5  scottr 			/* printf_intr("moving device 0x%02x to 0x%02x (index
   1806  1.5  scottr 			 * 0x%02x)  ", device, saveptr, i); */
   1807  1.1  scottr 
   1808  1.1  scottr 			/* send TALK R3 to address */
   1809  1.1  scottr 			command = (int) (0x0f | ((int) (device & 0x000f) << 4));
   1810  1.1  scottr 			adb_op_sync((Ptr) send_string, (Ptr) 0, (Ptr) 0, (short) command);
   1811  1.5  scottr 
   1812  1.1  scottr 			/* move device to higher address */
   1813  1.5  scottr 			command = (int) (0x0b | ((int) (device & 0x000f) << 4));
   1814  1.5  scottr 			send_string[0] = 2;
   1815  1.5  scottr 			send_string[1] = (u_char) (saveptr | 0x60);
   1816  1.5  scottr 			send_string[2] = 0xfe;
   1817  1.5  scottr 			adb_op_sync((Ptr) send_string, (Ptr) 0, (Ptr) 0, (short) command);
   1818  1.5  scottr 
   1819  1.1  scottr 			/* send TALK R3 - anything at old address? */
   1820  1.1  scottr 			command = (int) (0x0f | ((int) (device & 0x000f) << 4));
   1821  1.1  scottr 			result = adb_op_sync((Ptr) send_string, (Ptr) 0, (Ptr) 0, (short) command);
   1822  1.5  scottr 			if (send_string[0] != 0) {
   1823  1.1  scottr 				/* new device found */
   1824  1.1  scottr 				/* update data for previously moved device */
   1825  1.5  scottr 				ADBDevTable[i].currentAddr = saveptr;
   1826  1.5  scottr 				/* printf_intr("old device at index %i\n",i); */
   1827  1.1  scottr 				/* add new device in table */
   1828  1.5  scottr 				/* printf_intr("new device found\n"); */
   1829  1.1  scottr 				ADBDevTable[++ADBNumDevices].devType = (u_char) send_string[2];
   1830  1.1  scottr 				ADBDevTable[ADBNumDevices].origAddr = device;
   1831  1.1  scottr 				ADBDevTable[ADBNumDevices].currentAddr = device;
   1832  1.5  scottr 				/* These will be set correctly in adbsys.c */
   1833  1.5  scottr 				/* Until then, unsol. data will be ignored. */
   1834  1.1  scottr 				ADBDevTable[ADBNumDevices].DataAreaAddr = (long) 0;
   1835  1.5  scottr 				ADBDevTable[ADBNumDevices].ServiceRtPtr = (void *) 0;
   1836  1.1  scottr 				/* find next unused address */
   1837  1.5  scottr 				for (x = saveptr; x > 0; x--)
   1838  1.5  scottr 					if (-1 == get_adb_info(&data, x)) {
   1839  1.5  scottr 						saveptr = x;
   1840  1.1  scottr 						break;
   1841  1.1  scottr 					}
   1842  1.5  scottr 				/* printf_intr("new free is 0x%02x\n",
   1843  1.5  scottr 				 * saveptr); */
   1844  1.5  scottr 				nonewtimes = 0;
   1845  1.5  scottr 				/* tell pm driver device is here */
   1846  1.5  scottr 				pm_check_adb_devices(device);
   1847  1.1  scottr 			} else {
   1848  1.5  scottr 				/* printf_intr("moving back...\n"); */
   1849  1.1  scottr 				/* move old device back */
   1850  1.5  scottr 				command = (int) (0x0b | ((int) (saveptr & 0x000f) << 4));
   1851  1.5  scottr 				send_string[0] = 2;
   1852  1.5  scottr 				send_string[1] = (u_char) (device | 0x60);
   1853  1.5  scottr 				send_string[2] = 0xfe;
   1854  1.5  scottr 				adb_op_sync((Ptr) send_string, (Ptr) 0, (Ptr) 0, (short) command);
   1855  1.1  scottr 			}
   1856  1.1  scottr 		}
   1857  1.1  scottr 	}
   1858  1.1  scottr 
   1859  1.5  scottr #ifdef DEBUG
   1860  1.5  scottr 	for (i = 1; i <= ADBNumDevices; i++) {
   1861  1.5  scottr 		x = get_ind_adb_info(&data, i);
   1862  1.5  scottr 		if (x != -1)
   1863  1.5  scottr 			printf_intr("index 0x%x, addr 0x%x, type 0x%x\n", i, x, data.devType);
   1864  1.5  scottr 
   1865  1.5  scottr 	}
   1866  1.5  scottr #endif
   1867  1.5  scottr 
   1868  1.5  scottr 	adb_prog_switch_enable();	/* enable the programmer's switch, if
   1869  1.5  scottr 					 * we have one */
   1870  1.1  scottr 
   1871  1.5  scottr 	if (0 == ADBNumDevices)	/* tell user if no devices found */
   1872  1.5  scottr 		printf_intr("adb: no devices found\n");
   1873  1.1  scottr 
   1874  1.5  scottr 	adbStarting = 0;	/* not starting anymore */
   1875  1.5  scottr 	printf_intr("adb: ADBReInit complete\n");
   1876  1.1  scottr 
   1877  1.5  scottr 	if (adbHardware != ADB_HW_PB)	/* ints must be on for PB? */
   1878  1.5  scottr 		splx(s);
   1879  1.5  scottr 	return;
   1880  1.1  scottr }
   1881  1.1  scottr 
   1882  1.1  scottr 
   1883  1.1  scottr /* adb_cmd_result
   1884  1.1  scottr  * This routine lets the caller know whether the specified adb command string should
   1885  1.1  scottr  * expect a returned result, such as a TALK command.
   1886  1.1  scottr  * returns: 0 if a result should be expected
   1887  1.1  scottr  *          1 if a result should NOT be expected
   1888  1.1  scottr  */
   1889  1.5  scottr int
   1890  1.5  scottr adb_cmd_result(u_char * in)
   1891  1.1  scottr {
   1892  1.5  scottr 	switch (adbHardware) {
   1893  1.5  scottr 		case ADB_HW_II:
   1894  1.5  scottr 		/* was it an ADB talk command? */
   1895  1.5  scottr 		if ((in[1] & 0x0c) == 0x0c)
   1896  1.5  scottr 			return 0;
   1897  1.5  scottr 		else
   1898  1.5  scottr 			return 1;
   1899  1.5  scottr 		break;
   1900  1.1  scottr 
   1901  1.5  scottr 	case ADB_HW_IISI:
   1902  1.5  scottr 	case ADB_HW_CUDA:
   1903  1.1  scottr 		/* was is an ADB talk command? */
   1904  1.5  scottr 		if ((in[1] == 0x00) && ((in[2] & 0x0c) == 0x0c))
   1905  1.5  scottr 			return 0;
   1906  1.5  scottr 		/* was is an RTC/PRAM read date/time? */
   1907  1.5  scottr 		else
   1908  1.5  scottr 			if ((in[1] == 0x01) && (in[2] == 0x03))
   1909  1.5  scottr 				return 0;
   1910  1.5  scottr 			else
   1911  1.5  scottr 				return 1;
   1912  1.5  scottr 		break;
   1913  1.1  scottr 
   1914  1.5  scottr 	case ADB_HW_PB:
   1915  1.5  scottr 		return 1;
   1916  1.5  scottr 		break;
   1917  1.5  scottr 
   1918  1.5  scottr 	case ADB_HW_UNKNOWN:
   1919  1.1  scottr 	default:
   1920  1.5  scottr 		return 1;
   1921  1.5  scottr 	}
   1922  1.1  scottr }
   1923  1.1  scottr 
   1924  1.1  scottr 
   1925  1.1  scottr /* adb_cmd_extra
   1926  1.1  scottr  * This routine lets the caller know whether the specified adb command string may have
   1927  1.1  scottr  * extra data appended to the end of it, such as a LISTEN command.
   1928  1.1  scottr  * returns: 0 if extra data is allowed
   1929  1.1  scottr  *          1 if extra data is NOT allowed
   1930  1.1  scottr  */
   1931  1.5  scottr int
   1932  1.5  scottr adb_cmd_extra(u_char * in)
   1933  1.1  scottr {
   1934  1.5  scottr 	switch (adbHardware) {
   1935  1.5  scottr 		case ADB_HW_II:
   1936  1.5  scottr 		if ((in[1] & 0x0c) == 0x08)	/* was it a listen command? */
   1937  1.5  scottr 			return 0;
   1938  1.5  scottr 		else
   1939  1.5  scottr 			return 1;
   1940  1.5  scottr 		break;
   1941  1.5  scottr 
   1942  1.5  scottr 	case ADB_HW_IISI:
   1943  1.5  scottr 	case ADB_HW_CUDA:
   1944  1.5  scottr 		/* TO DO: support needs to be added to recognize RTC and PRAM
   1945  1.5  scottr 		 * commands */
   1946  1.5  scottr 		if ((in[2] & 0x0c) == 0x08)	/* was it a listen command? */
   1947  1.5  scottr 			return 0;
   1948  1.5  scottr 		else		/* add others later */
   1949  1.5  scottr 			return 1;
   1950  1.5  scottr 		break;
   1951  1.1  scottr 
   1952  1.5  scottr 	case ADB_HW_PB:
   1953  1.5  scottr 		return 1;
   1954  1.5  scottr 		break;
   1955  1.5  scottr 
   1956  1.5  scottr 	case ADB_HW_UNKNOWN:
   1957  1.1  scottr 	default:
   1958  1.5  scottr 		return 1;
   1959  1.5  scottr 	}
   1960  1.1  scottr }
   1961  1.1  scottr 
   1962  1.1  scottr 
   1963  1.1  scottr /* adb_op_sync
   1964  1.1  scottr  * This routine does exactly what the adb_op routine does, except that after the
   1965  1.1  scottr  * adb_op is called, it waits until the return value is present before returning
   1966  1.1  scottr  */
   1967  1.5  scottr int
   1968  1.1  scottr adb_op_sync(Ptr buffer, Ptr compRout, Ptr data, short command)
   1969  1.1  scottr {
   1970  1.5  scottr 	int result;
   1971  1.5  scottr 	volatile int flag = 0;
   1972  1.1  scottr 
   1973  1.5  scottr 	result = adb_op(buffer, (void *) adb_op_comprout,
   1974  1.5  scottr 	    (void *) &flag, command);	/* send command */
   1975  1.5  scottr 	if (result == 0) {	/* send ok? */
   1976  1.5  scottr 		while (0 == flag);	/* wait for compl. routine */
   1977  1.5  scottr 		return 0;
   1978  1.5  scottr 	} else
   1979  1.5  scottr 		return result;
   1980  1.1  scottr }
   1981  1.1  scottr 
   1982  1.1  scottr 
   1983  1.1  scottr /* adb_op_comprout
   1984  1.5  scottr  * This function is used by the adb_op_sync routine so it knows when the function is
   1985  1.1  scottr  * done.
   1986  1.1  scottr  */
   1987  1.5  scottr void
   1988  1.5  scottr adb_op_comprout(void)
   1989  1.1  scottr {
   1990  1.5  scottr #ifdef __NetBSD__
   1991  1.5  scottr 	asm("movw	#1,a2@			| update flag value");
   1992  1.5  scottr #else				/* for macos based testing */
   1993  1.5  scottr 	asm {
   1994  1.5  scottr 		move.w #1,(a2) }		/* update flag value */
   1995  1.5  scottr #endif
   1996  1.1  scottr }
   1997  1.1  scottr 
   1998  1.1  scottr void
   1999  1.1  scottr adb_setup_hw_type(void)
   2000  1.1  scottr {
   2001  1.5  scottr 	long response;
   2002  1.1  scottr 
   2003  1.5  scottr 	response = mac68k_machine.machineid;
   2004  1.1  scottr 
   2005  1.5  scottr 	switch (response) {
   2006  1.5  scottr 	case 6:		/* II */
   2007  1.5  scottr 	case 7:		/* IIx */
   2008  1.5  scottr 	case 8:		/* IIcx */
   2009  1.5  scottr 	case 9:		/* SE/30 */
   2010  1.5  scottr 	case 11:	/* IIci */
   2011  1.5  scottr 	case 22:	/* Quadra 700 */
   2012  1.5  scottr 	case 30:	/* Centris 650 */
   2013  1.5  scottr 	case 35:	/* Quadra 800 */
   2014  1.5  scottr 	case 36:	/* Quadra 650 */
   2015  1.5  scottr 	case 52:	/* Centris 610 */
   2016  1.5  scottr 	case 53:	/* Quadra 610 */
   2017  1.5  scottr 		adbHardware = ADB_HW_II;
   2018  1.5  scottr 		printf_intr("adb: using II series hardware support\n");
   2019  1.5  scottr 		break;
   2020  1.5  scottr 	case 18:	/* IIsi */
   2021  1.5  scottr 	case 20:	/* Quadra 900 - not sure if IIsi or not */
   2022  1.5  scottr 	case 23:	/* Classic II */
   2023  1.5  scottr 	case 26:	/* Quadra 950 - not sure if IIsi or not */
   2024  1.5  scottr 	case 27:	/* LC III, Performa 450 */
   2025  1.5  scottr 	case 37:	/* LC II, Performa 400/405/430 */
   2026  1.5  scottr 	case 44:	/* IIvi */
   2027  1.5  scottr 	case 45:	/* Performa 600 */
   2028  1.5  scottr 	case 48:	/* IIvx */
   2029  1.5  scottr 	case 49:	/* Color Classic - not sure if IIsi or not */
   2030  1.5  scottr 	case 62:	/* Performa 460/465/467 */
   2031  1.5  scottr 	case 83:	/* Color Classic II - not sure if IIsi or not */
   2032  1.5  scottr 		adbHardware = ADB_HW_IISI;
   2033  1.5  scottr 		printf_intr("adb: using IIsi series hardware support\n");
   2034  1.5  scottr 		break;
   2035  1.5  scottr 	case 21:	/* PowerBook 170 */
   2036  1.5  scottr 	case 25:	/* PowerBook 140 */
   2037  1.5  scottr 	case 54:	/* PowerBook 145 */
   2038  1.5  scottr 	case 34:	/* PowerBook 160 */
   2039  1.5  scottr 	case 84:	/* PowerBook 165 */
   2040  1.5  scottr 	case 50:	/* PowerBook 165c */
   2041  1.5  scottr 	case 33:	/* PowerBook 180 */
   2042  1.5  scottr 	case 71:	/* PowerBook 180c */
   2043  1.5  scottr 	case 115:	/* PowerBook 150 */
   2044  1.5  scottr 		adbHardware = ADB_HW_PB;
   2045  1.5  scottr 		pm_setup_adb();
   2046  1.5  scottr 		printf_intr("adb: using PowerBook 100-series hardware support\n");
   2047  1.5  scottr 		break;
   2048  1.5  scottr 	case 29:	/* PowerBook Duo 210 */
   2049  1.5  scottr 	case 32:	/* PowerBook Duo 230 */
   2050  1.5  scottr 	case 38:	/* PowerBook Duo 250 */
   2051  1.5  scottr 	case 72:	/* PowerBook 500 series */
   2052  1.5  scottr 	case 77:	/* PowerBook Duo 270 */
   2053  1.5  scottr 	case 102:	/* PowerBook Duo 280 */
   2054  1.5  scottr 	case 103:	/* PowerBook Duo 280c */
   2055  1.5  scottr 		adbHardware = ADB_HW_PB;
   2056  1.5  scottr 		pm_setup_adb();
   2057  1.1  scottr 		printf_intr("adb: using PowerBook Duo-series and PowerBook 500-series hardware support\n");
   2058  1.5  scottr 		break;
   2059  1.5  scottr 	case 56:	/* LC 520 */
   2060  1.5  scottr 	case 60:	/* Centris 660AV */
   2061  1.5  scottr 	case 78:	/* Quadra 840AV */
   2062  1.5  scottr 	case 80:	/* LC 550, Performa 550 */
   2063  1.5  scottr 	case 89:	/* LC 475, Performa 475/476 */
   2064  1.5  scottr 	case 92:	/* LC 575, Performa 575/577/578 */
   2065  1.5  scottr 	case 94:	/* Quadra 605 */
   2066  1.5  scottr 	case 98:	/* LC 630, Performa 630, Quadra 630 */
   2067  1.5  scottr 		adbHardware = ADB_HW_CUDA;
   2068  1.5  scottr 		printf_intr("adb: using Cuda series hardware support\n");
   2069  1.5  scottr 		break;
   2070  1.5  scottr 	default:
   2071  1.5  scottr 		adbHardware = ADB_HW_UNKNOWN;
   2072  1.5  scottr 		printf_intr("adb: hardware type unknown for this machine\n");
   2073  1.5  scottr 		printf_intr("adb: ADB support is disabled\n");
   2074  1.5  scottr 		break;
   2075  1.5  scottr 	}
   2076  1.1  scottr }
   2077  1.1  scottr 
   2078  1.1  scottr int
   2079  1.1  scottr count_adbs(void)
   2080  1.1  scottr {
   2081  1.5  scottr 	int i;
   2082  1.5  scottr 	int found;
   2083  1.1  scottr 
   2084  1.5  scottr 	found = 0;
   2085  1.1  scottr 
   2086  1.5  scottr 	for (i = 1; i < 16; i++)
   2087  1.5  scottr 		if (0 != ADBDevTable[i].devType)
   2088  1.5  scottr 			found++;
   2089  1.1  scottr 
   2090  1.5  scottr 	return found;
   2091  1.1  scottr }
   2092  1.1  scottr 
   2093  1.1  scottr int
   2094  1.1  scottr get_ind_adb_info(ADBDataBlock * info, int index)
   2095  1.1  scottr {
   2096  1.5  scottr 	if ((index < 1) || (index > 15))	/* check range 1-15 */
   2097  1.5  scottr 		return (-1);
   2098  1.1  scottr 
   2099  1.5  scottr 	/* printf_intr("index 0x%x devType is: 0x%x\n", index,
   2100  1.5  scottr 	    ADBDevTable[index].devType); */
   2101  1.5  scottr 	if (0 == ADBDevTable[index].devType)	/* make sure it's a valid entry */
   2102  1.5  scottr 		return (-1);
   2103  1.5  scottr 
   2104  1.5  scottr 	info->devType = ADBDevTable[index].devType;
   2105  1.5  scottr 	info->origADBAddr = ADBDevTable[index].origAddr;
   2106  1.5  scottr 	info->dbServiceRtPtr = (Ptr) ADBDevTable[index].ServiceRtPtr;
   2107  1.5  scottr 	info->dbDataAreaAddr = (Ptr) ADBDevTable[index].DataAreaAddr;
   2108  1.1  scottr 
   2109  1.5  scottr 	return (ADBDevTable[index].currentAddr);
   2110  1.1  scottr }
   2111  1.1  scottr 
   2112  1.1  scottr int
   2113  1.1  scottr get_adb_info(ADBDataBlock * info, int adbAddr)
   2114  1.1  scottr {
   2115  1.5  scottr 	int i;
   2116  1.1  scottr 
   2117  1.5  scottr 	if ((adbAddr < 1) || (adbAddr > 15))	/* check range 1-15 */
   2118  1.5  scottr 		return (-1);
   2119  1.1  scottr 
   2120  1.5  scottr 	for (i = 1; i < 15; i++)
   2121  1.5  scottr 		if (ADBDevTable[i].currentAddr == adbAddr) {
   2122  1.5  scottr 			info->devType = ADBDevTable[i].devType;
   2123  1.5  scottr 			info->origADBAddr = ADBDevTable[i].origAddr;
   2124  1.5  scottr 			info->dbServiceRtPtr = (Ptr)ADBDevTable[i].ServiceRtPtr;
   2125  1.5  scottr 			info->dbDataAreaAddr = ADBDevTable[i].DataAreaAddr;
   2126  1.5  scottr 			return 0;	/* found */
   2127  1.5  scottr 		}
   2128  1.1  scottr 
   2129  1.5  scottr 	return (-1);		/* not found */
   2130  1.1  scottr }
   2131  1.1  scottr 
   2132  1.1  scottr int
   2133  1.1  scottr set_adb_info(ADBSetInfoBlock * info, int adbAddr)
   2134  1.1  scottr {
   2135  1.5  scottr 	int i;
   2136  1.1  scottr 
   2137  1.5  scottr 	if ((adbAddr < 1) || (adbAddr > 15))	/* check range 1-15 */
   2138  1.5  scottr 		return (-1);
   2139  1.1  scottr 
   2140  1.5  scottr 	for (i = 1; i < 15; i++)
   2141  1.5  scottr 		if (ADBDevTable[i].currentAddr == adbAddr) {
   2142  1.5  scottr 			ADBDevTable[i].ServiceRtPtr =
   2143  1.5  scottr 			    (void *)(info->siServiceRtPtr);
   2144  1.5  scottr 			ADBDevTable[i].DataAreaAddr = info->siDataAreaAddr;
   2145  1.5  scottr 			return 0;	/* found */
   2146  1.5  scottr 		}
   2147  1.1  scottr 
   2148  1.5  scottr 	return (-1);		/* not found */
   2149  1.1  scottr 
   2150  1.1  scottr }
   2151  1.1  scottr 
   2152  1.1  scottr #ifndef MRG_ADB
   2153  1.1  scottr long
   2154  1.1  scottr mrg_adbintr(void)
   2155  1.1  scottr {
   2156  1.5  scottr 	adb_intr();
   2157  1.1  scottr 	return 1;	/* mimic mrg_adbintr in macrom.h just in case */
   2158  1.1  scottr }
   2159  1.1  scottr 
   2160  1.1  scottr long
   2161  1.7  briggs mrg_pmintr(void)
   2162  1.1  scottr {
   2163  1.1  scottr 	pm_intr();
   2164  1.1  scottr 	return 1;	/* mimic mrg_pmintr in macrom.h just in case */
   2165  1.1  scottr }
   2166  1.5  scottr #endif
   2167  1.1  scottr 
   2168  1.1  scottr /* caller should really use machine-independant version: getPramTime */
   2169  1.1  scottr /* this version does pseudo-adb access only */
   2170  1.1  scottr int
   2171  1.1  scottr adb_read_date_time(unsigned long *time)
   2172  1.1  scottr {
   2173  1.5  scottr 	u_char output[MAX_ADB_MSG_LENGTH];
   2174  1.5  scottr 	int result;
   2175  1.5  scottr 	volatile int flag = 0;
   2176  1.5  scottr 
   2177  1.5  scottr 	switch (adbHardware) {
   2178  1.5  scottr 	case ADB_HW_II:
   2179  1.5  scottr 		return -1;
   2180  1.5  scottr 
   2181  1.5  scottr 	case ADB_HW_IISI:
   2182  1.5  scottr 		output[0] = 0x02;	/* 2 byte message */
   2183  1.5  scottr 		output[1] = 0x01;	/* to pram/rtc device */
   2184  1.5  scottr 		output[2] = 0x03;	/* read date/time */
   2185  1.5  scottr 		result = send_adb_IIsi((u_char *) output,
   2186  1.5  scottr 		    (u_char *) output, (void *) adb_op_comprout,
   2187  1.5  scottr 		    (int *) &flag, (int) 0);
   2188  1.5  scottr 		if (result != 0)	/* exit if not sent */
   2189  1.5  scottr 			return -1;
   2190  1.1  scottr 
   2191  1.5  scottr 		while (0 == flag)	/* wait for result */
   2192  1.5  scottr 			;
   2193  1.1  scottr 
   2194  1.5  scottr 		*time = (long) (*(long *) (output + 1));
   2195  1.5  scottr 		return 0;
   2196  1.1  scottr 
   2197  1.5  scottr 	case ADB_HW_PB:
   2198  1.5  scottr 		return -1;
   2199  1.1  scottr 
   2200  1.1  scottr 	case ADB_HW_CUDA:
   2201  1.5  scottr 		output[0] = 0x02;	/* 2 byte message */
   2202  1.5  scottr 		output[1] = 0x01;	/* to pram/rtc device */
   2203  1.5  scottr 		output[2] = 0x03;	/* read date/time */
   2204  1.5  scottr 		result = send_adb_cuda((u_char *) output,
   2205  1.5  scottr 		    (u_char *) output, (void *) adb_op_comprout,
   2206  1.5  scottr 		    (void *) &flag, (int) 0);
   2207  1.5  scottr 		if (result != 0)	/* exit if not sent */
   2208  1.5  scottr 			return -1;
   2209  1.5  scottr 
   2210  1.5  scottr 		while (0 == flag)	/* wait for result */
   2211  1.5  scottr 			;
   2212  1.5  scottr 
   2213  1.5  scottr 		*time = (long) (*(long *) (output + 1));
   2214  1.5  scottr 		return 0;
   2215  1.5  scottr 
   2216  1.5  scottr 	case ADB_HW_UNKNOWN:
   2217  1.5  scottr 	default:
   2218  1.5  scottr 		return -1;
   2219  1.5  scottr 	}
   2220  1.1  scottr }
   2221  1.1  scottr 
   2222  1.1  scottr /* caller should really use machine-independant version: setPramTime */
   2223  1.1  scottr /* this version does pseudo-adb access only */
   2224  1.1  scottr int
   2225  1.1  scottr adb_set_date_time(unsigned long time)
   2226  1.1  scottr {
   2227  1.5  scottr 	u_char output[MAX_ADB_MSG_LENGTH];
   2228  1.5  scottr 	int result;
   2229  1.5  scottr 	volatile int flag = 0;
   2230  1.1  scottr 
   2231  1.5  scottr 	switch (adbHardware) {
   2232  1.5  scottr 	case ADB_HW_II:
   2233  1.1  scottr 		return -1;
   2234  1.1  scottr 
   2235  1.5  scottr 	case ADB_HW_IISI:
   2236  1.5  scottr 		output[0] = 0x06;	/* 6 byte message */
   2237  1.5  scottr 		output[1] = 0x01;	/* to pram/rtc device */
   2238  1.5  scottr 		output[2] = 0x09;	/* set date/time */
   2239  1.5  scottr 		output[3] = (u_char) (time >> 24);
   2240  1.5  scottr 		output[4] = (u_char) (time >> 16);
   2241  1.5  scottr 		output[5] = (u_char) (time >> 8);
   2242  1.5  scottr 		output[6] = (u_char) (time);
   2243  1.5  scottr 		result = send_adb_IIsi((u_char *) output,
   2244  1.5  scottr 		    (u_char *) 0, (void *) adb_op_comprout,
   2245  1.5  scottr 		    (void *) &flag, (int) 0);
   2246  1.5  scottr 		if (result != 0)	/* exit if not sent */
   2247  1.5  scottr 			return -1;
   2248  1.1  scottr 
   2249  1.5  scottr 		while (0 == flag)	/* wait for send to finish */
   2250  1.5  scottr 			;
   2251  1.1  scottr 
   2252  1.5  scottr 		return 0;
   2253  1.1  scottr 
   2254  1.5  scottr 	case ADB_HW_PB:
   2255  1.5  scottr 		return -1;
   2256  1.1  scottr 
   2257  1.1  scottr 	case ADB_HW_CUDA:
   2258  1.5  scottr 		output[0] = 0x06;	/* 6 byte message */
   2259  1.5  scottr 		output[1] = 0x01;	/* to pram/rtc device */
   2260  1.5  scottr 		output[2] = 0x09;	/* set date/time */
   2261  1.5  scottr 		output[3] = (u_char) (time >> 24);
   2262  1.5  scottr 		output[4] = (u_char) (time >> 16);
   2263  1.5  scottr 		output[5] = (u_char) (time >> 8);
   2264  1.5  scottr 		output[6] = (u_char) (time);
   2265  1.5  scottr 		result = send_adb_cuda((u_char *) output,
   2266  1.5  scottr 		    (u_char *) 0, (void *) adb_op_comprout,
   2267  1.5  scottr 		    (void *) &flag, (int) 0);
   2268  1.5  scottr 		if (result != 0)	/* exit if not sent */
   2269  1.5  scottr 			return -1;
   2270  1.1  scottr 
   2271  1.5  scottr 		while (0 == flag)	/* wait for send to finish */
   2272  1.5  scottr 			;
   2273  1.1  scottr 
   2274  1.5  scottr 		return 0;
   2275  1.1  scottr 
   2276  1.5  scottr 	case ADB_HW_UNKNOWN:
   2277  1.1  scottr 	default:
   2278  1.5  scottr 		return -1;
   2279  1.5  scottr 	}
   2280  1.1  scottr }
   2281  1.1  scottr 
   2282  1.1  scottr 
   2283  1.1  scottr int
   2284  1.1  scottr adb_poweroff(void)
   2285  1.1  scottr {
   2286  1.5  scottr 	u_char output[MAX_ADB_MSG_LENGTH];
   2287  1.5  scottr 	int result;
   2288  1.1  scottr 
   2289  1.5  scottr 	switch (adbHardware) {
   2290  1.5  scottr 	case ADB_HW_IISI:
   2291  1.5  scottr 		output[0] = 0x02;	/* 2 byte message */
   2292  1.5  scottr 		output[1] = 0x01;	/* to pram/rtc/soft-power device */
   2293  1.5  scottr 		output[2] = 0x0a;	/* set date/time */
   2294  1.5  scottr 		result = send_adb_IIsi((u_char *) output,
   2295  1.5  scottr 		    (u_char *) 0, (void *) 0, (void *) 0, (int) 0);
   2296  1.5  scottr 		if (result != 0)	/* exit if not sent */
   2297  1.5  scottr 			return -1;
   2298  1.1  scottr 
   2299  1.5  scottr 		for (;;);		/* wait for power off */
   2300  1.1  scottr 
   2301  1.5  scottr 		return 0;
   2302  1.1  scottr 
   2303  1.5  scottr 	case ADB_HW_PB:
   2304  1.5  scottr 		return -1;
   2305  1.1  scottr 
   2306  1.1  scottr 	/* TO DO: some cuda models claim to do soft power - check out */
   2307  1.5  scottr 	case ADB_HW_II:			/* II models don't do soft power */
   2308  1.1  scottr 	case ADB_HW_CUDA:		/* cuda doesn't do soft power */
   2309  1.5  scottr 	case ADB_HW_UNKNOWN:
   2310  1.1  scottr 	default:
   2311  1.5  scottr 		return -1;
   2312  1.5  scottr 	}
   2313  1.5  scottr }
   2314  1.1  scottr 
   2315  1.1  scottr int
   2316  1.1  scottr adb_prog_switch_enable(void)
   2317  1.1  scottr {
   2318  1.5  scottr 	u_char output[MAX_ADB_MSG_LENGTH];
   2319  1.5  scottr 	int result;
   2320  1.5  scottr 	volatile int flag = 0;
   2321  1.5  scottr 
   2322  1.5  scottr 	switch (adbHardware) {
   2323  1.5  scottr 	case ADB_HW_IISI:
   2324  1.5  scottr 		output[0] = 0x03;	/* 3 byte message */
   2325  1.5  scottr 		output[1] = 0x01;	/* to pram/rtc/soft-power device */
   2326  1.5  scottr 		output[2] = 0x1c;	/* prog. switch control */
   2327  1.5  scottr 		output[3] = 0x01;	/* enable */
   2328  1.5  scottr 		result = send_adb_IIsi((u_char *) output,
   2329  1.5  scottr 		    (u_char *) 0, (void *) adb_op_comprout,
   2330  1.5  scottr 		    (void *) &flag, (int) 0);
   2331  1.5  scottr 		if (result != 0)	/* exit if not sent */
   2332  1.5  scottr 			return -1;
   2333  1.5  scottr 
   2334  1.5  scottr 		while (0 == flag)	/* wait for send to finish */
   2335  1.5  scottr 			;
   2336  1.5  scottr 
   2337  1.5  scottr 		return 0;
   2338  1.5  scottr 
   2339  1.5  scottr 	case ADB_HW_PB:
   2340  1.5  scottr 		return -1;
   2341  1.5  scottr 
   2342  1.5  scottr 	case ADB_HW_II:		/* II models don't do prog. switch */
   2343  1.5  scottr 	case ADB_HW_CUDA:	/* cuda doesn't do prog. switch TO DO: verify this */
   2344  1.5  scottr 	case ADB_HW_UNKNOWN:
   2345  1.1  scottr 	default:
   2346  1.5  scottr 		return -1;
   2347  1.5  scottr 	}
   2348  1.5  scottr }
   2349  1.1  scottr 
   2350  1.1  scottr int
   2351  1.1  scottr adb_prog_switch_disable(void)
   2352  1.1  scottr {
   2353  1.5  scottr 	u_char output[MAX_ADB_MSG_LENGTH];
   2354  1.5  scottr 	int result;
   2355  1.5  scottr 	volatile int flag = 0;
   2356  1.5  scottr 
   2357  1.5  scottr 	switch (adbHardware) {
   2358  1.5  scottr 	case ADB_HW_IISI:
   2359  1.5  scottr 		output[0] = 0x03;	/* 3 byte message */
   2360  1.5  scottr 		output[1] = 0x01;	/* to pram/rtc/soft-power device */
   2361  1.5  scottr 		output[2] = 0x1c;	/* prog. switch control */
   2362  1.5  scottr 		output[3] = 0x01;	/* disable */
   2363  1.5  scottr 		result = send_adb_IIsi((u_char *) output,
   2364  1.5  scottr 		    (u_char *) 0, (void *) adb_op_comprout,
   2365  1.5  scottr 		    (void *) &flag, (int) 0);
   2366  1.5  scottr 		if (result != 0)	/* exit if not sent */
   2367  1.5  scottr 			return -1;
   2368  1.5  scottr 
   2369  1.5  scottr 		while (0 == flag)	/* wait for send to finish */
   2370  1.5  scottr 			;
   2371  1.5  scottr 
   2372  1.5  scottr 		return 0;
   2373  1.5  scottr 
   2374  1.5  scottr 	case ADB_HW_PB:
   2375  1.5  scottr 		return -1;
   2376  1.5  scottr 
   2377  1.5  scottr 	case ADB_HW_II:		/* II models don't do prog. switch */
   2378  1.5  scottr 	case ADB_HW_CUDA:	/* cuda doesn't do prog. switch */
   2379  1.5  scottr 	case ADB_HW_UNKNOWN:
   2380  1.1  scottr 	default:
   2381  1.5  scottr 		return -1;
   2382  1.5  scottr 	}
   2383  1.5  scottr }
   2384  1.1  scottr 
   2385  1.1  scottr #ifndef MRG_ADB
   2386  1.5  scottr 
   2387  1.1  scottr int
   2388  1.1  scottr CountADBs(void)
   2389  1.1  scottr {
   2390  1.5  scottr 	return (count_adbs());
   2391  1.1  scottr }
   2392  1.1  scottr 
   2393  1.1  scottr void
   2394  1.1  scottr ADBReInit(void)
   2395  1.1  scottr {
   2396  1.5  scottr 	adb_reinit();
   2397  1.1  scottr }
   2398  1.1  scottr 
   2399  1.1  scottr int
   2400  1.1  scottr GetIndADB(ADBDataBlock * info, int index)
   2401  1.1  scottr {
   2402  1.5  scottr 	return (get_ind_adb_info(info, index));
   2403  1.1  scottr }
   2404  1.1  scottr 
   2405  1.1  scottr int
   2406  1.1  scottr GetADBInfo(ADBDataBlock * info, int adbAddr)
   2407  1.1  scottr {
   2408  1.5  scottr 	return (get_adb_info(info, adbAddr));
   2409  1.1  scottr }
   2410  1.1  scottr 
   2411  1.1  scottr int
   2412  1.1  scottr SetADBInfo(ADBSetInfoBlock * info, int adbAddr)
   2413  1.1  scottr {
   2414  1.5  scottr 	return (set_adb_info(info, adbAddr));
   2415  1.1  scottr }
   2416  1.1  scottr 
   2417  1.1  scottr int
   2418  1.1  scottr ADBOp(Ptr buffer, Ptr compRout, Ptr data, short commandNum)
   2419  1.1  scottr {
   2420  1.5  scottr 	return (adb_op(buffer, compRout, data, commandNum));
   2421  1.1  scottr }
   2422  1.5  scottr 
   2423  1.5  scottr #endif
   2424  1.5  scottr 
   2425