1/* $NetBSD: sbic.c,v 1.15 2009/05/12 06:54:10 cegger Exp $ */
2
3/*
4 * Copyright (c) 2001 Richard Earnshaw
5 * All rights reserved.
6 *
7 * 1. Redistributions of source code must retain the above copyright
8 *    notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 *    notice, this list of conditions and the following disclaimer in the
11 *    documentation and/or other materials provided with the distribution.
12 * 3. The name of the company nor the name of the author may be used to
13 *    endorse or promote products derived from this software without specific
14 *    prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
20 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
22 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
23 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
24 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * POSSIBILITY OF SUCH DAMAGE.
27 *
28 * Copyright (c) 1990 The Regents of the University of California.
29 * All rights reserved.
30 *
31 * This code is derived from software contributed to Berkeley by
32 * Van Jacobson of Lawrence Berkeley Laboratory.
33 *
34 * Redistribution and use in source and binary forms, with or without
35 * modification, are permitted provided that the following conditions
36 * are met:
37 * 1. Redistributions of source code must retain the above copyright
38 *    notice, this list of conditions and the following disclaimer.
39 * 2. Redistributions in binary form must reproduce the above copyright
40 *    notice, this list of conditions and the following disclaimer in the
41 *    documentation and/or other materials provided with the distribution.
42 * 3. Neither the name of the University nor the names of its contributors
43 *    may be used to endorse or promote products derived from this software
44 *    without specific prior written permission.
45 *
46 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
47 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
48 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
49 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
50 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
51 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
52 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
53 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
54 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
55 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
56 * SUCH DAMAGE.
57 *
58 * Copyright (c) 1994 Christian E. Hopps
59 *
60 * This code is derived from software contributed to Berkeley by
61 * Van Jacobson of Lawrence Berkeley Laboratory.
62 *
63 * Redistribution and use in source and binary forms, with or without
64 * modification, are permitted provided that the following conditions
65 * are met:
66 * 1. Redistributions of source code must retain the above copyright
67 *    notice, this list of conditions and the following disclaimer.
68 * 2. Redistributions in binary form must reproduce the above copyright
69 *    notice, this list of conditions and the following disclaimer in the
70 *    documentation and/or other materials provided with the distribution.
71 * 3. All advertising materials mentioning features or use of this software
72 *    must display the following acknowledgement:
73 *	This product includes software developed by the University of
74 *	California, Berkeley and its contributors.
75 * 4. Neither the name of the University nor the names of its contributors
76 *    may be used to endorse or promote products derived from this software
77 *    without specific prior written permission.
78 *
79 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
80 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
81 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
82 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
83 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
84 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
85 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
86 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
87 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
88 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
89 * SUCH DAMAGE.
90 *
91 *	from: sbic.c,v 1.21 1996/01/07 22:01:54
92 */
93
94/*
95 * WD 33C93 scsi adaptor driver
96 */
97
98#if 0
99/*
100 * The UPROTECTED_CSR code is bogus.  It can read the csr (SCSI Status
101 * register) at times when an interrupt may be pending.  Doing this will
102 * clear the interrupt, so we won't see it at times when we really need
103 * to.
104 */
105#define UNPROTECTED_CSR
106#endif
107
108#ifndef DEBUG
109#define DEBUG
110#endif
111/* #define SBIC_DEBUG(a) a */
112
113#include "opt_ddb.h"
114
115#include <sys/param.h>
116
117__KERNEL_RCSID(0, "$NetBSD: sbic.c,v 1.15 2009/05/12 06:54:10 cegger Exp $");
118
119#include <sys/systm.h>
120#include <sys/callout.h>
121#include <sys/kernel.h> /* For hz */
122#include <sys/device.h>
123#include <sys/buf.h>
124#include <sys/bus.h>
125
126#include <uvm/uvm_extern.h>
127
128#include <machine/intr.h>
129
130#include <dev/scsipi/scsi_all.h>
131#include <dev/scsipi/scsipi_all.h>
132#include <dev/scsipi/scsiconf.h>
133
134#include <acorn32/podulebus/sbicreg.h>
135#include <acorn32/podulebus/sbicvar.h>
136
137/*
138 * SCSI delays
139 * In u-seconds, primarily for state changes on the SPC.
140 */
141#define	SBIC_CMD_WAIT	50000	/* wait per step of 'immediate' cmds */
142#define	SBIC_DATA_WAIT	50000	/* wait per data in/out step */
143#define	SBIC_INIT_WAIT	50000	/* wait per step (both) during init */
144
145#define SBIC_WAIT(regs, until, timeo) sbicwait(regs, until, timeo, __LINE__)
146
147static int  sbicicmd		(struct sbic_softc *, int, int,
148				 struct sbic_acb *);
149static int  sbicgo		(struct sbic_softc *, struct scsipi_xfer *);
150static int  sbicwait		(sbic_regmap_p, char, int , int);
151static int  sbicselectbus	(struct sbic_softc *, sbic_regmap_p, u_char,
152				 u_char, u_char);
153static int  sbicxfstart		(sbic_regmap_p, int, u_char, int);
154static int  sbicxfout		(sbic_regmap_p regs, int, void *, int);
155static int  sbicfromscsiperiod	(struct sbic_softc *, sbic_regmap_p, int);
156static int  sbictoscsiperiod	(struct sbic_softc *, sbic_regmap_p, int);
157static int  sbicpoll		(struct sbic_softc *);
158static int  sbicnextstate	(struct sbic_softc *, u_char, u_char);
159static int  sbicmsgin		(struct sbic_softc *);
160static int  sbicxfin		(sbic_regmap_p regs, int, void *);
161static int  sbicabort		(struct sbic_softc *, sbic_regmap_p, const char *);
162static void sbicxfdone		(struct sbic_softc *, sbic_regmap_p, int);
163static void sbicerror		(struct sbic_softc *, sbic_regmap_p, u_char);
164static void sbicreset		(struct sbic_softc *);
165static void sbic_scsidone	(struct sbic_acb *, int);
166static void sbic_sched		(struct sbic_softc *);
167static void sbic_save_ptrs	(struct sbic_softc *, sbic_regmap_p);
168
169/*
170 * Synch xfer parameters, and timing conversions
171 */
172int sbic_min_period = SBIC_SYN_MIN_PERIOD;  /* in cycles = f(ICLK,FSn) */
173int sbic_max_offset = SBIC_SYN_MAX_OFFSET;  /* pure number */
174
175int sbic_cmd_wait = SBIC_CMD_WAIT;
176int sbic_data_wait = SBIC_DATA_WAIT;
177int sbic_init_wait = SBIC_INIT_WAIT;
178
179/*
180 * was broken before.. now if you want this you get it for all drives
181 * on sbic controllers.
182 */
183u_char sbic_inhibit_sync[8];
184int sbic_enable_reselect = 1;
185int sbic_clock_override = 0;
186int sbic_no_dma = 1;	/* was 0 */
187int sbic_parallel_operations = 1;
188
189#ifdef DEBUG
190sbic_regmap_p debug_sbic_regs;
191int	sbicdma_ops = 0;	/* total DMA operations */
192int     sbicdma_saves = 0;
193#define QPRINTF(a)	if (sbic_debug > 1) printf a
194#define DBGPRINTF(x,p)	if (p) printf x
195#define DBG(x)		x
196int	sbic_debug = 0;
197int	sync_debug = 0;
198int	sbic_dma_debug = 0;
199int	reselect_debug = 0;
200int	data_pointer_debug = 0;
201u_char	debug_asr, debug_csr, routine;
202
203void sbicdumpstate	(void);
204void sbictimeout	(struct sbic_softc *);
205void sbic_dump		(struct sbic_softc *);
206void sbic_dump_acb	(struct sbic_acb *);
207
208#define CSR_TRACE_SIZE 32
209#if CSR_TRACE_SIZE
210#define CSR_TRACE(w,c,a,x) do { \
211	int _s = splbio(); \
212	csr_trace[csr_traceptr].whr = (w); csr_trace[csr_traceptr].csr = (c); \
213	csr_trace[csr_traceptr].asr = (a); csr_trace[csr_traceptr].xtn = (x); \
214	csr_traceptr = (csr_traceptr + 1) & (CSR_TRACE_SIZE - 1); \
215	splx(_s); \
216} while (0)
217int csr_traceptr;
218int csr_tracesize = CSR_TRACE_SIZE;
219struct {
220	u_char whr;
221	u_char csr;
222	u_char asr;
223	u_char xtn;
224} csr_trace[CSR_TRACE_SIZE];
225#else
226#define CSR_TRACE
227#endif
228
229#define SBIC_TRACE_SIZE 0
230#if SBIC_TRACE_SIZE
231#define SBIC_TRACE(dev) do { \
232	int s = splbio(); \
233	sbic_trace[sbic_traceptr].sp = &s; \
234	sbic_trace[sbic_traceptr].line = __LINE__; \
235	sbic_trace[sbic_traceptr].sr = s; \
236	sbic_trace[sbic_traceptr].csr = csr_traceptr; \
237	sbic_traceptr = (sbic_traceptr + 1) & (SBIC_TRACE_SIZE - 1); \
238	splx(s); \
239} while (0)
240int sbic_traceptr;
241int sbic_tracesize = SBIC_TRACE_SIZE;
242struct {
243	void *sp;
244	u_short line;
245	u_short sr;
246	int csr;
247} sbic_trace[SBIC_TRACE_SIZE];
248#else
249#define SBIC_TRACE(dev)
250#endif
251
252#else
253#define QPRINTF(a)
254#define DBGPRINTF(x,p)
255#define DBG(x)
256#define CSR_TRACE
257#define SBIC_TRACE
258#endif
259
260#ifndef SBIC_DEBUG
261#define SBIC_DEBUG(x)
262#endif
263
264/*
265 * default minphys routine for sbic based controllers
266 */
267void
268sbic_minphys(struct buf *bp)
269{
270	/*
271	 * No max transfer at this level.
272	 */
273	minphys(bp);
274}
275
276/*
277 * Save DMA pointers.  Take into account partial transfer. Shut down DMA.
278 */
279static void
280sbic_save_ptrs(struct sbic_softc *dev, sbic_regmap_p regs)
281{
282	int count, asr, s;
283	struct sbic_acb* acb;
284
285	SBIC_TRACE(dev);
286	if (!(dev->sc_flags & SBICF_INDMA))
287		return; /* DMA not active */
288
289	s = splbio();
290
291	acb = dev->sc_nexus;
292	if (acb == NULL) {
293		splx(s);
294		return;
295	}
296	count = -1;
297	do {
298		GET_SBIC_asr(regs, asr);
299		if (asr & SBIC_ASR_DBR) {
300			printf("sbic_save_ptrs: asr %02x canceled!\n", asr);
301			splx(s);
302			SBIC_TRACE(dev);
303			return;
304		}
305	} while (asr & (SBIC_ASR_BSY | SBIC_ASR_CIP));
306
307	/* Save important state */
308	/* must be done before dmastop */
309	SBIC_TC_GET(regs, count);
310
311	/* Shut down DMA ====CAREFUL==== */
312	dev->sc_dmastop(dev->sc_dmah, dev->sc_dmat, acb);
313	dev->sc_flags &= ~SBICF_INDMA;
314#ifdef DIAGNOSTIC
315	{
316		int count2;
317
318		SBIC_TC_GET(regs, count2);
319		if (count2 != count)
320			panic("sbic_save_ptrs: DMA was still active(%d,%d)",
321			    count, count2);
322	}
323#endif
324	/* Note where we got to before stopping.  We need this to resume
325	   later. */
326	acb->offset += acb->sc_tcnt - count;
327	SBIC_TC_PUT(regs, 0);
328
329	DBGPRINTF(("SBIC saving tgt %d data pointers: Offset now %d ASR:%02x",
330	    dev->target, acb->offset, asr), data_pointer_debug >= 1);
331
332	acb->sc_tcnt = 0;
333
334	DBG(sbicdma_saves++);
335	splx(s);
336	SBIC_TRACE(dev);
337}
338
339/*
340 * used by specific sbic controller
341 *
342 * it appears that the higher level code does nothing with LUN's
343 * so I will too.  I could plug it in, however so could they
344 * in scsi_scsi_cmd().
345 */
346void
347sbic_scsi_request(struct scsipi_channel *chan,
348			scsipi_adapter_req_t req, void *arg)
349{
350	struct scsipi_xfer *xs;
351	struct sbic_acb *acb;
352	struct sbic_softc *dev = (void *)chan->chan_adapter->adapt_dev;
353	struct scsipi_periph *periph;
354	int flags, s, stat;
355
356	switch (req) {
357	case ADAPTER_REQ_RUN_XFER:
358		xs = arg;
359		periph = xs->xs_periph;
360		SBIC_TRACE(dev);
361		flags = xs->xs_control;
362
363		if (flags & XS_CTL_DATA_UIO)
364			panic("sbic: scsi data uio requested");
365
366		if (dev->sc_nexus && (flags & XS_CTL_POLL))
367			panic("sbic_scsicmd: busy");
368
369		s = splbio();
370		acb = dev->free_list.tqh_first;
371		if (acb)
372			TAILQ_REMOVE(&dev->free_list, acb, chain);
373		splx(s);
374
375		if (acb == NULL) {
376			DBG(printf("sbic_scsicmd: unable to queue request for "
377			    "target %d\n", periph->periph_target));
378#if defined(DDB) && defined(DEBUG)
379			Debugger();
380#endif
381			xs->error = XS_RESOURCE_SHORTAGE;
382			SBIC_TRACE(dev);
383			scsipi_done(xs);
384			return;
385		}
386
387		acb->flags = ACB_ACTIVE;
388		if (flags & XS_CTL_DATA_IN)
389			acb->flags |= ACB_DATAIN;
390		acb->xs = xs;
391		memcpy(&acb->cmd, xs->cmd, xs->cmdlen);
392		acb->clen = xs->cmdlen;
393		acb->data = xs->data;
394		acb->datalen = xs->datalen;
395
396		QPRINTF(("sbic_scsi_request: Cmd %02x (len %d), Data %p(%d)\n",
397		    (unsigned) acb->cmd.opcode, acb->clen, xs->data,
398		    xs->datalen));
399		if (flags & XS_CTL_POLL) {
400			s = splbio();
401			/*
402			 * This has major side effects -- it locks up the
403			 * machine.
404			 */
405
406			dev->sc_flags |= SBICF_ICMD;
407			do {
408				while (dev->sc_nexus)
409					sbicpoll(dev);
410				dev->sc_nexus = acb;
411				dev->sc_stat[0] = -1;
412				dev->target = periph->periph_target;
413				dev->lun = periph->periph_lun;
414				stat = sbicicmd(dev, periph->periph_target,
415				    periph->periph_lun, acb);
416			} while (dev->sc_nexus != acb);
417
418			sbic_scsidone(acb, stat);
419			splx(s);
420			SBIC_TRACE(dev);
421			return;
422		}
423
424		s = splbio();
425		TAILQ_INSERT_TAIL(&dev->ready_list, acb, chain);
426
427		if (dev->sc_nexus) {
428			splx(s);
429			SBIC_TRACE(dev);
430			return;
431		}
432
433		/*
434		 * Nothing is active, try to start it now.
435		 */
436		sbic_sched(dev);
437		splx(s);
438
439		SBIC_TRACE(dev);
440/* TODO:  add sbic_poll to do XS_CTL_POLL operations */
441		return;
442
443	case ADAPTER_REQ_GROW_RESOURCES:
444	case ADAPTER_REQ_SET_XFER_MODE:
445		/* XXX Not supported.  */
446		return;
447	}
448}
449
450/*
451 * attempt to start the next available command
452 */
453static void
454sbic_sched(struct sbic_softc *dev)
455{
456	struct scsipi_xfer *xs;
457	struct scsipi_periph *periph;
458	struct sbic_acb *acb;
459	int flags, /*phase,*/ stat, i;
460
461	SBIC_TRACE(dev);
462	if (dev->sc_nexus)
463		return;			/* a command is current active */
464
465	SBIC_TRACE(dev);
466	for (acb = dev->ready_list.tqh_first; acb; acb = acb->chain.tqe_next) {
467		periph = acb->xs->xs_periph;
468		i = periph->periph_target;
469		if (!(dev->sc_tinfo[i].lubusy & (1 << periph->periph_lun))) {
470			struct sbic_tinfo *ti = &dev->sc_tinfo[i];
471
472			TAILQ_REMOVE(&dev->ready_list, acb, chain);
473			dev->sc_nexus = acb;
474			periph = acb->xs->xs_periph;
475			ti = &dev->sc_tinfo[periph->periph_target];
476			ti->lubusy |= (1 << periph->periph_lun);
477			break;
478		}
479	}
480
481	SBIC_TRACE(dev);
482	if (acb == NULL)
483		return;			/* did not find an available command */
484
485	xs = acb->xs;
486	periph = xs->xs_periph;
487	flags = xs->xs_control;
488
489	if (flags & XS_CTL_RESET)
490		sbicreset(dev);
491
492	DBGPRINTF(("sbic_sched(%d,%d)\n", periph->periph_target,
493	    periph->periph_lun), data_pointer_debug > 1);
494	DBG(if (data_pointer_debug > 1) sbic_dump_acb(acb));
495	dev->sc_stat[0] = -1;
496	dev->target = periph->periph_target;
497	dev->lun = periph->periph_lun;
498
499	/* Decide if we can use DMA for this transfer.  */
500	if ((flags & XS_CTL_POLL) == 0
501	    && !sbic_no_dma
502	    && dev->sc_dmaok(dev->sc_dmah, dev->sc_dmat, acb))
503		acb->flags |= ACB_DMA;
504
505	if ((flags & XS_CTL_POLL) ||
506	    (!sbic_parallel_operations && (acb->flags & ACB_DMA) == 0))
507		stat = sbicicmd(dev, periph->periph_target,
508		    periph->periph_lun, acb);
509	else if (sbicgo(dev, xs) == 0 && xs->error != XS_SELTIMEOUT) {
510		SBIC_TRACE(dev);
511		return;
512	} else
513		stat = dev->sc_stat[0];
514
515	sbic_scsidone(acb, stat);
516	SBIC_TRACE(dev);
517}
518
519static void
520sbic_scsidone(struct sbic_acb *acb, int stat)
521{
522	struct scsipi_xfer *xs;
523	struct scsipi_periph *periph;
524	struct sbic_softc *dev;
525/*	int s;*/
526	int dosched = 0;
527
528	xs = acb->xs;
529	periph = xs->xs_periph;
530	dev = (void *)periph->periph_channel->chan_adapter->adapt_dev;
531	SBIC_TRACE(dev);
532#ifdef DIAGNOSTIC
533	if (acb == NULL || xs == NULL) {
534		printf("sbic_scsidone -- (%d,%d) no scsipi_xfer\n",
535		       dev->target, dev->lun);
536#ifdef DDB
537		Debugger();
538#endif
539		return;
540	}
541#endif
542
543	DBGPRINTF(("scsidone: (%d,%d)->(%d,%d)%02x acbfl=%x\n",
544	    periph->periph_target, periph->periph_lun,
545	    dev->target,  dev->lun,  stat, acb->flags),
546	    data_pointer_debug > 1);
547	DBG(if (xs->xs_periph->periph_target == dev->sc_channel.chan_id)
548	    panic("target == hostid"));
549
550	xs->status = stat;
551	xs->resid = 0;
552	if (xs->error == XS_NOERROR) {
553		if (stat == SCSI_CHECK || stat == SCSI_BUSY)
554			xs->error = XS_BUSY;
555	}
556
557	/*
558	 * Remove the ACB from whatever queue it's on.  We have to do a bit of
559	 * a hack to figure out which queue it's on.  Note that it is *not*
560	 * necessary to cdr down the ready queue, but we must cdr down the
561	 * nexus queue and see if it's there, so we can mark the unit as no
562	 * longer busy.  This code is sickening, but it works.
563	 */
564	if (acb == dev->sc_nexus) {
565		dev->sc_nexus = NULL;
566		dev->sc_tinfo[periph->periph_target].lubusy &=
567		    ~(1 << periph->periph_lun);
568		if (dev->ready_list.tqh_first)
569			dosched = 1;	/* start next command */
570	} else if (dev->ready_list.tqh_last == &acb->chain.tqe_next) {
571		TAILQ_REMOVE(&dev->ready_list, acb, chain);
572	} else {
573		register struct sbic_acb *acb2;
574		for (acb2 = dev->nexus_list.tqh_first; acb2;
575		    acb2 = acb2->chain.tqe_next) {
576			if (acb2 == acb) {
577				TAILQ_REMOVE(&dev->nexus_list, acb, chain);
578				dev->sc_tinfo[periph->periph_target].lubusy
579					&= ~(1 << periph->periph_lun);
580				break;
581			}
582		}
583		if (acb2)
584			;
585		else if (acb->chain.tqe_next) {
586			TAILQ_REMOVE(&dev->ready_list, acb, chain);
587		} else {
588			printf("%s: can't find matching acb\n",
589			    device_xname(&dev->sc_dev));
590#ifdef DDB
591			Debugger();
592#endif
593		}
594	}
595	/* Put it on the free list. */
596	acb->flags = ACB_FREE;
597	TAILQ_INSERT_HEAD(&dev->free_list, acb, chain);
598
599	dev->sc_tinfo[periph->periph_target].cmds++;
600
601	scsipi_done(xs);
602
603	if (dosched)
604		sbic_sched(dev);
605	SBIC_TRACE(dev);
606}
607
608static int
609sbicwait(sbic_regmap_p regs, char until, int timeo, int line)
610{
611	u_char val;
612	int csr;
613
614	SBIC_TRACE((struct sbic_softc *)0);
615	if (timeo == 0)
616		timeo = 1000000;	/* some large value.. */
617
618	GET_SBIC_asr(regs,val);
619	while ((val & until) == 0) {
620		if (timeo-- == 0) {
621			GET_SBIC_csr(regs, csr);
622			printf("sbicwait TIMEO @%d with asr=x%x csr=x%x\n",
623			    line, val, csr);
624#if defined(DDB) && defined(DEBUG)
625			Debugger();
626#endif
627			return val; /* Maybe I should abort */
628			break;
629		}
630		DELAY(1);
631		GET_SBIC_asr(regs,val);
632	}
633	SBIC_TRACE((struct sbic_softc *)0);
634	return val;
635}
636
637static int
638sbicabort(struct sbic_softc *dev, sbic_regmap_p regs, const char *where)
639{
640	u_char csr, asr;
641
642	GET_SBIC_asr(regs, asr);
643	GET_SBIC_csr(regs, csr);
644
645	printf ("%s: abort %s: csr = 0x%02x, asr = 0x%02x\n",
646	    device_xname(&dev->sc_dev), where, csr, asr);
647
648
649#if 0
650	/* Clean up running command */
651	if (dev->sc_nexus != NULL) {
652		dev->sc_nexus->xs->error = XS_DRIVER_STUFFUP;
653		sbic_scsidone(dev->sc_nexus, dev->sc_stat[0]);
654	}
655	while (acb = dev->nexus_list.tqh_first) {
656		acb->xs->error = XS_DRIVER_STUFFUP;
657		sbic_scsidone(acb, -1 /*acb->stat[0]*/);
658	}
659#endif
660
661	/* Clean up chip itself */
662	if (dev->sc_flags & SBICF_SELECTED) {
663		while (asr & SBIC_ASR_DBR) {
664			/* sbic is jammed w/data. need to clear it */
665			/* But we don't know what direction it needs to go */
666			GET_SBIC_data(regs, asr);
667			printf("%s: abort %s: clearing data buffer 0x%02x\n",
668			       device_xname(&dev->sc_dev), where, asr);
669			GET_SBIC_asr(regs, asr);
670			/* Not the read direction, then */
671			if (asr & SBIC_ASR_DBR)
672				SET_SBIC_data(regs, asr);
673			GET_SBIC_asr(regs, asr);
674		}
675		WAIT_CIP(regs);
676		printf("%s: sbicabort - sending ABORT command\n",
677		    device_xname(&dev->sc_dev));
678		SET_SBIC_cmd(regs, SBIC_CMD_ABORT);
679		WAIT_CIP(regs);
680
681		GET_SBIC_asr(regs, asr);
682		if (asr & (SBIC_ASR_BSY | SBIC_ASR_LCI)) {
683			/* ok, get more drastic.. */
684
685			printf("%s: sbicabort - asr %x, trying to reset\n",
686			    device_xname(&dev->sc_dev), asr);
687			sbicreset(dev);
688			dev->sc_flags &= ~SBICF_SELECTED;
689			return -1;
690		}
691		printf("%s: sbicabort - sending DISC command\n",
692		    device_xname(&dev->sc_dev));
693		SET_SBIC_cmd(regs, SBIC_CMD_DISC);
694
695		do {
696			asr = SBIC_WAIT (regs, SBIC_ASR_INT, 0);
697			GET_SBIC_csr (regs, csr);
698			CSR_TRACE('a',csr,asr,0);
699		} while ((csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1)
700		    && (csr != SBIC_CSR_CMD_INVALID));
701
702		/* lets just hope it worked.. */
703		dev->sc_flags &= ~SBICF_SELECTED;
704	}
705	return -1;
706}
707
708
709/*
710 * Initialize driver-private structures
711 */
712
713int
714sbicinit(struct sbic_softc *dev)
715{
716	sbic_regmap_p regs;
717	u_int i;
718/*	u_int my_id, s;*/
719/*	u_char csr;*/
720	struct sbic_acb *acb;
721	u_int inhibit_sync;
722
723	extern u_long scsi_nosync;
724	extern int shift_nosync;
725
726	SBIC_DEBUG(printf("sbicinit:\n"));
727
728	regs = &dev->sc_sbicp;
729
730	if ((dev->sc_flags & SBICF_ALIVE) == 0) {
731		TAILQ_INIT(&dev->ready_list);
732		TAILQ_INIT(&dev->nexus_list);
733		TAILQ_INIT(&dev->free_list);
734		callout_init(&dev->sc_timo_ch, 0);
735		dev->sc_nexus = NULL;
736		acb = dev->sc_acb;
737		memset(acb, 0, sizeof(dev->sc_acb));
738
739		SBIC_DEBUG(printf("sbicinit: %d\n", __LINE__));
740
741		for (i = 0; i < sizeof(dev->sc_acb) / sizeof(*acb); i++) {
742			TAILQ_INSERT_TAIL(&dev->free_list, acb, chain);
743			acb++;
744		}
745		memset(dev->sc_tinfo, 0, sizeof(dev->sc_tinfo));
746		/* make sure timeout is really not needed */
747		DBG(callout_reset(&dev->sc_timo_ch, 30 * hz,
748		    (void *)sbictimeout, dev));
749	} else
750		panic("sbic: reinitializing driver!");
751
752	SBIC_DEBUG(printf("sbicinit: %d\n", __LINE__));
753
754	dev->sc_flags |= SBICF_ALIVE;
755	dev->sc_flags &= ~SBICF_SELECTED;
756
757	/* initialize inhibit array */
758	if (scsi_nosync) {
759
760		SBIC_DEBUG(printf("sbicinit: %d\n", __LINE__));
761
762		inhibit_sync = (scsi_nosync >> shift_nosync) & 0xff;
763		shift_nosync += 8;
764
765		DBGPRINTF(("%s: Inhibiting synchronous transfer %02x\n",
766		    device_xname(&dev->sc_dev), inhibit_sync), inhibit_sync);
767
768		for (i = 0; i < 8; ++i)
769			if (inhibit_sync & (1 << i))
770				sbic_inhibit_sync[i] = 1;
771	}
772
773	SBIC_DEBUG(printf("sbicinit: %d\n", __LINE__));
774
775	sbicreset(dev);
776	return 0;
777}
778
779static void
780sbicreset(struct sbic_softc *dev)
781{
782	sbic_regmap_p regs;
783	u_int my_id, s;
784/*	u_int i;*/
785	u_char csr;
786/*	struct sbic_acb *acb;*/
787
788	SBIC_DEBUG(printf("sbicreset: %d\n", __LINE__));
789
790	regs = &dev->sc_sbicp;
791
792	SBIC_DEBUG(printf("sbicreset: regs = %08x\n", regs));
793
794#if 0
795	if (dev->sc_flags & SBICF_ALIVE) {
796		SET_SBIC_cmd(regs, SBIC_CMD_ABORT);
797		WAIT_CIP(regs);
798	}
799#else
800	SET_SBIC_cmd(regs, SBIC_CMD_ABORT);
801
802	SBIC_DEBUG(printf("sbicreset: %d\n", __LINE__));
803
804	WAIT_CIP(regs);
805
806	SBIC_DEBUG(printf("sbicreset: %d\n", __LINE__));
807#endif
808	s = splbio();
809	my_id = dev->sc_channel.chan_id & SBIC_ID_MASK;
810
811	/* Enable advanced mode */
812	my_id |= SBIC_ID_EAF /*| SBIC_ID_EHP*/ ;
813	SET_SBIC_myid(regs, my_id);
814
815	SBIC_DEBUG(printf("sbicreset: %d\n", __LINE__));
816
817	/*
818	 * Disable interrupts (in dmainit) then reset the chip
819	 */
820	SET_SBIC_cmd(regs, SBIC_CMD_RESET);
821	DELAY(25);
822	SBIC_WAIT(regs, SBIC_ASR_INT, 0);
823	GET_SBIC_csr(regs, csr);       /* clears interrupt also */
824
825	if (dev->sc_clkfreq < 110)
826		my_id |= SBIC_ID_FS_8_10;
827	else if (dev->sc_clkfreq < 160)
828		my_id |= SBIC_ID_FS_12_15;
829	else if (dev->sc_clkfreq < 210)
830		my_id |= SBIC_ID_FS_16_20;
831
832	SET_SBIC_myid(regs, my_id);
833
834	SBIC_DEBUG(printf("sbicreset: %d\n", __LINE__));
835
836	/*
837	 * Set up various chip parameters
838	 */
839	SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI /* | SBIC_CTL_HSP */
840	    | dev->sc_dmamode);
841	/*
842	 * don't allow (re)selection (SBIC_RID_ES)
843	 * until we can handle target mode!!
844	 */
845	SET_SBIC_rselid(regs, SBIC_RID_ER);
846	SET_SBIC_syn(regs, 0);     /* asynch for now */
847
848	/*
849	 * anything else was zeroed by reset
850	 */
851	splx(s);
852
853#if 0
854	if ((dev->sc_flags & SBICF_ALIVE) == 0) {
855		TAILQ_INIT(&dev->ready_list);
856		TAILQ_INIT(&dev->nexus_list);
857		TAILQ_INIT(&dev->free_list);
858		dev->sc_nexus = NULL;
859		acb = dev->sc_acb;
860		memset(acb, 0, sizeof(dev->sc_acb));
861		for (i = 0; i < sizeof(dev->sc_acb) / sizeof(*acb); i++) {
862			TAILQ_INSERT_TAIL(&dev->free_list, acb, chain);
863			acb++;
864		}
865		memset(dev->sc_tinfo, 0, sizeof(dev->sc_tinfo));
866	} else {
867		if (dev->sc_nexus != NULL) {
868			dev->sc_nexus->xs->error = XS_DRIVER_STUFFUP;
869			sbic_scsidone(dev->sc_nexus, dev->sc_stat[0]);
870		}
871		while (acb = dev->nexus_list.tqh_first) {
872			acb->xs->error = XS_DRIVER_STUFFUP;
873			sbic_scsidone(acb, -1 /*acb->stat[0]*/);
874		}
875	}
876
877	dev->sc_flags |= SBICF_ALIVE;
878#endif
879	dev->sc_flags &= ~SBICF_SELECTED;
880}
881
882static void
883sbicerror(struct sbic_softc *dev, sbic_regmap_p regs, u_char csr)
884{
885#ifdef DIAGNOSTIC
886	if (dev->sc_nexus == NULL)
887		panic("sbicerror");
888#endif
889	if (dev->sc_nexus->xs->xs_control & XS_CTL_SILENT)
890		return;
891
892	printf("%s: ", device_xname(&dev->sc_dev));
893	printf("csr == 0x%02x\n", csr);	/* XXX */
894}
895
896/*
897 * select the bus, return when selected or error.
898 */
899static int
900sbicselectbus(struct sbic_softc *dev, sbic_regmap_p regs, u_char target,
901    u_char lun, u_char our_addr)
902{
903	u_char asr, csr, id;
904
905	SBIC_TRACE(dev);
906	QPRINTF(("sbicselectbus %d\n", target));
907
908	/*
909	 * if we're already selected, return (XXXX panic maybe?)
910	 */
911	if (dev->sc_flags & SBICF_SELECTED) {
912		SBIC_TRACE(dev);
913		return 1;
914	}
915
916	/*
917	 * issue select
918	 */
919	SBIC_TC_PUT(regs, 0);
920	SET_SBIC_selid(regs, target);
921	SET_SBIC_timeo(regs, SBIC_TIMEOUT(250,dev->sc_clkfreq));
922
923	/*
924	 * set sync or async
925	 */
926	if (dev->sc_sync[target].state == SYNC_DONE)
927		SET_SBIC_syn(regs, SBIC_SYN (dev->sc_sync[target].offset,
928		    dev->sc_sync[target].period));
929	else
930		SET_SBIC_syn(regs, SBIC_SYN (0, sbic_min_period));
931
932	GET_SBIC_asr(regs, asr);
933	if (asr & (SBIC_ASR_INT | SBIC_ASR_BSY)) {
934		/* This means we got ourselves reselected upon */
935/*		printf("sbicselectbus: INT/BSY asr %02x\n", asr);*/
936#ifdef DDB
937/*		Debugger();*/
938#endif
939		SBIC_TRACE(dev);
940		return 1;
941	}
942
943	SET_SBIC_cmd(regs, SBIC_CMD_SEL_ATN);
944
945	/*
946	 * wait for select (merged from separate function may need
947	 * cleanup)
948	 */
949	WAIT_CIP(regs);
950	do {
951		asr = SBIC_WAIT(regs, SBIC_ASR_INT | SBIC_ASR_LCI, 0);
952		if (asr & SBIC_ASR_LCI) {
953
954			DBGPRINTF(("sbicselectbus: late LCI asr %02x\n", asr),
955			    reselect_debug);
956
957			SBIC_TRACE(dev);
958			return 1;
959		}
960		GET_SBIC_csr (regs, csr);
961		CSR_TRACE('s',csr,asr,target);
962		QPRINTF(("%02x ", csr));
963		if (csr == SBIC_CSR_RSLT_NI || csr == SBIC_CSR_RSLT_IFY) {
964
965			DBGPRINTF(("sbicselectbus: reselected asr %02x\n",
966			    asr), reselect_debug);
967
968			/* We need to handle this now so we don't lock
969			   up later */
970			sbicnextstate(dev, csr, asr);
971			SBIC_TRACE(dev);
972			return 1;
973		}
974		if (csr == SBIC_CSR_SLT || csr == SBIC_CSR_SLT_ATN) {
975			panic("sbicselectbus: target issued select!");
976			return 1;
977		}
978	} while (csr != (SBIC_CSR_MIS_2 | MESG_OUT_PHASE) &&
979	    csr != (SBIC_CSR_MIS_2 | CMD_PHASE) &&
980	    csr != SBIC_CSR_SEL_TIMEO);
981
982	/* Enable (or not) reselection */
983	if (!sbic_enable_reselect && dev->nexus_list.tqh_first == NULL)
984		SET_SBIC_rselid (regs, 0);
985	else
986		SET_SBIC_rselid (regs, SBIC_RID_ER);
987
988	if (csr == (SBIC_CSR_MIS_2 | CMD_PHASE)) {
989		dev->sc_flags |= SBICF_SELECTED;  /* device ignored ATN */
990		GET_SBIC_selid(regs, id);
991		dev->target = id;
992		GET_SBIC_tlun(regs,dev->lun);
993		if (dev->lun & SBIC_TLUN_VALID)
994			dev->lun &= SBIC_TLUN_MASK;
995		else
996			dev->lun = lun;
997	} else if (csr == (SBIC_CSR_MIS_2 | MESG_OUT_PHASE)) {
998		/*
999		 * Send identify message
1000		 * (SCSI-2 requires an identify msg (?))
1001		 */
1002		GET_SBIC_selid(regs, id);
1003		dev->target = id;
1004		GET_SBIC_tlun(regs,dev->lun);
1005		if (dev->lun & SBIC_TLUN_VALID)
1006			dev->lun &= SBIC_TLUN_MASK;
1007		else
1008			dev->lun = lun;
1009		/*
1010		 * handle drives that don't want to be asked
1011		 * whether to go sync at all.
1012		 */
1013		if (sbic_inhibit_sync[id]
1014		    && dev->sc_sync[id].state == SYNC_START) {
1015			DBGPRINTF(("Forcing target %d asynchronous.\n", id),
1016			    sync_debug);
1017
1018			dev->sc_sync[id].offset = 0;
1019			dev->sc_sync[id].period = sbic_min_period;
1020			dev->sc_sync[id].state = SYNC_DONE;
1021		}
1022
1023
1024		if (dev->sc_sync[id].state != SYNC_START){
1025			if ((dev->sc_nexus->xs->xs_control & XS_CTL_POLL)
1026			    || (dev->sc_flags & SBICF_ICMD)
1027			    || !sbic_enable_reselect)
1028				SEND_BYTE(regs, MSG_IDENTIFY | lun);
1029			else
1030				SEND_BYTE(regs, MSG_IDENTIFY_DR | lun);
1031		} else {
1032			/*
1033			 * try to initiate a sync transfer.
1034			 * So compose the sync message we're going
1035			 * to send to the target
1036			 */
1037
1038			DBGPRINTF(("Sending sync request to target %d ... ",
1039			    id), sync_debug);
1040
1041			/*
1042			 * setup scsi message sync message request
1043			 */
1044			dev->sc_msg[0] = MSG_IDENTIFY | lun;
1045			dev->sc_msg[1] = MSG_EXT_MESSAGE;
1046			dev->sc_msg[2] = 3;
1047			dev->sc_msg[3] = MSG_SYNC_REQ;
1048			dev->sc_msg[4] = sbictoscsiperiod(dev, regs,
1049			    sbic_min_period);
1050			dev->sc_msg[5] = sbic_max_offset;
1051
1052			if (sbicxfstart(regs, 6, MESG_OUT_PHASE,
1053			    sbic_cmd_wait))
1054				sbicxfout(regs, 6, dev->sc_msg,
1055				    MESG_OUT_PHASE);
1056
1057			dev->sc_sync[id].state = SYNC_SENT;
1058
1059			DBGPRINTF(("sent\n"), sync_debug);
1060		}
1061
1062		asr = SBIC_WAIT (regs, SBIC_ASR_INT, 0);
1063		GET_SBIC_csr (regs, csr);
1064		CSR_TRACE('y',csr,asr,target);
1065		QPRINTF(("[%02x]", csr));
1066
1067		DBGPRINTF(("csr-result of last msgout: 0x%x\n", csr),
1068		    sync_debug && dev->sc_sync[id].state == SYNC_SENT);
1069
1070		if (csr != SBIC_CSR_SEL_TIMEO)
1071			dev->sc_flags |= SBICF_SELECTED;
1072	}
1073	if (csr == SBIC_CSR_SEL_TIMEO)
1074		dev->sc_nexus->xs->error = XS_SELTIMEOUT;
1075
1076	QPRINTF(("\n"));
1077
1078	SBIC_TRACE(dev);
1079	return csr == SBIC_CSR_SEL_TIMEO;
1080}
1081
1082static int
1083sbicxfstart(sbic_regmap_p regs, int len, u_char phase, int wait)
1084{
1085	u_char id;
1086
1087	switch (phase) {
1088	case DATA_IN_PHASE:
1089	case MESG_IN_PHASE:
1090		GET_SBIC_selid (regs, id);
1091		id |= SBIC_SID_FROM_SCSI;
1092		SET_SBIC_selid (regs, id);
1093		SBIC_TC_PUT (regs, (unsigned)len);
1094		break;
1095	case DATA_OUT_PHASE:
1096	case MESG_OUT_PHASE:
1097	case CMD_PHASE:
1098		GET_SBIC_selid (regs, id);
1099		id &= ~SBIC_SID_FROM_SCSI;
1100		SET_SBIC_selid (regs, id);
1101		SBIC_TC_PUT (regs, (unsigned)len);
1102		break;
1103	default:
1104		SBIC_TC_PUT (regs, 0);
1105	}
1106	QPRINTF(("sbicxfstart %d, %d, %d\n", len, phase, wait));
1107
1108	return 1;
1109}
1110
1111static int
1112sbicxfout(sbic_regmap_p regs, int len, void *bp, int phase)
1113{
1114#ifdef UNPROTECTED_CSR
1115	u_char orig_csr
1116#endif
1117	u_char asr, *buf;
1118/*	u_char csr;*/
1119	int wait;
1120
1121	buf = bp;
1122	wait = sbic_data_wait;
1123
1124	QPRINTF(("sbicxfout {%d} %02x %02x %02x %02x %02x "
1125	    "%02x %02x %02x %02x %02x\n", len, buf[0], buf[1], buf[2],
1126	    buf[3], buf[4], buf[5], buf[6], buf[7], buf[8], buf[9]));
1127
1128#ifdef UNPROTECTED_CSR
1129	GET_SBIC_csr (regs, orig_csr);
1130	CSR_TRACE('>',orig_csr,0,0);
1131#endif
1132
1133	/*
1134	 * sigh.. WD-PROTO strikes again.. sending the command in one go
1135	 * causes the chip to lock up if talking to certain (misbehaving?)
1136	 * targets. Anyway, this procedure should work for all targets, but
1137	 * it's slightly slower due to the overhead
1138	 */
1139	WAIT_CIP (regs);
1140	SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO);
1141	for (;len > 0; len--) {
1142		GET_SBIC_asr (regs, asr);
1143		while ((asr & SBIC_ASR_DBR) == 0) {
1144			if ((asr & SBIC_ASR_INT) || --wait < 0) {
1145
1146				DBGPRINTF(("sbicxfout fail: l%d i%x w%d\n",
1147				    len, asr, wait), sbic_debug);
1148
1149				return len;
1150			}
1151/*			DELAY(1);*/
1152			GET_SBIC_asr (regs, asr);
1153		}
1154
1155		SET_SBIC_data (regs, *buf);
1156		buf++;
1157	}
1158	SBIC_TC_GET(regs, len);
1159	QPRINTF(("sbicxfout done %d bytes\n", len));
1160	/*
1161	 * this leaves with one csr to be read
1162	 */
1163	return 0;
1164}
1165
1166/* returns # bytes left to read */
1167static int
1168sbicxfin(sbic_regmap_p regs, int len, void *bp)
1169{
1170	int wait;
1171/*	int read;*/
1172	u_char *obp, *buf;
1173#ifdef UNPROTECTED_CSR
1174	u_char orig_csr, csr;
1175#endif
1176	u_char asr;
1177
1178	wait = sbic_data_wait;
1179	obp = bp;
1180	buf = bp;
1181
1182#ifdef UNPROTECTED_CSR
1183	GET_SBIC_csr (regs, orig_csr);
1184	CSR_TRACE('<',orig_csr,0,0);
1185
1186	QPRINTF(("sbicxfin %d, csr=%02x\n", len, orig_csr));
1187#endif
1188
1189	WAIT_CIP (regs);
1190	SET_SBIC_cmd (regs, SBIC_CMD_XFER_INFO);
1191	for (;len > 0; len--) {
1192		GET_SBIC_asr (regs, asr);
1193		if ((asr & SBIC_ASR_PE)) {
1194			DBG(printf("sbicxfin parity error: l%d i%x w%d\n",
1195			    len, asr, wait));
1196#if defined(DDB) && defined(DEBUG)
1197			Debugger();
1198#endif
1199			DBG(return ((unsigned long)buf - (unsigned long)bp));
1200		}
1201		while ((asr & SBIC_ASR_DBR) == 0) {
1202			if ((asr & SBIC_ASR_INT) || --wait < 0) {
1203
1204				DBG(if (sbic_debug) {
1205	QPRINTF(("sbicxfin fail:{%d} %02x %02x %02x %02x %02x %02x "
1206	    "%02x %02x %02x %02x\n", len, obp[0], obp[1], obp[2],
1207	    obp[3], obp[4], obp[5], obp[6], obp[7], obp[8], obp[9]));
1208	printf("sbicxfin fail: l%d i%x w%d\n", len, asr, wait); });
1209
1210				return len;
1211			}
1212
1213#ifdef UNPROTECTED_CSR
1214			if (!(asr & SBIC_ASR_BSY)) {
1215				GET_SBIC_csr(regs, csr);
1216				CSR_TRACE('<',csr,asr,len);
1217				QPRINTF(("[CSR%02xASR%02x]", csr, asr));
1218			}
1219#endif
1220
1221/*			DELAY(1);*/
1222			GET_SBIC_asr (regs, asr);
1223		}
1224
1225		GET_SBIC_data (regs, *buf);
1226/*		QPRINTF(("asr=%02x, csr=%02x, data=%02x\n", asr, csr, *buf));*/
1227		buf++;
1228	}
1229
1230	QPRINTF(("sbicxfin {%d} %02x %02x %02x %02x %02x %02x "
1231	    "%02x %02x %02x %02x\n", len, obp[0], obp[1], obp[2],
1232	    obp[3], obp[4], obp[5], obp[6], obp[7], obp[8], obp[9]));
1233
1234	/* this leaves with one csr to be read */
1235	return len;
1236}
1237
1238/*
1239 * SCSI 'immediate' command:  issue a command to some SCSI device
1240 * and get back an 'immediate' response (i.e., do programmed xfer
1241 * to get the response data).  'cbuf' is a buffer containing a scsi
1242 * command of length clen bytes.  'buf' is a buffer of length 'len'
1243 * bytes for data.  The transfer direction is determined by the device
1244 * (i.e., by the scsi bus data xfer phase).  If 'len' is zero, the
1245 * command must supply no data.
1246 */
1247static int
1248sbicicmd(struct sbic_softc *dev, int target, int lun, struct sbic_acb *acb)
1249{
1250	sbic_regmap_p regs;
1251	u_char phase, csr, asr;
1252	int wait;
1253/*	int newtarget, cmd_sent, parity_err;*/
1254
1255/*	int discon;*/
1256	int i;
1257
1258	void *cbuf, *buf;
1259	int clen, len;
1260
1261#define CSR_LOG_BUF_SIZE 0
1262#if CSR_LOG_BUF_SIZE
1263	int bufptr;
1264	int csrbuf[CSR_LOG_BUF_SIZE];
1265	bufptr = 0;
1266#endif
1267
1268	cbuf = &acb->cmd;
1269	clen = acb->clen;
1270	buf = acb->data;
1271	len = acb->datalen;
1272
1273	SBIC_TRACE(dev);
1274	regs = &dev->sc_sbicp;
1275
1276	acb->sc_tcnt = 0;
1277
1278	DBG(routine = 3);
1279	DBG(debug_sbic_regs = regs); /* store this to allow debug calls */
1280	DBGPRINTF(("sbicicmd(%d,%d):%d\n", target, lun, len),
1281	    data_pointer_debug > 1);
1282
1283	/*
1284	 * set the sbic into non-DMA mode
1285	 */
1286	SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI /*| SBIC_CTL_HSP*/);
1287
1288	dev->sc_stat[0] = 0xff;
1289	dev->sc_msg[0] = 0xff;
1290	i = 1; /* pre-load */
1291
1292	/* We're stealing the SCSI bus */
1293	dev->sc_flags |= SBICF_ICMD;
1294
1295	do {
1296		/*
1297		 * select the SCSI bus (it's an error if bus isn't free)
1298		 */
1299		if (!(dev->sc_flags & SBICF_SELECTED)
1300		    && sbicselectbus(dev, regs, target, lun,
1301			dev->sc_scsiaddr)) {
1302			/*printf("sbicicmd trying to select busy bus!\n");*/
1303			dev->sc_flags &= ~SBICF_ICMD;
1304			return -1;
1305		}
1306
1307		/*
1308		 * Wait for a phase change (or error) then let the
1309		 * device sequence us through the various SCSI phases.
1310		 */
1311
1312		wait = sbic_cmd_wait;
1313
1314		GET_SBIC_asr (regs, asr);
1315		GET_SBIC_csr (regs, csr);
1316		CSR_TRACE('I',csr,asr,target);
1317		QPRINTF((">ASR:%02xCSR:%02x<", asr, csr));
1318
1319#if CSR_LOG_BUF_SIZE
1320		csrbuf[bufptr++] = csr;
1321#endif
1322
1323
1324		switch (csr) {
1325		case SBIC_CSR_S_XFERRED:
1326		case SBIC_CSR_DISC:
1327		case SBIC_CSR_DISC_1:
1328			dev->sc_flags &= ~SBICF_SELECTED;
1329			GET_SBIC_cmd_phase (regs, phase);
1330			if (phase == 0x60) {
1331				GET_SBIC_tlun (regs, dev->sc_stat[0]);
1332				i = 0; /* done */
1333/*				break;*/ /* Bypass all the state gobldygook */
1334			} else {
1335				DBGPRINTF(("sbicicmd: handling disconnect\n"),
1336				    reselect_debug > 1);
1337
1338				i = SBIC_STATE_DISCONNECT;
1339			}
1340			break;
1341
1342		case SBIC_CSR_XFERRED | CMD_PHASE:
1343		case SBIC_CSR_MIS     | CMD_PHASE:
1344		case SBIC_CSR_MIS_1   | CMD_PHASE:
1345		case SBIC_CSR_MIS_2   | CMD_PHASE:
1346			if (sbicxfstart(regs, clen, CMD_PHASE, sbic_cmd_wait))
1347				if (sbicxfout(regs, clen,
1348					      cbuf, CMD_PHASE))
1349					i = sbicabort(dev, regs,
1350					    "icmd sending cmd");
1351#if 0
1352			GET_SBIC_csr(regs, csr); /* Lets us reload tcount */
1353			WAIT_CIP(regs);
1354			GET_SBIC_asr(regs, asr);
1355			CSR_TRACE('I',csr,asr,target);
1356			if (asr & (SBIC_ASR_BSY | SBIC_ASR_LCI | SBIC_ASR_CIP))
1357				printf("next: cmd sent asr %02x, csr %02x\n",
1358				    asr, csr);
1359#endif
1360			break;
1361
1362#if 0
1363		case SBIC_CSR_XFERRED | DATA_OUT_PHASE:
1364		case SBIC_CSR_XFERRED | DATA_IN_PHASE:
1365		case SBIC_CSR_MIS     | DATA_OUT_PHASE:
1366		case SBIC_CSR_MIS     | DATA_IN_PHASE:
1367		case SBIC_CSR_MIS_1   | DATA_OUT_PHASE:
1368		case SBIC_CSR_MIS_1   | DATA_IN_PHASE:
1369		case SBIC_CSR_MIS_2   | DATA_OUT_PHASE:
1370		case SBIC_CSR_MIS_2   | DATA_IN_PHASE:
1371			if (acb->datalen <= 0)
1372				i = sbicabort(dev, regs, "icmd out of data");
1373			else {
1374			  wait = sbic_data_wait;
1375			  if (sbicxfstart(regs, acb->datalen,
1376					  SBIC_PHASE(csr), wait))
1377			    if (csr & 0x01)
1378			      /* data in? */
1379			      i = sbicxfin(regs, acb->datalen, acb->data);
1380			    else
1381			      i = sbicxfout(regs, acb->datalen, acb->data,
1382				  SBIC_PHASE(csr));
1383			  acb->data += acb->datalen - i;
1384			  acb->datalen = i;
1385			  i = 1;
1386			}
1387			break;
1388
1389#endif
1390		case SBIC_CSR_XFERRED | STATUS_PHASE:
1391		case SBIC_CSR_MIS     | STATUS_PHASE:
1392		case SBIC_CSR_MIS_1   | STATUS_PHASE:
1393		case SBIC_CSR_MIS_2   | STATUS_PHASE:
1394			/*
1395			 * the sbic does the status/cmd-complete reading ok,
1396			 * so do this with its hi-level commands.
1397			 */
1398			DBGPRINTF(("SBICICMD status phase\n"), sbic_debug);
1399
1400			SBIC_TC_PUT(regs, 0);
1401			SET_SBIC_cmd_phase(regs, 0x46);
1402			SET_SBIC_cmd(regs, SBIC_CMD_SEL_ATN_XFER);
1403			break;
1404
1405#if THIS_IS_A_RESERVED_STATE
1406		case BUS_FREE_PHASE:		/* This is not legal */
1407			if (dev->sc_stat[0] != 0xff)
1408				goto out;
1409			break;
1410#endif
1411
1412		default:
1413			i = sbicnextstate(dev, csr, asr);
1414		}
1415
1416		/*
1417		 * make sure the last command was taken,
1418		 * ie. we're not hunting after an ignored command..
1419		 */
1420		GET_SBIC_asr(regs, asr);
1421
1422		/* tapes may take a loooong time.. */
1423		while (asr & SBIC_ASR_BSY){
1424			if (asr & SBIC_ASR_DBR) {
1425				printf("sbicicmd: Waiting while sbic is "
1426				    "jammed, CSR:%02x,ASR:%02x\n",
1427				    csr, asr);
1428#ifdef DDB
1429				Debugger();
1430#endif
1431				/* SBIC is jammed */
1432				/* DUNNO which direction */
1433				/* Try old direction */
1434				GET_SBIC_data(regs,i);
1435				GET_SBIC_asr(regs, asr);
1436				if (asr & SBIC_ASR_DBR) /* Wants us to write */
1437					SET_SBIC_data(regs,i);
1438			}
1439			GET_SBIC_asr(regs, asr);
1440		}
1441
1442		/*
1443		 * wait for last command to complete
1444		 */
1445		if (asr & SBIC_ASR_LCI) {
1446			printf("sbicicmd: last command ignored\n");
1447		}
1448		else if (i == 1) /* Bsy */
1449			SBIC_WAIT(regs, SBIC_ASR_INT, wait);
1450
1451		/*
1452		 * do it again
1453		 */
1454	} while (i > 0 && dev->sc_stat[0] == 0xff);
1455
1456	/* Sometimes we need to do an extra read of the CSR */
1457	GET_SBIC_csr(regs, csr);
1458	CSR_TRACE('I',csr,asr,0xff);
1459
1460#if CSR_LOG_BUF_SIZE
1461	if (reselect_debug > 1)
1462		for (i = 0; i < bufptr; i++)
1463			printf("CSR:%02x", csrbuf[i]);
1464#endif
1465
1466	DBGPRINTF(("sbicicmd done(%d,%d):%d =%d=\n",
1467	    dev->target, lun,
1468	    acb->datalen,
1469	    dev->sc_stat[0]),
1470	    data_pointer_debug > 1);
1471
1472	QPRINTF(("=STS:%02x=", dev->sc_stat[0]));
1473	dev->sc_flags &= ~SBICF_ICMD;
1474
1475	SBIC_TRACE(dev);
1476	return dev->sc_stat[0];
1477}
1478
1479/*
1480 * Finish SCSI xfer command:  After the completion interrupt from
1481 * a read/write operation, sequence through the final phases in
1482 * programmed i/o.  This routine is a lot like sbicicmd except we
1483 * skip (and don't allow) the select, cmd out and data in/out phases.
1484 */
1485static void
1486sbicxfdone(struct sbic_softc *dev, sbic_regmap_p regs, int target)
1487{
1488	u_char phase, asr, csr;
1489	int s;
1490
1491	SBIC_TRACE(dev);
1492	QPRINTF(("{"));
1493	s = splbio();
1494
1495	/*
1496	 * have the sbic complete on its own
1497	 */
1498	SBIC_TC_PUT(regs, 0);
1499	SET_SBIC_cmd_phase(regs, 0x46);
1500	SET_SBIC_cmd(regs, SBIC_CMD_SEL_ATN_XFER);
1501
1502	do {
1503		asr = SBIC_WAIT (regs, SBIC_ASR_INT, 0);
1504		GET_SBIC_csr (regs, csr);
1505		CSR_TRACE('f',csr,asr,target);
1506		QPRINTF(("%02x:", csr));
1507	} while ((csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1)
1508	    && (csr != SBIC_CSR_S_XFERRED));
1509
1510	dev->sc_flags &= ~SBICF_SELECTED;
1511
1512	GET_SBIC_cmd_phase (regs, phase);
1513	QPRINTF(("}%02x", phase));
1514	if (phase == 0x60)
1515		GET_SBIC_tlun(regs, dev->sc_stat[0]);
1516	else
1517		sbicerror(dev, regs, csr);
1518
1519	QPRINTF(("=STS:%02x=\n", dev->sc_stat[0]));
1520	splx(s);
1521	SBIC_TRACE(dev);
1522}
1523
1524	/*
1525	 * No DMA chains
1526	 */
1527
1528static int
1529sbicgo(struct sbic_softc *dev, struct scsipi_xfer *xs)
1530{
1531	int i, usedma;
1532/*	int dmaflags, count; */
1533/*	int wait;*/
1534/*	u_char cmd;*/
1535	u_char asr = 0, csr = 0;
1536/*	u_char *addr; */
1537	sbic_regmap_p regs;
1538	struct sbic_acb *acb;
1539
1540	SBIC_TRACE(dev);
1541	dev->target = xs->xs_periph->periph_target;
1542	dev->lun = xs->xs_periph->periph_lun;
1543	acb = dev->sc_nexus;
1544	regs = &dev->sc_sbicp;
1545
1546	usedma = acb->flags & ACB_DMA;
1547
1548	DBG(routine = 1);
1549	DBG(debug_sbic_regs = regs); /* store this to allow debug calls */
1550	DBGPRINTF(("sbicgo(%d,%d)\n", dev->target, dev->lun),
1551	    data_pointer_debug > 1);
1552
1553	/*
1554	 * set the sbic into DMA mode
1555	 */
1556	if (usedma)
1557		SET_SBIC_control(regs,
1558		    SBIC_CTL_EDI | SBIC_CTL_IDI | dev->sc_dmamode);
1559	else
1560		SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
1561
1562
1563	/*
1564	 * select the SCSI bus (it's an error if bus isn't free)
1565	 */
1566	if (sbicselectbus(dev, regs, dev->target, dev->lun,
1567	    dev->sc_scsiaddr)) {
1568/*		printf("sbicgo: Trying to select busy bus!\n"); */
1569		SBIC_TRACE(dev);
1570		/* Not done: may need to be rescheduled */
1571		return 0;
1572	}
1573	dev->sc_stat[0] = 0xff;
1574
1575	/*
1576	 * Allocate the DMA chain
1577	 */
1578
1579	/* Mark end of segment */
1580	acb->sc_tcnt = 0;
1581
1582	SBIC_TRACE(dev);
1583	/* Enable interrupts */
1584	dev->sc_enintr(dev);
1585	if (usedma) {
1586		int tcnt;
1587
1588		acb->offset = 0;
1589		acb->sc_tcnt = 0;
1590		/* Note, this does not start DMA */
1591		tcnt = dev->sc_dmasetup(dev->sc_dmah, dev->sc_dmat, acb,
1592		    (acb->flags & ACB_DATAIN) != 0);
1593
1594		DBG(dev->sc_dmatimo = tcnt ? 1 : 0);
1595		DBG(++sbicdma_ops);	/* count total DMA operations */
1596	}
1597
1598	SBIC_TRACE(dev);
1599
1600	/*
1601	 * enintr() also enables interrupts for the sbic
1602	 */
1603	DBG(debug_asr = asr);
1604	DBG(debug_csr = csr);
1605
1606	/*
1607	 * Lets cycle a while then let the interrupt handler take over
1608	 */
1609
1610	GET_SBIC_asr(regs, asr);
1611	do {
1612		GET_SBIC_csr(regs, csr);
1613		CSR_TRACE('g', csr, asr, dev->target);
1614
1615		DBG(debug_csr = csr);
1616		DBG(routine = 1);
1617
1618		QPRINTF(("go[0x%x]", csr));
1619
1620		i = sbicnextstate(dev, csr, asr);
1621
1622		WAIT_CIP(regs);
1623		GET_SBIC_asr(regs, asr);
1624
1625		DBG(debug_asr = asr);
1626
1627		if (asr & SBIC_ASR_LCI)
1628			printf("sbicgo: LCI asr:%02x csr:%02x\n", asr, csr);
1629	} while (i == SBIC_STATE_RUNNING &&
1630	    (asr & (SBIC_ASR_INT | SBIC_ASR_LCI)));
1631
1632	CSR_TRACE('g',csr,asr,i<<4);
1633	SBIC_TRACE(dev);
1634	if (i == SBIC_STATE_DONE && dev->sc_stat[0] == 0xff)
1635		printf("sbicgo: done & stat = 0xff\n");
1636	if (i == SBIC_STATE_DONE && dev->sc_stat[0] != 0xff) {
1637/*	if (i == SBIC_STATE_DONE && dev->sc_stat[0]) { */
1638		/* Did we really finish that fast? */
1639		return 1;
1640	}
1641	return 0;
1642}
1643
1644
1645int
1646sbicintr(struct sbic_softc *dev)
1647{
1648	sbic_regmap_p regs;
1649	u_char asr, csr;
1650/*	u_char *tmpaddr;*/
1651/*	struct sbic_acb *acb;*/
1652	int i;
1653/*	int newtarget, newlun;*/
1654/*	unsigned tcnt;*/
1655
1656	regs = &dev->sc_sbicp;
1657
1658	/*
1659	 * pending interrupt?
1660	 */
1661	GET_SBIC_asr (regs, asr);
1662	if ((asr & SBIC_ASR_INT) == 0)
1663		return 0;
1664
1665	SBIC_TRACE(dev);
1666	do {
1667		GET_SBIC_csr(regs, csr);
1668		CSR_TRACE('i',csr,asr,dev->target);
1669
1670		DBG(debug_csr = csr);
1671		DBG(routine = 2);
1672
1673		QPRINTF(("intr[0x%x]", csr));
1674
1675		i = sbicnextstate(dev, csr, asr);
1676
1677		WAIT_CIP(regs);
1678		GET_SBIC_asr(regs, asr);
1679
1680		DBG(debug_asr = asr);
1681
1682#if 0
1683		if (asr & SBIC_ASR_LCI)
1684			printf("sbicintr: LCI asr:%02x csr:%02x\n", asr, csr);
1685#endif
1686	} while (i == SBIC_STATE_RUNNING &&
1687	    (asr & (SBIC_ASR_INT | SBIC_ASR_LCI)));
1688	CSR_TRACE('i', csr, asr, i << 4);
1689	SBIC_TRACE(dev);
1690	return 1;
1691}
1692
1693/*
1694 * Run commands and wait for disconnect
1695 */
1696static int
1697sbicpoll(struct sbic_softc *dev)
1698{
1699	sbic_regmap_p regs;
1700	u_char asr, csr;
1701/*	struct sbic_pending* pendp;*/
1702	int i;
1703/*	unsigned tcnt;*/
1704
1705	SBIC_TRACE(dev);
1706	regs = &dev->sc_sbicp;
1707
1708	do {
1709		GET_SBIC_asr (regs, asr);
1710
1711		DBG(debug_asr = asr);
1712
1713		GET_SBIC_csr(regs, csr);
1714		CSR_TRACE('p', csr, asr, dev->target);
1715
1716		DBG(debug_csr = csr);
1717		DBG(routine = 2);
1718
1719		QPRINTF(("poll[0x%x]", csr));
1720
1721		i = sbicnextstate(dev, csr, asr);
1722
1723		WAIT_CIP(regs);
1724		GET_SBIC_asr(regs, asr);
1725		/* tapes may take a loooong time.. */
1726		while (asr & SBIC_ASR_BSY){
1727			if (asr & SBIC_ASR_DBR) {
1728				printf("sbipoll: Waiting while sbic is "
1729				    "jammed, CSR:%02x,ASR:%02x\n",
1730				    csr, asr);
1731#ifdef DDB
1732				Debugger();
1733#endif
1734				/* SBIC is jammed */
1735				/* DUNNO which direction */
1736				/* Try old direction */
1737				GET_SBIC_data(regs,i);
1738				GET_SBIC_asr(regs, asr);
1739				if (asr & SBIC_ASR_DBR) /* Wants us to write */
1740					SET_SBIC_data(regs,i);
1741			}
1742			GET_SBIC_asr(regs, asr);
1743		}
1744
1745		if (asr & SBIC_ASR_LCI)
1746			printf("sbicpoll: LCI asr:%02x csr:%02x\n", asr, csr);
1747		else if (i == 1) /* BSY */
1748			SBIC_WAIT(regs, SBIC_ASR_INT, sbic_cmd_wait);
1749	} while (i == SBIC_STATE_RUNNING);
1750	CSR_TRACE('p', csr, asr, i << 4);
1751	SBIC_TRACE(dev);
1752	return 1;
1753}
1754
1755/*
1756 * Handle a single msgin
1757 */
1758
1759static int
1760sbicmsgin(struct sbic_softc *dev)
1761{
1762	sbic_regmap_p regs;
1763	int recvlen;
1764	u_char asr, csr, *tmpaddr;
1765
1766	regs = &dev->sc_sbicp;
1767
1768	dev->sc_msg[0] = 0xff;
1769	dev->sc_msg[1] = 0xff;
1770
1771	GET_SBIC_asr(regs, asr);
1772
1773	DBGPRINTF(("sbicmsgin asr=%02x\n", asr), reselect_debug > 1);
1774
1775	sbic_save_ptrs(dev, regs);
1776
1777	GET_SBIC_selid (regs, csr);
1778	SET_SBIC_selid (regs, csr | SBIC_SID_FROM_SCSI);
1779
1780	SBIC_TC_PUT(regs, 0);
1781	tmpaddr = dev->sc_msg;
1782	recvlen = 1;
1783	do {
1784		while (recvlen--) {
1785			GET_SBIC_asr(regs, asr);
1786			GET_SBIC_csr(regs, csr);
1787			QPRINTF(("sbicmsgin ready to go (csr,asr)=(%02x,%02x)\n",
1788				 csr, asr));
1789
1790			RECV_BYTE(regs, *tmpaddr);
1791			CSR_TRACE('m', csr, asr, *tmpaddr);
1792#if 1
1793			/*
1794			 * get the command completion interrupt, or we
1795			 * can't send a new command (LCI)
1796			 */
1797			SBIC_WAIT(regs, SBIC_ASR_INT, 0);
1798			GET_SBIC_csr(regs, csr);
1799			CSR_TRACE('X', csr, asr, dev->target);
1800#else
1801			WAIT_CIP(regs);
1802			do {
1803				GET_SBIC_asr(regs, asr);
1804				csr = 0xff;
1805				GET_SBIC_csr(regs, csr);
1806				CSR_TRACE('X', csr, asr, dev->target);
1807				if (csr == 0xff)
1808					printf("sbicmsgin waiting: csr %02x "
1809					    "asr %02x\n", csr, asr);
1810			} while (csr == 0xff);
1811#endif
1812
1813			DBGPRINTF(("sbicmsgin: got %02x csr %02x asr %02x\n",
1814			    *tmpaddr, csr, asr), reselect_debug > 1);
1815
1816#if do_parity_check
1817			if (asr & SBIC_ASR_PE) {
1818				printf("Parity error");
1819				/* This code simply does not work. */
1820				WAIT_CIP(regs);
1821				SET_SBIC_cmd(regs, SBIC_CMD_SET_ATN);
1822				WAIT_CIP(regs);
1823				GET_SBIC_asr(regs, asr);
1824				WAIT_CIP(regs);
1825				SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK);
1826				WAIT_CIP(regs);
1827				if (!(asr & SBIC_ASR_LCI))
1828					/* Target wants to send garbled msg*/
1829					continue;
1830				printf("--fixing\n");
1831				/* loop until a msgout phase occurs on
1832				   target */
1833				while ((csr & 0x07) != MESG_OUT_PHASE) {
1834					while ((asr & SBIC_ASR_BSY) &&
1835					    !(asr &
1836						(SBIC_ASR_DBR | SBIC_ASR_INT)))
1837						GET_SBIC_asr(regs, asr);
1838					if (asr & SBIC_ASR_DBR)
1839						panic("msgin: jammed again!");
1840					GET_SBIC_csr(regs, csr);
1841					CSR_TRACE('e', csr, asr, dev->target);
1842					if ((csr & 0x07) != MESG_OUT_PHASE) {
1843						sbicnextstate(dev, csr, asr);
1844						sbic_save_ptrs(dev, regs);
1845					}
1846				}
1847				/* Should be msg out by now */
1848				SEND_BYTE(regs, MSG_PARITY_ERROR);
1849			}
1850			else
1851#endif
1852				tmpaddr++;
1853
1854			if (recvlen) {
1855				/* Clear ACK */
1856				WAIT_CIP(regs);
1857				GET_SBIC_asr(regs, asr);
1858				GET_SBIC_csr(regs, csr);
1859				CSR_TRACE('X',csr,asr,dev->target);
1860				QPRINTF(("sbicmsgin pre byte CLR_ACK (csr,asr)=(%02x,%02x)\n",
1861					 csr, asr));
1862				SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK);
1863				SBIC_WAIT(regs, SBIC_ASR_INT, 0);
1864			}
1865
1866		};
1867
1868		if (dev->sc_msg[0] == 0xff) {
1869			printf("sbicmsgin: sbic swallowed our message\n");
1870			break;
1871		}
1872
1873		DBGPRINTF(("msgin done csr 0x%x asr 0x%x msg 0x%x\n",
1874		    csr, asr, dev->sc_msg[0]), sync_debug);
1875
1876		/*
1877		 * test whether this is a reply to our sync
1878		 * request
1879		 */
1880		if (MSG_ISIDENTIFY(dev->sc_msg[0])) {
1881			QPRINTF(("IFFY"));
1882			/* Got IFFY msg -- ack it */
1883		} else if (dev->sc_msg[0] == MSG_REJECT
1884			   && dev->sc_sync[dev->target].state == SYNC_SENT) {
1885			QPRINTF(("REJECT of SYN"));
1886
1887			DBGPRINTF(("target %d rejected sync, going async\n",
1888			    dev->target), sync_debug);
1889
1890			dev->sc_sync[dev->target].period = sbic_min_period;
1891			dev->sc_sync[dev->target].offset = 0;
1892			dev->sc_sync[dev->target].state = SYNC_DONE;
1893			SET_SBIC_syn(regs,
1894				     SBIC_SYN(dev->sc_sync[dev->target].offset,
1895					      dev->sc_sync[dev->target].period));
1896		} else if ((dev->sc_msg[0] == MSG_REJECT)) {
1897			QPRINTF(("REJECT"));
1898			/*
1899			 * we'll never REJECt a REJECT message..
1900			 */
1901		} else if ((dev->sc_msg[0] == MSG_SAVE_DATA_PTR)) {
1902			QPRINTF(("MSG_SAVE_DATA_PTR"));
1903			/*
1904			 * don't reject this either.
1905			 */
1906		} else if ((dev->sc_msg[0] == MSG_DISCONNECT)) {
1907			QPRINTF(("DISCONNECT"));
1908
1909			DBGPRINTF(("sbicmsgin: got disconnect msg %s\n",
1910			    (dev->sc_flags & SBICF_ICMD) ? "rejecting" : ""),
1911			    reselect_debug > 1 &&
1912			    dev->sc_msg[0] == MSG_DISCONNECT);
1913
1914			if (dev->sc_flags & SBICF_ICMD) {
1915				/* We're in immediate mode. Prevent
1916                                   disconnects. */
1917				/* prepare to reject the message, NACK */
1918				SET_SBIC_cmd(regs, SBIC_CMD_SET_ATN);
1919				WAIT_CIP(regs);
1920			}
1921		} else if (dev->sc_msg[0] == MSG_CMD_COMPLETE) {
1922			QPRINTF(("CMD_COMPLETE"));
1923			/* !! KLUDGE ALERT !! quite a few drives don't seem to
1924			 * really like the current way of sending the
1925			 * sync-handshake together with the ident-message, and
1926			 * they react by sending command-complete and
1927			 * disconnecting right after returning the valid sync
1928			 * handshake. So, all I can do is reselect the drive,
1929			 * and hope it won't disconnect again. I don't think
1930			 * this is valid behavior, but I can't help fixing a
1931			 * problem that apparently exists.
1932			 *
1933			 * Note: we should not get here on `normal' command
1934			 * completion, as that condition is handled by the
1935			 * high-level sel&xfer resume command used to walk
1936			 * thru status/cc-phase.
1937			 */
1938
1939			DBGPRINTF(("GOT MSG %d! target %d acting weird.."
1940			    " waiting for disconnect...\n",
1941			    dev->sc_msg[0], dev->target), sync_debug);
1942
1943			/* Check to see if sbic is handling this */
1944			GET_SBIC_asr(regs, asr);
1945			if (asr & SBIC_ASR_BSY)
1946				return SBIC_STATE_RUNNING;
1947
1948			/* Let's try this: Assume it works and set
1949                           status to 00 */
1950			dev->sc_stat[0] = 0;
1951		} else if (dev->sc_msg[0] == MSG_EXT_MESSAGE
1952			   && tmpaddr == &dev->sc_msg[1]) {
1953			QPRINTF(("ExtMSG\n"));
1954			/* Read in whole extended message */
1955			SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK);
1956			SBIC_WAIT(regs, SBIC_ASR_INT, 0);
1957			GET_SBIC_asr(regs, asr);
1958			GET_SBIC_csr(regs, csr);
1959			QPRINTF(("CLR ACK asr %02x, csr %02x\n", asr, csr));
1960			RECV_BYTE(regs, *tmpaddr);
1961			CSR_TRACE('x',csr,asr,*tmpaddr);
1962			/* Wait for command completion IRQ */
1963			SBIC_WAIT(regs, SBIC_ASR_INT, 0);
1964			recvlen = *tmpaddr++;
1965			QPRINTF(("Recving ext msg, asr %02x csr %02x len %02x\n",
1966			       asr, csr, recvlen));
1967		} else if (dev->sc_msg[0] == MSG_EXT_MESSAGE &&
1968		    dev->sc_msg[1] == 3 &&
1969		    dev->sc_msg[2] == MSG_SYNC_REQ) {
1970			QPRINTF(("SYN"));
1971			dev->sc_sync[dev->target].period =
1972				sbicfromscsiperiod(dev,
1973						   regs, dev->sc_msg[3]);
1974			dev->sc_sync[dev->target].offset = dev->sc_msg[4];
1975			dev->sc_sync[dev->target].state = SYNC_DONE;
1976			SET_SBIC_syn(regs,
1977				     SBIC_SYN(dev->sc_sync[dev->target].offset,
1978					      dev->sc_sync[dev->target].period));
1979			printf("%s: target %d now synchronous,"
1980			       " period=%dns, offset=%d.\n",
1981			       device_xname(&dev->sc_dev), dev->target,
1982			       dev->sc_msg[3] * 4, dev->sc_msg[4]);
1983		} else {
1984
1985			DBGPRINTF(("sbicmsgin: Rejecting message 0x%02x\n",
1986			    dev->sc_msg[0]), sbic_debug || sync_debug);
1987
1988			/* prepare to reject the message, NACK */
1989			SET_SBIC_cmd(regs, SBIC_CMD_SET_ATN);
1990			WAIT_CIP(regs);
1991		}
1992		/* Clear ACK */
1993		WAIT_CIP(regs);
1994		GET_SBIC_asr(regs, asr);
1995		GET_SBIC_csr(regs, csr);
1996		CSR_TRACE('X',csr,asr,dev->target);
1997		QPRINTF(("sbicmsgin pre CLR_ACK (csr,asr)=(%02x,%02x)%d\n",
1998			 csr, asr, recvlen));
1999		SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK);
2000		SBIC_WAIT(regs, SBIC_ASR_INT, 0);
2001	}
2002#if 0
2003	while ((csr == SBIC_CSR_MSGIN_W_ACK) ||
2004	    (SBIC_PHASE(csr) == MESG_IN_PHASE));
2005#else
2006	while (recvlen > 0);
2007#endif
2008
2009	QPRINTF(("sbicmsgin finished: csr %02x, asr %02x\n",csr, asr));
2010
2011	/* Should still have one CSR to read */
2012	return SBIC_STATE_RUNNING;
2013}
2014
2015
2016/*
2017 * sbicnextstate()
2018 * return:
2019 *		0  == done
2020 *		1  == working
2021 *		2  == disconnected
2022 *		-1 == error
2023 */
2024static int
2025sbicnextstate(struct sbic_softc *dev, u_char csr, u_char asr)
2026{
2027	sbic_regmap_p regs;
2028	struct sbic_acb *acb;
2029/*	int i;*/
2030	int newtarget, newlun, wait;
2031/*	unsigned tcnt;*/
2032
2033	SBIC_TRACE(dev);
2034	regs = &dev->sc_sbicp;
2035	acb = dev->sc_nexus;
2036
2037	QPRINTF(("next[%02x,%02x]",asr,csr));
2038
2039	switch (csr) {
2040	case SBIC_CSR_XFERRED | CMD_PHASE:
2041	case SBIC_CSR_MIS     | CMD_PHASE:
2042	case SBIC_CSR_MIS_1   | CMD_PHASE:
2043	case SBIC_CSR_MIS_2   | CMD_PHASE:
2044		sbic_save_ptrs(dev, regs);
2045		if (sbicxfstart(regs, acb->clen, CMD_PHASE, sbic_cmd_wait))
2046			if (sbicxfout(regs, acb->clen,
2047				      &acb->cmd, CMD_PHASE))
2048				goto abort;
2049		break;
2050
2051	case SBIC_CSR_XFERRED | STATUS_PHASE:
2052	case SBIC_CSR_MIS     | STATUS_PHASE:
2053	case SBIC_CSR_MIS_1   | STATUS_PHASE:
2054	case SBIC_CSR_MIS_2   | STATUS_PHASE:
2055		/*
2056		 * this should be the normal i/o completion case.
2057		 * get the status & cmd complete msg then let the
2058		 * device driver look at what happened.
2059		 */
2060		sbicxfdone(dev,regs,dev->target);
2061
2062		if (acb->flags & ACB_DMA) {
2063			DBG(dev->sc_dmatimo = 0);
2064
2065			dev->sc_dmafinish(dev->sc_dmah, dev->sc_dmat, acb);
2066
2067			dev->sc_flags &= ~SBICF_INDMA;
2068		}
2069		sbic_scsidone(acb, dev->sc_stat[0]);
2070		SBIC_TRACE(dev);
2071		return SBIC_STATE_DONE;
2072
2073	case SBIC_CSR_XFERRED | DATA_OUT_PHASE:
2074	case SBIC_CSR_XFERRED | DATA_IN_PHASE:
2075	case SBIC_CSR_MIS     | DATA_OUT_PHASE:
2076	case SBIC_CSR_MIS     | DATA_IN_PHASE:
2077	case SBIC_CSR_MIS_1   | DATA_OUT_PHASE:
2078	case SBIC_CSR_MIS_1   | DATA_IN_PHASE:
2079	case SBIC_CSR_MIS_2   | DATA_OUT_PHASE:
2080	case SBIC_CSR_MIS_2   | DATA_IN_PHASE:
2081	{
2082		int i = 0;
2083
2084		if ((acb->xs->xs_control & XS_CTL_POLL) ||
2085		    (dev->sc_flags & SBICF_ICMD) ||
2086		    (acb->flags & ACB_DMA) == 0) {
2087			/* Do PIO */
2088			SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
2089			if (acb->datalen <= 0) {
2090				printf("sbicnextstate:xfer count %d asr%x csr%x\n",
2091				    acb->datalen, asr, csr);
2092				goto abort;
2093			}
2094			wait = sbic_data_wait;
2095			if (sbicxfstart(regs, acb->datalen,
2096			    SBIC_PHASE(csr), wait)) {
2097				if (SBIC_PHASE(csr) == DATA_IN_PHASE)
2098					/* data in? */
2099					i = sbicxfin(regs, acb->datalen,
2100					    acb->data);
2101				else
2102					i = sbicxfout(regs, acb->datalen,
2103					    acb->data, SBIC_PHASE(csr));
2104			}
2105			acb->data += acb->datalen - i;
2106			acb->datalen = i;
2107		} else {
2108			/* Transfer = using DMA */
2109			/*
2110			 * do scatter-gather dma
2111			 * hacking the controller chip, ouch..
2112			 */
2113			SET_SBIC_control(regs,
2114			    SBIC_CTL_EDI | SBIC_CTL_IDI | dev->sc_dmamode);
2115			/*
2116			 * set next dma addr and dec count
2117			 */
2118			sbic_save_ptrs(dev, regs);
2119
2120			if (acb->offset >= acb->datalen) {
2121				printf("sbicnextstate:xfer offset %d asr%x csr%x\n",
2122				    acb->offset, asr, csr);
2123				goto abort;
2124			}
2125			DBGPRINTF(("next dmanext: %d(offset %d)\n",
2126			    dev->target, acb->offset),
2127			    data_pointer_debug > 1);
2128			DBG(dev->sc_dmatimo = 1);
2129
2130			acb->sc_tcnt =
2131			    dev->sc_dmanext(dev->sc_dmah, dev->sc_dmat,
2132				acb, acb->offset);
2133			DBGPRINTF(("dmanext transfering %ld bytes\n",
2134			    acb->sc_tcnt), data_pointer_debug);
2135			SBIC_TC_PUT(regs, (unsigned)acb->sc_tcnt);
2136			SET_SBIC_cmd(regs, SBIC_CMD_XFER_INFO);
2137			dev->sc_flags |= SBICF_INDMA;
2138		}
2139		break;
2140	}
2141	case SBIC_CSR_XFERRED | MESG_IN_PHASE:
2142	case SBIC_CSR_MIS     | MESG_IN_PHASE:
2143	case SBIC_CSR_MIS_1   | MESG_IN_PHASE:
2144	case SBIC_CSR_MIS_2   | MESG_IN_PHASE:
2145		SBIC_TRACE(dev);
2146		return sbicmsgin(dev);
2147
2148	case SBIC_CSR_MSGIN_W_ACK:
2149		/* Dunno what I'm ACKing */
2150		SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK);
2151		printf("Acking unknown msgin CSR:%02x",csr);
2152		break;
2153
2154	case SBIC_CSR_XFERRED | MESG_OUT_PHASE:
2155	case SBIC_CSR_MIS     | MESG_OUT_PHASE:
2156	case SBIC_CSR_MIS_1   | MESG_OUT_PHASE:
2157	case SBIC_CSR_MIS_2   | MESG_OUT_PHASE:
2158
2159		DBGPRINTF(("sending REJECT msg to last msg.\n"), sync_debug);
2160
2161		sbic_save_ptrs(dev, regs);
2162		/*
2163		 * Should only get here on reject, since it's always
2164		 * US that initiate a sync transfer.
2165		 */
2166		SEND_BYTE(regs, MSG_REJECT);
2167		WAIT_CIP(regs);
2168		if (asr & (SBIC_ASR_BSY | SBIC_ASR_LCI | SBIC_ASR_CIP))
2169			printf("next: REJECT sent asr %02x\n", asr);
2170		SBIC_TRACE(dev);
2171		return SBIC_STATE_RUNNING;
2172
2173	case SBIC_CSR_DISC:
2174	case SBIC_CSR_DISC_1:
2175		dev->sc_flags &= ~(SBICF_INDMA | SBICF_SELECTED);
2176
2177		/* Try to schedule another target */
2178		DBGPRINTF(("sbicnext target %d disconnected\n", dev->target),
2179		    reselect_debug > 1);
2180
2181		TAILQ_INSERT_HEAD(&dev->nexus_list, acb, chain);
2182		++dev->sc_tinfo[dev->target].dconns;
2183		dev->sc_nexus = NULL;
2184
2185		if ((acb->xs->xs_control & XS_CTL_POLL)
2186		    || (dev->sc_flags & SBICF_ICMD)
2187		    || (!sbic_parallel_operations)) {
2188			SBIC_TRACE(dev);
2189			return SBIC_STATE_DISCONNECT;
2190		}
2191		sbic_sched(dev);
2192		SBIC_TRACE(dev);
2193		return SBIC_STATE_DISCONNECT;
2194
2195	case SBIC_CSR_RSLT_NI:
2196	case SBIC_CSR_RSLT_IFY:
2197		GET_SBIC_rselid(regs, newtarget);
2198		/* check SBIC_RID_SIV? */
2199		newtarget &= SBIC_RID_MASK;
2200		if (csr == SBIC_CSR_RSLT_IFY) {
2201			/* Read IFY msg to avoid lockup */
2202			GET_SBIC_data(regs, newlun);
2203			WAIT_CIP(regs);
2204			newlun &= SBIC_TLUN_MASK;
2205			CSR_TRACE('r',csr,asr,newtarget);
2206		} else {
2207			/* Need to get IFY message */
2208			for (newlun = 256; newlun; --newlun) {
2209				GET_SBIC_asr(regs, asr);
2210				if (asr & SBIC_ASR_INT)
2211					break;
2212				delay(1);
2213			}
2214			newlun = 0;	/* XXXX */
2215			if ((asr & SBIC_ASR_INT) == 0) {
2216
2217				DBGPRINTF(("RSLT_NI - no IFFY message? asr %x\n",
2218				    asr), reselect_debug);
2219
2220			} else {
2221				GET_SBIC_csr(regs,csr);
2222				CSR_TRACE('n',csr,asr,newtarget);
2223				if ((csr == (SBIC_CSR_MIS | MESG_IN_PHASE)) ||
2224				    (csr == (SBIC_CSR_MIS_1 | MESG_IN_PHASE)) ||
2225				    (csr == (SBIC_CSR_MIS_2 | MESG_IN_PHASE))) {
2226					sbicmsgin(dev);
2227					newlun = dev->sc_msg[0] & 7;
2228				} else {
2229					printf("RSLT_NI - not MESG_IN_PHASE %x\n",
2230					    csr);
2231				}
2232			}
2233		}
2234
2235		DBGPRINTF(("sbicnext: reselect %s from targ %d lun %d\n",
2236		    csr == SBIC_CSR_RSLT_NI ? "NI" : "IFY",
2237		    newtarget, newlun),
2238		    reselect_debug > 1 ||
2239		    (reselect_debug && csr == SBIC_CSR_RSLT_NI));
2240
2241		if (dev->sc_nexus) {
2242			DBGPRINTF(("%s: reselect %s with active command\n",
2243			    device_xname(&dev->sc_dev),
2244			    csr == SBIC_CSR_RSLT_NI ? "NI" : "IFY"),
2245			    reselect_debug > 1);
2246#if defined(DDB) && defined (DEBUG)
2247/*			Debugger();*/
2248#endif
2249
2250			TAILQ_INSERT_HEAD(&dev->ready_list, dev->sc_nexus,
2251			    chain);
2252			dev->sc_tinfo[dev->target].lubusy &= ~(1 << dev->lun);
2253			dev->sc_nexus = NULL;
2254		}
2255		/* Reload sync values for this target */
2256		if (dev->sc_sync[newtarget].state == SYNC_DONE)
2257			SET_SBIC_syn(regs,
2258			    SBIC_SYN(dev->sc_sync[newtarget].offset,
2259				dev->sc_sync[newtarget].period));
2260		else
2261			SET_SBIC_syn(regs, SBIC_SYN (0, sbic_min_period));
2262		for (acb = dev->nexus_list.tqh_first; acb;
2263		    acb = acb->chain.tqe_next) {
2264			if (acb->xs->xs_periph->periph_target != newtarget ||
2265			    acb->xs->xs_periph->periph_lun != newlun)
2266				continue;
2267			TAILQ_REMOVE(&dev->nexus_list, acb, chain);
2268			dev->sc_nexus = acb;
2269			dev->sc_flags |= SBICF_SELECTED;
2270			dev->target = newtarget;
2271			dev->lun = newlun;
2272			break;
2273		}
2274		if (acb == NULL) {
2275			printf("%s: reselect %s targ %d not in nexus_list %p\n",
2276			    device_xname(&dev->sc_dev),
2277			    csr == SBIC_CSR_RSLT_NI ? "NI" : "IFY", newtarget,
2278			    &dev->nexus_list.tqh_first);
2279			panic("bad reselect in sbic");
2280		}
2281		if (csr == SBIC_CSR_RSLT_IFY)
2282			SET_SBIC_cmd(regs, SBIC_CMD_CLR_ACK);
2283		break;
2284
2285	default:
2286        abort:
2287		/*
2288		 * Something unexpected happened -- deal with it.
2289		 */
2290		printf("sbicnextstate: aborting csr %02x asr %02x\n", csr,
2291		    asr);
2292#ifdef DDB
2293		Debugger();
2294#endif
2295		DBG(dev->sc_dmatimo = 0);
2296
2297		if (dev->sc_flags & SBICF_INDMA) {
2298			dev->sc_dmafinish(dev->sc_dmah, dev->sc_dmat, acb);
2299			dev->sc_flags &= ~SBICF_INDMA;
2300			DBG(dev->sc_dmatimo = 0);
2301		}
2302		SET_SBIC_control(regs, SBIC_CTL_EDI | SBIC_CTL_IDI);
2303		sbicerror(dev, regs, csr);
2304		sbicabort(dev, regs, "next");
2305		sbic_scsidone(acb, -1);
2306		SBIC_TRACE(dev);
2307                return SBIC_STATE_ERROR;
2308	}
2309
2310	SBIC_TRACE(dev);
2311	return SBIC_STATE_RUNNING;
2312}
2313
2314static int
2315sbictoscsiperiod(struct sbic_softc *dev, sbic_regmap_p regs, int a)
2316{
2317	unsigned int fs;
2318
2319	/*
2320	 * cycle = DIV / (2*CLK)
2321	 * DIV = FS+2
2322	 * best we can do is 200ns at 20 MHz, 2 cycles
2323	 */
2324
2325	GET_SBIC_myid(regs,fs);
2326	fs = (fs >> 6) + 2;		/* DIV */
2327	fs = (fs * 10000) / (dev->sc_clkfreq << 1);	/* Cycle, in ns */
2328	if (a < 2)
2329		a = 8;		/* map to Cycles */
2330	return (fs * a) >> 2;		/* in 4 ns units */
2331}
2332
2333static int
2334sbicfromscsiperiod(struct sbic_softc *dev, sbic_regmap_p regs, int p)
2335{
2336	register unsigned int fs, ret;
2337
2338	/* Just the inverse of the above */
2339
2340	GET_SBIC_myid(regs, fs);
2341	fs = (fs >> 6) + 2;		/* DIV */
2342	fs = (fs * 10000) / (dev->sc_clkfreq << 1);   /* Cycle, in ns */
2343
2344	ret = p << 2;			/* in ns units */
2345	ret = ret / fs;			/* in Cycles */
2346	if (ret < sbic_min_period)
2347		return sbic_min_period;
2348
2349	/* verify rounding */
2350	if (sbictoscsiperiod(dev, regs, ret) < p)
2351		ret++;
2352	return (ret >= 8) ? 0 : ret;
2353}
2354
2355#ifdef DEBUG
2356
2357void
2358sbicdumpstate(void)
2359{
2360	u_char csr, asr;
2361
2362	GET_SBIC_asr(debug_sbic_regs,asr);
2363	GET_SBIC_csr(debug_sbic_regs,csr);
2364	printf("%s: asr:csr(%02x:%02x)->(%02x:%02x)\n",
2365	    (routine == 1) ? "sbicgo" :
2366	    (routine == 2) ? "sbicintr" :
2367	    (routine == 3) ? "sbicicmd" :
2368	    (routine == 4) ? "sbicnext" : "unknown",
2369	    debug_asr, debug_csr, asr, csr);
2370
2371}
2372
2373void
2374sbictimeout(struct sbic_softc *dev)
2375{
2376	int s, asr;
2377
2378	s = splbio();
2379	if (dev->sc_dmatimo) {
2380		if (dev->sc_dmatimo > 1) {
2381			printf("%s: DMA timeout #%d\n",
2382			    device_xname(&dev->sc_dev), dev->sc_dmatimo - 1);
2383			GET_SBIC_asr(&dev->sc_sbicp, asr);
2384			if (asr & SBIC_ASR_INT) {
2385				/* We need to service a missed IRQ */
2386				printf("Servicing a missed int:(%02x,%02x)->(%02x,?)\n",
2387				    debug_asr, debug_csr, asr);
2388				sbicintr(dev);
2389			}
2390			sbicdumpstate();
2391		}
2392		dev->sc_dmatimo++;
2393	}
2394	splx(s);
2395	callout_reset(&dev->sc_timo_ch, 30 * hz,
2396	    (void *)sbictimeout, dev);
2397}
2398
2399void
2400sbic_dump_acb(struct sbic_acb *acb)
2401{
2402	u_char *b = (u_char *) &acb->cmd;
2403	int i;
2404
2405	printf("acb@%p ", acb);
2406	if (acb->xs == NULL) {
2407		printf("<unused>\n");
2408		return;
2409	}
2410	printf("(%d:%d) flags %2x clen %2d cmd ",
2411	    acb->xs->xs_periph->periph_target,
2412	    acb->xs->xs_periph->periph_lun, acb->flags, acb->clen);
2413	for (i = acb->clen; i; --i)
2414		printf(" %02x", *b++);
2415	printf("\n");
2416	printf("  xs: %8p data %8p:%04x ", acb->xs, acb->xs->data,
2417	    acb->xs->datalen);
2418	printf("tcnt %lx\n", acb->sc_tcnt);
2419}
2420
2421void
2422sbic_dump(struct sbic_softc *dev)
2423{
2424	sbic_regmap_p regs;
2425	u_char csr, asr;
2426	struct sbic_acb *acb;
2427	int s;
2428	int i;
2429
2430	s = splbio();
2431	regs = &dev->sc_sbicp;
2432#if CSR_TRACE_SIZE
2433	printf("csr trace: ");
2434	i = csr_traceptr;
2435	do {
2436		printf("%c%02x%02x%02x ", csr_trace[i].whr,
2437		    csr_trace[i].csr, csr_trace[i].asr, csr_trace[i].xtn);
2438		switch(csr_trace[i].whr) {
2439		case 'g':
2440			printf("go "); break;
2441		case 's':
2442			printf("select "); break;
2443		case 'y':
2444			printf("select+ "); break;
2445		case 'i':
2446			printf("intr "); break;
2447		case 'f':
2448			printf("finish "); break;
2449		case '>':
2450			printf("out "); break;
2451		case '<':
2452			printf("in "); break;
2453		case 'm':
2454			printf("msgin "); break;
2455		case 'x':
2456			printf("msginx "); break;
2457		case 'X':
2458			printf("msginX "); break;
2459		case 'r':
2460			printf("reselect "); break;
2461		case 'I':
2462			printf("icmd "); break;
2463		case 'a':
2464			printf("abort "); break;
2465		default:
2466			printf("? ");
2467		}
2468		switch(csr_trace[i].csr) {
2469		case 0x11:
2470			printf("INITIATOR"); break;
2471		case 0x16:
2472			printf("S_XFERRED"); break;
2473		case 0x20:
2474			printf("MSGIN_ACK"); break;
2475		case 0x41:
2476			printf("DISC"); break;
2477		case 0x42:
2478			printf("SEL_TIMEO"); break;
2479		case 0x80:
2480			printf("RSLT_NI"); break;
2481		case 0x81:
2482			printf("RSLT_IFY"); break;
2483		case 0x85:
2484			printf("DISC_1"); break;
2485		case 0x18: case 0x19: case 0x1a:
2486		case 0x1b: case 0x1e: case 0x1f:
2487		case 0x28: case 0x29: case 0x2a:
2488		case 0x2b: case 0x2e: case 0x2f:
2489		case 0x48: case 0x49: case 0x4a:
2490		case 0x4b: case 0x4e: case 0x4f:
2491		case 0x88: case 0x89: case 0x8a:
2492		case 0x8b: case 0x8e: case 0x8f:
2493			switch(csr_trace[i].csr & 0xf0) {
2494			case 0x10:
2495				printf("DONE_"); break;
2496			case 0x20:
2497				printf("STOP_"); break;
2498			case 0x40:
2499				printf("ERR_"); break;
2500			case 0x80:
2501				printf("REQ_"); break;
2502			}
2503			switch(csr_trace[i].csr & 7) {
2504			case 0:
2505				printf("DATA_OUT"); break;
2506			case 1:
2507				printf("DATA_IN"); break;
2508			case 2:
2509				printf("CMD"); break;
2510			case 3:
2511				printf("STATUS"); break;
2512			case 6:
2513				printf("MSG_OUT"); break;
2514			case 7:
2515				printf("MSG_IN"); break;
2516			default:
2517				printf("invld phs");
2518			}
2519			break;
2520		default:    printf("****"); break;
2521		}
2522		if (csr_trace[i].asr & SBIC_ASR_INT)
2523			printf(" ASR_INT");
2524		if (csr_trace[i].asr & SBIC_ASR_LCI)
2525			printf(" ASR_LCI");
2526		if (csr_trace[i].asr & SBIC_ASR_BSY)
2527			printf(" ASR_BSY");
2528		if (csr_trace[i].asr & SBIC_ASR_CIP)
2529			printf(" ASR_CIP");
2530		printf("\n");
2531		i = (i + 1) & (CSR_TRACE_SIZE - 1);
2532	} while (i != csr_traceptr);
2533#endif
2534	GET_SBIC_asr(regs, asr);
2535	if ((asr & SBIC_ASR_INT) == 0)
2536		GET_SBIC_csr(regs, csr);
2537	else
2538		csr = 0;
2539	printf("%s@%p regs %p asr %x csr %x\n", device_xname(&dev->sc_dev),
2540	    dev, regs, asr, csr);
2541	if ((acb = dev->free_list.tqh_first)) {
2542		printf("Free list:\n");
2543		while (acb) {
2544			sbic_dump_acb(acb);
2545			acb = acb->chain.tqe_next;
2546		}
2547	}
2548	if ((acb = dev->ready_list.tqh_first)) {
2549		printf("Ready list:\n");
2550		while (acb) {
2551			sbic_dump_acb(acb);
2552			acb = acb->chain.tqe_next;
2553		}
2554	}
2555	if ((acb = dev->nexus_list.tqh_first)) {
2556		printf("Nexus list:\n");
2557		while (acb) {
2558			sbic_dump_acb(acb);
2559			acb = acb->chain.tqe_next;
2560		}
2561	}
2562	if (dev->sc_nexus) {
2563		printf("nexus:\n");
2564		sbic_dump_acb(dev->sc_nexus);
2565	}
2566	printf("targ %d lun %d flags %x\n",
2567	    dev->target, dev->lun, dev->sc_flags);
2568	for (i = 0; i < 8; ++i) {
2569		if (dev->sc_tinfo[i].cmds > 2) {
2570			printf("tgt %d: cmds %d disc %d lubusy %x\n",
2571			    i, dev->sc_tinfo[i].cmds,
2572			    dev->sc_tinfo[i].dconns,
2573			    dev->sc_tinfo[i].lubusy);
2574		}
2575	}
2576	splx(s);
2577}
2578
2579#endif
2580