diff --git a/sys/dev/aac/aac.c b/sys/dev/aac/aac.c
index e8d36070e660..e9f3e23f0df4 100644
--- a/sys/dev/aac/aac.c
+++ b/sys/dev/aac/aac.c
@@ -33,6 +33,9 @@ __FBSDID("$FreeBSD$");
 /*
  * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
  */
+#define AAC_DRIVER_VERSION		0x02000000
+#define AAC_DRIVER_BUILD_DATE		__DATE__ " " __TIME__
+#define AAC_DRIVERNAME			"aac"
 
 #include "opt_aac.h"
 
@@ -51,11 +54,15 @@ __FBSDID("$FreeBSD$");
 #include <sys/signalvar.h>
 #include <sys/time.h>
 #include <sys/eventhandler.h>
+#include <sys/rman.h>
 
 #include <machine/bus.h>
 #include <sys/bus_dma.h>
 #include <machine/resource.h>
 
+#include <dev/pci/pcireg.h>
+#include <dev/pci/pcivar.h>
+
 #include <dev/aac/aacreg.h>
 #include <sys/aac_ioctl.h>
 #include <dev/aac/aacvar.h>
@@ -116,7 +123,8 @@ struct aac_interface aac_fa_interface = {
 	aac_fa_clear_istatus,
 	aac_fa_set_mailbox,
 	aac_fa_get_mailbox,
-	aac_fa_set_interrupts
+	aac_fa_set_interrupts,
+	NULL, NULL, NULL
 };
 
 /* StrongARM interface */
@@ -137,7 +145,8 @@ struct aac_interface aac_sa_interface = {
 	aac_sa_clear_istatus,
 	aac_sa_set_mailbox,
 	aac_sa_get_mailbox,
-	aac_sa_set_interrupts
+	aac_sa_set_interrupts,
+	NULL, NULL, NULL
 };
 
 /* i960Rx interface */	
@@ -150,6 +159,9 @@ static void	aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
 				   u_int32_t arg2, u_int32_t arg3);
 static int	aac_rx_get_mailbox(struct aac_softc *sc, int mb);
 static void	aac_rx_set_interrupts(struct aac_softc *sc, int enable);
+static int aac_rx_send_command(struct aac_softc *sc, struct aac_command *cm);
+static int aac_rx_get_outb_queue(struct aac_softc *sc);
+static void aac_rx_set_outb_queue(struct aac_softc *sc, int index);
 
 struct aac_interface aac_rx_interface = {
 	aac_rx_get_fwstatus,
@@ -158,7 +170,10 @@ struct aac_interface aac_rx_interface = {
 	aac_rx_clear_istatus,
 	aac_rx_set_mailbox,
 	aac_rx_get_mailbox,
-	aac_rx_set_interrupts
+	aac_rx_set_interrupts,
+	aac_rx_send_command,
+	aac_rx_get_outb_queue,
+	aac_rx_set_outb_queue
 };
 
 /* Rocket/MIPS interface */	
@@ -171,6 +186,9 @@ static void	aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command,
 				    u_int32_t arg2, u_int32_t arg3);
 static int	aac_rkt_get_mailbox(struct aac_softc *sc, int mb);
 static void	aac_rkt_set_interrupts(struct aac_softc *sc, int enable);
+static int aac_rkt_send_command(struct aac_softc *sc, struct aac_command *cm);
+static int aac_rkt_get_outb_queue(struct aac_softc *sc);
+static void aac_rkt_set_outb_queue(struct aac_softc *sc, int index);
 
 struct aac_interface aac_rkt_interface = {
 	aac_rkt_get_fwstatus,
@@ -179,7 +197,10 @@ struct aac_interface aac_rkt_interface = {
 	aac_rkt_clear_istatus,
 	aac_rkt_set_mailbox,
 	aac_rkt_get_mailbox,
-	aac_rkt_set_interrupts
+	aac_rkt_set_interrupts,
+	aac_rkt_send_command,
+	aac_rkt_get_outb_queue,
+	aac_rkt_set_outb_queue
 };
 
 /* Debugging and Diagnostics */
@@ -199,6 +220,9 @@ static int		aac_rev_check(struct aac_softc *sc, caddr_t udata);
 static int		aac_getnext_aif(struct aac_softc *sc, caddr_t arg);
 static int		aac_return_aif(struct aac_softc *sc, caddr_t uptr);
 static int		aac_query_disk(struct aac_softc *sc, caddr_t uptr);
+static int		aac_get_pci_info(struct aac_softc *sc, caddr_t uptr);
+static void		aac_ioctl_event(struct aac_softc *sc,
+				        struct aac_event *event, void *arg);
 
 static struct cdevsw aac_cdevsw = {
 	.d_version =	D_VERSION,
@@ -242,9 +266,6 @@ aac_attach(struct aac_softc *sc)
 	 */
 	TASK_INIT(&sc->aac_task_complete, 0, aac_complete, sc);
 
-	/* disable interrupts before we enable anything */
-	AAC_MASK_INTERRUPTS(sc);
-
 	/* mark controller as suspended until we get ourselves organised */
 	sc->aac_state |= AAC_STATE_SUSPEND;
 
@@ -271,6 +292,40 @@ aac_attach(struct aac_softc *sc)
 	if ((error = aac_init(sc)) != 0)
 		return(error);
 
+	/* 
+	 * Allocate and connect our interrupt.
+	 */
+	sc->aac_irq_rid = 0;
+	if ((sc->aac_irq = bus_alloc_resource_any(sc->aac_dev, SYS_RES_IRQ,
+			   			  &sc->aac_irq_rid,
+			   			  RF_SHAREABLE |
+						  RF_ACTIVE)) == NULL) {
+		device_printf(sc->aac_dev, "can't allocate interrupt\n");
+		return (EINVAL);
+	}
+	if (sc->flags & AAC_FLAGS_NEW_COMM) {
+		if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
+				   INTR_MPSAFE|INTR_TYPE_BIO, aac_new_intr,
+				   sc, &sc->aac_intr)) {
+			device_printf(sc->aac_dev, "can't set up interrupt\n");
+			return (EINVAL);
+		}
+	} else {
+		if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
+				   INTR_FAST|INTR_TYPE_BIO, aac_fast_intr,
+				   sc, &sc->aac_intr)) {
+			device_printf(sc->aac_dev,
+				      "can't set up FAST interrupt\n");
+			if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
+					   INTR_MPSAFE|INTR_TYPE_BIO,
+					   aac_fast_intr, sc, &sc->aac_intr)) {
+				device_printf(sc->aac_dev,
+					     "can't set up MPSAFE interrupt\n");
+				return (EINVAL);
+			}
+		}
+	}
+
 	/* 
 	 * Print a little information about the controller.
 	 */
@@ -299,7 +354,7 @@ aac_attach(struct aac_softc *sc)
 
 	/* Create the AIF thread */
 	if (kthread_create((void(*)(void *))aac_command_thread, sc,
-			   &sc->aifthread, 0, 0, "aac%daif", unit))
+		   &sc->aifthread, 0, 0, "aac%daif", unit))
 		panic("Could not create AIF thread\n");
 
 	/* Register the shutdown method to only be called post-dump */
@@ -317,6 +372,23 @@ aac_attach(struct aac_softc *sc)
 	return(0);
 }
 
+void
+aac_add_event(struct aac_softc *sc, struct aac_event *event)
+{
+
+	switch (event->ev_type & AAC_EVENT_MASK) {
+	case AAC_EVENT_CMFREE:
+		TAILQ_INSERT_TAIL(&sc->aac_ev_cmfree, event, ev_links);
+		break;
+	default:
+		device_printf(sc->aac_dev, "aac_add event: unknown event %d\n",
+		    event->ev_type);
+		break;
+	}
+
+	return;
+}
+
 /*
  * Probe for containers, create disks.
  */
@@ -336,6 +408,7 @@ aac_startup(void *arg)
 	/* disconnect ourselves from the intrhook chain */
 	config_intrhook_disestablish(&sc->aac_ich);
 
+	mtx_lock(&sc->aac_io_lock);
 	aac_alloc_sync_fib(sc, &fib);
 	mi = (struct aac_mntinfo *)&fib->data[0];
 
@@ -360,6 +433,7 @@ aac_startup(void *arg)
 	} while ((i < count) && (i < AAC_MAX_CONTAINERS));
 
 	aac_release_sync_fib(sc);
+	mtx_unlock(&sc->aac_io_lock);
 
 	/* poke the bus to actually attach the child devices */
 	if (bus_generic_attach(sc->aac_dev))
@@ -550,6 +624,7 @@ aac_shutdown(device_t dev)
 	 */
 	device_printf(sc->aac_dev, "shutting down controller...");
 
+	mtx_lock(&sc->aac_io_lock);
 	aac_alloc_sync_fib(sc, &fib);
 	cc = (struct aac_close_command *)&fib->data[0];
 
@@ -581,6 +656,7 @@ aac_shutdown(device_t dev)
 
 	AAC_MASK_INTERRUPTS(sc);
 	aac_release_sync_fib(sc);
+	mtx_unlock(&sc->aac_io_lock);
 
 	return(0);
 }
@@ -621,10 +697,91 @@ aac_resume(device_t dev)
 }
 
 /*
- * Take an interrupt.
+ * Interrupt handler for NEW_COMM interface.
  */
 void
