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