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