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