--- old/usr/src/pkg/manifests/driver-storage-aac.mf	Thu Nov  1 14:48:22 2012
+++ new/usr/src/pkg/manifests/driver-storage-aac.mf	Thu Nov  1 14:48:22 2012
@@ -46,7 +46,11 @@
     alias=pci9005,285 \
     alias=pci9005,286 \
     alias=pciex9005,285 \
-    alias=pciex9005,286
+    alias=pciex9005,286 \
+    alias=pciex9005,28b \
+    alias=pciex9005,28c \
+    alias=pciex9005,28d \
+    alias=pciex9005,28f
 file path=kernel/drv/$(ARCH64)/aac group=sys
 $(i386_ONLY)file path=kernel/drv/aac group=sys
 file path=kernel/drv/aac.conf group=sys \
--- old/usr/src/uts/common/io/aac/README	Thu Nov  1 14:48:23 2012
+++ new/usr/src/uts/common/io/aac/README	Thu Nov  1 14:48:22 2012
@@ -23,6 +23,9 @@
 # Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
+
+# XXX KEBE SAYS UPDATE ME! 
+
 aac driver 2.0
 ================
 The Solaris aac driver enhancement updates the Solaris aac 1.6 driver
--- old/usr/src/uts/common/io/aac/THIRDPARTYLICENSE	Thu Nov  1 14:48:24 2012
+++ new/usr/src/uts/common/io/aac/THIRDPARTYLICENSE	Thu Nov  1 14:48:23 2012
@@ -1,5 +1,5 @@
- * Copyright 2005-06 Adaptec, Inc.
- * Copyright (c) 2005-06 Adaptec Inc., Achim Leubner
+ * Copyright (c) 2010-12 PMC-Sierra, Inc.
+ * Copyright (c) 2005-10 Adaptec Inc., Achim Leubner
  * Copyright (c) 2000 Michael Smith
  * Copyright (c) 2001 Scott Long
  * Copyright (c) 2000 BSDi
--- old/usr/src/uts/common/io/aac/aac.c	Thu Nov  1 14:48:24 2012
+++ new/usr/src/uts/common/io/aac/aac.c	Thu Nov  1 14:48:24 2012
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  */
 
 /*
- * Copyright 2005-08 Adaptec, Inc.
- * Copyright (c) 2005-08 Adaptec Inc., Achim Leubner
+ * Copyright (c) 2010-12 PMC-Sierra, Inc.
+ * Copyright (c) 2005-10 Adaptec Inc., Achim Leubner
  * Copyright (c) 2000 Michael Smith
  * Copyright (c) 2001 Scott Long
  * Copyright (c) 2000 BSDi
@@ -31,6 +32,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+#pragma ident	"@(#)aac.c	1.19	08/01/29 SMI"
+
 #include <sys/modctl.h>
 #include <sys/conf.h>
 #include <sys/cmn_err.h>
@@ -43,17 +46,33 @@
 #include <sys/ksynch.h>
 #include <sys/sunddi.h>
 #include <sys/byteorder.h>
+#include <sys/utsname.h>
 #include "aac_regs.h"
 #include "aac.h"
 
 /*
- * FMA header files
+ * FMA header files, macros
  */
 #include <sys/ddifm.h>
 #include <sys/fm/protocol.h>
 #include <sys/fm/util.h>
 #include <sys/fm/io/ddi.h>
+#ifndef DDI_FM_DEVICE
+#define DDI_FM_DEVICE			"device"
+#define DDI_FM_DEVICE_NO_RESPONSE	"no_response"
+#define ddi_fm_acc_err_clear(a, b)
+#endif
+#define aac_fm_service_impact(a, b) { \
+	if (aac_fm_valid) \
+		ddi_fm_service_impact(a, b); \
+	}
+#define aac_fm_acc_err_clear(a, b) { \
+	if (aac_fm_valid) \
+		ddi_fm_acc_err_clear(a, b); \
+	}
 
+char _depends_on[] = "misc/scsi";
+
 /*
  * For minor nodes created by the SCSA framework, minor numbers are
  * formed by left-shifting instance by INST_MINOR_SHIFT and OR in a
@@ -79,10 +98,6 @@
 				&(softs)->containers[(t)].dev : \
 				((t) < AAC_MAX_DEV(softs)) ? \
 				&(softs)->nondasds[AAC_PD(t)].dev : NULL)
-#define	AAC_DEVCFG_BEGIN(softs, tgt) \
-				aac_devcfg((softs), (tgt), 1)
-#define	AAC_DEVCFG_END(softs, tgt) \
-				aac_devcfg((softs), (tgt), 0)
 #define	PKT2AC(pkt)		((struct aac_cmd *)(pkt)->pkt_ha_private)
 #define	AAC_BUSYWAIT(cond, timeout /* in millisecond */) { \
 		if (!(cond)) { \
@@ -148,28 +163,28 @@
 #define	AAC_IS_Q_EMPTY(q)	((q)->q_head == NULL)
 #define	AAC_CMDQ(acp)		(!((acp)->flags & AAC_CMD_SYNC))
 
-#define	PCI_MEM_GET32(softs, off) \
-	ddi_get32((softs)->pci_mem_handle, \
-	    (void *)((softs)->pci_mem_base_vaddr + (off)))
-#define	PCI_MEM_PUT32(softs, off, val) \
-	ddi_put32((softs)->pci_mem_handle, \
-	    (void *)((softs)->pci_mem_base_vaddr + (off)), \
+#define	PCI_MEM_GET32(softs, i, off) \
+	ddi_get32((softs)->pci_mem_handle[i], \
+	    (uint32_t *)((softs)->pci_mem_base_vaddr[i] + (off)))
+#define	PCI_MEM_PUT32(softs, i, off, val) \
+	ddi_put32((softs)->pci_mem_handle[i], \
+	    (uint32_t *)((softs)->pci_mem_base_vaddr[i] + (off)), \
 	    (uint32_t)(val))
-#define	PCI_MEM_GET16(softs, off) \
-	ddi_get16((softs)->pci_mem_handle, \
-	(void *)((softs)->pci_mem_base_vaddr + (off)))
-#define	PCI_MEM_PUT16(softs, off, val) \
-	ddi_put16((softs)->pci_mem_handle, \
-	(void *)((softs)->pci_mem_base_vaddr + (off)), (uint16_t)(val))
-/* Write host data at valp to device mem[off] repeatedly count times */
-#define	PCI_MEM_REP_PUT8(softs, off, valp, count) \
-	ddi_rep_put8((softs)->pci_mem_handle, (uint8_t *)(valp), \
-	    (uint8_t *)((softs)->pci_mem_base_vaddr + (off)), \
+#define	PCI_MEM_GET16(softs, i, off) \
+	ddi_get16((softs)->pci_mem_handle[i], \
+	(uint16_t *)((softs)->pci_mem_base_vaddr[i] + (off)))
+#define	PCI_MEM_PUT16(softs, i, off, val) \
+	ddi_put16((softs)->pci_mem_handle[i], \
+	(uint16_t *)((softs)->pci_mem_base_vaddr[i] + (off)), (uint16_t)(val))
+/* Write host data at valp to device mem[i][off] repeatedly count times */
+#define	PCI_MEM_REP_PUT8(softs, i, off, valp, count) \
+	ddi_rep_put8((softs)->pci_mem_handle[i], (uint8_t *)(valp), \
+	    (uint8_t *)((softs)->pci_mem_base_vaddr[i] + (off)), \
 	    count, DDI_DEV_AUTOINCR)
-/* Read device data at mem[off] to host addr valp repeatedly count times */
-#define	PCI_MEM_REP_GET8(softs, off, valp, count) \
-	ddi_rep_get8((softs)->pci_mem_handle, (uint8_t *)(valp), \
-	    (uint8_t *)((softs)->pci_mem_base_vaddr + (off)), \
+/* Read device data at mem[i][off] to host addr valp repeatedly count times */
+#define	PCI_MEM_REP_GET8(softs, i, off, valp, count) \
+	ddi_rep_get8((softs)->pci_mem_handle[i], (uint8_t *)(valp), \
+	    (uint8_t *)((softs)->pci_mem_base_vaddr[i] + (off)), \
 	    count, DDI_DEV_AUTOINCR)
 #define	AAC_GET_FIELD8(acc, d, s, field) \
 	(d)->field = ddi_get8(acc, (uint8_t *)&(s)->field)
@@ -184,23 +199,18 @@
 	ddi_rep_get32((acc), (uint32_t *)&(d)->field, \
 	    (uint32_t *)&(s)->field, (r), DDI_DEV_AUTOINCR)
 
-#define	AAC_ENABLE_INTR(softs) { \
-		if (softs->flags & AAC_FLAGS_NEW_COMM) \
-			PCI_MEM_PUT32(softs, AAC_OIMR, ~AAC_DB_INTR_NEW); \
-		else \
-			PCI_MEM_PUT32(softs, AAC_OIMR, ~AAC_DB_INTR_BITS); \
-		softs->state |= AAC_STATE_INTR; \
-	}
+#define	AAC_OUTB_GET(softs)		PCI_MEM_GET32(softs, 0, AAC_OQUE)
+#define	AAC_OUTB_SET(softs, val)	PCI_MEM_PUT32(softs, 0, AAC_OQUE, val)
 
-#define	AAC_DISABLE_INTR(softs)	{ \
-		PCI_MEM_PUT32(softs, AAC_OIMR, ~0); \
-		softs->state &= ~AAC_STATE_INTR; \
-	}
-#define	AAC_STATUS_CLR(softs, mask)	PCI_MEM_PUT32(softs, AAC_ODBR, mask)
-#define	AAC_STATUS_GET(softs)		PCI_MEM_GET32(softs, AAC_ODBR)
-#define	AAC_NOTIFY(softs, val)		PCI_MEM_PUT32(softs, AAC_IDBR, val)
-#define	AAC_OUTB_GET(softs)		PCI_MEM_GET32(softs, AAC_OQUE)
-#define	AAC_OUTB_SET(softs, val)	PCI_MEM_PUT32(softs, AAC_OQUE, val)
+#define	AAC_SET_INTR(softs, enable)	\
+	((softs)->aac_if.aif_set_intr((softs), (enable)))
+#define	AAC_STATUS_CLR(softs, mask)	\
+	((softs)->aac_if.aif_status_clr((softs), (mask)))
+#define	AAC_STATUS_GET(softs)	\
+	((softs)->aac_if.aif_status_get(softs))
+#define	AAC_NOTIFY(softs, val)	\
+	((softs)->aac_if.aif_notify((softs), (val)))
+
 #define	AAC_FWSTATUS_GET(softs)	\
 	((softs)->aac_if.aif_get_fwstatus(softs))
 #define	AAC_MAILBOX_GET(softs, mb) \
@@ -208,8 +218,9 @@
 #define	AAC_MAILBOX_SET(softs, cmd, arg0, arg1, arg2, arg3) \
 	((softs)->aac_if.aif_set_mailbox((softs), (cmd), \
 	    (arg0), (arg1), (arg2), (arg3)))
+#define	AAC_SEND_COMMAND(softs, slotp) \
+	((softs)->aac_if.aif_send_command((softs), (slotp)))
 
-#define	AAC_MGT_SLOT_NUM	2
 #define	AAC_THROTTLE_DRAIN	-1
 
 #define	AAC_QUIESCE_TICK	1	/* 1 second */
@@ -220,22 +231,34 @@
 /* Poll time for aac_do_poll_io() */
 #define	AAC_POLL_TIME		60	/* 60 seconds */
 
-/* IOP reset */
-#define	AAC_IOP_RESET_SUCCEED		0	/* IOP reset succeed */
-#define	AAC_IOP_RESET_FAILED		-1	/* IOP reset failed */
-#define	AAC_IOP_RESET_ABNORMAL		-2	/* Reset operation abnormal */
-
 /*
  * Hardware access functions
  */
+static void aac_rx_set_intr(struct aac_softstate *, int);
+static void aac_rx_status_clr(struct aac_softstate *, int);
+static int aac_rx_status_get(struct aac_softstate *);
+static void aac_rx_notify(struct aac_softstate *, int);
 static int aac_rx_get_fwstatus(struct aac_softstate *);
 static int aac_rx_get_mailbox(struct aac_softstate *, int);
 static void aac_rx_set_mailbox(struct aac_softstate *, uint32_t, uint32_t,
     uint32_t, uint32_t, uint32_t);
+static int aac_rx_send_command(struct aac_softstate *, struct aac_slot *);
 static int aac_rkt_get_fwstatus(struct aac_softstate *);
 static int aac_rkt_get_mailbox(struct aac_softstate *, int);
 static void aac_rkt_set_mailbox(struct aac_softstate *, uint32_t, uint32_t,
     uint32_t, uint32_t, uint32_t);
+static void aac_src_set_intr(struct aac_softstate *, int);
+static void aac_src_status_clr(struct aac_softstate *, int);
+static int aac_src_status_get(struct aac_softstate *);
+static void aac_src_notify(struct aac_softstate *, int);
+static int aac_src_get_fwstatus(struct aac_softstate *);
+static int aac_src_get_mailbox(struct aac_softstate *, int);
+static void aac_src_set_mailbox(struct aac_softstate *, uint32_t, uint32_t,
+    uint32_t, uint32_t, uint32_t);
+static int aac_src_send_command(struct aac_softstate *, struct aac_slot *);
+static int aac_srcv_get_mailbox(struct aac_softstate *, int);
+static void aac_srcv_set_mailbox(struct aac_softstate *, uint32_t, uint32_t,
+    uint32_t, uint32_t, uint32_t);
 
 /*
  * SCSA function prototypes
@@ -243,17 +266,10 @@
 static int aac_attach(dev_info_t *, ddi_attach_cmd_t);
 static int aac_detach(dev_info_t *, ddi_detach_cmd_t);
 static int aac_reset(dev_info_t *, ddi_reset_cmd_t);
-static int aac_quiesce(dev_info_t *);
-static int aac_getinfo(dev_info_t *, ddi_info_cmd_t, void *, void **);
 
 /*
  * Interrupt handler functions
  */
-static int aac_query_intrs(struct aac_softstate *, int);
-static int aac_add_intrs(struct aac_softstate *);
-static void aac_remove_intrs(struct aac_softstate *);
-static int aac_enable_intrs(struct aac_softstate *);
-static int aac_disable_intrs(struct aac_softstate *);
 static uint_t aac_intr_old(caddr_t);
 static uint_t aac_intr_new(caddr_t);
 static uint_t aac_softintr(caddr_t);
@@ -275,7 +291,7 @@
  * Sync FIB operation functions
  */
 int aac_sync_mbcommand(struct aac_softstate *, uint32_t, uint32_t,
-    uint32_t, uint32_t, uint32_t, uint32_t *);
+    uint32_t, uint32_t, uint32_t, uint32_t *, uint32_t *);
 static int aac_sync_fib(struct aac_softstate *, uint16_t, uint16_t);
 
 /*
@@ -307,24 +323,24 @@
 /*
  * Internal functions
  */
-static void aac_cmd_fib_header(struct aac_softstate *, struct aac_cmd *,
-    uint16_t);
+static void aac_cmd_fib_header(struct aac_softstate *, struct aac_slot *,
+    uint16_t, uint16_t);
 static void aac_cmd_fib_rawio(struct aac_softstate *, struct aac_cmd *);
+static void aac_cmd_fib_rawio2(struct aac_softstate *, struct aac_cmd *);
+static uint_t aac_convert_sgraw2(struct aac_softstate *, struct aac_cmd *, 
+								 uint_t, uint_t, uint_t, uint16_t *);
 static void aac_cmd_fib_brw64(struct aac_softstate *, struct aac_cmd *);
 static void aac_cmd_fib_brw(struct aac_softstate *, struct aac_cmd *);
 static void aac_cmd_fib_sync(struct aac_softstate *, struct aac_cmd *);
+static void aac_cmd_aif_request(struct aac_softstate *, struct aac_cmd *);
+static void aac_aifreq_complete(struct aac_softstate *, struct aac_cmd *);
 static void aac_cmd_fib_scsi32(struct aac_softstate *, struct aac_cmd *);
 static void aac_cmd_fib_scsi64(struct aac_softstate *, struct aac_cmd *);
-static void aac_cmd_fib_startstop(struct aac_softstate *, struct aac_cmd *);
 static void aac_start_waiting_io(struct aac_softstate *);
 static void aac_drain_comp_q(struct aac_softstate *);
 int aac_do_io(struct aac_softstate *, struct aac_cmd *);
-static int aac_sync_fib_slot_bind(struct aac_softstate *, struct aac_cmd *);
-static void aac_sync_fib_slot_release(struct aac_softstate *, struct aac_cmd *);
-static void aac_start_io(struct aac_softstate *, struct aac_cmd *);
 static int aac_do_poll_io(struct aac_softstate *, struct aac_cmd *);
 static int aac_do_sync_io(struct aac_softstate *, struct aac_cmd *);
-static int aac_send_command(struct aac_softstate *, struct aac_slot *);
 static void aac_cmd_timeout(struct aac_softstate *, struct aac_cmd *);
 static int aac_dma_sync_ac(struct aac_cmd *);
 static int aac_shutdown(struct aac_softstate *);
@@ -334,20 +350,18 @@
 static void aac_unhold_bus(struct aac_softstate *, int);
 static void aac_set_throttle(struct aac_softstate *, struct aac_device *,
     int, int);
+static int aac_atoi(char **pptr);
+static void aac_config_pd(void *);
 
 /*
  * Adapter Initiated FIB handling function
  */
-static void aac_save_aif(struct aac_softstate *, ddi_acc_handle_t,
-    struct aac_fib *, int);
-static int aac_handle_aif(struct aac_softstate *, struct aac_aif_command *);
+static int aac_handle_aif(struct aac_softstate *, struct aac_fib *);
 
 /*
- * Event handling related functions
+ * Timeout handling thread function
  */
-static void aac_timer(void *);
-static void aac_event_thread(struct aac_softstate *);
-static void aac_event_disp(struct aac_softstate *, int);
+static void aac_daemon(void *);
 
 /*
  * IOCTL interface related functions
@@ -365,19 +379,13 @@
 static int aac_fm_error_cb(dev_info_t *, ddi_fm_error_t *, const void *);
 int aac_check_acc_handle(ddi_acc_handle_t);
 int aac_check_dma_handle(ddi_dma_handle_t);
-void aac_fm_ereport(struct aac_softstate *, char *);
+void aac_fm_ereport(struct aac_softstate *, char *, int);
 
-/*
- * Auto enumeration functions
- */
-static dev_info_t *aac_find_child(struct aac_softstate *, uint16_t, uint8_t);
 static int aac_tran_bus_config(dev_info_t *, uint_t, ddi_bus_config_op_t,
     void *, dev_info_t **);
-static int aac_handle_dr(struct aac_softstate *, int, int, int);
+static int aac_dr_event(struct aac_softstate *, int, int, int);
 
-extern pri_t minclsyspri;
-
-#ifdef DEBUG
+#ifdef AAC_DEBUG
 /*
  * UART	debug output support
  */
@@ -390,8 +398,6 @@
 #define	AAC_FW_DBG_BLED_OFFSET		0x08
 
 static int aac_get_fw_debug_buffer(struct aac_softstate *);
-static void aac_print_scmd(struct aac_softstate *, struct aac_cmd *);
-static void aac_print_aif(struct aac_softstate *, struct aac_aif_command *);
 
 static char aac_prt_buf[AAC_PRINT_BUFFER_SIZE];
 static char aac_fmt[] = " %s";
@@ -404,8 +410,8 @@
  */
 uint32_t aac_debug_flags =
 /*    AACDB_FLAGS_KERNEL_PRINT | */
-/*    AACDB_FLAGS_FW_PRINT |	*/
-/*    AACDB_FLAGS_MISC |	*/
+    AACDB_FLAGS_FW_PRINT |	
+    AACDB_FLAGS_MISC |	
 /*    AACDB_FLAGS_FUNC1 |	*/
 /*    AACDB_FLAGS_FUNC2 |	*/
 /*    AACDB_FLAGS_SCMD |	*/
@@ -413,16 +419,22 @@
 /*    AACDB_FLAGS_FIB |		*/
 /*    AACDB_FLAGS_IOCTL |	*/
 0;
-uint32_t aac_debug_fib_flags =
-/*    AACDB_FLAGS_FIB_RW |	*/
-/*    AACDB_FLAGS_FIB_IOCTL |	*/
-/*    AACDB_FLAGS_FIB_SRB |	*/
-/*    AACDB_FLAGS_FIB_SYNC |	*/
-/*    AACDB_FLAGS_FIB_HEADER |	*/
-/*    AACDB_FLAGS_FIB_TIMEOUT |	*/
-0;
+#endif /* AAC_DEBUG */
 
-#endif /* DEBUG */
+#ifdef AAC_DEBUG_ALL
+#ifndef GETG0COUNT
+#define GETG0COUNT(cdb)		(cdb)->g0_count0
+#endif
+#ifndef GETG1COUNT
+#define GETG1COUNT(cdb)		(((cdb)->g1_count1 << 8) + ((cdb)->g1_count0))
+#endif
+#ifndef GETG4COUNT
+#define GETG4COUNT(cdb)		(((cdb)->g4_count3 << 24) + \
+	((cdb)->g4_count2 << 16) + ((cdb)->g4_count1 << 8) + ((cdb)->g4_count0))
+#endif
+static void aac_print_scmd(struct aac_softstate *, struct aac_cmd *);
+static void aac_print_aif(struct aac_softstate *, struct aac_aif_command *);
+#endif /* AAC_DEBUG_ALL */
 
 static struct cb_ops aac_cb_ops = {
 	aac_open,	/* open */
@@ -448,7 +460,7 @@
 static struct dev_ops aac_dev_ops = {
 	DEVO_REV,
 	0,
-	aac_getinfo,
+	nodev,
 	nulldev,
 	nulldev,
 	aac_attach,
@@ -456,8 +468,7 @@
 	aac_reset,
 	&aac_cb_ops,
 	NULL,
-	NULL,
-	aac_quiesce,
+	NULL
 };
 
 static struct modldrv aac_modldrv = {
@@ -611,9 +622,14 @@
  * Hardware access functions for i960 based cards
  */
 static struct aac_interface aac_rx_interface = {
+	aac_rx_set_intr,
+	aac_rx_status_clr,
+	aac_rx_status_get,
+	aac_rx_notify,
 	aac_rx_get_fwstatus,
 	aac_rx_get_mailbox,
-	aac_rx_set_mailbox
+	aac_rx_set_mailbox,
+	aac_rx_send_command
 };
 
 /*
@@ -620,13 +636,46 @@
  * Hardware access functions for Rocket based cards
  */
 static struct aac_interface aac_rkt_interface = {
+	aac_rx_set_intr,
+	aac_rx_status_clr,
+	aac_rx_status_get,
+	aac_rx_notify,
 	aac_rkt_get_fwstatus,
 	aac_rkt_get_mailbox,
-	aac_rkt_set_mailbox
+	aac_rkt_set_mailbox,
+	aac_rx_send_command
 };
 
+/*
+ * Hardware access functions for PMC SRC based cards
+ */
+static struct aac_interface aac_src_interface = {
+	aac_src_set_intr,
+	aac_src_status_clr,
+	aac_src_status_get,
+	aac_src_notify,
+	aac_src_get_fwstatus,
+	aac_src_get_mailbox,
+	aac_src_set_mailbox,
+	aac_src_send_command
+};
+
+/*
+ * Hardware access functions for PMC SRCv based cards
+ */
+static struct aac_interface aac_srcv_interface = {
+	aac_src_set_intr,
+	aac_src_status_clr,
+	aac_src_status_get,
+	aac_src_notify,
+	aac_src_get_fwstatus,
+	aac_srcv_get_mailbox,
+	aac_srcv_set_mailbox,
+	aac_src_send_command
+};
+
 ddi_device_acc_attr_t aac_acc_attr = {
-	DDI_DEVICE_ATTR_V1,
+	DDI_DEVICE_ATTR_V0,
 	DDI_STRUCTURE_LE_ACC,
 	DDI_STRICTORDER_ACC,
 	DDI_DEFAULT_ACC
@@ -664,8 +713,17 @@
 	0		/* DMA transfer flags */
 };
 
+struct aac_drinfo {
+	struct aac_softstate *softs;
+	int tgt;
+	int lun;
+	int event;
+};
+
 static int aac_tick = AAC_DEFAULT_TICK;	/* tick for the internal timer */
 static uint32_t aac_timebase = 0;	/* internal timer in seconds */
+static uint32_t aac_sync_time = 0;	/* next time to sync. with firmware */
+static int aac_fm_valid = 0;		/* FMA support */
 
 /*
  * Warlock directives
@@ -687,6 +745,7 @@
     aac_sg_table aac_srb))
 _NOTE(SCHEME_PROTECTS_DATA("unique to sync fib and cdb", scsi_inquiry))
 _NOTE(SCHEME_PROTECTS_DATA("stable data", scsi_device scsi_address))
+_NOTE(SCHEME_PROTECTS_DATA("unique to dr event", aac_drinfo))
 _NOTE(SCHEME_PROTECTS_DATA("unique to scsi_transport", buf))
 
 int
@@ -694,7 +753,7 @@
 {
 	int rval = 0;
 
-#ifdef DEBUG
+#ifdef AAC_DEBUG
 	mutex_init(&aac_prt_mutex, NULL, MUTEX_DRIVER, NULL);
 #endif
 	DBCALLED(NULL, 1);
@@ -717,7 +776,7 @@
 
 error:
 	AACDB_PRINT(NULL, CE_WARN, "Mod init error!");
-#ifdef DEBUG
+#ifdef AAC_DEBUG
 	mutex_destroy(&aac_prt_mutex);
 #endif
 	return (rval);
@@ -746,7 +805,7 @@
 
 	scsi_hba_fini(&aac_modlinkage);
 	ddi_soft_state_fini((void *)&aac_softstatep);
-#ifdef DEBUG
+#ifdef AAC_DEBUG
 	mutex_destroy(&aac_prt_mutex);
 #endif
 	return (0);
@@ -759,7 +818,7 @@
 static int
 aac_attach(dev_info_t *dip, ddi_attach_cmd_t cmd)
 {
-	int instance, i;
+	int instance, i, major, minor;
 	struct aac_softstate *softs = NULL;
 	int attach_state = 0;
 	char *data;
@@ -789,17 +848,11 @@
 	softs->devinfo_p = dip;
 	softs->buf_dma_attr = softs->addr_dma_attr = aac_dma_attr;
 	softs->addr_dma_attr.dma_attr_granular = 1;
-	softs->acc_attr = aac_acc_attr;
-	softs->reg_attr = aac_acc_attr;
 	softs->card = AAC_UNKNOWN_CARD;
-#ifdef DEBUG
+#ifdef AAC_DEBUG
 	softs->debug_flags = aac_debug_flags;
-	softs->debug_fib_flags = aac_debug_fib_flags;
 #endif
 
-	/* Initialize FMA */
-	aac_fm_init(softs);
-
 	/* Check the card type */
 	if (aac_check_card_type(softs) == AACERR) {
 		AACDB_PRINT(softs, CE_WARN, "Card not supported");
@@ -808,85 +861,159 @@
 	/* We have found the right card and everything is OK */
 	attach_state |= AAC_ATTACH_CARD_DETECTED;
 
+	/*
+	 * Initialize FMA
+	 */
+#ifdef FORCE_FM_SUPPORT
+	aac_fm_valid = 1;
+#else
+	aac_fm_valid = 0;
+	/* check OS version */
+	data = (char *)utsname.release;
+	major = aac_atoi(&data);
+	if (*data == '.') {
+		data++;
+		minor = aac_atoi(&data);
+		/* enable FMA support in Solaris 11 first */
+		if (major >= 5 && minor >= 11)
+			aac_fm_valid = 1;
+	}
+#endif
+	aac_fm_init(softs);
+
 	/* Map PCI mem space */
 	if (ddi_regs_map_setup(dip, 1,
-	    (caddr_t *)&softs->pci_mem_base_vaddr, 0,
-	    softs->map_size_min, &softs->reg_attr,
-	    &softs->pci_mem_handle) != DDI_SUCCESS)
+	    (caddr_t *)&softs->pci_mem_base_vaddr[0], 0,
+	    softs->map_size_min, &aac_acc_attr,
+	    &softs->pci_mem_handle[0]) != DDI_SUCCESS)
 		goto error;
+	if (softs->hwif == AAC_HWIF_SRC) {
+		/*
+		 * Map whole space because map_size_min is not enough
+		 * for NEMER/ARK family with APRE
+		 */
+		if (ddi_regs_map_setup(dip, 2,
+		    (caddr_t *)&softs->pci_mem_base_vaddr[1], 0,
+		    softs->hwif == AAC_HWIF_SRC ? AAC_MAP_SIZE_MIN_SRC_BAR1 : AAC_MAP_SIZE_MIN_SRCV_BAR1, 
+			&aac_acc_attr,
+		    &softs->pci_mem_handle[1]) != DDI_SUCCESS) {
+			ddi_regs_map_free(&softs->pci_mem_handle[0]);
+			goto error;
+		}
+	} else {
+		/* Setup BAR1 related values */
+		softs->pci_mem_handle[1] = softs->pci_mem_handle[0];
+		softs->pci_mem_base_vaddr[1] = softs->pci_mem_base_vaddr[0];
+	}
 
 	softs->map_size = softs->map_size_min;
 	attach_state |= AAC_ATTACH_PCI_MEM_MAPPED;
 
-	AAC_DISABLE_INTR(softs);
+	AAC_SET_INTR(softs, 0);
 
-	/* Init mutexes and condvars */
-	mutex_init(&softs->io_lock, NULL, MUTEX_DRIVER,
-	    DDI_INTR_PRI(softs->intr_pri));
-	mutex_init(&softs->q_comp_mutex, NULL, MUTEX_DRIVER,
-	    DDI_INTR_PRI(softs->intr_pri));
-	mutex_init(&softs->time_mutex, NULL, MUTEX_DRIVER,
-	    DDI_INTR_PRI(softs->intr_pri));
-	mutex_init(&softs->ev_lock, NULL, MUTEX_DRIVER,
-	    DDI_INTR_PRI(softs->intr_pri));
-	mutex_init(&softs->aifq_mutex, NULL,
-	    MUTEX_DRIVER, DDI_INTR_PRI(softs->intr_pri));
+	if (ddi_intr_hilevel(dip, 0)) {
+		AACDB_PRINT(softs, CE_WARN,
+		    "High level interrupt is not supported!");
+		goto error;
+	}
+
+	/* Init mutexes */
+	if (ddi_get_iblock_cookie(dip, 0, &softs->iblock_cookie) !=
+	    DDI_SUCCESS) {
+		AACDB_PRINT(softs, CE_WARN,
+		    "Can not get interrupt block cookie!");
+		goto error;
+	}
+	mutex_init(&softs->q_comp_mutex, NULL,
+	    MUTEX_DRIVER, (void *)softs->iblock_cookie);
 	cv_init(&softs->event, NULL, CV_DRIVER, NULL);
-	cv_init(&softs->sync_fib_cv, NULL, CV_DRIVER, NULL);
+	mutex_init(&softs->aifq_mutex, NULL,
+	    MUTEX_DRIVER, (void *)softs->iblock_cookie);
+	cv_init(&softs->aifv, NULL, CV_DRIVER, NULL);
 	cv_init(&softs->drain_cv, NULL, CV_DRIVER, NULL);
-	cv_init(&softs->event_wait_cv, NULL, CV_DRIVER, NULL);
-	cv_init(&softs->event_disp_cv, NULL, CV_DRIVER, NULL);
-	cv_init(&softs->aifq_cv, NULL, CV_DRIVER, NULL);
+	mutex_init(&softs->io_lock, NULL, MUTEX_DRIVER,
+	    (void *)softs->iblock_cookie);
 	attach_state |= AAC_ATTACH_KMUTEX_INITED;
 
-	/* Init the cmd queues */
-	for (i = 0; i < AAC_CMDQ_NUM; i++)
-		aac_cmd_initq(&softs->q_wait[i]);
-	aac_cmd_initq(&softs->q_busy);
-	aac_cmd_initq(&softs->q_comp);
-
 	/* Check for legacy device naming support */
-	softs->legacy = 1; /* default to use legacy name */
 	if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0,
 	    "legacy-name-enable", &data) == DDI_SUCCESS)) {
-		if (strcmp(data, "no") == 0) {
-			AACDB_PRINT(softs, CE_NOTE, "legacy-name disabled");
-			softs->legacy = 0;
+		if (strcmp(data, "yes") == 0) {
+			AACDB_PRINT(softs, CE_NOTE, "aac-legacy-name enabled");
+			softs->legacy = 1;
 		}
 		ddi_prop_free(data);
 	}
-
-	/*
-	 * Everything has been set up till now,
-	 * we will do some common attach.
-	 */
-	mutex_enter(&softs->io_lock);
-	if (aac_common_attach(softs) == AACERR) {
-		mutex_exit(&softs->io_lock);
-		goto error;
+	/* Check for sync. transfer mode */
+	if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0,
+	    "enforce-sync-mode", &data) == DDI_SUCCESS)) {
+		if (strcmp(data, "yes") == 0) {
+			AACDB_PRINT(softs, CE_NOTE, "enforce-sync-mode set");
+			softs->sync_mode = 1;
+		}
+		ddi_prop_free(data);
 	}
-	mutex_exit(&softs->io_lock);
-	attach_state |= AAC_ATTACH_COMM_SPACE_SETUP;
-
-	/* Check for buf breakup support */
+	/* Convert S/G table (NEW_COMM_TYPE2) */
 	if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, dip, 0,
-	    "breakup-enable", &data) == DDI_SUCCESS)) {
+	    "disable-sgl-conversion", &data) == DDI_SUCCESS)) {
 		if (strcmp(data, "yes") == 0) {
-			AACDB_PRINT(softs, CE_NOTE, "buf breakup enabled");
-			softs->flags |= AAC_FLAGS_BRKUP;
+			AACDB_PRINT(softs, CE_NOTE, "disable-sgl-conversion set");
+			softs->no_sgl_conv = 1;
 		}
 		ddi_prop_free(data);
 	}
-	softs->dma_max = softs->buf_dma_attr.dma_attr_maxxfer;
-	if (softs->flags & AAC_FLAGS_BRKUP) {
-		softs->dma_max = ddi_prop_get_int(DDI_DEV_T_ANY, dip,
-		    DDI_PROP_DONTPASS, "dma-max", softs->dma_max);
+
+	/* Create a taskq for dealing with dr events, suspend taskq */
+	if ((softs->taskq = ddi_taskq_create(dip, "aac_dr_taskq", 1,
+	    TASKQ_DEFAULTPRI, 0)) == NULL) {
+		AACDB_PRINT(softs, CE_WARN, "ddi_taskq_create failed");
+		goto error;
 	}
+	ddi_taskq_suspend(softs->taskq);
 
+	/*
+	 * Everything has been set up till now (especially taskq and hba_tran
+	 * for auto-enumeration), we will do some common attach.
+	 */
+	if (aac_common_attach(softs) == AACERR)
+		goto error;
+	attach_state |= AAC_ATTACH_COMM_SPACE_SETUP;
+
+	/* Init the cmd queues */
+	for (i = 0; i < AAC_CMDQ_NUM; i++)
+		aac_cmd_initq(&softs->q_wait[i]);
+	aac_cmd_initq(&softs->q_busy);
+	aac_cmd_initq(&softs->q_comp);
+
+	/* allocate and fill the scsi_hba_tran_t structure */
 	if (aac_hba_setup(softs) != AACOK)
 		goto error;
 	attach_state |= AAC_ATTACH_SCSI_TRAN_SETUP;
 
+	/* scsi_hba_tran is now initialized, resume taskq */
+	ddi_taskq_resume(softs->taskq);
+
+	/* Connect interrupt handlers */
+	if (ddi_add_softintr(dip, DDI_SOFTINT_LOW, &softs->softint_id,
+	    NULL, NULL, aac_softintr, (caddr_t)softs) != DDI_SUCCESS) {
+		AACDB_PRINT(softs, CE_WARN,
+		    "Can not setup soft interrupt handler!");
+		goto error;
+	}
+	attach_state |= AAC_ATTACH_SOFT_INTR_SETUP;
+
+	/* Solaris 11 Express: avoid tran_start calls before aac_unhold_bus() */
+	mutex_enter(&softs->io_lock);
+
+	if (ddi_add_intr(dip, 0, &softs->iblock_cookie,
+	    (ddi_idevice_cookie_t *)0,
+	    (softs->flags & AAC_FLAGS_NEW_COMM) ?
+	    aac_intr_new : aac_intr_old, (caddr_t)softs) != DDI_SUCCESS) {
+		AACDB_PRINT(softs, CE_WARN, "Can not setup interrupt handler!");
+		goto error;
+	}
+	attach_state |= AAC_ATTACH_HARD_INTR_SETUP;
+
 	/* Create devctl/scsi nodes for cfgadm */
 	if (ddi_create_minor_node(dip, "devctl", S_IFCHR,
 	    INST2DEVCTL(instance), DDI_NT_SCSI_NEXUS, 0) != DDI_SUCCESS) {
@@ -909,30 +1036,23 @@
 		goto error;
 	}
 
-	/* Common attach is OK, so we are attached! */
-	softs->state |= AAC_STATE_RUN;
-
-	/* Create event thread */
-	softs->fibctx_p = &softs->aifctx;
-	if ((softs->event_thread = thread_create(NULL, 0, aac_event_thread,
-	    softs, 0, &p0, TS_RUN, minclsyspri)) == NULL) {
-		AACDB_PRINT(softs, CE_WARN, "aif thread create failed");
-		softs->state &= ~AAC_STATE_RUN;
-		goto error;
-	}
-
 	aac_unhold_bus(softs, AAC_IOCMD_SYNC | AAC_IOCMD_ASYNC);
+	softs->state = AAC_STATE_RUN;
+	mutex_exit(&softs->io_lock);
 
 	/* Create a thread for command timeout */
-	softs->timeout_id = timeout(aac_timer, (void *)softs,
-	    (aac_tick * drv_usectohz(1000000)));
+	softs->timeout_id = timeout(aac_daemon, (void *)softs,
+	    (60 * drv_usectohz(1000000)));
 
 	/* Common attach is OK, so we are attached! */
+	AAC_SET_INTR(softs, 1);
 	ddi_report_dev(dip);
 	AACDB_PRINT(softs, CE_NOTE, "aac attached ok");
 	return (DDI_SUCCESS);
 
 error:
+	if (softs && softs->taskq)
+		ddi_taskq_destroy(softs->taskq);
 	if (attach_state & AAC_ATTACH_CREATE_SCSI)
 		ddi_remove_minor_node(dip, "scsi");
 	if (attach_state & AAC_ATTACH_CREATE_DEVCTL)
@@ -943,21 +1063,23 @@
 		(void) scsi_hba_detach(dip);
 		scsi_hba_tran_free(AAC_DIP2TRAN(dip));
 	}
+	if (attach_state & AAC_ATTACH_HARD_INTR_SETUP)
+		ddi_remove_intr(dip, 0, softs->iblock_cookie);
+	if (attach_state & AAC_ATTACH_SOFT_INTR_SETUP)
+		ddi_remove_softintr(softs->softint_id);
 	if (attach_state & AAC_ATTACH_KMUTEX_INITED) {
-		mutex_destroy(&softs->io_lock);
 		mutex_destroy(&softs->q_comp_mutex);
-		mutex_destroy(&softs->time_mutex);
-		mutex_destroy(&softs->ev_lock);
-		mutex_destroy(&softs->aifq_mutex);
 		cv_destroy(&softs->event);
-		cv_destroy(&softs->sync_fib_cv);
+		mutex_destroy(&softs->aifq_mutex);
+		cv_destroy(&softs->aifv);
 		cv_destroy(&softs->drain_cv);
-		cv_destroy(&softs->event_wait_cv);
-		cv_destroy(&softs->event_disp_cv);
-		cv_destroy(&softs->aifq_cv);
+		mutex_destroy(&softs->io_lock);
 	}
-	if (attach_state & AAC_ATTACH_PCI_MEM_MAPPED)
-		ddi_regs_map_free(&softs->pci_mem_handle);
+	if (attach_state & AAC_ATTACH_PCI_MEM_MAPPED) {
+		ddi_regs_map_free(&softs->pci_mem_handle[0]);
+		if (softs->hwif == AAC_HWIF_SRC)
+			ddi_regs_map_free(&softs->pci_mem_handle[1]);
+	}
 	aac_fm_fini(softs);
 	if (attach_state & AAC_ATTACH_CARD_DETECTED)
 		softs->card = AACERR;
@@ -984,52 +1106,39 @@
 	}
 
 	mutex_enter(&softs->io_lock);
-	AAC_DISABLE_INTR(softs);
+	AAC_SET_INTR(softs, 0);
 	softs->state = AAC_STATE_STOPPED;
 
+	mutex_exit(&softs->io_lock);
+	(void) untimeout(softs->timeout_id);
+	mutex_enter(&softs->io_lock);
+	softs->timeout_id = 0;
+
+	ddi_taskq_destroy(softs->taskq);
+
 	ddi_remove_minor_node(dip, "aac");
 	ddi_remove_minor_node(dip, "scsi");
 	ddi_remove_minor_node(dip, "devctl");
+
 	mutex_exit(&softs->io_lock);
+	ddi_remove_intr(dip, 0, softs->iblock_cookie);
+	ddi_remove_softintr(softs->softint_id);
 
 	aac_common_detach(softs);
 
-	mutex_enter(&softs->io_lock);
 	(void) scsi_hba_detach(dip);
 	scsi_hba_tran_free(tran);
-	mutex_exit(&softs->io_lock);
 
-	/* Stop timer */
-	mutex_enter(&softs->time_mutex);
-	if (softs->timeout_id) {
-		timeout_id_t tid = softs->timeout_id;
-		softs->timeout_id = 0;
-
-		mutex_exit(&softs->time_mutex);
-		(void) untimeout(tid);
-		mutex_enter(&softs->time_mutex);
-	}
-	mutex_exit(&softs->time_mutex);
-
-	/* Destroy event thread */
-	mutex_enter(&softs->ev_lock);
-	cv_signal(&softs->event_disp_cv);
-	cv_wait(&softs->event_wait_cv, &softs->ev_lock);
-	mutex_exit(&softs->ev_lock);
-
-	cv_destroy(&softs->aifq_cv);
-	cv_destroy(&softs->event_disp_cv);
-	cv_destroy(&softs->event_wait_cv);
-	cv_destroy(&softs->drain_cv);
-	cv_destroy(&softs->sync_fib_cv);
+	mutex_destroy(&softs->q_comp_mutex);
 	cv_destroy(&softs->event);
 	mutex_destroy(&softs->aifq_mutex);
-	mutex_destroy(&softs->ev_lock);
-	mutex_destroy(&softs->time_mutex);
-	mutex_destroy(&softs->q_comp_mutex);
+	cv_destroy(&softs->aifv);
+	cv_destroy(&softs->drain_cv);
 	mutex_destroy(&softs->io_lock);
 
-	ddi_regs_map_free(&softs->pci_mem_handle);
+	ddi_regs_map_free(&softs->pci_mem_handle[0]);
+	if (softs->hwif == AAC_HWIF_SRC)
+		ddi_regs_map_free(&softs->pci_mem_handle[1]);
 	aac_fm_fini(softs);
 	softs->hwif = AAC_HWIF_UNKNOWN;
 	softs->card = AAC_UNKNOWN_CARD;
@@ -1047,7 +1156,6 @@
 	DBCALLED(softs, 1);
 
 	mutex_enter(&softs->io_lock);
-	AAC_DISABLE_INTR(softs);
 	(void) aac_shutdown(softs);
 	mutex_exit(&softs->io_lock);
 
@@ -1055,47 +1163,6 @@
 }
 
 /*
- * quiesce(9E) entry point.
- *
- * This function is called when the system is single-threaded at high
- * PIL with preemption disabled. Therefore, this function must not be
- * blocked.
- *
- * This function returns DDI_SUCCESS on success, or DDI_FAILURE on failure.
- * DDI_FAILURE indicates an error condition and should almost never happen.
- */
-static int
-aac_quiesce(dev_info_t *dip)
-{
-	struct aac_softstate *softs = AAC_DIP2SOFTS(dip);
-
-	if (softs == NULL)
-		return (DDI_FAILURE);
-
-	_NOTE(ASSUMING_PROTECTED(softs->state))
-	AAC_DISABLE_INTR(softs);
-
-	return (DDI_SUCCESS);
-}
-
-/* ARGSUSED */
-static int
-aac_getinfo(dev_info_t *self, ddi_info_cmd_t infocmd, void *arg,
-    void **result)
-{
-	int error = DDI_SUCCESS;
-
-	switch (infocmd) {
-	case DDI_INFO_DEVT2INSTANCE:
-		*result = (void *)(intptr_t)(MINOR2INST(getminor((dev_t)arg)));
-		break;
-	default:
-		error = DDI_FAILURE;
-	}
-	return (error);
-}
-
-/*
  * Bring the controller down to a dormant state and detach all child devices.
  * This function is called before detach or system shutdown.
  * Note: we can assume that the q_wait on the controller is empty, as we
@@ -1104,15 +1171,11 @@
 static int
 aac_shutdown(struct aac_softstate *softs)
 {
-	ddi_acc_handle_t acc;
-	struct aac_close_command *cc;
+	ddi_acc_handle_t acc = softs->sync_slot->fib_acc_handle;
+	struct aac_close_command *cc = (struct aac_close_command *) \
+	    &softs->sync_slot->fibp->data[0];
 	int rval;
 
-	(void) aac_sync_fib_slot_bind(softs, &softs->sync_ac);
-	acc = softs->sync_ac.slotp->fib_acc_handle;
-
-	cc = (struct aac_close_command *)&softs->sync_ac.slotp->fibp->data[0];
-
 	ddi_put32(acc, &cc->Command, VM_CloseAll);
 	ddi_put32(acc, &cc->ContainerId, 0xfffffffful);
 
@@ -1119,7 +1182,6 @@
 	/* Flush all caches, set FW to write through mode */
 	rval = aac_sync_fib(softs, ContainerCommand,
 	    AAC_FIB_SIZEOF(struct aac_close_command));
-	aac_sync_fib_slot_release(softs, &softs->sync_ac);
 
 	AACDB_PRINT(softs, CE_NOTE,
 	    "shutting down aac %s", (rval == AACOK) ? "ok" : "fail");
@@ -1129,27 +1191,28 @@
 static uint_t
 aac_softintr(caddr_t arg)
 {
-	struct aac_softstate *softs = (void *)arg;
+	struct aac_softstate *softs = (struct aac_softstate *)arg;
 
 	if (!AAC_IS_Q_EMPTY(&softs->q_comp)) {
 		aac_drain_comp_q(softs);
+		return (DDI_INTR_CLAIMED);
+	} else {
+		return (DDI_INTR_UNCLAIMED);
 	}
-	return (DDI_INTR_CLAIMED);
 }
 
 /*
  * Setup auto sense data for pkt
  */
-static void
-aac_set_arq_data(struct scsi_pkt *pkt, uchar_t key,
-    uchar_t add_code, uchar_t qual_code, uint64_t info)
+static struct scsi_arq_status *
+aac_set_arq_common(struct scsi_pkt *pkt)
 {
-	struct scsi_arq_status *arqstat = (void *)(pkt->pkt_scbp);
+	struct scsi_arq_status *arqstat;
 
-	*pkt->pkt_scbp = STATUS_CHECK; /* CHECK CONDITION */
-	pkt->pkt_state |= STATE_ARQ_DONE;
+	pkt->pkt_state |= STATE_GOT_STATUS | STATE_ARQ_DONE;
 
-	*(uint8_t *)&arqstat->sts_rqpkt_status = STATUS_GOOD;
+	arqstat = (struct scsi_arq_status *)(pkt->pkt_scbp);
+	arqstat->sts_status.sts_chk = 1; /* CHECK CONDITION */
 	arqstat->sts_rqpkt_reason = CMD_CMPLT;
 	arqstat->sts_rqpkt_resid = 0;
 	arqstat->sts_rqpkt_state =
@@ -1159,6 +1222,32 @@
 	    STATE_XFERRED_DATA;
 	arqstat->sts_rqpkt_statistics = 0;
 
+	return (arqstat);
+}
+
+static void
+aac_copy_arq_data(struct scsi_pkt *pkt, uint8_t *sense_data, int32_t sense_len,
+    ddi_acc_handle_t acc)
+{
+	struct scsi_arq_status *arqstat;
+
+	arqstat = aac_set_arq_common(pkt);
+
+	if (sense_len > sizeof (struct scsi_extended_sense))
+		sense_len = sizeof (struct scsi_extended_sense);
+
+	ddi_rep_get8(acc, (uint8_t *)&arqstat->sts_sensedata,
+	    (uint8_t *)sense_data, sense_len, DDI_DEV_AUTOINCR);
+}
+
+static void
+aac_set_arq_data(struct scsi_pkt *pkt, uchar_t key,
+    uchar_t add_code, uchar_t qual_code, uint64_t info)
+{
+	struct scsi_arq_status *arqstat;
+
+	arqstat = aac_set_arq_common(pkt);
+
 	if (info <= 0xfffffffful) {
 		arqstat->sts_sensedata.es_valid = 1;
 		arqstat->sts_sensedata.es_class = CLASS_EXTENDED_SENSE;
@@ -1207,35 +1296,26 @@
 	union scsi_cdb *cdbp;
 	uint64_t err_blkno;
 
-	cdbp = (void *)acp->pkt->pkt_cdbp;
+	cdbp = (union scsi_cdb *)acp->pkt->pkt_cdbp;
 	err_blkno = AAC_GETGXADDR(acp->cmdlen, cdbp);
 	aac_set_arq_data(acp->pkt, KEY_HARDWARE_ERROR, 0x00, 0x00, err_blkno);
 }
 
 /*
- * Send a command to the adapter in New Comm. interface
+ * Setup auto sense data for UNIT ATTENTION
  */
-static int
-aac_send_command(struct aac_softstate *softs, struct aac_slot *slotp)
+/*ARGSUSED*/
+static void
+aac_set_arq_data_reset(struct aac_softstate *softs, struct aac_cmd *acp)
 {
-	uint32_t index, device;
+	struct aac_container *dvp = (struct aac_container *)acp->dvp;
 
-	index = PCI_MEM_GET32(softs, AAC_IQUE);
-	if (index == 0xffffffffUL) {
-		index = PCI_MEM_GET32(softs, AAC_IQUE);
-		if (index == 0xffffffffUL)
-			return (AACERR);
-	}
+	ASSERT(dvp->dev.type == AAC_DEV_LD);
 
-	device = index;
-	PCI_MEM_PUT32(softs, device,
-	    (uint32_t)(slotp->fib_phyaddr & 0xfffffffful));
-	device += 4;
-	PCI_MEM_PUT32(softs, device, (uint32_t)(slotp->fib_phyaddr >> 32));
-	device += 4;
-	PCI_MEM_PUT32(softs, device, slotp->acp->fib_size);
-	PCI_MEM_PUT32(softs, AAC_IQUE, index);
-	return (AACOK);
+	if (dvp->reset) {
+		dvp->reset = 0;
+		aac_set_arq_data(acp->pkt, KEY_UNIT_ATTENTION, 0x29, 0x02, 0);
+	}
 }
 
 static void
@@ -1245,10 +1325,8 @@
 	int q = AAC_CMDQ(acp);
 
 	if (acp->slotp) { /* outstanding cmd */
-		if (!(acp->flags & AAC_CMD_IN_SYNC_SLOT)) {
-			aac_release_slot(softs, acp->slotp);
-			acp->slotp = NULL;
-		}
+		aac_release_slot(softs, acp->slotp);
+		acp->slotp = NULL;
 		if (dvp) {
 			dvp->ncmds[q]--;
 			if (dvp->throttle[q] == AAC_THROTTLE_DRAIN &&
@@ -1255,61 +1333,41 @@
 			    dvp->ncmds[q] == 0 && q == AAC_CMDQ_ASYNC)
 				aac_set_throttle(softs, dvp, q,
 				    softs->total_slots);
-			/*
-			 * Setup auto sense data for UNIT ATTENTION
-			 * Each lun should generate a unit attention
-			 * condition when reset.
-			 * Phys. drives are treated as logical ones
-			 * during error recovery.
-			 */
-			if (dvp->type == AAC_DEV_LD) {
-				struct aac_container *ctp =
-				    (struct aac_container *)dvp;
-				if (ctp->reset == 0)
-					goto noreset;
-
-				AACDB_PRINT(softs, CE_NOTE,
-				    "Unit attention: reset");
-				ctp->reset = 0;
-				aac_set_arq_data(acp->pkt, KEY_UNIT_ATTENTION,
-				    0x29, 0x02, 0);
-			}
 		}
-noreset:
 		softs->bus_ncmds[q]--;
-		aac_cmd_delete(&softs->q_busy, acp);
+		(void) aac_cmd_delete(&softs->q_busy, acp);
 	} else { /* cmd in waiting queue */
 		aac_cmd_delete(&softs->q_wait[q], acp);
 	}
 
-	if (!(acp->flags & (AAC_CMD_NO_CB | AAC_CMD_NO_INTR))) { /* async IO */
-		mutex_enter(&softs->q_comp_mutex);
-		aac_cmd_enqueue(&softs->q_comp, acp);
-		mutex_exit(&softs->q_comp_mutex);
-	} else if (acp->flags & AAC_CMD_NO_CB) { /* sync IO */
-		cv_broadcast(&softs->event);
+	acp->cur_segment++;
+	if (acp->cur_segment >= acp->segment_cnt) {
+		if (!(acp->flags & (AAC_CMD_NO_CB | AAC_CMD_NO_INTR | AAC_CMD_AIF))) { /* async IO */
+			mutex_enter(&softs->q_comp_mutex);
+			aac_cmd_enqueue(&softs->q_comp, acp);
+			mutex_exit(&softs->q_comp_mutex);
+		} else if (acp->flags & AAC_CMD_NO_CB) { /* sync IO */
+			cv_broadcast(&softs->event);
+		}
+	} else {
+		acp->flags &= AAC_CMD_CONSISTENT | AAC_CMD_DMA_PARTIAL | \
+			AAC_CMD_BUF_READ | AAC_CMD_BUF_WRITE | AAC_CMD_DMA_VALID;
+		acp->timeout = acp->pkt->pkt_time;
+		if (acp->pkt->pkt_flags & FLAG_NOINTR)
+			acp->flags |= AAC_CMD_NO_INTR;
+		aac_do_io(softs, acp);
 	}
 }
 
 static void
-aac_handle_io(struct aac_softstate *softs, int index)
+aac_handle_io(struct aac_softstate *softs, struct aac_slot *slotp, int fast)
 {
-	struct aac_slot *slotp;
 	struct aac_cmd *acp;
-	uint32_t fast;
 
-	fast = index & AAC_SENDERADDR_MASK_FAST_RESPONSE;
-	index >>= 2;
-
 	/* Make sure firmware reported index is valid */
-	ASSERT(index >= 0 && index < softs->total_slots);
-	slotp = &softs->io_slot[index];
-	ASSERT(slotp->index == index);
 	acp = slotp->acp;
-
 	if (acp == NULL || acp->slotp != slotp) {
-		cmn_err(CE_WARN,
-		    "Firmware error: invalid slot index received from FW");
+		AACDB_PRINT(softs, CE_NOTE, "Command already freed, discarding");
 		return;
 	}
 
@@ -1335,23 +1393,105 @@
 			    &slotp->fibp->Header.XferState,
 			    state | AAC_FIBSTATE_DONEADAP);
 			ddi_put32(slotp->fib_acc_handle,
-			    (void *)&slotp->fibp->data[0], ST_OK);
+			    (uint32_t *)&slotp->fibp->data[0], ST_OK);
+			acp->flags |= AAC_CMD_FASTRESP;
 		}
 
 		/* Handle completed ac */
-		acp->ac_comp(softs, acp);
+		if (acp->cur_segment + 1 >= acp->segment_cnt)
+			acp->ac_comp(softs, acp);
 	} else {
-		ddi_fm_service_impact(softs->devinfo_p, DDI_SERVICE_UNAFFECTED);
+		aac_fm_service_impact(softs->devinfo_p, DDI_SERVICE_UNAFFECTED);
 		acp->flags |= AAC_CMD_ERR;
 		if (acp->pkt) {
 			acp->pkt->pkt_reason = CMD_TRAN_ERR;
 			acp->pkt->pkt_statistics = 0;
 		}
+		acp->cur_segment = acp->segment_cnt - 1;
 	}
 	aac_end_io(softs, acp);
 }
 
 /*
+ * Interrupt handler for New Comm. Type1 interface
+ */
+static int
+aac_process_intr_new_type1(struct aac_softstate *softs)
+{
+	struct aac_cmd *acp;
+	uint32_t bellbits, bellbits_shifted, index, handle;
+	int isFastResponse;
+	int our_interrupt = 0;
+
+	bellbits = PCI_MEM_GET32(softs, 0, AAC_SRC_ODBR_R);
+	if (bellbits & AAC_DB_RESPONSE_SENT_NS) {
+		bellbits = AAC_DB_RESPONSE_SENT_NS;
+		/* handle async. status */
+		our_interrupt = 1;
+		index = softs->aac_host_rrq_idx;
+		for (;;) {
+			isFastResponse = 0;
+			/* remove toggle bit (31) */
+			handle = (softs->comm_space->aac_host_rrq[index] & 0x7fffffff);
+			/* check fast response bit (30) */
+			if (handle & 0x40000000) 
+				isFastResponse = 1;
+
+			handle &= 0x0000ffff;
+			if (handle == 0) 
+				break;
+
+			acp = softs->io_slot[handle-1].acp;
+			ASSERT((handle-1) >= 0 && (handle-1) < softs->total_slots);
+			aac_handle_io(softs, &softs->io_slot[handle-1], isFastResponse);
+
+			softs->comm_space->aac_host_rrq[index++] = 0;
+			if (index == softs->aac_max_fibs) 
+				index = 0;
+			softs->aac_host_rrq_idx = index;
+
+			if (acp && (acp->flags & AAC_CMD_AIF)) {
+				if (acp->flags & AAC_CMD_AIF_NOMORE) {
+					kmem_free(acp, sizeof(struct aac_cmd));
+				} else {
+					acp->timeout = AAC_AIF_TIMEOUT;
+					acp->aac_cmd_fib = aac_cmd_aif_request;
+					acp->ac_comp = aac_aifreq_complete;
+					aac_do_io(softs, acp);
+				}
+			}
+		}
+	} else {
+		bellbits_shifted = (bellbits >> AAC_SRC_ODR_SHIFT);
+		if (bellbits_shifted & AAC_DB_AIF_PENDING) {
+			our_interrupt = 1;
+			/* handle AIF */
+			if ((acp = kmem_zalloc(sizeof(struct aac_cmd), KM_NOSLEEP)) != NULL) {
+				acp->timeout = AAC_AIF_TIMEOUT;
+				acp->aac_cmd_fib = aac_cmd_aif_request;
+				acp->ac_comp = aac_aifreq_complete;
+				aac_do_io(softs, acp);
+			}
+		} else if (bellbits_shifted & AAC_DB_SYNC_COMMAND) {
+			if (softs->sync_mode_slot) {
+				our_interrupt = 1;
+				aac_handle_io(softs, softs->sync_mode_slot, isFastResponse);
+				softs->sync_slot_busy = 0;
+			}
+		}
+	}
+	if (our_interrupt) 
+		PCI_MEM_PUT32(softs, 0, AAC_SRC_ODBR_C, bellbits);
+
+    /*
+     * Process waiting cmds before start new ones to
+     * ensure first IOs are serviced first.
+     */
+    aac_start_waiting_io(softs);
+    return (our_interrupt ? AAC_DB_COMMAND_READY:0);
+}
+
+/*
  * Interrupt handler for New Comm. interface
  * New Comm. interface use a different mechanism for interrupt. No explict
  * message queues, and driver need only accesses the mapped PCI mem space to
@@ -1361,21 +1501,25 @@
 aac_process_intr_new(struct aac_softstate *softs)
 {
 	uint32_t index;
+    int fast;
 
 	index = AAC_OUTB_GET(softs);
 	if (index == 0xfffffffful)
 		index = AAC_OUTB_GET(softs);
-	if (aac_check_acc_handle(softs->pci_mem_handle) != DDI_SUCCESS) {
-		ddi_fm_service_impact(softs->devinfo_p, DDI_SERVICE_UNAFFECTED);
-		return (0);
+	if (aac_check_acc_handle(softs->pci_mem_handle[0]) != DDI_SUCCESS) {
+		aac_fm_service_impact(softs->devinfo_p, DDI_SERVICE_UNAFFECTED);
+		return (DDI_INTR_UNCLAIMED);
 	}
 	if (index != 0xfffffffful) {
 		do {
 			if ((index & AAC_SENDERADDR_MASK_AIF) == 0) {
-				aac_handle_io(softs, index);
+				fast= index & AAC_SENDERADDR_MASK_FAST_RESPONSE;
+				index >>= 2;
+				ASSERT(index >= 0 && index < softs->total_slots);
+				aac_handle_io(softs, &softs->io_slot[index], fast);
 			} else if (index != 0xfffffffeul) {
 				struct aac_fib *fibp;	/* FIB in AIF queue */
-				uint16_t fib_size;
+				uint16_t fib_size, fib_size0;
 
 				/*
 				 * 0xfffffffe means that the controller wants
@@ -1384,13 +1528,25 @@
 				 */
 				index &= ~2;
 
-				fibp = (struct aac_fib *)(softs-> \
-				    pci_mem_base_vaddr + index);
-				fib_size = PCI_MEM_GET16(softs, index + \
+				mutex_enter(&softs->aifq_mutex);
+				/*
+				 * Copy AIF from adapter to the empty AIF slot
+				 */
+				fibp = &softs->aifq[softs->aifq_idx].d;
+				fib_size0 = PCI_MEM_GET16(softs, 0, index + \
 				    offsetof(struct aac_fib, Header.Size));
+				fib_size = (fib_size0 > AAC_FIB_SIZE) ?
+				    AAC_FIB_SIZE : fib_size0;
+				PCI_MEM_REP_GET8(softs, 0, index, fibp,
+				    fib_size);
 
-				aac_save_aif(softs, softs->pci_mem_handle,
-				    fibp, fib_size);
+				if (aac_check_acc_handle(softs-> \
+				    pci_mem_handle[0]) == DDI_SUCCESS)
+					(void) aac_handle_aif(softs, fibp);
+				else
+					aac_fm_service_impact(softs->devinfo_p,
+					    DDI_SERVICE_UNAFFECTED);
+				mutex_exit(&softs->aifq_mutex);
 
 				/*
 				 * AIF memory is owned by the adapter, so let it
@@ -1417,11 +1573,18 @@
 static uint_t
 aac_intr_new(caddr_t arg)
 {
-	struct aac_softstate *softs = (void *)arg;
+	struct aac_softstate *softs = (struct aac_softstate *)arg;
+	int status;
 	uint_t rval;
 
 	mutex_enter(&softs->io_lock);
-	if (aac_process_intr_new(softs))
+	if ((softs->flags & AAC_FLAGS_NEW_COMM_TYPE1) ||
+		(softs->flags & AAC_FLAGS_NEW_COMM_TYPE2) ||
+		(softs->flags & AAC_FLAGS_NEW_COMM_TYPE34))
+		status = aac_process_intr_new_type1(softs);
+	else
+		status = aac_process_intr_new(softs);
+	if (status)
 		rval = DDI_INTR_CLAIMED;
 	else
 		rval = DDI_INTR_UNCLAIMED;
@@ -1443,19 +1606,23 @@
 	uint16_t status;
 
 	status = AAC_STATUS_GET(softs);
-	if (aac_check_acc_handle(softs->pci_mem_handle) != DDI_SUCCESS) {
-		ddi_fm_service_impact(softs->devinfo_p, DDI_SERVICE_UNAFFECTED);
+	if (aac_check_acc_handle(softs->pci_mem_handle[0]) != DDI_SUCCESS) {
+		aac_fm_service_impact(softs->devinfo_p, DDI_SERVICE_UNAFFECTED);
 		return (DDI_INTR_UNCLAIMED);
 	}
 	if (status & AAC_DB_RESPONSE_READY) {
-		int slot_idx;
+		int slot_idx, fast;
 
 		/* ACK the intr */
 		AAC_STATUS_CLR(softs, AAC_DB_RESPONSE_READY);
 		(void) AAC_STATUS_GET(softs);
 		while (aac_fib_dequeue(softs, AAC_HOST_NORM_RESP_Q,
-		    &slot_idx) == AACOK)
-			aac_handle_io(softs, slot_idx);
+		    &slot_idx) == AACOK) {
+			fast = slot_idx & AAC_SENDERADDR_MASK_FAST_RESPONSE;
+			slot_idx >>= 2;
+			ASSERT(slot_idx >= 0 && slot_idx < softs->total_slots);
+			aac_handle_io(softs, &softs->io_slot[slot_idx], fast);
+        }
 
 		/*
 		 * Process waiting cmds before start new ones to
@@ -1471,8 +1638,9 @@
 		if (aac_fib_dequeue(softs, AAC_HOST_NORM_CMD_Q, &aif_idx) ==
 		    AACOK) {
 			ddi_acc_handle_t acc = softs->comm_space_acc_handle;
-			struct aac_fib *fibp;	/* FIB in communication space */
-			uint16_t fib_size;
+			struct aac_fib *fibp;	/* FIB in AIF queue */
+			struct aac_fib *fibp0;	/* FIB in communication space */
+			uint16_t fib_size, fib_size0;
 			uint32_t fib_xfer_state;
 			uint32_t addr, size;
 
@@ -1484,21 +1652,29 @@
 	    adapter_fibs[(aif_idx)]), AAC_FIB_SIZE, \
 	    (type)); }
 
+			mutex_enter(&softs->aifq_mutex);
 			/* Copy AIF from adapter to the empty AIF slot */
+			fibp = &softs->aifq[softs->aifq_idx].d;
 			AAC_SYNC_AIF(softs, aif_idx, DDI_DMA_SYNC_FORCPU);
-			fibp = &softs->comm_space->adapter_fibs[aif_idx];
-			fib_size = ddi_get16(acc, &fibp->Header.Size);
+			fibp0 = &softs->comm_space->adapter_fibs[aif_idx];
+			fib_size0 = ddi_get16(acc, &fibp0->Header.Size);
+			fib_size = (fib_size0 > AAC_FIB_SIZE) ?
+			    AAC_FIB_SIZE : fib_size0;
+			ddi_rep_get8(acc, (uint8_t *)fibp, (uint8_t *)fibp0,
+			    fib_size, DDI_DEV_AUTOINCR);
 
-			aac_save_aif(softs, acc, fibp, fib_size);
+			(void) aac_handle_aif(softs, fibp);
+			mutex_exit(&softs->aifq_mutex);
 
 			/* Complete AIF back to adapter with good status */
 			fib_xfer_state = LE_32(fibp->Header.XferState);
 			if (fib_xfer_state & AAC_FIBSTATE_FROMADAP) {
-				ddi_put32(acc, &fibp->Header.XferState,
+				ddi_put32(acc, &fibp0->Header.XferState,
 				    fib_xfer_state | AAC_FIBSTATE_DONEHOST);
-				ddi_put32(acc, (void *)&fibp->data[0], ST_OK);
-				if (fib_size > AAC_FIB_SIZE)
-					ddi_put16(acc, &fibp->Header.Size,
+				ddi_put32(acc, (uint32_t *)&fibp0->data[0],
+				    ST_OK);
+				if (fib_size0 > AAC_FIB_SIZE)
+					ddi_put16(acc, &fibp0->Header.Size,
 					    AAC_FIB_SIZE);
 				AAC_SYNC_AIF(softs, aif_idx,
 				    DDI_DMA_SYNC_FORDEV);
@@ -1513,7 +1689,7 @@
 			    Header.Size);
 			ddi_put32(acc,
 			    &softs->comm_space->adapter_fibs[aif_idx]. \
-			    Header.ReceiverFibAddress, addr);
+			    Header.a.ReceiverFibAddress, addr);
 			if (aac_fib_enqueue(softs, AAC_ADAP_NORM_RESP_Q,
 			    addr, size) == AACERR)
 				cmn_err(CE_NOTE, "!AIF ack failed");
@@ -1531,7 +1707,7 @@
 			cmn_err(CE_NOTE, "MSG From Adapter: %s",
 			    softs->comm_space->adapter_print_buf);
 		else
-			ddi_fm_service_impact(softs->devinfo_p,
+			aac_fm_service_impact(softs->devinfo_p,
 			    DDI_SERVICE_UNAFFECTED);
 		AAC_NOTIFY(softs, AAC_DB_PRINTF_READY);
 		return (AAC_DB_PRINTF_READY);
@@ -1556,7 +1732,7 @@
 static uint_t
 aac_intr_old(caddr_t arg)
 {
-	struct aac_softstate *softs = (void *)arg;
+	struct aac_softstate *softs = (struct aac_softstate *)arg;
 	int rval;
 
 	mutex_enter(&softs->io_lock);
@@ -1571,205 +1747,6 @@
 }
 
 /*
- * Query FIXED or MSI interrupts
- */
-static int
-aac_query_intrs(struct aac_softstate *softs, int intr_type)
-{
-	dev_info_t *dip = softs->devinfo_p;
-	int avail, actual, count;
-	int i, flag, ret;
-
-	AACDB_PRINT(softs, CE_NOTE,
-	    "aac_query_intrs:interrupt type 0x%x", intr_type);
-
-	/* Get number of interrupts */
-	ret = ddi_intr_get_nintrs(dip, intr_type, &count);
-	if ((ret != DDI_SUCCESS) || (count == 0)) {
-		AACDB_PRINT(softs, CE_WARN,
-		    "ddi_intr_get_nintrs() failed, ret %d count %d",
-		    ret, count);
-		return (DDI_FAILURE);
-	}
-
-	/* Get number of available interrupts */
-	ret = ddi_intr_get_navail(dip, intr_type, &avail);
-	if ((ret != DDI_SUCCESS) || (avail == 0)) {
-		AACDB_PRINT(softs, CE_WARN,
-		    "ddi_intr_get_navail() failed, ret %d avail %d",
-		    ret, avail);
-		return (DDI_FAILURE);
-	}
-
-	AACDB_PRINT(softs, CE_NOTE,
-	    "ddi_intr_get_nvail returned %d, navail() returned %d",
-	    count, avail);
-
-	/* Allocate an array of interrupt handles */
-	softs->intr_size = count * sizeof (ddi_intr_handle_t);
-	softs->htable = kmem_alloc(softs->intr_size, KM_SLEEP);
-
-	if (intr_type == DDI_INTR_TYPE_MSI) {
-		count = 1; /* only one vector needed by now */
-		flag = DDI_INTR_ALLOC_STRICT;
-	} else { /* must be DDI_INTR_TYPE_FIXED */
-		flag = DDI_INTR_ALLOC_NORMAL;
-	}
-
-	/* Call ddi_intr_alloc() */
-	ret = ddi_intr_alloc(dip, softs->htable, intr_type, 0,
-	    count, &actual, flag);
-
-	if ((ret != DDI_SUCCESS) || (actual == 0)) {
-		AACDB_PRINT(softs, CE_WARN,
-		    "ddi_intr_alloc() failed, ret = %d", ret);
-		actual = 0;
-		goto error;
-	}
-
-	if (actual < count) {
-		AACDB_PRINT(softs, CE_NOTE,
-		    "Requested: %d, Received: %d", count, actual);
-		goto error;
-	}
-
-	softs->intr_cnt = actual;
-
-	/* Get priority for first msi, assume remaining are all the same */
-	if ((ret = ddi_intr_get_pri(softs->htable[0],
-	    &softs->intr_pri)) != DDI_SUCCESS) {
-		AACDB_PRINT(softs, CE_WARN,
-		    "ddi_intr_get_pri() failed, ret = %d", ret);
-		goto error;
-	}
-
-	/* Test for high level mutex */
-	if (softs->intr_pri >= ddi_intr_get_hilevel_pri()) {
-		AACDB_PRINT(softs, CE_WARN,
-		    "aac_query_intrs: Hi level interrupt not supported");
-		goto error;
-	}
-
-	return (DDI_SUCCESS);
-
-error:
-	/* Free already allocated intr */
-	for (i = 0; i < actual; i++)
-		(void) ddi_intr_free(softs->htable[i]);
-
-	kmem_free(softs->htable, softs->intr_size);
-	return (DDI_FAILURE);
-}
-
-
-/*
- * Register FIXED or MSI interrupts, and enable them
- */
-static int
-aac_add_intrs(struct aac_softstate *softs)
-{
-	int i, ret;
-	int actual;
-	ddi_intr_handler_t *aac_intr;
-
-	actual = softs->intr_cnt;
-	aac_intr = (ddi_intr_handler_t *)((softs->flags & AAC_FLAGS_NEW_COMM) ?
-	    aac_intr_new : aac_intr_old);
-
-	/* Call ddi_intr_add_handler() */
-	for (i = 0; i < actual; i++) {
-		if ((ret = ddi_intr_add_handler(softs->htable[i],
-		    aac_intr, (caddr_t)softs, NULL)) != DDI_SUCCESS) {
-			cmn_err(CE_WARN,
-			    "ddi_intr_add_handler() failed ret = %d", ret);
-
-			/* Free already allocated intr */
-			for (i = 0; i < actual; i++)
-				(void) ddi_intr_free(softs->htable[i]);
-
-			kmem_free(softs->htable, softs->intr_size);
-			return (DDI_FAILURE);
-		}
-	}
-
-	if ((ret = ddi_intr_get_cap(softs->htable[0], &softs->intr_cap))
-	    != DDI_SUCCESS) {
-		cmn_err(CE_WARN, "ddi_intr_get_cap() failed, ret = %d", ret);
-
-		/* Free already allocated intr */
-		for (i = 0; i < actual; i++)
-			(void) ddi_intr_free(softs->htable[i]);
-
-		kmem_free(softs->htable, softs->intr_size);
-		return (DDI_FAILURE);
-	}
-
-	return (DDI_SUCCESS);
-}
-
-/*
- * Unregister FIXED or MSI interrupts
- */
-static void
-aac_remove_intrs(struct aac_softstate *softs)
-{
-	int i;
-
-	/* Disable all interrupts */
-	(void) aac_disable_intrs(softs);
-	/* Call ddi_intr_remove_handler() */
-	for (i = 0; i < softs->intr_cnt; i++) {
-		(void) ddi_intr_remove_handler(softs->htable[i]);
-		(void) ddi_intr_free(softs->htable[i]);
-	}
-
-	kmem_free(softs->htable, softs->intr_size);
-}
-
-static int
-aac_enable_intrs(struct aac_softstate *softs)
-{
-	int rval = AACOK;
-
-	if (softs->intr_cap & DDI_INTR_FLAG_BLOCK) {
-		/* for MSI block enable */
-		if (ddi_intr_block_enable(softs->htable, softs->intr_cnt) !=
-		    DDI_SUCCESS)
-			rval = AACERR;
-	} else {
-		int i;
-
-		/* Call ddi_intr_enable() for legacy/MSI non block enable */
-		for (i = 0; i < softs->intr_cnt; i++) {
-			if (ddi_intr_enable(softs->htable[i]) != DDI_SUCCESS)
-				rval = AACERR;
-		}
-	}
-	return (rval);
-}
-
-static int
-aac_disable_intrs(struct aac_softstate *softs)
-{
-	int rval = AACOK;
-
-	if (softs->intr_cap & DDI_INTR_FLAG_BLOCK) {
-		/* Call ddi_intr_block_disable() */
-		if (ddi_intr_block_disable(softs->htable, softs->intr_cnt) !=
-		    DDI_SUCCESS)
-			rval = AACERR;
-	} else {
-		int i;
-
-		for (i = 0; i < softs->intr_cnt; i++) {
-			if (ddi_intr_disable(softs->htable[i]) != DDI_SUCCESS)
-				rval = AACERR;
-		}
-	}
-	return (rval);
-}
-
-/*
  * Set pkt_reason and OR in pkt_statistics flag
  */
 static void
@@ -1795,7 +1772,7 @@
 	acp->flags |= AAC_CMD_CMPLT;
 
 	acp->pkt->pkt_state |= STATE_GOT_BUS | STATE_GOT_TARGET | \
-	    STATE_SENT_CMD | STATE_GOT_STATUS;
+	    STATE_SENT_CMD;
 	if (acp->pkt->pkt_state & STATE_XFERRED_DATA)
 		acp->pkt->pkt_resid = 0;
 
@@ -1826,8 +1803,6 @@
 	ASSERT(!(acp->flags & AAC_CMD_SYNC));
 	ASSERT(!(acp->flags & AAC_CMD_NO_CB));
 
-	acp->pkt->pkt_state |= STATE_GOT_STATUS;
-
 	/*
 	 * block_read/write has a similar response header, use blockread
 	 * response for both.
@@ -1837,6 +1812,8 @@
 	if (status == ST_OK) {
 		acp->pkt->pkt_resid = 0;
 		acp->pkt->pkt_state |= STATE_XFERRED_DATA;
+	} else if (status == ST_NOT_READY) {
+		aac_set_pkt_reason(softs, acp, CMD_TIMEOUT, STAT_TIMEOUT);
 	} else {
 		aac_set_arq_data_hwerr(acp);
 	}
@@ -1852,170 +1829,88 @@
 	struct aac_fib *fibp = acp->slotp->fibp;
 	struct scsi_pkt *pkt = acp->pkt;
 	struct aac_srb_reply *resp;
-	uint32_t resp_status;
+	uint32_t resp_status, scsi_status;
+	uint32_t srb_status, data_xfer_length;
+	uint32_t sense_data_size;
 
 	ASSERT(!(acp->flags & AAC_CMD_SYNC));
 	ASSERT(!(acp->flags & AAC_CMD_NO_CB));
 
 	resp = (struct aac_srb_reply *)&fibp->data[0];
-	resp_status = ddi_get32(acc, &resp->status);
+	if (acp->flags & AAC_CMD_FASTRESP) {
+		resp_status = ST_OK;
+		sense_data_size = 0;
+		srb_status = SRB_STATUS_SUCCESS;
+		data_xfer_length = 0;
+		scsi_status = 0;
+	} else {
+		resp_status = ddi_get32(acc, &resp->status);
+		sense_data_size = ddi_get32(acc, &resp->sense_data_size);
+		srb_status = ddi_get32(acc, &resp->srb_status);
+		data_xfer_length = ddi_get32(acc, &resp->data_xfer_length);
+		scsi_status = ddi_get32(acc, &resp->scsi_status);
+	}
 
 	/* First check FIB status */
 	if (resp_status == ST_OK) {
-		uint32_t scsi_status;
-		uint32_t srb_status;
-		uint32_t data_xfer_length;
+		if (data_xfer_length) {
+			/* When the cmd failed, data_xfer_length is 0 */
+			pkt->pkt_state |= STATE_XFERRED_DATA;
+			pkt->pkt_resid = acp->bcount - data_xfer_length;
+		}
 
-		scsi_status = ddi_get32(acc, &resp->scsi_status);
-		srb_status = ddi_get32(acc, &resp->srb_status);
-		data_xfer_length = ddi_get32(acc, &resp->data_xfer_length);
-
-		*pkt->pkt_scbp = (uint8_t)scsi_status;
-		pkt->pkt_state |= STATE_GOT_STATUS;
-		if (scsi_status == STATUS_GOOD) {
-			uchar_t cmd = ((union scsi_cdb *)(void *)
-			    (pkt->pkt_cdbp))->scc_cmd;
-
-			/* Next check SRB status */
-			switch (srb_status & 0x3f) {
-			case SRB_STATUS_DATA_OVERRUN:
-				AACDB_PRINT(softs, CE_NOTE, "DATA_OVERRUN: " \
-				    "scmd=%d, xfer=%d, buflen=%d",
-				    (uint32_t)cmd, data_xfer_length,
-				    acp->bcount);
-
-				switch (cmd) {
-				case SCMD_READ:
-				case SCMD_WRITE:
-				case SCMD_READ_G1:
-				case SCMD_WRITE_G1:
-				case SCMD_READ_G4:
-				case SCMD_WRITE_G4:
-				case SCMD_READ_G5:
-				case SCMD_WRITE_G5:
-					aac_set_pkt_reason(softs, acp,
-					    CMD_DATA_OVR, 0);
-					break;
-				}
-				/*FALLTHRU*/
-			case SRB_STATUS_ERROR_RECOVERY:
-			case SRB_STATUS_PENDING:
-			case SRB_STATUS_SUCCESS:
-				/*
-				 * pkt_resid should only be calculated if the
-				 * status is ERROR_RECOVERY/PENDING/SUCCESS/
-				 * OVERRUN/UNDERRUN
-				 */
-				if (data_xfer_length) {
-					pkt->pkt_state |= STATE_XFERRED_DATA;
-					pkt->pkt_resid = acp->bcount - \
-					    data_xfer_length;
-					ASSERT(pkt->pkt_resid >= 0);
-				}
+		/* Next check SRB status */
+		switch (srb_status & 0x3f) {
+		case SRB_STATUS_ERROR_RECOVERY:
+		case SRB_STATUS_PENDING:
+		case SRB_STATUS_SUCCESS:
+			break;
+		case SRB_STATUS_ABORTED:
+			aac_set_pkt_reason(softs, acp, CMD_ABORTED,
+			    STAT_ABORTED);
+			break;
+		case SRB_STATUS_ABORT_FAILED:
+			aac_set_pkt_reason(softs, acp, CMD_ABORT_FAIL, 0);
+			break;
+		case SRB_STATUS_DATA_OVERRUN:
+			switch (((union scsi_cdb *)(pkt->pkt_cdbp))->scc_cmd) {
+			case SCMD_READ:
+			case SCMD_WRITE:
+			case SCMD_READ_G1:
+			case SCMD_WRITE_G1:
+			case SCMD_READ_G4:
+			case SCMD_WRITE_G4:
+				aac_set_pkt_reason(softs, acp, CMD_DATA_OVR, 0);
 				break;
-			case SRB_STATUS_ABORTED:
-				AACDB_PRINT(softs, CE_NOTE,
-				    "SRB_STATUS_ABORTED, xfer=%d, resid=%d",
-				    data_xfer_length, pkt->pkt_resid);
-				aac_set_pkt_reason(softs, acp, CMD_ABORTED,
-				    STAT_ABORTED);
-				break;
-			case SRB_STATUS_ABORT_FAILED:
-				AACDB_PRINT(softs, CE_NOTE,
-				    "SRB_STATUS_ABORT_FAILED, xfer=%d, " \
-				    "resid=%d", data_xfer_length,
-				    pkt->pkt_resid);
-				aac_set_pkt_reason(softs, acp, CMD_ABORT_FAIL,
-				    0);
-				break;
-			case SRB_STATUS_PARITY_ERROR:
-				AACDB_PRINT(softs, CE_NOTE,
-				    "SRB_STATUS_PARITY_ERROR, xfer=%d, " \
-				    "resid=%d", data_xfer_length,
-				    pkt->pkt_resid);
-				aac_set_pkt_reason(softs, acp, CMD_PER_FAIL, 0);
-				break;
-			case SRB_STATUS_NO_DEVICE:
-			case SRB_STATUS_INVALID_PATH_ID:
-			case SRB_STATUS_INVALID_TARGET_ID:
-			case SRB_STATUS_INVALID_LUN:
-			case SRB_STATUS_SELECTION_TIMEOUT:
-#ifdef DEBUG
-				if (AAC_DEV_IS_VALID(acp->dvp)) {
-					AACDB_PRINT(softs, CE_NOTE,
-					    "SRB_STATUS_NO_DEVICE(%d), " \
-					    "xfer=%d, resid=%d ",
-					    srb_status & 0x3f,
-					    data_xfer_length, pkt->pkt_resid);
-				}
-#endif
-				aac_set_pkt_reason(softs, acp, CMD_DEV_GONE, 0);
-				break;
-			case SRB_STATUS_COMMAND_TIMEOUT:
-			case SRB_STATUS_TIMEOUT:
-				AACDB_PRINT(softs, CE_NOTE,
-				    "SRB_STATUS_COMMAND_TIMEOUT, xfer=%d, " \
-				    "resid=%d", data_xfer_length,
-				    pkt->pkt_resid);
-				aac_set_pkt_reason(softs, acp, CMD_TIMEOUT,
-				    STAT_TIMEOUT);
-				break;
-			case SRB_STATUS_BUS_RESET:
-				AACDB_PRINT(softs, CE_NOTE,
-				    "SRB_STATUS_BUS_RESET, xfer=%d, " \
-				    "resid=%d", data_xfer_length,
-				    pkt->pkt_resid);
-				aac_set_pkt_reason(softs, acp, CMD_RESET,
-				    STAT_BUS_RESET);
-				break;
-			default:
-				AACDB_PRINT(softs, CE_NOTE, "srb_status=%d, " \
-				    "xfer=%d, resid=%d", srb_status & 0x3f,
-				    data_xfer_length, pkt->pkt_resid);
-				aac_set_pkt_reason(softs, acp, CMD_TRAN_ERR, 0);
-				break;
 			}
-		} else if (scsi_status == STATUS_CHECK) {
-			/* CHECK CONDITION */
-			struct scsi_arq_status *arqstat =
-			    (void *)(pkt->pkt_scbp);
-			uint32_t sense_data_size;
-
-			pkt->pkt_state |= STATE_ARQ_DONE;
-
-			*(uint8_t *)&arqstat->sts_rqpkt_status = STATUS_GOOD;
-			arqstat->sts_rqpkt_reason = CMD_CMPLT;
-			arqstat->sts_rqpkt_resid = 0;
-			arqstat->sts_rqpkt_state =
-			    STATE_GOT_BUS |
-			    STATE_GOT_TARGET |
-			    STATE_SENT_CMD |
-			    STATE_XFERRED_DATA;
-			arqstat->sts_rqpkt_statistics = 0;
-
-			sense_data_size = ddi_get32(acc,
-			    &resp->sense_data_size);
-			ASSERT(sense_data_size <= AAC_SENSE_BUFFERSIZE);
-			AACDB_PRINT(softs, CE_NOTE,
-			    "CHECK CONDITION: sense len=%d, xfer len=%d",
-			    sense_data_size, data_xfer_length);
-
-			if (sense_data_size > SENSE_LENGTH)
-				sense_data_size = SENSE_LENGTH;
-			ddi_rep_get8(acc, (uint8_t *)&arqstat->sts_sensedata,
-			    (uint8_t *)resp->sense_data, sense_data_size,
-			    DDI_DEV_AUTOINCR);
-		} else {
-			AACDB_PRINT(softs, CE_WARN, "invaild scsi status: " \
-			    "scsi_status=%d, srb_status=%d",
-			    scsi_status, srb_status);
+			break;
+		case SRB_STATUS_COMMAND_TIMEOUT:
+		case SRB_STATUS_TIMEOUT:
+			aac_set_pkt_reason(softs, acp, CMD_TIMEOUT,
+			    STAT_TIMEOUT);
+			break;
+		case SRB_STATUS_BUS_RESET:
+			aac_set_pkt_reason(softs, acp, CMD_RESET,
+			    STAT_BUS_RESET);
+			break;
+		default:
 			aac_set_pkt_reason(softs, acp, CMD_TRAN_ERR, 0);
+			break;
 		}
+	} else if (resp_status == ST_NOT_READY) {
+		aac_set_pkt_reason(softs, acp, CMD_TIMEOUT, STAT_TIMEOUT);
 	} else {
 		AACDB_PRINT(softs, CE_NOTE, "SRB failed: fib status %d",
 		    resp_status);
-		aac_set_pkt_reason(softs, acp, CMD_TRAN_ERR, 0);
 	}
+
+	/* Finally SCSI status */
+	if (scsi_status == 2) {
+		AACDB_PRINT(softs, CE_NOTE, "CHECK CONDITION: len=%d",
+		    sense_data_size);
+		ASSERT(sense_data_size <= AAC_SENSE_BUFFERSIZE);
+		aac_copy_arq_data(pkt, resp->sense_data, sense_data_size, acc);
+	}
 }
 
 /*
@@ -2045,15 +1940,6 @@
 }
 
 /*
- * Handle completed sync fib command
- */
-/*ARGSUSED*/
-void
-aac_sync_complete(struct aac_softstate *softs, struct aac_cmd *acp)
-{
-}
-
-/*
  * Handle completed Flush command
  */
 /*ARGSUSED*/
@@ -2067,8 +1953,6 @@
 
 	ASSERT(!(acp->flags & AAC_CMD_SYNC));
 
-	acp->pkt->pkt_state |= STATE_GOT_STATUS;
-
 	resp = (struct aac_synchronize_reply *)&slotp->fibp->data[0];
 	status = ddi_get32(acc, &resp->Status);
 	if (status != CT_OK)
@@ -2075,24 +1959,44 @@
 		aac_set_arq_data_hwerr(acp);
 }
 
+/*
+ * Handle completed AIF request command
+ */
 /*ARGSUSED*/
 static void
-aac_startstop_complete(struct aac_softstate *softs, struct aac_cmd *acp)
+aac_aifreq_complete(struct aac_softstate *softs, struct aac_cmd *acp)
 {
 	struct aac_slot *slotp = acp->slotp;
 	ddi_acc_handle_t acc = slotp->fib_acc_handle;
-	struct aac_Container_resp *resp;
 	uint32_t status;
+	struct aac_fib *fibp;	/* FIB in AIF queue */
+	uint16_t fib_size, fib_size0;
 
 	ASSERT(!(acp->flags & AAC_CMD_SYNC));
 
-	acp->pkt->pkt_state |= STATE_GOT_STATUS;
+	acp->flags |= AAC_CMD_AIF;
+	status = ddi_get32(acc, &slotp->fibp->Header.XferState);
+	if (status & AAC_FIBSTATE_NOMOREAIF) {
+		acp->flags |= AAC_CMD_AIF_NOMORE;
+	} else {
+		mutex_enter(&softs->aifq_mutex);
+		/*
+		 * Copy AIF from adapter to the empty AIF slot
+		 */
+		fibp = &softs->aifq[softs->aifq_idx].d;
+		fib_size0 = ddi_get16(acc, &slotp->fibp->Header.Size);
+		fib_size = (fib_size0 > AAC_FIB_SIZE) ?
+			AAC_FIB_SIZE : fib_size0;
+		ddi_rep_get8(acc, (uint8_t *)fibp, (uint8_t *)slotp->fibp,
+			fib_size, DDI_DEV_AUTOINCR);
 
-	resp = (struct aac_Container_resp *)&slotp->fibp->data[0];
-	status = ddi_get32(acc, &resp->Status);
-	if (status != 0) {
-		AACDB_PRINT(softs, CE_WARN, "Cannot start/stop a unit");
-		aac_set_arq_data_hwerr(acp);
+		if (aac_check_acc_handle(softs-> \
+			pci_mem_handle[0]) == DDI_SUCCESS)
+			(void) aac_handle_aif(softs, fibp);
+		else
+			aac_fm_service_impact(softs->devinfo_p,
+				DDI_SERVICE_UNAFFECTED);
+		mutex_exit(&softs->aifq_mutex);
 	}
 }
 
@@ -2152,6 +2056,14 @@
 		case 0x286:
 			softs->hwif = AAC_HWIF_RKT;
 			break;
+		case 0x28b:
+			softs->hwif = AAC_HWIF_SRC;
+			break;
+		case 0x28c:
+		case 0x28d:
+		case 0x28f:
+			softs->hwif = AAC_HWIF_SRCV;
+			break;
 		default:
 			AACDB_PRINT(softs, CE_WARN,
 			    "Unknown device \"pci9005,%x\"", softs->devid);
@@ -2169,6 +2081,14 @@
 		softs->aac_if = aac_rkt_interface;
 		softs->map_size_min = AAC_MAP_SIZE_MIN_RKT;
 		break;
+	case AAC_HWIF_SRC:
+		softs->aac_if = aac_src_interface;
+		softs->map_size_min = AAC_MAP_SIZE_MIN_SRC_BAR0;
+		break;
+	case AAC_HWIF_SRCV:
+		softs->aac_if = aac_srcv_interface;
+		softs->map_size_min = AAC_MAP_SIZE_MIN_SRCV_BAR0;
+		break;
 	default:
 		AACDB_PRINT(softs, CE_WARN,
 		    "Unknown hardware interface %d", softs->hwif);
@@ -2197,8 +2117,14 @@
 	}
 
 	/* Set memory base to map */
-	softs->pci_mem_base_paddr = 0xfffffff0UL & \
+	softs->pci_mem_base_paddr[0] = 0xfffffff0UL & \
 	    pci_config_get32(pci_config_handle, PCI_CONF_BASE0);
+	if (softs->hwif == AAC_HWIF_SRC) {
+		softs->pci_mem_base_paddr[1] = 0xfffffff0UL & \
+		    pci_config_get32(pci_config_handle, PCI_CONF_BASE2);
+	} else {
+		softs->pci_mem_base_paddr[1] = softs->pci_mem_base_paddr[0];
+	}
 
 	pci_config_teardown(&pci_config_handle);
 
@@ -2209,77 +2135,6 @@
 }
 
 /*
- * Do the usual interrupt handler setup stuff.
- */
-static int
-aac_register_intrs(struct aac_softstate *softs)
-{
-	dev_info_t *dip;
-	int intr_types;
-
-	ASSERT(softs->devinfo_p);
-	dip = softs->devinfo_p;
-
-	/* Get the type of device intrrupts */
-	if (ddi_intr_get_supported_types(dip, &intr_types) != DDI_SUCCESS) {
-		AACDB_PRINT(softs, CE_WARN,
-		    "ddi_intr_get_supported_types() failed");
-		return (AACERR);
-	}
-	AACDB_PRINT(softs, CE_NOTE,
-	    "ddi_intr_get_supported_types() ret: 0x%x", intr_types);
-
-	/* Query interrupt, and alloc/init all needed struct */
-	if (intr_types & DDI_INTR_TYPE_MSI) {
-		if (aac_query_intrs(softs, DDI_INTR_TYPE_MSI)
-		    != DDI_SUCCESS) {
-			AACDB_PRINT(softs, CE_WARN,
-			    "MSI interrupt query failed");
-			return (AACERR);
-		}
-		softs->intr_type = DDI_INTR_TYPE_MSI;
-	} else if (intr_types & DDI_INTR_TYPE_FIXED) {
-		if (aac_query_intrs(softs, DDI_INTR_TYPE_FIXED)
-		    != DDI_SUCCESS) {
-			AACDB_PRINT(softs, CE_WARN,
-			    "FIXED interrupt query failed");
-			return (AACERR);
-		}
-		softs->intr_type = DDI_INTR_TYPE_FIXED;
-	} else {
-		AACDB_PRINT(softs, CE_WARN,
-		    "Device cannot suppport both FIXED and MSI interrupts");
-		return (AACERR);
-	}
-
-	/* Connect interrupt handlers */
-	if (aac_add_intrs(softs) != DDI_SUCCESS) {
-		AACDB_PRINT(softs, CE_WARN,
-		    "Interrupt registration failed, intr type: %s",
-		    softs->intr_type == DDI_INTR_TYPE_MSI ? "MSI" : "FIXED");
-		return (AACERR);
-	}
-	(void) aac_enable_intrs(softs);
-
-	if (ddi_add_softintr(dip, DDI_SOFTINT_LOW, &softs->softint_id,
-	    NULL, NULL, aac_softintr, (caddr_t)softs) != DDI_SUCCESS) {
-		AACDB_PRINT(softs, CE_WARN,
-		    "Can not setup soft interrupt handler!");
-		aac_remove_intrs(softs);
-		return (AACERR);
-	}
-
-	return (AACOK);
-}
-
-static void
-aac_unregister_intrs(struct aac_softstate *softs)
-{
-	aac_remove_intrs(softs);
-	ddi_remove_softintr(softs->softint_id);
-}
-
-/*
  * Check the firmware to determine the features to support and the FIB
  * parameters to use.
  */
@@ -2289,8 +2144,8 @@
 	uint32_t options;
 	uint32_t atu_size;
 	ddi_acc_handle_t pci_handle;
-	uint8_t *data;
-	uint32_t max_fibs;
+	char *pci_mbr;
+	uint32_t max_fibs, max_aif;
 	uint32_t max_fib_size;
 	uint32_t sg_tablesize;
 	uint32_t max_sectors;
@@ -2297,8 +2152,9 @@
 	uint32_t status;
 
 	/* Get supported options */
+	softs->sync_slot_busy = 1;
 	if ((aac_sync_mbcommand(softs, AAC_MONKER_GETINFO, 0, 0, 0, 0,
-	    &status)) != AACOK) {
+	    &status, NULL)) != AACOK) {
 		if (status != SRB_STATUS_INVALID_REQUEST) {
 			cmn_err(CE_CONT,
 			    "?Fatal error: request adapter info error");
@@ -2357,21 +2213,41 @@
 	}
 
 	if (options & AAC_SUPPORTED_NONDASD) {
-		if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, softs->devinfo_p, 0,
-		    "nondasd-enable", (char **)&data) == DDI_SUCCESS)) {
-			if (strcmp((char *)data, "yes") == 0) {
-				AACDB_PRINT(softs, CE_NOTE,
-				    "!Enable Non-DASD access");
-				softs->flags |= AAC_FLAGS_NONDASD;
-			}
-			ddi_prop_free(data);
-		}
+		softs->flags |= AAC_FLAGS_NONDASD;
+		AACDB_PRINT(softs, CE_NOTE, "!Enable Non-DASD access");
 	}
 
+	if ((options & AAC_SUPPORTED_NEW_COMM_TYPE3) ||
+		(options & AAC_SUPPORTED_NEW_COMM_TYPE4)) {
+		softs->flags |= AAC_FLAGS_NEW_COMM | AAC_FLAGS_NEW_COMM_TYPE34;
+	} else if (options & AAC_SUPPORTED_NEW_COMM_TYPE2) {
+		softs->flags |= AAC_FLAGS_NEW_COMM | AAC_FLAGS_NEW_COMM_TYPE2;
+		AACDB_PRINT(softs, CE_NOTE,	"!Enable New Comm. Type2 interface");
+	} else if (options & AAC_SUPPORTED_NEW_COMM_TYPE1) {
+		softs->flags |= AAC_FLAGS_NEW_COMM | AAC_FLAGS_NEW_COMM_TYPE1;
+		AACDB_PRINT(softs, CE_NOTE,	"!Enable New Comm. Type1 interface");
+	} else if (options & AAC_SUPPORTED_NEW_COMM) {
+		softs->flags |= AAC_FLAGS_NEW_COMM;
+		AACDB_PRINT(softs, CE_NOTE,	"!Enable New Comm. interface");
+	}
+
+	if (softs->sync_mode &&
+		((softs->flags & AAC_FLAGS_NEW_COMM_TYPE1) || 
+		 (softs->flags & AAC_FLAGS_NEW_COMM_TYPE2) || 
+		 (softs->flags & AAC_FLAGS_NEW_COMM_TYPE34))) {
+		cmn_err(CE_NOTE, "aac: Sync. mode enforced by driver parameter. This will cause a significant performance decrease!");
+		softs->flags |= AAC_FLAGS_SYNC_MODE;
+	} else if (softs->flags & AAC_FLAGS_NEW_COMM_TYPE34) {
+		cmn_err(CE_NOTE, "aac: Async. mode not supported by current driver, sync. mode enforced.");
+		cmn_err(CE_NOTE, "aac: Please update driver to get full performance.");
+		softs->flags |= AAC_FLAGS_SYNC_MODE;
+	}
+
 	/* Read preferred settings */
 	max_fib_size = 0;
+	softs->sync_slot_busy = 1;
 	if ((aac_sync_mbcommand(softs, AAC_MONKER_GETCOMMPREF,
-	    0, 0, 0, 0, NULL)) == AACOK) {
+	    0, 0, 0, 0, NULL, NULL)) == AACOK) {
 		options = AAC_MAILBOX_GET(softs, 1);
 		max_fib_size = (options & 0xffff);
 		max_sectors = (options >> 16) << 1;
@@ -2379,26 +2255,28 @@
 		sg_tablesize = (options >> 16);
 		options = AAC_MAILBOX_GET(softs, 3);
 		max_fibs = (options & 0xffff);
+		options = AAC_MAILBOX_GET(softs, 4);
+		max_aif = (options & 0xffff);
 	}
 
 	/* Enable new comm. and rawio at the same time */
-	if ((softs->support_opt & AAC_SUPPORTED_NEW_COMM) &&
+	if ((softs->flags & AAC_FLAGS_NEW_COMM) &&
 	    (max_fib_size != 0)) {
-		/* read out and save PCI MBR */
-		if ((atu_size > softs->map_size) &&
-		    (ddi_regs_map_setup(softs->devinfo_p, 1,
-		    (caddr_t *)&data, 0, atu_size, &softs->reg_attr,
-		    &pci_handle) == DDI_SUCCESS)) {
-			ddi_regs_map_free(&softs->pci_mem_handle);
-			softs->pci_mem_handle = pci_handle;
-			softs->pci_mem_base_vaddr = data;
+        if ((atu_size > softs->map_size) &&
+			(ddi_regs_map_setup(softs->devinfo_p, 1,
+				(caddr_t *)&pci_mbr, 0, atu_size, &aac_acc_attr,
+				&pci_handle) == DDI_SUCCESS)) {
+			ddi_regs_map_free(&softs->pci_mem_handle[0]);
+			softs->pci_mem_handle[0] = pci_handle;
+			softs->pci_mem_base_vaddr[0] = pci_mbr;
 			softs->map_size = atu_size;
+			if (softs->hwif != AAC_HWIF_SRC) {
+				softs->pci_mem_handle[1] =
+					softs->pci_mem_handle[0];
+				softs->pci_mem_base_vaddr[1] =
+					softs->pci_mem_base_vaddr[0];
+			}
 		}
-		if (atu_size == softs->map_size) {
-			softs->flags |= AAC_FLAGS_NEW_COMM;
-			AACDB_PRINT(softs, CE_NOTE,
-			    "!Enable New Comm. interface");
-		}
 	}
 
 	/* Set FIB parameters */
@@ -2407,6 +2285,7 @@
 		softs->aac_max_fib_size = max_fib_size;
 		softs->aac_max_sectors = max_sectors;
 		softs->aac_sg_tablesize = sg_tablesize;
+		softs->aac_max_aif = max_aif;
 
 		softs->flags |= AAC_FLAGS_RAW_IO;
 		AACDB_PRINT(softs, CE_NOTE, "!Enable RawIO");
@@ -2452,7 +2331,9 @@
 	    softs->buf_dma_attr.dma_attr_maxxfer - 1;
 
 	/* Setup FIB operations */
-	if (softs->flags & AAC_FLAGS_RAW_IO)
+	if (softs->flags & AAC_FLAGS_NEW_COMM_TYPE2) 
+		softs->aac_cmd_fib = aac_cmd_fib_rawio2;
+	else if (softs->flags & AAC_FLAGS_RAW_IO)
 		softs->aac_cmd_fib = aac_cmd_fib_rawio;
 	else if (softs->flags & AAC_FLAGS_SG_64BIT)
 		softs->aac_cmd_fib = aac_cmd_fib_brw64;
@@ -2479,7 +2360,7 @@
 aac_fsa_rev(struct aac_softstate *softs, struct FsaRev *fsarev0,
     struct FsaRev *fsarev1)
 {
-	ddi_acc_handle_t acc = softs->sync_ac.slotp->fib_acc_handle;
+	ddi_acc_handle_t acc = softs->comm_space_acc_handle;
 
 	AAC_GET_FIELD8(acc, fsarev1, fsarev0, external.comp.dash);
 	AAC_GET_FIELD8(acc, fsarev1, fsarev0, external.comp.type);
@@ -2497,23 +2378,16 @@
 aac_get_adapter_info(struct aac_softstate *softs,
     struct aac_adapter_info *ainfr, struct aac_supplement_adapter_info *sinfr)
 {
-	struct aac_cmd *acp = &softs->sync_ac;
-	ddi_acc_handle_t acc;
-	struct aac_fib *fibp;
+	ddi_acc_handle_t acc = softs->sync_slot->fib_acc_handle;
+	struct aac_fib *fibp = softs->sync_slot->fibp;
 	struct aac_adapter_info *ainfp;
 	struct aac_supplement_adapter_info *sinfp;
-	int rval;
 
-	(void) aac_sync_fib_slot_bind(softs, acp);
-	acc = acp->slotp->fib_acc_handle;
-	fibp = acp->slotp->fibp;
-
 	ddi_put8(acc, &fibp->data[0], 0);
 	if (aac_sync_fib(softs, RequestAdapterInfo,
 	    AAC_FIB_SIZEOF(struct aac_adapter_info)) != AACOK) {
 		AACDB_PRINT(softs, CE_WARN, "RequestAdapterInfo failed");
-		rval = AACERR;
-		goto finish;
+		return (AACERR);
 	}
 	ainfp = (struct aac_adapter_info *)fibp->data;
 	if (ainfr) {
@@ -2545,17 +2419,14 @@
 		    AAC_SUPPORTED_SUPPLEMENT_ADAPTER_INFO)) {
 			AACDB_PRINT(softs, CE_WARN,
 			    "SupplementAdapterInfo not supported");
-			rval = AACERR;
-			goto finish;
+			return (AACERR);
 		}
 		ddi_put8(acc, &fibp->data[0], 0);
 		if (aac_sync_fib(softs, RequestSupplementAdapterInfo,
-		    AAC_FIB_SIZEOF(struct aac_supplement_adapter_info))
-		    != AACOK) {
+		    AAC_FIB_SIZEOF(struct aac_supplement_adapter_info)) != AACOK) {
 			AACDB_PRINT(softs, CE_WARN,
 			    "RequestSupplementAdapterInfo failed");
-			rval = AACERR;
-			goto finish;
+			return (AACERR);
 		}
 		sinfp = (struct aac_supplement_adapter_info *)fibp->data;
 		AAC_REP_GET_FIELD8(acc, sinfr, sinfp, AdapterTypeText[0], 17+1);
@@ -2584,16 +2455,11 @@
 		AAC_GET_FIELD32(acc, sinfr, sinfp, ExpansionFlag);
 		if (sinfr->ExpansionFlag == 1) {
 			AAC_GET_FIELD32(acc, sinfr, sinfp, FeatureBits3);
-			AAC_GET_FIELD32(acc, sinfr, sinfp,
-			    SupportedPerformanceMode);
-			AAC_REP_GET_FIELD32(acc, sinfr, sinfp,
-			    ReservedGrowth[0], 80);
+			AAC_GET_FIELD32(acc, sinfr, sinfp, SupportedPerformanceMode);
+			AAC_REP_GET_FIELD32(acc, sinfr, sinfp, ReservedGrowth[0], 80);
 		}
 	}
-	rval = AACOK;
-finish:
-	aac_sync_fib_slot_release(softs, acp);
-	return (rval);
+	return (AACOK);
 }
 
 static int
@@ -2600,9 +2466,8 @@
 aac_get_bus_info(struct aac_softstate *softs, uint32_t *bus_max,
     uint32_t *tgt_max)
 {
-	struct aac_cmd *acp = &softs->sync_ac;
-	ddi_acc_handle_t acc;
-	struct aac_fib *fibp;
+	ddi_acc_handle_t acc = softs->sync_slot->fib_acc_handle;
+	struct aac_fib *fibp = softs->sync_slot->fibp;
 	struct aac_ctcfg *c_cmd;
 	struct aac_ctcfg_resp *c_resp;
 	uint32_t scsi_method_id;
@@ -2610,10 +2475,6 @@
 	struct aac_bus_info_response *resp;
 	int rval;
 
-	(void) aac_sync_fib_slot_bind(softs, acp);
-	acc = acp->slotp->fib_acc_handle;
-	fibp = acp->slotp->fibp;
-
 	/* Detect MethodId */
 	c_cmd = (struct aac_ctcfg *)&fibp->data[0];
 	ddi_put32(acc, &c_cmd->Command, VM_ContainerConfig);
@@ -2625,8 +2486,7 @@
 	if (rval != AACOK || ddi_get32(acc, &c_resp->Status) != 0) {
 		AACDB_PRINT(softs, CE_WARN,
 		    "VM_ContainerConfig command fail");
-		rval = AACERR;
-		goto finish;
+		return (AACERR);
 	}
 	scsi_method_id = ddi_get32(acc, &c_resp->param);
 
@@ -2650,14 +2510,10 @@
 	/* Scan all coordinates with INQUIRY */
 	if ((rval != AACOK) || (ddi_get32(acc, &resp->Status) != 0)) {
 		AACDB_PRINT(softs, CE_WARN, "GetBusInfo command fail");
-		rval = AACERR;
-		goto finish;
+		return (AACERR);
 	}
 	*bus_max = ddi_get32(acc, &resp->BusCount);
 	*tgt_max = ddi_get32(acc, &resp->TargetsPerBus);
-
-finish:
-	aac_sync_fib_slot_release(softs, acp);
 	return (AACOK);
 }
 
@@ -2702,9 +2558,8 @@
 static int
 aac_handle_adapter_config_issues(struct aac_softstate *softs)
 {
-	struct aac_cmd *acp = &softs->sync_ac;
-	ddi_acc_handle_t acc;
-	struct aac_fib *fibp;
+	ddi_acc_handle_t acc = softs->sync_slot->fib_acc_handle;
+	struct aac_fib *fibp = softs->sync_slot->fibp;
 	struct aac_Container *cmd;
 	struct aac_Container_resp *resp;
 	struct aac_cf_status_header *cfg_sts_hdr;
@@ -2713,10 +2568,6 @@
 	uint32_t cfg_stat_action;
 	int rval;
 
-	(void) aac_sync_fib_slot_bind(softs, acp);
-	acc = acp->slotp->fib_acc_handle;
-	fibp = acp->slotp->fibp;
-
 	/* Get adapter config status */
 	cmd = (struct aac_Container *)&fibp->data[0];
 
@@ -2764,8 +2615,6 @@
 		cmn_err(CE_WARN, "!Configuration issue, auto-commit aborted");
 		rval = AACMPE_CONFIG_STATUS;
 	}
-
-	aac_sync_fib_slot_release(softs, acp);
 	return (rval);
 }
 
@@ -2777,6 +2626,7 @@
 {
 	uint32_t status;
 	int i;
+	char version_string[160];
 	struct aac_supplement_adapter_info sinf;
 
 	DBCALLED(softs, 1);
@@ -2788,8 +2638,10 @@
 	 * the driver like when the system crashes and the crash dump driver
 	 * gets loaded.
 	 */
-	while (AAC_OUTB_GET(softs) != 0xfffffffful)
-		;
+	if (softs->hwif != AAC_HWIF_SRC && softs->hwif != AAC_HWIF_SRCV) {
+		while (AAC_OUTB_GET(softs) != 0xfffffffful)
+			;
+	}
 
 	/*
 	 * Wait the card to complete booting up before do anything that
@@ -2802,42 +2654,25 @@
 	AAC_BUSYWAIT(AAC_FWSTATUS_GET(softs) & AAC_KERNEL_UP_AND_RUNNING, i);
 	if (i == 0) {
 		cmn_err(CE_CONT, "?Fatal error: controller not ready");
-		aac_fm_ereport(softs, DDI_FM_DEVICE_NO_RESPONSE);
-		ddi_fm_service_impact(softs->devinfo_p, DDI_SERVICE_LOST);
+		aac_fm_ereport(softs, DDI_FM_DEVICE_NO_RESPONSE, DDI_SERVICE_LOST);
 		goto error;
 	}
 
 	/* Read and set card supported options and settings */
 	if (aac_check_firmware(softs) == AACERR) {
-		aac_fm_ereport(softs, DDI_FM_DEVICE_NO_RESPONSE);
-		ddi_fm_service_impact(softs->devinfo_p, DDI_SERVICE_LOST);
+		aac_fm_ereport(softs, DDI_FM_DEVICE_NO_RESPONSE, DDI_SERVICE_LOST);
 		goto error;
 	}
 
-	/* Add interrupt handlers */
-	if (aac_register_intrs(softs) == AACERR) {
-		cmn_err(CE_CONT,
-		    "?Fatal error: interrupts register failed");
-		goto error;
-	}
+	/* Clear out all interrupts */
+	AAC_STATUS_CLR(softs, ~0);
 
-	/* Setup communication space with the card */
+	/* Allocate communication space with the card */
 	if (softs->comm_space_dma_handle == NULL) {
 		if (aac_alloc_comm_space(softs) != AACOK)
 			goto error;
 	}
-	if (aac_setup_comm_space(softs) != AACOK) {
-		cmn_err(CE_CONT, "?Setup communication space failed");
-		aac_fm_ereport(softs, DDI_FM_DEVICE_NO_RESPONSE);
-		ddi_fm_service_impact(softs->devinfo_p, DDI_SERVICE_LOST);
-		goto error;
-	}
 
-#ifdef DEBUG
-	if (aac_get_fw_debug_buffer(softs) != AACOK)
-		cmn_err(CE_CONT, "?firmware UART trace not supported");
-#endif
-
 	/* Allocate slots */
 	if ((softs->total_slots == 0) && (aac_create_slots(softs) != AACOK)) {
 		cmn_err(CE_CONT, "?Fatal error: slots allocate failed");
@@ -2854,13 +2689,12 @@
 		    softs->total_fibs);
 	}
 
-	AAC_STATUS_CLR(softs, ~0); /* Clear out all interrupts */
-	AAC_ENABLE_INTR(softs); /* Enable the interrupts we can handle */
+	if (aac_get_adapter_info(softs, NULL, &sinf) != AACOK) {
+		cmn_err(CE_CONT, "?Query adapter information failed");
+	} else {
+		softs->aac_feature_bits = sinf.FeatureBits;
+		softs->aac_support_opt2 = sinf.SupportedOptions2;
 
-	if (aac_get_adapter_info(softs, NULL, &sinf) == AACOK) {
-		softs->feature_bits = sinf.FeatureBits;
-		softs->support_opt2 = sinf.SupportedOptions2;
-
 		/* Get adapter names */
 		if (CARD_IS_UNKNOWN(softs->card)) {
 			char *p, *p0, *p1;
@@ -2901,12 +2735,23 @@
 					    p0, AAC_PRODUCT_LEN);
 			}
 		}
-	} else {
-		cmn_err(CE_CONT, "?Query adapter information failed");
 	}
 
+	if (!(softs->flags & AAC_FLAGS_SYNC_MODE)) {
+		/* Setup communication space with the card */
+		if (aac_setup_comm_space(softs) != AACOK) {
+			cmn_err(CE_CONT, "?Setup communication space failed");
+			aac_fm_ereport(softs, DDI_FM_DEVICE_NO_RESPONSE, DDI_SERVICE_LOST);
+			goto error;
+		}
+	}
 
-	cmn_err(CE_NOTE,
+#ifdef AAC_DEBUG
+	if (aac_get_fw_debug_buffer(softs) != AACOK)
+		cmn_err(CE_CONT, "?firmware UART trace not supported");
+#endif
+
+	sprintf(version_string,
 	    "!aac driver %d.%02d.%02d-%d, found card: " \
 	    "%s %s(pci0x%x.%x.%x.%x) at 0x%x",
 	    AAC_DRIVER_MAJOR_VERSION,
@@ -2915,13 +2760,14 @@
 	    AAC_DRIVER_BUILD,
 	    softs->vendor_name, softs->product_name,
 	    softs->vendid, softs->devid, softs->subvendid, softs->subsysid,
-	    softs->pci_mem_base_paddr);
+	    softs->pci_mem_base_paddr[0]);
+	cmn_err(CE_NOTE, version_string);
+	AACDB_PRINT(softs, CE_NOTE, version_string);
 
 	/* Perform acceptance of adapter-detected config changes if possible */
 	if (aac_handle_adapter_config_issues(softs) != AACMPE_OK) {
 		cmn_err(CE_CONT, "?Handle adapter config issues failed");
-		aac_fm_ereport(softs, DDI_FM_DEVICE_NO_RESPONSE);
-		ddi_fm_service_impact(softs->devinfo_p, DDI_SERVICE_LOST);
+		aac_fm_ereport(softs, DDI_FM_DEVICE_NO_RESPONSE, DDI_SERVICE_LOST);
 		goto error;
 	}
 
@@ -2931,22 +2777,8 @@
 		goto error;
 	}
 
-	/* Check for JBOD support. Default disable */
-	char *data;
-	if (softs->feature_bits & AAC_FEATURE_SUPPORTED_JBOD) {
-		if ((ddi_prop_lookup_string(DDI_DEV_T_ANY, softs->devinfo_p,
-		    0, "jbod-enable", &data) == DDI_SUCCESS)) {
-			if (strcmp(data, "yes") == 0) {
-				AACDB_PRINT(softs, CE_NOTE,
-				    "Enable JBOD access");
-				softs->flags |= AAC_FLAGS_JBOD;
-			}
-			ddi_prop_free(data);
-		}
-	}
-
 	/* Setup phys. devices */
-	if (softs->flags & (AAC_FLAGS_NONDASD | AAC_FLAGS_JBOD)) {
+	if (softs->flags & AAC_FLAGS_NONDASD) {
 		uint32_t bus_max, tgt_max;
 		uint32_t bus, tgt;
 		int index;
@@ -2987,12 +2819,12 @@
 
 	/* Check dma & acc handles allocated in attach */
 	if (aac_check_dma_handle(softs->comm_space_dma_handle) != DDI_SUCCESS) {
-		ddi_fm_service_impact(softs->devinfo_p, DDI_SERVICE_LOST);
+		aac_fm_service_impact(softs->devinfo_p, DDI_SERVICE_LOST);
 		goto error;
 	}
 
-	if (aac_check_acc_handle(softs->pci_mem_handle) != DDI_SUCCESS) {
-		ddi_fm_service_impact(softs->devinfo_p, DDI_SERVICE_LOST);
+	if (aac_check_acc_handle(softs->pci_mem_handle[0]) != DDI_SUCCESS) {
+		aac_fm_service_impact(softs->devinfo_p, DDI_SERVICE_LOST);
 		goto error;
 	}
 
@@ -2999,7 +2831,7 @@
 	for (i = 0; i < softs->total_slots; i++) {
 		if (aac_check_dma_handle(softs->io_slot[i].fib_dma_handle) !=
 		    DDI_SUCCESS) {
-			ddi_fm_service_impact(softs->devinfo_p,
+			aac_fm_service_impact(softs->devinfo_p,
 			    DDI_SERVICE_LOST);
 			goto error;
 		}
@@ -3031,9 +2863,6 @@
 {
 	DBCALLED(softs, 1);
 
-	aac_unregister_intrs(softs);
-
-	mutex_enter(&softs->io_lock);
 	(void) aac_shutdown(softs);
 
 	if (softs->nondasds) {
@@ -3044,7 +2873,6 @@
 	aac_destroy_fibs(softs);
 	aac_destroy_slots(softs);
 	aac_free_comm_space(softs);
-	mutex_exit(&softs->io_lock);
 }
 
 /*
@@ -3054,14 +2882,11 @@
 int
 aac_sync_mbcommand(struct aac_softstate *softs, uint32_t cmd,
     uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3,
-    uint32_t *statusp)
+    uint32_t *statusp, uint32_t *r1)
 {
 	int timeout;
 	uint32_t status;
 
-	if (statusp != NULL)
-		*statusp = SRB_STATUS_SUCCESS;
-
 	/* Fill in mailbox */
 	AAC_MAILBOX_SET(softs, cmd, arg0, arg1, arg2, arg3);
 
@@ -3071,27 +2896,36 @@
 	/* Then set it to signal the adapter */
 	AAC_NOTIFY(softs, AAC_DB_SYNC_COMMAND);
 
-	/* Spin waiting for the command to complete */
-	timeout = AAC_IMMEDIATE_TIMEOUT * 1000;
-	AAC_BUSYWAIT(AAC_STATUS_GET(softs) & AAC_DB_SYNC_COMMAND, timeout);
-	if (!timeout) {
-		AACDB_PRINT(softs, CE_WARN,
-		    "Sync command timed out after %d seconds (0x%x)!",
-		    AAC_IMMEDIATE_TIMEOUT, AAC_FWSTATUS_GET(softs));
-		return (AACERR);
-	}
+	if ((cmd != AAC_MONKER_SYNCFIB) || (statusp == NULL) || (*statusp != 0)) {
+		if (statusp != NULL)
+			*statusp = SRB_STATUS_SUCCESS;
+		/* Spin waiting for the command to complete */
+		timeout = AAC_IMMEDIATE_TIMEOUT * 1000;
+		AAC_BUSYWAIT(AAC_STATUS_GET(softs) & AAC_DB_SYNC_COMMAND, timeout);
+		if (!timeout) {
+			AACDB_PRINT(softs, CE_WARN,
+				"Sync command %d timed out after %d seconds (0x%x)!",
+				cmd, AAC_IMMEDIATE_TIMEOUT, AAC_FWSTATUS_GET(softs));
+			softs->sync_slot_busy = 0;
+			return (AACERR);
+		}
 
-	/* Clear the completion flag */
-	AAC_STATUS_CLR(softs, AAC_DB_SYNC_COMMAND);
+		/* Clear the completion flag */
+		AAC_STATUS_CLR(softs, AAC_DB_SYNC_COMMAND);
 
-	/* Get the command status */
-	status = AAC_MAILBOX_GET(softs, 0);
-	if (statusp != NULL)
-		*statusp = status;
-	if (status != SRB_STATUS_SUCCESS) {
-		AACDB_PRINT(softs, CE_WARN,
-		    "Sync command fail: status = 0x%x", status);
-		return (AACERR);
+		/* Get the command status */
+		status = AAC_MAILBOX_GET(softs, 0);
+		if (statusp != NULL)
+			*statusp = status;
+		if (status != SRB_STATUS_SUCCESS) {
+			AACDB_PRINT(softs, CE_WARN,
+				"Sync command %d failed: status = 0x%x", cmd, status);
+			softs->sync_slot_busy = 0;
+			return (AACERR);
+		}	
+		if (r1 != NULL) 
+			*r1 = AAC_MAILBOX_GET(softs, 1);
+		softs->sync_slot_busy = 0;
 	}
 
 	return (AACOK);
@@ -3099,37 +2933,48 @@
 
 /*
  * Send a synchronous FIB to the adapter and wait for its completion
- */
+ */            
 static int
 aac_sync_fib(struct aac_softstate *softs, uint16_t cmd, uint16_t fibsize)
 {
-	struct aac_cmd *acp = &softs->sync_ac;
+	struct aac_slot *slotp = softs->sync_slot;
+	ddi_dma_handle_t dma = slotp->fib_dma_handle;
+	uint32_t status = 1;
+	int rval;
 
-	acp->flags = AAC_CMD_SYNC | AAC_CMD_IN_SYNC_SLOT;
-	if (softs->state & AAC_STATE_INTR)
-		acp->flags |= AAC_CMD_NO_CB;
-	else
-		acp->flags |= AAC_CMD_NO_INTR;
+	/* Sync fib only supports 512 bytes */
+	if (fibsize > AAC_FIB_SIZE)
+		return (AACERR);
 
-	acp->ac_comp = aac_sync_complete;
-	acp->timeout = AAC_SYNC_TIMEOUT;
-	acp->fib_size = fibsize;
-
 	/*
-	 * Only need to setup sync fib header, caller should have init
-	 * fib data
+	 * Setup sync fib
+	 * Need not reinitialize FIB header if it's already been filled
+	 * by others like aac_cmd_fib_scsi as aac_cmd.
 	 */
-	aac_cmd_fib_header(softs, acp, cmd);
+	if (slotp->acp == NULL)
+		aac_cmd_fib_header(softs, slotp, cmd, fibsize);
 
-	(void) ddi_dma_sync(acp->slotp->fib_dma_handle, 0, fibsize,
-	    DDI_DMA_SYNC_FORDEV);
+	(void) ddi_dma_sync(dma, 0, fibsize, DDI_DMA_SYNC_FORDEV);
 
-	aac_start_io(softs, acp);
+	/* Give the FIB to the controller, wait for a response. */
+	softs->sync_slot_busy = 1;
+	rval = aac_sync_mbcommand(softs, AAC_MONKER_SYNCFIB,
+	    slotp->fib_phyaddr, 0, 0, 0, &status, NULL);
+	if (rval == AACERR) {
+		AACDB_PRINT(softs, CE_WARN,
+		    "Send sync fib to controller failed");
+		return (AACERR);
+	}
 
-	if (softs->state & AAC_STATE_INTR)
-		return (aac_do_sync_io(softs, acp));
-	else
-		return (aac_do_poll_io(softs, acp));
+	(void) ddi_dma_sync(dma, 0, AAC_FIB_SIZE, DDI_DMA_SYNC_FORCPU);
+
+	if ((aac_check_acc_handle(softs->pci_mem_handle[0]) != DDI_SUCCESS) ||
+	    (aac_check_dma_handle(dma) != DDI_SUCCESS)) {
+		aac_fm_service_impact(softs->devinfo_p, DDI_SERVICE_UNAFFECTED);
+		return (AACERR);
+	}
+
+	return (AACOK);
 }
 
 static void
@@ -3211,11 +3056,11 @@
 	ASSERT(queue == AAC_ADAP_NORM_CMD_Q || queue == AAC_ADAP_NORM_RESP_Q);
 
 	/* Get the producer/consumer indices */
-	(void) ddi_dma_sync(dma, (uintptr_t)softs->qtablep->qt_qindex[queue] - \
-	    (uintptr_t)softs->comm_space, sizeof (uint32_t) * 2,
+	(void) ddi_dma_sync(dma, (uint8_t *)softs->qtablep->qt_qindex[queue] - \
+	    (uint8_t *)softs->comm_space, sizeof (uint32_t) * 2,
 	    DDI_DMA_SYNC_FORCPU);
 	if (aac_check_dma_handle(dma) != DDI_SUCCESS) {
-		ddi_fm_service_impact(softs->devinfo_p, DDI_SERVICE_UNAFFECTED);
+		aac_fm_service_impact(softs->devinfo_p, DDI_SERVICE_UNAFFECTED);
 		return (AACERR);
 	}
 
@@ -3238,8 +3083,8 @@
 	/* Fill in queue entry */
 	ddi_put32(acc, &((softs->qentries[queue] + pi)->aq_fib_size), fib_size);
 	ddi_put32(acc, &((softs->qentries[queue] + pi)->aq_fib_addr), fib_addr);
-	(void) ddi_dma_sync(dma, (uintptr_t)(softs->qentries[queue] + pi) - \
-	    (uintptr_t)softs->comm_space, sizeof (struct aac_queue_entry),
+	(void) ddi_dma_sync(dma, (uint8_t *)(softs->qentries[queue] + pi) - \
+	    (uint8_t *)softs->comm_space, sizeof (struct aac_queue_entry),
 	    DDI_DMA_SYNC_FORDEV);
 
 	/* Update producer index */
@@ -3246,8 +3091,8 @@
 	ddi_put32(acc, &softs->qtablep->qt_qindex[queue][AAC_PRODUCER_INDEX],
 	    pi + 1);
 	(void) ddi_dma_sync(dma,
-	    (uintptr_t)&softs->qtablep->qt_qindex[queue][AAC_PRODUCER_INDEX] - \
-	    (uintptr_t)softs->comm_space, sizeof (uint32_t),
+	    (uint8_t *)&softs->qtablep->qt_qindex[queue][AAC_PRODUCER_INDEX] - \
+	    (uint8_t *)softs->comm_space, sizeof (uint32_t),
 	    DDI_DMA_SYNC_FORDEV);
 
 	if (aac_qinfo[queue].notify != 0)
@@ -3272,8 +3117,8 @@
 	ASSERT(idxp);
 
 	/* Get the producer/consumer indices */
-	(void) ddi_dma_sync(dma, (uintptr_t)softs->qtablep->qt_qindex[queue] - \
-	    (uintptr_t)softs->comm_space, sizeof (uint32_t) * 2,
+	(void) ddi_dma_sync(dma, (uint8_t *)softs->qtablep->qt_qindex[queue] - \
+	    (uint8_t *)softs->comm_space, sizeof (uint32_t) * 2,
 	    DDI_DMA_SYNC_FORCPU);
 	pi = ddi_get32(acc,
 	    &softs->qtablep->qt_qindex[queue][AAC_PRODUCER_INDEX]);
@@ -3299,11 +3144,11 @@
 		ci = 0;
 
 	/* Fetch the entry */
-	(void) ddi_dma_sync(dma, (uintptr_t)(softs->qentries[queue] + pi) - \
-	    (uintptr_t)softs->comm_space, sizeof (struct aac_queue_entry),
+	(void) ddi_dma_sync(dma, (uint8_t *)(softs->qentries[queue] + pi) - \
+	    (uint8_t *)softs->comm_space, sizeof (struct aac_queue_entry),
 	    DDI_DMA_SYNC_FORCPU);
 	if (aac_check_dma_handle(dma) != DDI_SUCCESS) {
-		ddi_fm_service_impact(softs->devinfo_p, DDI_SERVICE_UNAFFECTED);
+		aac_fm_service_impact(softs->devinfo_p, DDI_SERVICE_UNAFFECTED);
 		return (AACERR);
 	}
 
@@ -3329,8 +3174,8 @@
 	ddi_put32(acc, &softs->qtablep->qt_qindex[queue][AAC_CONSUMER_INDEX],
 	    ci + 1);
 	(void) ddi_dma_sync(dma,
-	    (uintptr_t)&softs->qtablep->qt_qindex[queue][AAC_CONSUMER_INDEX] - \
-	    (uintptr_t)softs->comm_space, sizeof (uint32_t),
+	    (uint8_t *)&softs->qtablep->qt_qindex[queue][AAC_CONSUMER_INDEX] - \
+	    (uint8_t *)softs->comm_space, sizeof (uint32_t),
 	    DDI_DMA_SYNC_FORDEV);
 
 	if (unfull && aac_qinfo[queue].notify != 0)
@@ -3338,11 +3183,14 @@
 	return (AACOK);
 }
 
+/*
+ * Request information of the container cid
+ */
 static struct aac_mntinforesp *
-aac_get_mntinfo(struct aac_softstate *softs, int cid)
+aac_get_container_info(struct aac_softstate *softs, int cid)
 {
-	ddi_acc_handle_t acc = softs->sync_ac.slotp->fib_acc_handle;
-	struct aac_fib *fibp = softs->sync_ac.slotp->fibp;
+	ddi_acc_handle_t acc = softs->sync_slot->fib_acc_handle;
+	struct aac_fib *fibp = softs->sync_slot->fibp;
 	struct aac_mntinfo *mi = (struct aac_mntinfo *)&fibp->data[0];
 	struct aac_mntinforesp *mir;
 
@@ -3367,37 +3215,26 @@
 static int
 aac_get_container_count(struct aac_softstate *softs, int *count)
 {
-	ddi_acc_handle_t acc;
+	ddi_acc_handle_t acc = softs->sync_slot->fib_acc_handle;
 	struct aac_mntinforesp *mir;
-	int rval;
 
-	(void) aac_sync_fib_slot_bind(softs, &softs->sync_ac);
-	acc = softs->sync_ac.slotp->fib_acc_handle;
-
-	if ((mir = aac_get_mntinfo(softs, 0)) == NULL) {
-		rval = AACERR;
-		goto finish;
-	}
+	if ((mir = aac_get_container_info(softs, 0)) == NULL)
+		return (AACERR);
 	*count = ddi_get32(acc, &mir->MntRespCount);
 	if (*count > AAC_MAX_LD) {
 		AACDB_PRINT(softs, CE_CONT,
 		    "container count(%d) > AAC_MAX_LD", *count);
-		rval = AACERR;
-		goto finish;
+		return (AACERR);
 	}
-	rval = AACOK;
-
-finish:
-	aac_sync_fib_slot_release(softs, &softs->sync_ac);
-	return (rval);
+	return (AACOK);
 }
 
 static int
 aac_get_container_uid(struct aac_softstate *softs, uint32_t cid, uint32_t *uid)
 {
-	ddi_acc_handle_t acc = softs->sync_ac.slotp->fib_acc_handle;
+	ddi_acc_handle_t acc = softs->sync_slot->fib_acc_handle;
 	struct aac_Container *ct = (struct aac_Container *) \
-	    &softs->sync_ac.slotp->fibp->data[0];
+	    &softs->sync_slot->fibp->data[0];
 
 	bzero(ct, sizeof (*ct) - CT_PACKET_SIZE);
 	ddi_put32(acc, &ct->Command, VM_ContainerConfig);
@@ -3414,78 +3251,44 @@
 	return (AACOK);
 }
 
-/*
- * Request information of the container cid
- */
-static struct aac_mntinforesp *
-aac_get_container_info(struct aac_softstate *softs, int cid)
-{
-	ddi_acc_handle_t acc = softs->sync_ac.slotp->fib_acc_handle;
-	struct aac_mntinforesp *mir;
-	int rval_uid;
-	uint32_t uid;
-
-	/* Get container UID first so that it will not overwrite mntinfo */
-	rval_uid = aac_get_container_uid(softs, cid, &uid);
-
-	/* Get container basic info */
-	if ((mir = aac_get_mntinfo(softs, cid)) == NULL) {
-		AACDB_PRINT(softs, CE_CONT,
-		    "query container %d info failed", cid);
-		return (NULL);
-	}
-	if (ddi_get32(acc, &mir->MntObj.VolType) == CT_NONE)
-		return (mir);
-	if (rval_uid != AACOK) {
-		AACDB_PRINT(softs, CE_CONT,
-		    "query container %d uid failed", cid);
-		return (NULL);
-	}
-
-	ddi_put32(acc, &mir->Status, uid);
-	return (mir);
-}
-
-static enum aac_cfg_event
+static int
 aac_probe_container(struct aac_softstate *softs, uint32_t cid)
 {
-	enum aac_cfg_event event = AAC_CFG_NULL_NOEXIST;
 	struct aac_container *dvp = &softs->containers[cid];
+	ddi_acc_handle_t acc = softs->sync_slot->fib_acc_handle;
 	struct aac_mntinforesp *mir;
-	ddi_acc_handle_t acc;
+	uint64_t size;
+	uint32_t uid;
 
-	(void) aac_sync_fib_slot_bind(softs, &softs->sync_ac);
-	acc = softs->sync_ac.slotp->fib_acc_handle;
-
 	/* Get container basic info */
-	if ((mir = aac_get_container_info(softs, cid)) == NULL) {
-		/* AAC_CFG_NULL_NOEXIST */
-		goto finish;
-	}
+	if ((mir = aac_get_container_info(softs, cid)) == NULL)
+		return (AACERR);
 
 	if (ddi_get32(acc, &mir->MntObj.VolType) == CT_NONE) {
-		if (AAC_DEV_IS_VALID(&dvp->dev)) {
+		if (dvp->dev.valid) {
 			AACDB_PRINT(softs, CE_NOTE,
 			    ">>> Container %d deleted", cid);
-			dvp->dev.flags &= ~AAC_DFLAG_VALID;
-			event = AAC_CFG_DELETE;
+			dvp->dev.valid = 0;
+			(void) aac_dr_event(softs, dvp->cid, -1,
+			    AAC_DEV_OFFLINE);
 		}
-		/* AAC_CFG_NULL_NOEXIST */
 	} else {
-		uint64_t size;
-		uint32_t uid;
+		size = AAC_MIR_SIZE(softs, acc, mir);
 
-		event = AAC_CFG_NULL_EXIST;
+		/* Get container UID */
+		if (aac_get_container_uid(softs, cid, &uid) == AACERR) {
+			AACDB_PRINT(softs, CE_CONT,
+			    "query container %d uid failed", cid);
+			return (AACERR);
+		}
+		AACDB_PRINT(softs, CE_CONT, "uid=0x%08x", uid);
 
-		size = AAC_MIR_SIZE(softs, acc, mir);
-		uid = ddi_get32(acc, &mir->Status);
-		if (AAC_DEV_IS_VALID(&dvp->dev)) {
+		if (dvp->dev.valid) {
 			if (dvp->uid != uid) {
 				AACDB_PRINT(softs, CE_WARN,
 				    ">>> Container %u uid changed to %d",
 				    cid, uid);
 				dvp->uid = uid;
-				event = AAC_CFG_CHANGE;
 			}
 			if (dvp->size != size) {
 				AACDB_PRINT(softs, CE_NOTE,
@@ -3492,7 +3295,6 @@
 				    ">>> Container %u size changed to %"PRIu64,
 				    cid, size);
 				dvp->size = size;
-				event = AAC_CFG_CHANGE;
 			}
 		} else { /* Init new container */
 			AACDB_PRINT(softs, CE_NOTE,
@@ -3503,7 +3305,7 @@
 			    ddi_get32(acc, &mir->MntObj.Capacity),
 			    ddi_get32(acc, &mir->MntObj.VolType),
 			    mir->MntObj.FileSystemName);
-			dvp->dev.flags |= AAC_DFLAG_VALID;
+			dvp->dev.valid = 1;
 			dvp->dev.type = AAC_DEV_LD;
 
 			dvp->cid = cid;
@@ -3511,14 +3313,11 @@
 			dvp->size = size;
 			dvp->locked = 0;
 			dvp->deleted = 0;
-
-			event = AAC_CFG_ADD;
+			(void) aac_dr_event(softs, dvp->cid, -1,
+			    AAC_DEV_ONLINE);
 		}
 	}
-
-finish:
-	aac_sync_fib_slot_release(softs, &softs->sync_ac);
-	return (event);
+	return (AACOK);
 }
 
 /*
@@ -3534,67 +3333,33 @@
 	count = softs->container_count;
 	if (aac_get_container_count(softs, &count) == AACERR)
 		return (AACERR);
-
 	for (i = total = 0; i < count; i++) {
-		enum aac_cfg_event event = aac_probe_container(softs, i);
-		if ((event != AAC_CFG_NULL_NOEXIST) &&
-		    (event != AAC_CFG_NULL_EXIST)) {
-			(void) aac_handle_dr(softs, i, -1, event);
+		if (aac_probe_container(softs, i) == AACOK)
 			total++;
-		}
 	}
-
 	if (count < softs->container_count) {
 		struct aac_container *dvp;
 
 		for (dvp = &softs->containers[count];
 		    dvp < &softs->containers[softs->container_count]; dvp++) {
-			if (!AAC_DEV_IS_VALID(&dvp->dev))
+			if (dvp->dev.valid == 0)
 				continue;
 			AACDB_PRINT(softs, CE_NOTE, ">>> Container %d deleted",
 			    dvp->cid);
-			dvp->dev.flags &= ~AAC_DFLAG_VALID;
-			(void) aac_handle_dr(softs, dvp->cid, -1,
-			    AAC_CFG_DELETE);
+			dvp->dev.valid = 0;
+			(void) aac_dr_event(softs, dvp->cid, -1,
+			    AAC_DEV_OFFLINE);
 		}
 	}
-
 	softs->container_count = count;
-	AACDB_PRINT(softs, CE_CONT, "?Total %d container(s) found", total);
+	AACDB_PRINT(softs, CE_CONT, "Total %d container(s) found", total);
 	return (AACOK);
 }
 
 static int
-aac_probe_jbod(struct aac_softstate *softs, int tgt, int event)
-{
-	ASSERT(AAC_MAX_LD <= tgt);
-	ASSERT(tgt < AAC_MAX_DEV(softs));
-	struct aac_device *dvp;
-	dvp = AAC_DEV(softs, tgt);
-
-	switch (event) {
-	case AAC_CFG_ADD:
-		AACDB_PRINT(softs, CE_NOTE,
-		    ">>> Jbod %d added", tgt - AAC_MAX_LD);
-		dvp->flags |= AAC_DFLAG_VALID;
-		dvp->type = AAC_DEV_PD;
-		break;
-	case AAC_CFG_DELETE:
-		AACDB_PRINT(softs, CE_NOTE,
-		    ">>> Jbod %d deleted", tgt - AAC_MAX_LD);
-		dvp->flags &= ~AAC_DFLAG_VALID;
-		break;
-	default:
-		return (AACERR);
-	}
-	(void) aac_handle_dr(softs, tgt, 0, event);
-	return (AACOK);
-}
-
-static int
 aac_alloc_comm_space(struct aac_softstate *softs)
 {
-	size_t rlen;
+	size_t rlen, maxsize;
 	ddi_dma_cookie_t cookie;
 	uint_t cookien;
 
@@ -3609,10 +3374,15 @@
 		    "Cannot alloc dma handle for communication area");
 		goto error;
 	}
+
+	maxsize = sizeof(struct aac_comm_space);
+	if ((softs->flags & AAC_FLAGS_NEW_COMM_TYPE1) ||
+		(softs->flags & AAC_FLAGS_NEW_COMM_TYPE2)) 
+		maxsize += (softs->aac_max_fibs-1) * sizeof(uint32_t);
 	if (ddi_dma_mem_alloc(
 	    softs->comm_space_dma_handle,
-	    sizeof (struct aac_comm_space),
-	    &softs->acc_attr,
+	    maxsize,
+	    &aac_acc_attr,
 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
 	    DDI_DMA_SLEEP,
 	    NULL,
@@ -3627,7 +3397,7 @@
 	    softs->comm_space_dma_handle,
 	    NULL,
 	    (caddr_t)softs->comm_space,
-	    sizeof (struct aac_comm_space),
+	    maxsize,
 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
 	    DDI_DMA_SLEEP,
 	    NULL,
@@ -3637,6 +3407,8 @@
 		    "DMA bind failed for communication area");
 		goto error;
 	}
+
+	bzero(softs->comm_space, maxsize);
 	softs->comm_space_phyaddr = cookie.dmac_address;
 
 	return (AACOK);
@@ -3655,7 +3427,6 @@
 static void
 aac_free_comm_space(struct aac_softstate *softs)
 {
-
 	(void) ddi_dma_unbind_handle(softs->comm_space_dma_handle);
 	ddi_dma_mem_free(&softs->comm_space_acc_handle);
 	softs->comm_space_acc_handle = NULL;
@@ -3679,25 +3450,41 @@
 
 	comm_space_phyaddr = softs->comm_space_phyaddr;
 
+	/* reset rrq index */
+	softs->aac_host_rrq_idx = 0;
+
 	/* Setup adapter init struct */
 	initp = &softs->comm_space->init_data;
-	bzero(initp, sizeof (struct aac_adapter_init));
 
 	ddi_put32(acc, &initp->InitStructRevision, AAC_INIT_STRUCT_REVISION);
 	ddi_put32(acc, &initp->HostElapsedSeconds, ddi_get_time());
+	ddi_put32(acc, &initp->MiniPortRevision,AAC_INIT_STRUCT_MINIPORT_REVISION);
 
 	/* Setup new/old comm. specific data */
-	if (softs->flags & AAC_FLAGS_RAW_IO) {
+	if (softs->flags & AAC_FLAGS_NEW_COMM) {
 		uint32_t init_flags = 0;
 
-		if (softs->flags & AAC_FLAGS_NEW_COMM)
-			init_flags |= AAC_INIT_FLAGS_NEW_COMM_SUPPORTED;
-		/* AAC_SUPPORTED_POWER_MANAGEMENT */
-		init_flags |= AAC_INIT_FLAGS_DRIVER_SUPPORTS_PM;
-		init_flags |= AAC_INIT_FLAGS_DRIVER_USES_UTC_TIME;
+		init_flags |= AAC_INIT_FLAGS_NEW_COMM_SUPPORTED;
+		if (softs->flags & AAC_FLAGS_NEW_COMM_TYPE1) {
+			init_flags |= (AAC_INITFLAGS_NEW_COMM_TYPE1_SUPPORTED |
+				AAC_INITFLAGS_DRIVER_SUPPORTS_FAST_JBOD);
+			ddi_put32(acc, &initp->InitStructRevision,
+				AAC_INIT_STRUCT_REVISION_6);
+		} else if (softs->flags & AAC_FLAGS_NEW_COMM_TYPE2) {
+			init_flags |= (AAC_INITFLAGS_NEW_COMM_TYPE2_SUPPORTED |
+				AAC_INITFLAGS_DRIVER_SUPPORTS_FAST_JBOD);
+			ddi_put32(acc, &initp->InitStructRevision,
+				AAC_INIT_STRUCT_REVISION_7);
+			ddi_put32(acc, &initp->MiniPortRevision, 0L);
+		} else { 
+			ddi_put32(acc, &initp->InitStructRevision,
+				AAC_INIT_STRUCT_REVISION_4);
+		}
+		if (softs->aac_support_opt2 & AAC_SUPPORTED_POWER_MANAGEMENT) {
+			init_flags |= AAC_INIT_FLAGS_DRIVER_SUPPORTS_PM;
+			init_flags |= AAC_INIT_FLAGS_DRIVER_USES_UTC_TIME;
+		}
 
-		ddi_put32(acc, &initp->InitStructRevision,
-		    AAC_INIT_STRUCT_REVISION_4);
 		ddi_put32(acc, &initp->InitFlags, init_flags);
 		/* Setup the preferred settings */
 		ddi_put32(acc, &initp->MaxIoCommands, softs->aac_max_fibs);
@@ -3704,6 +3491,9 @@
 		ddi_put32(acc, &initp->MaxIoSize,
 		    (softs->aac_max_sectors << 9));
 		ddi_put32(acc, &initp->MaxFibSize, softs->aac_max_fib_size);
+		ddi_put32(acc, &initp->MaxNumAif, softs->aac_max_aif);
+		ddi_put32(acc, &initp->HostRRQ_AddrLow, 
+			comm_space_phyaddr + offsetof(struct aac_comm_space,aac_host_rrq));
 	} else {
 		/*
 		 * Tells the adapter about the physical location of various
@@ -3721,8 +3511,6 @@
 		    offsetof(struct aac_comm_space, adapter_print_buf));
 		ddi_put32(acc, &initp->PrintfBufferSize,
 		    AAC_ADAPTER_PRINT_BUFSIZE);
-		ddi_put32(acc, &initp->MiniPortRevision,
-		    AAC_INIT_STRUCT_MINIPORT_REVISION);
 		ddi_put32(acc, &initp->HostPhysMemPages, AAC_MAX_PFN);
 
 		qoffset = (comm_space_phyaddr + \
@@ -3806,10 +3594,11 @@
 	(void) ddi_dma_sync(dma, 0, 0, DDI_DMA_SYNC_FORDEV);
 
 	/* Send init structure to the card */
+	softs->sync_slot_busy = 1;
 	if (aac_sync_mbcommand(softs, AAC_MONKER_INITSTRUCT,
 	    comm_space_phyaddr + \
 	    offsetof(struct aac_comm_space, init_data),
-	    0, 0, 0, NULL) == AACERR) {
+	    0, 0, 0, NULL, NULL) == AACERR) {
 		AACDB_PRINT(softs, CE_WARN,
 		    "Cannot send init structure to adapter");
 		return (AACERR);
@@ -3885,8 +3674,8 @@
 		switch (page) {
 		case 0x00:
 			/* Supported VPD pages */
-			if (vpdp == NULL ||
-			    bp->b_bcount < (AAC_VPD_PAGE_DATA + 3))
+			if (vpdp == NULL || 
+				bp->b_bcount < (AAC_VPD_PAGE_DATA + 3))
 				return;
 			bzero(vpdp, AAC_VPD_PAGE_LENGTH);
 			vpdp[AAC_VPD_PAGE_CODE] = 0x00;
@@ -3902,7 +3691,7 @@
 		case 0x80:
 			/* Unit serial number page */
 			if (vpdp == NULL ||
-			    bp->b_bcount < (AAC_VPD_PAGE_DATA + 8))
+				bp->b_bcount < (AAC_VPD_PAGE_DATA + 8))
 				return;
 			bzero(vpdp, AAC_VPD_PAGE_LENGTH);
 			vpdp[AAC_VPD_PAGE_CODE] = 0x80;
@@ -3917,7 +3706,7 @@
 		case 0x83:
 			/* Device identification page */
 			if (vpdp == NULL ||
-			    bp->b_bcount < (AAC_VPD_PAGE_DATA + 32))
+				bp->b_bcount < (AAC_VPD_ID_DATA + 32))
 				return;
 			bzero(vpdp, AAC_VPD_PAGE_LENGTH);
 			vpdp[AAC_VPD_PAGE_CODE] = 0x83;
@@ -3939,11 +3728,10 @@
 			sp = aac_vendor_id(softs, sp);
 			sp = aac_product_id(softs, sp);
 			sp = aac_lun_serialno(softs, tgt, sp);
-			idp[AAC_VPD_ID_LENGTH] = (uintptr_t)sp - \
-			    (uintptr_t)&idp[AAC_VPD_ID_DATA];
+			idp[AAC_VPD_ID_LENGTH] = sp - &idp[AAC_VPD_ID_DATA];
 
-			vpdp[AAC_VPD_PAGE_LENGTH] = (uintptr_t)sp - \
-			    (uintptr_t)&vpdp[AAC_VPD_PAGE_DATA];
+			vpdp[AAC_VPD_PAGE_LENGTH] =
+			    sp - &vpdp[AAC_VPD_PAGE_DATA];
 			pkt->pkt_state |= STATE_XFERRED_DATA;
 			break;
 
@@ -3990,18 +3778,26 @@
     union scsi_cdb *cdbp, struct buf *bp, int capacity)
 {
 	uchar_t pagecode;
+	struct mode_format *page3p;
+	struct mode_geometry *page4p;
 	struct mode_header *headerp;
-	struct mode_header_g1 *g1_headerp;
 	unsigned int ncyl;
-	caddr_t sense_data;
-	caddr_t next_page;
-	size_t sdata_size;
-	size_t pages_size;
-	int unsupport_page = 0;
+	union {
+		struct mode_header header;
+		struct {
+			uchar_t header[MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH];
+			struct mode_format page;
+		} page3;
+		struct {
+			uchar_t header[MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH];
+			struct mode_geometry page;
+		} page4;
+		struct {
+			uchar_t header[MODE_HEADER_LENGTH + MODE_BLK_DESC_LENGTH];
+			struct mode_control_scsi3 page;
+		} pageA;
+	} mode;
 
-	ASSERT(cdbp->scc_cmd == SCMD_MODE_SENSE ||
-	    cdbp->scc_cmd == SCMD_MODE_SENSE_G1);
-
 	if (!(bp && bp->b_un.b_addr && bp->b_bcount))
 		return;
 
@@ -4008,89 +3804,26 @@
 	if (bp->b_flags & (B_PHYS | B_PAGEIO))
 		bp_mapin(bp);
 	pkt->pkt_state |= STATE_XFERRED_DATA;
-	pagecode = cdbp->cdb_un.sg.scsi[0] & 0x3F;
+	bzero(&mode, sizeof(mode));
+	bzero(bp->b_un.b_addr, bp->b_bcount);
+	pagecode = cdbp->cdb_un.sg.scsi[0];
+	headerp = &mode.header;
 
-	/* calculate the size of needed buffer */
-	if (cdbp->scc_cmd == SCMD_MODE_SENSE)
-		sdata_size = MODE_HEADER_LENGTH;
-	else /* must be SCMD_MODE_SENSE_G1 */
-		sdata_size = MODE_HEADER_LENGTH_G1;
-
-	pages_size = 0;
 	switch (pagecode) {
+	/* SBC-3 7.1.3.3 Format device page */
 	case SD_MODE_SENSE_PAGE3_CODE:
-		pages_size += sizeof (struct mode_format);
-		break;
-
-	case SD_MODE_SENSE_PAGE4_CODE:
-		pages_size += sizeof (struct mode_geometry);
-		break;
-
-	case MODEPAGE_CTRL_MODE:
-		if (softs->flags & AAC_FLAGS_LBA_64BIT) {
-			pages_size += sizeof (struct mode_control_scsi3);
-		} else {
-			unsupport_page = 1;
-		}
-		break;
-
-	case MODEPAGE_ALLPAGES:
-		if (softs->flags & AAC_FLAGS_LBA_64BIT) {
-			pages_size += sizeof (struct mode_format) +
-			    sizeof (struct mode_geometry) +
-			    sizeof (struct mode_control_scsi3);
-		} else {
-			pages_size += sizeof (struct mode_format) +
-			    sizeof (struct mode_geometry);
-		}
-		break;
-
-	default:
-		/* unsupported pages */
-		unsupport_page = 1;
-	}
-
-	/* allocate buffer to fill the send data */
-	sdata_size += pages_size;
-	sense_data = kmem_zalloc(sdata_size, KM_SLEEP);
-
-	if (cdbp->scc_cmd == SCMD_MODE_SENSE) {
-		headerp = (struct mode_header *)sense_data;
-		headerp->length = MODE_HEADER_LENGTH + pages_size -
-		    sizeof (headerp->length);
-		headerp->bdesc_length = 0;
-		next_page = sense_data + sizeof (struct mode_header);
-	} else {
-		g1_headerp = (void *)sense_data;
-		g1_headerp->length = BE_16(MODE_HEADER_LENGTH_G1 + pages_size -
-		    sizeof (g1_headerp->length));
-		g1_headerp->bdesc_length = 0;
-		next_page = sense_data + sizeof (struct mode_header_g1);
-	}
-
-	if (unsupport_page)
-		goto finish;
-
-	if (pagecode == SD_MODE_SENSE_PAGE3_CODE ||
-	    pagecode == MODEPAGE_ALLPAGES) {
-		/* SBC-3 7.1.3.3 Format device page */
-		struct mode_format *page3p;
-
-		page3p = (void *)next_page;
+		headerp->bdesc_length = MODE_BLK_DESC_LENGTH;
+		page3p = &mode.page3.page;
 		page3p->mode_page.code = SD_MODE_SENSE_PAGE3_CODE;
 		page3p->mode_page.length = sizeof (struct mode_format);
 		page3p->data_bytes_sect = BE_16(AAC_SECTOR_SIZE);
 		page3p->sect_track = BE_16(AAC_SECTORS_PER_TRACK);
+		break;
 
-		next_page += sizeof (struct mode_format);
-	}
-
-	if (pagecode == SD_MODE_SENSE_PAGE4_CODE ||
-	    pagecode == MODEPAGE_ALLPAGES) {
-		/* SBC-3 7.1.3.8 Rigid disk device geometry page */
-		struct mode_geometry *page4p;
-
-		page4p = (void *)next_page;
+	/* SBC-3 7.1.3.8 Rigid disk device geometry page */
+	case SD_MODE_SENSE_PAGE4_CODE:
+		headerp->bdesc_length = MODE_BLK_DESC_LENGTH;
+		page4p = &mode.page4.page;
 		page4p->mode_page.code = SD_MODE_SENSE_PAGE4_CODE;
 		page4p->mode_page.length = sizeof (struct mode_geometry);
 		page4p->heads = AAC_NUMBER_OF_HEADS;
@@ -4099,27 +3832,57 @@
 		page4p->cyl_lb = ncyl & 0xff;
 		page4p->cyl_mb = (ncyl >> 8) & 0xff;
 		page4p->cyl_ub = (ncyl >> 16) & 0xff;
+		break;
 
-		next_page += sizeof (struct mode_geometry);
+	case MODEPAGE_CTRL_MODE: /* 64-bit LBA need large sense data */
+		if (softs->flags & AAC_FLAGS_LBA_64BIT) {
+			struct mode_control_scsi3 *mctl;
+
+			headerp->bdesc_length = MODE_BLK_DESC_LENGTH;
+			mctl = &mode.pageA.page;
+			mctl->mode_page.code = MODEPAGE_CTRL_MODE;
+			mctl->mode_page.length =
+			    sizeof (struct mode_control_scsi3) -
+			    sizeof (struct mode_page);
+			mctl->d_sense = 1;
+		}
+		break;
 	}
+	bcopy(&mode, bp->b_un.b_addr, 
+		(bp->b_bcount < sizeof(mode)) ? bp->b_bcount : sizeof(mode));
+}
 
-	if ((pagecode == MODEPAGE_CTRL_MODE || pagecode == MODEPAGE_ALLPAGES) &&
-	    softs->flags & AAC_FLAGS_LBA_64BIT) {
-		/* 64-bit LBA need large sense data */
-		struct mode_control_scsi3 *mctl;
+/*
+ * Start/Stop unit (Power Management)
+ */
+static void
+aac_startstop(struct aac_softstate *softs, union scsi_cdb *cdbp, uint32_t cid)
+{
+	ddi_acc_handle_t acc = softs->sync_slot->fib_acc_handle;
+	struct aac_fib *fibp = softs->sync_slot->fibp;
+	struct aac_Container *cmd;
+	struct aac_Container_resp *resp;
+	uint32_t resp_status;
+	int rval;
 
-		mctl = (void *)next_page;
-		mctl->mode_page.code = MODEPAGE_CTRL_MODE;
-		mctl->mode_page.length =
-		    sizeof (struct mode_control_scsi3) -
-		    sizeof (struct mode_page);
-		mctl->d_sense = 1;
-	}
+	/* Get adapter config status */
+	cmd = (struct aac_Container *)&fibp->data[0];
 
-finish:
-	/* copyout the valid data. */
-	bcopy(sense_data, bp->b_un.b_addr, min(sdata_size, bp->b_bcount));
-	kmem_free(sense_data, sdata_size);
+	bzero(cmd, sizeof (*cmd) - CT_PACKET_SIZE);
+	ddi_put32(acc, &cmd->Command, VM_ContainerConfig);
+	ddi_put32(acc, &cmd->CTCommand.command, CT_PM_DRIVER_SUPPORT);
+	ddi_put32(acc, &cmd->CTCommand.param[0], cdbp->cdb_opaque[4] & 1 ?
+		AAC_PM_DRIVERSUP_START_UNIT : AAC_PM_DRIVERSUP_STOP_UNIT);
+	ddi_put32(acc, &cmd->CTCommand.param[1], cid); 
+	ddi_put32(acc, &cmd->CTCommand.param[2], cdbp->cdb_opaque[1] & 1);
+
+	rval = aac_sync_fib(softs, ContainerCommand,
+		AAC_FIB_SIZEOF(struct aac_Container));
+
+	resp = (struct aac_Container_resp *)cmd;
+	resp_status = ddi_get32(acc, &resp->Status);
+	if (rval != AACOK || resp_status != 0)
+		AACDB_PRINT(softs, CE_WARN, "Cannot start/stop a unit");
 }
 
 static int
@@ -4146,26 +3909,18 @@
     scsi_hba_tran_t *tran, struct scsi_device *sd)
 {
 	struct aac_softstate *softs = AAC_TRAN2SOFTS(tran);
-#if defined(DEBUG) || defined(__lock_lint)
+#if defined(AAC_DEBUG) || defined(__lock_lint)
 	int ctl = ddi_get_instance(softs->devinfo_p);
 #endif
-	uint16_t tgt = sd->sd_address.a_target;
-	uint8_t lun = sd->sd_address.a_lun;
+	int tgt = sd->sd_address.a_target;
+	int lun = sd->sd_address.a_lun;
 	struct aac_device *dvp;
 
 	DBCALLED(softs, 2);
 
 	if (ndi_dev_is_persistent_node(tgt_dip) == 0) {
-		/*
-		 * If no persistent node exist, we don't allow .conf node
-		 * to be created.
-		 */
-		if (aac_find_child(softs, tgt, lun) != NULL) {
-			if (ndi_merge_node(tgt_dip, aac_name_node) !=
-			    DDI_SUCCESS)
-				/* Create this .conf node */
-				return (DDI_SUCCESS);
-		}
+		(void) ndi_merge_node(tgt_dip, aac_name_node);
+		ddi_set_name_addr(tgt_dip, NULL);
 		return (DDI_FAILURE);
 	}
 
@@ -4174,7 +3929,7 @@
 	 * detected and valid
 	 */
 	mutex_enter(&softs->io_lock);
-	if (tgt >= AAC_MAX_DEV(softs)) {
+	if (tgt < 0 || tgt >= AAC_MAX_DEV(softs)) {
 		AACDB_PRINT_TRAN(softs,
 		    "aac_tran_tgt_init: c%dt%dL%d out", ctl, tgt, lun);
 		mutex_exit(&softs->io_lock);
@@ -4181,9 +3936,9 @@
 		return (DDI_FAILURE);
 	}
 
+	dvp = AAC_DEV(softs, tgt);
 	if (tgt < AAC_MAX_LD) {
-		dvp = (struct aac_device *)&softs->containers[tgt];
-		if (lun != 0 || !AAC_DEV_IS_VALID(dvp)) {
+		if (dvp == NULL || !(dvp->valid) || lun != 0) {
 			AACDB_PRINT_TRAN(softs, "aac_tran_tgt_init: c%dt%dL%d",
 			    ctl, tgt, lun);
 			mutex_exit(&softs->io_lock);
@@ -4197,27 +3952,8 @@
 		if (softs->containers[tgt].dev.dip == NULL &&
 		    strcmp(ddi_driver_name(sd->sd_dev), "sd") == 0)
 			softs->containers[tgt].dev.dip = tgt_dip;
-	} else {
-		dvp = (struct aac_device *)&softs->nondasds[AAC_PD(tgt)];
-		/*
-		 * Save the tgt_dip for the given target if one doesn't exist
-		 * already. Dip's for non-existance tgt's will be cleared in
-		 * tgt_free.
-		 */
-
-		if (softs->nondasds[AAC_PD(tgt)].dev.dip  == NULL &&
-		    strcmp(ddi_driver_name(sd->sd_dev), "sd") == 0)
-			softs->nondasds[AAC_PD(tgt)].dev.dip  = tgt_dip;
 	}
 
-	if (softs->flags & AAC_FLAGS_BRKUP) {
-		if (ndi_prop_update_int(DDI_DEV_T_NONE, tgt_dip,
-		    "buf_break", 1) != DDI_PROP_SUCCESS) {
-			cmn_err(CE_CONT, "unable to create "
-			    "property for t%dL%d (buf_break)", tgt, lun);
-		}
-	}
-
 	AACDB_PRINT(softs, CE_NOTE,
 	    "aac_tran_tgt_init: c%dt%dL%d ok (%s)", ctl, tgt, lun,
 	    (dvp->type == AAC_DEV_PD) ? "pd" : "ld");
@@ -4237,14 +3973,10 @@
 	int tgt = sd->sd_address.a_target;
 
 	mutex_enter(&softs->io_lock);
-	if (tgt < AAC_MAX_LD) {
-		if (softs->containers[tgt].dev.dip == tgt_dip)
-			softs->containers[tgt].dev.dip = NULL;
-	} else {
-		if (softs->nondasds[AAC_PD(tgt)].dev.dip == tgt_dip)
-			softs->nondasds[AAC_PD(tgt)].dev.dip = NULL;
-		softs->nondasds[AAC_PD(tgt)].dev.flags &= ~AAC_DFLAG_VALID;
-	}
+	if (tgt < AAC_MAX_LD)
+		softs->containers[tgt].dev.dip = NULL;
+	else
+		softs->nondasds[AAC_PD(tgt)].dev.valid = 0;
 	mutex_exit(&softs->io_lock);
 }
 
@@ -4260,16 +3992,16 @@
 {
 	int rval;
 
-	rval = PCI_MEM_GET32(softs, AAC_OMR0);
+	rval = AAC_FWSTATUS_GET(softs);
 
 	if (rval & AAC_KERNEL_UP_AND_RUNNING) {
 		rval = 0;
 	} else if (rval & AAC_KERNEL_PANIC) {
-		cmn_err(CE_WARN, "firmware panic");
 		rval = ((rval >> 16) & 0xff) + 1; /* avoid 0 as return value */
+		cmn_err(CE_WARN, "!Adapter firmware crashed with BLED %d", rval - 1);
 	} else {
-		cmn_err(CE_WARN, "firmware dead");
 		rval = -1;
+		cmn_err(CE_WARN, "!Adapter firmware dead");
 	}
 	return (rval);
 }
@@ -4281,26 +4013,26 @@
 	acp->flags |= AAC_CMD_ABORT;
 
 	if (acp->pkt) {
-		if (acp->slotp) { /* outstanding cmd */
-			acp->pkt->pkt_state |= STATE_GOT_STATUS;
-		}
+		/*
+		 * Each lun should generate a unit attention
+		 * condition when reset.
+		 * Phys. drives are treated as logical ones
+		 * during error recovery.
+		 */
+		if (softs->flags & AAC_STATE_RESET)
+			aac_set_arq_data_reset(softs, acp);
 
 		switch (reason) {
 		case CMD_TIMEOUT:
-			AACDB_PRINT(softs, CE_NOTE, "CMD_TIMEOUT: acp=0x%p",
-			    acp);
 			aac_set_pkt_reason(softs, acp, CMD_TIMEOUT,
 			    STAT_TIMEOUT | STAT_BUS_RESET);
 			break;
 		case CMD_RESET:
 			/* aac support only RESET_ALL */
-			AACDB_PRINT(softs, CE_NOTE, "CMD_RESET: acp=0x%p", acp);
 			aac_set_pkt_reason(softs, acp, CMD_RESET,
 			    STAT_BUS_RESET);
 			break;
 		case CMD_ABORTED:
-			AACDB_PRINT(softs, CE_NOTE, "CMD_ABORTED: acp=0x%p",
-			    acp);
 			aac_set_pkt_reason(softs, acp, CMD_ABORTED,
 			    STAT_ABORTED);
 			break;
@@ -4337,7 +4069,7 @@
 		struct aac_cmd *acp;
 
 		for (i = 0; i < AAC_MAX_LD; i++) {
-			if (AAC_DEV_IS_VALID(&softs->containers[i].dev))
+			if (softs->containers[i].dev.valid)
 				softs->containers[i].reset = 1;
 		}
 		while ((acp = softs->q_busy.q_head) != NULL)
@@ -4368,7 +4100,6 @@
 
 	mutex_enter(&softs->io_lock);
 	if (softs->ndrains) {
-		softs->drain_timeid = 0;
 		/*
 		 * If both ASYNC and SYNC bus throttle are held,
 		 * wake up threads only when both are drained out.
@@ -4393,7 +4124,6 @@
 aac_start_drain(struct aac_softstate *softs)
 {
 	if (softs->ndrains == 0) {
-		ASSERT(softs->drain_timeid == 0);
 		softs->drain_timeid = timeout(aac_check_drain, softs,
 		    AAC_QUIESCE_TICK * drv_usectohz(1000000));
 	}
@@ -4432,21 +4162,25 @@
 static int
 aac_reset_adapter(struct aac_softstate *softs)
 {
+	ddi_acc_handle_t acc = softs->comm_space_acc_handle;
 	int health;
-	uint32_t status;
-	int rval = AAC_IOP_RESET_FAILED;
+	uint32_t status, wait_count, reset_mask;
+	struct aac_fib *fibp;
+	struct aac_pause_command *pc;
+	int rval = AACERR;
 
 	DBCALLED(softs, 1);
-
 	ASSERT(softs->state & AAC_STATE_RESET);
 
-	ddi_fm_acc_err_clear(softs->pci_mem_handle, DDI_FME_VER0);
+	aac_fm_acc_err_clear(softs->pci_mem_handle[0], DDI_FME_VER0);
 	/* Disable interrupt */
-	AAC_DISABLE_INTR(softs);
+	AAC_SET_INTR(softs, 0);
 
 	health = aac_check_adapter_health(softs);
+	AACDB_PRINT(softs, CE_NOTE, 
+		"aac_reset_adapter() called, health %d", health);
 	if (health == -1) {
-		ddi_fm_service_impact(softs->devinfo_p, DDI_SERVICE_LOST);
+		aac_fm_service_impact(softs->devinfo_p, DDI_SERVICE_LOST);
 		goto finish;
 	}
 	if (health == 0) /* flush drives if possible */
@@ -4453,45 +4187,41 @@
 		(void) aac_shutdown(softs);
 
 	/* Execute IOP reset */
-	if ((aac_sync_mbcommand(softs, AAC_IOP_RESET, 0, 0, 0, 0,
-	    &status)) != AACOK) {
-		ddi_acc_handle_t acc;
-		struct aac_fib *fibp;
-		struct aac_pause_command *pc;
+	if (softs->aac_support_opt2 & AAC_SUPPORTED_MU_RESET) {
+		/*
+		 * Sunrise Lake has dual cores and we must drag the
+		 * other core with us to reset simultaneously. There
+		 * are 2 bits in the Inbound Reset Control and Status
+		 * Register (offset 0x38) of the Sunrise Lake to reset
+		 * the chip without clearing out the PCI configuration
+		 * info (COMMAND & BARS).
+		 */
+		PCI_MEM_PUT32(softs, 0, AAC_IRCSR, AAC_IRCSR_CORES_RST);
 
-		if ((status & 0xf) == 0xf) {
-			uint32_t wait_count;
-
-			/*
-			 * Sunrise Lake has dual cores and we must drag the
-			 * other core with us to reset simultaneously. There
-			 * are 2 bits in the Inbound Reset Control and Status
-			 * Register (offset 0x38) of the Sunrise Lake to reset
-			 * the chip without clearing out the PCI configuration
-			 * info (COMMAND & BARS).
-			 */
-			PCI_MEM_PUT32(softs, AAC_IRCSR, AAC_IRCSR_CORES_RST);
-
-			/*
-			 * We need to wait for 5 seconds before accessing the MU
-			 * again 10000 * 100us = 1000,000us = 1000ms = 1s
-			 */
-			wait_count = 5 * 10000;
-			while (wait_count) {
-				drv_usecwait(100); /* delay 100 microseconds */
-				wait_count--;
-			}
-		} else {
-			if (status == SRB_STATUS_INVALID_REQUEST)
+		/*
+		 * We need to wait for 5 seconds before accessing the MU
+		 * again 10000 * 100us = 1000,000us = 1000ms = 1s
+		 */
+		wait_count = 5 * 10000;
+		while (wait_count) {
+			drv_usecwait(100); /* delay 100 microseconds */
+			wait_count--;
+		}
+	} else {
+		softs->sync_slot_busy = 1;
+		if ((aac_sync_mbcommand(softs, AAC_IOP_RESET_ALWAYS, 0, 0, 0, 0,
+			&status, &reset_mask)) != AACOK) {
+			if (status == SRB_STATUS_INVALID_REQUEST) {
 				cmn_err(CE_WARN, "!IOP_RESET not supported");
-			else /* probably timeout */
+				AACDB_PRINT(softs, CE_NOTE, 
+					"IOP_RESET not supported");
+			} else {		/* probably timeout */
 				cmn_err(CE_WARN, "!IOP_RESET failed");
-
+				AACDB_PRINT(softs, CE_NOTE, 
+					"IOP_RESET failed");
+			}
 			/* Unwind aac_shutdown() */
-			(void) aac_sync_fib_slot_bind(softs, &softs->sync_ac);
-			acc = softs->sync_ac.slotp->fib_acc_handle;
-
-			fibp = softs->sync_ac.slotp->fibp;
+			fibp = softs->sync_slot->fibp;
 			pc = (struct aac_pause_command *)&fibp->data[0];
 
 			bzero(pc, sizeof (*pc));
@@ -4502,20 +4232,28 @@
 			ddi_put32(acc, &pc->NoRescan, 1);
 
 			(void) aac_sync_fib(softs, ContainerCommand,
-			    AAC_FIB_SIZEOF(struct aac_pause_command));
-			aac_sync_fib_slot_release(softs, &softs->sync_ac);
+				AAC_FIB_SIZEOF(struct aac_pause_command));
 
-			if (aac_check_adapter_health(softs) != 0)
-				ddi_fm_service_impact(softs->devinfo_p,
-				    DDI_SERVICE_LOST);
-			else
-				/*
-				 * IOP reset not supported or IOP not reseted
-				 */
-				rval = AAC_IOP_RESET_ABNORMAL;
+			aac_fm_service_impact(softs->devinfo_p,
+				DDI_SERVICE_LOST);
+			if (health == 0)
+				rval = AACOK2;
 			goto finish;
+		} else if (softs->aac_support_opt2 & AAC_SUPPORTED_DOORBELL_RESET) {
+			PCI_MEM_PUT32(softs, 0, AAC_SRC_IDBR, reset_mask);
+			/*
+			 * We need to wait for 5 seconds before accessing the doorbell
+			 * again 10000 * 100us = 1000,000us = 1000ms = 1s
+			 */
+			wait_count = 5 * 10000;
+			while (wait_count) {
+				drv_usecwait(100); /* delay 100 microseconds */
+				wait_count--;
+			}
 		}
 	}
+	cmn_err(CE_NOTE, "!IOP_RESET finished successfully");
+	AACDB_PRINT(softs, CE_NOTE, "IOP_RESET finished successfully");
 
 	/*
 	 * Re-read and renegotiate the FIB parameters, as one of the actions
@@ -4525,10 +4263,10 @@
 	if (aac_common_attach(softs) != AACOK)
 		goto finish;
 
-	rval = AAC_IOP_RESET_SUCCEED;
+	rval = AACOK;
 
 finish:
-	AAC_ENABLE_INTR(softs);
+	AAC_SET_INTR(softs, 1);
 	return (rval);
 }
 
@@ -4567,7 +4305,7 @@
 static void
 aac_unhold_bus(struct aac_softstate *softs, int iocmds)
 {
-	int i, q, max_throttle;
+	int i, q;
 
 	for (q = 0; q < AAC_CMDQ_NUM; q++) {
 		if (iocmds & (1 << q)) {
@@ -4579,19 +4317,14 @@
 			if (q == AAC_CMDQ_ASYNC && ((softs->state &
 			    AAC_STATE_QUIESCED) || softs->ndrains))
 				continue;
-			if (q == AAC_CMDQ_ASYNC)
-				max_throttle = softs->total_slots -
-				    AAC_MGT_SLOT_NUM;
-			else
-				max_throttle = softs->total_slots - 1;
-			softs->bus_throttle[q] = max_throttle;
+			softs->bus_throttle[q] = softs->total_slots;
 			for (i = 0; i < AAC_MAX_LD; i++)
 				aac_set_throttle(softs,
 				    &softs->containers[i].dev,
-				    q, max_throttle);
+				    q, softs->total_slots);
 			for (i = 0; i < AAC_MAX_PD(softs); i++)
 				aac_set_throttle(softs, &softs->nondasds[i].dev,
-				    q, max_throttle);
+				    q, softs->total_slots);
 		}
 	}
 }
@@ -4599,24 +4332,20 @@
 static int
 aac_do_reset(struct aac_softstate *softs)
 {
-	int health;
-	int rval;
+	int health, rval;
+	int sync_cmds, async_cmds;
 
 	softs->state |= AAC_STATE_RESET;
 	health = aac_check_adapter_health(softs);
+	AACDB_PRINT(softs, CE_NOTE, "aac_do_reset() called, health %d", health);
 
 	/*
 	 * Hold off new io commands and wait all outstanding io
 	 * commands to complete.
 	 */
-	if (health == 0) {
-		int sync_cmds = softs->bus_ncmds[AAC_CMDQ_SYNC];
-		int async_cmds = softs->bus_ncmds[AAC_CMDQ_ASYNC];
-
-		if (sync_cmds == 0 && async_cmds == 0) {
-			rval = AAC_IOP_RESET_SUCCEED;
-			goto finish;
-		}
+	sync_cmds = softs->bus_ncmds[AAC_CMDQ_SYNC];
+	async_cmds = softs->bus_ncmds[AAC_CMDQ_ASYNC];
+	if (health == 0 && (sync_cmds || async_cmds)) {
 		/*
 		 * Give the adapter up to AAC_QUIESCE_TIMEOUT more seconds
 		 * to complete the outstanding io commands
@@ -4629,8 +4358,14 @@
 		 * Poll the adapter by ourselves in case interrupt is disabled
 		 * and to avoid releasing the io_lock.
 		 */
-		intr_handler = (softs->flags & AAC_FLAGS_NEW_COMM) ?
-		    aac_process_intr_new : aac_process_intr_old;
+		if ((softs->flags & AAC_FLAGS_NEW_COMM_TYPE1) ||
+			(softs->flags & AAC_FLAGS_NEW_COMM_TYPE2) ||
+			(softs->flags & AAC_FLAGS_NEW_COMM_TYPE34))
+			intr_handler = aac_process_intr_new_type1;
+		else if (softs->flags & AAC_FLAGS_NEW_COMM) 
+			intr_handler = aac_process_intr_new;
+		else
+			intr_handler = aac_process_intr_old;
 		while ((softs->bus_ncmds[AAC_CMDQ_SYNC] ||
 		    softs->bus_ncmds[AAC_CMDQ_ASYNC]) && timeout) {
 			drv_usecwait(100);
@@ -4638,28 +4373,21 @@
 			timeout--;
 		}
 		aac_unhold_bus(softs, AAC_IOCMD_SYNC | AAC_IOCMD_ASYNC);
-
-		if (softs->bus_ncmds[AAC_CMDQ_SYNC] == 0 &&
-		    softs->bus_ncmds[AAC_CMDQ_ASYNC] == 0) {
-			/* Cmds drained out */
-			rval = AAC_IOP_RESET_SUCCEED;
-			goto finish;
-		} else if (softs->bus_ncmds[AAC_CMDQ_SYNC] < sync_cmds ||
-		    softs->bus_ncmds[AAC_CMDQ_ASYNC] < async_cmds) {
-			/* Cmds not drained out, adapter overloaded */
-			rval = AAC_IOP_RESET_ABNORMAL;
-			goto finish;
-		}
 	}
 
 	/*
-	 * If a longer waiting time still can't drain any outstanding io
+	 * If a longer waiting time still can't drain all outstanding io
 	 * commands, do IOP reset.
 	 */
-	if ((rval = aac_reset_adapter(softs)) == AAC_IOP_RESET_FAILED)
-		softs->state |= AAC_STATE_DEAD;
+	if ((sync_cmds || async_cmds) &&
+		(softs->bus_ncmds[AAC_CMDQ_SYNC] == sync_cmds) &&
+		(softs->bus_ncmds[AAC_CMDQ_ASYNC] == async_cmds)) { 
+		if ((rval = aac_reset_adapter(softs)) == AACERR)
+			softs->state |= AAC_STATE_DEAD;
+	} else {
+		rval = AACOK2;
+	}
 
-finish:
 	softs->state &= ~AAC_STATE_RESET;
 	return (rval);
 }
@@ -4668,9 +4396,10 @@
 aac_tran_reset(struct scsi_address *ap, int level)
 {
 	struct aac_softstate *softs = AAC_TRAN2SOFTS(ap->a_hba_tran);
-	int rval;
+	int rval, rval2;
 
 	DBCALLED(softs, 1);
+	AACDB_PRINT(softs, CE_NOTE, "aac_tran_reset() called, level %d", level);
 
 	if (level != RESET_ALL) {
 		cmn_err(CE_NOTE, "!reset target/lun not supported");
@@ -4678,23 +4407,21 @@
 	}
 
 	mutex_enter(&softs->io_lock);
-	switch (rval = aac_do_reset(softs)) {
-	case AAC_IOP_RESET_SUCCEED:
-		aac_abort_iocmds(softs, AAC_IOCMD_OUTSTANDING | AAC_IOCMD_ASYNC,
-		    NULL, CMD_RESET);
+	rval2 = aac_do_reset(softs);
+	rval = (rval2 != AACERR) ? 1 : 0;
+	if (rval == 1 && !ddi_in_panic()) {
+		if (rval2 == AACOK)
+			aac_abort_iocmds(softs, AAC_IOCMD_OUTSTANDING | AAC_IOCMD_ASYNC,
+				NULL, CMD_RESET);
 		aac_start_waiting_io(softs);
-		break;
-	case AAC_IOP_RESET_FAILED:
-		/* Abort IOCTL cmds when adapter is dead */
+	} else {
+		/* Abort IOCTL cmds when system panic or adapter dead */
 		aac_abort_iocmds(softs, AAC_IOCMD_ALL, NULL, CMD_RESET);
-		break;
-	case AAC_IOP_RESET_ABNORMAL:
-		aac_start_waiting_io(softs);
 	}
 	mutex_exit(&softs->io_lock);
 
 	aac_drain_comp_q(softs);
-	return (rval == 0);
+	return (rval);
 }
 
 static int
@@ -4703,6 +4430,7 @@
 	struct aac_softstate *softs = AAC_TRAN2SOFTS(ap->a_hba_tran);
 
 	DBCALLED(softs, 1);
+	AACDB_PRINT(softs, CE_NOTE, "aac_tran_abort() called, pkt %p", pkt);
 
 	mutex_enter(&softs->io_lock);
 	aac_abort_iocmds(softs, 0, pkt, CMD_ABORTED);
@@ -4715,26 +4443,37 @@
 void
 aac_free_dmamap(struct aac_cmd *acp)
 {
+	uint_t i;
+	uint32_t offset;
+
 	/* Free dma mapping */
 	if (acp->flags & AAC_CMD_DMA_VALID) {
-		ASSERT(acp->buf_dma_handle);
-		(void) ddi_dma_unbind_handle(acp->buf_dma_handle);
+		ASSERT(acp->segments[0].buf_dma_handle);
+		for (i = 0; i < acp->segment_cnt; ++i) 
+			(void) ddi_dma_unbind_handle(acp->segments[i].buf_dma_handle);
 		acp->flags &= ~AAC_CMD_DMA_VALID;
 	}
 
-	if (acp->abp != NULL) { /* free non-aligned buf DMA */
-		ASSERT(acp->buf_dma_handle);
-		if ((acp->flags & AAC_CMD_BUF_WRITE) == 0 && acp->bp)
-			ddi_rep_get8(acp->abh, (uint8_t *)acp->bp->b_un.b_addr,
-			    (uint8_t *)acp->abp, acp->bp->b_bcount,
-			    DDI_DEV_AUTOINCR);
-		ddi_dma_mem_free(&acp->abh);
-		acp->abp = NULL;
+	if (acp->segments[0].abp != NULL) { /* free non-aligned buf DMA */
+		ASSERT(acp->segments[0].buf_dma_handle);
+		for (i = 0, offset = 0; i < acp->segment_cnt; ++i) {
+			if ((acp->flags & AAC_CMD_BUF_WRITE) == 0 && acp->bp)
+				ddi_rep_get8(acp->segments[i].abh, 
+					(uint8_t *)acp->bp->b_un.b_addr + offset,
+					(uint8_t *)acp->segments[i].abp, 
+					acp->segments[i].abp_size,
+					DDI_DEV_AUTOINCR);
+			offset += acp->segments[i].abp_size;
+			ddi_dma_mem_free(&acp->segments[i].abh);
+			acp->segments[i].abp = NULL;
+		}
 	}
 
-	if (acp->buf_dma_handle) {
-		ddi_dma_free_handle(&acp->buf_dma_handle);
-		acp->buf_dma_handle = NULL;
+	for (i = 0; i < acp->segment_cnt; ++i) {
+		if (acp->segments[i].buf_dma_handle) {
+			ddi_dma_free_handle(&acp->segments[i].buf_dma_handle);
+			acp->segments[i].buf_dma_handle = NULL;
+		}
 	}
 }
 
@@ -4742,7 +4481,7 @@
 aac_unknown_scmd(struct aac_softstate *softs, struct aac_cmd *acp)
 {
 	AACDB_PRINT(softs, CE_CONT, "SCMD 0x%x not supported",
-	    ((union scsi_cdb *)(void *)acp->pkt->pkt_cdbp)->scc_cmd);
+	    ((union scsi_cdb *)acp->pkt->pkt_cdbp)->scc_cmd);
 	aac_free_dmamap(acp);
 	aac_set_arq_data(acp->pkt, KEY_ILLEGAL_REQUEST, 0x20, 0x00, 0);
 	aac_soft_callback(softs, acp);
@@ -4762,7 +4501,7 @@
 
 	dvp = (struct aac_container *)acp->dvp;
 	pkt = acp->pkt;
-	cdbp = (void *)pkt->pkt_cdbp;
+	cdbp = (union scsi_cdb *)pkt->pkt_cdbp;
 	bp = acp->bp;
 
 	switch (cdbp->scc_cmd) {
@@ -4790,7 +4529,8 @@
 			aac_free_dmamap(acp);
 			if (bp->b_flags & (B_PHYS|B_PAGEIO))
 				bp_mapin(bp);
-			bcopy(&cap, bp->b_un.b_addr, min(bp->b_bcount, 8));
+			bcopy(&cap, bp->b_un.b_addr, 
+				bp->b_bcount < 8 ? bp->b_bcount : 8);
 			pkt->pkt_state |= STATE_XFERRED_DATA;
 		}
 		aac_soft_callback(softs, acp);
@@ -4805,14 +4545,14 @@
 				int cap_len = sizeof (struct scsi_capacity_16);
 
 				bzero(&cap16, cap_len);
-				cap16.sc_capacity = BE_64(dvp->size - 1);
+				cap16.sc_capacity = BE_64(dvp->size);
 				cap16.sc_lbasize = BE_32(AAC_SECTOR_SIZE);
 
 				aac_free_dmamap(acp);
 				if (bp->b_flags & (B_PHYS | B_PAGEIO))
 					bp_mapin(bp);
-				bcopy(&cap16, bp->b_un.b_addr,
-				    min(bp->b_bcount, cap_len));
+				bcopy(&cap16, bp->b_un.b_addr, 
+					bp->b_bcount < cap_len ? bp->b_bcount : cap_len);
 				pkt->pkt_state |= STATE_XFERRED_DATA;
 			}
 			aac_soft_callback(softs, acp);
@@ -4841,11 +4581,6 @@
 		acp->blkno = GETG0ADDR(cdbp);
 		goto do_io;
 
-	case SCMD_READ_G5: /* read_12 */
-	case SCMD_WRITE_G5: /* write_12 */
-		acp->blkno = GETG5ADDR(cdbp);
-		goto do_io;
-
 	case SCMD_READ_G1: /* read_10 */
 	case SCMD_WRITE_G1: /* write_10 */
 		acp->blkno = (uint32_t)GETG1ADDR(cdbp);
@@ -4899,14 +4634,6 @@
 		break;
 	}
 
-	case SCMD_START_STOP:
-		if (softs->support_opt2 & AAC_SUPPORTED_POWER_MANAGEMENT) {
-			acp->aac_cmd_fib = aac_cmd_fib_startstop;
-			acp->ac_comp = aac_startstop_complete;
-			rval = aac_do_io(softs, acp);
-			break;
-		}
-	/* FALLTHRU */
 	case SCMD_TEST_UNIT_READY:
 	case SCMD_REQUEST_SENSE:
 	case SCMD_FORMAT:
@@ -4937,6 +4664,14 @@
 		rval = TRAN_ACCEPT;
 		break;
 
+	case SCMD_START_STOP:
+		aac_free_dmamap(acp);
+		if (softs->aac_support_opt2 & AAC_SUPPORTED_POWER_MANAGEMENT) 
+			aac_startstop(softs, cdbp, dvp->cid);
+		aac_soft_callback(softs, acp);
+		rval = TRAN_ACCEPT;
+		break;
+
 	default: /* unknown command */
 		aac_unknown_scmd(softs, acp);
 		rval = TRAN_ACCEPT;
@@ -4965,13 +4700,11 @@
 	acp->timeout = acp->pkt->pkt_time;
 	if (pkt->pkt_flags & FLAG_NOINTR)
 		acp->flags |= AAC_CMD_NO_INTR;
-#ifdef DEBUG
-	acp->fib_flags = AACDB_FLAGS_FIB_SCMD;
-#endif
+	acp->cur_segment = 0;
 	pkt->pkt_reason = CMD_CMPLT;
 	pkt->pkt_state = 0;
 	pkt->pkt_statistics = 0;
-	*pkt->pkt_scbp = STATUS_GOOD; /* clear arq scsi_status */
+	*pkt->pkt_scbp = 0; /* clear arq scsi_status */
 
 	if (acp->flags & AAC_CMD_DMA_VALID) {
 		pkt->pkt_resid = acp->bcount;
@@ -4979,7 +4712,7 @@
 		if ((acp->flags & AAC_CMD_CONSISTENT) &&
 		    (acp->flags & AAC_CMD_BUF_WRITE))
 			if (aac_dma_sync_ac(acp) != AACOK) {
-				ddi_fm_service_impact(softs->devinfo_p,
+				aac_fm_service_impact(softs->devinfo_p,
 				    DDI_SERVICE_UNAFFECTED);
 				return (TRAN_BADPKT);
 			}
@@ -4989,31 +4722,19 @@
 
 	mutex_enter(&softs->io_lock);
 	AACDB_PRINT_SCMD(softs, acp);
-	if ((dvp->flags & (AAC_DFLAG_VALID | AAC_DFLAG_CONFIGURING)) &&
-	    !(softs->state & AAC_STATE_DEAD)) {
-		if (dvp->type == AAC_DEV_LD) {
-			if (ap->a_lun == 0)
-				rval = aac_tran_start_ld(softs, acp);
-			else
-				goto error;
-		} else {
+	if (dvp->valid && ap->a_lun == 0 && !(softs->state & AAC_STATE_DEAD)) {
+		if (dvp->type == AAC_DEV_LD)
+			rval = aac_tran_start_ld(softs, acp);
+		else if (acp->segment_cnt > 1)
+			rval = TRAN_BADPKT;
+		else
 			rval = aac_do_io(softs, acp);
-		}
 	} else {
-error:
-#ifdef DEBUG
-		if (!(softs->state & AAC_STATE_DEAD)) {
-			AACDB_PRINT_TRAN(softs,
-			    "Cannot send cmd to target t%dL%d: %s",
-			    ap->a_target, ap->a_lun,
-			    "target invalid");
-		} else {
-			AACDB_PRINT(softs, CE_WARN,
-			    "Cannot send cmd to target t%dL%d: %s",
-			    ap->a_target, ap->a_lun,
-			    "adapter dead");
-		}
-#endif
+		AACDB_PRINT(softs, CE_WARN,
+		    "Cannot send cmd to target t%dL%d: %s",
+		    ap->a_target, ap->a_lun,
+		    (softs->state & AAC_STATE_DEAD) ?
+		    "adapter dead" : "target invalid");
 		rval = TRAN_FATAL_ERROR;
 	}
 	mutex_exit(&softs->io_lock);
@@ -5038,9 +4759,9 @@
 
 	mutex_enter(&softs->io_lock);
 	dvp = AAC_DEV(softs, ap->a_target);
-	if (dvp == NULL || !AAC_DEV_IS_VALID(dvp)) {
+	if (dvp == NULL || !dvp->valid) {
 		mutex_exit(&softs->io_lock);
-		AACDB_PRINT_TRAN(softs, "Bad target t%dL%d to getcap",
+		AACDB_PRINT(softs, CE_WARN, "Bad target t%dL%d to getcap",
 		    ap->a_target, ap->a_lun);
 		return (-1);
 	}
@@ -5054,7 +4775,7 @@
 		rval = 1;
 		break;
 	case SCSI_CAP_DMA_MAX:
-		rval = softs->dma_max;
+		rval = softs->buf_dma_attr.dma_attr_maxxfer;
 		break;
 	default:
 		rval = -1;
@@ -5086,9 +4807,9 @@
 
 	mutex_enter(&softs->io_lock);
 	dvp = AAC_DEV(softs, ap->a_target);
-	if (dvp == NULL || !AAC_DEV_IS_VALID(dvp)) {
+	if (dvp == NULL || !dvp->valid) {
 		mutex_exit(&softs->io_lock);
-		AACDB_PRINT_TRAN(softs, "Bad target t%dL%d to setcap",
+		AACDB_PRINT(softs, CE_WARN, "Bad target t%dL%d to setcap",
 		    ap->a_target, ap->a_lun);
 		return (-1);
 	}
@@ -5146,16 +4867,20 @@
 			off_t off;
 			size_t len;
 
-			rval = ddi_dma_getwin(acp->buf_dma_handle, acp->cur_win,
-			    &off, &len, &acp->cookie, &acp->left_cookien);
+			rval = ddi_dma_getwin(acp->segments[0].buf_dma_handle, 
+				acp->cur_win, &off, &len,
+				&acp->segments[0].cookie, &acp->segments[0].left_cookien);
+			acp->segment_cnt = 1;
+			acp->left_cookien = acp->segments[0].left_cookien;
 			if (rval == DDI_SUCCESS)
 				goto get_dma_cookies;
 			AACDB_PRINT(softs, CE_WARN,
 			    "ddi_dma_getwin() fail %d", rval);
 			return (AACERR);
+		} else {
+			AACDB_PRINT(softs, CE_WARN, "Nothing to transfer");
+			return (AACERR);
 		}
-		AACDB_PRINT(softs, CE_WARN, "Nothing to transfer");
-		return (AACERR);
 	}
 
 	/* We need to transfer data, so we alloc DMA resources for this pkt */
@@ -5162,6 +4887,9 @@
 	if (bp && bp->b_bcount != 0 && !(acp->flags & AAC_CMD_DMA_VALID)) {
 		uint_t dma_flags = 0;
 		struct aac_sge *sge;
+		int repeat = 0;
+		uint_t i, j;
+		uint32_t offset;
 
 		/*
 		 * We will still use this point to fake some
@@ -5182,110 +4910,183 @@
 		if (flags & PKT_DMA_PARTIAL)
 			dma_flags |= DDI_DMA_PARTIAL;
 
-		/* Alloc buf dma handle */
-		if (!acp->buf_dma_handle) {
-			rval = ddi_dma_alloc_handle(softs->devinfo_p,
-			    &softs->buf_dma_attr, cb, arg,
-			    &acp->buf_dma_handle);
-			if (rval != DDI_SUCCESS) {
-				AACDB_PRINT(softs, CE_WARN,
-				    "Can't allocate DMA handle, errno=%d",
-				    rval);
-				goto error_out;
-			}
-		}
+		do {
+			/* Bind buf */
+			if (((uintptr_t)bp->b_un.b_addr & AAC_DMA_ALIGN_MASK) == 0
+				&& !repeat) {
+				/* Alloc buf dma handle */
+				if (!acp->segments[0].buf_dma_handle) {
+					rval = ddi_dma_alloc_handle(softs->devinfo_p,
+						&softs->buf_dma_attr, cb, arg,
+						&acp->segments[0].buf_dma_handle);
+					if (rval != DDI_SUCCESS) {
+						AACDB_PRINT(softs, CE_WARN,
+							"Can't allocate DMA handle, errno=%d",
+							rval);
+						goto error_out;
+					}
+				}
+				rval = ddi_dma_buf_bind_handle(acp->segments[0].buf_dma_handle,
+					bp, dma_flags, cb, arg, &acp->segments[0].cookie,
+					&acp->segments[0].left_cookien);
+				acp->segment_cnt = 1;
+				acp->left_cookien = acp->segments[0].left_cookien;
+			} else {
+				AACDB_PRINT_TRAN(softs,
+					"non-aligned buffer: addr=0x%p, cnt=%lu",
+					(void *)bp->b_un.b_addr, bp->b_bcount);
+				if (bp->b_flags & (B_PAGEIO|B_PHYS))
+					bp_mapin(bp);
 
-		/* Bind buf */
-		if (((uintptr_t)bp->b_un.b_addr & AAC_DMA_ALIGN_MASK) == 0) {
-			rval = ddi_dma_buf_bind_handle(acp->buf_dma_handle,
-			    bp, dma_flags, cb, arg, &acp->cookie,
-			    &acp->left_cookien);
-		} else {
-			size_t bufsz;
+				if (repeat) {
+					repeat = 0;
+					acp->segment_cnt = (bp->b_bcount - 1) /
+						softs->buf_dma_attr.dma_attr_maxxfer + 1;
+					if (acp->segment_cnt > AAC_MAXSEGMENTS) {
+						AACDB_PRINT(softs, CE_WARN,
+							"After DDI_DMA_TOOBIG: Too much segments!");
+						acp->segment_cnt = AAC_MAXSEGMENTS;
+						goto error_out;
+					}
 
-			AACDB_PRINT_TRAN(softs,
-			    "non-aligned buffer: addr=0x%p, cnt=%lu",
-			    (void *)bp->b_un.b_addr, bp->b_bcount);
-			if (bp->b_flags & (B_PAGEIO|B_PHYS))
-				bp_mapin(bp);
+					for (i = 0; i < acp->segment_cnt; ++i) {
+						rval = ddi_dma_alloc_handle(softs->devinfo_p,
+							&softs->buf_dma_attr, cb, arg,
+							&acp->segments[i].buf_dma_handle);
+						if (rval != DDI_SUCCESS) {
+							AACDB_PRINT(softs, CE_WARN,
+								"After DDI_DMA_TOOBIG: Can't allocate DMA handle, errno=%d",
+								rval);
+							goto error_out;
+						}
+						if ((i == acp->segment_cnt - 1) &&
+							(bp->b_bcount % softs->buf_dma_attr.dma_attr_maxxfer))
+							acp->segments[i].abp_size = bp->b_bcount % 
+								softs->buf_dma_attr.dma_attr_maxxfer;
+						else
+							acp->segments[i].abp_size = 
+								softs->buf_dma_attr.dma_attr_maxxfer;
+						rval = ddi_dma_mem_alloc(acp->segments[i].buf_dma_handle,
+							acp->segments[i].abp_size,
+							&aac_acc_attr, DDI_DMA_STREAMING,
+							cb, arg, &acp->segments[i].abp, 
+							&acp->segments[i].abp_real_size, 
+							&acp->segments[i].abh);
 
-			rval = ddi_dma_mem_alloc(acp->buf_dma_handle,
-			    AAC_ROUNDUP(bp->b_bcount, AAC_DMA_ALIGN),
-			    &softs->acc_attr, DDI_DMA_STREAMING,
-			    cb, arg, &acp->abp, &bufsz, &acp->abh);
+						if (rval != DDI_SUCCESS) {
+							AACDB_PRINT(softs, CE_NOTE,
+								"Cannot alloc DMA to non-aligned buf");
+							bioerr = 0;
+							goto error_out;
+						}
+					}
+				} else {
+					/* Alloc buf dma handle */
+					if (!acp->segments[0].buf_dma_handle) {
+						rval = ddi_dma_alloc_handle(softs->devinfo_p,
+							&softs->buf_dma_attr, cb, arg,
+							&acp->segments[0].buf_dma_handle);
+						if (rval != DDI_SUCCESS) {
+							AACDB_PRINT(softs, CE_WARN,
+								"Can't allocate DMA handle, errno=%d",
+								rval);
+							goto error_out;
+						}
+					}
+					rval = ddi_dma_mem_alloc(acp->segments[0].buf_dma_handle,
+						AAC_ROUNDUP(bp->b_bcount, AAC_DMA_ALIGN),
+						&aac_acc_attr, DDI_DMA_STREAMING,
+						cb, arg, &acp->segments[0].abp, 
+						&acp->segments[0].abp_real_size, 
+						&acp->segments[0].abh);
 
-			if (rval != DDI_SUCCESS) {
-				AACDB_PRINT(softs, CE_NOTE,
-				    "Cannot alloc DMA to non-aligned buf");
-				bioerr = 0;
-				goto error_out;
+					if (rval != DDI_SUCCESS) {
+						AACDB_PRINT(softs, CE_NOTE,
+							"Cannot alloc DMA to non-aligned buf");
+						bioerr = 0;
+						goto error_out;
+					}
+					acp->segment_cnt = 1;
+					acp->segments[0].abp_size = bp->b_bcount;
+				}
+
+				acp->left_cookien = 0;
+				for (i = 0, offset = 0; i < acp->segment_cnt; ++i) {
+					if (acp->flags & AAC_CMD_BUF_WRITE) {
+						ddi_rep_put8(acp->segments[i].abh,
+							(uint8_t *)bp->b_un.b_addr + offset,
+							(uint8_t *)acp->segments[i].abp, 
+							acp->segments[i].abp_size,
+							DDI_DEV_AUTOINCR);
+						offset += acp->segments[i].abp_size;
+					}
+
+					rval = ddi_dma_addr_bind_handle(acp->segments[i].buf_dma_handle,
+						NULL, acp->segments[i].abp, 
+						acp->segments[i].abp_real_size, dma_flags, cb, arg,
+						&acp->segments[i].cookie, &acp->segments[i].left_cookien);
+					if (rval != DDI_DMA_MAPPED)
+						break;
+
+					acp->left_cookien += acp->segments[i].left_cookien;
+				}
 			}
 
-			if (acp->flags & AAC_CMD_BUF_WRITE)
-				ddi_rep_put8(acp->abh,
-				    (uint8_t *)bp->b_un.b_addr,
-				    (uint8_t *)acp->abp, bp->b_bcount,
-				    DDI_DEV_AUTOINCR);
+			switch (rval) {
+			case DDI_DMA_PARTIAL_MAP:
+				if (ddi_dma_numwin(acp->segments[0].buf_dma_handle,
+					&acp->total_nwin) == DDI_FAILURE) {
+					AACDB_PRINT(softs, CE_WARN,
+						"Cannot get number of DMA windows");
+					bioerr = 0;
+					goto error_out;
+				}
+				AACDB_PRINT_TRAN(softs, "buf bind, %d seg(s)",
+					acp->left_cookien);
+				acp->cur_win = 0;
+				break;
 
-			rval = ddi_dma_addr_bind_handle(acp->buf_dma_handle,
-			    NULL, acp->abp, bufsz, dma_flags, cb, arg,
-			    &acp->cookie, &acp->left_cookien);
-		}
+			case DDI_DMA_MAPPED:
+				AACDB_PRINT_TRAN(softs, "buf bind, %d seg(s)",
+					acp->left_cookien);
+				acp->cur_win = 0;
+				acp->total_nwin = 1;
+				break;
 
-		switch (rval) {
-		case DDI_DMA_PARTIAL_MAP:
-			if (ddi_dma_numwin(acp->buf_dma_handle,
-			    &acp->total_nwin) == DDI_FAILURE) {
-				AACDB_PRINT(softs, CE_WARN,
-				    "Cannot get number of DMA windows");
+			case DDI_DMA_NORESOURCES:
 				bioerr = 0;
+				AACDB_PRINT(softs, CE_WARN,
+					"Cannot bind buf for DMA: DDI_DMA_NORESOURCES");
 				goto error_out;
+			case DDI_DMA_BADATTR:
+			case DDI_DMA_NOMAPPING:
+				bioerr = EFAULT;
+				AACDB_PRINT(softs, CE_WARN,
+					"Cannot bind buf for DMA: DDI_DMA_NOMAPPING");
+				goto error_out;
+			case DDI_DMA_TOOBIG:
+				if (bp->b_bcount > softs->buf_dma_attr.dma_attr_maxxfer &&
+					acp->segment_cnt == 1) {
+					repeat = 1;
+					break;
+				} else {
+					bioerr = EINVAL;
+					AACDB_PRINT(softs, CE_WARN,
+						"Cannot bind buf for DMA: DDI_DMA_TOOBIG(%d) - returning EINVAL",
+						bp->b_bcount);
+					goto error_out;
+				}
+			default:
+				bioerr = EINVAL;
+				AACDB_PRINT(softs, CE_WARN,
+					"Cannot bind buf for DMA: %d", rval);
+				goto error_out;
 			}
-			AACDB_PRINT_TRAN(softs, "buf bind, %d seg(s)",
-			    acp->left_cookien);
-			acp->cur_win = 0;
-			break;
-
-		case DDI_DMA_MAPPED:
-			AACDB_PRINT_TRAN(softs, "buf bind, %d seg(s)",
-			    acp->left_cookien);
-			acp->cur_win = 0;
-			acp->total_nwin = 1;
-			break;
-
-		case DDI_DMA_NORESOURCES:
-			bioerr = 0;
-			AACDB_PRINT(softs, CE_WARN,
-			    "Cannot bind buf for DMA: DDI_DMA_NORESOURCES");
-			goto error_out;
-		case DDI_DMA_BADATTR:
-		case DDI_DMA_NOMAPPING:
-			bioerr = EFAULT;
-			AACDB_PRINT(softs, CE_WARN,
-			    "Cannot bind buf for DMA: DDI_DMA_NOMAPPING");
-			goto error_out;
-		case DDI_DMA_TOOBIG:
-			bioerr = EINVAL;
-			AACDB_PRINT(softs, CE_WARN,
-			    "Cannot bind buf for DMA: DDI_DMA_TOOBIG(%d)",
-			    bp->b_bcount);
-			goto error_out;
-		default:
-			bioerr = EINVAL;
-			AACDB_PRINT(softs, CE_WARN,
-			    "Cannot bind buf for DMA: %d", rval);
-			goto error_out;
-		}
+		} while (repeat);
 		acp->flags |= AAC_CMD_DMA_VALID;
 
 get_dma_cookies:
 		ASSERT(acp->left_cookien > 0);
-		if (acp->left_cookien > softs->aac_sg_tablesize) {
-			AACDB_PRINT(softs, CE_NOTE, "large cookiec received %d",
-			    acp->left_cookien);
-			bioerr = EINVAL;
-			goto error_out;
-		}
 		if (oldcookiec != acp->left_cookien && acp->sgt != NULL) {
 			kmem_free(acp->sgt, sizeof (struct aac_sge) * \
 			    oldcookiec);
@@ -5303,16 +5104,25 @@
 		}
 
 		sge = &acp->sgt[0];
-		sge->bcount = acp->cookie.dmac_size;
-		sge->addr.ad64.lo = AAC_LS32(acp->cookie.dmac_laddress);
-		sge->addr.ad64.hi = AAC_MS32(acp->cookie.dmac_laddress);
-		acp->bcount = acp->cookie.dmac_size;
-		for (sge++; sge < &acp->sgt[acp->left_cookien]; sge++) {
-			ddi_dma_nextcookie(acp->buf_dma_handle, &acp->cookie);
-			sge->bcount = acp->cookie.dmac_size;
-			sge->addr.ad64.lo = AAC_LS32(acp->cookie.dmac_laddress);
-			sge->addr.ad64.hi = AAC_MS32(acp->cookie.dmac_laddress);
-			acp->bcount += acp->cookie.dmac_size;
+		acp->bcount = 0;
+		for (i = 0; i < acp->segment_cnt; ++i) {
+			acp->segments[i].sgt = sge;
+			if (acp->segments[i].left_cookien > softs->aac_sg_tablesize) {
+				AACDB_PRINT(softs, CE_NOTE, "large cookiec received %d",
+					acp->segments[i].left_cookien);
+				bioerr = EINVAL;
+				goto error_out;
+			}
+			for (j = 0; j < acp->segments[i].left_cookien; ++j) {
+				if (j > 0)
+					ddi_dma_nextcookie(acp->segments[i].buf_dma_handle, 
+						&acp->segments[i].cookie);
+				sge->bcount = acp->segments[i].cookie.dmac_size;
+				sge->addr.ad64.lo = AAC_LS32(acp->segments[i].cookie.dmac_laddress);
+				sge->addr.ad64.hi = AAC_MS32(acp->segments[i].cookie.dmac_laddress);
+				acp->bcount += acp->segments[i].cookie.dmac_size;
+				sge++;
+			}
 		}
 
 		/*
@@ -5320,7 +5130,8 @@
 		 * dma_attr_maxxfer attribute. So we have to ensure
 		 * it by ourself.
 		 */
-		if (acp->bcount > softs->buf_dma_attr.dma_attr_maxxfer) {
+		if (acp->segment_cnt == 1 &&
+			acp->bcount > softs->buf_dma_attr.dma_attr_maxxfer) {
 			AACDB_PRINT(softs, CE_NOTE,
 			    "large xfer size received %d\n", acp->bcount);
 			bioerr = EINVAL;
@@ -5328,25 +5139,16 @@
 		}
 
 		acp->total_xfer += acp->bcount;
-
 		if (acp->pkt) {
 			/* Return remaining byte count */
-			if (acp->total_xfer <= bp->b_bcount) {
-				acp->pkt->pkt_resid = bp->b_bcount - \
-				    acp->total_xfer;
-			} else {
-				/*
-				 * Allocated DMA size is greater than the buf
-				 * size of bp. This is caused by devices like
-				 * tape. we have extra bytes allocated, but
-				 * the packet residual has to stay correct.
-				 */
-				acp->pkt->pkt_resid = 0;
-			}
+			acp->pkt->pkt_resid = bp->b_bcount - acp->total_xfer;
+
 			AACDB_PRINT_TRAN(softs,
 			    "bp=0x%p, xfered=%d/%d, resid=%d",
 			    (void *)bp->b_un.b_addr, (int)acp->total_xfer,
 			    (int)bp->b_bcount, (int)acp->pkt->pkt_resid);
+
+			ASSERT(acp->pkt->pkt_resid >= 0);
 		}
 	}
 	return (AACOK);
@@ -5418,7 +5220,7 @@
 	DBCALLED(NULL, 2);
 
 	if (aac_dma_sync_ac(acp) != AACOK)
-		ddi_fm_service_impact(
+		aac_fm_service_impact(
 		    (AAC_TRAN2SOFTS(ap->a_hba_tran))->devinfo_p,
 		    DDI_SERVICE_UNAFFECTED);
 }
@@ -5529,6 +5331,9 @@
 	hba_tran->tran_quiesce = aac_tran_quiesce;
 	hba_tran->tran_unquiesce = aac_tran_unquiesce;
 	hba_tran->tran_bus_config = aac_tran_bus_config;
+#if 0
+	hba_tran->tran_interconnect_type = INTERCONNECT_PARALLEL;
+#endif
 	rval = scsi_hba_attach_setup(softs->devinfo_p, &softs->buf_dma_attr,
 	    hba_tran, 0);
 	if (rval != DDI_SUCCESS) {
@@ -5549,10 +5354,9 @@
  * Init FIB header
  */
 static void
-aac_cmd_fib_header(struct aac_softstate *softs, struct aac_cmd *acp,
-    uint16_t cmd)
+aac_cmd_fib_header(struct aac_softstate *softs, struct aac_slot *slotp,
+    uint16_t cmd, uint16_t fib_size)
 {
-	struct aac_slot *slotp = acp->slotp;
 	ddi_acc_handle_t acc = slotp->fib_acc_handle;
 	struct aac_fib *fibp = slotp->fibp;
 	uint32_t xfer_state;
@@ -5561,26 +5365,162 @@
 	    AAC_FIBSTATE_HOSTOWNED |
 	    AAC_FIBSTATE_INITIALISED |
 	    AAC_FIBSTATE_EMPTY |
-	    AAC_FIBSTATE_FAST_RESPONSE | /* enable fast io */
 	    AAC_FIBSTATE_FROMHOST |
 	    AAC_FIBSTATE_REXPECTED |
 	    AAC_FIBSTATE_NORM;
+	if (slotp->acp && !(slotp->acp->flags & AAC_CMD_SYNC)) {
+		xfer_state |=
+		    AAC_FIBSTATE_ASYNC |
+		    AAC_FIBSTATE_FAST_RESPONSE /* enable fast io */;
+		ddi_put16(acc, &fibp->Header.SenderSize,
+		    softs->aac_max_fib_size);
+	} else {
+		ddi_put16(acc, &fibp->Header.SenderSize, AAC_FIB_SIZE);
+	}
 
-	if (!(acp->flags & AAC_CMD_SYNC))
-		xfer_state |= AAC_FIBSTATE_ASYNC;
-
 	ddi_put32(acc, &fibp->Header.XferState, xfer_state);
 	ddi_put16(acc, &fibp->Header.Command, cmd);
 	ddi_put8(acc, &fibp->Header.StructType, AAC_FIBTYPE_TFIB);
-	ddi_put8(acc, &fibp->Header.Flags, 0); /* don't care */
-	ddi_put16(acc, &fibp->Header.Size, acp->fib_size);
-	ddi_put16(acc, &fibp->Header.SenderSize, softs->aac_max_fib_size);
+	ddi_put8(acc, &fibp->Header.Unused, 0); /* don't care */
+	ddi_put16(acc, &fibp->Header.Size, fib_size);
 	ddi_put32(acc, &fibp->Header.SenderFibAddress, (slotp->index << 2));
-	ddi_put32(acc, &fibp->Header.ReceiverFibAddress, slotp->fib_phyaddr);
-	ddi_put32(acc, &fibp->Header.SenderData, 0); /* don't care */
+	ddi_put32(acc, &fibp->Header.a.ReceiverFibAddress, slotp->fib_phyaddr);
+	ddi_put32(acc, &fibp->Header.Handle, slotp->index + 1); 
 }
 
 /*
+ * Init FIB for raw IO2 command
+ */
+static void
+aac_cmd_fib_rawio2(struct aac_softstate *softs, struct aac_cmd *acp)
+{
+	ddi_acc_handle_t acc = acp->slotp->fib_acc_handle;
+	struct aac_raw_io2 *io = (struct aac_raw_io2 *)&acp->slotp->fibp->data[0];
+	struct aac_sge_ieee1212 *sgp;
+	struct aac_sge *sge = &acp->sgt[0];
+	uint_t i, left_cookien, conformable;
+	uint32_t min_size, cur_size, nom_size;
+	uint16_t flags;
+
+	if (acp->segment_cnt > 1) {
+		uint_t idx = acp->cur_segment;
+		left_cookien = acp->segments[idx].left_cookien;
+		acp->bcount = acp->segments[idx].abp_size;
+		sge = acp->segments[idx].sgt;
+		if (idx > 0) 
+			acp->blkno += acp->segments[idx-1].abp_size / AAC_BLK_SIZE;
+	} else
+		left_cookien = acp->left_cookien;
+
+	ddi_put32(acc, &io->strtBlkLow, AAC_LS32(acp->blkno));
+	ddi_put32(acc, &io->strtBlkHigh, AAC_MS32(acp->blkno));
+	ddi_put32(acc, &io->byteCnt, acp->bcount);
+	ddi_put16(acc, &io->ldNum,
+	    ((struct aac_container *)acp->dvp)->cid);
+	flags = (acp->flags & AAC_CMD_BUF_READ) ? 
+		RIO2_IO_TYPE_READ : RIO2_IO_TYPE_WRITE;
+	flags |= RIO2_SG_FORMAT_IEEE1212;
+
+	/* Fill SG table */
+	for (i = 0, sgp = &io->sge[0]; i < left_cookien; i++, sge++, sgp++) {
+		ddi_put32(acc, &sgp->addrLow, sge->addr.ad64.lo);
+		ddi_put32(acc, &sgp->addrHigh, sge->addr.ad64.hi);
+		ddi_put32(acc, &sgp->length, sge->bcount);
+		ddi_put32(acc, &sgp->flags, 0L);
+		cur_size = sge->bcount;
+		if (i == 0) {
+			conformable = 1;
+			ddi_put32(acc, &io->sgeFirstSize, cur_size);
+		} else if (i == 1) {
+			nom_size = cur_size;
+			ddi_put32(acc, &io->sgeNominalSize, nom_size);
+			min_size = cur_size;
+		} else if ((i+1) < left_cookien && cur_size != nom_size) {
+			conformable = 0;
+			if (cur_size < min_size)
+				min_size = cur_size;
+		}
+	}
+
+	/* not conformable: evaluate required sg elements */
+	if (!conformable) {
+		uint_t j, err_found, left_cookien_new = left_cookien;
+		for (i = min_size / AAC_PAGE_SIZE; i >= 1; --i) {
+			err_found = 0;
+			left_cookien_new = 2;
+			for (j = 1; j < left_cookien - 1; ++j) {
+				if (ddi_get32(acc, &io->sge[j].length) % (i*AAC_PAGE_SIZE)) {
+					err_found = 1;
+					break;
+				}
+				left_cookien_new += (ddi_get32(acc, &io->sge[j].length) / (i*AAC_PAGE_SIZE));
+			}
+			if (!err_found)
+				break;
+		}
+		if (i > 0 && left_cookien_new <= softs->aac_sg_tablesize && 
+			!softs->no_sgl_conv)
+			left_cookien = aac_convert_sgraw2(softs, 
+				acp, i, left_cookien, left_cookien_new, &flags);
+	} else {
+		flags |= RIO2_SGL_CONFORMANT;
+	}
+	ddi_put16(acc, &io->flags, flags);
+	ddi_put8(acc, &io->sgeCnt, left_cookien);
+
+	/* Calculate FIB size */
+	acp->fib_size = sizeof (struct aac_fib_header) + \
+	    sizeof (struct aac_raw_io2) + (left_cookien - 1) * \
+	    sizeof (struct aac_sge_ieee1212);
+
+	aac_cmd_fib_header(softs, acp->slotp, RawIo2, acp->fib_size);
+}
+
+
+static uint_t 
+aac_convert_sgraw2(struct aac_softstate *softs, struct aac_cmd *acp,
+				   uint_t pages, uint_t left_cookien, uint_t left_cookien_new,
+				   uint16_t *flags)
+{
+	ddi_acc_handle_t acc = acp->slotp->fib_acc_handle;
+	struct aac_raw_io2 *io = (struct aac_raw_io2 *)&acp->slotp->fibp->data[0];
+	struct aac_sge_ieee1212 *sge;
+	uint_t i, j, pos;
+	uint32_t addr_low_new, addr_low;
+
+	sge = kmem_alloc(left_cookien_new * sizeof(struct aac_sge_ieee1212), 
+					 KM_NOSLEEP);
+	if (sge == NULL)
+		return left_cookien;
+
+	for (i = 1, pos = 1; i < left_cookien-1; ++i) {
+		for (j = 0; j < ddi_get32(acc, &io->sge[i].length) / (pages * AAC_PAGE_SIZE); ++j) {
+			addr_low = ddi_get32(acc, &io->sge[i].addrLow);
+			addr_low_new = addr_low + j * pages * AAC_PAGE_SIZE;
+			sge[pos].addrLow = addr_low_new;
+			sge[pos].addrHigh = ddi_get32(acc, &io->sge[i].addrHigh);
+			if (addr_low_new < addr_low)
+				sge[pos].addrHigh++;
+			sge[pos].length = pages * AAC_PAGE_SIZE;
+			sge[pos].flags = 0;
+			pos++;
+		}
+	}
+	sge[pos].addrLow = ddi_get32(acc, &io->sge[left_cookien-1].addrLow);
+	sge[pos].addrHigh = ddi_get32(acc, &io->sge[left_cookien-1].addrHigh);
+	sge[pos].length = ddi_get32(acc, &io->sge[left_cookien-1].length);
+	sge[pos].flags = 0;
+	ddi_rep_put8(acc, (uint8_t *)&sge[1], 
+		(uint8_t *)&io->sge[1], (left_cookien_new-1) *
+		sizeof(struct aac_sge_ieee1212), DDI_DEV_AUTOINCR);
+
+	kmem_free(sge, left_cookien_new * sizeof(struct aac_sge_ieee1212));
+	*flags |= RIO2_SGL_CONFORMANT;
+	ddi_put32(acc, &io->sgeNominalSize, pages * AAC_PAGE_SIZE);
+	return left_cookien_new;
+}
+
+/*
  * Init FIB for raw IO command
  */
 static void
@@ -5589,14 +5529,25 @@
 	ddi_acc_handle_t acc = acp->slotp->fib_acc_handle;
 	struct aac_raw_io *io = (struct aac_raw_io *)&acp->slotp->fibp->data[0];
 	struct aac_sg_entryraw *sgp;
-	struct aac_sge *sge;
+	struct aac_sge *sge = &acp->sgt[0];
+	uint_t i, left_cookien;
 
+	if (acp->segment_cnt > 1) {
+		uint_t idx = acp->cur_segment;
+		left_cookien = acp->segments[idx].left_cookien;
+		acp->bcount = acp->segments[idx].abp_size;
+		sge = acp->segments[idx].sgt;
+		if (idx > 0) 
+			acp->blkno += acp->segments[idx-1].abp_size / AAC_BLK_SIZE;
+	} else
+		left_cookien = acp->left_cookien;
+
 	/* Calculate FIB size */
 	acp->fib_size = sizeof (struct aac_fib_header) + \
-	    sizeof (struct aac_raw_io) + (acp->left_cookien - 1) * \
+	    sizeof (struct aac_raw_io) + (left_cookien - 1) * \
 	    sizeof (struct aac_sg_entryraw);
 
-	aac_cmd_fib_header(softs, acp, RawIo);
+	aac_cmd_fib_header(softs, acp->slotp, RawIo, acp->fib_size);
 
 	ddi_put16(acc, &io->Flags, (acp->flags & AAC_CMD_BUF_READ) ? 1 : 0);
 	ddi_put16(acc, &io->BpTotal, 0);
@@ -5608,11 +5559,11 @@
 	    ((struct aac_container *)acp->dvp)->cid);
 
 	/* Fill SG table */
-	ddi_put32(acc, &io->SgMapRaw.SgCount, acp->left_cookien);
+	ddi_put32(acc, &io->SgMapRaw.SgCount, left_cookien);
 	ddi_put32(acc, &io->ByteCount, acp->bcount);
 
-	for (sge = &acp->sgt[0], sgp = &io->SgMapRaw.SgEntryRaw[0];
-	    sge < &acp->sgt[acp->left_cookien]; sge++, sgp++) {
+	for (i = 0, sgp = &io->SgMapRaw.SgEntryRaw[0]; 
+		i < left_cookien; i++, sge++, sgp++) {
 		ddi_put32(acc, AAC_LO32(&sgp->SgAddress), sge->addr.ad64.lo);
 		ddi_put32(acc, AAC_HI32(&sgp->SgAddress), sge->addr.ad64.hi);
 		ddi_put32(acc, &sgp->SgByteCount, sge->bcount);
@@ -5630,13 +5581,25 @@
 	struct aac_blockread64 *br = (struct aac_blockread64 *) \
 	    &acp->slotp->fibp->data[0];
 	struct aac_sg_entry64 *sgp;
-	struct aac_sge *sge;
+	struct aac_sge *sge = &acp->sgt[0];
+	uint_t i, left_cookien;
 
+	if (acp->segment_cnt > 1) {
+		uint_t idx = acp->cur_segment;
+		left_cookien = acp->segments[idx].left_cookien;
+		acp->bcount = acp->segments[idx].abp_size;
+		sge = acp->segments[idx].sgt;
+		if (idx > 0) 
+			acp->blkno += acp->segments[idx-1].abp_size / AAC_BLK_SIZE;
+	} else
+		left_cookien = acp->left_cookien;
+
 	acp->fib_size = sizeof (struct aac_fib_header) + \
-	    sizeof (struct aac_blockread64) + (acp->left_cookien - 1) * \
+	    sizeof (struct aac_blockread64) + (left_cookien - 1) * \
 	    sizeof (struct aac_sg_entry64);
 
-	aac_cmd_fib_header(softs, acp, ContainerCommand64);
+	aac_cmd_fib_header(softs, acp->slotp, ContainerCommand64,
+	    acp->fib_size);
 
 	/*
 	 * The definitions for aac_blockread64 and aac_blockwrite64
@@ -5651,11 +5614,11 @@
 	ddi_put16(acc, &br->Flags, 0);
 
 	/* Fill SG table */
-	ddi_put32(acc, &br->SgMap64.SgCount, acp->left_cookien);
+	ddi_put32(acc, &br->SgMap64.SgCount, left_cookien);
 	ddi_put16(acc, &br->SectorCount, acp->bcount / AAC_BLK_SIZE);
 
-	for (sge = &acp->sgt[0], sgp = &br->SgMap64.SgEntry64[0];
-	    sge < &acp->sgt[acp->left_cookien]; sge++, sgp++) {
+	for (i = 0, sgp = &br->SgMap64.SgEntry64[0];
+	    i < left_cookien; i++, sge++, sgp++) {
 		ddi_put32(acc, AAC_LO32(&sgp->SgAddress), sge->addr.ad64.lo);
 		ddi_put32(acc, AAC_HI32(&sgp->SgAddress), sge->addr.ad64.hi);
 		ddi_put32(acc, &sgp->SgByteCount, sge->bcount);
@@ -5671,28 +5634,39 @@
 	    &acp->slotp->fibp->data[0];
 	struct aac_sg_entry *sgp;
 	struct aac_sge *sge = &acp->sgt[0];
+	uint_t i, left_cookien;
 
+	if (acp->segment_cnt > 1) {
+		uint_t idx = acp->cur_segment;
+		left_cookien = acp->segments[idx].left_cookien;
+		acp->bcount = acp->segments[idx].abp_size;
+		sge = acp->segments[idx].sgt;
+		if (idx > 0) 
+			acp->blkno += acp->segments[idx-1].abp_size / AAC_BLK_SIZE;
+	} else
+		left_cookien = acp->left_cookien;
+
 	if (acp->flags & AAC_CMD_BUF_READ) {
 		acp->fib_size = sizeof (struct aac_fib_header) + \
-		    sizeof (struct aac_blockread) + (acp->left_cookien - 1) * \
+		    sizeof (struct aac_blockread) + (left_cookien - 1) * \
 		    sizeof (struct aac_sg_entry);
 
 		ddi_put32(acc, &br->Command, VM_CtBlockRead);
-		ddi_put32(acc, &br->SgMap.SgCount, acp->left_cookien);
+		ddi_put32(acc, &br->SgMap.SgCount, left_cookien);
 		sgp = &br->SgMap.SgEntry[0];
 	} else {
 		struct aac_blockwrite *bw = (struct aac_blockwrite *)br;
 
 		acp->fib_size = sizeof (struct aac_fib_header) + \
-		    sizeof (struct aac_blockwrite) + (acp->left_cookien - 1) * \
+		    sizeof (struct aac_blockwrite) + (left_cookien - 1) * \
 		    sizeof (struct aac_sg_entry);
 
 		ddi_put32(acc, &bw->Command, VM_CtBlockWrite);
 		ddi_put32(acc, &bw->Stable, CUNSTABLE);
-		ddi_put32(acc, &bw->SgMap.SgCount, acp->left_cookien);
+		ddi_put32(acc, &bw->SgMap.SgCount, left_cookien);
 		sgp = &bw->SgMap.SgEntry[0];
 	}
-	aac_cmd_fib_header(softs, acp, ContainerCommand);
+	aac_cmd_fib_header(softs, acp->slotp, ContainerCommand, acp->fib_size);
 
 	/*
 	 * aac_blockread and aac_blockwrite have the similar
@@ -5704,8 +5678,7 @@
 	ddi_put32(acc, &br->ByteCount, acp->bcount);
 
 	/* Fill SG table */
-	for (sge = &acp->sgt[0];
-	    sge < &acp->sgt[acp->left_cookien]; sge++, sgp++) {
+	for (i = 0; i < left_cookien; i++, sge++, sgp++) {
 		ddi_put32(acc, &sgp->SgAddress, sge->addr.ad32);
 		ddi_put32(acc, &sgp->SgByteCount, sge->bcount);
 	}
@@ -5722,20 +5695,23 @@
 	ddi_rep_put8(acc, (uint8_t *)acp->fibp, (uint8_t *)fibp,
 	    acp->fib_size,   /* only copy data of needed length */
 	    DDI_DEV_AUTOINCR);
-	ddi_put32(acc, &fibp->Header.ReceiverFibAddress, slotp->fib_phyaddr);
+	ddi_put32(acc, &fibp->Header.a.ReceiverFibAddress,slotp->fib_phyaddr);
 	ddi_put32(acc, &fibp->Header.SenderFibAddress, slotp->index << 2);
+	ddi_put32(acc, &fibp->Header.Handle, slotp->index + 1);
 }
 
 static void
 aac_cmd_fib_sync(struct aac_softstate *softs, struct aac_cmd *acp)
 {
-	ddi_acc_handle_t acc = acp->slotp->fib_acc_handle;
+	struct aac_slot *slotp = acp->slotp;
+	ddi_acc_handle_t acc = slotp->fib_acc_handle;
 	struct aac_synchronize_command *sync =
-	    (struct aac_synchronize_command *)&acp->slotp->fibp->data[0];
+	    (struct aac_synchronize_command *)&slotp->fibp->data[0];
 
-	acp->fib_size = AAC_FIB_SIZEOF(struct aac_synchronize_command);
+	acp->fib_size = sizeof (struct aac_fib_header) + \
+	    sizeof (struct aac_synchronize_command);
 
-	aac_cmd_fib_header(softs, acp, ContainerCommand);
+	aac_cmd_fib_header(softs, slotp, ContainerCommand, acp->fib_size);
 	ddi_put32(acc, &sync->Command, VM_ContainerConfig);
 	ddi_put32(acc, &sync->Type, (uint32_t)CT_FLUSH_CACHE);
 	ddi_put32(acc, &sync->Cid, ((struct aac_container *)acp->dvp)->cid);
@@ -5743,28 +5719,18 @@
 	    sizeof (((struct aac_synchronize_reply *)0)->Data));
 }
 
-/*
- * Start/Stop unit (Power Management)
- */
 static void
-aac_cmd_fib_startstop(struct aac_softstate *softs, struct aac_cmd *acp)
+aac_cmd_aif_request(struct aac_softstate *softs, struct aac_cmd *acp)
 {
-	ddi_acc_handle_t acc = acp->slotp->fib_acc_handle;
-	struct aac_Container *cmd =
-	    (struct aac_Container *)&acp->slotp->fibp->data[0];
-	union scsi_cdb *cdbp = (void *)acp->pkt->pkt_cdbp;
+	struct aac_slot *slotp = acp->slotp;
+	ddi_acc_handle_t acc = slotp->fib_acc_handle;
+	struct aac_aif_command *aif =
+	    (struct aac_aif_command *)&slotp->fibp->data[0];
 
-	acp->fib_size = AAC_FIB_SIZEOF(struct aac_Container);
+	acp->fib_size = sizeof(struct aac_fib);
 
-	aac_cmd_fib_header(softs, acp, ContainerCommand);
-	bzero(cmd, sizeof (*cmd) - CT_PACKET_SIZE);
-	ddi_put32(acc, &cmd->Command, VM_ContainerConfig);
-	ddi_put32(acc, &cmd->CTCommand.command, CT_PM_DRIVER_SUPPORT);
-	ddi_put32(acc, &cmd->CTCommand.param[0], cdbp->cdb_opaque[4] & 1 ? \
-	    AAC_PM_DRIVERSUP_START_UNIT : AAC_PM_DRIVERSUP_STOP_UNIT);
-	ddi_put32(acc, &cmd->CTCommand.param[1],
-	    ((struct aac_container *)acp->dvp)->cid);
-	ddi_put32(acc, &cmd->CTCommand.param[2], cdbp->cdb_opaque[1] & 1);
+	aac_cmd_fib_header(softs, slotp, AifRequest, acp->fib_size);
+	ddi_put32(acc, (uint32_t *)&aif->command, AifReqEvent);
 }
 
 /*
@@ -5773,8 +5739,9 @@
 static void
 aac_cmd_fib_srb(struct aac_cmd *acp)
 {
-	ddi_acc_handle_t acc = acp->slotp->fib_acc_handle;
-	struct aac_srb *srb = (struct aac_srb *)&acp->slotp->fibp->data[0];
+	struct aac_slot *slotp = acp->slotp;
+	ddi_acc_handle_t acc = slotp->fib_acc_handle;
+	struct aac_srb *srb = (struct aac_srb *)&slotp->fibp->data[0];
 	uint8_t *cdb;
 
 	ddi_put32(acc, &srb->function, SRBF_ExecuteScsi);
@@ -5816,7 +5783,7 @@
 	    acp->left_cookien * sizeof (struct aac_sg_entry);
 
 	/* Fill FIB and SRB headers, and copy cdb */
-	aac_cmd_fib_header(softs, acp, ScsiPortCommand);
+	aac_cmd_fib_header(softs, acp->slotp, ScsiPortCommand, acp->fib_size);
 	aac_cmd_fib_srb(acp);
 
 	/* Fill SG table */
@@ -5843,7 +5810,8 @@
 	    acp->left_cookien * sizeof (struct aac_sg_entry64);
 
 	/* Fill FIB and SRB headers, and copy cdb */
-	aac_cmd_fib_header(softs, acp, ScsiPortCommandU64);
+	aac_cmd_fib_header(softs, acp->slotp, ScsiPortCommandU64,
+	    acp->fib_size);
 	aac_cmd_fib_srb(acp);
 
 	/* Fill SG table */
@@ -5864,12 +5832,20 @@
 {
 	struct aac_slot *slotp;
 
+	if ((softs->flags & AAC_FLAGS_SYNC_MODE) &&
+		softs->sync_slot_busy)
+		return (AACERR);
+
 	if (slotp = aac_get_slot(softs)) {
 		acp->slotp = slotp;
 		slotp->acp = acp;
 		acp->aac_cmd_fib(softs, acp);
 		(void) ddi_dma_sync(slotp->fib_dma_handle, 0, 0,
-		    DDI_DMA_SYNC_FORDEV);
+			DDI_DMA_SYNC_FORDEV);
+		if (softs->flags & AAC_FLAGS_SYNC_MODE) {
+			softs->sync_slot_busy = 1;
+			softs->sync_mode_slot = slotp;
+		}
 		return (AACOK);
 	}
 	return (AACERR);
@@ -5881,55 +5857,25 @@
 	struct aac_device *dvp = acp->dvp;
 	int q = AAC_CMDQ(acp);
 
-	if (softs->bus_ncmds[q] < softs->bus_throttle[q]) {
-		if (dvp) {
-			if (dvp->ncmds[q] < dvp->throttle[q]) {
-				if (!(acp->flags & AAC_CMD_NTAG) ||
-				    dvp->ncmds[q] == 0) {
-					return (aac_cmd_slot_bind(softs, acp));
-				}
-				ASSERT(q == AAC_CMDQ_ASYNC);
-				aac_set_throttle(softs, dvp, AAC_CMDQ_ASYNC,
-				    AAC_THROTTLE_DRAIN);
+	if (dvp) {
+		if (dvp->ncmds[q] < dvp->throttle[q]) {
+			if (!(acp->flags & AAC_CMD_NTAG) ||
+			    dvp->ncmds[q] == 0) {
+do_bind:
+				return (aac_cmd_slot_bind(softs, acp));
 			}
-		} else {
-			return (aac_cmd_slot_bind(softs, acp));
+			ASSERT(q == AAC_CMDQ_ASYNC);
+			aac_set_throttle(softs, dvp, AAC_CMDQ_ASYNC,
+			    AAC_THROTTLE_DRAIN);
 		}
+	} else {
+		if (softs->bus_ncmds[q] < softs->bus_throttle[q])
+			goto do_bind;
 	}
 	return (AACERR);
 }
 
-static int
-aac_sync_fib_slot_bind(struct aac_softstate *softs, struct aac_cmd *acp)
-{
-	struct aac_slot *slotp;
-
-	while (softs->sync_ac.slotp)
-		cv_wait(&softs->sync_fib_cv, &softs->io_lock);
-
-	if (slotp = aac_get_slot(softs)) {
-		ASSERT(acp->slotp == NULL);
-
-		acp->slotp = slotp;
-		slotp->acp = acp;
-		return (AACOK);
-	}
-	return (AACERR);
-}
-
 static void
-aac_sync_fib_slot_release(struct aac_softstate *softs, struct aac_cmd *acp)
-{
-	ASSERT(acp->slotp);
-
-	aac_release_slot(softs, acp->slotp);
-	acp->slotp->acp = NULL;
-	acp->slotp = NULL;
-
-	cv_signal(&softs->sync_fib_cv);
-}
-
-static void
 aac_start_io(struct aac_softstate *softs, struct aac_cmd *acp)
 {
 	struct aac_slot *slotp = acp->slotp;
@@ -5949,10 +5895,13 @@
 	softs->bus_ncmds[q]++;
 	aac_cmd_enqueue(&softs->q_busy, acp);
 
-	AACDB_PRINT_FIB(softs, slotp);
 
-	if (softs->flags & AAC_FLAGS_NEW_COMM) {
-		rval = aac_send_command(softs, slotp);
+	if (softs->flags & AAC_FLAGS_SYNC_MODE) {
+		uint32_t wait = 0;
+		rval = aac_sync_mbcommand(softs, AAC_MONKER_SYNCFIB,
+			slotp->fib_phyaddr, 0, 0, 0, &wait, NULL);
+	} else if (softs->flags & AAC_FLAGS_NEW_COMM) {
+		rval = AAC_SEND_COMMAND(softs, slotp);
 	} else {
 		/*
 		 * If fib can not be enqueued, the adapter is in an abnormal
@@ -5963,7 +5912,7 @@
 	}
 
 	if (aac_check_dma_handle(slotp->fib_dma_handle) != DDI_SUCCESS)
-		ddi_fm_service_impact(softs->devinfo_p, DDI_SERVICE_UNAFFECTED);
+		aac_fm_service_impact(softs->devinfo_p, DDI_SERVICE_UNAFFECTED);
 
 	/*
 	 * NOTE: We send command only when slots availabe, so should never
@@ -6033,7 +5982,7 @@
 				if ((acp->flags & AAC_CMD_CONSISTENT) &&
 				    (acp->flags & AAC_CMD_BUF_READ)) {
 					if (aac_dma_sync_ac(acp) != AACOK) {
-						ddi_fm_service_impact(
+						aac_fm_service_impact(
 						    softs->devinfo_p,
 						    DDI_SERVICE_UNAFFECTED);
 						pkt->pkt_reason = CMD_TRAN_ERR;
@@ -6043,23 +5992,23 @@
 				if ((aac_check_acc_handle(softs-> \
 				    comm_space_acc_handle) != DDI_SUCCESS) ||
 				    (aac_check_acc_handle(softs-> \
-				    pci_mem_handle) != DDI_SUCCESS)) {
-					ddi_fm_service_impact(softs->devinfo_p,
+				    pci_mem_handle[0]) != DDI_SUCCESS)) {
+					aac_fm_service_impact(softs->devinfo_p,
 					    DDI_SERVICE_UNAFFECTED);
-					ddi_fm_acc_err_clear(softs-> \
-					    pci_mem_handle, DDI_FME_VER0);
+					aac_fm_acc_err_clear(softs-> \
+					    pci_mem_handle[0], DDI_FME_VER0);
 					pkt->pkt_reason = CMD_TRAN_ERR;
 					pkt->pkt_statistics = 0;
 				}
 				if (aac_check_dma_handle(softs-> \
 				    comm_space_dma_handle) != DDI_SUCCESS) {
-					ddi_fm_service_impact(softs->devinfo_p,
+					aac_fm_service_impact(softs->devinfo_p,
 					    DDI_SERVICE_UNAFFECTED);
 					pkt->pkt_reason = CMD_TRAN_ERR;
 					pkt->pkt_statistics = 0;
 				}
 			}
-			scsi_hba_pkt_comp(pkt);
+			(*pkt->pkt_comp)(pkt);
 		} else {
 			break;
 		}
@@ -6069,7 +6018,7 @@
 static int
 aac_alloc_fib(struct aac_softstate *softs, struct aac_slot *slotp)
 {
-	size_t rlen;
+	size_t rlen, maxsize;
 	ddi_dma_cookie_t cookie;
 	uint_t cookien;
 
@@ -6084,10 +6033,17 @@
 		    "Cannot alloc dma handle for slot fib area");
 		goto error;
 	}
+
+	if (softs->flags & AAC_FLAGS_NEW_COMM_TYPE1) 
+		maxsize = softs->aac_max_fib_size + sizeof(struct aac_fib_xporthdr) + 31;
+	else if (softs->flags & AAC_FLAGS_NEW_COMM_TYPE2) 
+		maxsize = softs->aac_max_fib_size + 31;
+	else
+		maxsize = softs->aac_max_fib_size;
 	if (ddi_dma_mem_alloc(
 	    slotp->fib_dma_handle,
-	    softs->aac_max_fib_size,
-	    &softs->acc_attr,
+	    maxsize,
+	    &aac_acc_attr,
 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
 	    DDI_DMA_SLEEP,
 	    NULL,
@@ -6102,7 +6058,7 @@
 	    slotp->fib_dma_handle,
 	    NULL,
 	    (caddr_t)slotp->fibp,
-	    softs->aac_max_fib_size,
+	    maxsize,
 	    DDI_DMA_RDWR | DDI_DMA_CONSISTENT,
 	    DDI_DMA_SLEEP,
 	    NULL,
@@ -6115,17 +6071,32 @@
 
 	/* Check dma handles allocated in fib attach */
 	if (aac_check_dma_handle(slotp->fib_dma_handle) != DDI_SUCCESS) {
-		ddi_fm_service_impact(softs->devinfo_p, DDI_SERVICE_LOST);
+		aac_fm_service_impact(softs->devinfo_p, DDI_SERVICE_LOST);
 		goto error;
 	}
 
 	/* Check acc handles allocated in fib attach */
 	if (aac_check_acc_handle(slotp->fib_acc_handle) != DDI_SUCCESS) {
-		ddi_fm_service_impact(softs->devinfo_p, DDI_SERVICE_LOST);
+		aac_fm_service_impact(softs->devinfo_p, DDI_SERVICE_LOST);
 		goto error;
 	}
 
 	slotp->fib_phyaddr = cookie.dmac_laddress;
+	if (softs->flags & AAC_FLAGS_NEW_COMM_TYPE1) {
+		uint64_t fibphys_aligned;
+		fibphys_aligned = 
+			(slotp->fib_phyaddr + sizeof(struct aac_fib_xporthdr) + 31) & ~31;
+		slotp->fibp = (struct aac_fib *)
+			((uint8_t *)slotp->fibp + (fibphys_aligned - slotp->fib_phyaddr));
+		slotp->fib_phyaddr = fibphys_aligned;
+	} else if (softs->flags & AAC_FLAGS_NEW_COMM_TYPE2) {
+		uint64_t fibphys_aligned;
+		fibphys_aligned = 
+			(slotp->fib_phyaddr + 31) & ~31;
+		slotp->fibp = (struct aac_fib *)
+			((uint8_t *)slotp->fibp + (fibphys_aligned - slotp->fib_phyaddr));
+		slotp->fib_phyaddr = fibphys_aligned;
+	}
 	return (AACOK);
 
 error:
@@ -6169,6 +6140,7 @@
 		aac_release_slot(softs, slotp);
 		softs->total_fibs++;
 	}
+	aac_alloc_fib(softs, softs->sync_slot);
 }
 
 static void
@@ -6184,6 +6156,7 @@
 		softs->total_fibs--;
 	}
 	ASSERT(softs->total_fibs == 0);
+	aac_free_fib(softs->sync_slot);
 }
 
 static int
@@ -6192,8 +6165,12 @@
 	int i;
 
 	softs->total_slots = softs->aac_max_fibs;
+	/* FIXME: patch max. outstanding commands */
+	if (softs->total_slots > 1) 
+		softs->total_slots -= 1;
+
 	softs->io_slot = kmem_zalloc(sizeof (struct aac_slot) * \
-	    softs->total_slots, KM_SLEEP);
+	    (softs->total_slots + 1), KM_SLEEP);
 	if (softs->io_slot == NULL) {
 		AACDB_PRINT(softs, CE_WARN, "Cannot allocate slot");
 		return (AACERR);
@@ -6202,6 +6179,7 @@
 		softs->io_slot[i].index = i;
 	softs->free_io_slot_head = NULL;
 	softs->total_fibs = 0;
+	softs->sync_slot = &softs->io_slot[softs->total_slots];
 	return (AACOK);
 }
 
@@ -6211,9 +6189,10 @@
 	ASSERT(softs->free_io_slot_head == NULL);
 
 	kmem_free(softs->io_slot, sizeof (struct aac_slot) * \
-	    softs->total_slots);
+	    (softs->total_slots + 1));
 	softs->io_slot = NULL;
 	softs->total_slots = 0;
+	softs->sync_slot = NULL;
 }
 
 struct aac_slot *
@@ -6271,8 +6250,14 @@
 	/*
 	 * Interrupt is disabled, we have to poll the adapter by ourselves.
 	 */
-	intr_handler = (softs->flags & AAC_FLAGS_NEW_COMM) ?
-	    aac_process_intr_new : aac_process_intr_old;
+	if ((softs->flags & AAC_FLAGS_NEW_COMM_TYPE1) || 
+		(softs->flags & AAC_FLAGS_NEW_COMM_TYPE2) ||
+		(softs->flags & AAC_FLAGS_NEW_COMM_TYPE34))
+		intr_handler = aac_process_intr_new_type1;
+	else if (softs->flags & AAC_FLAGS_NEW_COMM) 
+		intr_handler = aac_process_intr_new;
+	else
+		intr_handler = aac_process_intr_old;
 	while (!(acp->flags & (AAC_CMD_CMPLT | AAC_CMD_ABORT))) {
 		int i = AAC_POLL_TIME * 1000;
 
@@ -6304,140 +6289,44 @@
 static int
 aac_dma_sync_ac(struct aac_cmd *acp)
 {
-	if (acp->buf_dma_handle) {
+	uint_t i;
+	uint32_t offset;
+	int rval = AACOK;
+
+	for (i = 0, offset = 0; i < acp->segment_cnt; ++i) {
+		if (!acp->segments[i].buf_dma_handle) {
+			offset += acp->segments[i].abp_size;
+			continue;
+		}
 		if (acp->flags & AAC_CMD_BUF_WRITE) {
-			if (acp->abp != NULL)
-				ddi_rep_put8(acp->abh,
-				    (uint8_t *)acp->bp->b_un.b_addr,
-				    (uint8_t *)acp->abp, acp->bp->b_bcount,
-				    DDI_DEV_AUTOINCR);
-			(void) ddi_dma_sync(acp->buf_dma_handle, 0, 0,
-			    DDI_DMA_SYNC_FORDEV);
+			if (acp->segments[i].abp != NULL) {
+				ddi_rep_put8(acp->segments[i].abh,
+					(uint8_t *)acp->bp->b_un.b_addr + offset,
+					(uint8_t *)acp->segments[i].abp, 
+					acp->segments[i].abp_size,
+					DDI_DEV_AUTOINCR);
+			}
+			(void) ddi_dma_sync(acp->segments[i].buf_dma_handle, 
+				0, 0, DDI_DMA_SYNC_FORDEV);
 		} else {
-			(void) ddi_dma_sync(acp->buf_dma_handle, 0, 0,
-			    DDI_DMA_SYNC_FORCPU);
-			if (aac_check_dma_handle(acp->buf_dma_handle) !=
-			    DDI_SUCCESS)
-				return (AACERR);
-			if (acp->abp != NULL)
-				ddi_rep_get8(acp->abh,
-				    (uint8_t *)acp->bp->b_un.b_addr,
-				    (uint8_t *)acp->abp, acp->bp->b_bcount,
-				    DDI_DEV_AUTOINCR);
-		}
-	}
-	return (AACOK);
-}
-
-/*
- * Copy AIF from adapter to the empty AIF slot and inform AIF threads
- */
-static void
-aac_save_aif(struct aac_softstate *softs, ddi_acc_handle_t acc,
-    struct aac_fib *fibp0, int fib_size0)
-{
-	struct aac_fib *fibp;	/* FIB in AIF queue */
-	int fib_size;
-	uint16_t fib_command;
-	int current, next;
-
-	/* Ignore non AIF messages */
-	fib_command = ddi_get16(acc, &fibp0->Header.Command);
-	if (fib_command != AifRequest) {
-		cmn_err(CE_WARN, "!Unknown command from controller");
-		return;
-	}
-
-	mutex_enter(&softs->aifq_mutex);
-
-	/* Save AIF */
-	fibp = &softs->aifq[softs->aifq_idx].d;
-	fib_size = (fib_size0 > AAC_FIB_SIZE) ? AAC_FIB_SIZE : fib_size0;
-	ddi_rep_get8(acc, (uint8_t *)fibp, (uint8_t *)fibp0, fib_size,
-	    DDI_DEV_AUTOINCR);
-
-	if (aac_check_acc_handle(softs->pci_mem_handle) != DDI_SUCCESS) {
-		ddi_fm_service_impact(softs->devinfo_p,
-		    DDI_SERVICE_UNAFFECTED);
-		mutex_exit(&softs->aifq_mutex);
-		return;
-	}
-
-	AACDB_PRINT_AIF(softs, (struct aac_aif_command *)&fibp->data[0]);
-
-	/* Modify AIF contexts */
-	current = softs->aifq_idx;
-	next = (current + 1) % AAC_AIFQ_LENGTH;
-	if (next == 0) {
-		struct aac_fib_context *ctx_p;
-
-		softs->aifq_wrap = 1;
-		for (ctx_p = softs->fibctx_p; ctx_p; ctx_p = ctx_p->next) {
-			if (next == ctx_p->ctx_idx) {
-				ctx_p->ctx_flags |= AAC_CTXFLAG_FILLED;
-			} else if (current == ctx_p->ctx_idx &&
-			    (ctx_p->ctx_flags & AAC_CTXFLAG_FILLED)) {
-				ctx_p->ctx_idx = next;
-				ctx_p->ctx_overrun++;
+			(void) ddi_dma_sync(acp->segments[i].buf_dma_handle, 
+				0, 0, DDI_DMA_SYNC_FORCPU);
+			if (aac_check_dma_handle(acp->segments[i].buf_dma_handle) !=
+			    DDI_SUCCESS) {
+				rval = AACERR;
+			} else if (acp->segments[i].abp != NULL) {
+				ddi_rep_get8(acp->segments[i].abh,
+					(uint8_t *)acp->bp->b_un.b_addr + offset,
+					(uint8_t *)acp->segments[i].abp, 
+					acp->segments[i].abp_size,
+					DDI_DEV_AUTOINCR);
 			}
 		}
+		offset += acp->segments[i].abp_size;
 	}
-	softs->aifq_idx = next;
-
-	/* Wakeup AIF threads */
-	cv_broadcast(&softs->aifq_cv);
-	mutex_exit(&softs->aifq_mutex);
-
-	/* Wakeup event thread to handle aif */
-	aac_event_disp(softs, AAC_EVENT_AIF);
-}
-
-static int
-aac_return_aif_common(struct aac_softstate *softs, struct aac_fib_context *ctx,
-    struct aac_fib **fibpp)
-{
-	int current;
-
-	current = ctx->ctx_idx;
-	if (current == softs->aifq_idx &&
-	    !(ctx->ctx_flags & AAC_CTXFLAG_FILLED))
-		return (EAGAIN); /* Empty */
-
-	*fibpp = &softs->aifq[current].d;
-
-	ctx->ctx_flags &= ~AAC_CTXFLAG_FILLED;
-	ctx->ctx_idx = (current + 1) % AAC_AIFQ_LENGTH;
-	return (0);
-}
-
-int
-aac_return_aif(struct aac_softstate *softs, struct aac_fib_context *ctx,
-    struct aac_fib **fibpp)
-{
-	int rval;
-
-	mutex_enter(&softs->aifq_mutex);
-	rval = aac_return_aif_common(softs, ctx, fibpp);
-	mutex_exit(&softs->aifq_mutex);
 	return (rval);
 }
 
-int
-aac_return_aif_wait(struct aac_softstate *softs, struct aac_fib_context *ctx,
-    struct aac_fib **fibpp)
-{
-	int rval;
-
-	mutex_enter(&softs->aifq_mutex);
-	rval = aac_return_aif_common(softs, ctx, fibpp);
-	if (rval == EAGAIN) {
-		AACDB_PRINT(softs, CE_NOTE, "Waiting for AIF");
-		rval = cv_wait_sig(&softs->aifq_cv, &softs->aifq_mutex);
-	}
-	mutex_exit(&softs->aifq_mutex);
-	return ((rval > 0) ? 0 : EINTR);
-}
-
 /*
  * The following function comes from Adaptec:
  *
@@ -6449,26 +6338,37 @@
  * another particular event. When sees that events come in, it will do rescan.
  */
 static int
-aac_handle_aif(struct aac_softstate *softs, struct aac_aif_command *aif)
+aac_handle_aif(struct aac_softstate *softs, struct aac_fib *fibp)
 {
 	ddi_acc_handle_t acc = softs->comm_space_acc_handle;
+	uint16_t fib_command;
+	struct aac_aif_command *aif;
 	int en_type;
 	int devcfg_needed;
-	int cid;
-	uint32_t bus_id, tgt_id;
-	enum aac_cfg_event event = AAC_CFG_NULL_EXIST;
+	int current, next;
 
+	fib_command = LE_16(fibp->Header.Command);
+	if (fib_command != AifRequest) {
+		cmn_err(CE_NOTE, "!Unknown command from controller: 0x%x",
+		    fib_command);
+		return (AACERR);
+	}
+
+	/* Update internal container state */
+	aif = (struct aac_aif_command *)&fibp->data[0];
+
+	AACDB_PRINT_AIF(softs, aif);
 	devcfg_needed = 0;
 	en_type = LE_32((uint32_t)aif->data.EN.type);
 
 	switch (LE_32((uint32_t)aif->command)) {
 	case AifCmdDriverNotify: {
-		cid = LE_32(aif->data.EN.data.ECC.container[0]);
+		int cid = LE_32(aif->data.EN.data.ECC.container[0]);
 
 		switch (en_type) {
 		case AifDenMorphComplete:
 		case AifDenVolumeExtendComplete:
-			if (AAC_DEV_IS_VALID(&softs->containers[cid].dev))
+			if (cid < AAC_MAX_LD && softs->containers[cid].dev.valid)
 				softs->devcfg_wait_on = AifEnConfigChange;
 			break;
 		}
@@ -6478,7 +6378,6 @@
 	}
 
 	case AifCmdEventNotify:
-		cid = LE_32(aif->data.EN.data.ECC.container[0]);
 		switch (en_type) {
 		case AifEnAddContainer:
 		case AifEnDeleteContainer:
@@ -6494,18 +6393,9 @@
 				devcfg_needed = 1;
 			break;
 		case AifEnAddJBOD:
-			if (!(softs->flags & AAC_FLAGS_JBOD))
-				return (AACERR);
-			event = AAC_CFG_ADD;
-			bus_id = (cid >> 24) & 0xf;
-			tgt_id = cid & 0xffff;
-			break;
 		case AifEnDeleteJBOD:
-			if (!(softs->flags & AAC_FLAGS_JBOD))
-				return (AACERR);
-			event = AAC_CFG_DELETE;
-			bus_id = (cid >> 24) & 0xf;
-			tgt_id = cid & 0xffff;
+		case AifRawDeviceRemove:
+			timeout(aac_config_pd, softs, drv_usectohz(1000));
 			break;
 		}
 		if (softs->devcfg_wait_on == en_type)
@@ -6531,63 +6421,101 @@
 		break;
 	}
 
-	if (devcfg_needed) {
-		softs->devcfg_wait_on = 0;
+	if (devcfg_needed)
 		(void) aac_probe_containers(softs);
-	}
 
-	if (event != AAC_CFG_NULL_EXIST) {
-		ASSERT(en_type == AifEnAddJBOD || en_type == AifEnDeleteJBOD);
-		(void) aac_probe_jbod(softs,
-		    AAC_P2VTGT(softs, bus_id, tgt_id), event);
+	/* Modify AIF contexts */
+	current = softs->aifq_idx;
+	next = (current + 1) % AAC_AIFQ_LENGTH;
+	if (next == 0) {
+		struct aac_fib_context *ctx;
+
+		softs->aifq_wrap = 1;
+		for (ctx = softs->fibctx; ctx; ctx = ctx->next) {
+			if (next == ctx->ctx_idx) {
+				ctx->ctx_filled = 1;
+			} else if (current == ctx->ctx_idx && ctx->ctx_filled) {
+				ctx->ctx_idx = next;
+			}
+		}
 	}
+	softs->aifq_idx = next;
+
+	/* Wakeup applications */
+	cv_broadcast(&softs->aifv);
 	return (AACOK);
 }
 
-
 /*
- * Check and handle AIF events
+ * Timeout recovery
  */
 static void
-aac_aif_event(struct aac_softstate *softs)
+aac_cmd_timeout(struct aac_softstate *softs, struct aac_cmd *acp)
 {
-	struct aac_fib *fibp;
+	int rval;
 
-	/*CONSTCOND*/
-	while (1) {
-		if (aac_return_aif(softs, &softs->aifctx, &fibp) != 0)
-			break; /* No more AIFs to handle, end loop */
+	/* print timed out command */
+#ifdef AAC_DEBUG
+	{
+		struct aac_slot *slotp = acp->slotp;
+		ddi_acc_handle_t acc = slotp->fib_acc_handle;
+		uint16_t i, cmd, size;
+		uint8_t *dataptr;
+		uint8_t data[16];
+		uint32_t timeout;
 
-		/* AIF overrun, array create/delete may missed. */
-		if (softs->aifctx.ctx_overrun) {
-			softs->aifctx.ctx_overrun = 0;
+		timeout = acp->timeout - aac_timebase - aac_tick;
+		if (acp->ac_comp == aac_ld_complete) {
+			AACDB_PRINT(softs, CE_NOTE,
+				"Container command timed out, index %d timeout %d flags 0x%x id %d",
+				slotp->index, timeout, acp->flags,
+				((struct aac_container *)acp->dvp)->cid);
+		} else if (acp->ac_comp == aac_pd_complete) {
+			AACDB_PRINT(softs, CE_NOTE,
+				"Nondasd command timed out, index %d timeout %d flags 0x%x bus %d tid %d",
+				slotp->index, timeout, acp->flags,
+				((struct aac_nondasd *)acp->dvp)->bus,
+				((struct aac_nondasd *)acp->dvp)->tid);
+		} else if (acp->ac_comp == aac_ioctl_complete) {
+			AACDB_PRINT(softs, CE_NOTE,
+				"IOCTL command timed out, index %d timeout %d flags 0x%x",
+				slotp->index, timeout, acp->flags);
+		} else if (acp->ac_comp == aac_synccache_complete) {
+			AACDB_PRINT(softs, CE_NOTE,
+				"Flush command timed out, index %d timeout %d flags 0x%x",
+				slotp->index, timeout, acp->flags);
+		} else if (acp->ac_comp == aac_aifreq_complete) {
+			AACDB_PRINT(softs, CE_NOTE,
+				"AIF request command timed out, index %d timeout %d flags 0x%x",
+				slotp->index, timeout, acp->flags);
 		}
+		cmd = ddi_get16(acc, &slotp->fibp->Header.Command);
+		size = acp->fib_size - sizeof(struct aac_fib_header);
+		AACDB_PRINT(softs, CE_NOTE, "Fib command 0x%x size %d data:", 
+			cmd, size);
 
-		/* AIF received, handle it */
-		struct aac_aif_command *aifp =
-		    (struct aac_aif_command *)&fibp->data[0];
-		uint32_t aif_command = LE_32((uint32_t)aifp->command);
-
-		if (aif_command == AifCmdDriverNotify ||
-		    aif_command == AifCmdEventNotify ||
-		    aif_command == AifCmdJobProgress)
-			(void) aac_handle_aif(softs, aifp);
+		if (size > AAC_FIB_DATASIZE) size = AAC_FIB_DATASIZE;
+		dataptr = &slotp->fibp->data[0];
+		while (size) {
+			for (i = 0; i < 16; ++i) {
+				if (size) {
+					data[i] = ddi_get8(acc, dataptr);
+					++dataptr;
+					--size;
+				} else {
+					data[i] = 0;
+				}
+			}
+			AACDB_PRINT(softs, CE_NOTE, "0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x 0x%02x",
+				data[0], data[1], data[2], data[3],
+				data[4], data[5], data[6], data[7],
+				data[8], data[9], data[10], data[11],
+				data[12], data[13], data[14], data[15]);
+		}
 	}
-}
-
-/*
- * Timeout recovery
- */
-/*ARGSUSED*/
-static void
-aac_cmd_timeout(struct aac_softstate *softs, struct aac_cmd *acp)
-{
-#ifdef DEBUG
-	acp->fib_flags |= AACDB_FLAGS_FIB_TIMEOUT;
-	AACDB_PRINT(softs, CE_WARN, "acp %p timed out", acp);
-	AACDB_PRINT_FIB(softs, acp->slotp);
 #endif
 
+
 	/*
 	 * Besides the firmware in unhealthy state, an overloaded
 	 * adapter may also incur pkt timeout.
@@ -6596,18 +6524,18 @@
 	 * to perform IOs. So the adapter is doing a build on a RAID-5
 	 * while being required longer completion times should be
 	 * tolerated.
-	 */
-	switch (aac_do_reset(softs)) {
-	case AAC_IOP_RESET_SUCCEED:
-		aac_abort_iocmds(softs, AAC_IOCMD_OUTSTANDING, NULL, CMD_RESET);
+	 */  
+	rval = aac_do_reset(softs);
+	if (rval == AACOK) {
+		aac_abort_iocmds(softs, AAC_IOCMD_OUTSTANDING, NULL,
+		    CMD_RESET);
 		aac_start_waiting_io(softs);
-		break;
-	case AAC_IOP_RESET_FAILED:
-		/* Abort all waiting cmds when adapter is dead */
-		aac_abort_iocmds(softs, AAC_IOCMD_ALL, NULL, CMD_TIMEOUT);
-		break;
-	case AAC_IOP_RESET_ABNORMAL:
+	} else if (rval == AACOK2) {
 		aac_start_waiting_io(softs);
+	} else {
+		/* Abort all waiting cmds when adapter is dead */
+		aac_abort_iocmds(softs, AAC_IOCMD_ALL, NULL,
+		    CMD_TIMEOUT);
 	}
 }
 
@@ -6617,226 +6545,271 @@
  * Time sync. command added to synchronize time with firmware every 30
  * minutes (required for correct AIF timestamps etc.)
  */
-static void
+static int
 aac_sync_tick(struct aac_softstate *softs)
 {
-	ddi_acc_handle_t acc;
-	int rval;
+	ddi_acc_handle_t acc = softs->sync_slot->fib_acc_handle;
+	struct aac_fib *fibp = softs->sync_slot->fibp;
 
-	mutex_enter(&softs->time_mutex);
-	ASSERT(softs->time_sync <= softs->timebase);
-	softs->time_sync = 0;
-	mutex_exit(&softs->time_mutex);
-
-	/* Time sync. with firmware every AAC_SYNC_TICK */
-	(void) aac_sync_fib_slot_bind(softs, &softs->sync_ac);
-	acc = softs->sync_ac.slotp->fib_acc_handle;
-
-	ddi_put32(acc, (void *)&softs->sync_ac.slotp->fibp->data[0],
-	    ddi_get_time());
-	rval = aac_sync_fib(softs, SendHostTime, AAC_FIB_SIZEOF(uint32_t));
-	aac_sync_fib_slot_release(softs, &softs->sync_ac);
-
-	mutex_enter(&softs->time_mutex);
-	softs->time_sync = softs->timebase;
-	if (rval != AACOK)
-		/* retry shortly */
-		softs->time_sync += aac_tick << 1;
-	else
-		softs->time_sync += AAC_SYNC_TICK;
-	mutex_exit(&softs->time_mutex);
+	ddi_put32(acc, (uint32_t *)&fibp->data[0], ddi_get_time());
+	return (aac_sync_fib(softs, SendHostTime, AAC_FIB_SIZEOF(uint32_t)));
 }
 
-/*
- * Timeout checking and handling
- */
 static void
-aac_daemon(struct aac_softstate *softs)
+aac_daemon(void *arg)
 {
-	int time_out; /* set if timeout happened */
-	int time_adjust;
-	uint32_t softs_timebase;
+	struct aac_softstate *softs = (struct aac_softstate *)arg;
+	struct aac_cmd *acp;
 
-	mutex_enter(&softs->time_mutex);
-	ASSERT(softs->time_out <= softs->timebase);
-	softs->time_out = 0;
-	softs_timebase = softs->timebase;
-	mutex_exit(&softs->time_mutex);
+	DBCALLED(softs, 2);
 
-	/* Check slots for timeout pkts */
-	time_adjust = 0;
-	do {
-		struct aac_cmd *acp;
-
-		time_out = 0;
-		for (acp = softs->q_busy.q_head; acp; acp = acp->next) {
-			if (acp->timeout == 0)
-				continue;
-
-			/*
-			 * If timeout happened, update outstanding cmds
-			 * to be checked later again.
-			 */
-			if (time_adjust) {
-				acp->timeout += time_adjust;
-				continue;
-			}
-
-			if (acp->timeout <= softs_timebase) {
+	mutex_enter(&softs->io_lock);
+	/* Check slot for timeout pkts */
+	aac_timebase += aac_tick;
+	for (acp = softs->q_busy.q_head; acp; acp = acp->next) {
+		if (acp->timeout) {
+			if (acp->timeout <= aac_timebase) {
 				aac_cmd_timeout(softs, acp);
-				time_out = 1;
-				time_adjust = aac_tick * drv_usectohz(1000000);
-				break; /* timeout happened */
-			} else {
-				break; /* no timeout */
+				ddi_trigger_softintr(softs->softint_id);
 			}
+			break;
 		}
-	} while (time_out);
+	}
 
-	mutex_enter(&softs->time_mutex);
-	softs->time_out = softs->timebase + aac_tick;
-	mutex_exit(&softs->time_mutex);
+	/* Time sync. with firmware every AAC_SYNC_TICK */
+	if (aac_sync_time <= aac_timebase) {
+		aac_sync_time = aac_timebase;
+		if (aac_sync_tick(softs) != AACOK)
+			aac_sync_time += aac_tick << 1; /* retry shortly */
+		else
+			aac_sync_time += AAC_SYNC_TICK;
+	}
+
+	if ((softs->state & AAC_STATE_RUN) && (softs->timeout_id != 0))
+		softs->timeout_id = timeout(aac_daemon, (void *)softs,
+		    (aac_tick * drv_usectohz(1000000)));
+	mutex_exit(&softs->io_lock);
 }
 
 /*
- * The event thread handles various tasks serially for the other parts of
- * the driver, so that they can run fast.
+ * Architecture dependent functions
  */
-static void
-aac_event_thread(struct aac_softstate *softs)
+static void 
+aac_rx_set_intr(struct aac_softstate *softs, int enable)
 {
-	int run = 1;
+	if (enable) {
+    	if (softs->flags & AAC_FLAGS_NEW_COMM)
+			PCI_MEM_PUT32(softs, 0, AAC_OIMR, ~AAC_DB_INTR_NEW);
+		else
+			PCI_MEM_PUT32(softs, 0, AAC_OIMR, ~AAC_DB_INTR_BITS);
+	} else {
+		PCI_MEM_PUT32(softs, 0, AAC_OIMR, ~0);
+	}
+}
 
-	DBCALLED(softs, 1);
+static void 
+aac_rx_status_clr(struct aac_softstate *softs, int mask)
+{
+	PCI_MEM_PUT32(softs, 0, AAC_ODBR, mask);
+}
 
-	mutex_enter(&softs->ev_lock);
-	while (run) {
-		int events;
+static int 
+aac_rx_status_get(struct aac_softstate *softs)
+{
+	return (PCI_MEM_GET32(softs, 0, AAC_ODBR));
+}
 
-		if ((events = softs->events) == 0) {
-			cv_wait(&softs->event_disp_cv, &softs->ev_lock);
-			events = softs->events;
-		}
-		softs->events = 0;
-		mutex_exit(&softs->ev_lock);
+static void 
+aac_rx_notify(struct aac_softstate *softs, int val)
+{
+	PCI_MEM_PUT32(softs, 0, AAC_IDBR, val);
+}
 
-		mutex_enter(&softs->io_lock);
-		if ((softs->state & AAC_STATE_RUN) &&
-		    (softs->state & AAC_STATE_DEAD) == 0) {
-			if (events & AAC_EVENT_TIMEOUT)
-				aac_daemon(softs);
-			if (events & AAC_EVENT_SYNCTICK)
-				aac_sync_tick(softs);
-			if (events & AAC_EVENT_AIF)
-				aac_aif_event(softs);
-		} else {
-			run = 0;
-		}
-		mutex_exit(&softs->io_lock);
+static int
+aac_rx_get_fwstatus(struct aac_softstate *softs)
+{
+	return (PCI_MEM_GET32(softs, 0, AAC_OMR0));
+}
 
-		mutex_enter(&softs->ev_lock);
-	}
-
-	cv_signal(&softs->event_wait_cv);
-	mutex_exit(&softs->ev_lock);
+static int
+aac_rx_get_mailbox(struct aac_softstate *softs, int mb)
+{
+	return (PCI_MEM_GET32(softs, 0, AAC_RX_MAILBOX + mb * 4));
 }
 
-/*
- * Internal timer. It is only responsbile for time counting and report time
- * related events. Events handling is done by aac_event_thread(), so that
- * the timer itself could be as precise as possible.
- */
 static void
-aac_timer(void *arg)
+aac_rx_set_mailbox(struct aac_softstate *softs, uint32_t cmd,
+    uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3)
 {
-	struct aac_softstate *softs = arg;
-	int events = 0;
+	PCI_MEM_PUT32(softs, 0, AAC_RX_MAILBOX, cmd);
+	PCI_MEM_PUT32(softs, 0, AAC_RX_MAILBOX + 4, arg0);
+	PCI_MEM_PUT32(softs, 0, AAC_RX_MAILBOX + 8, arg1);
+	PCI_MEM_PUT32(softs, 0, AAC_RX_MAILBOX + 12, arg2);
+	PCI_MEM_PUT32(softs, 0, AAC_RX_MAILBOX + 16, arg3);
+}
 
-	mutex_enter(&softs->time_mutex);
+static int
+aac_rx_send_command(struct aac_softstate *softs, struct aac_slot *slotp)
+{
+	uint32_t index, device;
 
-	/* If timer is being stopped, exit */
-	if (softs->timeout_id) {
-		softs->timeout_id = timeout(aac_timer, (void *)softs,
-		    (aac_tick * drv_usectohz(1000000)));
-	} else {
-		mutex_exit(&softs->time_mutex);
-		return;
+	index = PCI_MEM_GET32(softs, 0, AAC_IQUE);
+	if (index == 0xffffffffUL) {
+		index = PCI_MEM_GET32(softs, 0, AAC_IQUE);
+		if (index == 0xffffffffUL)
+			return (AACERR);
 	}
 
-	/* Time counting */
-	softs->timebase += aac_tick;
+	device = index;
+	PCI_MEM_PUT32(softs, 0, device,
+	    (uint32_t)(slotp->fib_phyaddr & 0xfffffffful));
+	device += 4;
+	PCI_MEM_PUT32(softs, 0, device, (uint32_t)(slotp->fib_phyaddr >> 32));
+	device += 4;
+	PCI_MEM_PUT32(softs, 0, device, slotp->acp->fib_size);
+	PCI_MEM_PUT32(softs, 0, AAC_IQUE, index);
+	return (AACOK);
+}
 
-	/* Check time related events */
-	if (softs->time_out && softs->time_out <= softs->timebase)
-		events |= AAC_EVENT_TIMEOUT;
-	if (softs->time_sync && softs->time_sync <= softs->timebase)
-		events |= AAC_EVENT_SYNCTICK;
+static int
+aac_rkt_get_fwstatus(struct aac_softstate *softs)
+{
+	return (PCI_MEM_GET32(softs, 0, AAC_OMR0));
+}
 
-	mutex_exit(&softs->time_mutex);
-
-	if (events)
-		aac_event_disp(softs, events);
+static int
+aac_rkt_get_mailbox(struct aac_softstate *softs, int mb)
+{
+	return (PCI_MEM_GET32(softs, 0, AAC_RKT_MAILBOX + mb *4));
 }
 
-/*
- * Dispatch events to daemon thread for handling
- */
 static void
-aac_event_disp(struct aac_softstate *softs, int events)
+aac_rkt_set_mailbox(struct aac_softstate *softs, uint32_t cmd,
+    uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3)
 {
-	mutex_enter(&softs->ev_lock);
-	softs->events |= events;
-	cv_broadcast(&softs->event_disp_cv);
-	mutex_exit(&softs->ev_lock);
+	PCI_MEM_PUT32(softs, 0, AAC_RKT_MAILBOX, cmd);
+	PCI_MEM_PUT32(softs, 0, AAC_RKT_MAILBOX + 4, arg0);
+	PCI_MEM_PUT32(softs, 0, AAC_RKT_MAILBOX + 8, arg1);
+	PCI_MEM_PUT32(softs, 0, AAC_RKT_MAILBOX + 12, arg2);
+	PCI_MEM_PUT32(softs, 0, AAC_RKT_MAILBOX + 16, arg3);
 }
 
-/*
- * Architecture dependent functions
- */
+static void 
+aac_src_set_intr(struct aac_softstate *softs, int enable)
+{
+	if (enable) {
+		PCI_MEM_PUT32(softs, 0, AAC_SRC_OIMR, ~AAC_DB_INTR_NEW_TYPE1);
+	} else {
+		PCI_MEM_PUT32(softs, 0, AAC_SRC_OIMR, ~0);
+	}
+}
+
+static void 
+aac_src_status_clr(struct aac_softstate *softs, int mask)
+{
+	PCI_MEM_PUT32(softs, 0, AAC_SRC_ODBR_C, mask << AAC_SRC_ODR_SHIFT);
+}
+
+static int 
+aac_src_status_get(struct aac_softstate *softs)
+{
+	return (PCI_MEM_GET32(softs, 0, AAC_SRC_ODBR_R) >> AAC_SRC_ODR_SHIFT);
+}
+
+static void 
+aac_src_notify(struct aac_softstate *softs, int val)
+{
+	PCI_MEM_PUT32(softs, 0, AAC_SRC_IDBR, val << AAC_SRC_IDR_SHIFT);
+}
+
 static int
-aac_rx_get_fwstatus(struct aac_softstate *softs)
+aac_src_get_fwstatus(struct aac_softstate *softs)
 {
-	return (PCI_MEM_GET32(softs, AAC_OMR0));
+	return (PCI_MEM_GET32(softs, 0, AAC_SRC_OMR));
 }
 
 static int
-aac_rx_get_mailbox(struct aac_softstate *softs, int mb)
+aac_src_get_mailbox(struct aac_softstate *softs, int mb)
 {
-	return (PCI_MEM_GET32(softs, AAC_RX_MAILBOX + mb * 4));
+	return (PCI_MEM_GET32(softs, 0, AAC_SRC_MAILBOX + mb *4));
 }
 
 static void
-aac_rx_set_mailbox(struct aac_softstate *softs, uint32_t cmd,
+aac_src_set_mailbox(struct aac_softstate *softs, uint32_t cmd,
     uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3)
 {
-	PCI_MEM_PUT32(softs, AAC_RX_MAILBOX, cmd);
-	PCI_MEM_PUT32(softs, AAC_RX_MAILBOX + 4, arg0);
-	PCI_MEM_PUT32(softs, AAC_RX_MAILBOX + 8, arg1);
-	PCI_MEM_PUT32(softs, AAC_RX_MAILBOX + 12, arg2);
-	PCI_MEM_PUT32(softs, AAC_RX_MAILBOX + 16, arg3);
+	PCI_MEM_PUT32(softs, 0, AAC_SRC_MAILBOX, cmd);
+	PCI_MEM_PUT32(softs, 0, AAC_SRC_MAILBOX + 4, arg0);
+	PCI_MEM_PUT32(softs, 0, AAC_SRC_MAILBOX + 8, arg1);
+	PCI_MEM_PUT32(softs, 0, AAC_SRC_MAILBOX + 12, arg2);
+	PCI_MEM_PUT32(softs, 0, AAC_SRC_MAILBOX + 16, arg3);
 }
 
 static int
-aac_rkt_get_fwstatus(struct aac_softstate *softs)
+aac_src_send_command(struct aac_softstate *softs, struct aac_slot *slotp)
 {
-	return (PCI_MEM_GET32(softs, AAC_OMR0));
+	ddi_acc_handle_t acc = slotp->fib_acc_handle;
+	uint32_t fibsize, hdr_size, high_addr;
+	uint64_t address;
+
+	hdr_size = (uint32_t)ddi_get16(acc, &slotp->fibp->Header.Size);
+	if (softs->flags & AAC_FLAGS_NEW_COMM_TYPE2) {
+		struct aac_fib *fibp = slotp->fibp;
+
+		/* Calculate the amount to the fibsize bits */
+		fibsize = (hdr_size + 127) / 128 - 1; 
+		/* New FIB header */
+		address = slotp->fib_phyaddr;
+		high_addr = (uint32_t)(address >> 32);
+		if (high_addr == 0L) {
+			ddi_put8(acc, &fibp->Header.StructType, AAC_FIBTYPE_TFIB2);
+			ddi_put32(acc, &fibp->Header.a.TimeStamp, 0L);
+		} else {
+			ddi_put8(acc, &fibp->Header.StructType, AAC_FIBTYPE_TFIB2_64);
+			ddi_put32(acc, &fibp->Header.a.SenderFibAddressHigh, high_addr);
+		}
+		ddi_put32(acc, &fibp->Header.SenderFibAddress, (uint32_t)address);
+	} else {
+		struct aac_fib_xporthdr *pFibX;
+
+		/* Calculate the amount to the fibsize bits */
+		fibsize = (sizeof(struct aac_fib_xporthdr) + hdr_size + 127) / 128 - 1; 
+		/* Fill XPORT header */ 
+		address = slotp->fib_phyaddr - sizeof(struct aac_fib_xporthdr);
+		high_addr = (uint32_t)(address >> 32);
+		pFibX = (struct aac_fib_xporthdr *)
+			((unsigned char *)slotp->fibp - sizeof(struct aac_fib_xporthdr));
+		ddi_put32(acc, &pFibX->Handle, slotp->index + 1);
+		ddi_put64(acc, &pFibX->HostAddress, slotp->fib_phyaddr);
+		ddi_put32(acc, &pFibX->Size, hdr_size);
+	}
+
+	if (fibsize > 31) 
+		fibsize = 31;
+	if (high_addr) {
+		PCI_MEM_PUT32(softs, 0, AAC_SRC_IQUE64_H, high_addr);
+		PCI_MEM_PUT32(softs, 0, AAC_SRC_IQUE64_L, (uint32_t)address + fibsize);
+	} else {
+		PCI_MEM_PUT32(softs, 0, AAC_SRC_IQUE32, (uint32_t)address + fibsize);
+	}
+	return (AACOK);
 }
 
 static int
-aac_rkt_get_mailbox(struct aac_softstate *softs, int mb)
+aac_srcv_get_mailbox(struct aac_softstate *softs, int mb)
 {
-	return (PCI_MEM_GET32(softs, AAC_RKT_MAILBOX + mb *4));
+	return (PCI_MEM_GET32(softs, 0, AAC_SRCV_MAILBOX + mb *4));
 }
 
 static void
-aac_rkt_set_mailbox(struct aac_softstate *softs, uint32_t cmd,
+aac_srcv_set_mailbox(struct aac_softstate *softs, uint32_t cmd,
     uint32_t arg0, uint32_t arg1, uint32_t arg2, uint32_t arg3)
 {
-	PCI_MEM_PUT32(softs, AAC_RKT_MAILBOX, cmd);
-	PCI_MEM_PUT32(softs, AAC_RKT_MAILBOX + 4, arg0);
-	PCI_MEM_PUT32(softs, AAC_RKT_MAILBOX + 8, arg1);
-	PCI_MEM_PUT32(softs, AAC_RKT_MAILBOX + 12, arg2);
-	PCI_MEM_PUT32(softs, AAC_RKT_MAILBOX + 16, arg3);
+	PCI_MEM_PUT32(softs, 0, AAC_SRCV_MAILBOX, cmd);
+	PCI_MEM_PUT32(softs, 0, AAC_SRCV_MAILBOX + 4, arg0);
+	PCI_MEM_PUT32(softs, 0, AAC_SRCV_MAILBOX + 8, arg1);
+	PCI_MEM_PUT32(softs, 0, AAC_SRCV_MAILBOX + 12, arg2);
+	PCI_MEM_PUT32(softs, 0, AAC_SRCV_MAILBOX + 16, arg3);
 }
 
 /*
@@ -6923,6 +6896,21 @@
 	return (ENXIO);
 }
 
+static int
+aac_atoi(char **pptr)
+{
+	char *ptr = *pptr;
+	int digit, rval = 0;
+
+	while (*ptr >= '0' && *ptr <= '9') {
+		digit = (int)(*ptr - '0');
+		rval = rval*10 + digit;
+		ptr++;
+	}
+	*pptr = ptr;
+	return (rval);
+}
+
 /*
  * The IO fault service error handling callback function
  */
@@ -6950,17 +6938,23 @@
 	 */
 	ddi_iblock_cookie_t fm_ibc;
 
+	if (!aac_fm_valid)
+		return;
+
+	/*
+	 * Initialize FMA
+	 */
 	softs->fm_capabilities = ddi_getprop(DDI_DEV_T_ANY, softs->devinfo_p,
-	    DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable",
-	    DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
-	    DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
+		DDI_PROP_CANSLEEP | DDI_PROP_DONTPASS, "fm-capable",
+		DDI_FM_EREPORT_CAPABLE | DDI_FM_ACCCHK_CAPABLE |
+		DDI_FM_DMACHK_CAPABLE | DDI_FM_ERRCB_CAPABLE);
 
 	/* Only register with IO Fault Services if we have some capability */
 	if (softs->fm_capabilities) {
 		/* Adjust access and dma attributes for FMA */
-		softs->reg_attr.devacc_attr_access = DDI_FLAGERR_ACC;
-		softs->addr_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
-		softs->buf_dma_attr.dma_attr_flags |= DDI_DMA_FLAGERR;
+		aac_acc_attr.devacc_attr_access = DDI_FLAGERR_ACC;
+		softs->buf_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
+		softs->addr_dma_attr.dma_attr_flags = DDI_DMA_FLAGERR;
 
 		/*
 		 * Register capabilities with IO Fault Services.
@@ -6985,6 +6979,11 @@
 			ddi_fm_handler_register(softs->devinfo_p,
 			    aac_fm_error_cb, (void *) softs);
 		}
+	} else {
+		/* Clear FMA if no capabilities */
+		aac_acc_attr.devacc_attr_access = DDI_DEFAULT_ACC;
+		softs->buf_dma_attr.dma_attr_flags = 0;
+		softs->addr_dma_attr.dma_attr_flags = 0;
 	}
 }
 
@@ -6995,6 +6994,9 @@
 static void
 aac_fm_fini(struct aac_softstate *softs)
 {
+	if (!aac_fm_valid)
+		return;
+
 	/* Only unregister FMA capabilities if registered */
 	if (softs->fm_capabilities) {
 		/*
@@ -7014,11 +7016,6 @@
 
 		/* Unregister from IO Fault Services */
 		ddi_fm_fini(softs->devinfo_p);
-
-		/* Adjust access and dma attributes for FMA */
-		softs->reg_attr.devacc_attr_access = DDI_DEFAULT_ACC;
-		softs->addr_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
-		softs->buf_dma_attr.dma_attr_flags &= ~DDI_DMA_FLAGERR;
 	}
 }
 
@@ -7027,6 +7024,9 @@
 {
 	ddi_fm_error_t de;
 
+	if (!aac_fm_valid)
+		return (DDI_SUCCESS);
+
 	ddi_fm_acc_err_get(handle, &de, DDI_FME_VERSION);
 	return (de.fme_status);
 }
@@ -7036,16 +7036,22 @@
 {
 	ddi_fm_error_t de;
 
+	if (!aac_fm_valid)
+		return (DDI_SUCCESS);
+
 	ddi_fm_dma_err_get(handle, &de, DDI_FME_VERSION);
 	return (de.fme_status);
 }
 
 void
-aac_fm_ereport(struct aac_softstate *softs, char *detail)
+aac_fm_ereport(struct aac_softstate *softs, char *detail, int impact)
 {
 	uint64_t ena;
 	char buf[FM_MAX_CLASS];
 
+	if (!aac_fm_valid)
+		return;
+
 	(void) snprintf(buf, FM_MAX_CLASS, "%s.%s", DDI_FM_DEVICE, detail);
 	ena = fm_ena_generate(0, FM_ENA_FMT1);
 	if (DDI_FM_EREPORT_CAP(softs->fm_capabilities)) {
@@ -7052,6 +7058,7 @@
 		ddi_fm_ereport_post(softs->devinfo_p, buf, ena, DDI_NOSLEEP,
 		    FM_VERSION, DATA_TYPE_UINT8, FM_EREPORT_VERSION, NULL);
 	}
+	ddi_fm_service_impact(softs->devinfo_p, impact);
 }
 
 /*
@@ -7100,34 +7107,27 @@
 }
 
 static dev_info_t *
-aac_find_child(struct aac_softstate *softs, uint16_t tgt, uint8_t lun)
+aac_find_child(struct aac_softstate *softs, int tgt, int lun)
 {
-	dev_info_t *child = NULL;
 	char addr[SCSI_MAXNAMELEN];
-	char tmp[MAXNAMELEN];
+	dev_info_t *child;
+	char *tmp;
 
 	if (tgt < AAC_MAX_LD) {
-		if (lun == 0) {
-			struct aac_device *dvp = &softs->containers[tgt].dev;
+		struct aac_device *dvp = &softs->containers[tgt].dev;
 
-			child = dvp->dip;
-		}
+		if (lun == 0 && dvp->valid)
+			return (dvp->dip);
 	} else {
 		(void) sprintf(addr, "%x,%x", tgt, lun);
 		for (child = ddi_get_child(softs->devinfo_p);
 		    child; child = ddi_get_next_sibling(child)) {
-			/* We don't care about non-persistent node */
-			if (ndi_dev_is_persistent_node(child) == 0)
-				continue;
-
-			if (aac_name_node(child, tmp, MAXNAMELEN) !=
-			    DDI_SUCCESS)
-				continue;
-			if (strcmp(addr, tmp) == 0)
-				break;
+			if ((tmp = ddi_get_name_addr(child)) != NULL &&
+			    strcmp(addr, tmp) == 0)
+				return (child);
 		}
 	}
-	return (child);
+	return (NULL);
 }
 
 static int
@@ -7137,7 +7137,6 @@
 	char *nodename = NULL;
 	char **compatible = NULL;
 	int ncompatible = 0;
-	char *childname;
 	dev_info_t *ldip = NULL;
 	int tgt = sd->sd_address.a_target;
 	int lun = sd->sd_address.a_lun;
@@ -7150,14 +7149,15 @@
 	    NULL, &nodename, &compatible, &ncompatible);
 	if (nodename == NULL) {
 		AACDB_PRINT(softs, CE_WARN,
-		    "found no comptible driver for t%dL%d", tgt, lun);
+		    "found no compatible driver for t%dL%d", tgt, lun);
 		rval = NDI_FAILURE;
 		goto finish;
 	}
-	childname = (softs->legacy && dtype == DTYPE_DIRECT) ? "sd" : nodename;
+	if (softs->legacy && dtype == DTYPE_DIRECT)
+		nodename = "sd";
 
 	/* Create dev node */
-	rval = ndi_devi_alloc(softs->devinfo_p, childname, DEVI_SID_NODEID,
+	rval = ndi_devi_alloc(softs->devinfo_p, nodename, DEVI_SID_NODEID,
 	    &ldip);
 	if (rval == NDI_SUCCESS) {
 		if (ndi_prop_update_int(DDI_DEV_T_NONE, ldip, "target", tgt)
@@ -7194,8 +7194,6 @@
 finish:
 	if (dipp)
 		*dipp = ldip;
-
-	scsi_hba_nodename_compatible_free(nodename, compatible);
 	return (rval);
 }
 
@@ -7208,59 +7206,32 @@
 
 	DBCALLED(softs, 2);
 
-	if (tgt < AAC_MAX_LD) {
-		enum aac_cfg_event event;
+	if (tgt < AAC_MAX_LD && lun != 0)
+		return (NDI_FAILURE);
 
-		if (lun == 0) {
-			mutex_enter(&softs->io_lock);
-			event = aac_probe_container(softs, tgt);
-			mutex_exit(&softs->io_lock);
-			if ((event != AAC_CFG_NULL_NOEXIST) &&
-			    (event != AAC_CFG_DELETE)) {
-				if (scsi_hba_probe(sd, NULL) ==
-				    SCSIPROBE_EXISTS)
-					return (NDI_SUCCESS);
-			}
-		}
+	if (scsi_hba_probe(sd, NULL) != SCSIPROBE_EXISTS)
 		return (NDI_FAILURE);
-	} else {
-		int dtype;
-		int qual; /* device qualifier */
+	if (tgt >= AAC_MAX_LD) {
+		int dtype = sd->sd_inq->inq_dtype & DTYPE_MASK;
 
-		if (scsi_hba_probe(sd, NULL) != SCSIPROBE_EXISTS)
-			return (NDI_FAILURE);
-
-		dtype = sd->sd_inq->inq_dtype & DTYPE_MASK;
-		qual = dtype >> 5;
-
 		AACDB_PRINT(softs, CE_NOTE,
 		    "Phys. device found: tgt %d dtype %d: %s",
 		    tgt, dtype, sd->sd_inq->inq_vid);
 
-		/* Only non-DASD and JBOD mode DASD are allowed exposed */
-		if (dtype == DTYPE_RODIRECT /* CDROM */ ||
-		    dtype == DTYPE_SEQUENTIAL /* TAPE */ ||
-		    dtype == DTYPE_ESI /* SES */) {
-			if (!(softs->flags & AAC_FLAGS_NONDASD))
-				return (NDI_FAILURE);
-			AACDB_PRINT(softs, CE_NOTE, "non-DASD %d found", tgt);
-
-		} else if (dtype == DTYPE_DIRECT) {
-			if (!(softs->flags & AAC_FLAGS_JBOD) || qual != 0)
-				return (NDI_FAILURE);
-			AACDB_PRINT(softs, CE_NOTE, "JBOD DASD %d found", tgt);
-		}
-
-		mutex_enter(&softs->io_lock);
-		softs->nondasds[AAC_PD(tgt)].dev.flags |= AAC_DFLAG_VALID;
-		mutex_exit(&softs->io_lock);
-		return (NDI_SUCCESS);
+		/* Only non-DASD and JBOD devices exposed */
+		if (dtype != DTYPE_RODIRECT /* CDROM */ &&
+		    dtype != DTYPE_SEQUENTIAL /* TYPE */ &&
+		    dtype != DTYPE_ESI /* SES */ &&
+			!(dtype == DTYPE_DIRECT && 
+			 (softs->aac_feature_bits & AAC_SUPPL_SUPPORTED_JBOD)))
+			return (NDI_FAILURE);
+		AACDB_PRINT(softs, CE_NOTE, "non-DASD/JBOD %d found", tgt);
 	}
+	return (NDI_SUCCESS);
 }
 
 static int
-aac_config_lun(struct aac_softstate *softs, uint16_t tgt, uint8_t lun,
-    dev_info_t **ldip)
+aac_config_lun(struct aac_softstate *softs, int tgt, int lun, dev_info_t **ldip)
 {
 	struct scsi_device sd;
 	dev_info_t *child;
@@ -7280,11 +7251,7 @@
 	sd.sd_address.a_lun = (uint8_t)lun;
 	if ((rval = aac_probe_lun(softs, &sd)) == NDI_SUCCESS)
 		rval = aac_config_child(softs, &sd, ldip);
-	/* scsi_unprobe is blank now. Free buffer manually */
-	if (sd.sd_inq) {
-		kmem_free(sd.sd_inq, SUN_INQSIZE);
-		sd.sd_inq = (struct scsi_inquiry *)NULL;
-	}
+	scsi_unprobe(&sd);
 	return (rval);
 }
 
@@ -7293,11 +7260,10 @@
 {
 	struct scsi_address ap;
 	struct buf *bp = NULL;
-	int buf_len = AAC_SCSI_RPTLUNS_HEAD_SIZE + AAC_SCSI_RPTLUNS_ADDR_SIZE;
-	int list_len = 0;
+	int list_len = 8;
 	int lun_total = 0;
 	dev_info_t *ldip;
-	int i;
+	int i, cmd_ok = 1;
 
 	ap.a_hba_tran = softs->hba_tran;
 	ap.a_target = (uint16_t)tgt;
@@ -7307,9 +7273,11 @@
 		struct scsi_pkt *pkt;
 		uchar_t *cdb;
 		uchar_t *p;
+		int buf_len;
 		uint32_t data;
 
 		if (bp == NULL) {
+			buf_len = AAC_SCSI_RPTLUNS_HEAD_SIZE + list_len;
 			if ((bp = scsi_alloc_consistent_buf(&ap, NULL,
 			    buf_len, B_READ, NULL_FUNC, NULL)) == NULL)
 			return (AACERR);
@@ -7334,8 +7302,10 @@
 		if (scsi_poll(pkt) < 0 ||
 		    ((struct scsi_status *)pkt->pkt_scbp)->sts_chk) {
 			scsi_destroy_pkt(pkt);
+			cmd_ok = 0;
 			break;
 		}
+		scsi_destroy_pkt(pkt);
 
 		/* Convert list_len from LE_32 to local */
 		for (p = (uchar_t *)bp->b_un.b_addr;
@@ -7343,23 +7313,24 @@
 			data <<= 8;
 			data |= *p;
 		}
-		list_len = data;
-		if (buf_len < list_len + AAC_SCSI_RPTLUNS_HEAD_SIZE) {
+
+		if (data <= list_len)
+			break;
+		if (i == 0) {
+			list_len = data;
 			scsi_free_consistent_buf(bp);
 			bp = NULL;
-			buf_len = list_len + AAC_SCSI_RPTLUNS_HEAD_SIZE;
 		}
-		scsi_destroy_pkt(pkt);
 	}
-	if (i >= 2) {
-		uint8_t *buf = (uint8_t *)(bp->b_un.b_addr +
-		    AAC_SCSI_RPTLUNS_HEAD_SIZE);
 
+	if (cmd_ok) {
+		char *buf = bp->b_un.b_addr + 8;
+
 		for (i = 0; i < (list_len / AAC_SCSI_RPTLUNS_ADDR_SIZE); i++) {
-			uint16_t lun;
+			int lun;
 
 			/* Determine report luns addressing type */
-			switch (buf[0] & AAC_SCSI_RPTLUNS_ADDR_MASK) {
+			switch (buf[i] & AAC_SCSI_RPTLUNS_ADDR_MASK) {
 			/*
 			 * Vendors in the field have been found to be
 			 * concatenating bus/target/lun to equal the
@@ -7369,19 +7340,13 @@
 			case AAC_SCSI_RPTLUNS_ADDR_PERIPHERAL:
 			case AAC_SCSI_RPTLUNS_ADDR_LOGICAL_UNIT:
 			case AAC_SCSI_RPTLUNS_ADDR_FLAT_SPACE:
-				lun = ((buf[0] & 0x3f) << 8) | buf[1];
-				if (lun > UINT8_MAX) {
-					AACDB_PRINT(softs, CE_WARN,
-					    "abnormal lun number: %d", lun);
-					break;
-				}
+				lun = (buf[i] & 0x3f) << 8;
+				lun |= buf[i + 1];
 				if (aac_config_lun(softs, tgt, lun, &ldip) ==
 				    NDI_SUCCESS)
 					lun_total++;
 				break;
 			}
-
-			buf += AAC_SCSI_RPTLUNS_ADDR_SIZE;
 		}
 	} else {
 		/* The target may do not support SCMD_REPORT_LUNS. */
@@ -7393,17 +7358,36 @@
 }
 
 static void
-aac_devcfg(struct aac_softstate *softs, int tgt, int en)
+aac_enable_pd(struct aac_softstate *softs, int tgt, int en)
 {
-	struct aac_device *dvp;
+	if (tgt >= AAC_MAX_LD) {
+		mutex_enter(&softs->io_lock);
+		softs->nondasds[AAC_PD(tgt)].dev.valid = (uint8_t)en;
+		mutex_exit(&softs->io_lock);
+	}
+}
 
-	mutex_enter(&softs->io_lock);
-	dvp = AAC_DEV(softs, tgt);
-	if (en)
-		dvp->flags |= AAC_DFLAG_CONFIGURING;
-	else
-		dvp->flags &= ~AAC_DFLAG_CONFIGURING;
-	mutex_exit(&softs->io_lock);
+static void
+aac_config_pd(void *arg)
+{
+	struct aac_softstate *softs = (struct aac_softstate *)arg;
+	uint32_t bus, tgt;
+	int index, total;
+
+	total = 0;
+	index = AAC_MAX_LD;
+	for (bus = 0; bus < softs->bus_max; bus++) {
+		AACDB_PRINT(softs, CE_NOTE, "bus %d:", bus);
+		for (tgt = 0; tgt < softs->tgt_max; tgt++, index++) {
+			aac_enable_pd(softs, index, 1);
+			if (aac_config_tgt(softs, index) == 0)
+				aac_enable_pd(softs, index, 0);
+			else
+				total++;
+		}
+	}
+	AACDB_PRINT(softs, CE_CONT,
+		"Total %d phys. device(s) found", total);
 }
 
 static int
@@ -7418,16 +7402,6 @@
 	    ddi_get_instance(parent))) == NULL)
 		return (NDI_FAILURE);
 
-	/* Commands for bus config should be blocked as the bus is quiesced */
-	mutex_enter(&softs->io_lock);
-	if (softs->state & AAC_STATE_QUIESCED) {
-		AACDB_PRINT(softs, CE_NOTE,
-		    "bus_config abroted because bus is quiesced");
-		mutex_exit(&softs->io_lock);
-		return (NDI_FAILURE);
-	}
-	mutex_exit(&softs->io_lock);
-
 	DBCALLED(softs, 1);
 
 	/* Hold the nexus across the bus_config */
@@ -7435,49 +7409,39 @@
 	switch (op) {
 	case BUS_CONFIG_ONE: {
 		int tgt, lun;
+		struct scsi_device sd;
 
 		if (aac_parse_devname(arg, &tgt, &lun) != AACOK) {
 			rval = NDI_FAILURE;
 			break;
 		}
-		if (tgt >= AAC_MAX_LD) {
-			if (tgt >= AAC_MAX_DEV(softs)) {
-				rval = NDI_FAILURE;
-				break;
-			}
+		if (*childp = aac_find_child(softs, tgt, lun)) {
+			rval = NDI_SUCCESS;
+			break;
 		}
 
-		AAC_DEVCFG_BEGIN(softs, tgt);
-		rval = aac_config_lun(softs, tgt, lun, childp);
-		AAC_DEVCFG_END(softs, tgt);
+		aac_enable_pd(softs, tgt, 1);
+		bzero(&sd, sizeof (struct scsi_device));
+		sd.sd_address.a_hba_tran = softs->hba_tran;
+		sd.sd_address.a_target = (uint16_t)tgt;
+		sd.sd_address.a_lun = (uint8_t)lun;
+		if ((rval = aac_probe_lun(softs, &sd)) == NDI_SUCCESS)
+			rval = aac_config_child(softs, &sd, childp);
+		else
+			aac_enable_pd(softs, tgt, 0);
+		scsi_unprobe(&sd);
 		break;
 	}
 
 	case BUS_CONFIG_DRIVER:
 	case BUS_CONFIG_ALL: {
-		uint32_t bus, tgt;
-		int index, total;
+		uint32_t tgt;
 
-		for (tgt = 0; tgt < AAC_MAX_LD; tgt++) {
-			AAC_DEVCFG_BEGIN(softs, tgt);
+		for (tgt = 0; tgt < AAC_MAX_LD; tgt++)
 			(void) aac_config_lun(softs, tgt, 0, NULL);
-			AAC_DEVCFG_END(softs, tgt);
-		}
 
 		/* Config the non-DASD devices connected to the card */
-		total = 0;
-		index = AAC_MAX_LD;
-		for (bus = 0; bus < softs->bus_max; bus++) {
-			AACDB_PRINT(softs, CE_NOTE, "bus %d:", bus);
-			for (tgt = 0; tgt < softs->tgt_max; tgt++, index++) {
-				AAC_DEVCFG_BEGIN(softs, index);
-				if (aac_config_tgt(softs, index))
-					total++;
-				AAC_DEVCFG_END(softs, index);
-			}
-		}
-		AACDB_PRINT(softs, CE_CONT,
-		    "?Total %d phys. device(s) found", total);
+		aac_config_pd((void *)softs);
 		rval = NDI_SUCCESS;
 		break;
 	}
@@ -7489,10 +7453,10 @@
 	return (rval);
 }
 
-/*ARGSUSED*/
-static int
-aac_handle_dr(struct aac_softstate *softs, int tgt, int lun, int event)
+static void
+aac_handle_dr(struct aac_drinfo *drp)
 {
+	struct aac_softstate *softs = drp->softs;
 	struct aac_device *dvp;
 	dev_info_t *dip;
 	int valid;
@@ -7501,26 +7465,25 @@
 	DBCALLED(softs, 1);
 
 	/* Hold the nexus across the bus_config */
-	dvp = AAC_DEV(softs, tgt);
-	valid = AAC_DEV_IS_VALID(dvp);
+	mutex_enter(&softs->io_lock);
+	dvp = AAC_DEV(softs, drp->tgt);
 	dip = dvp->dip;
-	if (!(softs->state & AAC_STATE_RUN))
-		return (AACERR);
+	valid = dvp->valid;
 	mutex_exit(&softs->io_lock);
 
-	switch (event) {
-	case AAC_CFG_ADD:
-	case AAC_CFG_DELETE:
+	switch (drp->event) {
+	case AAC_DEV_ONLINE:
+	case AAC_DEV_OFFLINE:
 		/* Device onlined */
 		if (dip == NULL && valid) {
 			ndi_devi_enter(softs->devinfo_p, &circ1);
-			(void) aac_config_lun(softs, tgt, 0, NULL);
+			(void) aac_config_lun(softs, drp->tgt, 0, NULL);
 			AACDB_PRINT(softs, CE_NOTE, "c%dt%dL%d onlined",
-			    softs->instance, tgt, lun);
+			    softs->instance, drp->tgt, drp->lun);
 			ndi_devi_exit(softs->devinfo_p, circ1);
 		}
 		/* Device offlined */
-		if (dip && !valid) {
+		if (dip && valid == 0) {
 			mutex_enter(&softs->io_lock);
 			(void) aac_do_reset(softs);
 			mutex_exit(&softs->io_lock);
@@ -7527,16 +7490,38 @@
 
 			(void) ndi_devi_offline(dip, NDI_DEVI_REMOVE);
 			AACDB_PRINT(softs, CE_NOTE, "c%dt%dL%d offlined",
-			    softs->instance, tgt, lun);
+			    softs->instance, drp->tgt, drp->lun);
 		}
 		break;
 	}
+	kmem_free(drp, sizeof (struct aac_drinfo));
+}
 
-	mutex_enter(&softs->io_lock);
+static int
+aac_dr_event(struct aac_softstate *softs, int tgt, int lun, int event)
+{
+	struct aac_drinfo *drp;
+
+	DBCALLED(softs, 1);
+
+	if (softs->taskq == NULL ||
+	    (drp = kmem_zalloc(sizeof (struct aac_drinfo), KM_NOSLEEP)) == NULL)
+		return (AACERR);
+
+	drp->softs = softs;
+	drp->tgt = tgt;
+	drp->lun = lun;
+	drp->event = event;
+	if ((ddi_taskq_dispatch(softs->taskq, (void (*)(void *))aac_handle_dr,
+	    drp, DDI_NOSLEEP)) != DDI_SUCCESS) {
+		AACDB_PRINT(softs, CE_WARN, "DR task start failed");
+		kmem_free(drp, sizeof (struct aac_drinfo));
+		return (AACERR);
+	}
 	return (AACOK);
 }
 
-#ifdef DEBUG
+#ifdef AAC_DEBUG_ALL
 
 /* -------------------------debug aid functions-------------------------- */
 
@@ -7980,7 +7965,9 @@
 	AAC_AIFEN_KEY_STRINGS,
 	-1,			NULL
 };
+#endif /* AAC_DEBUG_ALL */
 
+#ifdef AAC_DEBUG
 /*
  * The following function comes from Adaptec:
  *
@@ -7990,8 +7977,9 @@
 static int
 aac_get_fw_debug_buffer(struct aac_softstate *softs)
 {
+	softs->sync_slot_busy = 1;
 	if (aac_sync_mbcommand(softs, AAC_MONKER_GETDRVPROP,
-	    0, 0, 0, 0, NULL) == AACOK) {
+	    0, 0, 0, 0, NULL, NULL) == AACOK) {
 		uint32_t mondrv_buf_paddrl = AAC_MAILBOX_GET(softs, 1);
 		uint32_t mondrv_buf_paddrh = AAC_MAILBOX_GET(softs, 2);
 		uint32_t mondrv_buf_size = AAC_MAILBOX_GET(softs, 3);
@@ -7999,7 +7987,7 @@
 
 		if (mondrv_buf_size) {
 			uint32_t offset = mondrv_buf_paddrl - \
-			    softs->pci_mem_base_paddr;
+			    softs->pci_mem_base_paddr[1];
 
 			/*
 			 * See if the address is already mapped in, and
@@ -8012,7 +8000,6 @@
 				softs->debug_header_size = mondrv_hdr_size;
 				softs->debug_buf_size = mondrv_buf_size;
 				softs->debug_fw_flags = 0;
-				softs->debug_flags &= ~AACDB_FLAGS_FW_PRINT;
 				mutex_exit(&aac_prt_mutex);
 
 				return (AACOK);
@@ -8096,7 +8083,7 @@
 			 * previous message length to clear (the handshake).
 			 */
 			for (i = 0; i < AAC_PRINT_TIMEOUT; i++) {
-				if (!PCI_MEM_GET32(softs,
+				if (!PCI_MEM_GET32(softs, 1,
 				    softs->debug_buf_offset + \
 				    AAC_FW_DBG_STRLEN_OFFSET))
 					break;
@@ -8110,17 +8097,17 @@
 			 * last because that is the signal for the Firmware to
 			 * pick it up.
 			 */
-			if (!PCI_MEM_GET32(softs, softs->debug_buf_offset + \
+			if (!PCI_MEM_GET32(softs, 1, softs->debug_buf_offset + \
 			    AAC_FW_DBG_STRLEN_OFFSET)) {
-				PCI_MEM_REP_PUT8(softs,
+				PCI_MEM_REP_PUT8(softs, 1,
 				    softs->debug_buf_offset + \
 				    softs->debug_header_size,
 				    aac_prt_buf, count);
-				PCI_MEM_PUT32(softs,
+				PCI_MEM_PUT32(softs, 1,
 				    softs->debug_buf_offset + \
 				    AAC_FW_DBG_FLAGS_OFFSET,
 				    softs->debug_fw_flags);
-				PCI_MEM_PUT32(softs,
+				PCI_MEM_PUT32(softs, 1,
 				    softs->debug_buf_offset + \
 				    AAC_FW_DBG_STRLEN_OFFSET, count);
 			} else {
@@ -8143,7 +8130,9 @@
 	}
 	mutex_exit(&aac_prt_mutex);
 }
+#endif /* AAC_DEBUG */
 
+#ifdef AAC_DEBUG_ALL
 /*
  * Translate command number to description string
  */
@@ -8168,7 +8157,7 @@
 	int ctl = ddi_get_instance(softs->devinfo_p);
 	int tgt = ap->a_target;
 	int lun = ap->a_lun;
-	union scsi_cdb *cdbp = (void *)pkt->pkt_cdbp;
+	union scsi_cdb *cdbp = (union scsi_cdb *)pkt->pkt_cdbp;
 	uchar_t cmd = cdbp->scc_cmd;
 	char *desc;
 
@@ -8213,14 +8202,6 @@
 		    (acp->flags & AAC_CMD_NO_INTR) ? "poll" : "intr",
 		    ctl, tgt, lun, is_pd ? "(pd)" : "");
 		break;
-	case SCMD_READ_G5:
-	case SCMD_WRITE_G5:
-		aac_printf(softs, CE_NOTE,
-		    "SCMD> %s 0x%x[%d] %s --> c%dt%dL%d %s",
-		    desc, GETG5ADDR(cdbp), GETG5COUNT(cdbp),
-		    (acp->flags & AAC_CMD_NO_INTR) ? "poll" : "intr",
-		    ctl, tgt, lun, is_pd ? "(pd)" : "");
-		break;
 	default:
 		aac_printf(softs, CE_NOTE, "SCMD> %s --> c%dt%dL%d %s",
 		    desc, ctl, tgt, lun, is_pd ? "(pd)" : "");
@@ -8228,191 +8209,56 @@
 }
 
 void
-aac_print_fib(struct aac_softstate *softs, struct aac_slot *slotp)
+aac_print_fib(struct aac_softstate *softs, struct aac_fib *fibp)
 {
-	struct aac_cmd *acp = slotp->acp;
-	struct aac_fib *fibp = slotp->fibp;
-	ddi_acc_handle_t acc = slotp->fib_acc_handle;
 	uint16_t fib_size;
-	uint32_t fib_cmd, sub_cmd;
+	int32_t fib_cmd, sub_cmd;
 	char *cmdstr, *subcmdstr;
-	char *caller;
-	int i;
+	struct aac_Container *pContainer;
 
-	if (acp) {
-		if (!(softs->debug_fib_flags & acp->fib_flags))
-			return;
-		if (acp->fib_flags & AACDB_FLAGS_FIB_SCMD)
-			caller = "SCMD";
-		else if (acp->fib_flags & AACDB_FLAGS_FIB_IOCTL)
-			caller = "IOCTL";
-		else if (acp->fib_flags & AACDB_FLAGS_FIB_SRB)
-			caller = "SRB";
-		else
-			return;
-	} else {
-		if (!(softs->debug_fib_flags & AACDB_FLAGS_FIB_SYNC))
-			return;
-		caller = "SYNC";
-	}
-
-	fib_cmd = ddi_get16(acc, &fibp->Header.Command);
+	fib_cmd = LE_16(fibp->Header.Command);
 	cmdstr = aac_cmd_name(fib_cmd, aac_fib_cmds);
-	sub_cmd = (uint32_t)-1;
+	sub_cmd = -1;
 	subcmdstr = NULL;
 
-	/* Print FIB header */
-	if (softs->debug_fib_flags & AACDB_FLAGS_FIB_HEADER) {
-		aac_printf(softs, CE_NOTE, "FIB> from %s", caller);
-		aac_printf(softs, CE_NOTE, "     XferState  %d",
-		    ddi_get32(acc, &fibp->Header.XferState));
-		aac_printf(softs, CE_NOTE, "     Command    %d",
-		    ddi_get16(acc, &fibp->Header.Command));
-		aac_printf(softs, CE_NOTE, "     StructType %d",
-		    ddi_get8(acc, &fibp->Header.StructType));
-		aac_printf(softs, CE_NOTE, "     Flags      0x%x",
-		    ddi_get8(acc, &fibp->Header.Flags));
-		aac_printf(softs, CE_NOTE, "     Size       %d",
-		    ddi_get16(acc, &fibp->Header.Size));
-		aac_printf(softs, CE_NOTE, "     SenderSize %d",
-		    ddi_get16(acc, &fibp->Header.SenderSize));
-		aac_printf(softs, CE_NOTE, "     SenderAddr 0x%x",
-		    ddi_get32(acc, &fibp->Header.SenderFibAddress));
-		aac_printf(softs, CE_NOTE, "     RcvrAddr   0x%x",
-		    ddi_get32(acc, &fibp->Header.ReceiverFibAddress));
-		aac_printf(softs, CE_NOTE, "     SenderData 0x%x",
-		    ddi_get32(acc, &fibp->Header.SenderData));
-	}
-
-	/* Print FIB data */
 	switch (fib_cmd) {
 	case ContainerCommand:
-		sub_cmd = ddi_get32(acc,
-		    (void *)&(((uint32_t *)(void *)&fibp->data[0])[0]));
+		pContainer = (struct aac_Container *)fibp->data;
+		sub_cmd = LE_32(pContainer->Command);
 		subcmdstr = aac_cmd_name(sub_cmd, aac_ctvm_subcmds);
 		if (subcmdstr == NULL)
 			break;
+		fib_cmd = sub_cmd;
+		cmdstr = subcmdstr;
+		sub_cmd = -1;
+		subcmdstr = NULL;
 
-		switch (sub_cmd) {
-		case VM_ContainerConfig: {
-			struct aac_Container *pContainer =
-			    (struct aac_Container *)fibp->data;
-
-			fib_cmd = sub_cmd;
-			cmdstr = subcmdstr;
-			sub_cmd = (uint32_t)-1;
-			subcmdstr = NULL;
-
-			sub_cmd = ddi_get32(acc,
-			    &pContainer->CTCommand.command);
+		switch (pContainer->Command) {
+		case VM_ContainerConfig:
+			sub_cmd = LE_32(pContainer->CTCommand.command);
 			subcmdstr = aac_cmd_name(sub_cmd, aac_ct_subcmds);
 			if (subcmdstr == NULL)
 				break;
 			aac_printf(softs, CE_NOTE, "FIB> %s (0x%x, 0x%x, 0x%x)",
 			    subcmdstr,
-			    ddi_get32(acc, &pContainer->CTCommand.param[0]),
-			    ddi_get32(acc, &pContainer->CTCommand.param[1]),
-			    ddi_get32(acc, &pContainer->CTCommand.param[2]));
+			    LE_32(pContainer->CTCommand.param[0]),
+			    LE_32(pContainer->CTCommand.param[1]),
+			    LE_32(pContainer->CTCommand.param[2]));
 			return;
-		}
-
 		case VM_Ioctl:
-			fib_cmd = sub_cmd;
-			cmdstr = subcmdstr;
-			sub_cmd = (uint32_t)-1;
-			subcmdstr = NULL;
-
-			sub_cmd = ddi_get32(acc,
-			    (void *)&(((uint32_t *)(void *)&fibp->data[0])[4]));
+			sub_cmd = LE_32(((int32_t *)pContainer)[4]);
 			subcmdstr = aac_cmd_name(sub_cmd, aac_ioctl_subcmds);
 			break;
-
-		case VM_CtBlockRead:
-		case VM_CtBlockWrite: {
-			struct aac_blockread *br =
-			    (struct aac_blockread *)fibp->data;
-			struct aac_sg_table *sg = &br->SgMap;
-			uint32_t sgcount = ddi_get32(acc, &sg->SgCount);
-
-			aac_printf(softs, CE_NOTE,
-			    "FIB> %s Container %d  0x%x/%d", subcmdstr,
-			    ddi_get32(acc, &br->ContainerId),
-			    ddi_get32(acc, &br->BlockNumber),
-			    ddi_get32(acc, &br->ByteCount));
-			for (i = 0; i < sgcount; i++)
-				aac_printf(softs, CE_NOTE,
-				    "     %d: 0x%08x/%d", i,
-				    ddi_get32(acc, &sg->SgEntry[i].SgAddress),
-				    ddi_get32(acc, &sg->SgEntry[i]. \
-				    SgByteCount));
-			return;
 		}
-		}
 		break;
 
-	case ContainerCommand64: {
-		struct aac_blockread64 *br =
-		    (struct aac_blockread64 *)fibp->data;
-		struct aac_sg_table64 *sg = &br->SgMap64;
-		uint32_t sgcount = ddi_get32(acc, &sg->SgCount);
-		uint64_t sgaddr;
-
-		sub_cmd = br->Command;
-		subcmdstr = NULL;
-		if (sub_cmd == VM_CtHostRead64)
-			subcmdstr = "VM_CtHostRead64";
-		else if (sub_cmd == VM_CtHostWrite64)
-			subcmdstr = "VM_CtHostWrite64";
-		else
-			break;
-
-		aac_printf(softs, CE_NOTE,
-		    "FIB> %s Container %d  0x%x/%d", subcmdstr,
-		    ddi_get16(acc, &br->ContainerId),
-		    ddi_get32(acc, &br->BlockNumber),
-		    ddi_get16(acc, &br->SectorCount));
-		for (i = 0; i < sgcount; i++) {
-			sgaddr = ddi_get64(acc,
-			    &sg->SgEntry64[i].SgAddress);
-			aac_printf(softs, CE_NOTE,
-			    "     %d: 0x%08x.%08x/%d", i,
-			    AAC_MS32(sgaddr), AAC_LS32(sgaddr),
-			    ddi_get32(acc, &sg->SgEntry64[i]. \
-			    SgByteCount));
-		}
-		return;
-	}
-
-	case RawIo: {
-		struct aac_raw_io *io = (struct aac_raw_io *)fibp->data;
-		struct aac_sg_tableraw *sg = &io->SgMapRaw;
-		uint32_t sgcount = ddi_get32(acc, &sg->SgCount);
-		uint64_t sgaddr;
-
-		aac_printf(softs, CE_NOTE,
-		    "FIB> RawIo Container %d  0x%llx/%d 0x%x",
-		    ddi_get16(acc, &io->ContainerId),
-		    ddi_get64(acc, &io->BlockNumber),
-		    ddi_get32(acc, &io->ByteCount),
-		    ddi_get16(acc, &io->Flags));
-		for (i = 0; i < sgcount; i++) {
-			sgaddr = ddi_get64(acc, &sg->SgEntryRaw[i].SgAddress);
-			aac_printf(softs, CE_NOTE, "     %d: 0x%08x.%08x/%d", i,
-			    AAC_MS32(sgaddr), AAC_LS32(sgaddr),
-			    ddi_get32(acc, &sg->SgEntryRaw[i].SgByteCount));
-		}
-		return;
-	}
-
 	case ClusterCommand:
-		sub_cmd = ddi_get32(acc,
-		    (void *)&(((uint32_t *)(void *)fibp->data)[0]));
+		sub_cmd = LE_32(((int32_t *)fibp->data)[0]);
 		subcmdstr = aac_cmd_name(sub_cmd, aac_cl_subcmds);
 		break;
 
 	case AifRequest:
-		sub_cmd = ddi_get32(acc,
-		    (void *)&(((uint32_t *)(void *)fibp->data)[0]));
+		sub_cmd = LE_32(((int32_t *)fibp->data)[0]);
 		subcmdstr = aac_cmd_name(sub_cmd, aac_aif_subcmds);
 		break;
 
@@ -8420,11 +8266,11 @@
 		break;
 	}
 
-	fib_size = ddi_get16(acc, &(fibp->Header.Size));
+	fib_size = LE_16(fibp->Header.Size);
 	if (subcmdstr)
 		aac_printf(softs, CE_NOTE, "FIB> %s, sz=%d",
 		    subcmdstr, fib_size);
-	else if (cmdstr && sub_cmd == (uint32_t)-1)
+	else if (cmdstr && sub_cmd == -1)
 		aac_printf(softs, CE_NOTE, "FIB> %s, sz=%d",
 		    cmdstr, fib_size);
 	else if (cmdstr)
@@ -8497,5 +8343,4 @@
 		break;
 	}
 }
-
-#endif /* DEBUG */
+#endif /* AAC_DEBUG_ALL */
--- old/usr/src/uts/common/io/aac/aac.h	Thu Nov  1 14:48:26 2012
+++ new/usr/src/uts/common/io/aac/aac.h	Thu Nov  1 14:48:26 2012
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  */
 
 /*
- * Copyright 2005-06 Adaptec, Inc.
- * Copyright (c) 2005-06 Adaptec Inc., Achim Leubner
+ * Copyright (c) 2010-12 PMC-Sierra, Inc.
+ * Copyright (c) 2005-10 Adaptec Inc., Achim Leubner
  * Copyright (c) 2000 Michael Smith
  * Copyright (c) 2001 Scott Long
  * Copyright (c) 2000 BSDi
@@ -30,17 +31,22 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * 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.47 2005/10/08 15:55:09 scottl Exp $
  */
 
 #ifndef	_AAC_H_
 #define	_AAC_H_
 
+#pragma ident	"@(#)aac.h	1.16	08/01/29 SMI"
+
 #ifdef	__cplusplus
 extern "C" {
 #endif
 
+#ifdef AAC_DEBUG_ALL
+#define AAC_DEBUG
+#define DEBUG 			/* activate assertions */
+#endif
+
 #define	AAC_ROUNDUP(x, y)		(((x) + (y) - 1) / (y) * (y))
 
 #define	AAC_TYPE_DEVO			1
@@ -53,8 +59,8 @@
 #endif
 
 #define	AAC_DRIVER_MAJOR_VERSION	2
-#define	AAC_DRIVER_MINOR_VERSION	2
-#define	AAC_DRIVER_BUGFIX_LEVEL		11
+#define	AAC_DRIVER_MINOR_VERSION	7
+#define	AAC_DRIVER_BUGFIX_LEVEL		1
 #define	AAC_DRIVER_TYPE			AAC_TYPE_RELEASE
 
 #define	STR(s)				# s
@@ -64,6 +70,7 @@
 					AAC_DRIVER_BUGFIX_LEVEL)
 
 #define	AACOK				0
+#define	AACOK2				1
 #define	AACERR				-1
 
 #define	AAC_MAX_ADAPTERS		64
@@ -94,12 +101,15 @@
 #endif
 #define	AAC_FWUP_TIMEOUT		180	/* wait up to 3 minutes */
 #define	AAC_IOCTL_TIMEOUT		900	/* wait up to 15 minutes */
-#define	AAC_SYNC_TIMEOUT		900	/* wait up to 15 minutes */
+#define AAC_AIF_TIMEOUT         180 /* up to 3 minutes */
 
 /* Adapter hardware interface types */
 #define	AAC_HWIF_UNKNOWN		0
 #define	AAC_HWIF_I960RX			1
 #define	AAC_HWIF_RKT			2
+#define	AAC_HWIF_NARK			3
+#define	AAC_HWIF_SRC			4
+#define	AAC_HWIF_SRCV			5
 
 #define	AAC_TYPE_UNKNOWN		0
 #define	AAC_TYPE_SCSI			1
@@ -112,13 +122,6 @@
 #define	AAC_HI32(p64)			((uint32_t *)(p64) + 1)
 
 /*
- * Internal events that will be handled serially by aac_event_thread()
- */
-#define	AAC_EVENT_AIF			(1 << 0)
-#define	AAC_EVENT_TIMEOUT		(1 << 1)
-#define	AAC_EVENT_SYNCTICK		(1 << 2)
-
-/*
  * AAC_CMDQ_SYNC should be 0 and AAC_CMDQ_ASYNC be 1 for Sync FIB io
  * to be served before async FIB io, see aac_start_waiting_io().
  * So that io requests sent by interactive userland commands get
@@ -156,32 +159,14 @@
 	char *desc;		/* ASCII data for INQUIRY command product id */
 };
 
-/* Device types */
-#define	AAC_DEV_LD		0	/* logical device */
-#define	AAC_DEV_PD		1	/* physical device */
+#define	AAC_DEV_LD	0	/* logical device */
+#define	AAC_DEV_PD	1	/* physical device */
 
-/* Device flags */
-#define	AAC_DFLAG_VALID		(1 << 0)
-#define	AAC_DFLAG_CONFIGURING	(1 << 1)
-
-#define	AAC_DEV_IS_VALID(dvp)	((dvp)->flags & AAC_DFLAG_VALID)
-#define	AAC_P2VTGT(softs, bus, tgt) \
-		((softs)->tgt_max * (bus) + (tgt) + AAC_MAX_LD)
-
-/*
- * Device config change events
- */
-enum aac_cfg_event {
-	AAC_CFG_NULL_NOEXIST = 0,	/* No change with no device */
-	AAC_CFG_NULL_EXIST,		/* No change but have device */
-	AAC_CFG_ADD,			/* Device added */
-	AAC_CFG_DELETE,			/* Device deleted */
-	AAC_CFG_CHANGE			/* Device changed */
-};
-
+#define	AAC_DEV_NONE	0
+#define	AAC_DEV_ONLINE	1
+#define	AAC_DEV_OFFLINE	2
 struct aac_device {
-	int flags;
-
+	uint8_t valid;
 	uint8_t type;
 	dev_info_t *dip;
 	int ncmds[AAC_CMDQ_NUM];	/* outstanding cmds of the device */
@@ -206,6 +191,7 @@
 
 	uint32_t bus;
 	uint32_t tid;
+	uint8_t dtype;		/* SCSI device type */
 };
 
 /*
@@ -223,94 +209,17 @@
 	struct aac_fib *fibp;	/* virtual address of FIB memory */
 };
 
-/*
- * Scatter-gather list structure defined by HBA hardware
- */
-struct aac_sge {
-	uint32_t bcount;	/* byte count */
-	union {
-		uint32_t ad32;	/* 32 bit address */
-		struct {
-			uint32_t lo;
-			uint32_t hi;
-		} ad64;		/* 64 bit address */
-	} addr;
-};
-
-/* aac_cmd flags */
-#define	AAC_CMD_CONSISTENT		(1 << 0)
-#define	AAC_CMD_DMA_PARTIAL		(1 << 1)
-#define	AAC_CMD_DMA_VALID		(1 << 2)
-#define	AAC_CMD_BUF_READ		(1 << 3)
-#define	AAC_CMD_BUF_WRITE		(1 << 4)
-#define	AAC_CMD_SYNC			(1 << 5) /* use sync FIB */
-#define	AAC_CMD_NO_INTR			(1 << 6) /* poll IO, no intr */
-#define	AAC_CMD_NO_CB			(1 << 7) /* sync IO, no callback */
-#define	AAC_CMD_NTAG			(1 << 8)
-#define	AAC_CMD_CMPLT			(1 << 9) /* cmd exec'ed by driver/fw */
-#define	AAC_CMD_ABORT			(1 << 10)
-#define	AAC_CMD_TIMEOUT			(1 << 11)
-#define	AAC_CMD_ERR			(1 << 12)
-#define	AAC_CMD_IN_SYNC_SLOT		(1 << 13)
-
-struct aac_softstate;
-typedef void (*aac_cmd_fib_t)(struct aac_softstate *, struct aac_cmd *);
-
-struct aac_cmd {
-	/*
-	 * Note: should be the first member for aac_cmd_queue to work
-	 * correctly.
-	 */
-	struct aac_cmd *next;
-	struct aac_cmd *prev;
-
-	struct scsi_pkt *pkt;
-	int cmdlen;
-	int flags;
-	uint32_t timeout; /* time when the cmd should have completed */
-	struct buf *bp;
-	ddi_dma_handle_t buf_dma_handle;
-
-	/* For non-aligned buffer and SRB */
-	caddr_t abp;
-	ddi_acc_handle_t abh;
-
-	/* Data transfer state */
-	ddi_dma_cookie_t cookie;
-	uint_t left_cookien;
-	uint_t cur_win;
-	uint_t total_nwin;
-	size_t total_xfer;
-	uint64_t blkno;
-	uint32_t bcount;	/* buffer size in byte */
-	struct aac_sge *sgt;	/* sg table */
-
-	/* FIB construct function */
-	aac_cmd_fib_t aac_cmd_fib;
-	/* Call back function for completed command */
-	void (*ac_comp)(struct aac_softstate *, struct aac_cmd *);
-
-	struct aac_slot *slotp;	/* slot used by this command */
-	struct aac_device *dvp;	/* target device */
-
-	/* FIB for this IO command */
-	int fib_size; /* size of the FIB xferred to/from the card */
-	struct aac_fib *fibp;
-
-#ifdef DEBUG
-	uint32_t fib_flags;
-#endif
-};
-
 /* Flags for attach tracking */
 #define	AAC_ATTACH_SOFTSTATE_ALLOCED	(1 << 0)
 #define	AAC_ATTACH_CARD_DETECTED	(1 << 1)
 #define	AAC_ATTACH_PCI_MEM_MAPPED	(1 << 2)
 #define	AAC_ATTACH_KMUTEX_INITED	(1 << 3)
-#define	AAC_ATTACH_SCSI_TRAN_SETUP	(1 << 4)
-#define	AAC_ATTACH_COMM_SPACE_SETUP	(1 << 5)
-#define	AAC_ATTACH_CREATE_DEVCTL	(1 << 6)
-#define	AAC_ATTACH_CREATE_SCSI		(1 << 7)
+#define	AAC_ATTACH_HARD_INTR_SETUP	(1 << 4)
+#define	AAC_ATTACH_SOFT_INTR_SETUP	(1 << 5)
+#define	AAC_ATTACH_SCSI_TRAN_SETUP	(1 << 6)
+#define	AAC_ATTACH_COMM_SPACE_SETUP	(1 << 7)
+#define	AAC_ATTACH_CREATE_DEVCTL	(1 << 8)
+#define	AAC_ATTACH_CREATE_SCSI		(1 << 9)
 
 /* Driver running states */
 #define	AAC_STATE_STOPPED	0
@@ -318,7 +227,6 @@
 #define	AAC_STATE_RESET		(1 << 1)
 #define	AAC_STATE_QUIESCED	(1 << 2)
 #define	AAC_STATE_DEAD		(1 << 3)
-#define	AAC_STATE_INTR		(1 << 4)
 
 /*
  * Flags for aac firmware
@@ -337,29 +245,33 @@
 #define	AAC_FLAGS_17SG		(1 << 8) /* quirk: 17 scatter gather maximum */
 #define	AAC_FLAGS_34SG		(1 << 9) /* quirk: 34 scatter gather maximum */
 #define	AAC_FLAGS_NONDASD	(1 << 10) /* non-DASD device supported */
-#define	AAC_FLAGS_BRKUP		(1 << 11) /* pkt breakup support */
-#define	AAC_FLAGS_JBOD		(1 << 12) /* JBOD mode support */
+#define AAC_FLAGS_NEW_COMM_TYPE1	(1 << 11)	/* New comm. type1 supported */
+#define AAC_FLAGS_NEW_COMM_TYPE2	(1 << 12)	/* New comm. type2 supported */
+#define AAC_FLAGS_NEW_COMM_TYPE34	(1 << 13)	/* New comm. type3-4 */
+#define AAC_FLAGS_SYNC_MODE	(1 << 14)	/* Sync. transfer mode */
 
 struct aac_softstate;
 struct aac_interface {
+	void (*aif_set_intr)(struct aac_softstate *, int enable);
+	void (*aif_status_clr)(struct aac_softstate *, int mask);
+	int (*aif_status_get)(struct aac_softstate *);
+	void (*aif_notify)(struct aac_softstate *, int val);
 	int (*aif_get_fwstatus)(struct aac_softstate *);
 	int (*aif_get_mailbox)(struct aac_softstate *, int);
 	void (*aif_set_mailbox)(struct aac_softstate *, uint32_t,
 	    uint32_t, uint32_t, uint32_t, uint32_t);
+	int (*aif_send_command)(struct aac_softstate *, struct aac_slot *);
 };
 
-#define	AAC_CTXFLAG_FILLED	0x01	/* aifq's full for this ctx */
-#define	AAC_CTXFLAG_RESETED	0x02
-
 struct aac_fib_context {
 	uint32_t unique;
 	int ctx_idx;
 	int ctx_filled;		/* aifq is full for this fib context */
-	int ctx_flags;
-	int ctx_overrun;
 	struct aac_fib_context *next, *prev;
 };
 
+typedef void (*aac_cmd_fib_t)(struct aac_softstate *, struct aac_cmd *);
+
 #define	AAC_VENDOR_LEN		8
 #define	AAC_PRODUCT_LEN		16
 
@@ -373,8 +285,6 @@
 	char vendor_name[AAC_VENDOR_LEN + 1];
 	char product_name[AAC_PRODUCT_LEN + 1];
 	uint32_t support_opt;	/* firmware features */
-	uint32_t support_opt2;
-	uint32_t feature_bits;
 	uint32_t atu_size;	/* actual size of PCI mem space */
 	uint32_t map_size;	/* mapped PCI mem space size */
 	uint32_t map_size_min;	/* minimum size of PCI mem that must be */
@@ -384,8 +294,9 @@
 	dev_info_t *devinfo_p;
 	scsi_hba_tran_t *hba_tran;
 	int slen;
-	int legacy;		/* legacy device naming */
-	uint32_t dma_max;	/* for buf breakup */
+	int legacy;
+	int sync_mode;
+	int no_sgl_conv;
 
 	/* DMA attributes */
 	ddi_dma_attr_t buf_dma_attr;
@@ -392,16 +303,16 @@
 	ddi_dma_attr_t addr_dma_attr;
 
 	/* PCI spaces */
-	ddi_device_acc_attr_t acc_attr;
-	ddi_device_acc_attr_t reg_attr;
-	ddi_acc_handle_t pci_mem_handle;
-	uint8_t *pci_mem_base_vaddr;
-	uint32_t pci_mem_base_paddr;
+	ddi_acc_handle_t pci_mem_handle[AAC_MAX_MEM_SPACE];
+	char *pci_mem_base_vaddr[AAC_MAX_MEM_SPACE];
+	uint32_t pci_mem_base_paddr[AAC_MAX_MEM_SPACE];
 
 	struct aac_interface aac_if;	/* adapter hardware interface */
 
-	struct aac_cmd sync_ac;		/* sync FIB */
-
+	struct aac_slot *sync_slot;      /* sync FIB */
+	int sync_slot_busy;
+	struct aac_slot *sync_mode_slot;
+    
 	/* Communication space */
 	struct aac_comm_space *comm_space;
 	ddi_acc_handle_t comm_space_acc_handle;
@@ -408,7 +319,10 @@
 	ddi_dma_handle_t comm_space_dma_handle;
 	uint32_t comm_space_phyaddr;
 
-	/* Old Comm. interface: message queues */
+	/* New Comm. type1: response buffer index */
+	uint32_t aac_host_rrq_idx;
+
+    /* Old Comm. interface: message queues */
 	struct aac_queue_table *qtablep;
 	struct aac_queue_entry *qentries[AAC_QUEUE_COUNT];
 
@@ -417,10 +331,12 @@
 	uint32_t aac_max_fib_size;	/* max. FIB size */
 	uint32_t aac_sg_tablesize;	/* max. sg count from host */
 	uint32_t aac_max_sectors;	/* max. I/O size from host (blocks) */
+	uint32_t aac_max_aif;		/* max. AIF count */
 
 	aac_cmd_fib_t aac_cmd_fib;	/* IO cmd FIB construct function */
 	aac_cmd_fib_t aac_cmd_fib_scsi;	/* SRB construct function */
 
+	ddi_iblock_cookie_t iblock_cookie;
 	ddi_softintr_t softint_id;	/* soft intr */
 
 	kmutex_t io_lock;
@@ -431,6 +347,8 @@
 	struct aac_nondasd *nondasds;
 	uint32_t bus_max;		/* max FW buses exposed */
 	uint32_t tgt_max;		/* max FW target per bus */
+	uint32_t aac_feature_bits;
+	uint32_t aac_support_opt2;
 
 	/*
 	 * Command queues
@@ -448,8 +366,9 @@
 	struct aac_slot *io_slot;	/* static list for allocated slots */
 	struct aac_slot *free_io_slot_head;
 
+	timeout_id_t timeout_id;	/* for timeout daemon */
+
 	kcondvar_t event;		/* for ioctl_send_fib() and sync IO */
-	kcondvar_t sync_fib_cv;		/* for sync_fib_slot_bind/release */
 
 	int bus_ncmds[AAC_CMDQ_NUM];	/* total outstanding async cmds */
 	int bus_throttle[AAC_CMDQ_NUM];	/* hold IO cmds for the bus */
@@ -457,45 +376,21 @@
 	timeout_id_t drain_timeid;	/* for outstanding cmd drain */
 	kcondvar_t drain_cv;		/* for quiesce drain */
 
-	/* Internal timer */
-	kmutex_t time_mutex;
-	timeout_id_t timeout_id;	/* for timeout daemon */
-	uint32_t timebase;		/* internal timer in seconds */
-	uint32_t time_sync;		/* next time to sync with firmware */
-	uint32_t time_out;		/* next time to check timeout */
-	uint32_t time_throttle;		/* next time to restore throttle */
-
-	/* Internal events handling */
-	kmutex_t ev_lock;
-	int events;
-	kthread_t *event_thread;	/* for AIF & timeout */
-	kcondvar_t event_wait_cv;
-	kcondvar_t event_disp_cv;
-
 	/* AIF */
 	kmutex_t aifq_mutex;		/* for AIF queue aifq */
-	kcondvar_t aifq_cv;
+	kcondvar_t aifv;
 	union aac_fib_align aifq[AAC_AIFQ_LENGTH];
 	int aifq_idx;			/* slot for next new AIF */
 	int aifq_wrap;			/* AIF queue has ever been wrapped */
-	struct aac_fib_context aifctx;	/* sys aif ctx */
-	struct aac_fib_context *fibctx_p;
+	struct aac_fib_context *fibctx;
 	int devcfg_wait_on;		/* AIF event waited for rescan */
 
 	int fm_capabilities;
+	ddi_taskq_t *taskq;
 
-	/* MSI specific fields */
-	ddi_intr_handle_t *htable;	/* For array of interrupts */
-	int intr_type;			/* What type of interrupt */
-	int intr_cnt;			/* # of intrs count returned */
-	int intr_size;
-	uint_t intr_pri;		/* Interrupt priority   */
-	int intr_cap;			/* Interrupt capabilities */
-
-#ifdef DEBUG
+#ifdef AAC_DEBUG
 	/* UART trace printf variables */
 	uint32_t debug_flags;		/* debug print flags bitmap */
-	uint32_t debug_fib_flags;	/* debug FIB print flags bitmap */
 	uint32_t debug_fw_flags;	/* FW debug flags */
 	uint32_t debug_buf_offset;	/* offset from DPMEM start */
 	uint32_t debug_buf_size;	/* FW debug buffer size in bytes */
@@ -511,10 +406,94 @@
 _NOTE(SCHEME_PROTECTS_DATA("stable data", aac_softstate::{flags slen \
     buf_dma_attr pci_mem_handle pci_mem_base_vaddr \
     comm_space_acc_handle comm_space_dma_handle aac_max_fib_size \
-    aac_sg_tablesize aac_cmd_fib aac_cmd_fib_scsi debug_flags bus_max tgt_max}))
+    aac_sg_tablesize aac_cmd_fib aac_cmd_fib_scsi debug_flags bus_max tgt_max \
+	aac_feature_bits}))
 
-#ifdef DEBUG
+/*
+ * Scatter-gather list structure defined by HBA hardware
+ */
+struct aac_sge {
+	uint32_t bcount;	/* byte count */
+	union {
+		uint32_t ad32;	/* 32 bit address */
+		struct {
+			uint32_t lo;
+			uint32_t hi;
+		} ad64;		/* 64 bit address */
+	} addr;
+};
 
+/* aac_cmd flags */
+#define	AAC_CMD_CONSISTENT		(1 << 0)
+#define	AAC_CMD_DMA_PARTIAL		(1 << 1)
+#define	AAC_CMD_DMA_VALID		(1 << 2)
+#define	AAC_CMD_BUF_READ		(1 << 3)
+#define	AAC_CMD_BUF_WRITE		(1 << 4)
+#define	AAC_CMD_SYNC			(1 << 5) /* use sync FIB */
+#define	AAC_CMD_NO_INTR			(1 << 6) /* poll IO, no intr */
+#define	AAC_CMD_NO_CB			(1 << 7) /* sync IO, no callback */
+#define	AAC_CMD_NTAG			(1 << 8)
+#define	AAC_CMD_CMPLT			(1 << 9) /* cmd exec'ed by driver/fw */
+#define	AAC_CMD_ABORT			(1 << 10)
+#define	AAC_CMD_TIMEOUT			(1 << 11)
+#define	AAC_CMD_ERR			(1 << 12)
+#define	AAC_CMD_AIF			(1 << 13)
+#define	AAC_CMD_AIF_NOMORE		(1 << 14)
+#define	AAC_CMD_FASTRESP		(1 << 15)
+
+#define AAC_MAXSEGMENTS		16
+
+struct aac_cmd {
+	/*
+	 * Note: should be the first member for aac_cmd_queue to work
+	 * correctly.
+	 */
+	struct aac_cmd *next;
+	struct aac_cmd *prev;
+
+	struct scsi_pkt *pkt;
+	int cmdlen;
+	int flags;
+	uint32_t timeout; /* time when the cmd should have completed */
+	struct buf *bp;
+
+	uint_t segment_cnt;
+	uint_t left_cookien;
+	struct {
+		ddi_dma_handle_t buf_dma_handle;
+		/* For non-aligned buffer and SRB */
+		caddr_t abp;
+		ddi_acc_handle_t abh;
+		uint32_t abp_size;
+		size_t abp_real_size;
+
+		/* Data transfer state */
+		ddi_dma_cookie_t cookie;
+		uint_t left_cookien;
+		struct aac_sge *sgt;
+	} segments[AAC_MAXSEGMENTS];
+	uint_t cur_segment;
+	uint_t cur_win;
+	uint_t total_nwin;
+	size_t total_xfer;
+	uint64_t blkno;
+	uint32_t bcount;	/* buffer size in byte */
+	struct aac_sge *sgt;	/* sg table */
+
+	/* FIB construct function */
+	aac_cmd_fib_t aac_cmd_fib;
+	/* Call back function for completed command */
+	void (*ac_comp)(struct aac_softstate *, struct aac_cmd *);
+
+	struct aac_slot *slotp;	/* slot used by this command */
+	struct aac_device *dvp;	/* target device */
+
+	/* FIB for this IO command */
+	int fib_size; /* size of the FIB xferred to/from the card */
+	struct aac_fib *fibp;
+};
+
+#ifdef AAC_DEBUG
 #define	AACDB_FLAGS_MASK		0x0000ffff
 #define	AACDB_FLAGS_KERNEL_PRINT	0x00000001
 #define	AACDB_FLAGS_FW_PRINT		0x00000002
@@ -528,23 +507,9 @@
 #define	AACDB_FLAGS_FIB			0x00000200
 #define	AACDB_FLAGS_IOCTL		0x00000400
 
-/*
- * Flags for FIB print
- */
-/* FIB sources */
-#define	AACDB_FLAGS_FIB_SCMD		0x00000001
-#define	AACDB_FLAGS_FIB_IOCTL		0x00000002
-#define	AACDB_FLAGS_FIB_SRB		0x00000004
-#define	AACDB_FLAGS_FIB_SYNC		0x00000008
-/* FIB components */
-#define	AACDB_FLAGS_FIB_HEADER		0x00000010
-/* FIB states */
-#define	AACDB_FLAGS_FIB_TIMEOUT		0x00000100
-
 extern uint32_t aac_debug_flags;
 extern int aac_dbflag_on(struct aac_softstate *, int);
 extern void aac_printf(struct aac_softstate *, uint_t, const char *, ...);
-extern void aac_print_fib(struct aac_softstate *, struct aac_slot *);
 
 #define	AACDB_PRINT(s, lev, ...) { \
 	if (aac_dbflag_on((s), AACDB_FLAGS_MISC)) \
@@ -561,7 +526,16 @@
 #define	DBCALLED(s, n) { \
 	if (aac_dbflag_on((s), AACDB_FLAGS_FUNC ## n)) \
 		aac_printf((s), CE_NOTE, "--- %s() called ---", __func__); }
+#else
+#define	AACDB_PRINT(s, lev, ...)
+#define	AACDB_PRINT_IOCTL(s, ...)
+#define	AACDB_PRINT_TRAN(s, ...)
+#define	DBCALLED(s, n)
+#endif /* AAC_DEBUG */
 
+#ifdef AAC_DEBUG_ALL
+extern void aac_print_fib(struct aac_softstate *, struct aac_fib *);
+
 #define	AACDB_PRINT_SCMD(s, x) { \
 	if (aac_dbflag_on((s), AACDB_FLAGS_SCMD)) aac_print_scmd((s), (x)); }
 
@@ -570,19 +544,12 @@
 
 #define	AACDB_PRINT_FIB(s, x) { \
 	if (aac_dbflag_on((s), AACDB_FLAGS_FIB)) aac_print_fib((s), (x)); }
-
-#else /* DEBUG */
-
-#define	AACDB_PRINT(s, lev, ...)
-#define	AACDB_PRINT_IOCTL(s, ...)
-#define	AACDB_PRINT_TRAN(s, ...)
+#else
 #define	AACDB_PRINT_FIB(s, x)
 #define	AACDB_PRINT_SCMD(s, x)
 #define	AACDB_PRINT_AIF(s, x)
-#define	DBCALLED(s, n)
+#endif /* AAC_DEBUG_ALL */
 
-#endif /* DEBUG */
-
 #ifdef	__cplusplus
 }
 #endif
--- old/usr/src/uts/common/io/aac/aac_ioctl.c	Thu Nov  1 14:48:27 2012
+++ new/usr/src/uts/common/io/aac/aac_ioctl.c	Thu Nov  1 14:48:27 2012
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  */
 
 /*
- * Copyright 2005-06 Adaptec, Inc.
- * Copyright (c) 2005-06 Adaptec Inc., Achim Leubner
+ * Copyright (c) 2010-12 PMC-Sierra, Inc.
+ * Copyright (c) 2005-10 Adaptec Inc., Achim Leubner
  * Copyright (c) 2000 Michael Smith
  * Copyright (c) 2001 Scott Long
  * Copyright (c) 2000 BSDi
@@ -31,6 +32,8 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  */
+#pragma ident	"@(#)aac_ioctl.c	1.9	07/10/30 SMI"
+
 #include <sys/modctl.h>
 #include <sys/conf.h>
 #include <sys/cmn_err.h>
@@ -58,7 +61,7 @@
  * External functions
  */
 extern int aac_sync_mbcommand(struct aac_softstate *, uint32_t, uint32_t,
-    uint32_t, uint32_t, uint32_t, uint32_t *);
+    uint32_t, uint32_t, uint32_t, uint32_t *, uint32_t *);
 extern int aac_cmd_dma_alloc(struct aac_softstate *, struct aac_cmd *,
     struct buf *, int, int (*)(), caddr_t);
 extern void aac_free_dmamap(struct aac_cmd *);
@@ -65,10 +68,6 @@
 extern int aac_do_io(struct aac_softstate *, struct aac_cmd *);
 extern void aac_cmd_fib_copy(struct aac_softstate *, struct aac_cmd *);
 extern void aac_ioctl_complete(struct aac_softstate *, struct aac_cmd *);
-extern int aac_return_aif_wait(struct aac_softstate *, struct aac_fib_context *,
-    struct aac_fib **);
-extern int aac_return_aif(struct aac_softstate *, struct aac_fib_context *,
-    struct aac_fib **);
 
 extern ddi_device_acc_attr_t aac_acc_attr;
 extern int aac_check_dma_handle(ddi_dma_handle_t);
@@ -262,16 +261,13 @@
 	acp->fib_size = fib_size;
 	fibp->Header.Size = LE_16(fib_size);
 
+	AACDB_PRINT_FIB(softs, fibp);
+
 	/* Process FIB */
 	if (fib_command == TakeABreakPt) {
-#ifdef DEBUG
-		if (aac_dbflag_on(softs, AACDB_FLAGS_FIB) &&
-		    (softs->debug_fib_flags & AACDB_FLAGS_FIB_IOCTL))
-			aac_printf(softs, CE_NOTE, "FIB> TakeABreakPt, sz=%d",
-			    fib_size);
-#endif
+		softs->sync_slot_busy = 1;
 		(void) aac_sync_mbcommand(softs, AAC_BREAKPOINT_REQ,
-		    0, 0, 0, 0, NULL);
+		    0, 0, 0, 0, NULL, NULL);
 		fibp->Header.XferState = LE_32(0);
 	} else {
 		ASSERT(!(fib_xfer_state & AAC_FIBSTATE_ASYNC));
@@ -280,9 +276,6 @@
 
 		acp->timeout = AAC_IOCTL_TIMEOUT;
 		acp->aac_cmd_fib = aac_cmd_fib_copy;
-#ifdef DEBUG
-		acp->fib_flags = AACDB_FLAGS_FIB_IOCTL;
-#endif
 		if ((rval = aac_send_fib(softs, acp)) != 0)
 			goto finish;
 	}
@@ -308,45 +301,45 @@
 static int
 aac_open_getadapter_fib(struct aac_softstate *softs, intptr_t arg, int mode)
 {
-	struct aac_fib_context *fibctx_p, *ctx_p;
+	struct aac_fib_context *fibctx, *ctx;
 
 	DBCALLED(softs, 2);
 
-	fibctx_p = kmem_zalloc(sizeof (struct aac_fib_context), KM_NOSLEEP);
-	if (fibctx_p == NULL)
+	fibctx = kmem_zalloc(sizeof (struct aac_fib_context), KM_NOSLEEP);
+	if (fibctx == NULL)
 		return (ENOMEM);
 
 	mutex_enter(&softs->aifq_mutex);
 	/* All elements are already 0, add to queue */
-	if (softs->fibctx_p == NULL) {
-		softs->fibctx_p = fibctx_p;
+	if (softs->fibctx == NULL) {
+		softs->fibctx = fibctx;
 	} else {
-		for (ctx_p = softs->fibctx_p; ctx_p->next; ctx_p = ctx_p->next)
+		for (ctx = softs->fibctx; ctx->next; ctx = ctx->next)
 			;
-		ctx_p->next = fibctx_p;
-		fibctx_p->prev = ctx_p;
+		ctx->next = fibctx;
+		fibctx->prev = ctx;
 	}
 
 	/* Evaluate unique value */
-	fibctx_p->unique = (unsigned long)fibctx_p & 0xfffffffful;
-	ctx_p = softs->fibctx_p;
-	while (ctx_p != fibctx_p) {
-		if (ctx_p->unique == fibctx_p->unique) {
-			fibctx_p->unique++;
-			ctx_p = softs->fibctx_p;
+	fibctx->unique = (unsigned long)fibctx & 0xfffffffful;
+	ctx = softs->fibctx;
+	while (ctx != fibctx) {
+		if (ctx->unique == fibctx->unique) {
+			fibctx->unique++;
+			ctx = softs->fibctx;
 		} else {
-			ctx_p = ctx_p->next;
+			ctx = ctx->next;
 		}
 	}
 
 	/* Set ctx_idx to the oldest AIF */
 	if (softs->aifq_wrap) {
-		fibctx_p->ctx_idx = softs->aifq_idx;
-		fibctx_p->ctx_filled = 1;
+		fibctx->ctx_idx = softs->aifq_idx;
+		fibctx->ctx_filled = 1;
 	}
 	mutex_exit(&softs->aifq_mutex);
 
-	if (ddi_copyout(&fibctx_p->unique, (void *)arg,
+	if (ddi_copyout(&fibctx->unique, (void *)arg,
 	    sizeof (uint32_t), mode) != 0)
 		return (EFAULT);
 
@@ -354,12 +347,30 @@
 }
 
 static int
+aac_return_aif(struct aac_softstate *softs,
+    struct aac_fib_context *ctx, caddr_t uptr, int mode)
+{
+	int current;
+
+	current = ctx->ctx_idx;
+	if (current == softs->aifq_idx && !ctx->ctx_filled)
+		return (EAGAIN); /* Empty */
+	if (ddi_copyout(&softs->aifq[current].d, (void *)uptr,
+	    sizeof (struct aac_fib), mode) != 0)
+		return (EFAULT);
+
+	ctx->ctx_filled = 0;
+	ctx->ctx_idx = (current + 1) % AAC_AIFQ_LENGTH;
+
+	return (0);
+}
+
+static int
 aac_next_getadapter_fib(struct aac_softstate *softs, intptr_t arg, int mode)
 {
 	union aac_get_adapter_fib_align un;
 	struct aac_get_adapter_fib *af = &un.d;
-	struct aac_fib_context *ctx_p;
-	struct aac_fib *fibp;
+	struct aac_fib_context *ctx;
 	int rval;
 
 	DBCALLED(softs, 2);
@@ -368,32 +379,39 @@
 		return (EFAULT);
 
 	mutex_enter(&softs->aifq_mutex);
-	for (ctx_p = softs->fibctx_p; ctx_p; ctx_p = ctx_p->next) {
-		if (af->context == ctx_p->unique)
+	for (ctx = softs->fibctx; ctx; ctx = ctx->next) {
+		if (af->context == ctx->unique)
 			break;
 	}
-	mutex_exit(&softs->aifq_mutex);
-
-	if (ctx_p) {
-		if (af->wait)
-			rval = aac_return_aif_wait(softs, ctx_p, &fibp);
-		else
-			rval = aac_return_aif(softs, ctx_p, &fibp);
-	}
-	else
-		rval = EFAULT;
-
-finish:
-	if (rval == 0) {
-		if (ddi_copyout(fibp,
-#ifdef _LP64
-		    (void *)(uint64_t)af->aif_fib,
+	if (ctx) {
+#ifdef	_LP64
+		rval = aac_return_aif(softs, ctx,
+		    (caddr_t)(uint64_t)af->aif_fib, mode);
 #else
-		    (void *)af->aif_fib,
+		rval = aac_return_aif(softs, ctx,
+		    (caddr_t)af->aif_fib, mode);
 #endif
-		    sizeof (struct aac_fib), mode) != 0)
-			rval = EFAULT;
+		if (rval == EAGAIN && af->wait) {
+			AACDB_PRINT(softs, CE_NOTE,
+			    "aac_next_getadapter_fib(): waiting for AIF");
+			rval = cv_wait_sig(&softs->aifv, &softs->aifq_mutex);
+			if (rval > 0) {
+#ifdef	_LP64
+				rval = aac_return_aif(softs, ctx,
+				    (caddr_t)(uint64_t)af->aif_fib, mode);
+#else
+				rval = aac_return_aif(softs, ctx,
+				    (caddr_t)af->aif_fib, mode);
+#endif
+			} else {
+				rval = EINTR;
+			}
+		}
+	} else {
+		rval = EFAULT;
 	}
+	mutex_exit(&softs->aifq_mutex);
+
 	return (rval);
 }
 
@@ -400,26 +418,26 @@
 static int
 aac_close_getadapter_fib(struct aac_softstate *softs, intptr_t arg)
 {
-	struct aac_fib_context *ctx_p;
+	struct aac_fib_context *ctx;
 
 	DBCALLED(softs, 2);
 
 	mutex_enter(&softs->aifq_mutex);
-	for (ctx_p = softs->fibctx_p; ctx_p; ctx_p = ctx_p->next) {
-		if (ctx_p->unique != (uint32_t)arg)
+	for (ctx = softs->fibctx; ctx; ctx = ctx->next) {
+		if (ctx->unique != (uint32_t)arg)
 			continue;
 
-		if (ctx_p == softs->fibctx_p)
-			softs->fibctx_p = ctx_p->next;
+		if (ctx == softs->fibctx)
+			softs->fibctx = ctx->next;
 		else
-			ctx_p->prev->next = ctx_p->next;
-		if (ctx_p->next)
-			ctx_p->next->prev = ctx_p->prev;
+			ctx->prev->next = ctx->next;
+		if (ctx->next)
+			ctx->next->prev = ctx->prev;
 		break;
 	}
 	mutex_exit(&softs->aifq_mutex);
-	if (ctx_p)
-		kmem_free(ctx_p, sizeof (struct aac_fib_context));
+	if (ctx)
+		kmem_free(ctx, sizeof (struct aac_fib_context));
 
 	return (0);
 }
@@ -499,24 +517,23 @@
 	}
 	for (usge = usgt; usge < &usgt[srb_sgcount]; usge++) {
 		if (sg64) {
-			struct aac_sg_entry64 *sg64p =
-			    (struct aac_sg_entry64 *)srb->sg.SgEntry;
-
-			usge->bcount = sg64p->SgByteCount;
+			usge->bcount = ((struct aac_sg_entry64 *)srb-> \
+			    sg.SgEntry)->SgByteCount;
 			usge->addr = (caddr_t)
 #ifndef _LP64
-			    (uint32_t)
+			    (uint32_t)((struct aac_sg_entry64 *) \
+			    srb->sg.SgEntry)->SgAddress;
+#else
+			    ((struct aac_sg_entry64 *) \
+			    srb->sg.SgEntry)->SgAddress;
 #endif
-			    sg64p->SgAddress;
 		} else {
-			struct aac_sg_entry *sgp = srb->sg.SgEntry;
-
-			usge->bcount = sgp->SgByteCount;
+			usge->bcount = srb->sg.SgEntry->SgByteCount;
 			usge->addr = (caddr_t)
 #ifdef _LP64
 			    (uint64_t)
 #endif
-			    sgp->SgAddress;
+			    srb->sg.SgEntry->SgAddress;
 		}
 		acp->bcount += usge->bcount;
 		if (usge->addr < addrlo)
@@ -554,12 +571,11 @@
 	for (usge = usgt; usge < &usgt[srb_sgcount]; usge++) {
 		struct buf *bp;
 
-		bp = ddi_umem_iosetup(cookie, (uintptr_t)usge->addr - \
-		    (uintptr_t)addrlo, usge->bcount, direct, dev, 0, NULL,
-		    DDI_UMEM_NOSLEEP);
+		bp = ddi_umem_iosetup(cookie, usge->addr - addrlo,
+		    usge->bcount, direct, dev, 0, NULL, DDI_UMEM_SLEEP);
 		if (bp == NULL) {
 			AACDB_PRINT(softs, CE_NOTE, "ddi_umem_iosetup failed");
-			rval = ENOMEM;
+			rval = EFAULT;
 			goto finish;
 		}
 		if (aac_cmd_dma_alloc(softs, &usge->acp, bp, 0, NULL_FUNC,
@@ -595,10 +611,8 @@
 	acp->timeout = srb->timeout;
 
 	/* Send FIB command */
+	AACDB_PRINT_FIB(softs, fibp);
 	acp->aac_cmd_fib = softs->aac_cmd_fib_scsi;
-#ifdef DEBUG
-	acp->fib_flags = AACDB_FLAGS_FIB_SRB;
-#endif
 	if ((rval = aac_send_fib(softs, acp)) != 0)
 		goto finish;
 
@@ -640,23 +654,20 @@
 {
 	union aac_pci_info_align un;
 	struct aac_pci_info *resp = &un.d;
-	pci_regspec_t *pci_rp;
-	uint_t num;
+	int val;
+	int *props;
+	unsigned int numProps;
 
 	DBCALLED(softs, 2);
 
-	if (ddi_prop_lookup_int_array(DDI_DEV_T_ANY, softs->devinfo_p,
-	    DDI_PROP_DONTPASS, "reg", (int **)&pci_rp, &num) !=
-	    DDI_PROP_SUCCESS)
-		return (EINVAL);
-	if (num < (sizeof (pci_regspec_t) / sizeof (int))) {
-		ddi_prop_free(pci_rp);
-		return (EINVAL);
-	}
+	val = ddi_prop_lookup_int_array(DDI_DEV_T_ANY,
+		softs->devinfo_p, 0, "reg", &props, &numProps);
+	if (val != DDI_PROP_SUCCESS || numProps == 0)
+		return (EFAULT);
 
-	resp->bus = PCI_REG_BUS_G(pci_rp->pci_phys_hi);
-	resp->slot = PCI_REG_DEV_G(pci_rp->pci_phys_hi);
-	ddi_prop_free(pci_rp);
+	resp->bus = PCI_REG_BUS_G(props[0]);
+	resp->slot = PCI_REG_DEV_G(props[0]);
+	ddi_prop_free(props);
 
 	if (ddi_copyout(resp, (void *)arg,
 	    sizeof (struct aac_pci_info), mode) != 0)
@@ -691,7 +702,7 @@
 
 	mutex_enter(&softs->io_lock);
 	dvp = &softs->containers[qdisk->container_no];
-	qdisk->valid = AAC_DEV_IS_VALID(&dvp->dev);
+	qdisk->valid = dvp->dev.valid;
 	qdisk->locked = dvp->locked;
 	qdisk->deleted = dvp->deleted;
 	mutex_exit(&softs->io_lock);
@@ -724,7 +735,7 @@
 	 * a container, rather we rely on an AIF coming from the
 	 * controller.
 	 */
-	if (AAC_DEV_IS_VALID(&dvp->dev)) {
+	if (dvp->dev.valid) {
 		if (dvp->locked)
 			rval = EBUSY;
 	}
@@ -762,16 +773,12 @@
 	if (f->feat.fValue == 0) {
 		f->feat.fBits.largeLBA =
 		    (softs->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
-		f->feat.fBits.JBODSupport =
-		    (softs->flags & AAC_FLAGS_JBOD) ? 1 : 0;
+		f->feat.fBits.JBODSupport = 1;
 		/* TODO: In the future, add other features state here as well */
 	} else {
 		if (f->feat.fBits.largeLBA)
 			f->feat.fBits.largeLBA =
 			    (softs->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
-		if (f->feat.fBits.JBODSupport)
-			f->feat.fBits.JBODSupport =
-			    (softs->flags & AAC_FLAGS_JBOD) ? 1 : 0;
 		/* TODO: Add other features state and data in the future */
 	}
 
--- old/usr/src/uts/common/io/aac/aac_ioctl.h	Thu Nov  1 14:48:28 2012
+++ new/usr/src/uts/common/io/aac/aac_ioctl.h	Thu Nov  1 14:48:27 2012
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  */
 
 /*
- * Copyright 2005-06 Adaptec, Inc.
- * Copyright (c) 2005-06 Adaptec Inc., Achim Leubner
+ * Copyright (c) 2010-11 PMC-Sierra, Inc.
+ * Copyright (c) 2005-10 Adaptec Inc., Achim Leubner
  * Copyright (c) 2000 Michael Smith
  * Copyright (c) 2000 Scott Long
  * Copyright (c) 2000 BSDi
@@ -30,14 +31,13 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- *
- *    $FreeBSD: /repoman/r/ncvs/src/sys/sys/aac_ioctl.h,
- *    v 1.11 2004/12/09 22:20:25 scottl Exp $
  */
 
 #ifndef	_AAC_IOCTL_H_
 #define	_AAC_IOCTL_H_
 
+#pragma ident	"@(#)aac_ioctl.h	1.3	07/10/30 SMI"
+
 #ifdef	__cplusplus
 extern "C" {
 #endif
@@ -83,7 +83,7 @@
 struct aac_get_adapter_fib
 {
 	uint32_t context;
-	int32_t wait;
+	int wait;
 	uint32_t aif_fib;	/* RAID config app is 32bit */
 };
 
@@ -116,9 +116,9 @@
 typedef union {
 	struct {
 		uint32_t largeLBA  : 1;	/* disk support greater 2TB */
-		uint32_t IoctlBuf  : 1; /* ARCIOCTL call support */
-		uint32_t AIFSupport: 1; /* AIF support */
-		uint32_t JBODSupport:1; /* firmware+driver both support JBOD */
+		uint32_t IoctlBuf  : 1;	/* ARCIOCTL call support */
+		uint32_t AIFSupport: 1;	/* AIF support */
+		uint32_t JBODSupport:1;	/* firmware + driver both support JBOD */
 		uint32_t fReserved : 28;
 	} fBits;
 	uint32_t fValue;
@@ -138,7 +138,7 @@
  *
  * Normally the packed structures are defined in a way that if the initial
  * member is aligned, then the following members will also be aligned. So
- * we need only to make sure the packed structure, ie. the first member, is
+ * we need only to make the packed structure, ie. the first member, is
  * aligned to satisfy alignment requirement.
  */
 union aac_revision_align {
--- old/usr/src/uts/common/io/aac/aac_regs.h	Thu Nov  1 14:48:28 2012
+++ new/usr/src/uts/common/io/aac/aac_regs.h	Thu Nov  1 14:48:28 2012
@@ -1,10 +1,11 @@
 /*
- * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+ * Use is subject to license terms.
  */
 
 /*
- * Copyright 2005-06 Adaptec, Inc.
- * Copyright (c) 2005-06 Adaptec Inc., Achim Leubner
+ * Copyright (c) 2010-12 PMC-Sierra, Inc.
+ * Copyright (c) 2005-10 Adaptec Inc., Achim Leubner
  * Copyright (c) 2000 Michael Smith
  * Copyright (c) 2000-2001 Scott Long
  * Copyright (c) 2000 BSDi
@@ -30,13 +31,13 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * 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 2005/10/14 16:22:45 scottl Exp $
  */
 
 #ifndef	__AAC_REGS_H__
 #define	__AAC_REGS_H__
 
+#pragma ident	"@(#)aac_regs.h	1.12	08/01/29 SMI"
+
 #ifdef	__cplusplus
 extern "C" {
 #endif
@@ -52,9 +53,14 @@
 #define	AAC_DB_RESPONSE_NOT_FULL	(1<<4)	/* response queue not full */
 #define	AAC_DB_PRINTF_READY		(1<<5)	/* adapter requests host */
 						/* printf */
+#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) */
+
 #define	AAC_DB_INTR_BITS (AAC_DB_COMMAND_READY | \
 	AAC_DB_RESPONSE_READY | AAC_DB_PRINTF_READY)
 #define	AAC_DB_INTR_NEW			0x08
+#define	AAC_DB_INTR_NEW_TYPE1	0x04
 
 /* Status bits in firmware status reg */
 #define	AAC_SELF_TEST_FAILED		0x00000004
@@ -76,6 +82,28 @@
 #define	AAC_RKT_MAILBOX		0x1000	/* mailbox, size=20bytes, rkt */
 #define	AAC_RKT_FWSTATUS	0x101c	/* firmware status, rkt */
 
+/*
+ * 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_IQUE32		0x40	/* inbound queue address 32-bit */
+#define AAC_SRC_IQUE64_L	0xc0	/* inbound queue address 64-bit (low) */
+#define AAC_SRC_IQUE64_H	0xc4	/* inbound queue address 64-bit (high) */
+
+#define AAC_SRC_MAILBOX		0x7fc60	/* mailbox (20 bytes) */
+#define AAC_SRCV_MAILBOX	0x1000	/* mailbox (20 bytes) */
+
+#define AAC_SRC_ODR_SHIFT 	12		/* outbound doorbell shift */
+#define AAC_SRC_IDR_SHIFT 	9		/* inbound doorbell shift */
+
+#define	AAC_MAX_MEM_SPACE	3	/* max number of PCI mem spaces */
+
 /* Synchronous commands to the monitor/kernel. */
 #define	AAC_BREAKPOINT_REQ	0x04
 #define	AAC_MONKER_INITSTRUCT	0x05
@@ -85,6 +113,7 @@
 #define	AAC_MONKER_GETDRVPROP	0x23
 #define	AAC_MONKER_GETCOMMPREF	0x26
 #define	AAC_IOP_RESET		0x1000
+#define	AAC_IOP_RESET_ALWAYS	0x1001
 
 /* Sunrise Lake dual core reset */
 #define	AAC_IRCSR_CORES_RST	3
@@ -114,6 +143,10 @@
  */
 #define	AAC_MAP_SIZE_MIN_RX	4096
 #define	AAC_MAP_SIZE_MIN_RKT	8192
+#define AAC_MAP_SIZE_MIN_SRC_BAR0	0x400000
+#define AAC_MAP_SIZE_MIN_SRC_BAR1	0x800
+#define AAC_MAP_SIZE_MIN_SRCV_BAR0	0x100000
+#define AAC_MAP_SIZE_MIN_SRCV_BAR1	0x400
 
 /*
  * Options supported by the adapter
@@ -137,21 +170,36 @@
 #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  /* Tupelo new comm */
+#define AAC_SUPPORTED_NEW_COMM_TYPE2	0x20000000  /* Denali new comm */
+#define AAC_SUPPORTED_NEW_COMM_TYPE3	0x40000000  /* Series 8 new comm */
+#define AAC_SUPPORTED_NEW_COMM_TYPE4	0x80000000  /* Series 9 new comm */
 
 /*
  * 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_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_FEATURE_SUPPORTED_JBOD		0x08000000
+#define AAC_SUPPL_SUPPORTED_JBOD	0x08000000
 
 #pragma	pack(1)
 
+/* transport FIB header (PMC) */
+struct aac_fib_xporthdr {
+	uint64_t	HostAddress;	/* FIB host address w/o xport header */
+	uint32_t	Size;			/* FIB size excluding xport header */
+	uint32_t	Handle;			/* driver handle to reference the FIB */
+	uint64_t	Reserved[2];
+};
+
 /*
  * FIB (FSA Interface Block) this is the data structure passed between
  * the host and adapter.
@@ -160,14 +208,18 @@
 	uint32_t	XferState;
 	uint16_t	Command;
 	uint8_t		StructType;
-	uint8_t		Flags;
+	uint8_t		Unused;
 	uint16_t	Size;
 	uint16_t	SenderSize;
 	uint32_t	SenderFibAddress;
-	uint32_t	ReceiverFibAddress;
-	uint32_t	SenderData;
-	int prev;
-	int next;
+	union {
+		uint32_t	ReceiverFibAddress;
+		uint32_t	SenderFibAddressHigh;
+		uint32_t	TimeStamp;
+	} a;
+	uint32_t	Handle;
+	uint32_t	Previous;
+	uint32_t	Next;
 };
 
 /* FIB completed without error or no data was transferred in the FIB */
@@ -197,9 +249,12 @@
 #define	AAC_FIBSTATE_NORM		(1<<12)	/* normal priority */
 #define	AAC_FIBSTATE_ASYNC		(1<<13)
 #define	AAC_FIBSTATE_FAST_RESPONSE	(1<<19)	/* fast response capable */
+#define AAC_FIBSTATE_NOMOREAIF		(1<<21)
 
 /* FIB types */
 #define	AAC_FIBTYPE_TFIB		1
+#define	AAC_FIBTYPE_TFIB2		4
+#define	AAC_FIBTYPE_TFIB2_64	5
 
 /*
  * FIB commands
@@ -237,6 +292,7 @@
 #define	ContainerCommand		500
 #define	ContainerCommand64		501
 #define	RawIo				502
+#define	RawIo2				503
 /* Cluster commands */
 #define	ClusterCommand			550
 /* Scsi Port commands (scsi passthrough) */
@@ -341,9 +397,9 @@
 	/* PCBA serial no. from th MFG sector */
 	uint8_t		MfgPcbaSerialNo[MFG_PCBA_SERIAL_NUMBER_WIDTH];
 	/* WWN from the MFG sector */
-	uint8_t		MfgWWNName[MFG_WWN_WIDTH];
-	uint32_t	SupportedOptions2;	/* more supported features */
-	uint32_t	ExpansionFlag;	/* 1 - following fields are valid */
+	uint8_t		MfgWWNName[MFG_WWN_WIDTH];  
+	uint32_t	SupportedOptions2;		/* more supported features */
+	uint32_t	ExpansionFlag;			/* 1 - following fields are valid */
 	uint32_t	FeatureBits3;
 	uint32_t	SupportedPerformanceMode;
 	/* Growth Area for future expansion */
@@ -364,6 +420,12 @@
 	uint64_t	ViaAdapterSerialNumber;
 };
 
+/* 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 */
+
 struct aac_mntobj {
 	uint32_t		ObjectId;
 	char			FileSystemName[16];
@@ -689,9 +751,66 @@
 	/* 210 added to support firmware cache sync operations */
 	CT_GET_CACHE_SYNC_INFO,
 	CT_SET_CACHE_SYNC_MODE,		/* 211 */
-	CT_PM_DRIVER_SUPPORT,		/* 212 */
-	CT_PM_CONFIGURATION,		/* 213 */
+	CT_GET_PARTITION_TABLE_500,	
+	CT_GET_PARTITION_INFO_500,
+	CT_GET_DISK_PARTITIONS_500,
 
+	CT_GET_RAID_CONFIG,			/* 215 */
+	CT_COPYBACK_ENABLE,
+	CT_CONTAINER_OPTIONS_500,
+
+	CT_MARK_BAD_STRIPES,		/* 218 */
+
+	CT_GET_RAID6_OPTIONS_500,	/* 219 */
+
+	CT_GET_SS_MAP_INFO,			/* 220 */
+
+	CT_CREATE_CONTAINER_64,		/* 221 */
+	CT_COPY_STATUS_64, 
+	CT_GET_SNAPSHOT_INFO_64,
+
+	CT_ENABLE_RAID_ENHANCED,	/* 224 */
+	
+	CT_GET_CONTAINER_SPITFIRE_SIZE,	/* 225 */
+	CT_STAMP_SPITFIRE_VM,
+
+	CT_GET_BST_INFO,			/* 227 */
+	CT_ERASE_BAD_STRIPE_TABLE,
+
+	CT_GET_CONTAINER_LIST,		/* 229 */
+										
+	CT_FREE_FOR_USE,			/* 230 */
+
+	CT_GET_HIST_LOG_SIZE,		/* 231 */
+	CT_GET_HIST_LOG_ENTRY,		
+
+	CT_CONTINUE_DATA_STOP,		/* 233 */
+
+	CT_GET_LOGDEV_INFO,			/* 234 */
+	CT_GET_LOGDEV_SEGMENT_LIST,
+
+	CT_SET_MINIARC_HOST_MEMORY_SEGMENTS,	/* 236 */
+
+	CT_CREATE_LOGICAL_DRIVE,	/* 237 */
+
+	CT_SET_CONTROLLER_DEVICE_CACHE_POLICY,	/* 238 */
+	CT_GET_CONTROLLER_DEVICE_CACHE_POLICY, 
+
+	CT_GET_MISC_STATUS_V3,		/* 240 */
+
+	CT_IDENTIFY_DEVICE,			/* 241 */
+
+	CT_CREATE_JBOD,				/* 242 */
+	CT_DELETE_JBOD,
+
+	CT_GET_STATISTIC_DATA,		/* 244 */
+
+	CT_PM_DRIVER_SUPPORT,		/* 245 */
+	CT_PM_CONFIGURATION,
+	CT_GET_PHYDEV_LIST,
+	CT_GET_PHYDEV_INFO,
+	CT_GET_LOGDEV_SEGMENT64_LIST,
+
 	CT_LAST_COMMAND			/* last command */
 } AAC_CTCommand;
 
@@ -705,6 +824,7 @@
 	AAC_PM_DRIVERSUP_STOP_UNIT
 } AAC_CT_PM_DRIVER_SUPPORT_SUB_COM;
 
+
 struct aac_fsa_ctm {
 	uint32_t	command;
 	uint32_t	param[CT_FIB_PARAMS];
@@ -816,6 +936,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,
@@ -900,6 +1021,13 @@
 	uint32_t	Flags;		/* reserved */
 };
 
+struct aac_sge_ieee1212 {
+	uint32_t	addrLow;
+	uint32_t	addrHigh;
+	uint32_t	length;
+	uint32_t	flags;		/* reserved */
+};
+
 struct aac_sg_table {
 	uint32_t		SgCount;
 	struct aac_sg_entry	SgEntry[1]; /* at least there is one */
@@ -978,6 +1106,34 @@
 	struct aac_sg_tableraw	SgMapRaw;
 };
 
+#define RIO2_IO_TYPE		0x0003
+#define RIO2_IO_TYPE_WRITE	0x0000
+#define RIO2_IO_TYPE_READ	0x0001
+#define RIO2_IO_TYPE_VERIFY	0x0002
+#define RIO2_IO_ERROR		0x0004
+#define RIO2_IO_SUREWRITE	0x0008
+#define RIO2_SGL_CONFORMANT	0x0010
+#define RIO2_SG_FORMAT		0xF000
+#define RIO2_SG_FORMAT_ARC	0x0000
+#define RIO2_SG_FORMAT_SRL	0x1000
+#define RIO2_SG_FORMAT_IEEE1212	0x2000
+
+struct aac_raw_io2 {
+	uint32_t		strtBlkLow;
+	uint32_t		strtBlkHigh;
+	uint32_t		byteCnt;
+	uint16_t		ldNum;
+	uint16_t		flags;			/* RIO2_xxx */
+	uint32_t		sgeFirstSize;	/* size of first S/G el. */
+	uint32_t		sgeNominalSize;	/* size of 2nd S/G el. */
+	uint8_t			sgeCnt;
+	uint8_t			bpTotal;		/* following elements reserved */
+	uint8_t			bpComplete;
+	uint8_t			sgeFirstIndex;
+	uint8_t			unused[4];
+	struct aac_sge_ieee1212	sge[1];	/* S/G list */
+};
+
 /*
  * Container shutdown command.
  */
@@ -1016,12 +1172,15 @@
 
 #define	AAC_INIT_STRUCT_REVISION		3
 #define	AAC_INIT_STRUCT_REVISION_4		4
+#define AAC_INIT_STRUCT_REVISION_6		6
+#define AAC_INIT_STRUCT_REVISION_7		7
 #define	AAC_INIT_STRUCT_MINIPORT_REVISION	1
-
 #define	AAC_INIT_FLAGS_NEW_COMM_SUPPORTED	1
-#define	AAC_INIT_FLAGS_DRIVER_USES_UTC_TIME	0x10
-#define	AAC_INIT_FLAGS_DRIVER_SUPPORTS_PM	0x20
-
+#define AAC_INIT_FLAGS_DRIVER_USES_UTC_TIME	0x10
+#define AAC_INIT_FLAGS_DRIVER_SUPPORTS_PM	0x20
+#define AAC_INITFLAGS_NEW_COMM_TYPE1_SUPPORTED  0x40
+#define AAC_INITFLAGS_DRIVER_SUPPORTS_FAST_JBOD  0x80
+#define AAC_INITFLAGS_NEW_COMM_TYPE2_SUPPORTED  0x100
 #define	AAC_PAGE_SIZE				4096
 struct aac_adapter_init {
 	uint32_t	InitStructRevision;
@@ -1042,6 +1201,11 @@
 	uint32_t	MaxIoCommands;
 	uint32_t	MaxIoSize;
 	uint32_t	MaxFibSize;
+	/* ADAPTER_INIT_STRUCT_REVISION_5 begins here */
+	uint32_t	MaxNumAif;	        /* max number of aif */ 
+	/* ADAPTER_INIT_STRUCT_REVISION_6 begins here */
+	uint32_t	HostRRQ_AddrLow;
+	uint32_t	HostRRQ_AddrHigh;	/* Host RRQ (response queue) for SRC */
 };
 
 /* ************AAC QUEUE DEFINES (BELOW)*********** */
@@ -1254,20 +1418,31 @@
 	AifEnConfigResume,	/* Container resume event */
 	AifEnFailoverChange,	/* Failover space assignment changed */
 	AifEnRAID5RebuildDone,	/* RAID5 rebuild finished */
-	AifEnEnclosureManagement,	/* Enclosure management event */
+	AifEnEnclosureManagement, /* Enclosure management event */
 	AifEnBatteryEvent,	/* Significant NV battery event */
 	AifEnAddContainer,	/* A new container was created. */
 	AifEnDeleteContainer,	/* A container was deleted. */
 	AifEnSMARTEvent,	/* SMART Event */
-	AifEnBatteryNeedsRecond,	/* The battery needs reconditioning */
-	AifEnClusterEvent,		/* Some cluster event */
-	AifEnDiskSetEvent,		/* A disk set event occured. */
-	AifEnAddJBOD = 30,	/* A new JBOD type drive was created (30) */
-	AifEnDeleteJBOD = 31,	/* A JBOD type drive was deleted (31) */
-	AifDriverNotifyStart = 199,	/* Notifies for host driver go here */
+	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 mess. */
+	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 */
-	AifDenVolumeExtendComplete	/* Volume expand operation completed */
+	AifDenMorphComplete,	/* A morph operation completed */
+	AifDenVolumeExtendComplete, /* Volume expand operation completed */
+	AifDriverNotifyDelay,
+	AifRawDeviceRemove			/* Raw device Failure event */
 } AAC_AifEventNotifyType;
 
 struct aac_AifEnsGeneric {
@@ -1365,7 +1540,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 {
@@ -1534,7 +1710,8 @@
 	uint32_t scsi_status;
 	uint32_t data_xfer_length;
 	uint32_t sense_data_size;
-	uint8_t sense_data[AAC_SENSE_BUFFERSIZE];
+	uint8_t sense_data[AAC_SENSE_BUFFERSIZE];    /* Can this be */
+						    /* SCSI_SENSE_BUFFERSIZE */
 };
 
 /*
@@ -1624,6 +1801,8 @@
 	struct aac_queue_table qtable;
 	char qt_align_pad[AAC_QUEUE_ALIGN];
 	char adapter_print_buf[AAC_ADAPTER_PRINT_BUFSIZE];
+    /* response buffer for SRC (new comm. type1) - must be last element */
+    uint32_t aac_host_rrq[1];
 };
 
 #ifdef	__cplusplus
