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