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