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