Only in /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64: +COMMENT
Only in /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64: +CONTENTS
Only in /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64: +DESC
Only in /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64: +POST-DEINSTALL
Only in /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64: +POST-INSTALL
Only in sys/dev/aac: CVS
diff -urw sys/dev/aac/aac.c /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac.c
--- sys/dev/aac/aac.c	2008-04-07 16:19:57.000000000 +0200
+++ /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac.c	2011-11-21 12:05:19.000000000 +0100
@@ -2,7 +2,8 @@
  * Copyright (c) 2000 Michael Smith
  * Copyright (c) 2001 Scott Long
  * Copyright (c) 2000 BSDi
- * Copyright (c) 2001 Adaptec, Inc.
+ * Copyright (c) 2001-2010 Adaptec, Inc.
+ * Copyright (c) 2010 PMC-Sierra, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,12 +29,11 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/aac/aac.c,v 1.120.2.11 2008/04/07 14:19:57 emaste Exp $");
+__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac.c,v 1.120.2.11 2008/04/07 14:19:57 emaste Exp $");
 
 /*
  * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
  */
-#define AAC_DRIVER_VERSION		0x02000000
 #define AAC_DRIVERNAME			"aac"
 
 #include "opt_aac.h"
@@ -64,6 +64,7 @@
 
 #include <dev/aac/aacreg.h>
 #include <sys/aac_ioctl.h>
+#include <dev/aac/aac_fwdb.h>
 #include <dev/aac/aacvar.h>
 #include <dev/aac/aac_tables.h>
 
@@ -71,6 +72,7 @@
 static void	aac_add_container(struct aac_softc *sc,
 				  struct aac_mntinforesp *mir, int f);
 static void	aac_get_bus_info(struct aac_softc *sc);
+static void	aac_daemon(void *arg);
 
 /* Command Processing */
 static void	aac_timeout(struct aac_softc *sc);
@@ -95,9 +97,6 @@
 			       int error);
 static int	aac_check_firmware(struct aac_softc *sc);
 static int	aac_init(struct aac_softc *sc);
-static int	aac_sync_command(struct aac_softc *sc, u_int32_t command,
-				 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2,
-				 u_int32_t arg3, u_int32_t *sp);
 static int	aac_setup_intr(struct aac_softc *sc);
 static int	aac_enqueue_fib(struct aac_softc *sc, int queue,
 				struct aac_command *cm);
@@ -204,6 +203,33 @@
 	aac_rkt_set_outb_queue
 };
 
+/* PMC SRC interface */
+static int	aac_src_get_fwstatus(struct aac_softc *sc);
+static void	aac_src_qnotify(struct aac_softc *sc, int qbit);
+static int	aac_src_get_istatus(struct aac_softc *sc);
+static void	aac_src_clear_istatus(struct aac_softc *sc, int mask);
+static void	aac_src_set_mailbox(struct aac_softc *sc, u_int32_t command,
+				    u_int32_t arg0, u_int32_t arg1,
+				    u_int32_t arg2, u_int32_t arg3);
+static int	aac_src_get_mailbox(struct aac_softc *sc, int mb);
+static void	aac_src_set_interrupts(struct aac_softc *sc, int enable);
+static int aac_src_send_command(struct aac_softc *sc, struct aac_command *cm);
+static int aac_src_get_outb_queue(struct aac_softc *sc);
+static void aac_src_set_outb_queue(struct aac_softc *sc, int index);
+
+struct aac_interface aac_src_interface = {
+	aac_src_get_fwstatus,
+	aac_src_qnotify,
+	aac_src_get_istatus,
+	aac_src_clear_istatus,
+	aac_src_set_mailbox,
+	aac_src_get_mailbox,
+	aac_src_set_interrupts,
+	aac_src_send_command,
+	aac_src_get_outb_queue,
+	aac_src_set_outb_queue
+};
+
 /* Debugging and Diagnostics */
 static void	aac_describe_controller(struct aac_softc *sc);
 static char	*aac_describe_code(struct aac_code_lookup *table,
@@ -218,6 +244,7 @@
 static int		aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg);
 static void		aac_handle_aif(struct aac_softc *sc,
 					   struct aac_fib *fib);
+static void		aac_request_aif(struct aac_softc *sc);
 static int		aac_rev_check(struct aac_softc *sc, caddr_t udata);
 static int		aac_open_aif(struct aac_softc *sc, caddr_t arg);
 static int		aac_close_aif(struct aac_softc *sc, caddr_t arg);
@@ -229,8 +256,11 @@
 static int		aac_supported_features(struct aac_softc *sc, caddr_t uptr);
 static void		aac_ioctl_event(struct aac_softc *sc,
 				        struct aac_event *event, void *arg);
+static int		aac_reset_adapter(struct aac_softc *sc);
 static struct aac_mntinforesp *
 	aac_get_container_info(struct aac_softc *sc, struct aac_fib *fib, int cid);
+static u_int32_t
+	aac_check_adapter_health(struct aac_softc *sc, u_int8_t *bled);
 
 static struct cdevsw aac_cdevsw = {
 	.d_version =	D_VERSION,
@@ -258,9 +288,10 @@
 aac_attach(struct aac_softc *sc)
 {
 	int error, unit;
+	struct timeval tv;
 
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
-
+	sc->hint_flags = device_get_flags(sc->aac_dev);
 	/*
 	 * Initialize per-controller queues.
 	 */
@@ -293,10 +324,14 @@
 	TAILQ_INIT(&sc->aac_ev_cmfree);
 
 	/*
-	 * Initialize the adapter.
+	 * Allocate adapter comm. space.
 	 */
 	if ((error = aac_alloc(sc)) != 0)
 		return(error);
+
+	/*
+	 * Initialize the adapter.
+	 */
 	if ((error = aac_init(sc)) != 0)
 		return(error);
 
@@ -333,7 +368,7 @@
 	sc->aac_dev_t->si_drv1 = sc;
 
 	/* Create the AIF thread */
-	if (kthread_create((void(*)(void *))aac_command_thread, sc,
+	if (kproc_create((void(*)(void *))aac_command_thread, sc,
 		   &sc->aifthread, 0, 0, "aac%daif", unit))
 		panic("Could not create AIF thread");
 
@@ -348,6 +383,9 @@
 		TAILQ_INIT(&sc->aac_sim_tqh);
 		aac_get_bus_info(sc);
 	}
+	tv.tv_sec = 60;
+	tv.tv_usec = 0;
+	sc->timeout_id = timeout(aac_daemon, (void *)sc, tvtohz(&tv));
 
 	return(0);
 }
@@ -369,6 +407,28 @@
 	return;
 }
 
+/* daemon */
+static void
+aac_daemon(void *arg)
+{
+	struct aac_softc *sc = (struct aac_softc *)arg;
+	struct timeval tv;
+	struct aac_fib *fib;
+
+	/* time sync. with firmware */
+	getmicrotime(&tv);
+	mtx_lock(&sc->aac_io_lock);
+	aac_alloc_sync_fib(sc, &fib);
+	*(uint32_t *)fib->data = tv.tv_sec;
+	aac_sync_fib(sc, SendHostTime, 0, fib, sizeof(uint32_t));
+	aac_release_sync_fib(sc);
+	mtx_unlock(&sc->aac_io_lock);
+
+	tv.tv_sec = 30*60;		/* 30 minutes */
+	tv.tv_usec = 0;
+	sc->timeout_id = timeout(aac_daemon, (void *)sc, tvtohz(&tv));
+}
+
 /*
  * Request information of container #cid
  */
@@ -482,6 +542,7 @@
 static int
 aac_alloc(struct aac_softc *sc)
 {
+	bus_size_t maxsize;
 
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
@@ -509,6 +570,11 @@
 	/*
 	 * Create DMA tag for mapping FIBs into controller-addressable space..
 	 */
+	if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE1) 
+		maxsize = sc->aac_max_fibs_alloc * (sc->aac_max_fib_size +
+			sizeof(struct aac_fib_xporthdr) + 31);
+	else
+		maxsize = sc->aac_max_fibs_alloc * sc->aac_max_fib_size;
 	if (bus_dma_tag_create(sc->aac_parent_dmat,	/* parent */
 			       1, 0, 			/* algnmnt, boundary */
 			       (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
@@ -516,11 +582,9 @@
 			       0x7fffffff,		/* lowaddr */
 			       BUS_SPACE_MAXADDR, 	/* highaddr */
 			       NULL, NULL, 		/* filter, filterarg */
-			       sc->aac_max_fibs_alloc *
-			       sc->aac_max_fib_size,  /* maxsize */
+				   maxsize,  		/* maxsize */
 			       1,			/* nsegments */
-			       sc->aac_max_fibs_alloc *
-			       sc->aac_max_fib_size,	/* maxsize */
+				   maxsize,			/* maxsize */
 			       0,			/* flags */
 			       NULL, NULL,		/* No locking needed */
 			       &sc->aac_fib_dmat)) {
@@ -531,6 +595,9 @@
 	/*
 	 * Create DMA tag for the common structure and allocate it.
 	 */
+	maxsize = 8192 + sizeof(struct aac_common);
+	if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE1) 
+		maxsize += sc->aac_max_fibs * sizeof(u_int32_t);
 	if (bus_dma_tag_create(sc->aac_parent_dmat, 	/* parent */
 			       1, 0,			/* algnmnt, boundary */
 			       (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
@@ -538,9 +605,9 @@
 			       0x7fffffff,		/* lowaddr */
 			       BUS_SPACE_MAXADDR, 	/* highaddr */
 			       NULL, NULL, 		/* filter, filterarg */
-			       8192 + sizeof(struct aac_common), /* maxsize */
+                   maxsize, 		/* maxsize */
 			       1,			/* nsegments */
-			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
+			       maxsize,			/* maxsegsize */
 			       0,			/* flags */
 			       NULL, NULL,		/* No locking needed */
 			       &sc->aac_common_dmat)) {
@@ -561,7 +628,7 @@
 	 * of ignored?
 	 */
 	(void)bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
-			sc->aac_common, 8192 + sizeof(*sc->aac_common),
+			sc->aac_common, maxsize,
 			aac_common_map, sc, 0);
 
 	if (sc->aac_common_busaddr < 8192) {
@@ -569,7 +636,7 @@
 		    ((uint8_t *)sc->aac_common + 8192);
 		sc->aac_common_busaddr += 8192;
 	}
-	bzero(sc->aac_common, sizeof(*sc->aac_common));
+	bzero(sc->aac_common, maxsize - 8192);
 
 	/* Allocate some FIBs and associated command structs */
 	TAILQ_INIT(&sc->aac_fibmap_tqh);
@@ -632,9 +699,13 @@
 		bus_dma_tag_destroy(sc->aac_parent_dmat);
 
 	/* release the register window mapping */
-	if (sc->aac_regs_resource != NULL)
+	if (sc->aac_regs_res0 != NULL)
+		bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
+				     sc->aac_regs_rid0, sc->aac_regs_res0);
+	if ((sc->aac_hwif == AAC_HWIF_SRC || sc->aac_hwif == AAC_HWIF_NARK)
+		&& sc->aac_regs_res1 != NULL)
 		bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
-				     sc->aac_regs_rid, sc->aac_regs_resource);
+				     sc->aac_regs_rid1, sc->aac_regs_res1);
 }
 
 /*
@@ -654,6 +725,8 @@
 	if (sc->aac_state & AAC_STATE_OPEN)
 		return(EBUSY);
 
+	untimeout(aac_daemon, (void *)sc, sc->timeout_id);
+
 	/* Remove the child containers */
 	while ((co = TAILQ_FIRST(&sc->aac_container_tqh)) != NULL) {
 		error = device_delete_child(dev, co->co_disk);
@@ -793,6 +866,107 @@
 }
 
 /*
+ * Interrupt handler for NEW_COMM_TYPE1 interface.
+ */
+void
+aac_new_intr_type1(void *arg)
+{
+	struct aac_softc *sc;
+	struct aac_command *cm;
+	struct aac_fib *fib;
+	u_int32_t bellbits, bellbits_shifted, index, handle;
+	int isFastResponse, isAif, noMoreAif;
+	int our_interrupt = 0;
+
+	sc = (struct aac_softc *)arg;
+
+	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+	mtx_lock(&sc->aac_io_lock);
+	bellbits = AAC_MEM0_GETREG4(sc, AAC_SRC_ODBR_R);
+	if (bellbits & AAC_DB_RESPONSE_SENT_NS) {
+		bellbits = AAC_DB_RESPONSE_SENT_NS;
+		/* handle async. status */
+		our_interrupt = 1;
+		index = sc->aac_host_rrq_idx;
+		if (sc->aac_common->ac_host_rrq[index] == 0) {
+			u_int32_t old_index = index;
+			/* adjust index */
+			do {
+				index++;
+				if (index == sc->aac_max_fibs) 
+					index = 0;
+				if (sc->aac_common->ac_host_rrq[index] != 0) 
+					break;
+			} while (index != old_index);
+			sc->aac_host_rrq_idx = index;
+		}
+		for (;;) {
+			isFastResponse = isAif = noMoreAif = 0;
+			/* remove toggle bit (31) */
+			handle = (sc->aac_common->ac_host_rrq[index] & 0x7fffffff);
+			/* check fast response bit (30) */
+			if (handle & 0x40000000) 
+				isFastResponse = 1;
+			/* check AIF bit (23) */
+			else if (handle & 0x00800000) 
+				isAif = TRUE;
+			handle &= 0x0000ffff;
+			if (handle == 0) 
+				break;
+
+			cm = sc->aac_commands + (handle - 1);
+			fib = cm->cm_fib;
+			if (isAif) {
+				noMoreAif = (fib->Header.XferState & AAC_FIBSTATE_NOMOREAIF) ? 1:0;
+				if (!noMoreAif) 
+					aac_handle_aif(sc, fib);
+				aac_remove_busy(cm);
+				aac_release_command(cm);
+			} else {
+				if (isFastResponse) {
+					fib->Header.XferState |= AAC_FIBSTATE_DONEADAP;
+					*((u_int32_t *)(fib->data)) = AAC_ERROR_NORMAL;
+				}
+				aac_remove_busy(cm);
+				aac_unmap_command(cm);
+				cm->cm_flags |= AAC_CMD_COMPLETED;
+
+				/* is there a completion handler? */
+				if (cm->cm_complete != NULL) {
+					cm->cm_complete(cm);
+				} else {
+					/* assume that someone is sleeping on this command */
+					wakeup(cm);
+				}
+				sc->flags &= ~AAC_QUEUE_FRZN;
+			}
+
+			sc->aac_common->ac_host_rrq[index++] = 0;
+			if (index == sc->aac_max_fibs) 
+				index = 0;
+			sc->aac_host_rrq_idx = index;
+
+			if ((isAif && !noMoreAif) || sc->aif_pending) 
+				aac_request_aif(sc);
+		}
+	} else {
+		bellbits_shifted = (bellbits >> AAC_SRC_ODR_SHIFT);
+		if (bellbits_shifted & AAC_DB_AIF_PENDING) {
+			our_interrupt = 1;
+			/* handle AIF */
+			aac_request_aif(sc);
+		}
+    }
+	if (our_interrupt) 
+		AAC_MEM0_SETREG4(sc, AAC_SRC_ODBR_C, bellbits);
+
+	/* see if we can start some more I/O */
+	if ((sc->flags & AAC_QUEUE_FRZN) == 0)
+		aac_startio(sc);
+	mtx_unlock(&sc->aac_io_lock);
+}
+
+/*
  * Interrupt handler for NEW_COMM interface.
  */
 void
@@ -834,7 +1008,7 @@
 			}
 			index &= ~2;
 			for (i = 0; i < sizeof(struct aac_fib)/4; ++i)
-				((u_int32_t *)fib)[i] = AAC_GETREG4(sc, index + i*4);
+				((u_int32_t *)fib)[i] = AAC_MEM1_GETREG4(sc, index + i*4);
 			aac_handle_aif(sc, fib);
 			free(fib, M_AACBUF);
 
