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