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