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