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