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