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