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