sci.c revision 1.3 1 1.1 chopps /*
2 1.1 chopps * Copyright (c) 1990 The Regents of the University of California.
3 1.1 chopps * All rights reserved.
4 1.1 chopps *
5 1.1 chopps * This code is derived from software contributed to Berkeley by
6 1.1 chopps * Van Jacobson of Lawrence Berkeley Laboratory.
7 1.1 chopps *
8 1.1 chopps * Redistribution and use in source and binary forms, with or without
9 1.1 chopps * modification, are permitted provided that the following conditions
10 1.1 chopps * are met:
11 1.1 chopps * 1. Redistributions of source code must retain the above copyright
12 1.1 chopps * notice, this list of conditions and the following disclaimer.
13 1.1 chopps * 2. Redistributions in binary form must reproduce the above copyright
14 1.1 chopps * notice, this list of conditions and the following disclaimer in the
15 1.1 chopps * documentation and/or other materials provided with the distribution.
16 1.1 chopps * 3. All advertising materials mentioning features or use of this software
17 1.1 chopps * must display the following acknowledgement:
18 1.1 chopps * This product includes software developed by the University of
19 1.1 chopps * California, Berkeley and its contributors.
20 1.1 chopps * 4. Neither the name of the University nor the names of its contributors
21 1.1 chopps * may be used to endorse or promote products derived from this software
22 1.1 chopps * without specific prior written permission.
23 1.1 chopps *
24 1.1 chopps * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25 1.1 chopps * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26 1.1 chopps * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27 1.1 chopps * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28 1.1 chopps * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29 1.1 chopps * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30 1.1 chopps * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 1.1 chopps * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32 1.1 chopps * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33 1.1 chopps * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34 1.1 chopps * SUCH DAMAGE.
35 1.1 chopps *
36 1.1 chopps * @(#)sci.c 7.5 (Berkeley) 5/4/91
37 1.3 chopps * $Id: sci.c,v 1.3 1994/04/18 04:09:15 chopps Exp $
38 1.1 chopps *
39 1.1 chopps */
40 1.1 chopps
41 1.1 chopps /*
42 1.1 chopps * AMIGA NCR 5380 scsi adaptor driver
43 1.1 chopps */
44 1.1 chopps
45 1.1 chopps #include "mlhscsi.h"
46 1.1 chopps #include "csa12gscsi.h"
47 1.1 chopps #include "suprascsi.h"
48 1.1 chopps #include "ivsscsi.h"
49 1.1 chopps #if (NMLHSCSI + NCSA12GSCSI + NSUPRASCSI + NIVSSCSI) > 0
50 1.1 chopps #define NSCI NMLHSCSI
51 1.1 chopps #if NSCI < NCSA12GSCSI
52 1.1 chopps #undef NSCI
53 1.1 chopps #define NSCI NCSA12GSCSI
54 1.1 chopps #endif
55 1.1 chopps #if NSCI < NSUPRASCSI
56 1.1 chopps #undef NSCI
57 1.2 chopps #define NSCI NSUPRASCSI
58 1.1 chopps #endif
59 1.1 chopps #if NSCI < NIVSSCSI
60 1.1 chopps #undef NSCI
61 1.1 chopps #define NSCI NIVSSCI
62 1.1 chopps #endif
63 1.1 chopps
64 1.1 chopps #ifndef lint
65 1.3 chopps static char rcsid[] = "$Header: /tank/opengrok/rsync2/NetBSD/src/sys/arch/amiga/dev/sci.c,v 1.3 1994/04/18 04:09:15 chopps Exp $";
66 1.1 chopps #endif
67 1.1 chopps
68 1.1 chopps /* need to know if any tapes have been configured */
69 1.1 chopps #include "st.h"
70 1.1 chopps
71 1.1 chopps #include <sys/param.h>
72 1.1 chopps #include <sys/systm.h>
73 1.1 chopps #include <sys/buf.h>
74 1.1 chopps #include <vm/vm.h>
75 1.1 chopps #include <vm/vm_kern.h>
76 1.1 chopps #include <vm/vm_page.h>
77 1.1 chopps #include <machine/pmap.h>
78 1.1 chopps
79 1.1 chopps #include <amiga/dev/device.h>
80 1.1 chopps
81 1.1 chopps #include <amiga/dev/scsidefs.h>
82 1.1 chopps #include <amiga/dev/scivar.h>
83 1.1 chopps #include <amiga/dev/scireg.h>
84 1.1 chopps
85 1.1 chopps #include <amiga/amiga/custom.h>
86 1.1 chopps
87 1.1 chopps #include <machine/cpu.h>
88 1.1 chopps
89 1.1 chopps extern u_int kvtop();
90 1.1 chopps
91 1.1 chopps static int sci_wait __P((char until, int timeo, int line));
92 1.1 chopps static void scsiabort __P((register struct sci_softc *dev, char *where));
93 1.1 chopps static void scsierror __P((register struct sci_softc *dev, u_char csr));
94 1.1 chopps static int issue_select __P((register struct sci_softc *dev, u_char target,
95 1.1 chopps u_char our_addr));
96 1.1 chopps static int ixfer_out __P((register struct sci_softc *dev, int len,
97 1.1 chopps register u_char *buf, int phase));
98 1.1 chopps static void ixfer_in __P((register struct sci_softc *dev, int len,
99 1.1 chopps register u_char *buf, int phase));
100 1.1 chopps static int scsiicmd __P((struct sci_softc *dev, int target, u_char *cbuf,
101 1.1 chopps int clen, u_char *buf, int len, u_char xferphase));
102 1.1 chopps
103 1.1 chopps
104 1.1 chopps /*
105 1.1 chopps * SCSI delays
106 1.1 chopps * In u-seconds, primarily for state changes on the SPC.
107 1.1 chopps */
108 1.1 chopps #define SCSI_CMD_WAIT 50000 /* wait per step of 'immediate' cmds */
109 1.1 chopps #define SCSI_DATA_WAIT 50000 /* wait per data in/out step */
110 1.1 chopps #define SCSI_INIT_WAIT 50000 /* wait per step (both) during init */
111 1.1 chopps
112 1.1 chopps extern void _insque();
113 1.1 chopps extern void _remque();
114 1.1 chopps
115 1.1 chopps void scistart __P((int unit));
116 1.1 chopps int scigo __P((int ctlr, int slave, int unit, struct buf *bp,
117 1.1 chopps struct scsi_fmt_cdb *cdb, int pad));
118 1.1 chopps int sciintr __P((void));
119 1.1 chopps void scidone __P((int unit));
120 1.1 chopps int sciustart __P((int unit));
121 1.1 chopps int scireq __P((register struct devqueue *dq));
122 1.1 chopps void scifree __P((register struct devqueue *dq));
123 1.1 chopps void scireset __P((int unit));
124 1.1 chopps void sci_delay __P((int delay));
125 1.1 chopps int sci_test_unit_rdy __P((int ctlr, int slave, int unit));
126 1.1 chopps int sci_start_stop_unit __P((int ctlr, int slave, int unit, int start));
127 1.1 chopps int sci_request_sense __P((int ctlr, int slave, int unit, u_char *buf,
128 1.1 chopps unsigned int len));
129 1.1 chopps int sci_immed_command __P((int ctlr, int slave, int unit,
130 1.1 chopps struct scsi_fmt_cdb *cdb, u_char *buf, unsigned int len, int rd));
131 1.1 chopps int sci_immed_command_nd __P((int ctlr, int slave, int unit,
132 1.1 chopps struct scsi_fmt_cdb *cdb));
133 1.1 chopps int sci_tt_read __P((int ctlr, int slave, int unit, u_char *buf,
134 1.1 chopps u_int len, daddr_t blk, int bshift));
135 1.1 chopps int sci_tt_write __P((int ctlr, int slave, int unit, u_char *buf,
136 1.1 chopps u_int len, daddr_t blk, int bshift));
137 1.1 chopps #if NST > 0
138 1.1 chopps int sci_tt_oddio __P((int ctlr, int slave, int unit, u_char *buf, u_int len, int b_flags, int freedma));
139 1.1 chopps #endif
140 1.1 chopps
141 1.1 chopps
142 1.1 chopps #if NMLHSCSI > 0
143 1.1 chopps int mlhscsiinit ();
144 1.1 chopps
145 1.1 chopps struct driver mlhscsidriver = {
146 1.1 chopps (int (*)(void *)) mlhscsiinit, "Mlhscsi", (int (*)(int)) scistart,
147 1.1 chopps (int (*)(int,...)) scigo, (int (*)(int,int)) sciintr,
148 1.1 chopps (int (*)())scidone, sciustart, scireq, scifree, scireset,
149 1.1 chopps sci_delay, sci_test_unit_rdy, sci_start_stop_unit,
150 1.1 chopps sci_request_sense, sci_immed_command, sci_immed_command_nd,
151 1.1 chopps sci_tt_read, sci_tt_write,
152 1.1 chopps #if NST > 0
153 1.1 chopps sci_tt_oddio
154 1.1 chopps #else
155 1.1 chopps NULL
156 1.1 chopps #endif
157 1.1 chopps };
158 1.1 chopps #endif
159 1.1 chopps
160 1.1 chopps #if NCSA12GSCSI > 0
161 1.1 chopps int csa12gscsiinit ();
162 1.1 chopps
163 1.1 chopps struct driver csa12gscsidriver = {
164 1.1 chopps (int (*)(void *)) csa12gscsiinit, "Csa12gscsi", (int (*)(int)) scistart,
165 1.1 chopps (int (*)(int,...)) scigo, (int (*)(int,int)) sciintr,
166 1.1 chopps (int (*)())scidone, sciustart, scireq, scifree, scireset,
167 1.1 chopps sci_delay, sci_test_unit_rdy, sci_start_stop_unit,
168 1.1 chopps sci_request_sense, sci_immed_command, sci_immed_command_nd,
169 1.1 chopps sci_tt_read, sci_tt_write,
170 1.1 chopps #if NST > 0
171 1.1 chopps sci_tt_oddio
172 1.1 chopps #else
173 1.1 chopps NULL
174 1.1 chopps #endif
175 1.1 chopps };
176 1.1 chopps #endif
177 1.1 chopps
178 1.1 chopps #if NSUPRASCSI > 0
179 1.1 chopps int suprascsiinit ();
180 1.1 chopps
181 1.1 chopps struct driver suprascsidriver = {
182 1.1 chopps (int (*)(void *)) suprascsiinit, "Suprascsi", (int (*)(int)) scistart,
183 1.1 chopps (int (*)(int,...)) scigo, (int (*)(int,int)) sciintr,
184 1.1 chopps (int (*)())scidone, sciustart, scireq, scifree, scireset,
185 1.1 chopps sci_delay, sci_test_unit_rdy, sci_start_stop_unit,
186 1.1 chopps sci_request_sense, sci_immed_command, sci_immed_command_nd,
187 1.1 chopps sci_tt_read, sci_tt_write,
188 1.1 chopps #if NST > 0
189 1.1 chopps sci_tt_oddio
190 1.1 chopps #else
191 1.1 chopps NULL
192 1.1 chopps #endif
193 1.1 chopps };
194 1.1 chopps #endif
195 1.1 chopps
196 1.1 chopps #if NIVSSCSI > 0
197 1.1 chopps int ivsscsiinit ();
198 1.1 chopps
199 1.1 chopps struct driver ivsscsidriver = {
200 1.1 chopps (int (*)(void *)) ivsscsiinit, "IVSscsi", (int (*)(int)) scistart,
201 1.1 chopps (int (*)(int,...)) scigo, (int (*)(int,int)) sciintr,
202 1.1 chopps (int (*)())scidone, sciustart, scireq, scifree, scireset,
203 1.1 chopps sci_delay, sci_test_unit_rdy, sci_start_stop_unit,
204 1.1 chopps sci_request_sense, sci_immed_command, sci_immed_command_nd,
205 1.1 chopps sci_tt_read, sci_tt_write,
206 1.1 chopps #if NST > 0
207 1.1 chopps sci_tt_oddio
208 1.1 chopps #else
209 1.1 chopps NULL
210 1.1 chopps #endif
211 1.1 chopps };
212 1.1 chopps #endif
213 1.1 chopps
214 1.1 chopps struct sci_softc sci_softc[NSCI];
215 1.1 chopps
216 1.1 chopps int sci_cmd_wait = SCSI_CMD_WAIT;
217 1.1 chopps int sci_data_wait = SCSI_DATA_WAIT;
218 1.1 chopps int sci_init_wait = SCSI_INIT_WAIT;
219 1.1 chopps
220 1.1 chopps int sci_no_dma = 0;
221 1.1 chopps
222 1.1 chopps #ifdef DEBUG
223 1.1 chopps int sci_debug = 0;
224 1.1 chopps #define WAITHIST
225 1.1 chopps #define QUASEL
226 1.1 chopps
227 1.1 chopps static long dmahits[NSCI];
228 1.1 chopps static long dmamisses[NSCI];
229 1.1 chopps #endif
230 1.1 chopps
231 1.1 chopps #ifdef QUASEL
232 1.1 chopps #define QPRINTF(a) if (sci_debug > 1) printf a
233 1.1 chopps #else
234 1.1 chopps #define QPRINTF
235 1.1 chopps #endif
236 1.1 chopps
237 1.1 chopps #ifdef WAITHIST
238 1.1 chopps #define MAXWAIT 1022
239 1.1 chopps u_int ixstart_wait[MAXWAIT+2];
240 1.1 chopps u_int ixin_wait[MAXWAIT+2];
241 1.1 chopps u_int ixout_wait[MAXWAIT+2];
242 1.1 chopps u_int mxin_wait[MAXWAIT+2];
243 1.1 chopps u_int mxin2_wait[MAXWAIT+2];
244 1.1 chopps u_int cxin_wait[MAXWAIT+2];
245 1.1 chopps u_int fxfr_wait[MAXWAIT+2];
246 1.1 chopps u_int sgo_wait[MAXWAIT+2];
247 1.1 chopps #define HIST(h,w) (++h[((w)>MAXWAIT? MAXWAIT : ((w) < 0 ? -1 : (w))) + 1]);
248 1.1 chopps #else
249 1.1 chopps #define HIST(h,w)
250 1.1 chopps #endif
251 1.1 chopps
252 1.1 chopps #define b_cylin b_resid
253 1.1 chopps
254 1.1 chopps static sci_wait (until, timeo, line)
255 1.1 chopps char until;
256 1.1 chopps int timeo;
257 1.1 chopps int line;
258 1.1 chopps {
259 1.1 chopps register unsigned char val;
260 1.1 chopps
261 1.1 chopps if (! timeo)
262 1.1 chopps timeo = 1000000; /* some large value.. */
263 1.1 chopps
264 1.1 chopps return val;
265 1.1 chopps }
266 1.1 chopps
267 1.1 chopps static void
268 1.1 chopps scsiabort(dev, where)
269 1.1 chopps register struct sci_softc *dev;
270 1.1 chopps char *where;
271 1.1 chopps {
272 1.1 chopps
273 1.1 chopps printf ("sci%d: abort %s: csr = 0x%02x, bus = 0x%02x\n",
274 1.1 chopps dev->sc_ac->amiga_unit,
275 1.1 chopps where, *dev->sci_csr, *dev->sci_bus_csr);
276 1.1 chopps
277 1.1 chopps if (dev->sc_flags & SCI_SELECTED) {
278 1.1 chopps
279 1.1 chopps /* XXX */
280 1.1 chopps scireset (dev->sc_ac->amiga_unit);
281 1.1 chopps /* lets just hope it worked.. */
282 1.1 chopps dev->sc_flags &= ~SCI_SELECTED;
283 1.1 chopps }
284 1.1 chopps }
285 1.1 chopps
286 1.1 chopps /*
287 1.1 chopps * XXX Set/reset long delays.
288 1.1 chopps *
289 1.1 chopps * if delay == 0, reset default delays
290 1.1 chopps * if delay < 0, set both delays to default long initialization values
291 1.1 chopps * if delay > 0, set both delays to this value
292 1.1 chopps *
293 1.1 chopps * Used when a devices is expected to respond slowly (e.g. during
294 1.1 chopps * initialization).
295 1.1 chopps */
296 1.1 chopps void
297 1.1 chopps sci_delay(delay)
298 1.1 chopps int delay;
299 1.1 chopps {
300 1.1 chopps static int saved_cmd_wait, saved_data_wait;
301 1.1 chopps
302 1.1 chopps if (delay) {
303 1.1 chopps saved_cmd_wait = sci_cmd_wait;
304 1.1 chopps saved_data_wait = sci_data_wait;
305 1.1 chopps if (delay > 0)
306 1.1 chopps sci_cmd_wait = sci_data_wait = delay;
307 1.1 chopps else
308 1.1 chopps sci_cmd_wait = sci_data_wait = sci_init_wait;
309 1.1 chopps } else {
310 1.1 chopps sci_cmd_wait = saved_cmd_wait;
311 1.1 chopps sci_data_wait = saved_data_wait;
312 1.1 chopps }
313 1.1 chopps }
314 1.1 chopps
315 1.1 chopps static int initialized[NSCI];
316 1.1 chopps
317 1.1 chopps #if NMLHSCSI > 0
318 1.1 chopps int
319 1.1 chopps mlhscsiinit(ac)
320 1.1 chopps register struct amiga_ctlr *ac;
321 1.1 chopps {
322 1.1 chopps register struct sci_softc *dev = &sci_softc[ac->amiga_unit];
323 1.1 chopps
324 1.1 chopps if (! ac->amiga_addr)
325 1.1 chopps return 0;
326 1.1 chopps
327 1.1 chopps if (initialized[ac->amiga_unit])
328 1.1 chopps return 0;
329 1.1 chopps
330 1.1 chopps if (ac->amiga_unit > NSCI)
331 1.1 chopps return 0;
332 1.1 chopps
333 1.1 chopps initialized[ac->amiga_unit] = 1;
334 1.1 chopps
335 1.1 chopps /* advance ac->amiga_addr to point to the real sci-registers */
336 1.1 chopps ac->amiga_addr = (caddr_t) ((int)ac->amiga_addr);
337 1.1 chopps dev->sci_data = (caddr_t) ac->amiga_addr + 1;
338 1.1 chopps dev->sci_odata = (caddr_t) ac->amiga_addr + 1;
339 1.1 chopps dev->sci_icmd = (caddr_t) ac->amiga_addr + 3;
340 1.1 chopps dev->sci_mode = (caddr_t) ac->amiga_addr + 5;
341 1.1 chopps dev->sci_tcmd = (caddr_t) ac->amiga_addr + 7;
342 1.1 chopps dev->sci_bus_csr = (caddr_t) ac->amiga_addr + 9;
343 1.1 chopps dev->sci_sel_enb = (caddr_t) ac->amiga_addr + 9;
344 1.1 chopps dev->sci_csr = (caddr_t) ac->amiga_addr + 11;
345 1.1 chopps dev->sci_dma_send = (caddr_t) ac->amiga_addr + 11;
346 1.1 chopps dev->sci_idata = (caddr_t) ac->amiga_addr + 13;
347 1.1 chopps dev->sci_trecv = (caddr_t) ac->amiga_addr + 13;
348 1.1 chopps dev->sci_iack = (caddr_t) ac->amiga_addr + 15;
349 1.1 chopps dev->sci_irecv = (caddr_t) ac->amiga_addr + 15;
350 1.1 chopps mlhdmainit (dev);
351 1.1 chopps
352 1.1 chopps /* hardwired IPL */
353 1.1 chopps ac->amiga_ipl = 0; /* doesn't use interrupts */
354 1.1 chopps dev->sc_ac = ac;
355 1.1 chopps dev->sc_sq.dq_forw = dev->sc_sq.dq_back = &dev->sc_sq;
356 1.1 chopps scireset (ac->amiga_unit);
357 1.1 chopps
358 1.1 chopps return(1);
359 1.1 chopps }
360 1.1 chopps #endif
361 1.1 chopps
362 1.1 chopps #if NCSA12GSCSI > 0
363 1.1 chopps int
364 1.1 chopps csa12gscsiinit(ac)
365 1.1 chopps register struct amiga_ctlr *ac;
366 1.1 chopps {
367 1.1 chopps register struct sci_softc *dev = &sci_softc[ac->amiga_unit];
368 1.1 chopps
369 1.1 chopps if (! ac->amiga_addr)
370 1.1 chopps return 0;
371 1.1 chopps
372 1.1 chopps if (initialized[ac->amiga_unit])
373 1.1 chopps return 0;
374 1.1 chopps
375 1.1 chopps if (ac->amiga_unit > NSCI)
376 1.1 chopps return 0;
377 1.1 chopps
378 1.1 chopps initialized[ac->amiga_unit] = 1;
379 1.1 chopps
380 1.1 chopps /* advance ac->amiga_addr to point to the real sci-registers */
381 1.1 chopps ac->amiga_addr = (caddr_t) ((int)ac->amiga_addr + 0x2000);
382 1.1 chopps dev->sci_data = (caddr_t) ac->amiga_addr;
383 1.1 chopps dev->sci_odata = (caddr_t) ac->amiga_addr;
384 1.1 chopps dev->sci_icmd = (caddr_t) ac->amiga_addr + 0x10;
385 1.1 chopps dev->sci_mode = (caddr_t) ac->amiga_addr + 0x20;
386 1.1 chopps dev->sci_tcmd = (caddr_t) ac->amiga_addr + 0x30;
387 1.1 chopps dev->sci_bus_csr = (caddr_t) ac->amiga_addr + 0x40;
388 1.1 chopps dev->sci_sel_enb = (caddr_t) ac->amiga_addr + 0x40;
389 1.1 chopps dev->sci_csr = (caddr_t) ac->amiga_addr + 0x50;
390 1.1 chopps dev->sci_dma_send = (caddr_t) ac->amiga_addr + 0x50;
391 1.1 chopps dev->sci_idata = (caddr_t) ac->amiga_addr + 0x60;
392 1.1 chopps dev->sci_trecv = (caddr_t) ac->amiga_addr + 0x60;
393 1.1 chopps dev->sci_iack = (caddr_t) ac->amiga_addr + 0x70;
394 1.1 chopps dev->sci_irecv = (caddr_t) ac->amiga_addr + 0x70;
395 1.1 chopps csa12gdmainit (dev);
396 1.1 chopps
397 1.1 chopps /* hardwired IPL */
398 1.1 chopps ac->amiga_ipl = 2;
399 1.1 chopps dev->sc_ac = ac;
400 1.1 chopps dev->sc_sq.dq_forw = dev->sc_sq.dq_back = &dev->sc_sq;
401 1.1 chopps scireset (ac->amiga_unit);
402 1.1 chopps
403 1.1 chopps /* make sure IPL2 interrupts are delivered to the cpu when the sci
404 1.1 chopps generates some. Note that this does not yet enable sci-interrupts,
405 1.1 chopps this is handled in dma.c, which selectively enables interrupts only
406 1.1 chopps while DMA requests are pending.
407 1.1 chopps
408 1.1 chopps Note that enabling PORTS interrupts also enables keyboard interrupts
409 1.1 chopps as soon as the corresponding int-enable bit in CIA-A is set. */
410 1.1 chopps
411 1.1 chopps custom.intreq = INTF_PORTS;
412 1.1 chopps custom.intena = INTF_SETCLR | INTF_PORTS;
413 1.1 chopps return(1);
414 1.1 chopps }
415 1.1 chopps #endif
416 1.1 chopps
417 1.1 chopps #if NSUPRASCSI > 0
418 1.1 chopps int
419 1.1 chopps suprascsiinit(ac)
420 1.1 chopps register struct amiga_ctlr *ac;
421 1.1 chopps {
422 1.1 chopps register struct sci_softc *dev = &sci_softc[ac->amiga_unit];
423 1.1 chopps
424 1.1 chopps if (! ac->amiga_addr)
425 1.1 chopps return 0;
426 1.1 chopps
427 1.1 chopps if (initialized[ac->amiga_unit])
428 1.1 chopps return 0;
429 1.1 chopps
430 1.1 chopps if (ac->amiga_unit > NSCI)
431 1.1 chopps return 0;
432 1.1 chopps
433 1.1 chopps initialized[ac->amiga_unit] = 1;
434 1.1 chopps
435 1.1 chopps /* advance ac->amiga_addr to point to the real sci-registers */
436 1.1 chopps /* XXX Supra Word Sync version 2 only for now !!! */
437 1.1 chopps dev->sci_data = (caddr_t) ac->amiga_addr;
438 1.1 chopps dev->sci_odata = (caddr_t) ac->amiga_addr;
439 1.1 chopps dev->sci_icmd = (caddr_t) ac->amiga_addr + 2;
440 1.1 chopps dev->sci_mode = (caddr_t) ac->amiga_addr + 4;
441 1.1 chopps dev->sci_tcmd = (caddr_t) ac->amiga_addr + 6;
442 1.1 chopps dev->sci_bus_csr = (caddr_t) ac->amiga_addr + 8;
443 1.1 chopps dev->sci_sel_enb = (caddr_t) ac->amiga_addr + 8;
444 1.1 chopps dev->sci_csr = (caddr_t) ac->amiga_addr + 10;
445 1.1 chopps dev->sci_dma_send = (caddr_t) ac->amiga_addr + 10;
446 1.1 chopps dev->sci_idata = (caddr_t) ac->amiga_addr + 12;
447 1.1 chopps dev->sci_trecv = (caddr_t) ac->amiga_addr + 12;
448 1.1 chopps dev->sci_iack = (caddr_t) ac->amiga_addr + 14;
449 1.1 chopps dev->sci_irecv = (caddr_t) ac->amiga_addr + 14;
450 1.1 chopps supradmainit (dev);
451 1.1 chopps
452 1.1 chopps /* hardwired IPL */
453 1.1 chopps ac->amiga_ipl = 2;
454 1.1 chopps dev->sc_ac = ac;
455 1.1 chopps dev->sc_sq.dq_forw = dev->sc_sq.dq_back = &dev->sc_sq;
456 1.1 chopps scireset (ac->amiga_unit);
457 1.1 chopps
458 1.1 chopps /* make sure IPL2 interrupts are delivered to the cpu when the sci
459 1.1 chopps generates some. Note that this does not yet enable sci-interrupts,
460 1.1 chopps this is handled in dma.c, which selectively enables interrupts only
461 1.1 chopps while DMA requests are pending.
462 1.1 chopps
463 1.1 chopps Note that enabling PORTS interrupts also enables keyboard interrupts
464 1.1 chopps as soon as the corresponding int-enable bit in CIA-A is set. */
465 1.1 chopps
466 1.1 chopps custom.intreq = INTF_PORTS;
467 1.1 chopps custom.intena = INTF_SETCLR | INTF_PORTS;
468 1.1 chopps return(1);
469 1.1 chopps }
470 1.1 chopps #endif
471 1.1 chopps
472 1.1 chopps #if NIVSSCSI > 0
473 1.1 chopps int
474 1.1 chopps ivsscsiinit(ac)
475 1.1 chopps register struct amiga_ctlr *ac;
476 1.1 chopps {
477 1.1 chopps register struct sci_softc *dev = &sci_softc[ac->amiga_unit];
478 1.1 chopps
479 1.1 chopps if (! ac->amiga_addr)
480 1.1 chopps return 0;
481 1.1 chopps
482 1.1 chopps if (initialized[ac->amiga_unit])
483 1.1 chopps return 0;
484 1.1 chopps
485 1.1 chopps if (ac->amiga_unit > NSCI)
486 1.1 chopps return 0;
487 1.1 chopps
488 1.1 chopps initialized[ac->amiga_unit] = 1;
489 1.1 chopps
490 1.1 chopps /* advance ac->amiga_addr to point to the real sci-registers */
491 1.1 chopps ac->amiga_addr = (caddr_t) ((int)ac->amiga_addr + 0x40);
492 1.1 chopps dev->sci_data = (caddr_t) ac->amiga_addr;
493 1.1 chopps dev->sci_odata = (caddr_t) ac->amiga_addr;
494 1.1 chopps dev->sci_icmd = (caddr_t) ac->amiga_addr + 2;
495 1.1 chopps dev->sci_mode = (caddr_t) ac->amiga_addr + 4;
496 1.1 chopps dev->sci_tcmd = (caddr_t) ac->amiga_addr + 6;
497 1.1 chopps dev->sci_bus_csr = (caddr_t) ac->amiga_addr + 8;
498 1.1 chopps dev->sci_sel_enb = (caddr_t) ac->amiga_addr + 8;
499 1.1 chopps dev->sci_csr = (caddr_t) ac->amiga_addr + 10;
500 1.1 chopps dev->sci_dma_send = (caddr_t) ac->amiga_addr + 10;
501 1.1 chopps dev->sci_idata = (caddr_t) ac->amiga_addr + 12;
502 1.1 chopps dev->sci_trecv = (caddr_t) ac->amiga_addr + 12;
503 1.1 chopps dev->sci_iack = (caddr_t) ac->amiga_addr + 14;
504 1.1 chopps dev->sci_irecv = (caddr_t) ac->amiga_addr + 14;
505 1.1 chopps ivsdmainit (dev);
506 1.1 chopps
507 1.1 chopps /* hardwired IPL */
508 1.1 chopps ac->amiga_ipl = 2;
509 1.1 chopps dev->sc_ac = ac;
510 1.1 chopps dev->sc_sq.dq_forw = dev->sc_sq.dq_back = &dev->sc_sq;
511 1.1 chopps scireset (ac->amiga_unit);
512 1.1 chopps
513 1.1 chopps /* make sure IPL2 interrupts are delivered to the cpu when the sci
514 1.1 chopps generates some. Note that this does not yet enable sci-interrupts,
515 1.1 chopps this is handled in dma.c, which selectively enables interrupts only
516 1.1 chopps while DMA requests are pending.
517 1.1 chopps
518 1.1 chopps Note that enabling PORTS interrupts also enables keyboard interrupts
519 1.1 chopps as soon as the corresponding int-enable bit in CIA-A is set. */
520 1.1 chopps
521 1.1 chopps custom.intreq = INTF_PORTS;
522 1.1 chopps custom.intena = INTF_SETCLR | INTF_PORTS;
523 1.1 chopps return(1);
524 1.1 chopps }
525 1.1 chopps #endif
526 1.1 chopps
527 1.1 chopps void
528 1.1 chopps scireset(unit)
529 1.1 chopps register int unit;
530 1.1 chopps {
531 1.1 chopps register struct sci_softc *dev = &sci_softc[unit];
532 1.1 chopps u_int i, s;
533 1.1 chopps u_char my_id, csr;
534 1.1 chopps
535 1.1 chopps if (dev->sc_flags & SCI_ALIVE)
536 1.1 chopps scsiabort(dev, "reset");
537 1.1 chopps
538 1.1 chopps printf("sci%d: ", unit);
539 1.1 chopps
540 1.1 chopps s = splbio();
541 1.1 chopps /* preserve our ID for now */
542 1.1 chopps my_id = 7;
543 1.1 chopps
544 1.1 chopps /*
545 1.1 chopps * Disable interrupts (in dmainit) then reset the chip
546 1.1 chopps */
547 1.1 chopps *dev->sci_icmd = SCI_ICMD_TEST;
548 1.1 chopps *dev->sci_icmd = SCI_ICMD_TEST | SCI_ICMD_RST;
549 1.1 chopps DELAY (25);
550 1.1 chopps *dev->sci_icmd = 0;
551 1.1 chopps
552 1.1 chopps /*
553 1.1 chopps * Set up various chip parameters
554 1.1 chopps */
555 1.1 chopps *dev->sci_icmd = 0;
556 1.1 chopps *dev->sci_tcmd = 0;
557 1.1 chopps *dev->sci_sel_enb = 0;
558 1.1 chopps
559 1.1 chopps /* anything else was zeroed by reset */
560 1.1 chopps
561 1.1 chopps splx (s);
562 1.1 chopps
563 1.1 chopps printf("sci id %d\n", my_id);
564 1.1 chopps dev->sc_flags |= SCI_ALIVE;
565 1.1 chopps dev->sc_flags &= ~SCI_SELECTED;
566 1.1 chopps }
567 1.1 chopps
568 1.1 chopps static void
569 1.1 chopps scsierror(dev, csr)
570 1.1 chopps register struct sci_softc *dev;
571 1.1 chopps u_char csr;
572 1.1 chopps {
573 1.1 chopps int unit = dev->sc_ac->amiga_unit;
574 1.1 chopps char *sep = "";
575 1.1 chopps
576 1.1 chopps printf("sci%d: ", unit);
577 1.1 chopps printf("\n");
578 1.1 chopps }
579 1.1 chopps
580 1.1 chopps static int
581 1.1 chopps issue_select(dev, target, our_addr)
582 1.1 chopps register struct sci_softc *dev;
583 1.1 chopps u_char target, our_addr;
584 1.1 chopps {
585 1.1 chopps register int timeo = 2500;
586 1.1 chopps
587 1.1 chopps QPRINTF (("issue_select %d\n", target));
588 1.1 chopps
589 1.1 chopps /* if we're already selected, return */
590 1.1 chopps if (dev->sc_flags & SCI_SELECTED) /* XXXX */
591 1.1 chopps return 1;
592 1.1 chopps
593 1.1 chopps if ((*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) &&
594 1.1 chopps (*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)) &&
595 1.1 chopps (*dev->sci_bus_csr & (SCI_BUS_BSY|SCI_BUS_SEL)))
596 1.1 chopps return 1;
597 1.1 chopps
598 1.1 chopps *dev->sci_tcmd = 0;
599 1.1 chopps *dev->sci_odata = 0x80 + (1 << target);
600 1.1 chopps *dev->sci_icmd = SCI_ICMD_DATA|SCI_ICMD_SEL;
601 1.1 chopps while ((*dev->sci_bus_csr & SCI_BUS_BSY) == 0) {
602 1.1 chopps if (--timeo > 0) {
603 1.1 chopps DELAY(100);
604 1.1 chopps } else {
605 1.1 chopps break;
606 1.1 chopps }
607 1.1 chopps }
608 1.1 chopps if (timeo) {
609 1.1 chopps *dev->sci_icmd = 0;
610 1.1 chopps dev->sc_flags |= SCI_SELECTED;
611 1.1 chopps return (0);
612 1.1 chopps }
613 1.1 chopps *dev->sci_icmd = 0;
614 1.1 chopps return (1);
615 1.1 chopps }
616 1.1 chopps
617 1.1 chopps static int
618 1.1 chopps ixfer_out(dev, len, buf, phase)
619 1.1 chopps register struct sci_softc *dev;
620 1.1 chopps int len;
621 1.1 chopps register u_char *buf;
622 1.1 chopps int phase;
623 1.1 chopps {
624 1.1 chopps register int wait = sci_data_wait;
625 1.1 chopps u_char csr;
626 1.1 chopps
627 1.1 chopps QPRINTF(("ixfer_out {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
628 1.1 chopps len, buf[0], buf[1], buf[2], buf[3], buf[4], buf[5],
629 1.1 chopps buf[6], buf[7], buf[8], buf[9]));
630 1.1 chopps
631 1.1 chopps *dev->sci_tcmd = phase;
632 1.1 chopps *dev->sci_icmd = SCI_ICMD_DATA;
633 1.1 chopps for (;len > 0; len--) {
634 1.1 chopps csr = *dev->sci_bus_csr;
635 1.1 chopps while (!(csr & SCI_BUS_REQ)) {
636 1.1 chopps if ((csr & SCI_BUS_BSY) == 0 || --wait < 0) {
637 1.1 chopps #ifdef DEBUG
638 1.1 chopps if (sci_debug)
639 1.1 chopps printf("ixfer_out fail: l%d i%x w%d\n",
640 1.1 chopps len, csr, wait);
641 1.1 chopps #endif
642 1.1 chopps HIST(ixout_wait, wait)
643 1.1 chopps return (len);
644 1.1 chopps }
645 1.1 chopps DELAY(1);
646 1.1 chopps csr = *dev->sci_bus_csr;
647 1.1 chopps }
648 1.1 chopps
649 1.1 chopps if (!(*dev->sci_csr & SCI_CSR_PHASE_MATCH))
650 1.1 chopps break;
651 1.1 chopps *dev->sci_odata = *buf;
652 1.1 chopps *dev->sci_icmd = SCI_ICMD_DATA|SCI_ICMD_ACK;
653 1.1 chopps buf++;
654 1.1 chopps while (*dev->sci_bus_csr & SCI_BUS_REQ);
655 1.1 chopps *dev->sci_icmd = SCI_ICMD_DATA;
656 1.1 chopps }
657 1.1 chopps
658 1.1 chopps QPRINTF(("ixfer_out done\n"));
659 1.1 chopps /* this leaves with one csr to be read */
660 1.1 chopps HIST(ixout_wait, wait)
661 1.1 chopps return (0);
662 1.1 chopps }
663 1.1 chopps
664 1.1 chopps static void
665 1.1 chopps ixfer_in(dev, len, buf, phase)
666 1.1 chopps struct sci_softc *dev;
667 1.1 chopps int len;
668 1.1 chopps register u_char *buf;
669 1.1 chopps int phase;
670 1.1 chopps {
671 1.1 chopps int wait = sci_data_wait;
672 1.1 chopps u_char *obp = buf;
673 1.1 chopps u_char csr;
674 1.1 chopps volatile register u_char *sci_bus_csr = dev->sci_bus_csr;
675 1.1 chopps volatile register u_char *sci_data = dev->sci_data;
676 1.1 chopps volatile register u_char *sci_icmd = dev->sci_icmd;
677 1.1 chopps
678 1.1 chopps csr = *sci_bus_csr;
679 1.1 chopps
680 1.1 chopps QPRINTF(("ixfer_in %d, csr=%02x\n", len, csr));
681 1.1 chopps
682 1.1 chopps *dev->sci_tcmd = phase;
683 1.1 chopps *sci_icmd = 0;
684 1.1 chopps for (;len > 0; len--) {
685 1.1 chopps csr = *sci_bus_csr;
686 1.1 chopps while (!(csr & SCI_BUS_REQ)) {
687 1.1 chopps if (!(csr & SCI_BUS_BSY) || --wait < 0) {
688 1.1 chopps #ifdef DEBUG
689 1.1 chopps if (sci_debug)
690 1.1 chopps printf("ixfer_in fail: l%d i%x w%d\n",
691 1.1 chopps len, csr, wait);
692 1.1 chopps #endif
693 1.1 chopps HIST(ixin_wait, wait)
694 1.1 chopps return;
695 1.1 chopps }
696 1.1 chopps
697 1.1 chopps DELAY(1);
698 1.1 chopps csr = *sci_bus_csr;
699 1.1 chopps }
700 1.1 chopps
701 1.1 chopps if (!(*dev->sci_csr & SCI_CSR_PHASE_MATCH))
702 1.1 chopps break;
703 1.1 chopps *buf = *sci_data;
704 1.1 chopps *sci_icmd = SCI_ICMD_ACK;
705 1.1 chopps buf++;
706 1.1 chopps while (*sci_bus_csr & SCI_BUS_REQ);
707 1.1 chopps *sci_icmd = 0;
708 1.1 chopps }
709 1.1 chopps
710 1.1 chopps QPRINTF(("ixfer_in {%d} %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n",
711 1.1 chopps len, obp[0], obp[1], obp[2], obp[3], obp[4], obp[5],
712 1.1 chopps obp[6], obp[7], obp[8], obp[9]));
713 1.1 chopps
714 1.1 chopps /* this leaves with one csr to be read */
715 1.1 chopps HIST(ixin_wait, wait)
716 1.1 chopps }
717 1.1 chopps
718 1.1 chopps /*
719 1.1 chopps * SCSI 'immediate' command: issue a command to some SCSI device
720 1.1 chopps * and get back an 'immediate' response (i.e., do programmed xfer
721 1.1 chopps * to get the response data). 'cbuf' is a buffer containing a scsi
722 1.1 chopps * command of length clen bytes. 'buf' is a buffer of length 'len'
723 1.1 chopps * bytes for data. The transfer direction is determined by the device
724 1.1 chopps * (i.e., by the scsi bus data xfer phase). If 'len' is zero, the
725 1.1 chopps * command must supply no data. 'xferphase' is the bus phase the
726 1.1 chopps * caller expects to happen after the command is issued. It should
727 1.1 chopps * be one of DATA_IN_PHASE, DATA_OUT_PHASE or STATUS_PHASE.
728 1.1 chopps */
729 1.1 chopps static int
730 1.1 chopps scsiicmd(dev, target, cbuf, clen, buf, len, xferphase)
731 1.1 chopps struct sci_softc *dev;
732 1.1 chopps int target;
733 1.1 chopps u_char *cbuf;
734 1.1 chopps int clen;
735 1.1 chopps u_char *buf;
736 1.1 chopps int len;
737 1.1 chopps u_char xferphase;
738 1.1 chopps {
739 1.1 chopps u_char phase, csr, asr;
740 1.1 chopps register int wait;
741 1.1 chopps
742 1.1 chopps /* select the SCSI bus (it's an error if bus isn't free) */
743 1.1 chopps if (issue_select (dev, target, dev->sc_scsi_addr))
744 1.1 chopps return -1;
745 1.1 chopps /*
746 1.1 chopps * Wait for a phase change (or error) then let the device
747 1.1 chopps * sequence us through the various SCSI phases.
748 1.1 chopps */
749 1.1 chopps dev->sc_stat[0] = 0xff;
750 1.1 chopps dev->sc_msg[0] = 0xff;
751 1.1 chopps phase = CMD_PHASE;
752 1.1 chopps while (1) {
753 1.1 chopps wait = sci_cmd_wait;
754 1.1 chopps
755 1.1 chopps while ((*dev->sci_bus_csr & (SCI_BUS_REQ|SCI_BUS_BSY)) == SCI_BUS_BSY);
756 1.1 chopps
757 1.1 chopps QPRINTF((">CSR:%02x<", *dev->sci_bus_csr));
758 1.1 chopps if ((*dev->sci_bus_csr & SCI_BUS_REQ) == 0) {
759 1.1 chopps return -1;
760 1.1 chopps }
761 1.1 chopps phase = SCI_PHASE(*dev->sci_bus_csr);
762 1.1 chopps
763 1.1 chopps switch (phase) {
764 1.1 chopps case CMD_PHASE:
765 1.1 chopps if (ixfer_out (dev, clen, cbuf, phase))
766 1.1 chopps goto abort;
767 1.1 chopps phase = xferphase;
768 1.1 chopps break;
769 1.1 chopps
770 1.1 chopps case DATA_IN_PHASE:
771 1.1 chopps if (len <= 0)
772 1.1 chopps goto abort;
773 1.1 chopps wait = sci_data_wait;
774 1.1 chopps ixfer_in (dev, len, buf, phase);
775 1.1 chopps phase = STATUS_PHASE;
776 1.1 chopps break;
777 1.1 chopps
778 1.1 chopps case DATA_OUT_PHASE:
779 1.1 chopps if (len <= 0)
780 1.1 chopps goto abort;
781 1.1 chopps wait = sci_data_wait;
782 1.1 chopps if (ixfer_out (dev, len, buf, phase))
783 1.1 chopps goto abort;
784 1.1 chopps phase = STATUS_PHASE;
785 1.1 chopps break;
786 1.1 chopps
787 1.1 chopps case MESG_IN_PHASE:
788 1.1 chopps dev->sc_msg[0] = 0xff;
789 1.1 chopps ixfer_in (dev, 1, dev->sc_msg,phase);
790 1.1 chopps dev->sc_flags &= ~SCI_SELECTED;
791 1.1 chopps while (*dev->sci_bus_csr & SCI_BUS_BSY);
792 1.1 chopps goto out;
793 1.1 chopps break;
794 1.1 chopps
795 1.1 chopps case MESG_OUT_PHASE:
796 1.1 chopps phase = STATUS_PHASE;
797 1.1 chopps break;
798 1.1 chopps
799 1.1 chopps case STATUS_PHASE:
800 1.1 chopps ixfer_in (dev, 1, dev->sc_stat, phase);
801 1.1 chopps phase = MESG_IN_PHASE;
802 1.1 chopps break;
803 1.1 chopps
804 1.1 chopps case BUS_FREE_PHASE:
805 1.1 chopps goto out;
806 1.1 chopps
807 1.1 chopps default:
808 1.1 chopps printf("sci: unexpected phase %d in icmd from %d\n",
809 1.1 chopps phase, target);
810 1.1 chopps goto abort;
811 1.1 chopps }
812 1.1 chopps #if 0
813 1.1 chopps if (wait <= 0)
814 1.1 chopps goto abort;
815 1.1 chopps #endif
816 1.1 chopps }
817 1.1 chopps
818 1.1 chopps abort:
819 1.1 chopps scsiabort(dev, "icmd");
820 1.1 chopps out:
821 1.1 chopps QPRINTF(("=STS:%02x=", dev->sc_stat[0]));
822 1.1 chopps return (dev->sc_stat[0]);
823 1.1 chopps }
824 1.1 chopps
825 1.1 chopps int
826 1.1 chopps sci_test_unit_rdy(ctlr, slave, unit)
827 1.1 chopps int ctlr, slave, unit;
828 1.1 chopps {
829 1.1 chopps register struct sci_softc *dev = &sci_softc[ctlr];
830 1.1 chopps static struct scsi_cdb6 cdb = { CMD_TEST_UNIT_READY };
831 1.1 chopps
832 1.1 chopps cdb.lun = unit;
833 1.1 chopps return (scsiicmd(dev, slave, (u_char *)&cdb, sizeof(cdb), (u_char *)0, 0,
834 1.1 chopps STATUS_PHASE));
835 1.1 chopps }
836 1.1 chopps
837 1.1 chopps int
838 1.1 chopps sci_start_stop_unit (ctlr, slave, unit, start)
839 1.1 chopps int ctlr, slave, unit;
840 1.1 chopps {
841 1.1 chopps register struct sci_softc *dev = &sci_softc[ctlr];
842 1.1 chopps static struct scsi_cdb6 cdb = { CMD_LOADUNLOAD };
843 1.1 chopps
844 1.1 chopps cdb.lun = unit;
845 1.1 chopps /* we don't set the immediate bit, so we wait for the
846 1.1 chopps command to succeed.
847 1.1 chopps We also don't touch the LoEj bit, which is primarily meant
848 1.1 chopps for floppies. */
849 1.1 chopps cdb.len = start & 0x01;
850 1.1 chopps return (scsiicmd(dev, slave, (u_char *)&cdb, sizeof(cdb), (u_char *)0, 0,
851 1.1 chopps STATUS_PHASE));
852 1.1 chopps }
853 1.1 chopps
854 1.1 chopps
855 1.1 chopps int
856 1.1 chopps sci_request_sense(ctlr, slave, unit, buf, len)
857 1.1 chopps int ctlr, slave, unit;
858 1.1 chopps u_char *buf;
859 1.1 chopps unsigned len;
860 1.1 chopps {
861 1.1 chopps register struct sci_softc *dev = &sci_softc[ctlr];
862 1.1 chopps static struct scsi_cdb6 cdb = { CMD_REQUEST_SENSE };
863 1.1 chopps
864 1.1 chopps cdb.lun = unit;
865 1.1 chopps cdb.len = len;
866 1.1 chopps return (scsiicmd(dev, slave, (u_char *)&cdb, sizeof(cdb), buf, len, DATA_IN_PHASE));
867 1.1 chopps }
868 1.1 chopps
869 1.1 chopps int
870 1.1 chopps sci_immed_command_nd(ctlr, slave, unit, cdb)
871 1.1 chopps int ctlr, slave, unit;
872 1.1 chopps struct scsi_fmt_cdb *cdb;
873 1.1 chopps {
874 1.1 chopps register struct sci_softc *dev = &sci_softc[ctlr];
875 1.1 chopps
876 1.1 chopps cdb->cdb[1] |= (unit << 5);
877 1.1 chopps return(scsiicmd(dev, slave, (u_char *) cdb->cdb, cdb->len,
878 1.1 chopps 0, 0, STATUS_PHASE));
879 1.1 chopps }
880 1.1 chopps
881 1.1 chopps int
882 1.1 chopps sci_immed_command(ctlr, slave, unit, cdb, buf, len, rd)
883 1.1 chopps int ctlr, slave, unit;
884 1.1 chopps struct scsi_fmt_cdb *cdb;
885 1.1 chopps u_char *buf;
886 1.1 chopps unsigned len;
887 1.1 chopps {
888 1.1 chopps register struct sci_softc *dev = &sci_softc[ctlr];
889 1.1 chopps
890 1.1 chopps cdb->cdb[1] |= (unit << 5);
891 1.1 chopps return (scsiicmd(dev, slave, (u_char *) cdb->cdb, cdb->len, buf, len,
892 1.1 chopps rd != 0? DATA_IN_PHASE : DATA_OUT_PHASE));
893 1.1 chopps }
894 1.1 chopps
895 1.1 chopps /*
896 1.1 chopps * The following routines are test-and-transfer i/o versions of read/write
897 1.1 chopps * for things like reading disk labels and writing core dumps. The
898 1.1 chopps * routine scigo should be used for normal data transfers, NOT these
899 1.1 chopps * routines.
900 1.1 chopps */
901 1.1 chopps int
902 1.1 chopps sci_tt_read(ctlr, slave, unit, buf, len, blk, bshift)
903 1.1 chopps int ctlr, slave, unit;
904 1.1 chopps u_char *buf;
905 1.1 chopps u_int len;
906 1.1 chopps daddr_t blk;
907 1.1 chopps int bshift;
908 1.1 chopps {
909 1.1 chopps register struct sci_softc *dev = &sci_softc[ctlr];
910 1.1 chopps struct scsi_cdb10 cdb;
911 1.1 chopps int stat;
912 1.1 chopps int old_wait = sci_data_wait;
913 1.1 chopps
914 1.1 chopps sci_data_wait = 300000;
915 1.1 chopps bzero(&cdb, sizeof(cdb));
916 1.1 chopps cdb.cmd = CMD_READ_EXT;
917 1.1 chopps cdb.lun = unit;
918 1.1 chopps blk >>= bshift;
919 1.1 chopps cdb.lbah = blk >> 24;
920 1.1 chopps cdb.lbahm = blk >> 16;
921 1.1 chopps cdb.lbalm = blk >> 8;
922 1.1 chopps cdb.lbal = blk;
923 1.1 chopps cdb.lenh = len >> (8 + DEV_BSHIFT + bshift);
924 1.1 chopps cdb.lenl = len >> (DEV_BSHIFT + bshift);
925 1.1 chopps stat = scsiicmd(dev, slave, (u_char *) &cdb, sizeof(cdb), buf, len, DATA_IN_PHASE);
926 1.1 chopps sci_data_wait = old_wait;
927 1.1 chopps return (stat);
928 1.1 chopps }
929 1.1 chopps
930 1.1 chopps int
931 1.1 chopps sci_tt_write(ctlr, slave, unit, buf, len, blk, bshift)
932 1.1 chopps int ctlr, slave, unit;
933 1.1 chopps u_char *buf;
934 1.1 chopps u_int len;
935 1.1 chopps daddr_t blk;
936 1.1 chopps int bshift;
937 1.1 chopps {
938 1.1 chopps register struct sci_softc *dev = &sci_softc[ctlr];
939 1.1 chopps struct scsi_cdb10 cdb;
940 1.1 chopps int stat;
941 1.1 chopps int old_wait = sci_data_wait;
942 1.1 chopps
943 1.1 chopps sci_data_wait = 300000;
944 1.1 chopps
945 1.1 chopps bzero(&cdb, sizeof(cdb));
946 1.1 chopps cdb.cmd = CMD_WRITE_EXT;
947 1.1 chopps cdb.lun = unit;
948 1.1 chopps blk >>= bshift;
949 1.1 chopps cdb.lbah = blk >> 24;
950 1.1 chopps cdb.lbahm = blk >> 16;
951 1.1 chopps cdb.lbalm = blk >> 8;
952 1.1 chopps cdb.lbal = blk;
953 1.1 chopps cdb.lenh = len >> (8 + DEV_BSHIFT + bshift);
954 1.1 chopps cdb.lenl = len >> (DEV_BSHIFT + bshift);
955 1.1 chopps stat = scsiicmd(dev, slave, (u_char *) &cdb, sizeof(cdb), buf, len, DATA_OUT_PHASE);
956 1.1 chopps sci_data_wait = old_wait;
957 1.1 chopps return (stat);
958 1.1 chopps }
959 1.1 chopps
960 1.1 chopps int
961 1.1 chopps scireq(dq)
962 1.1 chopps register struct devqueue *dq;
963 1.1 chopps {
964 1.1 chopps register struct devqueue *hq;
965 1.1 chopps
966 1.1 chopps hq = &sci_softc[dq->dq_ctlr].sc_sq;
967 1.1 chopps insque(dq, hq->dq_back);
968 1.1 chopps if (dq->dq_back == hq)
969 1.1 chopps return(1);
970 1.1 chopps return(0);
971 1.1 chopps }
972 1.1 chopps
973 1.1 chopps int
974 1.1 chopps sciustart (int unit)
975 1.1 chopps {
976 1.1 chopps register struct sci_softc *dev = &sci_softc[unit];
977 1.1 chopps
978 1.1 chopps /* If we got here, this controller is not busy
979 1.1 chopps so we are ready to accept a command
980 1.1 chopps */
981 1.1 chopps return(1);
982 1.1 chopps }
983 1.1 chopps
984 1.1 chopps void
985 1.1 chopps scistart (int unit)
986 1.1 chopps {
987 1.1 chopps register struct devqueue *dq;
988 1.1 chopps
989 1.1 chopps dq = sci_softc[unit].sc_sq.dq_forw;
990 1.1 chopps (dq->dq_driver->d_go)(dq->dq_unit);
991 1.1 chopps }
992 1.1 chopps
993 1.1 chopps int
994 1.1 chopps scigo(ctlr, slave, unit, bp, cdb, pad)
995 1.1 chopps int ctlr, slave, unit;
996 1.1 chopps struct buf *bp;
997 1.1 chopps struct scsi_fmt_cdb *cdb;
998 1.1 chopps int pad;
999 1.1 chopps {
1000 1.1 chopps register struct sci_softc *dev = &sci_softc[ctlr];
1001 1.1 chopps u_char phase, csr, asr, cmd;
1002 1.1 chopps char *addr;
1003 1.1 chopps int count;
1004 1.1 chopps register struct devqueue *dq;
1005 1.1 chopps
1006 1.1 chopps cdb->cdb[1] |= unit << 5;
1007 1.1 chopps
1008 1.1 chopps addr = bp->b_un.b_addr;
1009 1.1 chopps count = bp->b_bcount;
1010 1.1 chopps
1011 1.1 chopps if (sci_no_dma) {
1012 1.1 chopps
1013 1.1 chopps scsiicmd (dev, slave, (u_char *) cdb->cdb, cdb->len,
1014 1.1 chopps addr, count,
1015 1.1 chopps bp->b_flags & B_READ ? DATA_IN_PHASE : DATA_OUT_PHASE);
1016 1.1 chopps
1017 1.1 chopps dq = dev->sc_sq.dq_forw;
1018 1.1 chopps dev->sc_flags &=~ (SCI_IO);
1019 1.1 chopps (dq->dq_driver->d_intr)(dq->dq_unit, dev->sc_stat[0]);
1020 1.1 chopps return dev->sc_stat[0];
1021 1.1 chopps }
1022 1.1 chopps
1023 1.1 chopps /* select the SCSI bus (it's an error if bus isn't free) */
1024 1.1 chopps if (issue_select (dev, slave, dev->sc_scsi_addr))
1025 1.1 chopps return -1;
1026 1.1 chopps /*
1027 1.1 chopps * Wait for a phase change (or error) then let the device
1028 1.1 chopps * sequence us through the various SCSI phases.
1029 1.1 chopps */
1030 1.1 chopps dev->sc_stat[0] = 0xff;
1031 1.1 chopps dev->sc_msg[0] = 0xff;
1032 1.1 chopps phase = CMD_PHASE;
1033 1.1 chopps while (1) {
1034 1.1 chopps while ((*dev->sci_bus_csr & (SCI_BUS_REQ|SCI_BUS_BSY)) ==
1035 1.1 chopps SCI_BUS_BSY);
1036 1.1 chopps
1037 1.1 chopps QPRINTF((">CSR:%02x<", *dev->sci_bus_csr));
1038 1.1 chopps if ((*dev->sci_bus_csr & SCI_BUS_REQ) == 0) {
1039 1.1 chopps goto abort;
1040 1.1 chopps }
1041 1.1 chopps phase = SCI_PHASE(*dev->sci_bus_csr);
1042 1.1 chopps
1043 1.1 chopps switch (phase) {
1044 1.1 chopps case CMD_PHASE:
1045 1.1 chopps if (ixfer_out (dev, cdb->len, cdb->cdb, phase))
1046 1.1 chopps goto abort;
1047 1.1 chopps phase = bp->b_flags & B_READ ? DATA_IN_PHASE : DATA_OUT_PHASE;
1048 1.1 chopps break;
1049 1.1 chopps
1050 1.1 chopps case DATA_IN_PHASE:
1051 1.1 chopps if (count <= 0)
1052 1.1 chopps goto abort;
1053 1.1 chopps /* XXX use psuedo DMA if available */
1054 1.1 chopps if (count >= 128 && dev->dma_xfer_in)
1055 1.1 chopps (*dev->dma_xfer_in)(dev, count, addr, phase);
1056 1.1 chopps else
1057 1.1 chopps ixfer_in (dev, count, addr, phase);
1058 1.1 chopps phase = STATUS_PHASE;
1059 1.1 chopps break;
1060 1.1 chopps
1061 1.1 chopps case DATA_OUT_PHASE:
1062 1.1 chopps if (count <= 0)
1063 1.1 chopps goto abort;
1064 1.1 chopps /* XXX use psuedo DMA if available */
1065 1.1 chopps if (count >= 128 && dev->dma_xfer_out)
1066 1.1 chopps (*dev->dma_xfer_out)(dev, count, addr, phase);
1067 1.1 chopps else
1068 1.1 chopps if (ixfer_out (dev, count, addr, phase))
1069 1.1 chopps goto abort;
1070 1.1 chopps phase = STATUS_PHASE;
1071 1.1 chopps break;
1072 1.1 chopps
1073 1.1 chopps case MESG_IN_PHASE:
1074 1.1 chopps dev->sc_msg[0] = 0xff;
1075 1.1 chopps ixfer_in (dev, 1, dev->sc_msg,phase);
1076 1.1 chopps dev->sc_flags &= ~SCI_SELECTED;
1077 1.1 chopps while (*dev->sci_bus_csr & SCI_BUS_BSY);
1078 1.1 chopps goto out;
1079 1.1 chopps break;
1080 1.1 chopps
1081 1.1 chopps case MESG_OUT_PHASE:
1082 1.1 chopps phase = STATUS_PHASE;
1083 1.1 chopps break;
1084 1.1 chopps
1085 1.1 chopps case STATUS_PHASE:
1086 1.1 chopps ixfer_in (dev, 1, dev->sc_stat, phase);
1087 1.1 chopps phase = MESG_IN_PHASE;
1088 1.1 chopps break;
1089 1.1 chopps
1090 1.1 chopps case BUS_FREE_PHASE:
1091 1.1 chopps goto out;
1092 1.1 chopps
1093 1.1 chopps default:
1094 1.1 chopps printf("sci: unexpected phase %d in icmd from %d\n",
1095 1.1 chopps phase, slave);
1096 1.1 chopps goto abort;
1097 1.1 chopps }
1098 1.1 chopps }
1099 1.1 chopps
1100 1.1 chopps abort:
1101 1.1 chopps scsiabort(dev, "go");
1102 1.1 chopps out:
1103 1.1 chopps QPRINTF(("=STS:%02x=", dev->sc_stat[0]));
1104 1.1 chopps dq = dev->sc_sq.dq_forw;
1105 1.1 chopps dev->sc_flags &=~ (SCI_IO);
1106 1.1 chopps (dq->dq_driver->d_intr)(dq->dq_unit, dev->sc_stat[0]);
1107 1.1 chopps return dev->sc_stat[0];
1108 1.1 chopps }
1109 1.1 chopps
1110 1.1 chopps void
1111 1.1 chopps scidone (int unit)
1112 1.1 chopps {
1113 1.1 chopps
1114 1.1 chopps #ifdef DEBUG
1115 1.1 chopps if (sci_debug)
1116 1.1 chopps printf("sci%d: done called!\n", unit);
1117 1.1 chopps #endif
1118 1.1 chopps }
1119 1.1 chopps
1120 1.1 chopps int
1121 1.1 chopps sciintr ()
1122 1.1 chopps {
1123 1.1 chopps register struct sci_softc *dev = sci_softc;
1124 1.1 chopps int unit;
1125 1.1 chopps int dummy;
1126 1.1 chopps int found = 0;
1127 1.1 chopps
1128 1.1 chopps for (unit = 0; unit < NSCI; ++unit, ++dev) {
1129 1.1 chopps if (dev->sc_ac->amiga_ipl == 0)
1130 1.1 chopps continue;
1131 1.1 chopps /* XXX check if expecting interrupt? */
1132 1.1 chopps if (dev->dma_intr)
1133 1.1 chopps found += (*dev->dma_intr)(dev);
1134 1.1 chopps else if ((*dev->sci_csr & SCI_CSR_INT)) {
1135 1.1 chopps *dev->sci_mode = 0;
1136 1.1 chopps dummy = *dev->sci_iack;
1137 1.1 chopps ++found;
1138 1.1 chopps }
1139 1.1 chopps }
1140 1.1 chopps return found;
1141 1.1 chopps }
1142 1.1 chopps
1143 1.1 chopps void
1144 1.1 chopps scifree(dq)
1145 1.1 chopps register struct devqueue *dq;
1146 1.1 chopps {
1147 1.1 chopps register struct devqueue *hq;
1148 1.1 chopps
1149 1.1 chopps hq = &sci_softc[dq->dq_ctlr].sc_sq;
1150 1.1 chopps remque(dq);
1151 1.1 chopps if ((dq = hq->dq_forw) != hq)
1152 1.1 chopps (dq->dq_driver->d_start)(dq->dq_unit);
1153 1.1 chopps }
1154 1.1 chopps
1155 1.1 chopps /*
1156 1.1 chopps * (XXX) The following routine is needed for the SCSI tape driver
1157 1.1 chopps * to read odd-size records.
1158 1.1 chopps */
1159 1.1 chopps
1160 1.1 chopps #if NST > 0
1161 1.1 chopps int
1162 1.1 chopps sci_tt_oddio(ctlr, slave, unit, buf, len, b_flags, freedma)
1163 1.1 chopps int ctlr, slave, unit, b_flags;
1164 1.1 chopps u_char *buf;
1165 1.1 chopps u_int len;
1166 1.1 chopps {
1167 1.1 chopps register struct sci_softc *dev = &sci_softc[ctlr];
1168 1.1 chopps struct scsi_cdb6 cdb;
1169 1.1 chopps u_char iphase;
1170 1.1 chopps int stat;
1171 1.1 chopps
1172 1.1 chopps /*
1173 1.1 chopps * First free any DMA channel that was allocated.
1174 1.1 chopps * We can't use DMA to do this transfer.
1175 1.1 chopps */
1176 1.1 chopps /*
1177 1.1 chopps * Initialize command block
1178 1.1 chopps */
1179 1.1 chopps bzero(&cdb, sizeof(cdb));
1180 1.1 chopps cdb.lun = unit;
1181 1.1 chopps cdb.lbam = (len >> 16) & 0xff;
1182 1.1 chopps cdb.lbal = (len >> 8) & 0xff;
1183 1.1 chopps cdb.len = len & 0xff;
1184 1.1 chopps if (buf == 0) {
1185 1.1 chopps cdb.cmd = CMD_SPACE;
1186 1.1 chopps cdb.lun |= 0x00;
1187 1.1 chopps len = 0;
1188 1.1 chopps iphase = MESG_IN_PHASE;
1189 1.1 chopps } else if (b_flags & B_READ) {
1190 1.1 chopps cdb.cmd = CMD_READ;
1191 1.1 chopps iphase = DATA_IN_PHASE;
1192 1.1 chopps } else {
1193 1.1 chopps cdb.cmd = CMD_WRITE;
1194 1.1 chopps iphase = DATA_OUT_PHASE;
1195 1.1 chopps }
1196 1.1 chopps /*
1197 1.1 chopps * Perform command (with very long delays)
1198 1.1 chopps */
1199 1.1 chopps sci_delay(30000000);
1200 1.1 chopps stat = scsiicmd(dev, slave, (u_char *) &cdb, sizeof(cdb), buf, len, iphase);
1201 1.1 chopps sci_delay(0);
1202 1.1 chopps return (stat);
1203 1.1 chopps }
1204 1.1 chopps #endif
1205 1.1 chopps #endif
1206