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