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