adb_direct.c revision 1.18 1 1.18 simonb /* $NetBSD: adb_direct.c,v 1.18 2001/06/19 12:02:55 simonb 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.1 tsubai
62 1.1 tsubai #include <sys/param.h>
63 1.1 tsubai #include <sys/cdefs.h>
64 1.1 tsubai #include <sys/systm.h>
65 1.13 thorpej #include <sys/callout.h>
66 1.1 tsubai #include <sys/device.h>
67 1.1 tsubai
68 1.1 tsubai #include <machine/param.h>
69 1.1 tsubai #include <machine/cpu.h>
70 1.1 tsubai #include <machine/adbsys.h>
71 1.1 tsubai
72 1.1 tsubai #include <macppc/dev/viareg.h>
73 1.1 tsubai #include <macppc/dev/adbvar.h>
74 1.17 matt #include <macppc/dev/pm_direct.h>
75 1.1 tsubai
76 1.1 tsubai #define printf_intr printf
77 1.1 tsubai
78 1.6 tsubai #ifdef DEBUG
79 1.6 tsubai #ifndef ADB_DEBUG
80 1.6 tsubai #define ADB_DEBUG
81 1.6 tsubai #endif
82 1.6 tsubai #endif
83 1.6 tsubai
84 1.1 tsubai /* some misc. leftovers */
85 1.1 tsubai #define vPB 0x0000
86 1.1 tsubai #define vPB3 0x08
87 1.1 tsubai #define vPB4 0x10
88 1.1 tsubai #define vPB5 0x20
89 1.1 tsubai #define vSR_INT 0x04
90 1.1 tsubai #define vSR_OUT 0x10
91 1.1 tsubai
92 1.1 tsubai /* the type of ADB action that we are currently preforming */
93 1.6 tsubai #define ADB_ACTION_NOTREADY 0x1 /* has not been initialized yet */
94 1.6 tsubai #define ADB_ACTION_IDLE 0x2 /* the bus is currently idle */
95 1.6 tsubai #define ADB_ACTION_OUT 0x3 /* sending out a command */
96 1.6 tsubai #define ADB_ACTION_IN 0x4 /* receiving data */
97 1.6 tsubai #define ADB_ACTION_POLLING 0x5 /* polling - II only */
98 1.1 tsubai
99 1.1 tsubai /*
100 1.1 tsubai * These describe the state of the ADB bus itself, although they
101 1.1 tsubai * don't necessarily correspond directly to ADB states.
102 1.1 tsubai * Note: these are not really used in the IIsi code.
103 1.1 tsubai */
104 1.6 tsubai #define ADB_BUS_UNKNOWN 0x1 /* we don't know yet - all models */
105 1.6 tsubai #define ADB_BUS_IDLE 0x2 /* bus is idle - all models */
106 1.6 tsubai #define ADB_BUS_CMD 0x3 /* starting a command - II models */
107 1.6 tsubai #define ADB_BUS_ODD 0x4 /* the "odd" state - II models */
108 1.6 tsubai #define ADB_BUS_EVEN 0x5 /* the "even" state - II models */
109 1.6 tsubai #define ADB_BUS_ACTIVE 0x6 /* active state - IIsi models */
110 1.6 tsubai #define ADB_BUS_ACK 0x7 /* currently ACKing - IIsi models */
111 1.1 tsubai
112 1.1 tsubai /*
113 1.1 tsubai * Shortcuts for setting or testing the VIA bit states.
114 1.1 tsubai * Not all shortcuts are used for every type of ADB hardware.
115 1.1 tsubai */
116 1.1 tsubai #define ADB_SET_STATE_IDLE_II() via_reg_or(VIA1, vBufB, (vPB4 | vPB5))
117 1.1 tsubai #define ADB_SET_STATE_IDLE_IISI() via_reg_and(VIA1, vBufB, ~(vPB4 | vPB5))
118 1.1 tsubai #define ADB_SET_STATE_IDLE_CUDA() via_reg_or(VIA1, vBufB, (vPB4 | vPB5))
119 1.1 tsubai #define ADB_SET_STATE_CMD() via_reg_and(VIA1, vBufB, ~(vPB4 | vPB5))
120 1.1 tsubai #define ADB_SET_STATE_EVEN() write_via_reg(VIA1, vBufB, \
121 1.1 tsubai (read_via_reg(VIA1, vBufB) | vPB4) & ~vPB5)
122 1.1 tsubai #define ADB_SET_STATE_ODD() write_via_reg(VIA1, vBufB, \
123 1.1 tsubai (read_via_reg(VIA1, vBufB) | vPB5) & ~vPB4 )
124 1.1 tsubai #define ADB_SET_STATE_ACTIVE() via_reg_or(VIA1, vBufB, vPB5)
125 1.1 tsubai #define ADB_SET_STATE_INACTIVE() via_reg_and(VIA1, vBufB, ~vPB5)
126 1.1 tsubai #define ADB_SET_STATE_TIP() via_reg_and(VIA1, vBufB, ~vPB5)
127 1.1 tsubai #define ADB_CLR_STATE_TIP() via_reg_or(VIA1, vBufB, vPB5)
128 1.1 tsubai #define ADB_SET_STATE_ACKON() via_reg_or(VIA1, vBufB, vPB4)
129 1.1 tsubai #define ADB_SET_STATE_ACKOFF() via_reg_and(VIA1, vBufB, ~vPB4)
130 1.1 tsubai #define ADB_TOGGLE_STATE_ACK_CUDA() via_reg_xor(VIA1, vBufB, vPB4)
131 1.1 tsubai #define ADB_SET_STATE_ACKON_CUDA() via_reg_and(VIA1, vBufB, ~vPB4)
132 1.1 tsubai #define ADB_SET_STATE_ACKOFF_CUDA() via_reg_or(VIA1, vBufB, vPB4)
133 1.1 tsubai #define ADB_SET_SR_INPUT() via_reg_and(VIA1, vACR, ~vSR_OUT)
134 1.1 tsubai #define ADB_SET_SR_OUTPUT() via_reg_or(VIA1, vACR, vSR_OUT)
135 1.1 tsubai #define ADB_SR() read_via_reg(VIA1, vSR)
136 1.1 tsubai #define ADB_VIA_INTR_ENABLE() write_via_reg(VIA1, vIER, 0x84)
137 1.1 tsubai #define ADB_VIA_INTR_DISABLE() write_via_reg(VIA1, vIER, 0x04)
138 1.1 tsubai #define ADB_VIA_CLR_INTR() write_via_reg(VIA1, vIFR, 0x04)
139 1.1 tsubai #define ADB_INTR_IS_OFF (vPB3 == (read_via_reg(VIA1, vBufB) & vPB3))
140 1.1 tsubai #define ADB_INTR_IS_ON (0 == (read_via_reg(VIA1, vBufB) & vPB3))
141 1.1 tsubai #define ADB_SR_INTR_IS_OFF (0 == (read_via_reg(VIA1, vIFR) & vSR_INT))
142 1.1 tsubai #define ADB_SR_INTR_IS_ON (vSR_INT == (read_via_reg(VIA1, \
143 1.1 tsubai vIFR) & vSR_INT))
144 1.1 tsubai
145 1.1 tsubai /*
146 1.1 tsubai * This is the delay that is required (in uS) between certain
147 1.1 tsubai * ADB transactions. The actual timing delay for for each uS is
148 1.1 tsubai * calculated at boot time to account for differences in machine speed.
149 1.1 tsubai */
150 1.8 tsubai #define ADB_DELAY 150
151 1.1 tsubai
152 1.1 tsubai /*
153 1.1 tsubai * Maximum ADB message length; includes space for data, result, and
154 1.1 tsubai * device code - plus a little for safety.
155 1.1 tsubai */
156 1.1 tsubai #define ADB_MAX_MSG_LENGTH 16
157 1.1 tsubai #define ADB_MAX_HDR_LENGTH 8
158 1.1 tsubai
159 1.1 tsubai #define ADB_QUEUE 32
160 1.1 tsubai #define ADB_TICKLE_TICKS 4
161 1.1 tsubai
162 1.1 tsubai /*
163 1.1 tsubai * A structure for storing information about each ADB device.
164 1.1 tsubai */
165 1.1 tsubai struct ADBDevEntry {
166 1.1 tsubai void (*ServiceRtPtr) __P((void));
167 1.1 tsubai void *DataAreaAddr;
168 1.14 tsubai int devType;
169 1.14 tsubai int origAddr;
170 1.14 tsubai int currentAddr;
171 1.1 tsubai };
172 1.1 tsubai
173 1.1 tsubai /*
174 1.1 tsubai * Used to hold ADB commands that are waiting to be sent out.
175 1.1 tsubai */
176 1.1 tsubai struct adbCmdHoldEntry {
177 1.1 tsubai u_char outBuf[ADB_MAX_MSG_LENGTH]; /* our message */
178 1.1 tsubai u_char *saveBuf; /* buffer to know where to save result */
179 1.1 tsubai u_char *compRout; /* completion routine pointer */
180 1.1 tsubai u_char *data; /* completion routine data pointer */
181 1.1 tsubai };
182 1.1 tsubai
183 1.1 tsubai /*
184 1.1 tsubai * Eventually used for two separate queues, the queue between
185 1.1 tsubai * the upper and lower halves, and the outgoing packet queue.
186 1.1 tsubai * TO DO: adbCommand can replace all of adbCmdHoldEntry eventually
187 1.1 tsubai */
188 1.1 tsubai struct adbCommand {
189 1.1 tsubai u_char header[ADB_MAX_HDR_LENGTH]; /* not used yet */
190 1.1 tsubai u_char data[ADB_MAX_MSG_LENGTH]; /* packet data only */
191 1.1 tsubai u_char *saveBuf; /* where to save result */
192 1.1 tsubai u_char *compRout; /* completion routine pointer */
193 1.1 tsubai u_char *compData; /* completion routine data pointer */
194 1.1 tsubai u_int cmd; /* the original command for this data */
195 1.1 tsubai u_int unsol; /* 1 if packet was unsolicited */
196 1.1 tsubai u_int ack_only; /* 1 for no special processing */
197 1.1 tsubai };
198 1.1 tsubai
199 1.1 tsubai /*
200 1.1 tsubai * A few variables that we need and their initial values.
201 1.1 tsubai */
202 1.1 tsubai int adbHardware = ADB_HW_UNKNOWN;
203 1.1 tsubai int adbActionState = ADB_ACTION_NOTREADY;
204 1.1 tsubai int adbBusState = ADB_BUS_UNKNOWN;
205 1.1 tsubai int adbWaiting = 0; /* waiting for return data from the device */
206 1.1 tsubai int adbWriteDelay = 0; /* working on (or waiting to do) a write */
207 1.1 tsubai int adbOutQueueHasData = 0; /* something in the queue waiting to go out */
208 1.1 tsubai int adbNextEnd = 0; /* the next incoming bute is the last (II) */
209 1.1 tsubai int adbSoftPower = 0; /* machine supports soft power */
210 1.1 tsubai
211 1.1 tsubai int adbWaitingCmd = 0; /* ADB command we are waiting for */
212 1.1 tsubai u_char *adbBuffer = (long)0; /* pointer to user data area */
213 1.1 tsubai void *adbCompRout = (long)0; /* pointer to the completion routine */
214 1.1 tsubai void *adbCompData = (long)0; /* pointer to the completion routine data */
215 1.1 tsubai long adbFakeInts = 0; /* keeps track of fake ADB interrupts for
216 1.1 tsubai * timeouts (II) */
217 1.1 tsubai int adbStarting = 1; /* doing ADBReInit so do polling differently */
218 1.1 tsubai int adbSendTalk = 0; /* the intr routine is sending the talk, not
219 1.1 tsubai * the user (II) */
220 1.1 tsubai int adbPolling = 0; /* we are polling for service request */
221 1.1 tsubai int adbPollCmd = 0; /* the last poll command we sent */
222 1.1 tsubai
223 1.1 tsubai u_char adbInputBuffer[ADB_MAX_MSG_LENGTH]; /* data input buffer */
224 1.1 tsubai u_char adbOutputBuffer[ADB_MAX_MSG_LENGTH]; /* data output buffer */
225 1.1 tsubai struct adbCmdHoldEntry adbOutQueue; /* our 1 entry output queue */
226 1.1 tsubai
227 1.1 tsubai int adbSentChars = 0; /* how many characters we have sent */
228 1.1 tsubai int adbLastDevice = 0; /* last ADB dev we heard from (II ONLY) */
229 1.1 tsubai int adbLastDevIndex = 0; /* last ADB dev loc in dev table (II ONLY) */
230 1.1 tsubai int adbLastCommand = 0; /* the last ADB command we sent (II) */
231 1.1 tsubai
232 1.1 tsubai struct ADBDevEntry ADBDevTable[16]; /* our ADB device table */
233 1.1 tsubai int ADBNumDevices; /* num. of ADB devices found with ADBReInit */
234 1.1 tsubai
235 1.1 tsubai struct adbCommand adbInbound[ADB_QUEUE]; /* incoming queue */
236 1.1 tsubai int adbInCount = 0; /* how many packets in in queue */
237 1.1 tsubai int adbInHead = 0; /* head of in queue */
238 1.1 tsubai int adbInTail = 0; /* tail of in queue */
239 1.1 tsubai struct adbCommand adbOutbound[ADB_QUEUE]; /* outgoing queue - not used yet */
240 1.1 tsubai int adbOutCount = 0; /* how many packets in out queue */
241 1.1 tsubai int adbOutHead = 0; /* head of out queue */
242 1.1 tsubai int adbOutTail = 0; /* tail of out queue */
243 1.1 tsubai
244 1.1 tsubai int tickle_count = 0; /* how many tickles seen for this packet? */
245 1.1 tsubai int tickle_serial = 0; /* the last packet tickled */
246 1.1 tsubai int adb_cuda_serial = 0; /* the current packet */
247 1.1 tsubai
248 1.13 thorpej struct callout adb_cuda_tickle_ch = CALLOUT_INITIALIZER;
249 1.13 thorpej struct callout adb_soft_intr_ch = CALLOUT_INITIALIZER;
250 1.13 thorpej
251 1.3 tsubai volatile u_char *Via1Base;
252 1.6 tsubai extern int adb_polling; /* Are we polling? */
253 1.1 tsubai
254 1.1 tsubai void pm_setup_adb __P((void));
255 1.1 tsubai void pm_check_adb_devices __P((int));
256 1.6 tsubai void pm_intr __P((void));
257 1.1 tsubai int pm_adb_op __P((u_char *, void *, void *, int));
258 1.1 tsubai void pm_init_adb_device __P((void));
259 1.1 tsubai
260 1.1 tsubai /*
261 1.1 tsubai * The following are private routines.
262 1.1 tsubai */
263 1.6 tsubai #ifdef ADB_DEBUG
264 1.1 tsubai void print_single __P((u_char *));
265 1.6 tsubai #endif
266 1.1 tsubai void adb_intr __P((void));
267 1.1 tsubai void adb_intr_II __P((void));
268 1.1 tsubai void adb_intr_IIsi __P((void));
269 1.1 tsubai void adb_intr_cuda __P((void));
270 1.1 tsubai void adb_soft_intr __P((void));
271 1.1 tsubai int send_adb_II __P((u_char *, u_char *, void *, void *, int));
272 1.1 tsubai int send_adb_IIsi __P((u_char *, u_char *, void *, void *, int));
273 1.1 tsubai int send_adb_cuda __P((u_char *, u_char *, void *, void *, int));
274 1.1 tsubai void adb_intr_cuda_test __P((void));
275 1.1 tsubai void adb_cuda_tickle __P((void));
276 1.1 tsubai void adb_pass_up __P((struct adbCommand *));
277 1.1 tsubai void adb_op_comprout __P((caddr_t, caddr_t, int));
278 1.1 tsubai void adb_reinit __P((void));
279 1.1 tsubai int count_adbs __P((void));
280 1.1 tsubai int get_ind_adb_info __P((ADBDataBlock *, int));
281 1.1 tsubai int get_adb_info __P((ADBDataBlock *, int));
282 1.1 tsubai int set_adb_info __P((ADBSetInfoBlock *, int));
283 1.1 tsubai void adb_setup_hw_type __P((void));
284 1.1 tsubai int adb_op __P((Ptr, Ptr, Ptr, short));
285 1.1 tsubai int adb_op_sync __P((Ptr, Ptr, Ptr, short));
286 1.1 tsubai void adb_read_II __P((u_char *));
287 1.1 tsubai void adb_hw_setup __P((void));
288 1.1 tsubai void adb_hw_setup_IIsi __P((u_char *));
289 1.1 tsubai void adb_comp_exec __P((void));
290 1.1 tsubai int adb_cmd_result __P((u_char *));
291 1.1 tsubai int adb_cmd_extra __P((u_char *));
292 1.1 tsubai int adb_guess_next_device __P((void));
293 1.1 tsubai int adb_prog_switch_enable __P((void));
294 1.1 tsubai int adb_prog_switch_disable __P((void));
295 1.1 tsubai /* we should create this and it will be the public version */
296 1.1 tsubai int send_adb __P((u_char *, void *, void *));
297 1.1 tsubai
298 1.17 matt int setsoftadb __P((void));
299 1.17 matt
300 1.6 tsubai #ifdef ADB_DEBUG
301 1.1 tsubai /*
302 1.1 tsubai * print_single
303 1.1 tsubai * Diagnostic display routine. Displays the hex values of the
304 1.1 tsubai * specified elements of the u_char. The length of the "string"
305 1.1 tsubai * is in [0].
306 1.1 tsubai */
307 1.1 tsubai void
308 1.14 tsubai print_single(str)
309 1.14 tsubai u_char *str;
310 1.1 tsubai {
311 1.1 tsubai int x;
312 1.1 tsubai
313 1.14 tsubai if (str == 0) {
314 1.14 tsubai printf_intr("no data - null pointer\n");
315 1.1 tsubai return;
316 1.1 tsubai }
317 1.14 tsubai if (*str == 0) {
318 1.14 tsubai printf_intr("nothing returned\n");
319 1.1 tsubai return;
320 1.1 tsubai }
321 1.14 tsubai if (*str > 20) {
322 1.1 tsubai printf_intr("ADB: ACK > 20 no way!\n");
323 1.14 tsubai *str = 20;
324 1.1 tsubai }
325 1.14 tsubai printf_intr("(length=0x%x):", *str);
326 1.14 tsubai for (x = 1; x <= *str; x++)
327 1.14 tsubai printf_intr(" 0x%02x", str[x]);
328 1.1 tsubai printf_intr("\n");
329 1.1 tsubai }
330 1.6 tsubai #endif
331 1.1 tsubai
332 1.1 tsubai void
333 1.1 tsubai adb_cuda_tickle(void)
334 1.1 tsubai {
335 1.1 tsubai volatile int s;
336 1.1 tsubai
337 1.1 tsubai if (adbActionState == ADB_ACTION_IN) {
338 1.1 tsubai if (tickle_serial == adb_cuda_serial) {
339 1.1 tsubai if (++tickle_count > 0) {
340 1.1 tsubai s = splhigh();
341 1.1 tsubai adbActionState = ADB_ACTION_IDLE;
342 1.1 tsubai adbInputBuffer[0] = 0;
343 1.1 tsubai ADB_SET_STATE_IDLE_CUDA();
344 1.1 tsubai splx(s);
345 1.1 tsubai }
346 1.1 tsubai } else {
347 1.1 tsubai tickle_serial = adb_cuda_serial;
348 1.1 tsubai tickle_count = 0;
349 1.1 tsubai }
350 1.1 tsubai } else {
351 1.1 tsubai tickle_serial = adb_cuda_serial;
352 1.1 tsubai tickle_count = 0;
353 1.1 tsubai }
354 1.1 tsubai
355 1.13 thorpej callout_reset(&adb_cuda_tickle_ch, ADB_TICKLE_TICKS,
356 1.13 thorpej (void *)adb_cuda_tickle, NULL);
357 1.1 tsubai }
358 1.1 tsubai
359 1.1 tsubai /*
360 1.1 tsubai * called when when an adb interrupt happens
361 1.1 tsubai *
362 1.1 tsubai * Cuda version of adb_intr
363 1.6 tsubai * TO DO: do we want to add some calls to intr_dispatch() here to
364 1.6 tsubai * grab serial interrupts?
365 1.1 tsubai */
366 1.1 tsubai void
367 1.1 tsubai adb_intr_cuda(void)
368 1.1 tsubai {
369 1.1 tsubai volatile int i, ending;
370 1.1 tsubai volatile unsigned int s;
371 1.1 tsubai struct adbCommand packet;
372 1.1 tsubai
373 1.1 tsubai s = splhigh(); /* can't be too careful - might be called */
374 1.1 tsubai /* from a routine, NOT an interrupt */
375 1.1 tsubai
376 1.1 tsubai ADB_VIA_CLR_INTR(); /* clear interrupt */
377 1.1 tsubai ADB_VIA_INTR_DISABLE(); /* disable ADB interrupt on IIs. */
378 1.1 tsubai
379 1.1 tsubai switch_start:
380 1.1 tsubai switch (adbActionState) {
381 1.1 tsubai case ADB_ACTION_IDLE:
382 1.1 tsubai /*
383 1.1 tsubai * This is an unexpected packet, so grab the first (dummy)
384 1.1 tsubai * byte, set up the proper vars, and tell the chip we are
385 1.1 tsubai * starting to receive the packet by setting the TIP bit.
386 1.1 tsubai */
387 1.1 tsubai adbInputBuffer[1] = ADB_SR();
388 1.1 tsubai adb_cuda_serial++;
389 1.1 tsubai if (ADB_INTR_IS_OFF) /* must have been a fake start */
390 1.1 tsubai break;
391 1.1 tsubai
392 1.1 tsubai ADB_SET_SR_INPUT();
393 1.1 tsubai ADB_SET_STATE_TIP();
394 1.1 tsubai
395 1.1 tsubai adbInputBuffer[0] = 1;
396 1.1 tsubai adbActionState = ADB_ACTION_IN;
397 1.1 tsubai #ifdef ADB_DEBUG
398 1.1 tsubai if (adb_debug)
399 1.1 tsubai printf_intr("idle 0x%02x ", adbInputBuffer[1]);
400 1.1 tsubai #endif
401 1.1 tsubai break;
402 1.1 tsubai
403 1.1 tsubai case ADB_ACTION_IN:
404 1.1 tsubai adbInputBuffer[++adbInputBuffer[0]] = ADB_SR();
405 1.1 tsubai /* intr off means this is the last byte (end of frame) */
406 1.1 tsubai if (ADB_INTR_IS_OFF)
407 1.1 tsubai ending = 1;
408 1.1 tsubai else
409 1.1 tsubai ending = 0;
410 1.1 tsubai
411 1.1 tsubai if (1 == ending) { /* end of message? */
412 1.1 tsubai #ifdef ADB_DEBUG
413 1.1 tsubai if (adb_debug) {
414 1.1 tsubai printf_intr("in end 0x%02x ",
415 1.1 tsubai adbInputBuffer[adbInputBuffer[0]]);
416 1.1 tsubai print_single(adbInputBuffer);
417 1.1 tsubai }
418 1.1 tsubai #endif
419 1.1 tsubai
420 1.1 tsubai /*
421 1.1 tsubai * Are we waiting AND does this packet match what we
422 1.1 tsubai * are waiting for AND is it coming from either the
423 1.1 tsubai * ADB or RTC/PRAM sub-device? This section _should_
424 1.1 tsubai * recognize all ADB and RTC/PRAM type commands, but
425 1.1 tsubai * there may be more... NOTE: commands are always at
426 1.1 tsubai * [4], even for RTC/PRAM commands.
427 1.1 tsubai */
428 1.1 tsubai /* set up data for adb_pass_up */
429 1.14 tsubai memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
430 1.1 tsubai
431 1.1 tsubai if ((adbWaiting == 1) &&
432 1.1 tsubai (adbInputBuffer[4] == adbWaitingCmd) &&
433 1.1 tsubai ((adbInputBuffer[2] == 0x00) ||
434 1.1 tsubai (adbInputBuffer[2] == 0x01))) {
435 1.1 tsubai packet.saveBuf = adbBuffer;
436 1.1 tsubai packet.compRout = adbCompRout;
437 1.1 tsubai packet.compData = adbCompData;
438 1.1 tsubai packet.unsol = 0;
439 1.1 tsubai packet.ack_only = 0;
440 1.1 tsubai adb_pass_up(&packet);
441 1.1 tsubai
442 1.1 tsubai adbWaitingCmd = 0; /* reset "waiting" vars */
443 1.1 tsubai adbWaiting = 0;
444 1.1 tsubai adbBuffer = (long)0;
445 1.1 tsubai adbCompRout = (long)0;
446 1.1 tsubai adbCompData = (long)0;
447 1.1 tsubai } else {
448 1.1 tsubai packet.unsol = 1;
449 1.1 tsubai packet.ack_only = 0;
450 1.1 tsubai adb_pass_up(&packet);
451 1.1 tsubai }
452 1.1 tsubai
453 1.1 tsubai
454 1.1 tsubai /* reset vars and signal the end of this frame */
455 1.1 tsubai adbActionState = ADB_ACTION_IDLE;
456 1.1 tsubai adbInputBuffer[0] = 0;
457 1.1 tsubai ADB_SET_STATE_IDLE_CUDA();
458 1.1 tsubai /*ADB_SET_SR_INPUT();*/
459 1.1 tsubai
460 1.1 tsubai /*
461 1.1 tsubai * If there is something waiting to be sent out,
462 1.1 tsubai * the set everything up and send the first byte.
463 1.1 tsubai */
464 1.1 tsubai if (adbWriteDelay == 1) {
465 1.1 tsubai delay(ADB_DELAY); /* required */
466 1.1 tsubai adbSentChars = 0;
467 1.1 tsubai adbActionState = ADB_ACTION_OUT;
468 1.1 tsubai /*
469 1.1 tsubai * If the interrupt is on, we were too slow
470 1.1 tsubai * and the chip has already started to send
471 1.1 tsubai * something to us, so back out of the write
472 1.1 tsubai * and start a read cycle.
473 1.1 tsubai */
474 1.1 tsubai if (ADB_INTR_IS_ON) {
475 1.1 tsubai ADB_SET_SR_INPUT();
476 1.1 tsubai ADB_SET_STATE_IDLE_CUDA();
477 1.1 tsubai adbSentChars = 0;
478 1.1 tsubai adbActionState = ADB_ACTION_IDLE;
479 1.1 tsubai adbInputBuffer[0] = 0;
480 1.1 tsubai break;
481 1.1 tsubai }
482 1.1 tsubai /*
483 1.1 tsubai * If we got here, it's ok to start sending
484 1.1 tsubai * so load the first byte and tell the chip
485 1.1 tsubai * we want to send.
486 1.1 tsubai */
487 1.1 tsubai ADB_SET_STATE_TIP();
488 1.1 tsubai ADB_SET_SR_OUTPUT();
489 1.1 tsubai write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]);
490 1.1 tsubai }
491 1.1 tsubai } else {
492 1.1 tsubai ADB_TOGGLE_STATE_ACK_CUDA();
493 1.1 tsubai #ifdef ADB_DEBUG
494 1.1 tsubai if (adb_debug)
495 1.1 tsubai printf_intr("in 0x%02x ",
496 1.1 tsubai adbInputBuffer[adbInputBuffer[0]]);
497 1.1 tsubai #endif
498 1.1 tsubai }
499 1.1 tsubai break;
500 1.1 tsubai
501 1.1 tsubai case ADB_ACTION_OUT:
502 1.1 tsubai i = ADB_SR(); /* reset SR-intr in IFR */
503 1.1 tsubai #ifdef ADB_DEBUG
504 1.1 tsubai if (adb_debug)
505 1.1 tsubai printf_intr("intr out 0x%02x ", i);
506 1.1 tsubai #endif
507 1.1 tsubai
508 1.1 tsubai adbSentChars++;
509 1.1 tsubai if (ADB_INTR_IS_ON) { /* ADB intr low during write */
510 1.1 tsubai #ifdef ADB_DEBUG
511 1.1 tsubai if (adb_debug)
512 1.1 tsubai printf_intr("intr was on ");
513 1.1 tsubai #endif
514 1.1 tsubai ADB_SET_SR_INPUT(); /* make sure SR is set to IN */
515 1.1 tsubai ADB_SET_STATE_IDLE_CUDA();
516 1.1 tsubai adbSentChars = 0; /* must start all over */
517 1.1 tsubai adbActionState = ADB_ACTION_IDLE; /* new state */
518 1.1 tsubai adbInputBuffer[0] = 0;
519 1.1 tsubai adbWriteDelay = 1; /* must retry when done with
520 1.1 tsubai * read */
521 1.1 tsubai delay(ADB_DELAY);
522 1.1 tsubai goto switch_start; /* process next state right
523 1.1 tsubai * now */
524 1.1 tsubai break;
525 1.1 tsubai }
526 1.1 tsubai if (adbOutputBuffer[0] == adbSentChars) { /* check for done */
527 1.1 tsubai if (0 == adb_cmd_result(adbOutputBuffer)) { /* do we expect data
528 1.1 tsubai * back? */
529 1.1 tsubai adbWaiting = 1; /* signal waiting for return */
530 1.1 tsubai adbWaitingCmd = adbOutputBuffer[2]; /* save waiting command */
531 1.1 tsubai } else { /* no talk, so done */
532 1.1 tsubai /* set up stuff for adb_pass_up */
533 1.14 tsubai memcpy(packet.data, adbInputBuffer, adbInputBuffer[0] + 1);
534 1.1 tsubai packet.saveBuf = adbBuffer;
535 1.1 tsubai packet.compRout = adbCompRout;
536 1.1 tsubai packet.compData = adbCompData;
537 1.1 tsubai packet.cmd = adbWaitingCmd;
538 1.1 tsubai packet.unsol = 0;
539 1.1 tsubai packet.ack_only = 1;
540 1.1 tsubai adb_pass_up(&packet);
541 1.1 tsubai
542 1.1 tsubai /* reset "waiting" vars, just in case */
543 1.1 tsubai adbWaitingCmd = 0;
544 1.1 tsubai adbBuffer = (long)0;
545 1.1 tsubai adbCompRout = (long)0;
546 1.1 tsubai adbCompData = (long)0;
547 1.1 tsubai }
548 1.1 tsubai
549 1.1 tsubai adbWriteDelay = 0; /* done writing */
550 1.1 tsubai adbActionState = ADB_ACTION_IDLE; /* signal bus is idle */
551 1.1 tsubai ADB_SET_SR_INPUT();
552 1.1 tsubai ADB_SET_STATE_IDLE_CUDA();
553 1.1 tsubai #ifdef ADB_DEBUG
554 1.1 tsubai if (adb_debug)
555 1.1 tsubai printf_intr("write done ");
556 1.1 tsubai #endif
557 1.1 tsubai } else {
558 1.1 tsubai write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]); /* send next byte */
559 1.1 tsubai ADB_TOGGLE_STATE_ACK_CUDA(); /* signal byte ready to
560 1.1 tsubai * shift */
561 1.1 tsubai #ifdef ADB_DEBUG
562 1.1 tsubai if (adb_debug)
563 1.1 tsubai printf_intr("toggle ");
564 1.1 tsubai #endif
565 1.1 tsubai }
566 1.1 tsubai break;
567 1.1 tsubai
568 1.1 tsubai case ADB_ACTION_NOTREADY:
569 1.6 tsubai #ifdef ADB_DEBUG
570 1.6 tsubai if (adb_debug)
571 1.6 tsubai printf_intr("adb: not yet initialized\n");
572 1.6 tsubai #endif
573 1.1 tsubai break;
574 1.1 tsubai
575 1.1 tsubai default:
576 1.6 tsubai #ifdef ADB_DEBUG
577 1.6 tsubai if (adb_debug)
578 1.6 tsubai printf_intr("intr: unknown ADB state\n");
579 1.6 tsubai #endif
580 1.1 tsubai }
581 1.1 tsubai
582 1.1 tsubai ADB_VIA_INTR_ENABLE(); /* enable ADB interrupt on IIs. */
583 1.1 tsubai
584 1.1 tsubai splx(s); /* restore */
585 1.1 tsubai
586 1.1 tsubai return;
587 1.1 tsubai } /* end adb_intr_cuda */
588 1.1 tsubai
589 1.1 tsubai
590 1.1 tsubai int
591 1.1 tsubai send_adb_cuda(u_char * in, u_char * buffer, void *compRout, void *data, int
592 1.1 tsubai command)
593 1.1 tsubai {
594 1.14 tsubai int s, len;
595 1.1 tsubai
596 1.1 tsubai #ifdef ADB_DEBUG
597 1.1 tsubai if (adb_debug)
598 1.1 tsubai printf_intr("SEND\n");
599 1.1 tsubai #endif
600 1.1 tsubai
601 1.1 tsubai if (adbActionState == ADB_ACTION_NOTREADY)
602 1.1 tsubai return 1;
603 1.1 tsubai
604 1.1 tsubai /* Don't interrupt while we are messing with the ADB */
605 1.1 tsubai s = splhigh();
606 1.1 tsubai
607 1.1 tsubai if ((adbActionState == ADB_ACTION_IDLE) && /* ADB available? */
608 1.1 tsubai (ADB_INTR_IS_OFF)) { /* and no incoming interrupt? */
609 1.1 tsubai } else
610 1.1 tsubai if (adbWriteDelay == 0) /* it's busy, but is anything waiting? */
611 1.1 tsubai adbWriteDelay = 1; /* if no, then we'll "queue"
612 1.1 tsubai * it up */
613 1.1 tsubai else {
614 1.1 tsubai splx(s);
615 1.1 tsubai return 1; /* really busy! */
616 1.1 tsubai }
617 1.1 tsubai
618 1.1 tsubai #ifdef ADB_DEBUG
619 1.1 tsubai if (adb_debug)
620 1.1 tsubai printf_intr("QUEUE\n");
621 1.1 tsubai #endif
622 1.1 tsubai if ((long)in == (long)0) { /* need to convert? */
623 1.1 tsubai /*
624 1.1 tsubai * Don't need to use adb_cmd_extra here because this section
625 1.1 tsubai * will be called ONLY when it is an ADB command (no RTC or
626 1.1 tsubai * PRAM)
627 1.1 tsubai */
628 1.1 tsubai if ((command & 0x0c) == 0x08) /* copy addl data ONLY if
629 1.1 tsubai * doing a listen! */
630 1.1 tsubai len = buffer[0]; /* length of additional data */
631 1.1 tsubai else
632 1.1 tsubai len = 0;/* no additional data */
633 1.1 tsubai
634 1.1 tsubai adbOutputBuffer[0] = 2 + len; /* dev. type + command + addl.
635 1.1 tsubai * data */
636 1.1 tsubai adbOutputBuffer[1] = 0x00; /* mark as an ADB command */
637 1.1 tsubai adbOutputBuffer[2] = (u_char)command; /* load command */
638 1.1 tsubai
639 1.14 tsubai /* copy additional output data, if any */
640 1.14 tsubai memcpy(adbOutputBuffer + 3, buffer + 1, len);
641 1.1 tsubai } else
642 1.14 tsubai /* if data ready, just copy over */
643 1.14 tsubai memcpy(adbOutputBuffer, in, in[0] + 2);
644 1.1 tsubai
645 1.1 tsubai adbSentChars = 0; /* nothing sent yet */
646 1.1 tsubai adbBuffer = buffer; /* save buffer to know where to save result */
647 1.1 tsubai adbCompRout = compRout; /* save completion routine pointer */
648 1.1 tsubai adbCompData = data; /* save completion routine data pointer */
649 1.1 tsubai adbWaitingCmd = adbOutputBuffer[2]; /* save wait command */
650 1.1 tsubai
651 1.1 tsubai if (adbWriteDelay != 1) { /* start command now? */
652 1.1 tsubai #ifdef ADB_DEBUG
653 1.1 tsubai if (adb_debug)
654 1.1 tsubai printf_intr("out start NOW");
655 1.1 tsubai #endif
656 1.1 tsubai delay(ADB_DELAY);
657 1.1 tsubai adbActionState = ADB_ACTION_OUT; /* set next state */
658 1.1 tsubai ADB_SET_SR_OUTPUT(); /* set shift register for OUT */
659 1.1 tsubai write_via_reg(VIA1, vSR, adbOutputBuffer[adbSentChars + 1]); /* load byte for output */
660 1.1 tsubai ADB_SET_STATE_ACKOFF_CUDA();
661 1.1 tsubai ADB_SET_STATE_TIP(); /* tell ADB that we want to send */
662 1.1 tsubai }
663 1.1 tsubai adbWriteDelay = 1; /* something in the write "queue" */
664 1.1 tsubai
665 1.1 tsubai splx(s);
666 1.1 tsubai
667 1.1 tsubai if ((s & (1 << 18)) || adb_polling) /* XXX were VIA1 interrupts blocked ? */
668 1.1 tsubai /* poll until byte done */
669 1.1 tsubai while ((adbActionState != ADB_ACTION_IDLE) || (ADB_INTR_IS_ON)
670 1.1 tsubai || (adbWaiting == 1))
671 1.1 tsubai if (ADB_SR_INTR_IS_ON) { /* wait for "interrupt" */
672 1.1 tsubai adb_intr_cuda(); /* process it */
673 1.1 tsubai adb_soft_intr();
674 1.1 tsubai }
675 1.1 tsubai
676 1.1 tsubai return 0;
677 1.1 tsubai } /* send_adb_cuda */
678 1.1 tsubai
679 1.1 tsubai
680 1.1 tsubai void
681 1.1 tsubai adb_intr_II(void)
682 1.1 tsubai {
683 1.1 tsubai panic("adb_intr_II");
684 1.1 tsubai }
685 1.1 tsubai
686 1.1 tsubai
687 1.1 tsubai /*
688 1.1 tsubai * send_adb version for II series machines
689 1.1 tsubai */
690 1.1 tsubai int
691 1.1 tsubai send_adb_II(u_char * in, u_char * buffer, void *compRout, void *data, int command)
692 1.1 tsubai {
693 1.1 tsubai panic("send_adb_II");
694 1.1 tsubai }
695 1.1 tsubai
696 1.1 tsubai
697 1.1 tsubai /*
698 1.1 tsubai * This routine is called from the II series interrupt routine
699 1.1 tsubai * to determine what the "next" device is that should be polled.
700 1.1 tsubai */
701 1.1 tsubai int
702 1.1 tsubai adb_guess_next_device(void)
703 1.1 tsubai {
704 1.1 tsubai int last, i, dummy;
705 1.1 tsubai
706 1.1 tsubai if (adbStarting) {
707 1.1 tsubai /*
708 1.1 tsubai * Start polling EVERY device, since we can't be sure there is
709 1.1 tsubai * anything in the device table yet
710 1.1 tsubai */
711 1.1 tsubai if (adbLastDevice < 1 || adbLastDevice > 15)
712 1.1 tsubai adbLastDevice = 1;
713 1.1 tsubai if (++adbLastDevice > 15) /* point to next one */
714 1.1 tsubai adbLastDevice = 1;
715 1.1 tsubai } else {
716 1.1 tsubai /* find the next device using the device table */
717 1.1 tsubai if (adbLastDevice < 1 || adbLastDevice > 15) /* let's be parinoid */
718 1.1 tsubai adbLastDevice = 2;
719 1.1 tsubai last = 1; /* default index location */
720 1.1 tsubai
721 1.1 tsubai for (i = 1; i < 16; i++) /* find index entry */
722 1.1 tsubai if (ADBDevTable[i].currentAddr == adbLastDevice) { /* look for device */
723 1.1 tsubai last = i; /* found it */
724 1.1 tsubai break;
725 1.1 tsubai }
726 1.1 tsubai dummy = last; /* index to start at */
727 1.1 tsubai for (;;) { /* find next device in index */
728 1.1 tsubai if (++dummy > 15) /* wrap around if needed */
729 1.1 tsubai dummy = 1;
730 1.1 tsubai if (dummy == last) { /* didn't find any other
731 1.1 tsubai * device! This can happen if
732 1.1 tsubai * there are no devices on the
733 1.1 tsubai * bus */
734 1.14 tsubai dummy = 1;
735 1.1 tsubai break;
736 1.1 tsubai }
737 1.1 tsubai /* found the next device */
738 1.1 tsubai if (ADBDevTable[dummy].devType != 0)
739 1.1 tsubai break;
740 1.1 tsubai }
741 1.1 tsubai adbLastDevice = ADBDevTable[dummy].currentAddr;
742 1.1 tsubai }
743 1.1 tsubai return adbLastDevice;
744 1.1 tsubai }
745 1.1 tsubai
746 1.1 tsubai
747 1.1 tsubai /*
748 1.1 tsubai * Called when when an adb interrupt happens.
749 1.1 tsubai * This routine simply transfers control over to the appropriate
750 1.1 tsubai * code for the machine we are running on.
751 1.1 tsubai */
752 1.1 tsubai void
753 1.1 tsubai adb_intr(void)
754 1.1 tsubai {
755 1.1 tsubai switch (adbHardware) {
756 1.1 tsubai case ADB_HW_II:
757 1.1 tsubai adb_intr_II();
758 1.1 tsubai break;
759 1.1 tsubai
760 1.1 tsubai case ADB_HW_IISI:
761 1.1 tsubai adb_intr_IIsi();
762 1.1 tsubai break;
763 1.1 tsubai
764 1.1 tsubai case ADB_HW_PB:
765 1.4 tsubai pm_intr();
766 1.1 tsubai break;
767 1.1 tsubai
768 1.1 tsubai case ADB_HW_CUDA:
769 1.1 tsubai adb_intr_cuda();
770 1.1 tsubai break;
771 1.1 tsubai
772 1.1 tsubai case ADB_HW_UNKNOWN:
773 1.1 tsubai break;
774 1.1 tsubai }
775 1.1 tsubai }
776 1.1 tsubai
777 1.1 tsubai
778 1.1 tsubai /*
779 1.1 tsubai * called when when an adb interrupt happens
780 1.1 tsubai *
781 1.1 tsubai * IIsi version of adb_intr
782 1.1 tsubai *
783 1.1 tsubai */
784 1.1 tsubai void
785 1.1 tsubai adb_intr_IIsi(void)
786 1.1 tsubai {
787 1.1 tsubai panic("adb_intr_IIsi");
788 1.1 tsubai }
789 1.1 tsubai
790 1.1 tsubai
791 1.1 tsubai /*****************************************************************************
792 1.1 tsubai * if the device is currently busy, and there is no data waiting to go out, then
793 1.1 tsubai * the data is "queued" in the outgoing buffer. If we are already waiting, then
794 1.1 tsubai * we return.
795 1.1 tsubai * in: if (in == 0) then the command string is built from command and buffer
796 1.1 tsubai * if (in != 0) then in is used as the command string
797 1.1 tsubai * buffer: additional data to be sent (used only if in == 0)
798 1.1 tsubai * this is also where return data is stored
799 1.1 tsubai * compRout: the completion routine that is called when then return value
800 1.1 tsubai * is received (if a return value is expected)
801 1.1 tsubai * data: a data pointer that can be used by the completion routine
802 1.1 tsubai * command: an ADB command to be sent (used only if in == 0)
803 1.1 tsubai *
804 1.1 tsubai */
805 1.1 tsubai int
806 1.1 tsubai send_adb_IIsi(u_char * in, u_char * buffer, void *compRout, void *data, int
807 1.1 tsubai command)
808 1.1 tsubai {
809 1.1 tsubai panic("send_adb_IIsi");
810 1.1 tsubai }
811 1.1 tsubai
812 1.1 tsubai
813 1.1 tsubai /*
814 1.1 tsubai * adb_pass_up is called by the interrupt-time routines.
815 1.1 tsubai * It takes the raw packet data that was received from the
816 1.1 tsubai * device and puts it into the queue that the upper half
817 1.1 tsubai * processes. It then signals for a soft ADB interrupt which
818 1.1 tsubai * will eventually call the upper half routine (adb_soft_intr).
819 1.1 tsubai *
820 1.1 tsubai * If in->unsol is 0, then this is either the notification
821 1.1 tsubai * that the packet was sent (on a LISTEN, for example), or the
822 1.1 tsubai * response from the device (on a TALK). The completion routine
823 1.1 tsubai * is called only if the user specified one.
824 1.1 tsubai *
825 1.1 tsubai * If in->unsol is 1, then this packet was unsolicited and
826 1.1 tsubai * so we look up the device in the ADB device table to determine
827 1.1 tsubai * what it's default service routine is.
828 1.1 tsubai *
829 1.1 tsubai * If in->ack_only is 1, then we really only need to call
830 1.1 tsubai * the completion routine, so don't do any other stuff.
831 1.1 tsubai *
832 1.1 tsubai * Note that in->data contains the packet header AND data,
833 1.1 tsubai * while adbInbound[]->data contains ONLY data.
834 1.1 tsubai *
835 1.1 tsubai * Note: Called only at interrupt time. Assumes this.
836 1.1 tsubai */
837 1.1 tsubai void
838 1.1 tsubai adb_pass_up(struct adbCommand *in)
839 1.1 tsubai {
840 1.14 tsubai int start = 0, len = 0, cmd = 0;
841 1.1 tsubai ADBDataBlock block;
842 1.1 tsubai
843 1.1 tsubai /* temp for testing */
844 1.1 tsubai /*u_char *buffer = 0;*/
845 1.1 tsubai /*u_char *compdata = 0;*/
846 1.1 tsubai /*u_char *comprout = 0;*/
847 1.1 tsubai
848 1.1 tsubai if (adbInCount >= ADB_QUEUE) {
849 1.6 tsubai #ifdef ADB_DEBUG
850 1.6 tsubai if (adb_debug)
851 1.6 tsubai printf_intr("adb: ring buffer overflow\n");
852 1.6 tsubai #endif
853 1.1 tsubai return;
854 1.1 tsubai }
855 1.1 tsubai
856 1.1 tsubai if (in->ack_only) {
857 1.1 tsubai len = in->data[0];
858 1.1 tsubai cmd = in->cmd;
859 1.1 tsubai start = 0;
860 1.1 tsubai } else {
861 1.1 tsubai switch (adbHardware) {
862 1.1 tsubai case ADB_HW_II:
863 1.1 tsubai cmd = in->data[1];
864 1.1 tsubai if (in->data[0] < 2)
865 1.1 tsubai len = 0;
866 1.1 tsubai else
867 1.1 tsubai len = in->data[0]-1;
868 1.1 tsubai start = 1;
869 1.1 tsubai break;
870 1.1 tsubai
871 1.1 tsubai case ADB_HW_IISI:
872 1.1 tsubai case ADB_HW_CUDA:
873 1.1 tsubai /* If it's unsolicited, accept only ADB data for now */
874 1.1 tsubai if (in->unsol)
875 1.1 tsubai if (0 != in->data[2])
876 1.1 tsubai return;
877 1.1 tsubai cmd = in->data[4];
878 1.1 tsubai if (in->data[0] < 5)
879 1.1 tsubai len = 0;
880 1.1 tsubai else
881 1.1 tsubai len = in->data[0]-4;
882 1.1 tsubai start = 4;
883 1.1 tsubai break;
884 1.1 tsubai
885 1.1 tsubai case ADB_HW_PB:
886 1.4 tsubai cmd = in->data[1];
887 1.4 tsubai if (in->data[0] < 2)
888 1.4 tsubai len = 0;
889 1.4 tsubai else
890 1.4 tsubai len = in->data[0]-1;
891 1.4 tsubai start = 1;
892 1.4 tsubai break;
893 1.1 tsubai
894 1.1 tsubai case ADB_HW_UNKNOWN:
895 1.1 tsubai return;
896 1.1 tsubai }
897 1.1 tsubai
898 1.1 tsubai /* Make sure there is a valid device entry for this device */
899 1.1 tsubai if (in->unsol) {
900 1.1 tsubai /* ignore unsolicited data during adbreinit */
901 1.1 tsubai if (adbStarting)
902 1.1 tsubai return;
903 1.1 tsubai /* get device's comp. routine and data area */
904 1.14 tsubai if (-1 == get_adb_info(&block, ADB_CMDADDR(cmd)))
905 1.1 tsubai return;
906 1.1 tsubai }
907 1.1 tsubai }
908 1.1 tsubai
909 1.1 tsubai /*
910 1.1 tsubai * If this is an unsolicited packet, we need to fill in
911 1.1 tsubai * some info so adb_soft_intr can process this packet
912 1.1 tsubai * properly. If it's not unsolicited, then use what
913 1.1 tsubai * the caller sent us.
914 1.1 tsubai */
915 1.1 tsubai if (in->unsol) {
916 1.1 tsubai adbInbound[adbInTail].compRout = (void *)block.dbServiceRtPtr;
917 1.1 tsubai adbInbound[adbInTail].compData = (void *)block.dbDataAreaAddr;
918 1.1 tsubai adbInbound[adbInTail].saveBuf = (void *)adbInbound[adbInTail].data;
919 1.1 tsubai } else {
920 1.1 tsubai adbInbound[adbInTail].compRout = (void *)in->compRout;
921 1.1 tsubai adbInbound[adbInTail].compData = (void *)in->compData;
922 1.1 tsubai adbInbound[adbInTail].saveBuf = (void *)in->saveBuf;
923 1.1 tsubai }
924 1.1 tsubai
925 1.1 tsubai #ifdef ADB_DEBUG
926 1.1 tsubai if (adb_debug && in->data[1] == 2)
927 1.1 tsubai printf_intr("adb: caught error\n");
928 1.1 tsubai #endif
929 1.1 tsubai
930 1.1 tsubai /* copy the packet data over */
931 1.1 tsubai /*
932 1.1 tsubai * TO DO: If the *_intr routines fed their incoming data
933 1.1 tsubai * directly into an adbCommand struct, which is passed to
934 1.1 tsubai * this routine, then we could eliminate this copy.
935 1.1 tsubai */
936 1.14 tsubai memcpy(adbInbound[adbInTail].data + 1, in->data + start + 1, len);
937 1.1 tsubai adbInbound[adbInTail].data[0] = len;
938 1.1 tsubai adbInbound[adbInTail].cmd = cmd;
939 1.1 tsubai
940 1.1 tsubai adbInCount++;
941 1.1 tsubai if (++adbInTail >= ADB_QUEUE)
942 1.1 tsubai adbInTail = 0;
943 1.1 tsubai
944 1.1 tsubai /*
945 1.1 tsubai * If the debugger is running, call upper half manually.
946 1.1 tsubai * Otherwise, trigger a soft interrupt to handle the rest later.
947 1.1 tsubai */
948 1.1 tsubai if (adb_polling)
949 1.1 tsubai adb_soft_intr();
950 1.1 tsubai else
951 1.1 tsubai setsoftadb();
952 1.1 tsubai
953 1.1 tsubai return;
954 1.1 tsubai }
955 1.1 tsubai
956 1.1 tsubai
957 1.1 tsubai /*
958 1.1 tsubai * Called to process the packets after they have been
959 1.1 tsubai * placed in the incoming queue.
960 1.1 tsubai *
961 1.1 tsubai */
962 1.1 tsubai void
963 1.1 tsubai adb_soft_intr(void)
964 1.1 tsubai {
965 1.14 tsubai int s;
966 1.1 tsubai int cmd = 0;
967 1.1 tsubai u_char *buffer = 0;
968 1.1 tsubai u_char *comprout = 0;
969 1.1 tsubai u_char *compdata = 0;
970 1.1 tsubai
971 1.1 tsubai #if 0
972 1.1 tsubai s = splhigh();
973 1.1 tsubai printf_intr("sr: %x\n", (s & 0x0700));
974 1.1 tsubai splx(s);
975 1.1 tsubai #endif
976 1.1 tsubai
977 1.1 tsubai /*delay(2*ADB_DELAY);*/
978 1.1 tsubai
979 1.1 tsubai while (adbInCount) {
980 1.1 tsubai #ifdef ADB_DEBUG
981 1.1 tsubai if (adb_debug & 0x80)
982 1.1 tsubai printf_intr("%x %x %x ",
983 1.1 tsubai adbInCount, adbInHead, adbInTail);
984 1.1 tsubai #endif
985 1.1 tsubai /* get the data we need from the queue */
986 1.1 tsubai buffer = adbInbound[adbInHead].saveBuf;
987 1.1 tsubai comprout = adbInbound[adbInHead].compRout;
988 1.1 tsubai compdata = adbInbound[adbInHead].compData;
989 1.1 tsubai cmd = adbInbound[adbInHead].cmd;
990 1.1 tsubai
991 1.1 tsubai /* copy over data to data area if it's valid */
992 1.1 tsubai /*
993 1.1 tsubai * Note that for unsol packets we don't want to copy the
994 1.1 tsubai * data anywhere, so buffer was already set to 0.
995 1.1 tsubai * For ack_only buffer was set to 0, so don't copy.
996 1.1 tsubai */
997 1.1 tsubai if (buffer)
998 1.14 tsubai memcpy(buffer, adbInbound[adbInHead].data,
999 1.14 tsubai adbInbound[adbInHead].data[0] + 1);
1000 1.1 tsubai
1001 1.1 tsubai #ifdef ADB_DEBUG
1002 1.1 tsubai if (adb_debug & 0x80) {
1003 1.1 tsubai printf_intr("%p %p %p %x ",
1004 1.1 tsubai buffer, comprout, compdata, (short)cmd);
1005 1.1 tsubai printf_intr("buf: ");
1006 1.1 tsubai print_single(adbInbound[adbInHead].data);
1007 1.1 tsubai }
1008 1.1 tsubai #endif
1009 1.1 tsubai
1010 1.1 tsubai /* call default completion routine if it's valid */
1011 1.1 tsubai if (comprout) {
1012 1.18 simonb void (*f)(caddr_t, caddr_t, int) =
1013 1.18 simonb (void (*)(caddr_t, caddr_t, int))comprout;
1014 1.1 tsubai
1015 1.1 tsubai (*f)(buffer, compdata, cmd);
1016 1.1 tsubai #if 0
1017 1.1 tsubai #ifdef __NetBSD__
1018 1.1 tsubai asm(" movml #0xffff,sp@- | save all registers
1019 1.1 tsubai movl %0,a2 | compdata
1020 1.1 tsubai movl %1,a1 | comprout
1021 1.1 tsubai movl %2,a0 | buffer
1022 1.1 tsubai movl %3,d0 | cmd
1023 1.1 tsubai jbsr a1@ | go call the routine
1024 1.1 tsubai movml sp@+,#0xffff | restore all registers"
1025 1.1 tsubai :
1026 1.1 tsubai : "g"(compdata), "g"(comprout),
1027 1.1 tsubai "g"(buffer), "g"(cmd)
1028 1.1 tsubai : "d0", "a0", "a1", "a2");
1029 1.1 tsubai #else /* for macos based testing */
1030 1.1 tsubai asm
1031 1.1 tsubai {
1032 1.1 tsubai movem.l a0/a1/a2/d0, -(a7)
1033 1.1 tsubai move.l compdata, a2
1034 1.1 tsubai move.l comprout, a1
1035 1.1 tsubai move.l buffer, a0
1036 1.1 tsubai move.w cmd, d0
1037 1.1 tsubai jsr(a1)
1038 1.1 tsubai movem.l(a7)+, d0/a2/a1/a0
1039 1.1 tsubai }
1040 1.1 tsubai #endif
1041 1.1 tsubai #endif
1042 1.1 tsubai }
1043 1.1 tsubai
1044 1.1 tsubai s = splhigh();
1045 1.1 tsubai adbInCount--;
1046 1.1 tsubai if (++adbInHead >= ADB_QUEUE)
1047 1.1 tsubai adbInHead = 0;
1048 1.1 tsubai splx(s);
1049 1.1 tsubai
1050 1.1 tsubai }
1051 1.1 tsubai return;
1052 1.1 tsubai }
1053 1.1 tsubai
1054 1.1 tsubai
1055 1.1 tsubai /*
1056 1.1 tsubai * This is my version of the ADBOp routine. It mainly just calls the
1057 1.1 tsubai * hardware-specific routine.
1058 1.1 tsubai *
1059 1.1 tsubai * data : pointer to data area to be used by compRout
1060 1.1 tsubai * compRout : completion routine
1061 1.1 tsubai * buffer : for LISTEN: points to data to send - MAX 8 data bytes,
1062 1.1 tsubai * byte 0 = # of bytes
1063 1.1 tsubai * : for TALK: points to place to save return data
1064 1.1 tsubai * command : the adb command to send
1065 1.1 tsubai * result : 0 = success
1066 1.1 tsubai * : -1 = could not complete
1067 1.1 tsubai */
1068 1.1 tsubai int
1069 1.1 tsubai adb_op(Ptr buffer, Ptr compRout, Ptr data, short command)
1070 1.1 tsubai {
1071 1.1 tsubai int result;
1072 1.1 tsubai
1073 1.1 tsubai switch (adbHardware) {
1074 1.1 tsubai case ADB_HW_II:
1075 1.1 tsubai result = send_adb_II((u_char *)0, (u_char *)buffer,
1076 1.1 tsubai (void *)compRout, (void *)data, (int)command);
1077 1.1 tsubai if (result == 0)
1078 1.1 tsubai return 0;
1079 1.1 tsubai else
1080 1.1 tsubai return -1;
1081 1.1 tsubai break;
1082 1.1 tsubai
1083 1.1 tsubai case ADB_HW_IISI:
1084 1.1 tsubai result = send_adb_IIsi((u_char *)0, (u_char *)buffer,
1085 1.1 tsubai (void *)compRout, (void *)data, (int)command);
1086 1.1 tsubai /*
1087 1.1 tsubai * I wish I knew why this delay is needed. It usually needs to
1088 1.1 tsubai * be here when several commands are sent in close succession,
1089 1.1 tsubai * especially early in device probes when doing collision
1090 1.1 tsubai * detection. It must be some race condition. Sigh. - jpw
1091 1.1 tsubai */
1092 1.1 tsubai delay(100);
1093 1.1 tsubai if (result == 0)
1094 1.1 tsubai return 0;
1095 1.1 tsubai else
1096 1.1 tsubai return -1;
1097 1.1 tsubai break;
1098 1.1 tsubai
1099 1.1 tsubai case ADB_HW_PB:
1100 1.1 tsubai result = pm_adb_op((u_char *)buffer, (void *)compRout,
1101 1.1 tsubai (void *)data, (int)command);
1102 1.1 tsubai
1103 1.1 tsubai if (result == 0)
1104 1.1 tsubai return 0;
1105 1.1 tsubai else
1106 1.1 tsubai return -1;
1107 1.1 tsubai break;
1108 1.1 tsubai
1109 1.1 tsubai case ADB_HW_CUDA:
1110 1.1 tsubai result = send_adb_cuda((u_char *)0, (u_char *)buffer,
1111 1.1 tsubai (void *)compRout, (void *)data, (int)command);
1112 1.1 tsubai if (result == 0)
1113 1.1 tsubai return 0;
1114 1.1 tsubai else
1115 1.1 tsubai return -1;
1116 1.1 tsubai break;
1117 1.1 tsubai
1118 1.1 tsubai case ADB_HW_UNKNOWN:
1119 1.1 tsubai default:
1120 1.1 tsubai return -1;
1121 1.1 tsubai }
1122 1.1 tsubai }
1123 1.1 tsubai
1124 1.1 tsubai
1125 1.1 tsubai /*
1126 1.1 tsubai * adb_hw_setup
1127 1.1 tsubai * This routine sets up the possible machine specific hardware
1128 1.1 tsubai * config (mainly VIA settings) for the various models.
1129 1.1 tsubai */
1130 1.1 tsubai void
1131 1.1 tsubai adb_hw_setup(void)
1132 1.1 tsubai {
1133 1.1 tsubai volatile int i;
1134 1.1 tsubai u_char send_string[ADB_MAX_MSG_LENGTH];
1135 1.1 tsubai
1136 1.1 tsubai switch (adbHardware) {
1137 1.1 tsubai case ADB_HW_II:
1138 1.4 tsubai via_reg_or(VIA1, vDirB, 0x30); /* register B bits 4 and 5:
1139 1.1 tsubai * outputs */
1140 1.4 tsubai via_reg_and(VIA1, vDirB, 0xf7); /* register B bit 3: input */
1141 1.4 tsubai via_reg_and(VIA1, vACR, ~vSR_OUT); /* make sure SR is set
1142 1.1 tsubai * to IN (II, IIsi) */
1143 1.1 tsubai adbActionState = ADB_ACTION_IDLE; /* used by all types of
1144 1.1 tsubai * hardware (II, IIsi) */
1145 1.1 tsubai adbBusState = ADB_BUS_IDLE; /* this var. used in II-series
1146 1.1 tsubai * code only */
1147 1.4 tsubai write_via_reg(VIA1, vIER, 0x84);/* make sure VIA interrupts
1148 1.1 tsubai * are on (II, IIsi) */
1149 1.1 tsubai ADB_SET_STATE_IDLE_II(); /* set ADB bus state to idle */
1150 1.1 tsubai
1151 1.1 tsubai ADB_VIA_CLR_INTR(); /* clear interrupt */
1152 1.1 tsubai break;
1153 1.1 tsubai
1154 1.1 tsubai case ADB_HW_IISI:
1155 1.4 tsubai via_reg_or(VIA1, vDirB, 0x30); /* register B bits 4 and 5:
1156 1.1 tsubai * outputs */
1157 1.4 tsubai via_reg_and(VIA1, vDirB, 0xf7); /* register B bit 3: input */
1158 1.4 tsubai via_reg_and(VIA1, vACR, ~vSR_OUT); /* make sure SR is set
1159 1.1 tsubai * to IN (II, IIsi) */
1160 1.1 tsubai adbActionState = ADB_ACTION_IDLE; /* used by all types of
1161 1.1 tsubai * hardware (II, IIsi) */
1162 1.1 tsubai adbBusState = ADB_BUS_IDLE; /* this var. used in II-series
1163 1.1 tsubai * code only */
1164 1.4 tsubai write_via_reg(VIA1, vIER, 0x84);/* make sure VIA interrupts
1165 1.1 tsubai * are on (II, IIsi) */
1166 1.1 tsubai ADB_SET_STATE_IDLE_IISI(); /* set ADB bus state to idle */
1167 1.1 tsubai
1168 1.1 tsubai /* get those pesky clock ticks we missed while booting */
1169 1.1 tsubai for (i = 0; i < 30; i++) {
1170 1.1 tsubai delay(ADB_DELAY);
1171 1.1 tsubai adb_hw_setup_IIsi(send_string);
1172 1.6 tsubai #ifdef ADB_DEBUG
1173 1.6 tsubai if (adb_debug) {
1174 1.6 tsubai printf_intr("adb: cleanup: ");
1175 1.6 tsubai print_single(send_string);
1176 1.6 tsubai }
1177 1.6 tsubai #endif
1178 1.1 tsubai delay(ADB_DELAY);
1179 1.1 tsubai if (ADB_INTR_IS_OFF)
1180 1.1 tsubai break;
1181 1.1 tsubai }
1182 1.1 tsubai break;
1183 1.1 tsubai
1184 1.1 tsubai case ADB_HW_PB:
1185 1.1 tsubai /*
1186 1.1 tsubai * XXX - really PM_VIA_CLR_INTR - should we put it in
1187 1.1 tsubai * pm_direct.h?
1188 1.1 tsubai */
1189 1.4 tsubai write_via_reg(VIA1, vIFR, 0x90); /* clear interrupt */
1190 1.1 tsubai break;
1191 1.1 tsubai
1192 1.1 tsubai case ADB_HW_CUDA:
1193 1.1 tsubai via_reg_or(VIA1, vDirB, 0x30); /* register B bits 4 and 5:
1194 1.1 tsubai * outputs */
1195 1.1 tsubai via_reg_and(VIA1, vDirB, 0xf7); /* register B bit 3: input */
1196 1.1 tsubai via_reg_and(VIA1, vACR, ~vSR_OUT); /* make sure SR is set
1197 1.1 tsubai * to IN */
1198 1.1 tsubai write_via_reg(VIA1, vACR, (read_via_reg(VIA1, vACR) | 0x0c) & ~0x10);
1199 1.1 tsubai adbActionState = ADB_ACTION_IDLE; /* used by all types of
1200 1.1 tsubai * hardware */
1201 1.1 tsubai adbBusState = ADB_BUS_IDLE; /* this var. used in II-series
1202 1.1 tsubai * code only */
1203 1.1 tsubai write_via_reg(VIA1, vIER, 0x84);/* make sure VIA interrupts
1204 1.1 tsubai * are on */
1205 1.1 tsubai ADB_SET_STATE_IDLE_CUDA(); /* set ADB bus state to idle */
1206 1.1 tsubai
1207 1.1 tsubai /* sort of a device reset */
1208 1.1 tsubai i = ADB_SR(); /* clear interrupt */
1209 1.1 tsubai ADB_VIA_INTR_DISABLE(); /* no interrupts while clearing */
1210 1.1 tsubai ADB_SET_STATE_IDLE_CUDA(); /* reset state to idle */
1211 1.1 tsubai delay(ADB_DELAY);
1212 1.1 tsubai ADB_SET_STATE_TIP(); /* signal start of frame */
1213 1.1 tsubai delay(ADB_DELAY);
1214 1.1 tsubai ADB_TOGGLE_STATE_ACK_CUDA();
1215 1.1 tsubai delay(ADB_DELAY);
1216 1.1 tsubai ADB_CLR_STATE_TIP();
1217 1.1 tsubai delay(ADB_DELAY);
1218 1.1 tsubai ADB_SET_STATE_IDLE_CUDA(); /* back to idle state */
1219 1.1 tsubai i = ADB_SR(); /* clear interrupt */
1220 1.1 tsubai ADB_VIA_INTR_ENABLE(); /* ints ok now */
1221 1.1 tsubai break;
1222 1.1 tsubai
1223 1.1 tsubai case ADB_HW_UNKNOWN:
1224 1.1 tsubai default:
1225 1.4 tsubai write_via_reg(VIA1, vIER, 0x04);/* turn interrupts off - TO
1226 1.1 tsubai * DO: turn PB ints off? */
1227 1.1 tsubai return;
1228 1.1 tsubai break;
1229 1.1 tsubai }
1230 1.1 tsubai }
1231 1.1 tsubai
1232 1.1 tsubai
1233 1.1 tsubai /*
1234 1.1 tsubai * adb_hw_setup_IIsi
1235 1.1 tsubai * This is sort of a "read" routine that forces the adb hardware through a read cycle
1236 1.1 tsubai * if there is something waiting. This helps "clean up" any commands that may have gotten
1237 1.1 tsubai * stuck or stopped during the boot process.
1238 1.1 tsubai *
1239 1.1 tsubai */
1240 1.1 tsubai void
1241 1.1 tsubai adb_hw_setup_IIsi(u_char * buffer)
1242 1.1 tsubai {
1243 1.1 tsubai panic("adb_hw_setup_IIsi");
1244 1.1 tsubai }
1245 1.1 tsubai
1246 1.1 tsubai
1247 1.1 tsubai /*
1248 1.1 tsubai * adb_reinit sets up the adb stuff
1249 1.1 tsubai *
1250 1.1 tsubai */
1251 1.1 tsubai void
1252 1.1 tsubai adb_reinit(void)
1253 1.1 tsubai {
1254 1.1 tsubai u_char send_string[ADB_MAX_MSG_LENGTH];
1255 1.14 tsubai ADBDataBlock data; /* temp. holder for getting device info */
1256 1.1 tsubai volatile int i, x;
1257 1.14 tsubai int s;
1258 1.1 tsubai int command;
1259 1.1 tsubai int result;
1260 1.1 tsubai int saveptr; /* point to next free relocation address */
1261 1.1 tsubai int device;
1262 1.1 tsubai int nonewtimes; /* times thru loop w/o any new devices */
1263 1.1 tsubai
1264 1.1 tsubai /* Make sure we are not interrupted while building the table. */
1265 1.1 tsubai if (adbHardware != ADB_HW_PB) /* ints must be on for PB? */
1266 1.1 tsubai s = splhigh();
1267 1.1 tsubai
1268 1.1 tsubai ADBNumDevices = 0; /* no devices yet */
1269 1.1 tsubai
1270 1.1 tsubai /* Let intr routines know we are running reinit */
1271 1.1 tsubai adbStarting = 1;
1272 1.1 tsubai
1273 1.1 tsubai /*
1274 1.1 tsubai * Initialize the ADB table. For now, we'll always use the same table
1275 1.1 tsubai * that is defined at the beginning of this file - no mallocs.
1276 1.1 tsubai */
1277 1.1 tsubai for (i = 0; i < 16; i++)
1278 1.1 tsubai ADBDevTable[i].devType = 0;
1279 1.1 tsubai
1280 1.1 tsubai adb_setup_hw_type(); /* setup hardware type */
1281 1.1 tsubai
1282 1.1 tsubai adb_hw_setup(); /* init the VIA bits and hard reset ADB */
1283 1.1 tsubai
1284 1.8 tsubai delay(1000);
1285 1.1 tsubai
1286 1.1 tsubai /* send an ADB reset first */
1287 1.1 tsubai adb_op_sync((Ptr)0, (Ptr)0, (Ptr)0, (short)0x00);
1288 1.16 tsubai delay(200000);
1289 1.1 tsubai
1290 1.1 tsubai /*
1291 1.1 tsubai * Probe for ADB devices. Probe devices 1-15 quickly to determine
1292 1.1 tsubai * which device addresses are in use and which are free. For each
1293 1.1 tsubai * address that is in use, move the device at that address to a higher
1294 1.1 tsubai * free address. Continue doing this at that address until no device
1295 1.1 tsubai * responds at that address. Then move the last device that was moved
1296 1.1 tsubai * back to the original address. Do this for the remaining addresses
1297 1.1 tsubai * that we determined were in use.
1298 1.1 tsubai *
1299 1.1 tsubai * When finished, do this entire process over again with the updated
1300 1.1 tsubai * list of in use addresses. Do this until no new devices have been
1301 1.1 tsubai * found in 20 passes though the in use address list. (This probably
1302 1.1 tsubai * seems long and complicated, but it's the best way to detect multiple
1303 1.1 tsubai * devices at the same address - sometimes it takes a couple of tries
1304 1.1 tsubai * before the collision is detected.)
1305 1.1 tsubai */
1306 1.1 tsubai
1307 1.1 tsubai /* initial scan through the devices */
1308 1.1 tsubai for (i = 1; i < 16; i++) {
1309 1.12 tsubai send_string[0] = 0;
1310 1.14 tsubai command = ADBTALK(i, 3);
1311 1.1 tsubai result = adb_op_sync((Ptr)send_string, (Ptr)0,
1312 1.1 tsubai (Ptr)0, (short)command);
1313 1.14 tsubai
1314 1.14 tsubai if (send_string[0] != 0) {
1315 1.14 tsubai /* check for valid device handler */
1316 1.14 tsubai switch (send_string[2]) {
1317 1.14 tsubai case 0:
1318 1.14 tsubai case 0xfd:
1319 1.14 tsubai case 0xfe:
1320 1.14 tsubai case 0xff:
1321 1.14 tsubai continue; /* invalid, skip */
1322 1.14 tsubai }
1323 1.14 tsubai
1324 1.14 tsubai /* found a device */
1325 1.14 tsubai ++ADBNumDevices;
1326 1.14 tsubai KASSERT(ADBNumDevices < 16);
1327 1.14 tsubai ADBDevTable[ADBNumDevices].devType =
1328 1.14 tsubai (int)send_string[2];
1329 1.1 tsubai ADBDevTable[ADBNumDevices].origAddr = i;
1330 1.1 tsubai ADBDevTable[ADBNumDevices].currentAddr = i;
1331 1.1 tsubai ADBDevTable[ADBNumDevices].DataAreaAddr =
1332 1.1 tsubai (long)0;
1333 1.1 tsubai ADBDevTable[ADBNumDevices].ServiceRtPtr = (void *)0;
1334 1.1 tsubai pm_check_adb_devices(i); /* tell pm driver device
1335 1.1 tsubai * is here */
1336 1.1 tsubai }
1337 1.1 tsubai }
1338 1.1 tsubai
1339 1.1 tsubai /* find highest unused address */
1340 1.1 tsubai for (saveptr = 15; saveptr > 0; saveptr--)
1341 1.1 tsubai if (-1 == get_adb_info(&data, saveptr))
1342 1.1 tsubai break;
1343 1.1 tsubai
1344 1.1 tsubai #ifdef ADB_DEBUG
1345 1.1 tsubai if (adb_debug & 0x80) {
1346 1.1 tsubai printf_intr("first free is: 0x%02x\n", saveptr);
1347 1.1 tsubai printf_intr("devices: %i\n", ADBNumDevices);
1348 1.1 tsubai }
1349 1.1 tsubai #endif
1350 1.1 tsubai
1351 1.1 tsubai nonewtimes = 0; /* no loops w/o new devices */
1352 1.14 tsubai while (saveptr > 0 && nonewtimes++ < 11) {
1353 1.1 tsubai for (i = 1; i <= ADBNumDevices; i++) {
1354 1.1 tsubai device = ADBDevTable[i].currentAddr;
1355 1.1 tsubai #ifdef ADB_DEBUG
1356 1.1 tsubai if (adb_debug & 0x80)
1357 1.1 tsubai printf_intr("moving device 0x%02x to 0x%02x "
1358 1.1 tsubai "(index 0x%02x) ", device, saveptr, i);
1359 1.1 tsubai #endif
1360 1.1 tsubai
1361 1.1 tsubai /* send TALK R3 to address */
1362 1.14 tsubai command = ADBTALK(device, 3);
1363 1.1 tsubai adb_op_sync((Ptr)send_string, (Ptr)0,
1364 1.1 tsubai (Ptr)0, (short)command);
1365 1.1 tsubai
1366 1.1 tsubai /* move device to higher address */
1367 1.14 tsubai command = ADBLISTEN(device, 3);
1368 1.1 tsubai send_string[0] = 2;
1369 1.1 tsubai send_string[1] = (u_char)(saveptr | 0x60);
1370 1.1 tsubai send_string[2] = 0xfe;
1371 1.1 tsubai adb_op_sync((Ptr)send_string, (Ptr)0,
1372 1.1 tsubai (Ptr)0, (short)command);
1373 1.8 tsubai delay(500);
1374 1.1 tsubai
1375 1.14 tsubai /* send TALK R3 - anything at new address? */
1376 1.14 tsubai command = ADBTALK(saveptr, 3);
1377 1.14 tsubai adb_op_sync((Ptr)send_string, (Ptr)0,
1378 1.14 tsubai (Ptr)0, (short)command);
1379 1.14 tsubai delay(500);
1380 1.14 tsubai
1381 1.14 tsubai if (send_string[0] == 0) {
1382 1.14 tsubai #ifdef ADB_DEBUG
1383 1.14 tsubai if (adb_debug & 0x80)
1384 1.14 tsubai printf_intr("failed, continuing\n");
1385 1.14 tsubai #endif
1386 1.14 tsubai continue;
1387 1.14 tsubai }
1388 1.14 tsubai
1389 1.1 tsubai /* send TALK R3 - anything at old address? */
1390 1.14 tsubai command = ADBTALK(device, 3);
1391 1.1 tsubai result = adb_op_sync((Ptr)send_string, (Ptr)0,
1392 1.1 tsubai (Ptr)0, (short)command);
1393 1.1 tsubai if (send_string[0] != 0) {
1394 1.14 tsubai /* check for valid device handler */
1395 1.14 tsubai switch (send_string[2]) {
1396 1.14 tsubai case 0:
1397 1.14 tsubai case 0xfd:
1398 1.14 tsubai case 0xfe:
1399 1.14 tsubai case 0xff:
1400 1.14 tsubai continue; /* invalid, skip */
1401 1.14 tsubai }
1402 1.14 tsubai
1403 1.1 tsubai /* new device found */
1404 1.1 tsubai /* update data for previously moved device */
1405 1.1 tsubai ADBDevTable[i].currentAddr = saveptr;
1406 1.1 tsubai #ifdef ADB_DEBUG
1407 1.1 tsubai if (adb_debug & 0x80)
1408 1.1 tsubai printf_intr("old device at index %i\n",i);
1409 1.1 tsubai #endif
1410 1.1 tsubai /* add new device in table */
1411 1.1 tsubai #ifdef ADB_DEBUG
1412 1.1 tsubai if (adb_debug & 0x80)
1413 1.1 tsubai printf_intr("new device found\n");
1414 1.1 tsubai #endif
1415 1.14 tsubai if (saveptr > ADBNumDevices) {
1416 1.14 tsubai ++ADBNumDevices;
1417 1.14 tsubai KASSERT(ADBNumDevices < 16);
1418 1.14 tsubai }
1419 1.14 tsubai ADBDevTable[ADBNumDevices].devType =
1420 1.14 tsubai (int)send_string[2];
1421 1.1 tsubai ADBDevTable[ADBNumDevices].origAddr = device;
1422 1.1 tsubai ADBDevTable[ADBNumDevices].currentAddr = device;
1423 1.1 tsubai /* These will be set correctly in adbsys.c */
1424 1.1 tsubai /* Until then, unsol. data will be ignored. */
1425 1.1 tsubai ADBDevTable[ADBNumDevices].DataAreaAddr =
1426 1.1 tsubai (long)0;
1427 1.1 tsubai ADBDevTable[ADBNumDevices].ServiceRtPtr =
1428 1.1 tsubai (void *)0;
1429 1.1 tsubai /* find next unused address */
1430 1.14 tsubai for (x = saveptr; x > 0; x--) {
1431 1.1 tsubai if (-1 == get_adb_info(&data, x)) {
1432 1.1 tsubai saveptr = x;
1433 1.1 tsubai break;
1434 1.1 tsubai }
1435 1.14 tsubai }
1436 1.14 tsubai if (x == 0)
1437 1.14 tsubai saveptr = 0;
1438 1.1 tsubai #ifdef ADB_DEBUG
1439 1.1 tsubai if (adb_debug & 0x80)
1440 1.1 tsubai printf_intr("new free is 0x%02x\n",
1441 1.1 tsubai saveptr);
1442 1.1 tsubai #endif
1443 1.1 tsubai nonewtimes = 0;
1444 1.1 tsubai /* tell pm driver device is here */
1445 1.1 tsubai pm_check_adb_devices(device);
1446 1.1 tsubai } else {
1447 1.1 tsubai #ifdef ADB_DEBUG
1448 1.1 tsubai if (adb_debug & 0x80)
1449 1.1 tsubai printf_intr("moving back...\n");
1450 1.1 tsubai #endif
1451 1.1 tsubai /* move old device back */
1452 1.14 tsubai command = ADBLISTEN(saveptr, 3);
1453 1.1 tsubai send_string[0] = 2;
1454 1.1 tsubai send_string[1] = (u_char)(device | 0x60);
1455 1.1 tsubai send_string[2] = 0xfe;
1456 1.1 tsubai adb_op_sync((Ptr)send_string, (Ptr)0,
1457 1.1 tsubai (Ptr)0, (short)command);
1458 1.8 tsubai delay(1000);
1459 1.1 tsubai }
1460 1.1 tsubai }
1461 1.1 tsubai }
1462 1.1 tsubai
1463 1.1 tsubai #ifdef ADB_DEBUG
1464 1.1 tsubai if (adb_debug) {
1465 1.1 tsubai for (i = 1; i <= ADBNumDevices; i++) {
1466 1.1 tsubai x = get_ind_adb_info(&data, i);
1467 1.1 tsubai if (x != -1)
1468 1.1 tsubai printf_intr("index 0x%x, addr 0x%x, type 0x%x\n",
1469 1.1 tsubai i, x, data.devType);
1470 1.1 tsubai }
1471 1.1 tsubai }
1472 1.1 tsubai #endif
1473 1.1 tsubai
1474 1.6 tsubai #ifndef MRG_ADB
1475 1.1 tsubai /* enable the programmer's switch, if we have one */
1476 1.1 tsubai adb_prog_switch_enable();
1477 1.6 tsubai #endif
1478 1.1 tsubai
1479 1.6 tsubai #ifdef ADB_DEBUG
1480 1.6 tsubai if (adb_debug) {
1481 1.6 tsubai if (0 == ADBNumDevices) /* tell user if no devices found */
1482 1.6 tsubai printf_intr("adb: no devices found\n");
1483 1.6 tsubai }
1484 1.6 tsubai #endif
1485 1.1 tsubai
1486 1.1 tsubai adbStarting = 0; /* not starting anymore */
1487 1.1 tsubai #ifdef ADB_DEBUG
1488 1.6 tsubai if (adb_debug)
1489 1.6 tsubai printf_intr("adb: ADBReInit complete\n");
1490 1.1 tsubai #endif
1491 1.1 tsubai
1492 1.1 tsubai if (adbHardware == ADB_HW_CUDA)
1493 1.13 thorpej callout_reset(&adb_cuda_tickle_ch, ADB_TICKLE_TICKS,
1494 1.13 thorpej (void *)adb_cuda_tickle, NULL);
1495 1.1 tsubai
1496 1.1 tsubai if (adbHardware != ADB_HW_PB) /* ints must be on for PB? */
1497 1.1 tsubai splx(s);
1498 1.1 tsubai }
1499 1.1 tsubai
1500 1.1 tsubai
1501 1.1 tsubai #if 0
1502 1.1 tsubai /*
1503 1.1 tsubai * adb_comp_exec
1504 1.1 tsubai * This is a general routine that calls the completion routine if there is one.
1505 1.1 tsubai * NOTE: This routine is now only used by pm_direct.c
1506 1.1 tsubai * All the code in this file (adb_direct.c) uses
1507 1.1 tsubai * the adb_pass_up routine now.
1508 1.1 tsubai */
1509 1.1 tsubai void
1510 1.1 tsubai adb_comp_exec(void)
1511 1.1 tsubai {
1512 1.1 tsubai if ((long)0 != adbCompRout) /* don't call if empty return location */
1513 1.1 tsubai #ifdef __NetBSD__
1514 1.1 tsubai asm(" movml #0xffff,sp@- | save all registers
1515 1.1 tsubai movl %0,a2 | adbCompData
1516 1.1 tsubai movl %1,a1 | adbCompRout
1517 1.1 tsubai movl %2,a0 | adbBuffer
1518 1.1 tsubai movl %3,d0 | adbWaitingCmd
1519 1.1 tsubai jbsr a1@ | go call the routine
1520 1.1 tsubai movml sp@+,#0xffff | restore all registers"
1521 1.1 tsubai :
1522 1.1 tsubai : "g"(adbCompData), "g"(adbCompRout),
1523 1.1 tsubai "g"(adbBuffer), "g"(adbWaitingCmd)
1524 1.1 tsubai : "d0", "a0", "a1", "a2");
1525 1.1 tsubai #else /* for Mac OS-based testing */
1526 1.1 tsubai asm {
1527 1.1 tsubai movem.l a0/a1/a2/d0, -(a7)
1528 1.1 tsubai move.l adbCompData, a2
1529 1.1 tsubai move.l adbCompRout, a1
1530 1.1 tsubai move.l adbBuffer, a0
1531 1.1 tsubai move.w adbWaitingCmd, d0
1532 1.1 tsubai jsr(a1)
1533 1.1 tsubai movem.l(a7) +, d0/a2/a1/a0
1534 1.1 tsubai }
1535 1.1 tsubai #endif
1536 1.1 tsubai }
1537 1.1 tsubai #endif
1538 1.1 tsubai
1539 1.1 tsubai
1540 1.1 tsubai /*
1541 1.1 tsubai * adb_cmd_result
1542 1.1 tsubai *
1543 1.1 tsubai * This routine lets the caller know whether the specified adb command string
1544 1.1 tsubai * should expect a returned result, such as a TALK command.
1545 1.1 tsubai *
1546 1.1 tsubai * returns: 0 if a result should be expected
1547 1.1 tsubai * 1 if a result should NOT be expected
1548 1.1 tsubai */
1549 1.1 tsubai int
1550 1.1 tsubai adb_cmd_result(u_char *in)
1551 1.1 tsubai {
1552 1.1 tsubai switch (adbHardware) {
1553 1.1 tsubai case ADB_HW_II:
1554 1.1 tsubai /* was it an ADB talk command? */
1555 1.1 tsubai if ((in[1] & 0x0c) == 0x0c)
1556 1.1 tsubai return 0;
1557 1.1 tsubai return 1;
1558 1.1 tsubai
1559 1.1 tsubai case ADB_HW_IISI:
1560 1.1 tsubai case ADB_HW_CUDA:
1561 1.1 tsubai /* was it an ADB talk command? */
1562 1.1 tsubai if ((in[1] == 0x00) && ((in[2] & 0x0c) == 0x0c))
1563 1.1 tsubai return 0;
1564 1.1 tsubai /* was it an RTC/PRAM read date/time? */
1565 1.1 tsubai if ((in[1] == 0x01) && (in[2] == 0x03))
1566 1.1 tsubai return 0;
1567 1.1 tsubai return 1;
1568 1.1 tsubai
1569 1.1 tsubai case ADB_HW_PB:
1570 1.1 tsubai return 1;
1571 1.1 tsubai
1572 1.1 tsubai case ADB_HW_UNKNOWN:
1573 1.1 tsubai default:
1574 1.1 tsubai return 1;
1575 1.1 tsubai }
1576 1.1 tsubai }
1577 1.1 tsubai
1578 1.1 tsubai
1579 1.1 tsubai /*
1580 1.1 tsubai * adb_cmd_extra
1581 1.1 tsubai *
1582 1.1 tsubai * This routine lets the caller know whether the specified adb command string
1583 1.1 tsubai * may have extra data appended to the end of it, such as a LISTEN command.
1584 1.1 tsubai *
1585 1.1 tsubai * returns: 0 if extra data is allowed
1586 1.1 tsubai * 1 if extra data is NOT allowed
1587 1.1 tsubai */
1588 1.1 tsubai int
1589 1.1 tsubai adb_cmd_extra(u_char *in)
1590 1.1 tsubai {
1591 1.1 tsubai switch (adbHardware) {
1592 1.1 tsubai case ADB_HW_II:
1593 1.1 tsubai if ((in[1] & 0x0c) == 0x08) /* was it a listen command? */
1594 1.1 tsubai return 0;
1595 1.1 tsubai return 1;
1596 1.1 tsubai
1597 1.1 tsubai case ADB_HW_IISI:
1598 1.1 tsubai case ADB_HW_CUDA:
1599 1.1 tsubai /*
1600 1.1 tsubai * TO DO: support needs to be added to recognize RTC and PRAM
1601 1.1 tsubai * commands
1602 1.1 tsubai */
1603 1.1 tsubai if ((in[2] & 0x0c) == 0x08) /* was it a listen command? */
1604 1.1 tsubai return 0;
1605 1.1 tsubai /* add others later */
1606 1.1 tsubai return 1;
1607 1.1 tsubai
1608 1.1 tsubai case ADB_HW_PB:
1609 1.1 tsubai return 1;
1610 1.1 tsubai
1611 1.1 tsubai case ADB_HW_UNKNOWN:
1612 1.1 tsubai default:
1613 1.1 tsubai return 1;
1614 1.1 tsubai }
1615 1.1 tsubai }
1616 1.1 tsubai
1617 1.1 tsubai /*
1618 1.1 tsubai * adb_op_sync
1619 1.1 tsubai *
1620 1.1 tsubai * This routine does exactly what the adb_op routine does, except that after
1621 1.1 tsubai * the adb_op is called, it waits until the return value is present before
1622 1.1 tsubai * returning.
1623 1.1 tsubai *
1624 1.1 tsubai * NOTE: The user specified compRout is ignored, since this routine specifies
1625 1.1 tsubai * it's own to adb_op, which is why you really called this in the first place
1626 1.1 tsubai * anyway.
1627 1.1 tsubai */
1628 1.1 tsubai int
1629 1.1 tsubai adb_op_sync(Ptr buffer, Ptr compRout, Ptr data, short command)
1630 1.1 tsubai {
1631 1.15 tsubai int tmout;
1632 1.1 tsubai int result;
1633 1.1 tsubai volatile int flag = 0;
1634 1.1 tsubai
1635 1.1 tsubai result = adb_op(buffer, (void *)adb_op_comprout,
1636 1.1 tsubai (void *)&flag, command); /* send command */
1637 1.15 tsubai if (result == 0) { /* send ok? */
1638 1.15 tsubai /*
1639 1.15 tsubai * Total time to wait is calculated as follows:
1640 1.15 tsubai * - Tlt (stop to start time): 260 usec
1641 1.15 tsubai * - start bit: 100 usec
1642 1.15 tsubai * - up to 8 data bytes: 64 * 100 usec = 6400 usec
1643 1.15 tsubai * - stop bit (with SRQ): 140 usec
1644 1.15 tsubai * Total: 6900 usec
1645 1.15 tsubai *
1646 1.15 tsubai * This is the total time allowed by the specification. Any
1647 1.15 tsubai * device that doesn't conform to this will fail to operate
1648 1.15 tsubai * properly on some Apple systems. In spite of this we
1649 1.15 tsubai * double the time to wait; some Cuda-based apparently
1650 1.15 tsubai * queues some commands and allows the main CPU to continue
1651 1.15 tsubai * processing (radical concept, eh?). To be safe, allow
1652 1.15 tsubai * time for two complete ADB transactions to occur.
1653 1.15 tsubai */
1654 1.15 tsubai for (tmout = 13800; !flag && tmout >= 10; tmout -= 10)
1655 1.15 tsubai delay(10);
1656 1.15 tsubai if (!flag && tmout > 0)
1657 1.15 tsubai delay(tmout);
1658 1.15 tsubai
1659 1.15 tsubai if (!flag)
1660 1.15 tsubai result = -2;
1661 1.15 tsubai }
1662 1.1 tsubai
1663 1.1 tsubai return result;
1664 1.1 tsubai }
1665 1.1 tsubai
1666 1.1 tsubai /*
1667 1.1 tsubai * adb_op_comprout
1668 1.1 tsubai *
1669 1.1 tsubai * This function is used by the adb_op_sync routine so it knows when the
1670 1.1 tsubai * function is done.
1671 1.1 tsubai */
1672 1.1 tsubai void
1673 1.1 tsubai adb_op_comprout(buffer, compdata, cmd)
1674 1.1 tsubai caddr_t buffer, compdata;
1675 1.1 tsubai int cmd;
1676 1.1 tsubai {
1677 1.1 tsubai short *p = (short *)compdata;
1678 1.1 tsubai
1679 1.1 tsubai *p = 1;
1680 1.1 tsubai }
1681 1.1 tsubai
1682 1.1 tsubai void
1683 1.1 tsubai adb_setup_hw_type(void)
1684 1.1 tsubai {
1685 1.6 tsubai switch (adbHardware) {
1686 1.6 tsubai case ADB_HW_CUDA:
1687 1.6 tsubai adbSoftPower = 1;
1688 1.4 tsubai return;
1689 1.4 tsubai
1690 1.6 tsubai case ADB_HW_PB:
1691 1.11 tsubai adbSoftPower = 1;
1692 1.4 tsubai pm_setup_adb();
1693 1.4 tsubai return;
1694 1.6 tsubai
1695 1.6 tsubai default:
1696 1.6 tsubai panic("unknown adb hardware");
1697 1.4 tsubai }
1698 1.6 tsubai #if 0
1699 1.1 tsubai response = 0; /*mac68k_machine.machineid;*/
1700 1.1 tsubai
1701 1.1 tsubai /*
1702 1.1 tsubai * Determine what type of ADB hardware we are running on.
1703 1.1 tsubai */
1704 1.1 tsubai switch (response) {
1705 1.6 tsubai case MACH_MACC610: /* Centris 610 */
1706 1.6 tsubai case MACH_MACC650: /* Centris 650 */
1707 1.6 tsubai case MACH_MACII: /* II */
1708 1.6 tsubai case MACH_MACIICI: /* IIci */
1709 1.6 tsubai case MACH_MACIICX: /* IIcx */
1710 1.6 tsubai case MACH_MACIIX: /* IIx */
1711 1.6 tsubai case MACH_MACQ610: /* Quadra 610 */
1712 1.6 tsubai case MACH_MACQ650: /* Quadra 650 */
1713 1.6 tsubai case MACH_MACQ700: /* Quadra 700 */
1714 1.6 tsubai case MACH_MACQ800: /* Quadra 800 */
1715 1.6 tsubai case MACH_MACSE30: /* SE/30 */
1716 1.1 tsubai adbHardware = ADB_HW_II;
1717 1.6 tsubai #ifdef ADB_DEBUG
1718 1.6 tsubai if (adb_debug)
1719 1.6 tsubai printf_intr("adb: using II series hardware support\n");
1720 1.6 tsubai #endif
1721 1.1 tsubai break;
1722 1.6 tsubai
1723 1.6 tsubai case MACH_MACCLASSICII: /* Classic II */
1724 1.6 tsubai case MACH_MACLCII: /* LC II, Performa 400/405/430 */
1725 1.6 tsubai case MACH_MACLCIII: /* LC III, Performa 450 */
1726 1.6 tsubai case MACH_MACIISI: /* IIsi */
1727 1.6 tsubai case MACH_MACIIVI: /* IIvi */
1728 1.6 tsubai case MACH_MACIIVX: /* IIvx */
1729 1.6 tsubai case MACH_MACP460: /* Performa 460/465/467 */
1730 1.6 tsubai case MACH_MACP600: /* Performa 600 */
1731 1.1 tsubai adbHardware = ADB_HW_IISI;
1732 1.6 tsubai #ifdef ADB_DEBUG
1733 1.6 tsubai if (adb_debug)
1734 1.6 tsubai printf_intr("adb: using IIsi series hardware support\n");
1735 1.6 tsubai #endif
1736 1.1 tsubai break;
1737 1.6 tsubai
1738 1.6 tsubai case MACH_MACPB140: /* PowerBook 140 */
1739 1.6 tsubai case MACH_MACPB145: /* PowerBook 145 */
1740 1.6 tsubai case MACH_MACPB150: /* PowerBook 150 */
1741 1.6 tsubai case MACH_MACPB160: /* PowerBook 160 */
1742 1.6 tsubai case MACH_MACPB165: /* PowerBook 165 */
1743 1.6 tsubai case MACH_MACPB165C: /* PowerBook 165c */
1744 1.6 tsubai case MACH_MACPB170: /* PowerBook 170 */
1745 1.6 tsubai case MACH_MACPB180: /* PowerBook 180 */
1746 1.6 tsubai case MACH_MACPB180C: /* PowerBook 180c */
1747 1.1 tsubai adbHardware = ADB_HW_PB;
1748 1.1 tsubai pm_setup_adb();
1749 1.6 tsubai #ifdef ADB_DEBUG
1750 1.6 tsubai if (adb_debug)
1751 1.6 tsubai printf_intr("adb: using PowerBook 100-series hardware support\n");
1752 1.6 tsubai #endif
1753 1.1 tsubai break;
1754 1.6 tsubai
1755 1.6 tsubai case MACH_MACPB210: /* PowerBook Duo 210 */
1756 1.6 tsubai case MACH_MACPB230: /* PowerBook Duo 230 */
1757 1.6 tsubai case MACH_MACPB250: /* PowerBook Duo 250 */
1758 1.6 tsubai case MACH_MACPB270: /* PowerBook Duo 270 */
1759 1.6 tsubai case MACH_MACPB280: /* PowerBook Duo 280 */
1760 1.6 tsubai case MACH_MACPB280C: /* PowerBook Duo 280c */
1761 1.6 tsubai case MACH_MACPB500: /* PowerBook 500 series */
1762 1.1 tsubai adbHardware = ADB_HW_PB;
1763 1.1 tsubai pm_setup_adb();
1764 1.6 tsubai #ifdef ADB_DEBUG
1765 1.6 tsubai if (adb_debug)
1766 1.6 tsubai printf_intr("adb: using PowerBook Duo-series and PowerBook 500-series hardware support\n");
1767 1.6 tsubai #endif
1768 1.1 tsubai break;
1769 1.6 tsubai
1770 1.6 tsubai case MACH_MACC660AV: /* Centris 660AV */
1771 1.6 tsubai case MACH_MACCCLASSIC: /* Color Classic */
1772 1.6 tsubai case MACH_MACCCLASSICII: /* Color Classic II */
1773 1.6 tsubai case MACH_MACLC475: /* LC 475, Performa 475/476 */
1774 1.6 tsubai case MACH_MACLC475_33: /* Clock-chipped 47x */
1775 1.6 tsubai case MACH_MACLC520: /* LC 520 */
1776 1.6 tsubai case MACH_MACLC575: /* LC 575, Performa 575/577/578 */
1777 1.6 tsubai case MACH_MACP550: /* LC 550, Performa 550 */
1778 1.6 tsubai case MACH_MACP580: /* Performa 580/588 */
1779 1.6 tsubai case MACH_MACQ605: /* Quadra 605 */
1780 1.6 tsubai case MACH_MACQ605_33: /* Clock-chipped Quadra 605 */
1781 1.6 tsubai case MACH_MACQ630: /* LC 630, Performa 630, Quadra 630 */
1782 1.6 tsubai case MACH_MACQ840AV: /* Quadra 840AV */
1783 1.1 tsubai adbHardware = ADB_HW_CUDA;
1784 1.6 tsubai #ifdef ADB_DEBUG
1785 1.6 tsubai if (adb_debug)
1786 1.6 tsubai printf_intr("adb: using Cuda series hardware support\n");
1787 1.6 tsubai #endif
1788 1.1 tsubai break;
1789 1.1 tsubai default:
1790 1.1 tsubai adbHardware = ADB_HW_UNKNOWN;
1791 1.6 tsubai #ifdef ADB_DEBUG
1792 1.6 tsubai if (adb_debug) {
1793 1.6 tsubai printf_intr("adb: hardware type unknown for this machine\n");
1794 1.6 tsubai printf_intr("adb: ADB support is disabled\n");
1795 1.6 tsubai }
1796 1.6 tsubai #endif
1797 1.1 tsubai break;
1798 1.1 tsubai }
1799 1.1 tsubai
1800 1.1 tsubai /*
1801 1.1 tsubai * Determine whether this machine has ADB based soft power.
1802 1.1 tsubai */
1803 1.1 tsubai switch (response) {
1804 1.6 tsubai case MACH_MACCCLASSIC: /* Color Classic */
1805 1.6 tsubai case MACH_MACCCLASSICII: /* Color Classic II */
1806 1.6 tsubai case MACH_MACIISI: /* IIsi */
1807 1.6 tsubai case MACH_MACIIVI: /* IIvi */
1808 1.6 tsubai case MACH_MACIIVX: /* IIvx */
1809 1.6 tsubai case MACH_MACLC520: /* LC 520 */
1810 1.6 tsubai case MACH_MACLC575: /* LC 575, Performa 575/577/578 */
1811 1.6 tsubai case MACH_MACP550: /* LC 550, Performa 550 */
1812 1.6 tsubai case MACH_MACP600: /* Performa 600 */
1813 1.6 tsubai case MACH_MACQ630: /* LC 630, Performa 630, Quadra 630 */
1814 1.6 tsubai case MACH_MACQ840AV: /* Quadra 840AV */
1815 1.1 tsubai adbSoftPower = 1;
1816 1.1 tsubai break;
1817 1.1 tsubai }
1818 1.6 tsubai #endif
1819 1.1 tsubai }
1820 1.1 tsubai
1821 1.1 tsubai int
1822 1.1 tsubai count_adbs(void)
1823 1.1 tsubai {
1824 1.1 tsubai int i;
1825 1.1 tsubai int found;
1826 1.1 tsubai
1827 1.1 tsubai found = 0;
1828 1.1 tsubai
1829 1.1 tsubai for (i = 1; i < 16; i++)
1830 1.1 tsubai if (0 != ADBDevTable[i].devType)
1831 1.1 tsubai found++;
1832 1.1 tsubai
1833 1.1 tsubai return found;
1834 1.1 tsubai }
1835 1.1 tsubai
1836 1.1 tsubai int
1837 1.1 tsubai get_ind_adb_info(ADBDataBlock * info, int index)
1838 1.1 tsubai {
1839 1.1 tsubai if ((index < 1) || (index > 15)) /* check range 1-15 */
1840 1.1 tsubai return (-1);
1841 1.1 tsubai
1842 1.1 tsubai #ifdef ADB_DEBUG
1843 1.1 tsubai if (adb_debug & 0x80)
1844 1.1 tsubai printf_intr("index 0x%x devType is: 0x%x\n", index,
1845 1.1 tsubai ADBDevTable[index].devType);
1846 1.1 tsubai #endif
1847 1.1 tsubai if (0 == ADBDevTable[index].devType) /* make sure it's a valid entry */
1848 1.1 tsubai return (-1);
1849 1.1 tsubai
1850 1.1 tsubai info->devType = ADBDevTable[index].devType;
1851 1.1 tsubai info->origADBAddr = ADBDevTable[index].origAddr;
1852 1.1 tsubai info->dbServiceRtPtr = (Ptr)ADBDevTable[index].ServiceRtPtr;
1853 1.1 tsubai info->dbDataAreaAddr = (Ptr)ADBDevTable[index].DataAreaAddr;
1854 1.1 tsubai
1855 1.1 tsubai return (ADBDevTable[index].currentAddr);
1856 1.1 tsubai }
1857 1.1 tsubai
1858 1.1 tsubai int
1859 1.1 tsubai get_adb_info(ADBDataBlock * info, int adbAddr)
1860 1.1 tsubai {
1861 1.1 tsubai int i;
1862 1.1 tsubai
1863 1.1 tsubai if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */
1864 1.1 tsubai return (-1);
1865 1.1 tsubai
1866 1.1 tsubai for (i = 1; i < 15; i++)
1867 1.1 tsubai if (ADBDevTable[i].currentAddr == adbAddr) {
1868 1.1 tsubai info->devType = ADBDevTable[i].devType;
1869 1.1 tsubai info->origADBAddr = ADBDevTable[i].origAddr;
1870 1.1 tsubai info->dbServiceRtPtr = (Ptr)ADBDevTable[i].ServiceRtPtr;
1871 1.1 tsubai info->dbDataAreaAddr = ADBDevTable[i].DataAreaAddr;
1872 1.1 tsubai return 0; /* found */
1873 1.1 tsubai }
1874 1.1 tsubai
1875 1.1 tsubai return (-1); /* not found */
1876 1.1 tsubai }
1877 1.1 tsubai
1878 1.1 tsubai int
1879 1.1 tsubai set_adb_info(ADBSetInfoBlock * info, int adbAddr)
1880 1.1 tsubai {
1881 1.1 tsubai int i;
1882 1.1 tsubai
1883 1.1 tsubai if ((adbAddr < 1) || (adbAddr > 15)) /* check range 1-15 */
1884 1.1 tsubai return (-1);
1885 1.1 tsubai
1886 1.1 tsubai for (i = 1; i < 15; i++)
1887 1.1 tsubai if (ADBDevTable[i].currentAddr == adbAddr) {
1888 1.1 tsubai ADBDevTable[i].ServiceRtPtr =
1889 1.1 tsubai (void *)(info->siServiceRtPtr);
1890 1.1 tsubai ADBDevTable[i].DataAreaAddr = info->siDataAreaAddr;
1891 1.1 tsubai return 0; /* found */
1892 1.1 tsubai }
1893 1.1 tsubai
1894 1.1 tsubai return (-1); /* not found */
1895 1.1 tsubai
1896 1.1 tsubai }
1897 1.1 tsubai
1898 1.6 tsubai #ifndef MRG_ADB
1899 1.6 tsubai
1900 1.1 tsubai /* caller should really use machine-independant version: getPramTime */
1901 1.1 tsubai /* this version does pseudo-adb access only */
1902 1.1 tsubai int
1903 1.1 tsubai adb_read_date_time(unsigned long *time)
1904 1.1 tsubai {
1905 1.1 tsubai u_char output[ADB_MAX_MSG_LENGTH];
1906 1.1 tsubai int result;
1907 1.1 tsubai volatile int flag = 0;
1908 1.1 tsubai
1909 1.1 tsubai switch (adbHardware) {
1910 1.1 tsubai case ADB_HW_II:
1911 1.1 tsubai return -1;
1912 1.1 tsubai
1913 1.1 tsubai case ADB_HW_IISI:
1914 1.1 tsubai output[0] = 0x02; /* 2 byte message */
1915 1.1 tsubai output[1] = 0x01; /* to pram/rtc device */
1916 1.1 tsubai output[2] = 0x03; /* read date/time */
1917 1.1 tsubai result = send_adb_IIsi((u_char *)output, (u_char *)output,
1918 1.1 tsubai (void *)adb_op_comprout, (int *)&flag, (int)0);
1919 1.1 tsubai if (result != 0) /* exit if not sent */
1920 1.1 tsubai return -1;
1921 1.1 tsubai
1922 1.1 tsubai while (0 == flag) /* wait for result */
1923 1.1 tsubai ;
1924 1.1 tsubai
1925 1.1 tsubai *time = (long)(*(long *)(output + 1));
1926 1.1 tsubai return 0;
1927 1.1 tsubai
1928 1.1 tsubai case ADB_HW_PB:
1929 1.7 tsubai pm_read_date_time(time);
1930 1.10 tsubai return 0;
1931 1.1 tsubai
1932 1.1 tsubai case ADB_HW_CUDA:
1933 1.1 tsubai output[0] = 0x02; /* 2 byte message */
1934 1.1 tsubai output[1] = 0x01; /* to pram/rtc device */
1935 1.1 tsubai output[2] = 0x03; /* read date/time */
1936 1.1 tsubai result = send_adb_cuda((u_char *)output, (u_char *)output,
1937 1.1 tsubai (void *)adb_op_comprout, (void *)&flag, (int)0);
1938 1.1 tsubai if (result != 0) /* exit if not sent */
1939 1.1 tsubai return -1;
1940 1.1 tsubai
1941 1.1 tsubai while (0 == flag) /* wait for result */
1942 1.1 tsubai ;
1943 1.1 tsubai
1944 1.6 tsubai memcpy(time, output + 1, 4);
1945 1.1 tsubai return 0;
1946 1.1 tsubai
1947 1.1 tsubai case ADB_HW_UNKNOWN:
1948 1.1 tsubai default:
1949 1.1 tsubai return -1;
1950 1.1 tsubai }
1951 1.1 tsubai }
1952 1.1 tsubai
1953 1.1 tsubai /* caller should really use machine-independant version: setPramTime */
1954 1.1 tsubai /* this version does pseudo-adb access only */
1955 1.1 tsubai int
1956 1.1 tsubai adb_set_date_time(unsigned long time)
1957 1.1 tsubai {
1958 1.1 tsubai u_char output[ADB_MAX_MSG_LENGTH];
1959 1.1 tsubai int result;
1960 1.1 tsubai volatile int flag = 0;
1961 1.1 tsubai
1962 1.1 tsubai switch (adbHardware) {
1963 1.1 tsubai
1964 1.1 tsubai case ADB_HW_CUDA:
1965 1.1 tsubai output[0] = 0x06; /* 6 byte message */
1966 1.1 tsubai output[1] = 0x01; /* to pram/rtc device */
1967 1.1 tsubai output[2] = 0x09; /* set date/time */
1968 1.1 tsubai output[3] = (u_char)(time >> 24);
1969 1.1 tsubai output[4] = (u_char)(time >> 16);
1970 1.1 tsubai output[5] = (u_char)(time >> 8);
1971 1.1 tsubai output[6] = (u_char)(time);
1972 1.1 tsubai result = send_adb_cuda((u_char *)output, (u_char *)0,
1973 1.1 tsubai (void *)adb_op_comprout, (void *)&flag, (int)0);
1974 1.1 tsubai if (result != 0) /* exit if not sent */
1975 1.1 tsubai return -1;
1976 1.1 tsubai
1977 1.1 tsubai while (0 == flag) /* wait for send to finish */
1978 1.1 tsubai ;
1979 1.1 tsubai
1980 1.1 tsubai return 0;
1981 1.1 tsubai
1982 1.10 tsubai case ADB_HW_PB:
1983 1.10 tsubai pm_set_date_time(time);
1984 1.10 tsubai return 0;
1985 1.10 tsubai
1986 1.1 tsubai case ADB_HW_II:
1987 1.1 tsubai case ADB_HW_IISI:
1988 1.1 tsubai case ADB_HW_UNKNOWN:
1989 1.1 tsubai default:
1990 1.1 tsubai return -1;
1991 1.1 tsubai }
1992 1.1 tsubai }
1993 1.1 tsubai
1994 1.1 tsubai
1995 1.1 tsubai int
1996 1.1 tsubai adb_poweroff(void)
1997 1.1 tsubai {
1998 1.1 tsubai u_char output[ADB_MAX_MSG_LENGTH];
1999 1.1 tsubai int result;
2000 1.1 tsubai
2001 1.1 tsubai if (!adbSoftPower)
2002 1.1 tsubai return -1;
2003 1.1 tsubai
2004 1.9 tsubai adb_polling = 1;
2005 1.9 tsubai
2006 1.1 tsubai switch (adbHardware) {
2007 1.1 tsubai case ADB_HW_IISI:
2008 1.1 tsubai output[0] = 0x02; /* 2 byte message */
2009 1.1 tsubai output[1] = 0x01; /* to pram/rtc/soft-power device */
2010 1.1 tsubai output[2] = 0x0a; /* set date/time */
2011 1.1 tsubai result = send_adb_IIsi((u_char *)output, (u_char *)0,
2012 1.1 tsubai (void *)0, (void *)0, (int)0);
2013 1.1 tsubai if (result != 0) /* exit if not sent */
2014 1.1 tsubai return -1;
2015 1.1 tsubai
2016 1.1 tsubai for (;;); /* wait for power off */
2017 1.1 tsubai
2018 1.1 tsubai return 0;
2019 1.1 tsubai
2020 1.1 tsubai case ADB_HW_PB:
2021 1.11 tsubai pm_adb_poweroff();
2022 1.11 tsubai
2023 1.11 tsubai for (;;); /* wait for power off */
2024 1.11 tsubai
2025 1.11 tsubai return 0;
2026 1.1 tsubai
2027 1.1 tsubai case ADB_HW_CUDA:
2028 1.1 tsubai output[0] = 0x02; /* 2 byte message */
2029 1.1 tsubai output[1] = 0x01; /* to pram/rtc/soft-power device */
2030 1.1 tsubai output[2] = 0x0a; /* set date/time */
2031 1.1 tsubai result = send_adb_cuda((u_char *)output, (u_char *)0,
2032 1.1 tsubai (void *)0, (void *)0, (int)0);
2033 1.1 tsubai if (result != 0) /* exit if not sent */
2034 1.1 tsubai return -1;
2035 1.1 tsubai
2036 1.1 tsubai for (;;); /* wait for power off */
2037 1.1 tsubai
2038 1.1 tsubai return 0;
2039 1.1 tsubai
2040 1.1 tsubai case ADB_HW_II: /* II models don't do ADB soft power */
2041 1.1 tsubai case ADB_HW_UNKNOWN:
2042 1.1 tsubai default:
2043 1.1 tsubai return -1;
2044 1.1 tsubai }
2045 1.1 tsubai }
2046 1.1 tsubai
2047 1.1 tsubai int
2048 1.1 tsubai adb_prog_switch_enable(void)
2049 1.1 tsubai {
2050 1.1 tsubai u_char output[ADB_MAX_MSG_LENGTH];
2051 1.1 tsubai int result;
2052 1.1 tsubai volatile int flag = 0;
2053 1.1 tsubai
2054 1.1 tsubai switch (adbHardware) {
2055 1.1 tsubai case ADB_HW_IISI:
2056 1.1 tsubai output[0] = 0x03; /* 3 byte message */
2057 1.1 tsubai output[1] = 0x01; /* to pram/rtc/soft-power device */
2058 1.1 tsubai output[2] = 0x1c; /* prog. switch control */
2059 1.1 tsubai output[3] = 0x01; /* enable */
2060 1.1 tsubai result = send_adb_IIsi((u_char *)output, (u_char *)0,
2061 1.1 tsubai (void *)adb_op_comprout, (void *)&flag, (int)0);
2062 1.1 tsubai if (result != 0) /* exit if not sent */
2063 1.1 tsubai return -1;
2064 1.1 tsubai
2065 1.1 tsubai while (0 == flag) /* wait for send to finish */
2066 1.1 tsubai ;
2067 1.1 tsubai
2068 1.1 tsubai return 0;
2069 1.1 tsubai
2070 1.1 tsubai case ADB_HW_PB:
2071 1.1 tsubai return -1;
2072 1.1 tsubai
2073 1.1 tsubai case ADB_HW_II: /* II models don't do prog. switch */
2074 1.1 tsubai case ADB_HW_CUDA: /* cuda doesn't do prog. switch TO DO: verify this */
2075 1.1 tsubai case ADB_HW_UNKNOWN:
2076 1.1 tsubai default:
2077 1.1 tsubai return -1;
2078 1.1 tsubai }
2079 1.1 tsubai }
2080 1.1 tsubai
2081 1.1 tsubai int
2082 1.1 tsubai adb_prog_switch_disable(void)
2083 1.1 tsubai {
2084 1.1 tsubai u_char output[ADB_MAX_MSG_LENGTH];
2085 1.1 tsubai int result;
2086 1.1 tsubai volatile int flag = 0;
2087 1.1 tsubai
2088 1.1 tsubai switch (adbHardware) {
2089 1.1 tsubai case ADB_HW_IISI:
2090 1.1 tsubai output[0] = 0x03; /* 3 byte message */
2091 1.1 tsubai output[1] = 0x01; /* to pram/rtc/soft-power device */
2092 1.1 tsubai output[2] = 0x1c; /* prog. switch control */
2093 1.1 tsubai output[3] = 0x01; /* disable */
2094 1.1 tsubai result = send_adb_IIsi((u_char *)output, (u_char *)0,
2095 1.1 tsubai (void *)adb_op_comprout, (void *)&flag, (int)0);
2096 1.1 tsubai if (result != 0) /* exit if not sent */
2097 1.1 tsubai return -1;
2098 1.1 tsubai
2099 1.1 tsubai while (0 == flag) /* wait for send to finish */
2100 1.1 tsubai ;
2101 1.1 tsubai
2102 1.1 tsubai return 0;
2103 1.1 tsubai
2104 1.1 tsubai case ADB_HW_PB:
2105 1.1 tsubai return -1;
2106 1.1 tsubai
2107 1.1 tsubai case ADB_HW_II: /* II models don't do prog. switch */
2108 1.1 tsubai case ADB_HW_CUDA: /* cuda doesn't do prog. switch */
2109 1.1 tsubai case ADB_HW_UNKNOWN:
2110 1.1 tsubai default:
2111 1.1 tsubai return -1;
2112 1.1 tsubai }
2113 1.1 tsubai }
2114 1.1 tsubai
2115 1.1 tsubai int
2116 1.1 tsubai CountADBs(void)
2117 1.1 tsubai {
2118 1.1 tsubai return (count_adbs());
2119 1.1 tsubai }
2120 1.1 tsubai
2121 1.1 tsubai void
2122 1.1 tsubai ADBReInit(void)
2123 1.1 tsubai {
2124 1.1 tsubai adb_reinit();
2125 1.1 tsubai }
2126 1.1 tsubai
2127 1.1 tsubai int
2128 1.1 tsubai GetIndADB(ADBDataBlock * info, int index)
2129 1.1 tsubai {
2130 1.1 tsubai return (get_ind_adb_info(info, index));
2131 1.1 tsubai }
2132 1.1 tsubai
2133 1.1 tsubai int
2134 1.1 tsubai GetADBInfo(ADBDataBlock * info, int adbAddr)
2135 1.1 tsubai {
2136 1.1 tsubai return (get_adb_info(info, adbAddr));
2137 1.1 tsubai }
2138 1.1 tsubai
2139 1.1 tsubai int
2140 1.1 tsubai SetADBInfo(ADBSetInfoBlock * info, int adbAddr)
2141 1.1 tsubai {
2142 1.1 tsubai return (set_adb_info(info, adbAddr));
2143 1.1 tsubai }
2144 1.1 tsubai
2145 1.1 tsubai int
2146 1.1 tsubai ADBOp(Ptr buffer, Ptr compRout, Ptr data, short commandNum)
2147 1.1 tsubai {
2148 1.1 tsubai return (adb_op(buffer, compRout, data, commandNum));
2149 1.1 tsubai }
2150 1.1 tsubai
2151 1.1 tsubai #endif
2152 1.1 tsubai
2153 1.1 tsubai int
2154 1.1 tsubai setsoftadb()
2155 1.1 tsubai {
2156 1.13 thorpej callout_reset(&adb_soft_intr_ch, 1, (void *)adb_soft_intr, NULL);
2157 1.1 tsubai return 0;
2158 1.1 tsubai }
2159 1.1 tsubai
2160 1.1 tsubai void
2161 1.3 tsubai adb_cuda_autopoll()
2162 1.1 tsubai {
2163 1.1 tsubai volatile int flag = 0;
2164 1.1 tsubai int result;
2165 1.1 tsubai u_char output[16];
2166 1.1 tsubai
2167 1.1 tsubai output[0] = 0x03; /* 3-byte message */
2168 1.1 tsubai output[1] = 0x01; /* to pram/rtc device */
2169 1.1 tsubai output[2] = 0x01; /* cuda autopoll */
2170 1.1 tsubai output[3] = 0x01;
2171 1.15 tsubai result = send_adb_cuda(output, output, adb_op_comprout, (void *)&flag,
2172 1.15 tsubai 0);
2173 1.1 tsubai if (result != 0) /* exit if not sent */
2174 1.1 tsubai return;
2175 1.1 tsubai
2176 1.1 tsubai while (flag == 0); /* wait for result */
2177 1.1 tsubai }
2178 1.1 tsubai
2179 1.1 tsubai void
2180 1.17 matt adb_restart(void)
2181 1.1 tsubai {
2182 1.1 tsubai int result;
2183 1.1 tsubai u_char output[16];
2184 1.1 tsubai
2185 1.9 tsubai adb_polling = 1;
2186 1.9 tsubai
2187 1.4 tsubai switch (adbHardware) {
2188 1.4 tsubai case ADB_HW_CUDA:
2189 1.4 tsubai output[0] = 0x02; /* 2 byte message */
2190 1.4 tsubai output[1] = 0x01; /* to pram/rtc/soft-power device */
2191 1.4 tsubai output[2] = 0x11; /* restart */
2192 1.15 tsubai result = send_adb_cuda(output, NULL, NULL, NULL, 0);
2193 1.4 tsubai if (result != 0) /* exit if not sent */
2194 1.4 tsubai return;
2195 1.4 tsubai while (1); /* not return */
2196 1.4 tsubai
2197 1.4 tsubai case ADB_HW_PB:
2198 1.4 tsubai pm_adb_restart();
2199 1.10 tsubai while (1); /* not return */
2200 1.4 tsubai }
2201 1.1 tsubai }
2202