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