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