@@ -935,6 +1109,8 @@
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
 	for (;;) {
+		if (sc->aac_state & AAC_STATE_RESET)
+			break;
 		/*
 		 * This flag might be set if the card is out of resources.
 		 * Checking it here prevents an infinite loop of deferrals.
@@ -1083,7 +1259,7 @@
 	mtx_unlock(&sc->aac_io_lock);
 	wakeup(sc->aac_dev);
 
-	kthread_exit(0);
+	kproc_exit(0);
 }
 
 /*
@@ -1175,13 +1351,22 @@
 	if ((bp = aac_dequeue_bio(sc)) == NULL)
 		goto fail;
 
+	ad = (struct aac_disk *)bp->bio_disk->d_drv1;
+	/* container still valid? */
+	if (ad->ad_container == NULL) {
+		bp->bio_flags |= BIO_ERROR;
+		bp->bio_error = EINVAL;
+		biodone(bp);
+		bp = NULL;
+		goto fail;
+	}
+
 	/* fill out the command */
 	cm->cm_data = (void *)bp->bio_data;
 	cm->cm_datalen = bp->bio_bcount;
 	cm->cm_complete = aac_bio_complete;
 	cm->cm_private = bp;
 	cm->cm_timestamp = time_uptime;
-	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
 
 	/* build the FIB */
 	fib = cm->cm_fib;
@@ -1197,8 +1382,6 @@
 		AAC_FIBSTATE_FAST_RESPONSE;
 
 	/* build the read/write request */
-	ad = (struct aac_disk *)bp->bio_disk->d_drv1;
-
 	if (sc->flags & AAC_FLAGS_RAW_IO) {
 		struct aac_raw_io *raw;
 		raw = (struct aac_raw_io *)&fib->data[0];
@@ -1294,7 +1477,9 @@
 
 	/* fetch relevant status and then release the command */
 	bp = (struct bio *)cm->cm_private;
-	if (bp->bio_cmd == BIO_READ) {
+	if (cm->cm_flags & AAC_CMD_RESET) {
+		status = ST_BUS_RESET;
+	} else if (bp->bio_cmd == BIO_READ) {
 		brr = (struct aac_blockread_response *)&cm->cm_fib->data[0];
 		status = brr->Status;
 	} else {
@@ -1307,7 +1492,7 @@
 	if (status == ST_OK) {
 		bp->bio_resid = 0;
 	} else {
-		bp->bio_error = EIO;
+		bp->bio_error = (status == ST_NOT_READY ? EBUSY : EIO);
 		bp->bio_flags |= BIO_ERROR;
 		/* pass an error string out to the disk layer */
 		bp->bio_driver1 = aac_describe_code(aac_command_status_table,
@@ -1336,7 +1521,6 @@
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
 	/* Put the command on the ready queue and get things going */
-	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
 	aac_enqueue_ready(cm);
 	aac_startio(sc);
 	error = msleep(cm, &sc->aac_io_lock, PRIBIO, "aacwait", 0);
@@ -1386,6 +1570,8 @@
 	cm->cm_flags = 0;
 	cm->cm_complete = NULL;
 	cm->cm_private = NULL;
+	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
+	cm->cm_passthr_dmat = 0;
 	cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
 	cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
 	cm->cm_fib->Header.Flags = 0;
@@ -1434,6 +1620,7 @@
 	struct aac_fibmap *fm;
 	uint64_t fibphys;
 	int i, error;
+	u_int32_t maxsize;
 
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
@@ -1453,26 +1640,40 @@
 		return (ENOMEM);
 	}
 
+	maxsize = sc->aac_max_fib_size;
+	if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE1) 
+		maxsize += sizeof(struct aac_fib_xporthdr) + 31;
+
 	/* Ignore errors since this doesn't bounce */
 	(void)bus_dmamap_load(sc->aac_fib_dmat, fm->aac_fibmap, fm->aac_fibs,
-			      sc->aac_max_fibs_alloc * sc->aac_max_fib_size,
+			      sc->aac_max_fibs_alloc * maxsize,
 			      aac_map_command_helper, &fibphys, 0);
 
 	/* initialize constant fields in the command structure */
-	bzero(fm->aac_fibs, sc->aac_max_fibs_alloc * sc->aac_max_fib_size);
+	bzero(fm->aac_fibs, sc->aac_max_fibs_alloc * maxsize);
 	for (i = 0; i < sc->aac_max_fibs_alloc; i++) {
 		cm = sc->aac_commands + sc->total_fibs;
 		fm->aac_commands = cm;
 		cm->cm_sc = sc;
 		cm->cm_fib = (struct aac_fib *)
-			((u_int8_t *)fm->aac_fibs + i*sc->aac_max_fib_size);
-		cm->cm_fibphys = fibphys + i*sc->aac_max_fib_size;
+			((u_int8_t *)fm->aac_fibs + i * maxsize);
+		cm->cm_fibphys = fibphys + i * maxsize;
+		if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE1) {
+			u_int64_t fibphys_aligned;
+			fibphys_aligned = 
+				(cm->cm_fibphys + sizeof(struct aac_fib_xporthdr) + 31) & ~31;
+			cm->cm_fib = (struct aac_fib *)
+				((u_int8_t *)cm->cm_fib + (fibphys_aligned - cm->cm_fibphys));
+			cm->cm_fibphys = fibphys_aligned;
+		}
 		cm->cm_index = sc->total_fibs;
 
 		if ((error = bus_dmamap_create(sc->aac_buffer_dmat, 0,
 					       &cm->cm_datamap)) != 0)
 			break;
 		mtx_lock(&sc->aac_io_lock);
+		/* FIXME: Patch max. outstanding commands */
+		if (sc->aac_max_fibs <= 1 || sc->aac_max_fibs - sc->total_fibs > 1)
 		aac_release_command(cm);
 		sc->total_fibs++;
 		mtx_unlock(&sc->aac_io_lock);
@@ -1584,14 +1785,17 @@
 	cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
 
 	/* save a pointer to the command for speedy reverse-lookup */
-	cm->cm_fib->Header.SenderData = cm->cm_index;
+	cm->cm_fib->Header.SenderData += cm->cm_index;
 
+	if (cm->cm_passthr_dmat == 0) {
 	if (cm->cm_flags & AAC_CMD_DATAIN)
 		bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
 				BUS_DMASYNC_PREREAD);
 	if (cm->cm_flags & AAC_CMD_DATAOUT)
 		bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
 				BUS_DMASYNC_PREWRITE);
+	}
+
 	cm->cm_flags |= AAC_CMD_MAPPED;
 
 	if (sc->flags & AAC_FLAGS_NEW_COMM) {
@@ -1630,7 +1834,7 @@
 	if (!(cm->cm_flags & AAC_CMD_MAPPED))
 		return;
 
-	if (cm->cm_datalen != 0) {
+	if (cm->cm_datalen != 0 && cm->cm_passthr_dmat == 0) {
 		if (cm->cm_flags & AAC_CMD_DATAIN)
 			bus_dmamap_sync(sc->aac_buffer_dmat, cm->cm_datamap,
 					BUS_DMASYNC_POSTREAD);
@@ -1664,7 +1868,8 @@
 static int
 aac_check_firmware(struct aac_softc *sc)
 {
-	u_int32_t code, major, minor, options = 0, atu_size = 0;
+	u_int32_t code, major, minor, maxsize;
+	u_int32_t options = 0, atu_size = 0;
 	int status;
 	time_t then;
 
@@ -1698,7 +1903,7 @@
 	 */
 	if (sc->flags & AAC_FLAGS_PERC2QC) {
 		if (aac_sync_command(sc, AAC_MONKER_GETKERNVER, 0, 0, 0, 0,
-				     NULL)) {
+				     NULL, NULL)) {
 			device_printf(sc->aac_dev,
 				      "Error reading firmware version\n");
 			return (EIO);
@@ -1714,13 +1919,12 @@
 			return (EINVAL);
 		}
 	}
-
 	/*
 	 * Retrieve the capabilities/supported options word so we know what
 	 * work-arounds to enable.  Some firmware revs don't support this
 	 * command.
 	 */
-	if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, &status)) {
+	if (aac_sync_command(sc, AAC_MONKER_GETINFO, 0, 0, 0, 0, &status, NULL)) {
 		if (status != AAC_SRB_STS_INVALID_REQUEST) {
 			device_printf(sc->aac_dev,
 			     "RequestAdapterInfo failed\n");
@@ -1737,14 +1941,18 @@
 		if (options & AAC_SUPPORTED_NONDASD)
 			sc->flags |= AAC_FLAGS_ENABLE_CAM;
 		if ((options & AAC_SUPPORTED_SGMAP_HOST64) != 0
-		     && (sizeof(bus_addr_t) > 4)) {
+			&& (sizeof(bus_addr_t) > 4)
+			&& (sc->hint_flags & 0x1)) {
 			device_printf(sc->aac_dev,
 			    "Enabling 64-bit address support\n");
 			sc->flags |= AAC_FLAGS_SG_64BIT;
 		}
-		if ((options & AAC_SUPPORTED_NEW_COMM)
-		 && sc->aac_if.aif_send_command)
+		if (sc->aac_if.aif_send_command) {
+			if (options & AAC_SUPPORTED_NEW_COMM_TYPE1)
+				sc->flags |= AAC_FLAGS_NEW_COMM | AAC_FLAGS_NEW_COMM_TYPE1;
+			else if (options & AAC_SUPPORTED_NEW_COMM)
 			sc->flags |= AAC_FLAGS_NEW_COMM;
+		}
 		if (options & AAC_SUPPORTED_64BIT_ARRAYSIZE)
 			sc->flags |= AAC_FLAGS_ARRAY_64BIT;
 	}
@@ -1753,32 +1961,71 @@
 	sc->aac_max_fibs = (sc->flags & AAC_FLAGS_256FIBS ? 256:512);
 
 	/* Remap mem. resource, if required */
+	if (sc->aac_hwif == AAC_HWIF_NARK) {
 	if ((sc->flags & AAC_FLAGS_NEW_COMM) &&
-		atu_size > rman_get_size(sc->aac_regs_resource)) {
+			atu_size > rman_get_size(sc->aac_regs_res1)) {
 		bus_release_resource(
 			sc->aac_dev, SYS_RES_MEMORY,
-			sc->aac_regs_rid, sc->aac_regs_resource);
-		sc->aac_regs_resource = bus_alloc_resource(
-			sc->aac_dev, SYS_RES_MEMORY, &sc->aac_regs_rid,
+				sc->aac_regs_rid1, sc->aac_regs_res1);
+			sc->aac_regs_res1 = bus_alloc_resource(
+				sc->aac_dev, SYS_RES_MEMORY, &sc->aac_regs_rid1,
 			0ul, ~0ul, atu_size, RF_ACTIVE);
-		if (sc->aac_regs_resource == NULL) {
-			sc->aac_regs_resource = bus_alloc_resource_any(
+			if (sc->aac_regs_res1 == NULL) {
+				sc->aac_regs_res1 = bus_alloc_resource_any(
 				sc->aac_dev, SYS_RES_MEMORY,
-				&sc->aac_regs_rid, RF_ACTIVE);
-			if (sc->aac_regs_resource == NULL) {
+					&sc->aac_regs_rid1, RF_ACTIVE);
+				if (sc->aac_regs_res1 == NULL) {
 				device_printf(sc->aac_dev,
 				    "couldn't allocate register window\n");
 				return (ENXIO);
 			}
 			sc->flags &= ~AAC_FLAGS_NEW_COMM;
 		}
-		sc->aac_btag = rman_get_bustag(sc->aac_regs_resource);
-		sc->aac_bhandle = rman_get_bushandle(sc->aac_regs_resource);
+			sc->aac_btag1 = rman_get_bustag(sc->aac_regs_res1);
+			sc->aac_bhandle1 = rman_get_bushandle(sc->aac_regs_res1);
+		}
+	} else {
+		if ((sc->flags & AAC_FLAGS_NEW_COMM) &&
+			atu_size > rman_get_size(sc->aac_regs_res0)) {
+			bus_release_resource(
+				sc->aac_dev, SYS_RES_MEMORY,
+				sc->aac_regs_rid0, sc->aac_regs_res0);
+			sc->aac_regs_res0 = bus_alloc_resource(
+				sc->aac_dev, SYS_RES_MEMORY, &sc->aac_regs_rid0,
+				0ul, ~0ul, atu_size, RF_ACTIVE);
+			if (sc->aac_regs_res0 == NULL) {
+				sc->aac_regs_res0 = bus_alloc_resource_any(
+					sc->aac_dev, SYS_RES_MEMORY,
+					&sc->aac_regs_rid0, RF_ACTIVE);
+				if (sc->aac_regs_res0 == NULL) {
+					device_printf(sc->aac_dev,
+						"couldn't allocate register window\n");
+					return (ENXIO);
+				}
+				sc->flags &= ~AAC_FLAGS_NEW_COMM;
+			}
+			sc->aac_btag0 = rman_get_bustag(sc->aac_regs_res0);
+			sc->aac_bhandle0 = rman_get_bushandle(sc->aac_regs_res0);
+		}
+		if (sc->aac_hwif != AAC_HWIF_SRC) {
+			sc->aac_regs_res1 = sc->aac_regs_res0;
+			sc->aac_regs_rid1 = sc->aac_regs_rid0;
+			sc->aac_btag1 = sc->aac_btag0;
+			sc->aac_bhandle1 = sc->aac_bhandle0;
+		}
+	}
+
+	if (sc->aac_hwif == AAC_HWIF_SRC && 
+		!(sc->flags & AAC_FLAGS_NEW_COMM_TYPE1)) {
+		device_printf(sc->aac_dev,
+			"invalid command interface for that controller family!\n");
+		return (EINVAL);
 	}
 
 	/* Read preferred settings */
 	sc->aac_max_fib_size = sizeof(struct aac_fib);
 	sc->aac_max_sectors = 128;				/* 64KB */
+	sc->aac_max_aif = 1;
 	if (sc->flags & AAC_FLAGS_SG_64BIT)
 		sc->aac_sg_tablesize = (AAC_FIB_DATASIZE
 		 - sizeof(struct aac_blockwrite64))
@@ -1788,7 +2035,7 @@
 		 - sizeof(struct aac_blockwrite))
 		 / sizeof(struct aac_sg_entry);
 
-	if (!aac_sync_command(sc, AAC_MONKER_GETCOMMPREF, 0, 0, 0, 0, NULL)) {
+	if (!aac_sync_command(sc, AAC_MONKER_GETCOMMPREF, 0, 0, 0, 0, NULL, NULL)) {
 		options = AAC_GET_MAILBOX(sc, 1);
 		sc->aac_max_fib_size = (options & 0xFFFF);
 		sc->aac_max_sectors = (options >> 16) << 1;
@@ -1796,10 +2043,22 @@
 		sc->aac_sg_tablesize = (options >> 16);
 		options = AAC_GET_MAILBOX(sc, 3);
 		sc->aac_max_fibs = (options & 0xFFFF);
+		options = AAC_GET_MAILBOX(sc, 4);
+		sc->aac_max_aif = (options & 0xFFFF);
+	}
+
+	/* PATCH: problem with SRC and max_fibs == 128 */
+	if (sc->aac_hwif == AAC_HWIF_SRC && sc->aac_max_fibs > 126)
+		sc->aac_max_fibs = 126;
+
+	maxsize = sc->aac_max_fib_size;
+	if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE1) 
+		maxsize += sizeof(struct aac_fib_xporthdr) + 31;
+	if (maxsize > PAGE_SIZE) {
+    	sc->aac_max_fib_size -= (maxsize - PAGE_SIZE);
+		maxsize = PAGE_SIZE;
 	}
-	if (sc->aac_max_fib_size > PAGE_SIZE)
-		sc->aac_max_fib_size = PAGE_SIZE;
-	sc->aac_max_fibs_alloc = PAGE_SIZE / sc->aac_max_fib_size;
+	sc->aac_max_fibs_alloc = PAGE_SIZE / maxsize;
 
 	if (sc->aac_max_fib_size > sizeof(struct aac_fib)) {
 		sc->flags |= AAC_FLAGS_RAW_IO;
@@ -1811,6 +2070,7 @@
 		device_printf(sc->aac_dev, "Enable 64-bit array\n");
 	}
 
+	aac_get_fw_debug_buffer(sc);
 	return (0);
 }
 
@@ -1859,10 +2119,28 @@
 	ip->HostElapsedSeconds = time_uptime;	/* reset later if invalid */
 
 	ip->InitFlags = 0;
-	if (sc->flags & AAC_FLAGS_NEW_COMM) {
-		ip->InitFlags = INITFLAGS_NEW_COMM_SUPPORTED;
+	if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE1) {
+		ip->InitStructRevision = AAC_INIT_STRUCT_REVISION_6;
+		ip->InitFlags |= AAC_INITFLAGS_NEW_COMM_TYPE1_SUPPORTED;
+		device_printf(sc->aac_dev, "New comm. interface type1 enabled\n");
+	} else if (sc->flags & AAC_FLAGS_NEW_COMM) {
+		ip->InitFlags |= AAC_INITFLAGS_NEW_COMM_SUPPORTED;
 		device_printf(sc->aac_dev, "New comm. interface enabled\n");
 	}
+	ip->MaxNumAif = sc->aac_max_aif;
+	ip->HostRRQ_AddrLow = 
+		sc->aac_common_busaddr + offsetof(struct aac_common, ac_host_rrq);
+	/* always 32-bit address */
+	ip->HostRRQ_AddrHigh = 0;
+
+	/* ADPml10863: Disable Power Management support */
+	sc->aac_support_opt2 &= ~AAC_SUPPORTED_POWER_MANAGEMENT;
+
+	if (sc->aac_support_opt2 & AAC_SUPPORTED_POWER_MANAGEMENT) {
+		ip->InitFlags |= AAC_INITFLAGS_DRIVER_SUPPORTS_PM;
+		ip->InitFlags |= AAC_INITFLAGS_DRIVER_USES_UTC_TIME;
+		device_printf(sc->aac_dev, "Power Management enabled\n");
+	}
 
 	ip->MaxIoCommands = sc->aac_max_fibs;
 	ip->MaxIoSize = sc->aac_max_sectors << 9;
@@ -1944,10 +2222,13 @@
 	 */
 	switch (sc->aac_hwif) {
 	case AAC_HWIF_I960RX:
-		AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
+		AAC_MEM0_SETREG4(sc, AAC_RX_ODBR, ~0);
 		break;
 	case AAC_HWIF_RKT:
-		AAC_SETREG4(sc, AAC_RKT_ODBR, ~0);
+		AAC_MEM0_SETREG4(sc, AAC_RKT_ODBR, ~0);
+		break;
+	case AAC_HWIF_SRC:
+		AAC_MEM0_SETREG4(sc, AAC_SRC_ODBR_C, ~0);
 		break;
 	default:
 		break;
@@ -1959,7 +2240,7 @@
 	if (aac_sync_command(sc, AAC_MONKER_INITSTRUCT,
 			     sc->aac_common_busaddr +
 			     offsetof(struct aac_common, ac_init), 0, 0, 0,
-			     NULL)) {
+			     NULL, NULL)) {
 		device_printf(sc->aac_dev,
 			      "error establishing init structure\n");
 		error = EIO;
@@ -1982,7 +2263,14 @@
 		device_printf(sc->aac_dev, "can't allocate interrupt\n");
 		return (EINVAL);
 	}
-	if (sc->flags & AAC_FLAGS_NEW_COMM) {
+	if (sc->flags & AAC_FLAGS_NEW_COMM_TYPE1) {
+		if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
+				   INTR_MPSAFE|INTR_TYPE_BIO, NULL, 
+				   aac_new_intr_type1, sc, &sc->aac_intr)) {
+			device_printf(sc->aac_dev, "can't set up interrupt\n");
+			return (EINVAL);
+		}
+	} else if (sc->flags & AAC_FLAGS_NEW_COMM) {
 		if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
 				   INTR_MPSAFE|INTR_TYPE_BIO, NULL, 
 				   aac_new_intr, sc, &sc->aac_intr)) {
@@ -2012,10 +2300,10 @@
  * Send a synchronous command to the controller and wait for a result.
  * Indicate if the controller completed the command with an error status.
  */
-static int
+int
 aac_sync_command(struct aac_softc *sc, u_int32_t command,
 		 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3,
-		 u_int32_t *sp)
+		 u_int32_t *sp, u_int32_t *r1)
 {
 	time_t then;
 	u_int32_t status;
@@ -2048,6 +2336,10 @@
 	if (sp != NULL)
 		*sp = status;
 
+	/* return parameter */
+	if (r1 != NULL) 
+		*r1 = AAC_GET_MAILBOX(sc, 1);
+
 	if (status != AAC_SRB_STS_SUCCESS)
 		return (-1);
 	return(0);
@@ -2083,7 +2375,7 @@
 	 * Give the FIB to the controller, wait for a response.
 	 */
 	if (aac_sync_command(sc, AAC_MONKER_SYNCFIB,
-			     fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) {
+			     fib->Header.ReceiverFibAddress, 0, 0, 0, NULL, NULL)) {
 		fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "IO error");
 		return(EIO);
 	}
@@ -2350,6 +2642,7 @@
 		if (code != AAC_UP_AND_RUNNING) {
 			device_printf(sc->aac_dev, "WARNING! Controller is no "
 				      "longer running! code= 0x%x\n", code);
+			aac_reset_adapter(sc);
 		}
 	}
 	return;
@@ -2367,7 +2660,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_SA_FWSTATUS));
+	return(AAC_MEM0_GETREG4(sc, AAC_SA_FWSTATUS));
 }
 
 static int
