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