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