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