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