1 /* $OpenBSD: ncr5380sbc.c,v 1.17 2003/10/21 18:58:49 jmc Exp $ */
2 /* $NetBSD: ncr5380sbc.c,v 1.13 1996/10/13 01:37:25 christos Exp $ */
3
4 /*
5 * Copyright (c) 1995 David Jones, Gordon W. Ross
6 * Copyright (c) 1994 Jarle Greipsland
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. The name of the authors may not be used to endorse or promote products
18 * derived from this software without specific prior written permission.
19 * 4. All advertising materials mentioning features or use of this software
20 * must display the following acknowledgement:
21 * This product includes software developed by
22 * David Jones and Gordon Ross
23 *
24 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
25 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27 * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
29 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
33 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 */
35
36 /*
37 * This is a machine-independent driver for the NCR5380
38 * SCSI Bus Controller (SBC), also known as the Am5380.
39 *
40 * This code should work with any memory-mapped 5380,
41 * and can be shared by multiple adapters that address
42 * the 5380 with different register offset spacings.
43 * (This can happen on the atari, for example.)
44 * For porting/design info. see: ncr5380.doc
45 *
46 * Credits, history:
47 *
48 * David Jones is the author of most of the code that now
49 * appears in this file, and was the architect of the
50 * current overall structure (MI/MD code separation, etc.)
51 *
52 * Gordon Ross integrated the message phase code, added lots of
53 * comments about what happens when and why (re. SCSI spec.),
54 * debugged some reentrance problems, and added several new
55 * "hooks" needed for the Sun3 "si" adapters.
56 *
57 * The message in/out code was taken nearly verbatim from
58 * the aic6360 driver by Jarle Greipsland.
59 *
60 * Several other NCR5380 drivers were used for reference
61 * while developing this driver, including work by:
62 * The Alice Group (mac68k port) namely:
63 * Allen K. Briggs, Chris P. Caputo, Michael L. Finch,
64 * Bradley A. Grantham, and Lawrence A. Kesteloot
65 * Michael L. Hitch (amiga drivers: sci.c)
66 * Leo Weppelman (atari driver: ncr5380.c)
67 * There are others too. Thanks, everyone.
68 */
69
70 #include <sys/types.h>
71 #include <sys/param.h>
72 #include <sys/systm.h>
73 #include <sys/kernel.h>
74 #include <sys/errno.h>
75 #include <sys/device.h>
76 #include <sys/buf.h>
77 #include <sys/proc.h>
78 #include <sys/user.h>
79
80 #include <scsi/scsi_all.h>
81 #include <scsi/scsi_debug.h>
82 #include <scsi/scsi_message.h>
83 #include <scsi/scsiconf.h>
84
85 #ifdef DDB
86 #include <ddb/db_output.h>
87 #endif
88
89 #include <dev/ic/ncr5380reg.h>
90 #include <dev/ic/ncr5380var.h>
91
92 static void ncr5380_sched(struct ncr5380_softc *);
93 static void ncr5380_done(struct ncr5380_softc *);
94
95 static int ncr5380_select(struct ncr5380_softc *, struct sci_req *);
96 static void ncr5380_reselect(struct ncr5380_softc *);
97
98 static int ncr5380_msg_in(struct ncr5380_softc *);
99 static int ncr5380_msg_out(struct ncr5380_softc *);
100 static int ncr5380_data_xfer(struct ncr5380_softc *, int);
101 static int ncr5380_command(struct ncr5380_softc *);
102 static int ncr5380_status(struct ncr5380_softc *);
103 static void ncr5380_machine(struct ncr5380_softc *);
104
105 void ncr5380_abort(struct ncr5380_softc *);
106 void ncr5380_cmd_timeout(void *);
107 /*
108 * Action flags returned by the info_transfer functions:
109 * (These determine what happens next.)
110 */
111 #define ACT_CONTINUE 0x00 /* No flags: expect another phase */
112 #define ACT_DISCONNECT 0x01 /* Target is disconnecting */
113 #define ACT_CMD_DONE 0x02 /* Need to call scsi_done() */
114 #define ACT_RESET_BUS 0x04 /* Need bus reset (cmd timeout) */
115 #define ACT_WAIT_DMA 0x10 /* Wait for DMA to complete */
116
117 /*****************************************************************
118 * Debugging stuff
119 *****************************************************************/
120
121 #ifndef DDB
122 /* This is used only in recoverable places. */
123 #define Debugger() printf("Debug: ncr5380.c:%d\n", __LINE__)
124 #endif
125
126 #ifdef NCR5380_DEBUG
127
128 #define NCR_DBG_BREAK 1
129 #define NCR_DBG_CMDS 2
130 int ncr5380_debug = NCR_DBG_BREAK|NCR_DBG_CMDS;
131 struct ncr5380_softc *ncr5380_debug_sc;
132
133 #define NCR_BREAK() \
134 do { if (ncr5380_debug & NCR_DBG_BREAK) Debugger(); } while (0)
135
136 static void ncr5380_show_scsi_cmd(struct scsi_xfer *);
137 static void ncr5380_show_sense(struct scsi_xfer *);
138
139 #ifdef DDB
140 void ncr5380_trace(char *, long);
141 void ncr5380_clear_trace(void);
142 void ncr5380_show_trace(void);
143 void ncr5380_show_req(struct sci_req *);
144 void ncr5380_show_req(struct sci_req *);
145 void ncr5380_show_state(void);
146 #endif /* DDB */
147 #else /* NCR5380_DEBUG */
148
149 #define NCR_BREAK() /* nada */
150 #define ncr5380_show_scsi_cmd(xs) /* nada */
151 #define ncr5380_show_sense(xs) /* nada */
152
153 #endif /* NCR5380_DEBUG */
154
155 static char *
156 phase_names[8] = {
157 "DATA_OUT",
158 "DATA_IN",
159 "COMMAND",
160 "STATUS",
161 "UNSPEC1",
162 "UNSPEC2",
163 "MSG_OUT",
164 "MSG_IN",
165 };
166
167 /*****************************************************************
168 * Actual chip control
169 *****************************************************************/
170
171 /*
172 * XXX: These timeouts might need to be tuned...
173 */
174
175 /* This one is used when waiting for a phase change. (X100uS.) */
176 int ncr5380_wait_phase_timo = 1000 * 10 * 300; /* 5 min. */
177
178 /* These are used in the following inline functions. */
179 int ncr5380_wait_req_timo = 1000 * 50; /* X2 = 100 mS. */
180 int ncr5380_wait_nrq_timo = 1000 * 25; /* X2 = 50 mS. */
181
182 static __inline int ncr5380_wait_req(struct ncr5380_softc *);
183 static __inline int ncr5380_wait_not_req(struct ncr5380_softc *);
184 static __inline void ncr_sched_msgout(struct ncr5380_softc *, int);
185
186 /* Return zero on success. */
ncr5380_wait_req(sc)187 static __inline int ncr5380_wait_req(sc)
188 struct ncr5380_softc *sc;
189 {
190 register int timo = ncr5380_wait_req_timo;
191 for (;;) {
192 if (*sc->sci_bus_csr & SCI_BUS_REQ) {
193 timo = 0; /* return 0 */
194 break;
195 }
196 if (--timo < 0)
197 break; /* return -1 */
198 delay(2);
199 }
200 return (timo);
201 }
202
203 /* Return zero on success. */
ncr5380_wait_not_req(sc)204 static __inline int ncr5380_wait_not_req(sc)
205 struct ncr5380_softc *sc;
206 {
207 register int timo = ncr5380_wait_nrq_timo;
208 for (;;) {
209 if ((*sc->sci_bus_csr & SCI_BUS_REQ) == 0) {
210 timo = 0; /* return 0 */
211 break;
212 }
213 if (--timo < 0)
214 break; /* return -1 */
215 delay(2);
216 }
217 return (timo);
218 }
219
220 /* Ask the target for a MSG_OUT phase. */
221 static __inline void
ncr_sched_msgout(sc,msg_code)222 ncr_sched_msgout(sc, msg_code)
223 struct ncr5380_softc *sc;
224 int msg_code;
225 {
226 /* First time, raise ATN line. */
227 if (sc->sc_msgpriq == 0) {
228 register u_char icmd;
229 icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
230 *sc->sci_icmd = icmd | SCI_ICMD_ATN;
231 delay(2);
232 }
233 sc->sc_msgpriq |= msg_code;
234 }
235
236
237 int
ncr5380_pio_out(sc,phase,count,data)238 ncr5380_pio_out(sc, phase, count, data)
239 struct ncr5380_softc *sc;
240 int phase, count;
241 unsigned char *data;
242 {
243 register u_char icmd;
244 register int resid;
245 register int error;
246
247 icmd = *(sc->sci_icmd) & SCI_ICMD_RMASK;
248
249 icmd |= SCI_ICMD_DATA;
250 *sc->sci_icmd = icmd;
251
252 resid = count;
253 while (resid > 0) {
254 if (!SCI_BUSY(sc)) {
255 NCR_TRACE("pio_out: lost BSY, resid=%d\n", resid);
256 break;
257 }
258 if (ncr5380_wait_req(sc)) {
259 NCR_TRACE("pio_out: no REQ, resid=%d\n", resid);
260 break;
261 }
262 if (SCI_BUS_PHASE(*sc->sci_bus_csr) != phase)
263 break;
264
265 /* Put the data on the bus. */
266 if (data)
267 *sc->sci_odata = *data++;
268 else
269 *sc->sci_odata = 0;
270
271 /* Tell the target it's there. */
272 icmd |= SCI_ICMD_ACK;
273 *sc->sci_icmd = icmd;
274
275 /* Wait for target to get it. */
276 error = ncr5380_wait_not_req(sc);
277
278 /* OK, it's got it (or we gave up waiting). */
279 icmd &= ~SCI_ICMD_ACK;
280 *sc->sci_icmd = icmd;
281
282 if (error) {
283 NCR_TRACE("pio_out: stuck REQ, resid=%d\n", resid);
284 break;
285 }
286
287 --resid;
288 }
289
290 /* Stop driving the data bus. */
291 icmd &= ~SCI_ICMD_DATA;
292 *sc->sci_icmd = icmd;
293
294 return (count - resid);
295 }
296
297
298 int
ncr5380_pio_in(sc,phase,count,data)299 ncr5380_pio_in(sc, phase, count, data)
300 struct ncr5380_softc *sc;
301 int phase, count;
302 unsigned char *data;
303 {
304 register u_char icmd;
305 register int resid;
306 register int error;
307
308 icmd = *(sc->sci_icmd) & SCI_ICMD_RMASK;
309
310 resid = count;
311 while (resid > 0) {
312 if (!SCI_BUSY(sc)) {
313 NCR_TRACE("pio_in: lost BSY, resid=%d\n", resid);
314 break;
315 }
316 if (ncr5380_wait_req(sc)) {
317 NCR_TRACE("pio_in: no REQ, resid=%d\n", resid);
318 break;
319 }
320 /* A phase change is not valid until AFTER REQ rises! */
321 if (SCI_BUS_PHASE(*sc->sci_bus_csr) != phase)
322 break;
323
324 /* Read the data bus. */
325 if (data)
326 *data++ = *sc->sci_data;
327 else
328 (void) *sc->sci_data;
329
330 /* Tell target we got it. */
331 icmd |= SCI_ICMD_ACK;
332 *sc->sci_icmd = icmd;
333
334 /* Wait for target to drop REQ... */
335 error = ncr5380_wait_not_req(sc);
336
337 /* OK, we can drop ACK. */
338 icmd &= ~SCI_ICMD_ACK;
339 *sc->sci_icmd = icmd;
340
341 if (error) {
342 NCR_TRACE("pio_in: stuck REQ, resid=%d\n", resid);
343 break;
344 }
345
346 --resid;
347 }
348
349 return (count - resid);
350 }
351
352
353 void
ncr5380_init(sc)354 ncr5380_init(sc)
355 struct ncr5380_softc *sc;
356 {
357 int i, j;
358 struct sci_req *sr;
359
360 #ifdef NCR5380_DEBUG
361 ncr5380_debug_sc = sc;
362 #endif
363
364 for (i = 0; i < SCI_OPENINGS; i++) {
365 sr = &sc->sc_ring[i];
366 sr->sr_xs = NULL;
367 timeout_set(&sr->sr_timeout, ncr5380_cmd_timeout, sr);
368 }
369 for (i = 0; i < 8; i++)
370 for (j = 0; j < 8; j++)
371 sc->sc_matrix[i][j] = NULL;
372
373 sc->sc_link.openings = 2; /* XXX - Not SCI_OPENINGS */
374 sc->sc_prevphase = PHASE_INVALID;
375 sc->sc_state = NCR_IDLE;
376
377 *sc->sci_tcmd = PHASE_INVALID;
378 *sc->sci_icmd = 0;
379 *sc->sci_mode = 0;
380 *sc->sci_sel_enb = 0;
381 SCI_CLR_INTR(sc);
382
383 /* XXX: Enable reselect interrupts... */
384 *sc->sci_sel_enb = 0x80;
385
386 /* Another hack (Er.. hook!) for the sun3 si: */
387 if (sc->sc_intr_on) {
388 NCR_TRACE("init: intr ON\n", 0);
389 sc->sc_intr_on(sc);
390 }
391 }
392
393
394 void
ncr5380_reset_scsibus(sc)395 ncr5380_reset_scsibus(sc)
396 struct ncr5380_softc *sc;
397 {
398
399 NCR_TRACE("reset_scsibus, cur=0x%x\n",
400 (long) sc->sc_current);
401
402 *sc->sci_icmd = SCI_ICMD_RST;
403 delay(500);
404 *sc->sci_icmd = 0;
405
406 *sc->sci_mode = 0;
407 *sc->sci_tcmd = PHASE_INVALID;
408
409 SCI_CLR_INTR(sc);
410 /* XXX - Need long delay here! */
411 delay(100000);
412
413 /* XXX - Need to cancel disconnected requests. */
414 }
415
416
417 /*
418 * Interrupt handler for the SCSI Bus Controller (SBC)
419 * This may also called for a DMA timeout (at splbio).
420 */
421 int
ncr5380_intr(sc)422 ncr5380_intr(sc)
423 struct ncr5380_softc *sc;
424 {
425 int claimed = 0;
426
427 /*
428 * Do not touch SBC regs here unless sc_current == NULL
429 * or it will complain about "register conflict" errors.
430 * Instead, just let ncr5380_machine() deal with it.
431 */
432 NCR_TRACE("intr: top, state=%d\n", sc->sc_state);
433
434 if (sc->sc_state == NCR_IDLE) {
435 /*
436 * Might be reselect. ncr5380_reselect() will check,
437 * and set up the connection if so. This will verify
438 * that sc_current == NULL at the beginning...
439 */
440
441 /* Another hack (Er.. hook!) for the sun3 si: */
442 if (sc->sc_intr_off) {
443 NCR_TRACE("intr: for reselect, intr off\n", 0);
444 sc->sc_intr_off(sc);
445 }
446
447 ncr5380_reselect(sc);
448 }
449
450 /*
451 * The remaining documented interrupt causes are phase mismatch and
452 * disconnect. In addition, the sunsi controller may produce a state
453 * where SCI_CSR_DONE is false, yet DMA is complete.
454 *
455 * The procedure in all these cases is to let ncr5380_machine()
456 * figure out what to do next.
457 */
458 if (sc->sc_state & NCR_WORKING) {
459 NCR_TRACE("intr: call machine, cur=0x%x\n",
460 (long) sc->sc_current);
461 /* This will usually free-up the nexus. */
462 ncr5380_machine(sc);
463 NCR_TRACE("intr: machine done, cur=0x%x\n",
464 (long) sc->sc_current);
465 claimed = 1;
466 }
467
468 /* Maybe we can run some commands now... */
469 if (sc->sc_state == NCR_IDLE) {
470 NCR_TRACE("intr: call sched, cur=0x%x\n",
471 (long) sc->sc_current);
472 ncr5380_sched(sc);
473 NCR_TRACE("intr: sched done, cur=0x%x\n",
474 (long) sc->sc_current);
475 }
476
477 return claimed;
478 }
479
480
481 /*
482 * Abort the current command (i.e. due to timeout)
483 */
484 void
ncr5380_abort(sc)485 ncr5380_abort(sc)
486 struct ncr5380_softc *sc;
487 {
488
489 /*
490 * Finish it now. If DMA is in progress, we
491 * can not call ncr_sched_msgout() because
492 * that hits the SBC (avoid DMA conflict).
493 */
494
495 /* Another hack (Er.. hook!) for the sun3 si: */
496 if (sc->sc_intr_off) {
497 NCR_TRACE("abort: intr off\n", 0);
498 sc->sc_intr_off(sc);
499 }
500
501 sc->sc_state |= NCR_ABORTING;
502 if ((sc->sc_state & NCR_DOINGDMA) == 0) {
503 ncr_sched_msgout(sc, SEND_ABORT);
504 }
505 NCR_TRACE("abort: call machine, cur=0x%x\n",
506 (long) sc->sc_current);
507 ncr5380_machine(sc);
508 NCR_TRACE("abort: machine done, cur=0x%x\n",
509 (long) sc->sc_current);
510
511 /* Another hack (Er.. hook!) for the sun3 si: */
512 if (sc->sc_intr_on) {
513 NCR_TRACE("abort: intr ON\n", 0);
514 sc->sc_intr_on(sc);
515 }
516 }
517
518 /*
519 * Timeout handler, scheduled for each SCSI command.
520 */
521 void
ncr5380_cmd_timeout(arg)522 ncr5380_cmd_timeout(arg)
523 void *arg;
524 {
525 struct sci_req *sr = arg;
526 struct scsi_xfer *xs;
527 struct scsi_link *sc_link;
528 struct ncr5380_softc *sc;
529 int s;
530
531 s = splbio();
532
533 /* Get all our variables... */
534 xs = sr->sr_xs;
535 if (xs == NULL) {
536 printf("ncr5380_cmd_timeout: no scsi_xfer\n");
537 goto out;
538 }
539 sc_link = xs->sc_link;
540 sc = sc_link->adapter_softc;
541
542 printf("%s: cmd timeout, targ=%d, lun=%d\n",
543 sc->sc_dev.dv_xname,
544 sr->sr_target, sr->sr_lun);
545
546 /*
547 * Mark the overdue job as failed, and arrange for
548 * ncr5380_machine to terminate it. If the victim
549 * is the current job, call ncr5380_machine() now.
550 * Otherwise arrange for ncr5380_sched() to do it.
551 */
552 sr->sr_flags |= SR_OVERDUE;
553 if (sc->sc_current == sr) {
554 NCR_TRACE("cmd_tmo: call abort, sr=0x%x\n", (long) sr);
555 ncr5380_abort(sc);
556 } else {
557 /*
558 * The driver may be idle, or busy with another job.
559 * Arrange for ncr5380_sched() to do the deed.
560 */
561 NCR_TRACE("cmd_tmo: clear matrix, t/l=0x%02x\n",
562 (sr->sr_target << 4) | sr->sr_lun);
563 sc->sc_matrix[sr->sr_target][sr->sr_lun] = NULL;
564 }
565
566 /*
567 * We may have aborted the current job, or may have
568 * already been idle. In either case, we should now
569 * be idle, so try to start another job.
570 */
571 if (sc->sc_state == NCR_IDLE) {
572 NCR_TRACE("cmd_tmo: call sched, cur=0x%x\n",
573 (long) sc->sc_current);
574 ncr5380_sched(sc);
575 NCR_TRACE("cmd_tmo: sched done, cur=0x%x\n",
576 (long) sc->sc_current);
577 }
578
579 out:
580 splx(s);
581 }
582
583
584 /*****************************************************************
585 * Interface to higher level
586 *****************************************************************/
587
588
589 /*
590 * Enter a new SCSI command into the "issue" queue, and
591 * if there is work to do, start it going.
592 *
593 * WARNING: This can be called recursively!
594 * (see comment in ncr5380_done)
595 */
596 int
ncr5380_scsi_cmd(xs)597 ncr5380_scsi_cmd(xs)
598 struct scsi_xfer *xs;
599 {
600 struct ncr5380_softc *sc;
601 struct sci_req *sr;
602 int s, rv, i, flags;
603
604 sc = xs->sc_link->adapter_softc;
605 flags = xs->flags;
606
607 if (sc->sc_flags & NCR5380_FORCE_POLLING)
608 flags |= SCSI_POLL;
609
610 if (flags & SCSI_DATA_UIO)
611 panic("ncr5380: scsi data uio requested");
612
613 s = splbio();
614
615 if (flags & SCSI_POLL) {
616 /* Terminate any current command. */
617 sr = sc->sc_current;
618 if (sr) {
619 printf("%s: polled request aborting %d/%d\n",
620 sc->sc_dev.dv_xname,
621 sr->sr_target, sr->sr_lun);
622 ncr5380_abort(sc);
623 }
624 if (sc->sc_state != NCR_IDLE) {
625 panic("ncr5380_scsi_cmd: polled request, abort failed");
626 }
627 }
628
629 /*
630 * Find lowest empty slot in ring buffer.
631 * XXX: What about "fairness" and cmd order?
632 */
633 for (i = 0; i < SCI_OPENINGS; i++)
634 if (sc->sc_ring[i].sr_xs == NULL)
635 goto new;
636
637 rv = TRY_AGAIN_LATER;
638 NCR_TRACE("scsi_cmd: no openings, rv=%d\n", rv);
639 goto out;
640
641 new:
642 /* Create queue entry */
643 sr = &sc->sc_ring[i];
644 sr->sr_xs = xs;
645 sr->sr_target = xs->sc_link->target;
646 sr->sr_lun = xs->sc_link->lun;
647 sr->sr_dma_hand = NULL;
648 sr->sr_dataptr = xs->data;
649 sr->sr_datalen = xs->datalen;
650 sr->sr_flags = (flags & SCSI_POLL) ? SR_IMMED : 0;
651 sr->sr_status = -1; /* no value */
652 sc->sc_ncmds++;
653 rv = SUCCESSFULLY_QUEUED;
654
655 NCR_TRACE("scsi_cmd: new sr=0x%x\n", (long)sr);
656
657 if (flags & SCSI_POLL) {
658 /* Force this new command to be next. */
659 sc->sc_rr = i;
660 }
661
662 /*
663 * If we were idle, run some commands...
664 */
665 if (sc->sc_state == NCR_IDLE) {
666 NCR_TRACE("scsi_cmd: call sched, cur=0x%x\n",
667 (long) sc->sc_current);
668 ncr5380_sched(sc);
669 NCR_TRACE("scsi_cmd: sched done, cur=0x%x\n",
670 (long) sc->sc_current);
671 }
672
673 if (flags & SCSI_POLL) {
674 /* Make sure ncr5380_sched() finished it. */
675 if ((xs->flags & ITSDONE) == 0)
676 panic("ncr5380_scsi_cmd: poll didn't finish");
677 rv = COMPLETE;
678 }
679
680 out:
681 splx(s);
682 return (rv);
683 }
684
685
686 /*
687 * POST PROCESSING OF SCSI_CMD (usually current)
688 * Called by ncr5380_sched(), ncr5380_machine()
689 */
690 static void
ncr5380_done(sc)691 ncr5380_done(sc)
692 struct ncr5380_softc *sc;
693 {
694 struct sci_req *sr;
695 struct scsi_xfer *xs;
696
697 #ifdef DIAGNOSTIC
698 if (sc->sc_state == NCR_IDLE)
699 panic("ncr5380_done: state=idle");
700 if (sc->sc_current == NULL)
701 panic("ncr5380_done: current=0");
702 #endif
703
704 sr = sc->sc_current;
705 xs = sr->sr_xs;
706
707 NCR_TRACE("done: top, cur=0x%x\n", (long) sc->sc_current);
708
709 /*
710 * Clean up DMA resources for this command.
711 */
712 if (sr->sr_dma_hand) {
713 NCR_TRACE("done: dma_free, dh=0x%x\n",
714 (long) sr->sr_dma_hand);
715 (*sc->sc_dma_free)(sc);
716 }
717 #ifdef DIAGNOSTIC
718 if (sr->sr_dma_hand)
719 panic("ncr5380_done: dma free did not");
720 #endif
721
722 if (sc->sc_state & NCR_ABORTING) {
723 NCR_TRACE("done: aborting, error=%d\n", xs->error);
724 if (xs->error == XS_NOERROR)
725 xs->error = XS_TIMEOUT;
726 }
727
728 NCR_TRACE("done: check error=%d\n", (long) xs->error);
729
730 /* If error is already set, ignore sr_status value. */
731 if (xs->error != XS_NOERROR)
732 goto finish;
733
734 NCR_TRACE("done: check status=%d\n", sr->sr_status);
735
736 switch (sr->sr_status) {
737 case SCSI_OK: /* 0 */
738 if (sr->sr_flags & SR_SENSE) {
739 #ifdef NCR5380_DEBUG
740 if (ncr5380_debug & NCR_DBG_CMDS) {
741 ncr5380_show_sense(xs);
742 }
743 #endif
744 xs->error = XS_SENSE;
745 }
746 break;
747
748 case SCSI_CHECK:
749 if (sr->sr_flags & SR_SENSE) {
750 /* Sense command also asked for sense? */
751 printf("ncr5380_done: sense asked for sense\n");
752 NCR_BREAK();
753 xs->error = XS_DRIVER_STUFFUP;
754 break;
755 }
756 sr->sr_flags |= SR_SENSE;
757 NCR_TRACE("done: get sense, sr=0x%x\n", (long) sr);
758 /*
759 * Leave queued, but clear sc_current so we start over
760 * with selection. Guaranteed to get the same request.
761 */
762 sc->sc_state = NCR_IDLE;
763 sc->sc_current = NULL;
764 sc->sc_matrix[sr->sr_target][sr->sr_lun] = NULL;
765 return; /* XXX */
766
767 case SCSI_BUSY:
768 xs->error = XS_BUSY;
769 break;
770
771 case -1:
772 /* This is our "impossible" initial value. */
773 /* fallthrough */
774 default:
775 printf("%s: target %d, bad status=%d\n",
776 sc->sc_dev.dv_xname, sr->sr_target, sr->sr_status);
777 xs->error = XS_DRIVER_STUFFUP;
778 break;
779 }
780
781 finish:
782
783 NCR_TRACE("done: finish, error=%d\n", xs->error);
784
785 /*
786 * Dequeue the finished command, but don't clear sc_state until
787 * after the call to scsi_done(), because that may call back to
788 * ncr5380_scsi_cmd() - unwanted recursion!
789 *
790 * Keeping sc->sc_state != idle terminates the recursion.
791 */
792 #ifdef DIAGNOSTIC
793 if ((sc->sc_state & NCR_WORKING) == 0)
794 panic("ncr5380_done: bad state");
795 #endif
796
797 /* Clear our pointers to the request. */
798 sc->sc_current = NULL;
799 sc->sc_matrix[sr->sr_target][sr->sr_lun] = NULL;
800 timeout_del(&sr->sr_timeout);
801
802 /* Make the request free. */
803 sr->sr_xs = NULL;
804 sc->sc_ncmds--;
805
806 /* Tell common SCSI code it is done. */
807 xs->flags |= ITSDONE;
808 scsi_done(xs);
809
810 sc->sc_state = NCR_IDLE;
811 /* Now ncr5380_sched() may be called again. */
812 }
813
814
815 /*
816 * Schedule a SCSI operation. This routine should return
817 * only after it achieves one of the following conditions:
818 * Busy (sc->sc_state != NCR_IDLE)
819 * No more work can be started.
820 */
821 static void
ncr5380_sched(sc)822 ncr5380_sched(sc)
823 struct ncr5380_softc *sc;
824 {
825 struct sci_req *sr;
826 struct scsi_xfer *xs;
827 int target = 0, lun = 0;
828 int error, i;
829
830 /* Another hack (Er.. hook!) for the sun3 si: */
831 if (sc->sc_intr_off) {
832 NCR_TRACE("sched: top, intr off\n", 0);
833 sc->sc_intr_off(sc);
834 }
835
836 next_job:
837 /*
838 * Grab the next job from queue. Must be idle.
839 */
840 #ifdef DIAGNOSTIC
841 if (sc->sc_state != NCR_IDLE)
842 panic("ncr5380_sched: not idle");
843 if (sc->sc_current)
844 panic("ncr5380_sched: current set");
845 #endif
846
847 /*
848 * Always start the search where we last looked.
849 * The REQUEST_SENSE logic depends on this to
850 * choose the same job as was last picked, so it
851 * can just clear sc_current and reschedule.
852 * (Avoids loss of "contingent allegiance".)
853 */
854 i = sc->sc_rr;
855 sr = NULL;
856 do {
857 if (sc->sc_ring[i].sr_xs) {
858 target = sc->sc_ring[i].sr_target;
859 lun = sc->sc_ring[i].sr_lun;
860 if (sc->sc_matrix[target][lun] == NULL) {
861 /*
862 * Do not mark the target/LUN busy yet,
863 * because reselect may cause some other
864 * job to become the current one, so we
865 * might not actually start this job.
866 * Instead, set sc_matrix later on.
867 */
868 sc->sc_rr = i;
869 sr = &sc->sc_ring[i];
870 break;
871 }
872 }
873 i++;
874 if (i == SCI_OPENINGS)
875 i = 0;
876 } while (i != sc->sc_rr);
877
878 if (sr == NULL) {
879 NCR_TRACE("sched: no work, cur=0x%x\n",
880 (long) sc->sc_current);
881
882 /* Another hack (Er.. hook!) for the sun3 si: */
883 if (sc->sc_intr_on) {
884 NCR_TRACE("sched: ret, intr ON\n", 0);
885 sc->sc_intr_on(sc);
886 }
887
888 return; /* No more work to do. */
889 }
890
891 NCR_TRACE("sched: select for t/l=0x%02x\n",
892 (sr->sr_target << 4) | sr->sr_lun);
893
894 sc->sc_state = NCR_WORKING;
895 error = ncr5380_select(sc, sr);
896 if (sc->sc_current) {
897 /* Lost the race! reselected out from under us! */
898 /* Work with the reselected job. */
899 if (sr->sr_flags & SR_IMMED) {
900 printf("%s: reselected while polling (abort)\n",
901 sc->sc_dev.dv_xname);
902 /* Abort the reselected job. */
903 sc->sc_state |= NCR_ABORTING;
904 sc->sc_msgpriq |= SEND_ABORT;
905 }
906 sr = sc->sc_current;
907 xs = sr->sr_xs;
908 NCR_TRACE("sched: reselect, new sr=0x%x\n", (long)sr);
909 goto have_nexus;
910 }
911
912 /* Normal selection result. Target/LUN is now busy. */
913 sc->sc_matrix[target][lun] = sr;
914 sc->sc_current = sr; /* connected */
915 xs = sr->sr_xs;
916
917 /*
918 * Initialize pointers, etc. for this job
919 */
920 sc->sc_dataptr = sr->sr_dataptr;
921 sc->sc_datalen = sr->sr_datalen;
922 sc->sc_prevphase = PHASE_INVALID;
923 sc->sc_msgpriq = SEND_IDENTIFY;
924 sc->sc_msgoutq = 0;
925 sc->sc_msgout = 0;
926
927 NCR_TRACE("sched: select rv=%d\n", error);
928
929 switch (error) {
930 case XS_NOERROR:
931 break;
932
933 case XS_BUSY:
934 /* XXX - Reset and try again. */
935 printf("%s: select found SCSI bus busy, resetting...\n",
936 sc->sc_dev.dv_xname);
937 ncr5380_reset_scsibus(sc);
938 /* fallthrough */
939 case XS_SELTIMEOUT:
940 default:
941 xs->error = error; /* from select */
942 NCR_TRACE("sched: call done, sr=0x%x\n", (long)sr);
943 ncr5380_done(sc);
944
945 /* Paranoia: clear everything. */
946 sc->sc_dataptr = NULL;
947 sc->sc_datalen = 0;
948 sc->sc_prevphase = PHASE_INVALID;
949 sc->sc_msgpriq = 0;
950 sc->sc_msgoutq = 0;
951 sc->sc_msgout = 0;
952
953 goto next_job;
954 }
955
956 /*
957 * Selection was successful. Normally, this means
958 * we are starting a new command. However, this
959 * might be the termination of an overdue job.
960 */
961 if (sr->sr_flags & SR_OVERDUE) {
962 NCR_TRACE("sched: overdue, sr=0x%x\n", (long)sr);
963 sc->sc_state |= NCR_ABORTING;
964 sc->sc_msgpriq |= SEND_ABORT;
965 goto have_nexus;
966 }
967
968 /*
969 * This may be the continuation of some job that
970 * completed with a "check condition" code.
971 */
972 if (sr->sr_flags & SR_SENSE) {
973 NCR_TRACE("sched: get sense, sr=0x%x\n", (long)sr);
974 /* Do not allocate DMA, nor set timeout. */
975 goto have_nexus;
976 }
977
978 /*
979 * OK, we are starting a new command.
980 * Initialize and allocate resources for the new command.
981 * Device reset is special (only uses MSG_OUT phase).
982 * Normal commands start in MSG_OUT phase where we will
983 * send and IDENDIFY message, and then expect CMD phase.
984 */
985 #ifdef NCR5380_DEBUG
986 if (ncr5380_debug & NCR_DBG_CMDS) {
987 printf("ncr5380_sched: begin, target=%d, LUN=%d\n",
988 xs->sc_link->target, xs->sc_link->lun);
989 ncr5380_show_scsi_cmd(xs);
990 }
991 #endif
992 if (xs->flags & SCSI_RESET) {
993 NCR_TRACE("sched: cmd=reset, sr=0x%x\n", (long)sr);
994 /* Not an error, so do not set NCR_ABORTING */
995 sc->sc_msgpriq |= SEND_DEV_RESET;
996 goto have_nexus;
997 }
998
999 #ifdef DIAGNOSTIC
1000 if ((xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) == 0) {
1001 if (sc->sc_dataptr) {
1002 printf("%s: ptr but no data in/out flags?\n",
1003 sc->sc_dev.dv_xname);
1004 NCR_BREAK();
1005 sc->sc_dataptr = NULL;
1006 }
1007 }
1008 #endif
1009
1010 /* Allocate DMA space (maybe) */
1011 if (sc->sc_dataptr && sc->sc_dma_alloc &&
1012 (sc->sc_datalen >= sc->sc_min_dma_len))
1013 {
1014 NCR_TRACE("sched: dma_alloc, len=%d\n", sc->sc_datalen);
1015 (*sc->sc_dma_alloc)(sc);
1016 }
1017
1018 /*
1019 * Initialization hook called just after select,
1020 * at the beginning of COMMAND phase.
1021 * (but AFTER the DMA allocation is done)
1022 *
1023 * The evil Sun "si" adapter (OBIO variant) needs some
1024 * setup done to the DMA engine BEFORE the target puts
1025 * the SCSI bus into any DATA phase.
1026 */
1027 if (sr->sr_dma_hand && sc->sc_dma_setup) {
1028 NCR_TRACE("sched: dma_setup, dh=0x%x\n",
1029 (long) sr->sr_dma_hand);
1030 sc->sc_dma_setup(sc);
1031 }
1032
1033 /*
1034 * Schedule a timeout for the job we are starting.
1035 */
1036 if ((sr->sr_flags & SR_IMMED) == 0) {
1037 i = (xs->timeout * hz) / 1000;
1038 NCR_TRACE("sched: set timeout=%d\n", i);
1039 timeout_add(&sr->sr_timeout, i);
1040 }
1041
1042 have_nexus:
1043 NCR_TRACE("sched: call machine, cur=0x%x\n",
1044 (long) sc->sc_current);
1045 ncr5380_machine(sc);
1046 NCR_TRACE("sched: machine done, cur=0x%x\n",
1047 (long) sc->sc_current);
1048
1049 /*
1050 * What state did ncr5380_machine() leave us in?
1051 * Hopefully it sometimes completes a job...
1052 */
1053 if (sc->sc_state == NCR_IDLE)
1054 goto next_job;
1055
1056 return; /* Have work in progress. */
1057 }
1058
1059
1060 /*
1061 * Reselect handler: checks for reselection, and if we are being
1062 * reselected, it sets up sc->sc_current.
1063 *
1064 * We are reselected when:
1065 * SEL is TRUE
1066 * IO is TRUE
1067 * BSY is FALSE
1068 */
1069 void
ncr5380_reselect(sc)1070 ncr5380_reselect(sc)
1071 struct ncr5380_softc *sc;
1072 {
1073 struct sci_req *sr;
1074 int target, lun, phase, timo;
1075 int target_mask;
1076 u_char bus, data, icmd, msg;
1077
1078 #ifdef DIAGNOSTIC
1079 /*
1080 * Note: sc_state will be "idle" when ncr5380_intr()
1081 * calls, or "working" when ncr5380_select() calls.
1082 * (So don't test that in this DIAGNOSTIC)
1083 */
1084 if (sc->sc_current)
1085 panic("ncr5380_reselect: current set");
1086 #endif
1087
1088 /*
1089 * First, check the select line.
1090 * (That has to be set first.)
1091 */
1092 bus = *(sc->sci_bus_csr);
1093 if ((bus & SCI_BUS_SEL) == 0) {
1094 /* Not a selection or reselection. */
1095 return;
1096 }
1097
1098 /*
1099 * The target will assert BSY first (for bus arbitration),
1100 * then raise SEL, and finally drop BSY. Only then is the
1101 * data bus required to have valid selection ID bits set.
1102 * Wait for: SEL==1, BSY==0 before reading the data bus.
1103 * While this theoretically can happen, we are apparently
1104 * never fast enough to get here before BSY drops.
1105 */
1106 timo = ncr5380_wait_nrq_timo;
1107 for (;;) {
1108 if ((bus & SCI_BUS_BSY) == 0)
1109 break;
1110 /* Probably never get here... */
1111 if (--timo <= 0) {
1112 printf("%s: reselect, BSY stuck, bus=0x%x\n",
1113 sc->sc_dev.dv_xname, bus);
1114 /* Not much we can do. Reset the bus. */
1115 ncr5380_reset_scsibus(sc);
1116 return;
1117 }
1118 delay(2);
1119 bus = *(sc->sci_bus_csr);
1120 /* If SEL went away, forget it. */
1121 if ((bus & SCI_BUS_SEL) == 0)
1122 return;
1123 /* Still have SEL, check BSY. */
1124 }
1125 NCR_TRACE("reselect, valid data after %d loops\n",
1126 ncr5380_wait_nrq_timo - timo);
1127
1128 /*
1129 * Good. We have SEL=1 and BSY=0. Now wait for a
1130 * "bus settle delay" before we sample the data bus
1131 */
1132 delay(2);
1133 data = *(sc->sci_data) & 0xFF;
1134 /* Parity check is implicit in data validation below. */
1135
1136 /*
1137 * Is this a reselect (I/O == 1) or have we been
1138 * selected as a target? (I/O == 0)
1139 */
1140 if ((bus & SCI_BUS_IO) == 0) {
1141 printf("%s: selected as target, data=0x%x\n",
1142 sc->sc_dev.dv_xname, data);
1143 /* Not much we can do. Reset the bus. */
1144 /* XXX: send some sort of message? */
1145 ncr5380_reset_scsibus(sc);
1146 return;
1147 }
1148
1149 /*
1150 * OK, this is a reselection.
1151 */
1152 for (target = 0; target < 7; target++) {
1153 target_mask = (1 << target);
1154 if (data & target_mask)
1155 break;
1156 }
1157 if ((data & 0x7F) != target_mask) {
1158 /* No selecting ID? or >2 IDs on bus? */
1159 printf("%s: bad reselect, data=0x%x\n",
1160 sc->sc_dev.dv_xname, data);
1161 return;
1162 }
1163
1164 NCR_TRACE("reselect: target=0x%x\n", target);
1165
1166 /* Raise BSY to acknowledge target reselection. */
1167 *(sc->sci_icmd) = SCI_ICMD_BSY;
1168
1169 /* Wait for target to drop SEL. */
1170 timo = ncr5380_wait_nrq_timo;
1171 for (;;) {
1172 bus = *(sc->sci_bus_csr);
1173 if ((bus & SCI_BUS_SEL) == 0)
1174 break; /* success */
1175 if (--timo <= 0) {
1176 printf("%s: reselect, SEL stuck, bus=0x%x\n",
1177 sc->sc_dev.dv_xname, bus);
1178 NCR_BREAK();
1179 /* assume connected (fail later if not) */
1180 break;
1181 }
1182 delay(2);
1183 }
1184
1185 /* Now we drop BSY, and we are connected. */
1186 *(sc->sci_icmd) = 0;
1187 *sc->sci_sel_enb = 0;
1188 SCI_CLR_INTR(sc);
1189
1190 /*
1191 * At this point the target should send an IDENTIFY message,
1192 * which will permit us to determine the reselecting LUN.
1193 * If not, we assume LUN 0.
1194 */
1195 lun = 0;
1196 /* Wait for REQ before reading bus phase. */
1197 if (ncr5380_wait_req(sc)) {
1198 printf("%s: reselect, no REQ\n",
1199 sc->sc_dev.dv_xname);
1200 /* Try to send an ABORT message. */
1201 goto abort;
1202 }
1203 phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
1204 if (phase != PHASE_MSG_IN) {
1205 printf("%s: reselect, phase=%d\n",
1206 sc->sc_dev.dv_xname, phase);
1207 goto abort;
1208 }
1209
1210 /* Ack. the change to PHASE_MSG_IN */
1211 *(sc->sci_tcmd) = PHASE_MSG_IN;
1212
1213 /* Peek at the message byte without consuming it! */
1214 msg = *(sc->sci_data);
1215 if ((msg & 0x80) == 0) {
1216 printf("%s: reselect, not identify, msg=%d\n",
1217 sc->sc_dev.dv_xname, msg);
1218 goto abort;
1219 }
1220 lun = msg & 7;
1221
1222 /* We now know target/LUN. Do we have the request? */
1223 sr = sc->sc_matrix[target][lun];
1224 if (sr) {
1225 /* We now have a nexus. */
1226 sc->sc_state |= NCR_WORKING;
1227 sc->sc_current = sr;
1228 NCR_TRACE("reselect: resume sr=0x%x\n", (long)sr);
1229
1230 /* Implicit restore pointers message */
1231 sc->sc_dataptr = sr->sr_dataptr;
1232 sc->sc_datalen = sr->sr_datalen;
1233
1234 sc->sc_prevphase = PHASE_INVALID;
1235 sc->sc_msgpriq = 0;
1236 sc->sc_msgoutq = 0;
1237 sc->sc_msgout = 0;
1238
1239 /* XXX: Restore the normal mode register. */
1240 /* If this target's bit is set, do NOT check parity. */
1241 if (sc->sc_parity_disable & target_mask)
1242 *sc->sci_mode = (SCI_MODE_MONBSY);
1243 else
1244 *sc->sci_mode = (SCI_MODE_MONBSY | SCI_MODE_PAR_CHK);
1245
1246 /*
1247 * Another hack for the Sun3 "si", which needs
1248 * some setup done to its DMA engine before the
1249 * target puts the SCSI bus into any DATA phase.
1250 */
1251 if (sr->sr_dma_hand && sc->sc_dma_setup) {
1252 NCR_TRACE("reselect: call DMA setup, dh=0x%x\n",
1253 (long) sr->sr_dma_hand);
1254 sc->sc_dma_setup(sc);
1255 }
1256
1257 /* Now consume the IDENTIFY message. */
1258 ncr5380_pio_in(sc, PHASE_MSG_IN, 1, &msg);
1259 return;
1260 }
1261
1262 printf("%s: phantom reselect: target=%d, LUN=%d\n",
1263 sc->sc_dev.dv_xname, target, lun);
1264 abort:
1265 /*
1266 * Try to send an ABORT message. This makes us
1267 * temporarily busy, but no current command...
1268 */
1269 sc->sc_state |= NCR_ABORTING;
1270
1271 /* Raise ATN, delay, raise ACK... */
1272 icmd = SCI_ICMD_ATN;
1273 *sc->sci_icmd = icmd;
1274 delay(2);
1275
1276 /* Now consume the IDENTIFY message. */
1277 ncr5380_pio_in(sc, PHASE_MSG_IN, 1, &msg);
1278
1279 /* Finally try to send the ABORT. */
1280 sc->sc_prevphase = PHASE_INVALID;
1281 sc->sc_msgpriq = SEND_ABORT;
1282 ncr5380_msg_out(sc);
1283
1284 *(sc->sci_tcmd) = PHASE_INVALID;
1285 *sc->sci_sel_enb = 0;
1286 SCI_CLR_INTR(sc);
1287 *sc->sci_sel_enb = 0x80;
1288
1289 sc->sc_state &= ~NCR_ABORTING;
1290 }
1291
1292
1293 /*
1294 * Select target: xs is the transfer that we are selecting for.
1295 * sc->sc_current should be NULL.
1296 *
1297 * Returns:
1298 * sc->sc_current != NULL ==> we were reselected (race!)
1299 * XS_NOERROR ==> selection worked
1300 * XS_BUSY ==> lost arbitration
1301 * XS_SELTIMEOUT ==> no response to selection
1302 */
1303 static int
ncr5380_select(sc,sr)1304 ncr5380_select(sc, sr)
1305 struct ncr5380_softc *sc;
1306 struct sci_req *sr;
1307 {
1308 int timo, s, target_mask;
1309 u_char data, icmd;
1310
1311 /* Check for reselect */
1312 ncr5380_reselect(sc);
1313 if (sc->sc_current) {
1314 NCR_TRACE("select: reselect, cur=0x%x\n",
1315 (long) sc->sc_current);
1316 return XS_BUSY; /* reselected */
1317 }
1318
1319 /*
1320 * Set phase bits to 0, otherwise the 5380 won't drive the bus during
1321 * selection.
1322 */
1323 *sc->sci_tcmd = PHASE_DATA_OUT;
1324 *sc->sci_icmd = icmd = 0;
1325 *sc->sci_mode = 0;
1326
1327 /*
1328 * Arbitrate for the bus. The 5380 takes care of the
1329 * time-critical bus interactions. We set our ID bit
1330 * in the output data register and set MODE_ARB. The
1331 * 5380 watches for the required "bus free" period.
1332 * If and when the "bus free" period is detected, the
1333 * 5380 drives BSY, drives the data bus, and sets the
1334 * "arbitration in progress" (AIP) bit to let us know
1335 * arbitration has started (and that it asserts BSY).
1336 * We then wait for one arbitration delay (2.2uS) and
1337 * check the ICMD_LST bit, which will be set if some
1338 * other target drives SEL during arbitration.
1339 *
1340 * There is a time-critical section during the period
1341 * after we enter arbitration up until we assert SEL.
1342 * Avoid long interrupts during this period.
1343 */
1344 s = splimp(); /* XXX: Begin time-critical section */
1345
1346 *(sc->sci_odata) = 0x80; /* OUR_ID */
1347 *(sc->sci_mode) = SCI_MODE_ARB;
1348
1349 #define WAIT_AIP_USEC 20 /* pleanty of time */
1350 /* Wait for the AIP bit to turn on. */
1351 timo = WAIT_AIP_USEC;
1352 for (;;) {
1353 if (*(sc->sci_icmd) & SCI_ICMD_AIP)
1354 break;
1355 if (timo <= 0) {
1356 /*
1357 * Did not see any "bus free" period.
1358 * The usual reason is a reselection,
1359 * so treat this as arbitration loss.
1360 */
1361 NCR_TRACE("select: bus busy, rc=%d\n", XS_BUSY);
1362 goto lost_arb;
1363 }
1364 timo -= 2;
1365 delay(2);
1366 }
1367 NCR_TRACE("select: have AIP after %d uSec.\n",
1368 WAIT_AIP_USEC - timo);
1369
1370 /* Got AIP. Wait one arbitration delay (2.2 uS.) */
1371 delay(3);
1372
1373 /* Check for ICMD_LST */
1374 if (*(sc->sci_icmd) & SCI_ICMD_LST) {
1375 /* Some other target asserted SEL. */
1376 NCR_TRACE("select: lost one, rc=%d\n", XS_BUSY);
1377 goto lost_arb;
1378 }
1379
1380 /*
1381 * No other device has declared itself the winner.
1382 * The spec. says to check for higher IDs, but we
1383 * are always the highest (ID=7) so don't bother.
1384 * We can now declare victory by asserting SEL.
1385 *
1386 * Note that the 5380 is asserting BSY because we
1387 * have entered arbitration mode. We will now hold
1388 * BSY directly so we can turn off ARB mode.
1389 */
1390 icmd = (SCI_ICMD_BSY | SCI_ICMD_SEL);
1391 *sc->sci_icmd = icmd;
1392
1393 /*
1394 * "The SCSI device that wins arbitration shall wait
1395 * at least a bus clear delay plus a bus settle delay
1396 * after asserting the SEL signal before changing
1397 * any [other] signal." (1.2uS. total)
1398 */
1399 delay(2);
1400
1401 /*
1402 * Check one last time to see if we really did
1403 * win arbitration. This might only happen if
1404 * there can be a higher selection ID than ours.
1405 * Keep this code for reference anyway...
1406 */
1407 if (*(sc->sci_icmd) & SCI_ICMD_LST) {
1408 /* Some other target asserted SEL. */
1409 NCR_TRACE("select: lost two, rc=%d\n", XS_BUSY);
1410
1411 lost_arb:
1412 *sc->sci_icmd = 0;
1413 *sc->sci_mode = 0;
1414
1415 splx(s); /* XXX: End of time-critical section. */
1416
1417 /*
1418 * When we lose arbitration, it usually means
1419 * there is a target trying to reselect us.
1420 */
1421 ncr5380_reselect(sc);
1422 return XS_BUSY;
1423 }
1424
1425 /* Leave ARB mode Now that we drive BSY+SEL */
1426 *sc->sci_mode = 0;
1427 *sc->sci_sel_enb = 0;
1428
1429 splx(s); /* XXX: End of time-critical section. */
1430
1431 /*
1432 * Arbitration is complete. Now do selection:
1433 * Drive the data bus with the ID bits for both
1434 * the host and target. Also set ATN now, to
1435 * ask the target for a message out phase.
1436 */
1437 target_mask = (1 << sr->sr_target);
1438 data = 0x80 | target_mask;
1439 *(sc->sci_odata) = data;
1440 icmd |= (SCI_ICMD_DATA | SCI_ICMD_ATN);
1441 *(sc->sci_icmd) = icmd;
1442 delay(2); /* two deskew delays. */
1443
1444 /* De-assert BSY (targets sample the data now). */
1445 icmd &= ~SCI_ICMD_BSY;
1446 *(sc->sci_icmd) = icmd;
1447 delay(3); /* Bus settle delay. */
1448
1449 /*
1450 * Wait for the target to assert BSY.
1451 * SCSI spec. says wait for 250 mS.
1452 */
1453 for (timo = 25000;;) {
1454 if (*sc->sci_bus_csr & SCI_BUS_BSY)
1455 goto success;
1456 if (--timo <= 0)
1457 break;
1458 delay(10);
1459 }
1460
1461 /*
1462 * There is no reaction from the target. Start the selection
1463 * timeout procedure. We release the databus but keep SEL+ATN
1464 * asserted. After that we wait a 'selection abort time' (200
1465 * usecs) and 2 deskew delays (90 ns) and check BSY again.
1466 * When BSY is asserted, we assume the selection succeeded,
1467 * otherwise we release the bus.
1468 */
1469 icmd &= ~SCI_ICMD_DATA;
1470 *(sc->sci_icmd) = icmd;
1471 delay(201);
1472 if ((*sc->sci_bus_csr & SCI_BUS_BSY) == 0) {
1473 /* Really no device on bus */
1474 *sc->sci_tcmd = PHASE_INVALID;
1475 *sc->sci_icmd = 0;
1476 *sc->sci_mode = 0;
1477 *sc->sci_sel_enb = 0;
1478 SCI_CLR_INTR(sc);
1479 *sc->sci_sel_enb = 0x80;
1480 NCR_TRACE("select: device down, rc=%d\n", XS_SELTIMEOUT);
1481 return XS_SELTIMEOUT;
1482 }
1483
1484 success:
1485 /*
1486 * The target is now driving BSY, so we can stop
1487 * driving SEL and the data bus (keep ATN true).
1488 * Configure the ncr5380 to monitor BSY, parity.
1489 */
1490 icmd &= ~(SCI_ICMD_DATA | SCI_ICMD_SEL);
1491 *sc->sci_icmd = icmd;
1492
1493 /* If this target's bit is set, do NOT check parity. */
1494 if (sc->sc_parity_disable & target_mask)
1495 *sc->sci_mode = (SCI_MODE_MONBSY);
1496 else
1497 *sc->sci_mode = (SCI_MODE_MONBSY | SCI_MODE_PAR_CHK);
1498
1499 return XS_NOERROR;
1500 }
1501
1502
1503 /*****************************************************************
1504 * Functions to handle each info. transfer phase:
1505 *****************************************************************/
1506
1507 /*
1508 * The message system:
1509 *
1510 * This is a revamped message system that now should easier accommodate
1511 * new messages, if necessary.
1512 *
1513 * Currently we accept these messages:
1514 * IDENTIFY (when reselecting)
1515 * COMMAND COMPLETE # (expect bus free after messages marked #)
1516 * NOOP
1517 * MESSAGE REJECT
1518 * SYNCHRONOUS DATA TRANSFER REQUEST
1519 * SAVE DATA POINTER
1520 * RESTORE POINTERS
1521 * DISCONNECT #
1522 *
1523 * We may send these messages in prioritized order:
1524 * BUS DEVICE RESET # if SCSI_RESET & xs->flags (or in weird sits.)
1525 * MESSAGE PARITY ERROR par. err. during MSGI
1526 * MESSAGE REJECT If we get a message we don't know how to handle
1527 * ABORT # send on errors
1528 * INITIATOR DETECTED ERROR also on errors (SCSI2) (during info xfer)
1529 * IDENTIFY At the start of each transfer
1530 * SYNCHRONOUS DATA TRANSFER REQUEST if appropriate
1531 * NOOP if nothing else fits the bill ...
1532 */
1533
1534 #define IS1BYTEMSG(m) (((m) != 0x01 && (m) < 0x20) || (m) >= 0x80)
1535 #define IS2BYTEMSG(m) (((m) & 0xf0) == 0x20)
1536 #define ISEXTMSG(m) ((m) == 0x01)
1537
1538 /*
1539 * Precondition:
1540 * The SCSI bus is already in the MSGI phase and there is a message byte
1541 * on the bus, along with an asserted REQ signal.
1542 *
1543 * Our return value determines whether our caller, ncr5380_machine()
1544 * will expect to see another REQ (and possibly phase change).
1545 */
1546 static int
ncr5380_msg_in(sc)1547 ncr5380_msg_in(sc)
1548 register struct ncr5380_softc *sc;
1549 {
1550 struct sci_req *sr = sc->sc_current;
1551 struct scsi_xfer *xs = sr->sr_xs;
1552 int n, phase;
1553 int act_flags;
1554 register u_char icmd;
1555
1556 /* acknowledge phase change */
1557 *sc->sci_tcmd = PHASE_MSG_IN;
1558
1559 act_flags = ACT_CONTINUE;
1560 icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
1561
1562 if (sc->sc_prevphase == PHASE_MSG_IN) {
1563 /* This is a continuation of the previous message. */
1564 n = sc->sc_imp - sc->sc_imess;
1565 NCR_TRACE("msg_in: continuation, n=%d\n", n);
1566 goto nextbyte;
1567 }
1568
1569 /* This is a new MESSAGE IN phase. Clean up our state. */
1570 sc->sc_state &= ~NCR_DROP_MSGIN;
1571
1572 nextmsg:
1573 n = 0;
1574 sc->sc_imp = &sc->sc_imess[n];
1575
1576 nextbyte:
1577 /*
1578 * Read a whole message, but don't ack the last byte. If we reject the
1579 * message, we have to assert ATN during the message transfer phase
1580 * itself.
1581 */
1582 for (;;) {
1583 /*
1584 * Read a message byte.
1585 * First, check BSY, REQ, phase...
1586 */
1587 if (!SCI_BUSY(sc)) {
1588 NCR_TRACE("msg_in: lost BSY, n=%d\n", n);
1589 /* XXX - Assume the command completed? */
1590 act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
1591 return (act_flags);
1592 }
1593 if (ncr5380_wait_req(sc)) {
1594 NCR_TRACE("msg_in: BSY but no REQ, n=%d\n", n);
1595 /* Just let ncr5380_machine() handle it... */
1596 return (act_flags);
1597 }
1598 phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
1599 if (phase != PHASE_MSG_IN) {
1600 /*
1601 * Target left MESSAGE IN, probably because it
1602 * a) noticed our ATN signal, or
1603 * b) ran out of messages.
1604 */
1605 return (act_flags);
1606 }
1607 /* Still in MESSAGE IN phase, and REQ is asserted. */
1608 if (*sc->sci_csr & SCI_CSR_PERR) {
1609 ncr_sched_msgout(sc, SEND_PARITY_ERROR);
1610 sc->sc_state |= NCR_DROP_MSGIN;
1611 }
1612
1613 /* Gather incoming message bytes if needed. */
1614 if ((sc->sc_state & NCR_DROP_MSGIN) == 0) {
1615 if (n >= NCR_MAX_MSG_LEN) {
1616 ncr_sched_msgout(sc, SEND_REJECT);
1617 sc->sc_state |= NCR_DROP_MSGIN;
1618 } else {
1619 *sc->sc_imp++ = *sc->sci_data;
1620 n++;
1621 /*
1622 * This testing is suboptimal, but most
1623 * messages will be of the one byte variety, so
1624 * it should not affect performance
1625 * significantly.
1626 */
1627 if (n == 1 && IS1BYTEMSG(sc->sc_imess[0]))
1628 goto have_msg;
1629 if (n == 2 && IS2BYTEMSG(sc->sc_imess[0]))
1630 goto have_msg;
1631 if (n >= 3 && ISEXTMSG(sc->sc_imess[0]) &&
1632 n == sc->sc_imess[1] + 2)
1633 goto have_msg;
1634 }
1635 }
1636
1637 /*
1638 * If we reach this spot we're either:
1639 * a) in the middle of a multi-byte message, or
1640 * b) dropping bytes.
1641 */
1642
1643 /* Ack the last byte read. */
1644 icmd |= SCI_ICMD_ACK;
1645 *sc->sci_icmd = icmd;
1646
1647 if (ncr5380_wait_not_req(sc)) {
1648 NCR_TRACE("msg_in: drop, stuck REQ, n=%d\n", n);
1649 act_flags |= ACT_RESET_BUS;
1650 }
1651
1652 icmd &= ~SCI_ICMD_ACK;
1653 *sc->sci_icmd = icmd;
1654
1655 if (act_flags != ACT_CONTINUE)
1656 return (act_flags);
1657
1658 /* back to nextbyte */
1659 }
1660
1661 have_msg:
1662 /* We now have a complete message. Parse it. */
1663
1664 switch (sc->sc_imess[0]) {
1665 case MSG_CMDCOMPLETE:
1666 NCR_TRACE("msg_in: CMDCOMPLETE\n", 0);
1667 /* Target is about to disconnect. */
1668 act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
1669 break;
1670
1671 case MSG_PARITY_ERROR:
1672 NCR_TRACE("msg_in: PARITY_ERROR\n", 0);
1673 /* Resend the last message. */
1674 ncr_sched_msgout(sc, sc->sc_msgout);
1675 /* Reset icmd after scheduling the REJECT cmd - jwg */
1676 icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
1677 break;
1678
1679 case MSG_MESSAGE_REJECT:
1680 /* The target rejects the last message we sent. */
1681 NCR_TRACE("msg_in: got reject for 0x%x\n", sc->sc_msgout);
1682 switch (sc->sc_msgout) {
1683 case SEND_IDENTIFY:
1684 /* Really old target controller? */
1685 /* XXX ... */
1686 break;
1687 case SEND_INIT_DET_ERR:
1688 goto abort;
1689 }
1690 break;
1691
1692 case MSG_NOOP:
1693 NCR_TRACE("msg_in: NOOP\n", 0);
1694 break;
1695
1696 case MSG_DISCONNECT:
1697 NCR_TRACE("msg_in: DISCONNECT\n", 0);
1698 /* Target is about to disconnect. */
1699 act_flags |= ACT_DISCONNECT;
1700 if ((xs->sc_link->quirks & SDEV_AUTOSAVE) == 0)
1701 break;
1702 /*FALLTHROUGH*/
1703
1704 case MSG_SAVEDATAPOINTER:
1705 NCR_TRACE("msg_in: SAVE_PTRS\n", 0);
1706 sr->sr_dataptr = sc->sc_dataptr;
1707 sr->sr_datalen = sc->sc_datalen;
1708 break;
1709
1710 case MSG_RESTOREPOINTERS:
1711 NCR_TRACE("msg_in: RESTORE_PTRS\n", 0);
1712 sc->sc_dataptr = sr->sr_dataptr;
1713 sc->sc_datalen = sr->sr_datalen;
1714 break;
1715
1716 case MSG_EXTENDED:
1717 switch (sc->sc_imess[2]) {
1718 case MSG_EXT_SDTR:
1719 case MSG_EXT_WDTR:
1720 /* The ncr5380 can not do synchronous mode. */
1721 goto reject;
1722 default:
1723 printf("%s: unrecognized MESSAGE EXTENDED; sending REJECT\n",
1724 sc->sc_dev.dv_xname);
1725 NCR_BREAK();
1726 goto reject;
1727 }
1728 break;
1729
1730 default:
1731 NCR_TRACE("msg_in: eh? imsg=0x%x\n", sc->sc_imess[0]);
1732 printf("%s: unrecognized MESSAGE; sending REJECT\n",
1733 sc->sc_dev.dv_xname);
1734 NCR_BREAK();
1735 /* fallthrough */
1736 reject:
1737 ncr_sched_msgout(sc, SEND_REJECT);
1738 /* Reset icmd after scheduling the REJECT cmd - jwg */
1739 icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
1740 break;
1741
1742 abort:
1743 sc->sc_state |= NCR_ABORTING;
1744 ncr_sched_msgout(sc, SEND_ABORT);
1745 break;
1746 }
1747
1748 /* Ack the last byte read. */
1749 icmd |= SCI_ICMD_ACK;
1750 *sc->sci_icmd = icmd;
1751
1752 if (ncr5380_wait_not_req(sc)) {
1753 NCR_TRACE("msg_in: last, stuck REQ, n=%d\n", n);
1754 act_flags |= ACT_RESET_BUS;
1755 }
1756
1757 icmd &= ~SCI_ICMD_ACK;
1758 *sc->sci_icmd = icmd;
1759
1760 /* Go get the next message, if any. */
1761 if (act_flags == ACT_CONTINUE)
1762 goto nextmsg;
1763
1764 return (act_flags);
1765 }
1766
1767
1768 /*
1769 * The message out (and in) stuff is a bit complicated:
1770 * If the target requests another message (sequence) without
1771 * having changed phase in between it really asks for a
1772 * retransmit, probably due to parity error(s).
1773 * The following messages can be sent:
1774 * IDENTIFY @ These 4 stem from SCSI command activity
1775 * SDTR @
1776 * WDTR @
1777 * DEV_RESET @
1778 * REJECT if MSGI doesn't make sense
1779 * PARITY_ERROR if parity error while in MSGI
1780 * INIT_DET_ERR if parity error while not in MSGI
1781 * ABORT if INIT_DET_ERR rejected
1782 * NOOP if asked for a message and there's nothing to send
1783 *
1784 * Note that we call this one with (sc_current == NULL)
1785 * when sending ABORT for unwanted reselections.
1786 */
1787 static int
ncr5380_msg_out(sc)1788 ncr5380_msg_out(sc)
1789 register struct ncr5380_softc *sc;
1790 {
1791 struct sci_req *sr = sc->sc_current;
1792 int act_flags, n, phase, progress;
1793 register u_char icmd, msg;
1794
1795 /* acknowledge phase change */
1796 *sc->sci_tcmd = PHASE_MSG_OUT;
1797
1798 progress = 0; /* did we send any messages? */
1799 act_flags = ACT_CONTINUE;
1800
1801 /*
1802 * Set ATN. If we're just sending a trivial 1-byte message,
1803 * we'll clear ATN later on anyway. Also drive the data bus.
1804 */
1805 icmd = *sc->sci_icmd & SCI_ICMD_RMASK;
1806 icmd |= (SCI_ICMD_ATN | SCI_ICMD_DATA);
1807 *sc->sci_icmd = icmd;
1808
1809 if (sc->sc_prevphase == PHASE_MSG_OUT) {
1810 if (sc->sc_omp == sc->sc_omess) {
1811 /*
1812 * This is a retransmission.
1813 *
1814 * We get here if the target stayed in MESSAGE OUT
1815 * phase. Section 5.1.9.2 of the SCSI 2 spec indicates
1816 * that all of the previously transmitted messages must
1817 * be sent again, in the same order. Therefore, we
1818 * requeue all the previously transmitted messages, and
1819 * start again from the top. Our simple priority
1820 * scheme keeps the messages in the right order.
1821 */
1822 sc->sc_msgpriq |= sc->sc_msgoutq;
1823 NCR_TRACE("msg_out: retrans priq=0x%x\n", sc->sc_msgpriq);
1824 } else {
1825 /* This is a continuation of the previous message. */
1826 n = sc->sc_omp - sc->sc_omess;
1827 NCR_TRACE("msg_out: continuation, n=%d\n", n);
1828 goto nextbyte;
1829 }
1830 }
1831
1832 /* No messages transmitted so far. */
1833 sc->sc_msgoutq = 0;
1834
1835 nextmsg:
1836 /* Pick up highest priority message. */
1837 sc->sc_msgout = sc->sc_msgpriq & -sc->sc_msgpriq;
1838 sc->sc_msgpriq &= ~sc->sc_msgout;
1839 sc->sc_msgoutq |= sc->sc_msgout;
1840
1841 /* Build the outgoing message data. */
1842 switch (sc->sc_msgout) {
1843 case SEND_IDENTIFY:
1844 NCR_TRACE("msg_out: SEND_IDENTIFY\n", 0);
1845 if (sr == NULL) {
1846 printf("%s: SEND_IDENTIFY while not connected; sending NOOP\n",
1847 sc->sc_dev.dv_xname);
1848 NCR_BREAK();
1849 goto noop;
1850 }
1851 /*
1852 * The identify message we send determines whether
1853 * disconnect/reselect is allowed for this command.
1854 * 0xC0+LUN: allows it, 0x80+LUN disallows it.
1855 */
1856 msg = 0xc0; /* MSG_IDENTIFY(0,1) */
1857 if (sc->sc_no_disconnect & (1 << sr->sr_target))
1858 msg = 0x80;
1859 if (sr->sr_flags & (SR_IMMED | SR_SENSE))
1860 msg = 0x80;
1861 sc->sc_omess[0] = msg | sr->sr_lun;
1862 n = 1;
1863 break;
1864
1865 case SEND_DEV_RESET:
1866 NCR_TRACE("msg_out: SEND_DEV_RESET\n", 0);
1867 /* Expect disconnect after this! */
1868 /* XXX: Kill jobs for this target? */
1869 act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
1870 sc->sc_omess[0] = MSG_BUS_DEV_RESET;
1871 n = 1;
1872 break;
1873
1874 case SEND_REJECT:
1875 NCR_TRACE("msg_out: SEND_REJECT\n", 0);
1876 sc->sc_omess[0] = MSG_MESSAGE_REJECT;
1877 n = 1;
1878 break;
1879
1880 case SEND_PARITY_ERROR:
1881 NCR_TRACE("msg_out: SEND_PARITY_ERROR\n", 0);
1882 sc->sc_omess[0] = MSG_PARITY_ERROR;
1883 n = 1;
1884 break;
1885
1886 case SEND_INIT_DET_ERR:
1887 NCR_TRACE("msg_out: SEND_INIT_DET_ERR\n", 0);
1888 sc->sc_omess[0] = MSG_INITIATOR_DET_ERR;
1889 n = 1;
1890 break;
1891
1892 case SEND_ABORT:
1893 NCR_TRACE("msg_out: SEND_ABORT\n", 0);
1894 /* Expect disconnect after this! */
1895 /* XXX: Set error flag? */
1896 act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
1897 sc->sc_omess[0] = MSG_ABORT;
1898 n = 1;
1899 break;
1900
1901 case 0:
1902 printf("%s: unexpected MESSAGE OUT; sending NOOP\n",
1903 sc->sc_dev.dv_xname);
1904 NCR_BREAK();
1905 noop:
1906 NCR_TRACE("msg_out: send NOOP\n", 0);
1907 sc->sc_omess[0] = MSG_NOOP;
1908 n = 1;
1909 break;
1910
1911 default:
1912 printf("%s: weird MESSAGE OUT; sending NOOP\n",
1913 sc->sc_dev.dv_xname);
1914 NCR_BREAK();
1915 goto noop;
1916 }
1917 sc->sc_omp = &sc->sc_omess[n];
1918
1919 nextbyte:
1920 /* Send message bytes. */
1921 while (n > 0) {
1922 /*
1923 * Send a message byte.
1924 * First check BSY, REQ, phase...
1925 */
1926 if (!SCI_BUSY(sc)) {
1927 NCR_TRACE("msg_out: lost BSY, n=%d\n", n);
1928 goto out;
1929 }
1930 if (ncr5380_wait_req(sc)) {
1931 NCR_TRACE("msg_out: no REQ, n=%d\n", n);
1932 goto out;
1933 }
1934 phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
1935 if (phase != PHASE_MSG_OUT) {
1936 /*
1937 * Target left MESSAGE OUT, possibly to reject
1938 * our message.
1939 */
1940 NCR_TRACE("msg_out: new phase=%d\n", phase);
1941 goto out;
1942 }
1943
1944 /* Yes, we can send this message byte. */
1945 --n;
1946
1947 /* Clear ATN before last byte if this is the last message. */
1948 if (n == 0 && sc->sc_msgpriq == 0) {
1949 icmd &= ~SCI_ICMD_ATN;
1950 *sc->sci_icmd = icmd;
1951 /* 2 deskew delays */
1952 delay(2); /* XXX */
1953 }
1954
1955 /* Put data on the bus. */
1956 *sc->sci_odata = *--sc->sc_omp;
1957
1958 /* Raise ACK to tell target data is on the bus. */
1959 icmd |= SCI_ICMD_ACK;
1960 *sc->sci_icmd = icmd;
1961
1962 /* Wait for REQ to be negated. */
1963 if (ncr5380_wait_not_req(sc)) {
1964 NCR_TRACE("msg_out: stuck REQ, n=%d\n", n);
1965 act_flags |= ACT_RESET_BUS;
1966 }
1967
1968 /* Finally, drop ACK. */
1969 icmd &= ~SCI_ICMD_ACK;
1970 *sc->sci_icmd = icmd;
1971
1972 /* Stuck bus or something... */
1973 if (act_flags & ACT_RESET_BUS)
1974 goto out;
1975
1976 }
1977 progress++;
1978
1979 /* We get here only if the entire message has been transmitted. */
1980 if (sc->sc_msgpriq != 0) {
1981 /* There are more outgoing messages. */
1982 goto nextmsg;
1983 }
1984
1985 /*
1986 * The last message has been transmitted. We need to remember the last
1987 * message transmitted (in case the target switches to MESSAGE IN phase
1988 * and sends a MESSAGE REJECT), and the list of messages transmitted
1989 * this time around (in case the target stays in MESSAGE OUT phase to
1990 * request a retransmit).
1991 */
1992
1993 out:
1994 /* Stop driving the data bus. */
1995 icmd &= ~SCI_ICMD_DATA;
1996 *sc->sci_icmd = icmd;
1997
1998 if (!progress)
1999 act_flags |= ACT_RESET_BUS;
2000
2001 return (act_flags);
2002 }
2003
2004
2005 /*
2006 * Handle command phase.
2007 */
2008 static int
ncr5380_command(sc)2009 ncr5380_command(sc)
2010 struct ncr5380_softc *sc;
2011 {
2012 struct sci_req *sr = sc->sc_current;
2013 struct scsi_xfer *xs = sr->sr_xs;
2014 struct scsi_sense rqs;
2015 int len;
2016
2017 /* acknowledge phase change */
2018 *sc->sci_tcmd = PHASE_COMMAND;
2019
2020 if (sr->sr_flags & SR_SENSE) {
2021 rqs.opcode = REQUEST_SENSE;
2022 rqs.byte2 = xs->sc_link->lun << 5;
2023 rqs.length = sizeof(xs->sense);
2024
2025 rqs.unused[0] = rqs.unused[1] = rqs.control = 0;
2026 len = ncr5380_pio_out(sc, PHASE_COMMAND, sizeof(rqs),
2027 (u_char *)&rqs);
2028 }
2029 else {
2030 /* Assume command can be sent in one go. */
2031 /* XXX: Do this using DMA, and get a phase change intr? */
2032 len = ncr5380_pio_out(sc, PHASE_COMMAND, xs->cmdlen,
2033 (u_char *)xs->cmd);
2034 }
2035
2036 if (len != xs->cmdlen) {
2037 #ifdef NCR5380_DEBUG
2038 printf("ncr5380_command: short transfer: wanted %d got %d.\n",
2039 xs->cmdlen, len);
2040 ncr5380_show_scsi_cmd(xs);
2041 NCR_BREAK();
2042 #endif
2043 if (len < 6) {
2044 xs->error = XS_DRIVER_STUFFUP;
2045 sc->sc_state |= NCR_ABORTING;
2046 ncr_sched_msgout(sc, SEND_ABORT);
2047 }
2048
2049 }
2050
2051 return ACT_CONTINUE;
2052 }
2053
2054
2055 /*
2056 * Handle either data_in or data_out
2057 */
2058 static int
ncr5380_data_xfer(sc,phase)2059 ncr5380_data_xfer(sc, phase)
2060 struct ncr5380_softc *sc;
2061 int phase;
2062 {
2063 struct sci_req *sr = sc->sc_current;
2064 struct scsi_xfer *xs = sr->sr_xs;
2065 int expected_phase;
2066 int len;
2067
2068 if (sr->sr_flags & SR_SENSE) {
2069 NCR_TRACE("data_xfer: get sense, sr=0x%x\n", (long)sr);
2070 if (phase != PHASE_DATA_IN) {
2071 printf("%s: sense phase error\n", sc->sc_dev.dv_xname);
2072 goto abort;
2073 }
2074 /* acknowledge phase change */
2075 *sc->sci_tcmd = PHASE_DATA_IN;
2076 len = ncr5380_pio_in(sc, phase, sizeof(xs->sense),
2077 (u_char *)&xs->sense);
2078 return ACT_CONTINUE;
2079 }
2080
2081 /*
2082 * When aborting a command, disallow any data phase.
2083 */
2084 if (sc->sc_state & NCR_ABORTING) {
2085 printf("%s: aborting, but phase=%s (reset)\n",
2086 sc->sc_dev.dv_xname, phase_names[phase & 7]);
2087 return ACT_RESET_BUS; /* XXX */
2088 }
2089
2090 /* Validate expected phase (data_in or data_out) */
2091 expected_phase = (xs->flags & SCSI_DATA_OUT) ?
2092 PHASE_DATA_OUT : PHASE_DATA_IN;
2093 if (phase != expected_phase) {
2094 printf("%s: data phase error\n", sc->sc_dev.dv_xname);
2095 goto abort;
2096 }
2097
2098 /* Make sure we have some data to move. */
2099 if (sc->sc_datalen <= 0) {
2100 /* Device needs padding. */
2101 if (phase == PHASE_DATA_IN)
2102 ncr5380_pio_in(sc, phase, 4096, NULL);
2103 else
2104 ncr5380_pio_out(sc, phase, 4096, NULL);
2105 /* Make sure that caused a phase change. */
2106 if (SCI_BUS_PHASE(*sc->sci_bus_csr) == phase) {
2107 /* More than 4k is just too much! */
2108 printf("%s: too much data padding\n",
2109 sc->sc_dev.dv_xname);
2110 goto abort;
2111 }
2112 return ACT_CONTINUE;
2113 }
2114
2115 /*
2116 * Attempt DMA only if dma_alloc gave us a DMA handle AND
2117 * there is enough left to transfer so DMA is worth while.
2118 */
2119 if (sr->sr_dma_hand &&
2120 (sc->sc_datalen >= sc->sc_min_dma_len))
2121 {
2122 /*
2123 * OK, really start DMA. Note, the MD start function
2124 * is responsible for setting the TCMD register, etc.
2125 * (Acknowledge the phase change there, not here.)
2126 */
2127 NCR_TRACE("data_xfer: dma_start, dh=0x%x\n",
2128 (long) sr->sr_dma_hand);
2129 (*sc->sc_dma_start)(sc);
2130 return ACT_WAIT_DMA;
2131 }
2132
2133 /*
2134 * Doing PIO for data transfer. (Possibly "Pseudo DMA")
2135 * XXX: Do PDMA functions need to set tcmd later?
2136 */
2137 NCR_TRACE("data_xfer: doing PIO, len=%d\n", sc->sc_datalen);
2138 /* acknowledge phase change */
2139 *sc->sci_tcmd = phase; /* XXX: OK for PDMA? */
2140 if (phase == PHASE_DATA_OUT) {
2141 len = (*sc->sc_pio_out)(sc, phase, sc->sc_datalen, sc->sc_dataptr);
2142 } else {
2143 len = (*sc->sc_pio_in) (sc, phase, sc->sc_datalen, sc->sc_dataptr);
2144 }
2145 sc->sc_dataptr += len;
2146 sc->sc_datalen -= len;
2147
2148 NCR_TRACE("data_xfer: did PIO, resid=%d\n", sc->sc_datalen);
2149 return (ACT_CONTINUE);
2150
2151 abort:
2152 sc->sc_state |= NCR_ABORTING;
2153 ncr_sched_msgout(sc, SEND_ABORT);
2154 return (ACT_CONTINUE);
2155 }
2156
2157
2158 static int
ncr5380_status(sc)2159 ncr5380_status(sc)
2160 struct ncr5380_softc *sc;
2161 {
2162 int len;
2163 u_char status;
2164 struct sci_req *sr = sc->sc_current;
2165
2166 /* acknowledge phase change */
2167 *sc->sci_tcmd = PHASE_STATUS;
2168
2169 len = ncr5380_pio_in(sc, PHASE_STATUS, 1, &status);
2170 if (len) {
2171 sr->sr_status = status;
2172 } else {
2173 printf("ncr5380_status: none?\n");
2174 }
2175
2176 return ACT_CONTINUE;
2177 }
2178
2179
2180 /*
2181 * This is the big state machine that follows SCSI phase changes.
2182 * This is somewhat like a co-routine. It will do a SCSI command,
2183 * and exit if the command is complete, or if it must wait, i.e.
2184 * for DMA to complete or for reselect to resume the job.
2185 *
2186 * The bus must be selected, and we need to know which command is
2187 * being undertaken.
2188 */
2189 static void
ncr5380_machine(sc)2190 ncr5380_machine(sc)
2191 struct ncr5380_softc *sc;
2192 {
2193 struct sci_req *sr;
2194 struct scsi_xfer *xs;
2195 int act_flags, phase, timo;
2196
2197 #ifdef DIAGNOSTIC
2198 if (sc->sc_state == NCR_IDLE)
2199 panic("ncr5380_machine: state=idle");
2200 if (sc->sc_current == NULL)
2201 panic("ncr5380_machine: no current cmd");
2202 #endif
2203
2204 sr = sc->sc_current;
2205 xs = sr->sr_xs;
2206 act_flags = ACT_CONTINUE;
2207
2208 /*
2209 * This will be called by ncr5380_intr() when DMA is
2210 * complete. Must stop DMA before touching the 5380 or
2211 * there will be "register conflict" errors.
2212 */
2213 if (sc->sc_state & NCR_DOINGDMA) {
2214 /* Pick-up where where we left off... */
2215 goto dma_done;
2216 }
2217
2218 next_phase:
2219
2220 if (!SCI_BUSY(sc)) {
2221 /* Unexpected disconnect */
2222 printf("ncr5380_machine: unexpected disconnect.\n");
2223 xs->error = XS_DRIVER_STUFFUP;
2224 act_flags |= (ACT_DISCONNECT | ACT_CMD_DONE);
2225 goto do_actions;
2226 }
2227
2228 /*
2229 * Wait for REQ before reading the phase.
2230 * Need to wait longer than usual here, because
2231 * some devices are just plain slow...
2232 */
2233 timo = ncr5380_wait_phase_timo;
2234 for (;;) {
2235 if (*sc->sci_bus_csr & SCI_BUS_REQ)
2236 break;
2237 if (--timo <= 0) {
2238 if (sc->sc_state & NCR_ABORTING) {
2239 printf("%s: no REQ while aborting, reset\n",
2240 sc->sc_dev.dv_xname);
2241 act_flags |= ACT_RESET_BUS;
2242 goto do_actions;
2243 }
2244 printf("%s: no REQ for next phase, abort\n",
2245 sc->sc_dev.dv_xname);
2246 sc->sc_state |= NCR_ABORTING;
2247 ncr_sched_msgout(sc, SEND_ABORT);
2248 goto next_phase;
2249 }
2250 delay(100);
2251 }
2252
2253 phase = SCI_BUS_PHASE(*sc->sci_bus_csr);
2254 NCR_TRACE("machine: phase=%s\n",
2255 (long) phase_names[phase & 7]);
2256
2257 /*
2258 * We assume that the device knows what it's doing,
2259 * so any phase is good.
2260 */
2261
2262 #if 0
2263 /*
2264 * XXX: Do not ACK the phase yet! do it later...
2265 * XXX: ... each phase routine does that itself.
2266 * In particular, DMA needs it done LATER.
2267 */
2268 *sc->sci_tcmd = phase; /* acknowledge phase change */
2269 #endif
2270
2271 switch (phase) {
2272
2273 case PHASE_DATA_OUT:
2274 case PHASE_DATA_IN:
2275 act_flags = ncr5380_data_xfer(sc, phase);
2276 break;
2277
2278 case PHASE_COMMAND:
2279 act_flags = ncr5380_command(sc);
2280 break;
2281
2282 case PHASE_STATUS:
2283 act_flags = ncr5380_status(sc);
2284 break;
2285
2286 case PHASE_MSG_OUT:
2287 act_flags = ncr5380_msg_out(sc);
2288 break;
2289
2290 case PHASE_MSG_IN:
2291 act_flags = ncr5380_msg_in(sc);
2292 break;
2293
2294 default:
2295 printf("ncr5380_machine: Unexpected phase 0x%x\n", phase);
2296 sc->sc_state |= NCR_ABORTING;
2297 ncr_sched_msgout(sc, SEND_ABORT);
2298 goto next_phase;
2299
2300 } /* switch */
2301 sc->sc_prevphase = phase;
2302
2303 do_actions:
2304 __asm("_ncr5380_actions:");
2305
2306 if (act_flags & ACT_WAIT_DMA) {
2307 act_flags &= ~ACT_WAIT_DMA;
2308 /* Wait for DMA to complete (polling, or interrupt). */
2309 if ((sr->sr_flags & SR_IMMED) == 0) {
2310 NCR_TRACE("machine: wait for DMA intr.\n", 0);
2311 return; /* will resume at dma_done */
2312 }
2313 /* Busy-wait for it to finish. */
2314 NCR_TRACE("machine: dma_poll, dh=0x%x\n",
2315 (long) sr->sr_dma_hand);
2316 (*sc->sc_dma_poll)(sc);
2317 dma_done:
2318 /* Return here after interrupt. */
2319 if (sr->sr_flags & SR_OVERDUE)
2320 sc->sc_state |= NCR_ABORTING;
2321 NCR_TRACE("machine: dma_stop, dh=0x%x\n",
2322 (long) sr->sr_dma_hand);
2323 (*sc->sc_dma_stop)(sc);
2324 SCI_CLR_INTR(sc); /* XXX */
2325 /*
2326 * While DMA is running we can not touch the SBC,
2327 * so various places just set NCR_ABORTING and
2328 * expect us the "kick it" when DMA is done.
2329 */
2330 if (sc->sc_state & NCR_ABORTING) {
2331 ncr_sched_msgout(sc, SEND_ABORT);
2332 }
2333 }
2334
2335 /*
2336 * Check for parity error.
2337 * XXX - better place to check?
2338 */
2339 if (*(sc->sci_csr) & SCI_CSR_PERR) {
2340 printf("%s: parity error!\n", sc->sc_dev.dv_xname);
2341 /* XXX: sc->sc_state |= NCR_ABORTING; */
2342 ncr_sched_msgout(sc, SEND_PARITY_ERROR);
2343 }
2344
2345 if (act_flags == ACT_CONTINUE)
2346 goto next_phase;
2347 /* All other actions "break" from the loop. */
2348
2349 NCR_TRACE("machine: act_flags=0x%x\n", act_flags);
2350
2351 if (act_flags & ACT_RESET_BUS) {
2352 act_flags |= ACT_CMD_DONE;
2353 /*
2354 * Reset the SCSI bus, usually due to a timeout.
2355 * The error code XS_TIMEOUT allows retries.
2356 */
2357 sc->sc_state |= NCR_ABORTING;
2358 printf("%s: reset SCSI bus for TID=%d LUN=%d\n",
2359 sc->sc_dev.dv_xname, sr->sr_target, sr->sr_lun);
2360 ncr5380_reset_scsibus(sc);
2361 }
2362
2363 if (act_flags & ACT_CMD_DONE) {
2364 act_flags |= ACT_DISCONNECT;
2365 /* Need to call scsi_done() */
2366 /* XXX: from the aic6360 driver, but why? */
2367 if (sc->sc_datalen < 0) {
2368 printf("%s: %d extra bytes from %d:%d\n",
2369 sc->sc_dev.dv_xname, -sc->sc_datalen,
2370 sr->sr_target, sr->sr_lun);
2371 sc->sc_datalen = 0;
2372 }
2373 xs->resid = sc->sc_datalen;
2374 /* Note: this will clear sc_current */
2375 NCR_TRACE("machine: call done, cur=0x%x\n", (long)sr);
2376 ncr5380_done(sc);
2377 }
2378
2379 if (act_flags & ACT_DISCONNECT) {
2380 /*
2381 * The device has dropped BSY (or will soon).
2382 * We have to wait here for BSY to drop, otherwise
2383 * the next command may decide we need a bus reset.
2384 */
2385 timo = ncr5380_wait_req_timo; /* XXX */
2386 for (;;) {
2387 if (!SCI_BUSY(sc))
2388 goto busfree;
2389 if (--timo <= 0)
2390 break;
2391 delay(2);
2392 }
2393 /* Device is sitting on the bus! */
2394 printf("%s: Target %d LUN %d stuck busy, resetting...\n",
2395 sc->sc_dev.dv_xname, sr->sr_target, sr->sr_lun);
2396 ncr5380_reset_scsibus(sc);
2397 busfree:
2398 NCR_TRACE("machine: discon, waited %d\n",
2399 ncr5380_wait_req_timo - timo);
2400
2401 *sc->sci_icmd = 0;
2402 *sc->sci_mode = 0;
2403 *sc->sci_tcmd = PHASE_INVALID;
2404 *sc->sci_sel_enb = 0;
2405 SCI_CLR_INTR(sc);
2406 *sc->sci_sel_enb = 0x80;
2407
2408 if ((act_flags & ACT_CMD_DONE) == 0) {
2409 __asm("_ncr5380_disconnected:");
2410 NCR_TRACE("machine: discon, cur=0x%x\n", (long)sr);
2411 }
2412
2413 /*
2414 * We may be here due to a disconnect message,
2415 * in which case we did NOT call ncr5380_done,
2416 * and we need to clear sc_current.
2417 */
2418 sc->sc_state = NCR_IDLE;
2419 sc->sc_current = NULL;
2420
2421 /* Paranoia: clear everything. */
2422 sc->sc_dataptr = NULL;
2423 sc->sc_datalen = 0;
2424 sc->sc_prevphase = PHASE_INVALID;
2425 sc->sc_msgpriq = 0;
2426 sc->sc_msgoutq = 0;
2427 sc->sc_msgout = 0;
2428
2429 /* Our caller will re-enable interrupts. */
2430 }
2431 }
2432
2433
2434 #ifdef NCR5380_DEBUG
2435
2436 static void
ncr5380_show_scsi_cmd(xs)2437 ncr5380_show_scsi_cmd(xs)
2438 struct scsi_xfer *xs;
2439 {
2440 u_char *b = (u_char *) xs->cmd;
2441 int i = 0;
2442
2443 if ( ! ( xs->flags & SCSI_RESET ) ) {
2444 printf("si(%d:%d:%d)-",
2445 xs->sc_link->scsibus, xs->sc_link->target,
2446 xs->sc_link->lun);
2447 while (i < xs->cmdlen) {
2448 if (i) printf(",");
2449 printf("%x",b[i++]);
2450 }
2451 printf("-\n");
2452 } else {
2453 printf("si(%d:%d:%d)-RESET-\n",
2454 xs->sc_link->scsibus, xs->sc_link->target,
2455 xs->sc_link->lun);
2456 }
2457 }
2458
2459
2460 static void
ncr5380_show_sense(xs)2461 ncr5380_show_sense(xs)
2462 struct scsi_xfer *xs;
2463 {
2464 u_char *b = (u_char *)&xs->sense;
2465 int i;
2466
2467 printf("sense:");
2468 for (i = 0; i < sizeof(xs->sense); i++)
2469 printf(" %02x", b[i]);
2470 printf("\n");
2471 }
2472
2473 int ncr5380_traceidx = 0;
2474
2475 #define TRACE_MAX 1024
2476 struct trace_ent {
2477 char *msg;
2478 long val;
2479 } ncr5380_tracebuf[TRACE_MAX];
2480
2481 void
ncr5380_trace(msg,val)2482 ncr5380_trace(msg, val)
2483 char *msg;
2484 long val;
2485 {
2486 register struct trace_ent *tr;
2487 register int s;
2488
2489 s = splbio();
2490
2491 tr = &ncr5380_tracebuf[ncr5380_traceidx];
2492
2493 ncr5380_traceidx++;
2494 if (ncr5380_traceidx >= TRACE_MAX)
2495 ncr5380_traceidx = 0;
2496
2497 tr->msg = msg;
2498 tr->val = val;
2499
2500 splx(s);
2501 }
2502
2503 #ifdef DDB
2504 void
ncr5380_clear_trace()2505 ncr5380_clear_trace()
2506 {
2507 ncr5380_traceidx = 0;
2508 bzero((char *) ncr5380_tracebuf, sizeof(ncr5380_tracebuf));
2509 }
2510
2511 void
ncr5380_show_trace()2512 ncr5380_show_trace()
2513 {
2514 struct trace_ent *tr;
2515 int idx;
2516
2517 idx = ncr5380_traceidx;
2518 do {
2519 tr = &ncr5380_tracebuf[idx];
2520 idx++;
2521 if (idx >= TRACE_MAX)
2522 idx = 0;
2523 if (tr->msg)
2524 db_printf(tr->msg, tr->val);
2525 } while (idx != ncr5380_traceidx);
2526 }
2527
2528 void
ncr5380_show_req(sr)2529 ncr5380_show_req(sr)
2530 struct sci_req *sr;
2531 {
2532 struct scsi_xfer *xs = sr->sr_xs;
2533
2534 db_printf("TID=%d ", sr->sr_target);
2535 db_printf("LUN=%d ", sr->sr_lun);
2536 db_printf("dh=%p ", sr->sr_dma_hand);
2537 db_printf("dptr=%p ", sr->sr_dataptr);
2538 db_printf("dlen=0x%x ", sr->sr_datalen);
2539 db_printf("flags=%d ", sr->sr_flags);
2540 db_printf("stat=%d ", sr->sr_status);
2541
2542 if (xs == NULL) {
2543 db_printf("(xs=NULL)\n");
2544 return;
2545 }
2546 db_printf("\n");
2547 #ifdef SCSIDEBUG
2548 show_scsi_xs(xs);
2549 #else
2550 db_printf("xs=%p\n", xs);
2551 #endif
2552 }
2553
2554 void
ncr5380_show_state()2555 ncr5380_show_state()
2556 {
2557 struct ncr5380_softc *sc;
2558 struct sci_req *sr;
2559 int i, j, k;
2560
2561 sc = ncr5380_debug_sc;
2562
2563 if (sc == NULL) {
2564 db_printf("ncr5380_debug_sc == NULL\n");
2565 return;
2566 }
2567
2568 db_printf("sc_ncmds=%d\n", sc->sc_ncmds);
2569 k = -1; /* which is current? */
2570 for (i = 0; i < SCI_OPENINGS; i++) {
2571 sr = &sc->sc_ring[i];
2572 if (sr->sr_xs) {
2573 if (sr == sc->sc_current)
2574 k = i;
2575 db_printf("req %d: (sr=%p)", i, (long)sr);
2576 ncr5380_show_req(sr);
2577 }
2578 }
2579 db_printf("sc_rr=%d, current=%d\n", sc->sc_rr, k);
2580
2581 db_printf("Active request matrix:\n");
2582 for(i = 0; i < 8; i++) { /* targets */
2583 for (j = 0; j < 8; j++) { /* LUN */
2584 sr = sc->sc_matrix[i][j];
2585 if (sr) {
2586 db_printf("TID=%d LUN=%d sr=0x%x\n", i, j, (long)sr);
2587 }
2588 }
2589 }
2590
2591 db_printf("sc_state=0x%x\n", sc->sc_state);
2592 db_printf("sc_current=%p\n", sc->sc_current);
2593 db_printf("sc_dataptr=%p\n", sc->sc_dataptr);
2594 db_printf("sc_datalen=0x%x\n", sc->sc_datalen);
2595
2596 db_printf("sc_prevphase=%d\n", sc->sc_prevphase);
2597 db_printf("sc_msgpriq=0x%x\n", sc->sc_msgpriq);
2598 }
2599
2600 #endif /* DDB */
2601 #endif /* NCR5380_DEBUG */
2602