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