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