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