@@ -2375,7 +2668,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_RX_FWSTATUS));
+	return(AAC_MEM0_GETREG4(sc, AAC_RX_OMR0));
 }
 
 static int
@@ -2385,7 +2678,7 @@
 
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	val = AAC_GETREG4(sc, AAC_FA_FWSTATUS);
+	val = AAC_MEM0_GETREG4(sc, AAC_FA_FWSTATUS);
 	return (val);
 }
 
@@ -2394,7 +2687,15 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_RKT_FWSTATUS));
+	return(AAC_MEM0_GETREG4(sc, AAC_RKT_OMR0));
+}
+
+static int
+aac_src_get_fwstatus(struct aac_softc *sc)
+{
+	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+	return(AAC_MEM0_GETREG4(sc, AAC_SRC_OMR));
 }
 
 /*
@@ -2406,7 +2707,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
+	AAC_MEM0_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
 }
 
 static void
@@ -2414,7 +2715,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_RX_IDBR, qbit);
+	AAC_MEM0_SETREG4(sc, AAC_RX_IDBR, qbit);
 }
 
 static void
@@ -2422,7 +2723,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG2(sc, AAC_FA_DOORBELL1, qbit);
+	AAC_MEM0_SETREG2(sc, AAC_FA_DOORBELL1, qbit);
 	AAC_FA_HACK(sc);
 }
 
@@ -2431,7 +2732,15 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_RKT_IDBR, qbit);
+	AAC_MEM0_SETREG4(sc, AAC_RKT_IDBR, qbit);
+}
+
+static void
+aac_src_qnotify(struct aac_softc *sc, int qbit)
+{
+	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+	AAC_MEM0_SETREG4(sc, AAC_SRC_IDBR, qbit << AAC_SRC_IDR_SHIFT);
 }
 
 /*
@@ -2442,7 +2751,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG2(sc, AAC_SA_DOORBELL0));
+	return(AAC_MEM0_GETREG2(sc, AAC_SA_DOORBELL0));
 }
 
 static int
@@ -2450,7 +2759,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_RX_ODBR));
+	return(AAC_MEM0_GETREG4(sc, AAC_RX_ODBR));
 }
 
 static int
@@ -2460,7 +2769,7 @@
 
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	val = AAC_GETREG2(sc, AAC_FA_DOORBELL0);
+	val = AAC_MEM0_GETREG2(sc, AAC_FA_DOORBELL0);
 	return (val);
 }
 
@@ -2469,7 +2778,15 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_RKT_ODBR));
+	return(AAC_MEM0_GETREG4(sc, AAC_RKT_ODBR));
+}
+
+static int
+aac_src_get_istatus(struct aac_softc *sc)
+{
+	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+	return(AAC_MEM0_GETREG4(sc, AAC_SRC_ODBR_R) >> AAC_SRC_ODR_SHIFT);
 }
 
 /*
@@ -2480,7 +2797,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
+	AAC_MEM0_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
 }
 
 static void
@@ -2488,7 +2805,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_RX_ODBR, mask);
+	AAC_MEM0_SETREG4(sc, AAC_RX_ODBR, mask);
 }
 
 static void
@@ -2496,7 +2813,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask);
+	AAC_MEM0_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask);
 	AAC_FA_HACK(sc);
 }
 
@@ -2505,7 +2822,15 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_RKT_ODBR, mask);
+	AAC_MEM0_SETREG4(sc, AAC_RKT_ODBR, mask);
+}
+
+static void
+aac_src_clear_istatus(struct aac_softc *sc, int mask)
+{
+	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+	AAC_MEM0_SETREG4(sc, AAC_SRC_ODBR_C, mask << AAC_SRC_ODR_SHIFT);
 }
 
 /*
@@ -2517,11 +2842,11 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_SA_MAILBOX, command);
-	AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
-	AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
-	AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
-	AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
+	AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX, command);
+	AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
+	AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
+	AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
+	AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
 }
 
 static void
@@ -2530,11 +2855,11 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_RX_MAILBOX, command);
-	AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
-	AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
-	AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
-	AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
+	AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX, command);
+	AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
+	AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
+	AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
+	AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
 }
 
 static void
@@ -2543,15 +2868,15 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_FA_MAILBOX, command);
+	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX, command);
 	AAC_FA_HACK(sc);
-	AAC_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0);
+	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0);
 	AAC_FA_HACK(sc);
-	AAC_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1);
+	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1);
 	AAC_FA_HACK(sc);
-	AAC_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2);
+	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2);
 	AAC_FA_HACK(sc);
-	AAC_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3);
+	AAC_MEM1_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3);
 	AAC_FA_HACK(sc);
 }
 
@@ -2561,11 +2886,24 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_RKT_MAILBOX, command);
-	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0);
-	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1);
-	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2);
-	AAC_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3);
+	AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX, command);
+	AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0);
+	AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1);
+	AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2);
+	AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3);
+}
+
+static void
+aac_src_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
+		    u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
+{
+	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+	AAC_MEM0_SETREG4(sc, AAC_SRC_MAILBOX, command);
+	AAC_MEM0_SETREG4(sc, AAC_SRC_MAILBOX + 4, arg0);
+	AAC_MEM0_SETREG4(sc, AAC_SRC_MAILBOX + 8, arg1);
+	AAC_MEM0_SETREG4(sc, AAC_SRC_MAILBOX + 12, arg2);
+	AAC_MEM0_SETREG4(sc, AAC_SRC_MAILBOX + 16, arg3);
 }
 
 /*
@@ -2576,7 +2914,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4)));
+	return(AAC_MEM1_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4)));
 }
 
 static int
@@ -2584,7 +2922,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
+	return(AAC_MEM1_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
 }
 
 static int
@@ -2594,7 +2932,7 @@
 
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	val = AAC_GETREG4(sc, AAC_FA_MAILBOX + (mb * 4));
+	val = AAC_MEM1_GETREG4(sc, AAC_FA_MAILBOX + (mb * 4));
 	return (val);
 }
 
@@ -2603,7 +2941,15 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4)));
+	return(AAC_MEM1_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4)));
+}
+
+static int
+aac_src_get_mailbox(struct aac_softc *sc, int mb)
+{
+	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+	return(AAC_MEM0_GETREG4(sc, AAC_SRC_MAILBOX + (mb * 4)));
 }
 
 /*
@@ -2615,9 +2961,9 @@
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
 
 	if (enable) {
-		AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
+		AAC_MEM0_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
 	} else {
-		AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
+		AAC_MEM0_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
 	}
 }
 
@@ -2628,11 +2974,11 @@
 
 	if (enable) {
 		if (sc->flags & AAC_FLAGS_NEW_COMM)
-			AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INT_NEW_COMM);
+			AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INT_NEW_COMM);
 		else
-			AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
+			AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
 	} else {
-		AAC_SETREG4(sc, AAC_RX_OIMR, ~0);
+		AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~0);
 	}
 }
 
@@ -2642,10 +2988,10 @@
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
 
 	if (enable) {
-		AAC_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
+		AAC_MEM0_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
 		AAC_FA_HACK(sc);
 	} else {
-		AAC_SETREG2((sc), AAC_FA_MASK0, ~0);
+		AAC_MEM0_SETREG2((sc), AAC_FA_MASK0, ~0);
 		AAC_FA_HACK(sc);
 	}
 }
@@ -2657,11 +3003,23 @@
 
 	if (enable) {
 		if (sc->flags & AAC_FLAGS_NEW_COMM)
-			AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INT_NEW_COMM);
+			AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INT_NEW_COMM);
 		else
-			AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
+			AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
 	} else {
-		AAC_SETREG4(sc, AAC_RKT_OIMR, ~0);
+		AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~0);
+	}
+}
+
+static void
+aac_src_set_interrupts(struct aac_softc *sc, int enable)
+{
+	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
+
+	if (enable) {
+		AAC_MEM0_SETREG4(sc, AAC_SRC_OIMR, ~AAC_DB_INT_NEW_COMM_TYPE1);
+	} else {
+		AAC_MEM0_SETREG4(sc, AAC_SRC_OIMR, ~0);
 	}
 }
 
@@ -2675,19 +3033,19 @@
 
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm.)");
 
-	index = AAC_GETREG4(sc, AAC_RX_IQUE);
+	index = AAC_MEM0_GETREG4(sc, AAC_RX_IQUE);
 	if (index == 0xffffffffL)
-		index = AAC_GETREG4(sc, AAC_RX_IQUE);
+		index = AAC_MEM0_GETREG4(sc, AAC_RX_IQUE);
 	if (index == 0xffffffffL)
 		return index;
 	aac_enqueue_busy(cm);
 	device = index;
-	AAC_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
+	AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
 	device += 4;
-	AAC_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
+	AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
 	device += 4;
-	AAC_SETREG4(sc, device, cm->cm_fib->Header.Size);
-	AAC_SETREG4(sc, AAC_RX_IQUE, index);
+	AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size);
+	AAC_MEM0_SETREG4(sc, AAC_RX_IQUE, index);
 	return 0;
 }
 
@@ -2698,19 +3056,48 @@
 
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm.)");
 
-	index = AAC_GETREG4(sc, AAC_RKT_IQUE);
+	index = AAC_MEM0_GETREG4(sc, AAC_RKT_IQUE);
 	if (index == 0xffffffffL)
-		index = AAC_GETREG4(sc, AAC_RKT_IQUE);
+		index = AAC_MEM0_GETREG4(sc, AAC_RKT_IQUE);
 	if (index == 0xffffffffL)
 		return index;
 	aac_enqueue_busy(cm);
 	device = index;
-	AAC_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
+	AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
 	device += 4;
-	AAC_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
+	AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
 	device += 4;
-	AAC_SETREG4(sc, device, cm->cm_fib->Header.Size);
-	AAC_SETREG4(sc, AAC_RKT_IQUE, index);
+	AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size);
+	AAC_MEM0_SETREG4(sc, AAC_RKT_IQUE, index);
+	return 0;
+}
+
+static int
+aac_src_send_command(struct aac_softc *sc, struct aac_command *cm)
+{
+	struct aac_fib_xporthdr *pFibX;
+	u_int32_t fibsize;
+	u_int64_t address;
+
+	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm. type1)");
+
+	/* Calculate the amount to the fibsize bits */
+	fibsize = (sizeof(struct aac_fib_xporthdr) + 
+	   cm->cm_fib->Header.Size + 127) / 128 - 1; 
+	if (fibsize > 31) 
+		fibsize = 31;
+
+	/* Fill XPORT header */ 
+	pFibX = (struct aac_fib_xporthdr *)
+		((unsigned char *)cm->cm_fib - sizeof(struct aac_fib_xporthdr));
+	pFibX->Handle = cm->cm_fib->Header.SenderData + 1;
+	pFibX->HostAddress = cm->cm_fibphys;
+	pFibX->Size = cm->cm_fib->Header.Size;
+	address = cm->cm_fibphys - sizeof(struct aac_fib_xporthdr);
+
+	aac_enqueue_busy(cm);
+	AAC_MEM0_SETREG4(sc, AAC_SRC_IQUE_H, (u_int32_t)(address >> 32));
+	AAC_MEM0_SETREG4(sc, AAC_SRC_IQUE_L, (u_int32_t)address + fibsize);
 	return 0;
 }
 
