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