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