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