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