-aac_intr(void *arg)
+aac_new_intr(void *arg)
+{
+	struct aac_softc *sc;
+	u_int32_t index, fast;
+	struct aac_command *cm;
+	struct aac_fib *fib;
+	int i;
+
+	debug_called(2);
+
+	sc = (struct aac_softc *)arg;
+
+	mtx_lock(&sc->aac_io_lock);
+	while (1) {
+		index = AAC_GET_OUTB_QUEUE(sc);
+		if (index == 0xffffffff)
+			index = AAC_GET_OUTB_QUEUE(sc);
+		if (index == 0xffffffff)
+			break;
+		if (index & 2) {
+			if (index == 0xfffffffe) {
+				/* XXX This means that the controller wants
+				 * more work.  Ignore it for now.
+				 */
+				continue;
+			}
+			/* AIF */
+			fib = (struct aac_fib *)malloc(sizeof *fib, M_AACBUF,
+				   M_NOWAIT | M_ZERO);
+			if (fib == NULL) {
+				/* If we're really this short on memory,
+				 * hopefully breaking out of the handler will
+				 * allow something to get freed.  This
+				 * actually sucks a whole lot.
+				 */
+				break;
+			}
+			index &= ~2;
+			for (i = 0; i < sizeof(struct aac_fib)/4; ++i)
+				((u_int32_t *)fib)[i] = AAC_GETREG4(sc, index + i*4);
+			aac_handle_aif(sc, fib);
+			free(fib, M_AACBUF);
+
+			/*
+			 * AIF memory is owned by the adapter, so let it
+			 * know that we are done with it.
+			 */
+			AAC_SET_OUTB_QUEUE(sc, index);
+			AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
+		} else {
+			fast = index & 1;
+			cm = sc->aac_commands + (index >> 2);
+			fib = cm->cm_fib;
+			if (fast) {
+				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;
+		}
+	}
+	/* 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);
+}
+
+void
+aac_fast_intr(void *arg)
 {
 	struct aac_softc *sc;
 	u_int16_t reason;
@@ -653,7 +810,7 @@ aac_intr(void *arg)
 		 * that start with a NULL.
 		 */
 		if ((reason & AAC_DB_PRINTF) &&
-		    (sc->aac_common->ac_printf[0] == 0))
+			(sc->aac_common->ac_printf[0] == 0))
 			sc->aac_common->ac_printf[0] = 32;
 
 		/*
@@ -781,8 +938,12 @@ aac_command_thread(struct aac_softc *sc)
 			aac_print_printf(sc);
 
 		/* Also check to see if the adapter has a command for us. */
-		while (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE,
-				       &fib_size, &fib) == 0) {
+		if (sc->flags & AAC_FLAGS_NEW_COMM)
+			continue;
+		for (;;) {
+			if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE,
+					   &fib_size, &fib)) 
+				break;
 	
 			AAC_PRINT_FIB(sc, fib);
 	
@@ -797,8 +958,9 @@ aac_command_thread(struct aac_softc *sc)
 			}
 
 			if ((fib->Header.XferState == 0) ||
-			    (fib->Header.StructType != AAC_FIBTYPE_TFIB))
+			    (fib->Header.StructType != AAC_FIBTYPE_TFIB)) {
 				break;
+			}
 
 			/* Return the AIF to the controller. */
 			if (fib->Header.XferState & AAC_FIBSTATE_FROMADAP) {
@@ -817,8 +979,8 @@ aac_command_thread(struct aac_softc *sc)
 				 * enqueue->startio chain.
 				 */
 				aac_enqueue_response(sc,
-						     AAC_ADAP_NORM_RESP_QUEUE,
-						     fib);
+						 AAC_ADAP_NORM_RESP_QUEUE,
+						 fib);
 			}
 		}
 	}
@@ -850,7 +1012,7 @@ aac_complete(void *context, int pending)
 	for (;;) {
 		/* look for completed FIBs on our queue */
 		if (aac_dequeue_fib(sc, AAC_HOST_NORM_RESP_QUEUE, &fib_size,
-				    &fib))
+							&fib))
 			break;	/* nothing to do */
 
 		/* get the command, unmap and hand off for processing */
@@ -859,9 +1021,9 @@ aac_complete(void *context, int pending)
 			AAC_PRINT_FIB(sc, fib);
 			break;
 		}
-
 		aac_remove_busy(cm);
-		aac_unmap_command(cm);
+
+ 		aac_unmap_command(cm);
 		cm->cm_flags |= AAC_CMD_COMPLETED;
 
 		/* is there a completion handler? */
@@ -944,7 +1106,25 @@ aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
 	/* build the read/write request */
 	ad = (struct aac_disk *)bp->bio_disk->d_drv1;
 
