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