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