-	if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
+	if (sc->flags & AAC_FLAGS_RAW_IO) {
+		struct aac_raw_io *raw;
+		raw = (struct aac_raw_io *)&fib->data[0];
+		fib->Header.Command = RawIo;
+		raw->BlockNumber = (u_int64_t)bp->bio_pblkno;
+		raw->ByteCount = bp->bio_bcount;
+		raw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
+		raw->BpTotal = 0;
+		raw->BpComplete = 0;
+		fib->Header.Size += sizeof(struct aac_raw_io);
+		cm->cm_sgtable = (struct aac_sg_table *)&raw->SgMapRaw;
+		if (bp->bio_cmd == BIO_READ) {
+			raw->Flags = 1;
+			cm->cm_flags |= AAC_CMD_DATAIN;
+		} else {
+			raw->Flags = 0;
+			cm->cm_flags |= AAC_CMD_DATAOUT;
+		}
+	} else if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
 		fib->Header.Command = ContainerCommand;
 		if (bp->bio_cmd == BIO_READ) {
 			struct aac_blockread *br;
@@ -1001,6 +1181,8 @@ aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
 	return(0);
 
 fail:
+	if (bp != NULL)
+		aac_enqueue_bio(sc, bp);
 	if (cm != NULL)
 		aac_release_command(cm);
 	return(ENOMEM);
@@ -1101,6 +1283,9 @@ aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
 void
 aac_release_command(struct aac_command *cm)
 {
+	struct aac_event *event;
+	struct aac_softc *sc;
+
 	debug_called(3);
 
 	/* (re)initialise the command/FIB */
@@ -1111,7 +1296,7 @@ aac_release_command(struct aac_command *cm)
 	cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
 	cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
 	cm->cm_fib->Header.Flags = 0;
-	cm->cm_fib->Header.SenderSize = sizeof(struct aac_fib);
+	cm->cm_fib->Header.SenderSize = cm->cm_sc->aac_max_fib_size;
 
 	/* 
 	 * These are duplicated in aac_start to cover the case where an
@@ -1122,6 +1307,13 @@ aac_release_command(struct aac_command *cm)
 	cm->cm_fib->Header.SenderData = 0;
 
 	aac_enqueue_free(cm);
+
+	sc = cm->cm_sc;
+	event = TAILQ_FIRST(&sc->aac_ev_cmfree);
+	if (event != NULL) {
+		TAILQ_REMOVE(&sc->aac_ev_cmfree, event, ev_links);
+		event->ev_callback(sc, event, event->ev_arg);
+	}
 }
 
 /*
@@ -1130,9 +1322,9 @@ aac_release_command(struct aac_command *cm)
 static void
 aac_map_command_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 {
-	uint32_t	*fibphys;
+	uint64_t	*fibphys;
 
-	fibphys = (uint32_t *)arg;
+	fibphys = (uint64_t *)arg;
 
 	debug_called(3);
 
@@ -1147,12 +1339,12 @@ aac_alloc_commands(struct aac_softc *sc)
 {
 	struct aac_command *cm;
 	struct aac_fibmap *fm;
-	uint32_t fibphys;
+	uint64_t fibphys;
 	int i, error;
  
 	debug_called(2);
 
-	if (sc->total_fibs + AAC_FIB_COUNT > sc->aac_max_fibs)
+	if (sc->total_fibs + sc->aac_max_fibs_alloc > sc->aac_max_fibs)
 		return (ENOMEM);
 
 	fm = malloc(sizeof(struct aac_fibmap), M_AACBUF, M_NOWAIT|M_ZERO);
@@ -1170,18 +1362,19 @@ aac_alloc_commands(struct aac_softc *sc)
 
 	/* Ignore errors since this doesn't bounce */
 	(void)bus_dmamap_load(sc->aac_fib_dmat, fm->aac_fibmap, fm->aac_fibs, 
-			      AAC_FIB_COUNT * sizeof(struct aac_fib),
+			      sc->aac_max_fibs_alloc * sc->aac_max_fib_size,
 			      aac_map_command_helper, &fibphys, 0);
 
 	/* initialise constant fields in the command structure */
 	mtx_lock(&sc->aac_io_lock);
-	bzero(fm->aac_fibs, AAC_FIB_COUNT * sizeof(struct aac_fib));
-	for (i = 0; i < AAC_FIB_COUNT; i++) {
+	bzero(fm->aac_fibs, sc->aac_max_fibs_alloc * sc->aac_max_fib_size);
+	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 = fm->aac_fibs + i;
-		cm->cm_fibphys = fibphys + (i * sizeof(struct aac_fib));
+		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;
 		cm->cm_index = sc->total_fibs;
 
 		if ((error = bus_dmamap_create(sc->aac_buffer_dmat, 0,
@@ -1225,7 +1418,7 @@ aac_free_commands(struct aac_softc *sc)
 		 * We check against total_fibs to handle partially
 		 * allocated blocks.
 		 */
-		for (i = 0; i < AAC_FIB_COUNT && sc->total_fibs--; i++) {
+		for (i = 0; i < sc->aac_max_fibs_alloc && sc->total_fibs--; i++) {
 			cm = fm->aac_commands + i;
 			bus_dmamap_destroy(sc->aac_buffer_dmat, cm->cm_datamap);
 		}
@@ -1254,7 +1447,20 @@ aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 
 	/* copy into the FIB */
 	if (cm->cm_sgtable != NULL) {
-		if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
+		if (fib->Header.Command == RawIo) {
+			struct aac_sg_tableraw *sg;
+			sg = (struct aac_sg_tableraw *)cm->cm_sgtable;
+			sg->SgCount = nseg;
+			for (i = 0; i < nseg; i++) {
+				sg->SgEntryRaw[i].SgAddress = segs[i].ds_addr;
+				sg->SgEntryRaw[i].SgByteCount = segs[i].ds_len;
+				sg->SgEntryRaw[i].Next = 0;
+				sg->SgEntryRaw[i].Prev = 0;
+				sg->SgEntryRaw[i].Flags = 0;
+			}
+			/* update the FIB size for the s/g count */
+			fib->Header.Size += nseg*sizeof(struct aac_sg_entryraw);
+		} else if ((cm->cm_sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
 			struct aac_sg_table *sg;
 			sg = cm->cm_sgtable;
 			sg->SgCount = nseg;
@@ -1263,7 +1469,7 @@ aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 				sg->SgEntry[i].SgByteCount = segs[i].ds_len;
 			}
 			/* update the FIB size for the s/g count */
-			fib->Header.Size += nseg * sizeof(struct aac_sg_entry);
+			fib->Header.Size += nseg*sizeof(struct aac_sg_entry);
 		} else {
 			struct aac_sg_table64 *sg;
 			sg = (struct aac_sg_table64 *)cm->cm_sgtable;
@@ -1279,10 +1485,11 @@ aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 
 	/* Fix up the address values in the FIB.  Use the command array index
 	 * instead of a pointer since these fields are only 32 bits.  Shift
-	 * the SenderFibAddress over to make room for the fast response bit.
+	 * the SenderFibAddress over to make room for the fast response bit 
+	 * and for the AIF bit
 	 */
-	cm->cm_fib->Header.SenderFibAddress = (cm->cm_index << 1);
-	cm->cm_fib->Header.ReceiverFibAddress = cm->cm_fibphys;
+	cm->cm_fib->Header.SenderFibAddress = (cm->cm_index << 2);
+	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;
@@ -1295,11 +1502,23 @@ aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 				BUS_DMASYNC_PREWRITE);
 	cm->cm_flags |= AAC_CMD_MAPPED;
 
-	/* Put the FIB on the outbound queue */
-	if (aac_enqueue_fib(sc, cm->cm_queue, cm) == EBUSY) {
-		aac_unmap_command(cm);
-		sc->flags |= AAC_QUEUE_FRZN;
-		aac_requeue_ready(cm);
+	if (sc->flags & AAC_FLAGS_NEW_COMM) {
+		int count = 10000000L;
+		while (AAC_SEND_COMMAND(sc, cm) != 0) {
+			if (--count == 0) {
+				aac_unmap_command(cm);
+				sc->flags |= AAC_QUEUE_FRZN;
+				aac_requeue_ready(cm);
+			}
+			DELAY(5);			/* wait 5 usec. */
+		}
+	} else {
+		/* Put the FIB on the outbound queue */
+		if (aac_enqueue_fib(sc, cm->cm_queue, cm) == EBUSY) {
+			aac_unmap_command(cm);
+			sc->flags |= AAC_QUEUE_FRZN;
+			aac_requeue_ready(cm);
+		}
 	}
 
 	return;
@@ -1355,7 +1574,7 @@ aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 static int
 aac_check_firmware(struct aac_softc *sc)
 {
-	u_int32_t major, minor, options;
+	u_int32_t major, minor, options, atu_size;
 
 	debug_called(1);
 
@@ -1391,6 +1610,7 @@ aac_check_firmware(struct aac_softc *sc)
 		return (EIO);
 	}
 	options = AAC_GET_MAILBOX(sc, 1);
+	atu_size = AAC_GET_MAILBOX(sc, 2);
 	sc->supported_options = options;
 
 	if ((options & AAC_SUPPORTED_4GB_WINDOW) != 0 &&
@@ -1403,13 +1623,60 @@ aac_check_firmware(struct aac_softc *sc)
 		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)
+		sc->flags |= AAC_FLAGS_NEW_COMM;
+    if (options & AAC_SUPPORTED_64BIT_ARRAYSIZE)
+		sc->flags |= AAC_FLAGS_ARRAY_64BIT;
 
 	/* Check for broken hardware that does a lower number of commands */
-	if ((sc->flags & AAC_FLAGS_256FIBS) == 0)
-		sc->aac_max_fibs = AAC_MAX_FIBS;
-	else
-		sc->aac_max_fibs = 256;
+	sc->aac_max_fibs = (sc->flags & AAC_FLAGS_256FIBS ? 256:512); 
 
+	/* Remap mem. resource, if required */
+	if ((sc->flags & AAC_FLAGS_NEW_COMM) && 
+		atu_size > rman_get_size(sc->aac_regs_resource)) {
+		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,
+			0ul, ~0ul, atu_size, RF_ACTIVE); 
+		if (sc->aac_regs_resource == NULL) {
+			sc->aac_regs_resource = bus_alloc_resource_any(
+				sc->aac_dev, SYS_RES_MEMORY,
+				&sc->aac_regs_rid, RF_ACTIVE);
+			if (sc->aac_regs_resource == 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);
+	}
+
+	/* Read preferred settings */
+	sc->aac_max_fib_size = sizeof(struct aac_fib);
+	sc->aac_max_sectors = 128;				/* 64KB */
+	if (sc->flags & AAC_FLAGS_SG_64BIT)
+		sc->aac_sg_tablesize = (AAC_FIB_DATASIZE - sizeof(struct aac_blockwrite64)
+			+ sizeof(struct aac_sg_table64)) / sizeof(struct aac_sg_table64);
+	else
+		sc->aac_sg_tablesize = (AAC_FIB_DATASIZE - sizeof(struct aac_blockwrite)
+			+ sizeof(struct aac_sg_table)) / sizeof(struct aac_sg_table);
+	if (!aac_sync_command(sc, AAC_MONKER_GETCOMMPREF, 0, 0, 0, 0, NULL)) {
+		options = AAC_GET_MAILBOX(sc, 1);
+		sc->aac_max_fib_size = (options & 0xFFFF);
+		sc->aac_max_sectors = (options >> 16) << 1;
+		options = AAC_GET_MAILBOX(sc, 2);
+		sc->aac_sg_tablesize = (options >> 16);
+		options = AAC_GET_MAILBOX(sc, 3);
+		sc->aac_max_fibs = (options & 0xFFFF);
+	}
+	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;
+    
 	return (0);
 }
 
@@ -1458,7 +1725,7 @@ aac_init(struct aac_softc *sc)
 			       BUS_SPACE_MAXADDR, 	/* highaddr */
 			       NULL, NULL, 		/* filter, filterarg */
 			       MAXBSIZE,		/* maxsize */
-			       AAC_MAXSGENTRIES,	/* nsegments */
+			       sc->aac_sg_tablesize,	/* nsegments */
 			       MAXBSIZE,		/* maxsegsize */
 			       BUS_DMA_ALLOCNOW,	/* flags */
 			       busdma_lock_mutex,	/* lockfunc */
@@ -1478,11 +1745,11 @@ aac_init(struct aac_softc *sc)
 			       0x7fffffff,		/* lowaddr */
 			       BUS_SPACE_MAXADDR, 	/* highaddr */
 			       NULL, NULL, 		/* filter, filterarg */
-			       AAC_FIB_COUNT *
-			       sizeof(struct aac_fib),  /* maxsize */
+			       sc->aac_max_fibs_alloc *
+			       sc->aac_max_fib_size,  /* maxsize */
 			       1,			/* nsegments */
-			       AAC_FIB_COUNT *
-			       sizeof(struct aac_fib),	/* maxsegsize */
+			       sc->aac_max_fibs_alloc *
+			       sc->aac_max_fib_size,	/* maxsegsize */
 			       0,			/* flags */
 			       NULL, NULL,		/* No locking needed */
 			       &sc->aac_fib_dmat)) {
@@ -1535,7 +1802,7 @@ aac_init(struct aac_softc *sc)
 
 	/* Allocate some FIBs and associated command structs */
 	TAILQ_INIT(&sc->aac_fibmap_tqh);
-	sc->aac_commands = malloc(AAC_MAX_FIBS * sizeof(struct aac_command),
+	sc->aac_commands = malloc(sc->aac_max_fibs * sizeof(struct aac_command),
 				  M_AACBUF, M_WAITOK|M_ZERO);
 	while (sc->total_fibs < AAC_PREALLOCATE_FIBS) {
 		if (aac_alloc_commands(sc) != 0)
@@ -1550,6 +1817,10 @@ aac_init(struct aac_softc *sc)
 	 */
 	ip = &sc->aac_common->ac_init;
 	ip->InitStructRevision = AAC_INIT_STRUCT_REVISION;
+	if (sc->aac_max_fib_size > sizeof(struct aac_fib)) {
+		ip->InitStructRevision = AAC_INIT_STRUCT_REVISION_4;
+		sc->flags |= AAC_FLAGS_RAW_IO;
+	}
 	ip->MiniPortRevision = AAC_INIT_STRUCT_MINIPORT_REVISION;
 
 	ip->AdapterFibsPhysicalAddress = sc->aac_common_busaddr +
@@ -1575,6 +1846,16 @@ aac_init(struct aac_softc *sc)
 	}
 	ip->HostElapsedSeconds = time_uptime;	/* reset later if invalid */
 
+	ip->InitFlags = 0;
+	if (sc->flags & AAC_FLAGS_NEW_COMM) {
+		ip->InitFlags = INITFLAGS_NEW_COMM_SUPPORTED;
+		device_printf(sc->aac_dev, "New comm. interface enabled\n");
+	}
+
+	ip->MaxIoCommands = sc->aac_max_fibs;
+	ip->MaxIoSize = sc->aac_max_sectors << 9;
+	ip->MaxFibSize = sc->aac_max_fib_size;
+
 	/*
 	 * Initialise FIB queues.  Note that it appears that the layout of the
 	 * indexes and the segmentation of the entries may be mandated by the
@@ -1680,6 +1961,7 @@ out:
 
 /*
  * 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
 aac_sync_command(struct aac_softc *sc, u_int32_t command,
@@ -1716,6 +1998,9 @@ aac_sync_command(struct aac_softc *sc, u_int32_t command,
 	status = AAC_GET_MAILBOX(sc, 0);
 	if (sp != NULL)
 		*sp = status;
+
+	if (status != 0x01)
+		return (-1);
 	return(0);
 }
 
@@ -1724,6 +2009,7 @@ aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
 		 struct aac_fib *fib, u_int16_t datasize)
 {
 	debug_called(3);
+	mtx_assert(&sc->aac_io_lock, MA_OWNED);
 
 	if (datasize > AAC_FIB_DATASIZE)
 		return(EINVAL);
@@ -1902,7 +2188,7 @@ aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
 		 * field.
 		 */
 		fib_index = (sc->aac_qentries[queue] + ci)->aq_fib_addr;
-		cm = sc->aac_commands + (fib_index >> 1);
+		cm = sc->aac_commands + (fib_index >> 2);
 		*fib_addr = cm->cm_fib;
 
 		/*
@@ -2292,7 +2578,10 @@ aac_rx_set_interrupts(struct aac_softc *sc, int enable)
 	debug(2, "%sable interrupts", enable ? "en" : "dis");
 
 	if (enable) {
-		AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
+		if (sc->flags & AAC_FLAGS_NEW_COMM)
+			AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INT_NEW_COMM);
+		else
+			AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
 	} else {
 		AAC_SETREG4(sc, AAC_RX_OIMR, ~0);
 	}
@@ -2318,12 +2607,99 @@ aac_rkt_set_interrupts(struct aac_softc *sc, int enable)
 	debug(2, "%sable interrupts", enable ? "en" : "dis");
 
 	if (enable) {
-		AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
+		if (sc->flags & AAC_FLAGS_NEW_COMM)
+			AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INT_NEW_COMM);
+		else
+			AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
 	} else {
 		AAC_SETREG4(sc, AAC_RKT_OIMR, ~0);
 	}
 }
 
+/*
+ * New comm. interface: Send command functions
+ */
+static int
+aac_rx_send_command(struct aac_softc *sc, struct aac_command *cm)
+{
+	u_int32_t index, device;
+
+	debug(2, "send command (new comm.)");
+
+	index = AAC_GETREG4(sc, AAC_RX_IQUE);
+	if (index == 0xffffffffL)
+		index = AAC_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));
+	device += 4;
+	AAC_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);
+	return 0;
+}
+
+static int
+aac_rkt_send_command(struct aac_softc *sc, struct aac_command *cm)
+{
+	u_int32_t index, device;
+
+	debug(2, "send command (new comm.)");
+
+	index = AAC_GETREG4(sc, AAC_RKT_IQUE);
+	if (index == 0xffffffffL)
+		index = AAC_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));
+	device += 4;
+	AAC_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);
+	return 0;
+}
+
+/* 
+ * New comm. interface: get, set outbound queue index 
+ */
+static int
+aac_rx_get_outb_queue(struct aac_softc *sc)
+{
+	debug_called(3);
+
+	return(AAC_GETREG4(sc, AAC_RX_OQUE));
+}
+
+static int
+aac_rkt_get_outb_queue(struct aac_softc *sc)
+{
+	debug_called(3);
+
+	return(AAC_GETREG4(sc, AAC_RKT_OQUE));
+}
+
+static void
+aac_rx_set_outb_queue(struct aac_softc *sc, int index)
+{
+	debug_called(3);
+
+	AAC_SETREG4(sc, AAC_RX_OQUE, index);
+}
+
+static void
+aac_rkt_set_outb_queue(struct aac_softc *sc, int index)
+{
+	debug_called(3);
+
+	AAC_SETREG4(sc, AAC_RKT_OQUE, index);
+}
+
 /*
  * Debugging and Diagnostics
  */
@@ -2352,6 +2728,12 @@ aac_describe_controller(struct aac_softc *sc)
 	info = (struct aac_adapter_info *)&fib->data[0];   
 	sc->aac_revision = info->KernelRevision;
 
+	device_printf(sc->aac_dev, "Adaptec Raid Controller %d.%d.%d-%d\n",
+		AAC_DRIVER_VERSION >> 24,
+		(AAC_DRIVER_VERSION >> 16) & 0xFF,
+		AAC_DRIVER_VERSION & 0xFF,
+		AAC_DRIVER_BUILD);
+
 	if (bootverbose) {
 		device_printf(sc->aac_dev, "%s %dMHz, %dMB memory "
 		    "(%dMB cache, %dMB execution), %s\n", 
@@ -2385,7 +2767,13 @@ aac_describe_controller(struct aac_softc *sc)
 			      "\12NORECOND"
 			      "\13SGMAP64"
 			      "\14ALARM"
-			      "\15NONDASD");
+			      "\15NONDASD"
+			      "\16SCSIMGT"
+			      "\17RAIDSCSI"
+			      "\21ADPTINFO"
+			      "\22NEWCOMM"
+			      "\23ARRAY64BIT"
+			      "\24HEATSENSOR");
 	}
 	aac_release_sync_fib(sc);
 }
