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