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