siop2.c revision 1.21 1 1.21 drochner /* $NetBSD: siop2.c,v 1.21 2003/06/18 08:58:36 drochner Exp $ */
2 1.1 is
3 1.1 is /*
4 1.1 is * Copyright (c) 1994,1998 Michael L. Hitch
5 1.1 is * Copyright (c) 1990 The Regents of the University of California.
6 1.1 is * All rights reserved.
7 1.1 is *
8 1.1 is * This code is derived from software contributed to Berkeley by
9 1.1 is * Van Jacobson of Lawrence Berkeley Laboratory.
10 1.1 is *
11 1.1 is * Redistribution and use in source and binary forms, with or without
12 1.1 is * modification, are permitted provided that the following conditions
13 1.1 is * are met:
14 1.1 is * 1. Redistributions of source code must retain the above copyright
15 1.1 is * notice, this list of conditions and the following disclaimer.
16 1.1 is * 2. Redistributions in binary form must reproduce the above copyright
17 1.1 is * notice, this list of conditions and the following disclaimer in the
18 1.1 is * documentation and/or other materials provided with the distribution.
19 1.1 is * 3. All advertising materials mentioning features or use of this software
20 1.1 is * must display the following acknowledgement:
21 1.1 is * This product includes software developed by the University of
22 1.1 is * California, Berkeley and its contributors.
23 1.1 is * 4. Neither the name of the University nor the names of its contributors
24 1.1 is * may be used to endorse or promote products derived from this software
25 1.1 is * without specific prior written permission.
26 1.1 is *
27 1.1 is * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
28 1.1 is * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
29 1.1 is * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
30 1.1 is * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
31 1.1 is * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
32 1.1 is * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
33 1.1 is * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
34 1.1 is * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
35 1.1 is * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
36 1.1 is * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
37 1.1 is * SUCH DAMAGE.
38 1.1 is *
39 1.1 is * @(#)siop.c 7.5 (Berkeley) 5/4/91
40 1.1 is */
41 1.1 is
42 1.1 is /*
43 1.1 is * AMIGA 53C720/770 scsi adaptor driver
44 1.1 is */
45 1.1 is
46 1.1 is #include "opt_ddb.h"
47 1.18 aymeric
48 1.18 aymeric #include <sys/cdefs.h>
49 1.21 drochner __KERNEL_RCSID(0, "$NetBSD: siop2.c,v 1.21 2003/06/18 08:58:36 drochner Exp $");
50 1.1 is
51 1.1 is #include <sys/param.h>
52 1.1 is #include <sys/systm.h>
53 1.1 is #include <sys/device.h>
54 1.1 is #include <sys/disklabel.h>
55 1.1 is #include <sys/buf.h>
56 1.1 is #include <sys/malloc.h>
57 1.20 thorpej
58 1.20 thorpej #include <uvm/uvm_extern.h>
59 1.20 thorpej
60 1.1 is #include <dev/scsipi/scsi_all.h>
61 1.1 is #include <dev/scsipi/scsipi_all.h>
62 1.1 is #include <dev/scsipi/scsiconf.h>
63 1.1 is #include <machine/cpu.h>
64 1.13 is #ifdef __m68k__
65 1.13 is #include <m68k/include/cacheops.h>
66 1.13 is #endif
67 1.1 is #include <amiga/amiga/custom.h>
68 1.1 is #include <amiga/amiga/isr.h>
69 1.1 is
70 1.1 is #define ARCH_720
71 1.1 is
72 1.1 is #include <amiga/dev/siopreg.h>
73 1.1 is #include <amiga/dev/siopvar.h>
74 1.1 is
75 1.1 is /*
76 1.1 is * SCSI delays
77 1.1 is * In u-seconds, primarily for state changes on the SPC.
78 1.1 is */
79 1.1 is #define SCSI_CMD_WAIT 500000 /* wait per step of 'immediate' cmds */
80 1.1 is #define SCSI_DATA_WAIT 500000 /* wait per data in/out step */
81 1.1 is #define SCSI_INIT_WAIT 500000 /* wait per step (both) during init */
82 1.1 is
83 1.17 aymeric void siopng_select(struct siop_softc *);
84 1.17 aymeric void siopngabort(struct siop_softc *, siop_regmap_p, char *);
85 1.17 aymeric void siopngerror(struct siop_softc *, siop_regmap_p, u_char);
86 1.17 aymeric int siopng_checkintr(struct siop_softc *, u_char, u_char, u_short, int *);
87 1.17 aymeric void siopngreset(struct siop_softc *);
88 1.17 aymeric void siopngsetdelay(int);
89 1.17 aymeric void siopng_scsidone(struct siop_acb *, int);
90 1.17 aymeric void siopng_sched(struct siop_softc *);
91 1.17 aymeric void siopng_poll(struct siop_softc *, struct siop_acb *);
92 1.17 aymeric void siopngintr(struct siop_softc *);
93 1.17 aymeric void scsi_period_to_siopng(struct siop_softc *, int);
94 1.17 aymeric void siopng_start(struct siop_softc *, int, int, u_char *, int, u_char *, int);
95 1.17 aymeric void siopng_dump_acb(struct siop_acb *);
96 1.1 is
97 1.1 is /* 53C720/770 script */
98 1.16 is
99 1.1 is #include <amiga/dev/siop2_script.out>
100 1.1 is
101 1.1 is /* default to not inhibit sync negotiation on any drive */
102 1.7 is u_char siopng_inhibit_sync[16] = {
103 1.7 is 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
104 1.7 is }; /* initialize, so patchable */
105 1.7 is
106 1.7 is u_char siopng_inhibit_wide[16] = {
107 1.7 is 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
108 1.7 is }; /* initialize, so patchable */
109 1.7 is
110 1.7 is u_char siopng_allow_disc[16] = {
111 1.7 is 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3
112 1.7 is };
113 1.7 is
114 1.1 is int siopng_no_dma = 0;
115 1.1 is
116 1.1 is int siopng_reset_delay = 250; /* delay after reset, in milleseconds */
117 1.1 is
118 1.1 is int siopng_cmd_wait = SCSI_CMD_WAIT;
119 1.1 is int siopng_data_wait = SCSI_DATA_WAIT;
120 1.1 is int siopng_init_wait = SCSI_INIT_WAIT;
121 1.1 is
122 1.1 is #define DEBUG_SYNC
123 1.1 is
124 1.1 is #ifdef DEBUG
125 1.1 is /*
126 1.1 is * 0x01 - full debug
127 1.1 is * 0x02 - DMA chaining
128 1.1 is * 0x04 - siopngintr
129 1.1 is * 0x08 - phase mismatch
130 1.1 is * 0x10 - <not used>
131 1.1 is * 0x20 - panic on unhandled exceptions
132 1.1 is * 0x100 - disconnect/reselect
133 1.1 is */
134 1.1 is int siopng_debug = 0;
135 1.1 is int siopngsync_debug = 0;
136 1.1 is int siopngdma_hits = 0;
137 1.1 is int siopngdma_misses = 0;
138 1.1 is int siopngchain_ints = 0;
139 1.1 is int siopngstarts = 0;
140 1.1 is int siopngints = 0;
141 1.1 is int siopngphmm = 0;
142 1.1 is #define SIOP_TRACE_SIZE 128
143 1.1 is #define SIOP_TRACE(a,b,c,d) \
144 1.1 is siopng_trbuf[siopng_trix] = (a); \
145 1.1 is siopng_trbuf[siopng_trix+1] = (b); \
146 1.1 is siopng_trbuf[siopng_trix+2] = (c); \
147 1.1 is siopng_trbuf[siopng_trix+3] = (d); \
148 1.1 is siopng_trix = (siopng_trix + 4) & (SIOP_TRACE_SIZE - 1);
149 1.1 is u_char siopng_trbuf[SIOP_TRACE_SIZE];
150 1.1 is int siopng_trix;
151 1.17 aymeric void siopng_dump(struct siop_softc *);
152 1.17 aymeric void siopng_dump_trace(void);
153 1.1 is #else
154 1.1 is #define SIOP_TRACE(a,b,c,d)
155 1.1 is #endif
156 1.1 is
157 1.1 is
158 1.4 is static char *siopng_chips[] = {
159 1.4 is "720", "720SE", "770", "0x3",
160 1.8 is "810A", "0x5", "0x6", "0x7",
161 1.4 is "0x8", "0x9", "0xA", "0xB",
162 1.4 is "0xC", "0xD", "0xE", "0xF",
163 1.4 is };
164 1.4 is
165 1.1 is /*
166 1.1 is * default minphys routine for siopng based controllers
167 1.1 is */
168 1.1 is void
169 1.17 aymeric siopng_minphys(struct buf *bp)
170 1.1 is {
171 1.1 is
172 1.1 is /*
173 1.1 is * No max transfer at this level.
174 1.1 is */
175 1.1 is minphys(bp);
176 1.1 is }
177 1.1 is
178 1.1 is /*
179 1.1 is * used by specific siopng controller
180 1.1 is *
181 1.1 is */
182 1.15 bouyer void
183 1.17 aymeric siopng_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req,
184 1.17 aymeric void *arg)
185 1.15 bouyer {
186 1.1 is struct scsipi_xfer *xs;
187 1.15 bouyer struct scsipi_periph *periph;
188 1.1 is struct siop_acb *acb;
189 1.15 bouyer struct siop_softc *sc = (void *)chan->chan_adapter->adapt_dev;
190 1.1 is int flags, s;
191 1.1 is
192 1.15 bouyer switch (req) {
193 1.15 bouyer case ADAPTER_REQ_RUN_XFER:
194 1.15 bouyer xs = arg;
195 1.15 bouyer periph = xs->xs_periph;
196 1.15 bouyer flags = xs->xs_control;
197 1.15 bouyer
198 1.15 bouyer /* XXXX ?? */
199 1.15 bouyer if (flags & XS_CTL_DATA_UIO)
200 1.15 bouyer panic("siopng: scsi data uio requested");
201 1.15 bouyer
202 1.15 bouyer /* XXXX ?? */
203 1.15 bouyer if (sc->sc_nexus && flags & XS_CTL_POLL)
204 1.15 bouyer /* panic("siopng_scsicmd: busy");*/
205 1.15 bouyer printf("siopng_scsicmd: busy\n");
206 1.15 bouyer
207 1.15 bouyer s = splbio();
208 1.15 bouyer acb = sc->free_list.tqh_first;
209 1.15 bouyer if (acb) {
210 1.15 bouyer TAILQ_REMOVE(&sc->free_list, acb, chain);
211 1.15 bouyer }
212 1.15 bouyer splx(s);
213 1.1 is
214 1.15 bouyer #ifdef DIAGNOSTIC
215 1.15 bouyer /*
216 1.15 bouyer * This should never happen as we track the resources
217 1.15 bouyer * in the mid-layer.
218 1.15 bouyer */
219 1.15 bouyer if (acb == NULL) {
220 1.15 bouyer scsipi_printaddr(periph);
221 1.15 bouyer printf("unable to allocate acb\n");
222 1.15 bouyer panic("siopng_scsipi_request");
223 1.15 bouyer }
224 1.15 bouyer #endif
225 1.15 bouyer acb->flags = ACB_ACTIVE;
226 1.15 bouyer acb->xs = xs;
227 1.15 bouyer bcopy(xs->cmd, &acb->cmd, xs->cmdlen);
228 1.15 bouyer acb->clen = xs->cmdlen;
229 1.15 bouyer acb->daddr = xs->data;
230 1.15 bouyer acb->dleft = xs->datalen;
231 1.1 is
232 1.15 bouyer s = splbio();
233 1.15 bouyer TAILQ_INSERT_TAIL(&sc->ready_list, acb, chain);
234 1.1 is
235 1.15 bouyer if (sc->sc_nexus == NULL)
236 1.15 bouyer siopng_sched(sc);
237 1.1 is
238 1.15 bouyer splx(s);
239 1.1 is
240 1.15 bouyer if (flags & XS_CTL_POLL || siopng_no_dma)
241 1.15 bouyer siopng_poll(sc, acb);
242 1.15 bouyer return;
243 1.1 is
244 1.15 bouyer case ADAPTER_REQ_GROW_RESOURCES:
245 1.15 bouyer return;
246 1.1 is
247 1.15 bouyer case ADAPTER_REQ_SET_XFER_MODE:
248 1.15 bouyer return;
249 1.15 bouyer }
250 1.1 is }
251 1.1 is
252 1.15 bouyer void
253 1.17 aymeric siopng_poll(struct siop_softc *sc, struct siop_acb *acb)
254 1.1 is {
255 1.1 is siop_regmap_p rp = sc->sc_siopp;
256 1.1 is struct scsipi_xfer *xs = acb->xs;
257 1.1 is int i;
258 1.1 is int status;
259 1.1 is u_char istat;
260 1.1 is u_char dstat;
261 1.1 is u_short sist;
262 1.1 is int s;
263 1.1 is int to;
264 1.1 is
265 1.1 is s = splbio();
266 1.1 is to = xs->timeout / 1000;
267 1.1 is if (sc->nexus_list.tqh_first)
268 1.1 is printf("%s: siopng_poll called with disconnected device\n",
269 1.1 is sc->sc_dev.dv_xname);
270 1.1 is for (;;) {
271 1.1 is /* use cmd_wait values? */
272 1.1 is i = 50000;
273 1.1 is /* XXX spl0(); */
274 1.1 is while (((istat = rp->siop_istat) &
275 1.1 is (SIOP_ISTAT_SIP | SIOP_ISTAT_DIP)) == 0) {
276 1.1 is if (--i <= 0) {
277 1.1 is #ifdef DEBUG
278 1.1 is printf ("waiting: tgt %d cmd %02x sbcl %02x istat %02x sbdl %04x\n dsp %lx (+%lx) dcmd %lx ds %p timeout %d\n",
279 1.15 bouyer xs->xs_periph->periph_target, acb->cmd.opcode,
280 1.1 is rp->siop_sbcl, istat, rp->siop_sbdl, rp->siop_dsp,
281 1.1 is rp->siop_dsp - sc->sc_scriptspa,
282 1.1 is *((long *)&rp->siop_dcmd), &acb->ds, acb->xs->timeout);
283 1.1 is #endif
284 1.1 is i = 50000;
285 1.1 is --to;
286 1.1 is if (to <= 0) {
287 1.1 is siopngreset(sc);
288 1.15 bouyer return;
289 1.1 is }
290 1.1 is }
291 1.1 is delay(20);
292 1.1 is }
293 1.1 is sist = rp->siop_sist;
294 1.1 is dstat = rp->siop_dstat;
295 1.1 is if (siopng_checkintr(sc, istat, dstat, sist, &status)) {
296 1.1 is if (acb != sc->sc_nexus)
297 1.1 is printf("%s: siopng_poll disconnected device completed\n",
298 1.1 is sc->sc_dev.dv_xname);
299 1.1 is else if ((sc->sc_flags & SIOP_INTDEFER) == 0) {
300 1.1 is sc->sc_flags &= ~SIOP_INTSOFF;
301 1.1 is rp->siop_sien = sc->sc_sien;
302 1.1 is rp->siop_dien = sc->sc_dien;
303 1.1 is }
304 1.1 is siopng_scsidone(sc->sc_nexus, status);
305 1.1 is }
306 1.14 thorpej if (xs->xs_status & XS_STS_DONE)
307 1.1 is break;
308 1.1 is }
309 1.1 is splx(s);
310 1.1 is }
311 1.1 is
312 1.1 is /*
313 1.1 is * start next command that's ready
314 1.1 is */
315 1.1 is void
316 1.17 aymeric siopng_sched(struct siop_softc *sc)
317 1.1 is {
318 1.15 bouyer struct scsipi_periph *periph;
319 1.1 is struct siop_acb *acb;
320 1.1 is int i;
321 1.1 is
322 1.1 is #ifdef DEBUG
323 1.1 is if (sc->sc_nexus) {
324 1.1 is printf("%s: siopng_sched- nexus %p/%d ready %p/%d\n",
325 1.1 is sc->sc_dev.dv_xname, sc->sc_nexus,
326 1.15 bouyer sc->sc_nexus->xs->xs_periph->periph_target,
327 1.1 is sc->ready_list.tqh_first,
328 1.15 bouyer sc->ready_list.tqh_first->xs->xs_periph->periph_target);
329 1.1 is return;
330 1.1 is }
331 1.1 is #endif
332 1.1 is for (acb = sc->ready_list.tqh_first; acb; acb = acb->chain.tqe_next) {
333 1.15 bouyer periph = acb->xs->xs_periph;
334 1.15 bouyer i = periph->periph_target;
335 1.15 bouyer if(!(sc->sc_tinfo[i].lubusy & (1 << periph->periph_lun))) {
336 1.1 is struct siop_tinfo *ti = &sc->sc_tinfo[i];
337 1.1 is
338 1.1 is TAILQ_REMOVE(&sc->ready_list, acb, chain);
339 1.1 is sc->sc_nexus = acb;
340 1.15 bouyer periph = acb->xs->xs_periph;
341 1.15 bouyer ti = &sc->sc_tinfo[periph->periph_target];
342 1.15 bouyer ti->lubusy |= (1 << periph->periph_lun);
343 1.1 is break;
344 1.1 is }
345 1.1 is }
346 1.1 is
347 1.1 is if (acb == NULL) {
348 1.1 is #ifdef DEBUGXXX
349 1.1 is printf("%s: siopng_sched didn't find ready command\n",
350 1.1 is sc->sc_dev.dv_xname);
351 1.1 is #endif
352 1.1 is return;
353 1.1 is }
354 1.1 is
355 1.14 thorpej if (acb->xs->xs_control & XS_CTL_RESET)
356 1.1 is siopngreset(sc);
357 1.1 is
358 1.1 is #if 0
359 1.15 bouyer acb->cmd.bytes[0] |= periph->periph_lun << 5; /* XXXX */
360 1.1 is #endif
361 1.1 is ++sc->sc_active;
362 1.1 is siopng_select(sc);
363 1.1 is }
364 1.1 is
365 1.1 is void
366 1.17 aymeric siopng_scsidone(struct siop_acb *acb, int stat)
367 1.1 is {
368 1.1 is struct scsipi_xfer *xs;
369 1.15 bouyer struct scsipi_periph *periph;
370 1.1 is struct siop_softc *sc;
371 1.1 is int dosched = 0;
372 1.1 is
373 1.1 is if (acb == NULL || (xs = acb->xs) == NULL) {
374 1.1 is #ifdef DIAGNOSTIC
375 1.1 is printf("siopng_scsidone: NULL acb or scsipi_xfer\n");
376 1.1 is #if defined(DEBUG) && defined(DDB)
377 1.1 is Debugger();
378 1.1 is #endif
379 1.1 is #endif
380 1.1 is return;
381 1.1 is }
382 1.15 bouyer periph = xs->xs_periph;
383 1.15 bouyer sc = (void *)periph->periph_channel->chan_adapter->adapt_dev;
384 1.15 bouyer
385 1.1 is xs->status = stat;
386 1.15 bouyer xs->resid = 0; /* XXXX */
387 1.1 is
388 1.15 bouyer if (xs->error == XS_NOERROR) {
389 1.15 bouyer if (stat == SCSI_CHECK || stat == SCSI_BUSY)
390 1.15 bouyer xs->error = XS_BUSY;
391 1.1 is }
392 1.1 is
393 1.1 is /*
394 1.1 is * Remove the ACB from whatever queue it's on. We have to do a bit of
395 1.1 is * a hack to figure out which queue it's on. Note that it is *not*
396 1.1 is * necessary to cdr down the ready queue, but we must cdr down the
397 1.1 is * nexus queue and see if it's there, so we can mark the unit as no
398 1.1 is * longer busy. This code is sickening, but it works.
399 1.1 is */
400 1.1 is if (acb == sc->sc_nexus) {
401 1.1 is sc->sc_nexus = NULL;
402 1.15 bouyer sc->sc_tinfo[periph->periph_target].lubusy &=
403 1.15 bouyer ~(1<<periph->periph_lun);
404 1.1 is if (sc->ready_list.tqh_first)
405 1.1 is dosched = 1; /* start next command */
406 1.1 is --sc->sc_active;
407 1.1 is SIOP_TRACE('d','a',stat,0)
408 1.1 is } else if (sc->ready_list.tqh_last == &acb->chain.tqe_next) {
409 1.1 is TAILQ_REMOVE(&sc->ready_list, acb, chain);
410 1.1 is SIOP_TRACE('d','r',stat,0)
411 1.1 is } else {
412 1.1 is register struct siop_acb *acb2;
413 1.1 is for (acb2 = sc->nexus_list.tqh_first; acb2;
414 1.1 is acb2 = acb2->chain.tqe_next)
415 1.1 is if (acb2 == acb) {
416 1.1 is TAILQ_REMOVE(&sc->nexus_list, acb, chain);
417 1.15 bouyer sc->sc_tinfo[periph->periph_target].lubusy
418 1.15 bouyer &= ~(1<<periph->periph_lun);
419 1.1 is --sc->sc_active;
420 1.1 is break;
421 1.1 is }
422 1.1 is if (acb2)
423 1.1 is ;
424 1.1 is else if (acb->chain.tqe_next) {
425 1.1 is TAILQ_REMOVE(&sc->ready_list, acb, chain);
426 1.1 is --sc->sc_active;
427 1.1 is } else {
428 1.1 is printf("%s: can't find matching acb\n",
429 1.1 is sc->sc_dev.dv_xname);
430 1.1 is #ifdef DDB
431 1.1 is /* Debugger(); */
432 1.1 is #endif
433 1.1 is }
434 1.1 is SIOP_TRACE('d','n',stat,0);
435 1.1 is }
436 1.1 is /* Put it on the free list. */
437 1.1 is acb->flags = ACB_FREE;
438 1.1 is TAILQ_INSERT_HEAD(&sc->free_list, acb, chain);
439 1.1 is
440 1.15 bouyer sc->sc_tinfo[periph->periph_target].cmds++;
441 1.1 is
442 1.1 is scsipi_done(xs);
443 1.1 is
444 1.1 is if (dosched && sc->sc_nexus == NULL)
445 1.1 is siopng_sched(sc);
446 1.1 is }
447 1.1 is
448 1.1 is void
449 1.17 aymeric siopngabort(register struct siop_softc *sc, siop_regmap_p rp, char *where)
450 1.1 is {
451 1.1 is #ifdef fix_this
452 1.1 is int i;
453 1.1 is #endif
454 1.1 is
455 1.1 is printf ("%s: abort %s: dstat %02x, istat %02x sist %04x sien %04x sbcl %02x\n",
456 1.1 is sc->sc_dev.dv_xname,
457 1.1 is where, rp->siop_dstat, rp->siop_istat, rp->siop_sist,
458 1.1 is rp->siop_sien, rp->siop_sbcl);
459 1.1 is siopng_dump_registers(sc);
460 1.1 is
461 1.1 is if (sc->sc_active > 0) {
462 1.1 is #ifdef TODO
463 1.1 is SET_SBIC_cmd (rp, SBIC_CMD_ABORT);
464 1.1 is WAIT_CIP (rp);
465 1.1 is
466 1.1 is GET_SBIC_asr (rp, asr);
467 1.1 is if (asr & (SBIC_ASR_BSY|SBIC_ASR_LCI))
468 1.1 is {
469 1.1 is /* ok, get more drastic.. */
470 1.1 is
471 1.1 is SET_SBIC_cmd (rp, SBIC_CMD_RESET);
472 1.1 is delay(25);
473 1.1 is SBIC_WAIT(rp, SBIC_ASR_INT, 0);
474 1.1 is GET_SBIC_csr (rp, csr); /* clears interrupt also */
475 1.1 is
476 1.1 is return;
477 1.1 is }
478 1.1 is
479 1.1 is do
480 1.1 is {
481 1.1 is SBIC_WAIT (rp, SBIC_ASR_INT, 0);
482 1.1 is GET_SBIC_csr (rp, csr);
483 1.1 is }
484 1.1 is while ((csr != SBIC_CSR_DISC) && (csr != SBIC_CSR_DISC_1)
485 1.1 is && (csr != SBIC_CSR_CMD_INVALID));
486 1.1 is #endif
487 1.1 is
488 1.1 is /* lets just hope it worked.. */
489 1.1 is #ifdef fix_this
490 1.1 is for (i = 0; i < 2; ++i) {
491 1.1 is if (sc->sc_iob[i].sc_xs && &sc->sc_iob[i] !=
492 1.1 is sc->sc_cur) {
493 1.1 is printf ("siopngabort: cleanup!\n");
494 1.1 is sc->sc_iob[i].sc_xs = NULL;
495 1.1 is }
496 1.1 is }
497 1.1 is #endif /* fix_this */
498 1.1 is /* sc->sc_active = 0; */
499 1.1 is }
500 1.1 is }
501 1.1 is
502 1.1 is void
503 1.17 aymeric siopnginitialize(struct siop_softc *sc)
504 1.1 is {
505 1.1 is int i;
506 1.1 is u_int inhibit_sync;
507 1.1 is extern u_long scsi_nosync;
508 1.1 is extern int shift_nosync;
509 1.1 is
510 1.1 is /*
511 1.1 is * Need to check that scripts is on a long word boundary
512 1.1 is * Also should verify that dev doesn't span non-contiguous
513 1.1 is * physical pages.
514 1.1 is */
515 1.1 is sc->sc_scriptspa = kvtop((caddr_t)siopng_scripts);
516 1.1 is
517 1.1 is /*
518 1.1 is * malloc sc_acb to ensure that DS is on a long word boundary.
519 1.1 is */
520 1.1 is
521 1.17 aymeric MALLOC(sc->sc_acb, struct siop_acb *,
522 1.1 is sizeof(struct siop_acb) * SIOP_NACB, M_DEVBUF, M_NOWAIT);
523 1.17 aymeric if (sc->sc_acb == NULL)
524 1.1 is panic("siopnginitialize: ACB malloc failed!");
525 1.1 is
526 1.1 is sc->sc_tcp[1] = 1000 / sc->sc_clock_freq;
527 1.1 is sc->sc_tcp[2] = 1500 / sc->sc_clock_freq;
528 1.1 is sc->sc_tcp[3] = 2000 / sc->sc_clock_freq;
529 1.1 is sc->sc_minsync = sc->sc_tcp[1]; /* in 4ns units */
530 1.1 is if (sc->sc_minsync < 25)
531 1.1 is sc->sc_minsync = 25;
532 1.6 mhitch sc->sc_minsync >>= 1; /* Using clock doubler, allow Ultra */
533 1.1 is if (sc->sc_clock_freq <= 25) {
534 1.1 is sc->sc_dcntl |= 0x80; /* SCLK/1 */
535 1.1 is sc->sc_tcp[0] = sc->sc_tcp[1];
536 1.1 is } else if (sc->sc_clock_freq <= 37) {
537 1.1 is sc->sc_dcntl |= 0x40; /* SCLK/1.5 */
538 1.1 is sc->sc_tcp[0] = sc->sc_tcp[2];
539 1.1 is } else if (sc->sc_clock_freq <= 50) {
540 1.1 is sc->sc_dcntl |= 0x00; /* SCLK/2 */
541 1.1 is sc->sc_tcp[0] = sc->sc_tcp[3];
542 1.1 is } else {
543 1.1 is sc->sc_dcntl |= 0xc0; /* SCLK/3 */
544 1.1 is sc->sc_tcp[0] = 3000 / sc->sc_clock_freq;
545 1.1 is }
546 1.1 is
547 1.1 is if (scsi_nosync) {
548 1.6 mhitch inhibit_sync = (scsi_nosync >> shift_nosync) & 0xffff;
549 1.6 mhitch shift_nosync += 16; /* XXX maxtarget */
550 1.1 is #ifdef DEBUG
551 1.1 is if (inhibit_sync)
552 1.1 is printf("%s: Inhibiting synchronous transfer %02x\n",
553 1.1 is sc->sc_dev.dv_xname, inhibit_sync);
554 1.1 is #endif
555 1.6 mhitch for (i = 0; i < 16; ++i) /* XXX maxtarget */
556 1.1 is if (inhibit_sync & (1 << i))
557 1.1 is siopng_inhibit_sync[i] = 1;
558 1.1 is }
559 1.1 is
560 1.1 is siopngreset (sc);
561 1.1 is }
562 1.1 is
563 1.1 is void
564 1.17 aymeric siopngreset(struct siop_softc *sc)
565 1.1 is {
566 1.1 is siop_regmap_p rp;
567 1.1 is u_int i, s;
568 1.1 is u_short dummy;
569 1.1 is struct siop_acb *acb;
570 1.1 is
571 1.1 is rp = sc->sc_siopp;
572 1.1 is
573 1.1 is if (sc->sc_flags & SIOP_ALIVE)
574 1.1 is siopngabort(sc, rp, "reset");
575 1.1 is
576 1.1 is printf("%s: ", sc->sc_dev.dv_xname); /* XXXX */
577 1.1 is
578 1.1 is s = splbio();
579 1.1 is
580 1.1 is /*
581 1.1 is * Reset the chip
582 1.1 is * XXX - is this really needed?
583 1.1 is */
584 1.1 is rp->siop_istat |= SIOP_ISTAT_ABRT; /* abort current script */
585 1.1 is rp->siop_istat |= SIOP_ISTAT_RST; /* reset chip */
586 1.1 is rp->siop_istat &= ~SIOP_ISTAT_RST;
587 1.1 is /*
588 1.1 is * Reset SCSI bus (do we really want this?)
589 1.1 is */
590 1.1 is rp->siop_sien = 0;
591 1.1 is rp->siop_scntl1 |= SIOP_SCNTL1_RST;
592 1.1 is delay(1);
593 1.1 is rp->siop_scntl1 &= ~SIOP_SCNTL1_RST;
594 1.1 is
595 1.1 is /*
596 1.1 is * Set up various chip parameters
597 1.1 is */
598 1.6 mhitch rp->siop_stest1 |= SIOP_STEST1_DBLEN; /* SCLK doubler enable */
599 1.1 is delay(20);
600 1.6 mhitch rp->siop_stest3 |= SIOP_STEST3_HSC; /* Halt SCSI clock */
601 1.6 mhitch rp->siop_scntl3 = 0x15; /* SCF/CCF*/
602 1.6 mhitch rp->siop_stest1 |= SIOP_STEST1_DBLSEL; /* SCLK doubler select */
603 1.6 mhitch rp->siop_stest3 &= ~SIOP_STEST3_HSC; /* Clear Halt SCSI clock */
604 1.1 is rp->siop_scntl0 = SIOP_ARB_FULL | /*SIOP_SCNTL0_EPC |*/ SIOP_SCNTL0_EPG;
605 1.1 is rp->siop_dcntl = sc->sc_dcntl;
606 1.1 is rp->siop_dmode = 0xc0; /* XXX burst length */
607 1.1 is rp->siop_sien = 0x00; /* don't enable interrupts yet */
608 1.1 is rp->siop_dien = 0x00; /* don't enable interrupts yet */
609 1.15 bouyer rp->siop_scid = sc->sc_channel.chan_id |
610 1.6 mhitch SIOP_SCID_RRE | SIOP_SCID_SRE;
611 1.15 bouyer rp->siop_respid = 1 << sc->sc_channel.chan_id;
612 1.1 is rp->siop_dwt = 0x00;
613 1.1 is rp->siop_stime0 = 0x0c; /* XXXXX check */
614 1.1 is
615 1.1 is /* will need to re-negotiate sync xfers */
616 1.1 is bzero(&sc->sc_sync, sizeof (sc->sc_sync));
617 1.1 is
618 1.1 is i = rp->siop_istat;
619 1.1 is if (i & SIOP_ISTAT_SIP)
620 1.1 is dummy = rp->siop_sist;
621 1.1 is if (i & SIOP_ISTAT_DIP)
622 1.1 is dummy = rp->siop_dstat;
623 1.1 is
624 1.1 is splx (s);
625 1.1 is
626 1.1 is delay (siopng_reset_delay * 1000);
627 1.12 is
628 1.12 is /*
629 1.12 is * is lower half unterminated?
630 1.12 is */
631 1.12 is if ((rp->siop_sbdl & 0x00ff) == 0x00ff) {
632 1.12 is printf(" no SCSI termination, host adapter deactivated.\n");
633 1.15 bouyer sc->sc_channel.chan_ntargets = 0; /* XXX */
634 1.12 is sc->sc_flags &= ~(SIOP_ALIVE|SIOP_INTDEFER|SIOP_INTSOFF);
635 1.12 is /* disable SCSI and DMA interrupts */
636 1.12 is sc->sc_sien = 0;
637 1.12 is sc->sc_dien = 0;
638 1.12 is rp->siop_sien = sc->sc_sien;
639 1.12 is rp->siop_dien = sc->sc_dien;
640 1.12 is
641 1.12 is return;
642 1.12 is }
643 1.12 is
644 1.1 is /*
645 1.1 is * Check if upper half of SCSI bus is unterminated, and disallow
646 1.1 is * disconnections if it appears to be unterminated.
647 1.1 is */
648 1.1 is if ((rp->siop_sbdl & 0xff00) == 0xff00) {
649 1.1 is printf(" NO WIDE TERM");
650 1.6 mhitch /* XXX need to restrict maximum target ID as well? */
651 1.15 bouyer sc->sc_channel.chan_ntargets = 8;
652 1.6 mhitch for (i = 0; i < 16; ++i) {
653 1.1 is siopng_allow_disc[i] = 0;
654 1.6 mhitch siopng_inhibit_wide[i] |= 0x80;
655 1.6 mhitch }
656 1.1 is }
657 1.4 is
658 1.4 is printf("siopng type %s id %d reset V%d\n",
659 1.4 is siopng_chips[rp->siop_macntl>>4],
660 1.15 bouyer sc->sc_channel.chan_ntargets,
661 1.1 is rp->siop_ctest3 >> 4);
662 1.1 is
663 1.1 is if ((sc->sc_flags & SIOP_ALIVE) == 0) {
664 1.1 is TAILQ_INIT(&sc->ready_list);
665 1.1 is TAILQ_INIT(&sc->nexus_list);
666 1.1 is TAILQ_INIT(&sc->free_list);
667 1.1 is sc->sc_nexus = NULL;
668 1.1 is acb = sc->sc_acb;
669 1.1 is bzero(acb, sizeof(struct siop_acb) * SIOP_NACB);
670 1.1 is for (i = 0; i < SIOP_NACB; i++) {
671 1.1 is TAILQ_INSERT_TAIL(&sc->free_list, acb, chain);
672 1.1 is acb++;
673 1.1 is }
674 1.1 is bzero(sc->sc_tinfo, sizeof(sc->sc_tinfo));
675 1.1 is } else {
676 1.1 is if (sc->sc_nexus != NULL) {
677 1.15 bouyer sc->sc_nexus->xs->error = XS_RESET;
678 1.1 is siopng_scsidone(sc->sc_nexus, sc->sc_nexus->stat[0]);
679 1.1 is }
680 1.1 is while ((acb = sc->nexus_list.tqh_first) > 0) {
681 1.15 bouyer acb->xs->error = XS_RESET;
682 1.1 is siopng_scsidone(acb, acb->stat[0]);
683 1.1 is }
684 1.1 is }
685 1.1 is
686 1.1 is sc->sc_flags |= SIOP_ALIVE;
687 1.1 is sc->sc_flags &= ~(SIOP_INTDEFER|SIOP_INTSOFF);
688 1.1 is /* enable SCSI and DMA interrupts */
689 1.1 is sc->sc_sien = SIOP_SIEN_MA | SIOP_SIEN_STO | /*SIOP_SIEN_GEN |*/
690 1.1 is /*SIOP_SIEN_SEL |*/ SIOP_SIEN_SGE | SIOP_SIEN_UDC |
691 1.1 is SIOP_SIEN_RST | SIOP_SIEN_PAR;
692 1.1 is sc->sc_dien = SIOP_DIEN_BF | SIOP_DIEN_ABRT | SIOP_DIEN_SIR |
693 1.1 is /*SIOP_DIEN_WTD |*/ SIOP_DIEN_IID;
694 1.1 is rp->siop_sien = sc->sc_sien;
695 1.1 is rp->siop_dien = sc->sc_dien;
696 1.10 is /*siopng_dump_registers(sc);*/
697 1.1 is }
698 1.1 is
699 1.1 is /*
700 1.1 is * Setup Data Storage for 53C720/770 and start SCRIPTS processing
701 1.1 is */
702 1.1 is
703 1.1 is void
704 1.17 aymeric siopng_start(struct siop_softc *sc, int target, int lun, u_char *cbuf,
705 1.17 aymeric int clen, u_char *buf, int len)
706 1.1 is {
707 1.1 is siop_regmap_p rp = sc->sc_siopp;
708 1.1 is int nchain;
709 1.1 is int count, tcount;
710 1.1 is char *addr, *dmaend;
711 1.1 is struct siop_acb *acb = sc->sc_nexus;
712 1.1 is #ifdef DEBUG
713 1.1 is int i;
714 1.1 is #endif
715 1.1 is
716 1.1 is #ifdef DEBUG
717 1.1 is if (siopng_debug & 0x100 && rp->siop_sbcl & SIOP_BSY) {
718 1.1 is printf ("ACK! siopng was busy: rp %p script %p dsa %p active %ld\n",
719 1.2 is rp, &siopng_scripts, &acb->ds, sc->sc_active);
720 1.1 is printf ("istat %02x sfbr %02x respid %02x sien %04x dien %02x\n",
721 1.1 is rp->siop_istat, rp->siop_sfbr, rp->siop_respid,
722 1.1 is rp->siop_sien, rp->siop_dien);
723 1.1 is #ifdef DDB
724 1.1 is /*Debugger();*/
725 1.1 is #endif
726 1.1 is }
727 1.1 is #endif
728 1.1 is acb->msgout[0] = MSG_IDENTIFY | lun;
729 1.1 is if (siopng_allow_disc[target] & 2 ||
730 1.1 is (siopng_allow_disc[target] && len == 0))
731 1.1 is acb->msgout[0] = MSG_IDENTIFY_DR | lun;
732 1.1 is acb->status = 0;
733 1.1 is acb->stat[0] = -1;
734 1.1 is acb->msg[0] = -1;
735 1.1 is acb->ds.scsi_addr = (target << 16) | (sc->sc_sync[target].sxfer << 8) |
736 1.6 mhitch (sc->sc_sync[target].scntl3 << 24);
737 1.1 is acb->ds.idlen = 1;
738 1.1 is acb->ds.idbuf = (char *) kvtop(&acb->msgout[0]);
739 1.1 is acb->ds.cmdlen = clen;
740 1.1 is acb->ds.cmdbuf = (char *) kvtop(cbuf);
741 1.1 is acb->ds.stslen = 1;
742 1.1 is acb->ds.stsbuf = (char *) kvtop(&acb->stat[0]);
743 1.1 is acb->ds.msglen = 1;
744 1.1 is acb->ds.msgbuf = (char *) kvtop(&acb->msg[0]);
745 1.1 is acb->msg[1] = -1;
746 1.1 is acb->ds.msginlen = 1;
747 1.1 is acb->ds.extmsglen = 1;
748 1.1 is acb->ds.synmsglen = 3;
749 1.6 mhitch acb->ds.msginbuf = acb->ds.msgbuf + 1;
750 1.6 mhitch acb->ds.extmsgbuf = acb->ds.msginbuf + 1;
751 1.6 mhitch acb->ds.synmsgbuf = acb->ds.extmsgbuf + 1;
752 1.1 is bzero(&acb->ds.chain, sizeof (acb->ds.chain));
753 1.1 is
754 1.6 mhitch if (sc->sc_sync[target].state == NEG_WIDE) {
755 1.6 mhitch if (siopng_inhibit_wide[target]) {
756 1.6 mhitch sc->sc_sync[target].state = NEG_SYNC;
757 1.6 mhitch sc->sc_sync[target].scntl3 &= ~SIOP_SCNTL3_EWS;
758 1.6 mhitch #ifdef DEBUG
759 1.6 mhitch if (siopngsync_debug)
760 1.6 mhitch printf ("Forcing target %d narrow\n", target);
761 1.6 mhitch #endif
762 1.6 mhitch }
763 1.6 mhitch else {
764 1.6 mhitch sc->sc_sync[target].scntl3 = 0x15 | /* XXX */
765 1.6 mhitch (sc->sc_sync[target].scntl3 & 0x88); /* XXX */
766 1.6 mhitch acb->msg[2] = -1;
767 1.6 mhitch acb->msgout[1] = MSG_EXT_MESSAGE;
768 1.6 mhitch acb->msgout[2] = 2;
769 1.6 mhitch acb->msgout[3] = MSG_WIDE_REQ;
770 1.6 mhitch acb->msgout[4] = 1;
771 1.6 mhitch acb->ds.idlen = 5;
772 1.6 mhitch acb->ds.synmsglen = 2;
773 1.6 mhitch sc->sc_sync[target].state = NEG_WAITW;
774 1.6 mhitch #ifdef DEBUG
775 1.6 mhitch if (siopngsync_debug)
776 1.6 mhitch printf("Sending wide request to target %d\n", target);
777 1.6 mhitch #endif
778 1.6 mhitch }
779 1.6 mhitch }
780 1.6 mhitch if (sc->sc_sync[target].state == NEG_SYNC) {
781 1.1 is if (siopng_inhibit_sync[target]) {
782 1.6 mhitch sc->sc_sync[target].state = NEG_DONE;
783 1.6 mhitch sc->sc_sync[target].scntl3 = 5 | /* XXX */
784 1.6 mhitch (sc->sc_sync[target].scntl3 & 0x88); /* XXX */
785 1.1 is sc->sc_sync[target].sxfer = 0;
786 1.1 is #ifdef DEBUG
787 1.1 is if (siopngsync_debug)
788 1.1 is printf ("Forcing target %d asynchronous\n", target);
789 1.1 is #endif
790 1.1 is }
791 1.1 is else {
792 1.6 mhitch sc->sc_sync[target].scntl3 = 0x15 | /* XXX */
793 1.6 mhitch (sc->sc_sync[target].scntl3 & 0x88); /* XXX */
794 1.1 is acb->msg[2] = -1;
795 1.1 is acb->msgout[1] = MSG_EXT_MESSAGE;
796 1.1 is acb->msgout[2] = 3;
797 1.1 is acb->msgout[3] = MSG_SYNC_REQ;
798 1.1 is #ifdef MAXTOR_SYNC_KLUDGE
799 1.1 is acb->msgout[4] = 50 / 4; /* ask for ridiculous period */
800 1.1 is #else
801 1.1 is acb->msgout[4] = sc->sc_minsync;
802 1.1 is #endif
803 1.1 is acb->msgout[5] = SIOP_MAX_OFFSET;
804 1.1 is acb->ds.idlen = 6;
805 1.6 mhitch sc->sc_sync[target].state = NEG_WAITS;
806 1.1 is #ifdef DEBUG
807 1.1 is if (siopngsync_debug)
808 1.1 is printf ("Sending sync request to target %d\n", target);
809 1.1 is #endif
810 1.1 is }
811 1.1 is }
812 1.1 is
813 1.1 is /*
814 1.1 is * Build physical DMA addresses for scatter/gather I/O
815 1.1 is */
816 1.1 is acb->iob_buf = buf;
817 1.1 is acb->iob_len = len;
818 1.1 is acb->iob_curbuf = acb->iob_curlen = 0;
819 1.1 is nchain = 0;
820 1.1 is count = len;
821 1.1 is addr = buf;
822 1.1 is dmaend = NULL;
823 1.1 is while (count > 0) {
824 1.1 is acb->ds.chain[nchain].databuf = (char *) kvtop (addr);
825 1.20 thorpej if (count < (tcount = PAGE_SIZE - ((int) addr & PGOFSET)))
826 1.1 is tcount = count;
827 1.3 is
828 1.3 is #if DEBUG_ONLY_IF_DESPERATE
829 1.3 is printf("chain[%d]: count %d tcount %d vaddr %p paddr %p\n",
830 1.3 is nchain, count, tcount, addr,
831 1.3 is acb->ds.chain[nchain].databuf);
832 1.3 is #endif
833 1.1 is acb->ds.chain[nchain].datalen = tcount;
834 1.1 is addr += tcount;
835 1.1 is count -= tcount;
836 1.1 is if (acb->ds.chain[nchain].databuf == dmaend) {
837 1.1 is dmaend += acb->ds.chain[nchain].datalen;
838 1.1 is acb->ds.chain[nchain].datalen = 0;
839 1.1 is acb->ds.chain[--nchain].datalen += tcount;
840 1.1 is #ifdef DEBUG
841 1.1 is ++siopngdma_hits;
842 1.1 is #endif
843 1.1 is }
844 1.1 is else {
845 1.1 is dmaend = acb->ds.chain[nchain].databuf +
846 1.1 is acb->ds.chain[nchain].datalen;
847 1.1 is acb->ds.chain[nchain].datalen = tcount;
848 1.1 is #ifdef DEBUG
849 1.1 is if (nchain) /* Don't count miss on first one */
850 1.1 is ++siopngdma_misses;
851 1.1 is #endif
852 1.1 is }
853 1.1 is ++nchain;
854 1.1 is }
855 1.1 is #ifdef DEBUG
856 1.1 is if (nchain != 1 && len != 0 && siopng_debug & 3) {
857 1.1 is printf ("DMA chaining set: %d\n", nchain);
858 1.1 is for (i = 0; i < nchain; ++i) {
859 1.1 is printf (" [%d] %8p %lx\n", i, acb->ds.chain[i].databuf,
860 1.1 is acb->ds.chain[i].datalen);
861 1.1 is }
862 1.1 is }
863 1.1 is #endif
864 1.1 is
865 1.1 is /* push data cache for all data the 53c720/770 needs to access */
866 1.1 is dma_cachectl ((caddr_t)acb, sizeof (struct siop_acb));
867 1.1 is dma_cachectl (cbuf, clen);
868 1.1 is if (buf != NULL && len != 0)
869 1.1 is dma_cachectl (buf, len);
870 1.1 is #ifdef DEBUG
871 1.1 is if (siopng_debug & 0x100 && rp->siop_sbcl & SIOP_BSY) {
872 1.1 is printf ("ACK! siopng was busy at start: rp %p script %p dsa %p active %ld\n",
873 1.2 is rp, &siopng_scripts, &acb->ds, sc->sc_active);
874 1.1 is #ifdef DDB
875 1.1 is /*Debugger();*/
876 1.1 is #endif
877 1.1 is }
878 1.1 is #endif
879 1.1 is if (sc->nexus_list.tqh_first == NULL) {
880 1.1 is if (rp->siop_istat & SIOP_ISTAT_CON)
881 1.1 is printf("%s: siopng_select while connected?\n",
882 1.1 is sc->sc_dev.dv_xname);
883 1.1 is rp->siop_temp = 0;
884 1.1 is #ifndef FIXME
885 1.6 mhitch rp->siop_scntl3 = sc->sc_sync[target].scntl3;
886 1.1 is #endif
887 1.1 is rp->siop_dsa = kvtop((caddr_t)&acb->ds);
888 1.1 is rp->siop_dsp = sc->sc_scriptspa;
889 1.1 is SIOP_TRACE('s',1,0,0)
890 1.1 is } else {
891 1.1 is if ((rp->siop_istat & SIOP_ISTAT_CON) == 0) {
892 1.1 is rp->siop_istat = SIOP_ISTAT_SIGP;
893 1.1 is SIOP_TRACE('s',2,0,0);
894 1.1 is }
895 1.1 is else {
896 1.1 is SIOP_TRACE('s',3,rp->siop_istat,0);
897 1.1 is }
898 1.1 is }
899 1.1 is #ifdef DEBUG
900 1.1 is ++siopngstarts;
901 1.1 is #endif
902 1.1 is }
903 1.1 is
904 1.1 is /*
905 1.1 is * Process a DMA or SCSI interrupt from the 53C720/770 SIOP
906 1.1 is */
907 1.1 is
908 1.1 is int
909 1.17 aymeric siopng_checkintr(struct siop_softc *sc, u_char istat, u_char dstat,
910 1.17 aymeric u_short sist, int *status)
911 1.1 is {
912 1.1 is siop_regmap_p rp = sc->sc_siopp;
913 1.1 is struct siop_acb *acb = sc->sc_nexus;
914 1.1 is int target = 0;
915 1.3 is int dfifo, dbc, sstat0, sstat1, sstat2;
916 1.1 is
917 1.1 is dfifo = rp->siop_dfifo;
918 1.1 is dbc = rp->siop_dbc0;
919 1.3 is sstat0 = rp->siop_sstat0;
920 1.1 is sstat1 = rp->siop_sstat1;
921 1.3 is sstat2 = rp->siop_sstat2;
922 1.1 is rp->siop_ctest3 |= SIOP_CTEST8_CLF;
923 1.1 is while ((rp->siop_ctest1 & SIOP_CTEST1_FMT) != SIOP_CTEST1_FMT)
924 1.1 is ;
925 1.1 is rp->siop_ctest3 &= ~SIOP_CTEST8_CLF;
926 1.1 is #ifdef DEBUG
927 1.1 is ++siopngints;
928 1.1 is #if 0
929 1.1 is if (siopng_debug & 0x100) {
930 1.1 is DCIAS(&acb->stat[0]); /* XXX */
931 1.1 is printf ("siopngchkintr: istat %x dstat %x sist %x dsps %x sbcl %x sts %x msg %x\n",
932 1.1 is istat, dstat, sist, rp->siop_dsps, rp->siop_sbcl, acb->stat[0], acb->msg[0]);
933 1.1 is printf ("sync msg in: %02x %02x %02x %02x %02x %02x\n",
934 1.1 is acb->msg[0], acb->msg[1], acb->msg[2],
935 1.1 is acb->msg[3], acb->msg[4], acb->msg[5]);
936 1.1 is }
937 1.1 is #endif
938 1.1 is if (rp->siop_dsp && (rp->siop_dsp < sc->sc_scriptspa ||
939 1.2 is rp->siop_dsp >= sc->sc_scriptspa + sizeof(siopng_scripts))) {
940 1.1 is printf ("%s: dsp not within script dsp %lx scripts %lx:%lx",
941 1.1 is sc->sc_dev.dv_xname, rp->siop_dsp, sc->sc_scriptspa,
942 1.2 is sc->sc_scriptspa + sizeof(siopng_scripts));
943 1.1 is printf(" istat %x dstat %x sist %x\n",
944 1.1 is istat, dstat, sist);
945 1.1 is #ifdef DDB
946 1.1 is Debugger();
947 1.1 is #endif
948 1.1 is }
949 1.1 is #endif
950 1.1 is SIOP_TRACE('i',dstat,istat,(istat&SIOP_ISTAT_DIP)?rp->siop_dsps&0xff:sist);
951 1.1 is if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff00) {
952 1.1 is /* Normal completion status, or check condition */
953 1.1 is #ifdef DEBUG
954 1.1 is if (rp->siop_dsa != kvtop((caddr_t)&acb->ds)) {
955 1.1 is printf ("siopng: invalid dsa: %lx %x\n", rp->siop_dsa,
956 1.1 is kvtop((caddr_t)&acb->ds));
957 1.1 is panic("*** siopng DSA invalid ***");
958 1.1 is }
959 1.1 is #endif
960 1.15 bouyer target = acb->xs->xs_periph->periph_target;
961 1.6 mhitch if (sc->sc_sync[target].state == NEG_WAITW) {
962 1.6 mhitch if (acb->msg[1] == 0xff)
963 1.6 mhitch printf ("%s: target %d ignored wide request\n",
964 1.6 mhitch sc->sc_dev.dv_xname, target);
965 1.6 mhitch else if (acb->msg[1] == MSG_REJECT)
966 1.6 mhitch printf ("%s: target %d rejected wide request\n",
967 1.6 mhitch sc->sc_dev.dv_xname, target);
968 1.6 mhitch else {
969 1.6 mhitch printf("%s: target %d (wide) %02x %02x %02x %02x\n",
970 1.6 mhitch sc->sc_dev.dv_xname, target, acb->msg[1],
971 1.6 mhitch acb->msg[2], acb->msg[3], acb->msg[4]);
972 1.6 mhitch if (acb->msg[1] == MSG_EXT_MESSAGE &&
973 1.6 mhitch acb->msg[2] == 2 &&
974 1.6 mhitch acb->msg[3] == MSG_WIDE_REQ)
975 1.6 mhitch sc->sc_sync[target].scntl3 = acb->msg[4] ?
976 1.6 mhitch sc->sc_sync[target].scntl3 | SIOP_SCNTL3_EWS :
977 1.6 mhitch sc->sc_sync[target].scntl3 & ~SIOP_SCNTL3_EWS;
978 1.6 mhitch }
979 1.6 mhitch sc->sc_sync[target].state = NEG_SYNC;
980 1.6 mhitch }
981 1.6 mhitch if (sc->sc_sync[target].state == NEG_WAITS) {
982 1.6 mhitch if (acb->msg[1] == 0xff)
983 1.6 mhitch printf ("%s: target %d ignored sync request\n",
984 1.6 mhitch sc->sc_dev.dv_xname, target);
985 1.6 mhitch else if (acb->msg[1] == MSG_REJECT)
986 1.6 mhitch printf ("%s: target %d rejected sync request\n",
987 1.6 mhitch sc->sc_dev.dv_xname, target);
988 1.6 mhitch else
989 1.6 mhitch /* XXX - need to set sync transfer parameters */
990 1.6 mhitch printf("%s: target %d (sync) %02x %02x %02x\n",
991 1.6 mhitch sc->sc_dev.dv_xname, target, acb->msg[1],
992 1.6 mhitch acb->msg[2], acb->msg[3]);
993 1.6 mhitch sc->sc_sync[target].state = NEG_DONE;
994 1.6 mhitch }
995 1.6 mhitch dma_cachectl(&acb->stat[0], 1);
996 1.6 mhitch *status = acb->stat[0];
997 1.6 mhitch #ifdef DEBUG
998 1.6 mhitch if (rp->siop_sbcl & SIOP_BSY) {
999 1.6 mhitch /*printf ("ACK! siop was busy at end: rp %x script %x dsa %x\n",
1000 1.6 mhitch rp, &siopng_scripts, &acb->ds);*/
1001 1.6 mhitch #ifdef DDB
1002 1.6 mhitch /*Debugger();*/
1003 1.6 mhitch #endif
1004 1.6 mhitch }
1005 1.6 mhitch if (acb->msg[0] != 0x00)
1006 1.6 mhitch printf("%s: message was not COMMAND COMPLETE: %x\n",
1007 1.6 mhitch sc->sc_dev.dv_xname, acb->msg[0]);
1008 1.6 mhitch #endif
1009 1.6 mhitch if (sc->nexus_list.tqh_first)
1010 1.6 mhitch rp->siop_dcntl |= SIOP_DCNTL_STD;
1011 1.6 mhitch return 1;
1012 1.6 mhitch }
1013 1.6 mhitch if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff0b) {
1014 1.15 bouyer target = acb->xs->xs_periph->periph_target;
1015 1.6 mhitch if (acb->msg[1] == MSG_EXT_MESSAGE && acb->msg[2] == 2 &&
1016 1.6 mhitch acb->msg[3] == MSG_WIDE_REQ) {
1017 1.6 mhitch #ifdef DEBUG
1018 1.6 mhitch if (siopngsync_debug)
1019 1.6 mhitch printf ("wide msg in: %02x %02x %02x %02x %02x %02x\n",
1020 1.6 mhitch acb->msg[0], acb->msg[1], acb->msg[2],
1021 1.6 mhitch acb->msg[3], acb->msg[4], acb->msg[5]);
1022 1.6 mhitch #endif
1023 1.6 mhitch sc->sc_sync[target].scntl3 &= ~(SIOP_SCNTL3_EWS);
1024 1.6 mhitch if (acb->msg[2] == 2 &&
1025 1.6 mhitch acb->msg[3] == MSG_WIDE_REQ &&
1026 1.6 mhitch acb->msg[4] != 0) {
1027 1.6 mhitch sc->sc_sync[target].scntl3 |= SIOP_SCNTL3_EWS;
1028 1.6 mhitch printf ("%s: target %d now wide %d\n",
1029 1.6 mhitch sc->sc_dev.dv_xname, target,
1030 1.6 mhitch acb->msg[4]);
1031 1.6 mhitch }
1032 1.6 mhitch rp->siop_scntl3 = sc->sc_sync[target].scntl3;
1033 1.6 mhitch if (sc->sc_sync[target].state == NEG_WAITW) {
1034 1.6 mhitch sc->sc_sync[target].state = NEG_SYNC;
1035 1.6 mhitch rp->siop_dsp = sc->sc_scriptspa + Ent_clear_ack;
1036 1.6 mhitch return(0);
1037 1.6 mhitch }
1038 1.6 mhitch rp->siop_dcntl |= SIOP_DCNTL_STD;
1039 1.6 mhitch sc->sc_sync[target].state = NEG_SYNC;
1040 1.6 mhitch return (0);
1041 1.6 mhitch }
1042 1.6 mhitch if (acb->msg[1] == MSG_EXT_MESSAGE && acb->msg[2] == 3 &&
1043 1.6 mhitch acb->msg[3] == MSG_SYNC_REQ) {
1044 1.1 is #ifdef DEBUG
1045 1.1 is if (siopngsync_debug)
1046 1.1 is printf ("sync msg in: %02x %02x %02x %02x %02x %02x\n",
1047 1.1 is acb->msg[0], acb->msg[1], acb->msg[2],
1048 1.1 is acb->msg[3], acb->msg[4], acb->msg[5]);
1049 1.1 is #endif
1050 1.1 is sc->sc_sync[target].sxfer = 0;
1051 1.6 mhitch sc->sc_sync[target].scntl3 = 5 | /* XXX */
1052 1.6 mhitch (sc->sc_sync[target].scntl3 & 0x88); /* XXX */
1053 1.1 is if (acb->msg[2] == 3 &&
1054 1.1 is acb->msg[3] == MSG_SYNC_REQ &&
1055 1.1 is acb->msg[5] != 0) {
1056 1.1 is #ifdef MAXTOR_KLUDGE
1057 1.1 is /*
1058 1.1 is * Kludge for my Maxtor XT8580S
1059 1.1 is * It accepts whatever we request, even
1060 1.1 is * though it won't work. So we ask for
1061 1.1 is * a short period than we can handle. If
1062 1.1 is * the device says it can do it, use 208ns.
1063 1.1 is * If the device says it can do less than
1064 1.1 is * 100ns, then we limit it to 100ns.
1065 1.1 is */
1066 1.1 is if (acb->msg[4] && acb->msg[4] < 100 / 4) {
1067 1.1 is #ifdef DEBUG
1068 1.1 is printf ("%d: target %d wanted %dns period\n",
1069 1.1 is sc->sc_dev.dv_xname, target,
1070 1.1 is acb->msg[4] * 4);
1071 1.1 is #endif
1072 1.1 is if (acb->msg[4] == 50 / 4)
1073 1.1 is acb->msg[4] = 208 / 4;
1074 1.1 is else
1075 1.1 is acb->msg[4] = 100 / 4;
1076 1.1 is }
1077 1.1 is #endif /* MAXTOR_KLUDGE */
1078 1.1 is printf ("%s: target %d now synchronous, period=%dns, offset=%d\n",
1079 1.1 is sc->sc_dev.dv_xname, target,
1080 1.11 mhitch (acb->msg[4] == 12) ? 50 : acb->msg[4] * 4,
1081 1.11 mhitch acb->msg[5]);
1082 1.1 is scsi_period_to_siopng (sc, target);
1083 1.1 is }
1084 1.6 mhitch rp->siop_sxfer = sc->sc_sync[target].sxfer;
1085 1.6 mhitch rp->siop_scntl3 = sc->sc_sync[target].scntl3;
1086 1.6 mhitch if (sc->sc_sync[target].state == NEG_WAITS) {
1087 1.6 mhitch sc->sc_sync[target].state = NEG_DONE;
1088 1.6 mhitch rp->siop_dsp = sc->sc_scriptspa + Ent_clear_ack;
1089 1.6 mhitch return(0);
1090 1.6 mhitch }
1091 1.6 mhitch rp->siop_dcntl |= SIOP_DCNTL_STD;
1092 1.6 mhitch sc->sc_sync[target].state = NEG_DONE;
1093 1.6 mhitch return (0);
1094 1.1 is }
1095 1.6 mhitch /* XXX - not SDTR message */
1096 1.1 is }
1097 1.1 is if (sist & SIOP_SIST_MA) { /* Phase mismatch */
1098 1.1 is #ifdef DEBUG
1099 1.1 is ++siopngphmm;
1100 1.1 is if (acb == NULL)
1101 1.1 is printf("%s: Phase mismatch with no active command?\n",
1102 1.1 is sc->sc_dev.dv_xname);
1103 1.1 is #endif
1104 1.1 is if (acb->iob_len) {
1105 1.1 is int adjust;
1106 1.1 is adjust = ((dfifo - (dbc & 0x7f)) & 0x7f);
1107 1.6 mhitch if (sstat0 & SIOP_SSTAT0_OLF) /* sstat0 SODL lsb */
1108 1.3 is ++adjust;
1109 1.9 mhitch if (sstat0 & SIOP_SSTAT0_ORF) /* sstat0 SODR lsb */
1110 1.3 is ++adjust;
1111 1.6 mhitch if (sstat2 & SIOP_SSTAT2_OLF1) /* sstat2 SODL msb */
1112 1.1 is ++adjust;
1113 1.9 mhitch if (sstat2 & SIOP_SSTAT2_ORF1) /* sstat2 SODR msb */
1114 1.1 is ++adjust;
1115 1.1 is acb->iob_curlen = *((long *)&rp->siop_dcmd) & 0xffffff;
1116 1.1 is acb->iob_curlen += adjust;
1117 1.1 is acb->iob_curbuf = *((long *)&rp->siop_dnad) - adjust;
1118 1.1 is #ifdef DEBUG
1119 1.1 is if (siopng_debug & 0x100) {
1120 1.1 is int i;
1121 1.1 is printf ("Phase mismatch: curbuf %lx curlen %lx dfifo %x dbc %x sstat1 %x adjust %x sbcl %x starts %d acb %p\n",
1122 1.1 is acb->iob_curbuf, acb->iob_curlen, dfifo,
1123 1.1 is dbc, sstat1, adjust, rp->siop_sbcl, siopngstarts, acb);
1124 1.1 is if (acb->ds.chain[1].datalen) {
1125 1.1 is for (i = 0; acb->ds.chain[i].datalen; ++i)
1126 1.1 is printf("chain[%d] addr %p len %lx\n",
1127 1.1 is i, acb->ds.chain[i].databuf,
1128 1.1 is acb->ds.chain[i].datalen);
1129 1.1 is }
1130 1.1 is }
1131 1.1 is #endif
1132 1.1 is dma_cachectl ((caddr_t)acb, sizeof(*acb));
1133 1.1 is }
1134 1.1 is #ifdef DEBUG
1135 1.1 is SIOP_TRACE('m',rp->siop_sbcl,(rp->siop_dsp>>8),rp->siop_dsp);
1136 1.1 is if (siopng_debug & 9)
1137 1.1 is printf ("Phase mismatch: %x dsp +%lx dcmd %lx\n",
1138 1.1 is rp->siop_sbcl,
1139 1.1 is rp->siop_dsp - sc->sc_scriptspa,
1140 1.1 is *((long *)&rp->siop_dcmd));
1141 1.1 is #endif
1142 1.1 is if ((rp->siop_sbcl & SIOP_REQ) == 0) {
1143 1.1 is printf ("Phase mismatch: REQ not asserted! %02x dsp %lx\n",
1144 1.1 is rp->siop_sbcl, rp->siop_dsp);
1145 1.1 is #if defined(DEBUG) && defined(DDB)
1146 1.1 is Debugger();
1147 1.1 is #endif
1148 1.1 is }
1149 1.1 is switch (rp->siop_sbcl & 7) {
1150 1.1 is case 0: /* data out */
1151 1.1 is case 1: /* data in */
1152 1.1 is case 2: /* status */
1153 1.1 is case 3: /* command */
1154 1.1 is case 6: /* message in */
1155 1.1 is case 7: /* message out */
1156 1.1 is rp->siop_dsp = sc->sc_scriptspa + Ent_switch;
1157 1.1 is break;
1158 1.1 is default:
1159 1.1 is goto bad_phase;
1160 1.1 is }
1161 1.1 is return 0;
1162 1.1 is }
1163 1.1 is if (sist & SIOP_SIST_STO) { /* Select timed out */
1164 1.1 is #ifdef DEBUG
1165 1.1 is if (acb == NULL)
1166 1.1 is printf("%s: Select timeout with no active command?\n",
1167 1.1 is sc->sc_dev.dv_xname);
1168 1.1 is if (rp->siop_sbcl & SIOP_BSY) {
1169 1.1 is printf ("ACK! siop was busy at timeout: rp %p script %p dsa %p\n",
1170 1.2 is rp, &siopng_scripts, &acb->ds);
1171 1.1 is printf(" sbcl %x sdid %x istat %x dstat %x sist %x\n",
1172 1.1 is rp->siop_sbcl, rp->siop_sdid, istat, dstat, sist);
1173 1.1 is if (!(rp->siop_sbcl & SIOP_BSY)) {
1174 1.1 is printf ("Yikes, it's not busy now!\n");
1175 1.1 is #if 0
1176 1.1 is *status = -1;
1177 1.1 is if (sc->nexus_list.tqh_first)
1178 1.1 is rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect;
1179 1.1 is return 1;
1180 1.1 is #endif
1181 1.1 is }
1182 1.1 is /* rp->siop_dcntl |= SIOP_DCNTL_STD;*/
1183 1.1 is return (0);
1184 1.1 is #ifdef DDB
1185 1.1 is Debugger();
1186 1.1 is #endif
1187 1.1 is }
1188 1.1 is #endif
1189 1.1 is *status = -1;
1190 1.1 is acb->xs->error = XS_SELTIMEOUT;
1191 1.1 is if (sc->nexus_list.tqh_first)
1192 1.1 is rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect;
1193 1.1 is return 1;
1194 1.1 is }
1195 1.1 is if (acb)
1196 1.15 bouyer target = acb->xs->xs_periph->periph_target;
1197 1.1 is else
1198 1.1 is target = 7;
1199 1.1 is if (sist & SIOP_SIST_UDC) {
1200 1.1 is #ifdef DEBUG
1201 1.1 is if (acb == NULL)
1202 1.1 is printf("%s: Unexpected disconnect with no active command?\n",
1203 1.1 is sc->sc_dev.dv_xname);
1204 1.1 is printf ("%s: target %d disconnected unexpectedly\n",
1205 1.1 is sc->sc_dev.dv_xname, target);
1206 1.1 is siopng_dump_registers(sc);
1207 1.1 is siopng_dump(sc);
1208 1.1 is #endif
1209 1.1 is #if 0
1210 1.1 is siopngabort (sc, rp, "siopngchkintr");
1211 1.1 is #endif
1212 1.1 is *status = STS_BUSY;
1213 1.1 is if (sc->nexus_list.tqh_first)
1214 1.1 is rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect;
1215 1.1 is return (acb != NULL);
1216 1.1 is }
1217 1.1 is if (dstat & SIOP_DSTAT_SIR && (rp->siop_dsps == 0xff01 ||
1218 1.1 is rp->siop_dsps == 0xff02)) {
1219 1.1 is #ifdef DEBUG
1220 1.1 is if (siopng_debug & 0x100)
1221 1.1 is printf ("%s: ID %02x disconnected TEMP %lx (+%lx) curbuf %lx curlen %lx buf %p len %lx dfifo %x dbc %x sstat1 %x starts %d acb %p\n",
1222 1.1 is sc->sc_dev.dv_xname, 1 << target, rp->siop_temp,
1223 1.1 is rp->siop_temp ? rp->siop_temp - sc->sc_scriptspa : 0,
1224 1.1 is acb->iob_curbuf, acb->iob_curlen,
1225 1.1 is acb->ds.chain[0].databuf, acb->ds.chain[0].datalen, dfifo, dbc, sstat1, siopngstarts, acb);
1226 1.1 is #endif
1227 1.1 is if (acb == NULL) {
1228 1.1 is printf("%s: Disconnect with no active command?\n",
1229 1.1 is sc->sc_dev.dv_xname);
1230 1.1 is return (0);
1231 1.1 is }
1232 1.1 is /*
1233 1.1 is * XXXX need to update iob_curbuf/iob_curlen to reflect
1234 1.1 is * current data transferred. If device disconnected in
1235 1.1 is * the middle of a DMA block, they should already be set
1236 1.1 is * by the phase change interrupt. If the disconnect
1237 1.1 is * occurs on a DMA block boundary, we have to figure out
1238 1.1 is * which DMA block it was.
1239 1.1 is */
1240 1.1 is if (acb->iob_len && rp->siop_temp) {
1241 1.1 is int n = rp->siop_temp - sc->sc_scriptspa;
1242 1.1 is
1243 1.1 is if (acb->iob_curlen && acb->iob_curlen != acb->ds.chain[0].datalen)
1244 1.1 is printf("%s: iob_curbuf/len already set? n %x iob %lx/%lx chain[0] %p/%lx\n",
1245 1.1 is sc->sc_dev.dv_xname, n, acb->iob_curbuf, acb->iob_curlen,
1246 1.1 is acb->ds.chain[0].databuf, acb->ds.chain[0].datalen);
1247 1.1 is if (n < Ent_datain)
1248 1.1 is n = (n - Ent_dataout) / 16;
1249 1.1 is else
1250 1.1 is n = (n - Ent_datain) / 16;
1251 1.1 is if (n <= 0 && n > DMAMAXIO)
1252 1.1 is printf("TEMP invalid %d\n", n);
1253 1.1 is else {
1254 1.1 is acb->iob_curbuf = (u_long)acb->ds.chain[n].databuf;
1255 1.1 is acb->iob_curlen = acb->ds.chain[n].datalen;
1256 1.1 is }
1257 1.1 is #ifdef DEBUG
1258 1.1 is if (siopng_debug & 0x100) {
1259 1.1 is printf("%s: TEMP offset %d", sc->sc_dev.dv_xname, n);
1260 1.1 is printf(" curbuf %lx curlen %lx\n", acb->iob_curbuf,
1261 1.1 is acb->iob_curlen);
1262 1.1 is }
1263 1.1 is #endif
1264 1.1 is }
1265 1.1 is /*
1266 1.1 is * If data transfer was interrupted by disconnect, iob_curbuf
1267 1.1 is * and iob_curlen should reflect the point of interruption.
1268 1.1 is * Adjust the DMA chain so that the data transfer begins
1269 1.1 is * at the appropriate place upon reselection.
1270 1.1 is * XXX This should only be done on save data pointer message?
1271 1.1 is */
1272 1.1 is if (acb->iob_curlen) {
1273 1.1 is int i, j;
1274 1.1 is
1275 1.1 is #ifdef DEBUG
1276 1.1 is if (siopng_debug & 0x100)
1277 1.1 is printf ("%s: adjusting DMA chain\n",
1278 1.1 is sc->sc_dev.dv_xname);
1279 1.1 is if (rp->siop_dsps == 0xff02)
1280 1.1 is printf ("%s: ID %02x disconnected without Save Data Pointers\n",
1281 1.1 is sc->sc_dev.dv_xname, 1 << target);
1282 1.1 is #endif
1283 1.1 is for (i = 0; i < DMAMAXIO; ++i) {
1284 1.1 is if (acb->ds.chain[i].datalen == 0)
1285 1.1 is break;
1286 1.1 is if (acb->iob_curbuf >= (long)acb->ds.chain[i].databuf &&
1287 1.1 is acb->iob_curbuf < (long)(acb->ds.chain[i].databuf +
1288 1.1 is acb->ds.chain[i].datalen))
1289 1.1 is break;
1290 1.1 is }
1291 1.1 is if (i >= DMAMAXIO || acb->ds.chain[i].datalen == 0) {
1292 1.1 is printf("couldn't find saved data pointer: ");
1293 1.1 is printf("curbuf %lx curlen %lx i %d\n",
1294 1.1 is acb->iob_curbuf, acb->iob_curlen, i);
1295 1.1 is #ifdef DDB
1296 1.1 is Debugger();
1297 1.1 is #endif
1298 1.1 is }
1299 1.1 is #ifdef DEBUG
1300 1.1 is if (siopng_debug & 0x100)
1301 1.1 is printf(" chain[0]: %p/%lx -> %lx/%lx\n",
1302 1.1 is acb->ds.chain[0].databuf,
1303 1.1 is acb->ds.chain[0].datalen,
1304 1.1 is acb->iob_curbuf,
1305 1.1 is acb->iob_curlen);
1306 1.1 is #endif
1307 1.1 is acb->ds.chain[0].databuf = (char *)acb->iob_curbuf;
1308 1.1 is acb->ds.chain[0].datalen = acb->iob_curlen;
1309 1.1 is for (j = 1, ++i; i < DMAMAXIO && acb->ds.chain[i].datalen; ++i, ++j) {
1310 1.1 is #ifdef DEBUG
1311 1.1 is if (siopng_debug & 0x100)
1312 1.1 is printf(" chain[%d]: %p/%lx -> %p/%lx\n", j,
1313 1.1 is acb->ds.chain[j].databuf,
1314 1.1 is acb->ds.chain[j].datalen,
1315 1.1 is acb->ds.chain[i].databuf,
1316 1.1 is acb->ds.chain[i].datalen);
1317 1.1 is #endif
1318 1.1 is acb->ds.chain[j].databuf = acb->ds.chain[i].databuf;
1319 1.1 is acb->ds.chain[j].datalen = acb->ds.chain[i].datalen;
1320 1.1 is }
1321 1.1 is if (j < DMAMAXIO)
1322 1.1 is acb->ds.chain[j].datalen = 0;
1323 1.1 is DCIAS(kvtop((caddr_t)&acb->ds.chain));
1324 1.1 is }
1325 1.1 is ++sc->sc_tinfo[target].dconns;
1326 1.1 is /*
1327 1.1 is * add nexus to waiting list
1328 1.1 is * clear nexus
1329 1.1 is * try to start another command for another target/lun
1330 1.1 is */
1331 1.1 is acb->status = sc->sc_flags & SIOP_INTSOFF;
1332 1.1 is TAILQ_INSERT_HEAD(&sc->nexus_list, acb, chain);
1333 1.1 is sc->sc_nexus = NULL; /* no current device */
1334 1.1 is /* start script to wait for reselect */
1335 1.1 is if (sc->sc_nexus == NULL)
1336 1.1 is rp->siop_dsp = sc->sc_scriptspa + Ent_wait_reselect;
1337 1.1 is /* XXXX start another command ? */
1338 1.1 is if (sc->ready_list.tqh_first)
1339 1.1 is siopng_sched(sc);
1340 1.1 is #if 0
1341 1.1 is else
1342 1.1 is rp->siop_dcntl |= SIOP_DCNTL_STD;
1343 1.1 is #endif
1344 1.1 is return (0);
1345 1.1 is }
1346 1.1 is if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff03) {
1347 1.1 is int reselid = rp->siop_scratcha & 0x7f;
1348 1.1 is int reselun = rp->siop_sfbr & 0x07;
1349 1.1 is
1350 1.1 is sc->sc_sstat1 = rp->siop_sbcl; /* XXXX save current SBCL */
1351 1.1 is #ifdef DEBUG
1352 1.1 is if (siopng_debug & 0x100)
1353 1.1 is printf ("%s: target ID %02x reselected dsps %lx\n",
1354 1.1 is sc->sc_dev.dv_xname, reselid,
1355 1.1 is rp->siop_dsps);
1356 1.1 is if ((rp->siop_sfbr & 0x80) == 0)
1357 1.1 is printf("%s: Reselect message in was not identify: %x\n",
1358 1.1 is sc->sc_dev.dv_xname, rp->siop_sfbr);
1359 1.1 is #endif
1360 1.1 is if (sc->sc_nexus) {
1361 1.1 is #ifdef DEBUG
1362 1.1 is if (siopng_debug & 0x100)
1363 1.1 is printf ("%s: reselect ID %02x w/active\n",
1364 1.1 is sc->sc_dev.dv_xname, reselid);
1365 1.1 is #endif
1366 1.1 is TAILQ_INSERT_HEAD(&sc->ready_list, sc->sc_nexus, chain);
1367 1.15 bouyer sc->sc_tinfo[sc->sc_nexus->xs->xs_periph->periph_target].lubusy
1368 1.15 bouyer &= ~(1 << sc->sc_nexus->xs->xs_periph->periph_lun);
1369 1.1 is --sc->sc_active;
1370 1.1 is }
1371 1.1 is /*
1372 1.1 is * locate acb of reselecting device
1373 1.1 is * set sc->sc_nexus to acb
1374 1.1 is */
1375 1.1 is for (acb = sc->nexus_list.tqh_first; acb;
1376 1.1 is acb = acb->chain.tqe_next) {
1377 1.1 is if (reselid != ((acb->ds.scsi_addr >> 16) & 0xff) ||
1378 1.1 is reselun != (acb->msgout[0] & 0x07))
1379 1.1 is continue;
1380 1.1 is TAILQ_REMOVE(&sc->nexus_list, acb, chain);
1381 1.1 is sc->sc_nexus = acb;
1382 1.1 is sc->sc_flags |= acb->status;
1383 1.1 is acb->status = 0;
1384 1.1 is DCIAS(kvtop(&acb->stat[0]));
1385 1.1 is rp->siop_dsa = kvtop((caddr_t)&acb->ds);
1386 1.1 is rp->siop_sxfer =
1387 1.15 bouyer sc->sc_sync[acb->xs->xs_periph->periph_target].sxfer;
1388 1.1 is #ifndef FIXME
1389 1.1 is rp->siop_scntl3 =
1390 1.15 bouyer sc->sc_sync[acb->xs->xs_periph->periph_target].scntl3;
1391 1.1 is #endif
1392 1.1 is break;
1393 1.1 is }
1394 1.1 is if (acb == NULL) {
1395 1.1 is printf("%s: target ID %02x reselect nexus_list %p\n",
1396 1.1 is sc->sc_dev.dv_xname, reselid,
1397 1.1 is sc->nexus_list.tqh_first);
1398 1.1 is panic("unable to find reselecting device");
1399 1.1 is }
1400 1.1 is dma_cachectl ((caddr_t)acb, sizeof(*acb));
1401 1.1 is rp->siop_temp = 0;
1402 1.1 is rp->siop_dcntl |= SIOP_DCNTL_STD;
1403 1.1 is return (0);
1404 1.1 is }
1405 1.1 is if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff04) {
1406 1.1 is #ifdef DEBUG
1407 1.1 is u_short ctest2 = rp->siop_ctest2;
1408 1.1 is
1409 1.1 is /* reselect was interrupted (by Sig_P or select) */
1410 1.1 is if (siopng_debug & 0x100 ||
1411 1.1 is (ctest2 & SIOP_CTEST2_SIGP) == 0)
1412 1.1 is printf ("%s: reselect interrupted (Sig_P?) scntl1 %x ctest2 %x sfbr %x istat %x/%x\n",
1413 1.1 is sc->sc_dev.dv_xname, rp->siop_scntl1,
1414 1.1 is ctest2, rp->siop_sfbr, istat, rp->siop_istat);
1415 1.1 is #endif
1416 1.1 is /* XXX assumes it was not select */
1417 1.1 is if (sc->sc_nexus == NULL) {
1418 1.1 is #ifdef DEBUG
1419 1.1 is printf("%s: reselect interrupted, sc_nexus == NULL\n",
1420 1.1 is sc->sc_dev.dv_xname);
1421 1.1 is #if 0
1422 1.1 is siopng_dump(sc);
1423 1.1 is #ifdef DDB
1424 1.1 is Debugger();
1425 1.1 is #endif
1426 1.1 is #endif
1427 1.1 is #endif
1428 1.1 is rp->siop_dcntl |= SIOP_DCNTL_STD;
1429 1.1 is return(0);
1430 1.1 is }
1431 1.15 bouyer target = sc->sc_nexus->xs->xs_periph->periph_target;
1432 1.1 is rp->siop_temp = 0;
1433 1.1 is rp->siop_dsa = kvtop((caddr_t)&sc->sc_nexus->ds);
1434 1.1 is rp->siop_sxfer = sc->sc_sync[target].sxfer;
1435 1.1 is #ifndef FIXME
1436 1.6 mhitch rp->siop_scntl3 = sc->sc_sync[target].scntl3;
1437 1.1 is #endif
1438 1.1 is rp->siop_dsp = sc->sc_scriptspa;
1439 1.1 is return (0);
1440 1.1 is }
1441 1.1 is if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff06) {
1442 1.1 is if (acb == NULL)
1443 1.1 is printf("%s: Bad message-in with no active command?\n",
1444 1.1 is sc->sc_dev.dv_xname);
1445 1.1 is /* Unrecognized message in byte */
1446 1.1 is dma_cachectl (&acb->msg[1],1);
1447 1.1 is printf ("%s: Unrecognized message in data sfbr %x msg %x sbcl %x\n",
1448 1.1 is sc->sc_dev.dv_xname, rp->siop_sfbr, acb->msg[1], rp->siop_sbcl);
1449 1.1 is /* what should be done here? */
1450 1.1 is DCIAS(kvtop(&acb->msg[1]));
1451 1.1 is rp->siop_dsp = sc->sc_scriptspa + Ent_switch;
1452 1.1 is return (0);
1453 1.1 is }
1454 1.1 is if (dstat & SIOP_DSTAT_SIR && rp->siop_dsps == 0xff0a) {
1455 1.1 is /* Status phase wasn't followed by message in phase? */
1456 1.1 is printf ("%s: Status phase not followed by message in phase? sbcl %x sbdl %x\n",
1457 1.1 is sc->sc_dev.dv_xname, rp->siop_sbcl, rp->siop_sbdl);
1458 1.1 is if (rp->siop_sbcl == 0xa7) {
1459 1.1 is /* It is now, just continue the script? */
1460 1.1 is rp->siop_dcntl |= SIOP_DCNTL_STD;
1461 1.1 is return (0);
1462 1.1 is }
1463 1.1 is }
1464 1.1 is if (sist == 0 && dstat & SIOP_DSTAT_SIR) {
1465 1.1 is dma_cachectl (&acb->stat[0], 1);
1466 1.1 is dma_cachectl (&acb->msg[0], 1);
1467 1.1 is printf ("SIOP interrupt: %lx sts %x msg %x %x sbcl %x\n",
1468 1.1 is rp->siop_dsps, acb->stat[0], acb->msg[0], acb->msg[1],
1469 1.1 is rp->siop_sbcl);
1470 1.1 is siopngreset (sc);
1471 1.1 is *status = -1;
1472 1.1 is return 0; /* siopngreset has cleaned up */
1473 1.1 is }
1474 1.1 is if (sist & SIOP_SIST_SGE)
1475 1.1 is printf ("SIOP: SCSI Gross Error\n");
1476 1.1 is if (sist & SIOP_SIST_PAR)
1477 1.1 is printf ("SIOP: Parity Error\n");
1478 1.1 is if (dstat & SIOP_DSTAT_IID)
1479 1.1 is printf ("SIOP: Invalid instruction detected\n");
1480 1.1 is bad_phase:
1481 1.1 is /*
1482 1.1 is * temporary panic for unhandled conditions
1483 1.1 is * displays various things about the 53C720/770 status and registers
1484 1.1 is * then panics.
1485 1.1 is * XXXX need to clean this up to print out the info, reset, and continue
1486 1.1 is */
1487 1.1 is printf ("siopngchkintr: target %x ds %p\n", target, &acb->ds);
1488 1.1 is printf ("scripts %lx ds %x rp %x dsp %lx dcmd %lx\n", sc->sc_scriptspa,
1489 1.1 is kvtop((caddr_t)&acb->ds), kvtop((caddr_t)rp), rp->siop_dsp,
1490 1.1 is *((long *)&rp->siop_dcmd));
1491 1.1 is printf ("siopngchkintr: istat %x dstat %x sist %x dsps %lx dsa %lx sbcl %x sts %x msg %x %x sfbr %x\n",
1492 1.1 is istat, dstat, sist, rp->siop_dsps, rp->siop_dsa,
1493 1.1 is rp->siop_sbcl, acb->stat[0], acb->msg[0], acb->msg[1], rp->siop_sfbr);
1494 1.1 is #ifdef DEBUG
1495 1.1 is if (siopng_debug & 0x20)
1496 1.1 is panic("siopngchkintr: **** temp ****");
1497 1.1 is #endif
1498 1.1 is #ifdef DDB
1499 1.1 is Debugger ();
1500 1.1 is #endif
1501 1.1 is siopngreset (sc); /* hard reset */
1502 1.1 is *status = -1;
1503 1.1 is return 0; /* siopngreset cleaned up */
1504 1.1 is }
1505 1.1 is
1506 1.1 is void
1507 1.17 aymeric siopng_select(struct siop_softc *sc)
1508 1.1 is {
1509 1.1 is siop_regmap_p rp;
1510 1.1 is struct siop_acb *acb = sc->sc_nexus;
1511 1.1 is
1512 1.1 is #ifdef DEBUG
1513 1.1 is if (siopng_debug & 1)
1514 1.1 is printf ("%s: select ", sc->sc_dev.dv_xname);
1515 1.1 is #endif
1516 1.1 is
1517 1.1 is rp = sc->sc_siopp;
1518 1.14 thorpej if (acb->xs->xs_control & XS_CTL_POLL || siopng_no_dma) {
1519 1.1 is sc->sc_flags |= SIOP_INTSOFF;
1520 1.1 is sc->sc_flags &= ~SIOP_INTDEFER;
1521 1.1 is if ((rp->siop_istat & 0x08) == 0) {
1522 1.1 is rp->siop_sien = 0;
1523 1.1 is rp->siop_dien = 0;
1524 1.1 is }
1525 1.1 is #if 0
1526 1.1 is } else if ((sc->sc_flags & SIOP_INTDEFER) == 0) {
1527 1.1 is sc->sc_flags &= ~SIOP_INTSOFF;
1528 1.1 is if ((rp->siop_istat & 0x08) == 0) {
1529 1.1 is rp->siop_sien = sc->sc_sien;
1530 1.1 is rp->siop_dien = sc->sc_dien;
1531 1.1 is }
1532 1.1 is #endif
1533 1.1 is }
1534 1.1 is #ifdef DEBUG
1535 1.1 is if (siopng_debug & 1)
1536 1.1 is printf ("siopng_select: target %x cmd %02x ds %p\n",
1537 1.15 bouyer acb->xs->xs_periph->periph_target, acb->cmd.opcode,
1538 1.1 is &sc->sc_nexus->ds);
1539 1.1 is #endif
1540 1.1 is
1541 1.15 bouyer siopng_start(sc, acb->xs->xs_periph->periph_target,
1542 1.15 bouyer acb->xs->xs_periph->periph_lun,
1543 1.1 is (u_char *)&acb->cmd, acb->clen, acb->daddr, acb->dleft);
1544 1.1 is
1545 1.1 is return;
1546 1.1 is }
1547 1.1 is
1548 1.1 is /*
1549 1.1 is * 53C720/770 interrupt handler
1550 1.1 is */
1551 1.1 is
1552 1.1 is void
1553 1.17 aymeric siopngintr(register struct siop_softc *sc)
1554 1.1 is {
1555 1.1 is siop_regmap_p rp;
1556 1.1 is u_char istat, dstat;
1557 1.1 is u_short sist;
1558 1.1 is int status;
1559 1.1 is int s = splbio();
1560 1.1 is
1561 1.1 is istat = sc->sc_istat;
1562 1.1 is if ((istat & (SIOP_ISTAT_SIP | SIOP_ISTAT_DIP)) == 0) {
1563 1.1 is splx(s);
1564 1.1 is return;
1565 1.1 is }
1566 1.1 is
1567 1.1 is /* Got a valid interrupt on this device */
1568 1.1 is rp = sc->sc_siopp;
1569 1.1 is dstat = sc->sc_dstat;
1570 1.1 is sist = sc->sc_sist;
1571 1.1 is if (dstat & SIOP_DSTAT_SIR)
1572 1.1 is sc->sc_intcode = rp->siop_dsps;
1573 1.1 is sc->sc_istat = 0;
1574 1.1 is #ifdef DEBUG
1575 1.1 is if (siopng_debug & 1)
1576 1.1 is printf ("%s: intr istat %x dstat %x sist %x\n",
1577 1.1 is sc->sc_dev.dv_xname, istat, dstat, sist);
1578 1.1 is if (!sc->sc_active) {
1579 1.1 is printf ("%s: spurious interrupt? istat %x dstat %x sist %x nexus %p status %x\n",
1580 1.1 is sc->sc_dev.dv_xname, istat, dstat, sist,
1581 1.1 is sc->sc_nexus, sc->sc_nexus ? sc->sc_nexus->stat[0] : 0);
1582 1.1 is }
1583 1.1 is #endif
1584 1.1 is
1585 1.1 is #ifdef DEBUG
1586 1.1 is if (siopng_debug & 5) {
1587 1.1 is DCIAS(kvtop(&sc->sc_nexus->stat[0]));
1588 1.1 is printf ("%s: intr istat %x dstat %x sist %x dsps %lx sbcl %x sts %x msg %x\n",
1589 1.1 is sc->sc_dev.dv_xname, istat, dstat, sist,
1590 1.1 is rp->siop_dsps, rp->siop_sbcl,
1591 1.1 is sc->sc_nexus->stat[0], sc->sc_nexus->msg[0]);
1592 1.1 is }
1593 1.1 is #endif
1594 1.1 is if (sc->sc_flags & SIOP_INTDEFER) {
1595 1.1 is sc->sc_flags &= ~(SIOP_INTDEFER | SIOP_INTSOFF);
1596 1.1 is rp->siop_sien = sc->sc_sien;
1597 1.1 is rp->siop_dien = sc->sc_dien;
1598 1.1 is }
1599 1.1 is if (siopng_checkintr (sc, istat, dstat, sist, &status)) {
1600 1.1 is #if 1
1601 1.1 is if (status == 0xff)
1602 1.1 is printf ("siopngintr: status == 0xff\n");
1603 1.1 is #endif
1604 1.1 is if ((sc->sc_flags & (SIOP_INTSOFF | SIOP_INTDEFER)) != SIOP_INTSOFF) {
1605 1.1 is #if 0
1606 1.1 is if (rp->siop_sbcl & SIOP_BSY) {
1607 1.1 is printf ("%s: SCSI bus busy at completion",
1608 1.1 is sc->sc_dev.dv_xname);
1609 1.1 is printf(" targ %d sbcl %02x sfbr %x respid %02x dsp +%x\n",
1610 1.15 bouyer sc->sc_nexus->xs->xs_periph->periph_target,
1611 1.1 is rp->siop_sbcl, rp->siop_sfbr, rp->siop_respid,
1612 1.1 is rp->siop_dsp - sc->sc_scriptspa);
1613 1.1 is }
1614 1.1 is #endif
1615 1.1 is siopng_scsidone(sc->sc_nexus, sc->sc_nexus ?
1616 1.1 is sc->sc_nexus->stat[0] : -1);
1617 1.1 is }
1618 1.1 is }
1619 1.1 is splx(s);
1620 1.1 is }
1621 1.1 is
1622 1.1 is /*
1623 1.1 is * This is based on the Progressive Peripherals 33Mhz Zeus driver and will
1624 1.1 is * not be correct for other 53c710 boards.
1625 1.1 is *
1626 1.1 is */
1627 1.1 is void
1628 1.17 aymeric scsi_period_to_siopng(struct siop_softc *sc, int target)
1629 1.1 is {
1630 1.1 is int period, offset, sxfer, scntl3 = 0;
1631 1.1 is
1632 1.1 is period = sc->sc_nexus->msg[4];
1633 1.1 is offset = sc->sc_nexus->msg[5];
1634 1.1 is #ifdef FIXME
1635 1.1 is for (scntl3 = 1; scntl3 < 4; ++scntl3) {
1636 1.1 is sxfer = (period * 4 - 1) / sc->sc_tcp[scntl3] - 3;
1637 1.1 is if (sxfer >= 0 && sxfer <= 7)
1638 1.1 is break;
1639 1.1 is }
1640 1.1 is if (scntl3 > 3) {
1641 1.1 is printf("siopng sync: unable to compute sync params for period %dns\n",
1642 1.1 is period * 4);
1643 1.1 is /*
1644 1.1 is * XXX need to pick a value we can do and renegotiate
1645 1.1 is */
1646 1.1 is sxfer = scntl3 = 0;
1647 1.1 is } else {
1648 1.1 is sxfer = (sxfer << 4) | ((offset <= SIOP_MAX_OFFSET) ?
1649 1.1 is offset : SIOP_MAX_OFFSET);
1650 1.1 is #ifdef DEBUG_SYNC
1651 1.1 is printf("siopng sync: params for period %dns: sxfer %x scntl3 %x",
1652 1.1 is period * 4, sxfer, scntl3);
1653 1.1 is printf(" actual period %dns\n",
1654 1.1 is sc->sc_tcp[scntl3] * ((sxfer >> 4) + 4));
1655 1.1 is #endif /* DEBUG_SYNC */
1656 1.1 is }
1657 1.1 is #else /* FIXME */
1658 1.1 is sxfer = offset <= SIOP_MAX_OFFSET ? offset : SIOP_MAX_OFFSET;
1659 1.6 mhitch sxfer |= 0x20; /* XXX XFERP: 5 */
1660 1.1 is #ifndef FIXME
1661 1.6 mhitch if (period <= (50 / 4)) /* XXX */
1662 1.6 mhitch scntl3 = 0x95; /* Ultra, SCF: /1, CCF: /4 */
1663 1.6 mhitch else if (period <= (100 / 4))
1664 1.6 mhitch scntl3 = 0x35; /* SCF: /2, CCF: /4 */
1665 1.6 mhitch else if (period <= (200 / 4))
1666 1.6 mhitch scntl3 = 0x55; /* SCF: /4, CCF: /4 */
1667 1.6 mhitch else
1668 1.6 mhitch scntl3 = 0xff; /* XXX ??? */
1669 1.1 is #else
1670 1.1 is scntl3 = 5;
1671 1.1 is #endif
1672 1.1 is #endif
1673 1.1 is sc->sc_sync[target].sxfer = sxfer;
1674 1.6 mhitch sc->sc_sync[target].scntl3 = scntl3 |
1675 1.6 mhitch (sc->sc_sync[target].scntl3 & SIOP_SCNTL3_EWS);
1676 1.1 is #ifdef DEBUG_SYNC
1677 1.1 is printf ("siopng sync: siop_sxfr %02x, siop_scntl3 %02x\n", sxfer, scntl3);
1678 1.1 is #endif
1679 1.1 is }
1680 1.1 is
1681 1.1 is void
1682 1.17 aymeric siopng_dump_registers(struct siop_softc *sc)
1683 1.1 is {
1684 1.1 is siop_regmap_p rp = sc->sc_siopp;
1685 1.1 is
1686 1.1 is printf(" scntl0 %02x scntl1 %02x scntl2 %02x scntl3 %02x\n",
1687 1.1 is rp->siop_scntl0, rp->siop_scntl1, rp->siop_scntl2, rp->siop_scntl3);
1688 1.1 is printf(" scid %02x sxfer %02x sdid %02x gpreg %02x\n",
1689 1.1 is rp->siop_scid, rp->siop_sxfer, rp->siop_sdid, rp->siop_gpreg);
1690 1.1 is printf(" sfbr %02x socl %02x ssid %02x sbcl %02x\n",
1691 1.1 is rp->siop_sfbr, rp->siop_socl, rp->siop_ssid, rp->siop_sbcl);
1692 1.1 is printf(" dstat %02x sstat0 %02x sstat1 %02x sstat2 %02x\n",
1693 1.1 is rp->siop_dstat, rp->siop_sstat0, rp->siop_sstat1, rp->siop_sstat2);
1694 1.1 is printf(" ctest0 %02x ctest1 %02x ctest2 %02x ctest3 %02x\n",
1695 1.1 is rp->siop_ctest0, rp->siop_ctest1, rp->siop_ctest2, rp->siop_ctest3);
1696 1.1 is printf(" dfifo %02x ctest4 %02x ctest5 %02x ctest6 %02x\n",
1697 1.1 is 0, rp->siop_ctest4, rp->siop_ctest5, rp->siop_ctest6);
1698 1.1 is printf(" dcmd %02x dbc2 %02x dbc1 %02x dbc0 %02x\n",
1699 1.1 is rp->siop_dcmd, rp->siop_dbc2, rp->siop_dbc1, rp->siop_dbc0);
1700 1.1 is printf(" dmode %02x dien %02x dwt %02x dcntl %02x\n",
1701 1.1 is rp->siop_dmode, rp->siop_dien, rp->siop_dwt, rp->siop_dcntl);
1702 1.1 is printf(" stest0 %02x stest1 %02x stest2 %02x stest3 %02x\n",
1703 1.1 is rp->siop_stest0, rp->siop_stest1, rp->siop_stest2, rp->siop_stest3);
1704 1.1 is printf(" istat %02x sien %04x sist %04x respid %04x\n",
1705 1.1 is rp->siop_istat, rp->siop_sien, rp->siop_sist, rp->siop_respid);
1706 1.1 is printf(" sidl %04x sodl %04x sbdl %04x\n",
1707 1.1 is rp->siop_sidl, rp->siop_sodl, rp->siop_sbdl);
1708 1.1 is printf(" dsps %08lx dsp %08lx (+%lx)\n",
1709 1.1 is rp->siop_dsps, rp->siop_dsp, rp->siop_dsp > sc->sc_scriptspa ?
1710 1.1 is rp->siop_dsp - sc->sc_scriptspa : 0);
1711 1.1 is printf(" dsa %08lx temp %08lx dnad %08lx\n",
1712 1.1 is rp->siop_dsa, rp->siop_temp, rp->siop_dnad);
1713 1.1 is printf(" scratcha %08lx scratchb %08lx adder %08lx\n",
1714 1.1 is rp->siop_scratcha, rp->siop_scratchb, rp->siop_adder);
1715 1.1 is }
1716 1.1 is
1717 1.1 is #ifdef DEBUG
1718 1.1 is
1719 1.1 is #if SIOP_TRACE_SIZE
1720 1.1 is void
1721 1.17 aymeric siopng_dump_trace(void)
1722 1.1 is {
1723 1.1 is int i;
1724 1.1 is
1725 1.1 is printf("siopng trace: next index %d\n", siopng_trix);
1726 1.1 is i = siopng_trix;
1727 1.1 is do {
1728 1.1 is printf("%3d: '%c' %02x %02x %02x\n", i, siopng_trbuf[i],
1729 1.1 is siopng_trbuf[i + 1], siopng_trbuf[i + 2], siopng_trbuf[i + 3]);
1730 1.1 is i = (i + 4) & (SIOP_TRACE_SIZE - 1);
1731 1.1 is } while (i != siopng_trix);
1732 1.1 is }
1733 1.1 is #endif
1734 1.1 is
1735 1.1 is void
1736 1.17 aymeric siopng_dump_acb(struct siop_acb *acb)
1737 1.1 is {
1738 1.1 is u_char *b = (u_char *) &acb->cmd;
1739 1.1 is int i;
1740 1.1 is
1741 1.1 is printf("acb@%p ", acb);
1742 1.1 is if (acb->xs == NULL) {
1743 1.1 is printf("<unused>\n");
1744 1.1 is return;
1745 1.1 is }
1746 1.1 is printf("(%d:%d) flags %2x clen %2d cmd ",
1747 1.15 bouyer acb->xs->xs_periph->periph_target,
1748 1.15 bouyer acb->xs->xs_periph->periph_lun, acb->flags, acb->clen);
1749 1.1 is for (i = acb->clen; i; --i)
1750 1.1 is printf(" %02x", *b++);
1751 1.1 is printf("\n");
1752 1.1 is printf(" xs: %p data %p:%04x ", acb->xs, acb->xs->data,
1753 1.1 is acb->xs->datalen);
1754 1.1 is printf("va %p:%lx ", acb->iob_buf, acb->iob_len);
1755 1.1 is printf("cur %lx:%lx\n", acb->iob_curbuf, acb->iob_curlen);
1756 1.1 is }
1757 1.1 is
1758 1.1 is void
1759 1.17 aymeric siopng_dump(struct siop_softc *sc)
1760 1.1 is {
1761 1.1 is struct siop_acb *acb;
1762 1.1 is siop_regmap_p rp = sc->sc_siopp;
1763 1.1 is int s;
1764 1.1 is int i;
1765 1.1 is
1766 1.1 is s = splbio();
1767 1.1 is #if SIOP_TRACE_SIZE
1768 1.1 is siopng_dump_trace();
1769 1.1 is #endif
1770 1.1 is printf("%s@%p regs %p istat %x\n",
1771 1.1 is sc->sc_dev.dv_xname, sc, rp, rp->siop_istat);
1772 1.1 is if ((acb = sc->free_list.tqh_first) > 0) {
1773 1.1 is printf("Free list:\n");
1774 1.1 is while (acb) {
1775 1.1 is siopng_dump_acb(acb);
1776 1.1 is acb = acb->chain.tqe_next;
1777 1.1 is }
1778 1.1 is }
1779 1.1 is if ((acb = sc->ready_list.tqh_first) > 0) {
1780 1.1 is printf("Ready list:\n");
1781 1.1 is while (acb) {
1782 1.1 is siopng_dump_acb(acb);
1783 1.1 is acb = acb->chain.tqe_next;
1784 1.1 is }
1785 1.1 is }
1786 1.1 is if ((acb = sc->nexus_list.tqh_first) > 0) {
1787 1.1 is printf("Nexus list:\n");
1788 1.1 is while (acb) {
1789 1.1 is siopng_dump_acb(acb);
1790 1.1 is acb = acb->chain.tqe_next;
1791 1.1 is }
1792 1.1 is }
1793 1.1 is if (sc->sc_nexus) {
1794 1.1 is printf("Nexus:\n");
1795 1.1 is siopng_dump_acb(sc->sc_nexus);
1796 1.1 is }
1797 1.1 is for (i = 0; i < 8; ++i) {
1798 1.1 is if (sc->sc_tinfo[i].cmds > 2) {
1799 1.15 bouyer printf("tgt %d: cmds %d disc %d lubusy %x\n",
1800 1.1 is i, sc->sc_tinfo[i].cmds,
1801 1.1 is sc->sc_tinfo[i].dconns,
1802 1.1 is sc->sc_tinfo[i].lubusy);
1803 1.1 is }
1804 1.1 is }
1805 1.1 is splx(s);
1806 1.1 is }
1807 1.1 is #endif
1808