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