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