Home | History | Annotate | Line # | Download | only in dev
      1  1.73      nat /*	$NetBSD: adb_direct.c,v 1.73 2025/06/14 13:57:45 nat Exp $	*/
      2   1.5   scottr 
      3  1.12   scottr /* From: adb_direct.c 2.02 4/18/97 jpw */
      4   1.1   scottr 
      5   1.1   scottr /*
      6   1.1   scottr  * Copyright (C) 1996, 1997 John P. Wittkoski
      7   1.1   scottr  * All rights reserved.
      8   1.1   scottr  *
      9   1.1   scottr  * Redistribution and use in source and binary forms, with or without
     10   1.1   scottr  * modification, are permitted provided that the following conditions
     11   1.1   scottr  * are met:
     12   1.1   scottr  * 1. Redistributions of source code must retain the above copyright
     13   1.1   scottr  *    notice, this list of conditions and the following disclaimer.
     14   1.1   scottr  * 2. Redistributions in binary form must reproduce the above copyright
     15   1.1   scottr  *    notice, this list of conditions and the following disclaimer in the
     16   1.1   scottr  *    documentation and/or other materials provided with the distribution.
     17   1.1   scottr  * 3. All advertising materials mentioning features or use of this software
     18   1.1   scottr  *    must display the following acknowledgement:
     19   1.1   scottr  *  This product includes software developed by John P. Wittkoski.
     20   1.1   scottr  * 4. The name of the author may not be used to endorse or promote products
     21   1.1   scottr  *    derived from this software without specific prior written permission.
     22   1.1   scottr  *
     23   1.1   scottr  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     24   1.1   scottr  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     25   1.1   scottr  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     26   1.1   scottr  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     27   1.1   scottr  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     28   1.1   scottr  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     29   1.1   scottr  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     30   1.1   scottr  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     31   1.1   scottr  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     32   1.1   scottr  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     33   1.1   scottr  */
     34   1.1   scottr 
     35  1.12   scottr /*
     36  1.12   scottr  * This code is rather messy, but I don't have time right now
     37   1.1   scottr  * to clean it up as much as I would like.
     38  1.12   scottr  * But it works, so I'm happy. :-) jpw
     39  1.12   scottr  */
     40   1.8   scottr 
     41  1.12   scottr /*
     42  1.12   scottr  * TO DO:
     43   1.8   scottr  *  - We could reduce the time spent in the adb_intr_* routines
     44   1.8   scottr  *    by having them save the incoming and outgoing data directly
     45   1.8   scottr  *    in the adbInbound and adbOutbound queues, as it would reduce
     46   1.8   scottr  *    the number of times we need to copy the data around. It
     47   1.8   scottr  *    would also make the code more readable and easier to follow.
     48   1.8   scottr  *  - (Related to above) Use the header part of adbCommand to
     49   1.8   scottr  *    reduce the number of copies we have to do of the data.
     50   1.8   scottr  *  - (Related to above) Actually implement the adbOutbound queue.
     51   1.8   scottr  *    This is fairly easy once you switch all the intr routines
     52   1.8   scottr  *    over to using adbCommand structs directly.
     53   1.8   scottr  *  - There is a bug in the state machine of adb_intr_cuda
     54   1.8   scottr  *    code that causes hangs, especially on 030 machines, probably
     55   1.8   scottr  *    because of some timing issues. Because I have been unable to
     56   1.8   scottr  *    determine the exact cause of this bug, I used the timeout function
     57   1.8   scottr  *    to check for and recover from this condition. If anyone finds
     58   1.8   scottr  *    the actual cause of this bug, the calls to timeout and the
     59   1.8   scottr  *    adb_cuda_tickle routine can be removed.
     60   1.8   scottr  */
     61   1.1   scottr 
     62   1.1   scottr #ifdef __NetBSD__
     63  1.49    lukem 
     64  1.49    lukem #include <sys/cdefs.h>
     65  1.73      nat __KERNEL_RCSID(0, "$NetBSD: adb_direct.c,v 1.73 2025/06/14 13:57:45 nat Exp $");
     66  1.49    lukem 
     67  1.11   scottr #include "opt_adb.h"
     68   1.3   scottr 
     69   1.1   scottr #include <sys/param.h>
     70  1.38   scottr #include <sys/pool.h>
     71  1.38   scottr #include <sys/queue.h>
     72   1.1   scottr #include <sys/systm.h>
     73  1.42  thorpej #include <sys/callout.h>
     74  1.60       ad #include <sys/cpu.h>
     75  1.60       ad #include <sys/intr.h>
     76   1.1   scottr 
     77   1.1   scottr #include <machine/viareg.h>
     78   1.1   scottr #include <machine/adbsys.h>			/* required for adbvar.h */
     79  1.24   briggs #include <machine/iopreg.h>			/* required for IOP support */
     80  1.18   briggs 
     81  1.71  thorpej #include <m68k/vectors.h>
     82  1.71  thorpej 
     83   1.6   scottr #include <mac68k/mac68k/macrom.h>
     84   1.6   scottr #include <mac68k/dev/adbvar.h>
     85   1.1   scottr #define printf_intr printf
     86  1.12   scottr #else /* !__NetBSD__, i.e. Mac OS */
     87   1.1   scottr #include "via.h"				/* for macos based testing */
     88  1.12   scottr /* #define ADB_DEBUG */				/* more verbose for testing */
     89  1.16    ender 
     90  1.16    ender /* Types of ADB hardware that we support */
     91  1.16    ender #define ADB_HW_UNKNOWN		0x0	/* don't know */
     92  1.16    ender #define ADB_HW_II		0x1	/* Mac II series */
     93  1.16    ender #define ADB_HW_IISI		0x2	/* Mac IIsi series */
     94  1.16    ender #define ADB_HW_PB		0x3	/* PowerBook series */
     95  1.16    ender #define ADB_HW_CUDA		0x4	/* Machines with a Cuda chip */
     96  1.12   scottr #endif /* __NetBSD__ */
     97   1.1   scottr 
     98   1.1   scottr /* some misc. leftovers */
     99   1.1   scottr #define vPB		0x0000
    100   1.1   scottr #define vPB3		0x08
    101   1.1   scottr #define vPB4		0x10
    102   1.1   scottr #define vPB5		0x20
    103   1.1   scottr #define vSR_INT		0x04
    104   1.1   scottr #define vSR_OUT		0x10
    105   1.1   scottr 
    106   1.1   scottr /* the type of ADB action that we are currently preforming */
    107  1.16    ender #define ADB_ACTION_NOTREADY	0x1	/* has not been initialized yet */
    108  1.16    ender #define ADB_ACTION_IDLE		0x2	/* the bus is currently idle */
    109  1.16    ender #define ADB_ACTION_OUT		0x3	/* sending out a command */
    110  1.16    ender #define ADB_ACTION_IN		0x4	/* receiving data */
    111  1.16    ender #define ADB_ACTION_POLLING	0x5	/* polling - II only */
    112  1.24   briggs #define ADB_ACTION_RUNNING	0x6	/* running - IOP only */
    113   1.1   scottr 
    114   1.1   scottr /*
    115   1.1   scottr  * These describe the state of the ADB bus itself, although they
    116   1.1   scottr  * don't necessarily correspond directly to ADB states.
    117   1.1   scottr  * Note: these are not really used in the IIsi code.
    118   1.1   scottr  */
    119  1.16    ender #define ADB_BUS_UNKNOWN		0x1	/* we don't know yet - all models */
    120  1.16    ender #define ADB_BUS_IDLE		0x2	/* bus is idle - all models */
    121  1.16    ender #define ADB_BUS_CMD		0x3	/* starting a command - II models */
    122  1.16    ender #define ADB_BUS_ODD		0x4	/* the "odd" state - II models */
    123  1.16    ender #define ADB_BUS_EVEN		0x5	/* the "even" state - II models */
    124  1.16    ender #define ADB_BUS_ACTIVE		0x6	/* active state - IIsi models */
    125  1.16    ender #define ADB_BUS_ACK		0x7	/* currently ACKing - IIsi models */
    126   1.1   scottr 
    127   1.1   scottr /*
    128   1.1   scottr  * Shortcuts for setting or testing the VIA bit states.
    129   1.1   scottr  * Not all shortcuts are used for every type of ADB hardware.
    130   1.1   scottr  */
    131   1.1   scottr #define ADB_SET_STATE_IDLE_II()		via_reg(VIA1, vBufB) |= (vPB4 | vPB5)
    132   1.1   scottr #define ADB_SET_STATE_IDLE_IISI()	via_reg(VIA1, vBufB) &= ~(vPB4 | vPB5)
    133   1.1   scottr #define ADB_SET_STATE_IDLE_CUDA()	via_reg(VIA1, vBufB) |= (vPB4 | vPB5)
    134   1.1   scottr #define ADB_SET_STATE_CMD()		via_reg(VIA1, vBufB) &= ~(vPB4 | vPB5)
    135   1.5   scottr #define ADB_SET_STATE_EVEN()		via_reg(VIA1, vBufB) = ((via_reg(VIA1, \
    136   1.5   scottr 						vBufB) | vPB4) & ~vPB5)
    137   1.5   scottr #define ADB_SET_STATE_ODD()		via_reg(VIA1, vBufB) = ((via_reg(VIA1, \
    138  1.12   scottr 						vBufB) | vPB5) & ~vPB4)
    139   1.1   scottr #define ADB_SET_STATE_ACTIVE() 		via_reg(VIA1, vBufB) |= vPB5
    140   1.1   scottr #define ADB_SET_STATE_INACTIVE()	via_reg(VIA1, vBufB) &= ~vPB5
    141   1.1   scottr #define ADB_SET_STATE_TIP()		via_reg(VIA1, vBufB) &= ~vPB5
    142   1.1   scottr #define ADB_CLR_STATE_TIP() 		via_reg(VIA1, vBufB) |= vPB5
    143   1.1   scottr #define ADB_SET_STATE_ACKON()		via_reg(VIA1, vBufB) |= vPB4
    144   1.1   scottr #define ADB_SET_STATE_ACKOFF()		via_reg(VIA1, vBufB) &= ~vPB4
    145   1.1   scottr #define ADB_TOGGLE_STATE_ACK_CUDA()	via_reg(VIA1, vBufB) ^= vPB4
    146   1.1   scottr #define ADB_SET_STATE_ACKON_CUDA()	via_reg(VIA1, vBufB) &= ~vPB4
    147   1.1   scottr #define ADB_SET_STATE_ACKOFF_CUDA()	via_reg(VIA1, vBufB) |= vPB4
    148   1.1   scottr #define ADB_SET_SR_INPUT()		via_reg(VIA1, vACR) &= ~vSR_OUT
    149   1.1   scottr #define ADB_SET_SR_OUTPUT()		via_reg(VIA1, vACR) |= vSR_OUT
    150   1.1   scottr #define ADB_SR()			via_reg(VIA1, vSR)
    151   1.1   scottr #define ADB_VIA_INTR_ENABLE()		via_reg(VIA1, vIER) = 0x84
    152   1.1   scottr #define ADB_VIA_INTR_DISABLE()		via_reg(VIA1, vIER) = 0x04
    153   1.1   scottr #define ADB_VIA_CLR_INTR()		via_reg(VIA1, vIFR) = 0x04
    154   1.5   scottr #define ADB_INTR_IS_OFF			(vPB3 == (via_reg(VIA1, vBufB) & vPB3))
    155   1.5   scottr #define ADB_INTR_IS_ON			(0 == (via_reg(VIA1, vBufB) & vPB3))
    156   1.5   scottr #define ADB_SR_INTR_IS_OFF		(0 == (via_reg(VIA1, vIFR) & vSR_INT))
    157   1.5   scottr #define ADB_SR_INTR_IS_ON		(vSR_INT == (via_reg(VIA1, \
    158   1.5   scottr 						vIFR) & vSR_INT))
    159   1.1   scottr 
    160   1.5   scottr /*
    161   1.1   scottr  * This is the delay that is required (in uS) between certain
    162  1.69  msaitoh  * ADB transactions. The actual timing delay for each uS is
    163   1.1   scottr  * calculated at boot time to account for differences in machine speed.
    164   1.1   scottr  */
    165   1.5   scottr #define ADB_DELAY	150
    166   1.1   scottr 
    167   1.1   scottr /*
    168   1.1   scottr  * Maximum ADB message length; includes space for data, result, and
    169   1.1   scottr  * device code - plus a little for safety.
    170   1.1   scottr  */
    171   1.8   scottr #define ADB_MAX_MSG_LENGTH	16
    172   1.8   scottr #define ADB_MAX_HDR_LENGTH	8
    173   1.8   scottr 
    174   1.8   scottr #define ADB_QUEUE		32
    175   1.8   scottr #define ADB_TICKLE_TICKS	4
    176   1.1   scottr 
    177   1.1   scottr /*
    178   1.1   scottr  * A structure for storing information about each ADB device.
    179   1.1   scottr  */
    180   1.5   scottr struct ADBDevEntry {
    181  1.50      chs 	void	(*ServiceRtPtr)(void);
    182  1.12   scottr 	void	*DataAreaAddr;
    183  1.20    ender 	int	devType;
    184  1.20    ender 	int	origAddr;
    185  1.20    ender 	int	currentAddr;
    186   1.1   scottr };
    187   1.1   scottr 
    188   1.1   scottr /*
    189   1.1   scottr  * Used to hold ADB commands that are waiting to be sent out.
    190   1.1   scottr  */
    191   1.1   scottr struct adbCmdHoldEntry {
    192   1.8   scottr 	u_char	outBuf[ADB_MAX_MSG_LENGTH];	/* our message */
    193   1.4   scottr 	u_char	*saveBuf;	/* buffer to know where to save result */
    194   1.4   scottr 	u_char	*compRout;	/* completion routine pointer */
    195   1.4   scottr 	u_char	*data;		/* completion routine data pointer */
    196   1.1   scottr };
    197   1.1   scottr 
    198   1.1   scottr /*
    199   1.8   scottr  * Eventually used for two separate queues, the queue between
    200   1.8   scottr  * the upper and lower halves, and the outgoing packet queue.
    201   1.8   scottr  * TO DO: adbCommand can replace all of adbCmdHoldEntry eventually
    202   1.8   scottr  */
    203   1.8   scottr struct adbCommand {
    204   1.8   scottr 	u_char	header[ADB_MAX_HDR_LENGTH];	/* not used yet */
    205   1.8   scottr 	u_char	data[ADB_MAX_MSG_LENGTH];	/* packet data only */
    206   1.8   scottr 	u_char	*saveBuf;	/* where to save result */
    207   1.8   scottr 	u_char	*compRout;	/* completion routine pointer */
    208   1.8   scottr 	u_char	*compData;	/* completion routine data pointer */
    209   1.8   scottr 	u_int	cmd;		/* the original command for this data */
    210   1.8   scottr 	u_int	unsol;		/* 1 if packet was unsolicited */
    211   1.8   scottr 	u_int	ack_only;	/* 1 for no special processing */
    212   1.8   scottr };
    213   1.8   scottr 
    214   1.8   scottr /*
    215  1.16    ender  * Text representations of each hardware class
    216  1.16    ender  */
    217  1.51      jmc const char	*adbHardwareDescr[MAX_ADB_HW + 1] = {
    218  1.16    ender 	"unknown",
    219  1.16    ender 	"II series",
    220  1.16    ender 	"IIsi series",
    221  1.16    ender 	"PowerBook",
    222  1.16    ender 	"Cuda",
    223  1.24   briggs 	"IOP",
    224  1.16    ender };
    225  1.16    ender 
    226  1.16    ender /*
    227   1.1   scottr  * A few variables that we need and their initial values.
    228   1.1   scottr  */
    229   1.1   scottr int	adbHardware = ADB_HW_UNKNOWN;
    230   1.1   scottr int	adbActionState = ADB_ACTION_NOTREADY;
    231   1.1   scottr int	adbBusState = ADB_BUS_UNKNOWN;
    232   1.1   scottr int	adbWaiting = 0;		/* waiting for return data from the device */
    233   1.1   scottr int	adbWriteDelay = 0;	/* working on (or waiting to do) a write */
    234   1.5   scottr int	adbOutQueueHasData = 0;	/* something in the queue waiting to go out */
    235   1.1   scottr int	adbNextEnd = 0;		/* the next incoming bute is the last (II) */
    236   1.8   scottr int	adbSoftPower = 0;	/* machine supports soft power */
    237   1.1   scottr 
    238   1.1   scottr int	adbWaitingCmd = 0;	/* ADB command we are waiting for */
    239  1.12   scottr u_char	*adbBuffer = (long)0;	/* pointer to user data area */
    240  1.12   scottr void	*adbCompRout = (long)0;	/* pointer to the completion routine */
    241  1.12   scottr void	*adbCompData = (long)0;	/* pointer to the completion routine data */
    242   1.1   scottr long	adbFakeInts = 0;	/* keeps track of fake ADB interrupts for
    243   1.1   scottr 				 * timeouts (II) */
    244   1.5   scottr int	adbStarting = 1;	/* doing ADBReInit so do polling differently */
    245   1.1   scottr int	adbSendTalk = 0;	/* the intr routine is sending the talk, not
    246   1.1   scottr 				 * the user (II) */
    247   1.1   scottr int	adbPolling = 0;		/* we are polling for service request */
    248   1.1   scottr int	adbPollCmd = 0;		/* the last poll command we sent */
    249   1.1   scottr 
    250   1.8   scottr u_char	adbInputBuffer[ADB_MAX_MSG_LENGTH];	/* data input buffer */
    251   1.8   scottr u_char	adbOutputBuffer[ADB_MAX_MSG_LENGTH];	/* data output buffer */
    252   1.5   scottr struct	adbCmdHoldEntry adbOutQueue;		/* our 1 entry output queue */
    253   1.1   scottr 
    254   1.1   scottr int	adbSentChars = 0;	/* how many characters we have sent */
    255   1.5   scottr int	adbLastDevice = 0;	/* last ADB dev we heard from (II ONLY) */
    256   1.5   scottr int	adbLastDevIndex = 0;	/* last ADB dev loc in dev table (II ONLY) */
    257   1.1   scottr int	adbLastCommand = 0;	/* the last ADB command we sent (II) */
    258   1.1   scottr 
    259   1.8   scottr struct	ADBDevEntry ADBDevTable[16];	/* our ADB device table */
    260   1.5   scottr int	ADBNumDevices;		/* num. of ADB devices found with ADBReInit */
    261   1.1   scottr 
    262   1.8   scottr struct	adbCommand adbInbound[ADB_QUEUE];	/* incoming queue */
    263  1.35   scottr volatile int	adbInCount = 0;		/* how many packets in in queue */
    264  1.12   scottr int	adbInHead = 0;			/* head of in queue */
    265  1.12   scottr int	adbInTail = 0;			/* tail of in queue */
    266  1.12   scottr struct	adbCommand adbOutbound[ADB_QUEUE]; /* outgoing queue - not used yet */
    267  1.12   scottr int	adbOutCount = 0;		/* how many packets in out queue */
    268  1.12   scottr int	adbOutHead = 0;			/* head of out queue */
    269  1.12   scottr int	adbOutTail = 0;			/* tail of out queue */
    270  1.12   scottr 
    271  1.12   scottr int	tickle_count = 0;		/* how many tickles seen for this packet? */
    272  1.12   scottr int	tickle_serial = 0;		/* the last packet tickled */
    273  1.12   scottr int	adb_cuda_serial = 0;		/* the current packet */
    274   1.8   scottr 
    275  1.58       ad callout_t adb_cuda_tickle_ch;
    276  1.42  thorpej 
    277  1.57  tsutsui void *adb_softintr_cookie;
    278  1.57  tsutsui 
    279   1.1   scottr extern struct mac68k_machine_S mac68k_machine;
    280   1.1   scottr 
    281  1.50      chs void	pm_setup_adb(void);
    282  1.50      chs void	pm_hw_setup(void);
    283  1.50      chs void	pm_check_adb_devices(int);
    284  1.50      chs void	pm_intr(void *);
    285  1.50      chs int	pm_adb_op(u_char *, void *, void *, int);
    286  1.50      chs void	pm_init_adb_device(void);
    287   1.1   scottr 
    288   1.1   scottr /*
    289   1.1   scottr  * The following are private routines.
    290   1.1   scottr  */
    291  1.16    ender #ifdef ADB_DEBUG
    292  1.50      chs void	print_single(u_char *);
    293  1.16    ender #endif
    294  1.50      chs void	adb_intr(void *);
    295  1.50      chs void	adb_intr_II(void *);
    296  1.50      chs void	adb_intr_IIsi(void *);
    297  1.50      chs void	adb_intr_cuda(void *);
    298  1.50      chs void	adb_soft_intr(void);
    299  1.50      chs int	send_adb_II(u_char *, u_char *, void *, void *, int);
    300  1.50      chs int	send_adb_IIsi(u_char *, u_char *, void *, void *, int);
    301  1.50      chs int	send_adb_cuda(u_char *, u_char *, void *, void *, int);
    302  1.50      chs void	adb_intr_cuda_test(void);
    303  1.50      chs void	adb_cuda_tickle(void);
    304  1.50      chs void	adb_pass_up(struct adbCommand *);
    305  1.50      chs void	adb_op_comprout(void);
    306  1.50      chs void	adb_reinit(void);
    307  1.50      chs int	count_adbs(void);
    308  1.50      chs int	get_ind_adb_info(ADBDataBlock *, int);
    309  1.50      chs int	get_adb_info(ADBDataBlock *, int);
    310  1.50      chs int	set_adb_info(ADBSetInfoBlock *, int);
    311  1.50      chs void	adb_setup_hw_type(void);
    312  1.50      chs int	adb_op(Ptr, Ptr, Ptr, short);
    313  1.50      chs void	adb_read_II(u_char *);
    314  1.50      chs void	adb_hw_setup(void);
    315  1.50      chs void	adb_hw_setup_IIsi(u_char *);
    316  1.50      chs void	adb_comp_exec(void);
    317  1.50      chs int	adb_cmd_result(u_char *);
    318  1.50      chs int	adb_cmd_extra(u_char *);
    319  1.50      chs int	adb_guess_next_device(void);
    320  1.50      chs int	adb_prog_switch_enable(void);
    321  1.50      chs int	adb_prog_switch_disable(void);
    322   1.1   scottr /* we should create this and it will be the public version */
    323  1.50      chs int	send_adb(u_char *, void *, void *);
    324  1.50      chs void	adb_iop_recv(IOP *, struct iop_msg *);
    325  1.50      chs int	send_adb_iop(int, u_char *, void *, void *);
    326   1.1   scottr 
    327  1.16    ender #ifdef ADB_DEBUG
    328   1.1   scottr /*
    329   1.1   scottr  * print_single
    330   1.1   scottr  * Diagnostic display routine. Displays the hex values of the
    331   1.1   scottr  * specified elements of the u_char. The length of the "string"
    332   1.1   scottr  * is in [0].
    333   1.1   scottr  */
    334   1.5   scottr void
    335  1.50      chs print_single(u_char *str)
    336   1.1   scottr {
    337   1.1   scottr 	int x;
    338   1.1   scottr 
    339  1.22   scottr 	if (str == 0) {
    340  1.22   scottr 		printf_intr("no data - null pointer\n");
    341   1.5   scottr 		return;
    342   1.5   scottr 	}
    343  1.22   scottr 	if (*str == 0) {
    344  1.22   scottr 		printf_intr("nothing returned\n");
    345   1.1   scottr 		return;
    346   1.1   scottr 	}
    347  1.22   scottr 	if (*str > 20) {
    348   1.1   scottr 		printf_intr("ADB: ACK > 20 no way!\n");
    349  1.22   scottr 		*str = (u_char)20;
    350   1.1   scottr 	}
    351  1.22   scottr 	printf_intr("(length=0x%x):", (u_int)*str);
    352  1.22   scottr 	for (x = 1; x <= *str; x++)
    353  1.22   scottr 		printf_intr("  0x%02x", (u_int)*(str + x));
    354   1.1   scottr 	printf_intr("\n");
    355   1.1   scottr }
    356  1.16    ender #endif
    357   1.1   scottr 
    358  1.71  thorpej static inline void
    359  1.71  thorpej adb_process_serial_intrs(void)
    360  1.71  thorpej {
    361  1.71  thorpej 	/* grab any serial interrupts (autovector IPL 4) */
    362  1.71  thorpej 	struct clockframe dummy_frame = {
    363  1.71  thorpej 		.cf_sr = PSL_S,
    364  1.71  thorpej 		.cf_vo = VECI_TO_VECO(VECI_INTRAV4),
    365  1.71  thorpej 	};
    366  1.71  thorpej 	(void)intr_dispatch(dummy_frame);
    367  1.71  thorpej }
    368  1.71  thorpej 
    369   1.8   scottr void
    370   1.8   scottr adb_cuda_tickle(void)
    371   1.8   scottr {
    372   1.8   scottr 	volatile int s;
    373   1.8   scottr 
    374  1.12   scottr 	if (adbActionState == ADB_ACTION_IN) {
    375  1.12   scottr 		if (tickle_serial == adb_cuda_serial) {
    376  1.12   scottr 			if (++tickle_count > 0) {
    377  1.12   scottr 				s = splhigh();
    378   1.8   scottr 				adbActionState = ADB_ACTION_IDLE;
    379   1.8   scottr 				adbInputBuffer[0] = 0;
    380   1.8   scottr 				ADB_SET_STATE_IDLE_CUDA();
    381   1.8   scottr 				splx(s);
    382   1.8   scottr 			}
    383   1.8   scottr 		} else {
    384  1.12   scottr 			tickle_serial = adb_cuda_serial;
    385  1.12   scottr 			tickle_count = 0;
    386   1.8   scottr 		}
    387   1.8   scottr 	} else {
    388  1.12   scottr 		tickle_serial = adb_cuda_serial;
    389  1.12   scottr 		tickle_count = 0;
    390   1.8   scottr 	}
    391   1.8   scottr 
    392  1.42  thorpej 	callout_reset(&adb_cuda_tickle_ch, ADB_TICKLE_TICKS,
    393  1.42  thorpej 	    (void *)adb_cuda_tickle, NULL);
    394   1.8   scottr }
    395   1.1   scottr 
    396   1.5   scottr /*
    397  1.72   andvar  * called when an adb interrupt happens
    398   1.1   scottr  *
    399   1.1   scottr  * Cuda version of adb_intr
    400  1.16    ender  * TO DO: do we want to add some calls to intr_dispatch() here to
    401  1.16    ender  * grab serial interrupts?
    402   1.1   scottr  */
    403   1.5   scottr void
    404  1.24   briggs adb_intr_cuda(void *arg)
    405   1.1   scottr {
    406  1.66   martin 	volatile int i __unused, ending;
    407   1.8   scottr 	volatile unsigned int s;
    408   1.8   scottr 	struct adbCommand packet;
    409   1.1   scottr 
    410   1.1   scottr 	s = splhigh();		/* can't be too careful - might be called */
    411   1.5   scottr 	/* from a routine, NOT an interrupt */
    412   1.1   scottr 
    413   1.1   scottr 	ADB_VIA_CLR_INTR();	/* clear interrupt */
    414   1.1   scottr 	ADB_VIA_INTR_DISABLE();	/* disable ADB interrupt on IIs. */
    415   1.1   scottr 
    416   1.1   scottr switch_start:
    417   1.1   scottr 	switch (adbActionState) {
    418   1.1   scottr 	case ADB_ACTION_IDLE:
    419  1.12   scottr 		/*
    420  1.12   scottr 		 * This is an unexpected packet, so grab the first (dummy)
    421   1.5   scottr 		 * byte, set up the proper vars, and tell the chip we are
    422  1.12   scottr 		 * starting to receive the packet by setting the TIP bit.
    423  1.12   scottr 		 */
    424   1.5   scottr 		adbInputBuffer[1] = ADB_SR();
    425   1.8   scottr 		adb_cuda_serial++;
    426   1.8   scottr 		if (ADB_INTR_IS_OFF)	/* must have been a fake start */
    427   1.8   scottr 			break;
    428   1.8   scottr 
    429   1.8   scottr 		ADB_SET_SR_INPUT();
    430   1.5   scottr 		ADB_SET_STATE_TIP();
    431   1.8   scottr 
    432   1.8   scottr 		adbInputBuffer[0] = 1;
    433   1.8   scottr 		adbActionState = ADB_ACTION_IN;
    434  1.11   scottr #ifdef ADB_DEBUG
    435  1.11   scottr 		if (adb_debug)
    436  1.11   scottr 			printf_intr("idle 0x%02x ", adbInputBuffer[1]);
    437   1.5   scottr #endif
    438   1.5   scottr 		break;
    439   1.5   scottr 
    440   1.5   scottr 	case ADB_ACTION_IN:
    441   1.5   scottr 		adbInputBuffer[++adbInputBuffer[0]] = ADB_SR();
    442   1.5   scottr 		/* intr off means this is the last byte (end of frame) */
    443   1.5   scottr 		if (ADB_INTR_IS_OFF)
    444   1.5   scottr 			ending = 1;
    445   1.5   scottr 		else
    446   1.5   scottr 			ending = 0;
    447   1.5   scottr 
    448   1.5   scottr 		if (1 == ending) {	/* end of message? */
    449  1.11   scottr #ifdef ADB_DEBUG
    450  1.11   scottr 			if (adb_debug) {
    451  1.11   scottr 				printf_intr("in end 0x%02x ",
    452  1.11   scottr 				    adbInputBuffer[adbInputBuffer[0]]);
    453  1.11   scottr 				print_single(adbInputBuffer);
    454  1.11   scottr 			}
    455   1.5   scottr #endif
    456   1.5   scottr 
    457  1.12   scottr 			/*
    458  1.12   scottr 			 * Are we waiting AND does this packet match what we
    459   1.5   scottr 			 * are waiting for AND is it coming from either the
    460   1.5   scottr 			 * ADB or RTC/PRAM sub-device? This section _should_
    461   1.5   scottr 			 * recognize all ADB and RTC/PRAM type commands, but
    462   1.5   scottr 			 * there may be more... NOTE: commands are always at
    463  1.12   scottr 			 * [4], even for RTC/PRAM commands.
    464  1.12   scottr 			 */
    465   1.8   scottr 			/* set up data for adb_pass_up */
    466  1.28   scottr 			memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
    467   1.8   scottr 
    468   1.5   scottr 			if ((adbWaiting == 1) &&
    469   1.5   scottr 			    (adbInputBuffer[4] == adbWaitingCmd) &&
    470   1.5   scottr 			    ((adbInputBuffer[2] == 0x00) ||
    471   1.5   scottr 			    (adbInputBuffer[2] == 0x01))) {
    472  1.12   scottr 				packet.saveBuf = adbBuffer;
    473  1.12   scottr 				packet.compRout = adbCompRout;
    474  1.12   scottr 				packet.compData = adbCompData;
    475  1.12   scottr 				packet.unsol = 0;
    476  1.12   scottr 				packet.ack_only = 0;
    477   1.8   scottr 				adb_pass_up(&packet);
    478   1.8   scottr 
    479   1.8   scottr 				adbWaitingCmd = 0;	/* reset "waiting" vars */
    480   1.5   scottr 				adbWaiting = 0;
    481  1.12   scottr 				adbBuffer = (long)0;
    482  1.12   scottr 				adbCompRout = (long)0;
    483  1.12   scottr 				adbCompData = (long)0;
    484   1.5   scottr 			} else {
    485  1.12   scottr 				packet.unsol = 1;
    486  1.12   scottr 				packet.ack_only = 0;
    487   1.8   scottr 				adb_pass_up(&packet);
    488   1.5   scottr 			}
    489   1.1   scottr 
    490   1.8   scottr 
    491   1.5   scottr 			/* reset vars and signal the end of this frame */
    492   1.5   scottr 			adbActionState = ADB_ACTION_IDLE;
    493   1.5   scottr 			adbInputBuffer[0] = 0;
    494   1.5   scottr 			ADB_SET_STATE_IDLE_CUDA();
    495   1.8   scottr 			/*ADB_SET_SR_INPUT();*/
    496   1.5   scottr 
    497   1.5   scottr 			/*
    498   1.5   scottr 			 * If there is something waiting to be sent out,
    499   1.5   scottr 			 * the set everything up and send the first byte.
    500   1.5   scottr 			 */
    501   1.5   scottr 			if (adbWriteDelay == 1) {
    502   1.5   scottr 				delay(ADB_DELAY);	/* required */
    503   1.5   scottr 				adbSentChars = 0;
    504   1.5   scottr 				adbActionState = ADB_ACTION_OUT;
    505   1.5   scottr 				/*
    506   1.5   scottr 				 * If the interrupt is on, we were too slow
    507   1.5   scottr 				 * and the chip has already started to send
    508   1.5   scottr 				 * something to us, so back out of the write
    509   1.5   scottr 				 * and start a read cycle.
    510   1.5   scottr 				 */
    511   1.5   scottr 				if (ADB_INTR_IS_ON) {
    512   1.8   scottr 					ADB_SET_SR_INPUT();
    513   1.5   scottr 					ADB_SET_STATE_IDLE_CUDA();
    514   1.5   scottr 					adbSentChars = 0;
    515   1.5   scottr 					adbActionState = ADB_ACTION_IDLE;
    516   1.5   scottr 					adbInputBuffer[0] = 0;
    517   1.5   scottr 					break;
    518   1.5   scottr 				}
    519   1.5   scottr 				/*
    520   1.5   scottr 				 * If we got here, it's ok to start sending
    521   1.5   scottr 				 * so load the first byte and tell the chip
    522   1.5   scottr 				 * we want to send.
    523   1.5   scottr 				 */
    524   1.8   scottr 				ADB_SET_STATE_TIP();
    525   1.5   scottr 				ADB_SET_SR_OUTPUT();
    526   1.5   scottr 				ADB_SR() = adbOutputBuffer[adbSentChars + 1];
    527   1.5   scottr 			}
    528   1.5   scottr 		} else {
    529   1.5   scottr 			ADB_TOGGLE_STATE_ACK_CUDA();
    530  1.11   scottr #ifdef ADB_DEBUG
    531  1.11   scottr 			if (adb_debug)
    532  1.11   scottr 				printf_intr("in 0x%02x ",
    533  1.11   scottr 				    adbInputBuffer[adbInputBuffer[0]]);
    534   1.5   scottr #endif
    535   1.5   scottr 		}
    536   1.5   scottr 		break;
    537   1.1   scottr 
    538   1.5   scottr 	case ADB_ACTION_OUT:
    539   1.5   scottr 		i = ADB_SR();	/* reset SR-intr in IFR */
    540  1.11   scottr #ifdef ADB_DEBUG
    541  1.11   scottr 		if (adb_debug)
    542  1.11   scottr 			printf_intr("intr out 0x%02x ", i);
    543   1.5   scottr #endif
    544   1.1   scottr 
    545   1.5   scottr 		adbSentChars++;
    546   1.5   scottr 		if (ADB_INTR_IS_ON) {	/* ADB intr low during write */
    547  1.11   scottr #ifdef ADB_DEBUG
    548  1.11   scottr 			if (adb_debug)
    549  1.11   scottr 				printf_intr("intr was on ");
    550   1.5   scottr #endif
    551   1.8   scottr 			ADB_SET_SR_INPUT();	/* make sure SR is set to IN */
    552   1.5   scottr 			ADB_SET_STATE_IDLE_CUDA();
    553   1.5   scottr 			adbSentChars = 0;	/* must start all over */
    554   1.5   scottr 			adbActionState = ADB_ACTION_IDLE;	/* new state */
    555   1.5   scottr 			adbInputBuffer[0] = 0;
    556   1.5   scottr 			adbWriteDelay = 1;	/* must retry when done with
    557   1.5   scottr 						 * read */
    558   1.5   scottr 			delay(ADB_DELAY);
    559   1.5   scottr 			goto switch_start;	/* process next state right
    560   1.5   scottr 						 * now */
    561   1.5   scottr 			break;
    562   1.5   scottr 		}
    563   1.5   scottr 		if (adbOutputBuffer[0] == adbSentChars) {	/* check for done */
    564   1.5   scottr 			if (0 == adb_cmd_result(adbOutputBuffer)) {	/* do we expect data
    565   1.5   scottr 									 * back? */
    566   1.5   scottr 				adbWaiting = 1;	/* signal waiting for return */
    567   1.5   scottr 				adbWaitingCmd = adbOutputBuffer[2];	/* save waiting command */
    568  1.12   scottr 			} else {	/* no talk, so done */
    569  1.12   scottr 				/* set up stuff for adb_pass_up */
    570  1.28   scottr 				memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
    571  1.12   scottr 				packet.saveBuf = adbBuffer;
    572  1.12   scottr 				packet.compRout = adbCompRout;
    573  1.12   scottr 				packet.compData = adbCompData;
    574  1.12   scottr 				packet.cmd = adbWaitingCmd;
    575  1.12   scottr 				packet.unsol = 0;
    576  1.12   scottr 				packet.ack_only = 1;
    577  1.12   scottr 				adb_pass_up(&packet);
    578  1.12   scottr 
    579  1.12   scottr 				/* reset "waiting" vars, just in case */
    580  1.12   scottr 				adbWaitingCmd = 0;
    581  1.12   scottr 				adbBuffer = (long)0;
    582  1.12   scottr 				adbCompRout = (long)0;
    583  1.12   scottr 				adbCompData = (long)0;
    584   1.5   scottr 			}
    585   1.1   scottr 
    586   1.5   scottr 			adbWriteDelay = 0;	/* done writing */
    587   1.5   scottr 			adbActionState = ADB_ACTION_IDLE;	/* signal bus is idle */
    588   1.8   scottr 			ADB_SET_SR_INPUT();
    589   1.5   scottr 			ADB_SET_STATE_IDLE_CUDA();
    590  1.11   scottr #ifdef ADB_DEBUG
    591  1.11   scottr 			if (adb_debug)
    592  1.11   scottr 				printf_intr("write done ");
    593   1.5   scottr #endif
    594   1.5   scottr 		} else {
    595   1.5   scottr 			ADB_SR() = adbOutputBuffer[adbSentChars + 1];	/* send next byte */
    596   1.5   scottr 			ADB_TOGGLE_STATE_ACK_CUDA();	/* signal byte ready to
    597   1.5   scottr 							 * shift */
    598  1.11   scottr #ifdef ADB_DEBUG
    599  1.11   scottr 			if (adb_debug)
    600  1.11   scottr 				printf_intr("toggle ");
    601   1.5   scottr #endif
    602   1.5   scottr 		}
    603   1.5   scottr 		break;
    604   1.1   scottr 
    605   1.5   scottr 	case ADB_ACTION_NOTREADY:
    606  1.16    ender #ifdef ADB_DEBUG
    607  1.16    ender 		if (adb_debug)
    608  1.16    ender 			printf_intr("adb: not yet initialized\n");
    609  1.16    ender #endif
    610   1.5   scottr 		break;
    611   1.1   scottr 
    612   1.5   scottr 	default:
    613  1.16    ender #ifdef ADB_DEBUG
    614  1.16    ender 		if (adb_debug)
    615  1.16    ender 			printf_intr("intr: unknown ADB state\n");
    616  1.16    ender #endif
    617  1.47  thorpej 		break;
    618   1.5   scottr 	}
    619   1.1   scottr 
    620   1.5   scottr 	ADB_VIA_INTR_ENABLE();	/* enable ADB interrupt on IIs. */
    621   1.1   scottr 
    622   1.5   scottr 	splx(s);		/* restore */
    623   1.1   scottr 
    624   1.5   scottr 	return;
    625   1.8   scottr }				/* end adb_intr_cuda */
    626   1.1   scottr 
    627   1.1   scottr 
    628   1.5   scottr int
    629  1.50      chs send_adb_cuda(u_char *in, u_char *buffer, void *compRout, void *data, int
    630   1.5   scottr 	command)
    631   1.5   scottr {
    632  1.28   scottr 	int s, len;
    633   1.1   scottr 
    634  1.11   scottr #ifdef ADB_DEBUG
    635  1.11   scottr 	if (adb_debug)
    636  1.11   scottr 		printf_intr("SEND\n");
    637   1.5   scottr #endif
    638   1.1   scottr 
    639   1.5   scottr 	if (adbActionState == ADB_ACTION_NOTREADY)
    640   1.5   scottr 		return 1;
    641   1.1   scottr 
    642  1.12   scottr 	/* Don't interrupt while we are messing with the ADB */
    643  1.12   scottr 	s = splhigh();
    644   1.1   scottr 
    645   1.5   scottr 	if ((adbActionState == ADB_ACTION_IDLE) &&	/* ADB available? */
    646   1.5   scottr 	    (ADB_INTR_IS_OFF)) {	/* and no incoming interrupt? */
    647   1.5   scottr 	} else
    648   1.5   scottr 		if (adbWriteDelay == 0)	/* it's busy, but is anything waiting? */
    649   1.5   scottr 			adbWriteDelay = 1;	/* if no, then we'll "queue"
    650   1.5   scottr 						 * it up */
    651   1.5   scottr 		else {
    652   1.5   scottr 			splx(s);
    653   1.5   scottr 			return 1;	/* really busy! */
    654   1.5   scottr 		}
    655   1.1   scottr 
    656  1.11   scottr #ifdef ADB_DEBUG
    657  1.11   scottr 	if (adb_debug)
    658  1.11   scottr 		printf_intr("QUEUE\n");
    659   1.1   scottr #endif
    660  1.12   scottr 	if ((long)in == (long)0) {	/* need to convert? */
    661  1.12   scottr 		/*
    662  1.12   scottr 		 * Don't need to use adb_cmd_extra here because this section
    663  1.12   scottr 		 * will be called ONLY when it is an ADB command (no RTC or
    664  1.12   scottr 		 * PRAM)
    665  1.12   scottr 		 */
    666   1.5   scottr 		if ((command & 0x0c) == 0x08)	/* copy addl data ONLY if
    667   1.5   scottr 						 * doing a listen! */
    668   1.5   scottr 			len = buffer[0];	/* length of additional data */
    669   1.5   scottr 		else
    670   1.5   scottr 			len = 0;/* no additional data */
    671   1.1   scottr 
    672   1.5   scottr 		adbOutputBuffer[0] = 2 + len;	/* dev. type + command + addl.
    673   1.5   scottr 						 * data */
    674   1.5   scottr 		adbOutputBuffer[1] = 0x00;	/* mark as an ADB command */
    675  1.12   scottr 		adbOutputBuffer[2] = (u_char)command;	/* load command */
    676   1.5   scottr 
    677  1.28   scottr 		/* copy additional output data, if any */
    678  1.28   scottr 		memcpy(adbOutputBuffer + 3, buffer + 1, len);
    679   1.5   scottr 	} else
    680  1.28   scottr 		/* if data ready, just copy over */
    681  1.28   scottr 		memcpy(adbOutputBuffer, in, in[0] + 2);
    682   1.5   scottr 
    683   1.5   scottr 	adbSentChars = 0;	/* nothing sent yet */
    684   1.5   scottr 	adbBuffer = buffer;	/* save buffer to know where to save result */
    685   1.5   scottr 	adbCompRout = compRout;	/* save completion routine pointer */
    686   1.5   scottr 	adbCompData = data;	/* save completion routine data pointer */
    687   1.5   scottr 	adbWaitingCmd = adbOutputBuffer[2];	/* save wait command */
    688   1.5   scottr 
    689   1.5   scottr 	if (adbWriteDelay != 1) {	/* start command now? */
    690  1.11   scottr #ifdef ADB_DEBUG
    691  1.11   scottr 		if (adb_debug)
    692  1.11   scottr 			printf_intr("out start NOW");
    693   1.5   scottr #endif
    694   1.5   scottr 		delay(ADB_DELAY);
    695   1.5   scottr 		adbActionState = ADB_ACTION_OUT;	/* set next state */
    696   1.5   scottr 		ADB_SET_SR_OUTPUT();	/* set shift register for OUT */
    697   1.5   scottr 		ADB_SR() = adbOutputBuffer[adbSentChars + 1];	/* load byte for output */
    698   1.5   scottr 		ADB_SET_STATE_ACKOFF_CUDA();
    699   1.5   scottr 		ADB_SET_STATE_TIP();	/* tell ADB that we want to send */
    700   1.5   scottr 	}
    701   1.5   scottr 	adbWriteDelay = 1;	/* something in the write "queue" */
    702   1.1   scottr 
    703   1.5   scottr 	splx(s);
    704   1.1   scottr 
    705  1.33   scottr 	if (0x0100 <= (s & 0x0700))	/* were VIA1 interrupts blocked? */
    706   1.5   scottr 		/* poll until byte done */
    707   1.5   scottr 		while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
    708   1.5   scottr 		    || (adbWaiting == 1))
    709  1.33   scottr 			if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
    710  1.33   scottr 				adb_intr_cuda(NULL); /* go process it */
    711  1.33   scottr 				if (adb_polling)
    712  1.26   scottr 					adb_soft_intr();
    713  1.33   scottr 			}
    714   1.1   scottr 
    715   1.5   scottr 	return 0;
    716   1.5   scottr }				/* send_adb_cuda */
    717   1.1   scottr 
    718   1.1   scottr 
    719   1.1   scottr void
    720  1.24   briggs adb_intr_II(void *arg)
    721   1.1   scottr {
    722   1.8   scottr 	struct adbCommand packet;
    723   1.8   scottr 	int i, intr_on = 0;
    724  1.12   scottr 	int send = 0;
    725   1.5   scottr 	unsigned int s;
    726   1.1   scottr 
    727   1.5   scottr 	s = splhigh();		/* can't be too careful - might be called */
    728   1.5   scottr 	/* from a routine, NOT an interrupt */
    729   1.1   scottr 
    730   1.5   scottr 	ADB_VIA_CLR_INTR();	/* clear interrupt */
    731   1.1   scottr 
    732   1.5   scottr 	ADB_VIA_INTR_DISABLE();	/* disable ADB interrupt on IIs. */
    733   1.1   scottr 
    734  1.12   scottr 	delay(ADB_DELAY);	/* yuck (don't remove) */
    735  1.24   briggs 
    736  1.71  thorpej 	adb_process_serial_intrs();
    737  1.12   scottr 
    738   1.5   scottr 	if (ADB_INTR_IS_ON)
    739   1.5   scottr 		intr_on = 1;	/* save for later */
    740  1.12   scottr 
    741  1.12   scottr switch_start:
    742   1.5   scottr 	switch (adbActionState) {
    743  1.12   scottr 	case ADB_ACTION_POLLING:
    744  1.12   scottr 		if (!intr_on) {
    745  1.12   scottr 			if (adbOutQueueHasData) {
    746  1.12   scottr #ifdef ADB_DEBUG
    747  1.12   scottr 				if (adb_debug & 0x80)
    748  1.12   scottr 					printf_intr("POLL-doing-out-queue. ");
    749  1.12   scottr #endif
    750  1.12   scottr 				ADB_SET_STATE_IDLE_II();
    751  1.12   scottr 				delay(ADB_DELAY);
    752  1.28   scottr 
    753  1.28   scottr 				/* copy over data */
    754  1.28   scottr 				memcpy(adbOutputBuffer, adbOutQueue.outBuf,
    755  1.28   scottr 				    adbOutQueue.outBuf[0] + 2);
    756  1.28   scottr 
    757  1.12   scottr 				adbBuffer = adbOutQueue.saveBuf;	/* user data area */
    758  1.12   scottr 				adbCompRout = adbOutQueue.compRout;	/* completion routine */
    759  1.12   scottr 				adbCompData = adbOutQueue.data;	/* comp. rout. data */
    760  1.12   scottr 				adbOutQueueHasData = 0;	/* currently processing
    761  1.12   scottr 							 * "queue" entry */
    762  1.12   scottr 				adbSentChars = 0;	/* nothing sent yet */
    763  1.12   scottr 				adbActionState = ADB_ACTION_OUT;	/* set next state */
    764  1.12   scottr 				ADB_SET_SR_OUTPUT();	/* set shift register for OUT */
    765  1.12   scottr 				ADB_SR() = adbOutputBuffer[1];	/* load byte for output */
    766  1.12   scottr 				adbBusState = ADB_BUS_CMD;	/* set bus to cmd state */
    767  1.28   scottr 				ADB_SET_STATE_CMD();	/* tell ADB that we want to send */
    768  1.12   scottr 				break;
    769  1.12   scottr 			} else {
    770  1.12   scottr #ifdef ADB_DEBUG
    771  1.12   scottr 				if (adb_debug)
    772  1.12   scottr 					printf_intr("pIDLE ");
    773  1.12   scottr #endif
    774  1.12   scottr 				adbActionState = ADB_ACTION_IDLE;
    775  1.12   scottr 			}
    776  1.12   scottr 		} else {
    777  1.12   scottr #ifdef ADB_DEBUG
    778  1.12   scottr 			if (adb_debug & 0x80)
    779  1.12   scottr 				printf_intr("pIN ");
    780  1.12   scottr #endif
    781  1.12   scottr 			adbActionState = ADB_ACTION_IN;
    782  1.12   scottr 		}
    783  1.12   scottr 		delay(ADB_DELAY);
    784  1.71  thorpej 		adb_process_serial_intrs();
    785  1.12   scottr 		goto switch_start;
    786  1.12   scottr 		break;
    787   1.5   scottr 	case ADB_ACTION_IDLE:
    788   1.5   scottr 		if (!intr_on) {
    789   1.5   scottr 			i = ADB_SR();
    790  1.12   scottr 			adbBusState = ADB_BUS_IDLE;
    791  1.12   scottr 			adbActionState = ADB_ACTION_IDLE;
    792  1.12   scottr 			ADB_SET_STATE_IDLE_II();
    793   1.5   scottr 			break;
    794   1.5   scottr 		}
    795   1.5   scottr 		adbInputBuffer[0] = 1;
    796   1.5   scottr 		adbInputBuffer[1] = ADB_SR();	/* get first byte */
    797  1.12   scottr #ifdef ADB_DEBUG
    798  1.12   scottr 		if (adb_debug & 0x80)
    799  1.12   scottr 			printf_intr("idle 0x%02x ", adbInputBuffer[1]);
    800  1.12   scottr #endif
    801   1.5   scottr 		ADB_SET_SR_INPUT();	/* make sure SR is set to IN */
    802   1.5   scottr 		adbActionState = ADB_ACTION_IN;	/* set next state */
    803   1.5   scottr 		ADB_SET_STATE_EVEN();	/* set bus state to even */
    804   1.5   scottr 		adbBusState = ADB_BUS_EVEN;
    805   1.5   scottr 		break;
    806   1.5   scottr 
    807   1.5   scottr 	case ADB_ACTION_IN:
    808   1.5   scottr 		adbInputBuffer[++adbInputBuffer[0]] = ADB_SR();	/* get byte */
    809  1.12   scottr #ifdef ADB_DEBUG
    810  1.12   scottr 		if (adb_debug & 0x80)
    811  1.12   scottr 			printf_intr("in 0x%02x ",
    812  1.12   scottr 			    adbInputBuffer[adbInputBuffer[0]]);
    813  1.12   scottr #endif
    814   1.5   scottr 		ADB_SET_SR_INPUT();	/* make sure SR is set to IN */
    815   1.1   scottr 
    816  1.12   scottr 		if (intr_on) {	/* process last byte of packet */
    817  1.12   scottr 			adbInputBuffer[0]--;	/* minus one */
    818  1.12   scottr 			/*
    819  1.12   scottr 			 * If intr_on was true, and it's the second byte, then
    820  1.12   scottr 			 * the byte we just discarded is really valid, so
    821  1.12   scottr 			 * adjust the count
    822  1.12   scottr 			 */
    823  1.12   scottr 			if (adbInputBuffer[0] == 2) {
    824  1.12   scottr 				adbInputBuffer[0]++;
    825  1.12   scottr 			}
    826  1.12   scottr 
    827  1.12   scottr #ifdef ADB_DEBUG
    828  1.12   scottr 			if (adb_debug & 0x80) {
    829  1.12   scottr 				printf_intr("done: ");
    830  1.12   scottr 				print_single(adbInputBuffer);
    831   1.5   scottr 			}
    832  1.12   scottr #endif
    833  1.12   scottr 
    834  1.41   scottr 			adbLastDevice = ADB_CMDADDR(adbInputBuffer[1]);
    835  1.12   scottr 
    836  1.12   scottr 			if (adbInputBuffer[0] == 1 && !adbWaiting) {	/* SRQ!!!*/
    837  1.12   scottr #ifdef ADB_DEBUG
    838  1.12   scottr 				if (adb_debug & 0x80)
    839  1.12   scottr 					printf_intr(" xSRQ! ");
    840  1.12   scottr #endif
    841  1.12   scottr 				adb_guess_next_device();
    842  1.12   scottr #ifdef ADB_DEBUG
    843  1.12   scottr 				if (adb_debug & 0x80)
    844  1.12   scottr 					printf_intr("try 0x%0x ",
    845  1.12   scottr 					    adbLastDevice);
    846  1.12   scottr #endif
    847  1.12   scottr 				adbOutputBuffer[0] = 1;
    848  1.41   scottr 				adbOutputBuffer[1] = ADBTALK(adbLastDevice, 0);
    849  1.12   scottr 
    850  1.12   scottr 				adbSentChars = 0;	/* nothing sent yet */
    851  1.12   scottr 				adbActionState = ADB_ACTION_POLLING;	/* set next state */
    852  1.12   scottr 				ADB_SET_SR_OUTPUT();	/* set shift register for OUT */
    853  1.12   scottr 				ADB_SR() = adbOutputBuffer[1];	/* load byte for output */
    854  1.12   scottr 				adbBusState = ADB_BUS_CMD;	/* set bus to cmd state */
    855  1.12   scottr 				ADB_SET_STATE_CMD();	/* tell ADB that we want to */
    856  1.12   scottr 				break;
    857  1.12   scottr 			}
    858  1.12   scottr 
    859  1.12   scottr 			/* set up data for adb_pass_up */
    860  1.28   scottr 			memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
    861   1.5   scottr 
    862  1.12   scottr 			if (!adbWaiting && (adbInputBuffer[0] != 0)) {
    863  1.12   scottr 				packet.unsol = 1;
    864  1.12   scottr 				packet.ack_only = 0;
    865  1.12   scottr 				adb_pass_up(&packet);
    866  1.12   scottr 			} else {
    867  1.12   scottr 				packet.saveBuf = adbBuffer;
    868  1.12   scottr 				packet.compRout = adbCompRout;
    869  1.12   scottr 				packet.compData = adbCompData;
    870  1.12   scottr 				packet.unsol = 0;
    871  1.12   scottr 				packet.ack_only = 0;
    872   1.8   scottr 				adb_pass_up(&packet);
    873  1.12   scottr 			}
    874  1.12   scottr 
    875   1.5   scottr 			adbWaiting = 0;
    876   1.5   scottr 			adbInputBuffer[0] = 0;
    877  1.12   scottr 			adbBuffer = (long)0;
    878  1.12   scottr 			adbCompRout = (long)0;
    879  1.12   scottr 			adbCompData = (long)0;
    880   1.5   scottr 			/*
    881   1.5   scottr 			 * Since we are done, check whether there is any data
    882   1.5   scottr 			 * waiting to do out. If so, start the sending the data.
    883   1.5   scottr 			 */
    884   1.5   scottr 			if (adbOutQueueHasData == 1) {
    885  1.12   scottr #ifdef ADB_DEBUG
    886  1.12   scottr 				if (adb_debug & 0x80)
    887  1.12   scottr 					printf_intr("XXX: DOING OUT QUEUE\n");
    888  1.12   scottr #endif
    889   1.5   scottr 				/* copy over data */
    890  1.28   scottr 				memcpy(adbOutputBuffer, adbOutQueue.outBuf,
    891  1.28   scottr 				    adbOutQueue.outBuf[0] + 2);
    892   1.5   scottr 				adbBuffer = adbOutQueue.saveBuf;	/* user data area */
    893   1.5   scottr 				adbCompRout = adbOutQueue.compRout;	/* completion routine */
    894   1.5   scottr 				adbCompData = adbOutQueue.data;	/* comp. rout. data */
    895   1.5   scottr 				adbOutQueueHasData = 0;	/* currently processing
    896   1.5   scottr 							 * "queue" entry */
    897   1.5   scottr 				send = 1;
    898  1.12   scottr 			} else {
    899  1.12   scottr #ifdef ADB_DEBUG
    900  1.12   scottr 				if (adb_debug & 0x80)
    901  1.12   scottr 					printf_intr("XXending ");
    902  1.12   scottr #endif
    903  1.12   scottr 				adb_guess_next_device();
    904  1.12   scottr 				adbOutputBuffer[0] = 1;
    905  1.12   scottr 				adbOutputBuffer[1] = ((adbLastDevice & 0x0f) << 4) | 0x0c;
    906  1.12   scottr 				adbSentChars = 0;	/* nothing sent yet */
    907  1.12   scottr 				adbActionState = ADB_ACTION_POLLING;	/* set next state */
    908  1.12   scottr 				ADB_SET_SR_OUTPUT();	/* set shift register for OUT */
    909  1.12   scottr 				ADB_SR() = adbOutputBuffer[1];	/* load byte for output */
    910  1.12   scottr 				adbBusState = ADB_BUS_CMD;	/* set bus to cmd state */
    911  1.12   scottr 				ADB_SET_STATE_CMD();	/* tell ADB that we want to */
    912  1.12   scottr 				break;
    913  1.12   scottr 			}
    914   1.5   scottr 		}
    915  1.12   scottr 
    916   1.5   scottr 		/*
    917   1.5   scottr 		 * If send is true then something above determined that
    918   1.5   scottr 		 * the message has ended and we need to start sending out
    919   1.5   scottr 		 * a new message immediately. This could be because there
    920   1.5   scottr 		 * is data waiting to go out or because an SRQ was seen.
    921   1.1   scottr 		 */
    922   1.5   scottr 		if (send) {
    923   1.5   scottr 			adbSentChars = 0;	/* nothing sent yet */
    924   1.5   scottr 			adbActionState = ADB_ACTION_OUT;	/* set next state */
    925   1.5   scottr 			ADB_SET_SR_OUTPUT();	/* set shift register for OUT */
    926   1.5   scottr 			ADB_SR() = adbOutputBuffer[1];	/* load byte for output */
    927   1.5   scottr 			adbBusState = ADB_BUS_CMD;	/* set bus to cmd state */
    928   1.5   scottr 			ADB_SET_STATE_CMD();	/* tell ADB that we want to
    929   1.5   scottr 						 * send */
    930   1.5   scottr 			break;
    931   1.5   scottr 		}
    932   1.5   scottr 		/* We only get this far if the message hasn't ended yet. */
    933   1.5   scottr 		switch (adbBusState) {	/* set to next state */
    934   1.5   scottr 		case ADB_BUS_EVEN:
    935   1.5   scottr 			ADB_SET_STATE_ODD();	/* set state to odd */
    936   1.1   scottr 			adbBusState = ADB_BUS_ODD;
    937   1.5   scottr 			break;
    938   1.1   scottr 
    939   1.1   scottr 		case ADB_BUS_ODD:
    940   1.5   scottr 			ADB_SET_STATE_EVEN();	/* set state to even */
    941   1.5   scottr 			adbBusState = ADB_BUS_EVEN;
    942   1.5   scottr 			break;
    943   1.5   scottr 		default:
    944   1.5   scottr 			printf_intr("strange state!!!\n");	/* huh? */
    945   1.5   scottr 			break;
    946   1.5   scottr 		}
    947   1.5   scottr 		break;
    948   1.5   scottr 
    949   1.5   scottr 	case ADB_ACTION_OUT:
    950   1.5   scottr 		i = ADB_SR();	/* clear interrupt */
    951   1.5   scottr 		adbSentChars++;
    952   1.5   scottr 		/*
    953   1.5   scottr 		 * If the outgoing data was a TALK, we must
    954   1.5   scottr 		 * switch to input mode to get the result.
    955   1.5   scottr 		 */
    956   1.5   scottr 		if ((adbOutputBuffer[1] & 0x0c) == 0x0c) {
    957   1.5   scottr 			adbInputBuffer[0] = 1;
    958   1.5   scottr 			adbInputBuffer[1] = i;
    959   1.5   scottr 			adbActionState = ADB_ACTION_IN;
    960   1.5   scottr 			ADB_SET_SR_INPUT();
    961   1.5   scottr 			adbBusState = ADB_BUS_EVEN;
    962   1.5   scottr 			ADB_SET_STATE_EVEN();
    963  1.12   scottr #ifdef ADB_DEBUG
    964  1.12   scottr 			if (adb_debug & 0x80)
    965  1.12   scottr 				printf_intr("talk out 0x%02x ", i);
    966  1.12   scottr #endif
    967  1.12   scottr 			/* we want something back */
    968  1.12   scottr 			adbWaiting = 1;
    969   1.5   scottr 			break;
    970   1.5   scottr 		}
    971  1.12   scottr 		/*
    972  1.12   scottr 		 * If it's not a TALK, check whether all data has been sent.
    973   1.5   scottr 		 * If so, call the completion routine and clean up. If not,
    974  1.12   scottr 		 * advance to the next state.
    975  1.12   scottr 		 */
    976  1.12   scottr #ifdef ADB_DEBUG
    977  1.12   scottr 		if (adb_debug & 0x80)
    978  1.12   scottr 			printf_intr("non-talk out 0x%0x ", i);
    979  1.12   scottr #endif
    980   1.5   scottr 		ADB_SET_SR_OUTPUT();
    981   1.5   scottr 		if (adbOutputBuffer[0] == adbSentChars) {	/* check for done */
    982  1.12   scottr #ifdef ADB_DEBUG
    983  1.12   scottr 			if (adb_debug & 0x80)
    984  1.12   scottr 				printf_intr("done \n");
    985  1.12   scottr #endif
    986  1.12   scottr 			/* set up stuff for adb_pass_up */
    987  1.28   scottr 			memcpy(packet.data, adbOutputBuffer, adbOutputBuffer[0] + 1);
    988  1.12   scottr 			packet.saveBuf = adbBuffer;
    989  1.12   scottr 			packet.compRout = adbCompRout;
    990  1.12   scottr 			packet.compData = adbCompData;
    991  1.12   scottr 			packet.cmd = adbWaitingCmd;
    992  1.12   scottr 			packet.unsol = 0;
    993  1.12   scottr 			packet.ack_only = 1;
    994  1.12   scottr 			adb_pass_up(&packet);
    995  1.12   scottr 
    996  1.12   scottr 			/* reset "waiting" vars, just in case */
    997  1.12   scottr 			adbBuffer = (long)0;
    998  1.12   scottr 			adbCompRout = (long)0;
    999  1.12   scottr 			adbCompData = (long)0;
   1000   1.5   scottr 			if (adbOutQueueHasData == 1) {
   1001   1.5   scottr 				/* copy over data */
   1002  1.28   scottr 				memcpy(adbOutputBuffer, adbOutQueue.outBuf,
   1003  1.28   scottr 				    adbOutQueue.outBuf[0] + 2);
   1004   1.5   scottr 				adbBuffer = adbOutQueue.saveBuf;	/* user data area */
   1005   1.5   scottr 				adbCompRout = adbOutQueue.compRout;	/* completion routine */
   1006   1.5   scottr 				adbCompData = adbOutQueue.data;	/* comp. rout. data */
   1007   1.5   scottr 				adbOutQueueHasData = 0;	/* currently processing
   1008   1.5   scottr 							 * "queue" entry */
   1009  1.12   scottr 				adbSentChars = 0;	/* nothing sent yet */
   1010  1.12   scottr 				adbActionState = ADB_ACTION_OUT;	/* set next state */
   1011  1.12   scottr 				ADB_SET_SR_OUTPUT();	/* set shift register for OUT */
   1012  1.12   scottr 				ADB_SR() = adbOutputBuffer[1];	/* load byte for output */
   1013  1.12   scottr 				adbBusState = ADB_BUS_CMD;	/* set bus to cmd state */
   1014  1.12   scottr 				ADB_SET_STATE_CMD();	/* tell ADB that we want to
   1015  1.12   scottr 							 * send */
   1016  1.12   scottr 				break;
   1017   1.5   scottr 			} else {
   1018  1.12   scottr 				/* send talk to last device instead */
   1019   1.5   scottr 				adbOutputBuffer[0] = 1;
   1020  1.41   scottr 				adbOutputBuffer[1] =
   1021  1.41   scottr 				    ADBTALK(ADB_CMDADDR(adbOutputBuffer[1]), 0);
   1022  1.12   scottr 
   1023  1.12   scottr 				adbSentChars = 0;	/* nothing sent yet */
   1024  1.12   scottr 				adbActionState = ADB_ACTION_IDLE;	/* set next state */
   1025  1.12   scottr 				ADB_SET_SR_OUTPUT();	/* set shift register for OUT */
   1026  1.12   scottr 				ADB_SR() = adbOutputBuffer[1];	/* load byte for output */
   1027  1.12   scottr 				adbBusState = ADB_BUS_CMD;	/* set bus to cmd state */
   1028  1.12   scottr 				ADB_SET_STATE_CMD();	/* tell ADB that we want to */
   1029  1.12   scottr 				break;
   1030   1.5   scottr 			}
   1031   1.5   scottr 		}
   1032   1.5   scottr 		ADB_SR() = adbOutputBuffer[adbSentChars + 1];
   1033   1.5   scottr 		switch (adbBusState) {	/* advance to next state */
   1034   1.5   scottr 		case ADB_BUS_EVEN:
   1035   1.5   scottr 			ADB_SET_STATE_ODD();	/* set state to odd */
   1036   1.5   scottr 			adbBusState = ADB_BUS_ODD;
   1037   1.5   scottr 			break;
   1038   1.5   scottr 
   1039   1.5   scottr 		case ADB_BUS_CMD:
   1040   1.5   scottr 		case ADB_BUS_ODD:
   1041   1.5   scottr 			ADB_SET_STATE_EVEN();	/* set state to even */
   1042   1.5   scottr 			adbBusState = ADB_BUS_EVEN;
   1043   1.5   scottr 			break;
   1044   1.5   scottr 
   1045   1.5   scottr 		default:
   1046  1.16    ender #ifdef ADB_DEBUG
   1047  1.16    ender 			if (adb_debug) {
   1048  1.16    ender 				printf_intr("strange state!!! (0x%x)\n",
   1049  1.16    ender 				    adbBusState);
   1050  1.18   briggs 			}
   1051  1.16    ender #endif
   1052   1.5   scottr 			break;
   1053   1.5   scottr 		}
   1054   1.5   scottr 		break;
   1055   1.5   scottr 
   1056   1.5   scottr 	default:
   1057  1.16    ender #ifdef ADB_DEBUG
   1058  1.16    ender 		if (adb_debug)
   1059  1.16    ender 			printf_intr("adb: unknown ADB state (during intr)\n");
   1060  1.16    ender #endif
   1061  1.47  thorpej 		break;
   1062   1.5   scottr 	}
   1063   1.5   scottr 
   1064   1.5   scottr 	ADB_VIA_INTR_ENABLE();	/* enable ADB interrupt on IIs. */
   1065   1.1   scottr 
   1066   1.5   scottr 	splx(s);		/* restore */
   1067   1.1   scottr 
   1068   1.5   scottr 	return;
   1069   1.1   scottr 
   1070   1.1   scottr }
   1071   1.1   scottr 
   1072   1.1   scottr 
   1073   1.5   scottr /*
   1074   1.5   scottr  * send_adb version for II series machines
   1075   1.1   scottr  */
   1076   1.1   scottr int
   1077  1.50      chs send_adb_II(u_char *in, u_char *buffer, void *compRout, void *data, int command)
   1078   1.1   scottr {
   1079  1.28   scottr 	int s, len;
   1080   1.5   scottr 
   1081   1.5   scottr 	if (adbActionState == ADB_ACTION_NOTREADY)	/* return if ADB not
   1082   1.5   scottr 							 * available */
   1083   1.5   scottr 		return 1;
   1084   1.5   scottr 
   1085  1.12   scottr 	/* Don't interrupt while we are messing with the ADB */
   1086  1.12   scottr 	s = splhigh();
   1087   1.1   scottr 
   1088   1.5   scottr 	if (0 != adbOutQueueHasData) {	/* right now, "has data" means "full" */
   1089   1.5   scottr 		splx(s);	/* sorry, try again later */
   1090   1.5   scottr 		return 1;
   1091   1.5   scottr 	}
   1092  1.12   scottr 	if ((long)in == (long)0) {	/* need to convert? */
   1093   1.5   scottr 		/*
   1094   1.5   scottr 		 * Don't need to use adb_cmd_extra here because this section
   1095   1.5   scottr 		 * will be called ONLY when it is an ADB command (no RTC or
   1096   1.5   scottr 		 * PRAM), especially on II series!
   1097   1.5   scottr 		 */
   1098   1.5   scottr 		if ((command & 0x0c) == 0x08)	/* copy addl data ONLY if
   1099   1.5   scottr 						 * doing a listen! */
   1100   1.5   scottr 			len = buffer[0];	/* length of additional data */
   1101   1.5   scottr 		else
   1102   1.5   scottr 			len = 0;/* no additional data */
   1103   1.1   scottr 
   1104   1.5   scottr 		adbOutQueue.outBuf[0] = 1 + len;	/* command + addl. data */
   1105  1.12   scottr 		adbOutQueue.outBuf[1] = (u_char)command;	/* load command */
   1106   1.1   scottr 
   1107  1.28   scottr 		/* copy additional output data, if any */
   1108  1.28   scottr 		memcpy(adbOutQueue.outBuf + 2, buffer + 1, len);
   1109   1.5   scottr 	} else
   1110   1.5   scottr 		/* if data ready, just copy over */
   1111  1.28   scottr 		memcpy(adbOutQueue.outBuf, in, in[0] + 2);
   1112   1.5   scottr 
   1113   1.5   scottr 	adbOutQueue.saveBuf = buffer;	/* save buffer to know where to save
   1114   1.5   scottr 					 * result */
   1115   1.5   scottr 	adbOutQueue.compRout = compRout;	/* save completion routine
   1116   1.5   scottr 						 * pointer */
   1117   1.5   scottr 	adbOutQueue.data = data;/* save completion routine data pointer */
   1118   1.5   scottr 
   1119   1.5   scottr 	if ((adbActionState == ADB_ACTION_IDLE) &&	/* is ADB available? */
   1120  1.12   scottr 	    (ADB_INTR_IS_OFF)) {	/* and no incoming interrupts? */
   1121   1.5   scottr 		/* then start command now */
   1122  1.28   scottr 		memcpy(adbOutputBuffer, adbOutQueue.outBuf,
   1123  1.28   scottr 		    adbOutQueue.outBuf[0] + 2);		/* copy over data */
   1124   1.5   scottr 
   1125   1.5   scottr 		adbBuffer = adbOutQueue.saveBuf;	/* pointer to user data
   1126   1.5   scottr 							 * area */
   1127   1.5   scottr 		adbCompRout = adbOutQueue.compRout;	/* pointer to the
   1128   1.5   scottr 							 * completion routine */
   1129   1.5   scottr 		adbCompData = adbOutQueue.data;	/* pointer to the completion
   1130   1.5   scottr 						 * routine data */
   1131   1.5   scottr 
   1132   1.5   scottr 		adbSentChars = 0;	/* nothing sent yet */
   1133   1.5   scottr 		adbActionState = ADB_ACTION_OUT;	/* set next state */
   1134   1.5   scottr 		adbBusState = ADB_BUS_CMD;	/* set bus to cmd state */
   1135   1.5   scottr 
   1136   1.5   scottr 		ADB_SET_SR_OUTPUT();	/* set shift register for OUT */
   1137   1.5   scottr 
   1138   1.5   scottr 		ADB_SR() = adbOutputBuffer[adbSentChars + 1];	/* load byte for output */
   1139   1.5   scottr 		ADB_SET_STATE_CMD();	/* tell ADB that we want to send */
   1140   1.5   scottr 		adbOutQueueHasData = 0;	/* currently processing "queue" entry */
   1141   1.5   scottr 	} else
   1142   1.5   scottr 		adbOutQueueHasData = 1;	/* something in the write "queue" */
   1143   1.5   scottr 
   1144   1.5   scottr 	splx(s);
   1145   1.5   scottr 
   1146  1.12   scottr 	if (0x0100 <= (s & 0x0700))	/* were VIA1 interrupts blocked? */
   1147   1.5   scottr 		/* poll until message done */
   1148   1.5   scottr 		while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
   1149  1.12   scottr 		    || (adbWaiting == 1))
   1150  1.12   scottr 			if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
   1151  1.33   scottr 				adb_intr_II(NULL); /* go process it */
   1152  1.33   scottr 				if (adb_polling)
   1153  1.26   scottr 					adb_soft_intr();
   1154   1.8   scottr 			}
   1155   1.1   scottr 
   1156   1.5   scottr 	return 0;
   1157   1.1   scottr }
   1158   1.1   scottr 
   1159   1.1   scottr 
   1160   1.1   scottr /*
   1161   1.1   scottr  * This routine is called from the II series interrupt routine
   1162   1.1   scottr  * to determine what the "next" device is that should be polled.
   1163   1.1   scottr  */
   1164   1.1   scottr int
   1165   1.1   scottr adb_guess_next_device(void)
   1166   1.1   scottr {
   1167   1.5   scottr 	int last, i, dummy;
   1168   1.1   scottr 
   1169   1.1   scottr 	if (adbStarting) {
   1170  1.12   scottr 		/*
   1171  1.12   scottr 		 * Start polling EVERY device, since we can't be sure there is
   1172  1.12   scottr 		 * anything in the device table yet
   1173  1.12   scottr 		 */
   1174   1.5   scottr 		if (adbLastDevice < 1 || adbLastDevice > 15)
   1175   1.1   scottr 			adbLastDevice = 1;
   1176   1.5   scottr 		if (++adbLastDevice > 15)	/* point to next one */
   1177   1.1   scottr 			adbLastDevice = 1;
   1178   1.1   scottr 	} else {
   1179   1.1   scottr 		/* find the next device using the device table */
   1180   1.5   scottr 		if (adbLastDevice < 1 || adbLastDevice > 15)	/* let's be parinoid */
   1181   1.1   scottr 			adbLastDevice = 2;
   1182   1.5   scottr 		last = 1;	/* default index location */
   1183   1.5   scottr 
   1184   1.1   scottr 		for (i = 1; i < 16; i++)	/* find index entry */
   1185   1.5   scottr 			if (ADBDevTable[i].currentAddr == adbLastDevice) {	/* look for device */
   1186   1.5   scottr 				last = i;	/* found it */
   1187   1.1   scottr 				break;
   1188   1.1   scottr 			}
   1189   1.5   scottr 		dummy = last;	/* index to start at */
   1190   1.5   scottr 		for (;;) {	/* find next device in index */
   1191   1.5   scottr 			if (++dummy > 15)	/* wrap around if needed */
   1192   1.1   scottr 				dummy = 1;
   1193   1.5   scottr 			if (dummy == last) {	/* didn't find any other
   1194   1.5   scottr 						 * device! This can happen if
   1195   1.5   scottr 						 * there are no devices on the
   1196   1.5   scottr 						 * bus */
   1197  1.34   scottr 				dummy = 1;
   1198   1.1   scottr 				break;
   1199   1.1   scottr 			}
   1200   1.1   scottr 			/* found the next device */
   1201   1.5   scottr 			if (ADBDevTable[dummy].devType != 0)
   1202   1.1   scottr 				break;
   1203   1.1   scottr 		}
   1204   1.5   scottr 		adbLastDevice = ADBDevTable[dummy].currentAddr;
   1205   1.1   scottr 	}
   1206   1.1   scottr 	return adbLastDevice;
   1207   1.1   scottr }
   1208   1.8   scottr 
   1209   1.8   scottr 
   1210   1.5   scottr /*
   1211  1.72   andvar  * Called when an adb interrupt happens.
   1212   1.1   scottr  * This routine simply transfers control over to the appropriate
   1213   1.1   scottr  * code for the machine we are running on.
   1214   1.1   scottr  */
   1215   1.5   scottr void
   1216  1.24   briggs adb_intr(void *arg)
   1217   1.1   scottr {
   1218   1.5   scottr 	switch (adbHardware) {
   1219   1.8   scottr 	case ADB_HW_II:
   1220  1.24   briggs 		adb_intr_II(arg);
   1221   1.5   scottr 		break;
   1222   1.1   scottr 
   1223   1.5   scottr 	case ADB_HW_IISI:
   1224  1.24   briggs 		adb_intr_IIsi(arg);
   1225   1.5   scottr 		break;
   1226   1.5   scottr 
   1227  1.24   briggs 	case ADB_HW_PB:		/* Should not come through here. */
   1228   1.5   scottr 		break;
   1229   1.1   scottr 
   1230   1.1   scottr 	case ADB_HW_CUDA:
   1231  1.24   briggs 		adb_intr_cuda(arg);
   1232  1.24   briggs 		break;
   1233  1.24   briggs 
   1234  1.24   briggs 	case ADB_HW_IOP:	/* Should not come through here. */
   1235   1.1   scottr 		break;
   1236   1.5   scottr 
   1237   1.5   scottr 	case ADB_HW_UNKNOWN:
   1238   1.5   scottr 		break;
   1239   1.5   scottr 	}
   1240   1.1   scottr }
   1241   1.1   scottr 
   1242   1.1   scottr 
   1243   1.5   scottr /*
   1244  1.72   andvar  * called when an adb interrupt happens
   1245   1.1   scottr  *
   1246   1.1   scottr  * IIsi version of adb_intr
   1247   1.1   scottr  *
   1248   1.1   scottr  */
   1249   1.5   scottr void
   1250  1.24   briggs adb_intr_IIsi(void *arg)
   1251   1.1   scottr {
   1252   1.8   scottr 	struct adbCommand packet;
   1253  1.64   martin 	int ending;
   1254   1.5   scottr 	unsigned int s;
   1255   1.1   scottr 
   1256   1.5   scottr 	s = splhigh();		/* can't be too careful - might be called */
   1257   1.5   scottr 	/* from a routine, NOT an interrupt */
   1258   1.1   scottr 
   1259   1.5   scottr 	ADB_VIA_CLR_INTR();	/* clear interrupt */
   1260   1.1   scottr 
   1261   1.5   scottr 	ADB_VIA_INTR_DISABLE();	/* disable ADB interrupt on IIs. */
   1262   1.1   scottr 
   1263   1.1   scottr switch_start:
   1264   1.5   scottr 	switch (adbActionState) {
   1265   1.5   scottr 	case ADB_ACTION_IDLE:
   1266   1.5   scottr 		delay(ADB_DELAY);	/* short delay is required before the
   1267   1.5   scottr 					 * first byte */
   1268   1.5   scottr 
   1269   1.5   scottr 		ADB_SET_SR_INPUT();	/* make sure SR is set to IN */
   1270   1.5   scottr 		ADB_SET_STATE_ACTIVE();	/* signal start of data frame */
   1271   1.5   scottr 		adbInputBuffer[1] = ADB_SR();	/* get byte */
   1272   1.5   scottr 		adbInputBuffer[0] = 1;
   1273   1.5   scottr 		adbActionState = ADB_ACTION_IN;	/* set next state */
   1274   1.5   scottr 
   1275   1.5   scottr 		ADB_SET_STATE_ACKON();	/* start ACK to ADB chip */
   1276   1.5   scottr 		delay(ADB_DELAY);	/* delay */
   1277   1.5   scottr 		ADB_SET_STATE_ACKOFF();	/* end ACK to ADB chip */
   1278  1.71  thorpej 		adb_process_serial_intrs();
   1279   1.5   scottr 		break;
   1280   1.5   scottr 
   1281   1.5   scottr 	case ADB_ACTION_IN:
   1282   1.5   scottr 		ADB_SET_SR_INPUT();	/* make sure SR is set to IN */
   1283   1.5   scottr 		adbInputBuffer[++adbInputBuffer[0]] = ADB_SR();	/* get byte */
   1284   1.5   scottr 		if (ADB_INTR_IS_OFF)	/* check for end of frame */
   1285   1.5   scottr 			ending = 1;
   1286   1.5   scottr 		else
   1287   1.5   scottr 			ending = 0;
   1288   1.5   scottr 
   1289   1.5   scottr 		ADB_SET_STATE_ACKON();	/* start ACK to ADB chip */
   1290   1.5   scottr 		delay(ADB_DELAY);	/* delay */
   1291   1.5   scottr 		ADB_SET_STATE_ACKOFF();	/* end ACK to ADB chip */
   1292  1.71  thorpej 		adb_process_serial_intrs();
   1293   1.5   scottr 
   1294   1.5   scottr 		if (1 == ending) {	/* end of message? */
   1295   1.5   scottr 			ADB_SET_STATE_INACTIVE();	/* signal end of frame */
   1296  1.12   scottr 			/*
   1297  1.12   scottr 			 * This section _should_ handle all ADB and RTC/PRAM
   1298  1.12   scottr 			 * type commands, but there may be more...  Note:
   1299  1.12   scottr 			 * commands are always at [4], even for rtc/pram
   1300  1.12   scottr 			 * commands
   1301  1.12   scottr 			 */
   1302   1.8   scottr 			/* set up data for adb_pass_up */
   1303  1.28   scottr 			memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
   1304   1.8   scottr 
   1305   1.5   scottr 			if ((adbWaiting == 1) &&	/* are we waiting AND */
   1306   1.5   scottr 			    (adbInputBuffer[4] == adbWaitingCmd) &&	/* the cmd we sent AND */
   1307   1.5   scottr 			    ((adbInputBuffer[2] == 0x00) ||	/* it's from the ADB
   1308   1.5   scottr 								 * device OR */
   1309   1.5   scottr 				(adbInputBuffer[2] == 0x01))) {	/* it's from the
   1310   1.5   scottr 								 * PRAM/RTC device */
   1311   1.5   scottr 
   1312  1.12   scottr 				packet.saveBuf = adbBuffer;
   1313  1.12   scottr 				packet.compRout = adbCompRout;
   1314  1.12   scottr 				packet.compData = adbCompData;
   1315  1.12   scottr 				packet.unsol = 0;
   1316  1.12   scottr 				packet.ack_only = 0;
   1317   1.8   scottr 				adb_pass_up(&packet);
   1318   1.5   scottr 
   1319   1.5   scottr 				adbWaitingCmd = 0;	/* reset "waiting" vars */
   1320   1.5   scottr 				adbWaiting = 0;
   1321  1.12   scottr 				adbBuffer = (long)0;
   1322  1.12   scottr 				adbCompRout = (long)0;
   1323  1.12   scottr 				adbCompData = (long)0;
   1324   1.5   scottr 			} else {
   1325  1.12   scottr 				packet.unsol = 1;
   1326  1.12   scottr 				packet.ack_only = 0;
   1327   1.8   scottr 				adb_pass_up(&packet);
   1328   1.5   scottr 			}
   1329   1.5   scottr 
   1330   1.5   scottr 			adbActionState = ADB_ACTION_IDLE;
   1331   1.5   scottr 			adbInputBuffer[0] = 0;	/* reset length */
   1332   1.5   scottr 
   1333   1.5   scottr 			if (adbWriteDelay == 1) {	/* were we waiting to
   1334   1.5   scottr 							 * write? */
   1335   1.5   scottr 				adbSentChars = 0;	/* nothing sent yet */
   1336   1.5   scottr 				adbActionState = ADB_ACTION_OUT;	/* set next state */
   1337   1.5   scottr 
   1338   1.5   scottr 				delay(ADB_DELAY);	/* delay */
   1339  1.71  thorpej 				adb_process_serial_intrs();
   1340   1.5   scottr 
   1341   1.5   scottr 				if (ADB_INTR_IS_ON) {	/* ADB intr low during
   1342   1.5   scottr 							 * write */
   1343   1.5   scottr 					ADB_SET_STATE_IDLE_IISI();	/* reset */
   1344   1.5   scottr 					ADB_SET_SR_INPUT();	/* make sure SR is set
   1345   1.5   scottr 								 * to IN */
   1346   1.5   scottr 					adbSentChars = 0;	/* must start all over */
   1347   1.5   scottr 					adbActionState = ADB_ACTION_IDLE;	/* new state */
   1348   1.5   scottr 					adbInputBuffer[0] = 0;
   1349   1.5   scottr 					/* may be able to take this out later */
   1350   1.5   scottr 					delay(ADB_DELAY);	/* delay */
   1351   1.5   scottr 					break;
   1352   1.5   scottr 				}
   1353   1.5   scottr 				ADB_SET_STATE_ACTIVE();	/* tell ADB that we want
   1354   1.5   scottr 							 * to send */
   1355   1.5   scottr 				ADB_SET_STATE_ACKOFF();	/* make sure */
   1356   1.5   scottr 				ADB_SET_SR_OUTPUT();	/* set shift register
   1357   1.5   scottr 							 * for OUT */
   1358   1.5   scottr 				ADB_SR() = adbOutputBuffer[adbSentChars + 1];
   1359   1.5   scottr 				ADB_SET_STATE_ACKON();	/* tell ADB byte ready
   1360   1.5   scottr 							 * to shift */
   1361   1.5   scottr 			}
   1362   1.5   scottr 		}
   1363   1.5   scottr 		break;
   1364   1.5   scottr 
   1365   1.5   scottr 	case ADB_ACTION_OUT:
   1366  1.64   martin 		(void)ADB_SR();	/* reset SR-intr in IFR */
   1367   1.5   scottr 		ADB_SET_SR_OUTPUT();	/* set shift register for OUT */
   1368   1.5   scottr 
   1369   1.5   scottr 		ADB_SET_STATE_ACKOFF();	/* finish ACK */
   1370   1.5   scottr 		adbSentChars++;
   1371   1.5   scottr 		if (ADB_INTR_IS_ON) {	/* ADB intr low during write */
   1372   1.5   scottr 			ADB_SET_STATE_IDLE_IISI();	/* reset */
   1373   1.5   scottr 			ADB_SET_SR_INPUT();	/* make sure SR is set to IN */
   1374   1.5   scottr 			adbSentChars = 0;	/* must start all over */
   1375   1.5   scottr 			adbActionState = ADB_ACTION_IDLE;	/* new state */
   1376   1.5   scottr 			adbInputBuffer[0] = 0;
   1377   1.5   scottr 			adbWriteDelay = 1;	/* must retry when done with
   1378   1.5   scottr 						 * read */
   1379   1.5   scottr 			delay(ADB_DELAY);	/* delay */
   1380  1.71  thorpej 			adb_process_serial_intrs();
   1381   1.5   scottr 			goto switch_start;	/* process next state right
   1382   1.5   scottr 						 * now */
   1383   1.5   scottr 			break;
   1384   1.5   scottr 		}
   1385   1.5   scottr 		delay(ADB_DELAY);	/* required delay */
   1386  1.71  thorpej 		adb_process_serial_intrs();
   1387   1.5   scottr 
   1388   1.5   scottr 		if (adbOutputBuffer[0] == adbSentChars) {	/* check for done */
   1389   1.5   scottr 			if (0 == adb_cmd_result(adbOutputBuffer)) {	/* do we expect data
   1390   1.5   scottr 									 * back? */
   1391   1.5   scottr 				adbWaiting = 1;	/* signal waiting for return */
   1392   1.5   scottr 				adbWaitingCmd = adbOutputBuffer[2];	/* save waiting command */
   1393   1.5   scottr 			} else {/* no talk, so done */
   1394   1.8   scottr 				/* set up stuff for adb_pass_up */
   1395  1.28   scottr 				memcpy(packet.data, adbInputBuffer,
   1396  1.28   scottr 				    adbInputBuffer[0] + 1);
   1397  1.12   scottr 				packet.saveBuf = adbBuffer;
   1398  1.12   scottr 				packet.compRout = adbCompRout;
   1399  1.12   scottr 				packet.compData = adbCompData;
   1400  1.12   scottr 				packet.cmd = adbWaitingCmd;
   1401  1.12   scottr 				packet.unsol = 0;
   1402  1.12   scottr 				packet.ack_only = 1;
   1403   1.8   scottr 				adb_pass_up(&packet);
   1404   1.8   scottr 
   1405   1.8   scottr 				/* reset "waiting" vars, just in case */
   1406   1.8   scottr 				adbWaitingCmd = 0;
   1407  1.12   scottr 				adbBuffer = (long)0;
   1408  1.12   scottr 				adbCompRout = (long)0;
   1409  1.12   scottr 				adbCompData = (long)0;
   1410   1.5   scottr 			}
   1411   1.5   scottr 
   1412   1.5   scottr 			adbWriteDelay = 0;	/* done writing */
   1413   1.5   scottr 			adbActionState = ADB_ACTION_IDLE;	/* signal bus is idle */
   1414   1.5   scottr 			ADB_SET_SR_INPUT();	/* make sure SR is set to IN */
   1415   1.5   scottr 			ADB_SET_STATE_INACTIVE();	/* end of frame */
   1416   1.5   scottr 		} else {
   1417   1.5   scottr 			ADB_SR() = adbOutputBuffer[adbSentChars + 1];	/* send next byte */
   1418   1.5   scottr 			ADB_SET_STATE_ACKON();	/* signal byte ready to shift */
   1419   1.5   scottr 		}
   1420   1.5   scottr 		break;
   1421   1.1   scottr 
   1422   1.5   scottr 	case ADB_ACTION_NOTREADY:
   1423  1.16    ender #ifdef ADB_DEBUG
   1424  1.16    ender 		if (adb_debug)
   1425  1.16    ender 			printf_intr("adb: not yet initialized\n");
   1426  1.16    ender #endif
   1427   1.5   scottr 		break;
   1428   1.5   scottr 
   1429   1.5   scottr 	default:
   1430  1.16    ender #ifdef ADB_DEBUG
   1431  1.16    ender 		if (adb_debug)
   1432  1.16    ender 			printf_intr("intr: unknown ADB state\n");
   1433  1.16    ender #endif
   1434  1.47  thorpej 		break;
   1435   1.5   scottr 	}
   1436   1.5   scottr 
   1437   1.5   scottr 	ADB_VIA_INTR_ENABLE();	/* enable ADB interrupt on IIs. */
   1438   1.1   scottr 
   1439   1.5   scottr 	splx(s);		/* restore */
   1440   1.1   scottr 
   1441   1.5   scottr 	return;
   1442   1.5   scottr }				/* end adb_intr_IIsi */
   1443   1.1   scottr 
   1444   1.1   scottr 
   1445   1.1   scottr /*****************************************************************************
   1446   1.1   scottr  * if the device is currently busy, and there is no data waiting to go out, then
   1447   1.1   scottr  * the data is "queued" in the outgoing buffer. If we are already waiting, then
   1448   1.1   scottr  * we return.
   1449  1.12   scottr  * in: if (in == 0) then the command string is built from command and buffer
   1450  1.12   scottr  *     if (in != 0) then in is used as the command string
   1451  1.12   scottr  * buffer: additional data to be sent (used only if in == 0)
   1452   1.1   scottr  *         this is also where return data is stored
   1453   1.5   scottr  * compRout: the completion routine that is called when then return value
   1454   1.1   scottr  *	     is received (if a return value is expected)
   1455   1.1   scottr  * data: a data pointer that can be used by the completion routine
   1456  1.12   scottr  * command: an ADB command to be sent (used only if in == 0)
   1457   1.5   scottr  *
   1458   1.1   scottr  */
   1459   1.5   scottr int
   1460  1.50      chs send_adb_IIsi(u_char *in, u_char *buffer, void *compRout, void *data, int
   1461   1.5   scottr 	command)
   1462   1.1   scottr {
   1463  1.28   scottr 	int s, len;
   1464   1.1   scottr 
   1465   1.5   scottr 	if (adbActionState == ADB_ACTION_NOTREADY)
   1466   1.5   scottr 		return 1;
   1467   1.1   scottr 
   1468  1.12   scottr 	/* Don't interrupt while we are messing with the ADB */
   1469  1.12   scottr 	s = splhigh();
   1470   1.5   scottr 
   1471   1.5   scottr 	if ((adbActionState == ADB_ACTION_IDLE) &&	/* ADB available? */
   1472   1.5   scottr 	    (ADB_INTR_IS_OFF)) {/* and no incoming interrupt? */
   1473   1.5   scottr 
   1474   1.5   scottr 	} else
   1475   1.5   scottr 		if (adbWriteDelay == 0)	/* it's busy, but is anything waiting? */
   1476   1.5   scottr 			adbWriteDelay = 1;	/* if no, then we'll "queue"
   1477   1.5   scottr 						 * it up */
   1478   1.5   scottr 		else {
   1479   1.5   scottr 			splx(s);
   1480   1.5   scottr 			return 1;	/* really busy! */
   1481   1.5   scottr 		}
   1482   1.1   scottr 
   1483  1.12   scottr 	if ((long)in == (long)0) {	/* need to convert? */
   1484  1.12   scottr 		/*
   1485  1.12   scottr 		 * Don't need to use adb_cmd_extra here because this section
   1486  1.12   scottr 		 * will be called ONLY when it is an ADB command (no RTC or
   1487  1.12   scottr 		 * PRAM)
   1488  1.12   scottr 		 */
   1489   1.5   scottr 		if ((command & 0x0c) == 0x08)	/* copy addl data ONLY if
   1490   1.5   scottr 						 * doing a listen! */
   1491   1.5   scottr 			len = buffer[0];	/* length of additional data */
   1492   1.5   scottr 		else
   1493   1.5   scottr 			len = 0;/* no additional data */
   1494   1.1   scottr 
   1495   1.5   scottr 		adbOutputBuffer[0] = 2 + len;	/* dev. type + command + addl.
   1496   1.5   scottr 						 * data */
   1497   1.5   scottr 		adbOutputBuffer[1] = 0x00;	/* mark as an ADB command */
   1498  1.12   scottr 		adbOutputBuffer[2] = (u_char)command;	/* load command */
   1499   1.1   scottr 
   1500  1.28   scottr 		/* copy additional output data, if any */
   1501  1.28   scottr 		memcpy(adbOutputBuffer + 3, buffer + 1, len);
   1502   1.5   scottr 	} else
   1503  1.28   scottr 		/* if data ready, just copy over */
   1504  1.28   scottr 		memcpy(adbOutputBuffer, in, in[0] + 2);
   1505   1.1   scottr 
   1506   1.5   scottr 	adbSentChars = 0;	/* nothing sent yet */
   1507   1.5   scottr 	adbBuffer = buffer;	/* save buffer to know where to save result */
   1508   1.5   scottr 	adbCompRout = compRout;	/* save completion routine pointer */
   1509   1.5   scottr 	adbCompData = data;	/* save completion routine data pointer */
   1510   1.5   scottr 	adbWaitingCmd = adbOutputBuffer[2];	/* save wait command */
   1511   1.1   scottr 
   1512   1.5   scottr 	if (adbWriteDelay != 1) {	/* start command now? */
   1513   1.5   scottr 		adbActionState = ADB_ACTION_OUT;	/* set next state */
   1514   1.1   scottr 
   1515   1.5   scottr 		ADB_SET_STATE_ACTIVE();	/* tell ADB that we want to send */
   1516   1.5   scottr 		ADB_SET_STATE_ACKOFF();	/* make sure */
   1517   1.1   scottr 
   1518   1.5   scottr 		ADB_SET_SR_OUTPUT();	/* set shift register for OUT */
   1519   1.1   scottr 
   1520   1.5   scottr 		ADB_SR() = adbOutputBuffer[adbSentChars + 1];	/* load byte for output */
   1521   1.1   scottr 
   1522   1.5   scottr 		ADB_SET_STATE_ACKON();	/* tell ADB byte ready to shift */
   1523   1.5   scottr 	}
   1524   1.5   scottr 	adbWriteDelay = 1;	/* something in the write "queue" */
   1525   1.1   scottr 
   1526   1.5   scottr 	splx(s);
   1527   1.1   scottr 
   1528  1.33   scottr 	if (0x0100 <= (s & 0x0700))	/* were VIA1 interrupts blocked? */
   1529   1.5   scottr 		/* poll until byte done */
   1530   1.5   scottr 		while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
   1531   1.5   scottr 		    || (adbWaiting == 1))
   1532  1.33   scottr 			if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
   1533  1.33   scottr 				adb_intr_IIsi(NULL); /* go process it */
   1534  1.33   scottr 				if (adb_polling)
   1535  1.26   scottr 					adb_soft_intr();
   1536   1.8   scottr 			}
   1537   1.1   scottr 
   1538   1.8   scottr 	 return 0;
   1539   1.5   scottr }				/* send_adb_IIsi */
   1540   1.1   scottr 
   1541  1.24   briggs void
   1542  1.24   briggs adb_iop_recv(IOP *iop, struct iop_msg *msg)
   1543  1.24   briggs {
   1544  1.24   briggs 	struct adbCommand	pkt;
   1545  1.24   briggs 	unsigned		flags;
   1546  1.24   briggs 
   1547  1.24   briggs 	if (adbActionState != ADB_ACTION_RUNNING)
   1548  1.24   briggs 		return;
   1549  1.24   briggs 
   1550  1.24   briggs 	switch (msg->status) {
   1551  1.24   briggs 	case IOP_MSGSTAT_SENT:
   1552  1.24   briggs 		if (0 == adb_cmd_result(msg->msg + 1)) {
   1553  1.24   briggs 			adbWaiting = 1;
   1554  1.24   briggs 			adbWaitingCmd = msg->msg[2];
   1555  1.24   briggs 		}
   1556  1.24   briggs 		break;
   1557  1.24   briggs 	case IOP_MSGSTAT_RECEIVED:
   1558  1.24   briggs 	case IOP_MSGSTAT_UNEXPECTED:
   1559  1.24   briggs 		flags = msg->msg[0];
   1560  1.24   briggs 		if (flags != 0) {
   1561  1.24   briggs 			printf("ADB FLAGS 0x%x", flags);
   1562  1.24   briggs 			break;
   1563  1.24   briggs 		}
   1564  1.24   briggs 		if (adbWaiting &&
   1565  1.24   briggs 		    (msg->msg[2] == adbWaitingCmd)) {
   1566  1.24   briggs 			pkt.saveBuf = msg->msg + 1;
   1567  1.24   briggs 			pkt.compRout = adbCompRout;
   1568  1.24   briggs 			pkt.compData = adbCompData;
   1569  1.24   briggs 			pkt.unsol = 0;
   1570  1.24   briggs 			pkt.ack_only = 0;
   1571  1.24   briggs 			adb_pass_up(&pkt);
   1572  1.24   briggs 
   1573  1.24   briggs 			adbWaitingCmd = 0;
   1574  1.24   briggs 			adbWaiting = 0;
   1575  1.24   briggs 		} else {
   1576  1.24   briggs 			pkt.unsol = 1;
   1577  1.24   briggs 			pkt.ack_only = 0;
   1578  1.24   briggs 			adb_pass_up(&pkt);
   1579  1.24   briggs 		}
   1580  1.24   briggs 		break;
   1581  1.24   briggs 	default:
   1582  1.24   briggs 		return;
   1583  1.24   briggs 	}
   1584  1.24   briggs }
   1585  1.24   briggs 
   1586  1.24   briggs int
   1587  1.24   briggs send_adb_iop(int cmd, u_char * buffer, void *compRout, void *data)
   1588  1.24   briggs {
   1589  1.24   briggs 	u_char	buff[32];
   1590  1.32   scottr 	int	cnt;
   1591  1.24   briggs 
   1592  1.24   briggs 	if (adbActionState != ADB_ACTION_RUNNING)
   1593  1.24   briggs 		return -1;
   1594  1.24   briggs 
   1595  1.24   briggs 	buff[0] = IOP_ADB_FL_EXPLICIT;
   1596  1.24   briggs 	buff[1] = buffer[0];
   1597  1.24   briggs 	buff[2] = cmd;
   1598  1.24   briggs 	cnt = (int) buff[1];
   1599  1.31   scottr 	memcpy(buff + 3, buffer + 1, cnt);
   1600  1.24   briggs 	return iop_send_msg(ISM_IOP, IOP_CHAN_ADB, buff, cnt+3,
   1601  1.24   briggs 			    adb_iop_recv, NULL);
   1602  1.24   briggs }
   1603   1.1   scottr 
   1604   1.8   scottr /*
   1605   1.8   scottr  * adb_pass_up is called by the interrupt-time routines.
   1606   1.8   scottr  * It takes the raw packet data that was received from the
   1607   1.8   scottr  * device and puts it into the queue that the upper half
   1608   1.8   scottr  * processes. It then signals for a soft ADB interrupt which
   1609   1.8   scottr  * will eventually call the upper half routine (adb_soft_intr).
   1610   1.8   scottr  *
   1611   1.8   scottr  * If in->unsol is 0, then this is either the notification
   1612   1.8   scottr  * that the packet was sent (on a LISTEN, for example), or the
   1613   1.8   scottr  * response from the device (on a TALK). The completion routine
   1614   1.8   scottr  * is called only if the user specified one.
   1615   1.8   scottr  *
   1616   1.8   scottr  * If in->unsol is 1, then this packet was unsolicited and
   1617   1.8   scottr  * so we look up the device in the ADB device table to determine
   1618  1.67      snj  * what its default service routine is.
   1619   1.8   scottr  *
   1620   1.8   scottr  * If in->ack_only is 1, then we really only need to call
   1621   1.8   scottr  * the completion routine, so don't do any other stuff.
   1622   1.8   scottr  *
   1623   1.8   scottr  * Note that in->data contains the packet header AND data,
   1624   1.8   scottr  * while adbInbound[]->data contains ONLY data.
   1625   1.8   scottr  *
   1626   1.8   scottr  * Note: Called only at interrupt time. Assumes this.
   1627   1.1   scottr  */
   1628   1.5   scottr void
   1629   1.8   scottr adb_pass_up(struct adbCommand *in)
   1630   1.1   scottr {
   1631  1.28   scottr 	int start = 0, len = 0, cmd = 0;
   1632   1.8   scottr 	ADBDataBlock block;
   1633   1.8   scottr 
   1634   1.8   scottr 	/* temp for testing */
   1635   1.8   scottr 	/*u_char *buffer = 0;*/
   1636   1.8   scottr 	/*u_char *compdata = 0;*/
   1637   1.8   scottr 	/*u_char *comprout = 0;*/
   1638   1.8   scottr 
   1639  1.12   scottr 	if (adbInCount >= ADB_QUEUE) {
   1640  1.16    ender #ifdef ADB_DEBUG
   1641  1.16    ender 		if (adb_debug)
   1642  1.16    ender 			printf_intr("adb: ring buffer overflow\n");
   1643  1.16    ender #endif
   1644   1.8   scottr 		return;
   1645   1.8   scottr 	}
   1646   1.8   scottr 
   1647   1.8   scottr 	if (in->ack_only) {
   1648  1.12   scottr 		len = in->data[0];
   1649  1.12   scottr 		cmd = in->cmd;
   1650  1.12   scottr 		start = 0;
   1651   1.8   scottr 	} else {
   1652   1.8   scottr 		switch (adbHardware) {
   1653  1.24   briggs 		case ADB_HW_IOP:
   1654   1.8   scottr 		case ADB_HW_II:
   1655   1.8   scottr 			cmd = in->data[1];
   1656   1.8   scottr 			if (in->data[0] < 2)
   1657  1.12   scottr 				len = 0;
   1658   1.8   scottr 			else
   1659  1.12   scottr 				len = in->data[0]-1;
   1660  1.12   scottr 			start = 1;
   1661   1.8   scottr 			break;
   1662   1.8   scottr 
   1663   1.8   scottr 		case ADB_HW_IISI:
   1664   1.8   scottr 		case ADB_HW_CUDA:
   1665   1.8   scottr 			/* If it's unsolicited, accept only ADB data for now */
   1666   1.8   scottr 			if (in->unsol)
   1667   1.8   scottr 				if (0 != in->data[2])
   1668   1.8   scottr 					return;
   1669   1.8   scottr 			cmd = in->data[4];
   1670   1.8   scottr 			if (in->data[0] < 5)
   1671  1.12   scottr 				len = 0;
   1672   1.8   scottr 			else
   1673  1.12   scottr 				len = in->data[0]-4;
   1674  1.12   scottr 			start = 4;
   1675   1.8   scottr 			break;
   1676   1.8   scottr 
   1677   1.8   scottr 		case ADB_HW_PB:
   1678  1.14   scottr 			cmd = in->data[1];
   1679  1.14   scottr 			if (in->data[0] < 2)
   1680  1.14   scottr 				len = 0;
   1681  1.14   scottr 			else
   1682  1.14   scottr 				len = in->data[0]-1;
   1683  1.14   scottr 			start = 1;
   1684  1.14   scottr 			break;
   1685   1.8   scottr 
   1686   1.8   scottr 		case ADB_HW_UNKNOWN:
   1687   1.8   scottr 			return;
   1688   1.8   scottr 		}
   1689   1.8   scottr 
   1690   1.8   scottr 		/* Make sure there is a valid device entry for this device */
   1691   1.8   scottr 		if (in->unsol) {
   1692   1.8   scottr 			/* ignore unsolicited data during adbreinit */
   1693   1.8   scottr 			if (adbStarting)
   1694   1.8   scottr 				return;
   1695   1.8   scottr 			/* get device's comp. routine and data area */
   1696  1.41   scottr 			if (-1 == get_adb_info(&block, ADB_CMDADDR(cmd)))
   1697   1.8   scottr 				return;
   1698   1.5   scottr 		}
   1699   1.8   scottr 	}
   1700   1.8   scottr 
   1701   1.8   scottr 	/*
   1702   1.8   scottr  	 * If this is an unsolicited packet, we need to fill in
   1703   1.8   scottr  	 * some info so adb_soft_intr can process this packet
   1704   1.8   scottr  	 * properly. If it's not unsolicited, then use what
   1705   1.8   scottr  	 * the caller sent us.
   1706   1.8   scottr  	 */
   1707   1.8   scottr 	if (in->unsol) {
   1708  1.65   martin 		if (in->ack_only) panic("invalid ack-only pkg");
   1709  1.65   martin 
   1710  1.12   scottr 		adbInbound[adbInTail].compRout = (void *)block.dbServiceRtPtr;
   1711  1.12   scottr 		adbInbound[adbInTail].compData = (void *)block.dbDataAreaAddr;
   1712  1.12   scottr 		adbInbound[adbInTail].saveBuf = (void *)adbInbound[adbInTail].data;
   1713   1.8   scottr 	} else {
   1714  1.12   scottr 		adbInbound[adbInTail].compRout = (void *)in->compRout;
   1715  1.12   scottr 		adbInbound[adbInTail].compData = (void *)in->compData;
   1716  1.12   scottr 		adbInbound[adbInTail].saveBuf = (void *)in->saveBuf;
   1717   1.8   scottr 	}
   1718   1.8   scottr 
   1719  1.11   scottr #ifdef ADB_DEBUG
   1720  1.11   scottr 	if (adb_debug && in->data[1] == 2)
   1721   1.8   scottr 		printf_intr("adb: caught error\n");
   1722   1.5   scottr #endif
   1723   1.8   scottr 
   1724   1.8   scottr 	/* copy the packet data over */
   1725  1.12   scottr 	/*
   1726  1.12   scottr 	 * TO DO: If the *_intr routines fed their incoming data
   1727   1.8   scottr 	 * directly into an adbCommand struct, which is passed to
   1728   1.8   scottr 	 * this routine, then we could eliminate this copy.
   1729   1.8   scottr 	 */
   1730  1.28   scottr 	memcpy(adbInbound[adbInTail].data + 1, in->data + start + 1, len);
   1731  1.12   scottr 	adbInbound[adbInTail].data[0] = len;
   1732  1.12   scottr 	adbInbound[adbInTail].cmd = cmd;
   1733   1.8   scottr 
   1734   1.8   scottr 	adbInCount++;
   1735   1.8   scottr 	if (++adbInTail >= ADB_QUEUE)
   1736  1.12   scottr 		adbInTail = 0;
   1737   1.8   scottr 
   1738  1.10   scottr 	/*
   1739  1.10   scottr 	 * If the debugger is running, call upper half manually.
   1740  1.10   scottr 	 * Otherwise, trigger a soft interrupt to handle the rest later.
   1741  1.10   scottr 	 */
   1742  1.29   scottr 	if (adb_polling)
   1743  1.10   scottr 		adb_soft_intr();
   1744  1.10   scottr 	else
   1745  1.60       ad 		softint_schedule(adb_softintr_cookie);
   1746   1.8   scottr 
   1747   1.8   scottr 	return;
   1748   1.1   scottr }
   1749   1.5   scottr 
   1750   1.1   scottr 
   1751   1.1   scottr /*
   1752   1.8   scottr  * Called to process the packets after they have been
   1753   1.8   scottr  * placed in the incoming queue.
   1754   1.5   scottr  *
   1755   1.1   scottr  */
   1756   1.5   scottr void
   1757   1.8   scottr adb_soft_intr(void)
   1758   1.1   scottr {
   1759  1.28   scottr 	int s;
   1760  1.12   scottr 	int cmd = 0;
   1761  1.12   scottr 	u_char *buffer = 0;
   1762  1.12   scottr 	u_char *comprout = 0;
   1763  1.12   scottr 	u_char *compdata = 0;
   1764   1.8   scottr 
   1765   1.8   scottr #if 0
   1766  1.12   scottr 	s = splhigh();
   1767   1.8   scottr 	printf_intr("sr: %x\n", (s & 0x0700));
   1768   1.8   scottr 	splx(s);
   1769   1.8   scottr #endif
   1770   1.5   scottr 
   1771   1.8   scottr /*delay(2*ADB_DELAY);*/
   1772   1.5   scottr 
   1773   1.8   scottr 	while (adbInCount) {
   1774  1.12   scottr #ifdef ADB_DEBUG
   1775  1.12   scottr 		if (adb_debug & 0x80)
   1776  1.12   scottr 			printf_intr("%x %x %x ",
   1777  1.12   scottr 			    adbInCount, adbInHead, adbInTail);
   1778  1.12   scottr #endif
   1779   1.8   scottr 		/* get the data we need from the queue */
   1780  1.12   scottr 		buffer = adbInbound[adbInHead].saveBuf;
   1781  1.12   scottr 		comprout = adbInbound[adbInHead].compRout;
   1782  1.12   scottr 		compdata = adbInbound[adbInHead].compData;
   1783  1.12   scottr 		cmd = adbInbound[adbInHead].cmd;
   1784   1.8   scottr 
   1785   1.8   scottr 		/* copy over data to data area if it's valid */
   1786  1.12   scottr 		/*
   1787  1.12   scottr 		 * Note that for unsol packets we don't want to copy the
   1788  1.12   scottr 	 	 * data anywhere, so buffer was already set to 0.
   1789  1.12   scottr 	 	 * For ack_only buffer was set to 0, so don't copy.
   1790  1.12   scottr 		 */
   1791   1.8   scottr 		if (buffer)
   1792  1.28   scottr 			memcpy(buffer, adbInbound[adbInHead].data,
   1793  1.28   scottr 			    adbInbound[adbInHead].data[0] + 1);
   1794  1.12   scottr 
   1795  1.12   scottr #ifdef ADB_DEBUG
   1796  1.12   scottr 			if (adb_debug & 0x80) {
   1797  1.12   scottr 				printf_intr("%p %p %p %x ",
   1798  1.12   scottr 				    buffer, comprout, compdata, (short)cmd);
   1799  1.12   scottr 				printf_intr("buf: ");
   1800  1.12   scottr 				print_single(adbInbound[adbInHead].data);
   1801  1.12   scottr 			}
   1802  1.12   scottr #endif
   1803   1.5   scottr 
   1804   1.8   scottr 		/* call default completion routine if it's valid */
   1805   1.8   scottr 		if (comprout) {
   1806   1.5   scottr #ifdef __NetBSD__
   1807  1.53    perry 			__asm volatile (
   1808  1.47  thorpej 			"	movml #0xffff,%%sp@- \n" /* save all regs */
   1809  1.47  thorpej 			"	movl %0,%%a2	\n" 	/* compdata */
   1810  1.47  thorpej 			"	movl %1,%%a1	\n" 	/* comprout */
   1811  1.47  thorpej 			"	movl %2,%%a0 	\n"	/* buffer */
   1812  1.47  thorpej 			"	movl %3,%%d0 	\n"	/* cmd */
   1813  1.47  thorpej 			"	jbsr %%a1@ 	\n"	/* go call routine */
   1814  1.47  thorpej 			"	movml %%sp@+,#0xffff"	/* restore all regs */
   1815  1.12   scottr 			    :
   1816  1.12   scottr 			    : "g"(compdata), "g"(comprout),
   1817  1.12   scottr 				"g"(buffer), "g"(cmd)
   1818  1.12   scottr 			    : "d0", "a0", "a1", "a2");
   1819   1.5   scottr #else					/* for macos based testing */
   1820   1.8   scottr 			asm
   1821   1.8   scottr 			{
   1822   1.8   scottr 				movem.l a0/a1/a2/d0, -(a7)
   1823   1.8   scottr 				move.l compdata, a2
   1824   1.8   scottr 				move.l comprout, a1
   1825   1.8   scottr 				move.l buffer, a0
   1826   1.8   scottr 				move.w cmd, d0
   1827   1.8   scottr 				jsr(a1)
   1828   1.8   scottr 				movem.l(a7)+, d0/a2/a1/a0
   1829   1.8   scottr 			}
   1830   1.8   scottr #endif
   1831  1.61   martin 
   1832   1.5   scottr 		}
   1833   1.8   scottr 
   1834  1.12   scottr 		s = splhigh();
   1835  1.12   scottr 		adbInCount--;
   1836  1.12   scottr 		if (++adbInHead >= ADB_QUEUE)
   1837  1.12   scottr 			adbInHead = 0;
   1838   1.8   scottr 		splx(s);
   1839   1.8   scottr 
   1840   1.5   scottr 	}
   1841   1.5   scottr 	return;
   1842   1.1   scottr }
   1843   1.1   scottr 
   1844   1.1   scottr 
   1845   1.1   scottr /*
   1846  1.12   scottr  * This is my version of the ADBOp routine. It mainly just calls the
   1847  1.12   scottr  * hardware-specific routine.
   1848   1.1   scottr  *
   1849   1.5   scottr  *   data 	: pointer to data area to be used by compRout
   1850   1.1   scottr  *   compRout	: completion routine
   1851   1.5   scottr  *   buffer	: for LISTEN: points to data to send - MAX 8 data bytes,
   1852   1.5   scottr  *		  byte 0 = # of bytes
   1853   1.5   scottr  *		: for TALK: points to place to save return data
   1854   1.1   scottr  *   command	: the adb command to send
   1855  1.12   scottr  *   result	: 0 = success
   1856  1.12   scottr  *		: -1 = could not complete
   1857   1.1   scottr  */
   1858   1.5   scottr int
   1859   1.1   scottr adb_op(Ptr buffer, Ptr compRout, Ptr data, short command)
   1860   1.1   scottr {
   1861   1.5   scottr 	int result;
   1862   1.5   scottr 
   1863   1.5   scottr 	switch (adbHardware) {
   1864   1.5   scottr 	case ADB_HW_II:
   1865  1.12   scottr 		result = send_adb_II((u_char *)0, (u_char *)buffer,
   1866  1.12   scottr 		    (void *)compRout, (void *)data, (int)command);
   1867   1.5   scottr 		if (result == 0)
   1868   1.5   scottr 			return 0;
   1869   1.5   scottr 		else
   1870   1.5   scottr 			return -1;
   1871   1.5   scottr 		break;
   1872   1.1   scottr 
   1873  1.24   briggs 	case ADB_HW_IOP:
   1874  1.37   scottr #ifdef __notyet__
   1875  1.24   briggs 		result = send_adb_iop((int)command, (u_char *)buffer,
   1876  1.24   briggs 		    (void *)compRout, (void *)data);
   1877  1.24   briggs 		if (result == 0)
   1878  1.24   briggs 			return 0;
   1879  1.24   briggs 		else
   1880  1.24   briggs #endif
   1881  1.24   briggs 			return -1;
   1882  1.24   briggs 		break;
   1883  1.24   briggs 
   1884   1.5   scottr 	case ADB_HW_IISI:
   1885  1.12   scottr 		result = send_adb_IIsi((u_char *)0, (u_char *)buffer,
   1886  1.12   scottr 		    (void *)compRout, (void *)data, (int)command);
   1887   1.1   scottr 		/*
   1888   1.1   scottr 		 * I wish I knew why this delay is needed. It usually needs to
   1889   1.5   scottr 		 * be here when several commands are sent in close succession,
   1890   1.1   scottr 		 * especially early in device probes when doing collision
   1891   1.1   scottr 		 * detection. It must be some race condition. Sigh. - jpw
   1892   1.1   scottr 		 */
   1893   1.1   scottr 		delay(100);
   1894   1.5   scottr 		if (result == 0)
   1895   1.5   scottr 			return 0;
   1896   1.5   scottr 		else
   1897   1.5   scottr 			return -1;
   1898   1.1   scottr 		break;
   1899   1.1   scottr 
   1900   1.5   scottr 	case ADB_HW_PB:
   1901   1.4   scottr 		result = pm_adb_op((u_char *)buffer, (void *)compRout,
   1902   1.4   scottr 		    (void *)data, (int)command);
   1903   1.5   scottr 
   1904   1.4   scottr 		if (result == 0)
   1905   1.4   scottr 			return 0;
   1906   1.4   scottr 		else
   1907   1.4   scottr 			return -1;
   1908   1.5   scottr 		break;
   1909   1.1   scottr 
   1910   1.5   scottr 	case ADB_HW_CUDA:
   1911  1.12   scottr 		result = send_adb_cuda((u_char *)0, (u_char *)buffer,
   1912  1.12   scottr 		    (void *)compRout, (void *)data, (int)command);
   1913   1.5   scottr 		if (result == 0)
   1914   1.5   scottr 			return 0;
   1915   1.5   scottr 		else
   1916   1.5   scottr 			return -1;
   1917   1.1   scottr 		break;
   1918   1.1   scottr 
   1919   1.5   scottr 	case ADB_HW_UNKNOWN:
   1920   1.1   scottr 	default:
   1921   1.5   scottr 		return -1;
   1922   1.5   scottr 	}
   1923   1.1   scottr }
   1924   1.1   scottr 
   1925   1.1   scottr 
   1926   1.1   scottr /*
   1927   1.8   scottr  * adb_hw_setup
   1928   1.8   scottr  * This routine sets up the possible machine specific hardware
   1929   1.8   scottr  * config (mainly VIA settings) for the various models.
   1930   1.1   scottr  */
   1931   1.5   scottr void
   1932   1.8   scottr adb_hw_setup(void)
   1933   1.1   scottr {
   1934   1.5   scottr 	volatile int i;
   1935   1.8   scottr 	u_char send_string[ADB_MAX_MSG_LENGTH];
   1936   1.5   scottr 
   1937   1.5   scottr 	switch (adbHardware) {
   1938   1.5   scottr 	case ADB_HW_II:
   1939  1.24   briggs 		via1_register_irq(2, adb_intr_II, NULL);
   1940  1.24   briggs 
   1941   1.8   scottr 		via_reg(VIA1, vDirB) |= 0x30;	/* register B bits 4 and 5:
   1942   1.8   scottr 						 * outputs */
   1943   1.8   scottr 		via_reg(VIA1, vDirB) &= 0xf7;	/* register B bit 3: input */
   1944   1.8   scottr 		via_reg(VIA1, vACR) &= ~vSR_OUT;	/* make sure SR is set
   1945   1.8   scottr 							 * to IN (II, IIsi) */
   1946   1.8   scottr 		adbActionState = ADB_ACTION_IDLE;	/* used by all types of
   1947   1.8   scottr 							 * hardware (II, IIsi) */
   1948   1.8   scottr 		adbBusState = ADB_BUS_IDLE;	/* this var. used in II-series
   1949   1.8   scottr 						 * code only */
   1950   1.8   scottr 		via_reg(VIA1, vIER) = 0x84;	/* make sure VIA interrupts
   1951   1.8   scottr 						 * are on (II, IIsi) */
   1952   1.8   scottr 		ADB_SET_STATE_IDLE_II();	/* set ADB bus state to idle */
   1953   1.8   scottr 
   1954   1.5   scottr 		ADB_VIA_CLR_INTR();	/* clear interrupt */
   1955   1.5   scottr 		break;
   1956   1.5   scottr 
   1957  1.24   briggs 	case ADB_HW_IOP:
   1958  1.24   briggs 		via_reg(VIA1, vIER) = 0x84;
   1959  1.24   briggs 		via_reg(VIA1, vIFR) = 0x04;
   1960  1.37   scottr #ifdef __notyet__
   1961  1.37   scottr 		adbActionState = ADB_ACTION_RUNNING;
   1962  1.37   scottr #endif
   1963  1.24   briggs 		break;
   1964  1.24   briggs 
   1965   1.5   scottr 	case ADB_HW_IISI:
   1966  1.24   briggs 		via1_register_irq(2, adb_intr_IIsi, NULL);
   1967   1.8   scottr 		via_reg(VIA1, vDirB) |= 0x30;	/* register B bits 4 and 5:
   1968   1.8   scottr 						 * outputs */
   1969   1.8   scottr 		via_reg(VIA1, vDirB) &= 0xf7;	/* register B bit 3: input */
   1970   1.8   scottr 		via_reg(VIA1, vACR) &= ~vSR_OUT;	/* make sure SR is set
   1971   1.8   scottr 							 * to IN (II, IIsi) */
   1972   1.8   scottr 		adbActionState = ADB_ACTION_IDLE;	/* used by all types of
   1973   1.8   scottr 							 * hardware (II, IIsi) */
   1974   1.8   scottr 		adbBusState = ADB_BUS_IDLE;	/* this var. used in II-series
   1975   1.8   scottr 						 * code only */
   1976   1.8   scottr 		via_reg(VIA1, vIER) = 0x84;	/* make sure VIA interrupts
   1977   1.8   scottr 						 * are on (II, IIsi) */
   1978   1.8   scottr 		ADB_SET_STATE_IDLE_IISI();	/* set ADB bus state to idle */
   1979   1.8   scottr 
   1980   1.5   scottr 		/* get those pesky clock ticks we missed while booting */
   1981   1.8   scottr 		for (i = 0; i < 30; i++) {
   1982   1.8   scottr 			delay(ADB_DELAY);
   1983   1.8   scottr 			adb_hw_setup_IIsi(send_string);
   1984  1.16    ender #ifdef ADB_DEBUG
   1985  1.16    ender 			if (adb_debug) {
   1986  1.16    ender 				printf_intr("adb: cleanup: ");
   1987  1.16    ender 				print_single(send_string);
   1988  1.16    ender 			}
   1989  1.16    ender #endif
   1990   1.8   scottr 			delay(ADB_DELAY);
   1991   1.8   scottr 			if (ADB_INTR_IS_OFF)
   1992   1.8   scottr 				break;
   1993   1.8   scottr 		}
   1994   1.5   scottr 		break;
   1995   1.5   scottr 
   1996   1.5   scottr 	case ADB_HW_PB:
   1997   1.5   scottr 		/*
   1998  1.12   scottr 		 * XXX - really PM_VIA_CLR_INTR - should we put it in
   1999   1.5   scottr 		 * pm_direct.h?
   2000   1.5   scottr 		 */
   2001  1.24   briggs 		pm_hw_setup();
   2002   1.5   scottr 		break;
   2003   1.5   scottr 
   2004   1.5   scottr 	case ADB_HW_CUDA:
   2005  1.24   briggs 		via1_register_irq(2, adb_intr_cuda, NULL);
   2006   1.8   scottr 		via_reg(VIA1, vDirB) |= 0x30;	/* register B bits 4 and 5:
   2007   1.8   scottr 						 * outputs */
   2008   1.8   scottr 		via_reg(VIA1, vDirB) &= 0xf7;	/* register B bit 3: input */
   2009   1.8   scottr 		via_reg(VIA1, vACR) &= ~vSR_OUT;	/* make sure SR is set
   2010   1.8   scottr 							 * to IN */
   2011   1.8   scottr 		via_reg(VIA1, vACR) = (via_reg(VIA1, vACR) | 0x0c) & ~0x10;
   2012   1.8   scottr 		adbActionState = ADB_ACTION_IDLE;	/* used by all types of
   2013   1.8   scottr 							 * hardware */
   2014   1.8   scottr 		adbBusState = ADB_BUS_IDLE;	/* this var. used in II-series
   2015   1.8   scottr 						 * code only */
   2016   1.8   scottr 		via_reg(VIA1, vIER) = 0x84;	/* make sure VIA interrupts
   2017   1.8   scottr 						 * are on */
   2018   1.8   scottr 		ADB_SET_STATE_IDLE_CUDA();	/* set ADB bus state to idle */
   2019   1.8   scottr 
   2020   1.8   scottr 		/* sort of a device reset */
   2021   1.5   scottr 		i = ADB_SR();	/* clear interrupt */
   2022   1.5   scottr 		ADB_VIA_INTR_DISABLE();	/* no interrupts while clearing */
   2023   1.5   scottr 		ADB_SET_STATE_IDLE_CUDA();	/* reset state to idle */
   2024   1.5   scottr 		delay(ADB_DELAY);
   2025   1.5   scottr 		ADB_SET_STATE_TIP();	/* signal start of frame */
   2026   1.5   scottr 		delay(ADB_DELAY);
   2027   1.5   scottr 		ADB_TOGGLE_STATE_ACK_CUDA();
   2028   1.5   scottr 		delay(ADB_DELAY);
   2029   1.5   scottr 		ADB_CLR_STATE_TIP();
   2030   1.5   scottr 		delay(ADB_DELAY);
   2031   1.5   scottr 		ADB_SET_STATE_IDLE_CUDA();	/* back to idle state */
   2032   1.5   scottr 		i = ADB_SR();	/* clear interrupt */
   2033   1.5   scottr 		ADB_VIA_INTR_ENABLE();	/* ints ok now */
   2034   1.5   scottr 		break;
   2035   1.5   scottr 
   2036   1.5   scottr 	case ADB_HW_UNKNOWN:
   2037   1.8   scottr 	default:
   2038   1.8   scottr 		via_reg(VIA1, vIER) = 0x04;	/* turn interrupts off - TO
   2039   1.8   scottr 						 * DO: turn PB ints off? */
   2040   1.5   scottr 		return;
   2041   1.8   scottr 		break;
   2042   1.5   scottr 	}
   2043   1.1   scottr }
   2044   1.5   scottr 
   2045   1.5   scottr 
   2046   1.5   scottr /*
   2047   1.8   scottr  * adb_hw_setup_IIsi
   2048   1.1   scottr  * This is sort of a "read" routine that forces the adb hardware through a read cycle
   2049   1.1   scottr  * if there is something waiting. This helps "clean up" any commands that may have gotten
   2050   1.1   scottr  * stuck or stopped during the boot process.
   2051   1.1   scottr  *
   2052   1.1   scottr  */
   2053   1.5   scottr void
   2054  1.50      chs adb_hw_setup_IIsi(u_char *buffer)
   2055   1.1   scottr {
   2056   1.5   scottr 	int i;
   2057   1.5   scottr 	int s;
   2058   1.5   scottr 	long my_time;
   2059   1.5   scottr 	int endofframe;
   2060   1.5   scottr 
   2061   1.5   scottr 	delay(ADB_DELAY);
   2062   1.5   scottr 
   2063   1.5   scottr 	i = 1;			/* skip over [0] */
   2064   1.5   scottr 	s = splhigh();		/* block ALL interrupts while we are working */
   2065   1.5   scottr 	ADB_SET_SR_INPUT();	/* make sure SR is set to IN */
   2066   1.5   scottr 	ADB_VIA_INTR_DISABLE();	/* disable ADB interrupt on IIs. */
   2067   1.5   scottr 	/* this is required, especially on faster machines */
   2068   1.5   scottr 	delay(ADB_DELAY);
   2069   1.5   scottr 
   2070   1.5   scottr 	if (ADB_INTR_IS_ON) {
   2071   1.5   scottr 		ADB_SET_STATE_ACTIVE();	/* signal start of data frame */
   2072   1.5   scottr 
   2073   1.5   scottr 		endofframe = 0;
   2074   1.5   scottr 		while (0 == endofframe) {
   2075  1.12   scottr 			/*
   2076  1.12   scottr 			 * Poll for ADB interrupt and watch for timeout.
   2077  1.12   scottr 			 * If time out, keep going in hopes of not hanging
   2078  1.12   scottr 			 * the ADB chip - I think
   2079  1.12   scottr 			 */
   2080   1.5   scottr 			my_time = ADB_DELAY * 5;
   2081   1.5   scottr 			while ((ADB_SR_INTR_IS_OFF) && (my_time-- > 0))
   2082  1.64   martin 				(void)via_reg(VIA1, vBufB);
   2083   1.5   scottr 
   2084   1.5   scottr 			buffer[i++] = ADB_SR();	/* reset interrupt flag by
   2085   1.5   scottr 						 * reading vSR */
   2086  1.12   scottr 			/*
   2087  1.12   scottr 			 * Perhaps put in a check here that ignores all data
   2088  1.12   scottr 			 * after the first ADB_MAX_MSG_LENGTH bytes ???
   2089  1.12   scottr 			 */
   2090   1.5   scottr 			if (ADB_INTR_IS_OFF)	/* check for end of frame */
   2091   1.5   scottr 				endofframe = 1;
   2092   1.5   scottr 
   2093   1.5   scottr 			ADB_SET_STATE_ACKON();	/* send ACK to ADB chip */
   2094   1.5   scottr 			delay(ADB_DELAY);	/* delay */
   2095   1.5   scottr 			ADB_SET_STATE_ACKOFF();	/* send ACK to ADB chip */
   2096   1.5   scottr 		}
   2097   1.5   scottr 		ADB_SET_STATE_INACTIVE();	/* signal end of frame and
   2098   1.5   scottr 						 * delay */
   2099   1.5   scottr 
   2100   1.5   scottr 		/* probably don't need to delay this long */
   2101   1.5   scottr 		delay(ADB_DELAY);
   2102   1.5   scottr 	}
   2103   1.5   scottr 	buffer[0] = --i;	/* [0] is length of message */
   2104   1.5   scottr 	ADB_VIA_INTR_ENABLE();	/* enable ADB interrupt on IIs. */
   2105   1.5   scottr 	splx(s);		/* restore interrupts */
   2106   1.5   scottr 
   2107   1.5   scottr 	return;
   2108   1.8   scottr }				/* adb_hw_setup_IIsi */
   2109   1.1   scottr 
   2110   1.1   scottr 
   2111   1.1   scottr 
   2112   1.1   scottr /*
   2113   1.1   scottr  * adb_reinit sets up the adb stuff
   2114   1.1   scottr  *
   2115   1.1   scottr  */
   2116   1.5   scottr void
   2117   1.1   scottr adb_reinit(void)
   2118   1.1   scottr {
   2119   1.8   scottr 	u_char send_string[ADB_MAX_MSG_LENGTH];
   2120  1.32   scottr 	ADBDataBlock data;	/* temp. holder for getting device info */
   2121   1.5   scottr 	volatile int i, x;
   2122  1.32   scottr 	int s;
   2123   1.5   scottr 	int command;
   2124   1.5   scottr 	int result;
   2125   1.5   scottr 	int saveptr;		/* point to next free relocation address */
   2126   1.5   scottr 	int device;
   2127   1.5   scottr 	int nonewtimes;		/* times thru loop w/o any new devices */
   2128  1.58       ad 	static bool again;
   2129  1.58       ad 
   2130  1.58       ad 	if (!again) {
   2131  1.58       ad 		callout_init(&adb_cuda_tickle_ch, 0);
   2132  1.58       ad 		again = true;
   2133  1.58       ad 	}
   2134   1.4   scottr 
   2135  1.44   scottr 	adb_setup_hw_type();	/* setup hardware type */
   2136  1.44   scottr 
   2137   1.5   scottr 	/* Make sure we are not interrupted while building the table. */
   2138  1.24   briggs 	/* ints must be on for PB & IOP (at least, for now) */
   2139  1.24   briggs 	if (adbHardware != ADB_HW_PB && adbHardware != ADB_HW_IOP)
   2140   1.5   scottr 		s = splhigh();
   2141  1.32   scottr 	else
   2142  1.32   scottr 		s = 0;		/* XXX shut the compiler up*/
   2143   1.5   scottr 
   2144   1.5   scottr 	ADBNumDevices = 0;	/* no devices yet */
   2145   1.5   scottr 
   2146   1.5   scottr 	/* Let intr routines know we are running reinit */
   2147   1.5   scottr 	adbStarting = 1;
   2148   1.5   scottr 
   2149  1.12   scottr 	/*
   2150  1.12   scottr 	 * Initialize the ADB table.  For now, we'll always use the same table
   2151  1.12   scottr 	 * that is defined at the beginning of this file - no mallocs.
   2152  1.12   scottr 	 */
   2153  1.43   scottr 	for (i = 0; i < 16; i++) {
   2154   1.5   scottr 		ADBDevTable[i].devType = 0;
   2155  1.43   scottr 		ADBDevTable[i].origAddr = ADBDevTable[i].currentAddr = 0;
   2156  1.43   scottr 	}
   2157   1.5   scottr 
   2158   1.8   scottr 	adb_hw_setup();		/* init the VIA bits and hard reset ADB */
   2159   1.5   scottr 
   2160  1.73      nat 	delay(100000);
   2161  1.27   scottr 
   2162   1.5   scottr 	/* send an ADB reset first */
   2163  1.43   scottr 	(void)adb_op_sync((Ptr)0, (Ptr)0, (Ptr)0, (short)0x00);
   2164  1.73      nat 	delay(300000);
   2165   1.5   scottr 
   2166  1.12   scottr 	/*
   2167  1.12   scottr 	 * Probe for ADB devices. Probe devices 1-15 quickly to determine
   2168   1.5   scottr 	 * which device addresses are in use and which are free. For each
   2169   1.5   scottr 	 * address that is in use, move the device at that address to a higher
   2170   1.5   scottr 	 * free address. Continue doing this at that address until no device
   2171   1.5   scottr 	 * responds at that address. Then move the last device that was moved
   2172   1.5   scottr 	 * back to the original address. Do this for the remaining addresses
   2173   1.5   scottr 	 * that we determined were in use.
   2174   1.5   scottr 	 *
   2175  1.12   scottr 	 * When finished, do this entire process over again with the updated
   2176  1.12   scottr 	 * list of in use addresses. Do this until no new devices have been
   2177  1.12   scottr 	 * found in 20 passes though the in use address list. (This probably
   2178  1.12   scottr 	 * seems long and complicated, but it's the best way to detect multiple
   2179   1.5   scottr 	 * devices at the same address - sometimes it takes a couple of tries
   2180  1.12   scottr 	 * before the collision is detected.)
   2181  1.12   scottr 	 */
   2182   1.5   scottr 
   2183   1.1   scottr 	/* initial scan through the devices */
   2184   1.5   scottr 	for (i = 1; i < 16; i++) {
   2185  1.41   scottr 		command = ADBTALK(i, 3);
   2186  1.12   scottr 		result = adb_op_sync((Ptr)send_string, (Ptr)0,
   2187  1.12   scottr 		    (Ptr)0, (short)command);
   2188  1.40   scottr 
   2189  1.43   scottr 		if (result == 0 && send_string[0] != 0) {
   2190  1.40   scottr 			/* found a device */
   2191  1.39   scottr 			++ADBNumDevices;
   2192  1.39   scottr 			KASSERT(ADBNumDevices < 16);
   2193  1.39   scottr 			ADBDevTable[ADBNumDevices].devType =
   2194  1.20    ender 				(int)(send_string[2]);
   2195   1.1   scottr 			ADBDevTable[ADBNumDevices].origAddr = i;
   2196   1.1   scottr 			ADBDevTable[ADBNumDevices].currentAddr = i;
   2197  1.12   scottr 			ADBDevTable[ADBNumDevices].DataAreaAddr =
   2198  1.12   scottr 			    (long)0;
   2199  1.12   scottr 			ADBDevTable[ADBNumDevices].ServiceRtPtr = (void *)0;
   2200   1.5   scottr 			pm_check_adb_devices(i);	/* tell pm driver device
   2201   1.5   scottr 							 * is here */
   2202   1.1   scottr 		}
   2203   1.1   scottr 	}
   2204   1.5   scottr 
   2205   1.1   scottr 	/* find highest unused address */
   2206   1.5   scottr 	for (saveptr = 15; saveptr > 0; saveptr--)
   2207   1.5   scottr 		if (-1 == get_adb_info(&data, saveptr))
   2208   1.1   scottr 			break;
   2209   1.5   scottr 
   2210  1.12   scottr #ifdef ADB_DEBUG
   2211  1.12   scottr 	if (adb_debug & 0x80) {
   2212  1.12   scottr 		printf_intr("first free is: 0x%02x\n", saveptr);
   2213  1.12   scottr 		printf_intr("devices: %i\n", ADBNumDevices);
   2214  1.12   scottr 	}
   2215  1.12   scottr #endif
   2216   1.5   scottr 
   2217   1.5   scottr 	nonewtimes = 0;		/* no loops w/o new devices */
   2218  1.39   scottr 	while (saveptr > 0 && nonewtimes++ < 11) {
   2219  1.43   scottr 		for (i = 1;saveptr > 0 && i <= ADBNumDevices; i++) {
   2220   1.5   scottr 			device = ADBDevTable[i].currentAddr;
   2221  1.12   scottr #ifdef ADB_DEBUG
   2222  1.12   scottr 			if (adb_debug & 0x80)
   2223  1.12   scottr 				printf_intr("moving device 0x%02x to 0x%02x "
   2224  1.12   scottr 				    "(index 0x%02x)  ", device, saveptr, i);
   2225  1.12   scottr #endif
   2226   1.1   scottr 
   2227   1.1   scottr 			/* send TALK R3 to address */
   2228  1.41   scottr 			command = ADBTALK(device, 3);
   2229  1.43   scottr 			(void)adb_op_sync((Ptr)send_string, (Ptr)0,
   2230  1.12   scottr 			    (Ptr)0, (short)command);
   2231   1.5   scottr 
   2232   1.1   scottr 			/* move device to higher address */
   2233  1.41   scottr 			command = ADBLISTEN(device, 3);
   2234   1.5   scottr 			send_string[0] = 2;
   2235  1.12   scottr 			send_string[1] = (u_char)(saveptr | 0x60);
   2236   1.5   scottr 			send_string[2] = 0xfe;
   2237  1.43   scottr 			(void)adb_op_sync((Ptr)send_string, (Ptr)0,
   2238  1.12   scottr 			    (Ptr)0, (short)command);
   2239  1.43   scottr 			delay(1000);
   2240   1.5   scottr 
   2241  1.70   andvar 			/* send TALK R3 - anything at new address? */
   2242  1.41   scottr 			command = ADBTALK(saveptr, 3);
   2243  1.43   scottr 			send_string[0] = 0;
   2244  1.43   scottr 			result = adb_op_sync((Ptr)send_string, (Ptr)0,
   2245  1.39   scottr 			    (Ptr)0, (short)command);
   2246  1.43   scottr 			delay(1000);
   2247  1.39   scottr 
   2248  1.43   scottr 			if (result != 0 || send_string[0] == 0) {
   2249  1.43   scottr 				/*
   2250  1.43   scottr 				 * maybe there's a communication breakdown;
   2251  1.43   scottr 				 * just in case, move it back from whence it
   2252  1.43   scottr 				 * came, and we'll try again later
   2253  1.43   scottr 				 */
   2254  1.43   scottr 				command = ADBLISTEN(saveptr, 3);
   2255  1.43   scottr 				send_string[0] = 2;
   2256  1.43   scottr 				send_string[1] = (u_char)(device | 0x60);
   2257  1.43   scottr 				send_string[2] = 0x00;
   2258  1.43   scottr 				(void)adb_op_sync((Ptr)send_string, (Ptr)0,
   2259  1.43   scottr 				    (Ptr)0, (short)command);
   2260  1.39   scottr #ifdef ADB_DEBUG
   2261  1.39   scottr 				if (adb_debug & 0x80)
   2262  1.39   scottr 					printf_intr("failed, continuing\n");
   2263  1.39   scottr #endif
   2264  1.43   scottr 				delay(1000);
   2265  1.39   scottr 				continue;
   2266  1.39   scottr 			}
   2267  1.39   scottr 
   2268   1.1   scottr 			/* send TALK R3 - anything at old address? */
   2269  1.41   scottr 			command = ADBTALK(device, 3);
   2270  1.43   scottr 			send_string[0] = 0;
   2271  1.12   scottr 			result = adb_op_sync((Ptr)send_string, (Ptr)0,
   2272  1.12   scottr 			    (Ptr)0, (short)command);
   2273  1.43   scottr 			if (result == 0 && send_string[0] != 0) {
   2274   1.1   scottr 				/* new device found */
   2275   1.1   scottr 				/* update data for previously moved device */
   2276   1.5   scottr 				ADBDevTable[i].currentAddr = saveptr;
   2277  1.12   scottr #ifdef ADB_DEBUG
   2278  1.12   scottr 				if (adb_debug & 0x80)
   2279  1.12   scottr 					printf_intr("old device at index %i\n",i);
   2280  1.12   scottr #endif
   2281   1.1   scottr 				/* add new device in table */
   2282  1.12   scottr #ifdef ADB_DEBUG
   2283  1.12   scottr 				if (adb_debug & 0x80)
   2284  1.12   scottr 					printf_intr("new device found\n");
   2285  1.12   scottr #endif
   2286  1.39   scottr 				if (saveptr > ADBNumDevices) {
   2287  1.39   scottr 					++ADBNumDevices;
   2288  1.39   scottr 					KASSERT(ADBNumDevices < 16);
   2289  1.39   scottr 				}
   2290  1.39   scottr 				ADBDevTable[ADBNumDevices].devType =
   2291  1.20    ender 					(int)(send_string[2]);
   2292   1.1   scottr 				ADBDevTable[ADBNumDevices].origAddr = device;
   2293   1.1   scottr 				ADBDevTable[ADBNumDevices].currentAddr = device;
   2294   1.5   scottr 				/* These will be set correctly in adbsys.c */
   2295   1.5   scottr 				/* Until then, unsol. data will be ignored. */
   2296  1.12   scottr 				ADBDevTable[ADBNumDevices].DataAreaAddr =
   2297  1.12   scottr 				    (long)0;
   2298  1.12   scottr 				ADBDevTable[ADBNumDevices].ServiceRtPtr =
   2299  1.12   scottr 				    (void *)0;
   2300   1.1   scottr 				/* find next unused address */
   2301  1.39   scottr 				for (x = saveptr; x > 0; x--) {
   2302   1.5   scottr 					if (-1 == get_adb_info(&data, x)) {
   2303   1.5   scottr 						saveptr = x;
   2304   1.1   scottr 						break;
   2305   1.1   scottr 					}
   2306  1.39   scottr 				}
   2307  1.39   scottr 				if (x == 0)
   2308  1.39   scottr 					saveptr = 0;
   2309  1.12   scottr #ifdef ADB_DEBUG
   2310  1.12   scottr 				if (adb_debug & 0x80)
   2311  1.12   scottr 					printf_intr("new free is 0x%02x\n",
   2312  1.12   scottr 					    saveptr);
   2313  1.12   scottr #endif
   2314   1.5   scottr 				nonewtimes = 0;
   2315   1.5   scottr 				/* tell pm driver device is here */
   2316   1.5   scottr 				pm_check_adb_devices(device);
   2317   1.1   scottr 			} else {
   2318  1.12   scottr #ifdef ADB_DEBUG
   2319  1.12   scottr 				if (adb_debug & 0x80)
   2320  1.12   scottr 					printf_intr("moving back...\n");
   2321  1.12   scottr #endif
   2322   1.1   scottr 				/* move old device back */
   2323  1.41   scottr 				command = ADBLISTEN(saveptr, 3);
   2324   1.5   scottr 				send_string[0] = 2;
   2325  1.12   scottr 				send_string[1] = (u_char)(device | 0x60);
   2326   1.5   scottr 				send_string[2] = 0xfe;
   2327  1.43   scottr 				(void)adb_op_sync((Ptr)send_string, (Ptr)0,
   2328  1.12   scottr 				    (Ptr)0, (short)command);
   2329  1.27   scottr 				delay(1000);
   2330   1.1   scottr 			}
   2331   1.1   scottr 		}
   2332   1.1   scottr 	}
   2333   1.1   scottr 
   2334  1.11   scottr #ifdef ADB_DEBUG
   2335  1.11   scottr 	if (adb_debug) {
   2336  1.11   scottr 		for (i = 1; i <= ADBNumDevices; i++) {
   2337  1.11   scottr 			x = get_ind_adb_info(&data, i);
   2338  1.11   scottr 			if (x != -1)
   2339  1.20    ender 				printf_intr("index 0x%x, addr 0x%x, type 0x%hx\n",
   2340  1.11   scottr 				    i, x, data.devType);
   2341  1.11   scottr 		}
   2342   1.5   scottr 	}
   2343   1.5   scottr #endif
   2344   1.5   scottr 
   2345  1.17   scottr #ifndef MRG_ADB
   2346  1.12   scottr 	/* enable the programmer's switch, if we have one */
   2347  1.12   scottr 	adb_prog_switch_enable();
   2348  1.17   scottr #endif
   2349   1.1   scottr 
   2350  1.16    ender #ifdef ADB_DEBUG
   2351  1.16    ender 	if (adb_debug) {
   2352  1.16    ender 		if (0 == ADBNumDevices)	/* tell user if no devices found */
   2353  1.16    ender 			printf_intr("adb: no devices found\n");
   2354  1.16    ender 	}
   2355  1.16    ender #endif
   2356   1.1   scottr 
   2357   1.5   scottr 	adbStarting = 0;	/* not starting anymore */
   2358  1.16    ender #ifdef ADB_DEBUG
   2359  1.16    ender 	if (adb_debug)
   2360  1.16    ender 		printf_intr("adb: ADBReInit complete\n");
   2361  1.16    ender #endif
   2362   1.1   scottr 
   2363  1.12   scottr 	if (adbHardware == ADB_HW_CUDA)
   2364  1.42  thorpej 		callout_reset(&adb_cuda_tickle_ch, ADB_TICKLE_TICKS,
   2365  1.42  thorpej 		    (void *)adb_cuda_tickle, NULL);
   2366   1.8   scottr 
   2367  1.24   briggs 	/* ints must be on for PB & IOP (at least, for now) */
   2368  1.24   briggs 	if (adbHardware != ADB_HW_PB && adbHardware != ADB_HW_IOP)
   2369   1.5   scottr 		splx(s);
   2370  1.22   scottr 
   2371   1.5   scottr 	return;
   2372   1.1   scottr }
   2373   1.1   scottr 
   2374   1.1   scottr 
   2375   1.8   scottr /*
   2376   1.8   scottr  * adb_comp_exec
   2377   1.8   scottr  * This is a general routine that calls the completion routine if there is one.
   2378   1.8   scottr  * NOTE: This routine is now only used by pm_direct.c
   2379   1.8   scottr  *       All the code in this file (adb_direct.c) uses
   2380   1.8   scottr  *       the adb_pass_up routine now.
   2381   1.8   scottr  */
   2382   1.8   scottr void
   2383   1.8   scottr adb_comp_exec(void)
   2384   1.8   scottr {
   2385  1.12   scottr 	if ((long)0 != adbCompRout) /* don't call if empty return location */
   2386   1.8   scottr #ifdef __NetBSD__
   2387  1.53    perry 		__asm volatile(
   2388  1.47  thorpej 		"	movml #0xffff,%%sp@- \n" /* save all registers */
   2389  1.47  thorpej 		"	movl %0,%%a2 \n"	/* adbCompData */
   2390  1.47  thorpej 		"	movl %1,%%a1 \n"	/* adbCompRout */
   2391  1.47  thorpej 		"	movl %2,%%a0 \n"	/* adbBuffer */
   2392  1.47  thorpej 		"	movl %3,%%d0 \n"	/* adbWaitingCmd */
   2393  1.47  thorpej 		"	jbsr %%a1@ \n"		/* go call the routine */
   2394  1.47  thorpej 		"	movml %%sp@+,#0xffff"	/* restore all registers */
   2395  1.12   scottr 		    :
   2396  1.12   scottr 		    : "g"(adbCompData), "g"(adbCompRout),
   2397  1.12   scottr 			"g"(adbBuffer), "g"(adbWaitingCmd)
   2398  1.12   scottr 		    : "d0", "a0", "a1", "a2");
   2399  1.12   scottr #else /* for Mac OS-based testing */
   2400  1.12   scottr 		asm {
   2401  1.12   scottr 			movem.l a0/a1/a2/d0, -(a7)
   2402  1.12   scottr 			move.l adbCompData, a2
   2403  1.12   scottr 			move.l adbCompRout, a1
   2404  1.12   scottr 			move.l adbBuffer, a0
   2405  1.12   scottr 			move.w adbWaitingCmd, d0
   2406  1.12   scottr 			jsr(a1)
   2407  1.12   scottr 			movem.l(a7) +, d0/a2/a1/a0
   2408  1.12   scottr 		}
   2409   1.8   scottr #endif
   2410   1.8   scottr }
   2411   1.8   scottr 
   2412   1.8   scottr 
   2413  1.12   scottr /*
   2414  1.12   scottr  * adb_cmd_result
   2415  1.12   scottr  *
   2416  1.12   scottr  * This routine lets the caller know whether the specified adb command string
   2417  1.12   scottr  * should expect a returned result, such as a TALK command.
   2418  1.12   scottr  *
   2419   1.1   scottr  * returns: 0 if a result should be expected
   2420   1.1   scottr  *          1 if a result should NOT be expected
   2421   1.1   scottr  */
   2422   1.5   scottr int
   2423  1.12   scottr adb_cmd_result(u_char *in)
   2424   1.1   scottr {
   2425   1.5   scottr 	switch (adbHardware) {
   2426  1.24   briggs 	case ADB_HW_IOP:
   2427  1.12   scottr 	case ADB_HW_II:
   2428   1.5   scottr 		/* was it an ADB talk command? */
   2429   1.5   scottr 		if ((in[1] & 0x0c) == 0x0c)
   2430   1.5   scottr 			return 0;
   2431  1.12   scottr 		return 1;
   2432   1.1   scottr 
   2433   1.5   scottr 	case ADB_HW_IISI:
   2434   1.5   scottr 	case ADB_HW_CUDA:
   2435  1.12   scottr 		/* was it an ADB talk command? */
   2436   1.5   scottr 		if ((in[1] == 0x00) && ((in[2] & 0x0c) == 0x0c))
   2437   1.5   scottr 			return 0;
   2438  1.12   scottr 		/* was it an RTC/PRAM read date/time? */
   2439  1.12   scottr 		if ((in[1] == 0x01) && (in[2] == 0x03))
   2440  1.12   scottr 			return 0;
   2441  1.12   scottr 		return 1;
   2442   1.1   scottr 
   2443   1.5   scottr 	case ADB_HW_PB:
   2444   1.5   scottr 		return 1;
   2445   1.5   scottr 
   2446   1.5   scottr 	case ADB_HW_UNKNOWN:
   2447   1.1   scottr 	default:
   2448   1.5   scottr 		return 1;
   2449   1.5   scottr 	}
   2450   1.1   scottr }
   2451   1.1   scottr 
   2452   1.1   scottr 
   2453  1.12   scottr /*
   2454  1.12   scottr  * adb_cmd_extra
   2455  1.12   scottr  *
   2456  1.12   scottr  * This routine lets the caller know whether the specified adb command string
   2457  1.12   scottr  * may have extra data appended to the end of it, such as a LISTEN command.
   2458  1.12   scottr  *
   2459   1.1   scottr  * returns: 0 if extra data is allowed
   2460   1.1   scottr  *          1 if extra data is NOT allowed
   2461   1.1   scottr  */
   2462   1.5   scottr int
   2463  1.12   scottr adb_cmd_extra(u_char *in)
   2464   1.1   scottr {
   2465   1.5   scottr 	switch (adbHardware) {
   2466  1.24   briggs 	case ADB_HW_II:
   2467  1.24   briggs 	case ADB_HW_IOP:
   2468   1.5   scottr 		if ((in[1] & 0x0c) == 0x08)	/* was it a listen command? */
   2469   1.5   scottr 			return 0;
   2470  1.12   scottr 		return 1;
   2471   1.5   scottr 
   2472   1.5   scottr 	case ADB_HW_IISI:
   2473   1.5   scottr 	case ADB_HW_CUDA:
   2474  1.12   scottr 		/*
   2475  1.12   scottr 		 * TO DO: support needs to be added to recognize RTC and PRAM
   2476  1.12   scottr 		 * commands
   2477  1.12   scottr 		 */
   2478   1.5   scottr 		if ((in[2] & 0x0c) == 0x08)	/* was it a listen command? */
   2479   1.5   scottr 			return 0;
   2480  1.12   scottr 		/* add others later */
   2481  1.12   scottr 		return 1;
   2482   1.1   scottr 
   2483   1.5   scottr 	case ADB_HW_PB:
   2484   1.5   scottr 		return 1;
   2485   1.5   scottr 
   2486   1.5   scottr 	case ADB_HW_UNKNOWN:
   2487   1.1   scottr 	default:
   2488   1.5   scottr 		return 1;
   2489   1.5   scottr 	}
   2490   1.1   scottr }
   2491   1.1   scottr 
   2492   1.1   scottr 
   2493   1.1   scottr void
   2494   1.1   scottr adb_setup_hw_type(void)
   2495   1.1   scottr {
   2496   1.5   scottr 	long response;
   2497   1.1   scottr 
   2498   1.5   scottr 	response = mac68k_machine.machineid;
   2499   1.1   scottr 
   2500   1.8   scottr 	/*
   2501   1.8   scottr 	 * Determine what type of ADB hardware we are running on.
   2502   1.8   scottr 	 */
   2503   1.5   scottr 	switch (response) {
   2504  1.17   scottr 	case MACH_MACC610:		/* Centris 610 */
   2505  1.17   scottr 	case MACH_MACC650:		/* Centris 650 */
   2506  1.17   scottr 	case MACH_MACII:		/* II */
   2507  1.17   scottr 	case MACH_MACIICI:		/* IIci */
   2508  1.17   scottr 	case MACH_MACIICX:		/* IIcx */
   2509  1.17   scottr 	case MACH_MACIIX:		/* IIx */
   2510  1.17   scottr 	case MACH_MACQ610:		/* Quadra 610 */
   2511  1.17   scottr 	case MACH_MACQ650:		/* Quadra 650 */
   2512  1.17   scottr 	case MACH_MACQ700:		/* Quadra 700 */
   2513  1.17   scottr 	case MACH_MACQ800:		/* Quadra 800 */
   2514  1.17   scottr 	case MACH_MACSE30:		/* SE/30 */
   2515   1.5   scottr 		adbHardware = ADB_HW_II;
   2516  1.16    ender #ifdef ADB_DEBUG
   2517  1.16    ender 		if (adb_debug)
   2518  1.16    ender 			printf_intr("adb: using II series hardware support\n");
   2519  1.16    ender #endif
   2520   1.5   scottr 		break;
   2521  1.17   scottr 
   2522  1.17   scottr 	case MACH_MACCLASSICII:		/* Classic II */
   2523  1.17   scottr 	case MACH_MACLCII:		/* LC II, Performa 400/405/430 */
   2524  1.17   scottr 	case MACH_MACLCIII:		/* LC III, Performa 450 */
   2525  1.17   scottr 	case MACH_MACIISI:		/* IIsi */
   2526  1.17   scottr 	case MACH_MACIIVI:		/* IIvi */
   2527  1.17   scottr 	case MACH_MACIIVX:		/* IIvx */
   2528  1.17   scottr 	case MACH_MACP460:		/* Performa 460/465/467 */
   2529  1.17   scottr 	case MACH_MACP600:		/* Performa 600 */
   2530   1.5   scottr 		adbHardware = ADB_HW_IISI;
   2531  1.16    ender #ifdef ADB_DEBUG
   2532  1.16    ender 		if (adb_debug)
   2533  1.16    ender 			printf_intr("adb: using IIsi series hardware support\n");
   2534  1.16    ender #endif
   2535   1.5   scottr 		break;
   2536  1.17   scottr 
   2537  1.17   scottr 	case MACH_MACPB140:		/* PowerBook 140 */
   2538  1.17   scottr 	case MACH_MACPB145:		/* PowerBook 145 */
   2539  1.17   scottr 	case MACH_MACPB160:		/* PowerBook 160 */
   2540  1.17   scottr 	case MACH_MACPB165:		/* PowerBook 165 */
   2541  1.17   scottr 	case MACH_MACPB165C:		/* PowerBook 165c */
   2542  1.17   scottr 	case MACH_MACPB170:		/* PowerBook 170 */
   2543  1.17   scottr 	case MACH_MACPB180:		/* PowerBook 180 */
   2544  1.17   scottr 	case MACH_MACPB180C:		/* PowerBook 180c */
   2545   1.5   scottr 		adbHardware = ADB_HW_PB;
   2546   1.5   scottr 		pm_setup_adb();
   2547  1.16    ender #ifdef ADB_DEBUG
   2548  1.16    ender 		if (adb_debug)
   2549  1.16    ender 			printf_intr("adb: using PowerBook 100-series hardware support\n");
   2550  1.16    ender #endif
   2551   1.5   scottr 		break;
   2552  1.17   scottr 
   2553  1.46    shiba 	case MACH_MACPB150:		/* PowerBook 150 */
   2554  1.17   scottr 	case MACH_MACPB210:		/* PowerBook Duo 210 */
   2555  1.17   scottr 	case MACH_MACPB230:		/* PowerBook Duo 230 */
   2556  1.17   scottr 	case MACH_MACPB250:		/* PowerBook Duo 250 */
   2557  1.17   scottr 	case MACH_MACPB270:		/* PowerBook Duo 270 */
   2558  1.17   scottr 	case MACH_MACPB280:		/* PowerBook Duo 280 */
   2559  1.17   scottr 	case MACH_MACPB280C:		/* PowerBook Duo 280c */
   2560  1.17   scottr 	case MACH_MACPB500:		/* PowerBook 500 series */
   2561  1.48    shiba 	case MACH_MACPB190:		/* PowerBook 190 */
   2562  1.48    shiba 	case MACH_MACPB190CS:		/* PowerBook 190cs */
   2563   1.5   scottr 		adbHardware = ADB_HW_PB;
   2564   1.5   scottr 		pm_setup_adb();
   2565  1.16    ender #ifdef ADB_DEBUG
   2566  1.16    ender 		if (adb_debug)
   2567  1.16    ender 			printf_intr("adb: using PowerBook Duo-series and PowerBook 500-series hardware support\n");
   2568  1.16    ender #endif
   2569   1.5   scottr 		break;
   2570  1.17   scottr 
   2571  1.17   scottr 	case MACH_MACC660AV:		/* Centris 660AV */
   2572  1.17   scottr 	case MACH_MACCCLASSIC:		/* Color Classic */
   2573  1.17   scottr 	case MACH_MACCCLASSICII:	/* Color Classic II */
   2574  1.17   scottr 	case MACH_MACLC475:		/* LC 475, Performa 475/476 */
   2575  1.17   scottr 	case MACH_MACLC475_33:		/* Clock-chipped 47x */
   2576  1.17   scottr 	case MACH_MACLC520:		/* LC 520 */
   2577  1.17   scottr 	case MACH_MACLC575:		/* LC 575, Performa 575/577/578 */
   2578  1.17   scottr 	case MACH_MACP550:		/* LC 550, Performa 550 */
   2579  1.36   scottr 	case MACH_MACTV:		/* Macintosh TV */
   2580  1.17   scottr 	case MACH_MACP580:		/* Performa 580/588 */
   2581  1.17   scottr 	case MACH_MACQ605:		/* Quadra 605 */
   2582  1.17   scottr 	case MACH_MACQ605_33:		/* Clock-chipped Quadra 605 */
   2583  1.17   scottr 	case MACH_MACQ630:		/* LC 630, Performa 630, Quadra 630 */
   2584  1.17   scottr 	case MACH_MACQ840AV:		/* Quadra 840AV */
   2585   1.5   scottr 		adbHardware = ADB_HW_CUDA;
   2586  1.16    ender #ifdef ADB_DEBUG
   2587  1.16    ender 		if (adb_debug)
   2588  1.16    ender 			printf_intr("adb: using Cuda series hardware support\n");
   2589  1.16    ender #endif
   2590   1.5   scottr 		break;
   2591  1.24   briggs 
   2592  1.24   briggs 	case MACH_MACQ900:		/* Quadra 900 */
   2593  1.24   briggs 	case MACH_MACQ950:		/* Quadra 950 */
   2594  1.24   briggs 	case MACH_MACIIFX:		/* Mac IIfx   */
   2595  1.24   briggs 		adbHardware = ADB_HW_IOP;
   2596  1.24   briggs 		iop_register_listener(ISM_IOP, IOP_CHAN_ADB, adb_iop_recv, NULL);
   2597  1.24   briggs #ifdef ADB_DEBUG
   2598  1.24   briggs 		if (adb_debug)
   2599  1.24   briggs 			printf_intr("adb: using IOP-based ADB\n");
   2600  1.24   briggs #endif
   2601  1.24   briggs 		break;
   2602  1.24   briggs 
   2603   1.5   scottr 	default:
   2604   1.5   scottr 		adbHardware = ADB_HW_UNKNOWN;
   2605  1.16    ender #ifdef ADB_DEBUG
   2606  1.16    ender 		if (adb_debug) {
   2607  1.16    ender 			printf_intr("adb: hardware type unknown for this machine\n");
   2608  1.16    ender 			printf_intr("adb: ADB support is disabled\n");
   2609  1.16    ender 		}
   2610  1.16    ender #endif
   2611   1.5   scottr 		break;
   2612   1.5   scottr 	}
   2613   1.8   scottr 
   2614   1.8   scottr 	/*
   2615   1.8   scottr 	 * Determine whether this machine has ADB based soft power.
   2616   1.8   scottr 	 */
   2617   1.8   scottr 	switch (response) {
   2618  1.17   scottr 	case MACH_MACCCLASSIC:		/* Color Classic */
   2619  1.17   scottr 	case MACH_MACCCLASSICII:	/* Color Classic II */
   2620  1.17   scottr 	case MACH_MACIISI:		/* IIsi */
   2621  1.17   scottr 	case MACH_MACIIVI:		/* IIvi */
   2622  1.17   scottr 	case MACH_MACIIVX:		/* IIvx */
   2623  1.17   scottr 	case MACH_MACLC520:		/* LC 520 */
   2624  1.17   scottr 	case MACH_MACLC575:		/* LC 575, Performa 575/577/578 */
   2625  1.17   scottr 	case MACH_MACP550:		/* LC 550, Performa 550 */
   2626  1.36   scottr 	case MACH_MACTV:		/* Macintosh TV */
   2627  1.23   scottr 	case MACH_MACP580:		/* Performa 580/588 */
   2628  1.17   scottr 	case MACH_MACP600:		/* Performa 600 */
   2629  1.17   scottr 	case MACH_MACQ630:		/* LC 630, Performa 630, Quadra 630 */
   2630  1.17   scottr 	case MACH_MACQ840AV:		/* Quadra 840AV */
   2631  1.12   scottr 		adbSoftPower = 1;
   2632   1.8   scottr 		break;
   2633   1.8   scottr 	}
   2634   1.1   scottr }
   2635   1.1   scottr 
   2636   1.1   scottr int
   2637   1.1   scottr count_adbs(void)
   2638   1.1   scottr {
   2639   1.5   scottr 	int i;
   2640   1.5   scottr 	int found;
   2641   1.1   scottr 
   2642   1.5   scottr 	found = 0;
   2643   1.1   scottr 
   2644   1.5   scottr 	for (i = 1; i < 16; i++)
   2645  1.43   scottr 		if (0 != ADBDevTable[i].currentAddr)
   2646   1.5   scottr 			found++;
   2647   1.1   scottr 
   2648   1.5   scottr 	return found;
   2649   1.1   scottr }
   2650   1.1   scottr 
   2651   1.1   scottr int
   2652  1.50      chs get_ind_adb_info(ADBDataBlock *info, int index)
   2653   1.1   scottr {
   2654   1.5   scottr 	if ((index < 1) || (index > 15))	/* check range 1-15 */
   2655   1.5   scottr 		return (-1);
   2656   1.1   scottr 
   2657  1.12   scottr #ifdef ADB_DEBUG
   2658  1.12   scottr 	if (adb_debug & 0x80)
   2659  1.12   scottr 		printf_intr("index 0x%x devType is: 0x%x\n", index,
   2660  1.12   scottr 		    ADBDevTable[index].devType);
   2661  1.12   scottr #endif
   2662   1.5   scottr 	if (0 == ADBDevTable[index].devType)	/* make sure it's a valid entry */
   2663   1.5   scottr 		return (-1);
   2664   1.5   scottr 
   2665  1.20    ender 	info->devType = (unsigned char)(ADBDevTable[index].devType);
   2666  1.20    ender 	info->origADBAddr = (unsigned char)(ADBDevTable[index].origAddr);
   2667  1.12   scottr 	info->dbServiceRtPtr = (Ptr)ADBDevTable[index].ServiceRtPtr;
   2668  1.12   scottr 	info->dbDataAreaAddr = (Ptr)ADBDevTable[index].DataAreaAddr;
   2669   1.1   scottr 
   2670   1.5   scottr 	return (ADBDevTable[index].currentAddr);
   2671   1.1   scottr }
   2672   1.1   scottr 
   2673   1.1   scottr int
   2674  1.50      chs get_adb_info(ADBDataBlock *info, int adbAddr)
   2675   1.1   scottr {
   2676   1.5   scottr 	int i;
   2677   1.1   scottr 
   2678   1.5   scottr 	if ((adbAddr < 1) || (adbAddr > 15))	/* check range 1-15 */
   2679   1.5   scottr 		return (-1);
   2680   1.1   scottr 
   2681   1.5   scottr 	for (i = 1; i < 15; i++)
   2682   1.5   scottr 		if (ADBDevTable[i].currentAddr == adbAddr) {
   2683  1.20    ender 			info->devType = (unsigned char)(ADBDevTable[i].devType);
   2684  1.20    ender 			info->origADBAddr = (unsigned char)(ADBDevTable[i].origAddr);
   2685   1.5   scottr 			info->dbServiceRtPtr = (Ptr)ADBDevTable[i].ServiceRtPtr;
   2686   1.5   scottr 			info->dbDataAreaAddr = ADBDevTable[i].DataAreaAddr;
   2687   1.5   scottr 			return 0;	/* found */
   2688   1.5   scottr 		}
   2689   1.1   scottr 
   2690   1.5   scottr 	return (-1);		/* not found */
   2691   1.1   scottr }
   2692   1.1   scottr 
   2693   1.1   scottr int
   2694  1.50      chs set_adb_info(ADBSetInfoBlock *info, int adbAddr)
   2695   1.1   scottr {
   2696   1.5   scottr 	int i;
   2697   1.1   scottr 
   2698   1.5   scottr 	if ((adbAddr < 1) || (adbAddr > 15))	/* check range 1-15 */
   2699   1.5   scottr 		return (-1);
   2700   1.1   scottr 
   2701   1.5   scottr 	for (i = 1; i < 15; i++)
   2702   1.5   scottr 		if (ADBDevTable[i].currentAddr == adbAddr) {
   2703   1.5   scottr 			ADBDevTable[i].ServiceRtPtr =
   2704   1.5   scottr 			    (void *)(info->siServiceRtPtr);
   2705   1.5   scottr 			ADBDevTable[i].DataAreaAddr = info->siDataAreaAddr;
   2706   1.5   scottr 			return 0;	/* found */
   2707   1.5   scottr 		}
   2708   1.1   scottr 
   2709   1.5   scottr 	return (-1);		/* not found */
   2710   1.1   scottr 
   2711   1.1   scottr }
   2712   1.1   scottr 
   2713   1.1   scottr #ifndef MRG_ADB
   2714   1.1   scottr long
   2715   1.1   scottr mrg_adbintr(void)
   2716   1.1   scottr {
   2717  1.24   briggs 	adb_intr(NULL);
   2718   1.1   scottr 	return 1;	/* mimic mrg_adbintr in macrom.h just in case */
   2719   1.1   scottr }
   2720   1.1   scottr 
   2721   1.1   scottr long
   2722   1.7   briggs mrg_pmintr(void)
   2723   1.1   scottr {
   2724  1.24   briggs 	pm_intr(NULL);
   2725   1.1   scottr 	return 1;	/* mimic mrg_pmintr in macrom.h just in case */
   2726   1.1   scottr }
   2727   1.1   scottr 
   2728  1.55      wiz /* caller should really use machine-independent version: getPramTime */
   2729   1.1   scottr /* this version does pseudo-adb access only */
   2730   1.1   scottr int
   2731  1.54      rjs adb_read_date_time(unsigned long *curtime)
   2732   1.1   scottr {
   2733   1.8   scottr 	u_char output[ADB_MAX_MSG_LENGTH];
   2734  1.63     yamt 	int result;
   2735   1.5   scottr 	volatile int flag = 0;
   2736   1.5   scottr 
   2737   1.5   scottr 	switch (adbHardware) {
   2738   1.5   scottr 	case ADB_HW_II:
   2739   1.5   scottr 		return -1;
   2740   1.5   scottr 
   2741  1.24   briggs 	case ADB_HW_IOP:
   2742  1.24   briggs 		return -1;
   2743  1.24   briggs 
   2744   1.5   scottr 	case ADB_HW_IISI:
   2745   1.5   scottr 		output[0] = 0x02;	/* 2 byte message */
   2746   1.5   scottr 		output[1] = 0x01;	/* to pram/rtc device */
   2747   1.5   scottr 		output[2] = 0x03;	/* read date/time */
   2748  1.12   scottr 		result = send_adb_IIsi((u_char *)output, (u_char *)output,
   2749  1.51      jmc 		    (void *)adb_op_comprout, __UNVOLATILE(&flag), (int)0);
   2750   1.5   scottr 		if (result != 0)	/* exit if not sent */
   2751   1.5   scottr 			return -1;
   2752   1.1   scottr 
   2753  1.62   scottr 		adb_spin(&flag);	/* wait for result */
   2754  1.62   scottr 		if (flag == 0)		/* exit it timeout */
   2755  1.61   martin 			return -1;
   2756   1.1   scottr 
   2757  1.54      rjs 		*curtime = (long)(*(long *)(output + 1));
   2758   1.5   scottr 		return 0;
   2759   1.1   scottr 
   2760   1.5   scottr 	case ADB_HW_PB:
   2761   1.5   scottr 		return -1;
   2762   1.1   scottr 
   2763   1.1   scottr 	case ADB_HW_CUDA:
   2764   1.5   scottr 		output[0] = 0x02;	/* 2 byte message */
   2765   1.5   scottr 		output[1] = 0x01;	/* to pram/rtc device */
   2766   1.5   scottr 		output[2] = 0x03;	/* read date/time */
   2767  1.12   scottr 		result = send_adb_cuda((u_char *)output, (u_char *)output,
   2768  1.51      jmc 		    (void *)adb_op_comprout, __UNVOLATILE(&flag), (int)0);
   2769   1.5   scottr 		if (result != 0)	/* exit if not sent */
   2770   1.5   scottr 			return -1;
   2771   1.5   scottr 
   2772  1.62   scottr 		adb_spin(&flag);	/* wait for result */
   2773  1.62   scottr 		if (flag == 0)		/* exit it timeout */
   2774  1.61   martin 			return -1;
   2775   1.5   scottr 
   2776  1.54      rjs 		*curtime = (long)(*(long *)(output + 1));
   2777   1.5   scottr 		return 0;
   2778   1.5   scottr 
   2779   1.5   scottr 	case ADB_HW_UNKNOWN:
   2780   1.5   scottr 	default:
   2781   1.5   scottr 		return -1;
   2782   1.5   scottr 	}
   2783   1.1   scottr }
   2784   1.1   scottr 
   2785  1.55      wiz /* caller should really use machine-independent version: setPramTime */
   2786   1.1   scottr /* this version does pseudo-adb access only */
   2787   1.1   scottr int
   2788  1.54      rjs adb_set_date_time(unsigned long curtime)
   2789   1.1   scottr {
   2790   1.8   scottr 	u_char output[ADB_MAX_MSG_LENGTH];
   2791   1.5   scottr 	int result;
   2792   1.5   scottr 	volatile int flag = 0;
   2793   1.1   scottr 
   2794   1.5   scottr 	switch (adbHardware) {
   2795   1.5   scottr 	case ADB_HW_II:
   2796   1.1   scottr 		return -1;
   2797   1.1   scottr 
   2798  1.24   briggs 	case ADB_HW_IOP:
   2799  1.24   briggs 		return -1;
   2800  1.24   briggs 
   2801   1.5   scottr 	case ADB_HW_IISI:
   2802   1.5   scottr 		output[0] = 0x06;	/* 6 byte message */
   2803   1.5   scottr 		output[1] = 0x01;	/* to pram/rtc device */
   2804   1.5   scottr 		output[2] = 0x09;	/* set date/time */
   2805  1.54      rjs 		output[3] = (u_char)(curtime >> 24);
   2806  1.54      rjs 		output[4] = (u_char)(curtime >> 16);
   2807  1.54      rjs 		output[5] = (u_char)(curtime >> 8);
   2808  1.54      rjs 		output[6] = (u_char)(curtime);
   2809  1.12   scottr 		result = send_adb_IIsi((u_char *)output, (u_char *)0,
   2810  1.51      jmc 		    (void *)adb_op_comprout, __UNVOLATILE(&flag), (int)0);
   2811   1.5   scottr 		if (result != 0)	/* exit if not sent */
   2812   1.5   scottr 			return -1;
   2813   1.1   scottr 
   2814  1.62   scottr 		adb_spin(&flag);	/* wait for result */
   2815  1.62   scottr 		if (flag == 0)		/* exit it timeout */
   2816  1.62   scottr 			return -1;
   2817   1.1   scottr 
   2818   1.5   scottr 		return 0;
   2819   1.1   scottr 
   2820   1.5   scottr 	case ADB_HW_PB:
   2821   1.5   scottr 		return -1;
   2822   1.1   scottr 
   2823   1.1   scottr 	case ADB_HW_CUDA:
   2824   1.5   scottr 		output[0] = 0x06;	/* 6 byte message */
   2825   1.5   scottr 		output[1] = 0x01;	/* to pram/rtc device */
   2826   1.5   scottr 		output[2] = 0x09;	/* set date/time */
   2827  1.54      rjs 		output[3] = (u_char)(curtime >> 24);
   2828  1.54      rjs 		output[4] = (u_char)(curtime >> 16);
   2829  1.54      rjs 		output[5] = (u_char)(curtime >> 8);
   2830  1.54      rjs 		output[6] = (u_char)(curtime);
   2831  1.12   scottr 		result = send_adb_cuda((u_char *)output, (u_char *)0,
   2832  1.51      jmc 		    (void *)adb_op_comprout, __UNVOLATILE(&flag), (int)0);
   2833   1.5   scottr 		if (result != 0)	/* exit if not sent */
   2834   1.5   scottr 			return -1;
   2835   1.1   scottr 
   2836  1.62   scottr 		adb_spin(&flag);	/* wait for result */
   2837  1.62   scottr 		if (flag == 0)		/* exit it timeout */
   2838  1.62   scottr 			return -1;
   2839   1.1   scottr 
   2840   1.5   scottr 		return 0;
   2841   1.1   scottr 
   2842   1.5   scottr 	case ADB_HW_UNKNOWN:
   2843   1.1   scottr 	default:
   2844   1.5   scottr 		return -1;
   2845   1.5   scottr 	}
   2846   1.1   scottr }
   2847   1.1   scottr 
   2848   1.1   scottr 
   2849   1.1   scottr int
   2850   1.1   scottr adb_poweroff(void)
   2851   1.1   scottr {
   2852   1.8   scottr 	u_char output[ADB_MAX_MSG_LENGTH];
   2853   1.5   scottr 	int result;
   2854   1.1   scottr 
   2855   1.8   scottr 	if (!adbSoftPower)
   2856   1.8   scottr 		return -1;
   2857  1.30   scottr 
   2858  1.30   scottr 	adb_polling = 1;
   2859   1.8   scottr 
   2860   1.5   scottr 	switch (adbHardware) {
   2861   1.5   scottr 	case ADB_HW_IISI:
   2862   1.5   scottr 		output[0] = 0x02;	/* 2 byte message */
   2863   1.5   scottr 		output[1] = 0x01;	/* to pram/rtc/soft-power device */
   2864   1.5   scottr 		output[2] = 0x0a;	/* set date/time */
   2865  1.12   scottr 		result = send_adb_IIsi((u_char *)output, (u_char *)0,
   2866  1.12   scottr 		    (void *)0, (void *)0, (int)0);
   2867   1.5   scottr 		if (result != 0)	/* exit if not sent */
   2868   1.5   scottr 			return -1;
   2869   1.1   scottr 
   2870   1.5   scottr 		for (;;);		/* wait for power off */
   2871   1.1   scottr 
   2872   1.5   scottr 		return 0;
   2873   1.1   scottr 
   2874   1.5   scottr 	case ADB_HW_PB:
   2875   1.5   scottr 		return -1;
   2876   1.1   scottr 
   2877   1.8   scottr 	case ADB_HW_CUDA:
   2878   1.8   scottr 		output[0] = 0x02;	/* 2 byte message */
   2879   1.8   scottr 		output[1] = 0x01;	/* to pram/rtc/soft-power device */
   2880   1.8   scottr 		output[2] = 0x0a;	/* set date/time */
   2881  1.12   scottr 		result = send_adb_cuda((u_char *)output, (u_char *)0,
   2882  1.12   scottr 		    (void *)0, (void *)0, (int)0);
   2883   1.8   scottr 		if (result != 0)	/* exit if not sent */
   2884   1.8   scottr 			return -1;
   2885   1.8   scottr 
   2886   1.8   scottr 		for (;;);		/* wait for power off */
   2887   1.8   scottr 
   2888   1.8   scottr 		return 0;
   2889   1.8   scottr 
   2890   1.8   scottr 	case ADB_HW_II:			/* II models don't do ADB soft power */
   2891  1.24   briggs 	case ADB_HW_IOP:		/* IOP models don't do ADB soft power */
   2892   1.5   scottr 	case ADB_HW_UNKNOWN:
   2893   1.1   scottr 	default:
   2894   1.5   scottr 		return -1;
   2895   1.5   scottr 	}
   2896   1.5   scottr }
   2897   1.1   scottr 
   2898   1.1   scottr int
   2899   1.1   scottr adb_prog_switch_enable(void)
   2900   1.1   scottr {
   2901   1.8   scottr 	u_char output[ADB_MAX_MSG_LENGTH];
   2902   1.5   scottr 	int result;
   2903   1.5   scottr 	volatile int flag = 0;
   2904   1.5   scottr 
   2905   1.5   scottr 	switch (adbHardware) {
   2906   1.5   scottr 	case ADB_HW_IISI:
   2907   1.5   scottr 		output[0] = 0x03;	/* 3 byte message */
   2908   1.5   scottr 		output[1] = 0x01;	/* to pram/rtc/soft-power device */
   2909   1.5   scottr 		output[2] = 0x1c;	/* prog. switch control */
   2910   1.5   scottr 		output[3] = 0x01;	/* enable */
   2911  1.12   scottr 		result = send_adb_IIsi((u_char *)output, (u_char *)0,
   2912  1.51      jmc 		    (void *)adb_op_comprout, __UNVOLATILE(&flag), (int)0);
   2913   1.5   scottr 		if (result != 0)	/* exit if not sent */
   2914   1.5   scottr 			return -1;
   2915   1.5   scottr 
   2916  1.62   scottr 		adb_spin(&flag);	/* wait for result */
   2917  1.62   scottr 		if (flag == 0)		/* exit it timeout */
   2918  1.62   scottr 			return -1;
   2919   1.5   scottr 
   2920   1.5   scottr 		return 0;
   2921   1.5   scottr 
   2922   1.5   scottr 	case ADB_HW_PB:
   2923   1.5   scottr 		return -1;
   2924   1.5   scottr 
   2925   1.5   scottr 	case ADB_HW_II:		/* II models don't do prog. switch */
   2926  1.24   briggs 	case ADB_HW_IOP:	/* IOP models don't do prog. switch */
   2927   1.5   scottr 	case ADB_HW_CUDA:	/* cuda doesn't do prog. switch TO DO: verify this */
   2928   1.5   scottr 	case ADB_HW_UNKNOWN:
   2929   1.1   scottr 	default:
   2930   1.5   scottr 		return -1;
   2931   1.5   scottr 	}
   2932   1.5   scottr }
   2933   1.1   scottr 
   2934   1.1   scottr int
   2935   1.1   scottr adb_prog_switch_disable(void)
   2936   1.1   scottr {
   2937   1.8   scottr 	u_char output[ADB_MAX_MSG_LENGTH];
   2938   1.5   scottr 	int result;
   2939   1.5   scottr 	volatile int flag = 0;
   2940   1.5   scottr 
   2941   1.5   scottr 	switch (adbHardware) {
   2942   1.5   scottr 	case ADB_HW_IISI:
   2943   1.5   scottr 		output[0] = 0x03;	/* 3 byte message */
   2944   1.5   scottr 		output[1] = 0x01;	/* to pram/rtc/soft-power device */
   2945   1.5   scottr 		output[2] = 0x1c;	/* prog. switch control */
   2946   1.5   scottr 		output[3] = 0x01;	/* disable */
   2947  1.12   scottr 		result = send_adb_IIsi((u_char *)output, (u_char *)0,
   2948  1.51      jmc 			(void *)adb_op_comprout, __UNVOLATILE(&flag), (int)0);
   2949   1.5   scottr 		if (result != 0)	/* exit if not sent */
   2950   1.5   scottr 			return -1;
   2951   1.5   scottr 
   2952  1.62   scottr 		adb_spin(&flag);	/* wait for result */
   2953  1.62   scottr 		if (flag == 0)		/* exit it timeout */
   2954  1.62   scottr 			return -1;
   2955   1.5   scottr 
   2956   1.5   scottr 		return 0;
   2957   1.5   scottr 
   2958   1.5   scottr 	case ADB_HW_PB:
   2959   1.5   scottr 		return -1;
   2960   1.5   scottr 
   2961   1.5   scottr 	case ADB_HW_II:		/* II models don't do prog. switch */
   2962  1.24   briggs 	case ADB_HW_IOP:	/* IOP models don't do prog. switch */
   2963   1.5   scottr 	case ADB_HW_CUDA:	/* cuda doesn't do prog. switch */
   2964   1.5   scottr 	case ADB_HW_UNKNOWN:
   2965   1.1   scottr 	default:
   2966   1.5   scottr 		return -1;
   2967   1.5   scottr 	}
   2968   1.5   scottr }
   2969   1.5   scottr 
   2970   1.1   scottr int
   2971   1.1   scottr CountADBs(void)
   2972   1.1   scottr {
   2973   1.5   scottr 	return (count_adbs());
   2974   1.1   scottr }
   2975   1.1   scottr 
   2976   1.1   scottr void
   2977   1.1   scottr ADBReInit(void)
   2978   1.1   scottr {
   2979   1.5   scottr 	adb_reinit();
   2980   1.1   scottr }
   2981   1.1   scottr 
   2982   1.1   scottr int
   2983  1.50      chs GetIndADB(ADBDataBlock *info, int index)
   2984   1.1   scottr {
   2985   1.5   scottr 	return (get_ind_adb_info(info, index));
   2986   1.1   scottr }
   2987   1.1   scottr 
   2988   1.1   scottr int
   2989  1.50      chs GetADBInfo(ADBDataBlock *info, int adbAddr)
   2990   1.1   scottr {
   2991   1.5   scottr 	return (get_adb_info(info, adbAddr));
   2992   1.1   scottr }
   2993   1.1   scottr 
   2994   1.1   scottr int
   2995  1.50      chs SetADBInfo(ADBSetInfoBlock *info, int adbAddr)
   2996   1.1   scottr {
   2997   1.5   scottr 	return (set_adb_info(info, adbAddr));
   2998   1.1   scottr }
   2999   1.1   scottr 
   3000   1.1   scottr int
   3001   1.1   scottr ADBOp(Ptr buffer, Ptr compRout, Ptr data, short commandNum)
   3002   1.1   scottr {
   3003   1.5   scottr 	return (adb_op(buffer, compRout, data, commandNum));
   3004   1.1   scottr }
   3005   1.5   scottr 
   3006   1.5   scottr #endif
   3007