xref: /freebsd/sys/dev/aac/aac.c (revision eb6d21b4ca6d668cf89afd99eef7baeafa712197)
1 /*-
2  * Copyright (c) 2000 Michael Smith
3  * Copyright (c) 2001 Scott Long
4  * Copyright (c) 2000 BSDi
5  * Copyright (c) 2001 Adaptec, Inc.
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  */
29 
30 #include <sys/cdefs.h>
31 __FBSDID("$FreeBSD$");
32 
33 /*
34  * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
35  */
36 #define AAC_DRIVER_VERSION		0x02000000
37 #define AAC_DRIVERNAME			"aac"
38 
39 #include "opt_aac.h"
40 
41 /* #include <stddef.h> */
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/malloc.h>
45 #include <sys/kernel.h>
46 #include <sys/kthread.h>
47 #include <sys/sysctl.h>
48 #include <sys/poll.h>
49 #include <sys/ioccom.h>
50 
51 #include <sys/bus.h>
52 #include <sys/conf.h>
53 #include <sys/signalvar.h>
54 #include <sys/time.h>
55 #include <sys/eventhandler.h>
56 #include <sys/rman.h>
57 
58 #include <machine/bus.h>
59 #include <sys/bus_dma.h>
60 #include <machine/resource.h>
61 
62 #include <dev/pci/pcireg.h>
63 #include <dev/pci/pcivar.h>
64 
65 #include <dev/aac/aacreg.h>
66 #include <sys/aac_ioctl.h>
67 #include <dev/aac/aacvar.h>
68 #include <dev/aac/aac_tables.h>
69 
70 static void	aac_startup(void *arg);
71 static void	aac_add_container(struct aac_softc *sc,
72 				  struct aac_mntinforesp *mir, int f);
73 static void	aac_get_bus_info(struct aac_softc *sc);
74 static void	aac_daemon(void *arg);
75 
76 /* Command Processing */
77 static void	aac_timeout(struct aac_softc *sc);
78 static void	aac_complete(void *context, int pending);
79 static int	aac_bio_command(struct aac_softc *sc, struct aac_command **cmp);
80 static void	aac_bio_complete(struct aac_command *cm);
81 static int	aac_wait_command(struct aac_command *cm);
82 static void	aac_command_thread(struct aac_softc *sc);
83 
84 /* Command Buffer Management */
85 static void	aac_map_command_sg(void *arg, bus_dma_segment_t *segs,
86 				   int nseg, int error);
87 static void	aac_map_command_helper(void *arg, bus_dma_segment_t *segs,
88 				       int nseg, int error);
89 static int	aac_alloc_commands(struct aac_softc *sc);
90 static void	aac_free_commands(struct aac_softc *sc);
91 static void	aac_unmap_command(struct aac_command *cm);
92 
93 /* Hardware Interface */
94 static int	aac_alloc(struct aac_softc *sc);
95 static void	aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg,
96 			       int error);
97 static int	aac_check_firmware(struct aac_softc *sc);
98 static int	aac_init(struct aac_softc *sc);
99 static int	aac_sync_command(struct aac_softc *sc, u_int32_t command,
100 				 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2,
101 				 u_int32_t arg3, u_int32_t *sp);
102 static int	aac_setup_intr(struct aac_softc *sc);
103 static int	aac_enqueue_fib(struct aac_softc *sc, int queue,
104 				struct aac_command *cm);
105 static int	aac_dequeue_fib(struct aac_softc *sc, int queue,
106 				u_int32_t *fib_size, struct aac_fib **fib_addr);
107 static int	aac_enqueue_response(struct aac_softc *sc, int queue,
108 				     struct aac_fib *fib);
109 
110 /* Falcon/PPC interface */
111 static int	aac_fa_get_fwstatus(struct aac_softc *sc);
112 static void	aac_fa_qnotify(struct aac_softc *sc, int qbit);
113 static int	aac_fa_get_istatus(struct aac_softc *sc);
114 static void	aac_fa_clear_istatus(struct aac_softc *sc, int mask);
115 static void	aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command,
116 				   u_int32_t arg0, u_int32_t arg1,
117 				   u_int32_t arg2, u_int32_t arg3);
118 static int	aac_fa_get_mailbox(struct aac_softc *sc, int mb);
119 static void	aac_fa_set_interrupts(struct aac_softc *sc, int enable);
120 
121 struct aac_interface aac_fa_interface = {
122 	aac_fa_get_fwstatus,
123 	aac_fa_qnotify,
124 	aac_fa_get_istatus,
125 	aac_fa_clear_istatus,
126 	aac_fa_set_mailbox,
127 	aac_fa_get_mailbox,
128 	aac_fa_set_interrupts,
129 	NULL, NULL, NULL
130 };
131 
132 /* StrongARM interface */
133 static int	aac_sa_get_fwstatus(struct aac_softc *sc);
134 static void	aac_sa_qnotify(struct aac_softc *sc, int qbit);
135 static int	aac_sa_get_istatus(struct aac_softc *sc);
136 static void	aac_sa_clear_istatus(struct aac_softc *sc, int mask);
137 static void	aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
138 				   u_int32_t arg0, u_int32_t arg1,
139 				   u_int32_t arg2, u_int32_t arg3);
140 static int	aac_sa_get_mailbox(struct aac_softc *sc, int mb);
141 static void	aac_sa_set_interrupts(struct aac_softc *sc, int enable);
142 
143 struct aac_interface aac_sa_interface = {
144 	aac_sa_get_fwstatus,
145 	aac_sa_qnotify,
146 	aac_sa_get_istatus,
147 	aac_sa_clear_istatus,
148 	aac_sa_set_mailbox,
149 	aac_sa_get_mailbox,
150 	aac_sa_set_interrupts,
151 	NULL, NULL, NULL
152 };
153 
154 /* i960Rx interface */
155 static int	aac_rx_get_fwstatus(struct aac_softc *sc);
156 static void	aac_rx_qnotify(struct aac_softc *sc, int qbit);
157 static int	aac_rx_get_istatus(struct aac_softc *sc);
158 static void	aac_rx_clear_istatus(struct aac_softc *sc, int mask);
159 static void	aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
160 				   u_int32_t arg0, u_int32_t arg1,
161 				   u_int32_t arg2, u_int32_t arg3);
162 static int	aac_rx_get_mailbox(struct aac_softc *sc, int mb);
163 static void	aac_rx_set_interrupts(struct aac_softc *sc, int enable);
164 static int aac_rx_send_command(struct aac_softc *sc, struct aac_command *cm);
165 static int aac_rx_get_outb_queue(struct aac_softc *sc);
166 static void aac_rx_set_outb_queue(struct aac_softc *sc, int index);
167 
168 struct aac_interface aac_rx_interface = {
169 	aac_rx_get_fwstatus,
170 	aac_rx_qnotify,
171 	aac_rx_get_istatus,
172 	aac_rx_clear_istatus,
173 	aac_rx_set_mailbox,
174 	aac_rx_get_mailbox,
175 	aac_rx_set_interrupts,
176 	aac_rx_send_command,
177 	aac_rx_get_outb_queue,
178 	aac_rx_set_outb_queue
179 };
180 
181 /* Rocket/MIPS interface */
182 static int	aac_rkt_get_fwstatus(struct aac_softc *sc);
183 static void	aac_rkt_qnotify(struct aac_softc *sc, int qbit);
184 static int	aac_rkt_get_istatus(struct aac_softc *sc);
185 static void	aac_rkt_clear_istatus(struct aac_softc *sc, int mask);
186 static void	aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command,
187 				    u_int32_t arg0, u_int32_t arg1,
188 				    u_int32_t arg2, u_int32_t arg3);
189 static int	aac_rkt_get_mailbox(struct aac_softc *sc, int mb);
190 static void	aac_rkt_set_interrupts(struct aac_softc *sc, int enable);
191 static int aac_rkt_send_command(struct aac_softc *sc, struct aac_command *cm);
192 static int aac_rkt_get_outb_queue(struct aac_softc *sc);
193 static void aac_rkt_set_outb_queue(struct aac_softc *sc, int index);
194 
195 struct aac_interface aac_rkt_interface = {
196 	aac_rkt_get_fwstatus,
197 	aac_rkt_qnotify,
198 	aac_rkt_get_istatus,
199 	aac_rkt_clear_istatus,
200 	aac_rkt_set_mailbox,
201 	aac_rkt_get_mailbox,
202 	aac_rkt_set_interrupts,
203 	aac_rkt_send_command,
204 	aac_rkt_get_outb_queue,
205 	aac_rkt_set_outb_queue
206 };
207 
208 /* Debugging and Diagnostics */
209 static void	aac_describe_controller(struct aac_softc *sc);
210 static char	*aac_describe_code(struct aac_code_lookup *table,
211 				   u_int32_t code);
212 
213 /* Management Interface */
214 static d_open_t		aac_open;
215 static d_close_t	aac_close;
216 static d_ioctl_t	aac_ioctl;
217 static d_poll_t		aac_poll;
218 static int		aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib);
219 static int		aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg);
220 static void		aac_handle_aif(struct aac_softc *sc,
221 					   struct aac_fib *fib);
222 static int		aac_rev_check(struct aac_softc *sc, caddr_t udata);
223 static int		aac_open_aif(struct aac_softc *sc, caddr_t arg);
224 static int		aac_close_aif(struct aac_softc *sc, caddr_t arg);
225 static int		aac_getnext_aif(struct aac_softc *sc, caddr_t arg);
226 static int		aac_return_aif(struct aac_softc *sc,
227 					struct aac_fib_context *ctx, caddr_t uptr);
228 static int		aac_query_disk(struct aac_softc *sc, caddr_t uptr);
229 static int		aac_get_pci_info(struct aac_softc *sc, caddr_t uptr);
230 static int		aac_supported_features(struct aac_softc *sc, caddr_t uptr);
231 static void		aac_ioctl_event(struct aac_softc *sc,
232 					struct aac_event *event, void *arg);
233 static struct aac_mntinforesp *
234 	aac_get_container_info(struct aac_softc *sc, struct aac_fib *fib, int cid);
235 
236 static struct cdevsw aac_cdevsw = {
237 	.d_version =	D_VERSION,
238 	.d_flags =	D_NEEDGIANT,
239 	.d_open =	aac_open,
240 	.d_close =	aac_close,
241 	.d_ioctl =	aac_ioctl,
242 	.d_poll =	aac_poll,
243 	.d_name =	"aac",
244 };
245 
246 MALLOC_DEFINE(M_AACBUF, "aacbuf", "Buffers for the AAC driver");
247 
248 /* sysctl node */
249 SYSCTL_NODE(_hw, OID_AUTO, aac, CTLFLAG_RD, 0, "AAC driver parameters");
250 
251 /*
252  * Device Interface
253  */
254 
255 /*
256  * Initialize the controller and softc
257  */
258 int
259 aac_attach(struct aac_softc *sc)
260 {
261 	int error, unit;
262 
263 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
264 
265 	/*
266 	 * Initialize per-controller queues.
267 	 */
268 	aac_initq_free(sc);
269 	aac_initq_ready(sc);
270 	aac_initq_busy(sc);
271 	aac_initq_bio(sc);
272 
273 	/*
274 	 * Initialize command-completion task.
275 	 */
276 	TASK_INIT(&sc->aac_task_complete, 0, aac_complete, sc);
277 
278 	/* mark controller as suspended until we get ourselves organised */
279 	sc->aac_state |= AAC_STATE_SUSPEND;
280 
281 	/*
282 	 * Check that the firmware on the card is supported.
283 	 */
284 	if ((error = aac_check_firmware(sc)) != 0)
285 		return(error);
286 
287 	/*
288 	 * Initialize locks
289 	 */
290 	mtx_init(&sc->aac_aifq_lock, "AAC AIF lock", NULL, MTX_DEF);
291 	mtx_init(&sc->aac_io_lock, "AAC I/O lock", NULL, MTX_DEF);
292 	mtx_init(&sc->aac_container_lock, "AAC container lock", NULL, MTX_DEF);
293 	TAILQ_INIT(&sc->aac_container_tqh);
294 	TAILQ_INIT(&sc->aac_ev_cmfree);
295 
296 	/* Initialize the clock daemon callout. */
297 	callout_init_mtx(&sc->aac_daemontime, &sc->aac_io_lock, 0);
298 
299 	/*
300 	 * Initialize the adapter.
301 	 */
302 	if ((error = aac_alloc(sc)) != 0)
303 		return(error);
304 	if ((error = aac_init(sc)) != 0)
305 		return(error);
306 
307 	/*
308 	 * Allocate and connect our interrupt.
309 	 */
310 	if ((error = aac_setup_intr(sc)) != 0)
311 		return(error);
312 
313 	/*
314 	 * Print a little information about the controller.
315 	 */
316 	aac_describe_controller(sc);
317 
318 	/*
319 	 * Register to probe our containers later.
320 	 */
321 	sc->aac_ich.ich_func = aac_startup;
322 	sc->aac_ich.ich_arg = sc;
323 	if (config_intrhook_establish(&sc->aac_ich) != 0) {
324 		device_printf(sc->aac_dev,
325 			      "can't establish configuration hook\n");
326 		return(ENXIO);
327 	}
328 
329 	/*
330 	 * Make the control device.
331 	 */
332 	unit = device_get_unit(sc->aac_dev);
333 	sc->aac_dev_t = make_dev(&aac_cdevsw, unit, UID_ROOT, GID_OPERATOR,
334 				 0640, "aac%d", unit);
335 	(void)make_dev_alias(sc->aac_dev_t, "afa%d", unit);
336 	(void)make_dev_alias(sc->aac_dev_t, "hpn%d", unit);
337 	sc->aac_dev_t->si_drv1 = sc;
338 
339 	/* Create the AIF thread */
340 	if (kproc_create((void(*)(void *))aac_command_thread, sc,
341 		   &sc->aifthread, 0, 0, "aac%daif", unit))
342 		panic("Could not create AIF thread");
343 
344 	/* Register the shutdown method to only be called post-dump */
345 	if ((sc->eh = EVENTHANDLER_REGISTER(shutdown_final, aac_shutdown,
346 	    sc->aac_dev, SHUTDOWN_PRI_DEFAULT)) == NULL)
347 		device_printf(sc->aac_dev,
348 			      "shutdown event registration failed\n");
349 
350 	/* Register with CAM for the non-DASD devices */
351 	if ((sc->flags & AAC_FLAGS_ENABLE_CAM) != 0) {
352 		TAILQ_INIT(&sc->aac_sim_tqh);
353 		aac_get_bus_info(sc);
354 	}
355 
356 	mtx_lock(&sc->aac_io_lock);
357 	callout_reset(&sc->aac_daemontime, 60 * hz, aac_daemon, sc);
358 	mtx_unlock(&sc->aac_io_lock);
359 
360 	return(0);
361 }
362 
363 static void
364 aac_daemon(void *arg)
365 {
366 	struct timeval tv;
367 	struct aac_softc *sc;
368 	struct aac_fib *fib;
369 
370 	sc = arg;
371 	mtx_assert(&sc->aac_io_lock, MA_OWNED);
372 
373 	if (callout_pending(&sc->aac_daemontime) ||
374 	    callout_active(&sc->aac_daemontime) == 0)
375 		return;
376 	getmicrotime(&tv);
377 	aac_alloc_sync_fib(sc, &fib);
378 	*(uint32_t *)fib->data = tv.tv_sec;
379 	aac_sync_fib(sc, SendHostTime, 0, fib, sizeof(uint32_t));
380 	aac_release_sync_fib(sc);
381 	callout_schedule(&sc->aac_daemontime, 30 * 60 * hz);
382 }
383 
384 void
385 aac_add_event(struct aac_softc *sc, struct aac_event *event)
386 {
387 
388 	switch (event->ev_type & AAC_EVENT_MASK) {
389 	case AAC_EVENT_CMFREE:
390 		TAILQ_INSERT_TAIL(&sc->aac_ev_cmfree, event, ev_links);
391 		break;
392 	default:
393 		device_printf(sc->aac_dev, "aac_add event: unknown event %d\n",
394 		    event->ev_type);
395 		break;
396 	}
397 
398 	return;
399 }
400 
401 /*
402  * Request information of container #cid
403  */
404 static struct aac_mntinforesp *
405 aac_get_container_info(struct aac_softc *sc, struct aac_fib *fib, int cid)
406 {
407 	struct aac_mntinfo *mi;
408 
409 	mi = (struct aac_mntinfo *)&fib->data[0];
410 	/* use 64-bit LBA if enabled */
411 	mi->Command = (sc->flags & AAC_FLAGS_LBA_64BIT) ?
412 	    VM_NameServe64 : VM_NameServe;
413 	mi->MntType = FT_FILESYS;
414 	mi->MntCount = cid;
415 
416 	if (aac_sync_fib(sc, ContainerCommand, 0, fib,
417 			 sizeof(struct aac_mntinfo))) {
418 		printf("Error probing container %d\n", cid);
419 		return (NULL);
420 	}
421 
422 	return ((struct aac_mntinforesp *)&fib->data[0]);
423 }
424 
425 /*
426  * Probe for containers, create disks.
427  */
428 static void
429 aac_startup(void *arg)
430 {
431 	struct aac_softc *sc;
432 	struct aac_fib *fib;
433 	struct aac_mntinforesp *mir;
434 	int count = 0, i = 0;
435 
436 	sc = (struct aac_softc *)arg;
437 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
438 
439 	/* disconnect ourselves from the intrhook chain */
440 	config_intrhook_disestablish(&sc->aac_ich);
441 
442 	mtx_lock(&sc->aac_io_lock);
443 	aac_alloc_sync_fib(sc, &fib);
444 
445 	/* loop over possible containers */
446 	do {
447 		if ((mir = aac_get_container_info(sc, fib, i)) == NULL)
448 			continue;
449 		if (i == 0)
450 			count = mir->MntRespCount;
451 		aac_add_container(sc, mir, 0);
452 		i++;
453 	} while ((i < count) && (i < AAC_MAX_CONTAINERS));
454 
455 	aac_release_sync_fib(sc);
456 	mtx_unlock(&sc->aac_io_lock);
457 
458 	/* poke the bus to actually attach the child devices */
459 	if (bus_generic_attach(sc->aac_dev))
460 		device_printf(sc->aac_dev, "bus_generic_attach failed\n");
461 
462 	/* mark the controller up */
463 	sc->aac_state &= ~AAC_STATE_SUSPEND;
464 
465 	/* enable interrupts now */
466 	AAC_UNMASK_INTERRUPTS(sc);
467 }
468 
469 /*
470  * Create a device to represent a new container
471  */
472 static void
473 aac_add_container(struct aac_softc *sc, struct aac_mntinforesp *mir, int f)
474 {
475 	struct aac_container *co;
476 	device_t child;
477 
478 	/*
479 	 * Check container volume type for validity.  Note that many of
480 	 * the possible types may never show up.
481 	 */
482 	if ((mir->Status == ST_OK) && (mir->MntTable[0].VolType != CT_NONE)) {
483 		co = (struct aac_container *)malloc(sizeof *co, M_AACBUF,
484 		       M_NOWAIT | M_ZERO);
485 		if (co == NULL)
486 			panic("Out of memory?!");
487 		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "id %x  name '%.16s'  size %u  type %d",
488 		      mir->MntTable[0].ObjectId,
489 		      mir->MntTable[0].FileSystemName,
490 		      mir->MntTable[0].Capacity, mir->MntTable[0].VolType);
491 
492 		if ((child = device_add_child(sc->aac_dev, "aacd", -1)) == NULL)
493 			device_printf(sc->aac_dev, "device_add_child failed\n");
494 		else
495 			device_set_ivars(child, co);
496 		device_set_desc(child, aac_describe_code(aac_container_types,
497 				mir->MntTable[0].VolType));
498 		co->co_disk = child;
499 		co->co_found = f;
500 		bcopy(&mir->MntTable[0], &co->co_mntobj,
501 		      sizeof(struct aac_mntobj));
502 		mtx_lock(&sc->aac_container_lock);
503 		TAILQ_INSERT_TAIL(&sc->aac_container_tqh, co, co_link);
504 		mtx_unlock(&sc->aac_container_lock);
505 	}
506 }
507 
508 /*
509  * Allocate resources associated with (sc)
510  */
511 static int
512 aac_alloc(struct aac_softc *sc)
513 {
514 
515 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
516 
517 	/*
518 	 * Create DMA tag for mapping buffers into controller-addressable space.
519 	 */
520 	if (bus_dma_tag_create(sc->aac_parent_dmat, 	/* parent */
521 			       1, 0, 			/* algnmnt, boundary */
522 			       (sc->flags & AAC_FLAGS_SG_64BIT) ?
523 			       BUS_SPACE_MAXADDR :
524 			       BUS_SPACE_MAXADDR_32BIT,	/* lowaddr */
525 			       BUS_SPACE_MAXADDR, 	/* highaddr */
526 			       NULL, NULL, 		/* filter, filterarg */
527 			       MAXBSIZE,		/* maxsize */
528 			       sc->aac_sg_tablesize,	/* nsegments */
529 			       MAXBSIZE,		/* maxsegsize */
530 			       BUS_DMA_ALLOCNOW,	/* flags */
531 			       busdma_lock_mutex,	/* lockfunc */
532 			       &sc->aac_io_lock,	/* lockfuncarg */
533 			       &sc->aac_buffer_dmat)) {
534 		device_printf(sc->aac_dev, "can't allocate buffer DMA tag\n");
535 		return (ENOMEM);
536 	}
537 
538 	/*
539 	 * Create DMA tag for mapping FIBs into controller-addressable space..
540 	 */
541 	if (bus_dma_tag_create(sc->aac_parent_dmat,	/* parent */
542 			       1, 0, 			/* algnmnt, boundary */
543 			       (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
544 			       BUS_SPACE_MAXADDR_32BIT :
545 			       0x7fffffff,		/* lowaddr */
546 			       BUS_SPACE_MAXADDR, 	/* highaddr */
547 			       NULL, NULL, 		/* filter, filterarg */
548 			       sc->aac_max_fibs_alloc *
549 			       sc->aac_max_fib_size,  /* maxsize */
550 			       1,			/* nsegments */
551 			       sc->aac_max_fibs_alloc *
552 			       sc->aac_max_fib_size,	/* maxsize */
553 			       0,			/* flags */
554 			       NULL, NULL,		/* No locking needed */
555 			       &sc->aac_fib_dmat)) {
556 		device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n");;
557 		return (ENOMEM);
558 	}
559 
560 	/*
561 	 * Create DMA tag for the common structure and allocate it.
562 	 */
563 	if (bus_dma_tag_create(sc->aac_parent_dmat, 	/* parent */
564 			       1, 0,			/* algnmnt, boundary */
565 			       (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
566 			       BUS_SPACE_MAXADDR_32BIT :
567 			       0x7fffffff,		/* lowaddr */
568 			       BUS_SPACE_MAXADDR, 	/* highaddr */
569 			       NULL, NULL, 		/* filter, filterarg */
570 			       8192 + sizeof(struct aac_common), /* maxsize */
571 			       1,			/* nsegments */
572 			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
573 			       0,			/* flags */
574 			       NULL, NULL,		/* No locking needed */
575 			       &sc->aac_common_dmat)) {
576 		device_printf(sc->aac_dev,
577 			      "can't allocate common structure DMA tag\n");
578 		return (ENOMEM);
579 	}
580 	if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common,
581 			     BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
582 		device_printf(sc->aac_dev, "can't allocate common structure\n");
583 		return (ENOMEM);
584 	}
585 
586 	/*
587 	 * Work around a bug in the 2120 and 2200 that cannot DMA commands
588 	 * below address 8192 in physical memory.
589 	 * XXX If the padding is not needed, can it be put to use instead
590 	 * of ignored?
591 	 */
592 	(void)bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
593 			sc->aac_common, 8192 + sizeof(*sc->aac_common),
594 			aac_common_map, sc, 0);
595 
596 	if (sc->aac_common_busaddr < 8192) {
597 		sc->aac_common = (struct aac_common *)
598 		    ((uint8_t *)sc->aac_common + 8192);
599 		sc->aac_common_busaddr += 8192;
600 	}
601 	bzero(sc->aac_common, sizeof(*sc->aac_common));
602 
603 	/* Allocate some FIBs and associated command structs */
604 	TAILQ_INIT(&sc->aac_fibmap_tqh);
605 	sc->aac_commands = malloc(sc->aac_max_fibs * sizeof(struct aac_command),
606 				  M_AACBUF, M_WAITOK|M_ZERO);
607 	while (sc->total_fibs < sc->aac_max_fibs) {
608 		if (aac_alloc_commands(sc) != 0)
609 			break;
610 	}
611 	if (sc->total_fibs == 0)
612 		return (ENOMEM);
613 
614 	return (0);
615 }
616 
617 /*
618  * Free all of the resources associated with (sc)
619  *
620  * Should not be called if the controller is active.
621  */
622 void
623 aac_free(struct aac_softc *sc)
624 {
625 
626 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
627 
628 	/* remove the control device */
629 	if (sc->aac_dev_t != NULL)
630 		destroy_dev(sc->aac_dev_t);
631 
632 	/* throw away any FIB buffers, discard the FIB DMA tag */
633 	aac_free_commands(sc);
634 	if (sc->aac_fib_dmat)
635 		bus_dma_tag_destroy(sc->aac_fib_dmat);
636 
637 	free(sc->aac_commands, M_AACBUF);
638 
639 	/* destroy the common area */
640 	if (sc->aac_common) {
641 		bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap);
642 		bus_dmamem_free(sc->aac_common_dmat, sc->aac_common,
643 				sc->aac_common_dmamap);
644 	}
645 	if (sc->aac_common_dmat)
646 		bus_dma_tag_destroy(sc->aac_common_dmat);
647 
648 	/* disconnect the interrupt handler */
649 	if (sc->aac_intr)
650 		bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr);
651 	if (sc->aac_irq != NULL)
652 		bus_release_resource(sc->aac_dev, SYS_RES_IRQ, sc->aac_irq_rid,
653 				     sc->aac_irq);
654 
655 	/* destroy data-transfer DMA tag */
656 	if (sc->aac_buffer_dmat)
657 		bus_dma_tag_destroy(sc->aac_buffer_dmat);
658 
659 	/* destroy the parent DMA tag */
660 	if (sc->aac_parent_dmat)
661 		bus_dma_tag_destroy(sc->aac_parent_dmat);
662 
663 	/* release the register window mapping */
664 	if (sc->aac_regs_res0 != NULL)
665 		bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
666 				     sc->aac_regs_rid0, sc->aac_regs_res0);
667 	if (sc->aac_hwif == AAC_HWIF_NARK && sc->aac_regs_res1 != NULL)
668 		bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
669 				     sc->aac_regs_rid1, sc->aac_regs_res1);
670 }
671 
672 /*
673  * Disconnect from the controller completely, in preparation for unload.
674  */
675 int
676 aac_detach(device_t dev)
677 {
678 	struct aac_softc *sc;
679 	struct aac_container *co;
680 	struct aac_sim	*sim;
681 	int error;
682 
683 	sc = device_get_softc(dev);
684 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
685 
686 	if (sc->aac_state & AAC_STATE_OPEN)
687 		return(EBUSY);
688 
689 	callout_drain(&sc->aac_daemontime);
690 
691 	/* Remove the child containers */
692 	while ((co = TAILQ_FIRST(&sc->aac_container_tqh)) != NULL) {
693 		error = device_delete_child(dev, co->co_disk);
694 		if (error)
695 			return (error);
696 		TAILQ_REMOVE(&sc->aac_container_tqh, co, co_link);
697 		free(co, M_AACBUF);
698 	}
699 
700 	/* Remove the CAM SIMs */
701 	while ((sim = TAILQ_FIRST(&sc->aac_sim_tqh)) != NULL) {
702 		TAILQ_REMOVE(&sc->aac_sim_tqh, sim, sim_link);
703 		error = device_delete_child(dev, sim->sim_dev);
704 		if (error)
705 			return (error);
706 		free(sim, M_AACBUF);
707 	}
708 
709 	if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
710 		sc->aifflags |= AAC_AIFFLAGS_EXIT;
711 		wakeup(sc->aifthread);
712 		tsleep(sc->aac_dev, PUSER | PCATCH, "aacdch", 30 * hz);
713 	}
714 
715 	if (sc->aifflags & AAC_AIFFLAGS_RUNNING)
716 		panic("Cannot shutdown AIF thread");
717 
718 	if ((error = aac_shutdown(dev)))
719 		return(error);
720 
721 	EVENTHANDLER_DEREGISTER(shutdown_final, sc->eh);
722 
723 	aac_free(sc);
724 
725 	mtx_destroy(&sc->aac_aifq_lock);
726 	mtx_destroy(&sc->aac_io_lock);
727 	mtx_destroy(&sc->aac_container_lock);
728 
729 	return(0);
730 }
731 
732 /*
733  * Bring the controller down to a dormant state and detach all child devices.
734  *
735  * This function is called before detach or system shutdown.
736  *
737  * Note that we can assume that the bioq on the controller is empty, as we won't
738  * allow shutdown if any device is open.
739  */
740 int
741 aac_shutdown(device_t dev)
742 {
743 	struct aac_softc *sc;
744 	struct aac_fib *fib;
745 	struct aac_close_command *cc;
746 
747 	sc = device_get_softc(dev);
748 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
749 
750 	sc->aac_state |= AAC_STATE_SUSPEND;
751 
752 	/*
753 	 * Send a Container shutdown followed by a HostShutdown FIB to the
754 	 * controller to convince it that we don't want to talk to it anymore.
755 	 * We've been closed and all I/O completed already
756 	 */
757 	device_printf(sc->aac_dev, "shutting down controller...");
758 
759 	mtx_lock(&sc->aac_io_lock);
760 	aac_alloc_sync_fib(sc, &fib);
761 	cc = (struct aac_close_command *)&fib->data[0];
762 
763 	bzero(cc, sizeof(struct aac_close_command));
764 	cc->Command = VM_CloseAll;
765 	cc->ContainerId = 0xffffffff;
766 	if (aac_sync_fib(sc, ContainerCommand, 0, fib,
767 	    sizeof(struct aac_close_command)))
768 		printf("FAILED.\n");
769 	else
770 		printf("done\n");
771 #if 0
772 	else {
773 		fib->data[0] = 0;
774 		/*
775 		 * XXX Issuing this command to the controller makes it shut down
776 		 * but also keeps it from coming back up without a reset of the
777 		 * PCI bus.  This is not desirable if you are just unloading the
778 		 * driver module with the intent to reload it later.
779 		 */
780 		if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN,
781 		    fib, 1)) {
782 			printf("FAILED.\n");
783 		} else {
784 			printf("done.\n");
785 		}
786 	}
787 #endif
788 
789 	AAC_MASK_INTERRUPTS(sc);
790 	aac_release_sync_fib(sc);
791 	mtx_unlock(&sc->aac_io_lock);
792 
793 	return(0);
794 }
795 
796 /*
797  * Bring the controller to a quiescent state, ready for system suspend.
798  */
799 int
800 aac_suspend(device_t dev)
801 {
802 	struct aac_softc *sc;
803 
804 	sc = device_get_softc(dev);
805 
806 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
807 	sc->aac_state |= AAC_STATE_SUSPEND;
808 
809 	AAC_MASK_INTERRUPTS(sc);
810 	return(0);
811 }
812 
813 /*
814  * Bring the controller back to a state ready for operation.
815  */
816 int
817 aac_resume(device_t dev)
818 {
819 	struct aac_softc *sc;
820 
821 	sc = device_get_softc(dev);
822 
823 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
824 	sc->aac_state &= ~AAC_STATE_SUSPEND;
825 	AAC_UNMASK_INTERRUPTS(sc);
826 	return(0);
827 }
828 
829 /*
830  * Interrupt handler for NEW_COMM interface.
831  */
832 void
833 aac_new_intr(void *arg)
834 {
835 	struct aac_softc *sc;
836 	u_int32_t index, fast;
837 	struct aac_command *cm;
838 	struct aac_fib *fib;
839 	int i;
840 
841 	sc = (struct aac_softc *)arg;
842 
843 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
844 	mtx_lock(&sc->aac_io_lock);
845 	while (1) {
846 		index = AAC_GET_OUTB_QUEUE(sc);
847 		if (index == 0xffffffff)
848 			index = AAC_GET_OUTB_QUEUE(sc);
849 		if (index == 0xffffffff)
850 			break;
851 		if (index & 2) {
852 			if (index == 0xfffffffe) {
853 				/* XXX This means that the controller wants
854 				 * more work.  Ignore it for now.
855 				 */
856 				continue;
857 			}
858 			/* AIF */
859 			fib = (struct aac_fib *)malloc(sizeof *fib, M_AACBUF,
860 				   M_NOWAIT | M_ZERO);
861 			if (fib == NULL) {
862 				/* If we're really this short on memory,
863 				 * hopefully breaking out of the handler will
864 				 * allow something to get freed.  This
865 				 * actually sucks a whole lot.
866 				 */
867 				break;
868 			}
869 			index &= ~2;
870 			for (i = 0; i < sizeof(struct aac_fib)/4; ++i)
871 				((u_int32_t *)fib)[i] = AAC_MEM1_GETREG4(sc, index + i*4);
872 			aac_handle_aif(sc, fib);
873 			free(fib, M_AACBUF);
874 
875 			/*
876 			 * AIF memory is owned by the adapter, so let it
877 			 * know that we are done with it.
878 			 */
879 			AAC_SET_OUTB_QUEUE(sc, index);
880 			AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
881 		} else {
882 			fast = index & 1;
883 			cm = sc->aac_commands + (index >> 2);
884 			fib = cm->cm_fib;
885 			if (fast) {
886 				fib->Header.XferState |= AAC_FIBSTATE_DONEADAP;
887 				*((u_int32_t *)(fib->data)) = AAC_ERROR_NORMAL;
888 			}
889 			aac_remove_busy(cm);
890  			aac_unmap_command(cm);
891 			cm->cm_flags |= AAC_CMD_COMPLETED;
892 
893 			/* is there a completion handler? */
894 			if (cm->cm_complete != NULL) {
895 				cm->cm_complete(cm);
896 			} else {
897 				/* assume that someone is sleeping on this
898 				 * command
899 				 */
900 				wakeup(cm);
901 			}
902 			sc->flags &= ~AAC_QUEUE_FRZN;
903 		}
904 	}
905 	/* see if we can start some more I/O */
906 	if ((sc->flags & AAC_QUEUE_FRZN) == 0)
907 		aac_startio(sc);
908 
909 	mtx_unlock(&sc->aac_io_lock);
910 }
911 
912 /*
913  * Interrupt filter for !NEW_COMM interface.
914  */
915 int
916 aac_filter(void *arg)
917 {
918 	struct aac_softc *sc;
919 	u_int16_t reason;
920 
921 	sc = (struct aac_softc *)arg;
922 
923 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
924 	/*
925 	 * Read the status register directly.  This is faster than taking the
926 	 * driver lock and reading the queues directly.  It also saves having
927 	 * to turn parts of the driver lock into a spin mutex, which would be
928 	 * ugly.
929 	 */
930 	reason = AAC_GET_ISTATUS(sc);
931 	AAC_CLEAR_ISTATUS(sc, reason);
932 
933 	/* handle completion processing */
934 	if (reason & AAC_DB_RESPONSE_READY)
935 		taskqueue_enqueue_fast(taskqueue_fast, &sc->aac_task_complete);
936 
937 	/* controller wants to talk to us */
938 	if (reason & (AAC_DB_PRINTF | AAC_DB_COMMAND_READY)) {
939 		/*
940 		 * XXX Make sure that we don't get fooled by strange messages
941 		 * that start with a NULL.
942 		 */
943 		if ((reason & AAC_DB_PRINTF) &&
944 			(sc->aac_common->ac_printf[0] == 0))
945 			sc->aac_common->ac_printf[0] = 32;
946 
947 		/*
948 		 * This might miss doing the actual wakeup.  However, the
949 		 * msleep that this is waking up has a timeout, so it will
950 		 * wake up eventually.  AIFs and printfs are low enough
951 		 * priority that they can handle hanging out for a few seconds
952 		 * if needed.
953 		 */
954 		wakeup(sc->aifthread);
955 	}
956 	return (FILTER_HANDLED);
957 }
958 
959 /*
960  * Command Processing
961  */
962 
963 /*
964  * Start as much queued I/O as possible on the controller
965  */
966 void
967 aac_startio(struct aac_softc *sc)
968 {
969 	struct aac_command *cm;
970 	int error;
971 
972 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
973 
974 	for (;;) {
975 		/*
976 		 * This flag might be set if the card is out of resources.
977 		 * Checking it here prevents an infinite loop of deferrals.
978 		 */
979 		if (sc->flags & AAC_QUEUE_FRZN)
980 			break;
981 
982 		/*
983 		 * Try to get a command that's been put off for lack of
984 		 * resources
985 		 */
986 		cm = aac_dequeue_ready(sc);
987 
988 		/*
989 		 * Try to build a command off the bio queue (ignore error
990 		 * return)
991 		 */
992 		if (cm == NULL)
993 			aac_bio_command(sc, &cm);
994 
995 		/* nothing to do? */
996 		if (cm == NULL)
997 			break;
998 
999 		/* don't map more than once */
1000 		if (cm->cm_flags & AAC_CMD_MAPPED)
1001 			panic("aac: command %p already mapped", cm);
1002 
1003 		/*
1004 		 * Set up the command to go to the controller.  If there are no
1005 		 * data buffers associated with the command then it can bypass
1006 		 * busdma.
1007 		 */
1008 		if (cm->cm_datalen != 0) {
1009 			error = bus_dmamap_load(sc->aac_buffer_dmat,
1010 						cm->cm_datamap, cm->cm_data,
1011 						cm->cm_datalen,
1012 						aac_map_command_sg, cm, 0);
1013 			if (error == EINPROGRESS) {
1014 				fwprintf(sc, HBA_FLAGS_DBG_COMM_B, "freezing queue\n");
1015 				sc->flags |= AAC_QUEUE_FRZN;
1016 				error = 0;
1017 			} else if (error != 0)
1018 				panic("aac_startio: unexpected error %d from "
1019 				      "busdma", error);
1020 		} else
1021 			aac_map_command_sg(cm, NULL, 0, 0);
1022 	}
1023 }
1024 
1025 /*
1026  * Handle notification of one or more FIBs coming from the controller.
1027  */
1028 static void
1029 aac_command_thread(struct aac_softc *sc)
1030 {
1031 	struct aac_fib *fib;
1032 	u_int32_t fib_size;
1033 	int size, retval;
1034 
1035 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1036 
1037 	mtx_lock(&sc->aac_io_lock);
1038 	sc->aifflags = AAC_AIFFLAGS_RUNNING;
1039 
1040 	while ((sc->aifflags & AAC_AIFFLAGS_EXIT) == 0) {
1041 
1042 		retval = 0;
1043 		if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0)
1044 			retval = msleep(sc->aifthread, &sc->aac_io_lock, PRIBIO,
1045 					"aifthd", AAC_PERIODIC_INTERVAL * hz);
1046 
1047 		/*
1048 		 * First see if any FIBs need to be allocated.  This needs
1049 		 * to be called without the driver lock because contigmalloc
1050 		 * will grab Giant, and would result in an LOR.
1051 		 */
1052 		if ((sc->aifflags & AAC_AIFFLAGS_ALLOCFIBS) != 0) {
1053 			mtx_unlock(&sc->aac_io_lock);
1054 			aac_alloc_commands(sc);
1055 			mtx_lock(&sc->aac_io_lock);
1056 			sc->aifflags &= ~AAC_AIFFLAGS_ALLOCFIBS;
1057 			aac_startio(sc);
1058 		}
1059 
1060 		/*
1061 		 * While we're here, check to see if any commands are stuck.
1062 		 * This is pretty low-priority, so it's ok if it doesn't
1063 		 * always fire.
1064 		 */
1065 		if (retval == EWOULDBLOCK)
1066 			aac_timeout(sc);
1067 
1068 		/* Check the hardware printf message buffer */
1069 		if (sc->aac_common->ac_printf[0] != 0)
1070 			aac_print_printf(sc);
1071 
1072 		/* Also check to see if the adapter has a command for us. */
1073 		if (sc->flags & AAC_FLAGS_NEW_COMM)
1074 			continue;
1075 		for (;;) {
1076 			if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE,
1077 					   &fib_size, &fib))
1078 				break;
1079 
1080 			AAC_PRINT_FIB(sc, fib);
1081 
1082 			switch (fib->Header.Command) {
1083 			case AifRequest:
1084 				aac_handle_aif(sc, fib);
1085 				break;
1086 			default:
1087 				device_printf(sc->aac_dev, "unknown command "
1088 					      "from controller\n");
1089 				break;
1090 			}
1091 
1092 			if ((fib->Header.XferState == 0) ||
1093 			    (fib->Header.StructType != AAC_FIBTYPE_TFIB)) {
1094 				break;
1095 			}
1096 
1097 			/* Return the AIF to the controller. */
1098 			if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) {
1099 				fib->Header.XferState |= AAC_FIBSTATE_DONEHOST;
1100 				*(AAC_FSAStatus*)fib->data = ST_OK;
1101 
1102 				/* XXX Compute the Size field? */
1103 				size = fib->Header.Size;
1104 				if (size > sizeof(struct aac_fib)) {
1105 					size = sizeof(struct aac_fib);
1106 					fib->Header.Size = size;
1107 				}
1108 				/*
1109 				 * Since we did not generate this command, it
1110 				 * cannot go through the normal
1111 				 * enqueue->startio chain.
1112 				 */
1113 				aac_enqueue_response(sc,
1114 						 AAC_ADAP_NORM_RESP_QUEUE,
1115 						 fib);
1116 			}
1117 		}
1118 	}
1119 	sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
1120 	mtx_unlock(&sc->aac_io_lock);
1121 	wakeup(sc->aac_dev);
1122 
1123 	kproc_exit(0);
1124 }
1125 
1126 /*
1127  * Process completed commands.
1128  */
1129 static void
1130 aac_complete(void *context, int pending)
1131 {
1132 	struct aac_softc *sc;
1133 	struct aac_command *cm;
1134 	struct aac_fib *fib;
1135 	u_int32_t fib_size;
1136 
1137 	sc = (struct aac_softc *)context;
1138 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1139 
1140 	mtx_lock(&sc->aac_io_lock);
1141 
1142 	/* pull completed commands off the queue */
1143 	for (;;) {
1144 		/* look for completed FIBs on our queue */
1145 		if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
1146 							&fib))
1147 			break;	/* nothing to do */
1148 
1149 		/* get the command, unmap and hand off for processing */
1150 		cm = sc->aac_commands + fib->Header.SenderData;
1151 		if (cm == NULL) {
1152 			AAC_PRINT_FIB(sc, fib);
1153 			break;
1154 		}
1155 		aac_remove_busy(cm);
1156 
1157  		aac_unmap_command(cm);
1158 		cm->cm_flags |= AAC_CMD_COMPLETED;
1159 
1160 		/* is there a completion handler? */
1161 		if (cm->cm_complete != NULL) {
1162 			cm->cm_complete(cm);
1163 		} else {
1164 			/* assume that someone is sleeping on this command */
1165 			wakeup(cm);
1166 		}
1167 	}
1168 
1169 	/* see if we can start some more I/O */
1170 	sc->flags &= ~AAC_QUEUE_FRZN;
1171 	aac_startio(sc);
1172 
1173 	mtx_unlock(&sc->aac_io_lock);
1174 }
1175 
1176 /*
1177  * Handle a bio submitted from a disk device.
1178  */
1179 void
1180 aac_submit_bio(struct bio *bp)
1181 {
1182 	struct aac_disk *ad;
1183 	struct aac_softc *sc;
1184 
1185 	ad = (struct aac_disk *)bp->bio_disk->d_drv1;
1186 	sc = ad->ad_controller;
1187 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1188 
1189 	/* queue the BIO and try to get some work done */
1190 	aac_enqueue_bio(sc, bp);
1191 	aac_startio(sc);
1192 }
1193 
1194 /*
1195  * Get a bio and build a command to go with it.
1196  */
1197 static int
1198 aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
1199 {
1200 	struct aac_command *cm;
1201 	struct aac_fib *fib;
1202 	struct aac_disk *ad;
1203 	struct bio *bp;
1204 
1205 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1206 
1207 	/* get the resources we will need */
1208 	cm = NULL;
1209 	bp = NULL;
1210 	if (aac_alloc_command(sc, &cm))	/* get a command */
1211 		goto fail;
1212 	if ((bp = aac_dequeue_bio(sc)) == NULL)
1213 		goto fail;
1214 
1215 	/* fill out the command */
1216 	cm->cm_data = (void *)bp->bio_data;
1217 	cm->cm_datalen = bp->bio_bcount;
1218 	cm->cm_complete = aac_bio_complete;
1219 	cm->cm_private = bp;
1220 	cm->cm_timestamp = time_uptime;
1221 	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
1222 
1223 	/* build the FIB */
1224 	fib = cm->cm_fib;
1225 	fib->Header.Size = sizeof(struct aac_fib_header);
1226 	fib->Header.XferState =
1227 		AAC_FIBSTATE_HOSTOWNED   |
1228 		AAC_FIBSTATE_INITIALISED |
1229 		AAC_FIBSTATE_EMPTY	 |
1230 		AAC_FIBSTATE_FROMHOST	 |
1231 		AAC_FIBSTATE_REXPECTED   |
1232 		AAC_FIBSTATE_NORM	 |
1233 		AAC_FIBSTATE_ASYNC	 |
1234 		AAC_FIBSTATE_FAST_RESPONSE;
1235 
1236 	/* build the read/write request */
1237 	ad = (struct aac_disk *)bp->bio_disk->d_drv1;
1238 
1239 	if (sc->flags & AAC_FLAGS_RAW_IO) {
1240 		struct aac_raw_io *raw;
1241 		raw = (struct aac_raw_io *)&fib->data[0];
1242 		fib->Header.Command = RawIo;
1243 		raw->BlockNumber = (u_int64_t)bp->bio_pblkno;
1244 		raw->ByteCount = bp->bio_bcount;
1245 		raw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1246 		raw->BpTotal = 0;
1247 		raw->BpComplete = 0;
1248 		fib->Header.Size += sizeof(struct aac_raw_io);
1249 		cm->cm_sgtable = (struct aac_sg_table *)&raw->SgMapRaw;
1250 		if (bp->bio_cmd == BIO_READ) {
1251 			raw->Flags = 1;
1252 			cm->cm_flags |= AAC_CMD_DATAIN;
1253 		} else {
1254 			raw->Flags = 0;
1255 			cm->cm_flags |= AAC_CMD_DATAOUT;
1256 		}
1257 	} else if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
1258 		fib->Header.Command = ContainerCommand;
1259 		if (bp->bio_cmd == BIO_READ) {
1260 			struct aac_blockread *br;
1261 			br = (struct aac_blockread *)&fib->data[0];
1262 			br->Command = VM_CtBlockRead;
1263 			br->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1264 			br->BlockNumber = bp->bio_pblkno;
1265 			br->ByteCount = bp->bio_bcount;
1266 			fib->Header.Size += sizeof(struct aac_blockread);
1267 			cm->cm_sgtable = &br->SgMap;
1268 			cm->cm_flags |= AAC_CMD_DATAIN;
1269 		} else {
1270 			struct aac_blockwrite *bw;
1271 			bw = (struct aac_blockwrite *)&fib->data[0];
1272 			bw->Command = VM_CtBlockWrite;
1273 			bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1274 			bw->BlockNumber = bp->bio_pblkno;
1275 			bw->ByteCount = bp->bio_bcount;
1276 			bw->Stable = CUNSTABLE;
1277 			fib->Header.Size += sizeof(struct aac_blockwrite);
1278 			cm->cm_flags |= AAC_CMD_DATAOUT;
1279 			cm->cm_sgtable = &bw->SgMap;
1280 		}
1281 	} else {
1282 		fib->Header.Command = ContainerCommand64;
1283 		if (bp->bio_cmd == BIO_READ) {
1284 			struct aac_blockread64 *br;
1285 			br = (struct aac_blockread64 *)&fib->data[0];
1286 			br->Command = VM_CtHostRead64;
1287 			br->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1288 			br->SectorCount = bp->bio_bcount / AAC_BLOCK_SIZE;
1289 			br->BlockNumber = bp->bio_pblkno;
1290 			br->Pad = 0;
1291 			br->Flags = 0;
1292 			fib->Header.Size += sizeof(struct aac_blockread64);
1293 			cm->cm_flags |= AAC_CMD_DATAIN;
1294 			cm->cm_sgtable = (struct aac_sg_table *)&br->SgMap64;
1295 		} else {
1296 			struct aac_blockwrite64 *bw;
1297 			bw = (struct aac_blockwrite64 *)&fib->data[0];
1298 			bw->Command = VM_CtHostWrite64;
1299 			bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1300 			bw->SectorCount = bp->bio_bcount / AAC_BLOCK_SIZE;
1301 			bw->BlockNumber = bp->bio_pblkno;
1302 			bw->Pad = 0;
1303 			bw->Flags = 0;
1304 			fib->Header.Size += sizeof(struct aac_blockwrite64);
1305 			cm->cm_flags |= AAC_CMD_DATAOUT;
1306 			cm->cm_sgtable = (struct aac_sg_table *)&bw->SgMap64;
1307 		}
1308 	}
1309 
1310 	*cmp = cm;
1311 	return(0);
1312 
1313 fail:
1314 	if (bp != NULL)
1315 		aac_enqueue_bio(sc, bp);
1316 	if (cm != NULL)
1317 		aac_release_command(cm);
1318 	return(ENOMEM);
1319 }
1320 
1321 /*
1322  * Handle a bio-instigated command that has been completed.
1323  */
1324 static void
1325 aac_bio_complete(struct aac_command *cm)
1326 {
1327 	struct aac_blockread_response *brr;
1328 	struct aac_blockwrite_response *bwr;
1329 	struct bio *bp;
1330 	AAC_FSAStatus status;
1331 
1332 	/* fetch relevant status and then release the command */
1333 	bp = (struct bio *)cm->cm_private;
1334 	if (bp->bio_cmd == BIO_READ) {
1335 		brr = (struct aac_blockread_response *)&cm->cm_fib->data[0];
1336 		status = brr->Status;
1337 	} else {
1338 		bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0];
1339 		status = bwr->Status;
1340 	}
1341 	aac_release_command(cm);
1342 
1343 	/* fix up the bio based on status */
1344 	if (status == ST_OK) {
1345 		bp->bio_resid = 0;
1346 	} else {
1347 		bp->bio_error = EIO;
1348 		bp->bio_flags |= BIO_ERROR;
1349 		/* pass an error string out to the disk layer */
1350 		bp->bio_driver1 = aac_describe_code(aac_command_status_table,
1351 						    status);
1352 	}
1353 	aac_biodone(bp);
1354 }
1355 
1356 /*
1357  * Submit a command to the controller, return when it completes.
1358  * XXX This is very dangerous!  If the card has gone out to lunch, we could
1359  *     be stuck here forever.  At the same time, signals are not caught
1360  *     because there is a risk that a signal could wakeup the sleep before
1361  *     the card has a chance to complete the command.  Since there is no way
1362  *     to cancel a command that is in progress, we can't protect against the
1363  *     card completing a command late and spamming the command and data
1364  *     memory.  So, we are held hostage until the command completes.
1365  */
1366 static int
1367 aac_wait_command(struct aac_command *cm)
1368 {
1369 	struct aac_softc *sc;
1370 	int error;
1371 
1372 	sc = cm->cm_sc;
1373 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1374 
1375 	/* Put the command on the ready queue and get things going */
1376 	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
1377 	aac_enqueue_ready(cm);
1378 	aac_startio(sc);
1379 	error = msleep(cm, &sc->aac_io_lock, PRIBIO, "aacwait", 0);
1380 	return(error);
1381 }
1382 
1383 /*
1384  *Command Buffer Management
1385  */
1386 
1387 /*
1388  * Allocate a command.
1389  */
1390 int
1391 aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
1392 {
1393 	struct aac_command *cm;
1394 
1395 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1396 
1397 	if ((cm = aac_dequeue_free(sc)) == NULL) {
1398 		if (sc->total_fibs < sc->aac_max_fibs) {
1399 			sc->aifflags |= AAC_AIFFLAGS_ALLOCFIBS;
1400 			wakeup(sc->aifthread);
1401 		}
1402 		return (EBUSY);
1403 	}
1404 
1405 	*cmp = cm;
1406 	return(0);
1407 }
1408 
1409 /*
1410  * Release a command back to the freelist.
1411  */
1412 void
1413 aac_release_command(struct aac_command *cm)
1414 {
1415 	struct aac_event *event;
1416 	struct aac_softc *sc;
1417 
1418 	sc = cm->cm_sc;
1419 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1420 
1421 	/* (re)initialize the command/FIB */
1422 	cm->cm_sgtable = NULL;
1423 	cm->cm_flags = 0;
1424 	cm->cm_complete = NULL;
1425 	cm->cm_private = NULL;
1426 	cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
1427 	cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
1428 	cm->cm_fib->Header.Flags = 0;
1429 	cm->cm_fib->Header.SenderSize = cm->cm_sc->aac_max_fib_size;
1430 
1431 	/*
1432 	 * These are duplicated in aac_start to cover the case where an
1433 	 * intermediate stage may have destroyed them.  They're left
1434 	 * initialized here for debugging purposes only.
1435 	 */
1436 	cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
1437 	cm->cm_fib->Header.SenderData = 0;
1438 
1439 	aac_enqueue_free(cm);
1440 
1441 	/*
1442 	 * Dequeue all events so that there's no risk of events getting
1443 	 * stranded.
1444 	 */
1445 	while ((event = TAILQ_FIRST(&sc->aac_ev_cmfree)) != NULL) {
1446 		TAILQ_REMOVE(&sc->aac_ev_cmfree, event, ev_links);
1447 		event->ev_callback(sc, event, event->ev_arg);
1448 	}
1449 }
1450 
1451 /*
1452  * Map helper for command/FIB allocation.
1453  */
1454 static void
1455 aac_map_command_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1456 {
1457 	uint64_t	*fibphys;
1458 
1459 	fibphys = (uint64_t *)arg;
1460 
1461 	*fibphys = segs[0].ds_addr;
1462 }
1463 
1464 /*
1465  * Allocate and initialize commands/FIBs for this adapter.
1466  */
1467 static int
1468 aac_alloc_commands(struct aac_softc *sc)
1469 {
1470 	struct aac_command *cm;
1471 	struct aac_fibmap *fm;
1472 	uint64_t fibphys;
1473 	int i, error;
1474 
1475 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1476 
1477 	if (sc->total_fibs + sc->aac_max_fibs_alloc > sc->aac_max_fibs)
1478 		return (ENOMEM);
1479 
1480 	fm = malloc(sizeof(struct aac_fibmap), M_AACBUF, M_NOWAIT|M_ZERO);
1481 	if (fm == NULL)
1482 		return (ENOMEM);
1483 
1484 	/* allocate the FIBs in DMAable memory and load them */
1485 	if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&fm->aac_fibs,
1486 			     BUS_DMA_NOWAIT, &fm->aac_fibmap)) {
1487 		device_printf(sc->aac_dev,
1488 			      "Not enough contiguous memory available.\n");
1489 		free(fm, M_AACBUF);
1490 		return (ENOMEM);
1491 	}
1492 
1493 	/* Ignore errors since this doesn't bounce */
1494 	(void)bus_dmamap_load(sc->aac_fib_dmat, fm->aac_fibmap, fm->aac_fibs,
1495 			      sc->aac_max_fibs_alloc * sc->aac_max_fib_size,
1496 			      aac_map_command_helper, &fibphys, 0);
1497 
1498 	/* initialize constant fields in the command structure */
1499 	bzero(fm->aac_fibs, sc->aac_max_fibs_alloc * sc->aac_max_fib_size);
1500 	for (i = 0; i < sc->aac_max_fibs_alloc; i++) {
1501 		cm = sc->aac_commands + sc->total_fibs;
1502 		fm->aac_commands = cm;
1503 		cm->cm_sc = sc;
1504 		cm->cm_fib = (struct aac_fib *)
1505 			((u_int8_t *)fm->aac_fibs + i*sc->aac_max_fib_size);
1506 		cm->cm_fibphys = fibphys + i*sc->aac_max_fib_size;
1507 		cm->cm_index = sc->total_fibs;
1508 
1509 		if ((error = bus_dmamap_create(sc->aac_buffer_dmat, 0,
1510 					       &cm->cm_datamap)) != 0)
1511 			break;
1512 		mtx_lock(&sc->aac_io_lock);
1513 		aac_release_command(cm);
1514 		sc->total_fibs++;
1515 		mtx_unlock(&sc->aac_io_lock);
1516 	}
1517 
1518 	if (i > 0) {
1519 		mtx_lock(&sc->aac_io_lock);
1520 		TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link);
1521 		fwprintf(sc, HBA_FLAGS_DBG_COMM_B, "total_fibs= %d\n", sc->total_fibs);
1522 		mtx_unlock(&sc->aac_io_lock);
1523 		return (0);
1524 	}
1525 
1526 	bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap);
1527 	bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap);
1528 	free(fm, M_AACBUF);
1529 	return (ENOMEM);
1530 }
1531 
1532 /*
1533  * Free FIBs owned by this adapter.
1534  */
1535 static void
1536 aac_free_commands(struct aac_softc *sc)
1537 {
1538 	struct aac_fibmap *fm;
1539 	struct aac_command *cm;
1540 	int i;
1541 
1542 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1543 
1544 	while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) {
1545 
1546 		TAILQ_REMOVE(&sc->aac_fibmap_tqh, fm, fm_link);
1547 		/*
1548 		 * We check against total_fibs to handle partially
1549 		 * allocated blocks.
1550 		 */
1551 		for (i = 0; i < sc->aac_max_fibs_alloc && sc->total_fibs--; i++) {
1552 			cm = fm->aac_commands + i;
1553 			bus_dmamap_destroy(sc->aac_buffer_dmat, cm->cm_datamap);
1554 		}
1555 		bus_dmamap_unload(sc->aac_fib_dmat, fm->aac_fibmap);
1556 		bus_dmamem_free(sc->aac_fib_dmat, fm->aac_fibs, fm->aac_fibmap);
1557 		free(fm, M_AACBUF);
1558 	}
1559 }
1560 
1561 /*
1562  * Command-mapping helper function - populate this command's s/g table.
1563  */
1564 static void
1565 aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1566 {
1567 	struct aac_softc *sc;
1568 	struct aac_command *cm;
1569 	struct aac_fib *fib;
1570 	int i;
1571 
1572 	cm = (struct aac_command *)arg;
1573 	sc = cm->cm_sc;
1574 	fib = cm->cm_fib;
1575 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1576 
1577 	/* copy into the FIB */
1578 	if (cm->cm_sgtable != NULL) {
1579 		if (fib->Header.Command == RawIo) {
1580 			struct aac_sg_tableraw *sg;
1581 			sg = (struct aac_sg_tableraw *)cm->cm_sgtable;
1582 			sg->SgCount = nseg;
1583 			for (i = 0; i < nseg; i++) {
1584 				sg->SgEntryRaw[i].SgAddress = segs[i].ds_addr;
1585 				sg->SgEntryRaw[i].SgByteCount = segs[i].ds_len;
1586 				sg->SgEntryRaw[i].Next = 0;
1587 				sg->SgEntryRaw[i].Prev = 0;
1588 				sg->SgEntryRaw[i].Flags = 0;
1589 			}
1590 			/* update the FIB size for the s/g count */
1591 			fib->Header.Size += nseg*sizeof(struct aac_sg_entryraw);
1592 		} else if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
1593 			struct aac_sg_table *sg;
1594 			sg = cm->cm_sgtable;
1595 			sg->SgCount = nseg;
1596 			for (i = 0; i < nseg; i++) {
1597 				sg->SgEntry[i].SgAddress = segs[i].ds_addr;
1598 				sg->SgEntry[i].SgByteCount = segs[i].ds_len;
1599 			}
1600 			/* update the FIB size for the s/g count */
1601 			fib->Header.Size += nseg*sizeof(struct aac_sg_entry);
1602 		} else {
1603 			struct aac_sg_table64 *sg;
1604 			sg = (struct aac_sg_table64 *)cm->cm_sgtable;
1605 			sg->SgCount = nseg;
1606 			for (i = 0; i < nseg; i++) {
1607 				sg->SgEntry64[i].SgAddress = segs[i].ds_addr;
1608 				sg->SgEntry64[i].SgByteCount = segs[i].ds_len;
1609 			}
1610 			/* update the FIB size for the s/g count */
1611 			fib->Header.Size += nseg*sizeof(struct aac_sg_entry64);
1612 		}
1613 	}
1614 
1615 	/* Fix up the address values in the FIB.  Use the command array index
1616 	 * instead of a pointer since these fields are only 32 bits.  Shift
1617 	 * the SenderFibAddress over to make room for the fast response bit
1618 	 * and for the AIF bit
1619 	 */
1620 	cm->cm_fib->Header.SenderFibAddress = (cm->cm_index << 2);
1621 	cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
1622 
1623 	/* save a pointer to the command for speedy reverse-lookup */
1624 	cm->cm_fib->Header.SenderData = cm->cm_index;
1625 
1626 	if (cm->cm_flags & AAC_CMD_DATAIN)
1627 		bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1628 				BUS_DMASYNC_PREREAD);
1629 	if (cm->cm_flags & AAC_CMD_DATAOUT)
1630 		bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1631 				BUS_DMASYNC_PREWRITE);
1632 	cm->cm_flags |= AAC_CMD_MAPPED;
1633 
1634 	if (sc->flags & AAC_FLAGS_NEW_COMM) {
1635 		int count = 10000000L;
1636 		while (AAC_SEND_COMMAND(sc, cm) != 0) {
1637 			if (--count == 0) {
1638 				aac_unmap_command(cm);
1639 				sc->flags |= AAC_QUEUE_FRZN;
1640 				aac_requeue_ready(cm);
1641 			}
1642 			DELAY(5);			/* wait 5 usec. */
1643 		}
1644 	} else {
1645 		/* Put the FIB on the outbound queue */
1646 		if (aac_enqueue_fib(sc, cm->cm_queue, cm) == EBUSY) {
1647 			aac_unmap_command(cm);
1648 			sc->flags |= AAC_QUEUE_FRZN;
1649 			aac_requeue_ready(cm);
1650 		}
1651 	}
1652 
1653 	return;
1654 }
1655 
1656 /*
1657  * Unmap a command from controller-visible space.
1658  */
1659 static void
1660 aac_unmap_command(struct aac_command *cm)
1661 {
1662 	struct aac_softc *sc;
1663 
1664 	sc = cm->cm_sc;
1665 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1666 
1667 	if (!(cm->cm_flags & AAC_CMD_MAPPED))
1668 		return;
1669 
1670 	if (cm->cm_datalen != 0) {
1671 		if (cm->cm_flags & AAC_CMD_DATAIN)
1672 			bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1673 					BUS_DMASYNC_POSTREAD);
1674 		if (cm->cm_flags & AAC_CMD_DATAOUT)
1675 			bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1676 					BUS_DMASYNC_POSTWRITE);
1677 
1678 		bus_dmamap_unload(sc->aac_buffer_dmat, cm->cm_datamap);
1679 	}
1680 	cm->cm_flags &= ~AAC_CMD_MAPPED;
1681 }
1682 
1683 /*
1684  * Hardware Interface
1685  */
1686 
1687 /*
1688  * Initialize the adapter.
1689  */
1690 static void
1691 aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1692 {
1693 	struct aac_softc *sc;
1694 
1695 	sc = (struct aac_softc *)arg;
1696 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1697 
1698 	sc->aac_common_busaddr = segs[0].ds_addr;
1699 }
1700 
1701 static int
1702 aac_check_firmware(struct aac_softc *sc)
1703 {
1704 	u_int32_t code, major, minor, options = 0, atu_size = 0;
1705 	int status;
1706 	time_t then;
1707 
1708 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1709 	/*
1710 	 * Wait for the adapter to come ready.
1711 	 */
1712 	then = time_uptime;
1713 	do {
1714 		code = AAC_GET_FWSTATUS(sc);
1715 		if (code & AAC_SELF_TEST_FAILED) {
1716 			device_printf(sc->aac_dev, "FATAL: selftest failed\n");
1717 			return(ENXIO);
1718 		}
1719 		if (code & AAC_KERNEL_PANIC) {
1720 			device_printf(sc->aac_dev,
1721 				      "FATAL: controller kernel panic");
1722 			return(ENXIO);
1723 		}
1724 		if (time_uptime > (then + AAC_BOOT_TIMEOUT)) {
1725 			device_printf(sc->aac_dev,
1726 				      "FATAL: controller not coming ready, "
1727 					   "status %x\n", code);
1728 			return(ENXIO);
1729 		}
1730 	} while (!(code & AAC_UP_AND_RUNNING));
1731 
1732 	/*
1733 	 * Retrieve the firmware version numbers.  Dell PERC2/QC cards with
1734 	 * firmware version 1.x are not compatible with this driver.
1735 	 */
1736 	if (sc->flags & AAC_FLAGS_PERC2QC) {
1737 		if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0,
1738 				     NULL)) {
1739 			device_printf(sc->aac_dev,
1740 				      "Error reading firmware version\n");
1741 			return (EIO);
1742 		}
1743 
1744 		/* These numbers are stored as ASCII! */
1745 		major = (AAC_GET_MAILBOX(sc, 1) & 0xff) - 0x30;
1746 		minor = (AAC_GET_MAILBOX(sc, 2) & 0xff) - 0x30;
1747 		if (major == 1) {
1748 			device_printf(sc->aac_dev,
1749 			    "Firmware version %d.%d is not supported.\n",
1750 			    major, minor);
1751 			return (EINVAL);
1752 		}
1753 	}
1754 
1755 	/*
1756 	 * Retrieve the capabilities/supported options word so we know what
1757 	 * work-arounds to enable.  Some firmware revs don't support this
1758 	 * command.
1759 	 */
1760 	if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, &status)) {
1761 		if (status != AAC_SRB_STS_INVALID_REQUEST) {
1762 			device_printf(sc->aac_dev,
1763 			     "RequestAdapterInfo failed\n");
1764 			return (EIO);
1765 		}
1766 	} else {
1767 		options = AAC_GET_MAILBOX(sc, 1);
1768 		atu_size = AAC_GET_MAILBOX(sc, 2);
1769 		sc->supported_options = options;
1770 
1771 		if ((options & AAC_SUPPORTED_4GB_WINDOW) != 0 &&
1772 		    (sc->flags & AAC_FLAGS_NO4GB) == 0)
1773 			sc->flags |= AAC_FLAGS_4GB_WINDOW;
1774 		if (options & AAC_SUPPORTED_NONDASD)
1775 			sc->flags |= AAC_FLAGS_ENABLE_CAM;
1776 		if ((options & AAC_SUPPORTED_SGMAP_HOST64) != 0
1777 		     && (sizeof(bus_addr_t) > 4)) {
1778 			device_printf(sc->aac_dev,
1779 			    "Enabling 64-bit address support\n");
1780 			sc->flags |= AAC_FLAGS_SG_64BIT;
1781 		}
1782 		if ((options & AAC_SUPPORTED_NEW_COMM)
1783 		 && sc->aac_if.aif_send_command)
1784 			sc->flags |= AAC_FLAGS_NEW_COMM;
1785 		if (options & AAC_SUPPORTED_64BIT_ARRAYSIZE)
1786 			sc->flags |= AAC_FLAGS_ARRAY_64BIT;
1787 	}
1788 
1789 	/* Check for broken hardware that does a lower number of commands */
1790 	sc->aac_max_fibs = (sc->flags & AAC_FLAGS_256FIBS ? 256:512);
1791 
1792 	/* Remap mem. resource, if required */
1793 	if ((sc->flags & AAC_FLAGS_NEW_COMM) &&
1794 		atu_size > rman_get_size(sc->aac_regs_res1)) {
1795 		bus_release_resource(
1796 			sc->aac_dev, SYS_RES_MEMORY,
1797 			sc->aac_regs_rid1, sc->aac_regs_res1);
1798 		sc->aac_regs_res1 = bus_alloc_resource(
1799 			sc->aac_dev, SYS_RES_MEMORY, &sc->aac_regs_rid1,
1800 			0ul, ~0ul, atu_size, RF_ACTIVE);
1801 		if (sc->aac_regs_res1 == NULL) {
1802 			sc->aac_regs_res1 = bus_alloc_resource_any(
1803 				sc->aac_dev, SYS_RES_MEMORY,
1804 				&sc->aac_regs_rid1, RF_ACTIVE);
1805 			if (sc->aac_regs_res1 == NULL) {
1806 				device_printf(sc->aac_dev,
1807 				    "couldn't allocate register window\n");
1808 				return (ENXIO);
1809 			}
1810 			sc->flags &= ~AAC_FLAGS_NEW_COMM;
1811 		}
1812 		sc->aac_btag1 = rman_get_bustag(sc->aac_regs_res1);
1813 		sc->aac_bhandle1 = rman_get_bushandle(sc->aac_regs_res1);
1814 
1815 		if (sc->aac_hwif == AAC_HWIF_NARK) {
1816 			sc->aac_regs_res0 = sc->aac_regs_res1;
1817 			sc->aac_regs_rid0 = sc->aac_regs_rid1;
1818 			sc->aac_btag0 = sc->aac_btag1;
1819 			sc->aac_bhandle0 = sc->aac_bhandle1;
1820 		}
1821 	}
1822 
1823 	/* Read preferred settings */
1824 	sc->aac_max_fib_size = sizeof(struct aac_fib);
1825 	sc->aac_max_sectors = 128;				/* 64KB */
1826 	if (sc->flags & AAC_FLAGS_SG_64BIT)
1827 		sc->aac_sg_tablesize = (AAC_FIB_DATASIZE
1828 		 - sizeof(struct aac_blockwrite64))
1829 		 / sizeof(struct aac_sg_entry64);
1830 	else
1831 		sc->aac_sg_tablesize = (AAC_FIB_DATASIZE
1832 		 - sizeof(struct aac_blockwrite))
1833 		 / sizeof(struct aac_sg_entry);
1834 
1835 	if (!aac_sync_command(sc, AAC_MONKER_GETCOMMPREF, 0, 0, 0, 0, NULL)) {
1836 		options = AAC_GET_MAILBOX(sc, 1);
1837 		sc->aac_max_fib_size = (options & 0xFFFF);
1838 		sc->aac_max_sectors = (options >> 16) << 1;
1839 		options = AAC_GET_MAILBOX(sc, 2);
1840 		sc->aac_sg_tablesize = (options >> 16);
1841 		options = AAC_GET_MAILBOX(sc, 3);
1842 		sc->aac_max_fibs = (options & 0xFFFF);
1843 	}
1844 	if (sc->aac_max_fib_size > PAGE_SIZE)
1845 		sc->aac_max_fib_size = PAGE_SIZE;
1846 	sc->aac_max_fibs_alloc = PAGE_SIZE / sc->aac_max_fib_size;
1847 
1848 	if (sc->aac_max_fib_size > sizeof(struct aac_fib)) {
1849 		sc->flags |= AAC_FLAGS_RAW_IO;
1850 		device_printf(sc->aac_dev, "Enable Raw I/O\n");
1851 	}
1852 	if ((sc->flags & AAC_FLAGS_RAW_IO) &&
1853 	    (sc->flags & AAC_FLAGS_ARRAY_64BIT)) {
1854 		sc->flags |= AAC_FLAGS_LBA_64BIT;
1855 		device_printf(sc->aac_dev, "Enable 64-bit array\n");
1856 	}
1857 
1858 	return (0);
1859 }
1860 
1861 static int
1862 aac_init(struct aac_softc *sc)
1863 {
1864 	struct aac_adapter_init	*ip;
1865 	u_int32_t qoffset;
1866 	int error;
1867 
1868 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
1869 
1870 	/*
1871 	 * Fill in the init structure.  This tells the adapter about the
1872 	 * physical location of various important shared data structures.
1873 	 */
1874 	ip = &sc->aac_common->ac_init;
1875 	ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
1876 	if (sc->aac_max_fib_size > sizeof(struct aac_fib)) {
1877 		ip->InitStructRevision = AAC_INIT_STRUCT_REVISION_4;
1878 		sc->flags |= AAC_FLAGS_RAW_IO;
1879 	}
1880 	ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION;
1881 
1882 	ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
1883 					 offsetof(struct aac_common, ac_fibs);
1884 	ip->AdapterFibsVirtualAddress = 0;
1885 	ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
1886 	ip->AdapterFibAlign = sizeof(struct aac_fib);
1887 
1888 	ip->PrintfBufferAddress = sc->aac_common_busaddr +
1889 				  offsetof(struct aac_common, ac_printf);
1890 	ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
1891 
1892 	/*
1893 	 * The adapter assumes that pages are 4K in size, except on some
1894  	 * broken firmware versions that do the page->byte conversion twice,
1895 	 * therefore 'assuming' that this value is in 16MB units (2^24).
1896 	 * Round up since the granularity is so high.
1897 	 */
1898 	ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE;
1899 	if (sc->flags & AAC_FLAGS_BROKEN_MEMMAP) {
1900 		ip->HostPhysMemPages =
1901 		    (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE;
1902 	}
1903 	ip->HostElapsedSeconds = time_uptime;	/* reset later if invalid */
1904 
1905 	ip->InitFlags = 0;
1906 	if (sc->flags & AAC_FLAGS_NEW_COMM) {
1907 		ip->InitFlags = INITFLAGS_NEW_COMM_SUPPORTED;
1908 		device_printf(sc->aac_dev, "New comm. interface enabled\n");
1909 	}
1910 
1911 	ip->MaxIoCommands = sc->aac_max_fibs;
1912 	ip->MaxIoSize = sc->aac_max_sectors << 9;
1913 	ip->MaxFibSize = sc->aac_max_fib_size;
1914 
1915 	/*
1916 	 * Initialize FIB queues.  Note that it appears that the layout of the
1917 	 * indexes and the segmentation of the entries may be mandated by the
1918 	 * adapter, which is only told about the base of the queue index fields.
1919 	 *
1920 	 * The initial values of the indices are assumed to inform the adapter
1921 	 * of the sizes of the respective queues, and theoretically it could
1922 	 * work out the entire layout of the queue structures from this.  We
1923 	 * take the easy route and just lay this area out like everyone else
1924 	 * does.
1925 	 *
1926 	 * The Linux driver uses a much more complex scheme whereby several
1927 	 * header records are kept for each queue.  We use a couple of generic
1928 	 * list manipulation functions which 'know' the size of each list by
1929 	 * virtue of a table.
1930 	 */
1931 	qoffset = offsetof(struct aac_common, ac_qbuf) + AAC_QUEUE_ALIGN;
1932 	qoffset &= ~(AAC_QUEUE_ALIGN - 1);
1933 	sc->aac_queues =
1934 	    (struct aac_queue_table *)((uintptr_t)sc->aac_common + qoffset);
1935 	ip->CommHeaderAddress = sc->aac_common_busaddr + qoffset;
1936 
1937 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1938 		AAC_HOST_NORM_CMD_ENTRIES;
1939 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1940 		AAC_HOST_NORM_CMD_ENTRIES;
1941 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1942 		AAC_HOST_HIGH_CMD_ENTRIES;
1943 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1944 		AAC_HOST_HIGH_CMD_ENTRIES;
1945 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1946 		AAC_ADAP_NORM_CMD_ENTRIES;
1947 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1948 		AAC_ADAP_NORM_CMD_ENTRIES;
1949 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1950 		AAC_ADAP_HIGH_CMD_ENTRIES;
1951 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1952 		AAC_ADAP_HIGH_CMD_ENTRIES;
1953 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1954 		AAC_HOST_NORM_RESP_ENTRIES;
1955 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1956 		AAC_HOST_NORM_RESP_ENTRIES;
1957 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1958 		AAC_HOST_HIGH_RESP_ENTRIES;
1959 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1960 		AAC_HOST_HIGH_RESP_ENTRIES;
1961 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1962 		AAC_ADAP_NORM_RESP_ENTRIES;
1963 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1964 		AAC_ADAP_NORM_RESP_ENTRIES;
1965 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1966 		AAC_ADAP_HIGH_RESP_ENTRIES;
1967 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1968 		AAC_ADAP_HIGH_RESP_ENTRIES;
1969 	sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] =
1970 		&sc->aac_queues->qt_HostNormCmdQueue[0];
1971 	sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
1972 		&sc->aac_queues->qt_HostHighCmdQueue[0];
1973 	sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
1974 		&sc->aac_queues->qt_AdapNormCmdQueue[0];
1975 	sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
1976 		&sc->aac_queues->qt_AdapHighCmdQueue[0];
1977 	sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] =
1978 		&sc->aac_queues->qt_HostNormRespQueue[0];
1979 	sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
1980 		&sc->aac_queues->qt_HostHighRespQueue[0];
1981 	sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
1982 		&sc->aac_queues->qt_AdapNormRespQueue[0];
1983 	sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
1984 		&sc->aac_queues->qt_AdapHighRespQueue[0];
1985 
1986 	/*
1987 	 * Do controller-type-specific initialisation
1988 	 */
1989 	switch (sc->aac_hwif) {
1990 	case AAC_HWIF_I960RX:
1991 		AAC_MEM0_SETREG4(sc, AAC_RX_ODBR, ~0);
1992 		break;
1993 	case AAC_HWIF_RKT:
1994 		AAC_MEM0_SETREG4(sc, AAC_RKT_ODBR, ~0);
1995 		break;
1996 	default:
1997 		break;
1998 	}
1999 
2000 	/*
2001 	 * Give the init structure to the controller.
2002 	 */
2003 	if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
2004 			     sc->aac_common_busaddr +
2005 			     offsetof(struct aac_common, ac_init), 0, 0, 0,
2006 			     NULL)) {
2007 		device_printf(sc->aac_dev,
2008 			      "error establishing init structure\n");
2009 		error = EIO;
2010 		goto out;
2011 	}
2012 
2013 	error = 0;
2014 out:
2015 	return(error);
2016 }
2017 
2018 static int
2019 aac_setup_intr(struct aac_softc *sc)
2020 {
2021 	sc->aac_irq_rid = 0;
2022 	if ((sc->aac_irq = bus_alloc_resource_any(sc->aac_dev, SYS_RES_IRQ,
2023 			   			  &sc->aac_irq_rid,
2024 			   			  RF_SHAREABLE |
2025 						  RF_ACTIVE)) == NULL) {
2026 		device_printf(sc->aac_dev, "can't allocate interrupt\n");
2027 		return (EINVAL);
2028 	}
2029 	if (sc->flags & AAC_FLAGS_NEW_COMM) {
2030 		if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
2031 				   INTR_MPSAFE|INTR_TYPE_BIO, NULL,
2032 				   aac_new_intr, sc, &sc->aac_intr)) {
2033 			device_printf(sc->aac_dev, "can't set up interrupt\n");
2034 			return (EINVAL);
2035 		}
2036 	} else {
2037 		if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
2038 				   INTR_TYPE_BIO, aac_filter, NULL,
2039 				   sc, &sc->aac_intr)) {
2040 			device_printf(sc->aac_dev,
2041 				      "can't set up interrupt filter\n");
2042 			return (EINVAL);
2043 		}
2044 	}
2045 	return (0);
2046 }
2047 
2048 /*
2049  * Send a synchronous command to the controller and wait for a result.
2050  * Indicate if the controller completed the command with an error status.
2051  */
2052 static int
2053 aac_sync_command(struct aac_softc *sc, u_int32_t command,
2054 		 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3,
2055 		 u_int32_t *sp)
2056 {
2057 	time_t then;
2058 	u_int32_t status;
2059 
2060 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2061 
2062 	/* populate the mailbox */
2063 	AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
2064 
2065 	/* ensure the sync command doorbell flag is cleared */
2066 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
2067 
2068 	/* then set it to signal the adapter */
2069 	AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
2070 
2071 	/* spin waiting for the command to complete */
2072 	then = time_uptime;
2073 	do {
2074 		if (time_uptime > (then + AAC_IMMEDIATE_TIMEOUT)) {
2075 			fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "timed out");
2076 			return(EIO);
2077 		}
2078 	} while (!(AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND));
2079 
2080 	/* clear the completion flag */
2081 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
2082 
2083 	/* get the command status */
2084 	status = AAC_GET_MAILBOX(sc, 0);
2085 	if (sp != NULL)
2086 		*sp = status;
2087 
2088 	if (status != AAC_SRB_STS_SUCCESS)
2089 		return (-1);
2090 	return(0);
2091 }
2092 
2093 int
2094 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
2095 		 struct aac_fib *fib, u_int16_t datasize)
2096 {
2097 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2098 	mtx_assert(&sc->aac_io_lock, MA_OWNED);
2099 
2100 	if (datasize > AAC_FIB_DATASIZE)
2101 		return(EINVAL);
2102 
2103 	/*
2104 	 * Set up the sync FIB
2105 	 */
2106 	fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED |
2107 				AAC_FIBSTATE_INITIALISED |
2108 				AAC_FIBSTATE_EMPTY;
2109 	fib->Header.XferState |= xferstate;
2110 	fib->Header.Command = command;
2111 	fib->Header.StructType = AAC_FIBTYPE_TFIB;
2112 	fib->Header.Size = sizeof(struct aac_fib_header) + datasize;
2113 	fib->Header.SenderSize = sizeof(struct aac_fib);
2114 	fib->Header.SenderFibAddress = 0;	/* Not needed */
2115 	fib->Header.ReceiverFibAddress = sc->aac_common_busaddr +
2116 					 offsetof(struct aac_common,
2117 						  ac_sync_fib);
2118 
2119 	/*
2120 	 * Give the FIB to the controller, wait for a response.
2121 	 */
2122 	if (aac_sync_command(sc, AAC_MONKER_SYNCFIB,
2123 			     fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) {
2124 		fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "IO error");
2125 		return(EIO);
2126 	}
2127 
2128 	return (0);
2129 }
2130 
2131 /*
2132  * Adapter-space FIB queue manipulation
2133  *
2134  * Note that the queue implementation here is a little funky; neither the PI or
2135  * CI will ever be zero.  This behaviour is a controller feature.
2136  */
2137 static struct {
2138 	int		size;
2139 	int		notify;
2140 } aac_qinfo[] = {
2141 	{AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL},
2142 	{AAC_HOST_HIGH_CMD_ENTRIES, 0},
2143 	{AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY},
2144 	{AAC_ADAP_HIGH_CMD_ENTRIES, 0},
2145 	{AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL},
2146 	{AAC_HOST_HIGH_RESP_ENTRIES, 0},
2147 	{AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY},
2148 	{AAC_ADAP_HIGH_RESP_ENTRIES, 0}
2149 };
2150 
2151 /*
2152  * Atomically insert an entry into the nominated queue, returns 0 on success or
2153  * EBUSY if the queue is full.
2154  *
2155  * Note: it would be more efficient to defer notifying the controller in
2156  *	 the case where we may be inserting several entries in rapid succession,
2157  *	 but implementing this usefully may be difficult (it would involve a
2158  *	 separate queue/notify interface).
2159  */
2160 static int
2161 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm)
2162 {
2163 	u_int32_t pi, ci;
2164 	int error;
2165 	u_int32_t fib_size;
2166 	u_int32_t fib_addr;
2167 
2168 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2169 
2170 	fib_size = cm->cm_fib->Header.Size;
2171 	fib_addr = cm->cm_fib->Header.ReceiverFibAddress;
2172 
2173 	/* get the producer/consumer indices */
2174 	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
2175 	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
2176 
2177 	/* wrap the queue? */
2178 	if (pi >= aac_qinfo[queue].size)
2179 		pi = 0;
2180 
2181 	/* check for queue full */
2182 	if ((pi + 1) == ci) {
2183 		error = EBUSY;
2184 		goto out;
2185 	}
2186 
2187 	/*
2188 	 * To avoid a race with its completion interrupt, place this command on
2189 	 * the busy queue prior to advertising it to the controller.
2190 	 */
2191 	aac_enqueue_busy(cm);
2192 
2193 	/* populate queue entry */
2194 	(sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
2195 	(sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
2196 
2197 	/* update producer index */
2198 	sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
2199 
2200 	/* notify the adapter if we know how */
2201 	if (aac_qinfo[queue].notify != 0)
2202 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
2203 
2204 	error = 0;
2205 
2206 out:
2207 	return(error);
2208 }
2209 
2210 /*
2211  * Atomically remove one entry from the nominated queue, returns 0 on
2212  * success or ENOENT if the queue is empty.
2213  */
2214 static int
2215 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
2216 		struct aac_fib **fib_addr)
2217 {
2218 	u_int32_t pi, ci;
2219 	u_int32_t fib_index;
2220 	int error;
2221 	int notify;
2222 
2223 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2224 
2225 	/* get the producer/consumer indices */
2226 	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
2227 	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
2228 
2229 	/* check for queue empty */
2230 	if (ci == pi) {
2231 		error = ENOENT;
2232 		goto out;
2233 	}
2234 
2235 	/* wrap the pi so the following test works */
2236 	if (pi >= aac_qinfo[queue].size)
2237 		pi = 0;
2238 
2239 	notify = 0;
2240 	if (ci == pi + 1)
2241 		notify++;
2242 
2243 	/* wrap the queue? */
2244 	if (ci >= aac_qinfo[queue].size)
2245 		ci = 0;
2246 
2247 	/* fetch the entry */
2248 	*fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size;
2249 
2250 	switch (queue) {
2251 	case AAC_HOST_NORM_CMD_QUEUE:
2252 	case AAC_HOST_HIGH_CMD_QUEUE:
2253 		/*
2254 		 * The aq_fib_addr is only 32 bits wide so it can't be counted
2255 		 * on to hold an address.  For AIF's, the adapter assumes
2256 		 * that it's giving us an address into the array of AIF fibs.
2257 		 * Therefore, we have to convert it to an index.
2258 		 */
2259 		fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr /
2260 			sizeof(struct aac_fib);
2261 		*fib_addr = &sc->aac_common->ac_fibs[fib_index];
2262 		break;
2263 
2264 	case AAC_HOST_NORM_RESP_QUEUE:
2265 	case AAC_HOST_HIGH_RESP_QUEUE:
2266 	{
2267 		struct aac_command *cm;
2268 
2269 		/*
2270 		 * As above, an index is used instead of an actual address.
2271 		 * Gotta shift the index to account for the fast response
2272 		 * bit.  No other correction is needed since this value was
2273 		 * originally provided by the driver via the SenderFibAddress
2274 		 * field.
2275 		 */
2276 		fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr;
2277 		cm = sc->aac_commands + (fib_index >> 2);
2278 		*fib_addr = cm->cm_fib;
2279 
2280 		/*
2281 		 * Is this a fast response? If it is, update the fib fields in
2282 		 * local memory since the whole fib isn't DMA'd back up.
2283 		 */
2284 		if (fib_index & 0x01) {
2285 			(*fib_addr)->Header.XferState |= AAC_FIBSTATE_DONEADAP;
2286 			*((u_int32_t*)((*fib_addr)->data)) = AAC_ERROR_NORMAL;
2287 		}
2288 		break;
2289 	}
2290 	default:
2291 		panic("Invalid queue in aac_dequeue_fib()");
2292 		break;
2293 	}
2294 
2295 	/* update consumer index */
2296 	sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
2297 
2298 	/* if we have made the queue un-full, notify the adapter */
2299 	if (notify && (aac_qinfo[queue].notify != 0))
2300 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
2301 	error = 0;
2302 
2303 out:
2304 	return(error);
2305 }
2306 
2307 /*
2308  * Put our response to an Adapter Initialed Fib on the response queue
2309  */
2310 static int
2311 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
2312 {
2313 	u_int32_t pi, ci;
2314 	int error;
2315 	u_int32_t fib_size;
2316 	u_int32_t fib_addr;
2317 
2318 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2319 
2320 	/* Tell the adapter where the FIB is */
2321 	fib_size = fib->Header.Size;
2322 	fib_addr = fib->Header.SenderFibAddress;
2323 	fib->Header.ReceiverFibAddress = fib_addr;
2324 
2325 	/* get the producer/consumer indices */
2326 	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
2327 	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
2328 
2329 	/* wrap the queue? */
2330 	if (pi >= aac_qinfo[queue].size)
2331 		pi = 0;
2332 
2333 	/* check for queue full */
2334 	if ((pi + 1) == ci) {
2335 		error = EBUSY;
2336 		goto out;
2337 	}
2338 
2339 	/* populate queue entry */
2340 	(sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
2341 	(sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
2342 
2343 	/* update producer index */
2344 	sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
2345 
2346 	/* notify the adapter if we know how */
2347 	if (aac_qinfo[queue].notify != 0)
2348 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
2349 
2350 	error = 0;
2351 
2352 out:
2353 	return(error);
2354 }
2355 
2356 /*
2357  * Check for commands that have been outstanding for a suspiciously long time,
2358  * and complain about them.
2359  */
2360 static void
2361 aac_timeout(struct aac_softc *sc)
2362 {
2363 	struct aac_command *cm;
2364 	time_t deadline;
2365 	int timedout, code;
2366 
2367 	/*
2368 	 * Traverse the busy command list, bitch about late commands once
2369 	 * only.
2370 	 */
2371 	timedout = 0;
2372 	deadline = time_uptime - AAC_CMD_TIMEOUT;
2373 	TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) {
2374 		if ((cm->cm_timestamp  < deadline)
2375 			/* && !(cm->cm_flags & AAC_CMD_TIMEDOUT) */) {
2376 			cm->cm_flags |= AAC_CMD_TIMEDOUT;
2377 			device_printf(sc->aac_dev,
2378 				      "COMMAND %p TIMEOUT AFTER %d SECONDS\n",
2379 				      cm, (int)(time_uptime-cm->cm_timestamp));
2380 			AAC_PRINT_FIB(sc, cm->cm_fib);
2381 			timedout++;
2382 		}
2383 	}
2384 
2385 	if (timedout) {
2386 		code = AAC_GET_FWSTATUS(sc);
2387 		if (code != AAC_UP_AND_RUNNING) {
2388 			device_printf(sc->aac_dev, "WARNING! Controller is no "
2389 				      "longer running! code= 0x%x\n", code);
2390 		}
2391 	}
2392 	return;
2393 }
2394 
2395 /*
2396  * Interface Function Vectors
2397  */
2398 
2399 /*
2400  * Read the current firmware status word.
2401  */
2402 static int
2403 aac_sa_get_fwstatus(struct aac_softc *sc)
2404 {
2405 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2406 
2407 	return(AAC_MEM0_GETREG4(sc, AAC_SA_FWSTATUS));
2408 }
2409 
2410 static int
2411 aac_rx_get_fwstatus(struct aac_softc *sc)
2412 {
2413 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2414 
2415 	return(AAC_MEM0_GETREG4(sc, sc->flags & AAC_FLAGS_NEW_COMM ?
2416 	    AAC_RX_OMR0 : AAC_RX_FWSTATUS));
2417 }
2418 
2419 static int
2420 aac_fa_get_fwstatus(struct aac_softc *sc)
2421 {
2422 	int val;
2423 
2424 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2425 
2426 	val = AAC_MEM0_GETREG4(sc, AAC_FA_FWSTATUS);
2427 	return (val);
2428 }
2429 
2430 static int
2431 aac_rkt_get_fwstatus(struct aac_softc *sc)
2432 {
2433 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2434 
2435 	return(AAC_MEM0_GETREG4(sc, sc->flags & AAC_FLAGS_NEW_COMM ?
2436 	    AAC_RKT_OMR0 : AAC_RKT_FWSTATUS));
2437 }
2438 
2439 /*
2440  * Notify the controller of a change in a given queue
2441  */
2442 
2443 static void
2444 aac_sa_qnotify(struct aac_softc *sc, int qbit)
2445 {
2446 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2447 
2448 	AAC_MEM0_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
2449 }
2450 
2451 static void
2452 aac_rx_qnotify(struct aac_softc *sc, int qbit)
2453 {
2454 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2455 
2456 	AAC_MEM0_SETREG4(sc, AAC_RX_IDBR, qbit);
2457 }
2458 
2459 static void
2460 aac_fa_qnotify(struct aac_softc *sc, int qbit)
2461 {
2462 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2463 
2464 	AAC_MEM0_SETREG2(sc, AAC_FA_DOORBELL1, qbit);
2465 	AAC_FA_HACK(sc);
2466 }
2467 
2468 static void
2469 aac_rkt_qnotify(struct aac_softc *sc, int qbit)
2470 {
2471 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2472 
2473 	AAC_MEM0_SETREG4(sc, AAC_RKT_IDBR, qbit);
2474 }
2475 
2476 /*
2477  * Get the interrupt reason bits
2478  */
2479 static int
2480 aac_sa_get_istatus(struct aac_softc *sc)
2481 {
2482 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2483 
2484 	return(AAC_MEM0_GETREG2(sc, AAC_SA_DOORBELL0));
2485 }
2486 
2487 static int
2488 aac_rx_get_istatus(struct aac_softc *sc)
2489 {
2490 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2491 
2492 	return(AAC_MEM0_GETREG4(sc, AAC_RX_ODBR));
2493 }
2494 
2495 static int
2496 aac_fa_get_istatus(struct aac_softc *sc)
2497 {
2498 	int val;
2499 
2500 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2501 
2502 	val = AAC_MEM0_GETREG2(sc, AAC_FA_DOORBELL0);
2503 	return (val);
2504 }
2505 
2506 static int
2507 aac_rkt_get_istatus(struct aac_softc *sc)
2508 {
2509 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2510 
2511 	return(AAC_MEM0_GETREG4(sc, AAC_RKT_ODBR));
2512 }
2513 
2514 /*
2515  * Clear some interrupt reason bits
2516  */
2517 static void
2518 aac_sa_clear_istatus(struct aac_softc *sc, int mask)
2519 {
2520 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2521 
2522 	AAC_MEM0_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
2523 }
2524 
2525 static void
2526 aac_rx_clear_istatus(struct aac_softc *sc, int mask)
2527 {
2528 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2529 
2530 	AAC_MEM0_SETREG4(sc, AAC_RX_ODBR, mask);
2531 }
2532 
2533 static void
2534 aac_fa_clear_istatus(struct aac_softc *sc, int mask)
2535 {
2536 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2537 
2538 	AAC_MEM0_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask);
2539 	AAC_FA_HACK(sc);
2540 }
2541 
2542 static void
2543 aac_rkt_clear_istatus(struct aac_softc *sc, int mask)
2544 {
2545 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2546 
2547 	AAC_MEM0_SETREG4(sc, AAC_RKT_ODBR, mask);
2548 }
2549 
2550 /*
2551  * Populate the mailbox and set the command word
2552  */
2553 static void
2554 aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
2555 		u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2556 {
2557 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2558 
2559 	AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX, command);
2560 	AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
2561 	AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
2562 	AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
2563 	AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
2564 }
2565 
2566 static void
2567 aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
2568 		u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2569 {
2570 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2571 
2572 	AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX, command);
2573 	AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
2574 	AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
2575 	AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
2576 	AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
2577 }
2578 
2579 static void
2580 aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command,
2581 		u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2582 {
2583 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2584 
2585 	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX, command);
2586 	AAC_FA_HACK(sc);
2587 	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0);
2588 	AAC_FA_HACK(sc);
2589 	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1);
2590 	AAC_FA_HACK(sc);
2591 	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2);
2592 	AAC_FA_HACK(sc);
2593 	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3);
2594 	AAC_FA_HACK(sc);
2595 }
2596 
2597 static void
2598 aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
2599 		    u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
2600 {
2601 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2602 
2603 	AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX, command);
2604 	AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0);
2605 	AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1);
2606 	AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2);
2607 	AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3);
2608 }
2609 
2610 /*
2611  * Fetch the immediate command status word
2612  */
2613 static int
2614 aac_sa_get_mailbox(struct aac_softc *sc, int mb)
2615 {
2616 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2617 
2618 	return(AAC_MEM1_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4)));
2619 }
2620 
2621 static int
2622 aac_rx_get_mailbox(struct aac_softc *sc, int mb)
2623 {
2624 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2625 
2626 	return(AAC_MEM1_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
2627 }
2628 
2629 static int
2630 aac_fa_get_mailbox(struct aac_softc *sc, int mb)
2631 {
2632 	int val;
2633 
2634 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2635 
2636 	val = AAC_MEM1_GETREG4(sc, AAC_FA_MAILBOX + (mb * 4));
2637 	return (val);
2638 }
2639 
2640 static int
2641 aac_rkt_get_mailbox(struct aac_softc *sc, int mb)
2642 {
2643 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2644 
2645 	return(AAC_MEM1_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4)));
2646 }
2647 
2648 /*
2649  * Set/clear interrupt masks
2650  */
2651 static void
2652 aac_sa_set_interrupts(struct aac_softc *sc, int enable)
2653 {
2654 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
2655 
2656 	if (enable) {
2657 		AAC_MEM0_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2658 	} else {
2659 		AAC_MEM0_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
2660 	}
2661 }
2662 
2663 static void
2664 aac_rx_set_interrupts(struct aac_softc *sc, int enable)
2665 {
2666 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
2667 
2668 	if (enable) {
2669 		if (sc->flags & AAC_FLAGS_NEW_COMM)
2670 			AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INT_NEW_COMM);
2671 		else
2672 			AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
2673 	} else {
2674 		AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~0);
2675 	}
2676 }
2677 
2678 static void
2679 aac_fa_set_interrupts(struct aac_softc *sc, int enable)
2680 {
2681 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
2682 
2683 	if (enable) {
2684 		AAC_MEM0_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
2685 		AAC_FA_HACK(sc);
2686 	} else {
2687 		AAC_MEM0_SETREG2((sc), AAC_FA_MASK0, ~0);
2688 		AAC_FA_HACK(sc);
2689 	}
2690 }
2691 
2692 static void
2693 aac_rkt_set_interrupts(struct aac_softc *sc, int enable)
2694 {
2695 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
2696 
2697 	if (enable) {
2698 		if (sc->flags & AAC_FLAGS_NEW_COMM)
2699 			AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INT_NEW_COMM);
2700 		else
2701 			AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
2702 	} else {
2703 		AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~0);
2704 	}
2705 }
2706 
2707 /*
2708  * New comm. interface: Send command functions
2709  */
2710 static int
2711 aac_rx_send_command(struct aac_softc *sc, struct aac_command *cm)
2712 {
2713 	u_int32_t index, device;
2714 
2715 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm.)");
2716 
2717 	index = AAC_MEM0_GETREG4(sc, AAC_RX_IQUE);
2718 	if (index == 0xffffffffL)
2719 		index = AAC_MEM0_GETREG4(sc, AAC_RX_IQUE);
2720 	if (index == 0xffffffffL)
2721 		return index;
2722 	aac_enqueue_busy(cm);
2723 	device = index;
2724 	AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
2725 	device += 4;
2726 	AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
2727 	device += 4;
2728 	AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size);
2729 	AAC_MEM0_SETREG4(sc, AAC_RX_IQUE, index);
2730 	return 0;
2731 }
2732 
2733 static int
2734 aac_rkt_send_command(struct aac_softc *sc, struct aac_command *cm)
2735 {
2736 	u_int32_t index, device;
2737 
2738 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm.)");
2739 
2740 	index = AAC_MEM0_GETREG4(sc, AAC_RKT_IQUE);
2741 	if (index == 0xffffffffL)
2742 		index = AAC_MEM0_GETREG4(sc, AAC_RKT_IQUE);
2743 	if (index == 0xffffffffL)
2744 		return index;
2745 	aac_enqueue_busy(cm);
2746 	device = index;
2747 	AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
2748 	device += 4;
2749 	AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
2750 	device += 4;
2751 	AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size);
2752 	AAC_MEM0_SETREG4(sc, AAC_RKT_IQUE, index);
2753 	return 0;
2754 }
2755 
2756 /*
2757  * New comm. interface: get, set outbound queue index
2758  */
2759 static int
2760 aac_rx_get_outb_queue(struct aac_softc *sc)
2761 {
2762 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2763 
2764 	return(AAC_MEM0_GETREG4(sc, AAC_RX_OQUE));
2765 }
2766 
2767 static int
2768 aac_rkt_get_outb_queue(struct aac_softc *sc)
2769 {
2770 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2771 
2772 	return(AAC_MEM0_GETREG4(sc, AAC_RKT_OQUE));
2773 }
2774 
2775 static void
2776 aac_rx_set_outb_queue(struct aac_softc *sc, int index)
2777 {
2778 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2779 
2780 	AAC_MEM0_SETREG4(sc, AAC_RX_OQUE, index);
2781 }
2782 
2783 static void
2784 aac_rkt_set_outb_queue(struct aac_softc *sc, int index)
2785 {
2786 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2787 
2788 	AAC_MEM0_SETREG4(sc, AAC_RKT_OQUE, index);
2789 }
2790 
2791 /*
2792  * Debugging and Diagnostics
2793  */
2794 
2795 /*
2796  * Print some information about the controller.
2797  */
2798 static void
2799 aac_describe_controller(struct aac_softc *sc)
2800 {
2801 	struct aac_fib *fib;
2802 	struct aac_adapter_info	*info;
2803 	char *adapter_type = "Adaptec RAID controller";
2804 
2805 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2806 
2807 	mtx_lock(&sc->aac_io_lock);
2808 	aac_alloc_sync_fib(sc, &fib);
2809 
2810 	fib->data[0] = 0;
2811 	if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) {
2812 		device_printf(sc->aac_dev, "RequestAdapterInfo failed\n");
2813 		aac_release_sync_fib(sc);
2814 		mtx_unlock(&sc->aac_io_lock);
2815 		return;
2816 	}
2817 
2818 	/* save the kernel revision structure for later use */
2819 	info = (struct aac_adapter_info *)&fib->data[0];
2820 	sc->aac_revision = info->KernelRevision;
2821 
2822 	if (bootverbose) {
2823 		device_printf(sc->aac_dev, "%s %dMHz, %dMB memory "
2824 		    "(%dMB cache, %dMB execution), %s\n",
2825 		    aac_describe_code(aac_cpu_variant, info->CpuVariant),
2826 		    info->ClockSpeed, info->TotalMem / (1024 * 1024),
2827 		    info->BufferMem / (1024 * 1024),
2828 		    info->ExecutionMem / (1024 * 1024),
2829 		    aac_describe_code(aac_battery_platform,
2830 		    info->batteryPlatform));
2831 
2832 		device_printf(sc->aac_dev,
2833 		    "Kernel %d.%d-%d, Build %d, S/N %6X\n",
2834 		    info->KernelRevision.external.comp.major,
2835 		    info->KernelRevision.external.comp.minor,
2836 		    info->KernelRevision.external.comp.dash,
2837 		    info->KernelRevision.buildNumber,
2838 		    (u_int32_t)(info->SerialNumber & 0xffffff));
2839 
2840 		device_printf(sc->aac_dev, "Supported Options=%b\n",
2841 			      sc->supported_options,
2842 			      "\20"
2843 			      "\1SNAPSHOT"
2844 			      "\2CLUSTERS"
2845 			      "\3WCACHE"
2846 			      "\4DATA64"
2847 			      "\5HOSTTIME"
2848 			      "\6RAID50"
2849 			      "\7WINDOW4GB"
2850 			      "\10SCSIUPGD"
2851 			      "\11SOFTERR"
2852 			      "\12NORECOND"
2853 			      "\13SGMAP64"
2854 			      "\14ALARM"
2855 			      "\15NONDASD"
2856 			      "\16SCSIMGT"
2857 			      "\17RAIDSCSI"
2858 			      "\21ADPTINFO"
2859 			      "\22NEWCOMM"
2860 			      "\23ARRAY64BIT"
2861 			      "\24HEATSENSOR");
2862 	}
2863 
2864 	if (sc->supported_options & AAC_SUPPORTED_SUPPLEMENT_ADAPTER_INFO) {
2865 		fib->data[0] = 0;
2866 		if (aac_sync_fib(sc, RequestSupplementAdapterInfo, 0, fib, 1))
2867 			device_printf(sc->aac_dev,
2868 			    "RequestSupplementAdapterInfo failed\n");
2869 		else
2870 			adapter_type = ((struct aac_supplement_adapter_info *)
2871 			    &fib->data[0])->AdapterTypeText;
2872 	}
2873 	device_printf(sc->aac_dev, "%s, aac driver %d.%d.%d-%d\n",
2874 		adapter_type,
2875 		AAC_DRIVER_VERSION >> 24,
2876 		(AAC_DRIVER_VERSION >> 16) & 0xFF,
2877 		AAC_DRIVER_VERSION & 0xFF,
2878 		AAC_DRIVER_BUILD);
2879 
2880 	aac_release_sync_fib(sc);
2881 	mtx_unlock(&sc->aac_io_lock);
2882 }
2883 
2884 /*
2885  * Look up a text description of a numeric error code and return a pointer to
2886  * same.
2887  */
2888 static char *
2889 aac_describe_code(struct aac_code_lookup *table, u_int32_t code)
2890 {
2891 	int i;
2892 
2893 	for (i = 0; table[i].string != NULL; i++)
2894 		if (table[i].code == code)
2895 			return(table[i].string);
2896 	return(table[i + 1].string);
2897 }
2898 
2899 /*
2900  * Management Interface
2901  */
2902 
2903 static int
2904 aac_open(struct cdev *dev, int flags, int fmt, struct thread *td)
2905 {
2906 	struct aac_softc *sc;
2907 
2908 	sc = dev->si_drv1;
2909 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2910 	sc->aac_open_cnt++;
2911 	sc->aac_state |= AAC_STATE_OPEN;
2912 
2913 	return 0;
2914 }
2915 
2916 static int
2917 aac_close(struct cdev *dev, int flags, int fmt, struct thread *td)
2918 {
2919 	struct aac_softc *sc;
2920 
2921 	sc = dev->si_drv1;
2922 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2923 	sc->aac_open_cnt--;
2924 	/* Mark this unit as no longer open  */
2925 	if (sc->aac_open_cnt == 0)
2926 		sc->aac_state &= ~AAC_STATE_OPEN;
2927 
2928 	return 0;
2929 }
2930 
2931 static int
2932 aac_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, struct thread *td)
2933 {
2934 	union aac_statrequest *as;
2935 	struct aac_softc *sc;
2936 	int error = 0;
2937 
2938 	as = (union aac_statrequest *)arg;
2939 	sc = dev->si_drv1;
2940 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
2941 
2942 	switch (cmd) {
2943 	case AACIO_STATS:
2944 		switch (as->as_item) {
2945 		case AACQ_FREE:
2946 		case AACQ_BIO:
2947 		case AACQ_READY:
2948 		case AACQ_BUSY:
2949 			bcopy(&sc->aac_qstat[as->as_item], &as->as_qstat,
2950 			      sizeof(struct aac_qstat));
2951 			break;
2952 		default:
2953 			error = ENOENT;
2954 			break;
2955 		}
2956 	break;
2957 
2958 	case FSACTL_SENDFIB:
2959 	case FSACTL_SEND_LARGE_FIB:
2960 		arg = *(caddr_t*)arg;
2961 	case FSACTL_LNX_SENDFIB:
2962 	case FSACTL_LNX_SEND_LARGE_FIB:
2963 		fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_SENDFIB");
2964 		error = aac_ioctl_sendfib(sc, arg);
2965 		break;
2966 	case FSACTL_SEND_RAW_SRB:
2967 		arg = *(caddr_t*)arg;
2968 	case FSACTL_LNX_SEND_RAW_SRB:
2969 		fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_SEND_RAW_SRB");
2970 		error = aac_ioctl_send_raw_srb(sc, arg);
2971 		break;
2972 	case FSACTL_AIF_THREAD:
2973 	case FSACTL_LNX_AIF_THREAD:
2974 		fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_AIF_THREAD");
2975 		error = EINVAL;
2976 		break;
2977 	case FSACTL_OPEN_GET_ADAPTER_FIB:
2978 		arg = *(caddr_t*)arg;
2979 	case FSACTL_LNX_OPEN_GET_ADAPTER_FIB:
2980 		fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_OPEN_GET_ADAPTER_FIB");
2981 		error = aac_open_aif(sc, arg);
2982 		break;
2983 	case FSACTL_GET_NEXT_ADAPTER_FIB:
2984 		arg = *(caddr_t*)arg;
2985 	case FSACTL_LNX_GET_NEXT_ADAPTER_FIB:
2986 		fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_NEXT_ADAPTER_FIB");
2987 		error = aac_getnext_aif(sc, arg);
2988 		break;
2989 	case FSACTL_CLOSE_GET_ADAPTER_FIB:
2990 		arg = *(caddr_t*)arg;
2991 	case FSACTL_LNX_CLOSE_GET_ADAPTER_FIB:
2992 		fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_CLOSE_GET_ADAPTER_FIB");
2993 		error = aac_close_aif(sc, arg);
2994 		break;
2995 	case FSACTL_MINIPORT_REV_CHECK:
2996 		arg = *(caddr_t*)arg;
2997 	case FSACTL_LNX_MINIPORT_REV_CHECK:
2998 		fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_MINIPORT_REV_CHECK");
2999 		error = aac_rev_check(sc, arg);
3000 		break;
3001 	case FSACTL_QUERY_DISK:
3002 		arg = *(caddr_t*)arg;
3003 	case FSACTL_LNX_QUERY_DISK:
3004 		fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_QUERY_DISK");
3005 		error = aac_query_disk(sc, arg);
3006 		break;
3007 	case FSACTL_DELETE_DISK:
3008 	case FSACTL_LNX_DELETE_DISK:
3009 		/*
3010 		 * We don't trust the underland to tell us when to delete a
3011 		 * container, rather we rely on an AIF coming from the
3012 		 * controller
3013 		 */
3014 		error = 0;
3015 		break;
3016 	case FSACTL_GET_PCI_INFO:
3017 		arg = *(caddr_t*)arg;
3018 	case FSACTL_LNX_GET_PCI_INFO:
3019 		fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_PCI_INFO");
3020 		error = aac_get_pci_info(sc, arg);
3021 		break;
3022 	case FSACTL_GET_FEATURES:
3023 		arg = *(caddr_t*)arg;
3024 	case FSACTL_LNX_GET_FEATURES:
3025 		fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_FEATURES");
3026 		error = aac_supported_features(sc, arg);
3027 		break;
3028 	default:
3029 		fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "unsupported cmd 0x%lx\n", cmd);
3030 		error = EINVAL;
3031 		break;
3032 	}
3033 	return(error);
3034 }
3035 
3036 static int
3037 aac_poll(struct cdev *dev, int poll_events, struct thread *td)
3038 {
3039 	struct aac_softc *sc;
3040 	struct aac_fib_context *ctx;
3041 	int revents;
3042 
3043 	sc = dev->si_drv1;
3044 	revents = 0;
3045 
3046 	mtx_lock(&sc->aac_aifq_lock);
3047 	if ((poll_events & (POLLRDNORM | POLLIN)) != 0) {
3048 		for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
3049 			if (ctx->ctx_idx != sc->aifq_idx || ctx->ctx_wrap) {
3050 				revents |= poll_events & (POLLIN | POLLRDNORM);
3051 				break;
3052 			}
3053 		}
3054 	}
3055 	mtx_unlock(&sc->aac_aifq_lock);
3056 
3057 	if (revents == 0) {
3058 		if (poll_events & (POLLIN | POLLRDNORM))
3059 			selrecord(td, &sc->rcv_select);
3060 	}
3061 
3062 	return (revents);
3063 }
3064 
3065 static void
3066 aac_ioctl_event(struct aac_softc *sc, struct aac_event *event, void *arg)
3067 {
3068 
3069 	switch (event->ev_type) {
3070 	case AAC_EVENT_CMFREE:
3071 		mtx_assert(&sc->aac_io_lock, MA_OWNED);
3072 		if (aac_alloc_command(sc, (struct aac_command **)arg)) {
3073 			aac_add_event(sc, event);
3074 			return;
3075 		}
3076 		free(event, M_AACBUF);
3077 		wakeup(arg);
3078 		break;
3079 	default:
3080 		break;
3081 	}
3082 }
3083 
3084 /*
3085  * Send a FIB supplied from userspace
3086  */
3087 static int
3088 aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
3089 {
3090 	struct aac_command *cm;
3091 	int size, error;
3092 
3093 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3094 
3095 	cm = NULL;
3096 
3097 	/*
3098 	 * Get a command
3099 	 */
3100 	mtx_lock(&sc->aac_io_lock);
3101 	if (aac_alloc_command(sc, &cm)) {
3102 		struct aac_event *event;
3103 
3104 		event = malloc(sizeof(struct aac_event), M_AACBUF,
3105 		    M_NOWAIT | M_ZERO);
3106 		if (event == NULL) {
3107 			error = EBUSY;
3108 			mtx_unlock(&sc->aac_io_lock);
3109 			goto out;
3110 		}
3111 		event->ev_type = AAC_EVENT_CMFREE;
3112 		event->ev_callback = aac_ioctl_event;
3113 		event->ev_arg = &cm;
3114 		aac_add_event(sc, event);
3115 		msleep(&cm, &sc->aac_io_lock, 0, "sendfib", 0);
3116 	}
3117 	mtx_unlock(&sc->aac_io_lock);
3118 
3119 	/*
3120 	 * Fetch the FIB header, then re-copy to get data as well.
3121 	 */
3122 	if ((error = copyin(ufib, cm->cm_fib,
3123 			    sizeof(struct aac_fib_header))) != 0)
3124 		goto out;
3125 	size = cm->cm_fib->Header.Size + sizeof(struct aac_fib_header);
3126 	if (size > sc->aac_max_fib_size) {
3127 		device_printf(sc->aac_dev, "incoming FIB oversized (%d > %d)\n",
3128 			      size, sc->aac_max_fib_size);
3129 		size = sc->aac_max_fib_size;
3130 	}
3131 	if ((error = copyin(ufib, cm->cm_fib, size)) != 0)
3132 		goto out;
3133 	cm->cm_fib->Header.Size = size;
3134 	cm->cm_timestamp = time_uptime;
3135 
3136 	/*
3137 	 * Pass the FIB to the controller, wait for it to complete.
3138 	 */
3139 	mtx_lock(&sc->aac_io_lock);
3140 	error = aac_wait_command(cm);
3141 	mtx_unlock(&sc->aac_io_lock);
3142 	if (error != 0) {
3143 		device_printf(sc->aac_dev,
3144 			      "aac_wait_command return %d\n", error);
3145 		goto out;
3146 	}
3147 
3148 	/*
3149 	 * Copy the FIB and data back out to the caller.
3150 	 */
3151 	size = cm->cm_fib->Header.Size;
3152 	if (size > sc->aac_max_fib_size) {
3153 		device_printf(sc->aac_dev, "outbound FIB oversized (%d > %d)\n",
3154 			      size, sc->aac_max_fib_size);
3155 		size = sc->aac_max_fib_size;
3156 	}
3157 	error = copyout(cm->cm_fib, ufib, size);
3158 
3159 out:
3160 	if (cm != NULL) {
3161 		mtx_lock(&sc->aac_io_lock);
3162 		aac_release_command(cm);
3163 		mtx_unlock(&sc->aac_io_lock);
3164 	}
3165 	return(error);
3166 }
3167 
3168 /*
3169  * Send a passthrough FIB supplied from userspace
3170  */
3171 static int
3172 aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg)
3173 {
3174 	return (EINVAL);
3175 }
3176 
3177 /*
3178  * Handle an AIF sent to us by the controller; queue it for later reference.
3179  * If the queue fills up, then drop the older entries.
3180  */
3181 static void
3182 aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
3183 {
3184 	struct aac_aif_command *aif;
3185 	struct aac_container *co, *co_next;
3186 	struct aac_fib_context *ctx;
3187 	struct aac_mntinforesp *mir;
3188 	int next, current, found;
3189 	int count = 0, added = 0, i = 0;
3190 
3191 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3192 
3193 	aif = (struct aac_aif_command*)&fib->data[0];
3194 	aac_print_aif(sc, aif);
3195 
3196 	/* Is it an event that we should care about? */
3197 	switch (aif->command) {
3198 	case AifCmdEventNotify:
3199 		switch (aif->data.EN.type) {
3200 		case AifEnAddContainer:
3201 		case AifEnDeleteContainer:
3202 			/*
3203 			 * A container was added or deleted, but the message
3204 			 * doesn't tell us anything else!  Re-enumerate the
3205 			 * containers and sort things out.
3206 			 */
3207 			aac_alloc_sync_fib(sc, &fib);
3208 			do {
3209 				/*
3210 				 * Ask the controller for its containers one at
3211 				 * a time.
3212 				 * XXX What if the controller's list changes
3213 				 * midway through this enumaration?
3214 				 * XXX This should be done async.
3215 				 */
3216 				if ((mir = aac_get_container_info(sc, fib, i)) == NULL)
3217 					continue;
3218 				if (i == 0)
3219 					count = mir->MntRespCount;
3220 				/*
3221 				 * Check the container against our list.
3222 				 * co->co_found was already set to 0 in a
3223 				 * previous run.
3224 				 */
3225 				if ((mir->Status == ST_OK) &&
3226 				    (mir->MntTable[0].VolType != CT_NONE)) {
3227 					found = 0;
3228 					TAILQ_FOREACH(co,
3229 						      &sc->aac_container_tqh,
3230 						      co_link) {
3231 						if (co->co_mntobj.ObjectId ==
3232 						    mir->MntTable[0].ObjectId) {
3233 							co->co_found = 1;
3234 							found = 1;
3235 							break;
3236 						}
3237 					}
3238 					/*
3239 					 * If the container matched, continue
3240 					 * in the list.
3241 					 */
3242 					if (found) {
3243 						i++;
3244 						continue;
3245 					}
3246 
3247 					/*
3248 					 * This is a new container.  Do all the
3249 					 * appropriate things to set it up.
3250 					 */
3251 					aac_add_container(sc, mir, 1);
3252 					added = 1;
3253 				}
3254 				i++;
3255 			} while ((i < count) && (i < AAC_MAX_CONTAINERS));
3256 			aac_release_sync_fib(sc);
3257 
3258 			/*
3259 			 * Go through our list of containers and see which ones
3260 			 * were not marked 'found'.  Since the controller didn't
3261 			 * list them they must have been deleted.  Do the
3262 			 * appropriate steps to destroy the device.  Also reset
3263 			 * the co->co_found field.
3264 			 */
3265 			co = TAILQ_FIRST(&sc->aac_container_tqh);
3266 			while (co != NULL) {
3267 				if (co->co_found == 0) {
3268 					mtx_unlock(&sc->aac_io_lock);
3269 					mtx_lock(&Giant);
3270 					device_delete_child(sc->aac_dev,
3271 							    co->co_disk);
3272 					mtx_unlock(&Giant);
3273 					mtx_lock(&sc->aac_io_lock);
3274 					co_next = TAILQ_NEXT(co, co_link);
3275 					mtx_lock(&sc->aac_container_lock);
3276 					TAILQ_REMOVE(&sc->aac_container_tqh, co,
3277 						     co_link);
3278 					mtx_unlock(&sc->aac_container_lock);
3279 					free(co, M_AACBUF);
3280 					co = co_next;
3281 				} else {
3282 					co->co_found = 0;
3283 					co = TAILQ_NEXT(co, co_link);
3284 				}
3285 			}
3286 
3287 			/* Attach the newly created containers */
3288 			if (added) {
3289 				mtx_unlock(&sc->aac_io_lock);
3290 				mtx_lock(&Giant);
3291 				bus_generic_attach(sc->aac_dev);
3292 				mtx_unlock(&Giant);
3293 				mtx_lock(&sc->aac_io_lock);
3294 			}
3295 
3296 			break;
3297 
3298 		default:
3299 			break;
3300 		}
3301 
3302 	default:
3303 		break;
3304 	}
3305 
3306 	/* Copy the AIF data to the AIF queue for ioctl retrieval */
3307 	mtx_lock(&sc->aac_aifq_lock);
3308 	current = sc->aifq_idx;
3309 	next = (current + 1) % AAC_AIFQ_LENGTH;
3310 	if (next == 0)
3311 		sc->aifq_filled = 1;
3312 	bcopy(fib, &sc->aac_aifq[current], sizeof(struct aac_fib));
3313 	/* modify AIF contexts */
3314 	if (sc->aifq_filled) {
3315 		for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
3316 			if (next == ctx->ctx_idx)
3317 				ctx->ctx_wrap = 1;
3318 			else if (current == ctx->ctx_idx && ctx->ctx_wrap)
3319 				ctx->ctx_idx = next;
3320 		}
3321 	}
3322 	sc->aifq_idx = next;
3323 	/* On the off chance that someone is sleeping for an aif... */
3324 	if (sc->aac_state & AAC_STATE_AIF_SLEEPER)
3325 		wakeup(sc->aac_aifq);
3326 	/* Wakeup any poll()ers */
3327 	selwakeuppri(&sc->rcv_select, PRIBIO);
3328 	mtx_unlock(&sc->aac_aifq_lock);
3329 
3330 	return;
3331 }
3332 
3333 /*
3334  * Return the Revision of the driver to userspace and check to see if the
3335  * userspace app is possibly compatible.  This is extremely bogus since
3336  * our driver doesn't follow Adaptec's versioning system.  Cheat by just
3337  * returning what the card reported.
3338  */
3339 static int
3340 aac_rev_check(struct aac_softc *sc, caddr_t udata)
3341 {
3342 	struct aac_rev_check rev_check;
3343 	struct aac_rev_check_resp rev_check_resp;
3344 	int error = 0;
3345 
3346 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3347 
3348 	/*
3349 	 * Copyin the revision struct from userspace
3350 	 */
3351 	if ((error = copyin(udata, (caddr_t)&rev_check,
3352 			sizeof(struct aac_rev_check))) != 0) {
3353 		return error;
3354 	}
3355 
3356 	fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "Userland revision= %d\n",
3357 	      rev_check.callingRevision.buildNumber);
3358 
3359 	/*
3360 	 * Doctor up the response struct.
3361 	 */
3362 	rev_check_resp.possiblyCompatible = 1;
3363 	rev_check_resp.adapterSWRevision.external.ul =
3364 	    sc->aac_revision.external.ul;
3365 	rev_check_resp.adapterSWRevision.buildNumber =
3366 	    sc->aac_revision.buildNumber;
3367 
3368 	return(copyout((caddr_t)&rev_check_resp, udata,
3369 			sizeof(struct aac_rev_check_resp)));
3370 }
3371 
3372 /*
3373  * Pass the fib context to the caller
3374  */
3375 static int
3376 aac_open_aif(struct aac_softc *sc, caddr_t arg)
3377 {
3378 	struct aac_fib_context *fibctx, *ctx;
3379 	int error = 0;
3380 
3381 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3382 
3383 	fibctx = malloc(sizeof(struct aac_fib_context), M_AACBUF, M_NOWAIT|M_ZERO);
3384 	if (fibctx == NULL)
3385 		return (ENOMEM);
3386 
3387 	mtx_lock(&sc->aac_aifq_lock);
3388 	/* all elements are already 0, add to queue */
3389 	if (sc->fibctx == NULL)
3390 		sc->fibctx = fibctx;
3391 	else {
3392 		for (ctx = sc->fibctx; ctx->next; ctx = ctx->next)
3393 			;
3394 		ctx->next = fibctx;
3395 		fibctx->prev = ctx;
3396 	}
3397 
3398 	/* evaluate unique value */
3399 	fibctx->unique = (*(u_int32_t *)&fibctx & 0xffffffff);
3400 	ctx = sc->fibctx;
3401 	while (ctx != fibctx) {
3402 		if (ctx->unique == fibctx->unique) {
3403 			fibctx->unique++;
3404 			ctx = sc->fibctx;
3405 		} else {
3406 			ctx = ctx->next;
3407 		}
3408 	}
3409 	mtx_unlock(&sc->aac_aifq_lock);
3410 
3411 	error = copyout(&fibctx->unique, (void *)arg, sizeof(u_int32_t));
3412 	if (error)
3413 		aac_close_aif(sc, (caddr_t)ctx);
3414 	return error;
3415 }
3416 
3417 /*
3418  * Close the caller's fib context
3419  */
3420 static int
3421 aac_close_aif(struct aac_softc *sc, caddr_t arg)
3422 {
3423 	struct aac_fib_context *ctx;
3424 
3425 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3426 
3427 	mtx_lock(&sc->aac_aifq_lock);
3428 	for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
3429 		if (ctx->unique == *(uint32_t *)&arg) {
3430 			if (ctx == sc->fibctx)
3431 				sc->fibctx = NULL;
3432 			else {
3433 				ctx->prev->next = ctx->next;
3434 				if (ctx->next)
3435 					ctx->next->prev = ctx->prev;
3436 			}
3437 			break;
3438 		}
3439 	}
3440 	mtx_unlock(&sc->aac_aifq_lock);
3441 	if (ctx)
3442 		free(ctx, M_AACBUF);
3443 
3444 	return 0;
3445 }
3446 
3447 /*
3448  * Pass the caller the next AIF in their queue
3449  */
3450 static int
3451 aac_getnext_aif(struct aac_softc *sc, caddr_t arg)
3452 {
3453 	struct get_adapter_fib_ioctl agf;
3454 	struct aac_fib_context *ctx;
3455 	int error;
3456 
3457 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3458 
3459 	if ((error = copyin(arg, &agf, sizeof(agf))) == 0) {
3460 		for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
3461 			if (agf.AdapterFibContext == ctx->unique)
3462 				break;
3463 		}
3464 		if (!ctx)
3465 			return (EFAULT);
3466 
3467 		error = aac_return_aif(sc, ctx, agf.AifFib);
3468 		if (error == EAGAIN && agf.Wait) {
3469 			fwprintf(sc, HBA_FLAGS_DBG_AIF_B, "aac_getnext_aif(): waiting for AIF");
3470 			sc->aac_state |= AAC_STATE_AIF_SLEEPER;
3471 			while (error == EAGAIN) {
3472 				error = tsleep(sc->aac_aifq, PRIBIO |
3473 					       PCATCH, "aacaif", 0);
3474 				if (error == 0)
3475 					error = aac_return_aif(sc, ctx, agf.AifFib);
3476 			}
3477 			sc->aac_state &= ~AAC_STATE_AIF_SLEEPER;
3478 		}
3479 	}
3480 	return(error);
3481 }
3482 
3483 /*
3484  * Hand the next AIF off the top of the queue out to userspace.
3485  */
3486 static int
3487 aac_return_aif(struct aac_softc *sc, struct aac_fib_context *ctx, caddr_t uptr)
3488 {
3489 	int current, error;
3490 
3491 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3492 
3493 	mtx_lock(&sc->aac_aifq_lock);
3494 	current = ctx->ctx_idx;
3495 	if (current == sc->aifq_idx && !ctx->ctx_wrap) {
3496 		/* empty */
3497 		mtx_unlock(&sc->aac_aifq_lock);
3498 		return (EAGAIN);
3499 	}
3500 	error =
3501 		copyout(&sc->aac_aifq[current], (void *)uptr, sizeof(struct aac_fib));
3502 	if (error)
3503 		device_printf(sc->aac_dev,
3504 		    "aac_return_aif: copyout returned %d\n", error);
3505 	else {
3506 		ctx->ctx_wrap = 0;
3507 		ctx->ctx_idx = (current + 1) % AAC_AIFQ_LENGTH;
3508 	}
3509 	mtx_unlock(&sc->aac_aifq_lock);
3510 	return(error);
3511 }
3512 
3513 static int
3514 aac_get_pci_info(struct aac_softc *sc, caddr_t uptr)
3515 {
3516 	struct aac_pci_info {
3517 		u_int32_t bus;
3518 		u_int32_t slot;
3519 	} pciinf;
3520 	int error;
3521 
3522 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3523 
3524 	pciinf.bus = pci_get_bus(sc->aac_dev);
3525 	pciinf.slot = pci_get_slot(sc->aac_dev);
3526 
3527 	error = copyout((caddr_t)&pciinf, uptr,
3528 			sizeof(struct aac_pci_info));
3529 
3530 	return (error);
3531 }
3532 
3533 static int
3534 aac_supported_features(struct aac_softc *sc, caddr_t uptr)
3535 {
3536 	struct aac_features f;
3537 	int error;
3538 
3539 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3540 
3541 	if ((error = copyin(uptr, &f, sizeof (f))) != 0)
3542 		return (error);
3543 
3544 	/*
3545 	 * When the management driver receives FSACTL_GET_FEATURES ioctl with
3546 	 * ALL zero in the featuresState, the driver will return the current
3547 	 * state of all the supported features, the data field will not be
3548 	 * valid.
3549 	 * When the management driver receives FSACTL_GET_FEATURES ioctl with
3550 	 * a specific bit set in the featuresState, the driver will return the
3551 	 * current state of this specific feature and whatever data that are
3552 	 * associated with the feature in the data field or perform whatever
3553 	 * action needed indicates in the data field.
3554 	 */
3555 	if (f.feat.fValue == 0) {
3556 		f.feat.fBits.largeLBA =
3557 		    (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
3558 		/* TODO: In the future, add other features state here as well */
3559 	} else {
3560 		if (f.feat.fBits.largeLBA)
3561 			f.feat.fBits.largeLBA =
3562 			    (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
3563 		/* TODO: Add other features state and data in the future */
3564 	}
3565 
3566 	error = copyout(&f, uptr, sizeof (f));
3567 	return (error);
3568 }
3569 
3570 /*
3571  * Give the userland some information about the container.  The AAC arch
3572  * expects the driver to be a SCSI passthrough type driver, so it expects
3573  * the containers to have b:t:l numbers.  Fake it.
3574  */
3575 static int
3576 aac_query_disk(struct aac_softc *sc, caddr_t uptr)
3577 {
3578 	struct aac_query_disk query_disk;
3579 	struct aac_container *co;
3580 	struct aac_disk	*disk;
3581 	int error, id;
3582 
3583 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
3584 
3585 	disk = NULL;
3586 
3587 	error = copyin(uptr, (caddr_t)&query_disk,
3588 		       sizeof(struct aac_query_disk));
3589 	if (error)
3590 		return (error);
3591 
3592 	id = query_disk.ContainerNumber;
3593 	if (id == -1)
3594 		return (EINVAL);
3595 
3596 	mtx_lock(&sc->aac_container_lock);
3597 	TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) {
3598 		if (co->co_mntobj.ObjectId == id)
3599 			break;
3600 		}
3601 
3602 	if (co == NULL) {
3603 			query_disk.Valid = 0;
3604 			query_disk.Locked = 0;
3605 			query_disk.Deleted = 1;		/* XXX is this right? */
3606 	} else {
3607 		disk = device_get_softc(co->co_disk);
3608 		query_disk.Valid = 1;
3609 		query_disk.Locked =
3610 		    (disk->ad_flags & AAC_DISK_OPEN) ? 1 : 0;
3611 		query_disk.Deleted = 0;
3612 		query_disk.Bus = device_get_unit(sc->aac_dev);
3613 		query_disk.Target = disk->unit;
3614 		query_disk.Lun = 0;
3615 		query_disk.UnMapped = 0;
3616 		sprintf(&query_disk.diskDeviceName[0], "%s%d",
3617 			disk->ad_disk->d_name, disk->ad_disk->d_unit);
3618 	}
3619 	mtx_unlock(&sc->aac_container_lock);
3620 
3621 	error = copyout((caddr_t)&query_disk, uptr,
3622 			sizeof(struct aac_query_disk));
3623 
3624 	return (error);
3625 }
3626 
3627 static void
3628 aac_get_bus_info(struct aac_softc *sc)
3629 {
3630 	struct aac_fib *fib;
3631 	struct aac_ctcfg *c_cmd;
3632 	struct aac_ctcfg_resp *c_resp;
3633 	struct aac_vmioctl *vmi;
3634 	struct aac_vmi_businf_resp *vmi_resp;
3635 	struct aac_getbusinf businfo;
3636 	struct aac_sim *caminf;
3637 	device_t child;
3638 	int i, found, error;
3639 
3640 	mtx_lock(&sc->aac_io_lock);
3641 	aac_alloc_sync_fib(sc, &fib);
3642 	c_cmd = (struct aac_ctcfg *)&fib->data[0];
3643 	bzero(c_cmd, sizeof(struct aac_ctcfg));
3644 
3645 	c_cmd->Command = VM_ContainerConfig;
3646 	c_cmd->cmd = CT_GET_SCSI_METHOD;
3647 	c_cmd->param = 0;
3648 
3649 	error = aac_sync_fib(sc, ContainerCommand, 0, fib,
3650 	    sizeof(struct aac_ctcfg));
3651 	if (error) {
3652 		device_printf(sc->aac_dev, "Error %d sending "
3653 		    "VM_ContainerConfig command\n", error);
3654 		aac_release_sync_fib(sc);
3655 		mtx_unlock(&sc->aac_io_lock);
3656 		return;
3657 	}
3658 
3659 	c_resp = (struct aac_ctcfg_resp *)&fib->data[0];
3660 	if (c_resp->Status != ST_OK) {
3661 		device_printf(sc->aac_dev, "VM_ContainerConfig returned 0x%x\n",
3662 		    c_resp->Status);
3663 		aac_release_sync_fib(sc);
3664 		mtx_unlock(&sc->aac_io_lock);
3665 		return;
3666 	}
3667 
3668 	sc->scsi_method_id = c_resp->param;
3669 
3670 	vmi = (struct aac_vmioctl *)&fib->data[0];
3671 	bzero(vmi, sizeof(struct aac_vmioctl));
3672 
3673 	vmi->Command = VM_Ioctl;
3674 	vmi->ObjType = FT_DRIVE;
3675 	vmi->MethId = sc->scsi_method_id;
3676 	vmi->ObjId = 0;
3677 	vmi->IoctlCmd = GetBusInfo;
3678 
3679 	error = aac_sync_fib(sc, ContainerCommand, 0, fib,
3680 	    sizeof(struct aac_vmi_businf_resp));
3681 	if (error) {
3682 		device_printf(sc->aac_dev, "Error %d sending VMIoctl command\n",
3683 		    error);
3684 		aac_release_sync_fib(sc);
3685 		mtx_unlock(&sc->aac_io_lock);
3686 		return;
3687 	}
3688 
3689 	vmi_resp = (struct aac_vmi_businf_resp *)&fib->data[0];
3690 	if (vmi_resp->Status != ST_OK) {
3691 		device_printf(sc->aac_dev, "VM_Ioctl returned %d\n",
3692 		    vmi_resp->Status);
3693 		aac_release_sync_fib(sc);
3694 		mtx_unlock(&sc->aac_io_lock);
3695 		return;
3696 	}
3697 
3698 	bcopy(&vmi_resp->BusInf, &businfo, sizeof(struct aac_getbusinf));
3699 	aac_release_sync_fib(sc);
3700 	mtx_unlock(&sc->aac_io_lock);
3701 
3702 	found = 0;
3703 	for (i = 0; i < businfo.BusCount; i++) {
3704 		if (businfo.BusValid[i] != AAC_BUS_VALID)
3705 			continue;
3706 
3707 		caminf = (struct aac_sim *)malloc( sizeof(struct aac_sim),
3708 		    M_AACBUF, M_NOWAIT | M_ZERO);
3709 		if (caminf == NULL) {
3710 			device_printf(sc->aac_dev,
3711 			    "No memory to add passthrough bus %d\n", i);
3712 			break;
3713 		};
3714 
3715 		child = device_add_child(sc->aac_dev, "aacp", -1);
3716 		if (child == NULL) {
3717 			device_printf(sc->aac_dev,
3718 			    "device_add_child failed for passthrough bus %d\n",
3719 			    i);
3720 			free(caminf, M_AACBUF);
3721 			break;
3722 		}
3723 
3724 		caminf->TargetsPerBus = businfo.TargetsPerBus;
3725 		caminf->BusNumber = i;
3726 		caminf->InitiatorBusId = businfo.InitiatorBusId[i];
3727 		caminf->aac_sc = sc;
3728 		caminf->sim_dev = child;
3729 
3730 		device_set_ivars(child, caminf);
3731 		device_set_desc(child, "SCSI Passthrough Bus");
3732 		TAILQ_INSERT_TAIL(&sc->aac_sim_tqh, caminf, sim_link);
3733 
3734 		found = 1;
3735 	}
3736 
3737 	if (found)
3738 		bus_generic_attach(sc->aac_dev);
3739 
3740 	return;
3741 }
3742