@@ -2722,7 +3109,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_RX_OQUE));
+	return(AAC_MEM0_GETREG4(sc, AAC_RX_OQUE));
 }
 
 static int
@@ -2730,7 +3117,15 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	return(AAC_GETREG4(sc, AAC_RKT_OQUE));
+	return(AAC_MEM0_GETREG4(sc, AAC_RKT_OQUE));
+}
+
+static int
+aac_src_get_outb_queue(struct aac_softc *sc)
+{
+	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+	return(-1);
 }
 
 static void
@@ -2738,7 +3133,7 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_RX_OQUE, index);
+	AAC_MEM0_SETREG4(sc, AAC_RX_OQUE, index);
 }
 
 static void
@@ -2746,7 +3141,13 @@
 {
 	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	AAC_SETREG4(sc, AAC_RKT_OQUE, index);
+	AAC_MEM0_SETREG4(sc, AAC_RKT_OQUE, index);
+}
+
+static void
+aac_src_set_outb_queue(struct aac_softc *sc, int index)
+{
+	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 }
 
 /*
@@ -2768,6 +3169,24 @@
 	mtx_lock(&sc->aac_io_lock);
 	aac_alloc_sync_fib(sc, &fib);
 
+	if (sc->supported_options & AAC_SUPPORTED_SUPPLEMENT_ADAPTER_INFO) {
+		fib->data[0] = 0;
+		if (aac_sync_fib(sc, RequestSupplementAdapterInfo, 0, fib, 1)) 
+			device_printf(sc->aac_dev, "RequestSupplementAdapterInfo failed\n");
+		else {
+			struct aac_supplement_adapter_info *supp_info;
+
+			supp_info = ((struct aac_supplement_adapter_info *)&fib->data[0]); 
+			adapter_type = supp_info->AdapterTypeText;
+			sc->aac_feature_bits = supp_info->FeatureBits;
+			sc->aac_support_opt2 = supp_info->SupportedOptions2;
+		}
+	}
+	device_printf(sc->aac_dev, "%s, aac driver %d.%d.%d-%d\n",
+		adapter_type,
+		AAC_DRIVER_MAJOR_VERSION, AAC_DRIVER_MINOR_VERSION,
+		AAC_DRIVER_BUGFIX_LEVEL, AAC_DRIVER_BUILD);
+
 	fib->data[0] = 0;
 	if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) {
 		device_printf(sc->aac_dev, "RequestAdapterInfo failed\n");
@@ -2822,22 +3241,6 @@
 			      "\24HEATSENSOR");
 	}
 
-	if (sc->supported_options & AAC_SUPPORTED_SUPPLEMENT_ADAPTER_INFO) {
-		fib->data[0] = 0;
-		if (aac_sync_fib(sc, RequestSupplementAdapterInfo, 0, fib, 1))
-			device_printf(sc->aac_dev,
-			    "RequestSupplementAdapterInfo failed\n");
-		else
-			adapter_type = ((struct aac_supplement_adapter_info *)
-			    &fib->data[0])->AdapterTypeText;
-	}
-	device_printf(sc->aac_dev, "%s, aac driver %d.%d.%d-%d\n",
-		adapter_type,
-		AAC_DRIVER_VERSION >> 24,
-		(AAC_DRIVER_VERSION >> 16) & 0xFF,
-		AAC_DRIVER_VERSION & 0xFF,
-		AAC_DRIVER_BUILD);
-
 	aac_release_sync_fib(sc);
 	mtx_unlock(&sc->aac_io_lock);
 }
@@ -3127,7 +3530,242 @@
 static int
 aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg)
 {
-	return (EINVAL);
+	struct aac_command *cm;
+	struct aac_fib *fib;
+	struct aac_srb *srbcmd;
+	struct aac_srb *user_srb = (struct aac_srb *)arg;
+	void *user_reply;
+	int error, transfer_data = 0;
+	bus_dmamap_t orig_map = 0;
+	u_int32_t fibsize = 0;
+	u_int64_t srb_sg_address;
+	u_int32_t srb_sg_bytecount;
+
+	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+	cm = NULL;
+
+	mtx_lock(&sc->aac_io_lock);
+	if (aac_alloc_command(sc, &cm)) {
+		struct aac_event *event;
+
+		event = malloc(sizeof(struct aac_event), M_AACBUF,
+		    M_NOWAIT | M_ZERO);
+		if (event == NULL) {
+			error = EBUSY;
+			mtx_unlock(&sc->aac_io_lock);
+			goto out;
+		}
+		event->ev_type = AAC_EVENT_CMFREE;
+		event->ev_callback = aac_ioctl_event;
+		event->ev_arg = &cm;
+		aac_add_event(sc, event);
+		msleep(cm, &sc->aac_io_lock, 0, "sndraw", 0);
+	}
+	mtx_unlock(&sc->aac_io_lock);
+
+	cm->cm_data = NULL;
+	/* save original dma map */
+	orig_map = cm->cm_datamap;
+
+	fib = cm->cm_fib;
+	srbcmd = (struct aac_srb *)fib->data;
+	if ((error = copyin((void *)&user_srb->data_len, &fibsize, 
+		sizeof (u_int32_t)) != 0)) 
+		goto out;
+	if (fibsize > (sc->aac_max_fib_size-sizeof(struct aac_fib_header))) {
+		error = EINVAL;
+		goto out;
+	}
+	if ((error = copyin((void *)user_srb, srbcmd, fibsize) != 0)) 
+		goto out;
+
+	srbcmd->function = 0;		/* SRBF_ExecuteScsi */
+	srbcmd->retry_limit = 0;	/* obsolete */
+
+	/* only one sg element from userspace supported */
+	if (srbcmd->sg_map.SgCount > 1) {
+		error = EINVAL;
+		goto out;
+	}
+	/* check fibsize */
+	if (fibsize == (sizeof(struct aac_srb) + 
+		srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry))) {
+		struct aac_sg_entry *sgp = srbcmd->sg_map.SgEntry;
+		srb_sg_bytecount = sgp->SgByteCount;
+		srb_sg_address = (u_int64_t)sgp->SgAddress;
+	} else if (fibsize == (sizeof(struct aac_srb) + 
+		srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry64))) {
+#ifdef __amd64__
+		struct aac_sg_entry64 *sgp = 
+			(struct aac_sg_entry64 *)srbcmd->sg_map.SgEntry;
+		srb_sg_bytecount = sgp->SgByteCount;
+		srb_sg_address = sgp->SgAddress;
+		if (srb_sg_address > 0xffffffffull && 
+			!(sc->flags & AAC_FLAGS_SG_64BIT))
+#endif	
+		{
+			error = EINVAL;
+			goto out;
+		}
+	} else {
+		error = EINVAL;
+		goto out;
+	}
+	user_reply = (char *)arg + fibsize;
+	srbcmd->data_len = srb_sg_bytecount;
+	if (srbcmd->sg_map.SgCount == 1) 
+		transfer_data = 1;
+
+	if (transfer_data) {
+		/*
+		 * Create DMA tag for the passthr. data buffer and allocate it.
+		 */
+		if (bus_dma_tag_create(sc->aac_parent_dmat, 	/* parent */
+			1, 0,			/* algnmnt, boundary */
+			(sc->flags & AAC_FLAGS_SG_64BIT) ?
+			BUS_SPACE_MAXADDR_32BIT :
+			0x7fffffff,		/* lowaddr */
+			BUS_SPACE_MAXADDR, 	/* highaddr */
+			NULL, NULL, 		/* filter, filterarg */
+			srb_sg_bytecount, 	/* size */
+			sc->aac_sg_tablesize,	/* nsegments */
+			srb_sg_bytecount, 	/* maxsegsize */
+			0,			/* flags */
+			NULL, NULL,		/* No locking needed */
+			&cm->cm_passthr_dmat)) {
+			error = ENOMEM;
+			goto out;
+		}
+		if (bus_dmamem_alloc(cm->cm_passthr_dmat, (void **)&cm->cm_data,
+			BUS_DMA_NOWAIT, &cm->cm_datamap)) {
+			error = ENOMEM;
+			goto out;
+		}
+		/* fill some cm variables */
+		cm->cm_datalen = srb_sg_bytecount;
+		if (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN) 
+			cm->cm_flags |= AAC_CMD_DATAIN;
+		if (srbcmd->flags & AAC_SRB_FLAGS_DATA_OUT)
+			cm->cm_flags |= AAC_CMD_DATAOUT;
+
+		if (srbcmd->flags & AAC_SRB_FLAGS_DATA_OUT) {
+			if ((error = copyin(
+#ifdef __amd64__
+				(void *)srb_sg_address,
+#else
+				(void *)(u_int32_t)srb_sg_address,
+#endif
+				cm->cm_data, cm->cm_datalen)) != 0)
+				goto out;
+			/* sync required for bus_dmamem_alloc() alloc. mem.? */
+			bus_dmamap_sync(cm->cm_passthr_dmat, cm->cm_datamap,
+				BUS_DMASYNC_PREWRITE);
+		}
+	}
+
+	/* build the FIB */
+	fib->Header.Size = sizeof(struct aac_fib_header) + 
+		sizeof(struct aac_srb);
+	fib->Header.XferState =
+		AAC_FIBSTATE_HOSTOWNED   |
+		AAC_FIBSTATE_INITIALISED |
+		AAC_FIBSTATE_EMPTY	 |
+		AAC_FIBSTATE_FROMHOST	 |
+		AAC_FIBSTATE_REXPECTED   |
+		AAC_FIBSTATE_NORM	 |
+		AAC_FIBSTATE_ASYNC	 |
+		AAC_FIBSTATE_FAST_RESPONSE;
+
+	fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) ? 
+		ScsiPortCommandU64 : ScsiPortCommand;
+	cm->cm_sgtable = (struct aac_sg_table *)&srbcmd->sg_map;
+
+	/* send command */
+	if (transfer_data) {
+		bus_dmamap_load(cm->cm_passthr_dmat,
+			cm->cm_datamap, cm->cm_data,
+			cm->cm_datalen,
+			aac_map_command_sg, cm, 0);
+	} else {
+		aac_map_command_sg(cm, NULL, 0, 0);
+	}
+
+	/* wait for completion */
+	mtx_lock(&sc->aac_io_lock);
+	while (!(cm->cm_flags & AAC_CMD_COMPLETED))
+		msleep(cm, &sc->aac_io_lock, 0, "sndrw2", 0);
+	mtx_unlock(&sc->aac_io_lock);
+
+	/* copy data */
+	if (transfer_data && (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN)) {
+		if ((error = copyout(cm->cm_data, 
+#ifdef __amd64__
+			(void *)srb_sg_address,
+#else
+			(void *)(u_int32_t)srb_sg_address,
+#endif
+			cm->cm_datalen)) != 0)
+			goto out;
+		/* sync required for bus_dmamem_alloc() allocated mem.? */
+		bus_dmamap_sync(cm->cm_passthr_dmat, cm->cm_datamap,
+				BUS_DMASYNC_POSTREAD);
+	}
+
+	/* status */
+	error = copyout(fib->data, user_reply, sizeof(struct aac_srb_response));
+
+out:
+	if (cm && cm->cm_data) {
+		if (transfer_data)
+			bus_dmamap_unload(cm->cm_passthr_dmat, cm->cm_datamap);
+		bus_dmamem_free(cm->cm_passthr_dmat, cm->cm_data, cm->cm_datamap);
+		cm->cm_datamap = orig_map;
+	}
+	if (cm && cm->cm_passthr_dmat) 
+		bus_dma_tag_destroy(cm->cm_passthr_dmat);
+	if (cm) { 
+		mtx_lock(&sc->aac_io_lock);
+		aac_release_command(cm);
+		mtx_unlock(&sc->aac_io_lock);
+	}
+	return(error);
+}
+
+/*
+ * Request an AIF from the controller (new comm. type1)
+ */
+static void
+aac_request_aif(struct aac_softc *sc)
+{
+	struct aac_command *cm;
+	struct aac_fib *fib;
+
+	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+	if (aac_alloc_command(sc, &cm)) {
+		sc->aif_pending = 1;
+		return;
+	}
+	sc->aif_pending = 0;
+    
+	/* build the FIB */
+	fib = cm->cm_fib;
+	fib->Header.Size = sizeof(struct aac_fib);
+	fib->Header.XferState =
+        AAC_FIBSTATE_HOSTOWNED   |
+        AAC_FIBSTATE_INITIALISED |
+        AAC_FIBSTATE_EMPTY	 |
+        AAC_FIBSTATE_FROMHOST	 |
+        AAC_FIBSTATE_REXPECTED   |
+        AAC_FIBSTATE_NORM	 |
+        AAC_FIBSTATE_ASYNC;
+	/* set AIF marker */
+	fib->Header.SenderData = 0x00800000;
+	fib->Header.Command = AifRequest;
+	((struct aac_aif_command *)fib->data)->command = AifReqEvent;
+
+	aac_map_command_sg(cm, NULL, 0, 0);
 }
 
 /*
@@ -3221,6 +3859,9 @@
 			co = TAILQ_FIRST(&sc->aac_container_tqh);
 			while (co != NULL) {
 				if (co->co_found == 0) {
+					struct aac_disk *ad;
+					ad = device_get_softc(co->co_disk);
+					ad->ad_container = NULL;
 					mtx_unlock(&sc->aac_io_lock);
 					mtx_lock(&Giant);
 					device_delete_child(sc->aac_dev,
@@ -3251,6 +3892,17 @@
 
 			break;
 
+		case AifEnAddJBOD:
+		case AifEnDeleteJBOD:
+			{
+				u_int32_t container = 
+					aif->data.EN.data.ECE.container;
+
+				/* re-enumerate JBOD devices */
+				aac_cam_rescan_jbod(sc,((container>>24) & 0xf));
+			}
+			break;
+
 		default:
 			break;
 		}
@@ -3316,10 +3968,16 @@
 	 * Doctor up the response struct.
 	 */
 	rev_check_resp.possiblyCompatible = 1;
-	rev_check_resp.adapterSWRevision.external.ul =
-	    sc->aac_revision.external.ul;
+	rev_check_resp.adapterSWRevision.external.comp.major =
+	    AAC_DRIVER_MAJOR_VERSION;
+	rev_check_resp.adapterSWRevision.external.comp.minor =
+		AAC_DRIVER_MINOR_VERSION;
+	rev_check_resp.adapterSWRevision.external.comp.type =
+		AAC_DRIVER_TYPE;
+	rev_check_resp.adapterSWRevision.external.comp.dash =
+		AAC_DRIVER_BUGFIX_LEVEL;
 	rev_check_resp.adapterSWRevision.buildNumber =
-	    sc->aac_revision.buildNumber;
+	    (u_int32_t)AAC_DRIVER_BUILD;
 
 	return(copyout((caddr_t)&rev_check_resp, udata,
 			sizeof(struct aac_rev_check_resp)));
