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