@@ -2523,7 +2911,7 @@ aac_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td)
 	case FSACTL_LNX_QUERY_DISK:
 		debug(1, "FSACTL_QUERY_DISK");
 		error = aac_query_disk(sc, arg);
-			break;
+		break;
 	case FSACTL_DELETE_DISK:
 	case FSACTL_LNX_DELETE_DISK:
 		/*
@@ -2533,6 +2921,12 @@ aac_ioctl(struct cdev *dev, u_long cmd, caddr_t arg, int flag, d_thread_t *td)
 		 */
 		error = 0;
 		break;
+	case FSACTL_GET_PCI_INFO:
+		arg = *(caddr_t*)arg;
+	case FSACTL_LNX_GET_PCI_INFO:
+		debug(1, "FSACTL_GET_PCI_INFO");
+		error = aac_get_pci_info(sc, arg);
+		break;
 	default:
 		debug(1, "unsupported cmd 0x%lx\n", cmd);
 		error = EINVAL;
@@ -2565,6 +2959,27 @@ aac_poll(struct cdev *dev, int poll_events, d_thread_t *td)
 	return (revents);
 }
 
+static void
+aac_ioctl_event(struct aac_softc *sc, struct aac_event *event, void *arg)
+{
+
+	switch (event->ev_type) {
+	case AAC_EVENT_CMFREE:
+		mtx_lock(&sc->aac_io_lock);
+		if (aac_alloc_command(sc, (struct aac_command **)arg) == 0) {
+			aac_add_event(sc, event);
+			mtx_unlock(&sc->aac_io_lock);
+			return;
+		}
+		free(event, M_AACBUF);
+		wakeup(aac_ioctl_sendfib);
+		mtx_unlock(&sc->aac_io_lock);
+		break;
+	default:
+		break;
+	}
+}
+
 /*
  * Send a FIB supplied from userspace
  */
@@ -2583,8 +2998,19 @@ aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
 	 */
 	mtx_lock(&sc->aac_io_lock);
 	if (aac_alloc_command(sc, &cm)) {
-		error = EBUSY;
-		goto out;
+		struct aac_event *event;
+
+		event = malloc(sizeof(struct aac_event), M_AACBUF,
+		    M_NOWAIT | M_ZERO);
+		if (event == NULL) {
+			error = EBUSY;
+			goto out;
+		}
+		event->ev_type = AAC_EVENT_CMFREE;
+		event->ev_callback = aac_ioctl_event;
+		event->ev_arg = &cm;
+		aac_add_event(sc, event);
+		msleep(aac_ioctl_sendfib, &sc->aac_io_lock, 0, "sendfib", 0);
 	}
 
 	/*
@@ -2736,8 +3162,12 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
 			co = TAILQ_FIRST(&sc->aac_container_tqh);
 			while (co != NULL) {
 				if (co->co_found == 0) {
+					mtx_unlock(&sc->aac_io_lock);
+					mtx_lock(&Giant);
 					device_delete_child(sc->aac_dev,
 							    co->co_disk);
+					mtx_unlock(&Giant);
+					mtx_lock(&sc->aac_io_lock);
 					co_next = TAILQ_NEXT(co, co_link);
 					mtx_lock(&sc->aac_container_lock);
 					TAILQ_REMOVE(&sc->aac_container_tqh, co,
@@ -2752,8 +3182,13 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
 			}
 
 			/* Attach the newly created containers */