@@ -3511,6 +4169,7 @@
 	 if (f.feat.fValue == 0) {
 		f.feat.fBits.largeLBA =
 		    (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
+		f.feat.fBits.JBODSupport = 1;
 		/* TODO: In the future, add other features state here as well */
 	} else {
 		if (f.feat.fBits.largeLBA)
@@ -3682,6 +4341,7 @@
 		caminf->InitiatorBusId = businfo.InitiatorBusId[i];
 		caminf->aac_sc = sc;
 		caminf->sim_dev = child;
+		caminf->aac_cam = NULL;
 
 		device_set_ivars(child, caminf);
 		device_set_desc(child, "SCSI Passthrough Bus");
@@ -3695,3 +4355,164 @@
 
 	return;
 }
+
+/*
+ * Check to see if the kernel is up and running. If we are in a
+ * BlinkLED state, return the BlinkLED code.
+ */
+static u_int32_t
+aac_check_adapter_health(struct aac_softc *sc, u_int8_t *bled)
+{
+	u_int32_t ret;
+
+	ret = AAC_GET_FWSTATUS(sc);
+
+	if (ret & AAC_UP_AND_RUNNING)
+		ret = 0;
+	else if (ret & AAC_KERNEL_PANIC && bled)
+		*bled = (ret >> 16) & 0xff;
+
+	return (ret);
+}
+
+/*
+ * Once do an IOP reset, basically have to re-initialize the card as
+ * if coming up from a cold boot, and the driver is responsible for
+ * any IO that was outstanding to the adapter at the time of the IOP
+ * RESET. And prepare the driver for IOP RESET by making the init code
+ * modular with the ability to call it from multiple places.
+ */
+static int
+aac_reset_adapter(struct aac_softc *sc)
+{
+	struct aac_command *cm;
+	struct aac_fib *fib;
+	struct aac_pause_command *pc;
+	u_int32_t status, old_flags, reset_mask, waitCount;
+
+	fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+	if (sc->aac_state & AAC_STATE_RESET) {
+		device_printf(sc->aac_dev, "aac_reset_adapter() already in progress\n");
+		return (EINVAL);
+	}
+	sc->aac_state |= AAC_STATE_RESET;
+
+	/* disable interrupt */
+	AAC_MASK_INTERRUPTS(sc);
+
+	/*
+	 * Abort all pending commands:
+	 * a) on the controller
+	 */
+	while ((cm = aac_dequeue_busy(sc)) != NULL) {
+		cm->cm_flags |= AAC_CMD_RESET;
+
+		/* is there a completion handler? */
+		if (cm->cm_complete != NULL) {
+			cm->cm_complete(cm);
+		} else {
+			/* assume that someone is sleeping on this
+			 * command
+			 */
+			wakeup(cm);
+		}
+	}
+
+	/* b) in the waiting queues */
+	while ((cm = aac_dequeue_ready(sc)) != NULL) {
+		cm->cm_flags |= AAC_CMD_RESET;
+
+		/* is there a completion handler? */
+		if (cm->cm_complete != NULL) {
+			cm->cm_complete(cm);
+		} else {
+			/* assume that someone is sleeping on this
+			 * command
+			 */
+			wakeup(cm);
+		}
+	}
+
+	/* flush drives */
+	if (aac_check_adapter_health(sc, NULL) == 0)
+		(void) aac_shutdown(sc->aac_dev);
+
+	/* execute IOP reset */
+	if (sc->supported_options & AAC_SUPPORTED_MU_RESET) {
+		AAC_MEM0_SETREG4(sc, AAC_IRCSR, AAC_IRCSR_CORES_RST);
+
+		/* We need to wait for 5 seconds before accessing the MU again
+		 * 10000 * 100us = 1000,000us = 1000ms = 1s  
+		 */
+		waitCount = 5 * 10000;
+		while (waitCount) {
+			DELAY(100);			/* delay 100 microseconds */
+			waitCount--;
+		}
+	} else if ((aac_sync_command(sc, 
+		AAC_IOP_RESET_ALWAYS, 0, 0, 0, 0, &status, &reset_mask)) != 0) {
+		/* call IOP_RESET for older firmware */
+		if ((aac_sync_command(sc, 
+			AAC_IOP_RESET, 0, 0, 0, 0, &status, NULL)) != 0) {
+
+			if (status == AAC_SRB_STS_INVALID_REQUEST)
+				device_printf(sc->aac_dev, "IOP_RESET not supported\n");
+			else
+				/* probably timeout */
+				device_printf(sc->aac_dev, "IOP_RESET failed\n");
+
+			/* unwind aac_shutdown() */
+			aac_alloc_sync_fib(sc, &fib);
+			pc = (struct aac_pause_command *)&fib->data[0];
+			pc->Command = VM_ContainerConfig;
+			pc->Type = CT_PAUSE_IO;
+			pc->Timeout = 1;
+			pc->Min = 1;
+			pc->NoRescan = 1;
+
+			(void) aac_sync_fib(sc, ContainerCommand, 0, fib,
+				sizeof (struct aac_pause_command));
+			aac_release_sync_fib(sc);
+
+			goto finish;
+		}
+	} else if (sc->supported_options & AAC_SUPPORTED_DOORBELL_RESET) {
+		AAC_MEM0_SETREG4(sc, AAC_SRC_IDBR, reset_mask);
+		/* We need to wait for 5 seconds before accessing the doorbell again
+		 * 10000 * 100us = 1000,000us = 1000ms = 1s  
+		 */
+		waitCount = 5 * 10000;
+		while (waitCount) {
+			DELAY(100);			/* delay 100 microseconds */
+			waitCount--;
+		}
+	}
+
+	/*
+	 * Re-read and renegotiate the FIB parameters, as one of the actions
+	 * that can result from an IOP reset is the running of a new firmware
+	 * image.
+	 */
+	old_flags = sc->flags;
+	/*
+	 * Initialize the adapter.
+	 */
+	if (aac_check_firmware(sc) != 0)
+		goto finish;
+	if (aac_init(sc) != 0)
+		goto finish;
+
+	if ((old_flags & AAC_FLAGS_NEW_COMM) &&
+		!(sc->flags & AAC_FLAGS_NEW_COMM)) {
+		/* remap interrupt handler */
+		aac_setup_intr(sc);
+	}
+
+finish:
+	sc->aac_state &= ~AAC_STATE_RESET;
+	AAC_UNMASK_INTERRUPTS(sc);
+	aac_startio(sc);
+	return (0);
+}
+
diff -urw sys/dev/aac/aac_cam.c /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac_cam.c
--- sys/dev/aac/aac_cam.c	2008-03-31 16:32:06.000000000 +0200
+++ /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac_cam.c	2011-11-21 12:05:19.000000000 +0100
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/aac/aac_cam.c,v 1.28.2.3 2008/03/31 14:32:06 emaste Exp $");
+__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_cam.c,v 1.28.2.3 2008/03/31 14:32:06 emaste Exp $");
 
 /*
  * CAM front-end for communicating with non-DASD devices
@@ -45,6 +45,7 @@
 #include <cam/cam_debug.h>
 #include <cam/cam_sim.h>
 #include <cam/cam_xpt_sim.h>
+#include <cam/cam_xpt_periph.h>
 #include <cam/scsi/scsi_all.h>
 #include <cam/scsi/scsi_message.h>
 
@@ -61,8 +62,11 @@
 
 #include <dev/aac/aacreg.h>
 #include <sys/aac_ioctl.h>
+#include <dev/aac/aac_fwdb.h>
 #include <dev/aac/aacvar.h>
 
+#include <cam/cam_periph.h>
+
 struct aac_cam {
 	device_t		dev;
 	struct aac_sim		*inf;
@@ -95,11 +99,44 @@
 	sizeof(struct aac_cam)
 };
 
-DRIVER_MODULE(aacp, aac, aac_pass_driver, aac_pass_devclass, 0, 0);
+DRIVER_MODULE(aacp, aacu, aac_pass_driver, aac_pass_devclass, 0, 0);
 MODULE_DEPEND(aacp, cam, 1, 1, 1);
 
 MALLOC_DEFINE(M_AACCAM, "aaccam", "AAC CAM info");
 
+void
+aac_cam_rescan_jbod(struct aac_softc *sc, u_int32_t chn)
+{
+	union ccb *ccb;
+	struct aac_sim *sim;
+	struct aac_cam *camsc;
+
+	/* re-enumerate JBOD devices */
+	for (sim = TAILQ_FIRST(&sc->aac_sim_tqh); sim != NULL;
+		sim = TAILQ_NEXT(sim, sim_link)) {
+		camsc = sim->aac_cam;
+		if (!camsc || !camsc->inf || camsc->inf->BusNumber != chn) 
+			continue;
+
+		ccb = xpt_alloc_ccb_nowait();
+		if (ccb == NULL) {
+			device_printf(sc->aac_dev,
+				"Cannot allocate ccb for bus rescan\n");
+			break;
+		}
+		if (xpt_create_path(&ccb->ccb_h.path, xpt_periph, 
+			cam_sim_path(camsc->sim), 
+			CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
+			xpt_free_ccb(ccb);
+			device_printf(sc->aac_dev,
+				"Cannot create path for bus rescan\n");
+			break;
+		}
+		xpt_rescan(ccb);
+		break;
+	}
+}
+
 static void
 aac_cam_event(struct aac_softc *sc, struct aac_event *event, void *arg)
 {
@@ -141,6 +178,7 @@
 
 	camsc = (struct aac_cam *)device_get_softc(dev);
 	sc = camsc->inf->aac_sc;
+	camsc->inf->aac_cam = NULL;
 
 	mtx_lock(&sc->aac_io_lock);
 
@@ -171,6 +209,7 @@
 	camsc = (struct aac_cam *)device_get_softc(dev);
 	inf = (struct aac_sim *)device_get_ivars(dev);
 	camsc->inf = inf;
+	camsc->inf->aac_cam = camsc;
 
 	devq = cam_simq_alloc(inf->TargetsPerBus);
 	if (devq == NULL)
@@ -211,7 +250,7 @@
 {
 	struct	aac_cam *camsc;
 	struct	aac_softc *sc;
-	struct	aac_srb32 *srb;
+	struct	aac_srb *srb;
 	struct	aac_fib *fib;
 	struct	aac_command *cm;
 
@@ -351,7 +390,7 @@
 	}
 
 	fib = cm->cm_fib;
-	srb = (struct aac_srb32 *)&fib->data[0];
+	srb = (struct aac_srb *)&fib->data[0];
 	cm->cm_datalen = 0;
 
 	switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
@@ -402,10 +441,10 @@
 				if (ccb->ccb_h.flags & CAM_DATA_PHYS) {
 					/* Send a 32bit command */
 					fib->Header.Command = ScsiPortCommand;
-					srb->sg_map32.SgCount = 1;
-					srb->sg_map32.SgEntry[0].SgAddress =
+					srb->sg_map.SgCount = 1;
+					srb->sg_map.SgEntry[0].SgAddress =
 					    (uint32_t)(uintptr_t)csio->data_ptr;
-					srb->sg_map32.SgEntry[0].SgByteCount =
+					srb->sg_map.SgEntry[0].SgByteCount =
 					    csio->dxfer_len;
 				} else {
 					/*
@@ -414,15 +453,15 @@
 					 */
 					cm->cm_data = (void *)csio->data_ptr;
 					cm->cm_datalen = csio->dxfer_len;
-					cm->cm_sgtable = &srb->sg_map32;
+					cm->cm_sgtable = &srb->sg_map;
 				}
 			} else {
 				/* XXX Need to handle multiple s/g elements */
 				panic("aac_cam: multiple s/g elements");
 			}
 		} else {
-			srb->sg_map32.SgCount = 0;
-			srb->sg_map32.SgEntry[0].SgByteCount = 0;
+			srb->sg_map.SgCount = 0;
+			srb->sg_map.SgEntry[0].SgByteCount = 0;
 			srb->data_len = 0;
 		}
 
@@ -450,7 +489,6 @@
 	cm->cm_complete = aac_cam_complete;
 	cm->cm_private = ccb;
 	cm->cm_timestamp = time_uptime;
-	cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
 
 	fib->Header.XferState =
 	    AAC_FIBSTATE_HOSTOWNED	|
@@ -459,7 +497,7 @@
 	    AAC_FIBSTATE_REXPECTED	|
 	    AAC_FIBSTATE_NORM;
 	fib->Header.Size = sizeof(struct aac_fib_header) +
-	    sizeof(struct aac_srb32);
+	    sizeof(struct aac_srb);
 
 	aac_enqueue_ready(cm);
 	aac_startio(cm->cm_sc);
@@ -488,7 +526,9 @@
 	ccb = cm->cm_private;
 	srbr = (struct aac_srb_response *)&cm->cm_fib->data[0];
 
