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