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