xref: /openbsd-src/sys/dev/ic/aac.c (revision 99fd087599a8791921855f21bd7e36130f39aadc)
1 /*	$OpenBSD: aac.c,v 1.76 2020/02/18 16:05:56 krw Exp $	*/
2 
3 /*-
4  * Copyright (c) 2000 Michael Smith
5  * Copyright (c) 2001 Scott Long
6  * Copyright (c) 2000 BSDi
7  * Copyright (c) 2001 Adaptec, Inc.
8  * Copyright (c) 2000 Niklas Hallqvist
9  * Copyright (c) 2004 Nathan Binkert
10  * All rights reserved.
11  *
12  * Redistribution and use in source and binary forms, with or without
13  * modification, are permitted provided that the following conditions
14  * are met:
15  * 1. Redistributions of source code must retain the above copyright
16  *    notice, this list of conditions and the following disclaimer.
17  * 2. Redistributions in binary form must reproduce the above copyright
18  *    notice, this list of conditions and the following disclaimer in the
19  *    documentation and/or other materials provided with the distribution.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  *
33  *	$FreeBSD: /c/ncvs/src/sys/dev/aac/aac.c,v 1.1 2000/09/13 03:20:34 msmith Exp $
34  */
35 
36 /*
37  * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
38  */
39 
40 /*
41  * This driver would not have rewritten for OpenBSD if it was not for the
42  * hardware donation from Nocom.  I want to thank them for their support.
43  * Of course, credit should go to Mike Smith for the original work he did
44  * in the FreeBSD driver where I found lots of reusable code and inspiration.
45  * - Niklas Hallqvist
46  */
47 
48 #include <sys/param.h>
49 #include <sys/systm.h>
50 #include <sys/buf.h>
51 #include <sys/device.h>
52 #include <sys/kernel.h>
53 #include <sys/kthread.h>
54 #include <sys/malloc.h>
55 #include <sys/rwlock.h>
56 #include <sys/selinfo.h>
57 #include <sys/time.h>
58 
59 #include <machine/bus.h>
60 
61 #include <uvm/uvm_extern.h>
62 
63 #include <scsi/scsi_all.h>
64 #include <scsi/scsi_disk.h>
65 #include <scsi/scsiconf.h>
66 
67 #include <dev/ic/aacreg.h>
68 #include <dev/ic/aacvar.h>
69 #include <dev/ic/aac_tables.h>
70 
71 /* Geometry constants. */
72 #define AAC_MAXCYLS		1024
73 #define AAC_HEADS		64
74 #define AAC_SECS		32	/* mapping 64*32 */
75 #define AAC_MEDHEADS		127
76 #define AAC_MEDSECS		63	/* mapping 127*63 */
77 #define AAC_BIGHEADS		255
78 #define AAC_BIGSECS		63	/* mapping 255*63 */
79 #define AAC_SECS32		0x1f	/* round capacity */
80 
81 struct scsi_xfer;
82 
83 void	aac_copy_internal_data(struct scsi_xfer *, u_int8_t *, size_t);
84 char   *aac_describe_code(struct aac_code_lookup *, u_int32_t);
85 void	aac_describe_controller(struct aac_softc *);
86 int	aac_enqueue_fib(struct aac_softc *, int, struct aac_command *);
87 int	aac_dequeue_fib(struct aac_softc *, int, u_int32_t *,
88 			struct aac_fib **);
89 int	aac_enqueue_response(struct aac_softc *sc, int queue,
90 			     struct aac_fib *fib);
91 
92 void	aac_eval_mapping(u_int32_t, int *, int *, int *);
93 void	aac_print_printf(struct aac_softc *);
94 int	aac_init(struct aac_softc *);
95 int	aac_check_firmware(struct aac_softc *);
96 void	aac_internal_cache_cmd(struct scsi_xfer *);
97 
98 /* Command Processing */
99 void	aac_timeout(struct aac_softc *);
100 void	aac_command_timeout(struct aac_command *);
101 int	aac_map_command(struct aac_command *);
102 void	aac_complete(void *);
103 int	aac_bio_command(struct aac_softc *, struct aac_command **);
104 void	aac_bio_complete(struct aac_command *);
105 int	aac_wait_command(struct aac_command *, int);
106 void	aac_create_thread(void *);
107 void	aac_command_thread(void *);
108 
109 /* Command Buffer Management */
110 void	aac_map_command_sg(void *, bus_dma_segment_t *, int, int);
111 int	aac_alloc_commands(struct aac_softc *);
112 void	aac_free_commands(struct aac_softc *);
113 void	aac_unmap_command(struct aac_command *);
114 int	aac_wait_command(struct aac_command *, int);
115 void *	aac_alloc_command(void *);
116 void	aac_scrub_command(struct aac_command *);
117 void	aac_release_command(void *, void *);
118 int	aac_alloc_sync_fib(struct aac_softc *, struct aac_fib **, int);
119 void	aac_release_sync_fib(struct aac_softc *);
120 int	aac_sync_fib(struct aac_softc *, u_int32_t, u_int32_t,
121 	    struct aac_fib *, u_int16_t);
122 
123 void	aac_scsi_cmd(struct scsi_xfer *);
124 void	aac_startio(struct aac_softc *);
125 void	aac_startup(struct aac_softc *);
126 int	aac_sync_command(struct aac_softc *, u_int32_t, u_int32_t,
127     u_int32_t, u_int32_t, u_int32_t, u_int32_t *);
128 
129 struct cfdriver aac_cd = {
130 	NULL, "aac", DV_DULL
131 };
132 
133 struct scsi_adapter aac_switch = {
134 	aac_scsi_cmd, NULL, NULL, NULL, NULL
135 };
136 
137 /* Falcon/PPC interface */
138 int	aac_fa_get_fwstatus(struct aac_softc *);
139 void	aac_fa_qnotify(struct aac_softc *, int);
140 int	aac_fa_get_istatus(struct aac_softc *);
141 void	aac_fa_clear_istatus(struct aac_softc *, int);
142 void	aac_fa_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t, u_int32_t,
143 			   u_int32_t, u_int32_t);
144 int	aac_fa_get_mailbox(struct aac_softc *, int);
145 void	aac_fa_set_interrupts(struct aac_softc *, int);
146 
147 struct aac_interface aac_fa_interface = {
148 	aac_fa_get_fwstatus,
149 	aac_fa_qnotify,
150 	aac_fa_get_istatus,
151 	aac_fa_clear_istatus,
152 	aac_fa_set_mailbox,
153 	aac_fa_get_mailbox,
154 	aac_fa_set_interrupts
155 };
156 
157 /* StrongARM interface */
158 int	aac_sa_get_fwstatus(struct aac_softc *);
159 void	aac_sa_qnotify(struct aac_softc *, int);
160 int	aac_sa_get_istatus(struct aac_softc *);
161 void	aac_sa_clear_istatus(struct aac_softc *, int);
162 void	aac_sa_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t,
163     u_int32_t, u_int32_t, u_int32_t);
164 int	aac_sa_get_mailbox(struct aac_softc *, int);
165 void	aac_sa_set_interrupts(struct aac_softc *, int);
166 
167 struct aac_interface aac_sa_interface = {
168 	aac_sa_get_fwstatus,
169 	aac_sa_qnotify,
170 	aac_sa_get_istatus,
171 	aac_sa_clear_istatus,
172 	aac_sa_set_mailbox,
173 	aac_sa_get_mailbox,
174 	aac_sa_set_interrupts
175 };
176 
177 /* i960Rx interface */
178 int	aac_rx_get_fwstatus(struct aac_softc *);
179 void	aac_rx_qnotify(struct aac_softc *, int);
180 int	aac_rx_get_istatus(struct aac_softc *);
181 void	aac_rx_clear_istatus(struct aac_softc *, int);
182 void	aac_rx_set_mailbox(struct aac_softc *, u_int32_t, u_int32_t,
183     u_int32_t, u_int32_t, u_int32_t);
184 int	aac_rx_get_mailbox(struct aac_softc *, int);
185 void	aac_rx_set_interrupts(struct aac_softc *, int);
186 
187 struct aac_interface aac_rx_interface = {
188 	aac_rx_get_fwstatus,
189 	aac_rx_qnotify,
190 	aac_rx_get_istatus,
191 	aac_rx_clear_istatus,
192 	aac_rx_set_mailbox,
193 	aac_rx_get_mailbox,
194 	aac_rx_set_interrupts
195 };
196 
197 /* Rocket/MIPS interface */
198 int	aac_rkt_get_fwstatus(struct aac_softc *);
199 void	aac_rkt_qnotify(struct aac_softc *, int);
200 int	aac_rkt_get_istatus(struct aac_softc *);
201 void	aac_rkt_clear_istatus(struct aac_softc *, int);
202 void	aac_rkt_set_mailbox(struct aac_softc *, u_int32_t,
203 				    u_int32_t, u_int32_t,
204 				    u_int32_t, u_int32_t);
205 int	aac_rkt_get_mailbox(struct aac_softc *, int);
206 void	aac_rkt_set_interrupts(struct aac_softc *, int);
207 
208 struct aac_interface aac_rkt_interface = {
209 	aac_rkt_get_fwstatus,
210 	aac_rkt_qnotify,
211 	aac_rkt_get_istatus,
212 	aac_rkt_clear_istatus,
213 	aac_rkt_set_mailbox,
214 	aac_rkt_get_mailbox,
215 	aac_rkt_set_interrupts
216 };
217 
218 #ifdef AAC_DEBUG
219 int	aac_debug = AAC_DEBUG;
220 #endif
221 
222 int
223 aac_attach(struct aac_softc *sc)
224 {
225 	struct scsibus_attach_args saa;
226 	int error;
227 
228 	/*
229 	 * Initialise per-controller queues.
230 	 */
231 	mtx_init(&sc->aac_free_mtx, IPL_BIO);
232 	aac_initq_free(sc);
233 	aac_initq_ready(sc);
234 	aac_initq_busy(sc);
235 	aac_initq_bio(sc);
236 
237 	/* disable interrupts before we enable anything */
238 	AAC_MASK_INTERRUPTS(sc);
239 
240 	/* mark controller as suspended until we get ourselves organised */
241 	sc->aac_state |= AAC_STATE_SUSPEND;
242 
243 	/*
244 	 * Check that the firmware on the card is supported.
245 	 */
246 	error = aac_check_firmware(sc);
247 	if (error)
248 		return (error);
249 
250 	/*
251 	 * Initialize locks
252 	 */
253 	AAC_LOCK_INIT(&sc->aac_sync_lock, "AAC sync FIB lock");
254 	AAC_LOCK_INIT(&sc->aac_aifq_lock, "AAC AIF lock");
255 	AAC_LOCK_INIT(&sc->aac_io_lock, "AAC I/O lock");
256 	AAC_LOCK_INIT(&sc->aac_container_lock, "AAC container lock");
257 	TAILQ_INIT(&sc->aac_container_tqh);
258 
259 	/* Initialize the local AIF queue pointers */
260 	sc->aac_aifq_head = sc->aac_aifq_tail = AAC_AIFQ_LENGTH;
261 
262 	/*
263 	 * Initialise the adapter.
264 	 */
265 	error = aac_init(sc);
266 	if (error)
267 		return (error);
268 
269 	/* Fill in the prototype scsi_link. */
270 	sc->aac_link.adapter_softc = sc;
271 	sc->aac_link.adapter = &aac_switch;
272 	sc->aac_link.openings = (sc->total_fibs - 8) /
273 	    (sc->aac_container_count ? sc->aac_container_count : 1);
274 	sc->aac_link.adapter_buswidth = AAC_MAX_CONTAINERS;
275 	sc->aac_link.adapter_target = AAC_MAX_CONTAINERS;
276 	sc->aac_link.pool = &sc->aac_iopool;
277 
278 	bzero(&saa, sizeof(saa));
279 	saa.saa_sc_link = &sc->aac_link;
280 
281 	config_found(&sc->aac_dev, &saa, scsiprint);
282 
283 	/* Create the AIF thread */
284 	sc->aifthread = 0;
285 	sc->aifflags = 0;
286 	kthread_create_deferred(aac_create_thread, sc);
287 
288 	return (0);
289 }
290 
291 void
292 aac_create_thread(void *arg)
293 {
294 	struct aac_softc *sc = arg;
295 
296 	if (kthread_create(aac_command_thread, sc, &sc->aifthread,
297 	    sc->aac_dev.dv_xname)) {
298 		/* TODO disable aac */
299 		printf("%s: failed to create kernel thread, disabled",
300 		sc->aac_dev.dv_xname);
301 	}
302 	AAC_DPRINTF(AAC_D_MISC, ("%s: aac_create_thread\n",
303 	    sc->aac_dev.dv_xname));
304 
305 }
306 
307 /*
308  * Probe for containers, create disks.
309  */
310 void
311 aac_startup(struct aac_softc *sc)
312 {
313 	struct aac_fib *fib;
314 	struct aac_mntinfo *mi;
315 	struct aac_mntinforesp *mir = NULL;
316 	int count = 0, i = 0;
317 
318 
319 	aac_alloc_sync_fib(sc, &fib, 0);
320 	mi = (struct aac_mntinfo *)&fib->data[0];
321 
322 	AAC_DPRINTF(AAC_D_MISC, ("%s: aac startup\n", sc->aac_dev.dv_xname));
323 
324 	sc->aac_container_count = 0;
325 	/* loop over possible containers */
326 	do {
327 		/* request information on this container */
328 		bzero(mi, sizeof(struct aac_mntinfo));
329 		mi->Command = VM_NameServe;
330 		mi->MntType = FT_FILESYS;
331 		mi->MntCount = i;
332 		if (aac_sync_fib(sc, ContainerCommand, 0, fib,
333 				 sizeof(struct aac_mntinfo))) {
334 			printf("%s: error probing container %d\n",
335 			       sc->aac_dev.dv_xname, i);
336 			continue;
337 		}
338 
339 		mir = (struct aac_mntinforesp *)&fib->data[0];
340 		/* XXX Need to check if count changed */
341 		count = mir->MntRespCount;
342 
343 		/*
344 		 * Check container volume type for validity.  Note
345 		 * that many of the possible types may never show up.
346 		 */
347 		if (mir->Status == ST_OK &&
348 		    mir->MntTable[0].VolType != CT_NONE) {
349 			int drv_cyls, drv_hds, drv_secs;
350 
351 			AAC_DPRINTF(AAC_D_MISC,
352 			    ("%s: %d: id %x  name '%.16s'  size %u  type %d\n",
353 			     sc->aac_dev.dv_xname, i,
354 			     mir->MntTable[0].ObjectId,
355 			     mir->MntTable[0].FileSystemName,
356 			     mir->MntTable[0].Capacity,
357 			     mir->MntTable[0].VolType));
358 
359 			sc->aac_container_count++;
360 			sc->aac_hdr[i].hd_present = 1;
361 			sc->aac_hdr[i].hd_size = mir->MntTable[0].Capacity;
362 
363 			/*
364 			 * Evaluate mapping (sectors per head, heads per cyl)
365 			 */
366 			sc->aac_hdr[i].hd_size &= ~AAC_SECS32;
367 			aac_eval_mapping(sc->aac_hdr[i].hd_size, &drv_cyls,
368 					 &drv_hds, &drv_secs);
369 			sc->aac_hdr[i].hd_heads = drv_hds;
370 			sc->aac_hdr[i].hd_secs = drv_secs;
371 			/* Round the size */
372 			sc->aac_hdr[i].hd_size = drv_cyls * drv_hds * drv_secs;
373 
374 			sc->aac_hdr[i].hd_devtype = mir->MntTable[0].VolType;
375 
376 			/* XXX Save the name too for use in IDENTIFY later */
377 		}
378 
379 		i++;
380 	} while ((i < count) && (i < AAC_MAX_CONTAINERS));
381 
382 	aac_release_sync_fib(sc);
383 
384 	/* mark the controller up */
385 	sc->aac_state &= ~AAC_STATE_SUSPEND;
386 
387 	/* enable interrupts now */
388 	AAC_UNMASK_INTERRUPTS(sc);
389 }
390 
391 /*
392  * Take an interrupt.
393  */
394 int
395 aac_intr(void *arg)
396 {
397 	struct aac_softc *sc = arg;
398 	u_int16_t reason;
399 
400 
401 	/*
402 	 * Read the status register directly.  This is faster than taking the
403 	 * driver lock and reading the queues directly.  It also saves having
404 	 * to turn parts of the driver lock into a spin mutex, which would be
405 	 * ugly.
406 	 */
407 	reason = AAC_GET_ISTATUS(sc);
408 	AAC_CLEAR_ISTATUS(sc, reason);
409 	(void)AAC_GET_ISTATUS(sc);
410 
411 	if (reason == 0)
412 		return (0);
413 
414 	AAC_DPRINTF(AAC_D_INTR, ("%s: intr: sc=%p: reason=%#x\n",
415 				 sc->aac_dev.dv_xname, sc, reason));
416 
417 	/* controller wants to talk to us */
418 	if (reason & (AAC_DB_PRINTF | AAC_DB_COMMAND_READY |
419 		      AAC_DB_RESPONSE_READY)) {
420 
421 		if (reason & AAC_DB_RESPONSE_READY) {
422 			/* handle completion processing */
423 			if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
424 				sc->aifflags |= AAC_AIFFLAGS_COMPLETE;
425 			} else {
426 				AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
427 				aac_complete(sc);
428 				AAC_LOCK_RELEASE(&sc->aac_io_lock);
429 			}
430 		}
431 
432 
433 		/*
434 		 * XXX Make sure that we don't get fooled by strange messages
435 		 * that start with a NULL.
436 		 */
437 		if (reason & AAC_DB_PRINTF)
438 			if (sc->aac_common->ac_printf[0] == 0)
439 				sc->aac_common->ac_printf[0] = 32;
440 
441 		/*
442 		 * This might miss doing the actual wakeup.  However, the
443 		 * msleep that this is waking up has a timeout, so it will
444 		 * wake up eventually.  AIFs and printfs are low enough
445 		 * priority that they can handle hanging out for a few seconds
446 		 * if needed.
447 		 */
448 		if (sc->aifthread)
449 			wakeup(sc->aifthread);
450 
451 	}
452 
453 	return (1);
454 }
455 
456 /*
457  * Command Processing
458  */
459 
460 /*
461  * Start as much queued I/O as possible on the controller
462  */
463 void
464 aac_startio(struct aac_softc *sc)
465 {
466 	struct aac_command *cm;
467 
468 	AAC_DPRINTF(AAC_D_CMD, ("%s: start command", sc->aac_dev.dv_xname));
469 
470 	if (sc->flags & AAC_QUEUE_FRZN) {
471 		AAC_DPRINTF(AAC_D_CMD, (": queue frozen"));
472 		return;
473 	}
474 
475 	AAC_DPRINTF(AAC_D_CMD, ("\n"));
476 
477 	for (;;) {
478 		/*
479 		 * Try to get a command that's been put off for lack of
480 		 * resources
481 		 */
482 		cm = aac_dequeue_ready(sc);
483 
484 		/*
485 		 * Try to build a command off the bio queue (ignore error
486 		 * return)
487 		 */
488 		if (cm == NULL) {
489 			AAC_DPRINTF(AAC_D_CMD, ("\n"));
490 			aac_bio_command(sc, &cm);
491 			AAC_DPRINTF(AAC_D_CMD, ("%s: start done bio",
492 						sc->aac_dev.dv_xname));
493 		}
494 
495 		/* nothing to do? */
496 		if (cm == NULL)
497 			break;
498 
499 		/*
500 		 * Try to give the command to the controller.  Any error is
501 		 * catastrophic since it means that bus_dmamap_load() failed.
502 		 */
503 		if (aac_map_command(cm) != 0)
504 			panic("aac: error mapping command %p", cm);
505 
506 		AAC_DPRINTF(AAC_D_CMD, ("\n%s: another command",
507 					sc->aac_dev.dv_xname));
508 	}
509 
510 	AAC_DPRINTF(AAC_D_CMD, ("\n"));
511 }
512 
513 /*
514  * Deliver a command to the controller; allocate controller resources at the
515  * last moment when possible.
516  */
517 int
518 aac_map_command(struct aac_command *cm)
519 {
520 	struct aac_softc *sc = cm->cm_sc;
521 	int error = 0;
522 
523 	AAC_DPRINTF(AAC_D_CMD, (": map command"));
524 
525 	/* don't map more than once */
526 	if (cm->cm_flags & AAC_CMD_MAPPED)
527 		panic("aac: command %p already mapped", cm);
528 
529 	if (cm->cm_datalen != 0) {
530 		error = bus_dmamap_load(sc->aac_dmat, cm->cm_datamap,
531 					cm->cm_data, cm->cm_datalen, NULL,
532 					BUS_DMA_NOWAIT);
533 		if (error)
534 			return (error);
535 
536 		aac_map_command_sg(cm, cm->cm_datamap->dm_segs,
537 				   cm->cm_datamap->dm_nsegs, 0);
538 	} else {
539 		aac_map_command_sg(cm, NULL, 0, 0);
540 	}
541 
542 	return (error);
543 }
544 
545 /*
546  * Handle notification of one or more FIBs coming from the controller.
547  */
548 void
549 aac_command_thread(void *arg)
550 {
551 	struct aac_softc *sc = arg;
552 	struct aac_fib *fib;
553 	u_int32_t fib_size;
554 	int size, retval;
555 
556 	AAC_DPRINTF(AAC_D_THREAD, ("%s: aac_command_thread: starting\n",
557 	    sc->aac_dev.dv_xname));
558 	AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
559 	sc->aifflags = AAC_AIFFLAGS_RUNNING;
560 
561 	while ((sc->aifflags & AAC_AIFFLAGS_EXIT) == 0) {
562 
563 		AAC_DPRINTF(AAC_D_THREAD,
564 		    ("%s: aac_command_thread: aifflags=%#x\n",
565 		    sc->aac_dev.dv_xname, sc->aifflags));
566 		retval = 0;
567 
568 		if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0) {
569 			AAC_DPRINTF(AAC_D_THREAD,
570 				    ("%s: command thread sleeping\n",
571 				     sc->aac_dev.dv_xname));
572 			AAC_LOCK_RELEASE(&sc->aac_io_lock);
573 			retval = tsleep_nsec(sc->aifthread, PRIBIO, "aifthd",
574 			    SEC_TO_NSEC(AAC_PERIODIC_INTERVAL));
575 			AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
576 		}
577 
578 		if ((sc->aifflags & AAC_AIFFLAGS_COMPLETE) != 0) {
579 			aac_complete(sc);
580 			sc->aifflags &= ~AAC_AIFFLAGS_COMPLETE;
581 		}
582 
583 		/*
584 		 * While we're here, check to see if any commands are stuck.
585 		 * This is pretty low-priority, so it's ok if it doesn't
586 		 * always fire.
587 		 */
588 		if (retval == EWOULDBLOCK)
589 			aac_timeout(sc);
590 
591 		/* Check the hardware printf message buffer */
592 		if (sc->aac_common->ac_printf[0] != 0)
593 			aac_print_printf(sc);
594 
595 		/* Also check to see if the adapter has a command for us. */
596 		while (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE,
597 				       &fib_size, &fib) == 0) {
598 
599 			AAC_PRINT_FIB(sc, fib);
600 
601 			switch (fib->Header.Command) {
602 			case AifRequest:
603 				//aac_handle_aif(sc, fib);
604 				break;
605 			default:
606 				printf("%s: unknown command from controller\n",
607 				       sc->aac_dev.dv_xname);
608 				break;
609 			}
610 
611 			if ((fib->Header.XferState == 0) ||
612 			    (fib->Header.StructType != AAC_FIBTYPE_TFIB))
613 				break;
614 
615 			/* Return the AIF to the controller. */
616 			if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) {
617 				fib->Header.XferState |= AAC_FIBSTATE_DONEHOST;
618 				*(AAC_FSAStatus*)fib->data = ST_OK;
619 
620 				/* XXX Compute the Size field? */
621 				size = fib->Header.Size;
622 				if (size > sizeof(struct aac_fib)) {
623 					size = sizeof(struct aac_fib);
624 					fib->Header.Size = size;
625 				}
626 
627 				/*
628 				 * Since we did not generate this command, it
629 				 * cannot go through the normal
630 				 * enqueue->startio chain.
631 				 */
632 				aac_enqueue_response(sc,
633 						     AAC_ADAP_NORM_RESP_QUEUE,
634 						     fib);
635 			}
636 		}
637 	}
638 	sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
639 	AAC_LOCK_RELEASE(&sc->aac_io_lock);
640 
641 	AAC_DPRINTF(AAC_D_THREAD, ("%s: aac_command_thread: exiting\n",
642 	    sc->aac_dev.dv_xname));
643 	kthread_exit(0);
644 }
645 
646 /*
647  * Process completed commands.
648  */
649 void
650 aac_complete(void *context)
651 {
652 	struct aac_softc *sc = (struct aac_softc *)context;
653 	struct aac_command *cm;
654 	struct aac_fib *fib;
655 	u_int32_t fib_size;
656 
657 	AAC_DPRINTF(AAC_D_CMD, ("%s: complete", sc->aac_dev.dv_xname));
658 
659 	/* pull completed commands off the queue */
660 	for (;;) {
661 		/* look for completed FIBs on our queue */
662 		if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
663 				    &fib))
664 			break;	/* nothing to do */
665 
666 		/* get the command, unmap and hand off for processing */
667 		cm = sc->aac_commands + fib->Header.SenderData;
668 		if (cm == NULL) {
669 			AAC_PRINT_FIB(sc, fib);
670 			break;
671 		}
672 
673 		aac_remove_busy(cm);
674 		aac_unmap_command(cm);
675 		cm->cm_flags |= AAC_CMD_COMPLETED;
676 
677 		/* is there a completion handler? */
678 		if (cm->cm_complete != NULL) {
679 			cm->cm_complete(cm);
680 		} else {
681 			/* assume that someone is sleeping on this command */
682 			wakeup(cm);
683 		}
684 	}
685 
686 	AAC_DPRINTF(AAC_D_CMD, ("\n"));
687 	/* see if we can start some more I/O */
688 	sc->flags &= ~AAC_QUEUE_FRZN;
689 	aac_startio(sc);
690 }
691 
692 /*
693  * Get a bio and build a command to go with it.
694  */
695 int
696 aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
697 {
698 	struct aac_command *cm;
699 	struct aac_fib *fib;
700 	struct scsi_xfer *xs;
701 	u_int8_t opcode = 0;
702 
703 	AAC_DPRINTF(AAC_D_CMD, ("%s: bio command", sc->aac_dev.dv_xname));
704 
705 	/* get the resources we will need */
706 	if ((cm = aac_dequeue_bio(sc)) == NULL)
707 		goto fail;
708 	xs = cm->cm_private;
709 
710 	/* build the FIB */
711 	fib = cm->cm_fib;
712 	fib->Header.Size = sizeof(struct aac_fib_header);
713 	fib->Header.XferState =
714 		AAC_FIBSTATE_HOSTOWNED   |
715 		AAC_FIBSTATE_INITIALISED |
716 		AAC_FIBSTATE_EMPTY	 |
717 		AAC_FIBSTATE_FROMHOST	 |
718 		AAC_FIBSTATE_REXPECTED   |
719 		AAC_FIBSTATE_NORM	 |
720 		AAC_FIBSTATE_ASYNC	 |
721 		AAC_FIBSTATE_FAST_RESPONSE;
722 
723 	switch(xs->cmd->opcode) {
724 	case READ_COMMAND:
725 	case READ_BIG:
726 		opcode = READ_COMMAND;
727 		break;
728 	case WRITE_COMMAND:
729 	case WRITE_BIG:
730 		opcode = WRITE_COMMAND;
731 		break;
732 	default:
733 		panic("%s: invalid opcode %#x", sc->aac_dev.dv_xname,
734 		      xs->cmd->opcode);
735 	}
736 
737 	/* build the read/write request */
738 	if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
739 		fib->Header.Command = ContainerCommand;
740 		if (opcode == READ_COMMAND) {
741 			struct aac_blockread *br;
742 			br = (struct aac_blockread *)&fib->data[0];
743 			br->Command = VM_CtBlockRead;
744 			br->ContainerId = xs->sc_link->target;
745 			br->BlockNumber = cm->cm_blkno;
746 			br->ByteCount = cm->cm_bcount * AAC_BLOCK_SIZE;
747 			fib->Header.Size += sizeof(struct aac_blockread);
748 			cm->cm_sgtable = &br->SgMap;
749 			cm->cm_flags |= AAC_CMD_DATAIN;
750 		} else {
751 			struct aac_blockwrite *bw;
752 			bw = (struct aac_blockwrite *)&fib->data[0];
753 			bw->Command = VM_CtBlockWrite;
754 			bw->ContainerId = xs->sc_link->target;
755 			bw->BlockNumber = cm->cm_blkno;
756 			bw->ByteCount = cm->cm_bcount * AAC_BLOCK_SIZE;
757 			bw->Stable = CUNSTABLE;
758 			fib->Header.Size += sizeof(struct aac_blockwrite);
759 			cm->cm_flags |= AAC_CMD_DATAOUT;
760 			cm->cm_sgtable = &bw->SgMap;
761 		}
762 	} else {
763 		fib->Header.Command = ContainerCommand64;
764 		if (opcode == READ_COMMAND) {
765 			struct aac_blockread64 *br;
766 			br = (struct aac_blockread64 *)&fib->data[0];
767 			br->Command = VM_CtHostRead64;
768 			br->ContainerId = xs->sc_link->target;
769 			br->BlockNumber = cm->cm_blkno;
770 			br->SectorCount = cm->cm_bcount;
771 			br->Pad = 0;
772 			br->Flags = 0;
773 			fib->Header.Size += sizeof(struct aac_blockread64);
774 			cm->cm_flags |= AAC_CMD_DATAOUT;
775 			cm->cm_sgtable = (struct aac_sg_table *)&br->SgMap64;
776 		} else {
777 			struct aac_blockwrite64 *bw;
778 			bw = (struct aac_blockwrite64 *)&fib->data[0];
779 			bw->Command = VM_CtHostWrite64;
780 			bw->ContainerId = xs->sc_link->target;
781 			bw->BlockNumber = cm->cm_blkno;
782 			bw->SectorCount = cm->cm_bcount;
783 			bw->Pad = 0;
784 			bw->Flags = 0;
785 			fib->Header.Size += sizeof(struct aac_blockwrite64);
786 			cm->cm_flags |= AAC_CMD_DATAIN;
787 			cm->cm_sgtable = (struct aac_sg_table *)&bw->SgMap64;
788 		}
789 	}
790 
791 	*cmp = cm;
792 	AAC_DPRINTF(AAC_D_CMD, ("\n"));
793 	return(0);
794 
795 fail:
796 	AAC_DPRINTF(AAC_D_CMD, ("\n"));
797 	return(ENOMEM);
798 }
799 
800 /*
801  * Handle a bio-instigated command that has been completed.
802  */
803 void
804 aac_bio_complete(struct aac_command *cm)
805 {
806 	struct aac_blockread_response *brr;
807 	struct aac_blockwrite_response *bwr;
808 	struct scsi_xfer *xs = (struct scsi_xfer *)cm->cm_private;
809 	AAC_FSAStatus status;
810 	int s;
811 
812 	AAC_DPRINTF(AAC_D_CMD,
813 		    ("%s: bio complete\n", cm->cm_sc->aac_dev.dv_xname));
814 
815 	/* fetch relevant status and then release the command */
816 	if (xs->flags & SCSI_DATA_IN) {
817 		brr = (struct aac_blockread_response *)&cm->cm_fib->data[0];
818 		status = brr->Status;
819 	} else {
820 		bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0];
821 		status = bwr->Status;
822 	}
823 
824 	xs->error = status == ST_OK? XS_NOERROR : XS_DRIVER_STUFFUP;
825 	xs->resid = 0;
826 	s = splbio();
827 	scsi_done(xs);
828 	splx(s);
829 }
830 
831 /*
832  * Submit a command to the controller, return when it completes.
833  * XXX This is very dangerous!  If the card has gone out to lunch, we could
834  *     be stuck here forever.  At the same time, signals are not caught
835  *     because there is a risk that a signal could wakeup the tsleep before
836  *     the card has a chance to complete the command.  The passed in timeout
837  *     is ignored for the same reason.  Since there is no way to cancel a
838  *     command in progress, we should probably create a 'dead' queue where
839  *     commands go that have been interrupted/timed-out/etc, that keeps them
840  *     out of the free pool.  That way, if the card is just slow, it won't
841  *     spam the memory of a command that has been recycled.
842  */
843 int
844 aac_wait_command(struct aac_command *cm, int msecs)
845 {
846 	struct aac_softc *sc = cm->cm_sc;
847 	int error = 0;
848 
849 	AAC_DPRINTF(AAC_D_CMD, (": wait for command"));
850 
851 	/* Put the command on the ready queue and get things going */
852 	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
853 	aac_enqueue_ready(cm);
854 	AAC_DPRINTF(AAC_D_CMD, ("\n"));
855 	aac_startio(sc);
856 	while (!(cm->cm_flags & AAC_CMD_COMPLETED) && (error != EWOULDBLOCK)) {
857 		AAC_DPRINTF(AAC_D_MISC, ("%s: sleeping until command done\n",
858 					 sc->aac_dev.dv_xname));
859 		AAC_LOCK_RELEASE(&sc->aac_io_lock);
860 		error = tsleep_nsec(cm, PRIBIO, "aacwait", MSEC_TO_NSEC(msecs));
861 		AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
862 	}
863 	return (error);
864 }
865 
866 /*
867  *Command Buffer Management
868  */
869 
870 /*
871  * Allocate a command.
872  */
873 void *
874 aac_alloc_command(void *xsc)
875 {
876 	struct aac_softc *sc = xsc;
877 	struct aac_command *cm;
878 
879 	AAC_DPRINTF(AAC_D_CMD, (": allocate command"));
880 	mtx_enter(&sc->aac_free_mtx);
881 	cm = aac_dequeue_free(sc);
882 	mtx_leave(&sc->aac_free_mtx);
883 
884 	return (cm);
885 }
886 
887 void
888 aac_scrub_command(struct aac_command *cm)
889 {
890 	cm->cm_sgtable = NULL;
891 	cm->cm_flags = 0;
892 	cm->cm_complete = NULL;
893 	cm->cm_private = NULL;
894 	cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
895 	cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
896 	cm->cm_fib->Header.Flags = 0;
897 	cm->cm_fib->Header.SenderSize = sizeof(struct aac_fib);
898 }
899 
900 /*
901  * Release a command back to the freelist.
902  */
903 void
904 aac_release_command(void *xsc, void *xcm)
905 {
906 	struct aac_softc *sc = xsc;
907 	struct aac_command *cm = xcm;
908 	AAC_DPRINTF(AAC_D_CMD, (": release command"));
909 
910 	mtx_enter(&sc->aac_free_mtx);
911 	aac_enqueue_free(cm);
912 	mtx_leave(&sc->aac_free_mtx);
913 }
914 
915 /*
916  * Allocate and initialise commands/FIBs for this adapter.
917  */
918 int
919 aac_alloc_commands(struct aac_softc *sc)
920 {
921 	struct aac_command *cm;
922 	struct aac_fibmap *fm;
923 	int i, error = ENOMEM;
924 
925 	if (sc->total_fibs + AAC_FIB_COUNT > sc->aac_max_fibs)
926 		return (ENOMEM);
927 
928 	fm = malloc(sizeof(*fm), M_DEVBUF, M_NOWAIT | M_ZERO);
929 	if (fm == NULL)
930 		goto exit;
931 
932 	/* allocate the FIBs in DMAable memory and load them */
933 	if (bus_dmamem_alloc(sc->aac_dmat, AAC_FIBMAP_SIZE, PAGE_SIZE, 0,
934 	    &fm->aac_seg, 1, &fm->aac_nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO)) {
935 		printf("%s: can't alloc FIBs\n", sc->aac_dev.dv_xname);
936 		error = ENOBUFS;
937 		goto exit_alloc;
938 	}
939 
940 	if (bus_dmamem_map(sc->aac_dmat, &fm->aac_seg, 1,
941 	    AAC_FIBMAP_SIZE, (caddr_t *)&fm->aac_fibs, BUS_DMA_NOWAIT)) {
942 		printf("%s: can't map FIB structure\n", sc->aac_dev.dv_xname);
943 		error = ENOBUFS;
944 		goto exit_map;
945 	}
946 
947 	if (bus_dmamap_create(sc->aac_dmat, AAC_FIBMAP_SIZE, 1,
948 	    AAC_FIBMAP_SIZE, 0, BUS_DMA_NOWAIT, &fm->aac_fibmap)) {
949 		printf("%s: can't create dma map\n", sc->aac_dev.dv_xname);
950 		error = ENOBUFS;
951 		goto exit_create;
952 	}
953 
954 	if (bus_dmamap_load(sc->aac_dmat, fm->aac_fibmap, fm->aac_fibs,
955 	    AAC_FIBMAP_SIZE, NULL, BUS_DMA_NOWAIT)) {
956 		printf("%s: can't load dma map\n", sc->aac_dev.dv_xname);
957 		error = ENOBUFS;
958 		goto exit_load;
959 	}
960 
961 	/* initialise constant fields in the command structure */
962 	AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
963 	for (i = 0; i < AAC_FIB_COUNT; i++) {
964 		cm = sc->aac_commands + sc->total_fibs;
965 		fm->aac_commands = cm;
966 		cm->cm_sc = sc;
967 		cm->cm_fib = fm->aac_fibs + i;
968 		cm->cm_fibphys = fm->aac_fibmap->dm_segs[0].ds_addr +
969 			(i * sizeof(struct aac_fib));
970 		cm->cm_index = sc->total_fibs;
971 
972 		if (bus_dmamap_create(sc->aac_dmat, MAXPHYS, AAC_MAXSGENTRIES,
973 		    MAXPHYS, 0, BUS_DMA_NOWAIT, &cm->cm_datamap)) {
974 			break;
975 		}
976 		aac_release_command(sc, cm);
977 		sc->total_fibs++;
978 	}
979 
980 	if (i > 0) {
981 		TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link);
982 		AAC_DPRINTF(AAC_D_MISC, ("%s: total_fibs= %d\n",
983 					 sc->aac_dev.dv_xname,
984 					 sc->total_fibs));
985 		AAC_LOCK_RELEASE(&sc->aac_io_lock);
986 		return (0);
987 	}
988 
989  exit_load:
990 	bus_dmamap_destroy(sc->aac_dmat, fm->aac_fibmap);
991  exit_create:
992 	bus_dmamem_unmap(sc->aac_dmat, (caddr_t)fm->aac_fibs, AAC_FIBMAP_SIZE);
993  exit_map:
994 	bus_dmamem_free(sc->aac_dmat, &fm->aac_seg, fm->aac_nsegs);
995  exit_alloc:
996 	free(fm, M_DEVBUF, sizeof *fm);
997  exit:
998 	AAC_LOCK_RELEASE(&sc->aac_io_lock);
999 	return (error);
1000 }
1001 
1002 /*
1003  * Free FIBs owned by this adapter.
1004  */
1005 void
1006 aac_free_commands(struct aac_softc *sc)
1007 {
1008 	struct aac_fibmap *fm;
1009 	struct aac_command *cm;
1010 	int i;
1011 
1012 	while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) {
1013 
1014 		TAILQ_REMOVE(&sc->aac_fibmap_tqh, fm, fm_link);
1015 
1016 		/*
1017 		 * We check against total_fibs to handle partially
1018 		 * allocated blocks.
1019 		 */
1020 		for (i = 0; i < AAC_FIB_COUNT && sc->total_fibs--; i++) {
1021 			cm = fm->aac_commands + i;
1022 			bus_dmamap_destroy(sc->aac_dmat, cm->cm_datamap);
1023 		}
1024 
1025 		bus_dmamap_unload(sc->aac_dmat, fm->aac_fibmap);
1026 		bus_dmamap_destroy(sc->aac_dmat, fm->aac_fibmap);
1027 		bus_dmamem_unmap(sc->aac_dmat, (caddr_t)fm->aac_fibs,
1028 				 AAC_FIBMAP_SIZE);
1029 		bus_dmamem_free(sc->aac_dmat, &fm->aac_seg, fm->aac_nsegs);
1030 		free(fm, M_DEVBUF, sizeof *fm);
1031 	}
1032 }
1033 
1034 
1035 /*
1036  * Command-mapping helper function - populate this command's s/g table.
1037  */
1038 void
1039 aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1040 {
1041 	struct aac_command *cm = arg;
1042 	struct aac_softc *sc = cm->cm_sc;
1043 	struct aac_fib *fib = cm->cm_fib;
1044 	int i;
1045 
1046 	/* copy into the FIB */
1047 	if (cm->cm_sgtable != NULL) {
1048 		if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
1049 			struct aac_sg_table *sg = cm->cm_sgtable;
1050 			sg->SgCount = nseg;
1051 			for (i = 0; i < nseg; i++) {
1052 				sg->SgEntry[i].SgAddress = segs[i].ds_addr;
1053 				sg->SgEntry[i].SgByteCount = segs[i].ds_len;
1054 			}
1055 			/* update the FIB size for the s/g count */
1056 			fib->Header.Size += nseg * sizeof(struct aac_sg_entry);
1057 		} else {
1058 			struct aac_sg_table64 *sg;
1059 			sg = (struct aac_sg_table64 *)cm->cm_sgtable;
1060 			sg->SgCount = nseg;
1061 			for (i = 0; i < nseg; i++) {
1062 				sg->SgEntry64[i].SgAddress = segs[i].ds_addr;
1063 				sg->SgEntry64[i].SgByteCount = segs[i].ds_len;
1064 			}
1065 			/* update the FIB size for the s/g count */
1066 			fib->Header.Size += nseg*sizeof(struct aac_sg_entry64);
1067 		}
1068 	}
1069 
1070 	/* Fix up the address values in the FIB.  Use the command array index
1071 	 * instead of a pointer since these fields are only 32 bits.  Shift
1072 	 * the SenderFibAddress over to make room for the fast response bit.
1073 	 */
1074 	cm->cm_fib->Header.SenderFibAddress = (cm->cm_index << 1);
1075 	cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
1076 
1077 	/* save a pointer to the command for speedy reverse-lookup */
1078 	cm->cm_fib->Header.SenderData = cm->cm_index;
1079 
1080 	if (cm->cm_flags & AAC_CMD_DATAIN)
1081 		bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0,
1082 				cm->cm_datamap->dm_mapsize,
1083 				BUS_DMASYNC_PREREAD);
1084 	if (cm->cm_flags & AAC_CMD_DATAOUT)
1085 		bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0,
1086 				cm->cm_datamap->dm_mapsize,
1087 				BUS_DMASYNC_PREWRITE);
1088 	cm->cm_flags |= AAC_CMD_MAPPED;
1089 
1090 	/* put the FIB on the outbound queue */
1091 	if (aac_enqueue_fib(sc, cm->cm_queue, cm) == EBUSY) {
1092 		aac_remove_busy(cm);
1093 		aac_unmap_command(cm);
1094 		aac_requeue_ready(cm);
1095 	}
1096 }
1097 
1098 /*
1099  * Unmap a command from controller-visible space.
1100  */
1101 void
1102 aac_unmap_command(struct aac_command *cm)
1103 {
1104 	struct aac_softc *sc = cm->cm_sc;
1105 
1106 	if (!(cm->cm_flags & AAC_CMD_MAPPED))
1107 		return;
1108 
1109 	if (cm->cm_datalen != 0) {
1110 		if (cm->cm_flags & AAC_CMD_DATAIN)
1111 			bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0,
1112 					cm->cm_datamap->dm_mapsize,
1113 					BUS_DMASYNC_POSTREAD);
1114 		if (cm->cm_flags & AAC_CMD_DATAOUT)
1115 			bus_dmamap_sync(sc->aac_dmat, cm->cm_datamap, 0,
1116 					cm->cm_datamap->dm_mapsize,
1117 					BUS_DMASYNC_POSTWRITE);
1118 
1119 		bus_dmamap_unload(sc->aac_dmat, cm->cm_datamap);
1120 	}
1121 	cm->cm_flags &= ~AAC_CMD_MAPPED;
1122 }
1123 
1124 /*
1125  * Hardware Interface
1126  */
1127 
1128 /*
1129  * Initialise the adapter.
1130  */
1131 int
1132 aac_check_firmware(struct aac_softc *sc)
1133 {
1134 	u_int32_t major, minor, options;
1135 
1136 	/*
1137 	 * Retrieve the firmware version numbers.  Dell PERC2/QC cards with
1138 	 * firmware version 1.x are not compatible with this driver.
1139 	 */
1140 	if (sc->flags & AAC_FLAGS_PERC2QC) {
1141 		if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0,
1142 				     NULL)) {
1143 			printf("%s: Error reading firmware version\n",
1144 			       sc->aac_dev.dv_xname);
1145 			return (EIO);
1146 		}
1147 
1148 		/* These numbers are stored as ASCII! */
1149 		major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30;
1150 		minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30;
1151 		if (major == 1) {
1152 			printf("%s: Firmware version %d.%d is not supported\n",
1153 			       sc->aac_dev.dv_xname, major, minor);
1154 			return (EINVAL);
1155 		}
1156 	}
1157 
1158 	/*
1159 	 * Retrieve the capabilities/supported options word so we know what
1160 	 * work-arounds to enable.
1161 	 */
1162 	if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, NULL)) {
1163 		printf("%s: RequestAdapterInfo failed\n",
1164 		       sc->aac_dev.dv_xname);
1165 		return (EIO);
1166 	}
1167 	options = AAC_GET_MAILBOX(sc, 1);
1168 	sc->supported_options = options;
1169 
1170 	if ((options & AAC_SUPPORTED_4GB_WINDOW) != 0 &&
1171 	    (sc->flags & AAC_FLAGS_NO4GB) == 0)
1172 		sc->flags |= AAC_FLAGS_4GB_WINDOW;
1173 	if (options & AAC_SUPPORTED_NONDASD)
1174 		sc->flags |= AAC_FLAGS_ENABLE_CAM;
1175 	if ((options & AAC_SUPPORTED_SGMAP_HOST64) != 0
1176 	     && (sizeof(bus_addr_t) > 4)) {
1177 		printf("%s: Enabling 64-bit address support\n",
1178 		       sc->aac_dev.dv_xname);
1179 		sc->flags |= AAC_FLAGS_SG_64BIT;
1180 	}
1181 
1182 	/* Check for broken hardware that does a lower number of commands */
1183 	if ((sc->flags & AAC_FLAGS_256FIBS) == 0)
1184 		sc->aac_max_fibs = AAC_MAX_FIBS;
1185 	else
1186 		sc->aac_max_fibs = 256;
1187 
1188 	return (0);
1189 }
1190 
1191 int
1192 aac_init(struct aac_softc *sc)
1193 {
1194 	bus_dma_segment_t seg;
1195 	int nsegs;
1196 	int i, error;
1197 	int state = 0;
1198 	struct aac_adapter_init	*ip;
1199 	time_t then;
1200 	u_int32_t code, qoffset;
1201 
1202 	/*
1203 	 * First wait for the adapter to come ready.
1204 	 */
1205 	then = time_uptime;
1206 	for (i = 0; i < AAC_BOOT_TIMEOUT * 1000; i++) {
1207 		code = AAC_GET_FWSTATUS(sc);
1208 		if (code & AAC_SELF_TEST_FAILED) {
1209 			printf("%s: FATAL: selftest failed\n",
1210 			    sc->aac_dev.dv_xname);
1211 			return (ENXIO);
1212 		}
1213 		if (code & AAC_KERNEL_PANIC) {
1214 			printf("%s: FATAL: controller kernel panic\n",
1215 			    sc->aac_dev.dv_xname);
1216 			return (ENXIO);
1217 		}
1218 		if (code & AAC_UP_AND_RUNNING)
1219 			break;
1220 		DELAY(1000);
1221 	}
1222 	if (i == AAC_BOOT_TIMEOUT * 1000) {
1223 		printf("%s: FATAL: controller not coming ready, status %x\n",
1224 		    sc->aac_dev.dv_xname, code);
1225 		return (ENXIO);
1226 	}
1227 
1228 	/*
1229 	 * Work around a bug in the 2120 and 2200 that cannot DMA commands
1230 	 * below address 8192 in physical memory.
1231 	 * XXX If the padding is not needed, can it be put to use instead
1232 	 * of ignored?
1233 	 */
1234 	if (bus_dmamem_alloc(sc->aac_dmat, AAC_COMMON_ALLOCSIZE, PAGE_SIZE, 0,
1235 			     &seg, 1, &nsegs, BUS_DMA_NOWAIT | BUS_DMA_ZERO)) {
1236 		printf("%s: can't allocate common structure\n",
1237 		    sc->aac_dev.dv_xname);
1238 		return (ENOMEM);
1239 	}
1240 	state++;
1241 
1242 	if (bus_dmamem_map(sc->aac_dmat, &seg, nsegs, AAC_COMMON_ALLOCSIZE,
1243 			   (caddr_t *)&sc->aac_common, BUS_DMA_NOWAIT)) {
1244 		printf("%s: can't map common structure\n",
1245 		    sc->aac_dev.dv_xname);
1246 		error = ENOMEM;
1247 		goto bail_out;
1248 	}
1249 	state++;
1250 
1251 	if (bus_dmamap_create(sc->aac_dmat, AAC_COMMON_ALLOCSIZE, 1,
1252 	    AAC_COMMON_ALLOCSIZE, 0, BUS_DMA_NOWAIT, &sc->aac_common_map)) {
1253 		printf("%s: can't create dma map\n", sc->aac_dev.dv_xname);
1254 		error = ENOBUFS;
1255 		goto bail_out;
1256 	}
1257 	state++;
1258 
1259 	if (bus_dmamap_load(sc->aac_dmat, sc->aac_common_map, sc->aac_common,
1260 	    AAC_COMMON_ALLOCSIZE, NULL, BUS_DMA_NOWAIT)) {
1261 		printf("%s: can't load dma map\n", sc->aac_dev.dv_xname);
1262 		error = ENOBUFS;
1263 		goto bail_out;
1264 	}
1265 	state++;
1266 
1267 	sc->aac_common_busaddr = sc->aac_common_map->dm_segs[0].ds_addr;
1268 
1269 	if (sc->aac_common_busaddr < 8192) {
1270 		sc->aac_common = (struct aac_common *)
1271 		    ((uint8_t *)sc->aac_common + 8192);
1272 		sc->aac_common_busaddr += 8192;
1273 	}
1274 
1275 	/* Allocate some FIBs and associated command structs */
1276 	TAILQ_INIT(&sc->aac_fibmap_tqh);
1277 	sc->aac_commands = malloc(AAC_MAX_FIBS * sizeof(struct aac_command),
1278 	    M_DEVBUF, M_WAITOK | M_ZERO);
1279 	while (sc->total_fibs < AAC_MAX_FIBS) {
1280 		if (aac_alloc_commands(sc) != 0)
1281 			break;
1282 	}
1283 	if (sc->total_fibs == 0)
1284 		goto out;
1285 
1286 	scsi_iopool_init(&sc->aac_iopool, sc,
1287 	    aac_alloc_command, aac_release_command);
1288 
1289 	/*
1290 	 * Fill in the init structure.  This tells the adapter about the
1291 	 * physical location of various important shared data structures.
1292 	 */
1293 	ip = &sc->aac_common->ac_init;
1294 	ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
1295 	ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION;
1296 
1297 	ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
1298 					 offsetof(struct aac_common, ac_fibs);
1299 	ip->AdapterFibsVirtualAddress = 0;
1300 	ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
1301 	ip->AdapterFibAlign = sizeof(struct aac_fib);
1302 
1303 	ip->PrintfBufferAddress = sc->aac_common_busaddr +
1304 				  offsetof(struct aac_common, ac_printf);
1305 	ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
1306 
1307 	/*
1308 	 * The adapter assumes that pages are 4K in size, except on some
1309 	 * broken firmware versions that do the page->byte conversion twice,
1310 	 * therefore 'assuming' that this value is in 16MB units (2^24).
1311 	 * Round up since the granularity is so high.
1312 	 */
1313 	ip->HostPhysMemPages = ptoa(physmem) / AAC_PAGE_SIZE;
1314 	if (sc->flags & AAC_FLAGS_BROKEN_MEMMAP) {
1315 		ip->HostPhysMemPages =
1316 		    (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE;
1317 	}
1318 	ip->HostElapsedSeconds = time_uptime; /* reset later if invalid */
1319 
1320 	/*
1321 	 * Initialise FIB queues.  Note that it appears that the layout of the
1322 	 * indexes and the segmentation of the entries may be mandated by the
1323 	 * adapter, which is only told about the base of the queue index fields.
1324 	 *
1325 	 * The initial values of the indices are assumed to inform the adapter
1326 	 * of the sizes of the respective queues, and theoretically it could
1327 	 * work out the entire layout of the queue structures from this.  We
1328 	 * take the easy route and just lay this area out like everyone else
1329 	 * does.
1330 	 *
1331 	 * The Linux driver uses a much more complex scheme whereby several
1332 	 * header records are kept for each queue.  We use a couple of generic
1333 	 * list manipulation functions which 'know' the size of each list by
1334 	 * virtue of a table.
1335 	 */
1336 	qoffset = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN;
1337 	qoffset &= ~(AAC_QUEUE_ALIGN - 1);
1338 	sc->aac_queues =
1339 	    (struct aac_queue_table *)((caddr_t)sc->aac_common + qoffset);
1340 	ip->CommHeaderAddress = sc->aac_common_busaddr + qoffset;
1341 
1342 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1343 		AAC_HOST_NORM_CMD_ENTRIES;
1344 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1345 		AAC_HOST_NORM_CMD_ENTRIES;
1346 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1347 		AAC_HOST_HIGH_CMD_ENTRIES;
1348 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1349 		AAC_HOST_HIGH_CMD_ENTRIES;
1350 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1351 		AAC_ADAP_NORM_CMD_ENTRIES;
1352 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1353 		AAC_ADAP_NORM_CMD_ENTRIES;
1354 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1355 		AAC_ADAP_HIGH_CMD_ENTRIES;
1356 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1357 		AAC_ADAP_HIGH_CMD_ENTRIES;
1358 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1359 		AAC_HOST_NORM_RESP_ENTRIES;
1360 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1361 		AAC_HOST_NORM_RESP_ENTRIES;
1362 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1363 		AAC_HOST_HIGH_RESP_ENTRIES;
1364 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1365 		AAC_HOST_HIGH_RESP_ENTRIES;
1366 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1367 		AAC_ADAP_NORM_RESP_ENTRIES;
1368 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1369 		AAC_ADAP_NORM_RESP_ENTRIES;
1370 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1371 		AAC_ADAP_HIGH_RESP_ENTRIES;
1372 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1373 		AAC_ADAP_HIGH_RESP_ENTRIES;
1374 	sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] =
1375 		&sc->aac_queues->qt_HostNormCmdQueue[0];
1376 	sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
1377 		&sc->aac_queues->qt_HostHighCmdQueue[0];
1378 	sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
1379 		&sc->aac_queues->qt_AdapNormCmdQueue[0];
1380 	sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
1381 		&sc->aac_queues->qt_AdapHighCmdQueue[0];
1382 	sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] =
1383 		&sc->aac_queues->qt_HostNormRespQueue[0];
1384 	sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
1385 		&sc->aac_queues->qt_HostHighRespQueue[0];
1386 	sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
1387 		&sc->aac_queues->qt_AdapNormRespQueue[0];
1388 	sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
1389 		&sc->aac_queues->qt_AdapHighRespQueue[0];
1390 
1391 	/*
1392 	 * Do controller-type-specific initialisation
1393 	 */
1394 	switch (sc->aac_hwif) {
1395 	case AAC_HWIF_I960RX:
1396 		AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
1397 		break;
1398 	case AAC_HWIF_RKT:
1399 		AAC_SETREG4(sc, AAC_RKT_ODBR, ~0);
1400 		break;
1401 	default:
1402 		break;
1403 	}
1404 
1405 	/*
1406 	 * Give the init structure to the controller.
1407 	 */
1408 	if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
1409 			     sc->aac_common_busaddr +
1410 			     offsetof(struct aac_common, ac_init), 0, 0, 0,
1411 			     NULL)) {
1412 		printf("%s: error establishing init structure\n",
1413 		    sc->aac_dev.dv_xname);
1414 		error = EIO;
1415 		goto bail_out;
1416 	}
1417 
1418 	aac_describe_controller(sc);
1419 	aac_startup(sc);
1420 
1421 	return (0);
1422 
1423  bail_out:
1424 	if (state > 3)
1425 		bus_dmamap_unload(sc->aac_dmat, sc->aac_common_map);
1426 	if (state > 2)
1427 		bus_dmamap_destroy(sc->aac_dmat, sc->aac_common_map);
1428 	if (state > 1)
1429 		bus_dmamem_unmap(sc->aac_dmat, (caddr_t)sc->aac_common,
1430 		    sizeof *sc->aac_common);
1431 	if (state > 0)
1432 		bus_dmamem_free(sc->aac_dmat, &seg, 1);
1433 
1434  out:
1435 	return (error);
1436 }
1437 
1438 /*
1439  * Send a synchronous command to the controller and wait for a result.
1440  */
1441 int
1442 aac_sync_command(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1443 		 u_int32_t arg1, u_int32_t arg2, u_int32_t arg3, u_int32_t *sp)
1444 {
1445 //	time_t then;
1446 	int i;
1447 	u_int32_t status;
1448 	u_int16_t reason;
1449 
1450 	/* populate the mailbox */
1451 	AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
1452 
1453 	/* ensure the sync command doorbell flag is cleared */
1454 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1455 
1456 	/* then set it to signal the adapter */
1457 	AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
1458 
1459 	DELAY(AAC_SYNC_DELAY);
1460 
1461 	/* spin waiting for the command to complete */
1462 	for (i = 0; i < AAC_IMMEDIATE_TIMEOUT * 1000; i++) {
1463 		reason = AAC_GET_ISTATUS(sc);
1464 		if (reason & AAC_DB_SYNC_COMMAND)
1465 			break;
1466 		reason = AAC_GET_ISTATUS(sc);
1467 		if (reason & AAC_DB_SYNC_COMMAND)
1468 			break;
1469 		reason = AAC_GET_ISTATUS(sc);
1470 		if (reason & AAC_DB_SYNC_COMMAND)
1471 			break;
1472 		DELAY(1000);
1473 	}
1474 	if (i == AAC_IMMEDIATE_TIMEOUT * 1000) {
1475 		printf("aac_sync_command: failed, reason=%#x\n", reason);
1476 		return (EIO);
1477 	}
1478 
1479 	/* clear the completion flag */
1480 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1481 
1482 	/* get the command status */
1483 	status = AAC_GET_MAILBOX(sc, 0);
1484 
1485 	if (sp != NULL)
1486 		*sp = status;
1487 
1488 	return(0);
1489 }
1490 
1491 /*
1492  * Grab the sync fib area.
1493  */
1494 int
1495 aac_alloc_sync_fib(struct aac_softc *sc, struct aac_fib **fib, int flags)
1496 {
1497 
1498 	/*
1499 	 * If the force flag is set, the system is shutting down, or in
1500 	 * trouble.  Ignore the mutex.
1501 	 */
1502 	if (!(flags & AAC_SYNC_LOCK_FORCE))
1503 		AAC_LOCK_ACQUIRE(&sc->aac_sync_lock);
1504 
1505 	*fib = &sc->aac_common->ac_sync_fib;
1506 
1507 	return (1);
1508 }
1509 
1510 /*
1511  * Release the sync fib area.
1512  */
1513 void
1514 aac_release_sync_fib(struct aac_softc *sc)
1515 {
1516 	AAC_LOCK_RELEASE(&sc->aac_sync_lock);
1517 }
1518 
1519 /*
1520  * Send a synchronous FIB to the controller and wait for a result.
1521  */
1522 int
1523 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
1524 	     struct aac_fib *fib, u_int16_t datasize)
1525 {
1526 
1527 	if (datasize > AAC_FIB_DATASIZE) {
1528 		printf("aac_sync_fib 1: datasize=%d AAC_FIB_DATASIZE %lu\n",
1529 		    datasize, AAC_FIB_DATASIZE);
1530 		return(EINVAL);
1531 	}
1532 
1533 	/*
1534 	 * Set up the sync FIB
1535 	 */
1536 	fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED |
1537 				AAC_FIBSTATE_INITIALISED |
1538 				AAC_FIBSTATE_EMPTY;
1539 	fib->Header.XferState |= xferstate;
1540 	fib->Header.Command = command;
1541 	fib->Header.StructType = AAC_FIBTYPE_TFIB;
1542 	fib->Header.Size = sizeof(struct aac_fib) + datasize;
1543 	fib->Header.SenderSize = sizeof(struct aac_fib);
1544 	fib->Header.SenderFibAddress = 0;	/* Not needed */
1545 	fib->Header.ReceiverFibAddress = sc->aac_common_busaddr +
1546 					 offsetof(struct aac_common,
1547 						  ac_sync_fib);
1548 
1549 	/*
1550 	 * Give the FIB to the controller, wait for a response.
1551 	 */
1552 	if (aac_sync_command(sc, AAC_MONKER_SYNCFIB,
1553 			     fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) {
1554 		AAC_DPRINTF(AAC_D_IO, ("%s: aac_sync_fib: IO error\n",
1555 				       sc->aac_dev.dv_xname));
1556 		printf("aac_sync_fib 2\n");
1557 		return(EIO);
1558 	}
1559 
1560 	return (0);
1561 }
1562 
1563 /*****************************************************************************
1564  * Adapter-space FIB queue manipulation
1565  *
1566  * Note that the queue implementation here is a little funky; neither the PI or
1567  * CI will ever be zero.  This behaviour is a controller feature.
1568  */
1569 static struct {
1570 	int size;
1571 	int notify;
1572 } aac_qinfo[] = {
1573 	{ AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL },
1574 	{ AAC_HOST_HIGH_CMD_ENTRIES, 0 },
1575 	{ AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY },
1576 	{ AAC_ADAP_HIGH_CMD_ENTRIES, 0 },
1577 	{ AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL },
1578 	{ AAC_HOST_HIGH_RESP_ENTRIES, 0 },
1579 	{ AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY },
1580 	{ AAC_ADAP_HIGH_RESP_ENTRIES, 0 }
1581 };
1582 
1583 /*
1584  * Atomically insert an entry into the nominated queue, returns 0 on success
1585  * or EBUSY if the queue is full.
1586  *
1587  * Note: it would be more efficient to defer notifying the controller in
1588  *	 the case where we may be inserting several entries in rapid
1589  *	 succession, but implementing this usefully may be difficult
1590  *	 (it would involve a separate queue/notify interface).
1591  */
1592 int
1593 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm)
1594 {
1595 	u_int32_t pi, ci;
1596 	int error;
1597 	u_int32_t fib_size;
1598 	u_int32_t fib_addr;
1599 
1600 	fib_size = cm->cm_fib->Header.Size;
1601 	fib_addr = cm->cm_fib->Header.ReceiverFibAddress;
1602 
1603 	/* get the producer/consumer indices */
1604 	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1605 	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1606 
1607 	/* wrap the queue? */
1608 	if (pi >= aac_qinfo[queue].size)
1609 		pi = 0;
1610 
1611 	/* check for queue full */
1612 	if ((pi + 1) == ci) {
1613 		error = EBUSY;
1614 		goto out;
1615 	}
1616 
1617 	/* populate queue entry */
1618 	(sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1619 	(sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1620 
1621 	/* update producer index */
1622 	sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1623 
1624 	/*
1625 	 * To avoid a race with its completion interrupt, place this command on
1626 	 * the busy queue prior to advertising it to the controller.
1627 	 */
1628 	aac_enqueue_busy(cm);
1629 
1630 	/* notify the adapter if we know how */
1631 	if (aac_qinfo[queue].notify != 0)
1632 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1633 
1634 	error = 0;
1635 
1636 out:
1637 	return (error);
1638 }
1639 
1640 /*
1641  * Atomically remove one entry from the nominated queue, returns 0 on success
1642  * or ENOENT if the queue is empty.
1643  */
1644 int
1645 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
1646 		struct aac_fib **fib_addr)
1647 {
1648 	u_int32_t pi, ci;
1649 	u_int32_t fib_index;
1650 	int notify;
1651 	int error;
1652 
1653 	/* get the producer/consumer indices */
1654 	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1655 	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1656 
1657 	/* check for queue empty */
1658 	if (ci == pi) {
1659 		error = ENOENT;
1660 		goto out;
1661 	}
1662 
1663 	/* wrap the pi so the following test works */
1664 	if (pi >= aac_qinfo[queue].size)
1665 		pi = 0;
1666 
1667 	notify = 0;
1668 	if (ci == pi + 1)
1669 		notify++;
1670 
1671 	/* wrap the queue? */
1672 	if (ci >= aac_qinfo[queue].size)
1673 		ci = 0;
1674 
1675 	/* fetch the entry */
1676 	*fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size;
1677 
1678 	switch (queue) {
1679 	case AAC_HOST_NORM_CMD_QUEUE:
1680 	case AAC_HOST_HIGH_CMD_QUEUE:
1681 		/*
1682 		 * The aq_fib_addr is only 32 bits wide so it can't be counted
1683 		 * on to hold an address.  For AIF's, the adapter assumes
1684 		 * that it's giving us an address into the array of AIF fibs.
1685 		 * Therefore, we have to convert it to an index.
1686 		 */
1687 		fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr /
1688 			sizeof(struct aac_fib);
1689 		*fib_addr = &sc->aac_common->ac_fibs[fib_index];
1690 		break;
1691 
1692 	case AAC_HOST_NORM_RESP_QUEUE:
1693 	case AAC_HOST_HIGH_RESP_QUEUE:
1694 	{
1695 		struct aac_command *cm;
1696 
1697 		/*
1698 		 * As above, an index is used instead of an actual address.
1699 		 * Gotta shift the index to account for the fast response
1700 		 * bit.  No other correction is needed since this value was
1701 		 * originally provided by the driver via the SenderFibAddress
1702 		 * field.
1703 		 */
1704 		fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr;
1705 		cm = sc->aac_commands + (fib_index >> 1);
1706 		*fib_addr = cm->cm_fib;
1707 
1708 		/*
1709 		 * Is this a fast response? If it is, update the fib fields in
1710 		 * local memory since the whole fib isn't DMA'd back up.
1711 		 */
1712 		if (fib_index & 0x01) {
1713 			(*fib_addr)->Header.XferState |= AAC_FIBSTATE_DONEADAP;
1714 			*((u_int32_t*)((*fib_addr)->data)) = AAC_ERROR_NORMAL;
1715 		}
1716 		break;
1717 	}
1718 	default:
1719 		panic("Invalid queue in aac_dequeue_fib()");
1720 		break;
1721 	}
1722 
1723 
1724 	/* update consumer index */
1725 	sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
1726 
1727 	/* if we have made the queue un-full, notify the adapter */
1728 	if (notify && (aac_qinfo[queue].notify != 0))
1729 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1730 	error = 0;
1731 
1732 out:
1733 	return (error);
1734 }
1735 
1736 /*
1737  * Put our response to an Adapter Initialed Fib on the response queue
1738  */
1739 int
1740 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
1741 {
1742 	u_int32_t pi, ci;
1743 	int error;
1744 	u_int32_t fib_size;
1745 	u_int32_t fib_addr;
1746 
1747 	/* Tell the adapter where the FIB is */
1748 	fib_size = fib->Header.Size;
1749 	fib_addr = fib->Header.SenderFibAddress;
1750 	fib->Header.ReceiverFibAddress = fib_addr;
1751 
1752 	/* get the producer/consumer indices */
1753 	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1754 	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1755 
1756 	/* wrap the queue? */
1757 	if (pi >= aac_qinfo[queue].size)
1758 		pi = 0;
1759 
1760 	/* check for queue full */
1761 	if ((pi + 1) == ci) {
1762 		error = EBUSY;
1763 		goto out;
1764 	}
1765 
1766 	/* populate queue entry */
1767 	(sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1768 	(sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1769 
1770 	/* update producer index */
1771 	sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1772 
1773 	/* notify the adapter if we know how */
1774 	if (aac_qinfo[queue].notify != 0)
1775 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1776 
1777 	error = 0;
1778 
1779 out:
1780 	return(error);
1781 }
1782 
1783 void
1784 aac_command_timeout(struct aac_command *cm)
1785 {
1786 	struct aac_softc *sc = cm->cm_sc;
1787 
1788 	printf("%s: COMMAND %p (flags=%#x) TIMEOUT AFTER %d SECONDS\n",
1789 	       sc->aac_dev.dv_xname, cm, cm->cm_flags,
1790 	       (int)(time_uptime - cm->cm_timestamp));
1791 
1792 	if (cm->cm_flags & AAC_CMD_TIMEDOUT)
1793 		return;
1794 
1795 	cm->cm_flags |= AAC_CMD_TIMEDOUT;
1796 
1797 	AAC_PRINT_FIB(sc, cm->cm_fib);
1798 
1799 	if (cm->cm_flags & AAC_ON_AACQ_BIO) {
1800 		struct scsi_xfer *xs = cm->cm_private;
1801 		int s = splbio();
1802 		xs->error = XS_DRIVER_STUFFUP;
1803 		splx(s);
1804 		scsi_done(xs);
1805 
1806 		aac_remove_bio(cm);
1807 		aac_unmap_command(cm);
1808 	}
1809 }
1810 
1811 void
1812 aac_timeout(struct aac_softc *sc)
1813 {
1814 	struct aac_command *cm;
1815 	time_t deadline;
1816 
1817 	/*
1818 	 * Traverse the busy command list and timeout any commands
1819 	 * that are past their deadline.
1820 	 */
1821 	deadline = time_uptime - AAC_CMD_TIMEOUT;
1822 	TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) {
1823 		if (cm->cm_timestamp  < deadline)
1824 			aac_command_timeout(cm);
1825 	}
1826 }
1827 
1828 /*
1829  * Interface Function Vectors
1830  */
1831 
1832 /*
1833  * Read the current firmware status word.
1834  */
1835 int
1836 aac_sa_get_fwstatus(struct aac_softc *sc)
1837 {
1838 	return (AAC_GETREG4(sc, AAC_SA_FWSTATUS));
1839 }
1840 
1841 int
1842 aac_rx_get_fwstatus(struct aac_softc *sc)
1843 {
1844 	return (AAC_GETREG4(sc, AAC_RX_FWSTATUS));
1845 }
1846 
1847 int
1848 aac_fa_get_fwstatus(struct aac_softc *sc)
1849 {
1850 	return (AAC_GETREG4(sc, AAC_FA_FWSTATUS));
1851 }
1852 
1853 int
1854 aac_rkt_get_fwstatus(struct aac_softc *sc)
1855 {
1856 	return(AAC_GETREG4(sc, AAC_RKT_FWSTATUS));
1857 }
1858 
1859 /*
1860  * Notify the controller of a change in a given queue
1861  */
1862 
1863 void
1864 aac_sa_qnotify(struct aac_softc *sc, int qbit)
1865 {
1866 	AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
1867 }
1868 
1869 void
1870 aac_rx_qnotify(struct aac_softc *sc, int qbit)
1871 {
1872 	AAC_SETREG4(sc, AAC_RX_IDBR, qbit);
1873 }
1874 
1875 void
1876 aac_fa_qnotify(struct aac_softc *sc, int qbit)
1877 {
1878 	AAC_SETREG2(sc, AAC_FA_DOORBELL1, qbit);
1879 	AAC_FA_HACK(sc);
1880 }
1881 
1882 void
1883 aac_rkt_qnotify(struct aac_softc *sc, int qbit)
1884 {
1885 	AAC_SETREG4(sc, AAC_RKT_IDBR, qbit);
1886 }
1887 
1888 /*
1889  * Get the interrupt reason bits
1890  */
1891 int
1892 aac_sa_get_istatus(struct aac_softc *sc)
1893 {
1894 	return (AAC_GETREG2(sc, AAC_SA_DOORBELL0));
1895 }
1896 
1897 int
1898 aac_rx_get_istatus(struct aac_softc *sc)
1899 {
1900 	return (AAC_GETREG4(sc, AAC_RX_ODBR));
1901 }
1902 
1903 int
1904 aac_fa_get_istatus(struct aac_softc *sc)
1905 {
1906 	return (AAC_GETREG2(sc, AAC_FA_DOORBELL0));
1907 }
1908 
1909 int
1910 aac_rkt_get_istatus(struct aac_softc *sc)
1911 {
1912 	return(AAC_GETREG4(sc, AAC_RKT_ODBR));
1913 }
1914 
1915 /*
1916  * Clear some interrupt reason bits
1917  */
1918 void
1919 aac_sa_clear_istatus(struct aac_softc *sc, int mask)
1920 {
1921 	AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
1922 }
1923 
1924 void
1925 aac_rx_clear_istatus(struct aac_softc *sc, int mask)
1926 {
1927 	AAC_SETREG4(sc, AAC_RX_ODBR, mask);
1928 }
1929 
1930 void
1931 aac_fa_clear_istatus(struct aac_softc *sc, int mask)
1932 {
1933 	AAC_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask);
1934 	AAC_FA_HACK(sc);
1935 }
1936 
1937 void
1938 aac_rkt_clear_istatus(struct aac_softc *sc, int mask)
1939 {
1940 	AAC_SETREG4(sc, AAC_RKT_ODBR, mask);
1941 }
1942 
1943 /*
1944  * Populate the mailbox and set the command word
1945  */
1946 void
1947 aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1948 		   u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1949 {
1950 	AAC_SETREG4(sc, AAC_SA_MAILBOX, command);
1951 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
1952 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
1953 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
1954 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
1955 }
1956 
1957 void
1958 aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1959 		   u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1960 {
1961 	AAC_SETREG4(sc, AAC_RX_MAILBOX, command);
1962 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
1963 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
1964 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
1965 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
1966 }
1967 
1968 void
1969 aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1970 		   u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1971 {
1972 	AAC_SETREG4(sc, AAC_FA_MAILBOX, command);
1973 	AAC_FA_HACK(sc);
1974 	AAC_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0);
1975 	AAC_FA_HACK(sc);
1976 	AAC_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1);
1977 	AAC_FA_HACK(sc);
1978 	AAC_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2);
1979 	AAC_FA_HACK(sc);
1980 	AAC_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3);
1981 	AAC_FA_HACK(sc);
1982 }
1983 
1984 void
1985 aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
1986 		    u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1987 {
1988 	AAC_SETREG4(sc, AAC_RKT_MAILBOX, command);
1989 	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0);
1990 	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1);
1991 	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2);
1992 	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3);
1993 }
1994 
1995 /*
1996  * Fetch the immediate command status word
1997  */
1998 int
1999 aac_sa_get_mailbox(struct aac_softc *sc, int mb)
2000 {
2001 	return (AAC_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4)));
2002 }
2003 
2004 int
2005 aac_rx_get_mailbox(struct aac_softc *sc, int mb)
2006 {
2007 	return (AAC_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
2008 }
2009 
2010 int
2011 aac_fa_get_mailbox(struct aac_softc *sc, int mb)
2012 {
2013 	return (AAC_GETREG4(sc, AAC_FA_MAILBOX + (mb * 4)));
2014 }
2015 
2016 int
2017 aac_rkt_get_mailbox(struct aac_softc *sc, int mb)
2018 {
2019 	return(AAC_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4)));
2020 }
2021 
2022 /*
2023  * Set/clear interrupt masks
2024  */
2025 void
2026 aac_sa_set_interrupts(struct aac_softc *sc, int enable)
2027 {
2028 	AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts\n",
2029 				 sc->aac_dev.dv_xname, enable ? "en" : "dis"));
2030 
2031 	if (enable)
2032 		AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2033 	else
2034 		AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
2035 }
2036 
2037 void
2038 aac_rx_set_interrupts(struct aac_softc *sc, int enable)
2039 {
2040 	AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts",
2041 				 sc->aac_dev.dv_xname, enable ? "en" : "dis"));
2042 
2043 	if (enable)
2044 		AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
2045 	else
2046 		AAC_SETREG4(sc, AAC_RX_OIMR, ~0);
2047 }
2048 
2049 void
2050 aac_fa_set_interrupts(struct aac_softc *sc, int enable)
2051 {
2052 	AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts",
2053 				 sc->aac_dev.dv_xname, enable ? "en" : "dis"));
2054 
2055 	if (enable) {
2056 		AAC_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2057 		AAC_FA_HACK(sc);
2058 	} else {
2059 		AAC_SETREG2((sc), AAC_FA_MASK0, ~0);
2060 		AAC_FA_HACK(sc);
2061 	}
2062 }
2063 
2064 void
2065 aac_rkt_set_interrupts(struct aac_softc *sc, int enable)
2066 {
2067 	AAC_DPRINTF(AAC_D_INTR, ("%s: %sable interrupts",
2068 				 sc->aac_dev.dv_xname, enable ? "en" : "dis"));
2069 
2070 	if (enable)
2071 		AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
2072 	else
2073 		AAC_SETREG4(sc, AAC_RKT_OIMR, ~0);
2074 }
2075 
2076 void
2077 aac_eval_mapping(size, cyls, heads, secs)
2078 	u_int32_t size;
2079 	int *cyls, *heads, *secs;
2080 {
2081 	*cyls = size / AAC_HEADS / AAC_SECS;
2082 	if (*cyls < AAC_MAXCYLS) {
2083 		*heads = AAC_HEADS;
2084 		*secs = AAC_SECS;
2085 	} else {
2086 		/* Too high for 64 * 32 */
2087 		*cyls = size / AAC_MEDHEADS / AAC_MEDSECS;
2088 		if (*cyls < AAC_MAXCYLS) {
2089 			*heads = AAC_MEDHEADS;
2090 			*secs = AAC_MEDSECS;
2091 		} else {
2092 			/* Too high for 127 * 63 */
2093 			*cyls = size / AAC_BIGHEADS / AAC_BIGSECS;
2094 			*heads = AAC_BIGHEADS;
2095 			*secs = AAC_BIGSECS;
2096 		}
2097 	}
2098 }
2099 
2100 void
2101 aac_copy_internal_data(struct scsi_xfer *xs, u_int8_t *data, size_t size)
2102 {
2103 	struct aac_softc *sc = xs->sc_link->adapter_softc;
2104 	size_t copy_cnt;
2105 
2106 	AAC_DPRINTF(AAC_D_MISC, ("%s: aac_copy_internal_data\n",
2107 				 sc->aac_dev.dv_xname));
2108 
2109 	if (!xs->datalen)
2110 		printf("%s: uio move not yet supported\n",
2111 		       sc->aac_dev.dv_xname);
2112 	else {
2113 		copy_cnt = MIN(size, xs->datalen);
2114 		bcopy(data, xs->data, copy_cnt);
2115 	}
2116 }
2117 
2118 /* Emulated SCSI operation on cache device */
2119 void
2120 aac_internal_cache_cmd(struct scsi_xfer *xs)
2121 {
2122 	struct scsi_link *link = xs->sc_link;
2123 	struct aac_softc *sc = link->adapter_softc;
2124 	struct scsi_inquiry_data inq;
2125 	struct scsi_sense_data sd;
2126 	struct scsi_read_cap_data rcd;
2127 	u_int8_t target = link->target;
2128 
2129 	AAC_DPRINTF(AAC_D_CMD, ("%s: aac_internal_cache_cmd: ",
2130 				sc->aac_dev.dv_xname));
2131 
2132 	switch (xs->cmd->opcode) {
2133 	case TEST_UNIT_READY:
2134 	case START_STOP:
2135 #if 0
2136 	case VERIFY:
2137 #endif
2138 		AAC_DPRINTF(AAC_D_CMD, ("opc %#x tgt %d ", xs->cmd->opcode,
2139 		    target));
2140 		break;
2141 
2142 	case REQUEST_SENSE:
2143 		AAC_DPRINTF(AAC_D_CMD, ("REQUEST SENSE tgt %d ", target));
2144 		bzero(&sd, sizeof sd);
2145 		sd.error_code = SSD_ERRCODE_CURRENT;
2146 		sd.segment = 0;
2147 		sd.flags = SKEY_NO_SENSE;
2148 		aac_enc32(sd.info, 0);
2149 		sd.extra_len = 0;
2150 		aac_copy_internal_data(xs, (u_int8_t *)&sd, sizeof sd);
2151 		break;
2152 
2153 	case INQUIRY:
2154 		AAC_DPRINTF(AAC_D_CMD, ("INQUIRY tgt %d devtype %x ", target,
2155 		    sc->aac_hdr[target].hd_devtype));
2156 		bzero(&inq, sizeof inq);
2157 		/* XXX How do we detect removable/CD-ROM devices?  */
2158 		inq.device = T_DIRECT;
2159 		inq.dev_qual2 = 0;
2160 		inq.version = 2;
2161 		inq.response_format = 2;
2162 		inq.additional_length = 32;
2163 		inq.flags |= SID_CmdQue;
2164 		strlcpy(inq.vendor, "Adaptec", sizeof inq.vendor);
2165 		snprintf(inq.product, sizeof inq.product, "Container #%02d",
2166 		    target);
2167 		strlcpy(inq.revision, "   ", sizeof inq.revision);
2168 		aac_copy_internal_data(xs, (u_int8_t *)&inq, sizeof inq);
2169 		break;
2170 
2171 	case READ_CAPACITY:
2172 		AAC_DPRINTF(AAC_D_CMD, ("READ CAPACITY tgt %d ", target));
2173 		bzero(&rcd, sizeof rcd);
2174 		_lto4b(sc->aac_hdr[target].hd_size - 1, rcd.addr);
2175 		_lto4b(AAC_BLOCK_SIZE, rcd.length);
2176 		aac_copy_internal_data(xs, (u_int8_t *)&rcd, sizeof rcd);
2177 		break;
2178 
2179 	default:
2180 		AAC_DPRINTF(AAC_D_CMD, ("\n"));
2181 		printf("aac_internal_cache_cmd got bad opcode: %#x\n",
2182 		    xs->cmd->opcode);
2183 		xs->error = XS_DRIVER_STUFFUP;
2184 		return;
2185 	}
2186 
2187 	xs->error = XS_NOERROR;
2188 }
2189 
2190 void
2191 aac_scsi_cmd(struct scsi_xfer *xs)
2192 {
2193 	struct scsi_link *link = xs->sc_link;
2194 	struct aac_softc *sc = link->adapter_softc;
2195 	u_int8_t target = link->target;
2196 	struct aac_command *cm;
2197 	u_int32_t blockno, blockcnt;
2198 	struct scsi_rw *rw;
2199 	struct scsi_rw_big *rwb;
2200 	int s;
2201 
2202 	s = splbio();
2203 
2204 	xs->error = XS_NOERROR;
2205 
2206 	if (target >= AAC_MAX_CONTAINERS || !sc->aac_hdr[target].hd_present ||
2207 	    link->lun != 0) {
2208 		/*
2209 		 * XXX Should be XS_SENSE but that would require setting up a
2210 		 * faked sense too.
2211 		 */
2212 		splx(s);
2213 		xs->error = XS_DRIVER_STUFFUP;
2214 		scsi_done(xs);
2215 		return;
2216 	}
2217 
2218 	AAC_DPRINTF(AAC_D_CMD, ("%s: aac_scsi_cmd: ", sc->aac_dev.dv_xname));
2219 
2220 	xs->error = XS_NOERROR;
2221 	cm = NULL;
2222 	link = xs->sc_link;
2223 	target = link->target;
2224 
2225 	switch (xs->cmd->opcode) {
2226 	case TEST_UNIT_READY:
2227 	case REQUEST_SENSE:
2228 	case INQUIRY:
2229 	case START_STOP:
2230 	case READ_CAPACITY:
2231 #if 0
2232 	case VERIFY:
2233 #endif
2234 		aac_internal_cache_cmd(xs);
2235 		scsi_done(xs);
2236 		goto ready;
2237 
2238 	case PREVENT_ALLOW:
2239 		AAC_DPRINTF(AAC_D_CMD, ("PREVENT/ALLOW "));
2240 		/* XXX Not yet implemented */
2241 		xs->error = XS_NOERROR;
2242 		scsi_done(xs);
2243 		goto ready;
2244 
2245 	case SYNCHRONIZE_CACHE:
2246 		AAC_DPRINTF(AAC_D_CMD, ("SYNCHRONIZE_CACHE "));
2247 		/* XXX Not yet implemented */
2248 		xs->error = XS_NOERROR;
2249 		scsi_done(xs);
2250 		goto ready;
2251 
2252 	default:
2253 		AAC_DPRINTF(AAC_D_CMD, ("unknown opc %#x ", xs->cmd->opcode));
2254 		/* XXX Not yet implemented */
2255 		xs->error = XS_DRIVER_STUFFUP;
2256 		scsi_done(xs);
2257 		goto ready;
2258 
2259 	case READ_COMMAND:
2260 	case READ_BIG:
2261 	case WRITE_COMMAND:
2262 	case WRITE_BIG:
2263 		AAC_DPRINTF(AAC_D_CMD, ("rw opc %#x ", xs->cmd->opcode));
2264 
2265 		/* A read or write operation. */
2266 		if (xs->cmdlen == 6) {
2267 			rw = (struct scsi_rw *)xs->cmd;
2268 			blockno = _3btol(rw->addr) &
2269 				(SRW_TOPADDR << 16 | 0xffff);
2270 			blockcnt = rw->length ? rw->length : 0x100;
2271 		} else {
2272 			rwb = (struct scsi_rw_big *)xs->cmd;
2273 			blockno = _4btol(rwb->addr);
2274 			blockcnt = _2btol(rwb->length);
2275 		}
2276 
2277 		AAC_DPRINTF(AAC_D_CMD, ("opcode=%d blkno=%d bcount=%d ",
2278 					xs->cmd->opcode, blockno, blockcnt));
2279 
2280 		if (blockno >= sc->aac_hdr[target].hd_size ||
2281 		    blockno + blockcnt > sc->aac_hdr[target].hd_size) {
2282 			AAC_DPRINTF(AAC_D_CMD, ("\n"));
2283 			printf("%s: out of bounds %u-%u >= %u\n",
2284 			       sc->aac_dev.dv_xname, blockno,
2285 			       blockcnt, sc->aac_hdr[target].hd_size);
2286 			/*
2287 			 * XXX Should be XS_SENSE but that
2288 			 * would require setting up a faked
2289 			 * sense too.
2290 			 */
2291 			xs->error = XS_DRIVER_STUFFUP;
2292 			scsi_done(xs);
2293 			goto ready;
2294 		}
2295 
2296 		cm = xs->io;
2297 		aac_scrub_command(cm);
2298 
2299 		/* fill out the command */
2300 		cm->cm_data = (void *)xs->data;
2301 		cm->cm_datalen = xs->datalen;
2302 		cm->cm_complete = aac_bio_complete;
2303 		cm->cm_private = xs;
2304 		cm->cm_timestamp = time_uptime;
2305 		cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
2306 		cm->cm_blkno = blockno;
2307 		cm->cm_bcount = blockcnt;
2308 
2309 		AAC_DPRINTF(AAC_D_CMD, ("\n"));
2310 		aac_enqueue_bio(cm);
2311 		aac_startio(sc);
2312 
2313 		/* XXX what if enqueue did not start a transfer? */
2314 		if (xs->flags & SCSI_POLL) {
2315 			if (!aac_wait_command(cm, xs->timeout))
2316 			{
2317 				printf("%s: command timed out\n",
2318 				       sc->aac_dev.dv_xname);
2319 				xs->error = XS_DRIVER_STUFFUP;
2320 				scsi_done(xs);
2321 				splx(s);
2322 				return;
2323 			}
2324 			scsi_done(xs);
2325 		}
2326 	}
2327 
2328  ready:
2329 	splx(s);
2330 	AAC_DPRINTF(AAC_D_CMD, ("%s: scsi_cmd complete\n",
2331 				sc->aac_dev.dv_xname));
2332 }
2333 
2334 /*
2335  * Debugging and Diagnostics
2336  */
2337 
2338 /*
2339  * Print some information about the controller.
2340  */
2341 void
2342 aac_describe_controller(struct aac_softc *sc)
2343 {
2344 	struct aac_fib *fib;
2345 	struct aac_adapter_info	*info;
2346 
2347 	aac_alloc_sync_fib(sc, &fib, 0);
2348 
2349 	fib->data[0] = 0;
2350 	if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) {
2351 		printf("%s: RequestAdapterInfo failed 2\n",
2352 		       sc->aac_dev.dv_xname);
2353 		aac_release_sync_fib(sc);
2354 		return;
2355 	}
2356 	info = (struct aac_adapter_info *)&fib->data[0];
2357 
2358 	printf("%s: %s %dMHz, %dMB cache memory, %s\n", sc->aac_dev.dv_xname,
2359 	       aac_describe_code(aac_cpu_variant, info->CpuVariant),
2360 	       info->ClockSpeed, info->BufferMem / (1024 * 1024),
2361 	       aac_describe_code(aac_battery_platform, info->batteryPlatform));
2362 
2363 	/* save the kernel revision structure for later use */
2364 	sc->aac_revision = info->KernelRevision;
2365 	printf("%s: Kernel %d.%d-%d, Build %d, S/N %6X\n",
2366 	       sc->aac_dev.dv_xname,
2367 	       info->KernelRevision.external.comp.major,
2368 	       info->KernelRevision.external.comp.minor,
2369 	       info->KernelRevision.external.comp.dash,
2370 	       info->KernelRevision.buildNumber,
2371 	       (u_int32_t)(info->SerialNumber & 0xffffff));
2372 
2373 	aac_release_sync_fib(sc);
2374 }
2375 
2376 /*
2377  * Look up a text description of a numeric error code and return a pointer to
2378  * same.
2379  */
2380 char *
2381 aac_describe_code(struct aac_code_lookup *table, u_int32_t code)
2382 {
2383 	int i;
2384 
2385 	for (i = 0; table[i].string != NULL; i++)
2386 		if (table[i].code == code)
2387 			return(table[i].string);
2388 	return(table[i + 1].string);
2389 }
2390 
2391 #ifdef AAC_DEBUG
2392 /*
2393  * Print a FIB
2394  */
2395 void
2396 aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller)
2397 {
2398 	printf("%s: FIB @ %p\n", caller, fib);
2399 	printf("  XferState %b\n", fib->Header.XferState, "\20"
2400 	    "\1HOSTOWNED"
2401 	    "\2ADAPTEROWNED"
2402 	    "\3INITIALISED"
2403 	    "\4EMPTY"
2404 	    "\5FROMPOOL"
2405 	    "\6FROMHOST"
2406 	    "\7FROMADAP"
2407 	    "\10REXPECTED"
2408 	    "\11RNOTEXPECTED"
2409 	    "\12DONEADAP"
2410 	    "\13DONEHOST"
2411 	    "\14HIGH"
2412 	    "\15NORM"
2413 	    "\16ASYNC"
2414 	    "\17PAGEFILEIO"
2415 	    "\20SHUTDOWN"
2416 	    "\21LAZYWRITE"
2417 	    "\22ADAPMICROFIB"
2418 	    "\23BIOSFIB"
2419 	    "\24FAST_RESPONSE"
2420 	    "\25APIFIB\n");
2421 	printf("  Command         %d\n", fib->Header.Command);
2422 	printf("  StructType      %d\n", fib->Header.StructType);
2423 	printf("  Flags           0x%x\n", fib->Header.Flags);
2424 	printf("  Size            %d\n", fib->Header.Size);
2425 	printf("  SenderSize      %d\n", fib->Header.SenderSize);
2426 	printf("  SenderAddress   0x%x\n", fib->Header.SenderFibAddress);
2427 	printf("  ReceiverAddress 0x%x\n", fib->Header.ReceiverFibAddress);
2428 	printf("  SenderData      0x%x\n", fib->Header.SenderData);
2429 	switch(fib->Header.Command) {
2430 	case ContainerCommand: {
2431 		struct aac_blockread *br = (struct aac_blockread *)fib->data;
2432 		struct aac_blockwrite *bw = (struct aac_blockwrite *)fib->data;
2433 		struct aac_sg_table *sg = NULL;
2434 		int i;
2435 
2436 		if (br->Command == VM_CtBlockRead) {
2437 			printf("  BlockRead: container %d  0x%x/%d\n",
2438 			    br->ContainerId, br->BlockNumber, br->ByteCount);
2439 			    sg = &br->SgMap;
2440 		}
2441 		if (bw->Command == VM_CtBlockWrite) {
2442 			printf("  BlockWrite: container %d  0x%x/%d (%s)\n",
2443 			    bw->ContainerId, bw->BlockNumber, bw->ByteCount,
2444 			    bw->Stable == CSTABLE ? "stable" : "unstable");
2445 			sg = &bw->SgMap;
2446 		}
2447 		if (sg != NULL) {
2448 			printf("  %d s/g entries\n", sg->SgCount);
2449 			for (i = 0; i < sg->SgCount; i++)
2450 				printf("  0x%08x/%d\n",
2451 				       sg->SgEntry[i].SgAddress,
2452 				       sg->SgEntry[i].SgByteCount);
2453 		}
2454 		break;
2455 	}
2456 	default:
2457 		printf("   %16D\n", fib->data, " ");
2458 		printf("   %16D\n", fib->data + 16, " ");
2459 	break;
2460 	}
2461 }
2462 
2463 /*
2464  * Describe an AIF we have received.
2465  */
2466 void
2467 aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
2468 {
2469 	printf("%s: print_aif: ", sc->aac_dev.dv_xname);
2470 
2471 	switch(aif->command) {
2472 	case AifCmdEventNotify:
2473 		printf("EventNotify(%d)\n", aif->seqNumber);
2474 
2475 		switch(aif->data.EN.type) {
2476 		case AifEnGeneric:
2477 			/* Generic notification */
2478 			printf("\t(Generic) %.*s\n",
2479 			       (int)sizeof(aif->data.EN.data.EG),
2480 			       aif->data.EN.data.EG.text);
2481 			break;
2482 		case AifEnTaskComplete:
2483 			/* Task has completed */
2484 			printf("\t(TaskComplete)\n");
2485 			break;
2486 		case AifEnConfigChange:
2487 			/* Adapter configuration change occurred */
2488 			printf("\t(ConfigChange)\n");
2489 			break;
2490 		case AifEnContainerChange:
2491 			/* Adapter specific container configuration change */
2492 			printf("\t(ContainerChange) container %d,%d\n",
2493 			       aif->data.EN.data.ECC.container[0],
2494 			       aif->data.EN.data.ECC.container[1]);
2495 			break;
2496 		case AifEnDeviceFailure:
2497 			/* SCSI device failed */
2498 			printf("\t(DeviceFailure) handle %d\n",
2499 			       aif->data.EN.data.EDF.deviceHandle);
2500 			break;
2501 		case AifEnMirrorFailover:
2502 			/* Mirror failover started */
2503 			printf("\t(MirrorFailover) container %d failed, "
2504 			       "migrating from slice %d to %d\n",
2505 			       aif->data.EN.data.EMF.container,
2506 			       aif->data.EN.data.EMF.failedSlice,
2507 			       aif->data.EN.data.EMF.creatingSlice);
2508 			break;
2509 		case AifEnContainerEvent:
2510 			/* Significant container event */
2511 			printf("\t(ContainerEvent) container %d event %d\n",
2512 			       aif->data.EN.data.ECE.container,
2513 			       aif->data.EN.data.ECE.eventType);
2514 			break;
2515 		case AifEnFileSystemChange:
2516 			/* File system changed */
2517 			printf("\t(FileSystemChange)\n");
2518 			break;
2519 		case AifEnConfigPause:
2520 			/* Container pause event */
2521 			printf("\t(ConfigPause)\n");
2522 			break;
2523 		case AifEnConfigResume:
2524 			/* Container resume event */
2525 			printf("\t(ConfigResume)\n");
2526 			break;
2527 		case AifEnFailoverChange:
2528 			/* Failover space assignment changed */
2529 			printf("\t(FailoverChange)\n");
2530 			break;
2531 		case AifEnRAID5RebuildDone:
2532 			/* RAID5 rebuild finished */
2533 			printf("\t(RAID5RebuildDone)\n");
2534 			break;
2535 		case AifEnEnclosureManagement:
2536 			/* Enclosure management event */
2537 			printf("\t(EnclosureManagement) EMPID %d unit %d "
2538 			       "event %d\n",
2539 			       aif->data.EN.data.EEE.empID,
2540 			       aif->data.EN.data.EEE.unitID,
2541 			       aif->data.EN.data.EEE.eventType);
2542 			break;
2543 		case AifEnBatteryEvent:
2544 			/* Significant NV battery event */
2545 			printf("\t(BatteryEvent) %d (state was %d, is %d\n",
2546 			       aif->data.EN.data.EBE.transition_type,
2547 			       aif->data.EN.data.EBE.current_state,
2548 			       aif->data.EN.data.EBE.prior_state);
2549 			break;
2550 		case AifEnAddContainer:
2551 			/* A new container was created. */
2552 			printf("\t(AddContainer)\n");
2553 			break;
2554 		case AifEnDeleteContainer:
2555 			/* A container was deleted. */
2556 			printf("\t(DeleteContainer)\n");
2557 			break;
2558 		case AifEnBatteryNeedsRecond:
2559 			/* The battery needs reconditioning */
2560 			printf("\t(BatteryNeedsRecond)\n");
2561 			break;
2562 		case AifEnClusterEvent:
2563 			/* Some cluster event */
2564 			printf("\t(ClusterEvent) event %d\n",
2565 			       aif->data.EN.data.ECLE.eventType);
2566 			break;
2567 		case AifEnDiskSetEvent:
2568 			/* A disk set event occured. */
2569 			printf("(DiskSetEvent) event %d "
2570 			       "diskset %lld creator %lld\n",
2571 			       aif->data.EN.data.EDS.eventType,
2572 			       aif->data.EN.data.EDS.DsNum,
2573 			       aif->data.EN.data.EDS.CreatorId);
2574 			break;
2575 		case AifDenMorphComplete:
2576 			/* A morph operation completed */
2577 			printf("\t(MorphComplete)\n");
2578 			break;
2579 		case AifDenVolumeExtendComplete:
2580 			/* A volume expand operation completed */
2581 			printf("\t(VolumeExtendComplete)\n");
2582 			break;
2583 		default:
2584 			printf("\t(%d)\n", aif->data.EN.type);
2585 			break;
2586 		}
2587 		break;
2588 	case AifCmdJobProgress:
2589 	{
2590 		char	*status;
2591 		switch(aif->data.PR[0].status) {
2592 		case AifJobStsSuccess:
2593 			status = "success"; break;
2594 		case AifJobStsFinished:
2595 			status = "finished"; break;
2596 		case AifJobStsAborted:
2597 			status = "aborted"; break;
2598 		case AifJobStsFailed:
2599 			status = "failed"; break;
2600 		case AifJobStsSuspended:
2601 			status = "suspended"; break;
2602 		case AifJobStsRunning:
2603 			status = "running"; break;
2604 		default:
2605 			status = "unknown status"; break;
2606 		}
2607 
2608 		printf("JobProgress (%d) - %s (%d, %d)\n",
2609 		       aif->seqNumber, status,
2610 		       aif->data.PR[0].currentTick,
2611 		       aif->data.PR[0].finalTick);
2612 
2613 		switch(aif->data.PR[0].jd.type) {
2614 		case AifJobScsiZero:
2615 			/* SCSI dev clear operation */
2616 			printf("\t(ScsiZero) handle %d\n",
2617 				      aif->data.PR[0].jd.client.scsi_dh);
2618 			break;
2619 		case AifJobScsiVerify:
2620 			/* SCSI device Verify operation NO REPAIR */
2621 			printf("\t(ScsiVerify) handle %d\n",
2622 				      aif->data.PR[0].jd.client.scsi_dh);
2623 			break;
2624 		case AifJobScsiExercise:
2625 			/* SCSI device Exercise operation */
2626 			printf("\t(ScsiExercise) handle %d\n",
2627 			       aif->data.PR[0].jd.client.scsi_dh);
2628 			break;
2629 		case AifJobScsiVerifyRepair:
2630 			/* SCSI device Verify operation WITH repair */
2631 			printf("\t(ScsiVerifyRepair) handle %d\n",
2632 			       aif->data.PR[0].jd.client.scsi_dh);
2633 			break;
2634 		case AifJobCtrZero:
2635 			/* Container clear operation */
2636 			printf("\t(ContainerZero) container %d\n",
2637 			       aif->data.PR[0].jd.client.container.src);
2638 			break;
2639 		case AifJobCtrCopy:
2640 			/* Container copy operation */
2641 			printf("\t(ContainerCopy) container %d to %d\n",
2642 			       aif->data.PR[0].jd.client.container.src,
2643 			       aif->data.PR[0].jd.client.container.dst);
2644 			break;
2645 		case AifJobCtrCreateMirror:
2646 			/* Container Create Mirror operation */
2647 			printf("\t(ContainerCreateMirror) container %d\n",
2648 			       aif->data.PR[0].jd.client.container.src);
2649 			/* XXX two containers? */
2650 			break;
2651 		case AifJobCtrMergeMirror:
2652 			/* Container Merge Mirror operation */
2653 			printf("\t(ContainerMergeMirror) container %d\n",
2654 			       aif->data.PR[0].jd.client.container.src);
2655 			/* XXX two containers? */
2656 			break;
2657 		case AifJobCtrScrubMirror:
2658 			/* Container Scrub Mirror operation */
2659 			printf("\t(ContainerScrubMirror) container %d\n",
2660 			       aif->data.PR[0].jd.client.container.src);
2661 			break;
2662 		case AifJobCtrRebuildRaid5:
2663 			/* Container Rebuild Raid5 operation */
2664 			printf("\t(ContainerRebuildRaid5) container %d\n",
2665 			       aif->data.PR[0].jd.client.container.src);
2666 			break;
2667 		case AifJobCtrScrubRaid5:
2668 			/* Container Scrub Raid5 operation */
2669 			printf("\t(ContainerScrubRaid5) container %d\n",
2670 			       aif->data.PR[0].jd.client.container.src);
2671 			break;
2672 		case AifJobCtrMorph:
2673 			/* Container morph operation */
2674 			printf("\t(ContainerMorph) container %d\n",
2675 			       aif->data.PR[0].jd.client.container.src);
2676 			/* XXX two containers? */
2677 			break;
2678 		case AifJobCtrPartCopy:
2679 			/* Container Partition copy operation */
2680 			printf("\t(ContainerPartCopy) container %d to %d\n",
2681 			       aif->data.PR[0].jd.client.container.src,
2682 			       aif->data.PR[0].jd.client.container.dst);
2683 			break;
2684 		case AifJobCtrRebuildMirror:
2685 			/* Container Rebuild Mirror operation */
2686 			printf("\t(ContainerRebuildMirror) container %d\n",
2687 			       aif->data.PR[0].jd.client.container.src);
2688 			break;
2689 		case AifJobCtrCrazyCache:
2690 			/* crazy cache */
2691 			printf("\t(ContainerCrazyCache) container %d\n",
2692 			       aif->data.PR[0].jd.client.container.src);
2693 			/* XXX two containers? */
2694 			break;
2695 		case AifJobFsCreate:
2696 			/* File System Create operation */
2697 			printf("\t(FsCreate)\n");
2698 			break;
2699 		case AifJobFsVerify:
2700 			/* File System Verify operation */
2701 			printf("\t(FsVerivy)\n");
2702 			break;
2703 		case AifJobFsExtend:
2704 			/* File System Extend operation */
2705 			printf("\t(FsExtend)\n");
2706 			break;
2707 		case AifJobApiFormatNTFS:
2708 			/* Format a drive to NTFS */
2709 			printf("\t(FormatNTFS)\n");
2710 			break;
2711 		case AifJobApiFormatFAT:
2712 			/* Format a drive to FAT */
2713 			printf("\t(FormatFAT)\n");
2714 			break;
2715 		case AifJobApiUpdateSnapshot:
2716 			/* update the read/write half of a snapshot */
2717 			printf("\t(UpdateSnapshot)\n");
2718 			break;
2719 		case AifJobApiFormatFAT32:
2720 			/* Format a drive to FAT32 */
2721 			printf("\t(FormatFAT32)\n");
2722 			break;
2723 		case AifJobCtlContinuousCtrVerify:
2724 			/* Adapter operation */
2725 			printf("\t(ContinuousCtrVerify)\n");
2726 			break;
2727 		default:
2728 			printf("\t(%d)\n", aif->data.PR[0].jd.type);
2729 			break;
2730 		}
2731 		break;
2732 	}
2733 	case AifCmdAPIReport:
2734 		printf("APIReport (%d)\n", aif->seqNumber);
2735 		break;
2736 	case AifCmdDriverNotify:
2737 		printf("DriverNotify (%d)\n", aif->seqNumber);
2738 		break;
2739 	default:
2740 		printf("AIF %d (%d)\n", aif->command, aif->seqNumber);
2741 		break;
2742 	}
2743 }
2744 #endif
2745