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