xref: /netbsd-src/sys/dev/ic/aha.c (revision 181254a7b1bdde6873432bffef2d2decc4b5c22f)
1 /*	$NetBSD: aha.c,v 1.63 2016/07/14 04:19:27 msaitoh Exp $	*/
2 
3 /*-
4  * Copyright (c) 1997, 1998 The NetBSD Foundation, Inc.
5  * All rights reserved.
6  *
7  * This code is derived from software contributed to The NetBSD Foundation
8  * by Charles M. Hannum and by Jason R. Thorpe of the Numerical Aerospace
9  * Simulation Facility, NASA Ames Research Center.
10  *
11  * Redistribution and use in source and binary forms, with or without
12  * modification, are permitted provided that the following conditions
13  * are met:
14  * 1. Redistributions of source code must retain the above copyright
15  *    notice, this list of conditions and the following disclaimer.
16  * 2. Redistributions in binary form must reproduce the above copyright
17  *    notice, this list of conditions and the following disclaimer in the
18  *    documentation and/or other materials provided with the distribution.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
21  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30  * POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * Originally written by Julian Elischer (julian@tfs.com)
35  * for TRW Financial Systems for use under the MACH(2.5) operating system.
36  *
37  * TRW Financial Systems, in accordance with their agreement with Carnegie
38  * Mellon University, makes this software available to CMU to distribute
39  * or use in any manner that they see fit as long as this message is kept with
40  * the software. For this reason TFS also grants any other persons or
41  * organisations permission to use or modify this software.
42  *
43  * TFS supplies this software to be publicly redistributed
44  * on the understanding that TFS is not responsible for the correct
45  * functioning of this software in any circumstances.
46  */
47 
48 #include <sys/cdefs.h>
49 __KERNEL_RCSID(0, "$NetBSD: aha.c,v 1.63 2016/07/14 04:19:27 msaitoh Exp $");
50 
51 #include "opt_ddb.h"
52 
53 #undef AHADIAG
54 
55 #include <sys/param.h>
56 #include <sys/systm.h>
57 #include <sys/callout.h>
58 #include <sys/kernel.h>
59 #include <sys/errno.h>
60 #include <sys/ioctl.h>
61 #include <sys/device.h>
62 #include <sys/malloc.h>
63 #include <sys/buf.h>
64 #include <sys/proc.h>
65 
66 #include <sys/bus.h>
67 #include <sys/intr.h>
68 
69 #include <dev/scsipi/scsi_all.h>
70 #include <dev/scsipi/scsipi_all.h>
71 #include <dev/scsipi/scsiconf.h>
72 
73 #include <dev/ic/ahareg.h>
74 #include <dev/ic/ahavar.h>
75 
76 #ifndef DDB
77 #define Debugger() panic("should call debugger here (aha1542.c)")
78 #endif /* ! DDB */
79 
80 #define	AHA_MAXXFER	((AHA_NSEG - 1) << PGSHIFT)
81 
82 #ifdef AHADEBUG
83 int	aha_debug = 1;
84 #endif /* AHADEBUG */
85 
86 static int	aha_cmd(bus_space_tag_t, bus_space_handle_t,
87 			struct aha_softc *, int, u_char *, int, u_char *);
88 static void	aha_finish_ccbs(struct aha_softc *);
89 static void	aha_free_ccb(struct aha_softc *, struct aha_ccb *);
90 static int	aha_init_ccb(struct aha_softc *, struct aha_ccb *);
91 static struct aha_ccb *aha_get_ccb(struct aha_softc *);
92 static struct aha_ccb *aha_ccb_phys_kv(struct aha_softc *, u_long);
93 static void	aha_queue_ccb(struct aha_softc *, struct aha_ccb *);
94 static void	aha_collect_mbo(struct aha_softc *);
95 static void	aha_start_ccbs(struct aha_softc *);
96 static void	aha_done(struct aha_softc *, struct aha_ccb *);
97 static int	aha_init(struct aha_softc *);
98 static void	aha_inquire_setup_information(struct aha_softc *);
99 static void	ahaminphys(struct buf *);
100 static void	aha_scsipi_request(struct scsipi_channel *,
101 				   scsipi_adapter_req_t, void *);
102 static int	aha_poll(struct aha_softc *, struct scsipi_xfer *, int);
103 static void	aha_timeout(void *arg);
104 static int	aha_create_ccbs(struct aha_softc *, struct aha_ccb *, int);
105 
106 #define AHA_RESET_TIMEOUT	2000	/* time to wait for reset (mSec) */
107 #define	AHA_ABORT_TIMEOUT	2000	/* time to wait for abort (mSec) */
108 
109 /*
110  * aha_cmd(iot, ioh, sc, icnt, ibuf, ocnt, obuf)
111  *
112  * Activate Adapter command
113  *    icnt:   number of args (outbound bytes including opcode)
114  *    ibuf:   argument buffer
115  *    ocnt:   number of expected returned bytes
116  *    obuf:   result buffer
117  *    wait:   number of seconds to wait for response
118  *
119  * Performs an adapter command through the ports.  Not to be confused with a
120  * scsi command, which is read in via the DMA; one of the adapter commands
121  * tells it to read in a scsi command.
122  */
123 static int
124 aha_cmd(bus_space_tag_t iot, bus_space_handle_t ioh, struct aha_softc *sc,
125     int icnt, u_char *ibuf, int ocnt, u_char *obuf)
126 {
127 	const char *name;
128 	int i;
129 	int wait;
130 	u_char sts;
131 	u_char opcode = ibuf[0];
132 
133 	if (sc != NULL)
134 		name = device_xname(sc->sc_dev);
135 	else
136 		name = "(aha probe)";
137 
138 	/*
139 	 * Calculate a reasonable timeout for the command.
140 	 */
141 	switch (opcode) {
142 	case AHA_INQUIRE_DEVICES:
143 		wait = 90 * 20000;
144 		break;
145 	default:
146 		wait = 1 * 20000;
147 		break;
148 	}
149 
150 	/*
151 	 * Wait for the adapter to go idle, unless it's one of
152 	 * the commands which don't need this
153 	 */
154 	if (opcode != AHA_MBO_INTR_EN) {
155 		for (i = 20000; i; i--) {	/* 1 sec? */
156 			sts = bus_space_read_1(iot, ioh, AHA_STAT_PORT);
157 			if (sts & AHA_STAT_IDLE)
158 				break;
159 			delay(50);
160 		}
161 		if (!i) {
162 			printf("%s: aha_cmd, host not idle(0x%x)\n",
163 			    name, sts);
164 			return (1);
165 		}
166 	}
167 	/*
168 	 * Now that it is idle, if we expect output, preflush the
169 	 * queue feeding to us.
170 	 */
171 	if (ocnt) {
172 		while ((bus_space_read_1(iot, ioh, AHA_STAT_PORT))
173 		    & AHA_STAT_DF)
174 			bus_space_read_1(iot, ioh, AHA_DATA_PORT);
175 	}
176 	/*
177 	 * Output the command and the number of arguments given
178 	 * for each byte, first check the port is empty.
179 	 */
180 	while (icnt--) {
181 		for (i = wait; i; i--) {
182 			sts = bus_space_read_1(iot, ioh, AHA_STAT_PORT);
183 			if (!(sts & AHA_STAT_CDF))
184 				break;
185 			delay(50);
186 		}
187 		if (!i) {
188 			if (opcode != AHA_INQUIRE_REVISION)
189 				printf("%s: aha_cmd, cmd/data port full\n",
190 				    name);
191 			bus_space_write_1(iot, ioh, AHA_CTRL_PORT,
192 			    AHA_CTRL_SRST);
193 			return (1);
194 		}
195 		bus_space_write_1(iot, ioh, AHA_CMD_PORT, *ibuf++);
196 	}
197 	/*
198 	 * If we expect input, loop that many times, each time,
199 	 * looking for the data register to have valid data
200 	 */
201 	while (ocnt--) {
202 		for (i = wait; i; i--) {
203 			sts = bus_space_read_1(iot, ioh, AHA_STAT_PORT);
204 			if (sts & AHA_STAT_DF)
205 				break;
206 			delay(50);
207 		}
208 		if (!i) {
209 			if (opcode != AHA_INQUIRE_REVISION)
210 				printf("%s: aha_cmd, cmd/data port empty %d\n",
211 				    name, ocnt);
212 			bus_space_write_1(iot, ioh, AHA_CTRL_PORT,
213 			    AHA_CTRL_SRST);
214 			return (1);
215 		}
216 		*obuf++ = bus_space_read_1(iot, ioh, AHA_DATA_PORT);
217 	}
218 	/*
219 	 * Wait for the board to report a finished instruction.
220 	 * We may get an extra interrupt for the HACC signal, but this is
221 	 * unimportant.
222 	 */
223 	if (opcode != AHA_MBO_INTR_EN) {
224 		for (i = 20000; i; i--) {	/* 1 sec? */
225 			sts = bus_space_read_1(iot, ioh, AHA_INTR_PORT);
226 			/* XXX Need to save this in the interrupt handler? */
227 			if (sts & AHA_INTR_HACC)
228 				break;
229 			delay(50);
230 		}
231 		if (!i) {
232 			printf("%s: aha_cmd, host not finished(0x%x)\n",
233 			    name, sts);
234 			return (1);
235 		}
236 	}
237 	bus_space_write_1(iot, ioh, AHA_CTRL_PORT, AHA_CTRL_IRST);
238 	return (0);
239 }
240 
241 void
242 aha_attach(struct aha_softc *sc, struct aha_probe_data *apd)
243 {
244 	struct scsipi_adapter *adapt = &sc->sc_adapter;
245 	struct scsipi_channel *chan = &sc->sc_channel;
246 
247 	TAILQ_INIT(&sc->sc_free_ccb);
248 	TAILQ_INIT(&sc->sc_waiting_ccb);
249 
250 	/*
251 	 * Fill in the scsipi_adapter.
252 	 */
253 	memset(adapt, 0, sizeof(*adapt));
254 	adapt->adapt_dev = sc->sc_dev;
255 	adapt->adapt_nchannels = 1;
256 	/* adapt_openings initialized below */
257 	/* adapt_max_periph initialized below */
258 	adapt->adapt_request = aha_scsipi_request;
259 	adapt->adapt_minphys = ahaminphys;
260 
261 	/*
262 	 * Fill in the scsipi_channel.
263 	 */
264 	memset(chan, 0, sizeof(*chan));
265 	chan->chan_adapter = adapt;
266 	chan->chan_bustype = &scsi_bustype;
267 	chan->chan_channel = 0;
268 	chan->chan_ntargets = 8;
269 	chan->chan_nluns = 8;
270 	chan->chan_id = apd->sc_scsi_dev;
271 
272 	aha_inquire_setup_information(sc);
273 	if (aha_init(sc) != 0) {
274 		/* Error during initialization! */
275 		return;
276 	}
277 
278 	/*
279 	 * ask the adapter what subunits are present
280 	 */
281 	config_found(sc->sc_dev, &sc->sc_channel, scsiprint);
282 }
283 
284 static void
285 aha_finish_ccbs(struct aha_softc *sc)
286 {
287 	struct aha_mbx_in *wmbi;
288 	struct aha_ccb *ccb;
289 	int i;
290 
291 	wmbi = wmbx->tmbi;
292 
293 	bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
294 	    AHA_MBI_OFF(wmbi), sizeof(struct aha_mbx_in),
295 	    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
296 
297 	if (wmbi->stat == AHA_MBI_FREE) {
298 		for (i = 0; i < AHA_MBX_SIZE; i++) {
299 			if (wmbi->stat != AHA_MBI_FREE) {
300 				printf("%s: mbi not in round-robin order\n",
301 				    device_xname(sc->sc_dev));
302 				goto AGAIN;
303 			}
304 			aha_nextmbx(wmbi, wmbx, mbi);
305 			bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
306 			    AHA_MBI_OFF(wmbi), sizeof(struct aha_mbx_in),
307 			    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
308 		}
309 #ifdef AHADIAGnot
310 		printf("%s: mbi interrupt with no full mailboxes\n",
311 		    device_xname(sc->sc_dev));
312 #endif
313 		return;
314 	}
315 
316 AGAIN:
317 	do {
318 		ccb = aha_ccb_phys_kv(sc, phystol(wmbi->ccb_addr));
319 		if (!ccb) {
320 			printf("%s: bad mbi ccb pointer; skipping\n",
321 			    device_xname(sc->sc_dev));
322 			goto next;
323 		}
324 
325 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
326 		    AHA_CCB_OFF(ccb), sizeof(struct aha_ccb),
327 		    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
328 
329 #ifdef AHADEBUG
330 		if (aha_debug) {
331 			u_char *cp = ccb->scsi_cmd;
332 			printf("op=%x %x %x %x %x %x\n",
333 			    cp[0], cp[1], cp[2], cp[3], cp[4], cp[5]);
334 			printf("stat %x for mbi addr = %p, ",
335 			    wmbi->stat, wmbi);
336 			printf("ccb addr = %p\n", ccb);
337 		}
338 #endif /* AHADEBUG */
339 
340 		switch (wmbi->stat) {
341 		case AHA_MBI_OK:
342 		case AHA_MBI_ERROR:
343 			if ((ccb->flags & CCB_ABORT) != 0) {
344 				/*
345 				 * If we already started an abort, wait for it
346 				 * to complete before clearing the CCB.  We
347 				 * could instead just clear CCB_SENDING, but
348 				 * what if the mailbox was already received?
349 				 * The worst that happens here is that we clear
350 				 * the CCB a bit later than we need to.  BFD.
351 				 */
352 				goto next;
353 			}
354 			break;
355 
356 		case AHA_MBI_ABORT:
357 		case AHA_MBI_UNKNOWN:
358 			/*
359 			 * Even if the CCB wasn't found, we clear it anyway.
360 			 * See preceding comment.
361 			 */
362 			break;
363 
364 		default:
365 			printf("%s: bad mbi status %02x; skipping\n",
366 			    device_xname(sc->sc_dev), wmbi->stat);
367 			goto next;
368 		}
369 
370 		callout_stop(&ccb->xs->xs_callout);
371 		aha_done(sc, ccb);
372 
373 	next:
374 		wmbi->stat = AHA_MBI_FREE;
375 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
376 		    AHA_MBI_OFF(wmbi), sizeof(struct aha_mbx_in),
377 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
378 		aha_nextmbx(wmbi, wmbx, mbi);
379 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
380 		    AHA_MBI_OFF(wmbi), sizeof(struct aha_mbx_in),
381 		    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
382 	} while (wmbi->stat != AHA_MBI_FREE);
383 
384 	wmbx->tmbi = wmbi;
385 }
386 
387 /*
388  * Catch an interrupt from the adaptor
389  */
390 int
391 aha_intr(void *arg)
392 {
393 	struct aha_softc *sc = arg;
394 	bus_space_tag_t iot = sc->sc_iot;
395 	bus_space_handle_t ioh = sc->sc_ioh;
396 	u_char sts;
397 
398 #ifdef AHADEBUG
399 	printf("%s: aha_intr ", device_xname(sc->sc_dev));
400 #endif /*AHADEBUG */
401 
402 	/*
403 	 * First acknowledge the interrupt, Then if it's not telling about
404 	 * a completed operation just return.
405 	 */
406 	sts = bus_space_read_1(iot, ioh, AHA_INTR_PORT);
407 	if ((sts & AHA_INTR_ANYINTR) == 0)
408 		return (0);
409 	bus_space_write_1(iot, ioh, AHA_CTRL_PORT, AHA_CTRL_IRST);
410 
411 #ifdef AHADIAG
412 	/* Make sure we clear CCB_SENDING before finishing a CCB. */
413 	aha_collect_mbo(sc);
414 #endif
415 
416 	/* Mail box out empty? */
417 	if (sts & AHA_INTR_MBOA) {
418 		struct aha_toggle toggle;
419 
420 		toggle.cmd.opcode = AHA_MBO_INTR_EN;
421 		toggle.cmd.enable = 0;
422 		aha_cmd(iot, ioh, sc,
423 		    sizeof(toggle.cmd), (u_char *)&toggle.cmd,
424 		    0, (u_char *)0);
425 		aha_start_ccbs(sc);
426 	}
427 
428 	/* Mail box in full? */
429 	if (sts & AHA_INTR_MBIF)
430 		aha_finish_ccbs(sc);
431 
432 	return (1);
433 }
434 
435 static inline void
436 aha_reset_ccb(struct aha_softc *sc, struct aha_ccb *ccb)
437 {
438 
439 	ccb->flags = 0;
440 }
441 
442 /*
443  * A ccb is put onto the free list.
444  */
445 static void
446 aha_free_ccb(struct aha_softc *sc, struct aha_ccb *ccb)
447 {
448 	int s;
449 
450 	s = splbio();
451 	aha_reset_ccb(sc, ccb);
452 	TAILQ_INSERT_HEAD(&sc->sc_free_ccb, ccb, chain);
453 	splx(s);
454 }
455 
456 static int
457 aha_init_ccb(struct aha_softc *sc, struct aha_ccb *ccb)
458 {
459 	bus_dma_tag_t dmat = sc->sc_dmat;
460 	int hashnum, error;
461 
462 	/*
463 	 * Create the DMA map for this CCB.
464 	 */
465 	error = bus_dmamap_create(dmat, AHA_MAXXFER, AHA_NSEG, AHA_MAXXFER,
466 	    0, BUS_DMA_NOWAIT|BUS_DMA_ALLOCNOW, &ccb->dmamap_xfer);
467 	if (error) {
468 		aprint_error_dev(sc->sc_dev,
469 		    "unable to create ccb DMA map, error = %d\n",
470 		    error);
471 		return (error);
472 	}
473 
474 	/*
475 	 * put in the phystokv hash table
476 	 * Never gets taken out.
477 	 */
478 	ccb->hashkey = sc->sc_dmamap_control->dm_segs[0].ds_addr +
479 	    AHA_CCB_OFF(ccb);
480 	hashnum = CCB_HASH(ccb->hashkey);
481 	ccb->nexthash = sc->sc_ccbhash[hashnum];
482 	sc->sc_ccbhash[hashnum] = ccb;
483 	aha_reset_ccb(sc, ccb);
484 	return (0);
485 }
486 
487 /*
488  * Create a set of ccbs and add them to the free list.  Called once
489  * by aha_init().  We return the number of CCBs successfully created.
490  */
491 static int
492 aha_create_ccbs(struct aha_softc *sc, struct aha_ccb *ccbstore, int count)
493 {
494 	struct aha_ccb *ccb;
495 	int i, error;
496 
497 	memset(ccbstore, 0, sizeof(struct aha_ccb) * count);
498 	for (i = 0; i < count; i++) {
499 		ccb = &ccbstore[i];
500 		if ((error = aha_init_ccb(sc, ccb)) != 0) {
501 			aprint_error_dev(sc->sc_dev,
502 			    "unable to initialize ccb, error = %d\n",
503 			    error);
504 			goto out;
505 		}
506 		TAILQ_INSERT_TAIL(&sc->sc_free_ccb, ccb, chain);
507 	}
508  out:
509 	return (i);
510 }
511 
512 /*
513  * Get a free ccb
514  *
515  * If there are none, see if we can allocate a new one.  If so, put it in
516  * the hash table too otherwise either return an error or sleep.
517  */
518 struct aha_ccb *
519 aha_get_ccb(struct aha_softc *sc)
520 {
521 	struct aha_ccb *ccb;
522 	int s;
523 
524 	s = splbio();
525 	ccb = TAILQ_FIRST(&sc->sc_free_ccb);
526 	if (ccb != NULL) {
527 		TAILQ_REMOVE(&sc->sc_free_ccb, ccb, chain);
528 		ccb->flags |= CCB_ALLOC;
529 	}
530 	splx(s);
531 	return (ccb);
532 }
533 
534 /*
535  * Given a physical address, find the ccb that it corresponds to.
536  */
537 static struct aha_ccb *
538 aha_ccb_phys_kv(struct aha_softc *sc, u_long ccb_phys)
539 {
540 	int hashnum = CCB_HASH(ccb_phys);
541 	struct aha_ccb *ccb = sc->sc_ccbhash[hashnum];
542 
543 	while (ccb) {
544 		if (ccb->hashkey == ccb_phys)
545 			break;
546 		ccb = ccb->nexthash;
547 	}
548 	return (ccb);
549 }
550 
551 /*
552  * Queue a CCB to be sent to the controller, and send it if possible.
553  */
554 static void
555 aha_queue_ccb(struct aha_softc *sc, struct aha_ccb *ccb)
556 {
557 
558 	TAILQ_INSERT_TAIL(&sc->sc_waiting_ccb, ccb, chain);
559 	aha_start_ccbs(sc);
560 }
561 
562 /*
563  * Garbage collect mailboxes that are no longer in use.
564  */
565 static void
566 aha_collect_mbo(struct aha_softc *sc)
567 {
568 	struct aha_mbx_out *wmbo;	/* Mail Box Out pointer */
569 #ifdef AHADIAG
570 	struct aha_ccb *ccb;
571 #endif
572 
573 	wmbo = wmbx->cmbo;
574 
575 	while (sc->sc_mbofull > 0) {
576 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
577 		    AHA_MBO_OFF(wmbo), sizeof(struct aha_mbx_out),
578 		    BUS_DMASYNC_POSTREAD|BUS_DMASYNC_POSTWRITE);
579 		if (wmbo->cmd != AHA_MBO_FREE)
580 			break;
581 
582 #ifdef AHADIAG
583 		ccb = aha_ccb_phys_kv(sc, phystol(wmbo->ccb_addr));
584 		ccb->flags &= ~CCB_SENDING;
585 #endif
586 
587 		--sc->sc_mbofull;
588 		aha_nextmbx(wmbo, wmbx, mbo);
589 	}
590 
591 	wmbx->cmbo = wmbo;
592 }
593 
594 /*
595  * Send as many CCBs as we have empty mailboxes for.
596  */
597 static void
598 aha_start_ccbs(struct aha_softc *sc)
599 {
600 	bus_space_tag_t iot = sc->sc_iot;
601 	bus_space_handle_t ioh = sc->sc_ioh;
602 	struct aha_mbx_out *wmbo;	/* Mail Box Out pointer */
603 	struct aha_ccb *ccb;
604 
605 	wmbo = wmbx->tmbo;
606 
607 	while ((ccb = sc->sc_waiting_ccb.tqh_first) != NULL) {
608 		if (sc->sc_mbofull >= AHA_MBX_SIZE) {
609 			aha_collect_mbo(sc);
610 			if (sc->sc_mbofull >= AHA_MBX_SIZE) {
611 				struct aha_toggle toggle;
612 
613 				toggle.cmd.opcode = AHA_MBO_INTR_EN;
614 				toggle.cmd.enable = 1;
615 				aha_cmd(iot, ioh, sc,
616 				    sizeof(toggle.cmd), (u_char *)&toggle.cmd,
617 				    0, (u_char *)0);
618 				break;
619 			}
620 		}
621 
622 		TAILQ_REMOVE(&sc->sc_waiting_ccb, ccb, chain);
623 #ifdef AHADIAG
624 		ccb->flags |= CCB_SENDING;
625 #endif
626 
627 		/* Link ccb to mbo. */
628 		ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
629 		    AHA_CCB_OFF(ccb), wmbo->ccb_addr);
630 		if (ccb->flags & CCB_ABORT)
631 			wmbo->cmd = AHA_MBO_ABORT;
632 		else
633 			wmbo->cmd = AHA_MBO_START;
634 
635 		 bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
636 		     AHA_MBO_OFF(wmbo), sizeof(struct aha_mbx_out),
637 		     BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
638 
639 		/* Tell the card to poll immediately. */
640 		bus_space_write_1(iot, ioh, AHA_CMD_PORT, AHA_START_SCSI);
641 
642 		if ((ccb->xs->xs_control & XS_CTL_POLL) == 0)
643 			callout_reset(&ccb->xs->xs_callout,
644 			    mstohz(ccb->timeout), aha_timeout, ccb);
645 
646 		++sc->sc_mbofull;
647 		aha_nextmbx(wmbo, wmbx, mbo);
648 	}
649 
650 	wmbx->tmbo = wmbo;
651 }
652 
653 /*
654  * We have a ccb which has been processed by the
655  * adaptor, now we look to see how the operation
656  * went. Wake up the owner if waiting
657  */
658 static void
659 aha_done(struct aha_softc *sc, struct aha_ccb *ccb)
660 {
661 	bus_dma_tag_t dmat = sc->sc_dmat;
662 	struct scsi_sense_data *s1, *s2;
663 	struct scsipi_xfer *xs = ccb->xs;
664 
665 	SC_DEBUG(xs->xs_periph, SCSIPI_DB2, ("aha_done\n"));
666 
667 	/*
668 	 * If we were a data transfer, unload the map that described
669 	 * the data buffer.
670 	 */
671 	if (xs->datalen) {
672 		bus_dmamap_sync(dmat, ccb->dmamap_xfer, 0,
673 		    ccb->dmamap_xfer->dm_mapsize,
674 		    (xs->xs_control & XS_CTL_DATA_IN) ? BUS_DMASYNC_POSTREAD :
675 		    BUS_DMASYNC_POSTWRITE);
676 		bus_dmamap_unload(dmat, ccb->dmamap_xfer);
677 	}
678 
679 	/*
680 	 * Otherwise, put the results of the operation
681 	 * into the xfer and call whoever started it
682 	 */
683 #ifdef AHADIAG
684 	if (ccb->flags & CCB_SENDING) {
685 		printf("%s: exiting ccb still in transit!\n",
686 		    device_xname(sc->sc_dev));
687 		Debugger();
688 		return;
689 	}
690 #endif
691 	if ((ccb->flags & CCB_ALLOC) == 0) {
692 		printf("%s: exiting ccb not allocated!\n",
693 		    device_xname(sc->sc_dev));
694 		Debugger();
695 		return;
696 	}
697 	if (xs->error == XS_NOERROR) {
698 		if (ccb->host_stat != AHA_OK) {
699 			switch (ccb->host_stat) {
700 			case AHA_SEL_TIMEOUT:	/* No response */
701 				xs->error = XS_SELTIMEOUT;
702 				break;
703 			default:	/* Other scsi protocol messes */
704 				printf("%s: host_stat %x\n",
705 				    device_xname(sc->sc_dev), ccb->host_stat);
706 				xs->error = XS_DRIVER_STUFFUP;
707 				break;
708 			}
709 		} else if (ccb->target_stat != SCSI_OK) {
710 			switch (ccb->target_stat) {
711 			case SCSI_CHECK:
712 				s1 = (struct scsi_sense_data *)
713 				    (((char *)(&ccb->scsi_cmd)) +
714 				    ccb->scsi_cmd_length);
715 				s2 = &xs->sense.scsi_sense;
716 				*s2 = *s1;
717 				xs->error = XS_SENSE;
718 				break;
719 			case SCSI_BUSY:
720 				xs->error = XS_BUSY;
721 				break;
722 			default:
723 				printf("%s: target_stat %x\n",
724 				    device_xname(sc->sc_dev), ccb->target_stat);
725 				xs->error = XS_DRIVER_STUFFUP;
726 				break;
727 			}
728 		} else
729 			xs->resid = 0;
730 	}
731 	aha_free_ccb(sc, ccb);
732 	scsipi_done(xs);
733 }
734 
735 /*
736  * Find the board and find its irq/drq
737  */
738 int
739 aha_find(bus_space_tag_t iot, bus_space_handle_t ioh,
740     struct aha_probe_data *sc)
741 {
742 	int i;
743 	u_char sts;
744 	struct aha_config config;
745 	int irq, drq;
746 
747 	/*
748 	 * assume invalid status means the board is not present.
749 	 */
750 
751 	sts = bus_space_read_1(iot, ioh, AHA_STAT_PORT);
752 	if (sts == 0)
753 		return (0);
754 	if ((sts & (AHA_STAT_STST|AHA_STAT_RSVD|AHA_STAT_CDF)) != 0)
755 		return (0);
756 	sts = bus_space_read_1(iot, ioh, AHA_INTR_PORT);
757 	if ((sts & AHA_INTR_RSVD) != 0)
758 		return (0);
759 
760 	/*
761 	 * reset board, If it doesn't respond, assume
762 	 * that it's not there.. good for the probe
763 	 */
764 
765 	bus_space_write_1(iot, ioh, AHA_CTRL_PORT,
766 	    AHA_CTRL_HRST | AHA_CTRL_SRST);
767 
768 	delay(100);
769 	for (i = AHA_RESET_TIMEOUT; i; i--) {
770 		sts = bus_space_read_1(iot, ioh, AHA_STAT_PORT);
771 		if (sts == (AHA_STAT_IDLE | AHA_STAT_INIT))
772 			break;
773 		delay(1000);	/* calibrated in msec */
774 	}
775 	if (!i) {
776 #ifdef AHADEBUG
777 		if (aha_debug)
778 			printf("aha_find: No answer from adaptec board\n");
779 #endif /* AHADEBUG */
780 		return (0);
781 	}
782 
783 	/*
784 	 * setup DMA channel from jumpers and save int
785 	 * level
786 	 */
787 	delay(1000);		/* for Bustek 545 */
788 	config.cmd.opcode = AHA_INQUIRE_CONFIG;
789 	aha_cmd(iot, ioh, (struct aha_softc *)0,
790 	    sizeof(config.cmd), (u_char *)&config.cmd,
791 	    sizeof(config.reply), (u_char *)&config.reply);
792 	switch (config.reply.chan) {
793 	case EISADMA:
794 		drq = -1;
795 		break;
796 	case CHAN0:
797 		drq = 0;
798 		break;
799 	case CHAN5:
800 		drq = 5;
801 		break;
802 	case CHAN6:
803 		drq = 6;
804 		break;
805 	case CHAN7:
806 		drq = 7;
807 		break;
808 	default:
809 		printf("aha_find: illegal drq setting %x\n", config.reply.chan);
810 		return (0);
811 	}
812 
813 	switch (config.reply.intr) {
814 	case INT9:
815 		irq = 9;
816 		break;
817 	case INT10:
818 		irq = 10;
819 		break;
820 	case INT11:
821 		irq = 11;
822 		break;
823 	case INT12:
824 		irq = 12;
825 		break;
826 	case INT14:
827 		irq = 14;
828 		break;
829 	case INT15:
830 		irq = 15;
831 		break;
832 	default:
833 		printf("aha_find: illegal irq setting %x\n", config.reply.intr);
834 		return (0);
835 	}
836 
837 	if (sc) {
838 		sc->sc_irq = irq;
839 		sc->sc_drq = drq;
840 		sc->sc_scsi_dev = config.reply.scsi_dev;
841 	}
842 
843 	return (1);
844 }
845 
846 /*
847  * Start the board, ready for normal operation
848  */
849 static int
850 aha_init(struct aha_softc *sc)
851 {
852 	bus_space_tag_t iot = sc->sc_iot;
853 	bus_space_handle_t ioh = sc->sc_ioh;
854 	bus_dma_segment_t seg;
855 	struct aha_devices devices;
856 	struct aha_setup setup;
857 	struct aha_mailbox mailbox;
858 	int error, i, j, initial_ccbs, rseg;
859 
860 	/*
861 	 * XXX
862 	 * If we are a 1542C or later, disable the extended BIOS so that the
863 	 * mailbox interface is unlocked.
864 	 * No need to check the extended BIOS flags as some of the
865 	 * extensions that cause us problems are not flagged in that byte.
866 	 */
867 	if (!strncmp(sc->sc_model, "1542C", 5)) {
868 		struct aha_extbios extbios;
869 		struct aha_unlock unlock;
870 
871 		printf("%s: unlocking mailbox interface\n",
872 		    device_xname(sc->sc_dev));
873 		extbios.cmd.opcode = AHA_EXT_BIOS;
874 		aha_cmd(iot, ioh, sc,
875 		    sizeof(extbios.cmd), (u_char *)&extbios.cmd,
876 		    sizeof(extbios.reply), (u_char *)&extbios.reply);
877 
878 #ifdef AHADEBUG
879 		printf("%s: flags=%02x, mailboxlock=%02x\n",
880 		    device_xname(sc->sc_dev),
881 		    extbios.reply.flags, extbios.reply.mailboxlock);
882 #endif /* AHADEBUG */
883 
884 		unlock.cmd.opcode = AHA_MBX_ENABLE;
885 		unlock.cmd.junk = 0;
886 		unlock.cmd.magic = extbios.reply.mailboxlock;
887 		aha_cmd(iot, ioh, sc,
888 		    sizeof(unlock.cmd), (u_char *)&unlock.cmd,
889 		    0, (u_char *)0);
890 	}
891 
892 #if 0
893 	/*
894 	 * Change the bus on/off times to not clash with other DMA users.
895 	 */
896 	aha_cmd(iot, ioh, 1, 0, 0, 0, AHA_BUS_ON_TIME_SET, 7);
897 	aha_cmd(iot, ioh, 1, 0, 0, 0, AHA_BUS_OFF_TIME_SET, 4);
898 #endif
899 
900 	/* Inquire Installed Devices (to force synchronous negotiation). */
901 	devices.cmd.opcode = AHA_INQUIRE_DEVICES;
902 	aha_cmd(iot, ioh, sc,
903 	    sizeof(devices.cmd), (u_char *)&devices.cmd,
904 	    sizeof(devices.reply), (u_char *)&devices.reply);
905 
906 	/* Count installed units */
907 	initial_ccbs = 0;
908 	for (i = 0; i < 8; i++) {
909 		for (j = 0; j < 8; j++) {
910 			if (((devices.reply.lun_map[i] >> j) & 1) == 1)
911 				initial_ccbs += 1;
912 		}
913 	}
914 	initial_ccbs *= 2;
915 	if (initial_ccbs > AHA_CCB_MAX)
916 		initial_ccbs = AHA_CCB_MAX;
917 	if (initial_ccbs == 0)	/* yes, this can happen */
918 		initial_ccbs = 2;
919 
920 	/* Obtain setup information from. */
921 	setup.cmd.opcode = AHA_INQUIRE_SETUP;
922 	setup.cmd.len = sizeof(setup.reply);
923 	aha_cmd(iot, ioh, sc,
924 	    sizeof(setup.cmd), (u_char *)&setup.cmd,
925 	    sizeof(setup.reply), (u_char *)&setup.reply);
926 
927 	printf("%s: %s, %s\n",
928 	    device_xname(sc->sc_dev),
929 	    setup.reply.sync_neg ? "sync" : "async",
930 	    setup.reply.parity ? "parity" : "no parity");
931 
932 	for (i = 0; i < 8; i++) {
933 		if (!setup.reply.sync[i].valid ||
934 		    (!setup.reply.sync[i].offset
935 			&& !setup.reply.sync[i].period))
936 			continue;
937 		printf("%s targ %d: sync, offset %d, period %dnsec\n",
938 		    device_xname(sc->sc_dev), i, setup.reply.sync[i].offset,
939 		    setup.reply.sync[i].period * 50 + 200);
940 	}
941 
942 	/*
943 	 * Allocate the mailbox and control blocks.
944 	 */
945 	if ((error = bus_dmamem_alloc(sc->sc_dmat, sizeof(struct aha_control),
946 	    PAGE_SIZE, 0, &seg, 1, &rseg, BUS_DMA_NOWAIT)) != 0) {
947 		aprint_error_dev(sc->sc_dev,
948 		    "unable to allocate control structures, "
949 		    "error = %d\n", error);
950 		return (error);
951 	}
952 	if ((error = bus_dmamem_map(sc->sc_dmat, &seg, rseg,
953 	    sizeof(struct aha_control), (void **)&sc->sc_control,
954 	    BUS_DMA_NOWAIT|BUS_DMA_COHERENT)) != 0) {
955 		aprint_error_dev(sc->sc_dev,
956 		    "unable to map control structures, error = %d\n", error);
957 		return (error);
958 	}
959 
960 	/*
961 	 * Create and load the DMA map used for the mailbox and
962 	 * control blocks.
963 	 */
964 	if ((error = bus_dmamap_create(sc->sc_dmat, sizeof(struct aha_control),
965 	    1, sizeof(struct aha_control), 0, BUS_DMA_NOWAIT,
966 	    &sc->sc_dmamap_control)) != 0) {
967 		aprint_error_dev(sc->sc_dev,
968 		    "unable to create control DMA map, error = %d\n", error);
969 		return (error);
970 	}
971 	if ((error = bus_dmamap_load(sc->sc_dmat, sc->sc_dmamap_control,
972 	    sc->sc_control, sizeof(struct aha_control), NULL,
973 	    BUS_DMA_NOWAIT)) != 0) {
974 		aprint_error_dev(sc->sc_dev,
975 		    "unable to load control DMA map, error = %d\n", error);
976 		return (error);
977 	}
978 
979 	/*
980 	 * Initialize the control blocks.
981 	 */
982 	i = aha_create_ccbs(sc, sc->sc_control->ac_ccbs, initial_ccbs);
983 	if (i == 0) {
984 		aprint_error_dev(sc->sc_dev,
985 		    "unable to create control blocks\n");
986 		return (ENOMEM);
987 	} else if (i != initial_ccbs) {
988 		printf("%s: WARNING: only %d of %d control blocks created\n",
989 		    device_xname(sc->sc_dev), i, initial_ccbs);
990 	}
991 
992 	sc->sc_adapter.adapt_openings = i;
993 	sc->sc_adapter.adapt_max_periph = sc->sc_adapter.adapt_openings;
994 
995 	/*
996 	 * Set up initial mail box for round-robin operation.
997 	 */
998 	for (i = 0; i < AHA_MBX_SIZE; i++) {
999 		wmbx->mbo[i].cmd = AHA_MBO_FREE;
1000 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
1001 		    AHA_MBO_OFF(&wmbx->mbo[i]), sizeof(struct aha_mbx_out),
1002 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1003 		wmbx->mbi[i].stat = AHA_MBI_FREE;
1004 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
1005 		    AHA_MBI_OFF(&wmbx->mbi[i]), sizeof(struct aha_mbx_in),
1006 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1007 	}
1008 	wmbx->cmbo = wmbx->tmbo = &wmbx->mbo[0];
1009 	wmbx->tmbi = &wmbx->mbi[0];
1010 	sc->sc_mbofull = 0;
1011 
1012 	/* Initialize mail box. */
1013 	mailbox.cmd.opcode = AHA_MBX_INIT;
1014 	mailbox.cmd.nmbx = AHA_MBX_SIZE;
1015 	ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
1016 	    offsetof(struct aha_control, ac_mbx), mailbox.cmd.addr);
1017 	aha_cmd(iot, ioh, sc,
1018 	    sizeof(mailbox.cmd), (u_char *)&mailbox.cmd,
1019 	    0, (u_char *)0);
1020 	return (0);
1021 }
1022 
1023 static void
1024 aha_inquire_setup_information(struct aha_softc *sc)
1025 {
1026 	bus_space_tag_t iot = sc->sc_iot;
1027 	bus_space_handle_t ioh = sc->sc_ioh;
1028 	struct aha_revision revision;
1029 	u_char sts;
1030 	int i;
1031 	char *p;
1032 
1033 	strcpy(sc->sc_model, "unknown");
1034 
1035 	/*
1036 	 * Assume we have a board at this stage, do an adapter inquire
1037 	 * to find out what type of controller it is.  If the command
1038 	 * fails, we assume it's either a crusty board or an old 1542
1039 	 * clone, and skip the board-specific stuff.
1040 	 */
1041 	revision.cmd.opcode = AHA_INQUIRE_REVISION;
1042 	if (aha_cmd(iot, ioh, sc,
1043 	    sizeof(revision.cmd), (u_char *)&revision.cmd,
1044 	    sizeof(revision.reply), (u_char *)&revision.reply)) {
1045 		/*
1046 		 * aha_cmd() already started the reset.  It's not clear we
1047 		 * even need to bother here.
1048 		 */
1049 		for (i = AHA_RESET_TIMEOUT; i; i--) {
1050 			sts = bus_space_read_1(iot, ioh, AHA_STAT_PORT);
1051 			if (sts == (AHA_STAT_IDLE | AHA_STAT_INIT))
1052 				break;
1053 			delay(1000);
1054 		}
1055 		if (!i) {
1056 #ifdef AHADEBUG
1057 			printf("aha_init: soft reset failed\n");
1058 #endif /* AHADEBUG */
1059 			return;
1060 		}
1061 #ifdef AHADEBUG
1062 		printf("aha_init: inquire command failed\n");
1063 #endif /* AHADEBUG */
1064 		goto noinquire;
1065 	}
1066 
1067 #ifdef AHADEBUG
1068 	printf("%s: inquire %x, %x, %x, %x\n",
1069 	    device_xname(sc->sc_dev),
1070 	    revision.reply.boardid, revision.reply.spec_opts,
1071 	    revision.reply.revision_1, revision.reply.revision_2);
1072 #endif /* AHADEBUG */
1073 
1074 	switch (revision.reply.boardid) {
1075 	case BOARD_1540_16HEAD_BIOS:
1076 	case BOARD_1540_64HEAD_BIOS:
1077 	case BOARD_1540:
1078 		strcpy(sc->sc_model, "1540");
1079 		break;
1080 	case BOARD_1542:
1081 		strcpy(sc->sc_model, "1540A/1542A/1542B");
1082 		break;
1083 	case BOARD_1640:
1084 		strcpy(sc->sc_model, "1640");
1085 		break;
1086 	case BOARD_1740:
1087 		strcpy(sc->sc_model, "1740");
1088 		break;
1089 	case BOARD_1542C:
1090 		strcpy(sc->sc_model, "1542C");
1091 		break;
1092 	case BOARD_1542CF:
1093 		strcpy(sc->sc_model, "1542CF");
1094 		break;
1095 	case BOARD_1542CP:
1096 		strcpy(sc->sc_model, "1542CP");
1097 		break;
1098 	}
1099 
1100 	p = sc->sc_firmware;
1101 	*p++ = revision.reply.revision_1;
1102 	*p++ = '.';
1103 	*p++ = revision.reply.revision_2;
1104 	*p = '\0';
1105 
1106 noinquire:
1107 	printf("%s: model AHA-%s, firmware %s\n",
1108 	       device_xname(sc->sc_dev),
1109 	       sc->sc_model, sc->sc_firmware);
1110 }
1111 
1112 static void
1113 ahaminphys(struct buf *bp)
1114 {
1115 
1116 	if (bp->b_bcount > AHA_MAXXFER)
1117 		bp->b_bcount = AHA_MAXXFER;
1118 	minphys(bp);
1119 }
1120 
1121 /*
1122  * start a scsi operation given the command and the data address. Also needs
1123  * the unit, target and lu.
1124  */
1125 
1126 static void
1127 aha_scsipi_request(struct scsipi_channel *chan, scsipi_adapter_req_t req,
1128     void *arg)
1129 {
1130 	struct scsipi_xfer *xs;
1131 	struct scsipi_periph *periph;
1132 	struct aha_softc *sc = device_private(chan->chan_adapter->adapt_dev);
1133 	bus_dma_tag_t dmat = sc->sc_dmat;
1134 	struct aha_ccb *ccb;
1135 	int error, seg, flags, s;
1136 
1137 
1138 	switch (req) {
1139 	case ADAPTER_REQ_RUN_XFER:
1140 		xs = arg;
1141 		periph = xs->xs_periph;
1142 		flags = xs->xs_control;
1143 
1144 		SC_DEBUG(periph, SCSIPI_DB2, ("aha_scsipi_request\n"));
1145 
1146 		/* Get a CCB to use. */
1147 		ccb = aha_get_ccb(sc);
1148 #ifdef DIAGNOSTIC
1149 		/*
1150 		 * This should never happen as we track the resources
1151 		 * in the mid-layer.
1152 		 */
1153 		if (ccb == NULL) {
1154 			scsipi_printaddr(periph);
1155 			printf("unable to allocate ccb\n");
1156 			panic("aha_scsipi_request");
1157 		}
1158 #endif
1159 
1160 		ccb->xs = xs;
1161 		ccb->timeout = xs->timeout;
1162 
1163 		/*
1164 		 * Put all the arguments for the xfer in the ccb
1165 		 */
1166 		if (flags & XS_CTL_RESET) {
1167 			ccb->opcode = AHA_RESET_CCB;
1168 			ccb->scsi_cmd_length = 0;
1169 		} else {
1170 			/* can't use S/G if zero length */
1171 			if (xs->cmdlen > sizeof(ccb->scsi_cmd)) {
1172 				printf("%s: cmdlen %d too large for CCB\n",
1173 				    device_xname(sc->sc_dev), xs->cmdlen);
1174 				xs->error = XS_DRIVER_STUFFUP;
1175 				goto out_bad;
1176 			}
1177 			ccb->opcode = (xs->datalen ? AHA_INIT_SCAT_GATH_CCB
1178 						   : AHA_INITIATOR_CCB);
1179 			memcpy(&ccb->scsi_cmd, xs->cmd,
1180 			    ccb->scsi_cmd_length = xs->cmdlen);
1181 		}
1182 
1183 		if (xs->datalen) {
1184 			/*
1185 			 * Map the DMA transfer.
1186 			 */
1187 #ifdef TFS
1188 			if (flags & XS_CTL_DATA_UIO) {
1189 				error = bus_dmamap_load_uio(dmat,
1190 				    ccb->dmamap_xfer, (struct uio *)xs->data,
1191 				    ((flags & XS_CTL_NOSLEEP) ? BUS_DMA_NOWAIT :
1192 				     BUS_DMA_WAITOK) | BUS_DMA_STREAMING |
1193 				     ((flags & XS_CTL_DATA_IN) ? BUS_DMA_READ :
1194 				      BUS_DMA_WRITE));
1195 			} else
1196 #endif
1197 			{
1198 				error = bus_dmamap_load(dmat,
1199 				    ccb->dmamap_xfer, xs->data, xs->datalen,
1200 				    NULL,
1201 				    ((flags & XS_CTL_NOSLEEP) ? BUS_DMA_NOWAIT :
1202 				     BUS_DMA_WAITOK) | BUS_DMA_STREAMING |
1203 				     ((flags & XS_CTL_DATA_IN) ? BUS_DMA_READ :
1204 				      BUS_DMA_WRITE));
1205 			}
1206 
1207 			switch (error) {
1208 			case 0:
1209 				break;
1210 
1211 			case ENOMEM:
1212 			case EAGAIN:
1213 				xs->error = XS_RESOURCE_SHORTAGE;
1214 				goto out_bad;
1215 
1216 			default:
1217 				xs->error = XS_DRIVER_STUFFUP;
1218 				if (error == EFBIG) {
1219 					printf("%s: aha_scsi_cmd, more than %d"
1220 					    " DMA segments\n",
1221 					    device_xname(sc->sc_dev), AHA_NSEG);
1222 				} else {
1223 					aprint_error_dev(sc->sc_dev,
1224 					    "error %d loading DMA map\n",
1225 					    error);
1226 				}
1227 out_bad:
1228 				aha_free_ccb(sc, ccb);
1229 				scsipi_done(xs);
1230 				return;
1231 			}
1232 
1233 			bus_dmamap_sync(dmat, ccb->dmamap_xfer, 0,
1234 			    ccb->dmamap_xfer->dm_mapsize,
1235 			    (flags & XS_CTL_DATA_IN) ? BUS_DMASYNC_PREREAD :
1236 			    BUS_DMASYNC_PREWRITE);
1237 
1238 			/*
1239 			 * Load the hardware scatter/gather map with the
1240 			 * contents of the DMA map.
1241 			 */
1242 			for (seg = 0; seg < ccb->dmamap_xfer->dm_nsegs; seg++) {
1243 				ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_addr,
1244 				    ccb->scat_gath[seg].seg_addr);
1245 				ltophys(ccb->dmamap_xfer->dm_segs[seg].ds_len,
1246 				    ccb->scat_gath[seg].seg_len);
1247 			}
1248 
1249 			ltophys(sc->sc_dmamap_control->dm_segs[0].ds_addr +
1250 			    AHA_CCB_OFF(ccb) +
1251 			    offsetof(struct aha_ccb, scat_gath),
1252 			    ccb->data_addr);
1253 			ltophys(ccb->dmamap_xfer->dm_nsegs *
1254 			    sizeof(struct aha_scat_gath), ccb->data_length);
1255 		} else {
1256 			/*
1257 			 * No data xfer, use non S/G values.
1258 			 */
1259 			ltophys(0, ccb->data_addr);
1260 			ltophys(0, ccb->data_length);
1261 		}
1262 
1263 		ccb->data_out = 0;
1264 		ccb->data_in = 0;
1265 		ccb->target = periph->periph_target;
1266 		ccb->lun = periph->periph_lun;
1267 		ccb->req_sense_length = sizeof(ccb->scsi_sense);
1268 		ccb->host_stat = 0x00;
1269 		ccb->target_stat = 0x00;
1270 		ccb->link_id = 0;
1271 		ltophys(0, ccb->link_addr);
1272 
1273 		bus_dmamap_sync(sc->sc_dmat, sc->sc_dmamap_control,
1274 		    AHA_CCB_OFF(ccb), sizeof(struct aha_ccb),
1275 		    BUS_DMASYNC_PREREAD|BUS_DMASYNC_PREWRITE);
1276 
1277 		s = splbio();
1278 		aha_queue_ccb(sc, ccb);
1279 		splx(s);
1280 
1281 		SC_DEBUG(periph, SCSIPI_DB3, ("cmd_sent\n"));
1282 		if ((flags & XS_CTL_POLL) == 0)
1283 			return;
1284 
1285 		/* Not allowed to use interrupts, poll for completion. */
1286 		if (aha_poll(sc, xs, ccb->timeout)) {
1287 			aha_timeout(ccb);
1288 			if (aha_poll(sc, xs, ccb->timeout))
1289 				aha_timeout(ccb);
1290 		}
1291 		return;
1292 
1293 	case ADAPTER_REQ_GROW_RESOURCES:
1294 		/* XXX Not supported. */
1295 		return;
1296 
1297 	case ADAPTER_REQ_SET_XFER_MODE:
1298 		/*
1299 		 * Can't really do this on the Adaptec; it has
1300 		 * its own config mechanism, but we do know how
1301 		 * to query what the firmware negotiated.
1302 		 */
1303 		/* XXX XXX XXX */
1304 		return;
1305 	}
1306 }
1307 
1308 /*
1309  * Poll a particular unit, looking for a particular xs
1310  */
1311 static int
1312 aha_poll(struct aha_softc *sc, struct scsipi_xfer *xs, int count)
1313 {
1314 	bus_space_tag_t iot = sc->sc_iot;
1315 	bus_space_handle_t ioh = sc->sc_ioh;
1316 
1317 	/* timeouts are in msec, so we loop in 1000 usec cycles */
1318 	while (count) {
1319 		/*
1320 		 * If we had interrupts enabled, would we
1321 		 * have got an interrupt?
1322 		 */
1323 		if (bus_space_read_1(iot, ioh, AHA_INTR_PORT)
1324 		    & AHA_INTR_ANYINTR)
1325 			aha_intr(sc);
1326 		if (xs->xs_status & XS_STS_DONE)
1327 			return (0);
1328 		delay(1000);	/* only happens in boot so ok */
1329 		count--;
1330 	}
1331 	return (1);
1332 }
1333 
1334 static void
1335 aha_timeout(void *arg)
1336 {
1337 	struct aha_ccb *ccb = arg;
1338 	struct scsipi_xfer *xs = ccb->xs;
1339 	struct scsipi_periph *periph = xs->xs_periph;
1340 	struct aha_softc *sc =
1341 	    device_private(periph->periph_channel->chan_adapter->adapt_dev);
1342 	int s;
1343 
1344 	scsipi_printaddr(periph);
1345 	printf("timed out");
1346 
1347 	s = splbio();
1348 
1349 #ifdef AHADIAG
1350 	/*
1351 	 * If The ccb's mbx is not free, then the board has gone south?
1352 	 */
1353 	aha_collect_mbo(sc);
1354 	if (ccb->flags & CCB_SENDING) {
1355 		aprint_error_dev(sc->sc_dev, "not taking commands!\n");
1356 		Debugger();
1357 	}
1358 #endif
1359 
1360 	/*
1361 	 * If it has been through before, then
1362 	 * a previous abort has failed, don't
1363 	 * try abort again
1364 	 */
1365 	if (ccb->flags & CCB_ABORT) {
1366 		/* abort timed out */
1367 		printf(" AGAIN\n");
1368 		/* XXX Must reset! */
1369 	} else {
1370 		/* abort the operation that has timed out */
1371 		printf("\n");
1372 		ccb->xs->error = XS_TIMEOUT;
1373 		ccb->timeout = AHA_ABORT_TIMEOUT;
1374 		ccb->flags |= CCB_ABORT;
1375 		aha_queue_ccb(sc, ccb);
1376 	}
1377 
1378 	splx(s);
1379 }
1380