1 1.47 andvar /* $NetBSD: adb_direct.c,v 1.47 2025/09/07 21:31:20 andvar Exp $ */ 2 1.1 tsubai 3 1.1 tsubai /* From: adb_direct.c 2.02 4/18/97 jpw */ 4 1.1 tsubai 5 1.1 tsubai /* 6 1.1 tsubai * Copyright (C) 1996, 1997 John P. Wittkoski 7 1.1 tsubai * All rights reserved. 8 1.1 tsubai * 9 1.1 tsubai * Redistribution and use in source and binary forms, with or without 10 1.1 tsubai * modification, are permitted provided that the following conditions 11 1.1 tsubai * are met: 12 1.1 tsubai * 1. Redistributions of source code must retain the above copyright 13 1.1 tsubai * notice, this list of conditions and the following disclaimer. 14 1.1 tsubai * 2. Redistributions in binary form must reproduce the above copyright 15 1.1 tsubai * notice, this list of conditions and the following disclaimer in the 16 1.1 tsubai * documentation and/or other materials provided with the distribution. 17 1.1 tsubai * 3. All advertising materials mentioning features or use of this software 18 1.1 tsubai * must display the following acknowledgement: 19 1.1 tsubai * This product includes software developed by John P. Wittkoski. 20 1.1 tsubai * 4. The name of the author may not be used to endorse or promote products 21 1.1 tsubai * derived from this software without specific prior written permission. 22 1.1 tsubai * 23 1.1 tsubai * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 24 1.1 tsubai * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 25 1.1 tsubai * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 26 1.1 tsubai * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 27 1.1 tsubai * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 28 1.1 tsubai * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 29 1.1 tsubai * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 30 1.1 tsubai * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 31 1.1 tsubai * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 32 1.1 tsubai * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 33 1.1 tsubai */ 34 1.1 tsubai 35 1.1 tsubai /* 36 1.1 tsubai * This code is rather messy, but I don't have time right now 37 1.1 tsubai * to clean it up as much as I would like. 38 1.1 tsubai * But it works, so I'm happy. :-) jpw 39 1.1 tsubai */ 40 1.1 tsubai 41 1.1 tsubai /* 42 1.1 tsubai * TO DO: 43 1.1 tsubai * - We could reduce the time spent in the adb_intr_* routines 44 1.1 tsubai * by having them save the incoming and outgoing data directly 45 1.1 tsubai * in the adbInbound and adbOutbound queues, as it would reduce 46 1.1 tsubai * the number of times we need to copy the data around. It 47 1.1 tsubai * would also make the code more readable and easier to follow. 48 1.1 tsubai * - (Related to above) Use the header part of adbCommand to 49 1.1 tsubai * reduce the number of copies we have to do of the data. 50 1.1 tsubai * - (Related to above) Actually implement the adbOutbound queue. 51 1.1 tsubai * This is fairly easy once you switch all the intr routines 52 1.1 tsubai * over to using adbCommand structs directly. 53 1.1 tsubai * - There is a bug in the state machine of adb_intr_cuda 54 1.1 tsubai * code that causes hangs, especially on 030 machines, probably 55 1.1 tsubai * because of some timing issues. Because I have been unable to 56 1.1 tsubai * determine the exact cause of this bug, I used the timeout function 57 1.1 tsubai * to check for and recover from this condition. If anyone finds 58 1.1 tsubai * the actual cause of this bug, the calls to timeout and the 59 1.1 tsubai * adb_cuda_tickle routine can be removed. 60 1.1 tsubai */ 61 1.25 lukem 62 1.25 lukem #include <sys/cdefs.h> 63 1.47 andvar __KERNEL_RCSID(0, "$NetBSD: adb_direct.c,v 1.47 2025/09/07 21:31:20 andvar Exp $"); 64 1.1 tsubai 65 1.1 tsubai #include <sys/param.h> 66 1.1 tsubai #include <sys/systm.h> 67 1.13 thorpej #include <sys/callout.h> 68 1.1 tsubai #include <sys/device.h> 69 1.1 tsubai 70 1.1 tsubai #include <machine/cpu.h> 71 1.39 garbled #include <machine/autoconf.h> 72 1.1 tsubai #include <machine/adbsys.h> 73 1.39 garbled #include <machine/pio.h> 74 1.1 tsubai 75 1.1 tsubai #include <macppc/dev/viareg.h> 76 1.1 tsubai #include <macppc/dev/adbvar.h> 77 1.17 matt #include <macppc/dev/pm_direct.h> 78 1.1 tsubai 79 1.1 tsubai #define printf_intr printf 80 1.1 tsubai 81 1.6 tsubai #ifdef DEBUG 82 1.6 tsubai #ifndef ADB_DEBUG 83 1.6 tsubai #define ADB_DEBUG 84 1.6 tsubai #endif 85 1.6 tsubai #endif 86 1.6 tsubai 87 1.1 tsubai /* some misc. leftovers */ 88 1.1 tsubai #define vPB 0x0000 89 1.1 tsubai #define vPB3 0x08 90 1.1 tsubai #define vPB4 0x10 91 1.1 tsubai #define vPB5 0x20 92 1.1 tsubai #define vSR_INT 0x04 93 1.1 tsubai #define vSR_OUT 0x10 94 1.1 tsubai 95 1.1 tsubai /* the type of ADB action that we are currently preforming */ 96 1.6 tsubai #define ADB_ACTION_NOTREADY 0x1 /* has not been initialized yet */ 97 1.6 tsubai #define ADB_ACTION_IDLE 0x2 /* the bus is currently idle */ 98 1.6 tsubai #define ADB_ACTION_OUT 0x3 /* sending out a command */ 99 1.6 tsubai #define ADB_ACTION_IN 0x4 /* receiving data */ 100 1.6 tsubai #define ADB_ACTION_POLLING 0x5 /* polling - II only */ 101 1.1 tsubai 102 1.1 tsubai /* 103 1.1 tsubai * These describe the state of the ADB bus itself, although they 104 1.1 tsubai * don't necessarily correspond directly to ADB states. 105 1.1 tsubai * Note: these are not really used in the IIsi code. 106 1.1 tsubai */ 107 1.6 tsubai #define ADB_BUS_UNKNOWN 0x1 /* we don't know yet - all models */ 108 1.6 tsubai #define ADB_BUS_IDLE 0x2 /* bus is idle - all models */ 109 1.6 tsubai #define ADB_BUS_CMD 0x3 /* starting a command - II models */ 110 1.6 tsubai #define ADB_BUS_ODD 0x4 /* the "odd" state - II models */ 111 1.6 tsubai #define ADB_BUS_EVEN 0x5 /* the "even" state - II models */ 112 1.6 tsubai #define ADB_BUS_ACTIVE 0x6 /* active state - IIsi models */ 113 1.6 tsubai #define ADB_BUS_ACK 0x7 /* currently ACKing - IIsi models */ 114 1.1 tsubai 115 1.1 tsubai /* 116 1.1 tsubai * Shortcuts for setting or testing the VIA bit states. 117 1.1 tsubai * Not all shortcuts are used for every type of ADB hardware. 118 1.1 tsubai */ 119 1.1 tsubai #define ADB_SET_STATE_IDLE_CUDA() via_reg_or(VIA1, vBufB, (vPB4 | vPB5)) 120 1.1 tsubai #define ADB_SET_STATE_TIP() via_reg_and(VIA1, vBufB, ~vPB5) 121 1.1 tsubai #define ADB_CLR_STATE_TIP() via_reg_or(VIA1, vBufB, vPB5) 122 1.1 tsubai #define ADB_TOGGLE_STATE_ACK_CUDA() via_reg_xor(VIA1, vBufB, vPB4) 123 1.1 tsubai #define ADB_SET_STATE_ACKOFF_CUDA() via_reg_or(VIA1, vBufB, vPB4) 124 1.1 tsubai #define ADB_SET_SR_INPUT() via_reg_and(VIA1, vACR, ~vSR_OUT) 125 1.1 tsubai #define ADB_SET_SR_OUTPUT() via_reg_or(VIA1, vACR, vSR_OUT) 126 1.1 tsubai #define ADB_SR() read_via_reg(VIA1, vSR) 127 1.1 tsubai #define ADB_VIA_INTR_ENABLE() write_via_reg(VIA1, vIER, 0x84) 128 1.1 tsubai #define ADB_VIA_INTR_DISABLE() write_via_reg(VIA1, vIER, 0x04) 129 1.1 tsubai #define ADB_INTR_IS_OFF (vPB3 == (read_via_reg(VIA1, vBufB) & vPB3)) 130 1.1 tsubai #define ADB_INTR_IS_ON (0 == (read_via_reg(VIA1, vBufB) & vPB3)) 131 1.1 tsubai #define ADB_SR_INTR_IS_OFF (0 == (read_via_reg(VIA1, vIFR) & vSR_INT)) 132 1.1 tsubai #define ADB_SR_INTR_IS_ON (vSR_INT == (read_via_reg(VIA1, \ 133 1.1 tsubai vIFR) & vSR_INT)) 134 1.1 tsubai 135 1.1 tsubai /* 136 1.1 tsubai * This is the delay that is required (in uS) between certain 137 1.45 msaitoh * ADB transactions. The actual timing delay for each uS is 138 1.1 tsubai * calculated at boot time to account for differences in machine speed. 139 1.1 tsubai */ 140 1.8 tsubai #define ADB_DELAY 150 141 1.1 tsubai 142 1.1 tsubai /* 143 1.1 tsubai * Maximum ADB message length; includes space for data, result, and 144 1.1 tsubai * device code - plus a little for safety. 145 1.1 tsubai */ 146 1.1 tsubai #define ADB_MAX_MSG_LENGTH 16 147 1.1 tsubai #define ADB_MAX_HDR_LENGTH 8 148 1.1 tsubai 149 1.1 tsubai #define ADB_QUEUE 32 150 1.1 tsubai #define ADB_TICKLE_TICKS 4 151 1.1 tsubai 152 1.1 tsubai /* 153 1.1 tsubai * A structure for storing information about each ADB device. 154 1.1 tsubai */ 155 1.1 tsubai struct ADBDevEntry { 156 1.40 dsl void (*ServiceRtPtr)(void); 157 1.1 tsubai void *DataAreaAddr; 158 1.14 tsubai int devType; 159 1.14 tsubai int origAddr; 160 1.14 tsubai int currentAddr; 161 1.1 tsubai }; 162 1.1 tsubai 163 1.1 tsubai /* 164 1.1 tsubai * Used to hold ADB commands that are waiting to be sent out. 165 1.1 tsubai */ 166 1.1 tsubai struct adbCmdHoldEntry { 167 1.1 tsubai u_char outBuf[ADB_MAX_MSG_LENGTH]; /* our message */ 168 1.1 tsubai u_char *saveBuf; /* buffer to know where to save result */ 169 1.32 nathanw adbComp *compRout; /* completion routine pointer */ 170 1.32 nathanw int *data; /* completion routine data pointer */ 171 1.1 tsubai }; 172 1.1 tsubai 173 1.1 tsubai /* 174 1.1 tsubai * Eventually used for two separate queues, the queue between 175 1.1 tsubai * the upper and lower halves, and the outgoing packet queue. 176 1.1 tsubai * TO DO: adbCommand can replace all of adbCmdHoldEntry eventually 177 1.1 tsubai */ 178 1.1 tsubai struct adbCommand { 179 1.1 tsubai u_char header[ADB_MAX_HDR_LENGTH]; /* not used yet */ 180 1.1 tsubai u_char data[ADB_MAX_MSG_LENGTH]; /* packet data only */ 181 1.1 tsubai u_char *saveBuf; /* where to save result */ 182 1.32 nathanw adbComp *compRout; /* completion routine pointer */ 183 1.32 nathanw volatile int *compData; /* completion routine data pointer */ 184 1.1 tsubai u_int cmd; /* the original command for this data */ 185 1.1 tsubai u_int unsol; /* 1 if packet was unsolicited */ 186 1.1 tsubai u_int ack_only; /* 1 for no special processing */ 187 1.1 tsubai }; 188 1.1 tsubai 189 1.1 tsubai /* 190 1.1 tsubai * A few variables that we need and their initial values. 191 1.1 tsubai */ 192 1.1 tsubai int adbHardware = ADB_HW_UNKNOWN; 193 1.1 tsubai int adbActionState = ADB_ACTION_NOTREADY; 194 1.1 tsubai int adbWaiting = 0; /* waiting for return data from the device */ 195 1.1 tsubai int adbWriteDelay = 0; /* working on (or waiting to do) a write */ 196 1.1 tsubai 197 1.1 tsubai int adbWaitingCmd = 0; /* ADB command we are waiting for */ 198 1.1 tsubai u_char *adbBuffer = (long)0; /* pointer to user data area */ 199 1.32 nathanw adbComp *adbCompRout = NULL; /* pointer to the completion routine */ 200 1.32 nathanw volatile int *adbCompData = NULL; /* pointer to the completion routine data */ 201 1.1 tsubai int adbStarting = 1; /* doing ADBReInit so do polling differently */ 202 1.1 tsubai 203 1.1 tsubai u_char adbInputBuffer[ADB_MAX_MSG_LENGTH]; /* data input buffer */ 204 1.1 tsubai u_char adbOutputBuffer[ADB_MAX_MSG_LENGTH]; /* data output buffer */ 205 1.1 tsubai 206 1.1 tsubai int adbSentChars = 0; /* how many characters we have sent */ 207 1.1 tsubai 208 1.1 tsubai struct ADBDevEntry ADBDevTable[16]; /* our ADB device table */ 209 1.1 tsubai int ADBNumDevices; /* num. of ADB devices found with ADBReInit */ 210 1.1 tsubai 211 1.1 tsubai struct adbCommand adbInbound[ADB_QUEUE]; /* incoming queue */ 212 1.1 tsubai int adbInCount = 0; /* how many packets in in queue */ 213 1.1 tsubai int adbInHead = 0; /* head of in queue */ 214 1.1 tsubai int adbInTail = 0; /* tail of in queue */ 215 1.1 tsubai struct adbCommand adbOutbound[ADB_QUEUE]; /* outgoing queue - not used yet */ 216 1.1 tsubai int adbOutCount = 0; /* how many packets in out queue */ 217 1.1 tsubai int adbOutHead = 0; /* head of out queue */ 218 1.1 tsubai int adbOutTail = 0; /* tail of out queue */ 219 1.1 tsubai 220 1.1 tsubai int tickle_count = 0; /* how many tickles seen for this packet? */ 221 1.1 tsubai int tickle_serial = 0; /* the last packet tickled */ 222 1.1 tsubai int adb_cuda_serial = 0; /* the current packet */ 223 1.1 tsubai 224 1.38 ad struct callout adb_cuda_tickle_ch; 225 1.38 ad struct callout adb_soft_intr_ch; 226 1.13 thorpej 227 1.43 matt volatile uint8_t *Via1Base; 228 1.6 tsubai extern int adb_polling; /* Are we polling? */ 229 1.1 tsubai 230 1.40 dsl void pm_setup_adb(void); 231 1.40 dsl void pm_check_adb_devices(int); 232 1.40 dsl int pm_adb_op(u_char *, void *, volatile void *, int); 233 1.40 dsl void pm_init_adb_device(void); 234 1.1 tsubai 235 1.1 tsubai /* 236 1.1 tsubai * The following are private routines. 237 1.1 tsubai */ 238 1.6 tsubai #ifdef ADB_DEBUG 239 1.40 dsl void print_single(u_char *); 240 1.6 tsubai #endif 241 1.40 dsl void adb_soft_intr(void); 242 1.40 dsl int send_adb_cuda(u_char *, u_char *, adbComp *, volatile void *, int); 243 1.40 dsl void adb_intr_cuda_test(void); 244 1.40 dsl void adb_cuda_tickle(void); 245 1.40 dsl void adb_pass_up(struct adbCommand *); 246 1.40 dsl void adb_op_comprout(void *, volatile int *, int); 247 1.40 dsl void adb_reinit(void); 248 1.40 dsl int count_adbs(void); 249 1.40 dsl int get_ind_adb_info(ADBDataBlock *, int); 250 1.40 dsl int get_adb_info(ADBDataBlock *, int); 251 1.40 dsl int set_adb_info(ADBSetInfoBlock *, int); 252 1.40 dsl void adb_setup_hw_type(void); 253 1.32 nathanw int adb_op (Ptr, adbComp *, volatile void *, short); 254 1.40 dsl int adb_op_sync(Ptr, adbComp *, Ptr, short); 255 1.40 dsl void adb_hw_setup(void); 256 1.40 dsl int adb_cmd_result(u_char *); 257 1.40 dsl int adb_cmd_extra(u_char *); 258 1.1 tsubai /* we should create this and it will be the public version */ 259 1.40 dsl int send_adb(u_char *, void *, void *); 260 1.1 tsubai 261 1.40 dsl int setsoftadb(void); 262 1.17 matt 263 1.6 tsubai #ifdef ADB_DEBUG 264 1.1 tsubai /* 265 1.1 tsubai * print_single 266 1.1 tsubai * Diagnostic display routine. Displays the hex values of the 267 1.1 tsubai * specified elements of the u_char. The length of the "string" 268 1.1 tsubai * is in [0]. 269 1.1 tsubai */ 270 1.1 tsubai void 271 1.41 dsl print_single(u_char *str) 272 1.1 tsubai { 273 1.1 tsubai int x; 274 1.1 tsubai 275 1.14 tsubai if (str == 0) { 276 1.14 tsubai printf_intr("no data - null pointer\n"); 277 1.1 tsubai return; 278 1.1 tsubai } 279 1.14 tsubai if (*str == 0) { 280 1.14 tsubai printf_intr("nothing returned\n"); 281 1.1 tsubai return; 282 1.1 tsubai } 283 1.14 tsubai if (*str > 20) { 284 1.1 tsubai printf_intr("ADB: ACK > 20 no way!\n"); 285 1.14 tsubai *str = 20; 286 1.1 tsubai } 287 1.14 tsubai printf_intr("(length=0x%x):", *str); 288 1.14 tsubai for (x = 1; x <= *str; x++) 289 1.14 tsubai printf_intr(" 0x%02x", str[x]); 290 1.1 tsubai printf_intr("\n"); 291 1.1 tsubai } 292 1.6 tsubai #endif 293 1.1 tsubai 294 1.1 tsubai void 295 1.1 tsubai adb_cuda_tickle(void) 296 1.1 tsubai { 297 1.1 tsubai volatile int s; 298 1.1 tsubai 299 1.1 tsubai if (adbActionState == ADB_ACTION_IN) { 300 1.1 tsubai if (tickle_serial == adb_cuda_serial) { 301 1.1 tsubai if (++tickle_count > 0) { 302 1.1 tsubai s = splhigh(); 303 1.1 tsubai adbActionState = ADB_ACTION_IDLE; 304 1.1 tsubai adbInputBuffer[0] = 0; 305 1.1 tsubai ADB_SET_STATE_IDLE_CUDA(); 306 1.1 tsubai splx(s); 307 1.1 tsubai } 308 1.1 tsubai } else { 309 1.1 tsubai tickle_serial = adb_cuda_serial; 310 1.1 tsubai tickle_count = 0; 311 1.1 tsubai } 312 1.1 tsubai } else { 313 1.1 tsubai tickle_serial = adb_cuda_serial; 314 1.1 tsubai tickle_count = 0; 315 1.1 tsubai } 316 1.1 tsubai 317 1.13 thorpej callout_reset(&adb_cuda_tickle_ch, ADB_TICKLE_TICKS, 318 1.13 thorpej (void *)adb_cuda_tickle, NULL); 319 1.1 tsubai } 320 1.1 tsubai 321 1.1 tsubai /* 322 1.46 andvar * called when an adb interrupt happens 323 1.1 tsubai * 324 1.1 tsubai * Cuda version of adb_intr 325 1.6 tsubai * TO DO: do we want to add some calls to intr_dispatch() here to 326 1.6 tsubai * grab serial interrupts? 327 1.1 tsubai */ 328 1.30 briggs int 329 1.30 briggs adb_intr_cuda(void *arg) 330 1.1 tsubai { 331 1.1 tsubai volatile int i, ending; 332 1.1 tsubai volatile unsigned int s; 333 1.1 tsubai struct adbCommand packet; 334 1.29 briggs uint8_t reg; 335 1.1 tsubai 336 1.1 tsubai s = splhigh(); /* can't be too careful - might be called */ 337 1.29 briggs /* from a routine, NOT an interrupt */ 338 1.29 briggs 339 1.29 briggs reg = read_via_reg(VIA1, vIFR); /* Read the interrupts */ 340 1.29 briggs if ((reg & 0x80) == 0) { 341 1.29 briggs splx(s); 342 1.30 briggs return 0; /* No interrupts to process */ 343 1.29 briggs } 344 1.29 briggs 345 1.29 briggs write_via_reg(VIA1, vIFR, reg & 0x7f); /* Clear 'em */ 346 1.1 tsubai 347 1.1 tsubai ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */ 348 1.1 tsubai 349 1.1 tsubai switch_start: 350 1.1 tsubai switch (adbActionState) { 351 1.1 tsubai case ADB_ACTION_IDLE: 352 1.1 tsubai /* 353 1.1 tsubai * This is an unexpected packet, so grab the first (dummy) 354 1.1 tsubai * byte, set up the proper vars, and tell the chip we are 355 1.1 tsubai * starting to receive the packet by setting the TIP bit. 356 1.1 tsubai */ 357 1.1 tsubai adbInputBuffer[1] = ADB_SR(); 358 1.1 tsubai adb_cuda_serial++; 359 1.1 tsubai if (ADB_INTR_IS_OFF) /* must have been a fake start */ 360 1.1 tsubai break; 361 1.1 tsubai 362 1.1 tsubai ADB_SET_SR_INPUT(); 363 1.1 tsubai ADB_SET_STATE_TIP(); 364 1.1 tsubai 365 1.1 tsubai adbInputBuffer[0] = 1; 366 1.1 tsubai adbActionState = ADB_ACTION_IN; 367 1.1 tsubai #ifdef ADB_DEBUG 368 1.1 tsubai if (adb_debug) 369 1.1 tsubai printf_intr("idle 0x%02x ", adbInputBuffer[1]); 370 1.1 tsubai #endif 371 1.1 tsubai break; 372 1.1 tsubai 373 1.1 tsubai case ADB_ACTION_IN: 374 1.1 tsubai adbInputBuffer[++adbInputBuffer[0]] = ADB_SR(); 375 1.1 tsubai /* intr off means this is the last byte (end of frame) */ 376 1.1 tsubai if (ADB_INTR_IS_OFF) 377 1.1 tsubai ending = 1; 378 1.1 tsubai else 379 1.1 tsubai ending = 0; 380 1.1 tsubai 381 1.1 tsubai if (1 == ending) { /* end of message? */ 382 1.1 tsubai #ifdef ADB_DEBUG 383 1.1 tsubai if (adb_debug) { 384 1.1 tsubai printf_intr("in end 0x%02x ", 385 1.1 tsubai adbInputBuffer[adbInputBuffer[0]]); 386 1.1 tsubai print_single(adbInputBuffer); 387 1.1 tsubai } 388 1.1 tsubai #endif 389 1.1 tsubai 390 1.1 tsubai /* 391 1.1 tsubai * Are we waiting AND does this packet match what we 392 1.1 tsubai * are waiting for AND is it coming from either the 393 1.1 tsubai * ADB or RTC/PRAM sub-device? This section _should_ 394 1.1 tsubai * recognize all ADB and RTC/PRAM type commands, but 395 1.1 tsubai * there may be more... NOTE: commands are always at 396 1.1 tsubai * [4], even for RTC/PRAM commands. 397 1.1 tsubai */ 398 1.1 tsubai /* set up data for adb_pass_up */ 399 1.14 tsubai memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1); 400 1.1 tsubai 401 1.1 tsubai if ((adbWaiting == 1) && 402 1.1 tsubai (adbInputBuffer[4] == adbWaitingCmd) && 403 1.1 tsubai ((adbInputBuffer[2] == 0x00) || 404 1.1 tsubai (adbInputBuffer[2] == 0x01))) { 405 1.1 tsubai packet.saveBuf = adbBuffer; 406 1.1 tsubai packet.compRout = adbCompRout; 407 1.1 tsubai packet.compData = adbCompData; 408 1.1 tsubai packet.unsol = 0; 409 1.1 tsubai packet.ack_only = 0; 410 1.1 tsubai adb_pass_up(&packet); 411 1.1 tsubai 412 1.1 tsubai adbWaitingCmd = 0; /* reset "waiting" vars */ 413 1.1 tsubai adbWaiting = 0; 414 1.1 tsubai adbBuffer = (long)0; 415 1.1 tsubai adbCompRout = (long)0; 416 1.1 tsubai adbCompData = (long)0; 417 1.1 tsubai } else { 418 1.1 tsubai packet.unsol = 1; 419 1.1 tsubai packet.ack_only = 0; 420 1.1 tsubai adb_pass_up(&packet); 421 1.1 tsubai } 422 1.1 tsubai 423 1.1 tsubai 424 1.1 tsubai /* reset vars and signal the end of this frame */ 425 1.1 tsubai adbActionState = ADB_ACTION_IDLE; 426 1.1 tsubai adbInputBuffer[0] = 0; 427 1.1 tsubai ADB_SET_STATE_IDLE_CUDA(); 428 1.1 tsubai /*ADB_SET_SR_INPUT();*/ 429 1.1 tsubai 430 1.1 tsubai /* 431 1.1 tsubai * If there is something waiting to be sent out, 432 1.1 tsubai * the set everything up and send the first byte. 433 1.1 tsubai */ 434 1.1 tsubai if (adbWriteDelay == 1) { 435 1.1 tsubai delay(ADB_DELAY); /* required */ 436 1.1 tsubai adbSentChars = 0; 437 1.1 tsubai adbActionState = ADB_ACTION_OUT; 438 1.1 tsubai /* 439 1.1 tsubai * If the interrupt is on, we were too slow 440 1.1 tsubai * and the chip has already started to send 441 1.1 tsubai * something to us, so back out of the write 442 1.1 tsubai * and start a read cycle. 443 1.1 tsubai */ 444 1.1 tsubai if (ADB_INTR_IS_ON) { 445 1.1 tsubai ADB_SET_SR_INPUT(); 446 1.1 tsubai ADB_SET_STATE_IDLE_CUDA(); 447 1.1 tsubai adbSentChars = 0; 448 1.1 tsubai adbActionState = ADB_ACTION_IDLE; 449 1.1 tsubai adbInputBuffer[0] = 0; 450 1.1 tsubai break; 451 1.1 tsubai } 452 1.1 tsubai /* 453 1.1 tsubai * If we got here, it's ok to start sending 454 1.1 tsubai * so load the first byte and tell the chip 455 1.1 tsubai * we want to send. 456 1.1 tsubai */ 457 1.1 tsubai ADB_SET_STATE_TIP(); 458 1.1 tsubai ADB_SET_SR_OUTPUT(); 459 1.1 tsubai write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]); 460 1.1 tsubai } 461 1.1 tsubai } else { 462 1.1 tsubai ADB_TOGGLE_STATE_ACK_CUDA(); 463 1.1 tsubai #ifdef ADB_DEBUG 464 1.1 tsubai if (adb_debug) 465 1.1 tsubai printf_intr("in 0x%02x ", 466 1.1 tsubai adbInputBuffer[adbInputBuffer[0]]); 467 1.1 tsubai #endif 468 1.1 tsubai } 469 1.1 tsubai break; 470 1.1 tsubai 471 1.1 tsubai case ADB_ACTION_OUT: 472 1.1 tsubai i = ADB_SR(); /* reset SR-intr in IFR */ 473 1.1 tsubai #ifdef ADB_DEBUG 474 1.1 tsubai if (adb_debug) 475 1.1 tsubai printf_intr("intr out 0x%02x ", i); 476 1.1 tsubai #endif 477 1.1 tsubai 478 1.1 tsubai adbSentChars++; 479 1.1 tsubai if (ADB_INTR_IS_ON) { /* ADB intr low during write */ 480 1.1 tsubai #ifdef ADB_DEBUG 481 1.1 tsubai if (adb_debug) 482 1.1 tsubai printf_intr("intr was on "); 483 1.1 tsubai #endif 484 1.1 tsubai ADB_SET_SR_INPUT(); /* make sure SR is set to IN */ 485 1.1 tsubai ADB_SET_STATE_IDLE_CUDA(); 486 1.1 tsubai adbSentChars = 0; /* must start all over */ 487 1.1 tsubai adbActionState = ADB_ACTION_IDLE; /* new state */ 488 1.1 tsubai adbInputBuffer[0] = 0; 489 1.1 tsubai adbWriteDelay = 1; /* must retry when done with 490 1.1 tsubai * read */ 491 1.1 tsubai delay(ADB_DELAY); 492 1.1 tsubai goto switch_start; /* process next state right 493 1.1 tsubai * now */ 494 1.1 tsubai break; 495 1.1 tsubai } 496 1.1 tsubai if (adbOutputBuffer[0] == adbSentChars) { /* check for done */ 497 1.1 tsubai if (0 == adb_cmd_result(adbOutputBuffer)) { /* do we expect data 498 1.1 tsubai * back? */ 499 1.1 tsubai adbWaiting = 1; /* signal waiting for return */ 500 1.1 tsubai adbWaitingCmd = adbOutputBuffer[2]; /* save waiting command */ 501 1.1 tsubai } else { /* no talk, so done */ 502 1.1 tsubai /* set up stuff for adb_pass_up */ 503 1.14 tsubai memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1); 504 1.1 tsubai packet.saveBuf = adbBuffer; 505 1.1 tsubai packet.compRout = adbCompRout; 506 1.1 tsubai packet.compData = adbCompData; 507 1.1 tsubai packet.cmd = adbWaitingCmd; 508 1.1 tsubai packet.unsol = 0; 509 1.1 tsubai packet.ack_only = 1; 510 1.1 tsubai adb_pass_up(&packet); 511 1.1 tsubai 512 1.1 tsubai /* reset "waiting" vars, just in case */ 513 1.1 tsubai adbWaitingCmd = 0; 514 1.1 tsubai adbBuffer = (long)0; 515 1.32 nathanw adbCompRout = NULL; 516 1.32 nathanw adbCompData = NULL; 517 1.1 tsubai } 518 1.1 tsubai 519 1.1 tsubai adbWriteDelay = 0; /* done writing */ 520 1.1 tsubai adbActionState = ADB_ACTION_IDLE; /* signal bus is idle */ 521 1.1 tsubai ADB_SET_SR_INPUT(); 522 1.1 tsubai ADB_SET_STATE_IDLE_CUDA(); 523 1.1 tsubai #ifdef ADB_DEBUG 524 1.1 tsubai if (adb_debug) 525 1.1 tsubai printf_intr("write done "); 526 1.1 tsubai #endif 527 1.1 tsubai } else { 528 1.1 tsubai write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]); /* send next byte */ 529 1.1 tsubai ADB_TOGGLE_STATE_ACK_CUDA(); /* signal byte ready to 530 1.1 tsubai * shift */ 531 1.1 tsubai #ifdef ADB_DEBUG 532 1.1 tsubai if (adb_debug) 533 1.1 tsubai printf_intr("toggle "); 534 1.1 tsubai #endif 535 1.1 tsubai } 536 1.1 tsubai break; 537 1.1 tsubai 538 1.1 tsubai case ADB_ACTION_NOTREADY: 539 1.6 tsubai #ifdef ADB_DEBUG 540 1.6 tsubai if (adb_debug) 541 1.6 tsubai printf_intr("adb: not yet initialized\n"); 542 1.6 tsubai #endif 543 1.1 tsubai break; 544 1.1 tsubai 545 1.1 tsubai default: 546 1.6 tsubai #ifdef ADB_DEBUG 547 1.6 tsubai if (adb_debug) 548 1.6 tsubai printf_intr("intr: unknown ADB state\n"); 549 1.6 tsubai #endif 550 1.19 tsubai break; 551 1.1 tsubai } 552 1.1 tsubai 553 1.1 tsubai ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */ 554 1.1 tsubai 555 1.1 tsubai splx(s); /* restore */ 556 1.1 tsubai 557 1.30 briggs return 1; 558 1.1 tsubai } /* end adb_intr_cuda */ 559 1.1 tsubai 560 1.1 tsubai 561 1.1 tsubai int 562 1.32 nathanw send_adb_cuda(u_char * in, u_char * buffer, adbComp *compRout, 563 1.32 nathanw volatile void *data, int command) 564 1.1 tsubai { 565 1.14 tsubai int s, len; 566 1.1 tsubai 567 1.1 tsubai #ifdef ADB_DEBUG 568 1.1 tsubai if (adb_debug) 569 1.1 tsubai printf_intr("SEND\n"); 570 1.1 tsubai #endif 571 1.1 tsubai 572 1.1 tsubai if (adbActionState == ADB_ACTION_NOTREADY) 573 1.1 tsubai return 1; 574 1.1 tsubai 575 1.1 tsubai /* Don't interrupt while we are messing with the ADB */ 576 1.1 tsubai s = splhigh(); 577 1.1 tsubai 578 1.1 tsubai if ((adbActionState == ADB_ACTION_IDLE) && /* ADB available? */ 579 1.1 tsubai (ADB_INTR_IS_OFF)) { /* and no incoming interrupt? */ 580 1.1 tsubai } else 581 1.1 tsubai if (adbWriteDelay == 0) /* it's busy, but is anything waiting? */ 582 1.1 tsubai adbWriteDelay = 1; /* if no, then we'll "queue" 583 1.1 tsubai * it up */ 584 1.1 tsubai else { 585 1.1 tsubai splx(s); 586 1.1 tsubai return 1; /* really busy! */ 587 1.1 tsubai } 588 1.1 tsubai 589 1.1 tsubai #ifdef ADB_DEBUG 590 1.1 tsubai if (adb_debug) 591 1.1 tsubai printf_intr("QUEUE\n"); 592 1.1 tsubai #endif 593 1.1 tsubai if ((long)in == (long)0) { /* need to convert? */ 594 1.1 tsubai /* 595 1.1 tsubai * Don't need to use adb_cmd_extra here because this section 596 1.1 tsubai * will be called ONLY when it is an ADB command (no RTC or 597 1.1 tsubai * PRAM) 598 1.1 tsubai */ 599 1.1 tsubai if ((command & 0x0c) == 0x08) /* copy addl data ONLY if 600 1.1 tsubai * doing a listen! */ 601 1.1 tsubai len = buffer[0]; /* length of additional data */ 602 1.1 tsubai else 603 1.1 tsubai len = 0;/* no additional data */ 604 1.1 tsubai 605 1.1 tsubai adbOutputBuffer[0] = 2 + len; /* dev. type + command + addl. 606 1.1 tsubai * data */ 607 1.1 tsubai adbOutputBuffer[1] = 0x00; /* mark as an ADB command */ 608 1.1 tsubai adbOutputBuffer[2] = (u_char)command; /* load command */ 609 1.1 tsubai 610 1.14 tsubai /* copy additional output data, if any */ 611 1.14 tsubai memcpy(adbOutputBuffer + 3, buffer + 1, len); 612 1.1 tsubai } else 613 1.14 tsubai /* if data ready, just copy over */ 614 1.14 tsubai memcpy(adbOutputBuffer, in, in[0] + 2); 615 1.1 tsubai 616 1.1 tsubai adbSentChars = 0; /* nothing sent yet */ 617 1.1 tsubai adbBuffer = buffer; /* save buffer to know where to save result */ 618 1.1 tsubai adbCompRout = compRout; /* save completion routine pointer */ 619 1.1 tsubai adbCompData = data; /* save completion routine data pointer */ 620 1.1 tsubai adbWaitingCmd = adbOutputBuffer[2]; /* save wait command */ 621 1.1 tsubai 622 1.1 tsubai if (adbWriteDelay != 1) { /* start command now? */ 623 1.1 tsubai #ifdef ADB_DEBUG 624 1.1 tsubai if (adb_debug) 625 1.1 tsubai printf_intr("out start NOW"); 626 1.1 tsubai #endif 627 1.1 tsubai delay(ADB_DELAY); 628 1.1 tsubai adbActionState = ADB_ACTION_OUT; /* set next state */ 629 1.1 tsubai ADB_SET_SR_OUTPUT(); /* set shift register for OUT */ 630 1.1 tsubai write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]); /* load byte for output */ 631 1.1 tsubai ADB_SET_STATE_ACKOFF_CUDA(); 632 1.1 tsubai ADB_SET_STATE_TIP(); /* tell ADB that we want to send */ 633 1.1 tsubai } 634 1.1 tsubai adbWriteDelay = 1; /* something in the write "queue" */ 635 1.1 tsubai 636 1.1 tsubai splx(s); 637 1.1 tsubai 638 1.1 tsubai if ((s & (1 << 18)) || adb_polling) /* XXX were VIA1 interrupts blocked ? */ 639 1.1 tsubai /* poll until byte done */ 640 1.1 tsubai while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON) 641 1.1 tsubai || (adbWaiting == 1)) 642 1.1 tsubai if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */ 643 1.30 briggs adb_intr_cuda(NULL); /* process it */ 644 1.1 tsubai adb_soft_intr(); 645 1.1 tsubai } 646 1.1 tsubai 647 1.1 tsubai return 0; 648 1.1 tsubai } /* send_adb_cuda */ 649 1.1 tsubai 650 1.30 briggs int 651 1.30 briggs adb_intr(void *arg) 652 1.1 tsubai { 653 1.1 tsubai switch (adbHardware) { 654 1.28 briggs case ADB_HW_PMU: 655 1.30 briggs return pm_intr(arg); 656 1.1 tsubai break; 657 1.1 tsubai 658 1.1 tsubai case ADB_HW_CUDA: 659 1.30 briggs return adb_intr_cuda(arg); 660 1.1 tsubai break; 661 1.1 tsubai 662 1.1 tsubai case ADB_HW_UNKNOWN: 663 1.1 tsubai break; 664 1.1 tsubai } 665 1.30 briggs return 0; 666 1.1 tsubai } 667 1.1 tsubai 668 1.1 tsubai 669 1.1 tsubai /* 670 1.1 tsubai * adb_pass_up is called by the interrupt-time routines. 671 1.1 tsubai * It takes the raw packet data that was received from the 672 1.1 tsubai * device and puts it into the queue that the upper half 673 1.1 tsubai * processes. It then signals for a soft ADB interrupt which 674 1.1 tsubai * will eventually call the upper half routine (adb_soft_intr). 675 1.1 tsubai * 676 1.1 tsubai * If in->unsol is 0, then this is either the notification 677 1.1 tsubai * that the packet was sent (on a LISTEN, for example), or the 678 1.1 tsubai * response from the device (on a TALK). The completion routine 679 1.1 tsubai * is called only if the user specified one. 680 1.1 tsubai * 681 1.1 tsubai * If in->unsol is 1, then this packet was unsolicited and 682 1.1 tsubai * so we look up the device in the ADB device table to determine 683 1.44 snj * what its default service routine is. 684 1.1 tsubai * 685 1.1 tsubai * If in->ack_only is 1, then we really only need to call 686 1.1 tsubai * the completion routine, so don't do any other stuff. 687 1.1 tsubai * 688 1.1 tsubai * Note that in->data contains the packet header AND data, 689 1.1 tsubai * while adbInbound[]->data contains ONLY data. 690 1.1 tsubai * 691 1.1 tsubai * Note: Called only at interrupt time. Assumes this. 692 1.1 tsubai */ 693 1.1 tsubai void 694 1.1 tsubai adb_pass_up(struct adbCommand *in) 695 1.1 tsubai { 696 1.14 tsubai int start = 0, len = 0, cmd = 0; 697 1.1 tsubai ADBDataBlock block; 698 1.1 tsubai 699 1.1 tsubai /* temp for testing */ 700 1.1 tsubai /*u_char *buffer = 0;*/ 701 1.1 tsubai /*u_char *compdata = 0;*/ 702 1.1 tsubai /*u_char *comprout = 0;*/ 703 1.1 tsubai 704 1.1 tsubai if (adbInCount >= ADB_QUEUE) { 705 1.6 tsubai #ifdef ADB_DEBUG 706 1.6 tsubai if (adb_debug) 707 1.6 tsubai printf_intr("adb: ring buffer overflow\n"); 708 1.6 tsubai #endif 709 1.1 tsubai return; 710 1.1 tsubai } 711 1.1 tsubai 712 1.1 tsubai if (in->ack_only) { 713 1.1 tsubai len = in->data[0]; 714 1.1 tsubai cmd = in->cmd; 715 1.1 tsubai start = 0; 716 1.1 tsubai } else { 717 1.1 tsubai switch (adbHardware) { 718 1.1 tsubai case ADB_HW_CUDA: 719 1.1 tsubai /* If it's unsolicited, accept only ADB data for now */ 720 1.1 tsubai if (in->unsol) 721 1.1 tsubai if (0 != in->data[2]) 722 1.1 tsubai return; 723 1.1 tsubai cmd = in->data[4]; 724 1.1 tsubai if (in->data[0] < 5) 725 1.1 tsubai len = 0; 726 1.1 tsubai else 727 1.1 tsubai len = in->data[0]-4; 728 1.1 tsubai start = 4; 729 1.1 tsubai break; 730 1.1 tsubai 731 1.28 briggs case ADB_HW_PMU: 732 1.4 tsubai cmd = in->data[1]; 733 1.4 tsubai if (in->data[0] < 2) 734 1.4 tsubai len = 0; 735 1.4 tsubai else 736 1.4 tsubai len = in->data[0]-1; 737 1.4 tsubai start = 1; 738 1.4 tsubai break; 739 1.1 tsubai 740 1.1 tsubai case ADB_HW_UNKNOWN: 741 1.1 tsubai return; 742 1.1 tsubai } 743 1.1 tsubai 744 1.1 tsubai /* Make sure there is a valid device entry for this device */ 745 1.1 tsubai if (in->unsol) { 746 1.1 tsubai /* ignore unsolicited data during adbreinit */ 747 1.1 tsubai if (adbStarting) 748 1.1 tsubai return; 749 1.1 tsubai /* get device's comp. routine and data area */ 750 1.14 tsubai if (-1 == get_adb_info(&block, ADB_CMDADDR(cmd))) 751 1.1 tsubai return; 752 1.1 tsubai } 753 1.1 tsubai } 754 1.1 tsubai 755 1.1 tsubai /* 756 1.1 tsubai * If this is an unsolicited packet, we need to fill in 757 1.1 tsubai * some info so adb_soft_intr can process this packet 758 1.1 tsubai * properly. If it's not unsolicited, then use what 759 1.1 tsubai * the caller sent us. 760 1.1 tsubai */ 761 1.1 tsubai if (in->unsol) { 762 1.1 tsubai adbInbound[adbInTail].compRout = (void *)block.dbServiceRtPtr; 763 1.1 tsubai adbInbound[adbInTail].compData = (void *)block.dbDataAreaAddr; 764 1.1 tsubai adbInbound[adbInTail].saveBuf = (void *)adbInbound[adbInTail].data; 765 1.1 tsubai } else { 766 1.32 nathanw adbInbound[adbInTail].compRout = in->compRout; 767 1.32 nathanw adbInbound[adbInTail].compData = in->compData; 768 1.32 nathanw adbInbound[adbInTail].saveBuf = in->saveBuf; 769 1.1 tsubai } 770 1.1 tsubai 771 1.1 tsubai #ifdef ADB_DEBUG 772 1.1 tsubai if (adb_debug && in->data[1] == 2) 773 1.1 tsubai printf_intr("adb: caught error\n"); 774 1.1 tsubai #endif 775 1.1 tsubai 776 1.1 tsubai /* copy the packet data over */ 777 1.1 tsubai /* 778 1.1 tsubai * TO DO: If the *_intr routines fed their incoming data 779 1.1 tsubai * directly into an adbCommand struct, which is passed to 780 1.1 tsubai * this routine, then we could eliminate this copy. 781 1.1 tsubai */ 782 1.14 tsubai memcpy(adbInbound[adbInTail].data + 1, in->data + start + 1, len); 783 1.1 tsubai adbInbound[adbInTail].data[0] = len; 784 1.1 tsubai adbInbound[adbInTail].cmd = cmd; 785 1.1 tsubai 786 1.1 tsubai adbInCount++; 787 1.1 tsubai if (++adbInTail >= ADB_QUEUE) 788 1.1 tsubai adbInTail = 0; 789 1.1 tsubai 790 1.1 tsubai /* 791 1.1 tsubai * If the debugger is running, call upper half manually. 792 1.1 tsubai * Otherwise, trigger a soft interrupt to handle the rest later. 793 1.1 tsubai */ 794 1.1 tsubai if (adb_polling) 795 1.1 tsubai adb_soft_intr(); 796 1.1 tsubai else 797 1.1 tsubai setsoftadb(); 798 1.1 tsubai 799 1.1 tsubai return; 800 1.1 tsubai } 801 1.1 tsubai 802 1.1 tsubai 803 1.1 tsubai /* 804 1.1 tsubai * Called to process the packets after they have been 805 1.1 tsubai * placed in the incoming queue. 806 1.1 tsubai * 807 1.1 tsubai */ 808 1.1 tsubai void 809 1.1 tsubai adb_soft_intr(void) 810 1.1 tsubai { 811 1.14 tsubai int s; 812 1.1 tsubai int cmd = 0; 813 1.1 tsubai u_char *buffer = 0; 814 1.32 nathanw adbComp *comprout = NULL; 815 1.32 nathanw volatile int *compdata = 0; 816 1.1 tsubai 817 1.1 tsubai #if 0 818 1.1 tsubai s = splhigh(); 819 1.1 tsubai printf_intr("sr: %x\n", (s & 0x0700)); 820 1.1 tsubai splx(s); 821 1.1 tsubai #endif 822 1.1 tsubai 823 1.1 tsubai /*delay(2*ADB_DELAY);*/ 824 1.1 tsubai 825 1.1 tsubai while (adbInCount) { 826 1.1 tsubai #ifdef ADB_DEBUG 827 1.1 tsubai if (adb_debug & 0x80) 828 1.1 tsubai printf_intr("%x %x %x ", 829 1.1 tsubai adbInCount, adbInHead, adbInTail); 830 1.1 tsubai #endif 831 1.1 tsubai /* get the data we need from the queue */ 832 1.1 tsubai buffer = adbInbound[adbInHead].saveBuf; 833 1.1 tsubai comprout = adbInbound[adbInHead].compRout; 834 1.1 tsubai compdata = adbInbound[adbInHead].compData; 835 1.1 tsubai cmd = adbInbound[adbInHead].cmd; 836 1.1 tsubai 837 1.1 tsubai /* copy over data to data area if it's valid */ 838 1.1 tsubai /* 839 1.1 tsubai * Note that for unsol packets we don't want to copy the 840 1.1 tsubai * data anywhere, so buffer was already set to 0. 841 1.1 tsubai * For ack_only buffer was set to 0, so don't copy. 842 1.1 tsubai */ 843 1.1 tsubai if (buffer) 844 1.14 tsubai memcpy(buffer, adbInbound[adbInHead].data, 845 1.14 tsubai adbInbound[adbInHead].data[0] + 1); 846 1.1 tsubai 847 1.1 tsubai #ifdef ADB_DEBUG 848 1.1 tsubai if (adb_debug & 0x80) { 849 1.1 tsubai printf_intr("%p %p %p %x ", 850 1.1 tsubai buffer, comprout, compdata, (short)cmd); 851 1.1 tsubai printf_intr("buf: "); 852 1.1 tsubai print_single(adbInbound[adbInHead].data); 853 1.1 tsubai } 854 1.1 tsubai #endif 855 1.21 dbj /* Remove the packet from the queue before calling 856 1.21 dbj * the completion routine, so that the completion 857 1.21 dbj * routine can reentrantly process the queue. For 858 1.21 dbj * example, this happens when polling is turned on 859 1.47 andvar * by entering the debugger by keystroke. 860 1.21 dbj */ 861 1.21 dbj s = splhigh(); 862 1.21 dbj adbInCount--; 863 1.21 dbj if (++adbInHead >= ADB_QUEUE) 864 1.21 dbj adbInHead = 0; 865 1.21 dbj splx(s); 866 1.1 tsubai 867 1.1 tsubai /* call default completion routine if it's valid */ 868 1.32 nathanw if (comprout) 869 1.32 nathanw (*comprout)(buffer, compdata, cmd); 870 1.1 tsubai } 871 1.1 tsubai return; 872 1.1 tsubai } 873 1.1 tsubai 874 1.1 tsubai 875 1.1 tsubai /* 876 1.1 tsubai * This is my version of the ADBOp routine. It mainly just calls the 877 1.1 tsubai * hardware-specific routine. 878 1.1 tsubai * 879 1.1 tsubai * data : pointer to data area to be used by compRout 880 1.1 tsubai * compRout : completion routine 881 1.1 tsubai * buffer : for LISTEN: points to data to send - MAX 8 data bytes, 882 1.1 tsubai * byte 0 = # of bytes 883 1.1 tsubai * : for TALK: points to place to save return data 884 1.1 tsubai * command : the adb command to send 885 1.1 tsubai * result : 0 = success 886 1.1 tsubai * : -1 = could not complete 887 1.1 tsubai */ 888 1.1 tsubai int 889 1.32 nathanw adb_op(Ptr buffer, adbComp *compRout, volatile void *data, short command) 890 1.1 tsubai { 891 1.1 tsubai int result; 892 1.1 tsubai 893 1.1 tsubai switch (adbHardware) { 894 1.28 briggs case ADB_HW_PMU: 895 1.32 nathanw result = pm_adb_op((u_char *)buffer, compRout, 896 1.32 nathanw data, (int)command); 897 1.1 tsubai 898 1.1 tsubai if (result == 0) 899 1.1 tsubai return 0; 900 1.1 tsubai else 901 1.1 tsubai return -1; 902 1.1 tsubai break; 903 1.1 tsubai 904 1.1 tsubai case ADB_HW_CUDA: 905 1.1 tsubai result = send_adb_cuda((u_char *)0, (u_char *)buffer, 906 1.32 nathanw compRout, data, (int)command); 907 1.1 tsubai if (result == 0) 908 1.1 tsubai return 0; 909 1.1 tsubai else 910 1.1 tsubai return -1; 911 1.1 tsubai break; 912 1.1 tsubai 913 1.1 tsubai case ADB_HW_UNKNOWN: 914 1.1 tsubai default: 915 1.1 tsubai return -1; 916 1.1 tsubai } 917 1.1 tsubai } 918 1.1 tsubai 919 1.1 tsubai 920 1.1 tsubai /* 921 1.1 tsubai * adb_hw_setup 922 1.1 tsubai * This routine sets up the possible machine specific hardware 923 1.1 tsubai * config (mainly VIA settings) for the various models. 924 1.1 tsubai */ 925 1.1 tsubai void 926 1.1 tsubai adb_hw_setup(void) 927 1.1 tsubai { 928 1.1 tsubai volatile int i; 929 1.1 tsubai 930 1.1 tsubai switch (adbHardware) { 931 1.28 briggs case ADB_HW_PMU: 932 1.1 tsubai /* 933 1.1 tsubai * XXX - really PM_VIA_CLR_INTR - should we put it in 934 1.1 tsubai * pm_direct.h? 935 1.1 tsubai */ 936 1.4 tsubai write_via_reg(VIA1, vIFR, 0x90); /* clear interrupt */ 937 1.1 tsubai break; 938 1.1 tsubai 939 1.1 tsubai case ADB_HW_CUDA: 940 1.1 tsubai via_reg_or(VIA1, vDirB, 0x30); /* register B bits 4 and 5: 941 1.1 tsubai * outputs */ 942 1.1 tsubai via_reg_and(VIA1, vDirB, 0xf7); /* register B bit 3: input */ 943 1.1 tsubai via_reg_and(VIA1, vACR, ~vSR_OUT); /* make sure SR is set 944 1.1 tsubai * to IN */ 945 1.1 tsubai write_via_reg(VIA1, vACR, (read_via_reg(VIA1, vACR) | 0x0c) & ~0x10); 946 1.1 tsubai adbActionState = ADB_ACTION_IDLE; /* used by all types of 947 1.1 tsubai * hardware */ 948 1.1 tsubai write_via_reg(VIA1, vIER, 0x84);/* make sure VIA interrupts 949 1.1 tsubai * are on */ 950 1.1 tsubai ADB_SET_STATE_IDLE_CUDA(); /* set ADB bus state to idle */ 951 1.1 tsubai 952 1.1 tsubai /* sort of a device reset */ 953 1.1 tsubai i = ADB_SR(); /* clear interrupt */ 954 1.1 tsubai ADB_VIA_INTR_DISABLE(); /* no interrupts while clearing */ 955 1.1 tsubai ADB_SET_STATE_IDLE_CUDA(); /* reset state to idle */ 956 1.1 tsubai delay(ADB_DELAY); 957 1.1 tsubai ADB_SET_STATE_TIP(); /* signal start of frame */ 958 1.1 tsubai delay(ADB_DELAY); 959 1.1 tsubai ADB_TOGGLE_STATE_ACK_CUDA(); 960 1.1 tsubai delay(ADB_DELAY); 961 1.1 tsubai ADB_CLR_STATE_TIP(); 962 1.1 tsubai delay(ADB_DELAY); 963 1.1 tsubai ADB_SET_STATE_IDLE_CUDA(); /* back to idle state */ 964 1.1 tsubai i = ADB_SR(); /* clear interrupt */ 965 1.1 tsubai ADB_VIA_INTR_ENABLE(); /* ints ok now */ 966 1.1 tsubai break; 967 1.1 tsubai 968 1.1 tsubai case ADB_HW_UNKNOWN: 969 1.1 tsubai default: 970 1.4 tsubai write_via_reg(VIA1, vIER, 0x04);/* turn interrupts off - TO 971 1.1 tsubai * DO: turn PB ints off? */ 972 1.1 tsubai return; 973 1.1 tsubai break; 974 1.1 tsubai } 975 1.1 tsubai } 976 1.1 tsubai 977 1.1 tsubai /* 978 1.1 tsubai * adb_reinit sets up the adb stuff 979 1.1 tsubai * 980 1.1 tsubai */ 981 1.1 tsubai void 982 1.1 tsubai adb_reinit(void) 983 1.1 tsubai { 984 1.1 tsubai u_char send_string[ADB_MAX_MSG_LENGTH]; 985 1.14 tsubai ADBDataBlock data; /* temp. holder for getting device info */ 986 1.1 tsubai volatile int i, x; 987 1.27 dyoung int s = 0; /* XXX: gcc */ 988 1.1 tsubai int command; 989 1.1 tsubai int result; 990 1.1 tsubai int saveptr; /* point to next free relocation address */ 991 1.1 tsubai int device; 992 1.1 tsubai int nonewtimes; /* times thru loop w/o any new devices */ 993 1.38 ad static bool callo; 994 1.38 ad 995 1.38 ad if (!callo) { 996 1.38 ad callo = true; 997 1.38 ad callout_init(&adb_cuda_tickle_ch, 0); 998 1.38 ad callout_init(&adb_soft_intr_ch, 0); 999 1.38 ad } 1000 1.1 tsubai 1001 1.1 tsubai /* Make sure we are not interrupted while building the table. */ 1002 1.28 briggs if (adbHardware != ADB_HW_PMU) /* ints must be on for PMU? */ 1003 1.1 tsubai s = splhigh(); 1004 1.1 tsubai 1005 1.1 tsubai ADBNumDevices = 0; /* no devices yet */ 1006 1.1 tsubai 1007 1.1 tsubai /* Let intr routines know we are running reinit */ 1008 1.1 tsubai adbStarting = 1; 1009 1.1 tsubai 1010 1.1 tsubai /* 1011 1.1 tsubai * Initialize the ADB table. For now, we'll always use the same table 1012 1.1 tsubai * that is defined at the beginning of this file - no mallocs. 1013 1.1 tsubai */ 1014 1.1 tsubai for (i = 0; i < 16; i++) 1015 1.1 tsubai ADBDevTable[i].devType = 0; 1016 1.1 tsubai 1017 1.1 tsubai adb_setup_hw_type(); /* setup hardware type */ 1018 1.1 tsubai 1019 1.1 tsubai adb_hw_setup(); /* init the VIA bits and hard reset ADB */ 1020 1.1 tsubai 1021 1.8 tsubai delay(1000); 1022 1.1 tsubai 1023 1.1 tsubai /* send an ADB reset first */ 1024 1.32 nathanw result = adb_op_sync((Ptr)0, NULL, (Ptr)0, (short)0x00); 1025 1.16 tsubai delay(200000); 1026 1.1 tsubai 1027 1.20 dbj #ifdef ADB_DEBUG 1028 1.20 dbj if (result && adb_debug) { 1029 1.20 dbj printf_intr("adb_reinit: failed to reset, result = %d\n",result); 1030 1.20 dbj } 1031 1.20 dbj #endif 1032 1.20 dbj 1033 1.1 tsubai /* 1034 1.1 tsubai * Probe for ADB devices. Probe devices 1-15 quickly to determine 1035 1.1 tsubai * which device addresses are in use and which are free. For each 1036 1.1 tsubai * address that is in use, move the device at that address to a higher 1037 1.1 tsubai * free address. Continue doing this at that address until no device 1038 1.1 tsubai * responds at that address. Then move the last device that was moved 1039 1.1 tsubai * back to the original address. Do this for the remaining addresses 1040 1.1 tsubai * that we determined were in use. 1041 1.1 tsubai * 1042 1.1 tsubai * When finished, do this entire process over again with the updated 1043 1.1 tsubai * list of in use addresses. Do this until no new devices have been 1044 1.1 tsubai * found in 20 passes though the in use address list. (This probably 1045 1.1 tsubai * seems long and complicated, but it's the best way to detect multiple 1046 1.1 tsubai * devices at the same address - sometimes it takes a couple of tries 1047 1.1 tsubai * before the collision is detected.) 1048 1.1 tsubai */ 1049 1.1 tsubai 1050 1.1 tsubai /* initial scan through the devices */ 1051 1.1 tsubai for (i = 1; i < 16; i++) { 1052 1.12 tsubai send_string[0] = 0; 1053 1.14 tsubai command = ADBTALK(i, 3); 1054 1.32 nathanw result = adb_op_sync((Ptr)send_string, NULL, 1055 1.1 tsubai (Ptr)0, (short)command); 1056 1.20 dbj 1057 1.20 dbj #ifdef ADB_DEBUG 1058 1.20 dbj if (result && adb_debug) { 1059 1.20 dbj printf_intr("adb_reinit: scan of device %d, result = %d, str = 0x%x\n", 1060 1.20 dbj i,result,send_string[0]); 1061 1.20 dbj } 1062 1.20 dbj #endif 1063 1.14 tsubai 1064 1.14 tsubai if (send_string[0] != 0) { 1065 1.14 tsubai /* check for valid device handler */ 1066 1.14 tsubai switch (send_string[2]) { 1067 1.14 tsubai case 0: 1068 1.14 tsubai case 0xfd: 1069 1.14 tsubai case 0xfe: 1070 1.14 tsubai case 0xff: 1071 1.14 tsubai continue; /* invalid, skip */ 1072 1.14 tsubai } 1073 1.14 tsubai 1074 1.14 tsubai /* found a device */ 1075 1.14 tsubai ++ADBNumDevices; 1076 1.14 tsubai KASSERT(ADBNumDevices < 16); 1077 1.14 tsubai ADBDevTable[ADBNumDevices].devType = 1078 1.14 tsubai (int)send_string[2]; 1079 1.1 tsubai ADBDevTable[ADBNumDevices].origAddr = i; 1080 1.1 tsubai ADBDevTable[ADBNumDevices].currentAddr = i; 1081 1.1 tsubai ADBDevTable[ADBNumDevices].DataAreaAddr = 1082 1.1 tsubai (long)0; 1083 1.1 tsubai ADBDevTable[ADBNumDevices].ServiceRtPtr = (void *)0; 1084 1.1 tsubai pm_check_adb_devices(i); /* tell pm driver device 1085 1.1 tsubai * is here */ 1086 1.1 tsubai } 1087 1.1 tsubai } 1088 1.1 tsubai 1089 1.1 tsubai /* find highest unused address */ 1090 1.1 tsubai for (saveptr = 15; saveptr > 0; saveptr--) 1091 1.1 tsubai if (-1 == get_adb_info(&data, saveptr)) 1092 1.1 tsubai break; 1093 1.1 tsubai 1094 1.1 tsubai #ifdef ADB_DEBUG 1095 1.1 tsubai if (adb_debug & 0x80) { 1096 1.1 tsubai printf_intr("first free is: 0x%02x\n", saveptr); 1097 1.1 tsubai printf_intr("devices: %i\n", ADBNumDevices); 1098 1.1 tsubai } 1099 1.1 tsubai #endif 1100 1.1 tsubai 1101 1.1 tsubai nonewtimes = 0; /* no loops w/o new devices */ 1102 1.14 tsubai while (saveptr > 0 && nonewtimes++ < 11) { 1103 1.1 tsubai for (i = 1; i <= ADBNumDevices; i++) { 1104 1.1 tsubai device = ADBDevTable[i].currentAddr; 1105 1.1 tsubai #ifdef ADB_DEBUG 1106 1.1 tsubai if (adb_debug & 0x80) 1107 1.1 tsubai printf_intr("moving device 0x%02x to 0x%02x " 1108 1.1 tsubai "(index 0x%02x) ", device, saveptr, i); 1109 1.1 tsubai #endif 1110 1.1 tsubai 1111 1.1 tsubai /* send TALK R3 to address */ 1112 1.14 tsubai command = ADBTALK(device, 3); 1113 1.32 nathanw adb_op_sync((Ptr)send_string, NULL, 1114 1.1 tsubai (Ptr)0, (short)command); 1115 1.1 tsubai 1116 1.1 tsubai /* move device to higher address */ 1117 1.14 tsubai command = ADBLISTEN(device, 3); 1118 1.1 tsubai send_string[0] = 2; 1119 1.1 tsubai send_string[1] = (u_char)(saveptr | 0x60); 1120 1.1 tsubai send_string[2] = 0xfe; 1121 1.32 nathanw adb_op_sync((Ptr)send_string, NULL, 1122 1.1 tsubai (Ptr)0, (short)command); 1123 1.8 tsubai delay(500); 1124 1.1 tsubai 1125 1.14 tsubai /* send TALK R3 - anything at new address? */ 1126 1.14 tsubai command = ADBTALK(saveptr, 3); 1127 1.32 nathanw adb_op_sync((Ptr)send_string, NULL, 1128 1.14 tsubai (Ptr)0, (short)command); 1129 1.14 tsubai delay(500); 1130 1.14 tsubai 1131 1.14 tsubai if (send_string[0] == 0) { 1132 1.14 tsubai #ifdef ADB_DEBUG 1133 1.14 tsubai if (adb_debug & 0x80) 1134 1.14 tsubai printf_intr("failed, continuing\n"); 1135 1.14 tsubai #endif 1136 1.14 tsubai continue; 1137 1.14 tsubai } 1138 1.14 tsubai 1139 1.1 tsubai /* send TALK R3 - anything at old address? */ 1140 1.14 tsubai command = ADBTALK(device, 3); 1141 1.32 nathanw result = adb_op_sync((Ptr)send_string, NULL, 1142 1.1 tsubai (Ptr)0, (short)command); 1143 1.1 tsubai if (send_string[0] != 0) { 1144 1.14 tsubai /* check for valid device handler */ 1145 1.14 tsubai switch (send_string[2]) { 1146 1.14 tsubai case 0: 1147 1.14 tsubai case 0xfd: 1148 1.14 tsubai case 0xfe: 1149 1.14 tsubai case 0xff: 1150 1.14 tsubai continue; /* invalid, skip */ 1151 1.14 tsubai } 1152 1.14 tsubai 1153 1.1 tsubai /* new device found */ 1154 1.1 tsubai /* update data for previously moved device */ 1155 1.1 tsubai ADBDevTable[i].currentAddr = saveptr; 1156 1.1 tsubai #ifdef ADB_DEBUG 1157 1.1 tsubai if (adb_debug & 0x80) 1158 1.1 tsubai printf_intr("old device at index %i\n",i); 1159 1.1 tsubai #endif 1160 1.1 tsubai /* add new device in table */ 1161 1.1 tsubai #ifdef ADB_DEBUG 1162 1.1 tsubai if (adb_debug & 0x80) 1163 1.1 tsubai printf_intr("new device found\n"); 1164 1.1 tsubai #endif 1165 1.14 tsubai if (saveptr > ADBNumDevices) { 1166 1.14 tsubai ++ADBNumDevices; 1167 1.14 tsubai KASSERT(ADBNumDevices < 16); 1168 1.14 tsubai } 1169 1.14 tsubai ADBDevTable[ADBNumDevices].devType = 1170 1.14 tsubai (int)send_string[2]; 1171 1.1 tsubai ADBDevTable[ADBNumDevices].origAddr = device; 1172 1.1 tsubai ADBDevTable[ADBNumDevices].currentAddr = device; 1173 1.1 tsubai /* These will be set correctly in adbsys.c */ 1174 1.1 tsubai /* Until then, unsol. data will be ignored. */ 1175 1.1 tsubai ADBDevTable[ADBNumDevices].DataAreaAddr = 1176 1.1 tsubai (long)0; 1177 1.1 tsubai ADBDevTable[ADBNumDevices].ServiceRtPtr = 1178 1.1 tsubai (void *)0; 1179 1.1 tsubai /* find next unused address */ 1180 1.14 tsubai for (x = saveptr; x > 0; x--) { 1181 1.1 tsubai if (-1 == get_adb_info(&data, x)) { 1182 1.1 tsubai saveptr = x; 1183 1.1 tsubai break; 1184 1.1 tsubai } 1185 1.14 tsubai } 1186 1.14 tsubai if (x == 0) 1187 1.14 tsubai saveptr = 0; 1188 1.1 tsubai #ifdef ADB_DEBUG 1189 1.1 tsubai if (adb_debug & 0x80) 1190 1.1 tsubai printf_intr("new free is 0x%02x\n", 1191 1.1 tsubai saveptr); 1192 1.1 tsubai #endif 1193 1.1 tsubai nonewtimes = 0; 1194 1.1 tsubai /* tell pm driver device is here */ 1195 1.1 tsubai pm_check_adb_devices(device); 1196 1.1 tsubai } else { 1197 1.1 tsubai #ifdef ADB_DEBUG 1198 1.1 tsubai if (adb_debug & 0x80) 1199 1.1 tsubai printf_intr("moving back...\n"); 1200 1.1 tsubai #endif 1201 1.1 tsubai /* move old device back */ 1202 1.14 tsubai command = ADBLISTEN(saveptr, 3); 1203 1.1 tsubai send_string[0] = 2; 1204 1.1 tsubai send_string[1] = (u_char)(device | 0x60); 1205 1.1 tsubai send_string[2] = 0xfe; 1206 1.32 nathanw adb_op_sync((Ptr)send_string, NULL, 1207 1.1 tsubai (Ptr)0, (short)command); 1208 1.8 tsubai delay(1000); 1209 1.1 tsubai } 1210 1.1 tsubai } 1211 1.1 tsubai } 1212 1.1 tsubai 1213 1.1 tsubai #ifdef ADB_DEBUG 1214 1.1 tsubai if (adb_debug) { 1215 1.1 tsubai for (i = 1; i <= ADBNumDevices; i++) { 1216 1.1 tsubai x = get_ind_adb_info(&data, i); 1217 1.1 tsubai if (x != -1) 1218 1.1 tsubai printf_intr("index 0x%x, addr 0x%x, type 0x%x\n", 1219 1.1 tsubai i, x, data.devType); 1220 1.1 tsubai } 1221 1.1 tsubai } 1222 1.1 tsubai #endif 1223 1.1 tsubai 1224 1.6 tsubai #ifdef ADB_DEBUG 1225 1.6 tsubai if (adb_debug) { 1226 1.6 tsubai if (0 == ADBNumDevices) /* tell user if no devices found */ 1227 1.6 tsubai printf_intr("adb: no devices found\n"); 1228 1.6 tsubai } 1229 1.6 tsubai #endif 1230 1.1 tsubai 1231 1.1 tsubai adbStarting = 0; /* not starting anymore */ 1232 1.1 tsubai #ifdef ADB_DEBUG 1233 1.6 tsubai if (adb_debug) 1234 1.6 tsubai printf_intr("adb: ADBReInit complete\n"); 1235 1.1 tsubai #endif 1236 1.1 tsubai 1237 1.1 tsubai if (adbHardware == ADB_HW_CUDA) 1238 1.13 thorpej callout_reset(&adb_cuda_tickle_ch, ADB_TICKLE_TICKS, 1239 1.13 thorpej (void *)adb_cuda_tickle, NULL); 1240 1.1 tsubai 1241 1.28 briggs if (adbHardware != ADB_HW_PMU) /* ints must be on for PMU? */ 1242 1.1 tsubai splx(s); 1243 1.1 tsubai } 1244 1.1 tsubai 1245 1.1 tsubai /* 1246 1.1 tsubai * adb_cmd_result 1247 1.1 tsubai * 1248 1.1 tsubai * This routine lets the caller know whether the specified adb command string 1249 1.1 tsubai * should expect a returned result, such as a TALK command. 1250 1.1 tsubai * 1251 1.1 tsubai * returns: 0 if a result should be expected 1252 1.1 tsubai * 1 if a result should NOT be expected 1253 1.1 tsubai */ 1254 1.1 tsubai int 1255 1.1 tsubai adb_cmd_result(u_char *in) 1256 1.1 tsubai { 1257 1.1 tsubai switch (adbHardware) { 1258 1.1 tsubai case ADB_HW_CUDA: 1259 1.1 tsubai /* was it an ADB talk command? */ 1260 1.1 tsubai if ((in[1] == 0x00) && ((in[2] & 0x0c) == 0x0c)) 1261 1.1 tsubai return 0; 1262 1.1 tsubai /* was it an RTC/PRAM read date/time? */ 1263 1.1 tsubai if ((in[1] == 0x01) && (in[2] == 0x03)) 1264 1.1 tsubai return 0; 1265 1.1 tsubai return 1; 1266 1.1 tsubai 1267 1.28 briggs case ADB_HW_PMU: 1268 1.1 tsubai return 1; 1269 1.1 tsubai 1270 1.1 tsubai case ADB_HW_UNKNOWN: 1271 1.1 tsubai default: 1272 1.1 tsubai return 1; 1273 1.1 tsubai } 1274 1.1 tsubai } 1275 1.1 tsubai 1276 1.1 tsubai 1277 1.1 tsubai /* 1278 1.1 tsubai * adb_cmd_extra 1279 1.1 tsubai * 1280 1.1 tsubai * This routine lets the caller know whether the specified adb command string 1281 1.1 tsubai * may have extra data appended to the end of it, such as a LISTEN command. 1282 1.1 tsubai * 1283 1.1 tsubai * returns: 0 if extra data is allowed 1284 1.1 tsubai * 1 if extra data is NOT allowed 1285 1.1 tsubai */ 1286 1.1 tsubai int 1287 1.1 tsubai adb_cmd_extra(u_char *in) 1288 1.1 tsubai { 1289 1.1 tsubai switch (adbHardware) { 1290 1.1 tsubai case ADB_HW_CUDA: 1291 1.1 tsubai /* 1292 1.1 tsubai * TO DO: support needs to be added to recognize RTC and PRAM 1293 1.1 tsubai * commands 1294 1.1 tsubai */ 1295 1.1 tsubai if ((in[2] & 0x0c) == 0x08) /* was it a listen command? */ 1296 1.1 tsubai return 0; 1297 1.1 tsubai /* add others later */ 1298 1.1 tsubai return 1; 1299 1.1 tsubai 1300 1.28 briggs case ADB_HW_PMU: 1301 1.1 tsubai return 1; 1302 1.1 tsubai 1303 1.1 tsubai case ADB_HW_UNKNOWN: 1304 1.1 tsubai default: 1305 1.1 tsubai return 1; 1306 1.1 tsubai } 1307 1.1 tsubai } 1308 1.1 tsubai 1309 1.1 tsubai /* 1310 1.1 tsubai * adb_op_sync 1311 1.1 tsubai * 1312 1.1 tsubai * This routine does exactly what the adb_op routine does, except that after 1313 1.1 tsubai * the adb_op is called, it waits until the return value is present before 1314 1.1 tsubai * returning. 1315 1.1 tsubai * 1316 1.1 tsubai * NOTE: The user specified compRout is ignored, since this routine specifies 1317 1.44 snj * its own to adb_op, which is why you really called this in the first place 1318 1.1 tsubai * anyway. 1319 1.1 tsubai */ 1320 1.1 tsubai int 1321 1.32 nathanw adb_op_sync(Ptr buffer, adbComp *compRout, Ptr data, short command) 1322 1.1 tsubai { 1323 1.15 tsubai int tmout; 1324 1.1 tsubai int result; 1325 1.1 tsubai volatile int flag = 0; 1326 1.1 tsubai 1327 1.32 nathanw result = adb_op(buffer, adb_op_comprout, 1328 1.32 nathanw &flag, command); /* send command */ 1329 1.15 tsubai if (result == 0) { /* send ok? */ 1330 1.15 tsubai /* 1331 1.15 tsubai * Total time to wait is calculated as follows: 1332 1.15 tsubai * - Tlt (stop to start time): 260 usec 1333 1.15 tsubai * - start bit: 100 usec 1334 1.15 tsubai * - up to 8 data bytes: 64 * 100 usec = 6400 usec 1335 1.15 tsubai * - stop bit (with SRQ): 140 usec 1336 1.15 tsubai * Total: 6900 usec 1337 1.15 tsubai * 1338 1.15 tsubai * This is the total time allowed by the specification. Any 1339 1.15 tsubai * device that doesn't conform to this will fail to operate 1340 1.15 tsubai * properly on some Apple systems. In spite of this we 1341 1.15 tsubai * double the time to wait; some Cuda-based apparently 1342 1.15 tsubai * queues some commands and allows the main CPU to continue 1343 1.15 tsubai * processing (radical concept, eh?). To be safe, allow 1344 1.15 tsubai * time for two complete ADB transactions to occur. 1345 1.15 tsubai */ 1346 1.15 tsubai for (tmout = 13800; !flag && tmout >= 10; tmout -= 10) 1347 1.15 tsubai delay(10); 1348 1.15 tsubai if (!flag && tmout > 0) 1349 1.15 tsubai delay(tmout); 1350 1.15 tsubai 1351 1.15 tsubai if (!flag) 1352 1.15 tsubai result = -2; 1353 1.15 tsubai } 1354 1.1 tsubai 1355 1.1 tsubai return result; 1356 1.1 tsubai } 1357 1.1 tsubai 1358 1.1 tsubai /* 1359 1.1 tsubai * adb_op_comprout 1360 1.1 tsubai * 1361 1.1 tsubai * This function is used by the adb_op_sync routine so it knows when the 1362 1.1 tsubai * function is done. 1363 1.1 tsubai */ 1364 1.32 nathanw void 1365 1.37 christos adb_op_comprout(void *buffer, volatile int *compdata, int cmd) 1366 1.1 tsubai { 1367 1.32 nathanw volatile int *p = compdata; 1368 1.1 tsubai 1369 1.1 tsubai *p = 1; 1370 1.1 tsubai } 1371 1.1 tsubai 1372 1.1 tsubai void 1373 1.1 tsubai adb_setup_hw_type(void) 1374 1.1 tsubai { 1375 1.6 tsubai switch (adbHardware) { 1376 1.6 tsubai case ADB_HW_CUDA: 1377 1.4 tsubai return; 1378 1.4 tsubai 1379 1.28 briggs case ADB_HW_PMU: 1380 1.4 tsubai pm_setup_adb(); 1381 1.4 tsubai return; 1382 1.6 tsubai 1383 1.6 tsubai default: 1384 1.6 tsubai panic("unknown adb hardware"); 1385 1.4 tsubai } 1386 1.1 tsubai } 1387 1.1 tsubai 1388 1.1 tsubai int 1389 1.1 tsubai count_adbs(void) 1390 1.1 tsubai { 1391 1.1 tsubai int i; 1392 1.1 tsubai int found; 1393 1.1 tsubai 1394 1.1 tsubai found = 0; 1395 1.1 tsubai 1396 1.1 tsubai for (i = 1; i < 16; i++) 1397 1.1 tsubai if (0 != ADBDevTable[i].devType) 1398 1.1 tsubai found++; 1399 1.1 tsubai 1400 1.1 tsubai return found; 1401 1.1 tsubai } 1402 1.1 tsubai 1403 1.1 tsubai int 1404 1.1 tsubai get_ind_adb_info(ADBDataBlock * info, int index) 1405 1.1 tsubai { 1406 1.1 tsubai if ((index < 1) || (index > 15)) /* check range 1-15 */ 1407 1.1 tsubai return (-1); 1408 1.1 tsubai 1409 1.1 tsubai #ifdef ADB_DEBUG 1410 1.1 tsubai if (adb_debug & 0x80) 1411 1.1 tsubai printf_intr("index 0x%x devType is: 0x%x\n", index, 1412 1.1 tsubai ADBDevTable[index].devType); 1413 1.1 tsubai #endif 1414 1.1 tsubai if (0 == ADBDevTable[index].devType) /* make sure it's a valid entry */ 1415 1.1 tsubai return (-1); 1416 1.1 tsubai 1417 1.1 tsubai info->devType = ADBDevTable[index].devType; 1418 1.1 tsubai info->origADBAddr = ADBDevTable[index].origAddr; 1419 1.1 tsubai info->dbServiceRtPtr = (Ptr)ADBDevTable[index].ServiceRtPtr; 1420 1.1 tsubai info->dbDataAreaAddr = (Ptr)ADBDevTable[index].DataAreaAddr; 1421 1.1 tsubai 1422 1.1 tsubai return (ADBDevTable[index].currentAddr); 1423 1.1 tsubai } 1424 1.1 tsubai 1425 1.1 tsubai int 1426 1.1 tsubai get_adb_info(ADBDataBlock * info, int adbAddr) 1427 1.1 tsubai { 1428 1.1 tsubai int i; 1429 1.1 tsubai 1430 1.1 tsubai if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */ 1431 1.1 tsubai return (-1); 1432 1.1 tsubai 1433 1.1 tsubai for (i = 1; i < 15; i++) 1434 1.1 tsubai if (ADBDevTable[i].currentAddr == adbAddr) { 1435 1.1 tsubai info->devType = ADBDevTable[i].devType; 1436 1.1 tsubai info->origADBAddr = ADBDevTable[i].origAddr; 1437 1.1 tsubai info->dbServiceRtPtr = (Ptr)ADBDevTable[i].ServiceRtPtr; 1438 1.1 tsubai info->dbDataAreaAddr = ADBDevTable[i].DataAreaAddr; 1439 1.1 tsubai return 0; /* found */ 1440 1.1 tsubai } 1441 1.1 tsubai 1442 1.1 tsubai return (-1); /* not found */ 1443 1.1 tsubai } 1444 1.1 tsubai 1445 1.1 tsubai int 1446 1.1 tsubai set_adb_info(ADBSetInfoBlock * info, int adbAddr) 1447 1.1 tsubai { 1448 1.1 tsubai int i; 1449 1.1 tsubai 1450 1.1 tsubai if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */ 1451 1.1 tsubai return (-1); 1452 1.1 tsubai 1453 1.1 tsubai for (i = 1; i < 15; i++) 1454 1.1 tsubai if (ADBDevTable[i].currentAddr == adbAddr) { 1455 1.1 tsubai ADBDevTable[i].ServiceRtPtr = 1456 1.1 tsubai (void *)(info->siServiceRtPtr); 1457 1.1 tsubai ADBDevTable[i].DataAreaAddr = info->siDataAreaAddr; 1458 1.1 tsubai return 0; /* found */ 1459 1.1 tsubai } 1460 1.1 tsubai 1461 1.1 tsubai return (-1); /* not found */ 1462 1.1 tsubai 1463 1.1 tsubai } 1464 1.1 tsubai 1465 1.6 tsubai #ifndef MRG_ADB 1466 1.6 tsubai 1467 1.35 wiz /* caller should really use machine-independent version: getPramTime */ 1468 1.1 tsubai /* this version does pseudo-adb access only */ 1469 1.1 tsubai int 1470 1.34 kardel adb_read_date_time(unsigned long *t) 1471 1.1 tsubai { 1472 1.1 tsubai u_char output[ADB_MAX_MSG_LENGTH]; 1473 1.1 tsubai int result; 1474 1.1 tsubai volatile int flag = 0; 1475 1.1 tsubai 1476 1.1 tsubai switch (adbHardware) { 1477 1.28 briggs case ADB_HW_PMU: 1478 1.34 kardel pm_read_date_time(t); 1479 1.10 tsubai return 0; 1480 1.1 tsubai 1481 1.1 tsubai case ADB_HW_CUDA: 1482 1.1 tsubai output[0] = 0x02; /* 2 byte message */ 1483 1.1 tsubai output[1] = 0x01; /* to pram/rtc device */ 1484 1.1 tsubai output[2] = 0x03; /* read date/time */ 1485 1.1 tsubai result = send_adb_cuda((u_char *)output, (u_char *)output, 1486 1.32 nathanw adb_op_comprout, &flag, (int)0); 1487 1.1 tsubai if (result != 0) /* exit if not sent */ 1488 1.1 tsubai return -1; 1489 1.1 tsubai 1490 1.1 tsubai while (0 == flag) /* wait for result */ 1491 1.1 tsubai ; 1492 1.1 tsubai 1493 1.34 kardel memcpy(t, output + 1, 4); 1494 1.1 tsubai return 0; 1495 1.1 tsubai 1496 1.1 tsubai case ADB_HW_UNKNOWN: 1497 1.1 tsubai default: 1498 1.1 tsubai return -1; 1499 1.1 tsubai } 1500 1.1 tsubai } 1501 1.1 tsubai 1502 1.35 wiz /* caller should really use machine-independent version: setPramTime */ 1503 1.1 tsubai /* this version does pseudo-adb access only */ 1504 1.1 tsubai int 1505 1.34 kardel adb_set_date_time(unsigned long t) 1506 1.1 tsubai { 1507 1.1 tsubai u_char output[ADB_MAX_MSG_LENGTH]; 1508 1.1 tsubai int result; 1509 1.1 tsubai volatile int flag = 0; 1510 1.1 tsubai 1511 1.1 tsubai switch (adbHardware) { 1512 1.1 tsubai 1513 1.1 tsubai case ADB_HW_CUDA: 1514 1.1 tsubai output[0] = 0x06; /* 6 byte message */ 1515 1.1 tsubai output[1] = 0x01; /* to pram/rtc device */ 1516 1.1 tsubai output[2] = 0x09; /* set date/time */ 1517 1.34 kardel output[3] = (u_char)(t >> 24); 1518 1.34 kardel output[4] = (u_char)(t >> 16); 1519 1.34 kardel output[5] = (u_char)(t >> 8); 1520 1.34 kardel output[6] = (u_char)(t); 1521 1.1 tsubai result = send_adb_cuda((u_char *)output, (u_char *)0, 1522 1.32 nathanw adb_op_comprout, &flag, (int)0); 1523 1.1 tsubai if (result != 0) /* exit if not sent */ 1524 1.1 tsubai return -1; 1525 1.1 tsubai 1526 1.1 tsubai while (0 == flag) /* wait for send to finish */ 1527 1.1 tsubai ; 1528 1.1 tsubai 1529 1.1 tsubai return 0; 1530 1.1 tsubai 1531 1.28 briggs case ADB_HW_PMU: 1532 1.34 kardel pm_set_date_time(t); 1533 1.10 tsubai return 0; 1534 1.10 tsubai 1535 1.1 tsubai case ADB_HW_UNKNOWN: 1536 1.1 tsubai default: 1537 1.1 tsubai return -1; 1538 1.1 tsubai } 1539 1.1 tsubai } 1540 1.1 tsubai 1541 1.1 tsubai 1542 1.1 tsubai int 1543 1.1 tsubai adb_poweroff(void) 1544 1.1 tsubai { 1545 1.1 tsubai u_char output[ADB_MAX_MSG_LENGTH]; 1546 1.1 tsubai int result; 1547 1.1 tsubai 1548 1.9 tsubai adb_polling = 1; 1549 1.9 tsubai 1550 1.1 tsubai switch (adbHardware) { 1551 1.28 briggs case ADB_HW_PMU: 1552 1.11 tsubai pm_adb_poweroff(); 1553 1.11 tsubai 1554 1.11 tsubai for (;;); /* wait for power off */ 1555 1.11 tsubai 1556 1.11 tsubai return 0; 1557 1.1 tsubai 1558 1.1 tsubai case ADB_HW_CUDA: 1559 1.1 tsubai output[0] = 0x02; /* 2 byte message */ 1560 1.1 tsubai output[1] = 0x01; /* to pram/rtc/soft-power device */ 1561 1.1 tsubai output[2] = 0x0a; /* set date/time */ 1562 1.1 tsubai result = send_adb_cuda((u_char *)output, (u_char *)0, 1563 1.1 tsubai (void *)0, (void *)0, (int)0); 1564 1.1 tsubai if (result != 0) /* exit if not sent */ 1565 1.1 tsubai return -1; 1566 1.1 tsubai 1567 1.1 tsubai for (;;); /* wait for power off */ 1568 1.1 tsubai 1569 1.1 tsubai return 0; 1570 1.1 tsubai 1571 1.1 tsubai case ADB_HW_UNKNOWN: 1572 1.1 tsubai default: 1573 1.1 tsubai return -1; 1574 1.1 tsubai } 1575 1.1 tsubai } 1576 1.1 tsubai 1577 1.1 tsubai int 1578 1.1 tsubai CountADBs(void) 1579 1.1 tsubai { 1580 1.1 tsubai return (count_adbs()); 1581 1.1 tsubai } 1582 1.1 tsubai 1583 1.1 tsubai void 1584 1.1 tsubai ADBReInit(void) 1585 1.1 tsubai { 1586 1.1 tsubai adb_reinit(); 1587 1.1 tsubai } 1588 1.1 tsubai 1589 1.1 tsubai int 1590 1.1 tsubai GetIndADB(ADBDataBlock * info, int index) 1591 1.1 tsubai { 1592 1.1 tsubai return (get_ind_adb_info(info, index)); 1593 1.1 tsubai } 1594 1.1 tsubai 1595 1.1 tsubai int 1596 1.1 tsubai GetADBInfo(ADBDataBlock * info, int adbAddr) 1597 1.1 tsubai { 1598 1.1 tsubai return (get_adb_info(info, adbAddr)); 1599 1.1 tsubai } 1600 1.1 tsubai 1601 1.1 tsubai int 1602 1.1 tsubai SetADBInfo(ADBSetInfoBlock * info, int adbAddr) 1603 1.1 tsubai { 1604 1.1 tsubai return (set_adb_info(info, adbAddr)); 1605 1.1 tsubai } 1606 1.1 tsubai 1607 1.1 tsubai int 1608 1.32 nathanw ADBOp(Ptr buffer, adbComp *compRout, Ptr data, short commandNum) 1609 1.1 tsubai { 1610 1.1 tsubai return (adb_op(buffer, compRout, data, commandNum)); 1611 1.1 tsubai } 1612 1.1 tsubai 1613 1.1 tsubai #endif 1614 1.1 tsubai 1615 1.1 tsubai int 1616 1.42 cegger setsoftadb(void) 1617 1.1 tsubai { 1618 1.13 thorpej callout_reset(&adb_soft_intr_ch, 1, (void *)adb_soft_intr, NULL); 1619 1.1 tsubai return 0; 1620 1.1 tsubai } 1621 1.1 tsubai 1622 1.1 tsubai void 1623 1.42 cegger adb_cuda_autopoll(void) 1624 1.1 tsubai { 1625 1.1 tsubai volatile int flag = 0; 1626 1.1 tsubai int result; 1627 1.1 tsubai u_char output[16]; 1628 1.1 tsubai 1629 1.1 tsubai output[0] = 0x03; /* 3-byte message */ 1630 1.1 tsubai output[1] = 0x01; /* to pram/rtc device */ 1631 1.1 tsubai output[2] = 0x01; /* cuda autopoll */ 1632 1.1 tsubai output[3] = 0x01; 1633 1.32 nathanw result = send_adb_cuda(output, output, adb_op_comprout, 1634 1.32 nathanw &flag, 0); 1635 1.1 tsubai if (result != 0) /* exit if not sent */ 1636 1.1 tsubai return; 1637 1.1 tsubai 1638 1.1 tsubai while (flag == 0); /* wait for result */ 1639 1.1 tsubai } 1640 1.1 tsubai 1641 1.1 tsubai void 1642 1.17 matt adb_restart(void) 1643 1.1 tsubai { 1644 1.1 tsubai int result; 1645 1.1 tsubai u_char output[16]; 1646 1.1 tsubai 1647 1.9 tsubai adb_polling = 1; 1648 1.9 tsubai 1649 1.4 tsubai switch (adbHardware) { 1650 1.4 tsubai case ADB_HW_CUDA: 1651 1.4 tsubai output[0] = 0x02; /* 2 byte message */ 1652 1.4 tsubai output[1] = 0x01; /* to pram/rtc/soft-power device */ 1653 1.4 tsubai output[2] = 0x11; /* restart */ 1654 1.15 tsubai result = send_adb_cuda(output, NULL, NULL, NULL, 0); 1655 1.4 tsubai if (result != 0) /* exit if not sent */ 1656 1.4 tsubai return; 1657 1.4 tsubai while (1); /* not return */ 1658 1.4 tsubai 1659 1.28 briggs case ADB_HW_PMU: 1660 1.4 tsubai pm_adb_restart(); 1661 1.10 tsubai while (1); /* not return */ 1662 1.4 tsubai } 1663 1.1 tsubai } 1664