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