-			if (added)
+			if (added) {
+				mtx_unlock(&sc->aac_io_lock);
+				mtx_lock(&Giant);
 				bus_generic_attach(sc->aac_dev);
+				mtx_unlock(&Giant);
+				mtx_lock(&sc->aac_io_lock);
+			}
 	
 			break;
 
@@ -2887,6 +3322,26 @@ aac_return_aif(struct aac_softc *sc, caddr_t uptr)
 	return(error);
 }
 
+static int
+aac_get_pci_info(struct aac_softc *sc, caddr_t uptr)
+{
+	struct aac_pci_info {
+		u_int32_t bus;
+		u_int32_t slot;
+	} pciinf;
+	int error;
+
+	debug_called(2);
+
+	pciinf.bus = pci_get_bus(sc->aac_dev);
+	pciinf.slot = pci_get_slot(sc->aac_dev);
+
+	error = copyout((caddr_t)&pciinf, uptr,
+			sizeof(struct aac_pci_info));
+
+	return (error);
+}
+
 /*
  * Give the userland some information about the container.  The AAC arch
  * expects the driver to be a SCSI passthrough type driver, so it expects
@@ -3024,7 +3479,7 @@ aac_get_bus_info(struct aac_softc *sc)
 			device_printf(sc->aac_dev,
 			    "No memory to add passthrough bus %d\n", i);
 			break;
-		}
+		};
 
 		child = device_add_child(sc->aac_dev, "aacp", -1);
 		if (child == NULL) {
@@ -3032,7 +3487,7 @@ aac_get_bus_info(struct aac_softc *sc)
 			    "device_add_child failed for passthrough bus %d\n",
 			    i);
 			free(caminf, M_AACBUF);
-			break;
+			break;		
 		}
 
 		caminf->TargetsPerBus = businfo.TargetsPerBus;
diff --git a/sys/dev/aac/aac_cam.c b/sys/dev/aac/aac_cam.c
index 978b2e24593c..aaca0d10cf4f 100644
--- a/sys/dev/aac/aac_cam.c
+++ b/sys/dev/aac/aac_cam.c
@@ -79,7 +79,6 @@ static void aac_cam_complete(struct aac_command *);
 static u_int32_t aac_cam_reset_bus(struct cam_sim *, union ccb *);
 static u_int32_t aac_cam_abort_ccb(struct cam_sim *, union ccb *);
 static u_int32_t aac_cam_term_io(struct cam_sim *, union ccb *);
-static int aac_cam_get_tran_settings(struct aac_softc *, struct ccb_trans_settings *, u_int32_t);
 
 static devclass_t	aac_pass_devclass;
 
@@ -101,6 +100,26 @@ MODULE_DEPEND(aacp, cam, 1, 1, 1);
 
 MALLOC_DEFINE(M_AACCAM, "aaccam", "AAC CAM info");
 
+static void
+aac_cam_event(struct aac_softc *sc, struct aac_event *event, void *arg)
+{
+	struct aac_cam *camsc;
+
+	switch (event->ev_type) {
+	case AAC_EVENT_CMFREE:
+		camsc = arg;
+		free(event, M_AACCAM);
+		xpt_release_simq(camsc->sim, 1);
+		break;
+	default:
+		device_printf(sc->aac_dev, "unknown event %d in aac_cam\n",
+		    event->ev_type);
+		break;
+	}
+
+	return;
+}
+
 static int
 aac_cam_probe(device_t dev)
 {
@@ -251,12 +270,9 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
 	}
 	case XPT_GET_TRAN_SETTINGS:
 	{
-		u_int32_t handle;
-
-		handle = AAC_BTL_TO_HANDLE(camsc->inf->BusNumber,
-		    ccb->ccb_h.target_id, ccb->ccb_h.target_lun);
-		ccb->ccb_h.status = aac_cam_get_tran_settings(sc, &ccb->cts,
-		    handle);
+		ccb->cts.flags &= ~(CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB);
+		ccb->cts.valid = CCB_TRANS_DISC_VALID | CCB_TRANS_TQ_VALID;
+		ccb->ccb_h.status = CAM_REQ_CMP;
 		xpt_done(ccb);
 		return;
 	}
@@ -292,10 +308,25 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
 
 	mtx_lock(&sc->aac_io_lock);
 	if (aac_alloc_command(sc, &cm)) {
-		mtx_unlock(&sc->aac_io_lock);
+		struct aac_event *event;
+
 		xpt_freeze_simq(sim, 1);
 		ccb->ccb_h.status = CAM_REQUEUE_REQ;
 		xpt_done(ccb);
+		event = malloc(sizeof(struct aac_event), M_AACCAM,
+		    M_NOWAIT | M_ZERO);
+		if (event == NULL) {
+			device_printf(sc->aac_dev,
+			    "Warning, out of memory for event\n");
+			/* XXX Yuck, what to do here? */
+			mtx_unlock(&sc->aac_io_lock);
+			return;
+		}
+		event->ev_callback = aac_cam_event;
+		event->ev_arg = camsc;
+		event->ev_type = AAC_EVENT_CMFREE;
+		aac_add_event(sc, event);
+		mtx_unlock(&sc->aac_io_lock);
 		return;
 	}
 
@@ -469,7 +500,7 @@ aac_cam_complete(struct aac_command *cm)
 				    srbr->sense_len);
 				ccb->csio.sense_len = sense_len;
 				ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
-				scsi_sense_print(&ccb->csio);
+				// scsi_sense_print(&ccb->csio);
 			}
 
 			/* If this is an inquiry command, fake things out */
@@ -518,6 +549,7 @@ aac_cam_reset_bus(struct cam_sim *sim, union ccb *ccb)
 		return (CAM_REQ_ABORTED);
 	}
 
+	mtx_lock(&sc->aac_io_lock);
 	aac_alloc_sync_fib(sc, &fib);
 
 	vmi = (struct aac_vmioctl *)&fib->data[0];
@@ -542,6 +574,7 @@ aac_cam_reset_bus(struct cam_sim *sim, union ccb *ccb)
 	}
 
 	aac_release_sync_fib(sc);
+	mtx_unlock(&sc->aac_io_lock);
 	return (CAM_REQ_CMP);
 }
 
@@ -557,59 +590,3 @@ aac_cam_term_io(struct cam_sim *sim, union ccb *ccb)
 	return (CAM_UA_TERMIO);
 }
 
-static int
-aac_cam_get_tran_settings(struct aac_softc *sc, struct ccb_trans_settings *cts, u_int32_t handle)
-{
-	struct aac_fib *fib;
-	struct aac_vmioctl *vmi;
-	struct aac_vmi_devinfo_resp *vmi_resp;
-	int error;
-
-	aac_alloc_sync_fib(sc, &fib);
-	vmi = (struct aac_vmioctl *)&fib->data[0];
-	bzero(vmi, sizeof(struct aac_vmioctl));
-
-	vmi->Command = VM_Ioctl;
-	vmi->ObjType = FT_DRIVE;
-	vmi->MethId = sc->scsi_method_id;
-	vmi->ObjId = handle;
-	vmi->IoctlCmd = GetDeviceProbeInfo;
-
-	error = aac_sync_fib(sc, ContainerCommand, 0, fib,
-	    sizeof(struct aac_vmioctl));
-	if (error) {
-		device_printf(sc->aac_dev, "Error %d sending GetDeviceProbeInfo"
-		              " command\n", error);
-		aac_release_sync_fib(sc);
-		return (CAM_REQ_INVALID);
-	}
-
-	vmi_resp = (struct aac_vmi_devinfo_resp *)&fib->data[0];
-	if (vmi_resp->Status != ST_OK) {
-		/*
-		 * The only reason why this command will return an error is
-		 * if the requested device doesn't exist.
-		 */
-		debug(1, "GetDeviceProbeInfo returned %d\n", vmi_resp->Status);
-		aac_release_sync_fib(sc);
-		return (CAM_DEV_NOT_THERE);
-	}
-
-	cts->bus_width = ((vmi_resp->Inquiry7 & 0x60) >> 5);
-	cts->valid = CCB_TRANS_BUS_WIDTH_VALID;
-
-	if (vmi_resp->ScsiRate) {
-		cts->sync_period =
-		    scsi_calc_syncparam((10000 / vmi_resp->ScsiRate));
-		cts->sync_offset = vmi_resp->ScsiOffset;
-		cts->valid |= CCB_TRANS_SYNC_RATE_VALID		|
-			      CCB_TRANS_SYNC_OFFSET_VALID;
-	}
-
-	cts->flags &= ~(CCB_TRANS_DISC_ENB | CCB_TRANS_TAG_ENB);
-	cts->valid |= CCB_TRANS_DISC_VALID		|
-		      CCB_TRANS_TQ_VALID;
-
-	aac_release_sync_fib(sc);
-	return (CAM_REQ_CMP);
-}
diff --git a/sys/dev/aac/aac_pci.c b/sys/dev/aac/aac_pci.c
index f97c85c60d43..de0f73933fd2 100644
--- a/sys/dev/aac/aac_pci.c
+++ b/sys/dev/aac/aac_pci.c
@@ -139,6 +139,59 @@ struct aac_ident
 	 "Adaptec SCSI RAID 2230S"},
 	{0x9005, 0x0286, 0x9005, 0x028d, AAC_HWIF_RKT, 0,
 	 "Adaptec SCSI RAID 2130S"},
