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