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