+
+	{0x9005, 0x0285, 0x9005, 0x0287, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
+	 AAC_FLAGS_256FIBS, "Adaptec SCSI RAID 2200S"},
+	{0x9005, 0x0285, 0x17aa, 0x0286, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
+	 AAC_FLAGS_256FIBS, "Legend S220"},
+	{0x9005, 0x0285, 0x17aa, 0x0287, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
+	 AAC_FLAGS_256FIBS, "Legend S230"},
+	{0x9005, 0x0285, 0x9005, 0x0288, AAC_HWIF_I960RX, 0,
+	 "Adaptec SCSI RAID 3230S"},
+	{0x9005, 0x0285, 0x9005, 0x0289, AAC_HWIF_I960RX, 0,
+	 "Adaptec SCSI RAID 3240S"},
+	{0x9005, 0x0285, 0x9005, 0x028a, AAC_HWIF_I960RX, 0,
+	 "Adaptec SCSI RAID 2020ZCR"},
+	{0x9005, 0x0285, 0x9005, 0x028b, AAC_HWIF_I960RX, 0,
+	 "Adaptec SCSI RAID 2025ZCR"},
+	{0x9005, 0x0286, 0x9005, 0x029b, AAC_HWIF_RKT, 0,
+	 "Adaptec SATA RAID 2820SA"},
+	{0x9005, 0x0286, 0x9005, 0x029c, AAC_HWIF_RKT, 0,
+	 "Adaptec SATA RAID 2620SA"},
+	{0x9005, 0x0286, 0x9005, 0x029d, AAC_HWIF_RKT, 0,
+	 "Adaptec SATA RAID 2420SA"},
+	{0x9005, 0x0286, 0x9005, 0x029e, AAC_HWIF_RKT, 0,
+	 "ICP9024RO SATA RAID"},
+	{0x9005, 0x0286, 0x9005, 0x029f, AAC_HWIF_RKT, 0,
+	 "ICP9014RO SATA 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,
+	 "Adaptec SAS RAID 4005SAS"},
+	{0x9005, 0x0285, 0x1014, 0x02f2, AAC_HWIF_I960RX, 0,
+	 "IBM ServeRAID 8i"},
+	{0x9005, 0x0285, 0x9005, 0x0298, AAC_HWIF_I960RX, 0,
+	 "Adaptec SAS RAID 4000SAS"},
+	{0x9005, 0x0285, 0x9005, 0x0299, AAC_HWIF_I960RX, 0,
+	 "Adaptec SAS RAID 4800SAS"},
+	{0x9005, 0x0285, 0x9005, 0x029a, AAC_HWIF_I960RX, 0,
+	 "Adaptec SAS RAID 4805SAS"},
+	{0x9005, 0x0285, 0x9005, 0x028e, AAC_HWIF_I960RX, 0,
+	 "Adaptec SATA RAID 2020SA ZCR"},
+	{0x9005, 0x0285, 0x9005, 0x028f, AAC_HWIF_I960RX, 0,
+	 "Adaptec SATA RAID 2025SA ZCR"},
+	{0x9005, 0x0285, 0x9005, 0x02a4, AAC_HWIF_I960RX, 0,
+	 "ICP 9085LI SAS RAID"},
+	{0x9005, 0x0285, 0x9005, 0x02a5, AAC_HWIF_I960RX, 0,
+	 "ICP 5085BR SAS RAID"},
+	{0x9005, 0x0286, 0x9005, 0x02a0, AAC_HWIF_RKT, 0,
+	 "ICP9047MA SATA RAID"},
+	{0x9005, 0x0286, 0x9005, 0x02a1, AAC_HWIF_RKT, 0,
+	 "ICP9087MA SATA RAID"},
 	{0, 0, 0, 0, 0, 0, 0}
 };
 
@@ -221,30 +274,6 @@ aac_pci_attach(device_t dev)
 	sc->aac_btag = rman_get_bustag(sc->aac_regs_resource);
 	sc->aac_bhandle = rman_get_bushandle(sc->aac_regs_resource);
 
-	/* 
-	 * Allocate and connect our interrupt.
-	 */
-	sc->aac_irq_rid = 0;
-	if ((sc->aac_irq = bus_alloc_resource_any(sc->aac_dev, SYS_RES_IRQ,
-			   			  &sc->aac_irq_rid,
-			   			  RF_SHAREABLE |
-						  RF_ACTIVE)) == NULL) {
-		device_printf(sc->aac_dev, "can't allocate interrupt\n");
-		goto out;
-	}
-	if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
-			   INTR_FAST|INTR_TYPE_BIO, aac_intr,
-			   sc, &sc->aac_intr)) {
-		device_printf(sc->aac_dev, "can't set up FAST interrupt\n");
-		if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
-				   INTR_MPSAFE|INTR_ENTROPY|INTR_TYPE_BIO,
-				   aac_intr, sc, &sc->aac_intr)) {
-			device_printf(sc->aac_dev,
-				      "can't set up MPSAFE interrupt\n");
-			goto out;
-		}
-	}
-
 	/* assume failure is 'out of memory' */
 	error = ENOMEM;
 
@@ -259,7 +288,7 @@ aac_pci_attach(device_t dev)
 			       BUS_SPACE_MAXADDR, 	/* highaddr */
 			       NULL, NULL, 		/* filter, filterarg */
 			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsize */
-			       AAC_MAXSGENTRIES,	/* nsegments */
+			       BUS_SPACE_UNRESTRICTED,	/* nsegments */
 			       BUS_SPACE_MAXSIZE_32BIT,	/* maxsegsize */
 			       0,			/* flags */
 			       NULL, NULL,		/* No locking needed */
@@ -292,7 +321,7 @@ aac_pci_attach(device_t dev)
 				sc->aac_if = aac_fa_interface;
 				break;
 			case AAC_HWIF_RKT:
-				debug(2, "setu hardware up for Rocket/MIPS");
+				debug(2, "set hardware up for Rocket/MIPS");
 				sc->aac_if = aac_rkt_interface;
 				break;
 			default:
@@ -317,7 +346,7 @@ aac_pci_attach(device_t dev)
 	 * Do bus-independent initialisation.
 	 */
 	error = aac_attach(sc);
-	
+
 out:
 	if (error)
 		aac_free(sc);
