xref: /openbsd-src/sys/dev/ic/siop.c (revision b2ea75c1b17e1a9a339660e7ed45cd24946b230e)
1 /*	$OpenBSD: siop.c,v 1.11 2001/07/04 22:55:03 espie Exp $ */
2 /*	$NetBSD: siop.c,v 1.39 2001/02/11 18:04:49 bouyer Exp $	*/
3 
4 /*
5  * Copyright (c) 2000 Manuel Bouyer.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  * 3. All advertising materials mentioning features or use of this software
16  *    must display the following acknowledgement:
17  *	This product includes software developed by Manuel Bouyer
18  * 4. The name of the author may not be used to endorse or promote products
19  *    derived from this software without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
22  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
23  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
24  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
25  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
26  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
27  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
28  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
29  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
30  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
31  *
32  */
33 
34 /* SYM53c7/8xx PCI-SCSI I/O Processors driver */
35 
36 #include <sys/param.h>
37 #include <sys/systm.h>
38 #include <sys/device.h>
39 #include <sys/malloc.h>
40 #include <sys/buf.h>
41 #include <sys/kernel.h>
42 
43 #include <machine/endian.h>
44 #include <machine/bus.h>
45 
46 #include <dev/microcode/siop/siop.out>
47 
48 #include <scsi/scsi_all.h>
49 #include <scsi/scsi_message.h>
50 #include <scsi/scsiconf.h>
51 
52 #include <dev/ic/siopreg.h>
53 #include <dev/ic/siopvar.h>
54 #include <dev/ic/siopvar_common.h>
55 
56 #ifndef DEBUG
57 #undef DEBUG
58 #endif
59 #undef SIOP_DEBUG
60 #undef SIOP_DEBUG_DR
61 #undef SIOP_DEBUG_INTR
62 #undef SIOP_DEBUG_SCHED
63 #undef DUMP_SCRIPT
64 
65 #define SIOP_STATS
66 
67 #ifndef SIOP_DEFAULT_TARGET
68 #define SIOP_DEFAULT_TARGET 7
69 #endif
70 
71 /* number of cmd descriptors per block */
72 #define SIOP_NCMDPB (PAGE_SIZE / sizeof(struct siop_xfer))
73 
74 /* number of scheduler slots (needs to match script) */
75 #define SIOP_NSLOTS 40
76 
77 void	siop_reset __P((struct siop_softc *));
78 void	siop_handle_reset __P((struct siop_softc *));
79 int	siop_handle_qtag_reject __P((struct siop_cmd *));
80 void	siop_scsicmd_end __P((struct siop_cmd *));
81 void	siop_start __P((struct siop_softc *));
82 void 	siop_timeout __P((void *));
83 int	siop_scsicmd __P((struct scsi_xfer *));
84 void	siop_dump_script __P((struct siop_softc *));
85 int	siop_morecbd __P((struct siop_softc *));
86 struct siop_lunsw *siop_get_lunsw __P((struct siop_softc *));
87 void	siop_add_reselsw __P((struct siop_softc *, int));
88 void	siop_update_scntl3 __P((struct siop_softc *, struct siop_target *));
89 
90 struct cfdriver siop_cd = {
91 	NULL, "siop", DV_DULL
92 };
93 
94 struct scsi_adapter siop_adapter = {
95 	siop_scsicmd,
96 	siop_minphys,
97 	NULL,
98 	NULL,
99 };
100 
101 struct scsi_device siop_dev = {
102 	NULL,
103 	NULL,
104 	NULL,
105 	NULL,
106 };
107 
108 #ifdef SIOP_STATS
109 static int siop_stat_intr = 0;
110 static int siop_stat_intr_shortxfer = 0;
111 static int siop_stat_intr_sdp = 0;
112 static int siop_stat_intr_done = 0;
113 static int siop_stat_intr_xferdisc = 0;
114 static int siop_stat_intr_lunresel = 0;
115 static int siop_stat_intr_qfull = 0;
116 void siop_printstats __P((void));
117 #define INCSTAT(x) x++
118 #else
119 #define INCSTAT(x)
120 #endif
121 
122 static __inline__ void siop_script_sync __P((struct siop_softc *, int));
123 static __inline__ void
124 siop_script_sync(sc, ops)
125 	struct siop_softc *sc;
126 	int ops;
127 {
128 	if ((sc->features & SF_CHIP_RAM) == 0)
129 		bus_dmamap_sync(sc->sc_dmat, sc->sc_scriptdma, ops);
130 }
131 
132 static __inline__ u_int32_t siop_script_read __P((struct siop_softc *, u_int));
133 static __inline__ u_int32_t
134 siop_script_read(sc, offset)
135 	struct siop_softc *sc;
136 	u_int offset;
137 {
138 	if (sc->features & SF_CHIP_RAM) {
139 		return bus_space_read_4(sc->sc_ramt, sc->sc_ramh, offset * 4);
140 	} else {
141 		return letoh32(sc->sc_script[offset]);
142 	}
143 }
144 
145 static __inline__ void siop_script_write __P((struct siop_softc *, u_int,
146 	u_int32_t));
147 static __inline__ void
148 siop_script_write(sc, offset, val)
149 	struct siop_softc *sc;
150 	u_int offset;
151 	u_int32_t val;
152 {
153 	if (sc->features & SF_CHIP_RAM) {
154 		bus_space_write_4(sc->sc_ramt, sc->sc_ramh, offset * 4, val);
155 	} else {
156 		sc->sc_script[offset] = htole32(val);
157 	}
158 }
159 
160 void
161 siop_attach(sc)
162 	struct siop_softc *sc;
163 {
164 	int error, i;
165 	bus_dma_segment_t seg;
166 	int rseg;
167 
168 	/*
169 	 * Allocate DMA-safe memory for the script and map it.
170 	 */
171 	if ((sc->features & SF_CHIP_RAM) == 0) {
172 		error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE,
173 		    PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT);
174 		if (error) {
175 			printf("%s: unable to allocate script DMA memory, "
176 			    "error = %d\n", sc->sc_dev.dv_xname, error);
177 			return;
178 		}
179 		error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, PAGE_SIZE,
180 		    (caddr_t *)&sc->sc_script, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
181 		if (error) {
182 			printf("%s: unable to map script DMA memory, "
183 			    "error = %d\n", sc->sc_dev.dv_xname, error);
184 			return;
185 		}
186 		error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1,
187 		    PAGE_SIZE, 0, BUS_DMA_NOWAIT, &sc->sc_scriptdma);
188 		if (error) {
189 			printf("%s: unable to create script DMA map, "
190 			    "error = %d\n", sc->sc_dev.dv_xname, error);
191 			return;
192 		}
193 		error = bus_dmamap_load(sc->sc_dmat, sc->sc_scriptdma,
194 		    sc->sc_script, PAGE_SIZE, NULL, BUS_DMA_NOWAIT);
195 		if (error) {
196 			printf("%s: unable to load script DMA map, "
197 			    "error = %d\n", sc->sc_dev.dv_xname, error);
198 			return;
199 		}
200 		sc->sc_scriptaddr = sc->sc_scriptdma->dm_segs[0].ds_addr;
201 		sc->ram_size = PAGE_SIZE;
202 	}
203 	TAILQ_INIT(&sc->free_list);
204 	TAILQ_INIT(&sc->ready_list);
205 	TAILQ_INIT(&sc->urgent_list);
206 	TAILQ_INIT(&sc->cmds);
207 	TAILQ_INIT(&sc->lunsw_list);
208 	sc->sc_currschedslot = 0;
209 #ifdef SIOP_DEBUG
210 	printf("%s: script size = %d, PHY addr=0x%x, VIRT=%p\n",
211 	    sc->sc_dev.dv_xname, (int)sizeof(siop_script),
212 	    (u_int32_t)sc->sc_scriptaddr, sc->sc_script);
213 #endif
214 
215 	sc->sc_link.adapter_softc = sc;
216 	sc->sc_link.openings = SIOP_OPENINGS;
217 	sc->sc_link.adapter_buswidth =
218 	    (sc->features & SF_BUS_WIDE) ? 16 : 8;
219 	sc->sc_link.adapter_target = bus_space_read_1(sc->sc_rt,
220 	    sc->sc_rh, SIOP_SCID);
221 	if (sc->sc_link.adapter_target == 0 ||
222 	    sc->sc_link.adapter_target >=
223 	    sc->sc_link.adapter_buswidth)
224 		sc->sc_link.adapter_target = SIOP_DEFAULT_TARGET;
225 	sc->sc_link.adapter = &siop_adapter;
226 	sc->sc_link.device = &siop_dev;
227 	sc->sc_link.flags  = 0;
228 
229 	for (i = 0; i < 16; i++)
230 		sc->targets[i] = NULL;
231 
232 	/* find min_dt_sync and min_st_sync for this chip */
233 	sc->min_dt_sync = 0;
234 	for (i = 0; i < sizeof(period_factor) / sizeof(period_factor[0]); i++)
235 		if (period_factor[i].scf[sc->scf_index].dt_scf != 0) {
236 			sc->min_dt_sync = period_factor[i].factor;
237 			break;
238 		}
239 
240 	sc->min_st_sync = 0;
241 	for (i = 0; i < sizeof(period_factor) / sizeof(period_factor[0]); i++)
242 		if (period_factor[i].scf[sc->scf_index].st_scf != 0) {
243 			sc->min_st_sync = period_factor[i].factor;
244 			break;
245 		}
246 
247 	if (sc->min_st_sync == 0)
248 		panic("%s: can't find minimum allowed sync period factor\n", sc->sc_dev.dv_xname);
249 
250 	/* Do a bus reset, so that devices fall back to narrow/async */
251 	siop_resetbus(sc);
252 	/*
253 	 * siop_reset() will reset the chip, thus clearing pending interrupts
254 	 */
255 	siop_reset(sc);
256 #ifdef DUMP_SCRIPT
257 	siop_dump_script(sc);
258 #endif
259 
260 	config_found((struct device*)sc, &sc->sc_link, scsiprint);
261 }
262 
263 void
264 siop_reset(sc)
265 	struct siop_softc *sc;
266 {
267 	int i, j;
268 	struct siop_lunsw *lunsw;
269 
270 	siop_common_reset(sc);
271 
272 	/* copy and patch the script */
273 	if (sc->features & SF_CHIP_RAM) {
274 		bus_space_write_region_4(sc->sc_ramt, sc->sc_ramh, 0,
275 		    siop_script, sizeof(siop_script) / sizeof(siop_script[0]));
276 		for (j = 0; j <
277 		    (sizeof(E_abs_msgin_Used) / sizeof(E_abs_msgin_Used[0]));
278 		    j++) {
279 			bus_space_write_4(sc->sc_ramt, sc->sc_ramh,
280 			    E_abs_msgin_Used[j] * 4,
281 			    sc->sc_scriptaddr + Ent_msgin_space);
282 		}
283 	} else {
284 		for (j = 0;
285 		    j < (sizeof(siop_script) / sizeof(siop_script[0])); j++) {
286 			sc->sc_script[j] = htole32(siop_script[j]);
287 		}
288 		for (j = 0; j <
289 		    (sizeof(E_abs_msgin_Used) / sizeof(E_abs_msgin_Used[0]));
290 		    j++) {
291 			sc->sc_script[E_abs_msgin_Used[j]] =
292 			    htole32(sc->sc_scriptaddr + Ent_msgin_space);
293 		}
294 	}
295 	sc->script_free_lo = sizeof(siop_script) / sizeof(siop_script[0]);
296 	sc->script_free_hi = sc->ram_size / 4;
297 
298 	/* free used and unused lun switches */
299 	while((lunsw = TAILQ_FIRST(&sc->lunsw_list)) != NULL) {
300 #ifdef SIOP_DEBUG
301 		printf("%s: free lunsw at offset %d\n",
302 				sc->sc_dev.dv_xname, lunsw->lunsw_off);
303 #endif
304 		TAILQ_REMOVE(&sc->lunsw_list, lunsw, next);
305 		free(lunsw, M_DEVBUF);
306 	}
307 	TAILQ_INIT(&sc->lunsw_list);
308 	/* restore reselect switch */
309 	for (i = 0; i < sc->sc_link.adapter_buswidth; i++) {
310 		if (sc->targets[i] == NULL)
311 			continue;
312 #ifdef SIOP_DEBUG
313 		printf("%s: restore sw for target %d\n",
314 				sc->sc_dev.dv_xname, i);
315 #endif
316 		free(sc->targets[i]->lunsw, M_DEVBUF);
317 		sc->targets[i]->lunsw = siop_get_lunsw(sc);
318 		if (sc->targets[i]->lunsw == NULL) {
319 			printf("%s: can't alloc lunsw for target %d\n",
320 			    sc->sc_dev.dv_xname, i);
321 			break;
322 		}
323 		siop_add_reselsw(sc, i);
324 	}
325 
326 	/* start script */
327 	if ((sc->features & SF_CHIP_RAM) == 0) {
328 		bus_dmamap_sync(sc->sc_dmat, sc->sc_scriptdma,
329 		    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
330 	}
331 	bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP,
332 	    sc->sc_scriptaddr + Ent_reselect);
333 }
334 
335 #if 0
336 #define CALL_SCRIPT(ent) do {\
337 	printf ("start script DSA 0x%lx DSP 0x%lx\n", \
338 	    siop_cmd->dsa, \
339 	    sc->sc_scriptaddr + ent); \
340 bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP, sc->sc_scriptaddr + ent); \
341 } while (0)
342 #else
343 #define CALL_SCRIPT(ent) do {\
344 bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP, sc->sc_scriptaddr + ent); \
345 } while (0)
346 #endif
347 
348 int
349 siop_intr(v)
350 	void *v;
351 {
352 	struct siop_softc *sc = v;
353 	struct siop_target *siop_target;
354 	struct siop_cmd *siop_cmd;
355 	struct siop_lun *siop_lun;
356 	struct scsi_xfer *xs;
357 	int istat, sist = 0, sstat1 = 0, dstat = 0;
358 	u_int32_t irqcode = 0;
359 	int need_reset = 0;
360 	int offset, target, lun, tag;
361 	bus_addr_t dsa;
362 	struct siop_cbd *cbdp;
363 	int freetarget = 0;
364 	int restart = 0;
365 
366 	istat = bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_ISTAT);
367 	if ((istat & (ISTAT_INTF | ISTAT_DIP | ISTAT_SIP)) == 0)
368 		return 0;
369 	INCSTAT(siop_stat_intr);
370 	if (istat & ISTAT_INTF) {
371 		printf("INTRF\n");
372 		bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_ISTAT, ISTAT_INTF);
373 	}
374 	/* use DSA to find the current siop_cmd */
375 	dsa = bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSA);
376 	for (cbdp = TAILQ_FIRST(&sc->cmds); cbdp != NULL;
377 	    cbdp = TAILQ_NEXT(cbdp, next)) {
378 		if (dsa >= cbdp->xferdma->dm_segs[0].ds_addr &&
379 	    	    dsa < cbdp->xferdma->dm_segs[0].ds_addr + PAGE_SIZE) {
380 			dsa -= cbdp->xferdma->dm_segs[0].ds_addr;
381 			siop_cmd = &cbdp->cmds[dsa / sizeof(struct siop_xfer)];
382 			siop_table_sync(siop_cmd,
383 			    BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
384 			break;
385 		}
386 	}
387 	if (cbdp == NULL) {
388 		siop_cmd = NULL;
389 	}
390 	if (siop_cmd) {
391 		xs = siop_cmd->xs;
392 		siop_target = siop_cmd->siop_target;
393 		target = siop_cmd->xs->sc_link->target;
394 		lun = siop_cmd->xs->sc_link->lun;
395 		tag = siop_cmd->tag;
396 		siop_lun = siop_target->siop_lun[lun];
397 #ifdef DIAGNOSTIC
398 		if (siop_cmd->status != CMDST_ACTIVE &&
399 		    siop_cmd->status != CMDST_SENSE_ACTIVE) {
400 			printf("siop_cmd (lun %d) not active (%d)\n",
401 				lun, siop_cmd->status);
402 			xs = NULL;
403 			siop_target = NULL;
404 			target = -1;
405 			lun = -1;
406 			tag = -1;
407 			siop_lun = NULL;
408 			siop_cmd = NULL;
409 		} else if (siop_lun->siop_tag[tag].active != siop_cmd) {
410 			printf("siop_cmd (lun %d tag %d) not in siop_lun "
411 			    "active (%p != %p)\n", lun, tag, siop_cmd,
412 			    siop_lun->siop_tag[tag].active);
413 		}
414 #endif
415 	} else {
416 		xs = NULL;
417 		siop_target = NULL;
418 		target = -1;
419 		lun = -1;
420 		tag = -1;
421 		siop_lun = NULL;
422 	}
423 	if (istat & ISTAT_DIP) {
424 		dstat = bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_DSTAT);
425 		if (dstat & DSTAT_SSI) {
426 			printf("single step dsp 0x%08x dsa 0x08%x\n",
427 			    (int)(bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSP) -
428 			    sc->sc_scriptaddr),
429 			    bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSA));
430 			if ((dstat & ~(DSTAT_DFE | DSTAT_SSI)) == 0 &&
431 			    (istat & ISTAT_SIP) == 0) {
432 				bus_space_write_1(sc->sc_rt, sc->sc_rh,
433 				    SIOP_DCNTL, bus_space_read_1(sc->sc_rt,
434 				    sc->sc_rh, SIOP_DCNTL) | DCNTL_STD);
435 			}
436 			return 1;
437 		}
438 		if (dstat & ~(DSTAT_SIR | DSTAT_DFE | DSTAT_SSI)) {
439 			printf("DMA IRQ:");
440 			if (dstat & DSTAT_IID)
441 				printf("Illegal instruction");
442 			if (dstat & DSTAT_ABRT)
443 				printf(" abort");
444 			if (dstat & DSTAT_BF)
445 				printf(" bus fault");
446 			if (dstat & DSTAT_MDPE)
447 				printf(" parity");
448 			if (dstat & DSTAT_DFE)
449 				printf(" dma fifo empty");
450 			printf(", DSP=0x%x DSA=0x%x: ",
451 			    (int)(bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSP) -
452 				sc->sc_scriptaddr),
453 			    bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSA));
454 			if (siop_cmd)
455 				printf("last msg_in=0x%x status=0x%x\n",
456 				    siop_cmd->siop_tables.msg_in[0],
457 				    letoh32(siop_cmd->siop_tables.status));
458 			else
459 				printf("%s: current DSA invalid\n",
460 				    sc->sc_dev.dv_xname);
461 			need_reset = 1;
462 		}
463 	}
464 	if (istat & ISTAT_SIP) {
465 		if (istat & ISTAT_DIP)
466 			delay(10);
467 		/*
468 		 * Can't read sist0 & sist1 independantly, or we have to
469 		 * insert delay
470 		 */
471 		sist = bus_space_read_2(sc->sc_rt, sc->sc_rh, SIOP_SIST0);
472 		sstat1 = bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_SSTAT1);
473 #ifdef SIOP_DEBUG_INTR
474 		printf("scsi interrupt, sist=0x%x sstat1=0x%x "
475 		    "DSA=0x%x DSP=0x%lx\n", sist,
476 		    bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_SSTAT1),
477 		    bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSA),
478 		    (u_long)(bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSP) -
479 		    sc->sc_scriptaddr));
480 #endif
481 		if (sist & SIST0_RST) {
482 			siop_handle_reset(sc);
483 			siop_start(sc);
484 			/* no table to flush here */
485 			return 1;
486 		}
487 		if (sist & SIST0_SGE) {
488 			if (siop_cmd)
489 				sc_print_addr(xs->sc_link);
490 			else
491 				printf("%s:", sc->sc_dev.dv_xname);
492 			printf("scsi gross error\n");
493 			goto reset;
494 		}
495 		if ((sist & SIST0_MA) && need_reset == 0) {
496 			if (siop_cmd) {
497 				int scratcha0;
498 				dstat = bus_space_read_1(sc->sc_rt, sc->sc_rh,
499 				    SIOP_DSTAT);
500 				/*
501 				 * first restore DSA, in case we were in a S/G
502 				 * operation.
503 				 */
504 				bus_space_write_4(sc->sc_rt, sc->sc_rh,
505 				    SIOP_DSA, siop_cmd->dsa);
506 				scratcha0 = bus_space_read_1(sc->sc_rt,
507 				    sc->sc_rh, SIOP_SCRATCHA);
508 				switch (sstat1 & SSTAT1_PHASE_MASK) {
509 				case SSTAT1_PHASE_STATUS:
510 				/*
511 				 * Previous phase may have aborted for any reason
512 				 * (for example, the target has less data to
513 				 * transfer than requested). Just go to status
514 				 * and the command should terminate.
515 				 */
516 					INCSTAT(siop_stat_intr_shortxfer);
517 					if ((dstat & DSTAT_DFE) == 0)
518 						siop_clearfifo(sc);
519 					/* no table to flush here */
520 					CALL_SCRIPT(Ent_status);
521 					return 1;
522 				case SSTAT1_PHASE_MSGIN:
523 					/*
524 					 * Target may be ready to disconnect.
525 					 * Save data pointers just in case.
526 					 */
527 					INCSTAT(siop_stat_intr_xferdisc);
528 					if (scratcha0 & A_flag_data)
529 						siop_sdp(siop_cmd);
530 					else if ((dstat & DSTAT_DFE) == 0)
531 						siop_clearfifo(sc);
532 					bus_space_write_1(sc->sc_rt, sc->sc_rh,
533 					    SIOP_SCRATCHA,
534 					    scratcha0 & ~A_flag_data);
535 					siop_table_sync(siop_cmd,
536 					    BUS_DMASYNC_PREREAD |
537 					    BUS_DMASYNC_PREWRITE);
538 					CALL_SCRIPT(Ent_msgin);
539 					return 1;
540 				}
541 				printf("%s: unexpected phase mismatch %d\n",
542 				    sc->sc_dev.dv_xname,
543 				    sstat1 & SSTAT1_PHASE_MASK);
544 			} else {
545 				printf("%s: phase mismatch without command\n",
546 				    sc->sc_dev.dv_xname);
547 			}
548 			need_reset = 1;
549 		}
550 		if (sist & SIST0_PAR) {
551 			/* parity error, reset */
552 			if (siop_cmd)
553 				sc_print_addr(xs->sc_link);
554 			else
555 				printf("%s:", sc->sc_dev.dv_xname);
556 			printf("parity error\n");
557 			goto reset;
558 		}
559 		if ((sist & (SIST1_STO << 8)) && need_reset == 0) {
560 			/* selection time out, assume there's no device here */
561 			if (siop_cmd) {
562 				siop_cmd->status = CMDST_DONE;
563 				xs->error = XS_SELTIMEOUT;
564 				freetarget = 1;
565 				goto end;
566 			} else {
567 				printf("%s: selection timeout without "
568 				    "command\n", sc->sc_dev.dv_xname);
569 				need_reset = 1;
570 			}
571 		}
572 		if (sist & SIST0_UDC) {
573 			/*
574 			 * unexpected disconnect. Usually the target signals
575 			 * a fatal condition this way. Attempt to get sense.
576 			 */
577 			 if (siop_cmd) {
578 				siop_cmd->siop_tables.status =
579 				    htole32(SCSI_CHECK);
580 				goto end;
581 			}
582 			printf("%s: unexpected disconnect without "
583 			    "command\n", sc->sc_dev.dv_xname);
584 			goto reset;
585 		}
586 		if (sist & (SIST1_SBMC << 8)) {
587 			/* SCSI bus mode change */
588 			if (siop_modechange(sc) == 0 || need_reset == 1)
589 				goto reset;
590 			if ((istat & ISTAT_DIP) && (dstat & DSTAT_SIR)) {
591 				/*
592 				 * We have a script interrupt. It will
593 				 * restart the script.
594 				 */
595 				goto scintr;
596 			}
597 			/*
598 			 * Else we have to restart the script ourself, at the
599 			 * interrupted instruction.
600 			 */
601 			bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP,
602 			    bus_space_read_4(sc->sc_rt, sc->sc_rh,
603 			    SIOP_DSP) - 8);
604 			return 1;
605 		}
606 		/* Else it's an unhandled exception (for now). */
607 		printf("%s: unhandled scsi interrupt, sist=0x%x sstat1=0x%x "
608 		    "DSA=0x%x DSP=0x%x\n", sc->sc_dev.dv_xname, sist,
609 		    bus_space_read_1(sc->sc_rt, sc->sc_rh, SIOP_SSTAT1),
610 		    bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSA),
611 		    (int)(bus_space_read_4(sc->sc_rt, sc->sc_rh, SIOP_DSP) -
612 		    sc->sc_scriptaddr));
613 		if (siop_cmd) {
614 			siop_cmd->status = CMDST_DONE;
615 			xs->error = XS_SELTIMEOUT;
616 			goto end;
617 		}
618 		need_reset = 1;
619 	}
620 	if (need_reset) {
621 reset:
622 		/* fatal error, reset the bus */
623 		siop_resetbus(sc);
624 		/* no table to flush here */
625 		return 1;
626 	}
627 
628 scintr:
629 	if ((istat & ISTAT_DIP) && (dstat & DSTAT_SIR)) { /* script interrupt */
630 		irqcode = bus_space_read_4(sc->sc_rt, sc->sc_rh,
631 		    SIOP_DSPS);
632 #ifdef SIOP_DEBUG_INTR
633 		printf("script interrupt 0x%x\n", irqcode);
634 #endif
635 		/*
636 		 * no command, or an inactive command is only valid for a
637 		 * reselect interrupt
638 		 */
639 		if ((irqcode & 0x80) == 0) {
640 			if (siop_cmd == NULL) {
641 				printf("%s: script interrupt (0x%x) with "
642 				    "invalid DSA !!!\n", sc->sc_dev.dv_xname,
643 				    irqcode);
644 				goto reset;
645 			}
646 			if (siop_cmd->status != CMDST_ACTIVE &&
647 			    siop_cmd->status != CMDST_SENSE_ACTIVE) {
648 				printf("%s: command with invalid status "
649 				    "(IRQ code 0x%x current status %d) !\n",
650 				    sc->sc_dev.dv_xname,
651 				    irqcode, siop_cmd->status);
652 				xs = NULL;
653 			}
654 		}
655 		switch(irqcode) {
656 		case A_int_err:
657 			printf("error, DSP=0x%x\n",
658 			    (int)(bus_space_read_4(sc->sc_rt, sc->sc_rh,
659 			    SIOP_DSP) - sc->sc_scriptaddr));
660 			if (xs) {
661 				xs->error = XS_SELTIMEOUT;
662 				goto end;
663 			} else {
664 				goto reset;
665 			}
666 		case A_int_reseltarg:
667 			printf("%s: reselect with invalid target\n",
668 				    sc->sc_dev.dv_xname);
669 			goto reset;
670 		case A_int_resellun:
671 			INCSTAT(siop_stat_intr_lunresel);
672 			target = bus_space_read_1(sc->sc_rt, sc->sc_rh,
673 			    SIOP_SCRATCHA) & 0xf;
674 			lun = bus_space_read_1(sc->sc_rt, sc->sc_rh,
675 			    SIOP_SCRATCHA + 1);
676 			tag = bus_space_read_1(sc->sc_rt, sc->sc_rh,
677 			    SIOP_SCRATCHA + 2);
678 			siop_target = sc->targets[target];
679 			if (siop_target == NULL) {
680 				printf("%s: reselect with invalid "
681 				    "target %d\n", sc->sc_dev.dv_xname, target);
682 				goto reset;
683 			}
684 			siop_lun = siop_target->siop_lun[lun];
685 			if (siop_lun == NULL) {
686 				printf("%s: target %d reselect with invalid "
687 				    "lun %d\n", sc->sc_dev.dv_xname,
688 				    target, lun);
689 				goto reset;
690 			}
691 			if (siop_lun->siop_tag[tag].active == NULL) {
692 				printf("%s: target %d lun %d tag %d reselect "
693 				    "without command\n", sc->sc_dev.dv_xname,
694 				    target, lun, tag);
695 				goto reset;
696 			}
697 			siop_cmd = siop_lun->siop_tag[tag].active;
698 			bus_space_write_4(sc->sc_rt, sc->sc_rh, SIOP_DSP,
699 			    siop_cmd->dsa + sizeof(struct siop_xfer_common) +
700 			    Ent_ldsa_reload_dsa);
701 			siop_table_sync(siop_cmd, BUS_DMASYNC_PREWRITE);
702 			return 1;
703 		case A_int_reseltag:
704 			printf("%s: reselect with invalid tag\n",
705 				    sc->sc_dev.dv_xname);
706 			goto reset;
707 		case A_int_msgin:
708 		{
709 			int msgin = bus_space_read_1(sc->sc_rt, sc->sc_rh,
710 			    SIOP_SFBR);
711 			if (msgin == MSG_MESSAGE_REJECT) {
712 				int msg, extmsg;
713 				if (siop_cmd->siop_tables.msg_out[0] & 0x80) {
714 					/*
715 					 * Message was part of an identify +
716 					 * something else. Identify shouldn't
717 					 * have been rejected.
718 					 */
719 					msg = siop_cmd->siop_tables.msg_out[1];
720 					extmsg =
721 					    siop_cmd->siop_tables.msg_out[3];
722 				} else {
723 					msg = siop_cmd->siop_tables.msg_out[0];
724 					extmsg =
725 					    siop_cmd->siop_tables.msg_out[2];
726 				}
727 				if (msg == MSG_MESSAGE_REJECT) {
728 					/* MSG_REJECT for a MSG_REJECT! */
729 					if (xs)
730 						sc_print_addr(xs->sc_link);
731 					else
732 						printf("%s: ",
733 						   sc->sc_dev.dv_xname);
734 					printf("our reject message was "
735 					    "rejected\n");
736 					goto reset;
737 				}
738 				if (msg == MSG_EXTENDED &&
739 				    extmsg == MSG_EXT_WDTR) {
740 					if ((siop_target->flags & TARF_SYNC)
741 					    == 0) {
742 						siop_target->status = TARST_OK;
743 						siop_print_info(sc, target);
744 						/* no table to flush here */
745 						CALL_SCRIPT(Ent_msgin_ack);
746 						return 1;
747 					}
748 					siop_target->status = TARST_SYNC_NEG;
749 					siop_sdtr_msg(siop_cmd, 0,
750 					    sc->min_st_sync, sc->maxoff);
751 					siop_table_sync(siop_cmd,
752 					    BUS_DMASYNC_PREREAD |
753 					    BUS_DMASYNC_PREWRITE);
754 					CALL_SCRIPT(Ent_send_msgout);
755 					return 1;
756 				} else if (msg == MSG_EXTENDED &&
757 				    extmsg == MSG_EXT_SDTR) {
758 					siop_target->status = TARST_OK;
759 					siop_print_info(sc, target);
760 					/* no table to flush here */
761 					CALL_SCRIPT(Ent_msgin_ack);
762 					return 1;
763 				} else if (msg == MSG_SIMPLE_Q_TAG ||
764 				    msg == MSG_HEAD_OF_Q_TAG ||
765 				    msg == MSG_ORDERED_Q_TAG) {
766 					if (siop_handle_qtag_reject(
767 					    siop_cmd) == -1)
768 						goto reset;
769 					CALL_SCRIPT(Ent_msgin_ack);
770 					return 1;
771 				}
772 				if (xs)
773 					sc_print_addr(xs->sc_link);
774 				else
775 					printf("%s: ", sc->sc_dev.dv_xname);
776 				if (msg == MSG_EXTENDED) {
777 					printf("scsi message reject, extended "
778 					    "message sent was 0x%x\n", extmsg);
779 				} else {
780 					printf("scsi message reject, message "
781 					    "sent was 0x%x\n", msg);
782 				}
783 				/* no table to flush here */
784 				CALL_SCRIPT(Ent_msgin_ack);
785 				return 1;
786 			}
787 			if (xs)
788 				sc_print_addr(xs->sc_link);
789 			else
790 				printf("%s: ", sc->sc_dev.dv_xname);
791 			printf("unhandled message 0x%x\n",
792 			    siop_cmd->siop_tables.msg_in[0]);
793 			siop_cmd->siop_tables.msg_out[0] = MSG_MESSAGE_REJECT;
794 			siop_cmd->siop_tables.t_msgout.count= htole32(1);
795 			siop_table_sync(siop_cmd,
796 			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
797 			CALL_SCRIPT(Ent_send_msgout);
798 			return 1;
799 		}
800 		case A_int_extmsgin:
801 #ifdef SIOP_DEBUG_INTR
802 			printf("extended message: msg 0x%x len %d\n",
803 			    siop_cmd->siop_tables.msg_in[2],
804 			    siop_cmd->siop_tables.msg_in[1]);
805 #endif
806 			if (siop_cmd->siop_tables.msg_in[1] > 6)
807 				printf("%s: extended message too big (%d)\n",
808 				    sc->sc_dev.dv_xname,
809 				    siop_cmd->siop_tables.msg_in[1]);
810 			siop_cmd->siop_tables.t_extmsgdata.count =
811 			    htole32(siop_cmd->siop_tables.msg_in[1] - 1);
812 			siop_table_sync(siop_cmd,
813 			    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
814 			CALL_SCRIPT(Ent_get_extmsgdata);
815 			return 1;
816 		case A_int_extmsgdata:
817 		{
818 #ifdef SIOP_DEBUG_INTR
819 			{
820 			int i;
821 			printf("extended message: 0x%x, data:",
822 			    siop_cmd->siop_tables.msg_in[2]);
823 			for (i = 3; i < 2 + siop_cmd->siop_tables.msg_in[1];
824 			    i++)
825 				printf(" 0x%x",
826 				    siop_cmd->siop_tables.msg_in[i]);
827 			printf("\n");
828 			}
829 #endif
830 			int neg_action = SIOP_NEG_NOP;
831 			const char *neg_name = "";
832 
833 			switch (siop_cmd->siop_tables.msg_in[2]) {
834 			case MSG_EXT_WDTR:
835 				neg_action = siop_wdtr_neg(siop_cmd);
836 				neg_name = "wdtr";
837 				break;
838 			case MSG_EXT_SDTR:
839 				neg_action = siop_sdtr_neg(siop_cmd);
840 				neg_name = "sdtr";
841 				break;
842 			case MSG_EXT_PPR:
843 				neg_action = siop_ppr_neg(siop_cmd);
844 				neg_name = "ppr";
845 				break;
846 			default:
847 				neg_action = SIOP_NEG_MSGREJ;
848 				break;
849 			}
850 
851 			switch (neg_action) {
852 			case SIOP_NEG_NOP:
853 				break;
854 			case SIOP_NEG_MSGOUT:
855 				siop_update_scntl3(sc, siop_cmd->siop_target);
856 				siop_table_sync(siop_cmd,
857 				    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
858 				CALL_SCRIPT(Ent_send_msgout);
859 				break;
860 			case SIOP_NEG_ACK:
861 				siop_update_scntl3(sc, siop_cmd->siop_target);
862 				siop_table_sync(siop_cmd,
863 				    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
864 				CALL_SCRIPT(Ent_msgin_ack);
865 				break;
866 			case SIOP_NEG_MSGREJ:
867 				siop_cmd->siop_tables.msg_out[0] = MSG_MESSAGE_REJECT;
868 				siop_cmd->siop_tables.t_msgout.count = htole32(1);
869 				siop_table_sync(siop_cmd,
870 				    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
871 				CALL_SCRIPT(Ent_send_msgout);
872 				break;
873 			default:
874 				panic("invalid return value from siop_%s_neg(): 0x%x", neg_name, neg_action);
875 			}
876 
877 			return (1);
878 		}
879 
880 		case A_int_disc:
881 			INCSTAT(siop_stat_intr_sdp);
882 			offset = bus_space_read_1(sc->sc_rt, sc->sc_rh,
883 			    SIOP_SCRATCHA + 1);
884 #ifdef SIOP_DEBUG_DR
885 			printf("disconnect offset %d\n", offset);
886 #endif
887 			if (offset > SIOP_NSG) {
888 				printf("%s: bad offset for disconnect (%d)\n",
889 				    sc->sc_dev.dv_xname, offset);
890 				goto reset;
891 			}
892 			/*
893 			 * offset == SIOP_NSG may be a valid condition if
894 			 * we get a sdp when the xfer is done.
895 			 * Don't call memmove in this case.
896 			 */
897 			if (offset < SIOP_NSG) {
898 				bcopy(&siop_cmd->siop_tables.data[offset],
899 				    &siop_cmd->siop_tables.data[0],
900 				    (SIOP_NSG - offset) * sizeof(scr_table_t));
901 				siop_table_sync(siop_cmd,
902 				    BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
903 			}
904 			CALL_SCRIPT(Ent_script_sched);
905 			/* check if we can put some command in scheduler */
906 			siop_start(sc);
907 			return 1;
908 		case A_int_resfail:
909 			printf("reselect failed\n");
910 			CALL_SCRIPT(Ent_script_sched);
911 			return  1;
912 		case A_int_done:
913 			if (xs == NULL) {
914 				printf("%s: done without command, DSA=0x%lx\n",
915 				    sc->sc_dev.dv_xname, (u_long)siop_cmd->dsa);
916 				siop_cmd->status = CMDST_FREE;
917 				siop_start(sc);
918 				CALL_SCRIPT(Ent_script_sched);
919 				return 1;
920 			}
921 #ifdef SIOP_DEBUG_INTR
922 			printf("done, DSA=0x%lx target id 0x%x last msg "
923 			    "in=0x%x status=0x%x\n", (u_long)siop_cmd->dsa,
924 			    letoh32(siop_cmd->siop_tables.id),
925 			    siop_cmd->siop_tables.msg_in[0],
926 			    letoh32(siop_cmd->siop_tables.status));
927 #endif
928 			INCSTAT(siop_stat_intr_done);
929 			if (siop_cmd->status == CMDST_SENSE_ACTIVE)
930 				siop_cmd->status = CMDST_SENSE_DONE;
931 			else
932 				siop_cmd->status = CMDST_DONE;
933 			goto end;
934 		default:
935 			printf("unknown irqcode %x\n", irqcode);
936 			if (xs) {
937 				xs->error = XS_SELTIMEOUT;
938 				goto end;
939 			}
940 			goto reset;
941 		}
942 		return 1;
943 	}
944 	/* We can get here if ISTAT_DIP and DSTAT_DFE are the only bits set. */
945 	/* But that *SHOULDN'T* happen. It does on powerpc (at least).	     */
946 	printf("%s: siop_intr() - we should not be here!\n"
947 	    "   istat = 0x%x, dstat = 0x%x, sist = 0x%x, sstat1 = 0x%x\n"
948 	    "   need_reset = %x, irqcode = %x, siop_cmd %s\n",
949 	    sc->sc_dev.dv_xname,
950 	    istat, dstat, sist, sstat1, need_reset, irqcode,
951 	    (siop_cmd == NULL) ? "== NULL" : "!= NULL");
952 	goto reset; /* Where we should have gone in the first place! */
953 end:
954 	/*
955 	 * Restart the script now if command completed properly.
956 	 * Otherwise wait for siop_scsicmd_end(), it may need to put
957 	 * a cmd at the front of the queue.
958 	 */
959 	if (letoh32(siop_cmd->siop_tables.status) == SCSI_OK &&
960 	    TAILQ_FIRST(&sc->urgent_list) != NULL)
961 		CALL_SCRIPT(Ent_script_sched);
962 	else
963 		restart = 1;
964 	siop_scsicmd_end(siop_cmd);
965 	siop_lun->siop_tag[tag].active = NULL;
966 	if (siop_cmd->status == CMDST_FREE) {
967 		TAILQ_INSERT_TAIL(&sc->free_list, siop_cmd, next);
968 		siop_lun->lun_flags &= ~SIOP_LUNF_FULL;
969 		if (freetarget && siop_target->status == TARST_PROBING)
970 			siop_del_dev(sc, target, lun);
971 	}
972 	siop_start(sc);
973 	if (restart)
974 		CALL_SCRIPT(Ent_script_sched);
975 	return 1;
976 }
977 
978 void
979 siop_scsicmd_end(siop_cmd)
980 	struct siop_cmd *siop_cmd;
981 {
982 	struct scsi_xfer *xs = siop_cmd->xs;
983 	struct siop_softc *sc = siop_cmd->siop_sc;
984 
985 	switch(letoh32(siop_cmd->siop_tables.status)) {
986 	case SCSI_OK:
987 		xs->error = (siop_cmd->status == CMDST_DONE) ?
988 		    XS_NOERROR : XS_SENSE;
989 		break;
990 	case SCSI_BUSY:
991 		xs->error = XS_BUSY;
992 		break;
993 	case SCSI_CHECK:
994 		if (siop_cmd->status == CMDST_SENSE_DONE) {
995 			/* request sense on a request sense ? */
996 			printf("request sense failed\n");
997 			xs->error = XS_DRIVER_STUFFUP;
998 		} else {
999 			siop_cmd->status = CMDST_SENSE;
1000 		}
1001 		break;
1002 	case SCSI_QUEUE_FULL:
1003 		{
1004 		struct siop_lun *siop_lun = siop_cmd->siop_target->siop_lun[
1005 		    xs->sc_link->lun];
1006 		/*
1007 		 * Device didn't queue the command. We have to retry
1008 		 * it.  We insert it into the urgent list, hoping to
1009 		 * preserve order.  But unfortunately, commands already
1010 		 * in the scheduler may be accepted before this one.
1011 		 * Also remember the condition, to avoid starting new
1012 		 * commands for this device before one is done.
1013 		 */
1014 		INCSTAT(siop_stat_intr_qfull);
1015 #ifdef SIOP_DEBUG
1016 		printf("%s:%d:%d: queue full (tag %d)\n", sc->sc_dev.dv_xname,
1017 		    xs->sc_link->target,
1018 		    xs->sc_link->lun, siop_cmd->tag);
1019 #endif
1020 		timeout_del(&xs->stimeout);
1021 		siop_lun->lun_flags |= SIOP_LUNF_FULL;
1022 		siop_cmd->status = CMDST_READY;
1023 		siop_setuptables(siop_cmd);
1024 		TAILQ_INSERT_TAIL(&sc->urgent_list, siop_cmd, next);
1025 		return;
1026 		}
1027 	case SCSI_SIOP_NOCHECK:
1028 		/*
1029 		 * don't check status, xs->error is already valid
1030 		 */
1031 		break;
1032 	case SCSI_SIOP_NOSTATUS:
1033 		/*
1034 		 * the status byte was not updated, cmd was
1035 		 * aborted
1036 		 */
1037 		xs->error = XS_SELTIMEOUT;
1038 		break;
1039 	default:
1040 		xs->error = XS_DRIVER_STUFFUP;
1041 	}
1042 	if (siop_cmd->status != CMDST_SENSE_DONE &&
1043 	    xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) {
1044 		bus_dmamap_sync(sc->sc_dmat, siop_cmd->dmamap_data,
1045 		    (xs->flags & SCSI_DATA_IN) ?
1046 		    BUS_DMASYNC_POSTREAD : BUS_DMASYNC_POSTWRITE);
1047 		bus_dmamap_unload(sc->sc_dmat, siop_cmd->dmamap_data);
1048 	}
1049 	bus_dmamap_unload(sc->sc_dmat, siop_cmd->dmamap_cmd);
1050 	if (siop_cmd->status == CMDST_SENSE) {
1051 		/* issue a request sense for this target */
1052 		int error;
1053 		siop_cmd->rs_cmd.opcode = REQUEST_SENSE;
1054 		siop_cmd->rs_cmd.byte2 = xs->sc_link->lun << 5;
1055 		siop_cmd->rs_cmd.unused[0] = siop_cmd->rs_cmd.unused[1] = 0;
1056 		siop_cmd->rs_cmd.length = sizeof(struct scsi_sense_data);
1057 		siop_cmd->rs_cmd.control = 0;
1058 		siop_cmd->flags &= ~CMDFL_TAG;
1059 		error = bus_dmamap_load(sc->sc_dmat, siop_cmd->dmamap_cmd,
1060 		    &siop_cmd->rs_cmd, sizeof(struct scsi_sense),
1061 		    NULL, BUS_DMA_NOWAIT);
1062 		if (error) {
1063 			printf("%s: unable to load cmd DMA map "
1064 			    "(for SENSE): %d\n",
1065 			    sc->sc_dev.dv_xname, error);
1066 			xs->error = XS_DRIVER_STUFFUP;
1067 			goto out;
1068 		}
1069 		error = bus_dmamap_load(sc->sc_dmat, siop_cmd->dmamap_data,
1070 		    &xs->sense, sizeof(struct scsi_sense_data),
1071 		    NULL, BUS_DMA_NOWAIT);
1072 		if (error) {
1073 			printf("%s: unable to load data DMA map "
1074 			    "(for SENSE): %d\n",
1075 			    sc->sc_dev.dv_xname, error);
1076 			xs->error = XS_DRIVER_STUFFUP;
1077 			bus_dmamap_unload(sc->sc_dmat, siop_cmd->dmamap_cmd);
1078 			goto out;
1079 		}
1080 		bus_dmamap_sync(sc->sc_dmat, siop_cmd->dmamap_data,
1081 		    BUS_DMASYNC_PREREAD);
1082 		bus_dmamap_sync(sc->sc_dmat, siop_cmd->dmamap_cmd,
1083 		    BUS_DMASYNC_PREWRITE);
1084 
1085 		siop_setuptables(siop_cmd);
1086 		/* arrange for the cmd to be handled now */
1087 		TAILQ_INSERT_HEAD(&sc->urgent_list, siop_cmd, next);
1088 		return;
1089 	} else if (siop_cmd->status == CMDST_SENSE_DONE) {
1090 		bus_dmamap_sync(sc->sc_dmat, siop_cmd->dmamap_data,
1091 		    BUS_DMASYNC_POSTREAD);
1092 		bus_dmamap_unload(sc->sc_dmat, siop_cmd->dmamap_data);
1093 	}
1094 out:
1095 	timeout_del(&siop_cmd->xs->stimeout);
1096 	siop_cmd->status = CMDST_FREE;
1097 	xs->flags |= ITSDONE;
1098 	xs->resid = 0;
1099 	scsi_done(xs);
1100 }
1101 
1102 /*
1103  * handle a rejected queue tag message: the command will run untagged,
1104  * has to adjust the reselect script.
1105  */
1106 int
1107 siop_handle_qtag_reject(siop_cmd)
1108 	struct siop_cmd *siop_cmd;
1109 {
1110 	struct siop_softc *sc = siop_cmd->siop_sc;
1111 	int target = siop_cmd->xs->sc_link->target;
1112 	int lun = siop_cmd->xs->sc_link->lun;
1113 	int tag = siop_cmd->siop_tables.msg_out[2];
1114 	struct siop_lun *siop_lun = sc->targets[target]->siop_lun[lun];
1115 
1116 #ifdef SIOP_DEBUG
1117 	printf("%s:%d:%d: tag message %d (%d) rejected (status %d)\n",
1118 	    sc->sc_dev.dv_xname, target, lun, tag, siop_cmd->tag,
1119 	    siop_cmd->status);
1120 #endif
1121 
1122 	if (siop_lun->siop_tag[0].active != NULL) {
1123 		printf("%s: untagged command already running for target %d "
1124 		    "lun %d (status %d)\n", sc->sc_dev.dv_xname, target, lun,
1125 		    siop_lun->siop_tag[0].active->status);
1126 		return -1;
1127 	}
1128 	/* clear tag slot */
1129 	siop_lun->siop_tag[tag].active = NULL;
1130 	/* add command to non-tagged slot */
1131 	siop_lun->siop_tag[0].active = siop_cmd;
1132 	siop_cmd->tag = 0;
1133 	/* adjust reselect script if there is one */
1134 	if (siop_lun->siop_tag[0].reseloff > 0) {
1135 		siop_script_write(sc,
1136 		    siop_lun->siop_tag[0].reseloff + 1,
1137 		    siop_cmd->dsa + sizeof(struct siop_xfer_common) +
1138 		    Ent_ldsa_reload_dsa);
1139 		siop_table_sync(siop_cmd, BUS_DMASYNC_PREWRITE);
1140 	}
1141 	return 0;
1142 }
1143 
1144 /*
1145  * Handle a bus reset: reset chip, unqueue all active commands, free all
1146  * target structs and report losage to upper layer.
1147  * As the upper layer may requeue immediately we have to first store
1148  * all active commands in a temporary queue.
1149  */
1150 void
1151 siop_handle_reset(sc)
1152 	struct siop_softc *sc;
1153 {
1154 	struct cmd_list reset_list;
1155 	struct siop_cmd *siop_cmd, *next_siop_cmd;
1156 	struct siop_lun *siop_lun;
1157 	int target, lun, tag;
1158 	/*
1159 	 * SCSI bus reset. Reset the chip and restart
1160 	 * the queue. Need to clean up all active commands.
1161 	 */
1162 	printf("%s: scsi bus reset\n", sc->sc_dev.dv_xname);
1163 	/* stop, reset and restart the chip */
1164 	siop_reset(sc);
1165 	TAILQ_INIT(&reset_list);
1166 	/*
1167 	 * Process all commands: first commmands being executed
1168 	 */
1169 	for (target = 0; target < sc->sc_link.adapter_buswidth;
1170 	    target++) {
1171 		if (sc->targets[target] == NULL)
1172 			continue;
1173 		for (lun = 0; lun < 8; lun++) {
1174 			siop_lun = sc->targets[target]->siop_lun[lun];
1175 			if (siop_lun == NULL)
1176 				continue;
1177 			siop_lun->lun_flags &= ~SIOP_LUNF_FULL;
1178 			for (tag = 0; tag <
1179 			    ((sc->targets[target]->flags & TARF_TAG) ?
1180 			    SIOP_NTAG : 1);
1181 			    tag++) {
1182 				siop_cmd = siop_lun->siop_tag[tag].active;
1183 				if (siop_cmd == NULL)
1184 					continue;
1185 				printf("cmd %p (target %d:%d) in reset list\n",
1186 				    siop_cmd, target, lun);
1187 				TAILQ_INSERT_TAIL(&reset_list, siop_cmd, next);
1188 				siop_lun->siop_tag[tag].active = NULL;
1189 			}
1190 		}
1191 		sc->targets[target]->status = TARST_ASYNC;
1192 		sc->targets[target]->flags &= ~(TARF_ISWIDE | TARF_ISDT | TARF_ISQAS | TARF_ISIUS);
1193 	}
1194 	/* Next commands from the urgent list */
1195 	for (siop_cmd = TAILQ_FIRST(&sc->urgent_list); siop_cmd != NULL;
1196 	    siop_cmd = next_siop_cmd) {
1197 		next_siop_cmd = TAILQ_NEXT(siop_cmd, next);
1198 		siop_cmd->flags &= ~CMDFL_TAG;
1199 		printf("cmd %p (target %d:%d) in reset list (wait)\n",
1200 		    siop_cmd, siop_cmd->xs->sc_link->target,
1201 		    siop_cmd->xs->sc_link->lun);
1202 		TAILQ_REMOVE(&sc->urgent_list, siop_cmd, next);
1203 		TAILQ_INSERT_TAIL(&reset_list, siop_cmd, next);
1204 	}
1205 	/* Then command waiting in the input list */
1206 	for (siop_cmd = TAILQ_FIRST(&sc->ready_list); siop_cmd != NULL;
1207 	    siop_cmd = next_siop_cmd) {
1208 		next_siop_cmd = TAILQ_NEXT(siop_cmd, next);
1209 		siop_cmd->flags &= ~CMDFL_TAG;
1210 		printf("cmd %p (target %d:%d) in reset list (wait)\n",
1211 		    siop_cmd, siop_cmd->xs->sc_link->target,
1212 		    siop_cmd->xs->sc_link->lun);
1213 		TAILQ_REMOVE(&sc->ready_list, siop_cmd, next);
1214 		TAILQ_INSERT_TAIL(&reset_list, siop_cmd, next);
1215 	}
1216 
1217 	for (siop_cmd = TAILQ_FIRST(&reset_list); siop_cmd != NULL;
1218 	    siop_cmd = next_siop_cmd) {
1219 		next_siop_cmd = TAILQ_NEXT(siop_cmd, next);
1220 		siop_cmd->xs->error = (siop_cmd->flags & CMDFL_TIMEOUT) ?
1221 		    XS_TIMEOUT : XS_RESET;
1222 		siop_cmd->siop_tables.status = htole32(SCSI_SIOP_NOCHECK);
1223 		printf("cmd %p (status %d) about to be processed\n", siop_cmd,
1224 		    siop_cmd->status);
1225 		if (siop_cmd->status == CMDST_SENSE ||
1226 		    siop_cmd->status == CMDST_SENSE_ACTIVE)
1227 			siop_cmd->status = CMDST_SENSE_DONE;
1228 		else
1229 			siop_cmd->status = CMDST_DONE;
1230 		TAILQ_REMOVE(&reset_list, siop_cmd, next);
1231 		siop_scsicmd_end(siop_cmd);
1232 		TAILQ_INSERT_TAIL(&sc->free_list, siop_cmd, next);
1233 	}
1234 }
1235 
1236 int
1237 siop_scsicmd(xs)
1238 	struct scsi_xfer *xs;
1239 {
1240 	struct scsi_inquiry_data *inqdata;
1241 	struct siop_softc *sc = (struct siop_softc *)xs->sc_link->adapter_softc;
1242 	struct siop_cmd *siop_cmd;
1243 	int s, error, i;
1244 	const int target = xs->sc_link->target;
1245 	const int lun = xs->sc_link->lun;
1246 
1247 	s = splbio();
1248 #ifdef SIOP_DEBUG_SCHED
1249 	printf("starting cmd 0x%02x for %d:%d\n", xs->cmd->opcode, target, lun);
1250 #endif
1251 	siop_cmd = TAILQ_FIRST(&sc->free_list);
1252 	if (siop_cmd) {
1253 		TAILQ_REMOVE(&sc->free_list, siop_cmd, next);
1254 	} else {
1255 		if (siop_morecbd(sc) == 0) {
1256 			siop_cmd = TAILQ_FIRST(&sc->free_list);
1257 #ifdef DIAGNOSTIC
1258 			if (siop_cmd == NULL)
1259 				panic("siop_morecbd succeed and does nothing");
1260 #endif
1261 			TAILQ_REMOVE(&sc->free_list, siop_cmd, next);
1262 		}
1263 	}
1264 	if (siop_cmd == NULL) {
1265 		xs->error = XS_DRIVER_STUFFUP;
1266 		splx(s);
1267 		return(TRY_AGAIN_LATER);
1268 	}
1269 
1270 	/* Always reset xs->stimeout, lest we timeout_del() with trash */
1271 	timeout_set(&xs->stimeout, siop_timeout, siop_cmd);
1272 
1273 #ifdef DIAGNOSTIC
1274 	if (siop_cmd->status != CMDST_FREE)
1275 		panic("siop_scsicmd: new cmd not free");
1276 #endif
1277 	if (sc->targets[target] == NULL) {
1278 #ifdef SIOP_DEBUG
1279 		printf("%s: alloc siop_target for target %d\n",
1280 			sc->sc_dev.dv_xname, target);
1281 #endif
1282 		sc->targets[target] =
1283 		    malloc(sizeof(struct siop_target), M_DEVBUF, M_NOWAIT);
1284 		if (sc->targets[target] == NULL) {
1285 			printf("%s: can't malloc memory for target %d\n",
1286 			    sc->sc_dev.dv_xname, target);
1287 			xs->error = XS_DRIVER_STUFFUP;
1288 			splx(s);
1289 			return(TRY_AGAIN_LATER);
1290 		}
1291 		sc->targets[target]->status = TARST_PROBING;
1292 		sc->targets[target]->flags  = 0;
1293 		sc->targets[target]->id = sc->clock_div << 24; /* scntl3 */
1294 		sc->targets[target]->id |=  target << 16; /* id */
1295 		/* sc->targets[target]->id |= 0x0 << 8; scxfer is 0 */
1296 
1297 		/* get a lun switch script */
1298 		sc->targets[target]->lunsw = siop_get_lunsw(sc);
1299 		if (sc->targets[target]->lunsw == NULL) {
1300 			printf("%s: can't alloc lunsw for target %d\n",
1301 			    sc->sc_dev.dv_xname, target);
1302 			xs->error = XS_DRIVER_STUFFUP;
1303 			splx(s);
1304 			return(TRY_AGAIN_LATER);
1305 		}
1306 		for (i=0; i < 8; i++)
1307 			sc->targets[target]->siop_lun[i] = NULL;
1308 		siop_add_reselsw(sc, target);
1309 	}
1310 
1311 	if (sc->targets[target]->siop_lun[lun] == NULL) {
1312 		sc->targets[target]->siop_lun[lun] =
1313 		    malloc(sizeof(struct siop_lun), M_DEVBUF, M_NOWAIT);
1314 		if (sc->targets[target]->siop_lun[lun] == NULL) {
1315 			printf("%s: can't alloc siop_lun for target %d "
1316 			    "lun %d\n", sc->sc_dev.dv_xname, target, lun);
1317 			xs->error = XS_DRIVER_STUFFUP;
1318 			splx(s);
1319 			return(TRY_AGAIN_LATER);
1320 		}
1321 		memset(sc->targets[target]->siop_lun[lun], 0,
1322 		    sizeof(struct siop_lun));
1323 	}
1324 	siop_cmd->siop_target = sc->targets[target];
1325 	siop_cmd->xs = xs;
1326 	siop_cmd->flags = 0;
1327 	siop_cmd->status = CMDST_READY;
1328 
1329 	/* load the DMA maps */
1330 	error = bus_dmamap_load(sc->sc_dmat, siop_cmd->dmamap_cmd,
1331 	    xs->cmd, xs->cmdlen, NULL, BUS_DMA_NOWAIT);
1332 	if (error) {
1333 		printf("%s: unable to load cmd DMA map: %d\n",
1334 		    sc->sc_dev.dv_xname, error);
1335 		xs->error = XS_DRIVER_STUFFUP;
1336 		splx(s);
1337 		return(TRY_AGAIN_LATER);
1338 	}
1339 	if (xs->flags & (SCSI_DATA_IN | SCSI_DATA_OUT)) {
1340 		error = bus_dmamap_load(sc->sc_dmat, siop_cmd->dmamap_data,
1341 		    xs->data, xs->datalen, NULL, BUS_DMA_NOWAIT);
1342 		if (error) {
1343 			printf("%s: unable to load cmd DMA map: %d\n",
1344 			    sc->sc_dev.dv_xname, error);
1345 			xs->error = XS_DRIVER_STUFFUP;
1346 			bus_dmamap_unload(sc->sc_dmat, siop_cmd->dmamap_cmd);
1347 			splx(s);
1348 			return(TRY_AGAIN_LATER);
1349 		}
1350 		bus_dmamap_sync(sc->sc_dmat, siop_cmd->dmamap_data,
1351 		    (xs->flags & SCSI_DATA_IN) ?
1352 		    BUS_DMASYNC_PREREAD : BUS_DMASYNC_PREWRITE);
1353 	}
1354 	bus_dmamap_sync(sc->sc_dmat, siop_cmd->dmamap_cmd,
1355 	    BUS_DMASYNC_PREWRITE);
1356 
1357 	siop_setuptables(siop_cmd);
1358 
1359 	TAILQ_INSERT_TAIL(&sc->ready_list, siop_cmd, next);
1360 
1361 	siop_start(sc);
1362 	if (xs->flags & SCSI_POLL) {
1363 		/* poll for command completion */
1364 		for(i = xs->timeout; i > 0; i--) {
1365 			siop_intr(sc);
1366 			if (xs->flags & ITSDONE) {
1367 				if ((xs->cmd->opcode == INQUIRY)
1368 				    && (xs->sc_link->lun == 0)
1369 				    && (xs->error == XS_NOERROR)) {
1370 					inqdata = (struct scsi_inquiry_data *)xs->data;
1371 
1372 					if (inqdata->flags & SID_CmdQue) {
1373 						sc->targets[target]->flags |= TARF_TAG;
1374 						xs->sc_link->openings += SIOP_NTAG - SIOP_OPENINGS;
1375 					}
1376 
1377 					if ((inqdata->flags & SID_WBus16) && (sc->features & SF_BUS_WIDE))
1378 						sc->targets[target]->flags |= TARF_WIDE;
1379 					if (inqdata->flags & SID_Sync)
1380 						sc->targets[target]->flags |= TARF_SYNC;
1381 
1382 					if ((sc->features & SF_CHIP_C10)
1383 					    && (sc->targets[target]->flags & TARF_WIDE)
1384 					    && (inqdata->flags2 & (SID_CLOCKING | SID_QAS | SID_IUS)))
1385 						sc->targets[target]->flags |= TARF_PPR;
1386 
1387 					sc->targets[target]->status = TARST_ASYNC;
1388 
1389 					if (sc->targets[target]->flags
1390 					    & (TARF_WIDE | TARF_SYNC | TARF_PPR)) {
1391 						siop_add_dev(sc, target, lun);
1392 					}
1393 				}
1394 				break;
1395 			}
1396 			delay(1000);
1397 		}
1398 		splx(s);
1399 		if (i == 0) {
1400 			siop_timeout(siop_cmd);
1401 			while ((xs->flags & ITSDONE) == 0)
1402 				siop_intr(sc);
1403 		}
1404 		return (COMPLETE);
1405 	}
1406 	splx(s);
1407 	return (SUCCESSFULLY_QUEUED);
1408 }
1409 
1410 void
1411 siop_start(sc)
1412 	struct siop_softc *sc;
1413 {
1414 	struct siop_cmd *siop_cmd, *next_siop_cmd;
1415 	struct siop_lun *siop_lun;
1416 	u_int32_t dsa;
1417 	int timeout;
1418 	int target, lun, tag, slot;
1419 	int newcmd = 0;
1420 	int doingready = 0;
1421 
1422 	/*
1423 	 * first make sure to read valid data
1424 	 */
1425 	siop_script_sync(sc, BUS_DMASYNC_POSTREAD | BUS_DMASYNC_POSTWRITE);
1426 
1427 	/*
1428 	 * The queue management here is a bit tricky: the script always looks
1429 	 * at the slots from first to last, so if we always use the first
1430 	 * free slot commands can stay at the tail of the queue ~forever.
1431 	 * The algorithm used here is to restart from the head when we know
1432 	 * that the queue is empty, and only add commands after the last one.
1433 	 * When we're at the end of the queue wait for the script to clear it.
1434 	 * The best thing to do here would be to implement a circular queue,
1435 	 * but using only 53c720 features this can be "interesting".
1436 	 * A mid-way solution could be to implement 2 queues and swap orders.
1437 	 */
1438 	slot = sc->sc_currschedslot;
1439 	/*
1440 	 * If the instruction is 0x80000000 (JUMP foo, IF FALSE) the slot is
1441 	 * free. As this is the last used slot, all previous slots are free,
1442 	 * we can restart from 1.
1443 	 * slot 0 is reserved for request sense commands.
1444 	 */
1445 	if (siop_script_read(sc, (Ent_script_sched_slot0 / 4) + slot * 2) ==
1446 	    0x80000000) {
1447 		slot = sc->sc_currschedslot = 1;
1448 	} else {
1449 		slot++;
1450 	}
1451 	/* first handle commands from the urgent list */
1452 	siop_cmd = TAILQ_FIRST(&sc->urgent_list);
1453 again:
1454 	for (; siop_cmd != NULL; siop_cmd = next_siop_cmd) {
1455 		next_siop_cmd = TAILQ_NEXT(siop_cmd, next);
1456 #ifdef DIAGNOSTIC
1457 		if (siop_cmd->status != CMDST_READY &&
1458 		    siop_cmd->status != CMDST_SENSE)
1459 			panic("siop: non-ready cmd in ready list");
1460 #endif
1461 		target = siop_cmd->xs->sc_link->target;
1462 		lun = siop_cmd->xs->sc_link->lun;
1463 		siop_lun = sc->targets[target]->siop_lun[lun];
1464 		/* if non-tagged command active, wait */
1465 		if (siop_lun->siop_tag[0].active != NULL)
1466 			continue;
1467 		/*
1468 		 * if we're in a queue full condition don't start a new
1469 		 * command, unless it's a request sense
1470 		 */
1471 		if ((siop_lun->lun_flags & SIOP_LUNF_FULL) &&
1472 		    siop_cmd->status == CMDST_READY)
1473 			continue;
1474 		/* find a free tag if needed */
1475 		if (siop_cmd->flags & CMDFL_TAG) {
1476 			for (tag = 1; tag < SIOP_NTAG; tag++) {
1477 				if (siop_lun->siop_tag[tag].active == NULL)
1478 					break;
1479 			}
1480 			if (tag == SIOP_NTAG) /* no free tag */
1481 				continue;
1482 		} else {
1483 			tag = 0;
1484 		}
1485 		siop_cmd->tag = tag;
1486 		/*
1487 		 * find a free scheduler slot and load it. If it's a request
1488 		 * sense we need to use slot 0.
1489 		 */
1490 		if (siop_cmd->status != CMDST_SENSE) {
1491 			for (; slot < SIOP_NSLOTS; slot++) {
1492 				/*
1493 				 * If cmd if 0x80000000 the slot is free
1494 				 */
1495 				if (siop_script_read(sc,
1496 				    (Ent_script_sched_slot0 / 4) + slot * 2) ==
1497 				    0x80000000)
1498 					break;
1499 			}
1500 			/* no more free slots, no need to continue */
1501 			if (slot == SIOP_NSLOTS) {
1502 				goto end;
1503 			}
1504 		} else {
1505 			slot = 0;
1506 			if (siop_script_read(sc, Ent_script_sched_slot0 / 4)
1507 			    != 0x80000000)
1508 				goto end;
1509 		}
1510 
1511 #ifdef SIOP_DEBUG_SCHED
1512 		printf("using slot %d for DSA 0x%lx\n", slot,
1513 		    (u_long)siop_cmd->dsa);
1514 #endif
1515 		/* Ok, we can add the tag message */
1516 		if (tag > 0) {
1517 #ifdef DIAGNOSTIC
1518 			int msgcount =
1519 			    letoh32(siop_cmd->siop_tables.t_msgout.count);
1520 			if (msgcount != 1)
1521 				printf("%s:%d:%d: tag %d with msgcount %d\n",
1522 				    sc->sc_dev.dv_xname, target, lun, tag,
1523 				    msgcount);
1524 #endif
1525 			if (siop_cmd->xs->bp != NULL &&
1526 			    (siop_cmd->xs->bp->b_flags & B_ASYNC))
1527 				siop_cmd->siop_tables.msg_out[1] =
1528 				    MSG_SIMPLE_Q_TAG;
1529 			else
1530 				siop_cmd->siop_tables.msg_out[1] =
1531 				    MSG_ORDERED_Q_TAG;
1532 			siop_cmd->siop_tables.msg_out[2] = tag;
1533 			siop_cmd->siop_tables.t_msgout.count = htole32(3);
1534 		}
1535 		/* note that we started a new command */
1536 		newcmd = 1;
1537 		/* mark command as active */
1538 		if (siop_cmd->status == CMDST_READY) {
1539 			siop_cmd->status = CMDST_ACTIVE;
1540 		} else if (siop_cmd->status == CMDST_SENSE) {
1541 			siop_cmd->status = CMDST_SENSE_ACTIVE;
1542 		} else
1543 			panic("siop_start: bad status");
1544 		if (doingready)
1545 			TAILQ_REMOVE(&sc->ready_list, siop_cmd, next);
1546 		else
1547 			TAILQ_REMOVE(&sc->urgent_list, siop_cmd, next);
1548 		siop_lun->siop_tag[tag].active = siop_cmd;
1549 		/* patch scripts with DSA addr */
1550 		dsa = siop_cmd->dsa;
1551 		/* first reselect switch, if we have an entry */
1552 		if (siop_lun->siop_tag[tag].reseloff > 0)
1553 			siop_script_write(sc,
1554 			    siop_lun->siop_tag[tag].reseloff + 1,
1555 			    dsa + sizeof(struct siop_xfer_common) +
1556 			    Ent_ldsa_reload_dsa);
1557 		/* CMD script: MOVE MEMORY addr */
1558 		siop_cmd->siop_xfer->resel[E_ldsa_abs_slot_Used[0]] =
1559 		   htole32(sc->sc_scriptaddr + Ent_script_sched_slot0 +
1560 		   slot * 8);
1561 		siop_table_sync(siop_cmd, BUS_DMASYNC_PREWRITE);
1562 		/* scheduler slot: JUMP ldsa_select */
1563 		siop_script_write(sc,
1564 		    (Ent_script_sched_slot0 / 4) + slot * 2 + 1,
1565 		    dsa + sizeof(struct siop_xfer_common) + Ent_ldsa_select);
1566 		/* handle timeout */
1567 		if (siop_cmd->status == CMDST_ACTIVE) {
1568 			if ((siop_cmd->xs->flags & SCSI_POLL) == 0) {
1569 				/* start expire timer */
1570 				timeout = (u_int64_t) siop_cmd->xs->timeout *
1571 				    (u_int64_t)hz / 1000;
1572 				if (timeout == 0)
1573 					timeout = 1;
1574 				timeout_add(&siop_cmd->xs->stimeout, timeout);
1575 			}
1576 		}
1577 		/*
1578 		 * Change JUMP cmd so that this slot will be handled
1579 		 */
1580 		siop_script_write(sc, (Ent_script_sched_slot0 / 4) + slot * 2,
1581 		    0x80080000);
1582 		/* if we're using the request sense slot, stop here */
1583 		if (slot == 0)
1584 			goto end;
1585 		sc->sc_currschedslot = slot;
1586 		slot++;
1587 	}
1588 	if (doingready == 0) {
1589 		/* now process ready list */
1590 		doingready = 1;
1591 		siop_cmd = TAILQ_FIRST(&sc->ready_list);
1592 		goto again;
1593 	}
1594 
1595 end:
1596 	/* if nothing changed no need to flush cache and wakeup script */
1597 	if (newcmd == 0)
1598 		return;
1599 	/* make sure SCRIPT processor will read valid data */
1600 	siop_script_sync(sc,BUS_DMASYNC_PREREAD |  BUS_DMASYNC_PREWRITE);
1601 	/* Signal script it has some work to do */
1602 	bus_space_write_1(sc->sc_rt, sc->sc_rh, SIOP_ISTAT, ISTAT_SIGP);
1603 	/* and wait for IRQ */
1604 	return;
1605 }
1606 
1607 void
1608 siop_timeout(v)
1609 	void *v;
1610 {
1611 	struct siop_cmd *siop_cmd = v;
1612 	struct siop_softc *sc = siop_cmd->siop_sc;
1613 	int s;
1614 
1615 	sc_print_addr(siop_cmd->xs->sc_link);
1616 	printf("command timeout\n");
1617 
1618 	s = splbio();
1619 	/* reset the scsi bus */
1620 	siop_resetbus(sc);
1621 
1622 	/* deactivate callout */
1623 	timeout_del(&siop_cmd->xs->stimeout);
1624 	/*
1625 	 * Mark command as being timed out and just return. The bus
1626 	 * reset will generate an interrupt, which will be handled
1627 	 * in siop_intr().
1628 	 */
1629 	siop_cmd->flags |= CMDFL_TIMEOUT;
1630 	splx(s);
1631 	return;
1632 
1633 }
1634 
1635 void
1636 siop_dump_script(sc)
1637 	struct siop_softc *sc;
1638 {
1639 	int i;
1640 	for (i = 0; i < PAGE_SIZE / 4; i += 2) {
1641 		printf("0x%04x: 0x%08x 0x%08x", i * 4,
1642 		    letoh32(sc->sc_script[i]), letoh32(sc->sc_script[i+1]));
1643 		if ((letoh32(sc->sc_script[i]) & 0xe0000000) == 0xc0000000) {
1644 			i++;
1645 			printf(" 0x%08x", letoh32(sc->sc_script[i+1]));
1646 		}
1647 		printf("\n");
1648 	}
1649 }
1650 
1651 int
1652 siop_morecbd(sc)
1653 	struct siop_softc *sc;
1654 {
1655 	int error, i, j;
1656 	bus_dma_segment_t seg;
1657 	int rseg;
1658 	struct siop_cbd *newcbd;
1659 	bus_addr_t dsa;
1660 	u_int32_t *scr;
1661 
1662 	/* allocate a new list head */
1663 	newcbd = malloc(sizeof(struct siop_cbd), M_DEVBUF, M_NOWAIT);
1664 	if (newcbd == NULL) {
1665 		printf("%s: can't allocate memory for command descriptors "
1666 		    "head\n", sc->sc_dev.dv_xname);
1667 		return ENOMEM;
1668 	}
1669 	memset(newcbd, 0, sizeof(struct siop_cbd));
1670 
1671 	/* allocate cmd list */
1672 	newcbd->cmds =
1673 	    malloc(sizeof(struct siop_cmd) * SIOP_NCMDPB, M_DEVBUF, M_NOWAIT);
1674 	if (newcbd->cmds == NULL) {
1675 		printf("%s: can't allocate memory for command descriptors\n",
1676 		    sc->sc_dev.dv_xname);
1677 		error = ENOMEM;
1678 		goto bad3;
1679 	}
1680 	memset(newcbd->cmds, 0, sizeof(struct siop_cmd) * SIOP_NCMDPB);
1681 	error = bus_dmamem_alloc(sc->sc_dmat, PAGE_SIZE, PAGE_SIZE, 0, &seg,
1682 	    1, &rseg, BUS_DMA_NOWAIT);
1683 	if (error) {
1684 		printf("%s: unable to allocate cbd DMA memory, error = %d\n",
1685 		    sc->sc_dev.dv_xname, error);
1686 		goto bad2;
1687 	}
1688 	error = bus_dmamem_map(sc->sc_dmat, &seg, rseg, PAGE_SIZE,
1689 	    (caddr_t *)&newcbd->xfers, BUS_DMA_NOWAIT|BUS_DMA_COHERENT);
1690 	if (error) {
1691 		printf("%s: unable to map cbd DMA memory, error = %d\n",
1692 		    sc->sc_dev.dv_xname, error);
1693 		goto bad2;
1694 	}
1695 	error = bus_dmamap_create(sc->sc_dmat, PAGE_SIZE, 1, PAGE_SIZE, 0,
1696 	    BUS_DMA_NOWAIT, &newcbd->xferdma);
1697 	if (error) {
1698 		printf("%s: unable to create cbd DMA map, error = %d\n",
1699 		    sc->sc_dev.dv_xname, error);
1700 		goto bad1;
1701 	}
1702 	error = bus_dmamap_load(sc->sc_dmat, newcbd->xferdma, newcbd->xfers,
1703 	    PAGE_SIZE, NULL, BUS_DMA_NOWAIT);
1704 	if (error) {
1705 		printf("%s: unable to load cbd DMA map, error = %d\n",
1706 		    sc->sc_dev.dv_xname, error);
1707 		goto bad0;
1708 	}
1709 #ifdef DEBUG
1710 	printf("%s: alloc newcdb at PHY addr 0x%lx\n", sc->sc_dev.dv_xname,
1711 	    (unsigned long)newcbd->xferdma->dm_segs[0].ds_addr);
1712 #endif
1713 
1714 	for (i = 0; i < SIOP_NCMDPB; i++) {
1715 		error = bus_dmamap_create(sc->sc_dmat, MAXPHYS, SIOP_NSG,
1716 		    MAXPHYS, 0, BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
1717 		    &newcbd->cmds[i].dmamap_data);
1718 		if (error) {
1719 			printf("%s: unable to create data DMA map for cbd: "
1720 			    "error %d\n",
1721 			    sc->sc_dev.dv_xname, error);
1722 			goto bad0;
1723 		}
1724 		error = bus_dmamap_create(sc->sc_dmat,
1725 		    sizeof(struct scsi_generic), 1,
1726 		    sizeof(struct scsi_generic), 0,
1727 		    BUS_DMA_NOWAIT | BUS_DMA_ALLOCNOW,
1728 		    &newcbd->cmds[i].dmamap_cmd);
1729 		if (error) {
1730 			printf("%s: unable to create cmd DMA map for cbd %d\n",
1731 			    sc->sc_dev.dv_xname, error);
1732 			goto bad0;
1733 		}
1734 		newcbd->cmds[i].siop_sc = sc;
1735 		newcbd->cmds[i].siop_cbdp = newcbd;
1736 		newcbd->cmds[i].siop_xfer = &newcbd->xfers[i];
1737 		memset(newcbd->cmds[i].siop_xfer, 0,
1738 		    sizeof(struct siop_xfer));
1739 		newcbd->cmds[i].dsa = newcbd->xferdma->dm_segs[0].ds_addr +
1740 		    i * sizeof(struct siop_xfer);
1741 		dsa = newcbd->cmds[i].dsa;
1742 		newcbd->cmds[i].status = CMDST_FREE;
1743 		newcbd->cmds[i].siop_tables.t_msgout.count= htole32(1);
1744 		newcbd->cmds[i].siop_tables.t_msgout.addr = htole32(dsa);
1745 		newcbd->cmds[i].siop_tables.t_msgin.count= htole32(1);
1746 		newcbd->cmds[i].siop_tables.t_msgin.addr = htole32(dsa + 16);
1747 		newcbd->cmds[i].siop_tables.t_extmsgin.count= htole32(2);
1748 		newcbd->cmds[i].siop_tables.t_extmsgin.addr = htole32(dsa + 17);
1749 		newcbd->cmds[i].siop_tables.t_extmsgdata.addr =
1750 		    htole32(dsa + 19);
1751 		newcbd->cmds[i].siop_tables.t_status.count= htole32(1);
1752 		newcbd->cmds[i].siop_tables.t_status.addr = htole32(dsa + 32);
1753 
1754 		/* The select/reselect script */
1755 		scr = &newcbd->cmds[i].siop_xfer->resel[0];
1756 		for (j = 0; j < sizeof(load_dsa) / sizeof(load_dsa[0]); j++)
1757 			scr[j] = htole32(load_dsa[j]);
1758 		/*
1759 		 * 0x78000000 is a 'move data8 to reg'. data8 is the second
1760 		 * octet, reg offset is the third.
1761 		 */
1762 		scr[Ent_rdsa0 / 4] =
1763 		    htole32(0x78100000 | ((dsa & 0x000000ff) <<  8));
1764 		scr[Ent_rdsa1 / 4] =
1765 		    htole32(0x78110000 | ( dsa & 0x0000ff00       ));
1766 		scr[Ent_rdsa2 / 4] =
1767 		    htole32(0x78120000 | ((dsa & 0x00ff0000) >>  8));
1768 		scr[Ent_rdsa3 / 4] =
1769 		    htole32(0x78130000 | ((dsa & 0xff000000) >> 16));
1770 		scr[E_ldsa_abs_reselected_Used[0]] =
1771 		    htole32(sc->sc_scriptaddr + Ent_reselected);
1772 		scr[E_ldsa_abs_reselect_Used[0]] =
1773 		    htole32(sc->sc_scriptaddr + Ent_reselect);
1774 		scr[E_ldsa_abs_selected_Used[0]] =
1775 		    htole32(sc->sc_scriptaddr + Ent_selected);
1776 		scr[E_ldsa_abs_data_Used[0]] =
1777 		    htole32(dsa + sizeof(struct siop_xfer_common) +
1778 		    Ent_ldsa_data);
1779 		/* JUMP foo, IF FALSE - used by MOVE MEMORY to clear the slot */
1780 		scr[Ent_ldsa_data / 4] = htole32(0x80000000);
1781 		TAILQ_INSERT_TAIL(&sc->free_list, &newcbd->cmds[i], next);
1782 #ifdef SIOP_DEBUG
1783 		printf("tables[%d]: in=0x%x out=0x%x status=0x%x\n", i,
1784 		    letoh32(newcbd->cmds[i].siop_tables.t_msgin.addr),
1785 		    letoh32(newcbd->cmds[i].siop_tables.t_msgout.addr),
1786 		    letoh32(newcbd->cmds[i].siop_tables.t_status.addr));
1787 #endif
1788 	}
1789 	TAILQ_INSERT_TAIL(&sc->cmds, newcbd, next);
1790 	return 0;
1791 bad0:
1792 	bus_dmamap_destroy(sc->sc_dmat, newcbd->xferdma);
1793 bad1:
1794 	bus_dmamem_free(sc->sc_dmat, &seg, rseg);
1795 bad2:
1796 	free(newcbd->cmds, M_DEVBUF);
1797 bad3:
1798 	free(newcbd, M_DEVBUF);
1799 	return error;
1800 }
1801 
1802 struct siop_lunsw *
1803 siop_get_lunsw(sc)
1804 	struct siop_softc *sc;
1805 {
1806 	struct siop_lunsw *lunsw;
1807 	int i;
1808 
1809 	if (sc->script_free_lo + (sizeof(lun_switch) / sizeof(lun_switch[0])) >=
1810 	    sc->script_free_hi)
1811 		return NULL;
1812 	lunsw = TAILQ_FIRST(&sc->lunsw_list);
1813 	if (lunsw != NULL) {
1814 #ifdef SIOP_DEBUG
1815 		printf("siop_get_lunsw got lunsw at offset %d\n",
1816 		    lunsw->lunsw_off);
1817 #endif
1818 		TAILQ_REMOVE(&sc->lunsw_list, lunsw, next);
1819 		return lunsw;
1820 	}
1821 	lunsw = malloc(sizeof(struct siop_lunsw), M_DEVBUF, M_NOWAIT);
1822 	if (lunsw == NULL)
1823 		return NULL;
1824 	memset(lunsw, 0, sizeof(struct siop_lunsw));
1825 #ifdef SIOP_DEBUG
1826 	printf("allocating lunsw at offset %d\n", sc->script_free_lo);
1827 #endif
1828 	if (sc->features & SF_CHIP_RAM) {
1829 		bus_space_write_region_4(sc->sc_ramt, sc->sc_ramh,
1830 		    sc->script_free_lo * 4, lun_switch,
1831 		    sizeof(lun_switch) / sizeof(lun_switch[0]));
1832 		bus_space_write_4(sc->sc_ramt, sc->sc_ramh,
1833 		    (sc->script_free_lo + E_abs_lunsw_return_Used[0]) * 4,
1834 		    sc->sc_scriptaddr + Ent_lunsw_return);
1835 	} else {
1836 		for (i = 0; i < sizeof(lun_switch) / sizeof(lun_switch[0]);
1837 		    i++)
1838 			sc->sc_script[sc->script_free_lo + i] =
1839 			    htole32(lun_switch[i]);
1840 		sc->sc_script[sc->script_free_lo + E_abs_lunsw_return_Used[0]] =
1841 		    htole32(sc->sc_scriptaddr + Ent_lunsw_return);
1842 	}
1843 	lunsw->lunsw_off = sc->script_free_lo;
1844 	lunsw->lunsw_size = sizeof(lun_switch) / sizeof(lun_switch[0]);
1845 	sc->script_free_lo += lunsw->lunsw_size;
1846 	if (sc->script_free_lo > 1024)
1847 		printf("%s: script_free_lo (%d) > 1024\n", sc->sc_dev.dv_xname,
1848 		    sc->script_free_lo);
1849 	siop_script_sync(sc, BUS_DMASYNC_PREREAD | BUS_DMASYNC_PREWRITE);
1850 	return lunsw;
1851 }
1852 
1853 void
1854 siop_add_reselsw(sc, target)
1855 	struct siop_softc *sc;
1856 	int target;
1857 {
1858 	int i;
1859 	struct siop_lun *siop_lun;
1860 	/*
1861 	 * add an entry to resel switch
1862 	 */
1863 	siop_script_sync(sc, BUS_DMASYNC_POSTWRITE);
1864 	for (i = 0; i < 15; i++) {
1865 		sc->targets[target]->reseloff = Ent_resel_targ0 / 4 + i * 2;
1866 		if ((siop_script_read(sc, sc->targets[target]->reseloff) & 0xff)
1867 		    == 0xff) { /* it's free */
1868 #ifdef SIOP_DEBUG
1869 			printf("siop: target %d slot %d offset %d\n",
1870 			    target, i, sc->targets[target]->reseloff);
1871 #endif
1872 			/* JUMP abs_foo, IF target | 0x80; */
1873 			siop_script_write(sc, sc->targets[target]->reseloff,
1874 			    0x800c0080 | target);
1875 			siop_script_write(sc, sc->targets[target]->reseloff + 1,
1876 			    sc->sc_scriptaddr +
1877 			    sc->targets[target]->lunsw->lunsw_off * 4 +
1878 			    Ent_lun_switch_entry);
1879 			break;
1880 		}
1881 	}
1882 	if (i == 15) /* no free slot, shouldn't happen */
1883 		panic("siop: resel switch full");
1884 
1885 	sc->sc_ntargets++;
1886 	for (i = 0; i < 8; i++) {
1887 		siop_lun = sc->targets[target]->siop_lun[i];
1888 		if (siop_lun == NULL)
1889 			continue;
1890 		if (siop_lun->reseloff > 0) {
1891 			siop_lun->reseloff = 0;
1892 			siop_add_dev(sc, target, i);
1893 		}
1894 	}
1895 	siop_update_scntl3(sc, sc->targets[target]);
1896 	siop_script_sync(sc, BUS_DMASYNC_PREWRITE);
1897 }
1898 
1899 void
1900 siop_update_scntl3(sc, siop_target)
1901 	struct siop_softc *sc;
1902 	struct siop_target *siop_target;
1903 {
1904 	/* MOVE target->id >> 24 TO SCNTL3 */
1905 	siop_script_write(sc,
1906 	    siop_target->lunsw->lunsw_off + (Ent_restore_scntl3 / 4),
1907 	    0x78030000 | ((siop_target->id >> 16) & 0x0000ff00));
1908 	/* MOVE target->id >> 8 TO SXFER */
1909 	siop_script_write(sc,
1910 	    siop_target->lunsw->lunsw_off + (Ent_restore_scntl3 / 4) + 2,
1911 	    0x78050000 | (siop_target->id & 0x0000ff00));
1912 	/* If DT, change null op ('MOVE 0xff TO SFBR') to 'MOVE n TO SCNTL4' */
1913 	if (siop_target->flags & TARF_ISDT)
1914 		siop_script_write(sc,
1915 		    siop_target->lunsw->lunsw_off + (Ent_restore_scntl3 / 4) + 4,
1916 		    0x78bc0000 | ((siop_target->id << 8) & 0x0000ff00));
1917 	else
1918 		siop_script_write(sc,
1919 		    siop_target->lunsw->lunsw_off + (Ent_restore_scntl3 / 4) + 4,
1920 		    0x7808ff00);
1921 
1922 	siop_script_sync(sc, BUS_DMASYNC_PREWRITE);
1923 }
1924 
1925 void
1926 siop_add_dev(sc, target, lun)
1927 	struct siop_softc *sc;
1928 	int target;
1929 	int lun;
1930 {
1931 	struct siop_lunsw *lunsw;
1932 	struct siop_lun *siop_lun = sc->targets[target]->siop_lun[lun];
1933 	int i, ntargets;
1934 
1935 	if (siop_lun->reseloff > 0)
1936 		return;
1937 	lunsw = sc->targets[target]->lunsw;
1938 	if ((lunsw->lunsw_off + lunsw->lunsw_size) < sc->script_free_lo) {
1939 		/*
1940 		 * Can't extend this slot. Probably not worth trying to deal
1941 		 * with this case.
1942 		 */
1943 #ifdef DEBUG
1944 		printf("%s:%d:%d: can't allocate a lun sw slot\n",
1945 		    sc->sc_dev.dv_xname, target, lun);
1946 #endif
1947 		return;
1948 	}
1949 	/* count how many free targets we still have to probe */
1950 	ntargets =  (sc->sc_link.adapter_buswidth - 1) - 1 - sc->sc_ntargets;
1951 
1952 	/*
1953 	 * We need 8 bytes for the lun sw additional entry, and
1954 	 * eventually sizeof(tag_switch) for the tag switch entry.
1955 	 * Keep enough free space for the free targets that could be
1956 	 * probed later.
1957 	 */
1958 	if (sc->script_free_lo + 2 +
1959 	    (ntargets * sizeof(lun_switch) / sizeof(lun_switch[0])) >=
1960 	    ((sc->targets[target]->flags & TARF_TAG) ?
1961 	    sc->script_free_hi - (sizeof(tag_switch) / sizeof(tag_switch[0])) :
1962 	    sc->script_free_hi)) {
1963 		/*
1964 		 * Not enough space, but probably not worth dealing with it.
1965 		 * We can hold 13 tagged-queuing capable devices in the 4k RAM.
1966 		 */
1967 #ifdef DEBUG
1968 		printf("%s:%d:%d: not enough memory for a lun sw slot\n",
1969 		    sc->sc_dev.dv_xname, target, lun);
1970 #endif
1971 		return;
1972 	}
1973 #ifdef SIOP_DEBUG
1974 	printf("%s:%d:%d: allocate lun sw entry\n",
1975 	    sc->sc_dev.dv_xname, target, lun);
1976 #endif
1977 	/* INT int_resellun */
1978 	siop_script_write(sc, sc->script_free_lo, 0x98080000);
1979 	siop_script_write(sc, sc->script_free_lo + 1, A_int_resellun);
1980 	/* Now the slot entry: JUMP abs_foo, IF lun */
1981 	siop_script_write(sc, sc->script_free_lo - 2,
1982 	    0x800c0000 | lun);
1983 	siop_script_write(sc, sc->script_free_lo - 1, 0);
1984 	siop_lun->reseloff = sc->script_free_lo - 2;
1985 	lunsw->lunsw_size += 2;
1986 	sc->script_free_lo += 2;
1987 	if (sc->targets[target]->flags & TARF_TAG) {
1988 		/* we need a tag switch */
1989 		sc->script_free_hi -=
1990 		    sizeof(tag_switch) / sizeof(tag_switch[0]);
1991 		if (sc->features & SF_CHIP_RAM) {
1992 			bus_space_write_region_4(sc->sc_ramt, sc->sc_ramh,
1993 			    sc->script_free_hi * 4, tag_switch,
1994 			    sizeof(tag_switch) / sizeof(tag_switch[0]));
1995 		} else {
1996 			for(i = 0;
1997 			    i < sizeof(tag_switch) / sizeof(tag_switch[0]);
1998 			    i++) {
1999 				sc->sc_script[sc->script_free_hi + i] =
2000 				    htole32(tag_switch[i]);
2001 			}
2002 		}
2003 		siop_script_write(sc,
2004 		    siop_lun->reseloff + 1,
2005 		    sc->sc_scriptaddr + sc->script_free_hi * 4 +
2006 		    Ent_tag_switch_entry);
2007 
2008 		for (i = 0; i < SIOP_NTAG; i++) {
2009 			siop_lun->siop_tag[i].reseloff =
2010 			    sc->script_free_hi + (Ent_resel_tag0 / 4) + i * 2;
2011 		}
2012 	} else {
2013 		/* non-tag case; just work with the lun switch */
2014 		siop_lun->siop_tag[0].reseloff =
2015 		    sc->targets[target]->siop_lun[lun]->reseloff;
2016 	}
2017 	siop_script_sync(sc, BUS_DMASYNC_PREWRITE);
2018 }
2019 
2020 void
2021 siop_del_dev(sc, target, lun)
2022 	struct siop_softc *sc;
2023 	int target;
2024 	int lun;
2025 {
2026 	int i;
2027 #ifdef SIOP_DEBUG
2028 		printf("%s:%d:%d: free lun sw entry\n",
2029 		    sc->sc_dev.dv_xname, target, lun);
2030 #endif
2031 	if (sc->targets[target] == NULL)
2032 		return;
2033 	free(sc->targets[target]->siop_lun[lun], M_DEVBUF);
2034 	sc->targets[target]->siop_lun[lun] = NULL;
2035 	/* XXX compact sw entry too ? */
2036 	/* check if we can free the whole target */
2037 	for (i = 0; i < 8; i++) {
2038 		if (sc->targets[target]->siop_lun[i] != NULL)
2039 			return;
2040 	}
2041 #ifdef SIOP_DEBUG
2042 	printf("%s: free siop_target for target %d lun %d lunsw offset %d\n",
2043 	    sc->sc_dev.dv_xname, target, lun,
2044 	    sc->targets[target]->lunsw->lunsw_off);
2045 #endif
2046 	/*
2047 	 * nothing here, free the target struct and resel
2048 	 * switch entry
2049 	 */
2050 	siop_script_write(sc, sc->targets[target]->reseloff, 0x800c00ff);
2051 	siop_script_sync(sc, BUS_DMASYNC_PREWRITE);
2052 	TAILQ_INSERT_TAIL(&sc->lunsw_list, sc->targets[target]->lunsw, next);
2053 	free(sc->targets[target], M_DEVBUF);
2054 	sc->targets[target] = NULL;
2055 	sc->sc_ntargets--;
2056 }
2057 
2058 #ifdef SIOP_STATS
2059 void
2060 siop_printstats()
2061 {
2062 	printf("siop_stat_intr %d\n", siop_stat_intr);
2063 	printf("siop_stat_intr_shortxfer %d\n", siop_stat_intr_shortxfer);
2064 	printf("siop_stat_intr_xferdisc %d\n", siop_stat_intr_xferdisc);
2065 	printf("siop_stat_intr_sdp %d\n", siop_stat_intr_sdp);
2066 	printf("siop_stat_intr_done %d\n", siop_stat_intr_done);
2067 	printf("siop_stat_intr_lunresel %d\n", siop_stat_intr_lunresel);
2068 	printf("siop_stat_intr_qfull %d\n", siop_stat_intr_qfull);
2069 }
2070 #endif
2071