-	if (srbr->fib_status != 0) {
+	if (cm->cm_flags & AAC_CMD_RESET) {
+		ccb->ccb_h.status = CAM_SCSI_BUS_RESET;
+	} else if (srbr->fib_status != 0) {
 		device_printf(sc->aac_dev, "Passthru FIB failed!\n");
 		ccb->ccb_h.status = CAM_REQ_ABORTED;
 	} else {
@@ -533,7 +573,8 @@
 				 * We want DASD and PROC devices to only be
 				 * visible through the pass device.
 				 */
-				if ((device == T_DIRECT) ||
+					if ((device == T_DIRECT && 
+						 !(sc->aac_feature_bits & AAC_SUPPL_SUPPORTED_JBOD)) ||
 				    (device == T_PROCESSOR) ||
 				    (sc->flags & AAC_FLAGS_CAM_PASSONLY))
 					ccb->csio.data_ptr[0] =
diff -urw sys/dev/aac/aac_compat.h /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac_compat.h
--- sys/dev/aac/aac_compat.h	2001-09-05 22:43:02.000000000 +0200
+++ /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac_compat.h	2011-11-21 12:05:19.000000000 +0100
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/dev/aac/aac_compat.h,v 1.3 2001/09/05 20:43:02 scottl Exp $
+ * $FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_compat.h,v 1.3 2001/09/05 20:43:02 scottl Exp $
  */
 /*
  * Backwards compatibility support.
diff -urw sys/dev/aac/aac_debug.c /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac_debug.c
--- sys/dev/aac/aac_debug.c	2008-03-31 16:32:06.000000000 +0200
+++ /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac_debug.c	2011-11-21 12:05:19.000000000 +0100
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/aac/aac_debug.c,v 1.22.2.2 2008/03/31 14:32:06 emaste Exp $");
+__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_debug.c,v 1.22.2.2 2008/03/31 14:32:06 emaste Exp $");
 
 /*
  * Debugging support.
@@ -47,10 +47,10 @@
 
 #include <dev/aac/aacreg.h>
 #include <sys/aac_ioctl.h>
+#include <dev/aac/aac_fwdb.h>
 #include <dev/aac/aacvar.h>
 
 #ifdef AAC_DEBUG
-int	aac_debug_enable = 0;
 void	aac_printstate0(void);
 
 /*
@@ -129,22 +129,22 @@
 {
 	struct aac_softc *sc;
 
-	sc = devclass_get_softc(devclass_find("aac"), 0);
+	sc = devclass_get_softc(devclass_find("aacu"), 0);
 
 	aac_print_queues(sc);
 	switch (sc->aac_hwif) {
 	case AAC_HWIF_I960RX:
 		device_printf(sc->aac_dev, "IDBR 0x%08x  IIMR 0x%08x  "
-		    "IISR 0x%08x\n", AAC_GETREG4(sc, AAC_RX_IDBR),
-		    AAC_GETREG4(sc, AAC_RX_IIMR), AAC_GETREG4(sc, AAC_RX_IISR));
+		    "IISR 0x%08x\n", AAC_MEM0_GETREG4(sc, AAC_RX_IDBR),
+		    AAC_MEM0_GETREG4(sc, AAC_RX_IIMR), AAC_MEM0_GETREG4(sc, AAC_RX_IISR));
 		device_printf(sc->aac_dev, "ODBR 0x%08x  OIMR 0x%08x  "
-		    "OISR 0x%08x\n", AAC_GETREG4(sc, AAC_RX_ODBR),
-		    AAC_GETREG4(sc, AAC_RX_OIMR), AAC_GETREG4(sc, AAC_RX_OISR));
-		AAC_SETREG4(sc, AAC_RX_OIMR, 0/*~(AAC_DB_COMMAND_READY |
+		    "OISR 0x%08x\n", AAC_MEM0_GETREG4(sc, AAC_RX_ODBR),
+		    AAC_MEM0_GETREG4(sc, AAC_RX_OIMR), AAC_MEM0_GETREG4(sc, AAC_RX_OISR));
+		AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, 0/*~(AAC_DB_COMMAND_READY |
 			    AAC_DB_RESPONSE_READY | AAC_DB_PRINTF)*/);
 		device_printf(sc->aac_dev, "ODBR 0x%08x  OIMR 0x%08x  "
-		    "OISR 0x%08x\n", AAC_GETREG4(sc, AAC_RX_ODBR),
-		    AAC_GETREG4(sc, AAC_RX_OIMR), AAC_GETREG4(sc, AAC_RX_OISR));
+		    "OISR 0x%08x\n", AAC_MEM0_GETREG4(sc, AAC_RX_ODBR),
+		    AAC_MEM0_GETREG4(sc, AAC_RX_OIMR), AAC_MEM0_GETREG4(sc, AAC_RX_OISR));
 		break;
 	case AAC_HWIF_STRONGARM:
 		/* XXX implement */
diff -urw sys/dev/aac/aac_disk.c /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac_disk.c
--- sys/dev/aac/aac_disk.c	2008-03-31 21:21:49.000000000 +0200
+++ /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac_disk.c	2011-11-21 12:05:19.000000000 +0100
@@ -28,7 +28,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/aac/aac_disk.c,v 1.43.10.2 2008/03/31 19:21:49 emaste Exp $");
+__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_disk.c,v 1.43.10.2 2008/03/31 19:21:49 emaste Exp $");
 
 #include "opt_aac.h"
 
@@ -51,6 +51,7 @@
 
 #include <dev/aac/aacreg.h>
 #include <sys/aac_ioctl.h>
+#include <dev/aac/aac_fwdb.h>
 #include <dev/aac/aacvar.h>
 
 /*
@@ -85,7 +86,7 @@
 
 #define AAC_MAXIO	65536
 
-DRIVER_MODULE(aacd, aac, aac_disk_driver, aac_disk_devclass, 0, 0);
+DRIVER_MODULE(aacd, aacu, aac_disk_driver, aac_disk_devclass, 0, 0);
 
 /* sysctl tunables */
 static unsigned int aac_iosize_max = AAC_MAXIO;	/* due to limits of the card */
@@ -104,25 +105,59 @@
 static int
 aac_disk_open(struct disk *dp)
 {
-	struct aac_disk	*sc;
+	struct aac_disk	*scd;
+	struct aac_softc *sc;
 
 	fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	sc = (struct aac_disk *)dp->d_drv1;
+	scd = (struct aac_disk *)dp->d_drv1;
 	
-	if (sc == NULL) {
+	if (scd == NULL) {
 		printf("aac_disk_open: No Softc\n");
 		return (ENXIO);
 	}
+	sc = scd->ad_controller;
 
 	/* check that the controller is up and running */
-	if (sc->ad_controller->aac_state & AAC_STATE_SUSPEND) {
+	if (sc->aac_state & AAC_STATE_SUSPEND) {
 		printf("Controller Suspended controller state = 0x%x\n",
-		       sc->ad_controller->aac_state);
+		       sc->aac_state);
 		return(ENXIO);
 	}
 
-	sc->ad_flags |= AAC_DISK_OPEN;
+	/* already opened? */
+	if (scd->ad_flags & AAC_DISK_OPEN) 
+		return (0);
+
+	/* power management */
+	if (sc->aac_support_opt2 & AAC_SUPPORTED_POWER_MANAGEMENT) {
+		struct aac_fib *fib;
+		struct aac_cnt_config *cmd;
+
+		mtx_lock(&sc->aac_io_lock);
+		aac_alloc_sync_fib(sc, &fib);
+
+		/* Start unit */
+		cmd = (struct aac_cnt_config *)&fib->data[0];
+		bzero(cmd, sizeof (*cmd) - CT_PACKET_SIZE);
+		cmd->Command = VM_ContainerConfig;
+		cmd->CTCommand.command = CT_PM_DRIVER_SUPPORT;
+		cmd->CTCommand.param[0] = AAC_PM_DRIVERSUP_START_UNIT;
+		cmd->CTCommand.param[1] = scd->ad_container->co_mntobj.ObjectId;
+		cmd->CTCommand.param[2] = 0;	/* 1 - immediate */
+
+		if (aac_sync_fib(sc, ContainerCommand, 0, fib,
+				 sizeof(struct aac_cnt_config)) ||
+			*(u_int32_t *)&fib->data[0] != 0) {
+			printf("Power Management: Error starting container %d\n", 
+				scd->ad_container->co_mntobj.ObjectId);
+		}
+
+		aac_release_sync_fib(sc);
+		mtx_unlock(&sc->aac_io_lock);
+	}
+
+    scd->ad_flags |= AAC_DISK_OPEN;
 	return (0);
 }
 
@@ -132,16 +167,50 @@
 static int
 aac_disk_close(struct disk *dp)
 {
-	struct aac_disk	*sc;
+	struct aac_disk	*scd;
+	struct aac_softc *sc;
 
 	fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-	sc = (struct aac_disk *)dp->d_drv1;
+	scd = (struct aac_disk *)dp->d_drv1;
 	
-	if (sc == NULL)
+	if (scd == NULL)
 		return (ENXIO);
+	sc = scd->ad_controller;
+
+	/* already closed? */
+	if (!(scd->ad_flags & AAC_DISK_OPEN)) 
+		return (0);
+
+	/* power management */
+	if (sc->aac_support_opt2 & AAC_SUPPORTED_POWER_MANAGEMENT) {
+		struct aac_fib *fib;
+		struct aac_cnt_config *cmd;
+
+		mtx_lock(&sc->aac_io_lock);
+		aac_alloc_sync_fib(sc, &fib);
+
+		/* Stop unit */
+		cmd = (struct aac_cnt_config *)&fib->data[0];
+		bzero(cmd, sizeof (*cmd) - CT_PACKET_SIZE);
+		cmd->Command = VM_ContainerConfig;
+		cmd->CTCommand.command = CT_PM_DRIVER_SUPPORT;
+		cmd->CTCommand.param[0] = AAC_PM_DRIVERSUP_STOP_UNIT;
+		cmd->CTCommand.param[1] = scd->ad_container->co_mntobj.ObjectId;
+		cmd->CTCommand.param[2] = 0;	/* 1 - immediate */
+
+		if (aac_sync_fib(sc, ContainerCommand, 0, fib,
+				 sizeof(struct aac_cnt_config)) ||
+			*(u_int32_t *)&fib->data[0] != 0) {
+			printf("Power Management: Error stopping container %d\n", 
+				scd->ad_container->co_mntobj.ObjectId);
+		}
+
+		aac_release_sync_fib(sc);
+		mtx_unlock(&sc->aac_io_lock);
+	}
 
-	sc->ad_flags &= ~AAC_DISK_OPEN;
+	scd->ad_flags &= ~AAC_DISK_OPEN;
 	return (0);
 }
 
Only in /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64: aac_fwdb.c
Only in /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64: aac_fwdb.h
diff -urw sys/dev/aac/aac_ioctl.h /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac_ioctl.h
--- sys/dev/aac/aac_ioctl.h	2008-03-31 21:21:48.000000000 +0200
+++ /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac_ioctl.h	2011-11-21 12:05:19.000000000 +0100
@@ -25,7 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$FreeBSD: src/sys/sys/aac_ioctl.h,v 1.11.12.2 2008/03/31 19:21:48 emaste Exp $
+ *	$FreeBSD: /repoman/r/ncvs/src/sys/sys/aac_ioctl.h,v 1.11.12.2 2008/03/31 19:21:48 emaste Exp $
  */
 
 /*
@@ -157,12 +157,12 @@
 struct aac_rev_check {
 	RevComponent		callingComponent;
 	struct FsaRevision	callingRevision;
-};
+} __packed;
 
 struct aac_rev_check_resp {
 	int			possiblyCompatible;
 	struct FsaRevision	adapterSWRevision;
-};
+} __packed;
 
 /*
  * Context passed in by a consumer looking to collect an AIF.
@@ -171,7 +171,7 @@
 	u_int32_t	AdapterFibContext;
 	int	  	Wait;
 	caddr_t		AifFib;
-};
+} __packed;
 
 struct aac_query_disk {
 	int32_t		ContainerNumber;
@@ -184,7 +184,7 @@
 	int32_t		Instance;
 	char		diskDeviceName[10];
 	u_int32_t	UnMapped;
-};
+} __packed;
 
 /* Features, asked from the tools to know if the driver
  * supports drives >2TB
@@ -192,7 +192,10 @@
 typedef union {
 	struct {
 		u_int32_t largeLBA  : 1;	/* disk support greater 2TB */
-		u_int32_t fReserved : 31;
+		u_int32_t IoctlBuf  : 1;    /* ARCIOCTL call support */
+		u_int32_t AIFSupport: 1;    /* AIF support */
+		u_int32_t JBODSupport:1;    /* firmware + driver both support JBOD */
+		u_int32_t fReserved : 28;
 	} fBits;
 	u_int32_t fValue;
 } featuresState;
diff -urw sys/dev/aac/aac_linux.c /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac_linux.c
--- sys/dev/aac/aac_linux.c	2006-12-20 18:10:53.000000000 +0100
+++ /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac_linux.c	2011-11-21 12:05:19.000000000 +0100
@@ -25,7 +25,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/aac/aac_linux.c,v 1.4 2006/12/20 17:10:53 delphij Exp $");
+__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_linux.c,v 1.4 2006/12/20 17:10:53 delphij Exp $");
 
 /*
  * Linux ioctl handler for the aac device driver
diff -urw sys/dev/aac/aac_pci.c /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac_pci.c
--- sys/dev/aac/aac_pci.c	2008-03-31 16:32:06.000000000 +0200
+++ /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac_pci.c	2011-11-21 12:05:19.000000000 +0100
@@ -2,7 +2,8 @@
  * Copyright (c) 2000 Michael Smith
  * Copyright (c) 2001 Scott Long
  * Copyright (c) 2000 BSDi
- * Copyright (c) 2001 Adaptec, Inc.
+ * Copyright (c) 2001-2010 Adaptec, Inc.
+ * Copyright (c) 2010 PMC-Sierra, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -28,7 +29,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/aac/aac_pci.c,v 1.62.2.4 2008/03/31 14:32:06 emaste Exp $");
+__FBSDID("$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_pci.c,v 1.62.2.4 2008/03/31 14:32:06 emaste Exp $");
 
 /*
  * PCI bus interface and resource allocation.
@@ -55,6 +56,7 @@
 
 #include <dev/aac/aacreg.h>
 #include <sys/aac_ioctl.h>
+#include <dev/aac/aac_fwdb.h>
 #include <dev/aac/aacvar.h>
 
 static int	aac_pci_probe(device_t dev);
@@ -74,14 +76,14 @@
 };
 
 static driver_t aac_pci_driver = {
-	"aac",
+	"aacu",
 	aac_methods,
 	sizeof(struct aac_softc)
 };
 
 static devclass_t	aac_devclass;
 
-DRIVER_MODULE(aac, pci, aac_pci_driver, aac_devclass, 0, 0);
+DRIVER_MODULE(aacu, pci, aac_pci_driver, aac_devclass, 0, 0);
 MODULE_DEPEND(aac, pci, 1, 1, 1);
 
 
@@ -168,8 +170,6 @@
 	 "ICP ICP9014RO SCSI RAID"},
 	{0x9005, 0x0285, 0x9005, 0x0294, AAC_HWIF_I960RX, 0,
 	 "Adaptec SATA RAID 2026ZCR"},
-	{0x9005, 0x0285, 0x103c, 0x3227, AAC_HWIF_I960RX, 0,
-	 "Adaptec SATA RAID 2610SA"},
 	{0x9005, 0x0285, 0x9005, 0x0296, AAC_HWIF_I960RX, 0,
 	 "Adaptec SCSI RAID 2240S"},
 	{0x9005, 0x0285, 0x9005, 0x0297, AAC_HWIF_I960RX, 0,
@@ -179,7 +179,7 @@
 	{0x9005, 0x0285, 0x1014, 0x0312, AAC_HWIF_I960RX, 0,
 	 "IBM ServeRAID 8i"},
 	{0x9005, 0x0285, 0x9005, 0x0298, AAC_HWIF_I960RX, 0,
-	 "Adaptec SAS RAID 4000SAS"},
+	 "Adaptec RAID 4000"},
 	{0x9005, 0x0285, 0x9005, 0x0299, AAC_HWIF_I960RX, 0,
 	 "Adaptec SAS RAID 4800SAS"},
 	{0x9005, 0x0285, 0x9005, 0x029a, AAC_HWIF_I960RX, 0,
@@ -278,6 +278,8 @@
 	 "Adaptec RAID Controller"},
 	{0x9005, 0x0286, 0, 0, AAC_HWIF_RKT, 0,
 	 "Adaptec RAID Controller"},
+	{0x9005, 0x028b, 0, 0, AAC_HWIF_SRC, 0,
+	 "Adaptec RAID Controller"},
 	{0, 0, 0, 0, 0, 0, 0}
 };
 
@@ -319,7 +321,7 @@
 
 	if ((id = aac_find_ident(dev)) != NULL) {
 		device_set_desc(dev, id->desc);
-		return(BUS_PROBE_DEFAULT);
+		return(BUS_PROBE_SPECIFIC);
 	}
 	return(ENXIO);
 }
@@ -364,23 +366,78 @@
 	}
 
 	/*
+	 * Detect the hardware interface version, set up the bus interface
+	 * indirection.
+	 */
+	id = aac_find_ident(dev);
+	sc->aac_hwif = id->hwif;
+	switch(sc->aac_hwif) {
+	case AAC_HWIF_I960RX:
+	case AAC_HWIF_NARK:
+		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for i960Rx/NARK");
+		sc->aac_if = aac_rx_interface;
+		break;
+	case AAC_HWIF_STRONGARM:
+		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for StrongARM");
+		sc->aac_if = aac_sa_interface;
+		break;
+	case AAC_HWIF_FALCON:
+		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for Falcon/PPC");
+		sc->aac_if = aac_fa_interface;
+		break;
+	case AAC_HWIF_RKT:
+		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for Rocket/MIPS");
+		sc->aac_if = aac_rkt_interface;
+		break;
+	case AAC_HWIF_SRC:
+		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for PMC SRC");
+		sc->aac_if = aac_src_interface;
+		break;
+	default:
+		sc->aac_hwif = AAC_HWIF_UNKNOWN;
+		device_printf(sc->aac_dev, "unknown hardware type\n");
+		error = ENXIO;
+		goto out;
+	}
+
+	/* assume failure is 'out of memory' */
+	error = ENOMEM;
+
+	/*
 	 * Allocate the PCI register window.
 	 */