diff --git a/sys/dev/aac/aac_tables.h b/sys/dev/aac/aac_tables.h
index 4ce82ac1dd3b..4a0d0e3dddd4 100644
--- a/sys/dev/aac/aac_tables.h
+++ b/sys/dev/aac/aac_tables.h
@@ -40,7 +40,7 @@ static struct aac_code_lookup aac_command_status_table[] = {
 	{"I/O error",				5},
 	{"device not configured",		6},
 	{"too big",				7},
-	{"permission denoed",			13},
+	{"permission denied",			13},
 	{"file exists",				17},
 	{"cross-device link",			18},
 	{"operation not supported by device",	19},
@@ -66,7 +66,7 @@ static struct aac_code_lookup aac_command_status_table[] = {
 	{"bad type",				10007},
 	{"jukebox",				10008},
 	{"not mounted",				10009},
-	{"in maintenace mode",			10010},
+	{"in maintenance mode",			10010},
 	{"stale ACL",				10011},
 	{NULL, 					0},
 	{"unknown command status",		0}
@@ -79,11 +79,14 @@ static struct aac_code_lookup aac_cpu_variant[] = {
 	{"i960CX",		CPUI960_CX},
 	{"i960HX",		CPUI960_HX},
 	{"i960RX",		CPUI960_RX},
+	{"i960 80303",		CPUI960_80303},
 	{"StrongARM SA110",	CPUARM_SA110},
-	{"MPC824x",		CPUMPC_824x},
+	{"PPC603e",		CPUPPC_603e},
+	{"XScale 80321",	CPU_XSCALE_80321},
+	{"MIPS 4KC",		CPU_MIPS_4KC},
+	{"MIPS 5KC",		CPU_MIPS_5KC},
 	{"Unknown StrongARM",	CPUARM_xxx},
 	{"Unknown PowerPC",	CPUPPC_xxx},
-	{"IOP302/303",		CPUI960_30X},
 	{NULL, 0},
 	{"Unknown processor",	0}
 };
@@ -113,6 +116,11 @@ static struct aac_code_lookup aac_container_types[] = {
 	{"Volume of Mirrors",	CT_VOLUME_OF_MIRRORS},
 	{"Pseudo RAID 3",	CT_PSEUDO_RAID3},
 	{"RAID 0/5",		CT_RAID50},
+	{"RAID 5D",		CT_RAID5D},
+	{"RAID 0/5D",		CT_RAID5D0},
+	{"RAID 1E",		CT_RAID1E},
+	{"RAID 6",		CT_RAID6},
+	{"RAID 0/6",		CT_RAID60},
 	{NULL, 0},
 	{"unknown",		0}
 };
diff --git a/sys/dev/aac/aacreg.h b/sys/dev/aac/aacreg.h
index 11357e32dcb8..efa14a1ffcca 100644
--- a/sys/dev/aac/aacreg.h
+++ b/sys/dev/aac/aacreg.h
@@ -200,12 +200,17 @@ typedef enum {
 	/* Container Commands */
 	ContainerCommand =		500,
 	ContainerCommand64 =		501,
+	RawIo = 			502,	
 
 	/* Cluster Commands */
 	ClusterCommand =		550,
 
 	/* Scsi Port commands (scsi passthrough) */
 	ScsiPortCommand =		600,
+	ScsiPortCommandU64 =		601,
+	SataPortCommandU64 =		602,
+	SasSmpPassThrough =		603,
+	SasRequestPhyInfo =		612,
 
 	/* misc house keeping and generic adapter initiated commands */
 	AifRequest =			700,
@@ -214,7 +219,21 @@ typedef enum {
 	RequestAdapterInfo =		703,
 	IsAdapterPaused =		704,
 	SendHostTime =			705,
-	LastMiscCommand =		706
+	RequestSupplementAdapterInfo =	706,	/* Supp. Info for set in UCC
+						 * use only if supported 
+						 * (RequestAdapterInfo first) */
+	LastMiscCommand =		707,
+  
+	OnLineDiagnostic =		800,      
+	FduAdapterTest =		801, 
+	RequestCompatibilityId =	802,
+	AdapterEnvironmentInfo =	803,	/* temp. sensors */
+	NvsramEventLog =		900,
+	ResetNvsramEventLogPointers =	901,
+	EnableEventLog =		902,
+	DisableEventLog =		903,
+	EncryptedKeyTransportFIB=	904,    
+	KeyableFeaturesFIB=		905     
 } AAC_FibCommands;
 
 /*
@@ -270,6 +289,7 @@ typedef enum {
 struct aac_adapter_init {
 	u_int32_t	InitStructRevision;
 #define AAC_INIT_STRUCT_REVISION		3
+#define AAC_INIT_STRUCT_REVISION_4		4
 	u_int32_t	MiniPortRevision;
 #define AAC_INIT_STRUCT_MINIPORT_REVISION	1
 	u_int32_t	FilesystemRevision;
@@ -284,6 +304,12 @@ struct aac_adapter_init {
 #define	AAC_PAGE_SIZE				4096
 	u_int32_t	HostPhysMemPages;
 	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
+	u_int32_t	MaxIoCommands;		/* max outstanding commands */
+	u_int32_t	MaxIoSize;			/* largest I/O command */
+	u_int32_t	MaxFibSize;			/* largest FIB to adapter */
 } __packed;
 
 /*
@@ -308,6 +334,11 @@ typedef enum {
 	CT_VOLUME_OF_MIRRORS,       /* volume of mirror */
 	CT_PSEUDO_RAID3,            /* really raid4 */
 	CT_RAID50,		    /* stripe of raid5 */
+	CT_RAID5D,		    /* raid5 distributed hot-sparing */
+	CT_RAID5D0,
+	CT_RAID1E,		    /* extended raid1 mirroring */
+	CT_RAID6,
+	CT_RAID60,
 } AAC_FSAVolType;
 
 /*
@@ -346,6 +377,14 @@ struct aac_sg_entry64 {
 	u_int32_t	SgByteCount;
 } __packed;
 
+struct aac_sg_entryraw {
+	u_int32_t	Next;		/* reserved for FW use */
+	u_int32_t	Prev;		/* reserved for FW use */
+	u_int64_t	SgAddress;
+	u_int32_t	SgByteCount;
+	u_int32_t	Flags;		/* reserved for FW use */
+} __packed;
+
 struct aac_sg_table {
 	u_int32_t		SgCount;
 	struct aac_sg_entry	SgEntry[0];
@@ -359,6 +398,14 @@ struct aac_sg_table64 {
 	struct aac_sg_entry64	SgEntry64[0];
 } __packed;
 
+/*
+ * s/g list for raw commands
+ */
+struct aac_sg_tableraw {
+	u_int32_t	SgCount;
+	struct aac_sg_entryraw	SgEntryRaw[0];
+} __packed;
+
 /*
  * Container creation data
  */
@@ -417,6 +464,8 @@ typedef enum {
 	CPU_ALPHA,
 	CPU_P7,
 	CPU_I960_RX,
+	CPU_MIPS,
+	CPU_XSCALE,
 	CPU__last
 } AAC_CpuType;  
 
@@ -427,9 +476,12 @@ typedef enum {
 	CPUI960_RX,
 	CPUARM_SA110,
 	CPUARM_xxx,
-	CPUMPC_824x,
+	CPUPPC_603e,
 	CPUPPC_xxx,
-	CPUI960_30X,
+	CPUI960_80303,
+	CPU_XSCALE_80321,
+	CPU_MIPS_4KC,
+	CPU_MIPS_5KC,
 	CPUSUBTYPE__last
 } AAC_CpuSubType;
 
@@ -454,6 +506,20 @@ typedef enum {
 	PLAT_POBLANO_XXX,
 	PLAT_JALAPENO_P2,
 	PLAT_HABANERO,
+	PLAT_VULCAN,
+	PLAT_CRUSADER,
+	PLAT_LANCER,
+	PLAT_HARRIER,
+	PLAT_TERMINATOR,
+	PLAT_SKYHAWK,
+	PLAT_CORSAIR,
+	PLAT_JAGUAR,
+	PLAT_SATAHAWK,
+	PLAT_SATANATOR,
+	PLAT_PROWLER,
+	PLAT_BLACKBIRD,
+	PLAT_SABREEXPRESS,
+	PLAT_INTRUDER,
 	PLAT__last
 } AAC_Platform;
 
@@ -463,9 +529,14 @@ typedef enum {
 	OEM_FLAVOR_HP,
 	OEM_FLAVOR_IBM,
 	OEM_FLAVOR_CPQ,
-	OEM_FLAVOR_BRAND_X,
-	OEM_FLAVOR_BRAND_Y,
+	OEM_FLAVOR_FSC,
+	OEM_FLAVOR_DWS,
 	OEM_FLAVOR_BRAND_Z,
+	OEM_FLAVOR_LEGEND,
+	OEM_FLAVOR_HITACHI,
+	OEM_FLAVOR_ESG,
+	OEM_FLAVOR_ICP,
+	OEM_FLAVOR_SCM,
 	OEM_FLAVOR__last
 } AAC_OemFlavor;
 
@@ -499,6 +570,12 @@ typedef enum
 #define AAC_SUPPORTED_SGMAP_HOST64	0x400
 #define AAC_SUPPORTED_ALARM		0x800
 #define AAC_SUPPORTED_NONDASD		0x1000
+#define AAC_SUPPORTED_SCSI_MANAGED	0x2000	
+#define AAC_SUPPORTED_RAID_SCSI_MODE	0x4000	
+#define AAC_SUPPORTED_SUPPLEMENT_ADAPTER_INFO	0x10000
+#define AAC_SUPPORTED_NEW_COMM		0x20000
+#define AAC_SUPPORTED_64BIT_ARRAYSIZE	0x40000
+#define AAC_SUPPORTED_HEAT_SENSOR	0x80000
 
 /* 
  * Structure used to respond to a RequestAdapterInfo fib.
@@ -534,10 +611,16 @@ struct aac_adapter_info {
 /*
  * Synchronous commands to the monitor/kernel.
  */
+#define AAC_MONKER_BREAKPOINT	0x04
 #define AAC_MONKER_INITSTRUCT	0x05
 #define AAC_MONKER_SYNCFIB	0x0c
 #define AAC_MONKER_GETKERNVER	0x11
+#define AAC_MONKER_POSTRESULTS	0x14
 #define AAC_MONKER_GETINFO	0x19
+#define AAC_MONKER_GETDRVPROP	0x23
+#define AAC_MONKER_RCVTEMP	0x25
+#define AAC_MONKER_GETCOMMPREF	0x26
+#define AAC_MONKER_REINIT	0xee
 
 /*
  *  Adapter Status Register
@@ -658,6 +741,7 @@ typedef enum {
 	AifJobScsiExercise,		/* SCSI device Exercise operation */
 	AifJobScsiVerifyRepair,		/* SCSI device Verify operation WITH
 					 * repair */
+	AifJobScsiWritePattern,		/* write pattern */
 	AifJobScsiMax = 99,		/* Max Scsi value */
 	AifJobCtrMin,			/* Min Ctr op value */
 	AifJobCtrZero,			/* Container clear operation */
@@ -671,6 +755,12 @@ typedef enum {
 	AifJobCtrPartCopy,		/* Container Partition copy operation */
 	AifJobCtrRebuildMirror,		/* Container Rebuild Mirror operation */
 	AifJobCtrCrazyCache,		/* crazy cache */
+	AifJobCtrCopyback,		/* Container Copyback operation */
+	AifJobCtrCompactRaid5D,		/* Container Compaction operation */
+	AifJobCtrExpandRaid5D,		/* Container Expansion operation */
+	AifJobCtrRebuildRaid6,		/* Container Rebuild Raid6 operation */
+	AifJobCtrScrubRaid6,		/* Container Scrub Raid6 operation */
+	AifJobCtrSSBackup,		/* Container snapshot backup task */
 	AifJobCtrMax = 199,		/* Max Ctr type operation */
 	AifJobFsMin,			/* Min Fs type operation */
 	AifJobFsCreate,			/* File System Create operation */
@@ -977,6 +1067,8 @@ typedef enum _VM_COMMANDS {
 	VM_CtBlockVerify64,
 	VM_CtHostRead64,
 	VM_CtHostWrite64,
+	VM_DrvErrTblLog,	/* drive error table/log type of command */
+	VM_NameServe64		 
 } AAC_VMCommand;
 
 /*
@@ -1071,8 +1163,15 @@ struct aac_vmi_businf_resp {
 	struct aac_getbusinf	BusInf;
 } __packed;
 
+#if 0
 #define AAC_BTL_TO_HANDLE(b, t, l) \
     (((b & 0x3f) << 7) | ((l & 0x7) << 4) | (t & 0xf))
+#else
+#define AAC_BTL_TO_HANDLE(b, t, l) \
+    ((((u_int32_t)b & 0x0f) << 24) | \
+     (((u_int32_t)l & 0xff) << 16) | \
+     ((u_int32_t)t & 0xffff))
+#endif
 #define GetDeviceProbeInfo 0x5
 
 struct aac_vmi_devinfo_resp {
@@ -1190,6 +1289,16 @@ struct aac_blockwrite_response {
 	u_int32_t		Committed;
 } __packed;
 
+struct aac_raw_io {
+	u_int64_t		BlockNumber;
+	u_int32_t		ByteCount;
+	u_int16_t		ContainerId;
+	u_int16_t		Flags;				/* 0: W, 1: R */
+	u_int16_t		BpTotal;			/* reserved for FW use */
+	u_int16_t		BpComplete;			/* reserved for FW use */
+	struct aac_sg_tableraw	SgMapRaw;	/* variable size */
+} __packed;
+
 /*
  * Container shutdown command.
  */
@@ -1334,6 +1443,8 @@ enum {
 #define AAC_RX_ODBR		0x2c	/* outbound doorbell register */
 #define AAC_RX_OISR		0x30	/* outbound interrupt status register */
 #define AAC_RX_OIMR		0x34	/* outbound interrupt mask register */
+#define AAC_RX_IQUE		0x40	/* inbound queue */
+#define AAC_RX_OQUE		0x44	/* outbound queue */
 
 #define AAC_RX_MAILBOX		0x50	/* mailbox (20 bytes) */
 #define AAC_RX_FWSTATUS		0x6c
@@ -1349,6 +1460,8 @@ enum {
 #define AAC_RKT_ODBR		0x2c	/* outbound doorbell register */
 #define AAC_RKT_OISR		0x30	/* outbound interrupt status register */
 #define AAC_RKT_OIMR		0x34	/* outbound interrupt mask register */
+#define AAC_RKT_IQUE		0x40	/* inbound queue */
+#define AAC_RKT_OQUE		0x44	/* outbound queue */
 
 #define AAC_RKT_MAILBOX		0x1000	/* mailbox */
 #define AAC_RKT_FWSTATUS	0x101c	/* Firmware Status (mailbox 7) */
@@ -1383,3 +1496,5 @@ enum {
 #define AAC_DB_INTERRUPTS	(AAC_DB_COMMAND_READY  |	\
 				 AAC_DB_RESPONSE_READY |	\
 				 AAC_DB_PRINTF)
+#define AAC_DB_INT_NEW_COMM		0x08		
+
diff --git a/sys/dev/aac/aacvar.h b/sys/dev/aac/aacvar.h
index 87e3c9c8ad75..a5ae32bf16ee 100644
--- a/sys/dev/aac/aacvar.h
+++ b/sys/dev/aac/aacvar.h
@@ -36,6 +36,9 @@
 #include <sys/selinfo.h>
 #include <geom/geom_disk.h>
 
+#ifndef AAC_DRIVER_BUILD
+# define AAC_DRIVER_BUILD 1
+#endif
 
 /*
  * Driver Parameter Definitions
@@ -56,9 +59,8 @@
  * FIBs are allocated in page-size chunks and can grow up to the 512
  * limit imposed by the hardware.
  */
-#define AAC_FIB_COUNT		(PAGE_SIZE/sizeof(struct aac_fib))
 #define AAC_PREALLOCATE_FIBS	128
-#define AAC_MAX_FIBS		504
+#define AAC_NUM_MGT_FIB		8
 
 /*
  * The controller reports status events in AIFs.  We hang on to a number of
@@ -146,7 +148,7 @@ struct aac_command
 
 	struct aac_fib		*cm_fib;	/* FIB associated with this
 						 * command */
-	u_int32_t		cm_fibphys;	/* bus address of the FIB */
+	u_int64_t		cm_fibphys;	/* bus address of the FIB */
 	struct bio		*cm_data;	/* pointer to data in kernel
 						 * space */
 	u_int32_t		cm_datalen;	/* data length */
@@ -165,7 +167,9 @@ struct aac_command
 #define AAC_ON_AACQ_FREE	(1<<5)
 #define AAC_ON_AACQ_READY	(1<<6)
 #define AAC_ON_AACQ_BUSY	(1<<7)
-#define AAC_ON_AACQ_MASK	((1<<5)|(1<<6)|(1<<7))
+#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. */
 
@@ -228,6 +232,9 @@ struct aac_interface
 				   u_int32_t arg2, u_int32_t arg3);
 	int	(*aif_get_mailbox)(struct aac_softc *sc, int mb);
 	void	(*aif_set_interrupts)(struct aac_softc *sc, int enable);
+	int (*aif_send_command)(struct aac_softc *sc, struct aac_command *cm);
+	int (*aif_get_outb_queue)(struct aac_softc *sc);
+	void (*aif_set_outb_queue)(struct aac_softc *sc, int index);
 };
 extern struct aac_interface	aac_rx_interface;
 extern struct aac_interface	aac_sa_interface;
@@ -248,6 +255,9 @@ extern struct aac_interface	aac_rkt_interface;
 					0))
 #define AAC_UNMASK_INTERRUPTS(sc)	((sc)->aac_if.aif_set_interrupts((sc), \
 					1))
