xref: /freebsd/sys/dev/aac/aac.c (revision 282873e2c0f685be7dc8fe3205bcea60557291a7)
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$
30  */
31 
32 /*
33  * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
34  */
35 
36 #include "opt_aac.h"
37 
38 /* #include <stddef.h> */
39 #include <sys/param.h>
40 #include <sys/systm.h>
41 #include <sys/malloc.h>
42 #include <sys/kernel.h>
43 #include <sys/kthread.h>
44 #include <sys/sysctl.h>
45 
46 #include <dev/aac/aac_compat.h>
47 
48 #include <sys/bus.h>
49 #include <sys/conf.h>
50 #include <sys/devicestat.h>
51 #include <sys/disk.h>
52 #include <sys/file.h>
53 #include <sys/signalvar.h>
54 #include <sys/time.h>
55 #include <sys/eventhandler.h>
56 
57 #include <machine/bus_memio.h>
58 #include <machine/bus.h>
59 #include <machine/resource.h>
60 
61 #include <dev/aac/aacreg.h>
62 #include <dev/aac/aac_ioctl.h>
63 #include <dev/aac/aacvar.h>
64 #include <dev/aac/aac_tables.h>
65 
66 devclass_t	aac_devclass;
67 
68 static void	aac_startup(void *arg);
69 static void	aac_add_container(struct aac_softc *sc,
70 				  struct aac_mntinforesponse *mir, int f);
71 
72 /* Command Processing */
73 static void	aac_startio(struct aac_softc *sc);
74 static void	aac_timeout(struct aac_softc *sc);
75 static int	aac_start(struct aac_command *cm);
76 static void	aac_complete(void *context, int pending);
77 static int	aac_bio_command(struct aac_softc *sc, struct aac_command **cmp);
78 static void	aac_bio_complete(struct aac_command *cm);
79 static int	aac_wait_command(struct aac_command *cm, int timeout);
80 static void	aac_host_command(struct aac_softc *sc);
81 static void	aac_host_response(struct aac_softc *sc);
82 
83 /* Command Buffer Management */
84 static int	aac_alloc_command(struct aac_softc *sc,
85 				  struct aac_command **cmp);
86 static void	aac_release_command(struct aac_command *cm);
87 static void	aac_map_command_helper(void *arg, bus_dma_segment_t *segs,
88 				       int nseg, int error);
89 static int	aac_alloc_commands(struct aac_softc *sc);
90 static void	aac_free_commands(struct aac_softc *sc);
91 static void	aac_map_command(struct aac_command *cm);
92 static void	aac_unmap_command(struct aac_command *cm);
93 
94 /* Hardware Interface */
95 static void	aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg,
96 			       int error);
97 static int	aac_init(struct aac_softc *sc);
98 static int	aac_sync_command(struct aac_softc *sc, u_int32_t command,
99 				 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2,
100 				 u_int32_t arg3, u_int32_t *sp);
101 static int	aac_sync_fib(struct aac_softc *sc, u_int32_t command,
102 			     u_int32_t xferstate, void *data,
103 			     u_int16_t datasize, void *result,
104 			     u_int16_t *resultsize);
105 static int	aac_enqueue_fib(struct aac_softc *sc, int queue,
106 				struct aac_command *cm);
107 static int	aac_dequeue_fib(struct aac_softc *sc, int queue,
108 				u_int32_t *fib_size, struct aac_fib **fib_addr);
109 static int	aac_enqueue_response(struct aac_softc *sc, int queue,
110 				     struct aac_fib *fib);
111 
112 /* StrongARM interface */
113 static int	aac_sa_get_fwstatus(struct aac_softc *sc);
114 static void	aac_sa_qnotify(struct aac_softc *sc, int qbit);
115 static int	aac_sa_get_istatus(struct aac_softc *sc);
116 static void	aac_sa_clear_istatus(struct aac_softc *sc, int mask);
117 static void	aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
118 				   u_int32_t arg0, u_int32_t arg1,
119 				   u_int32_t arg2, u_int32_t arg3);
120 static int	aac_sa_get_mailboxstatus(struct aac_softc *sc);
121 static void	aac_sa_set_interrupts(struct aac_softc *sc, int enable);
122 
123 struct aac_interface aac_sa_interface = {
124 	aac_sa_get_fwstatus,
125 	aac_sa_qnotify,
126 	aac_sa_get_istatus,
127 	aac_sa_clear_istatus,
128 	aac_sa_set_mailbox,
129 	aac_sa_get_mailboxstatus,
130 	aac_sa_set_interrupts
131 };
132 
133 /* i960Rx interface */
134 static int	aac_rx_get_fwstatus(struct aac_softc *sc);
135 static void	aac_rx_qnotify(struct aac_softc *sc, int qbit);
136 static int	aac_rx_get_istatus(struct aac_softc *sc);
137 static void	aac_rx_clear_istatus(struct aac_softc *sc, int mask);
138 static void	aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
139 				   u_int32_t arg0, u_int32_t arg1,
140 				   u_int32_t arg2, u_int32_t arg3);
141 static int	aac_rx_get_mailboxstatus(struct aac_softc *sc);
142 static void	aac_rx_set_interrupts(struct aac_softc *sc, int enable);
143 
144 struct aac_interface aac_rx_interface = {
145 	aac_rx_get_fwstatus,
146 	aac_rx_qnotify,
147 	aac_rx_get_istatus,
148 	aac_rx_clear_istatus,
149 	aac_rx_set_mailbox,
150 	aac_rx_get_mailboxstatus,
151 	aac_rx_set_interrupts
152 };
153 
154 /* Debugging and Diagnostics */
155 static void	aac_describe_controller(struct aac_softc *sc);
156 static char	*aac_describe_code(struct aac_code_lookup *table,
157 				   u_int32_t code);
158 
159 /* Management Interface */
160 static d_open_t		aac_open;
161 static d_close_t	aac_close;
162 static d_ioctl_t	aac_ioctl;
163 static int		aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib);
164 static void		aac_handle_aif(struct aac_softc *sc,
165 					   struct aac_fib *fib);
166 static int		aac_rev_check(struct aac_softc *sc, caddr_t udata);
167 static int		aac_getnext_aif(struct aac_softc *sc, caddr_t arg);
168 static int		aac_return_aif(struct aac_softc *sc, caddr_t uptr);
169 static int		aac_query_disk(struct aac_softc *sc, caddr_t uptr);
170 
171 #define AAC_CDEV_MAJOR	150
172 
173 static struct cdevsw aac_cdevsw = {
174 	aac_open,		/* open */
175 	aac_close,		/* close */
176 	noread,			/* read */
177 	nowrite,		/* write */
178 	aac_ioctl,		/* ioctl */
179 	nopoll,			/* poll */
180 	nommap,			/* mmap */
181 	nostrategy,		/* strategy */
182 	"aac",			/* name */
183 	AAC_CDEV_MAJOR,		/* major */
184 	nodump,			/* dump */
185 	nopsize,		/* psize */
186 	0,			/* flags */
187 #if __FreeBSD_version < 500005
188 	-1,			/* bmaj */
189 #endif
190 };
191 
192 MALLOC_DEFINE(M_AACBUF, "aacbuf", "Buffers for the AAC driver");
193 
194 /* sysctl node */
195 SYSCTL_NODE(_hw, OID_AUTO, aac, CTLFLAG_RD, 0, "AAC driver parameters");
196 
197 /*
198  * Device Interface
199  */
200 
201 /*
202  * Initialise the controller and softc
203  */
204 int
205 aac_attach(struct aac_softc *sc)
206 {
207 	int error, unit;
208 
209 	debug_called(1);
210 
211 	/*
212 	 * Initialise per-controller queues.
213 	 */
214 	aac_initq_free(sc);
215 	aac_initq_ready(sc);
216 	aac_initq_busy(sc);
217 	aac_initq_complete(sc);
218 	aac_initq_bio(sc);
219 
220 #if __FreeBSD_version >= 500005
221 	/*
222 	 * Initialise command-completion task.
223 	 */
224 	TASK_INIT(&sc->aac_task_complete, 0, aac_complete, sc);
225 #endif
226 
227 	/* disable interrupts before we enable anything */
228 	AAC_MASK_INTERRUPTS(sc);
229 
230 	/* mark controller as suspended until we get ourselves organised */
231 	sc->aac_state |= AAC_STATE_SUSPEND;
232 
233 	/*
234 	 * Allocate command structures.
235 	 */
236 	if ((error = aac_alloc_commands(sc)) != 0)
237 		return(error);
238 
239 	/*
240 	 * Initialise the adapter.
241 	 */
242 	if ((error = aac_init(sc)) != 0)
243 		return(error);
244 
245 	/*
246 	 * Print a little information about the controller.
247 	 */
248 	aac_describe_controller(sc);
249 
250 	/*
251 	 * Register to probe our containers later.
252 	 */
253 	TAILQ_INIT(&sc->aac_container_tqh);
254 	AAC_LOCK_INIT(&sc->aac_container_lock);
255 
256 	sc->aac_ich.ich_func = aac_startup;
257 	sc->aac_ich.ich_arg = sc;
258 	if (config_intrhook_establish(&sc->aac_ich) != 0) {
259 		device_printf(sc->aac_dev,
260 			      "can't establish configuration hook\n");
261 		return(ENXIO);
262 	}
263 
264 	/*
265 	 * Make the control device.
266 	 */
267 	unit = device_get_unit(sc->aac_dev);
268 	sc->aac_dev_t = make_dev(&aac_cdevsw, unit, UID_ROOT, GID_WHEEL, 0644,
269 				 "aac%d", unit);
270 #if __FreeBSD_version > 500005
271 	(void)make_dev_alias(sc->aac_dev_t, "afa%d", unit);
272 	(void)make_dev_alias(sc->aac_dev_t, "hpn%d", unit);
273 #endif
274 	sc->aac_dev_t->si_drv1 = sc;
275 
276 	/* Create the AIF thread */
277 #if __FreeBSD_version > 500005
278 	if (kthread_create((void(*)(void *))aac_host_command, sc,
279 			   &sc->aifthread, 0, "aac%daif", unit))
280 #else
281 	if (kthread_create((void(*)(void *))aac_host_command, sc,
282 			   &sc->aifthread, "aac%daif", unit))
283 #endif
284 		panic("Could not create AIF thread\n");
285 
286 	/* Register the shutdown method to only be called post-dump */
287 	if ((EVENTHANDLER_REGISTER(shutdown_final, aac_shutdown, sc->aac_dev,
288 				   SHUTDOWN_PRI_DEFAULT)) == NULL)
289 	device_printf(sc->aac_dev, "shutdown event registration failed\n");
290 
291 	return(0);
292 }
293 
294 /*
295  * Probe for containers, create disks.
296  */
297 static void
298 aac_startup(void *arg)
299 {
300 	struct aac_softc *sc;
301 	struct aac_mntinfo mi;
302 	struct aac_mntinforesponse mir;
303 	u_int16_t rsize;
304 	int i = 0;
305 
306 	debug_called(1);
307 
308 	sc = (struct aac_softc *)arg;
309 
310 	/* disconnect ourselves from the intrhook chain */
311 	config_intrhook_disestablish(&sc->aac_ich);
312 
313 	/* loop over possible containers */
314 	mi.Command = VM_NameServe;
315 	mi.MntType = FT_FILESYS;
316 	do {
317 		/* request information on this container */
318 		mi.MntCount = i;
319 		rsize = sizeof(mir);
320 		if (aac_sync_fib(sc, ContainerCommand, 0, &mi,
321 				 sizeof(struct aac_mntinfo), &mir, &rsize)) {
322 			debug(2, "error probing container %d", i);
323 			continue;
324 		}
325 		/* check response size */
326 		if (rsize != sizeof(mir)) {
327 			debug(2, "container info response wrong size "
328 			      "(%d should be %d)", rsize, sizeof(mir));
329 			continue;
330 		}
331 
332 		aac_add_container(sc, &mir, 0);
333 		i++;
334 	} while ((i < mir.MntRespCount) && (i < AAC_MAX_CONTAINERS));
335 
336 	/* poke the bus to actually attach the child devices */
337 	if (bus_generic_attach(sc->aac_dev))
338 		device_printf(sc->aac_dev, "bus_generic_attach failed\n");
339 
340 	/* mark the controller up */
341 	sc->aac_state &= ~AAC_STATE_SUSPEND;
342 
343 	/* enable interrupts now */
344 	AAC_UNMASK_INTERRUPTS(sc);
345 
346 	/* enable the timeout watchdog */
347 	timeout((timeout_t*)aac_timeout, sc, AAC_PERIODIC_INTERVAL * hz);
348 }
349 
350 /*
351  * Create a device to respresent a new container
352  */
353 static void
354 aac_add_container(struct aac_softc *sc, struct aac_mntinforesponse *mir, int f)
355 {
356 	struct aac_container *co;
357 	device_t child;
358 
359 	/*
360 	 * Check container volume type for validity.  Note that many of
361 	 * the possible types may never show up.
362 	 */
363 	if ((mir->Status == ST_OK) && (mir->MntTable[0].VolType != CT_NONE)) {
364 		MALLOC(co, struct aac_container *, sizeof *co, M_AACBUF,
365 		       M_NOWAIT);
366 		if (co == NULL)
367 			panic("Out of memory?!\n");
368 		debug(1, "id %x  name '%.16s'  size %u  type %d",
369 		      mir->MntTable[0].ObjectId,
370 		      mir->MntTable[0].FileSystemName,
371 		      mir->MntTable[0].Capacity, mir->MntTable[0].VolType);
372 
373 		if ((child = device_add_child(sc->aac_dev, NULL, -1)) == NULL)
374 			device_printf(sc->aac_dev, "device_add_child failed\n");
375 		else
376 			device_set_ivars(child, co);
377 		device_set_desc(child, aac_describe_code(aac_container_types,
378 				mir->MntTable[0].VolType));
379 		co->co_disk = child;
380 		co->co_found = f;
381 		bcopy(&mir->MntTable[0], &co->co_mntobj,
382 		      sizeof(struct aac_mntobj));
383 		AAC_LOCK_AQUIRE(&sc->aac_container_lock);
384 		TAILQ_INSERT_TAIL(&sc->aac_container_tqh, co, co_link);
385 		AAC_LOCK_RELEASE(&sc->aac_container_lock);
386 	}
387 }
388 
389 /*
390  * Free all of the resources associated with (sc)
391  *
392  * Should not be called if the controller is active.
393  */
394 void
395 aac_free(struct aac_softc *sc)
396 {
397 	debug_called(1);
398 
399 	/* remove the control device */
400 	if (sc->aac_dev_t != NULL)
401 		destroy_dev(sc->aac_dev_t);
402 
403 	/* throw away any FIB buffers, discard the FIB DMA tag */
404 	if (sc->aac_fibs != NULL)
405 		aac_free_commands(sc);
406 	if (sc->aac_fib_dmat)
407 		bus_dma_tag_destroy(sc->aac_fib_dmat);
408 
409 	/* destroy the common area */
410 	if (sc->aac_common) {
411 		bus_dmamap_unload(sc->aac_common_dmat, sc->aac_common_dmamap);
412 		bus_dmamem_free(sc->aac_common_dmat, sc->aac_common,
413 				sc->aac_common_dmamap);
414 	}
415 	if (sc->aac_common_dmat)
416 		bus_dma_tag_destroy(sc->aac_common_dmat);
417 
418 	/* disconnect the interrupt handler */
419 	if (sc->aac_intr)
420 		bus_teardown_intr(sc->aac_dev, sc->aac_irq, sc->aac_intr);
421 	if (sc->aac_irq != NULL)
422 		bus_release_resource(sc->aac_dev, SYS_RES_IRQ, sc->aac_irq_rid,
423 				     sc->aac_irq);
424 
425 	/* destroy data-transfer DMA tag */
426 	if (sc->aac_buffer_dmat)
427 		bus_dma_tag_destroy(sc->aac_buffer_dmat);
428 
429 	/* destroy the parent DMA tag */
430 	if (sc->aac_parent_dmat)
431 		bus_dma_tag_destroy(sc->aac_parent_dmat);
432 
433 	/* release the register window mapping */
434 	if (sc->aac_regs_resource != NULL)
435 		bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
436 				     sc->aac_regs_rid, sc->aac_regs_resource);
437 }
438 
439 /*
440  * Disconnect from the controller completely, in preparation for unload.
441  */
442 int
443 aac_detach(device_t dev)
444 {
445 	struct aac_softc *sc;
446 #if AAC_BROKEN
447 	int error;
448 #endif
449 
450 	debug_called(1);
451 
452 	sc = device_get_softc(dev);
453 
454 	if (sc->aac_state & AAC_STATE_OPEN)
455 	return(EBUSY);
456 
457 #if AAC_BROKEN
458 	if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
459 		sc->aifflags |= AAC_AIFFLAGS_EXIT;
460 		wakeup(sc->aifthread);
461 		tsleep(sc->aac_dev, PUSER | PCATCH, "aacdch", 30 * hz);
462 	}
463 
464 	if (sc->aifflags & AAC_AIFFLAGS_RUNNING)
465 		panic("Cannot shutdown AIF thread\n");
466 
467 	if ((error = aac_shutdown(dev)))
468 		return(error);
469 
470 	aac_free(sc);
471 
472 	return(0);
473 #else
474 	return (EBUSY);
475 #endif
476 }
477 
478 /*
479  * Bring the controller down to a dormant state and detach all child devices.
480  *
481  * This function is called before detach or system shutdown.
482  *
483  * Note that we can assume that the bioq on the controller is empty, as we won't
484  * allow shutdown if any device is open.
485  */
486 int
487 aac_shutdown(device_t dev)
488 {
489 	struct aac_softc *sc;
490 	struct aac_close_command cc;
491 	int s, i;
492 
493 	debug_called(1);
494 
495 	sc = device_get_softc(dev);
496 
497 	s = splbio();
498 
499 	sc->aac_state |= AAC_STATE_SUSPEND;
500 
501 	/*
502 	 * Send a Container shutdown followed by a HostShutdown FIB to the
503 	 * controller to convince it that we don't want to talk to it anymore.
504 	 * We've been closed and all I/O completed already
505 	 */
506 	device_printf(sc->aac_dev, "shutting down controller...");
507 
508 	cc.Command = VM_CloseAll;
509 	cc.ContainerId = 0xffffffff;
510 	if (aac_sync_fib(sc, ContainerCommand, 0, &cc, sizeof(cc), NULL, NULL))
511 		printf("FAILED.\n");
512 	else {
513 		i = 0;
514 		/*
515 		 * XXX Issuing this command to the controller makes it shut down
516 		 * but also keeps it from coming back up without a reset of the
517 		 * PCI bus.  This is not desirable if you are just unloading the
518 		 * driver module with the intent to reload it later.
519 		 */
520 		if (aac_sync_fib(sc, FsaHostShutdown, AAC_FIBSTATE_SHUTDOWN, &i,
521 				 sizeof(i), NULL, NULL)) {
522 			printf("FAILED.\n");
523 		} else {
524 			printf("done.\n");
525 		}
526 	}
527 
528 	AAC_MASK_INTERRUPTS(sc);
529 
530 	splx(s);
531 	return(0);
532 }
533 
534 /*
535  * Bring the controller to a quiescent state, ready for system suspend.
536  */
537 int
538 aac_suspend(device_t dev)
539 {
540 	struct aac_softc *sc;
541 	int s;
542 
543 	debug_called(1);
544 
545 	sc = device_get_softc(dev);
546 
547 	s = splbio();
548 
549 	sc->aac_state |= AAC_STATE_SUSPEND;
550 
551 	AAC_MASK_INTERRUPTS(sc);
552 	splx(s);
553 	return(0);
554 }
555 
556 /*
557  * Bring the controller back to a state ready for operation.
558  */
559 int
560 aac_resume(device_t dev)
561 {
562 	struct aac_softc *sc;
563 
564 	debug_called(1);
565 
566 	sc = device_get_softc(dev);
567 
568 	sc->aac_state &= ~AAC_STATE_SUSPEND;
569 	AAC_UNMASK_INTERRUPTS(sc);
570 	return(0);
571 }
572 
573 /*
574  * Take an interrupt.
575  */
576 void
577 aac_intr(void *arg)
578 {
579 	struct aac_softc *sc;
580 	u_int16_t reason;
581 
582 	debug_called(2);
583 
584 	sc = (struct aac_softc *)arg;
585 
586 	reason = AAC_GET_ISTATUS(sc);
587 
588 	/* controller wants to talk to the log?  Defer it to the AIF thread */
589 	if (reason & AAC_DB_PRINTF) {
590 		AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF);
591 		if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
592 			sc->aifflags |= AAC_AIFFLAGS_PENDING;
593 			wakeup(sc->aifthread);
594 		} else
595 			aac_print_printf(sc);
596 	}
597 
598 	/* controller has a message for us? */
599 	if (reason & AAC_DB_COMMAND_READY) {
600 		AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_READY);
601 		/* XXX What happens if the thread is already awake? */
602 		if (sc->aifflags & AAC_AIFFLAGS_RUNNING) {
603 			sc->aifflags |= AAC_AIFFLAGS_PENDING;
604 			wakeup(sc->aifthread);
605 		}
606 	}
607 
608 	/* controller has a response for us? */
609 	if (reason & AAC_DB_RESPONSE_READY) {
610 		AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
611 		aac_host_response(sc);
612 	}
613 
614 	/*
615 	 * spurious interrupts that we don't use - reset the mask and clear the
616 	 * interrupts
617 	 */
618 	if (reason & (AAC_DB_COMMAND_NOT_FULL | AAC_DB_RESPONSE_NOT_FULL)) {
619 		AAC_UNMASK_INTERRUPTS(sc);
620 		AAC_CLEAR_ISTATUS(sc, AAC_DB_COMMAND_NOT_FULL |
621 				  AAC_DB_RESPONSE_NOT_FULL);
622 	}
623 };
624 
625 /*
626  * Command Processing
627  */
628 
629 /*
630  * Start as much queued I/O as possible on the controller
631  */
632 static void
633 aac_startio(struct aac_softc *sc)
634 {
635 	struct aac_command *cm;
636 
637 	debug_called(2);
638 
639 	for (;;) {
640 		/*
641 		 * Try to get a command that's been put off for lack of
642 		 * resources
643 		 */
644 		cm = aac_dequeue_ready(sc);
645 
646 		/*
647 		 * Try to build a command off the bio queue (ignore error
648 		 * return)
649 		 */
650 		if (cm == NULL)
651 			aac_bio_command(sc, &cm);
652 
653 		/* nothing to do? */
654 		if (cm == NULL)
655 			break;
656 
657 		/* try to give the command to the controller */
658 		if (aac_start(cm) == EBUSY) {
659 			/* put it on the ready queue for later */
660 			aac_requeue_ready(cm);
661 			break;
662 		}
663 	}
664 }
665 
666 /*
667  * Deliver a command to the controller; allocate controller resources at the
668  * last moment when possible.
669  */
670 static int
671 aac_start(struct aac_command *cm)
672 {
673 	struct aac_softc *sc;
674 	int error;
675 
676 	debug_called(2);
677 
678 	sc = cm->cm_sc;
679 
680 	/* get the command mapped */
681 	aac_map_command(cm);
682 
683 	/* fix up the address values in the FIB */
684 	cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib;
685 	cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
686 
687 	/* save a pointer to the command for speedy reverse-lookup */
688 	cm->cm_fib->Header.SenderData = (u_int32_t)cm;	/* XXX 64-bit physical
689 							 * address issue */
690 
691 	/* put the FIB on the outbound queue */
692 	error = aac_enqueue_fib(sc, cm->cm_queue, cm);
693 	return(error);
694 }
695 
696 /*
697  * Handle notification of one or more FIBs coming from the controller.
698  */
699 static void
700 aac_host_command(struct aac_softc *sc)
701 {
702 	struct aac_fib *fib;
703 	u_int32_t fib_size;
704 	int size;
705 
706 	debug_called(2);
707 
708 	sc->aifflags |= AAC_AIFFLAGS_RUNNING;
709 
710 	while (!(sc->aifflags & AAC_AIFFLAGS_EXIT)) {
711 		if (!(sc->aifflags & AAC_AIFFLAGS_PENDING))
712 			tsleep(sc->aifthread, PRIBIO, "aifthd", 15 * hz);
713 
714 		sc->aifflags &= ~AAC_AIFFLAGS_PENDING;
715 		for (;;) {
716 			if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE,
717 					    &fib_size, &fib))
718 				break;	/* nothing to do */
719 
720 			AAC_PRINT_FIB(sc, fib);
721 
722 			switch (fib->Header.Command) {
723 			case AifRequest:
724 				aac_handle_aif(sc, fib);
725 				break;
726 			default:
727 				device_printf(sc->aac_dev, "unknown command "
728 					      "from controller\n");
729 				break;
730 			}
731 
732 			/* Return the AIF to the controller. */
733 			if ((fib->Header.XferState == 0) ||
734 			    (fib->Header.StructType != AAC_FIBTYPE_TFIB))
735 				break;
736 
737 			if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) {
738 				fib->Header.XferState |= AAC_FIBSTATE_DONEHOST;
739 				*(AAC_FSAStatus*)fib->data = ST_OK;
740 
741 				/* XXX Compute the Size field? */
742 				size = fib->Header.Size;
743 				if (size > sizeof(struct aac_fib)) {
744 	 				size = sizeof(struct aac_fib);
745 					fib->Header.Size = size;
746 				}
747 				/*
748 				 * Since we did not generate this command, it
749 				 * cannot go through the normal
750 				 * enqueue->startio chain.
751 				 */
752 				aac_enqueue_response(sc,
753 						     AAC_ADAP_NORM_RESP_QUEUE,
754 						     fib);
755 			}
756 		}
757 		aac_print_printf(sc);
758 
759 	}
760 	sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
761 	wakeup(sc->aac_dev);
762 
763 #if __FreeBSD_version > 500005
764 	mtx_lock(&Giant);
765 #endif
766 	kthread_exit(0);
767 }
768 
769 /*
770  * Handle notification of one or more FIBs completed by the controller
771  */
772 static void
773 aac_host_response(struct aac_softc *sc)
774 {
775 	struct aac_command *cm;
776 	struct aac_fib *fib;
777 	u_int32_t fib_size;
778 
779 	debug_called(2);
780 
781 	for (;;) {
782 		/* look for completed FIBs on our queue */
783 		if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
784 				    &fib))
785 			break;	/* nothing to do */
786 
787 		/* get the command, unmap and queue for later processing */
788 		cm = (struct aac_command *)fib->Header.SenderData;
789 		if (cm == NULL) {
790 			AAC_PRINT_FIB(sc, fib);
791 		} else {
792 			aac_remove_busy(cm);
793 			aac_unmap_command(cm);		/* XXX defer? */
794 			aac_enqueue_complete(cm);
795 		}
796 	}
797 
798 	/* handle completion processing */
799 #if __FreeBSD_version >= 500005
800 	taskqueue_enqueue(taskqueue_swi, &sc->aac_task_complete);
801 #else
802 	aac_complete(sc, 0);
803 #endif
804 }
805 
806 /*
807  * Process completed commands.
808  */
809 static void
810 aac_complete(void *context, int pending)
811 {
812 	struct aac_softc *sc;
813 	struct aac_command *cm;
814 
815 	debug_called(2);
816 
817 	sc = (struct aac_softc *)context;
818 
819 	/* pull completed commands off the queue */
820 	for (;;) {
821 		cm = aac_dequeue_complete(sc);
822 		if (cm == NULL)
823 			break;
824 		cm->cm_flags |= AAC_CMD_COMPLETED;
825 
826 		/* is there a completion handler? */
827 		if (cm->cm_complete != NULL) {
828 			cm->cm_complete(cm);
829 		} else {
830 			/* assume that someone is sleeping on this command */
831 			wakeup(cm);
832 		}
833 	}
834 
835 	/* see if we can start some more I/O */
836 	aac_startio(sc);
837 }
838 
839 /*
840  * Handle a bio submitted from a disk device.
841  */
842 void
843 aac_submit_bio(struct bio *bp)
844 {
845 	struct aac_disk *ad;
846 	struct aac_softc *sc;
847 
848 	debug_called(2);
849 
850 	ad = (struct aac_disk *)bp->bio_dev->si_drv1;
851 	sc = ad->ad_controller;
852 
853 	/* queue the BIO and try to get some work done */
854 	aac_enqueue_bio(sc, bp);
855 	aac_startio(sc);
856 }
857 
858 /*
859  * Get a bio and build a command to go with it.
860  */
861 static int
862 aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
863 {
864 	struct aac_command *cm;
865 	struct aac_fib *fib;
866 	struct aac_blockread *br;
867 	struct aac_blockwrite *bw;
868 	struct aac_disk *ad;
869 	struct bio *bp;
870 
871 	debug_called(2);
872 
873 	/* get the resources we will need */
874 	cm = NULL;
875 	if ((bp = aac_dequeue_bio(sc)) == NULL)
876 		goto fail;
877 	if (aac_alloc_command(sc, &cm))	/* get a command */
878 		goto fail;
879 
880 	/* fill out the command */
881 	cm->cm_data = (void *)bp->bio_data;
882 	cm->cm_datalen = bp->bio_bcount;
883 	cm->cm_complete = aac_bio_complete;
884 	cm->cm_private = bp;
885 	cm->cm_timestamp = time_second;
886 	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
887 
888 	/* build the FIB */
889 	fib = cm->cm_fib;
890 	fib->Header.XferState =
891 	AAC_FIBSTATE_HOSTOWNED   |
892 	AAC_FIBSTATE_INITIALISED |
893 	AAC_FIBSTATE_FROMHOST	 |
894 	AAC_FIBSTATE_REXPECTED   |
895 	AAC_FIBSTATE_NORM;
896 	fib->Header.Command = ContainerCommand;
897 	fib->Header.Size = sizeof(struct aac_fib_header);
898 
899 	/* build the read/write request */
900 	ad = (struct aac_disk *)bp->bio_dev->si_drv1;
901 	if (BIO_IS_READ(bp)) {
902 		br = (struct aac_blockread *)&fib->data[0];
903 		br->Command = VM_CtBlockRead;
904 		br->ContainerId = ad->ad_container->co_mntobj.ObjectId;
905 		br->BlockNumber = bp->bio_pblkno;
906 		br->ByteCount = bp->bio_bcount;
907 		fib->Header.Size += sizeof(struct aac_blockread);
908 		cm->cm_sgtable = &br->SgMap;
909 		cm->cm_flags |= AAC_CMD_DATAIN;
910 	} else {
911 		bw = (struct aac_blockwrite *)&fib->data[0];
912 		bw->Command = VM_CtBlockWrite;
913 		bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
914 		bw->BlockNumber = bp->bio_pblkno;
915 		bw->ByteCount = bp->bio_bcount;
916 		bw->Stable = CUNSTABLE;	/* XXX what's appropriate here? */
917 		fib->Header.Size += sizeof(struct aac_blockwrite);
918 		cm->cm_flags |= AAC_CMD_DATAOUT;
919 		cm->cm_sgtable = &bw->SgMap;
920 	}
921 
922 	*cmp = cm;
923 	return(0);
924 
925 fail:
926 	if (bp != NULL)
927 		aac_enqueue_bio(sc, bp);
928 	if (cm != NULL)
929 		aac_release_command(cm);
930 	return(ENOMEM);
931 }
932 
933 /*
934  * Handle a bio-instigated command that has been completed.
935  */
936 static void
937 aac_bio_complete(struct aac_command *cm)
938 {
939 	struct aac_blockread_response *brr;
940 	struct aac_blockwrite_response *bwr;
941 	struct bio *bp;
942 	AAC_FSAStatus status;
943 
944 	/* fetch relevant status and then release the command */
945 	bp = (struct bio *)cm->cm_private;
946 	if (BIO_IS_READ(bp)) {
947 		brr = (struct aac_blockread_response *)&cm->cm_fib->data[0];
948 		status = brr->Status;
949 	} else {
950 		bwr = (struct aac_blockwrite_response *)&cm->cm_fib->data[0];
951 		status = bwr->Status;
952 	}
953 	aac_release_command(cm);
954 
955 	/* fix up the bio based on status */
956 	if (status == ST_OK) {
957 		bp->bio_resid = 0;
958 	} else {
959 		bp->bio_error = EIO;
960 		bp->bio_flags |= BIO_ERROR;
961 		/* pass an error string out to the disk layer */
962 		bp->bio_driver1 = aac_describe_code(aac_command_status_table,
963 						    status);
964 	}
965 	aac_biodone(bp);
966 }
967 
968 /*
969  * Dump a block of data to the controller.  If the queue is full, tell the
970  * caller to hold off and wait for the queue to drain.
971  */
972 int
973 aac_dump_enqueue(struct aac_disk *ad, u_int32_t lba, void *data, int dumppages)
974 {
975 	struct aac_softc *sc;
976 	struct aac_command *cm;
977 	struct aac_fib *fib;
978 	struct aac_blockwrite *bw;
979 
980 	sc = ad->ad_controller;
981 	cm = NULL;
982 
983 	if (aac_alloc_command(sc, &cm))
984 		return (EBUSY);
985 
986 	/* fill out the command */
987 	cm->cm_data = data;
988 	cm->cm_datalen = dumppages * PAGE_SIZE;
989 	cm->cm_complete = NULL;
990 	cm->cm_private = NULL;
991 	cm->cm_timestamp = time_second;
992 	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
993 
994 	/* build the FIB */
995 	fib = cm->cm_fib;
996 	fib->Header.XferState =
997 	AAC_FIBSTATE_HOSTOWNED   |
998 	AAC_FIBSTATE_INITIALISED |
999 	AAC_FIBSTATE_FROMHOST	 |
1000 	AAC_FIBSTATE_REXPECTED   |
1001 	AAC_FIBSTATE_NORM;
1002 	fib->Header.Command = ContainerCommand;
1003 	fib->Header.Size = sizeof(struct aac_fib_header);
1004 
1005 	bw = (struct aac_blockwrite *)&fib->data[0];
1006 	bw->Command = VM_CtBlockWrite;
1007 	bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
1008 	bw->BlockNumber = lba;
1009 	bw->ByteCount = dumppages * PAGE_SIZE;
1010 	bw->Stable = CUNSTABLE;		/* XXX what's appropriate here? */
1011 	fib->Header.Size += sizeof(struct aac_blockwrite);
1012 	cm->cm_flags |= AAC_CMD_DATAOUT;
1013 	cm->cm_sgtable = &bw->SgMap;
1014 
1015 	return (aac_start(cm));
1016 }
1017 
1018 /*
1019  * Wait for the card's queue to drain when dumping.  Also check for monitor
1020  * printf's
1021  */
1022 void
1023 aac_dump_complete(struct aac_softc *sc)
1024 {
1025 	struct aac_fib *fib;
1026 	struct aac_command *cm;
1027 	u_int16_t reason;
1028 	u_int32_t pi, ci, fib_size;
1029 
1030 	do {
1031 		reason = AAC_GET_ISTATUS(sc);
1032 		if (reason & AAC_DB_RESPONSE_READY) {
1033 			AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
1034 			for (;;) {
1035 				if (aac_dequeue_fib(sc,
1036 						    AAC_HOST_NORM_RESP_QUEUE,
1037 						    &fib_size, &fib))
1038 					break;
1039 				cm = (struct aac_command *)
1040 					fib->Header.SenderData;
1041 				if (cm == NULL)
1042 					AAC_PRINT_FIB(sc, fib);
1043 				else {
1044 					aac_remove_busy(cm);
1045 					aac_unmap_command(cm);
1046 					aac_enqueue_complete(cm);
1047 					aac_release_command(cm);
1048 				}
1049 			}
1050 		}
1051 		if (reason & AAC_DB_PRINTF) {
1052 			AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF);
1053 			aac_print_printf(sc);
1054 		}
1055 		pi = sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][
1056 			AAC_PRODUCER_INDEX];
1057 		ci = sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][
1058 			AAC_CONSUMER_INDEX];
1059 	} while (ci != pi);
1060 
1061 	return;
1062 }
1063 
1064 /*
1065  * Submit a command to the controller, return when it completes.
1066  */
1067 static int
1068 aac_wait_command(struct aac_command *cm, int timeout)
1069 {
1070 	int s, error = 0;
1071 
1072 	debug_called(2);
1073 
1074 	/* Put the command on the ready queue and get things going */
1075 	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
1076 	aac_enqueue_ready(cm);
1077 	aac_startio(cm->cm_sc);
1078 	s = splbio();
1079 	while (!(cm->cm_flags & AAC_CMD_COMPLETED) && (error != EWOULDBLOCK)) {
1080 		error = tsleep(cm, PRIBIO | PCATCH, "aacwait", 0);
1081 		if ((error == ERESTART) || (error == EINTR))
1082 			break;
1083 	}
1084 	splx(s);
1085 	return(error);
1086 }
1087 
1088 /*
1089  *Command Buffer Management
1090  */
1091 
1092 /*
1093  * Allocate a command.
1094  */
1095 static int
1096 aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
1097 {
1098 	struct aac_command *cm;
1099 
1100 	debug_called(3);
1101 
1102 	if ((cm = aac_dequeue_free(sc)) == NULL)
1103 		return(ENOMEM);
1104 
1105 	*cmp = cm;
1106 	return(0);
1107 }
1108 
1109 /*
1110  * Release a command back to the freelist.
1111  */
1112 static void
1113 aac_release_command(struct aac_command *cm)
1114 {
1115 	debug_called(3);
1116 
1117 	/* (re)initialise the command/FIB */
1118 	cm->cm_sgtable = NULL;
1119 	cm->cm_flags = 0;
1120 	cm->cm_complete = NULL;
1121 	cm->cm_private = NULL;
1122 	cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
1123 	cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
1124 	cm->cm_fib->Header.Flags = 0;
1125 	cm->cm_fib->Header.SenderSize = sizeof(struct aac_fib);
1126 
1127 	/*
1128 	 * These are duplicated in aac_start to cover the case where an
1129 	 * intermediate stage may have destroyed them.  They're left
1130 	 * initialised here for debugging purposes only.
1131 	 */
1132 	cm->cm_fib->Header.SenderFibAddress = (u_int32_t)cm->cm_fib;
1133 	cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
1134 
1135 	aac_enqueue_free(cm);
1136 }
1137 
1138 /*
1139  * Map helper for command/FIB allocation.
1140  */
1141 static void
1142 aac_map_command_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1143 {
1144 	struct aac_softc *sc;
1145 
1146 	sc = (struct aac_softc *)arg;
1147 
1148 	debug_called(3);
1149 
1150 	sc->aac_fibphys = segs[0].ds_addr;
1151 }
1152 
1153 /*
1154  * Allocate and initialise commands/FIBs for this adapter.
1155  */
1156 static int
1157 aac_alloc_commands(struct aac_softc *sc)
1158 {
1159 	struct aac_command *cm;
1160 	int i;
1161 
1162 	debug_called(1);
1163 
1164 	/* allocate the FIBs in DMAable memory and load them */
1165 	if (bus_dmamem_alloc(sc->aac_fib_dmat, (void **)&sc->aac_fibs,
1166 			 BUS_DMA_NOWAIT, &sc->aac_fibmap)) {
1167 		return(ENOMEM);
1168 	}
1169 	bus_dmamap_load(sc->aac_fib_dmat, sc->aac_fibmap, sc->aac_fibs,
1170 			AAC_FIB_COUNT * sizeof(struct aac_fib),
1171 			aac_map_command_helper, sc, 0);
1172 
1173 	/* initialise constant fields in the command structure */
1174 	for (i = 0; i < AAC_FIB_COUNT; i++) {
1175 		cm = &sc->aac_command[i];
1176 		cm->cm_sc = sc;
1177 		cm->cm_fib = sc->aac_fibs + i;
1178 		cm->cm_fibphys = sc->aac_fibphys + (i * sizeof(struct aac_fib));
1179 
1180 		if (!bus_dmamap_create(sc->aac_buffer_dmat, 0, &cm->cm_datamap))
1181 			aac_release_command(cm);
1182 	}
1183 	return(0);
1184 }
1185 
1186 /*
1187  * Free FIBs owned by this adapter.
1188  */
1189 static void
1190 aac_free_commands(struct aac_softc *sc)
1191 {
1192 	int i;
1193 
1194 	debug_called(1);
1195 
1196 	for (i = 0; i < AAC_FIB_COUNT; i++)
1197 		bus_dmamap_destroy(sc->aac_buffer_dmat,
1198 				   sc->aac_command[i].cm_datamap);
1199 
1200 	bus_dmamap_unload(sc->aac_fib_dmat, sc->aac_fibmap);
1201 	bus_dmamem_free(sc->aac_fib_dmat, sc->aac_fibs, sc->aac_fibmap);
1202 }
1203 
1204 /*
1205  * Command-mapping helper function - populate this command's s/g table.
1206  */
1207 static void
1208 aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1209 {
1210 	struct aac_command *cm;
1211 	struct aac_fib *fib;
1212 	struct aac_sg_table *sg;
1213 	int i;
1214 
1215 	debug_called(3);
1216 
1217 	cm = (struct aac_command *)arg;
1218 	fib = cm->cm_fib;
1219 
1220 	/* find the s/g table */
1221 	sg = cm->cm_sgtable;
1222 
1223 	/* copy into the FIB */
1224 	if (sg != NULL) {
1225 		sg->SgCount = nseg;
1226 		for (i = 0; i < nseg; i++) {
1227 			sg->SgEntry[i].SgAddress = segs[i].ds_addr;
1228 			sg->SgEntry[i].SgByteCount = segs[i].ds_len;
1229 		}
1230 		/* update the FIB size for the s/g count */
1231 		fib->Header.Size += nseg * sizeof(struct aac_sg_entry);
1232 	}
1233 
1234 }
1235 
1236 /*
1237  * Map a command into controller-visible space.
1238  */
1239 static void
1240 aac_map_command(struct aac_command *cm)
1241 {
1242 	struct aac_softc *sc;
1243 
1244 	debug_called(2);
1245 
1246 	sc = cm->cm_sc;
1247 
1248 	/* don't map more than once */
1249 	if (cm->cm_flags & AAC_CMD_MAPPED)
1250 		return;
1251 
1252 	if (cm->cm_datalen != 0) {
1253 		bus_dmamap_load(sc->aac_buffer_dmat, cm->cm_datamap,
1254 				cm->cm_data, cm->cm_datalen,
1255 				aac_map_command_sg, cm, 0);
1256 
1257 	if (cm->cm_flags & AAC_CMD_DATAIN)
1258 		bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1259 				BUS_DMASYNC_PREREAD);
1260 	if (cm->cm_flags & AAC_CMD_DATAOUT)
1261 		bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1262 				BUS_DMASYNC_PREWRITE);
1263 	}
1264 	cm->cm_flags |= AAC_CMD_MAPPED;
1265 }
1266 
1267 /*
1268  * Unmap a command from controller-visible space.
1269  */
1270 static void
1271 aac_unmap_command(struct aac_command *cm)
1272 {
1273 	struct aac_softc *sc;
1274 
1275 	debug_called(2);
1276 
1277 	sc = cm->cm_sc;
1278 
1279 	if (!(cm->cm_flags & AAC_CMD_MAPPED))
1280 		return;
1281 
1282 	if (cm->cm_datalen != 0) {
1283 		if (cm->cm_flags & AAC_CMD_DATAIN)
1284 			bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1285 					BUS_DMASYNC_POSTREAD);
1286 		if (cm->cm_flags & AAC_CMD_DATAOUT)
1287 			bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
1288 					BUS_DMASYNC_POSTWRITE);
1289 
1290 		bus_dmamap_unload(sc->aac_buffer_dmat, cm->cm_datamap);
1291 	}
1292 	cm->cm_flags &= ~AAC_CMD_MAPPED;
1293 }
1294 
1295 /*
1296  * Hardware Interface
1297  */
1298 
1299 /*
1300  * Initialise the adapter.
1301  */
1302 static void
1303 aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
1304 {
1305 	struct aac_softc *sc;
1306 
1307 	debug_called(1);
1308 
1309 	sc = (struct aac_softc *)arg;
1310 
1311 	sc->aac_common_busaddr = segs[0].ds_addr;
1312 }
1313 
1314 static int
1315 aac_init(struct aac_softc *sc)
1316 {
1317 	struct aac_adapter_init	*ip;
1318 	time_t then;
1319 	u_int32_t code;
1320 	u_int8_t *qaddr;
1321 
1322 	debug_called(1);
1323 
1324 	/*
1325 	 * First wait for the adapter to come ready.
1326 	 */
1327 	then = time_second;
1328 	do {
1329 		code = AAC_GET_FWSTATUS(sc);
1330 		if (code & AAC_SELF_TEST_FAILED) {
1331 			device_printf(sc->aac_dev, "FATAL: selftest failed\n");
1332 			return(ENXIO);
1333 		}
1334 		if (code & AAC_KERNEL_PANIC) {
1335 			device_printf(sc->aac_dev,
1336 				      "FATAL: controller kernel panic\n");
1337 			return(ENXIO);
1338 		}
1339 		if (time_second > (then + AAC_BOOT_TIMEOUT)) {
1340 			device_printf(sc->aac_dev,
1341 				      "FATAL: controller not coming ready, "
1342 					   "status %x\n", code);
1343 			return(ENXIO);
1344 		}
1345 	} while (!(code & AAC_UP_AND_RUNNING));
1346 
1347 	/*
1348 	 * Create DMA tag for the common structure and allocate it.
1349 	 */
1350 	if (bus_dma_tag_create(sc->aac_parent_dmat, 	/* parent */
1351 			       1, 0, 			/* algnmnt, boundary */
1352 			       BUS_SPACE_MAXADDR,	/* lowaddr */
1353 			       BUS_SPACE_MAXADDR, 	/* highaddr */
1354 			       NULL, NULL, 		/* filter, filterarg */
1355 			       sizeof(struct aac_common), /* maxsize */
1356 			       1,			/* nsegments */
1357 			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
1358 			       0,			/* flags */
1359 			       &sc->aac_common_dmat)) {
1360 		device_printf(sc->aac_dev,
1361 			      "can't allocate common structure DMA tag\n");
1362 		return(ENOMEM);
1363 	}
1364 	if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common,
1365 			     BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
1366 		device_printf(sc->aac_dev, "can't allocate common structure\n");
1367 		return(ENOMEM);
1368 	}
1369 	bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
1370 			sc->aac_common, sizeof(*sc->aac_common), aac_common_map,
1371 		        sc, 0);
1372 	bzero(sc->aac_common, sizeof(*sc->aac_common));
1373 
1374 	/*
1375 	 * Fill in the init structure.  This tells the adapter about the
1376 	 * physical location of various important shared data structures.
1377 	 */
1378 	ip = &sc->aac_common->ac_init;
1379 	ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
1380 
1381 	ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
1382 					 offsetof(struct aac_common, ac_fibs);
1383 	ip->AdapterFibsVirtualAddress = &sc->aac_common->ac_fibs[0];
1384 	ip->AdapterFibsSize = AAC_ADAPTER_FIBS * sizeof(struct aac_fib);
1385 	ip->AdapterFibAlign = sizeof(struct aac_fib);
1386 
1387 	ip->PrintfBufferAddress = sc->aac_common_busaddr +
1388 				  offsetof(struct aac_common, ac_printf);
1389 	ip->PrintfBufferSize = AAC_PRINTF_BUFSIZE;
1390 
1391 	ip->HostPhysMemPages = 0;		/* not used? */
1392 	ip->HostElapsedSeconds = time_second;	/* reset later if invalid */
1393 
1394 	/*
1395 	 * Initialise FIB queues.  Note that it appears that the layout of the
1396 	 * indexes and the segmentation of the entries may be mandated by the
1397 	 * adapter, which is only told about the base of the queue index fields.
1398 	 *
1399 	 * The initial values of the indices are assumed to inform the adapter
1400 	 * of the sizes of the respective queues, and theoretically it could
1401 	 * work out the entire layout of the queue structures from this.  We
1402 	 * take the easy route and just lay this area out like everyone else
1403 	 * does.
1404 	 *
1405 	 * The Linux driver uses a much more complex scheme whereby several
1406 	 * header records are kept for each queue.  We use a couple of generic
1407 	 * list manipulation functions which 'know' the size of each list by
1408 	 * virtue of a table.
1409 	 */
1410 	qaddr = &sc->aac_common->ac_qbuf[0] + AAC_QUEUE_ALIGN;
1411 	qaddr -= (u_int32_t)qaddr % AAC_QUEUE_ALIGN;
1412 	sc->aac_queues = (struct aac_queue_table *)qaddr;
1413 	ip->CommHeaderAddress = sc->aac_common_busaddr +
1414 				((u_int32_t)sc->aac_queues -
1415 				(u_int32_t)sc->aac_common);
1416 	bzero(sc->aac_queues, sizeof(struct aac_queue_table));
1417 
1418 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1419 		AAC_HOST_NORM_CMD_ENTRIES;
1420 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1421 		AAC_HOST_NORM_CMD_ENTRIES;
1422 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1423 		AAC_HOST_HIGH_CMD_ENTRIES;
1424 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1425 		AAC_HOST_HIGH_CMD_ENTRIES;
1426 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1427 		AAC_ADAP_NORM_CMD_ENTRIES;
1428 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1429 		AAC_ADAP_NORM_CMD_ENTRIES;
1430 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_PRODUCER_INDEX] =
1431 		AAC_ADAP_HIGH_CMD_ENTRIES;
1432 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][AAC_CONSUMER_INDEX] =
1433 		AAC_ADAP_HIGH_CMD_ENTRIES;
1434 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1435 		AAC_HOST_NORM_RESP_ENTRIES;
1436 	sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1437 		AAC_HOST_NORM_RESP_ENTRIES;
1438 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1439 		AAC_HOST_HIGH_RESP_ENTRIES;
1440 	sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1441 		AAC_HOST_HIGH_RESP_ENTRIES;
1442 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1443 		AAC_ADAP_NORM_RESP_ENTRIES;
1444 	sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1445 		AAC_ADAP_NORM_RESP_ENTRIES;
1446 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_PRODUCER_INDEX]=
1447 		AAC_ADAP_HIGH_RESP_ENTRIES;
1448 	sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][AAC_CONSUMER_INDEX]=
1449 		AAC_ADAP_HIGH_RESP_ENTRIES;
1450 	sc->aac_qentries[AAC_HOST_NORM_CMD_QUEUE] =
1451 		&sc->aac_queues->qt_HostNormCmdQueue[0];
1452 	sc->aac_qentries[AAC_HOST_HIGH_CMD_QUEUE] =
1453 		&sc->aac_queues->qt_HostHighCmdQueue[0];
1454 	sc->aac_qentries[AAC_ADAP_NORM_CMD_QUEUE] =
1455 		&sc->aac_queues->qt_AdapNormCmdQueue[0];
1456 	sc->aac_qentries[AAC_ADAP_HIGH_CMD_QUEUE] =
1457 		&sc->aac_queues->qt_AdapHighCmdQueue[0];
1458 	sc->aac_qentries[AAC_HOST_NORM_RESP_QUEUE] =
1459 		&sc->aac_queues->qt_HostNormRespQueue[0];
1460 	sc->aac_qentries[AAC_HOST_HIGH_RESP_QUEUE] =
1461 		&sc->aac_queues->qt_HostHighRespQueue[0];
1462 	sc->aac_qentries[AAC_ADAP_NORM_RESP_QUEUE] =
1463 		&sc->aac_queues->qt_AdapNormRespQueue[0];
1464 	sc->aac_qentries[AAC_ADAP_HIGH_RESP_QUEUE] =
1465 		&sc->aac_queues->qt_AdapHighRespQueue[0];
1466 
1467 	/*
1468 	 * Do controller-type-specific initialisation
1469 	 */
1470 	switch (sc->aac_hwif) {
1471 	case AAC_HWIF_I960RX:
1472 		AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
1473 		break;
1474 	}
1475 
1476 	/*
1477 	 * Give the init structure to the controller.
1478 	 */
1479 	if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
1480 			     sc->aac_common_busaddr +
1481 			     offsetof(struct aac_common, ac_init), 0, 0, 0,
1482 			     NULL)) {
1483 		device_printf(sc->aac_dev,
1484 			      "error establishing init structure\n");
1485 		return(EIO);
1486 	}
1487 
1488 	return(0);
1489 }
1490 
1491 /*
1492  * Send a synchronous command to the controller and wait for a result.
1493  */
1494 static int
1495 aac_sync_command(struct aac_softc *sc, u_int32_t command,
1496 		 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3,
1497 		 u_int32_t *sp)
1498 {
1499 	time_t then;
1500 	u_int32_t status;
1501 
1502 	debug_called(3);
1503 
1504 	/* populate the mailbox */
1505 	AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
1506 
1507 	/* ensure the sync command doorbell flag is cleared */
1508 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1509 
1510 	/* then set it to signal the adapter */
1511 	AAC_QNOTIFY(sc, AAC_DB_SYNC_COMMAND);
1512 
1513 	/* spin waiting for the command to complete */
1514 	then = time_second;
1515 	do {
1516 		if (time_second > (then + AAC_IMMEDIATE_TIMEOUT)) {
1517 			debug(2, "timed out");
1518 			return(EIO);
1519 		}
1520 	} while (!(AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND));
1521 
1522 	/* clear the completion flag */
1523 	AAC_CLEAR_ISTATUS(sc, AAC_DB_SYNC_COMMAND);
1524 
1525 	/* get the command status */
1526 	status = AAC_GET_MAILBOXSTATUS(sc);
1527 	if (sp != NULL)
1528 		*sp = status;
1529 	return(0);
1530 }
1531 
1532 /*
1533  * Send a synchronous FIB to the controller and wait for a result.
1534  */
1535 static int
1536 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
1537 		 void *data, u_int16_t datasize,
1538 		 void *result, u_int16_t *resultsize)
1539 {
1540 	struct aac_fib *fib;
1541 
1542 	debug_called(3);
1543 
1544 	fib = &sc->aac_common->ac_sync_fib;
1545 
1546 	if (datasize > AAC_FIB_DATASIZE)
1547 		return(EINVAL);
1548 
1549 	/*
1550 	 * Set up the sync FIB
1551 	 */
1552 	fib->Header.XferState = AAC_FIBSTATE_HOSTOWNED |
1553 				AAC_FIBSTATE_INITIALISED |
1554 				AAC_FIBSTATE_EMPTY;
1555 	fib->Header.XferState |= xferstate;
1556 	fib->Header.Command = command;
1557 	fib->Header.StructType = AAC_FIBTYPE_TFIB;
1558 	fib->Header.Size = sizeof(struct aac_fib) + datasize;
1559 	fib->Header.SenderSize = sizeof(struct aac_fib);
1560 	fib->Header.SenderFibAddress = (u_int32_t)fib;
1561 	fib->Header.ReceiverFibAddress = sc->aac_common_busaddr +
1562 					 offsetof(struct aac_common,
1563 						  ac_sync_fib);
1564 
1565 	/*
1566 	 * Copy in data.
1567 	 */
1568 	if (data != NULL) {
1569 		KASSERT(datasize <= sizeof(fib->data),
1570 			("aac_sync_fib: datasize to large"));
1571 		bcopy(data, fib->data, datasize);
1572 		fib->Header.XferState |= AAC_FIBSTATE_FROMHOST |
1573 					 AAC_FIBSTATE_NORM;
1574 	}
1575 
1576 	/*
1577 	 * Give the FIB to the controller, wait for a response.
1578 	 */
1579 	if (aac_sync_command(sc, AAC_MONKER_SYNCFIB,
1580 			     fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) {
1581 		debug(2, "IO error");
1582 		return(EIO);
1583 	}
1584 
1585 	/*
1586 	 * Copy out the result
1587 	 */
1588 	if (result != NULL) {
1589 		u_int copysize;
1590 
1591 		copysize = fib->Header.Size - sizeof(struct aac_fib_header);
1592 		if (copysize > *resultsize)
1593 			copysize = *resultsize;
1594 		*resultsize = fib->Header.Size - sizeof(struct aac_fib_header);
1595 		bcopy(fib->data, result, copysize);
1596 	}
1597 	return(0);
1598 }
1599 
1600 /*
1601  * Adapter-space FIB queue manipulation
1602  *
1603  * Note that the queue implementation here is a little funky; neither the PI or
1604  * CI will ever be zero.  This behaviour is a controller feature.
1605  */
1606 static struct {
1607 	int		size;
1608 	int		notify;
1609 } aac_qinfo[] = {
1610 	{AAC_HOST_NORM_CMD_ENTRIES, AAC_DB_COMMAND_NOT_FULL},
1611 	{AAC_HOST_HIGH_CMD_ENTRIES, 0},
1612 	{AAC_ADAP_NORM_CMD_ENTRIES, AAC_DB_COMMAND_READY},
1613 	{AAC_ADAP_HIGH_CMD_ENTRIES, 0},
1614 	{AAC_HOST_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_NOT_FULL},
1615 	{AAC_HOST_HIGH_RESP_ENTRIES, 0},
1616 	{AAC_ADAP_NORM_RESP_ENTRIES, AAC_DB_RESPONSE_READY},
1617 	{AAC_ADAP_HIGH_RESP_ENTRIES, 0}
1618 };
1619 
1620 /*
1621  * Atomically insert an entry into the nominated queue, returns 0 on success or
1622  * EBUSY if the queue is full.
1623  *
1624  * Note: it would be more efficient to defer notifying the controller in
1625  *	 the case where we may be inserting several entries in rapid succession,
1626  *	 but implementing this usefully may be difficult (it would involve a
1627  *	 separate queue/notify interface).
1628  */
1629 static int
1630 aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm)
1631 {
1632 	u_int32_t pi, ci;
1633 	int s, error;
1634 	u_int32_t fib_size;
1635 	u_int32_t fib_addr;
1636 
1637 	debug_called(3);
1638 
1639 	fib_size = cm->cm_fib->Header.Size;
1640 	fib_addr = cm->cm_fib->Header.ReceiverFibAddress;
1641 
1642 	s = splbio();
1643 
1644 	/* get the producer/consumer indices */
1645 	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1646 	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1647 
1648 	/* wrap the queue? */
1649 	if (pi >= aac_qinfo[queue].size)
1650 		pi = 0;
1651 
1652 	/* check for queue full */
1653 	if ((pi + 1) == ci) {
1654 		error = EBUSY;
1655 		goto out;
1656 	}
1657 
1658 	/* populate queue entry */
1659 	(sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1660 	(sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1661 
1662 	/* update producer index */
1663 	sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1664 
1665 	/*
1666 	 * To avoid a race with its completion interrupt, place this command on
1667 	 * the busy queue prior to advertising it to the controller.
1668 	 */
1669 	aac_enqueue_busy(cm);
1670 
1671 	/* notify the adapter if we know how */
1672 	if (aac_qinfo[queue].notify != 0)
1673 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1674 
1675 	error = 0;
1676 
1677 out:
1678 	splx(s);
1679 	return(error);
1680 }
1681 
1682 /*
1683  * Atomically remove one entry from the nominated queue, returns 0 on
1684  * success or ENOENT if the queue is empty.
1685  */
1686 static int
1687 aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
1688 		struct aac_fib **fib_addr)
1689 {
1690 	u_int32_t pi, ci;
1691 	int s, error;
1692 	int notify;
1693 
1694 	debug_called(3);
1695 
1696 	s = splbio();
1697 
1698 	/* get the producer/consumer indices */
1699 	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1700 	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1701 
1702 	/* check for queue empty */
1703 	if (ci == pi) {
1704 		error = ENOENT;
1705 		goto out;
1706 	}
1707 
1708 	notify = 0;
1709 	if (ci == pi + 1)
1710 		notify++;
1711 
1712 	/* wrap the queue? */
1713 	if (ci >= aac_qinfo[queue].size)
1714 		ci = 0;
1715 
1716 	/* fetch the entry */
1717 	*fib_size = (sc->aac_qentries[queue] + ci)->aq_fib_size;
1718 	*fib_addr = (struct aac_fib *)(sc->aac_qentries[queue] +
1719 				       ci)->aq_fib_addr;
1720 
1721 	/* update consumer index */
1722 	sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX] = ci + 1;
1723 
1724 	/* if we have made the queue un-full, notify the adapter */
1725 	if (notify && (aac_qinfo[queue].notify != 0))
1726 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1727 	error = 0;
1728 
1729 out:
1730 	splx(s);
1731 	return(error);
1732 }
1733 
1734 /*
1735  * Put our response to an Adapter Initialed Fib on the response queue
1736  */
1737 static int
1738 aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
1739 {
1740 	u_int32_t pi, ci;
1741 	int s, error;
1742 	u_int32_t fib_size;
1743 	u_int32_t fib_addr;
1744 
1745 	debug_called(1);
1746 
1747 	/* Tell the adapter where the FIB is */
1748 	fib_size = fib->Header.Size;
1749 	fib_addr = fib->Header.SenderFibAddress;
1750 	fib->Header.ReceiverFibAddress = fib_addr;
1751 
1752 	s = splbio();
1753 
1754 	/* get the producer/consumer indices */
1755 	pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
1756 	ci = sc->aac_queues->qt_qindex[queue][AAC_CONSUMER_INDEX];
1757 
1758 	/* wrap the queue? */
1759 	if (pi >= aac_qinfo[queue].size)
1760 		pi = 0;
1761 
1762 	/* check for queue full */
1763 	if ((pi + 1) == ci) {
1764 		error = EBUSY;
1765 		goto out;
1766 	}
1767 
1768 	/* populate queue entry */
1769 	(sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
1770 	(sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
1771 
1772 	/* update producer index */
1773 	sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX] = pi + 1;
1774 
1775 	/* notify the adapter if we know how */
1776 	if (aac_qinfo[queue].notify != 0)
1777 		AAC_QNOTIFY(sc, aac_qinfo[queue].notify);
1778 
1779 	error = 0;
1780 
1781 out:
1782 	splx(s);
1783 	return(error);
1784 }
1785 
1786 /*
1787  * Check for commands that have been outstanding for a suspiciously long time,
1788  * and complain about them.
1789  */
1790 static void
1791 aac_timeout(struct aac_softc *sc)
1792 {
1793 	int s;
1794 	struct aac_command *cm;
1795 	time_t deadline;
1796 
1797 #if 0
1798 	/* simulate an interrupt to handle possibly-missed interrupts */
1799 	/*
1800 	 * XXX This was done to work around another bug which has since been
1801 	 * fixed.  It is dangerous anyways because you don't want multiple
1802 	 * threads in the interrupt handler at the same time!  If calling
1803 	 * is deamed neccesary in the future, proper mutexes must be used.
1804 	 */
1805 	s = splbio();
1806 	aac_intr(sc);
1807 	splx(s);
1808 
1809 	/* kick the I/O queue to restart it in the case of deadlock */
1810 	aac_startio(sc);
1811 #endif
1812 
1813 	/*
1814 	 * traverse the busy command list, bitch about late commands once
1815 	 * only.
1816 	 */
1817 	deadline = time_second - AAC_CMD_TIMEOUT;
1818 	s = splbio();
1819 	TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) {
1820 		if ((cm->cm_timestamp  < deadline)
1821 			/* && !(cm->cm_flags & AAC_CMD_TIMEDOUT) */) {
1822 			cm->cm_flags |= AAC_CMD_TIMEDOUT;
1823 			device_printf(sc->aac_dev,
1824 				      "COMMAND %p TIMEOUT AFTER %d SECONDS\n",
1825 				      cm, (int)(time_second-cm->cm_timestamp));
1826 			AAC_PRINT_FIB(sc, cm->cm_fib);
1827 		}
1828 	}
1829 	splx(s);
1830 
1831 	/* reset the timer for next time */
1832 	timeout((timeout_t*)aac_timeout, sc, AAC_PERIODIC_INTERVAL * hz);
1833 	return;
1834 }
1835 
1836 /*
1837  * Interface Function Vectors
1838  */
1839 
1840 /*
1841  * Read the current firmware status word.
1842  */
1843 static int
1844 aac_sa_get_fwstatus(struct aac_softc *sc)
1845 {
1846 	debug_called(3);
1847 
1848 	return(AAC_GETREG4(sc, AAC_SA_FWSTATUS));
1849 }
1850 
1851 static int
1852 aac_rx_get_fwstatus(struct aac_softc *sc)
1853 {
1854 	debug_called(3);
1855 
1856 	return(AAC_GETREG4(sc, AAC_RX_FWSTATUS));
1857 }
1858 
1859 /*
1860  * Notify the controller of a change in a given queue
1861  */
1862 
1863 static void
1864 aac_sa_qnotify(struct aac_softc *sc, int qbit)
1865 {
1866 	debug_called(3);
1867 
1868 	AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
1869 }
1870 
1871 static void
1872 aac_rx_qnotify(struct aac_softc *sc, int qbit)
1873 {
1874 	debug_called(3);
1875 
1876 	AAC_SETREG4(sc, AAC_RX_IDBR, qbit);
1877 }
1878 
1879 /*
1880  * Get the interrupt reason bits
1881  */
1882 static int
1883 aac_sa_get_istatus(struct aac_softc *sc)
1884 {
1885 	debug_called(3);
1886 
1887 	return(AAC_GETREG2(sc, AAC_SA_DOORBELL0));
1888 }
1889 
1890 static int
1891 aac_rx_get_istatus(struct aac_softc *sc)
1892 {
1893 	debug_called(3);
1894 
1895 	return(AAC_GETREG4(sc, AAC_RX_ODBR));
1896 }
1897 
1898 /*
1899  * Clear some interrupt reason bits
1900  */
1901 static void
1902 aac_sa_clear_istatus(struct aac_softc *sc, int mask)
1903 {
1904 	debug_called(3);
1905 
1906 	AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
1907 }
1908 
1909 static void
1910 aac_rx_clear_istatus(struct aac_softc *sc, int mask)
1911 {
1912 	debug_called(3);
1913 
1914 	AAC_SETREG4(sc, AAC_RX_ODBR, mask);
1915 }
1916 
1917 /*
1918  * Populate the mailbox and set the command word
1919  */
1920 static void
1921 aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
1922 		u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1923 {
1924 	debug_called(4);
1925 
1926 	AAC_SETREG4(sc, AAC_SA_MAILBOX, command);
1927 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
1928 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
1929 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
1930 	AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
1931 }
1932 
1933 static void
1934 aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
1935 		u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
1936 {
1937 	debug_called(4);
1938 
1939 	AAC_SETREG4(sc, AAC_RX_MAILBOX, command);
1940 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
1941 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
1942 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
1943 	AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
1944 }
1945 
1946 /*
1947  * Fetch the immediate command status word
1948  */
1949 static int
1950 aac_sa_get_mailboxstatus(struct aac_softc *sc)
1951 {
1952 	debug_called(4);
1953 
1954 	return(AAC_GETREG4(sc, AAC_SA_MAILBOX));
1955 }
1956 
1957 static int
1958 aac_rx_get_mailboxstatus(struct aac_softc *sc)
1959 {
1960 	debug_called(4);
1961 
1962 	return(AAC_GETREG4(sc, AAC_RX_MAILBOX));
1963 }
1964 
1965 /*
1966  * Set/clear interrupt masks
1967  */
1968 static void
1969 aac_sa_set_interrupts(struct aac_softc *sc, int enable)
1970 {
1971 	debug(2, "%sable interrupts", enable ? "en" : "dis");
1972 
1973 	if (enable) {
1974 		AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
1975 	} else {
1976 		AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
1977 	}
1978 }
1979 
1980 static void
1981 aac_rx_set_interrupts(struct aac_softc *sc, int enable)
1982 {
1983 	debug(2, "%sable interrupts", enable ? "en" : "dis");
1984 
1985 	if (enable) {
1986 		AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
1987 	} else {
1988 		AAC_SETREG4(sc, AAC_RX_OIMR, ~0);
1989 	}
1990 }
1991 
1992 /*
1993  * Debugging and Diagnostics
1994  */
1995 
1996 /*
1997  * Print some information about the controller.
1998  */
1999 static void
2000 aac_describe_controller(struct aac_softc *sc)
2001 {
2002 	u_int8_t buf[AAC_FIB_DATASIZE];	/* XXX really a bit big
2003 					 * for the stack */
2004 	u_int16_t bufsize;
2005 	struct aac_adapter_info	*info;
2006 	u_int8_t arg;
2007 
2008 	debug_called(2);
2009 
2010 	arg = 0;
2011 	bufsize = sizeof(buf);
2012 	if (aac_sync_fib(sc, RequestAdapterInfo, 0, &arg, sizeof(arg), &buf,
2013 			 &bufsize)) {
2014 		device_printf(sc->aac_dev, "RequestAdapterInfo failed\n");
2015 		return;
2016 	}
2017 	if (bufsize != sizeof(*info)) {
2018 		device_printf(sc->aac_dev,
2019 			      "RequestAdapterInfo returned wrong data size "
2020 			      "(%d != %d)\n", bufsize, sizeof(*info));
2021 		/*return;*/
2022 	}
2023 	info = (struct aac_adapter_info *)&buf[0];
2024 
2025 	device_printf(sc->aac_dev, "%s %dMHz, %dMB cache memory, %s\n",
2026 		      aac_describe_code(aac_cpu_variant, info->CpuVariant),
2027 		      info->ClockSpeed, info->BufferMem / (1024 * 1024),
2028 		      aac_describe_code(aac_battery_platform,
2029 					info->batteryPlatform));
2030 
2031 	/* save the kernel revision structure for later use */
2032 	sc->aac_revision = info->KernelRevision;
2033 	device_printf(sc->aac_dev, "Kernel %d.%d-%d, Build %d, S/N %6X\n",
2034 		      info->KernelRevision.external.comp.major,
2035 		      info->KernelRevision.external.comp.minor,
2036 		      info->KernelRevision.external.comp.dash,
2037 		      info->KernelRevision.buildNumber,
2038 		      (u_int32_t)(info->SerialNumber & 0xffffff));
2039 }
2040 
2041 /*
2042  * Look up a text description of a numeric error code and return a pointer to
2043  * same.
2044  */
2045 static char *
2046 aac_describe_code(struct aac_code_lookup *table, u_int32_t code)
2047 {
2048 	int i;
2049 
2050 	for (i = 0; table[i].string != NULL; i++)
2051 		if (table[i].code == code)
2052 			return(table[i].string);
2053 	return(table[i + 1].string);
2054 }
2055 
2056 /*
2057  * Management Interface
2058  */
2059 
2060 static int
2061 aac_open(dev_t dev, int flags, int fmt, struct thread *td)
2062 {
2063 	struct aac_softc *sc;
2064 
2065 	debug_called(2);
2066 
2067 	sc = dev->si_drv1;
2068 
2069 	/* Check to make sure the device isn't already open */
2070 	if (sc->aac_state & AAC_STATE_OPEN) {
2071 		return EBUSY;
2072 	}
2073 	sc->aac_state |= AAC_STATE_OPEN;
2074 
2075 	return 0;
2076 }
2077 
2078 static int
2079 aac_close(dev_t dev, int flags, int fmt, struct thread *td)
2080 {
2081 	struct aac_softc *sc;
2082 
2083 	debug_called(2);
2084 
2085 	sc = dev->si_drv1;
2086 
2087 	/* Mark this unit as no longer open  */
2088 	sc->aac_state &= ~AAC_STATE_OPEN;
2089 
2090 	return 0;
2091 }
2092 
2093 static int
2094 aac_ioctl(dev_t dev, u_long cmd, caddr_t arg, int flag, struct thread *td)
2095 {
2096 	union aac_statrequest *as;
2097 	struct aac_softc *sc;
2098 	int error = 0;
2099 	int i;
2100 
2101 	debug_called(2);
2102 
2103 	as = (union aac_statrequest *)arg;
2104 	sc = dev->si_drv1;
2105 
2106 	switch (cmd) {
2107 	case AACIO_STATS:
2108 		switch (as->as_item) {
2109 		case AACQ_FREE:
2110 		case AACQ_BIO:
2111 		case AACQ_READY:
2112 		case AACQ_BUSY:
2113 		case AACQ_COMPLETE:
2114 			bcopy(&sc->aac_qstat[as->as_item], &as->as_qstat,
2115 			      sizeof(struct aac_qstat));
2116 			break;
2117 		default:
2118 			error = ENOENT;
2119 			break;
2120 		}
2121 	break;
2122 
2123 	case FSACTL_SENDFIB:
2124 		arg = *(caddr_t*)arg;
2125 	case FSACTL_LNX_SENDFIB:
2126 		debug(1, "FSACTL_SENDFIB");
2127 		error = aac_ioctl_sendfib(sc, arg);
2128 		break;
2129 	case FSACTL_AIF_THREAD:
2130 	case FSACTL_LNX_AIF_THREAD:
2131 		debug(1, "FSACTL_AIF_THREAD");
2132 		error = EINVAL;
2133 		break;
2134 	case FSACTL_OPEN_GET_ADAPTER_FIB:
2135 		arg = *(caddr_t*)arg;
2136 		case FSACTL_LNX_OPEN_GET_ADAPTER_FIB:
2137 		debug(1, "FSACTL_OPEN_GET_ADAPTER_FIB");
2138 		/*
2139 		 * Pass the caller out an AdapterFibContext.
2140 		 *
2141 		 * Note that because we only support one opener, we
2142 		 * basically ignore this.  Set the caller's context to a magic
2143 		 * number just in case.
2144 		 *
2145 		 * The Linux code hands the driver a pointer into kernel space,
2146 		 * and then trusts it when the caller hands it back.  Aiee!
2147 		 * Here, we give it the proc pointer of the per-adapter aif
2148 		 * thread. It's only used as a sanity check in other calls.
2149 		 */
2150 		i = (int)sc->aifthread;
2151 		error = copyout(&i, arg, sizeof(i));
2152 		break;
2153 	case FSACTL_GET_NEXT_ADAPTER_FIB:
2154 		arg = *(caddr_t*)arg;
2155 	case FSACTL_LNX_GET_NEXT_ADAPTER_FIB:
2156 		debug(1, "FSACTL_GET_NEXT_ADAPTER_FIB");
2157 		error = aac_getnext_aif(sc, arg);
2158 		break;
2159 	case FSACTL_CLOSE_GET_ADAPTER_FIB:
2160 	case FSACTL_LNX_CLOSE_GET_ADAPTER_FIB:
2161 		debug(1, "FSACTL_CLOSE_GET_ADAPTER_FIB");
2162 		/* don't do anything here */
2163 		break;
2164 	case FSACTL_MINIPORT_REV_CHECK:
2165 		arg = *(caddr_t*)arg;
2166 	case FSACTL_LNX_MINIPORT_REV_CHECK:
2167 		debug(1, "FSACTL_MINIPORT_REV_CHECK");
2168 		error = aac_rev_check(sc, arg);
2169 		break;
2170 	case FSACTL_QUERY_DISK:
2171 		arg = *(caddr_t*)arg;
2172 	case FSACTL_LNX_QUERY_DISK:
2173 		debug(1, "FSACTL_QUERY_DISK");
2174 		error = aac_query_disk(sc, arg);
2175 			break;
2176 	case FSACTL_DELETE_DISK:
2177 	case FSACTL_LNX_DELETE_DISK:
2178 		/*
2179 		 * We don't trust the underland to tell us when to delete a
2180 		 * container, rather we rely on an AIF coming from the
2181 		 * controller
2182 		 */
2183 		error = 0;
2184 		break;
2185 	default:
2186 		device_printf(sc->aac_dev, "unsupported cmd 0x%lx\n", cmd);
2187 		error = EINVAL;
2188 		break;
2189 	}
2190 	return(error);
2191 }
2192 
2193 /*
2194  * Send a FIB supplied from userspace
2195  */
2196 static int
2197 aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
2198 {
2199 	struct aac_command *cm;
2200 	int size, error;
2201 
2202 	debug_called(2);
2203 
2204 	cm = NULL;
2205 
2206 	/*
2207 	 * Get a command
2208 	 */
2209 	if (aac_alloc_command(sc, &cm)) {
2210 		error = EBUSY;
2211 		goto out;
2212 	}
2213 
2214 	/*
2215 	 * Fetch the FIB header, then re-copy to get data as well.
2216 	 */
2217 	if ((error = copyin(ufib, cm->cm_fib,
2218 			    sizeof(struct aac_fib_header))) != 0)
2219 		goto out;
2220 	size = cm->cm_fib->Header.Size + sizeof(struct aac_fib_header);
2221 	if (size > sizeof(struct aac_fib)) {
2222 		device_printf(sc->aac_dev, "incoming FIB oversized (%d > %d)\n",
2223 			      size, sizeof(struct aac_fib));
2224 		size = sizeof(struct aac_fib);
2225 	}
2226 	if ((error = copyin(ufib, cm->cm_fib, size)) != 0)
2227 		goto out;
2228 	cm->cm_fib->Header.Size = size;
2229 	cm->cm_timestamp = time_second;
2230 
2231 	/*
2232 	 * Pass the FIB to the controller, wait for it to complete.
2233 	 */
2234 	if ((error = aac_wait_command(cm, 30)) != 0)	/* XXX user timeout? */
2235 		goto out;
2236 
2237 	/*
2238 	 * Copy the FIB and data back out to the caller.
2239 	 */
2240 	size = cm->cm_fib->Header.Size;
2241 	if (size > sizeof(struct aac_fib)) {
2242 		device_printf(sc->aac_dev, "outbound FIB oversized (%d > %d)\n",
2243 			      size, sizeof(struct aac_fib));
2244 		size = sizeof(struct aac_fib);
2245 	}
2246 	error = copyout(cm->cm_fib, ufib, size);
2247 
2248 out:
2249 	if (cm != NULL) {
2250 		aac_release_command(cm);
2251 	}
2252 	return(error);
2253 }
2254 
2255 /*
2256  * Handle an AIF sent to us by the controller; queue it for later reference.
2257  * If the queue fills up, then drop the older entries.
2258  */
2259 static void
2260 aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
2261 {
2262 	struct aac_aif_command *aif;
2263 	struct aac_container *co, *co_next;
2264 	struct aac_mntinfo mi;
2265 	struct aac_mntinforesponse mir;
2266 	u_int16_t rsize;
2267 	int next, s, found;
2268 	int added = 0, i = 0;
2269 
2270 	debug_called(2);
2271 
2272 	aif = (struct aac_aif_command*)&fib->data[0];
2273 	aac_print_aif(sc, aif);
2274 
2275 	/* Is it an event that we should care about? */
2276 	switch (aif->command) {
2277 	case AifCmdEventNotify:
2278 		switch (aif->data.EN.type) {
2279 		case AifEnAddContainer:
2280 		case AifEnDeleteContainer:
2281 			/*
2282 			 * A container was added or deleted, but the message
2283 			 * doesn't tell us anything else!  Re-enumerate the
2284 			 * containers and sort things out.
2285 			 */
2286 			mi.Command = VM_NameServe;
2287 			mi.MntType = FT_FILESYS;
2288 			do {
2289 				/*
2290 				 * Ask the controller for its containers one at
2291 				 * a time.
2292 				 * XXX What if the controller's list changes
2293 				 * midway through this enumaration?
2294 				 * XXX This should be done async.
2295 				 */
2296 				mi.MntCount = i;
2297 				rsize = sizeof(mir);
2298 				if (aac_sync_fib(sc, ContainerCommand, 0, &mi,
2299 						 sizeof(mi), &mir, &rsize)) {
2300 					debug(2, "Error probing container %d\n",
2301 					      i);
2302 					continue;
2303 				}
2304 				if (rsize != sizeof(mir)) {
2305 					debug(2, "Container response size too "
2306 						 "large\n");
2307 					continue;
2308 				}
2309 				/*
2310 				 * Check the container against our list.
2311 				 * co->co_found was already set to 0 in a
2312 				 * previous run.
2313 				 */
2314 				if ((mir.Status == ST_OK) &&
2315 				    (mir.MntTable[0].VolType != CT_NONE)) {
2316 					found = 0;
2317 					TAILQ_FOREACH(co,
2318 						      &sc->aac_container_tqh,
2319 						      co_link) {
2320 						if (co->co_mntobj.ObjectId ==
2321 						    mir.MntTable[0].ObjectId) {
2322 							co->co_found = 1;
2323 							found = 1;
2324 							break;
2325 						}
2326 					}
2327 					/*
2328 					 * If the container matched, continue
2329 					 * in the list.
2330 					 */
2331 					if (found) {
2332 						i++;
2333 						continue;
2334 					}
2335 
2336 					/*
2337 					 * This is a new container.  Do all the
2338 					 * appropriate things to set it up.						 */
2339 					aac_add_container(sc, &mir, 1);
2340 					added = 1;
2341 				}
2342 				i++;
2343 			} while ((i < mir.MntRespCount) &&
2344 				 (i < AAC_MAX_CONTAINERS));
2345 
2346 			/*
2347 			 * Go through our list of containers and see which ones
2348 			 * were not marked 'found'.  Since the controller didn't
2349 			 * list them they must have been deleted.  Do the
2350 			 * appropriate steps to destroy the device.  Also reset
2351 			 * the co->co_found field.
2352 			 */
2353 			co = TAILQ_FIRST(&sc->aac_container_tqh);
2354 			while (co != NULL) {
2355 				if (co->co_found == 0) {
2356 					device_delete_child(sc->aac_dev,
2357 							    co->co_disk);
2358 					co_next = TAILQ_NEXT(co, co_link);
2359 					AAC_LOCK_AQUIRE(&sc->
2360 							aac_container_lock);
2361 					TAILQ_REMOVE(&sc->aac_container_tqh, co,
2362 						     co_link);
2363 					AAC_LOCK_RELEASE(&sc->
2364 							 aac_container_lock);
2365 					FREE(co, M_AACBUF);
2366 					co = co_next;
2367 				} else {
2368 					co->co_found = 0;
2369 					co = TAILQ_NEXT(co, co_link);
2370 				}
2371 			}
2372 
2373 			/* Attach the newly created containers */
2374 			if (added)
2375 				bus_generic_attach(sc->aac_dev);
2376 
2377 				break;
2378 
2379 		default:
2380 			break;
2381 		}
2382 
2383 	default:
2384 		break;
2385 	}
2386 
2387 	/* Copy the AIF data to the AIF queue for ioctl retrieval */
2388 	s = splbio();
2389 	next = (sc->aac_aifq_head + 1) % AAC_AIFQ_LENGTH;
2390 	if (next != sc->aac_aifq_tail) {
2391 		bcopy(aif, &sc->aac_aifq[next], sizeof(struct aac_aif_command));
2392 	sc->aac_aifq_head = next;
2393 	if (sc->aac_state & AAC_STATE_AIF_SLEEPER)
2394 		wakeup(sc->aac_aifq);
2395 	}
2396 	splx(s);
2397 
2398 	return;
2399 }
2400 
2401 /*
2402  * Linux Management Interface
2403  * This is soon to be removed!
2404  */
2405 
2406 #ifdef AAC_COMPAT_LINUX
2407 
2408 #include <sys/proc.h>
2409 #include <machine/../linux/linux.h>
2410 #include <machine/../linux/linux_proto.h>
2411 #include <compat/linux/linux_ioctl.h>
2412 
2413 /* There are multiple ioctl number ranges that need to be handled */
2414 #define AAC_LINUX_IOCTL_MIN  0x0000
2415 #define AAC_LINUX_IOCTL_MAX  0x21ff
2416 
2417 static linux_ioctl_function_t aac_linux_ioctl;
2418 static struct linux_ioctl_handler aac_handler = {aac_linux_ioctl,
2419 						 AAC_LINUX_IOCTL_MIN,
2420 						 AAC_LINUX_IOCTL_MAX};
2421 
2422 SYSINIT  (aac_register,   SI_SUB_KLD, SI_ORDER_MIDDLE,
2423 	  linux_ioctl_register_handler, &aac_handler);
2424 SYSUNINIT(aac_unregister, SI_SUB_KLD, SI_ORDER_MIDDLE,
2425 	  linux_ioctl_unregister_handler, &aac_handler);
2426 
2427 MODULE_DEPEND(aac, linux, 1, 1, 1);
2428 
2429 static int
2430 aac_linux_ioctl(struct thread *td, struct linux_ioctl_args *args)
2431 {
2432 	struct file *fp;
2433 	u_long cmd;
2434 
2435 	debug_called(2);
2436 
2437 	fp = td->td_proc->p_fd->fd_ofiles[args->fd];
2438 	cmd = args->cmd;
2439 
2440 	/*
2441 	 * Pass the ioctl off to our standard handler.
2442 	 */
2443 	return(fo_ioctl(fp, cmd, (caddr_t)args->arg, td));
2444 }
2445 
2446 #endif
2447 
2448 /*
2449  * Return the Revision of the driver to userspace and check to see if the
2450  * userspace app is possibly compatible.  This is extremely bogus since
2451  * our driver doesn't follow Adaptec's versioning system.  Cheat by just
2452  * returning what the card reported.
2453  */
2454 static int
2455 aac_rev_check(struct aac_softc *sc, caddr_t udata)
2456 {
2457 	struct aac_rev_check rev_check;
2458 	struct aac_rev_check_resp rev_check_resp;
2459 	int error = 0;
2460 
2461 	debug_called(2);
2462 
2463 	/*
2464 	 * Copyin the revision struct from userspace
2465 	 */
2466 	if ((error = copyin(udata, (caddr_t)&rev_check,
2467 			sizeof(struct aac_rev_check))) != 0) {
2468 		return error;
2469 	}
2470 
2471 	debug(2, "Userland revision= %d\n",
2472 	      rev_check.callingRevision.buildNumber);
2473 
2474 	/*
2475 	 * Doctor up the response struct.
2476 	 */
2477 	rev_check_resp.possiblyCompatible = 1;
2478 	rev_check_resp.adapterSWRevision.external.ul =
2479 	    sc->aac_revision.external.ul;
2480 	rev_check_resp.adapterSWRevision.buildNumber =
2481 	    sc->aac_revision.buildNumber;
2482 
2483 	return(copyout((caddr_t)&rev_check_resp, udata,
2484 			sizeof(struct aac_rev_check_resp)));
2485 }
2486 
2487 /*
2488  * Pass the caller the next AIF in their queue
2489  */
2490 static int
2491 aac_getnext_aif(struct aac_softc *sc, caddr_t arg)
2492 {
2493 	struct get_adapter_fib_ioctl agf;
2494 	int error, s;
2495 
2496 	debug_called(2);
2497 
2498 	if ((error = copyin(arg, &agf, sizeof(agf))) == 0) {
2499 
2500 		/*
2501 		 * Check the magic number that we gave the caller.
2502 		 */
2503 		if (agf.AdapterFibContext != (int)sc->aifthread) {
2504 			error = EFAULT;
2505 		} else {
2506 
2507 			s = splbio();
2508 			error = aac_return_aif(sc, agf.AifFib);
2509 
2510 			if ((error == EAGAIN) && (agf.Wait)) {
2511 				sc->aac_state |= AAC_STATE_AIF_SLEEPER;
2512 				while (error == EAGAIN) {
2513 					error = tsleep(sc->aac_aifq, PRIBIO |
2514 						       PCATCH, "aacaif", 0);
2515 					if (error == 0)
2516 						error = aac_return_aif(sc,
2517 						    agf.AifFib);
2518 				}
2519 				sc->aac_state &= ~AAC_STATE_AIF_SLEEPER;
2520 			}
2521 		splx(s);
2522 		}
2523 	}
2524 	return(error);
2525 }
2526 
2527 /*
2528  * Hand the next AIF off the top of the queue out to userspace.
2529  */
2530 static int
2531 aac_return_aif(struct aac_softc *sc, caddr_t uptr)
2532 {
2533 	int error, s;
2534 
2535 	debug_called(2);
2536 
2537 	s = splbio();
2538 	if (sc->aac_aifq_tail == sc->aac_aifq_head) {
2539 		error = EAGAIN;
2540 	} else {
2541 		error = copyout(&sc->aac_aifq[sc->aac_aifq_tail], uptr,
2542 				sizeof(struct aac_aif_command));
2543 		if (error)
2544 			printf("aac_return_aif: copyout returned %d\n", error);
2545 		if (!error)
2546 			sc->aac_aifq_tail = (sc->aac_aifq_tail + 1) %
2547 					    AAC_AIFQ_LENGTH;
2548 	}
2549 	splx(s);
2550 	return(error);
2551 }
2552 
2553 /*
2554  * Give the userland some information about the container.  The AAC arch
2555  * expects the driver to be a SCSI passthrough type driver, so it expects
2556  * the containers to have b:t:l numbers.  Fake it.
2557  */
2558 static int
2559 aac_query_disk(struct aac_softc *sc, caddr_t uptr)
2560 {
2561 	struct aac_query_disk query_disk;
2562 	struct aac_container *co;
2563 	struct aac_disk	*disk;
2564 	int error, id;
2565 
2566 	debug_called(2);
2567 
2568 	disk = NULL;
2569 
2570 	error = copyin(uptr, (caddr_t)&query_disk,
2571 		       sizeof(struct aac_query_disk));
2572 	if (error)
2573 		return (error);
2574 
2575 	id = query_disk.ContainerNumber;
2576 	if (id == -1)
2577 		return (EINVAL);
2578 
2579 	AAC_LOCK_AQUIRE(&sc->aac_container_lock);
2580 	TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) {
2581 		if (co->co_mntobj.ObjectId == id)
2582 			break;
2583 		}
2584 
2585 		if (co == NULL) {
2586 			query_disk.Valid = 0;
2587 			query_disk.Locked = 0;
2588 			query_disk.Deleted = 1;		/* XXX is this right? */
2589 		} else {
2590 			disk = device_get_softc(co->co_disk);
2591 			query_disk.Valid = 1;
2592 			query_disk.Locked =
2593 			    (disk->ad_flags & AAC_DISK_OPEN) ? 1 : 0;
2594 			query_disk.Deleted = 0;
2595 			query_disk.Bus = 0;
2596 			query_disk.Target = disk->unit;
2597 			query_disk.Lun = 0;
2598 			query_disk.UnMapped = 0;
2599 			bcopy(disk->ad_dev_t->si_name,
2600 			      &query_disk.diskDeviceName[0], 10);
2601 		}
2602 	AAC_LOCK_RELEASE(&sc->aac_container_lock);
2603 
2604 	error = copyout((caddr_t)&query_disk, uptr,
2605 			sizeof(struct aac_query_disk));
2606 
2607 	return (error);
2608 }
2609 
2610