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