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