-	sc->aac_regs_rid = PCIR_BAR(0);
-	if ((sc->aac_regs_resource = bus_alloc_resource_any(sc->aac_dev,
+	sc->aac_regs_rid0 = PCIR_BAR(0);
+	if ((sc->aac_regs_res0 = bus_alloc_resource_any(sc->aac_dev,
 							    SYS_RES_MEMORY,
-							    &sc->aac_regs_rid,
+							    &sc->aac_regs_rid0,
 							    RF_ACTIVE)) ==
 							    NULL) {
 		device_printf(sc->aac_dev,
-			      "couldn't allocate register window\n");
+			      "couldn't allocate register window 0\n");
 		goto out;
 	}
-	sc->aac_btag = rman_get_bustag(sc->aac_regs_resource);
-	sc->aac_bhandle = rman_get_bushandle(sc->aac_regs_resource);
+	sc->aac_btag0 = rman_get_bustag(sc->aac_regs_res0);
+	sc->aac_bhandle0 = rman_get_bushandle(sc->aac_regs_res0);
 
-	/* assume failure is 'out of memory' */
-	error = ENOMEM;
+	if (sc->aac_hwif == AAC_HWIF_SRC || sc->aac_hwif == AAC_HWIF_NARK) {
+		sc->aac_regs_rid1 = PCIR_BAR(2);
+		if ((sc->aac_regs_res1 = bus_alloc_resource_any(sc->aac_dev,
+									SYS_RES_MEMORY,
+									&sc->aac_regs_rid1,
+									RF_ACTIVE)) ==
+									NULL) {
+			device_printf(sc->aac_dev,
+					  "couldn't allocate register window 0\n");
+			goto out;
+		}
+		sc->aac_btag1 = rman_get_bustag(sc->aac_regs_res1);
+		sc->aac_bhandle1 = rman_get_bushandle(sc->aac_regs_res1);
+	} else {
+		sc->aac_regs_res1 = sc->aac_regs_res0;
+		sc->aac_regs_rid1 = sc->aac_regs_rid0;
+		sc->aac_btag1 = sc->aac_btag0;
+		sc->aac_bhandle1 = sc->aac_bhandle0;
+	}
 
 	/*
 	 * Allocate the parent bus DMA tag appropriate for our PCI interface.
@@ -402,36 +459,6 @@
 		goto out;
 	}
 
-	/* 
-	 * Detect the hardware interface version, set up the bus interface
-	 * indirection.
-	 */
-	id = aac_find_ident(dev);
-	sc->aac_hwif = id->hwif;
-	switch(sc->aac_hwif) {
-	case AAC_HWIF_I960RX:
-		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for i960Rx");
-		sc->aac_if = aac_rx_interface;
-		break;
-	case AAC_HWIF_STRONGARM:
-		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for StrongARM");
-		sc->aac_if = aac_sa_interface;
-		break;
-	case AAC_HWIF_FALCON:
-		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for Falcon/PPC");
-		sc->aac_if = aac_fa_interface;
-		break;
-	case AAC_HWIF_RKT:
-		fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for Rocket/MIPS");
-		sc->aac_if = aac_rkt_interface;
-		break;
-	default:
-		sc->aac_hwif = AAC_HWIF_UNKNOWN;
-		device_printf(sc->aac_dev, "unknown hardware type\n");
-		error = ENXIO;
-		goto out;
-	}
-
 	/* Set up quirks */
 	sc->flags = id->quirks;
 
@@ -468,13 +495,13 @@
 };
 
 static driver_t aacch_driver = {
-	"aacch",
+	"aacchu",
 	aacch_methods,
 	sizeof(struct aacch_softc)
 };
 
 static devclass_t	aacch_devclass;
-DRIVER_MODULE(aacch, pci, aacch_driver, aacch_devclass, 0, 0);
+DRIVER_MODULE(aacchu, pci, aacch_driver, aacch_devclass, 0, 0);
 
 static int
 aacch_probe(device_t dev)
diff -urw sys/dev/aac/aac_tables.h /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac_tables.h
--- sys/dev/aac/aac_tables.h	2005-10-08 17:55:09.000000000 +0200
+++ /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aac_tables.h	2011-11-21 12:05:19.000000000 +0100
@@ -24,7 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$FreeBSD: src/sys/dev/aac/aac_tables.h,v 1.6 2005/10/08 15:55:09 scottl Exp $
+ *	$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aac_tables.h,v 1.6 2005/10/08 15:55:09 scottl Exp $
  */
 
 /*
@@ -57,6 +57,7 @@
 	{"quota exceeded",			69},
 	{"stale file handle",			70},
 	{"too many levels of remote in path",	71},
+	{"device busy (spinning up)",		72},
 	{"bad file handle",			10001},
 	{"not sync",				10002},
 	{"bad cookie",				10003},
@@ -68,6 +69,7 @@
 	{"not mounted",				10009},
 	{"in maintenance mode",			10010},
 	{"stale ACL",				10011},
+	{"bus reset - command aborted",		20001},
 	{NULL, 					0},
 	{"unknown command status",		0}
 };
diff -urw sys/dev/aac/aacreg.h /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aacreg.h
--- sys/dev/aac/aacreg.h	2008-03-31 21:21:49.000000000 +0200
+++ /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aacreg.h	2011-11-21 12:05:19.000000000 +0100
@@ -2,7 +2,8 @@
  * Copyright (c) 2000 Michael Smith
  * Copyright (c) 2000-2001 Scott Long
  * Copyright (c) 2000 BSDi
- * Copyright (c) 2001 Adaptec, Inc.
+ * Copyright (c) 2001-2010 Adaptec, Inc.
+ * Copyright (c) 2010 PMC-Sierra, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$FreeBSD: src/sys/dev/aac/aacreg.h,v 1.23.2.2 2008/03/31 19:21:49 emaste Exp $
+ *	$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aacreg.h,v 1.23.2.2 2008/03/31 19:21:49 emaste Exp $
  */
 
 /*
@@ -123,6 +124,14 @@
 #define AAC_ADAP_NORM_RESP_QUEUE	6
 #define AAC_ADAP_HIGH_RESP_QUEUE	7
 
+/* transport FIB header (PMC) */
+struct aac_fib_xporthdr {
+	u_int64_t	HostAddress;	/* FIB host address w/o xport header */
+	u_int32_t	Size;			/* FIB size excluding xport header */
+	u_int32_t	Handle;			/* driver handle to reference the FIB */
+	u_int64_t	Reserved[2];
+} __packed;
+
 /*
  * List structure used to chain FIBs (used by the adapter - we hang FIBs off
  * our private command structure and don't touch these)
@@ -268,6 +277,7 @@
 #define AAC_FIBSTATE_BIOSFIB		(1<<18)
 #define AAC_FIBSTATE_FAST_RESPONSE	(1<<19)	/* fast response capable */
 #define AAC_FIBSTATE_APIFIB		(1<<20)
+#define AAC_FIBSTATE_NOMOREAIF		(1<<21)
 
 /*
  * FIB error values
@@ -290,6 +300,7 @@
 	u_int32_t	InitStructRevision;
 #define AAC_INIT_STRUCT_REVISION		3
 #define AAC_INIT_STRUCT_REVISION_4		4
+#define AAC_INIT_STRUCT_REVISION_6		6
 	u_int32_t	MiniPortRevision;
 #define AAC_INIT_STRUCT_MINIPORT_REVISION	1
 	u_int32_t	FilesystemRevision;
@@ -306,10 +317,18 @@
 	u_int32_t	HostElapsedSeconds;
 	/* ADAPTER_INIT_STRUCT_REVISION_4 begins here */
 	u_int32_t	InitFlags;			/* flags for supported features */
-#define INITFLAGS_NEW_COMM_SUPPORTED	1
+#define AAC_INITFLAGS_NEW_COMM_SUPPORTED	1
+#define AAC_INITFLAGS_DRIVER_USES_UTC_TIME	0x10
+#define AAC_INITFLAGS_DRIVER_SUPPORTS_PM	0x20
+#define AAC_INITFLAGS_NEW_COMM_TYPE1_SUPPORTED  0x41
 	u_int32_t	MaxIoCommands;		/* max outstanding commands */
 	u_int32_t	MaxIoSize;			/* largest I/O command */
 	u_int32_t	MaxFibSize;			/* largest FIB to adapter */
+	/* ADAPTER_INIT_STRUCT_REVISION_5 begins here */
+	u_int32_t	MaxNumAif;	        /* max number of aif */ 
+	/* ADAPTER_INIT_STRUCT_REVISION_6 begins here */
+	u_int32_t	HostRRQ_AddrLow;
+	u_int32_t	HostRRQ_AddrHigh;	/* Host RRQ (response queue) for SRC */
 } __packed;
 
 /*
@@ -576,6 +595,7 @@
 #define AAC_SUPPORTED_NEW_COMM		0x20000
 #define AAC_SUPPORTED_64BIT_ARRAYSIZE	0x40000
 #define AAC_SUPPORTED_HEAT_SENSOR	0x80000
+#define AAC_SUPPORTED_NEW_COMM_TYPE1	0x10000000  /* PMC type new comm */
 
 /* 
  * Structure used to respond to a RequestAdapterInfo fib.
@@ -605,6 +625,20 @@
 } __packed;
 
 /* 
+ * More options from supplement info - SupportedOptions2
+ */
+#define AAC_SUPPORTED_MU_RESET			0x01
+#define AAC_SUPPORTED_IGNORE_RESET		0x02
+#define AAC_SUPPORTED_POWER_MANAGEMENT		0x04
+#define AAC_SUPPORTED_ARCIO_PHYDEV		0x08
+#define AAC_SUPPORTED_DOORBELL_RESET		0x4000
+
+/*
+ * FeatureBits of RequestSupplementAdapterInfo used in the driver
+ */
+#define AAC_SUPPL_SUPPORTED_JBOD	0x08000000
+
+/* 
  * Structure used to respond to a RequestSupplementAdapterInfo fib.
  */
 struct vpd_info {
@@ -652,8 +686,12 @@
 	u_int8_t		MfgPcbaSerialNo[MFG_PCBA_SERIAL_NUMBER_WIDTH];
 	/* WWN from the MFG sector */
 	u_int8_t		MfgWWNName[MFG_WWN_WIDTH];
-	/* Growth Area for future expansion ((7*4) - 12 - 8)/4 = 2 words */
-	u_int32_t	ReservedGrowth[2];
+	u_int32_t	SupportedOptions2;		/* more supported features */
+	u_int32_t	ExpansionFlag;			/* 1 - following fields are valid */
+	u_int32_t	FeatureBits3;
+	u_int32_t	SupportedPerformanceMode;
+	/* Growth Area for future expansion */
+	u_int32_t	ReservedGrowth[80];
 } __packed;
 
 /*
@@ -673,6 +711,8 @@
 #define AAC_MONKER_RCVTEMP	0x25
 #define AAC_MONKER_GETCOMMPREF	0x26
 #define AAC_MONKER_REINIT	0xee
+#define	AAC_IOP_RESET		0x1000
+#define	AAC_IOP_RESET_ALWAYS	0x1001
 
 /*
  *  Adapter Status Register
@@ -885,6 +925,17 @@
 	AifEnBatteryNeedsRecond,	/* The battery needs reconditioning */
 	AifEnClusterEvent,		/* Some cluster event */
 	AifEnDiskSetEvent,		/* A disk set event occured. */
+	AifEnContainerScsiEvent,	/* a container event with no. and scsi id */
+	AifEnPicBatteryEvent,	/* An event gen. by pic_battery.c for an ABM */
+	AifEnExpEvent,			/* Exp. Event Type to replace CTPopUp messages */
+	AifEnRAID6RebuildDone,	/* RAID6 rebuild finished */
+	AifEnSensorOverHeat,	/* Heat Sensor indicate overheat */
+	AifEnSensorCoolDown,	/* Heat Sensor ind. cooled down after overheat */
+	AifFeatureKeysModified,	/* notif. of updated feature keys */
+	AifApplicationExpirationEvent,	/* notif. on app. expiration status */
+	AifEnBackgroundConsistencyCheck,	/* BCC notif. for NEC - DDTS 94700 */
+	AifEnAddJBOD,		/* A new JBOD type drive was created (30) */
+	AifEnDeleteJBOD,		/* A JBOD type drive was deleted (31) */
 	AifDriverNotifyStart=199,	/* Notifies for host driver go here */
 	/* Host driver notifications start here */
 	AifDenMorphComplete, 		/* A morph operation completed */
@@ -986,7 +1037,8 @@
 	AifReqSendAPIReport,	/* API generic report requests */
 	AifReqAPIJobStart,	/* Start a job from the API */
 	AifReqAPIJobUpdate,	/* Update a job report from the API */
-	AifReqAPIJobFinish	/* Finish a job from the API */
+	AifReqAPIJobFinish,	/* Finish a job from the API */
+	AifReqEvent = 200	/* PMC NEW COMM: Request the event data */
 } AAC_AifCommand;
 
 struct aac_aif_command {
@@ -1081,6 +1133,7 @@
 	ST_DQUOT = 69,
 	ST_STALE = 70,
 	ST_REMOTE = 71,
+	ST_NOT_READY = 72,
 	ST_BADHANDLE = 10001,
 	ST_NOT_SYNC = 10002,
 	ST_BAD_COOKIE = 10003,
@@ -1091,7 +1144,8 @@
 	ST_JUKEBOX = 10008,
 	ST_NOTMOUNTED = 10009,
 	ST_MAINTMODE = 10010,
-	ST_STALEACL = 10011
+	ST_STALEACL = 10011,
+	ST_BUS_RESET = 20001
 } AAC_FSAStatus;
 
 /*
@@ -1123,6 +1177,42 @@
 	VM_NameServe64		 
 } AAC_VMCommand;
 
+/* Container Configuration Sub-Commands */
+#define CT_GET_SCSI_METHOD	64
+#define	CT_PAUSE_IO			65
+#define	CT_RELEASE_IO			66
+#define	CT_GET_CONFIG_STATUS		147
+#define	CT_COMMIT_CONFIG		152
+#define CT_PM_DRIVER_SUPPORT		245
+
+/* CT_PM_DRIVER_SUPPORT parameter */
+typedef enum {
+	AAC_PM_DRIVERSUP_GET_STATUS = 1,
+	AAC_PM_DRIVERSUP_START_UNIT,
+	AAC_PM_DRIVERSUP_STOP_UNIT
+} AAC_CT_PM_DRIVER_SUPPORT_SUB_COM;
+
+/*
+ * CT_PAUSE_IO is immediate minimal runtime command that is used
+ * to restart the applications and cache.
+ */
+struct aac_pause_command {
+	u_int32_t	Command;
+	u_int32_t	Type;
+	u_int32_t	Timeout;
+	u_int32_t	Min;
+	u_int32_t	NoRescan;
+	u_int32_t	Parm3;
+	u_int32_t	Parm4;
+	u_int32_t	Count;
+} __packed;
+
+/* Flag values for ContentState */
+#define AAC_FSCS_NOTCLEAN	0x1	/* fscheck is necessary before mounting */
+#define AAC_FSCS_READONLY	0x2	/* possible result of broken mirror */
+#define AAC_FSCS_HIDDEN		0x4	/* container should be ignored by driver */
+#define AAC_FSCS_NOT_READY	0x8	/* cnt is in spinn. state, not rdy for IO's */
+
 /*
  * "mountable object"
  */
@@ -1167,7 +1257,6 @@
 /*
  * Container Config Command
  */
-#define CT_GET_SCSI_METHOD	64
 struct aac_ctcfg {
 	u_int32_t		Command;
 	u_int32_t		cmd;
@@ -1289,6 +1378,24 @@
 	CMUNSTABLE
 } AAC_CommitLevel;
 
+
+#define	CT_FIB_PARAMS			6
+#define	MAX_FIB_PARAMS			10
+#define	CT_PACKET_SIZE \
+	(AAC_FIB_DATASIZE - sizeof (u_int32_t) - \
+	((sizeof (u_int32_t)) * (MAX_FIB_PARAMS + 1)))
+
+struct aac_fsa_ctm {
+	u_int32_t	command;
+	u_int32_t	param[CT_FIB_PARAMS];
+	int8_t		data[CT_PACKET_SIZE];
+};
+
+struct aac_cnt_config {
+	u_int32_t		Command;
+	struct aac_fsa_ctm	CTCommand;
+};
+
 /*
  * Block read/write operations.
  * These structures are packed into the 'data' area in the FIB.
@@ -1358,12 +1465,12 @@
 struct aac_close_command {
 	u_int32_t		Command;
 	u_int32_t		ContainerId;
-};
+} __packed;
 
 /*
  * SCSI Passthrough structures
  */
-struct aac_srb32 {
+struct aac_srb {
 	u_int32_t		function;
 	u_int32_t		bus;
 	u_int32_t		target;
@@ -1374,8 +1481,8 @@
 	u_int32_t		retry_limit;
 	u_int32_t		cdb_len;
 	u_int8_t		cdb[16];
-	struct aac_sg_table	sg_map32;
-};
+	struct aac_sg_table	sg_map;
+} __packed;
 
 enum {
 	AAC_SRB_FUNC_EXECUTE_SCSI	= 0x00,
@@ -1416,7 +1523,7 @@
 	u_int32_t	data_len;
 	u_int32_t	sense_len;
 	u_int8_t	sense[AAC_HOST_SENSE_DATA_MAX];
-};
+} __packed;
 
 /*
  * Status codes for SCSI passthrough commands.  Since they are based on ASPI,
@@ -1468,7 +1575,7 @@
 #define	AAC_FA_FWSTATUS			0x2c	/* Mailbox 7 */
 #define	AAC_FA_INTSRC			0x900
 
-#define AAC_FA_HACK(sc)	(void)AAC_GETREG4(sc, AAC_FA_INTSRC)
+#define AAC_FA_HACK(sc)	(void)AAC_MEM0_GETREG4(sc, AAC_FA_INTSRC)
 
 /*
  * Register definitions for the Adaptec AAC-364 'Jalapeno I/II' adapters, based
@@ -1495,6 +1602,8 @@
  * and other related adapters.
  */
 
+#define AAC_RX_OMR0		0x18	/* outbound message register 0 */
+#define AAC_RX_OMR1		0x1c	/* outbound message register 1 */
 #define AAC_RX_IDBR		0x20	/* inbound doorbell register */
 #define AAC_RX_IISR		0x24	/* inbound interrupt status register */
 #define AAC_RX_IIMR		0x28	/* inbound interrupt mask register */
@@ -1512,6 +1621,8 @@
  * Unsurprisingly, it's quite similar to the i960!
  */
 
