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