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