+#define AAC_RKT_OMR0		0x18	/* outbound message register 0 */
+#define AAC_RKT_OMR1		0x1c	/* outbound message register 1 */
 #define AAC_RKT_IDBR		0x20	/* inbound doorbell register */
 #define AAC_RKT_IISR		0x24	/* inbound interrupt status register */
 #define AAC_RKT_IIMR		0x28	/* inbound interrupt mask register */
@@ -1525,6 +1636,29 @@
 #define AAC_RKT_FWSTATUS	0x101c	/* Firmware Status (mailbox 7) */
 
 /*
+ * Register definitions for the Adaptec PMC SRC adapters.
+ */
+/* accessible via BAR0 */
+#define AAC_SRC_OMR			0xbc	/* outbound message register */
+#define AAC_SRC_IDBR		0x20	/* inbound doorbell register */
+#define AAC_SRC_IISR		0x24	/* inbound interrupt status register */
+#define AAC_SRC_ODBR_R		0x9c	/* outbound doorbell register read */
+#define AAC_SRC_ODBR_C		0xa0	/* outbound doorbell register clear */
+#define AAC_SRC_OIMR		0x34	/* outbound interrupt mask register */
+#define AAC_SRC_IQUE_L		0xc0	/* inbound queue address (low) */
+#define AAC_SRC_IQUE_H		0xc4	/* inbound queue address (high) */
+
+#define AAC_SRC_MAILBOX		0x7fc60	/* mailbox (20 bytes) */
+
+#define AAC_SRC_ODR_SHIFT 	12		/* outbound doorbell shift */
+#define AAC_SRC_IDR_SHIFT 	9		/* inbound doorbell shift */
+
+/* Sunrise Lake dual core reset */
+#define AAC_IRCSR		0x38	/* inbound dual cores reset */
+#define AAC_IRCSR_CORES_RST	3
+
+
+/*
  * Common bit definitions for the doorbell registers.
  */
 
@@ -1536,6 +1670,9 @@
 #define AAC_DB_RESPONSE_READY	(1<<2)	/* one or more commands complete */
 #define AAC_DB_COMMAND_NOT_FULL	(1<<3)	/* command queue not full */
 #define AAC_DB_RESPONSE_NOT_FULL (1<<4)	/* response queue not full */
+#define AAC_DB_AIF_PENDING		(1<<6)	/* pending AIF (new comm. type1) */
+/* PMC specific outbound doorbell bits */
+#define AAC_DB_RESPONSE_SENT_NS		(1<<1)	/* response sent (not shifted) */
 
 /*
  * The adapter can request the host print a message by setting the
@@ -1555,4 +1692,5 @@
 				 AAC_DB_RESPONSE_READY |	\
 				 AAC_DB_PRINTF)
 #define AAC_DB_INT_NEW_COMM		0x08		
+#define AAC_DB_INT_NEW_COMM_TYPE1	0x04
 
Only in /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64: aacu.ko
diff -urw sys/dev/aac/aacvar.h /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aacvar.h
--- sys/dev/aac/aacvar.h	2008-03-31 21:21:49.000000000 +0200
+++ /home/s/tmp/raid/aac/aacraid_freebsd_b18668/freebsd8/aac8x-amd64/aacvar.h	2011-11-21 12:05:19.000000000 +0100
@@ -2,7 +2,8 @@
  * Copyright (c) 2000 Michael Smith
  * Copyright (c) 2001 Scott Long
  * Copyright (c) 2000 BSDi
- * Copyright (c) 2001 Adaptec, Inc.
+ * Copyright (c) 2001-2010 Adaptec, Inc.
+ * Copyright (c) 2010 PMC-Sierra, Inc.
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -26,7 +27,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *	$FreeBSD: src/sys/dev/aac/aacvar.h,v 1.48.2.3 2008/03/31 19:21:49 emaste Exp $
+ *	$FreeBSD: /repoman/r/ncvs/src/sys/dev/aac/aacvar.h,v 1.48.2.3 2008/03/31 19:21:49 emaste Exp $
  */
 
 #include <sys/bio.h>
@@ -36,8 +37,18 @@
 #include <sys/selinfo.h>
 #include <geom/geom_disk.h>
 
+#define	AAC_TYPE_DEVO			1
+#define	AAC_TYPE_ALPHA			2
+#define	AAC_TYPE_BETA			3
+#define	AAC_TYPE_RELEASE		4
+
+#define	AAC_DRIVER_MAJOR_VERSION	2
+#define	AAC_DRIVER_MINOR_VERSION	4
+#define	AAC_DRIVER_BUGFIX_LEVEL		2
+#define	AAC_DRIVER_TYPE			AAC_TYPE_RELEASE
+
 #ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 1
+# define AAC_DRIVER_BUILD 18668 
 #endif
 
 /*
@@ -45,12 +56,6 @@
  */
 
 /*
- * The firmware interface allows for a 16-bit s/g list length.  We limit 
- * ourselves to a reasonable maximum and ensure alignment.
- */
-#define AAC_MAXSGENTRIES	64	/* max S/G entries, limit 65535 */		
-
-/*
  * We allocate a small set of FIBs for the adapter to use to send us messages.
  */
 #define AAC_ADAPTER_FIBS	8
@@ -59,7 +64,7 @@
  * FIBs are allocated in page-size chunks and can grow up to the 512
  * limit imposed by the hardware.
  */
-#define AAC_PREALLOCATE_FIBS	128
+#define AAC_PREALLOCATE_FIBS	512
 #define AAC_NUM_MGT_FIB		8
 
 /*
@@ -109,6 +114,7 @@
 /*
  * Per-SIM data structure
  */
+struct aac_cam;
 struct aac_sim
 {
 	device_t		sim_dev;
@@ -116,6 +122,7 @@
 	int			BusNumber;
 	int			InitiatorBusId;
 	struct aac_softc	*aac_sc;
+	struct aac_cam		*aac_cam;
 	TAILQ_ENTRY(aac_sim)	sim_link;
 };
 
@@ -170,14 +177,15 @@
 #define AAC_ON_AACQ_AIF		(1<<8)
 #define AAC_ON_AACQ_NORM	(1<<10)
 #define AAC_ON_AACQ_MASK	((1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<10))
-#define AAC_QUEUE_FRZN		(1<<9)		/* Freeze the processing of
-						 * commands on the queue. */
+#define AAC_CMD_RESET		(1<<9)
 
 	void			(* cm_complete)(struct aac_command *cm);
 	void			*cm_private;
 	time_t			cm_timestamp;	/* command creation time */
 	int			cm_queue;
 	int			cm_index;
+	bus_dma_tag_t		cm_passthr_dmat;	/* passthrough buffer/command
+							 * DMA tag */
 };
 
 struct aac_fibmap {
@@ -216,6 +224,9 @@
 	
 	/* fib for synchronous commands */
 	struct aac_fib		ac_sync_fib;
+
+	/* response buffer for SRC (new comm. type1) - must be last element */
+	u_int32_t   ac_host_rrq[0];
 };
 
 /*
@@ -240,6 +251,7 @@
 extern struct aac_interface	aac_sa_interface;
 extern struct aac_interface	aac_fa_interface;
 extern struct aac_interface	aac_rkt_interface;
+extern struct aac_interface	aac_src_interface;
 
 #define AAC_GET_FWSTATUS(sc)		((sc)->aac_if.aif_get_fwstatus((sc)))
 #define AAC_QNOTIFY(sc, qbit)		((sc)->aac_if.aif_qnotify((sc), (qbit)))
@@ -259,18 +271,31 @@
 #define AAC_GET_OUTB_QUEUE(sc)		((sc)->aac_if.aif_get_outb_queue((sc)))
 #define AAC_SET_OUTB_QUEUE(sc, idx)	((sc)->aac_if.aif_set_outb_queue((sc), (idx)))
 
-#define AAC_SETREG4(sc, reg, val)	bus_space_write_4(sc->aac_btag, \
-					sc->aac_bhandle, reg, val)
-#define AAC_GETREG4(sc, reg)		bus_space_read_4 (sc->aac_btag, \
-					sc->aac_bhandle, reg)
-#define AAC_SETREG2(sc, reg, val)	bus_space_write_2(sc->aac_btag, \
-					sc->aac_bhandle, reg, val)
-#define AAC_GETREG2(sc, reg)		bus_space_read_2 (sc->aac_btag, \
-					sc->aac_bhandle, reg)
-#define AAC_SETREG1(sc, reg, val)	bus_space_write_1(sc->aac_btag, \
-					sc->aac_bhandle, reg, val)
-#define AAC_GETREG1(sc, reg)		bus_space_read_1 (sc->aac_btag, \
-					sc->aac_bhandle, reg)
+#define AAC_MEM0_SETREG4(sc, reg, val)	bus_space_write_4(sc->aac_btag0, \
+					sc->aac_bhandle0, reg, val)
+#define AAC_MEM0_GETREG4(sc, reg)		bus_space_read_4 (sc->aac_btag0, \
+					sc->aac_bhandle0, reg)
+#define AAC_MEM0_SETREG2(sc, reg, val)	bus_space_write_2(sc->aac_btag0, \
+					sc->aac_bhandle0, reg, val)
+#define AAC_MEM0_GETREG2(sc, reg)		bus_space_read_2 (sc->aac_btag0, \
+					sc->aac_bhandle0, reg)
+#define AAC_MEM0_SETREG1(sc, reg, val)	bus_space_write_1(sc->aac_btag0, \
+					sc->aac_bhandle0, reg, val)
+#define AAC_MEM0_GETREG1(sc, reg)		bus_space_read_1 (sc->aac_btag0, \
+					sc->aac_bhandle0, reg)
+
+#define AAC_MEM1_SETREG4(sc, reg, val)	bus_space_write_4(sc->aac_btag1, \
+					sc->aac_bhandle1, reg, val)
+#define AAC_MEM1_GETREG4(sc, reg)		bus_space_read_4 (sc->aac_btag1, \
+					sc->aac_bhandle1, reg)
+#define AAC_MEM1_SETREG2(sc, reg, val)	bus_space_write_2(sc->aac_btag1, \
+					sc->aac_bhandle1, reg, val)
+#define AAC_MEM1_GETREG2(sc, reg)		bus_space_read_2 (sc->aac_btag1, \
+					sc->aac_bhandle1, reg)
+#define AAC_MEM1_SETREG1(sc, reg, val)	bus_space_write_1(sc->aac_btag1, \
+					sc->aac_bhandle1, reg, val)
+#define AAC_MEM1_GETREG1(sc, reg)		bus_space_read_1 (sc->aac_btag1, \
+					sc->aac_bhandle1, reg)
 
 /* fib context (IOCTL) */
 struct aac_fib_context {
@@ -287,11 +312,10 @@
 {
 	/* bus connections */
 	device_t		aac_dev;
-	struct resource		*aac_regs_resource;	/* register interface
-							 * window */
-	int			aac_regs_rid;		/* resource ID */
-	bus_space_handle_t	aac_bhandle;		/* bus space handle */
-	bus_space_tag_t		aac_btag;		/* bus space tag */
+	struct resource		*aac_regs_res0, *aac_regs_res1;	/* reg. if. window */
+	int			aac_regs_rid0, aac_regs_rid1;		/* resource ID */
+	bus_space_handle_t	aac_bhandle0, aac_bhandle1;		/* bus space handle */
+	bus_space_tag_t		aac_btag0, aac_btag1;		/* bus space tag */
 	bus_dma_tag_t		aac_parent_dmat;	/* parent DMA tag */
 	bus_dma_tag_t		aac_buffer_dmat;	/* data buffer/command
 							 * DMA tag */
@@ -299,6 +323,7 @@
 	int			aac_irq_rid;
 	void			*aac_intr;		/* interrupt handle */
 	eventhandler_tag	eh;
+	struct callout_handle	timeout_id;		/* timeout handle */
 
 	/* controller features, limits and status */
 	int			aac_state;
@@ -306,6 +331,7 @@
 #define	AAC_STATE_OPEN		(1<<1)
 #define AAC_STATE_INTERRUPTS_ON	(1<<2)
 #define AAC_STATE_AIF_SLEEPER	(1<<3)
+#define AAC_STATE_RESET		(1<<4)
 	int			aac_open_cnt;
 	struct FsaRevision		aac_revision;
 
@@ -315,6 +341,8 @@
 #define AAC_HWIF_STRONGARM	1
 #define AAC_HWIF_FALCON		2
 #define AAC_HWIF_RKT		3
+#define AAC_HWIF_NARK		4
+#define AAC_HWIF_SRC		5
 #define AAC_HWIF_UNKNOWN	-1
 	bus_dma_tag_t		aac_common_dmat;	/* common structure
 							 * DMA tag */
@@ -322,6 +350,7 @@
 							 * DMA map */
 	struct aac_common	*aac_common;
 	u_int32_t		aac_common_busaddr;
+	u_int32_t		aac_host_rrq_idx;
 	struct aac_interface	aac_if;
 
 	/* command/fib resources */
@@ -364,6 +393,7 @@
 	struct aac_fib		aac_aifq[AAC_AIFQ_LENGTH];
 	int			aifq_idx;
 	int			aifq_filled;
+	int aif_pending;
 	struct aac_fib_context *fibctx;
 	struct selinfo		rcv_select;
 	struct proc		*aifthread;
@@ -393,7 +423,11 @@
 #define AAC_FLAGS_RAW_IO	(1 << 12)	/* Raw I/O interface */
 #define AAC_FLAGS_ARRAY_64BIT	(1 << 13)	/* 64-bit array size */
 #define	AAC_FLAGS_LBA_64BIT	(1 << 14)	/* 64-bit LBA support */
-
+#define AAC_QUEUE_FRZN		(1<<15)		/* Freeze the processing of
+						 * commands on the queue. */
+#define AAC_FLAGS_NEW_COMM_TYPE1	(1 << 16)	/* New comm. type1 supported */
+	u_int32_t		hint_flags;		/* driver parameters */
+	int	sim_freezed;				/* flag for sim_freeze/release */		
 	u_int32_t		supported_options;
 	u_int32_t		scsi_method_id;
 	TAILQ_HEAD(,aac_sim)	aac_sim_tqh;
@@ -403,6 +437,15 @@
 	u_int32_t	aac_max_fib_size;		/* max. FIB size */
 	u_int32_t	aac_sg_tablesize;		/* max. sg count from host */
 	u_int32_t	aac_max_sectors;		/* max. I/O size from host (blocks) */
+	u_int32_t	aac_feature_bits;		/* feature bits from suppl. info */
+	u_int32_t	aac_support_opt2;		/* supp. options from suppl. info */
+	u_int32_t	aac_max_aif;			/* max. AIF count */
+
+	u_int32_t	DebugFlags;			/* Debug print flags bitmap */
+	u_int32_t	DebugOffset;			/* Offset from DPMEM start */
+	u_int32_t	DebugHeaderSize;		/* Size of debug header */
+	u_int32_t	FwDebugFlags;			/* FW Debug Flags */
+	u_int32_t	FwDebugBufferSize;		/* FW Debug Buffer Size in Bytes */
 };
 
 /*
@@ -431,6 +474,7 @@
 extern int		aac_shutdown(device_t dev);
 extern int		aac_suspend(device_t dev); 
 extern int		aac_resume(device_t dev);
+extern void		aac_new_intr_type1(void *arg);
 extern void		aac_new_intr(void *arg);
 extern int		aac_fast_intr(void *arg);
 extern void		aac_submit_bio(struct bio *bp);
@@ -444,19 +488,11 @@
 				     u_int16_t datasize);
 extern void		aac_add_event(struct aac_softc *sc, struct aac_event
 				      *event);
+extern void		aac_cam_rescan_jbod(struct aac_softc *sc, u_int32_t chn);
 
 #ifdef AAC_DEBUG
-extern int	aac_debug_enable;
 # define fwprintf(sc, flags, fmt, args...)				\
-do {									\
-	if (!aac_debug_enable)						\
-		break;							\
-	if (sc != NULL)							\
-		device_printf(((struct aac_softc *)sc)->aac_dev,	\
-		    "%s: " fmt "\n", __func__, ##args);			\
-	else								\
-		printf("%s: " fmt "\n", __func__, ##args);		\
-} while(0)
+	aac_fw_printf(sc, flags, "%s: " fmt, __func__, ##args);	
 
 extern void	aac_print_queues(struct aac_softc *sc);
 extern void	aac_panic(struct aac_softc *sc, char *reason);