+#define AAC_SEND_COMMAND(sc, cm)	((sc)->aac_if.aif_send_command((sc), (cm)))
+#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)
@@ -317,6 +327,11 @@ struct aac_softc
 	TAILQ_HEAD(,aac_command) aac_ready;	/* commands on hold for
 						 * controller resources */
 	TAILQ_HEAD(,aac_command) aac_busy;
+	TAILQ_HEAD(,aac_command) aac_aif;
+#if 0
+	TAILQ_HEAD(,aac_command) aac_norm;
+#endif
+	TAILQ_HEAD(,aac_event)	aac_ev_cmfree;
 	struct bio_queue_head	aac_bioq;
 	struct aac_queue_table	*aac_queues;
 	struct aac_queue_entry	*aac_qentries[AAC_QUEUE_COUNT];
@@ -366,13 +381,39 @@ struct aac_softc
 #define	AAC_FLAGS_NO4GB		(1 << 6)	/* Can't access host mem >2GB */
 #define	AAC_FLAGS_256FIBS	(1 << 7)	/* Can only do 256 commands */
 #define	AAC_FLAGS_BROKEN_MEMMAP (1 << 8)	/* Broken HostPhysMemPages */
+#define AAC_FLAGS_SLAVE	(1 << 9)
+#define AAC_FLAGS_MASTER	(1 << 10)
+#define AAC_FLAGS_NEW_COMM	(1 << 11)	/* New comm. interface supported */
+#define AAC_FLAGS_RAW_IO	(1 << 12)	/* Raw I/O interface */
+#define AAC_FLAGS_ARRAY_64BIT	(1 << 13)	/* 64-bit array size */
 
 	u_int32_t		supported_options;
-	int			aac_max_fibs;
 	u_int32_t		scsi_method_id;
 	TAILQ_HEAD(,aac_sim)	aac_sim_tqh;
+
+	u_int32_t	aac_max_fibs;           /* max. FIB count */
+	u_int32_t	aac_max_fibs_alloc;		/* max. alloc. per alloc_commands() */
+	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) */
 };
 
+/*
+ * Event callback mechanism for the driver
+ */
+#define AAC_EVENT_NONE		0x00
+#define AAC_EVENT_CMFREE	0x01
+#define	AAC_EVENT_MASK		0xff
+#define AAC_EVENT_REPEAT	0x100
+
+typedef void aac_event_cb_t(struct aac_softc *sc, struct aac_event *event,
+    void *arg);
+struct aac_event {
+	TAILQ_ENTRY(aac_event)	ev_links;
+	int			ev_type;
+	aac_event_cb_t		*ev_callback;
+	void			*ev_arg;
+};
 
 /*
  * Public functions
@@ -383,7 +424,8 @@ extern int		aac_detach(device_t dev);
 extern int		aac_shutdown(device_t dev);
 extern int		aac_suspend(device_t dev); 
 extern int		aac_resume(device_t dev);
-extern void		aac_intr(void *arg);
+extern void		aac_new_intr(void *arg);
+extern void		aac_fast_intr(void *arg);
 extern void		aac_submit_bio(struct bio *bp);
 extern void		aac_biodone(struct bio *bp);
 extern void		aac_startio(struct aac_softc *sc);
@@ -393,6 +435,8 @@ extern void		aac_release_command(struct aac_command *cm);
 extern int		aac_sync_fib(struct aac_softc *sc, u_int32_t command,
 				     u_int32_t xferstate, struct aac_fib *fib,
 				     u_int16_t datasize);
+extern void		aac_add_event(struct aac_softc *sc, struct aac_event
+				      *event);
 
 /*
  * Debugging levels:
@@ -571,7 +615,7 @@ static __inline int
 aac_alloc_sync_fib(struct aac_softc *sc, struct aac_fib **fib)
 {
 
-	mtx_lock(&sc->aac_io_lock);
+	mtx_assert(&sc->aac_io_lock, MA_OWNED);
 	*fib = &sc->aac_common->ac_sync_fib;
 	return (0);
 }
@@ -580,6 +624,6 @@ static __inline void
 aac_release_sync_fib(struct aac_softc *sc)
 {
 
-	mtx_unlock(&sc->aac_io_lock);
+	mtx_assert(&sc->aac_io_lock, MA_OWNED);
 }