aac(4): Update to version 2.1.9-1 (current FreeBSD).
authorSascha Wildner <saw@online.de>
Fri, 7 Jan 2011 05:14:19 +0000 (06:14 +0100)
committerSascha Wildner <saw@online.de>
Fri, 7 Jan 2011 05:14:44 +0000 (06:14 +0100)
This brings in support for ~40 additional controllers of the family. See
the manual page for the full list.

It also fixes dumping to aac(4).

Tested with a Dell PERC 320/DC.

Reported-by: Archimedes Gaviola <archimedes.gaviola@gmail.com>
Dragonfly-bug: <http://bugs.dragonflybsd.org/issue1391>

17 files changed:
share/man/man4/aac.4
sys/conf/files
sys/conf/options
sys/config/LINT
sys/dev/raid/aac/Makefile
sys/dev/raid/aac/Makefile_linux.module [deleted file]
sys/dev/raid/aac/aac.c
sys/dev/raid/aac/aac_cam.c
sys/dev/raid/aac/aac_debug.c
sys/dev/raid/aac/aac_disk.c
sys/dev/raid/aac/aac_ioctl.h
sys/dev/raid/aac/aac_linux.c
sys/dev/raid/aac/aac_linux/Makefile
sys/dev/raid/aac/aac_pci.c
sys/dev/raid/aac/aac_tables.h
sys/dev/raid/aac/aacreg.h
sys/dev/raid/aac/aacvar.h

index 21f1e0e..7a9fbfe 100644 (file)
@@ -22,9 +22,8 @@
 .\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 .\" SUCH DAMAGE.
 .\"
-.\" $FreeBSD: src/share/man/man4/aac.4,v 1.31.2.1.2.1 2006/12/14 23:56:26 brueffer Exp $
-.\" $DragonFly: src/share/man/man4/aac.4,v 1.8 2008/09/02 11:50:46 matthias Exp $
-.Dd May 8, 2009
+.\" $FreeBSD: src/share/man/man4/aac.4,v 1.41 2009/07/11 08:10:18 jkim Exp $
+.Dd January 7, 2011
 .Dt AAC 4
 .Os
 .Sh NAME
@@ -40,7 +39,7 @@ kernel configuration file:
 .Cd device aacp
 .Pp
 To compile in debugging code:
-.Cd options AAC_DEBUG=N
+.Cd options AAC_DEBUG
 .Ed
 .Pp
 Alternatively, to load the driver as a
@@ -74,7 +73,7 @@ The aliases
 .Pa /dev/afa?
 and
 .Pa /dev/hpn?
-exist for compatibilty with the Dell and HP versions of management tools,
+exist for compatibility with the Dell and HP versions of management tools,
 respectively.
 If the kernel is compiled with the
 .Dv COMPAT_LINUX
@@ -87,24 +86,6 @@ Linux-compatible
 .Xr ioctl 2
 interface for the management device will be enabled and will allow
 Linux-based management applications to control the card.
-.Ss Tuning
-The read-only sysctl
-.Va hw.aac.iosize_max
-defaults to 65536 and may be set at boot time to another value via
-.Xr loader 8 .
-This value determines the maximum data transfer size allowed
-to/from an array.
-Setting it higher will result in better performance,
-especially for large sequential access patterns.
-.Em Beware :
-internal limitations
-of the card limit this value to 64K for arrays with many members.
-While it may be safe to raise this value, this is done
-.Em at the operator's own risk .
-Note also that
-performance peaks at a value of 96K,
-and drops off dramatically at 128K,
-due to other limitations of the card.
 .Sh HARDWARE
 Controllers supported by the
 .Nm
@@ -114,6 +95,42 @@ driver include:
 .It
 Adaptec AAC-364
 .It
+Adaptec RAID 2045
+.It
+Adaptec RAID 2405
+.It
+Adaptec RAID 2445
+.It
+Adaptec RAID 2805
+.It
+Adaptec RAID 3085
+.It
+Adaptec RAID 31205
+.It
+Adaptec RAID 31605
+.It
+Adaptec RAID 5085
+.It
+Adaptec RAID 51205
+.It
+Adaptec RAID 51245
+.It
+Adaptec RAID 51605
+.It
+Adaptec RAID 51645
+.It
+Adaptec RAID 52445
+.It
+Adaptec RAID 5405
+.It
+Adaptec RAID 5445
+.It
+Adaptec RAID 5805
+.It
+Adaptec SAS RAID 3405
+.It
+Adaptec SAS RAID 3805
+.It
 Adaptec SAS RAID 4000SAS
 .It
 Adaptec SAS RAID 4005SAS
@@ -184,12 +201,36 @@ IBM ServeRAID 8i
 .It
 IBM ServeRAID 8k
 .It
+IBM ServeRAID 8s
+.It
+ICP RAID ICP5045BL
+.It
+ICP RAID ICP5085BL
+.It
+ICP RAID ICP5085SL
+.It
+ICP RAID ICP5125BR
+.It
+ICP RAID ICP5125SL
+.It
+ICP RAID ICP5165BR
+.It
+ICP RAID ICP5165SL
+.It
+ICP RAID ICP5445SL
+.It
+ICP RAID ICP5805BL
+.It
+ICP RAID ICP5805SL
+.It
 ICP ICP5085BR SAS RAID
 .It
 ICP ICP9085LI SAS RAID
 .It
 ICP ICP9047MA SATA RAID
 .It
+ICP ICP9067MA SATA RAID
+.It
 ICP ICP9087MA SATA RAID
 .It
 ICP ICP9014RO SCSI RAID
@@ -199,9 +240,29 @@ ICP ICP9024RO SCSI RAID
 Legend S220
 .It
 Legend S230
+.It
+Sun STK RAID REM
+.It
+Sun STK RAID EM
+.It
+SG-XPCIESAS-R-IN
+.It
+SG-XPCIESAS-R-EX
+.It
+AOC-USAS-S4i
+.It
+AOC-USAS-S8i
+.It
+AOC-USAS-S4iR
+.It
+AOC-USAS-S8iR
+.It
+AOC-USAS-S8i-LP
+.It
+AOC-USAS-S8iR-LP
 .El
 .Sh FILES
-.Bl -tag -width ".Pa /dev/aacd?" -compact
+.Bl -tag -width /boot/kernel/aac.ko -compact
 .It Pa /dev/aac?
 aac management interface
 .It Pa /dev/aacd?
@@ -210,8 +271,7 @@ disk/container interface
 .Sh DIAGNOSTICS
 Compiling with
 .Dv AAC_DEBUG
-set to a number between 0 and 2
-will enable increasingly verbose debug messages.
+will enable debug messages.
 .Pp
 The adapter can send status and alert messages asynchronously
 to the driver.
@@ -221,9 +281,7 @@ and are also queued for retrieval by a management application.
 .Xr kld 4 ,
 .Xr linux 4 ,
 .Xr scsi 4 ,
-.Xr kldload 8 ,
-.Xr loader 8 ,
-.Xr sysctl 8
+.Xr kldload 8
 .Sh HISTORY
 The
 .Nm
@@ -240,6 +298,4 @@ firmware.
 The firmware version is the same as the kernel version printed in the BIOS
 POST and driver attach messages.
 .Pp
-.\"This driver will not work on systems with more than 4GB of memory.
-.\".Pp
 The controller is not actually paused on suspend/resume.
index 3a0ce75..41dfcfc 100644 (file)
@@ -118,12 +118,12 @@ ddb/db_trap.c                             optional ddb
 ddb/db_variables.c                     optional ddb
 ddb/db_watch.c                         optional ddb
 ddb/db_write_cmd.c                     optional ddb
-dev/raid/aac/aac.c                     optional nowerror aac
+dev/raid/aac/aac.c                     optional aac
+dev/raid/aac/aac_cam.c                 optional aacp aac
 dev/raid/aac/aac_debug.c               optional aac
 dev/raid/aac/aac_disk.c                        optional aac
-dev/raid/aac/aac_pci.c                 optional aac pci
 dev/raid/aac/aac_linux.c               optional aac compat_linux
-dev/raid/aac/aac_cam.c                 optional aacp aac
+dev/raid/aac/aac_pci.c                 optional aac pci
 dev/raid/arcmsr/arcmsr.c               optional arcmsr pci
 
 
index a16ab11..6ac400b 100644 (file)
 # opt_<name-of-option-in-lower-case>.h
 
 # Adaptec Array Controller driver options
-AAC_DEBUG              opt_aac.h       # Debugging levels:
-                                       # 0 - quiet, only emit warnings
-                                       # 1 - noisy, emit major function
-                                       #     points and things done
-                                       # 2 - noisier, emit trace items
-                                       #     in loops, etc.
-                                       # 3 - even more noisy, more function
-                                       #     points
-                                       # 4 - noisiest
+AAC_DEBUG              opt_aac.h
 
 # Adaptec aic7xxx SCSI controller options
 AHC_ALLOW_MEMIO                opt_aic7xxx.h   # Allow PCI devices to use memory
index f7ad2ad..323c777 100644 (file)
@@ -1248,7 +1248,7 @@ device            stg0    at isa? port 0x140 irq 11
 # the Dell PERC 2/QC and the HP NetRAID-4M
 #
 device         aac
-options                AAC_DEBUG=4
+options                AAC_DEBUG
 device         aacp    # SCSI Passthrough interface (optional, CAM required)
 
 #
index d3faf41..962a103 100644 (file)
@@ -1,12 +1,15 @@
-# $FreeBSD: src/sys/modules/aac/Makefile,v 1.2.2.4 2003/03/28 19:51:37 scottl Exp $
+# $FreeBSD: src/sys/modules/aac/Makefile,v 1.9 2010/08/23 06:13:29 imp Exp $
 
+.if ${MACHINE_ARCH} == "i386"
 SUBDIR= aac_linux
+.endif
 
 KMOD=  aac
 SRCS=  aac.c aac_pci.c aac_disk.c aac_cam.c
 SRCS+= opt_scsi.h opt_cam.h opt_aac.h
 SRCS+= device_if.h bus_if.h pci_if.h
 
+# To enable debug output from the driver, uncomment these two lines.
 #CFLAGS+= -DAAC_DEBUG=2
 #SRCS+=        aac_debug.c
 
diff --git a/sys/dev/raid/aac/Makefile_linux.module b/sys/dev/raid/aac/Makefile_linux.module
deleted file mode 100644 (file)
index 112bf6f..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# $FreeBSD: src/sys/modules/aac/aac_linux/Makefile,v 1.1.4.1 2003/03/28 19:51:37 scottl Exp $
-# $DragonFly: src/sys/dev/raid/aac/Makefile_linux.module,v 1.2 2003/06/17 04:28:43 dillon Exp $
-
-.PATH: ${.CURDIR}/../../../dev/aac
-
-KMOD=  aac_linux
-SRCS=  aac_linux.c
-
-.include <bsd.kmod.mk>
index d9927bf..8868af5 100644 (file)
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     $FreeBSD: src/sys/dev/aac/aac.c,v 1.9.2.14 2003/04/08 13:22:08 scottl Exp $
+ * $FreeBSD: src/sys/dev/aac/aac.c,v 1.165 2010/09/29 14:22:00 emaste Exp $
  */
 
 /*
  * Driver for the Adaptec 'FSA' family of PCI/SCSI RAID adapters.
  */
-#define AAC_DRIVER_VERSION             0x02000000
 #define AAC_DRIVERNAME                 "aac"
 
 #include "opt_aac.h"
 #include <sys/kernel.h>
 #include <sys/kthread.h>
 #include <sys/sysctl.h>
-#include <sys/event.h>
+#include <sys/poll.h>
 
 #include <sys/bus.h>
 #include <sys/conf.h>
-#include <sys/devicestat.h>
-#include <sys/disk.h>
 #include <sys/signalvar.h>
 #include <sys/time.h>
 #include <sys/eventhandler.h>
 #include <sys/rman.h>
 
+#include <sys/bus_dma.h>
+#include <sys/device.h>
 #include <sys/mplock2.h>
 
 #include <bus/pci/pcireg.h>
 #include <bus/pci/pcivar.h>
 
-#include "aacreg.h"
-#include "aac_ioctl.h"
-#include "aacvar.h"
-#include "aac_tables.h"
+#include <dev/raid/aac/aacreg.h>
+#include <dev/raid/aac/aac_ioctl.h>
+#include <dev/raid/aac/aacvar.h>
+#include <dev/raid/aac/aac_tables.h>
 
 static void    aac_startup(void *arg);
 static void    aac_add_container(struct aac_softc *sc,
                                  struct aac_mntinforesp *mir, int f);
 static void    aac_get_bus_info(struct aac_softc *sc);
-static int     aac_shutdown(device_t dev);
+static void    aac_daemon(void *arg);
 
 /* Command Processing */
-static void    aac_timeout(void *ssc);
-static int     aac_map_command(struct aac_command *cm);
+static void    aac_timeout(struct aac_softc *sc);
 static void    aac_complete(void *context, int pending);
 static int     aac_bio_command(struct aac_softc *sc, struct aac_command **cmp);
 static void    aac_bio_complete(struct aac_command *cm);
@@ -90,6 +88,7 @@ static void   aac_free_commands(struct aac_softc *sc);
 static void    aac_unmap_command(struct aac_command *cm);
 
 /* Hardware Interface */
+static int     aac_alloc(struct aac_softc *sc);
 static void    aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg,
                               int error);
 static int     aac_check_firmware(struct aac_softc *sc);
@@ -97,6 +96,7 @@ static int    aac_init(struct aac_softc *sc);
 static int     aac_sync_command(struct aac_softc *sc, u_int32_t command,
                                 u_int32_t arg0, u_int32_t arg1, u_int32_t arg2,
                                 u_int32_t arg3, u_int32_t *sp);
+static int     aac_setup_intr(struct aac_softc *sc);
 static int     aac_enqueue_fib(struct aac_softc *sc, int queue,
                                struct aac_command *cm);
 static int     aac_dequeue_fib(struct aac_softc *sc, int queue,
@@ -104,28 +104,6 @@ static int aac_dequeue_fib(struct aac_softc *sc, int queue,
 static int     aac_enqueue_response(struct aac_softc *sc, int queue,
                                     struct aac_fib *fib);
 
-/* Falcon/PPC interface */
-static int     aac_fa_get_fwstatus(struct aac_softc *sc);
-static void    aac_fa_qnotify(struct aac_softc *sc, int qbit);
-static int     aac_fa_get_istatus(struct aac_softc *sc);
-static void    aac_fa_clear_istatus(struct aac_softc *sc, int mask);
-static void    aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command,
-                                  u_int32_t arg0, u_int32_t arg1,
-                                  u_int32_t arg2, u_int32_t arg3);
-static int     aac_fa_get_mailbox(struct aac_softc *sc, int mb);
-static void    aac_fa_set_interrupts(struct aac_softc *sc, int enable);
-
-struct aac_interface aac_fa_interface = {
-       aac_fa_get_fwstatus,
-       aac_fa_qnotify,
-       aac_fa_get_istatus,
-       aac_fa_clear_istatus,
-       aac_fa_set_mailbox,
-       aac_fa_get_mailbox,
-       aac_fa_set_interrupts,
-       NULL, NULL, NULL
-};
-
 /* StrongARM interface */
 static int     aac_sa_get_fwstatus(struct aac_softc *sc);
 static void    aac_sa_qnotify(struct aac_softc *sc, int qbit);
@@ -213,17 +191,25 @@ static d_close_t  aac_close;
 static d_ioctl_t       aac_ioctl;
 static d_kqfilter_t    aac_kqfilter;
 static void            aac_filter_detach(struct knote *kn);
-static int             aac_filter(struct knote *kn, long hint);
-static int             aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib) __unused;
+static int             aac_filter_read(struct knote *kn, long hint);
+static int             aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib);
+static int             aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg);
 static void            aac_handle_aif(struct aac_softc *sc,
                                           struct aac_fib *fib);
 static int             aac_rev_check(struct aac_softc *sc, caddr_t udata);
+static int             aac_open_aif(struct aac_softc *sc, caddr_t arg);
+static int             aac_close_aif(struct aac_softc *sc, caddr_t arg);
 static int             aac_getnext_aif(struct aac_softc *sc, caddr_t arg);
-static int             aac_return_aif(struct aac_softc *sc, caddr_t uptr);
+static int             aac_return_aif(struct aac_softc *sc,
+                                       struct aac_fib_context *ctx, caddr_t uptr);
 static int             aac_query_disk(struct aac_softc *sc, caddr_t uptr);
 static int             aac_get_pci_info(struct aac_softc *sc, caddr_t uptr);
+static int             aac_supported_features(struct aac_softc *sc, caddr_t uptr);
 static void            aac_ioctl_event(struct aac_softc *sc,
-                                       struct aac_event *event, void *arg);
+                                       struct aac_event *event, void *arg);
+static struct aac_mntinforesp *
+       aac_get_container_info(struct aac_softc *sc, struct aac_fib *fib, int cid);
+
 static struct dev_ops aac_ops = {
        { "aac", 0, 0 },
        .d_open =       aac_open,
@@ -232,8 +218,6 @@ static struct dev_ops aac_ops = {
        .d_kqfilter =   aac_kqfilter
 };
 
-DECLARE_DUMMY_MODULE(aac);
-
 MALLOC_DEFINE(M_AACBUF, "aacbuf", "Buffers for the AAC driver");
 
 /* sysctl node */
@@ -244,27 +228,25 @@ SYSCTL_NODE(_hw, OID_AUTO, aac, CTLFLAG_RD, 0, "AAC driver parameters");
  */
 
 /*
- * Initialise the controller and softc
+ * Initialize the controller and softc
  */
 int
 aac_attach(struct aac_softc *sc)
 {
        int error, unit;
 
-       debug_called(1);
-       callout_init(&sc->aac_watchdog);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        /*
-        * Initialise per-controller queues.
+        * Initialize per-controller queues.
         */
        aac_initq_free(sc);
        aac_initq_ready(sc);
        aac_initq_busy(sc);
-       aac_initq_complete(sc);
        aac_initq_bio(sc);
 
        /*
-        * Initialise command-completion task.
+        * Initialize command-completion task.
         */
        TASK_INIT(&sc->aac_task_complete, 0, aac_complete, sc);
 
@@ -280,54 +262,28 @@ aac_attach(struct aac_softc *sc)
        /*
         * Initialize locks
         */
-       AAC_LOCK_INIT(&sc->aac_aifq_lock, "AAC AIF lock");
-       AAC_LOCK_INIT(&sc->aac_io_lock, "AAC I/O lock");
-       AAC_LOCK_INIT(&sc->aac_container_lock, "AAC container lock");
+       lockinit(&sc->aac_aifq_lock, "AAC AIF lock", 0, LK_CANRECURSE);
+       lockinit(&sc->aac_io_lock, "AAC I/O lock", 0, LK_CANRECURSE);
+       lockinit(&sc->aac_container_lock, "AAC container lock", 0, LK_CANRECURSE);
        TAILQ_INIT(&sc->aac_container_tqh);
        TAILQ_INIT(&sc->aac_ev_cmfree);
 
-
-       /* Initialize the local AIF queue pointers */
-       sc->aac_aifq_head = sc->aac_aifq_tail = AAC_AIFQ_LENGTH;
+       /* Initialize the clock daemon callout. */
+       callout_init(&sc->aac_daemontime);
 
        /*
-        * Initialise the adapter.
+        * Initialize the adapter.
         */
+       if ((error = aac_alloc(sc)) != 0)
+               return(error);
        if ((error = aac_init(sc)) != 0)
                return(error);
 
        /*
         * Allocate and connect our interrupt.
         */
-       sc->aac_irq_rid = 0;
-       if ((sc->aac_irq = bus_alloc_resource_any(sc->aac_dev, SYS_RES_IRQ,
-                                                 &sc->aac_irq_rid,
-                                                 RF_SHAREABLE |
-                                                 RF_ACTIVE)) == NULL) {
-               device_printf(sc->aac_dev, "can't allocate interrupt\n");
-               return (EINVAL);
-       }
-       if (sc->flags & AAC_FLAGS_NEW_COMM) {
-               if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
-                                  0, aac_new_intr,
-                                  sc, &sc->aac_intr, NULL)) {
-                       device_printf(sc->aac_dev, "can't set up interrupt\n");
-                       return (EINVAL);
-               }
-       } else {
-               if (bus_setup_intr(sc->aac_dev, sc->aac_irq, 0,
-                                  aac_fast_intr, sc, &sc->aac_intr, NULL)) {
-                       device_printf(sc->aac_dev,
-                                     "can't set up FAST interrupt\n");
-                       if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
-                                          0, aac_fast_intr,
-                                          sc, &sc->aac_intr, NULL)) {
-                               device_printf(sc->aac_dev,
-                                            "can't set up MPSAFE interrupt\n");
-                               return (EINVAL);
-                       }
-               }
-       }
+       if ((error = aac_setup_intr(sc)) != 0)
+               return(error);
 
        /*
         * Print a little information about the controller.
@@ -339,7 +295,6 @@ aac_attach(struct aac_softc *sc)
         */
        sc->aac_ich.ich_func = aac_startup;
        sc->aac_ich.ich_arg = sc;
-       sc->aac_ich.ich_desc = "aac";
        if (config_intrhook_establish(&sc->aac_ich) != 0) {
                device_printf(sc->aac_dev,
                              "can't establish configuration hook\n");
@@ -352,17 +307,18 @@ aac_attach(struct aac_softc *sc)
        unit = device_get_unit(sc->aac_dev);
        sc->aac_dev_t = make_dev(&aac_ops, unit, UID_ROOT, GID_OPERATOR,
                                 0640, "aac%d", unit);
+       (void)make_dev_alias(sc->aac_dev_t, "afa%d", unit);
+       (void)make_dev_alias(sc->aac_dev_t, "hpn%d", unit);
        sc->aac_dev_t->si_drv1 = sc;
-       reference_dev(sc->aac_dev_t);
 
        /* Create the AIF thread */
        if (kthread_create(aac_command_thread, sc,
                           &sc->aifthread, "aac%daif", unit))
-               panic("Could not create AIF thread\n");
+               panic("Could not create AIF thread");
 
        /* Register the shutdown method to only be called post-dump */
-       if ((sc->eh = EVENTHANDLER_REGISTER(shutdown_post_sync, aac_shutdown,
-           sc->aac_dev, SHUTDOWN_PRI_DRIVER)) == NULL)
+       if ((sc->eh = EVENTHANDLER_REGISTER(shutdown_final, aac_shutdown,
+           sc->aac_dev, SHUTDOWN_PRI_DEFAULT)) == NULL)
                device_printf(sc->aac_dev,
                              "shutdown event registration failed\n");
 
@@ -372,9 +328,35 @@ aac_attach(struct aac_softc *sc)
                aac_get_bus_info(sc);
        }
 
+       lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
+       callout_reset(&sc->aac_daemontime, 60 * hz, aac_daemon, sc);
+       lockmgr(&sc->aac_io_lock, LK_RELEASE);
+
        return(0);
 }
 
+static void
+aac_daemon(void *arg)
+{
+       struct timeval tv;
+       struct aac_softc *sc;
+       struct aac_fib *fib;
+
+       sc = arg;
+       lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
+
+       if (callout_pending(&sc->aac_daemontime) ||
+           callout_active(&sc->aac_daemontime) == 0)
+               return;
+       getmicrotime(&tv);
+       aac_alloc_sync_fib(sc, &fib);
+       *(uint32_t *)fib->data = tv.tv_sec;
+       aac_sync_fib(sc, SendHostTime, 0, fib, sizeof(uint32_t));
+       aac_release_sync_fib(sc);
+       lockmgr(&sc->aac_io_lock, LK_RELEASE);
+       callout_reset(&sc->aac_daemontime, 30 * 60 * hz, aac_daemon, sc);
+}
+
 void
 aac_add_event(struct aac_softc *sc, struct aac_event *event)
 {
@@ -393,6 +375,30 @@ aac_add_event(struct aac_softc *sc, struct aac_event *event)
 }
 
 /*
+ * Request information of container #cid
+ */
+static struct aac_mntinforesp *
+aac_get_container_info(struct aac_softc *sc, struct aac_fib *fib, int cid)
+{
+       struct aac_mntinfo *mi;
+
+       mi = (struct aac_mntinfo *)&fib->data[0];
+       /* use 64-bit LBA if enabled */
+       mi->Command = (sc->flags & AAC_FLAGS_LBA_64BIT) ?
+           VM_NameServe64 : VM_NameServe;
+       mi->MntType = FT_FILESYS;
+       mi->MntCount = cid;
+
+       if (aac_sync_fib(sc, ContainerCommand, 0, fib,
+                        sizeof(struct aac_mntinfo))) {
+               device_printf(sc->aac_dev, "Error probing container %d\n", cid);
+               return (NULL);
+       }
+
+       return ((struct aac_mntinforesp *)&fib->data[0]);
+}
+
+/*
  * Probe for containers, create disks.
  */
 static void
@@ -400,45 +406,30 @@ aac_startup(void *arg)
 {
        struct aac_softc *sc;
        struct aac_fib *fib;
-       struct aac_mntinfo *mi;
-       struct aac_mntinforesp *mir = NULL;
+       struct aac_mntinforesp *mir;
        int count = 0, i = 0;
-       
-       debug_called(1);
 
        sc = (struct aac_softc *)arg;
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        /* disconnect ourselves from the intrhook chain */
        config_intrhook_disestablish(&sc->aac_ich);
 
-       AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+       lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
        aac_alloc_sync_fib(sc, &fib);
-       mi = (struct aac_mntinfo *)&fib->data[0];
 
        /* loop over possible containers */
        do {
-               /* request information on this container */
-               bzero(mi, sizeof(struct aac_mntinfo));
-               mi->Command = VM_NameServe;
-               mi->MntType = FT_FILESYS;
-               mi->MntCount = i;
-               if (aac_sync_fib(sc, ContainerCommand, 0, fib,
-                                sizeof(struct aac_mntinfo))) {
-                       device_printf(sc->aac_dev,
-                           "error probing container %d", i);
-
+               if ((mir = aac_get_container_info(sc, fib, i)) == NULL)
                        continue;
-               }
-
-               mir = (struct aac_mntinforesp *)&fib->data[0];
-               /* XXX Need to check if count changed */
-               count = mir->MntRespCount;
+               if (i == 0)
+                       count = mir->MntRespCount;
                aac_add_container(sc, mir, 0);
                i++;
        } while ((i < count) && (i < AAC_MAX_CONTAINERS));
 
        aac_release_sync_fib(sc);
-       AAC_LOCK_RELEASE(&sc->aac_io_lock);
+       lockmgr(&sc->aac_io_lock, LK_RELEASE);
 
        /* poke the bus to actually attach the child devices */
        if (bus_generic_attach(sc->aac_dev))
@@ -452,7 +443,7 @@ aac_startup(void *arg)
 }
 
 /*
- * Create a device to respresent a new container
+ * Create a device to represent a new container
  */
 static void
 aac_add_container(struct aac_softc *sc, struct aac_mntinforesp *mir, int f)
@@ -467,7 +458,7 @@ aac_add_container(struct aac_softc *sc, struct aac_mntinforesp *mir, int f)
        if ((mir->Status == ST_OK) && (mir->MntTable[0].VolType != CT_NONE)) {
                co = (struct aac_container *)kmalloc(sizeof *co, M_AACBUF,
                       M_INTWAIT | M_ZERO);
-               debug(1, "id %x  name '%.16s'  size %u  type %d",
+               fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "id %x  name '%.16s'  size %u  type %d",
                      mir->MntTable[0].ObjectId,
                      mir->MntTable[0].FileSystemName,
                      mir->MntTable[0].Capacity, mir->MntTable[0].VolType);
@@ -482,10 +473,115 @@ aac_add_container(struct aac_softc *sc, struct aac_mntinforesp *mir, int f)
                co->co_found = f;
                bcopy(&mir->MntTable[0], &co->co_mntobj,
                      sizeof(struct aac_mntobj));
-               AAC_LOCK_ACQUIRE(&sc->aac_container_lock);
+               lockmgr(&sc->aac_container_lock, LK_EXCLUSIVE);
                TAILQ_INSERT_TAIL(&sc->aac_container_tqh, co, co_link);
-               AAC_LOCK_RELEASE(&sc->aac_container_lock);
+               lockmgr(&sc->aac_container_lock, LK_RELEASE);
+       }
+}
+
+/*
+ * Allocate resources associated with (sc)
+ */
+static int
+aac_alloc(struct aac_softc *sc)
+{
+
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+       /*
+        * Create DMA tag for mapping buffers into controller-addressable space.
+        */
+       if (bus_dma_tag_create(sc->aac_parent_dmat,     /* parent */
+                              1, 0,                    /* algnmnt, boundary */
+                              (sc->flags & AAC_FLAGS_SG_64BIT) ?
+                              BUS_SPACE_MAXADDR :
+                              BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
+                              BUS_SPACE_MAXADDR,       /* highaddr */
+                              NULL, NULL,              /* filter, filterarg */
+                              MAXBSIZE,                /* maxsize */
+                              sc->aac_sg_tablesize,    /* nsegments */
+                              MAXBSIZE,                /* maxsegsize */
+                              BUS_DMA_ALLOCNOW,        /* flags */
+                              &sc->aac_buffer_dmat)) {
+               device_printf(sc->aac_dev, "can't allocate buffer DMA tag\n");
+               return (ENOMEM);
+       }
+
+       /*
+        * Create DMA tag for mapping FIBs into controller-addressable space..
+        */
+       if (bus_dma_tag_create(sc->aac_parent_dmat,     /* parent */
+                              1, 0,                    /* algnmnt, boundary */
+                              (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
+                              BUS_SPACE_MAXADDR_32BIT :
+                              0x7fffffff,              /* lowaddr */
+                              BUS_SPACE_MAXADDR,       /* highaddr */
+                              NULL, NULL,              /* filter, filterarg */
+                              sc->aac_max_fibs_alloc *
+                              sc->aac_max_fib_size,  /* maxsize */
+                              1,                       /* nsegments */
+                              sc->aac_max_fibs_alloc *
+                              sc->aac_max_fib_size,    /* maxsize */
+                              0,                       /* flags */
+                              &sc->aac_fib_dmat)) {
+               device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n");
+               return (ENOMEM);
        }
+
+       /*
+        * Create DMA tag for the common structure and allocate it.
+        */
+       if (bus_dma_tag_create(sc->aac_parent_dmat,     /* parent */
+                              1, 0,                    /* algnmnt, boundary */
+                              (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
+                              BUS_SPACE_MAXADDR_32BIT :
+                              0x7fffffff,              /* lowaddr */
+                              BUS_SPACE_MAXADDR,       /* highaddr */
+                              NULL, NULL,              /* filter, filterarg */
+                              8192 + sizeof(struct aac_common), /* maxsize */
+                              1,                       /* nsegments */
+                              BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
+                              0,                       /* flags */
+                              &sc->aac_common_dmat)) {
+               device_printf(sc->aac_dev,
+                             "can't allocate common structure DMA tag\n");
+               return (ENOMEM);
+       }
+       if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common,
+                            BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
+               device_printf(sc->aac_dev, "can't allocate common structure\n");
+               return (ENOMEM);
+       }
+
+       /*
+        * Work around a bug in the 2120 and 2200 that cannot DMA commands
+        * below address 8192 in physical memory.
+        * XXX If the padding is not needed, can it be put to use instead
+        * of ignored?
+        */
+       (void)bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
+                       sc->aac_common, 8192 + sizeof(*sc->aac_common),
+                       aac_common_map, sc, 0);
+
+       if (sc->aac_common_busaddr < 8192) {
+               sc->aac_common = (struct aac_common *)
+                   ((uint8_t *)sc->aac_common + 8192);
+               sc->aac_common_busaddr += 8192;
+       }
+       bzero(sc->aac_common, sizeof(*sc->aac_common));
+
+       /* Allocate some FIBs and associated command structs */
+       TAILQ_INIT(&sc->aac_fibmap_tqh);
+       sc->aac_commands = kmalloc(sc->aac_max_fibs * sizeof(struct aac_command),
+                                 M_AACBUF, M_WAITOK|M_ZERO);
+       while (sc->total_fibs < sc->aac_max_fibs) {
+               if (aac_alloc_commands(sc) != 0)
+                       break;
+       }
+       if (sc->total_fibs == 0)
+               return (ENOMEM);
+
+       return (0);
 }
 
 /*
@@ -497,7 +593,7 @@ void
 aac_free(struct aac_softc *sc)
 {
 
-       debug_called(1);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        /* remove the control device */
        if (sc->aac_dev_t != NULL)
@@ -535,10 +631,12 @@ aac_free(struct aac_softc *sc)
                bus_dma_tag_destroy(sc->aac_parent_dmat);
 
        /* release the register window mapping */
-       if (sc->aac_regs_resource != NULL) {
+       if (sc->aac_regs_res0 != NULL)
                bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
-                                    sc->aac_regs_rid, sc->aac_regs_resource);
-       }
+                                    sc->aac_regs_rid0, sc->aac_regs_res0);
+       if (sc->aac_hwif == AAC_HWIF_NARK && sc->aac_regs_res1 != NULL)
+               bus_release_resource(sc->aac_dev, SYS_RES_MEMORY,
+                                    sc->aac_regs_rid1, sc->aac_regs_res1);
        dev_ops_remove_minor(&aac_ops, device_get_unit(sc->aac_dev));
 }
 
@@ -553,14 +651,10 @@ aac_detach(device_t dev)
        struct aac_sim  *sim;
        int error;
 
-       debug_called(1);
-
        sc = device_get_softc(dev);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       callout_stop(&sc->aac_watchdog);
-
-       if (sc->aac_state & AAC_STATE_OPEN)
-               return(EBUSY);
+       callout_stop(&sc->aac_daemontime);
 
        /* Remove the child containers */
        while ((co = TAILQ_FIRST(&sc->aac_container_tqh)) != NULL) {
@@ -587,12 +681,12 @@ aac_detach(device_t dev)
        }
 
        if (sc->aifflags & AAC_AIFFLAGS_RUNNING)
-               panic("Cannot shutdown AIF thread\n");
+               panic("Cannot shutdown AIF thread");
 
        if ((error = aac_shutdown(dev)))
                return(error);
 
-       EVENTHANDLER_DEREGISTER(shutdown_post_sync, sc->eh);
+       EVENTHANDLER_DEREGISTER(shutdown_final, sc->eh);
 
        aac_free(sc);
 
@@ -611,16 +705,15 @@ aac_detach(device_t dev)
  * Note that we can assume that the bioq on the controller is empty, as we won't
  * allow shutdown if any device is open.
  */
-static int
+int
 aac_shutdown(device_t dev)
 {
        struct aac_softc *sc;
        struct aac_fib *fib;
        struct aac_close_command *cc;
 
-       debug_called(1);
-
        sc = device_get_softc(dev);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        sc->aac_state |= AAC_STATE_SUSPEND;
 
@@ -631,7 +724,7 @@ aac_shutdown(device_t dev)
         */
        device_printf(sc->aac_dev, "shutting down controller...");
 
-       AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+       lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
        aac_alloc_sync_fib(sc, &fib);
        cc = (struct aac_close_command *)&fib->data[0];
 
@@ -663,7 +756,7 @@ aac_shutdown(device_t dev)
 
        AAC_MASK_INTERRUPTS(sc);
        aac_release_sync_fib(sc);
-       AAC_LOCK_RELEASE(&sc->aac_io_lock);
+       lockmgr(&sc->aac_io_lock, LK_RELEASE);
 
        return(0);
 }
@@ -676,10 +769,9 @@ aac_suspend(device_t dev)
 {
        struct aac_softc *sc;
 
-       debug_called(1);
-
        sc = device_get_softc(dev);
 
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
        sc->aac_state |= AAC_STATE_SUSPEND;
 
        AAC_MASK_INTERRUPTS(sc);
@@ -694,10 +786,9 @@ aac_resume(device_t dev)
 {
        struct aac_softc *sc;
 
-       debug_called(1);
-
        sc = device_get_softc(dev);
 
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
        sc->aac_state &= ~AAC_STATE_SUSPEND;
        AAC_UNMASK_INTERRUPTS(sc);
        return(0);
@@ -715,11 +806,10 @@ aac_new_intr(void *arg)
        struct aac_fib *fib;
        int i;
 
-       debug_called(2);
-
        sc = (struct aac_softc *)arg;
 
-       AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+       lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
        while (1) {
                index = AAC_GET_OUTB_QUEUE(sc);
                if (index == 0xffffffff)
@@ -738,7 +828,7 @@ aac_new_intr(void *arg)
                                   M_INTWAIT | M_ZERO);
                        index &= ~2;
                        for (i = 0; i < sizeof(struct aac_fib)/4; ++i)
-                               ((u_int32_t *)fib)[i] = AAC_GETREG4(sc, index + i*4);
+                               ((u_int32_t *)fib)[i] = AAC_MEM1_GETREG4(sc, index + i*4);
                        aac_handle_aif(sc, fib);
                        kfree(fib, M_AACBUF);
 
@@ -776,19 +866,21 @@ aac_new_intr(void *arg)
        if ((sc->flags & AAC_QUEUE_FRZN) == 0)
                aac_startio(sc);
 
-       AAC_LOCK_RELEASE(&sc->aac_io_lock);
+       lockmgr(&sc->aac_io_lock, LK_RELEASE);
 }
 
+/*
+ * Interrupt filter for !NEW_COMM interface.
+ */
 void
-aac_fast_intr(void *arg)
+aac_filter(void *arg)
 {
        struct aac_softc *sc;
        u_int16_t reason;
 
-       debug_called(2);
-
        sc = (struct aac_softc *)arg;
 
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
        /*
         * Read the status register directly.  This is faster than taking the
         * driver lock and reading the queues directly.  It also saves having
@@ -814,7 +906,7 @@ aac_fast_intr(void *arg)
 
                /*
                 * This might miss doing the actual wakeup.  However, the
-                * ssleep that this is waking up has a timeout, so it will
+                * lksleep that this is waking up has a timeout, so it will
                 * wake up eventually.  AIFs and printfs are low enough
                 * priority that they can handle hanging out for a few seconds
                 * if needed.
@@ -834,14 +926,19 @@ void
 aac_startio(struct aac_softc *sc)
 {
        struct aac_command *cm;
+       int error;
 
-       debug_called(2);
-
-       if (sc->flags & AAC_QUEUE_FRZN)
-               return;
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        for (;;) {
                /*
+                * This flag might be set if the card is out of resources.
+                * Checking it here prevents an infinite loop of deferrals.
+                */
+               if (sc->flags & AAC_QUEUE_FRZN)
+                       break;
+
+               /*
                 * Try to get a command that's been put off for lack of
                 * resources
                 */
@@ -858,47 +955,30 @@ aac_startio(struct aac_softc *sc)
                if (cm == NULL)
                        break;
 
+               /* don't map more than once */
+               if (cm->cm_flags & AAC_CMD_MAPPED)
+                       panic("aac: command %p already mapped", cm);
+
                /*
-                * Try to give the command to the controller.  Any error is
-                * catastrophic since it means that bus_dmamap_load() failed.
+                * Set up the command to go to the controller.  If there are no
+                * data buffers associated with the command then it can bypass
+                * busdma.
                 */
-               if (aac_map_command(cm) != 0)
-                       panic("aac: error mapping command %p\n", cm);
-       }
-}
-
-/*
- * Deliver a command to the controller; allocate controller resources at the
- * last moment when possible.
- */
-static int
-aac_map_command(struct aac_command *cm)
-{
-       struct aac_softc *sc;
-       int error;
-
-       debug_called(2);
-
-       sc = cm->cm_sc;
-       error = 0;
-
-       /* don't map more than once */
-       if (cm->cm_flags & AAC_CMD_MAPPED)
-               panic("aac: command %p already mapped", cm);
-
-       if (cm->cm_datalen != 0) {
-               error = bus_dmamap_load(sc->aac_buffer_dmat, cm->cm_datamap,
-                                       cm->cm_data, cm->cm_datalen,
-                                       aac_map_command_sg, cm, 0);
-               if (error == EINPROGRESS) {
-                       debug(1, "freezing queue\n");
-                       sc->flags |= AAC_QUEUE_FRZN;
-                       error = 0;
-               }
-       } else {
-               aac_map_command_sg(cm, NULL, 0, 0);
+               if (cm->cm_datalen != 0) {
+                       error = bus_dmamap_load(sc->aac_buffer_dmat,
+                                               cm->cm_datamap, cm->cm_data,
+                                               cm->cm_datalen,
+                                               aac_map_command_sg, cm, 0);
+                       if (error == EINPROGRESS) {
+                               fwprintf(sc, HBA_FLAGS_DBG_COMM_B, "freezing queue\n");
+                               sc->flags |= AAC_QUEUE_FRZN;
+                               error = 0;
+                       } else if (error != 0)
+                               panic("aac_startio: unexpected error %d from "
+                                     "busdma", error);
+               } else
+                       aac_map_command_sg(cm, NULL, 0, 0);
        }
-       return (error);
 }
 
 /*
@@ -912,30 +992,27 @@ aac_command_thread(void *arg)
        u_int32_t fib_size;
        int size, retval;
 
-       get_mplock();
-       debug_called(2);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+       lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
        sc->aifflags = AAC_AIFFLAGS_RUNNING;
 
        while ((sc->aifflags & AAC_AIFFLAGS_EXIT) == 0) {
+
                retval = 0;
-               if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0) {
-                       tsleep_interlock(sc->aifthread, 0);
-                       AAC_LOCK_RELEASE(&sc->aac_io_lock);
-                       retval = tsleep(sc->aifthread, PINTERLOCKED,
+               if ((sc->aifflags & AAC_AIFFLAGS_PENDING) == 0)
+                       retval = lksleep(sc->aifthread, &sc->aac_io_lock, 0,
                                        "aifthd", AAC_PERIODIC_INTERVAL * hz);
-                       AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
-               }
+
                /*
                 * First see if any FIBs need to be allocated.  This needs
                 * to be called without the driver lock because contigmalloc
                 * will grab Giant, and would result in an LOR.
                 */
                if ((sc->aifflags & AAC_AIFFLAGS_ALLOCFIBS) != 0) {
-                       AAC_LOCK_RELEASE(&sc->aac_io_lock);
+                       lockmgr(&sc->aac_io_lock, LK_RELEASE);
                        aac_alloc_commands(sc);
-                       AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+                       lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
                        sc->aifflags &= ~AAC_AIFFLAGS_ALLOCFIBS;
                        aac_startio(sc);
                }
@@ -957,7 +1034,7 @@ aac_command_thread(void *arg)
                        continue;
                for (;;) {
                        if (aac_dequeue_fib(sc, AAC_HOST_NORM_CMD_QUEUE,
-                                           &fib_size, &fib))
+                                          &fib_size, &fib))
                                break;
 
                        AAC_PRINT_FIB(sc, fib);
@@ -1000,10 +1077,8 @@ aac_command_thread(void *arg)
                }
        }
        sc->aifflags &= ~AAC_AIFFLAGS_RUNNING;
-       AAC_LOCK_RELEASE(&sc->aac_io_lock);
+       lockmgr(&sc->aac_io_lock, LK_RELEASE);
        wakeup(sc->aac_dev);
-
-       rel_mplock();
 }
 
 /*
@@ -1017,11 +1092,10 @@ aac_complete(void *context, int pending)
        struct aac_fib *fib;
        u_int32_t fib_size;
 
-       debug_called(2);
-
        sc = (struct aac_softc *)context;
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+       lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
 
        /* pull completed commands off the queue */
        for (;;) {
@@ -1030,14 +1104,20 @@ aac_complete(void *context, int pending)
                                                        &fib))
                        break;  /* nothing to do */
 
-               /* get the command, unmap and queue for later processing */
+               /* get the command, unmap and hand off for processing */
                cm = sc->aac_commands + fib->Header.SenderData;
                if (cm == NULL) {
                        AAC_PRINT_FIB(sc, fib);
                        break;
                }
+               if ((cm->cm_flags & AAC_CMD_TIMEDOUT) != 0)
+                       device_printf(sc->aac_dev,
+                           "COMMAND %p COMPLETED AFTER %d SECONDS\n",
+                           cm, (int)(time_second-cm->cm_timestamp));
+
                aac_remove_busy(cm);
-               aac_unmap_command(cm);          /* XXX defer? */
+
+               aac_unmap_command(cm);
                cm->cm_flags |= AAC_CMD_COMPLETED;
 
                /* is there a completion handler? */
@@ -1053,7 +1133,7 @@ aac_complete(void *context, int pending)
        sc->flags &= ~AAC_QUEUE_FRZN;
        aac_startio(sc);
 
-       AAC_LOCK_RELEASE(&sc->aac_io_lock);
+       lockmgr(&sc->aac_io_lock, LK_RELEASE);
 }
 
 /*
@@ -1064,10 +1144,9 @@ aac_submit_bio(struct aac_disk *ad, struct bio *bio)
 {
        struct aac_softc *sc;
 
-       debug_called(2);
-
        bio->bio_driver_info = ad;
        sc = ad->ad_controller;
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        /* queue the BIO and try to get some work done */
        aac_enqueue_bio(sc, bio);
@@ -1086,7 +1165,7 @@ aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
        struct bio *bio;
        struct buf *bp;
 
-       debug_called(2);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        /* get the resources we will need */
        cm = NULL;
@@ -1103,7 +1182,6 @@ aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
        cm->cm_complete = aac_bio_complete;
        cm->cm_private = bio;
        cm->cm_timestamp = time_second;
-       cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
 
        /* build the FIB */
        fib = cm->cm_fib;
@@ -1175,7 +1253,7 @@ aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
                        br->Pad = 0;
                        br->Flags = 0;
                        fib->Header.Size += sizeof(struct aac_blockread64);
-                       cm->cm_flags |= AAC_CMD_DATAOUT;
+                       cm->cm_flags |= AAC_CMD_DATAIN;
                        cm->cm_sgtable = (struct aac_sg_table *)&br->SgMap64;
                } else {
                        struct aac_blockwrite64 *bw;
@@ -1187,7 +1265,7 @@ aac_bio_command(struct aac_softc *sc, struct aac_command **cmp)
                        bw->Pad = 0;
                        bw->Flags = 0;
                        fib->Header.Size += sizeof(struct aac_blockwrite64);
-                       cm->cm_flags |= AAC_CMD_DATAIN;
+                       cm->cm_flags |= AAC_CMD_DATAOUT;
                        cm->cm_sgtable = (struct aac_sg_table *)&bw->SgMap64;
                }
        }
@@ -1242,104 +1320,6 @@ aac_bio_complete(struct aac_command *cm)
 }
 
 /*
- * Dump a block of data to the controller.  If the queue is full, tell the
- * caller to hold off and wait for the queue to drain.
- */
-int
-aac_dump_enqueue(struct aac_disk *ad, u_int64_t lba, void *data, int dumppages)
-{
-       struct aac_softc *sc;
-       struct aac_command *cm;
-       struct aac_fib *fib;
-       struct aac_blockwrite *bw;
-
-       sc = ad->ad_controller;
-       cm = NULL;
-
-       KKASSERT(lba <= 0x100000000ULL);
-
-       if (aac_alloc_command(sc, &cm))
-               return (EBUSY);
-
-       /* fill out the command */
-       cm->cm_data = data;
-       cm->cm_datalen = dumppages * PAGE_SIZE;
-       cm->cm_complete = NULL;
-       cm->cm_private = NULL;
-       cm->cm_timestamp = time_second;
-       cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
-
-       /* build the FIB */
-       fib = cm->cm_fib;
-       fib->Header.XferState =  
-       AAC_FIBSTATE_HOSTOWNED   | 
-       AAC_FIBSTATE_INITIALISED | 
-       AAC_FIBSTATE_FROMHOST    |
-       AAC_FIBSTATE_REXPECTED   |
-       AAC_FIBSTATE_NORM;
-       fib->Header.Command = ContainerCommand;
-       fib->Header.Size = sizeof(struct aac_fib_header);
-
-       bw = (struct aac_blockwrite *)&fib->data[0];
-       bw->Command = VM_CtBlockWrite;
-       bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
-       bw->BlockNumber = lba;
-       bw->ByteCount = dumppages * PAGE_SIZE;
-       bw->Stable = CUNSTABLE;         /* XXX what's appropriate here? */
-       fib->Header.Size += sizeof(struct aac_blockwrite);
-       cm->cm_flags |= AAC_CMD_DATAOUT;
-       cm->cm_sgtable = &bw->SgMap;
-
-       return (aac_map_command(cm));
-}
-
-/*
- * Wait for the card's queue to drain when dumping.  Also check for monitor
- * kprintf's
- */
-void
-aac_dump_complete(struct aac_softc *sc)
-{
-       struct aac_fib *fib;
-       struct aac_command *cm;
-       u_int16_t reason;
-       u_int32_t pi, ci, fib_size;
-
-       do {
-               reason = AAC_GET_ISTATUS(sc);
-               if (reason & AAC_DB_RESPONSE_READY) {
-                       AAC_CLEAR_ISTATUS(sc, AAC_DB_RESPONSE_READY);
-                       for (;;) {
-                               if (aac_dequeue_fib(sc,
-                                                   AAC_HOST_NORM_RESP_QUEUE,
-                                                   &fib_size, &fib))
-                                       break;
-                               cm = (struct aac_command *)
-                                       fib->Header.SenderData;
-                               if (cm == NULL)
-                                       AAC_PRINT_FIB(sc, fib);
-                               else {
-                                       aac_remove_busy(cm);
-                                       aac_unmap_command(cm);
-                                       aac_enqueue_complete(cm);
-                                       aac_release_command(cm);
-                               }
-                       }
-               }
-               if (reason & AAC_DB_PRINTF) {
-                       AAC_CLEAR_ISTATUS(sc, AAC_DB_PRINTF);
-                       aac_print_printf(sc);
-               }
-               pi = sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][
-                       AAC_PRODUCER_INDEX];
-               ci = sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][        
-                       AAC_CONSUMER_INDEX];
-       } while (ci != pi);
-
-       return;
-}
-
-/*
  * Submit a command to the controller, return when it completes.
  * XXX This is very dangerous!  If the card has gone out to lunch, we could
  *     be stuck here forever.  At the same time, signals are not caught
@@ -1355,20 +1335,13 @@ aac_wait_command(struct aac_command *cm)
        struct aac_softc *sc;
        int error;
 
-       debug_called(2);
-
        sc = cm->cm_sc;
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        /* Put the command on the ready queue and get things going */
-       cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
        aac_enqueue_ready(cm);
        aac_startio(sc);
-       /* Lock is held */
-       KKASSERT(lockstatus(&sc->aac_io_lock, curthread) != 0);
-       tsleep_interlock(cm, 0);
-       AAC_LOCK_RELEASE(&sc->aac_io_lock);
-       error = tsleep(cm, PINTERLOCKED, "aacwait", 0);
-       AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+       error = lksleep(cm, &sc->aac_io_lock, 0, "aacwait", 0);
        return(error);
 }
 
@@ -1384,7 +1357,7 @@ aac_alloc_command(struct aac_softc *sc, struct aac_command **cmp)
 {
        struct aac_command *cm;
 
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        if ((cm = aac_dequeue_free(sc)) == NULL) {
                if (sc->total_fibs < sc->aac_max_fibs) {
@@ -1407,13 +1380,15 @@ aac_release_command(struct aac_command *cm)
        struct aac_event *event;
        struct aac_softc *sc;
 
-       debug_called(3);
+       sc = cm->cm_sc;
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       /* (re)initialise the command/FIB */
+       /* (re)initialize the command/FIB */
        cm->cm_sgtable = NULL;
        cm->cm_flags = 0;
        cm->cm_complete = NULL;
        cm->cm_private = NULL;
+       cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
        cm->cm_fib->Header.XferState = AAC_FIBSTATE_EMPTY;
        cm->cm_fib->Header.StructType = AAC_FIBTYPE_TFIB;
        cm->cm_fib->Header.Flags = 0;
@@ -1422,16 +1397,18 @@ aac_release_command(struct aac_command *cm)
        /*
         * These are duplicated in aac_start to cover the case where an
         * intermediate stage may have destroyed them.  They're left
-        * initialised here for debugging purposes only.
+        * initialized here for debugging purposes only.
         */
        cm->cm_fib->Header.ReceiverFibAddress = (u_int32_t)cm->cm_fibphys;
        cm->cm_fib->Header.SenderData = 0;
 
        aac_enqueue_free(cm);
 
-       sc = cm->cm_sc;
-       event = TAILQ_FIRST(&sc->aac_ev_cmfree);
-       if (event != NULL) {
+       /*
+        * Dequeue all events so that there's no risk of events getting
+        * stranded.
+        */
+       while ((event = TAILQ_FIRST(&sc->aac_ev_cmfree)) != NULL) {
                TAILQ_REMOVE(&sc->aac_ev_cmfree, event, ev_links);
                event->ev_callback(sc, event, event->ev_arg);
        }
@@ -1447,13 +1424,11 @@ aac_map_command_helper(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 
        fibphys = (uint64_t *)arg;
 
-       debug_called(3);
-
        *fibphys = segs[0].ds_addr;
 }
 
 /*
- * Allocate and initialise commands/FIBs for this adapter.
+ * Allocate and initialize commands/FIBs for this adapter.
  */
 static int
 aac_alloc_commands(struct aac_softc *sc)
@@ -1463,7 +1438,7 @@ aac_alloc_commands(struct aac_softc *sc)
        uint64_t fibphys;
        int i, error;
 
-       debug_called(2);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        if (sc->total_fibs + sc->aac_max_fibs_alloc > sc->aac_max_fibs)
                return (ENOMEM);
@@ -1480,11 +1455,11 @@ aac_alloc_commands(struct aac_softc *sc)
        }
 
        /* Ignore errors since this doesn't bounce */
-       bus_dmamap_load(sc->aac_fib_dmat, fm->aac_fibmap, fm->aac_fibs,
-                       sc->aac_max_fibs_alloc * sc->aac_max_fib_size,
-                       aac_map_command_helper, &fibphys, 0);
+       (void)bus_dmamap_load(sc->aac_fib_dmat, fm->aac_fibmap, fm->aac_fibs,
+                             sc->aac_max_fibs_alloc * sc->aac_max_fib_size,
+                             aac_map_command_helper, &fibphys, 0);
 
-       /* initialise constant fields in the command structure */
+       /* initialize constant fields in the command structure */
        bzero(fm->aac_fibs, sc->aac_max_fibs_alloc * sc->aac_max_fib_size);
        for (i = 0; i < sc->aac_max_fibs_alloc; i++) {
                cm = sc->aac_commands + sc->total_fibs;
@@ -1498,17 +1473,17 @@ aac_alloc_commands(struct aac_softc *sc)
                if ((error = bus_dmamap_create(sc->aac_buffer_dmat, 0,
                                               &cm->cm_datamap)) != 0)
                        break;
-               AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+               lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
                aac_release_command(cm);
                sc->total_fibs++;
-               AAC_LOCK_RELEASE(&sc->aac_io_lock);
+               lockmgr(&sc->aac_io_lock, LK_RELEASE);
        }
 
        if (i > 0) {
-               AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+               lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
                TAILQ_INSERT_TAIL(&sc->aac_fibmap_tqh, fm, fm_link);
-               debug(1, "total_fibs= %d\n", sc->total_fibs);
-               AAC_LOCK_RELEASE(&sc->aac_io_lock);
+               fwprintf(sc, HBA_FLAGS_DBG_COMM_B, "total_fibs= %d\n", sc->total_fibs);
+               lockmgr(&sc->aac_io_lock, LK_RELEASE);
                return (0);
        }
 
@@ -1528,7 +1503,7 @@ aac_free_commands(struct aac_softc *sc)
        struct aac_command *cm;
        int i;
 
-       debug_called(1);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        while ((fm = TAILQ_FIRST(&sc->aac_fibmap_tqh)) != NULL) {
 
@@ -1558,11 +1533,10 @@ aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
        struct aac_fib *fib;
        int i;
 
-       debug_called(3);
-
        cm = (struct aac_command *)arg;
        sc = cm->cm_sc;
        fib = cm->cm_fib;
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        /* copy into the FIB */
        if (cm->cm_sgtable != NULL) {
@@ -1628,7 +1602,6 @@ aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
                                aac_unmap_command(cm);
                                sc->flags |= AAC_QUEUE_FRZN;
                                aac_requeue_ready(cm);
-                               break;
                        }
                        DELAY(5);                       /* wait 5 usec. */
                }
@@ -1640,6 +1613,8 @@ aac_map_command_sg(void *arg, bus_dma_segment_t *segs, int nseg, int error)
                        aac_requeue_ready(cm);
                }
        }
+
+       return;
 }
 
 /*
@@ -1650,9 +1625,8 @@ aac_unmap_command(struct aac_command *cm)
 {
        struct aac_softc *sc;
 
-       debug_called(2);
-
        sc = cm->cm_sc;
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        if (!(cm->cm_flags & AAC_CMD_MAPPED))
                return;
@@ -1675,16 +1649,15 @@ aac_unmap_command(struct aac_command *cm)
  */
 
 /*
- * Initialise the adapter.
+ * Initialize the adapter.
  */
 static void
 aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 {
        struct aac_softc *sc;
 
-       debug_called(1);
-
        sc = (struct aac_softc *)arg;
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        sc->aac_common_busaddr = segs[0].ds_addr;
 }
@@ -1692,10 +1665,33 @@ aac_common_map(void *arg, bus_dma_segment_t *segs, int nseg, int error)
 static int
 aac_check_firmware(struct aac_softc *sc)
 {
-       u_int32_t major, minor, options = 0, atu_size = 0;
+       u_int32_t code, major, minor, options = 0, atu_size = 0;
        int status;
+       time_t then;
 
-       debug_called(1);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+       /*
+        * Wait for the adapter to come ready.
+        */
+       then = time_second;
+       do {
+               code = AAC_GET_FWSTATUS(sc);
+               if (code & AAC_SELF_TEST_FAILED) {
+                       device_printf(sc->aac_dev, "FATAL: selftest failed\n");
+                       return(ENXIO);
+               }
+               if (code & AAC_KERNEL_PANIC) {
+                       device_printf(sc->aac_dev,
+                                     "FATAL: controller kernel panic");
+                       return(ENXIO);
+               }
+               if (time_second > (then + AAC_BOOT_TIMEOUT)) {
+                       device_printf(sc->aac_dev,
+                                     "FATAL: controller not coming ready, "
+                                          "status %x\n", code);
+                       return(ENXIO);
+               }
+       } while (!(code & AAC_UP_AND_RUNNING));
 
        /*
         * Retrieve the firmware version numbers.  Dell PERC2/QC cards with
@@ -1759,26 +1755,33 @@ aac_check_firmware(struct aac_softc *sc)
 
        /* Remap mem. resource, if required */
        if ((sc->flags & AAC_FLAGS_NEW_COMM) &&
-               atu_size > rman_get_size(sc->aac_regs_resource)) {
+               atu_size > rman_get_size(sc->aac_regs_res1)) {
                bus_release_resource(
                        sc->aac_dev, SYS_RES_MEMORY,
-                       sc->aac_regs_rid, sc->aac_regs_resource);
-               sc->aac_regs_resource = bus_alloc_resource(
-                       sc->aac_dev, SYS_RES_MEMORY, &sc->aac_regs_rid,
+                       sc->aac_regs_rid1, sc->aac_regs_res1);
+               sc->aac_regs_res1 = bus_alloc_resource(
+                       sc->aac_dev, SYS_RES_MEMORY, &sc->aac_regs_rid1,
                        0ul, ~0ul, atu_size, RF_ACTIVE);
-               if (sc->aac_regs_resource == NULL) {
-                       sc->aac_regs_resource = bus_alloc_resource_any(
+               if (sc->aac_regs_res1 == NULL) {
+                       sc->aac_regs_res1 = bus_alloc_resource_any(
                                sc->aac_dev, SYS_RES_MEMORY,
-                               &sc->aac_regs_rid, RF_ACTIVE);
-                       if (sc->aac_regs_resource == NULL) {
+                               &sc->aac_regs_rid1, RF_ACTIVE);
+                       if (sc->aac_regs_res1 == NULL) {
                                device_printf(sc->aac_dev,
                                    "couldn't allocate register window\n");
                                return (ENXIO);
                        }
                        sc->flags &= ~AAC_FLAGS_NEW_COMM;
                }
-               sc->aac_btag = rman_get_bustag(sc->aac_regs_resource);
-               sc->aac_bhandle = rman_get_bushandle(sc->aac_regs_resource);
+               sc->aac_btag1 = rman_get_bustag(sc->aac_regs_res1);
+               sc->aac_bhandle1 = rman_get_bushandle(sc->aac_regs_res1);
+
+               if (sc->aac_hwif == AAC_HWIF_NARK) {
+                       sc->aac_regs_res0 = sc->aac_regs_res1;
+                       sc->aac_regs_rid0 = sc->aac_regs_rid1;
+                       sc->aac_btag0 = sc->aac_btag1;
+                       sc->aac_bhandle0 = sc->aac_bhandle1;
+               }
        }
 
        /* Read preferred settings */
@@ -1786,14 +1789,12 @@ aac_check_firmware(struct aac_softc *sc)
        sc->aac_max_sectors = 128;                              /* 64KB */
        if (sc->flags & AAC_FLAGS_SG_64BIT)
                sc->aac_sg_tablesize = (AAC_FIB_DATASIZE
-                - sizeof(struct aac_blockwrite64)
-                + sizeof(struct aac_sg_table64))
-                / sizeof(struct aac_sg_table64);
+                - sizeof(struct aac_blockwrite64))
+                / sizeof(struct aac_sg_entry64);
        else
                sc->aac_sg_tablesize = (AAC_FIB_DATASIZE
-                - sizeof(struct aac_blockwrite)
-                + sizeof(struct aac_sg_table))
-                / sizeof(struct aac_sg_table);
+                - sizeof(struct aac_blockwrite))
+                / sizeof(struct aac_sg_entry);
 
        if (!aac_sync_command(sc, AAC_MONKER_GETCOMMPREF, 0, 0, 0, 0, NULL)) {
                options = AAC_GET_MAILBOX(sc, 1);
@@ -1808,6 +1809,16 @@ aac_check_firmware(struct aac_softc *sc)
                sc->aac_max_fib_size = PAGE_SIZE;
        sc->aac_max_fibs_alloc = PAGE_SIZE / sc->aac_max_fib_size;
 
+       if (sc->aac_max_fib_size > sizeof(struct aac_fib)) {
+               sc->flags |= AAC_FLAGS_RAW_IO;
+               device_printf(sc->aac_dev, "Enable Raw I/O\n");
+       }
+       if ((sc->flags & AAC_FLAGS_RAW_IO) &&
+           (sc->flags & AAC_FLAGS_ARRAY_64BIT)) {
+               sc->flags |= AAC_FLAGS_LBA_64BIT;
+               device_printf(sc->aac_dev, "Enable 64-bit array\n");
+       }
+
        return (0);
 }
 
@@ -1815,127 +1826,10 @@ static int
 aac_init(struct aac_softc *sc)
 {
        struct aac_adapter_init *ip;
-       time_t then;
-       u_int32_t code, qoffset;
+       u_int32_t qoffset;
        int error;
 
-       debug_called(1);
-
-       /*
-        * First wait for the adapter to come ready.
-        */
-       then = time_second;
-       do {
-               code = AAC_GET_FWSTATUS(sc);
-               if (code & AAC_SELF_TEST_FAILED) {
-                       device_printf(sc->aac_dev, "FATAL: selftest failed\n");
-                       return(ENXIO);
-               }
-               if (code & AAC_KERNEL_PANIC) {
-                       device_printf(sc->aac_dev,
-                                     "FATAL: controller kernel panic\n");
-                       return(ENXIO);
-               }
-               if (time_second > (then + AAC_BOOT_TIMEOUT)) {
-                       device_printf(sc->aac_dev,
-                                     "FATAL: controller not coming ready, "
-                                          "status %x\n", code);
-                       return(ENXIO);
-               }
-       } while (!(code & AAC_UP_AND_RUNNING));
-
-       error = ENOMEM;
-       /*
-        * Create DMA tag for mapping buffers into controller-addressable space.
-        */
-       if (bus_dma_tag_create(sc->aac_parent_dmat,     /* parent */
-                              1, 0,                    /* algnmnt, boundary */
-                              (sc->flags & AAC_FLAGS_SG_64BIT) ?
-                              BUS_SPACE_MAXADDR :
-                              BUS_SPACE_MAXADDR_32BIT, /* lowaddr */
-                              BUS_SPACE_MAXADDR,       /* highaddr */
-                              NULL, NULL,              /* filter, filterarg */
-                              MAXBSIZE,                /* maxsize */
-                              sc->aac_sg_tablesize,    /* nsegments */
-                              MAXBSIZE,                /* maxsegsize */
-                              BUS_DMA_ALLOCNOW,        /* flags */
-                              &sc->aac_buffer_dmat)) {
-               device_printf(sc->aac_dev, "can't allocate buffer DMA tag\n");
-               goto out;
-       }
-       /*
-        * Create DMA tag for mapping FIBs into controller-addressable space..
-        */
-       if (bus_dma_tag_create(sc->aac_parent_dmat,     /* parent */
-                              1, 0,                    /* algnmnt, boundary */
-                              (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
-                              BUS_SPACE_MAXADDR_32BIT :
-                              0x7fffffff,              /* lowaddr */
-                              BUS_SPACE_MAXADDR,       /* highaddr */
-                              NULL, NULL,              /* filter, filterarg */
-                              sc->aac_max_fibs_alloc *
-                              sc->aac_max_fib_size,    /* maxsize */
-                              1,                       /* nsegments */
-                              sc->aac_max_fibs_alloc *
-                              sc->aac_max_fib_size,    /* maxsegsize */
-                              0,                       /* flags */
-                              &sc->aac_fib_dmat)) {
-               device_printf(sc->aac_dev, "can't allocate FIB DMA tag\n");
-               goto out;
-       }
-       /*
-        * Create DMA tag for the common structure and allocate it.
-        */
-       if (bus_dma_tag_create(sc->aac_parent_dmat,     /* parent */
-                              1, 0,                    /* algnmnt, boundary */
-                              (sc->flags & AAC_FLAGS_4GB_WINDOW) ?
-                              BUS_SPACE_MAXADDR_32BIT :
-                              0x7fffffff,              /* lowaddr */
-                              BUS_SPACE_MAXADDR,       /* highaddr */
-                              NULL, NULL,              /* filter, filterarg */
-                              8192 + sizeof(struct aac_common), /* maxsize */
-                              1,                       /* nsegments */
-                              BUS_SPACE_MAXSIZE_32BIT, /* maxsegsize */
-                              0,                       /* flags */
-                              &sc->aac_common_dmat)) {
-               device_printf(sc->aac_dev,
-                             "can't allocate common structure DMA tag\n");
-               goto out;
-       }
-       if (bus_dmamem_alloc(sc->aac_common_dmat, (void **)&sc->aac_common,
-                            BUS_DMA_NOWAIT, &sc->aac_common_dmamap)) {
-               device_printf(sc->aac_dev, "can't allocate common structure\n");
-               goto out;
-       }
-       /*
-        * Work around a bug in the 2120 and 2200 that cannot DMA commands
-        * below address 8192 in physical memory.
-        * XXX If the padding is not needed, can it be put to use instead
-        * of ignored?
-        */
-       bus_dmamap_load(sc->aac_common_dmat, sc->aac_common_dmamap,
-                       sc->aac_common, 8192 + sizeof(*sc->aac_common),
-                       aac_common_map, sc, 0);
-
-       if (sc->aac_common_busaddr < 8192) {
-               sc->aac_common =
-                   (struct aac_common *)((uint8_t *)sc->aac_common + 8192);
-               sc->aac_common_busaddr += 8192;
-       }
-       bzero(sc->aac_common, sizeof(*sc->aac_common));
-
-       /* Allocate some FIBs and associated command structs */
-       TAILQ_INIT(&sc->aac_fibmap_tqh);
-       sc->aac_commands = kmalloc(sc->aac_max_fibs * sizeof(struct aac_command),
-                                 M_AACBUF, M_INTWAIT | M_ZERO);
-       while (sc->total_fibs < AAC_PREALLOCATE_FIBS) {
-               if (aac_alloc_commands(sc) != 0)
-                       break;
-       }
-       if (sc->total_fibs == 0)
-               goto out;
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        /*
         * Fill in the init structure.  This tells the adapter about the
@@ -1965,8 +1859,7 @@ aac_init(struct aac_softc *sc)
         * therefore 'assuming' that this value is in 16MB units (2^24).
         * Round up since the granularity is so high.
         */
-       /* XXX why should the adapter care? */
-       ip->HostPhysMemPages = ctob((int)Maxmem) / AAC_PAGE_SIZE;
+       ip->HostPhysMemPages = ctob(physmem) / AAC_PAGE_SIZE;
        if (sc->flags & AAC_FLAGS_BROKEN_MEMMAP) {
                ip->HostPhysMemPages =
                    (ip->HostPhysMemPages + AAC_PAGE_SIZE) / AAC_PAGE_SIZE;
@@ -1975,7 +1868,7 @@ aac_init(struct aac_softc *sc)
 
        ip->InitFlags = 0;
        if (sc->flags & AAC_FLAGS_NEW_COMM) {
-               ip->InitFlags INITFLAGS_NEW_COMM_SUPPORTED;
+               ip->InitFlags |= AAC_INITFLAGS_NEW_COMM_SUPPORTED;
                device_printf(sc->aac_dev, "New comm. interface enabled\n");
        }
 
@@ -1984,7 +1877,7 @@ aac_init(struct aac_softc *sc)
        ip->MaxFibSize = sc->aac_max_fib_size;
 
        /*
-        * Initialise FIB queues.  Note that it appears that the layout of the
+        * Initialize FIB queues.  Note that it appears that the layout of the
         * indexes and the segmentation of the entries may be mandated by the
         * adapter, which is only told about the base of the queue index fields.
         *
@@ -2059,10 +1952,10 @@ aac_init(struct aac_softc *sc)
         */
        switch (sc->aac_hwif) {
        case AAC_HWIF_I960RX:
-               AAC_SETREG4(sc, AAC_RX_ODBR, ~0);
+               AAC_MEM0_SETREG4(sc, AAC_RX_ODBR, ~0);
                break;
        case AAC_HWIF_RKT:
-               AAC_SETREG4(sc, AAC_RKT_ODBR, ~0);
+               AAC_MEM0_SETREG4(sc, AAC_RKT_ODBR, ~0);
                break;
        default:
                break;
@@ -2086,6 +1979,36 @@ out:
        return(error);
 }
 
+static int
+aac_setup_intr(struct aac_softc *sc)
+{
+       sc->aac_irq_rid = 0;
+       if ((sc->aac_irq = bus_alloc_resource_any(sc->aac_dev, SYS_RES_IRQ,
+                                                 &sc->aac_irq_rid,
+                                                 RF_SHAREABLE |
+                                                 RF_ACTIVE)) == NULL) {
+               device_printf(sc->aac_dev, "can't allocate interrupt\n");
+               return (EINVAL);
+       }
+       if (sc->flags & AAC_FLAGS_NEW_COMM) {
+               if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
+                                  INTR_MPSAFE,
+                                  aac_new_intr, sc, &sc->aac_intr, NULL)) {
+                       device_printf(sc->aac_dev, "can't set up interrupt\n");
+                       return (EINVAL);
+               }
+       } else {
+               if (bus_setup_intr(sc->aac_dev, sc->aac_irq,
+                                  0, aac_filter,
+                                  sc, &sc->aac_intr, NULL)) {
+                       device_printf(sc->aac_dev,
+                                     "can't set up interrupt filter\n");
+                       return (EINVAL);
+               }
+       }
+       return (0);
+}
+
 /*
  * Send a synchronous command to the controller and wait for a result.
  * Indicate if the controller completed the command with an error status.
@@ -2098,7 +2021,7 @@ aac_sync_command(struct aac_softc *sc, u_int32_t command,
        time_t then;
        u_int32_t status;
 
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        /* populate the mailbox */
        AAC_SET_MAILBOX(sc, command, arg0, arg1, arg2, arg3);
@@ -2113,7 +2036,7 @@ aac_sync_command(struct aac_softc *sc, u_int32_t command,
        then = time_second;
        do {
                if (time_second > (then + AAC_IMMEDIATE_TIMEOUT)) {
-                       debug(1, "timed out");
+                       fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "timed out");
                        return(EIO);
                }
        } while (!(AAC_GET_ISTATUS(sc) & AAC_DB_SYNC_COMMAND));
@@ -2135,8 +2058,10 @@ int
 aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
                 struct aac_fib *fib, u_int16_t datasize)
 {
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+#if 0 /* XXX swildner */
        KKASSERT(lockstatus(&sc->aac_io_lock, curthread) != 0);
+#endif
 
        if (datasize > AAC_FIB_DATASIZE)
                return(EINVAL);
@@ -2150,7 +2075,7 @@ aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
        fib->Header.XferState |= xferstate;
        fib->Header.Command = command;
        fib->Header.StructType = AAC_FIBTYPE_TFIB;
-       fib->Header.Size = sizeof(struct aac_fib) + datasize;
+       fib->Header.Size = sizeof(struct aac_fib_header) + datasize;
        fib->Header.SenderSize = sizeof(struct aac_fib);
        fib->Header.SenderFibAddress = 0;       /* Not needed */
        fib->Header.ReceiverFibAddress = sc->aac_common_busaddr +
@@ -2162,7 +2087,7 @@ aac_sync_fib(struct aac_softc *sc, u_int32_t command, u_int32_t xferstate,
         */
        if (aac_sync_command(sc, AAC_MONKER_SYNCFIB,
                             fib->Header.ReceiverFibAddress, 0, 0, 0, NULL)) {
-               debug(2, "IO error");
+               fwprintf(sc, HBA_FLAGS_DBG_ERROR_B, "IO error");
                return(EIO);
        }
 
@@ -2206,7 +2131,7 @@ aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm)
        u_int32_t fib_size;
        u_int32_t fib_addr;
 
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        fib_size = cm->cm_fib->Header.Size;
        fib_addr = cm->cm_fib->Header.ReceiverFibAddress;
@@ -2224,14 +2149,13 @@ aac_enqueue_fib(struct aac_softc *sc, int queue, struct aac_command *cm)
                error = EBUSY;
                goto out;
        }
+
        /*
         * To avoid a race with its completion interrupt, place this command on
         * the busy queue prior to advertising it to the controller.
         */
        aac_enqueue_busy(cm);
 
-
-
        /* populate queue entry */
        (sc->aac_qentries[queue] + pi)->aq_fib_size = fib_size;
        (sc->aac_qentries[queue] + pi)->aq_fib_addr = fib_addr;
@@ -2262,7 +2186,7 @@ aac_dequeue_fib(struct aac_softc *sc, int queue, u_int32_t *fib_size,
        int error;
        int notify;
 
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        /* get the producer/consumer indices */
        pi = sc->aac_queues->qt_qindex[queue][AAC_PRODUCER_INDEX];
@@ -2357,7 +2281,7 @@ aac_enqueue_response(struct aac_softc *sc, int queue, struct aac_fib *fib)
        u_int32_t fib_size;
        u_int32_t fib_addr;
 
-       debug_called(1);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        /* Tell the adapter where the FIB is */
        fib_size = fib->Header.Size;
@@ -2400,12 +2324,12 @@ out:
  * and complain about them.
  */
 static void
-aac_timeout(void *xsc)
+aac_timeout(struct aac_softc *sc)
 {
-       struct aac_softc *sc = xsc;
        struct aac_command *cm;
        time_t deadline;
        int timedout, code;
+
        /*
         * Traverse the busy command list, bitch about late commands once
         * only.
@@ -2414,23 +2338,25 @@ aac_timeout(void *xsc)
        deadline = time_second - AAC_CMD_TIMEOUT;
        TAILQ_FOREACH(cm, &sc->aac_busy, cm_link) {
                if ((cm->cm_timestamp  < deadline)
-                       /* && !(cm->cm_flags & AAC_CMD_TIMEDOUT) */) {
+                   && !(cm->cm_flags & AAC_CMD_TIMEDOUT)) {
                        cm->cm_flags |= AAC_CMD_TIMEDOUT;
                        device_printf(sc->aac_dev,
-                                     "COMMAND %p TIMEOUT AFTER %d SECONDS\n",
-                                     cm, (int)(time_second-cm->cm_timestamp));
+                           "COMMAND %p (TYPE %d) TIMEOUT AFTER %d SECONDS\n",
+                           cm, cm->cm_fib->Header.Command,
+                           (int)(time_second-cm->cm_timestamp));
                        AAC_PRINT_FIB(sc, cm->cm_fib);
                        timedout++;
                }
        }
+
        if (timedout) {
                code = AAC_GET_FWSTATUS(sc);
                if (code != AAC_UP_AND_RUNNING) {
                        device_printf(sc->aac_dev, "WARNING! Controller is no "
                                      "longer running! code= 0x%x\n", code);
-
                }
        }
+       return;
 }
 
 /*
@@ -2443,36 +2369,27 @@ aac_timeout(void *xsc)
 static int
 aac_sa_get_fwstatus(struct aac_softc *sc)
 {
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       return(AAC_GETREG4(sc, AAC_SA_FWSTATUS));
+       return(AAC_MEM0_GETREG4(sc, AAC_SA_FWSTATUS));
 }
 
 static int
 aac_rx_get_fwstatus(struct aac_softc *sc)
 {
-       debug_called(3);
-
-       return(AAC_GETREG4(sc, AAC_RX_FWSTATUS));
-}
-
-static int
-aac_fa_get_fwstatus(struct aac_softc *sc)
-{
-       int val;
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       debug_called(3);
-
-       val = AAC_GETREG4(sc, AAC_FA_FWSTATUS);
-       return (val);
+       return(AAC_MEM0_GETREG4(sc, sc->flags & AAC_FLAGS_NEW_COMM ?
+           AAC_RX_OMR0 : AAC_RX_FWSTATUS));
 }
 
 static int
 aac_rkt_get_fwstatus(struct aac_softc *sc)
 {
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       return(AAC_GETREG4(sc, AAC_RKT_FWSTATUS));
+       return(AAC_MEM0_GETREG4(sc, sc->flags & AAC_FLAGS_NEW_COMM ?
+           AAC_RKT_OMR0 : AAC_RKT_FWSTATUS));
 }
 
 /*
@@ -2482,34 +2399,25 @@ aac_rkt_get_fwstatus(struct aac_softc *sc)
 static void
 aac_sa_qnotify(struct aac_softc *sc, int qbit)
 {
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       AAC_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
+       AAC_MEM0_SETREG2(sc, AAC_SA_DOORBELL1_SET, qbit);
 }
 
 static void
 aac_rx_qnotify(struct aac_softc *sc, int qbit)
 {
-       debug_called(3);
-
-       AAC_SETREG4(sc, AAC_RX_IDBR, qbit);
-}
-
-static void
-aac_fa_qnotify(struct aac_softc *sc, int qbit)
-{
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       AAC_SETREG2(sc, AAC_FA_DOORBELL1, qbit);
-       AAC_FA_HACK(sc);
+       AAC_MEM0_SETREG4(sc, AAC_RX_IDBR, qbit);
 }
 
 static void
 aac_rkt_qnotify(struct aac_softc *sc, int qbit)
 {
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       AAC_SETREG4(sc, AAC_RKT_IDBR, qbit);
+       AAC_MEM0_SETREG4(sc, AAC_RKT_IDBR, qbit);
 }
 
 /*
@@ -2518,36 +2426,25 @@ aac_rkt_qnotify(struct aac_softc *sc, int qbit)
 static int
 aac_sa_get_istatus(struct aac_softc *sc)
 {
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       return(AAC_GETREG2(sc, AAC_SA_DOORBELL0));
+       return(AAC_MEM0_GETREG2(sc, AAC_SA_DOORBELL0));
 }
 
 static int
 aac_rx_get_istatus(struct aac_softc *sc)
 {
-       debug_called(3);
-
-       return(AAC_GETREG4(sc, AAC_RX_ODBR));
-}
-
-static int
-aac_fa_get_istatus(struct aac_softc *sc)
-{
-       int val;
-
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       val = AAC_GETREG2(sc, AAC_FA_DOORBELL0);
-       return (val);
+       return(AAC_MEM0_GETREG4(sc, AAC_RX_ODBR));
 }
 
 static int
 aac_rkt_get_istatus(struct aac_softc *sc)
 {
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       return(AAC_GETREG4(sc, AAC_RKT_ODBR));
+       return(AAC_MEM0_GETREG4(sc, AAC_RKT_ODBR));
 }
 
 /*
@@ -2556,34 +2453,25 @@ aac_rkt_get_istatus(struct aac_softc *sc)
 static void
 aac_sa_clear_istatus(struct aac_softc *sc, int mask)
 {
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       AAC_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
+       AAC_MEM0_SETREG2(sc, AAC_SA_DOORBELL0_CLEAR, mask);
 }
 
 static void
 aac_rx_clear_istatus(struct aac_softc *sc, int mask)
 {
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       AAC_SETREG4(sc, AAC_RX_ODBR, mask);
-}
-
-static void
-aac_fa_clear_istatus(struct aac_softc *sc, int mask)
-{
-       debug_called(3);
-
-       AAC_SETREG2(sc, AAC_FA_DOORBELL0_CLEAR, mask);
-       AAC_FA_HACK(sc);
+       AAC_MEM0_SETREG4(sc, AAC_RX_ODBR, mask);
 }
 
 static void
 aac_rkt_clear_istatus(struct aac_softc *sc, int mask)
 {
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       AAC_SETREG4(sc, AAC_RKT_ODBR, mask);
+       AAC_MEM0_SETREG4(sc, AAC_RKT_ODBR, mask);
 }
 
 /*
@@ -2593,57 +2481,39 @@ static void
 aac_sa_set_mailbox(struct aac_softc *sc, u_int32_t command,
                u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
 {
-       debug_called(4);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       AAC_SETREG4(sc, AAC_SA_MAILBOX, command);
-       AAC_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
-       AAC_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
-       AAC_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
-       AAC_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
+       AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX, command);
+       AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 4, arg0);
+       AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 8, arg1);
+       AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 12, arg2);
+       AAC_MEM1_SETREG4(sc, AAC_SA_MAILBOX + 16, arg3);
 }
 
 static void
 aac_rx_set_mailbox(struct aac_softc *sc, u_int32_t command,
                u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
 {
-       debug_called(4);
-
-       AAC_SETREG4(sc, AAC_RX_MAILBOX, command);
-       AAC_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
-       AAC_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
-       AAC_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
-       AAC_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
-}
-
-static void
-aac_fa_set_mailbox(struct aac_softc *sc, u_int32_t command,
-               u_int32_t arg0, u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
-{
-       debug_called(4);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       AAC_SETREG4(sc, AAC_FA_MAILBOX, command);
-       AAC_FA_HACK(sc);
-       AAC_SETREG4(sc, AAC_FA_MAILBOX + 4, arg0);
-       AAC_FA_HACK(sc);
-       AAC_SETREG4(sc, AAC_FA_MAILBOX + 8, arg1);
-       AAC_FA_HACK(sc);
-       AAC_SETREG4(sc, AAC_FA_MAILBOX + 12, arg2);
-       AAC_FA_HACK(sc);
-       AAC_SETREG4(sc, AAC_FA_MAILBOX + 16, arg3);
-       AAC_FA_HACK(sc);
+       AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX, command);
+       AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 4, arg0);
+       AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 8, arg1);
+       AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 12, arg2);
+       AAC_MEM1_SETREG4(sc, AAC_RX_MAILBOX + 16, arg3);
 }
 
 static void
 aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
                    u_int32_t arg1, u_int32_t arg2, u_int32_t arg3)
 {
-       debug_called(4);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       AAC_SETREG4(sc, AAC_RKT_MAILBOX, command);
-       AAC_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0);
-       AAC_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1);
-       AAC_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2);
-       AAC_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3);
+       AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX, command);
+       AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 4, arg0);
+       AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 8, arg1);
+       AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 12, arg2);
+       AAC_MEM1_SETREG4(sc, AAC_RKT_MAILBOX + 16, arg3);
 }
 
 /*
@@ -2652,36 +2522,25 @@ aac_rkt_set_mailbox(struct aac_softc *sc, u_int32_t command, u_int32_t arg0,
 static int
 aac_sa_get_mailbox(struct aac_softc *sc, int mb)
 {
-       debug_called(4);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       return(AAC_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4)));
+       return(AAC_MEM1_GETREG4(sc, AAC_SA_MAILBOX + (mb * 4)));
 }
 
 static int
 aac_rx_get_mailbox(struct aac_softc *sc, int mb)
 {
-       debug_called(4);
-
-       return(AAC_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
-}
-
-static int
-aac_fa_get_mailbox(struct aac_softc *sc, int mb)
-{
-       int val;
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       debug_called(4);
-
-       val = AAC_GETREG4(sc, AAC_FA_MAILBOX + (mb * 4));
-       return (val);
+       return(AAC_MEM1_GETREG4(sc, AAC_RX_MAILBOX + (mb * 4)));
 }
 
 static int
 aac_rkt_get_mailbox(struct aac_softc *sc, int mb)
 {
-       debug_called(4);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       return(AAC_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4)));
+       return(AAC_MEM1_GETREG4(sc, AAC_RKT_MAILBOX + (mb * 4)));
 }
 
 /*
@@ -2690,56 +2549,42 @@ aac_rkt_get_mailbox(struct aac_softc *sc, int mb)
 static void
 aac_sa_set_interrupts(struct aac_softc *sc, int enable)
 {
-       debug(2, "%sable interrupts", enable ? "en" : "dis");
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
 
        if (enable) {
-               AAC_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
+               AAC_MEM0_SETREG2((sc), AAC_SA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
        } else {
-               AAC_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
+               AAC_MEM0_SETREG2((sc), AAC_SA_MASK0_SET, ~0);
        }
 }
 
 static void
 aac_rx_set_interrupts(struct aac_softc *sc, int enable)
 {
-       debug(2, "%sable interrupts", enable ? "en" : "dis");
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
 
        if (enable) {
                if (sc->flags & AAC_FLAGS_NEW_COMM)
-                       AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INT_NEW_COMM);
+                       AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INT_NEW_COMM);
                else
-                       AAC_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
-       } else {
-               AAC_SETREG4(sc, AAC_RX_OIMR, ~0);
-       }
-}
-
-static void
-aac_fa_set_interrupts(struct aac_softc *sc, int enable)
-{
-       debug(2, "%sable interrupts", enable ? "en" : "dis");
-
-       if (enable) {
-               AAC_SETREG2((sc), AAC_FA_MASK0_CLEAR, AAC_DB_INTERRUPTS);
-               AAC_FA_HACK(sc);
+                       AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~AAC_DB_INTERRUPTS);
        } else {
-               AAC_SETREG2((sc), AAC_FA_MASK0, ~0);
-               AAC_FA_HACK(sc);
+               AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, ~0);
        }
 }
 
 static void
 aac_rkt_set_interrupts(struct aac_softc *sc, int enable)
 {
-       debug(2, "%sable interrupts", enable ? "en" : "dis");
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "%sable interrupts", enable ? "en" : "dis");
 
        if (enable) {
                if (sc->flags & AAC_FLAGS_NEW_COMM)
-                       AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INT_NEW_COMM);
+                       AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INT_NEW_COMM);
                else
-                       AAC_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
+                       AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~AAC_DB_INTERRUPTS);
        } else {
-               AAC_SETREG4(sc, AAC_RKT_OIMR, ~0);
+               AAC_MEM0_SETREG4(sc, AAC_RKT_OIMR, ~0);
        }
 }
 
@@ -2751,21 +2596,21 @@ aac_rx_send_command(struct aac_softc *sc, struct aac_command *cm)
 {
        u_int32_t index, device;
 
-       debug(2, "send command (new comm.)");
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm.)");
 
-       index = AAC_GETREG4(sc, AAC_RX_IQUE);
+       index = AAC_MEM0_GETREG4(sc, AAC_RX_IQUE);
        if (index == 0xffffffffL)
-               index = AAC_GETREG4(sc, AAC_RX_IQUE);
+               index = AAC_MEM0_GETREG4(sc, AAC_RX_IQUE);
        if (index == 0xffffffffL)
                return index;
        aac_enqueue_busy(cm);
        device = index;
-       AAC_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
+       AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
        device += 4;
-       AAC_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
+       AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
        device += 4;
-       AAC_SETREG4(sc, device, cm->cm_fib->Header.Size);
-       AAC_SETREG4(sc, AAC_RX_IQUE, index);
+       AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size);
+       AAC_MEM0_SETREG4(sc, AAC_RX_IQUE, index);
        return 0;
 }
 
@@ -2774,21 +2619,21 @@ aac_rkt_send_command(struct aac_softc *sc, struct aac_command *cm)
 {
        u_int32_t index, device;
 
-       debug(2, "send command (new comm.)");
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "send command (new comm.)");
 
-       index = AAC_GETREG4(sc, AAC_RKT_IQUE);
+       index = AAC_MEM0_GETREG4(sc, AAC_RKT_IQUE);
        if (index == 0xffffffffL)
-               index = AAC_GETREG4(sc, AAC_RKT_IQUE);
+               index = AAC_MEM0_GETREG4(sc, AAC_RKT_IQUE);
        if (index == 0xffffffffL)
                return index;
        aac_enqueue_busy(cm);
        device = index;
-       AAC_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
+       AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys & 0xffffffffUL));
        device += 4;
-       AAC_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
+       AAC_MEM1_SETREG4(sc, device, (u_int32_t)(cm->cm_fibphys >> 32));
        device += 4;
-       AAC_SETREG4(sc, device, cm->cm_fib->Header.Size);
-       AAC_SETREG4(sc, AAC_RKT_IQUE, index);
+       AAC_MEM1_SETREG4(sc, device, cm->cm_fib->Header.Size);
+       AAC_MEM0_SETREG4(sc, AAC_RKT_IQUE, index);
        return 0;
 }
 
@@ -2798,33 +2643,33 @@ aac_rkt_send_command(struct aac_softc *sc, struct aac_command *cm)
 static int
 aac_rx_get_outb_queue(struct aac_softc *sc)
 {
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       return(AAC_GETREG4(sc, AAC_RX_OQUE));
+       return(AAC_MEM0_GETREG4(sc, AAC_RX_OQUE));
 }
 
 static int
 aac_rkt_get_outb_queue(struct aac_softc *sc)
 {
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       return(AAC_GETREG4(sc, AAC_RKT_OQUE));
+       return(AAC_MEM0_GETREG4(sc, AAC_RKT_OQUE));
 }
 
 static void
 aac_rx_set_outb_queue(struct aac_softc *sc, int index)
 {
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       AAC_SETREG4(sc, AAC_RX_OQUE, index);
+       AAC_MEM0_SETREG4(sc, AAC_RX_OQUE, index);
 }
 
 static void
 aac_rkt_set_outb_queue(struct aac_softc *sc, int index)
 {
-       debug_called(3);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       AAC_SETREG4(sc, AAC_RKT_OQUE, index);
+       AAC_MEM0_SETREG4(sc, AAC_RKT_OQUE, index);
 }
 
 /*
@@ -2839,17 +2684,18 @@ aac_describe_controller(struct aac_softc *sc)
 {
        struct aac_fib *fib;
        struct aac_adapter_info *info;
+       char *adapter_type = "Adaptec RAID controller";
 
-       debug_called(2);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+       lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
        aac_alloc_sync_fib(sc, &fib);
 
        fib->data[0] = 0;
        if (aac_sync_fib(sc, RequestAdapterInfo, 0, fib, 1)) {
                device_printf(sc->aac_dev, "RequestAdapterInfo failed\n");
                aac_release_sync_fib(sc);
-               AAC_LOCK_RELEASE(&sc->aac_io_lock);
+               lockmgr(&sc->aac_io_lock, LK_RELEASE);
                return;
        }
 
@@ -2857,12 +2703,6 @@ aac_describe_controller(struct aac_softc *sc)
        info = (struct aac_adapter_info *)&fib->data[0];
        sc->aac_revision = info->KernelRevision;
 
-       device_printf(sc->aac_dev, "Adaptec Raid Controller %d.%d.%d-%d\n",
-               AAC_DRIVER_VERSION >> 24,
-               (AAC_DRIVER_VERSION >> 16) & 0xFF,
-               AAC_DRIVER_VERSION & 0xFF,
-               AAC_DRIVER_BUILD);
-
        if (bootverbose) {
                device_printf(sc->aac_dev, "%s %dMHz, %dMB memory "
                    "(%dMB cache, %dMB execution), %s\n",
@@ -2904,8 +2744,23 @@ aac_describe_controller(struct aac_softc *sc)
                              "\23ARRAY64BIT"
                              "\24HEATSENSOR");
        }
+
+       if (sc->supported_options & AAC_SUPPORTED_SUPPLEMENT_ADAPTER_INFO) {
+               fib->data[0] = 0;
+               if (aac_sync_fib(sc, RequestSupplementAdapterInfo, 0, fib, 1))
+                       device_printf(sc->aac_dev,
+                           "RequestSupplementAdapterInfo failed\n");
+               else
+                       adapter_type = ((struct aac_supplement_adapter_info *)
+                           &fib->data[0])->AdapterTypeText;
+       }
+       device_printf(sc->aac_dev, "%s, aac driver %d.%d.%d-%d\n",
+               adapter_type,
+               AAC_DRIVER_MAJOR_VERSION, AAC_DRIVER_MINOR_VERSION,
+               AAC_DRIVER_BUGFIX_LEVEL, AAC_DRIVER_BUILD);
+
        aac_release_sync_fib(sc);
-       AAC_LOCK_RELEASE(&sc->aac_io_lock);
+       lockmgr(&sc->aac_io_lock, LK_RELEASE);
 }
 
 /*
@@ -2933,31 +2788,9 @@ aac_open(struct dev_open_args *ap)
        cdev_t dev = ap->a_head.a_dev;
        struct aac_softc *sc;
 
-       debug_called(2);
-
-       sc = dev->si_drv1;
-
-       /* Check to make sure the device isn't already open */
-       if (sc->aac_state & AAC_STATE_OPEN) {
-               return EBUSY;
-       }
-       sc->aac_state |= AAC_STATE_OPEN;
-
-       return 0;
-}
-
-static int
-aac_close(struct dev_close_args *ap)
-{
-       cdev_t dev = ap->a_head.a_dev;
-       struct aac_softc *sc;
-
-       debug_called(2);
-
        sc = dev->si_drv1;
-
-       /* Mark this unit as no longer open  */
-       sc->aac_state &= ~AAC_STATE_OPEN;
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+       device_busy(sc->aac_dev);
 
        return 0;
 }
@@ -2965,23 +2798,24 @@ aac_close(struct dev_close_args *ap)
 static int
 aac_ioctl(struct dev_ioctl_args *ap)
 {
-       cdev_t dev = ap->a_head.a_dev;
        caddr_t arg = ap->a_data;
-       struct aac_softc *sc = dev->si_drv1;
+       cdev_t dev = ap->a_head.a_dev;
+       u_long cmd = ap->a_cmd;
+       union aac_statrequest *as;
+       struct aac_softc *sc;
        int error = 0;
-       uint32_t cookie;
 
-       debug_called(2);
-
-       if (ap->a_cmd == AACIO_STATS) {
-               union aac_statrequest *as = (union aac_statrequest *)arg;
+       as = (union aac_statrequest *)arg;
+       sc = dev->si_drv1;
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
+       switch (cmd) {
+       case AACIO_STATS:
                switch (as->as_item) {
                case AACQ_FREE:
                case AACQ_BIO:
                case AACQ_READY:
                case AACQ_BUSY:
-               case AACQ_COMPLETE:
                        bcopy(&sc->aac_qstat[as->as_item], &as->as_qstat,
                              sizeof(struct aac_qstat));
                        break;
@@ -2989,55 +2823,59 @@ aac_ioctl(struct dev_ioctl_args *ap)
                        error = ENOENT;
                        break;
                }
-               return(error);
-       }
+       break;
 
-       arg = *(caddr_t *)arg;
-
-       switch (ap->a_cmd) {
-       /* AACIO_STATS already handled above */
        case FSACTL_SENDFIB:
-               debug(1, "FSACTL_SENDFIB");
+       case FSACTL_SEND_LARGE_FIB:
+               arg = *(caddr_t*)arg;
+       case FSACTL_LNX_SENDFIB:
+       case FSACTL_LNX_SEND_LARGE_FIB:
+               fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_SENDFIB");
                error = aac_ioctl_sendfib(sc, arg);
                break;
+       case FSACTL_SEND_RAW_SRB:
+               arg = *(caddr_t*)arg;
+       case FSACTL_LNX_SEND_RAW_SRB:
+               fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_SEND_RAW_SRB");
+               error = aac_ioctl_send_raw_srb(sc, arg);
+               break;
        case FSACTL_AIF_THREAD:
-               debug(1, "FSACTL_AIF_THREAD");
+       case FSACTL_LNX_AIF_THREAD:
+               fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_AIF_THREAD");
                error = EINVAL;
                break;
        case FSACTL_OPEN_GET_ADAPTER_FIB:
-               debug(1, "FSACTL_OPEN_GET_ADAPTER_FIB");
-               /*
-                * Pass the caller out an AdapterFibContext.
-                *
-                * Note that because we only support one opener, we
-                * basically ignore this.  Set the caller's context to a magic
-                * number just in case.
-                *
-                * The Linux code hands the driver a pointer into kernel space,
-                * and then trusts it when the caller hands it back.  Aiee!
-                * Here, we give it the proc pointer of the per-adapter aif
-                * thread. It's only used as a sanity check in other calls.
-                */
-               cookie = (uint32_t)(uintptr_t)sc->aifthread;
-               error = copyout(&cookie, arg, sizeof(cookie));
+               arg = *(caddr_t*)arg;
+       case FSACTL_LNX_OPEN_GET_ADAPTER_FIB:
+               fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_OPEN_GET_ADAPTER_FIB");
+               error = aac_open_aif(sc, arg);
                break;
        case FSACTL_GET_NEXT_ADAPTER_FIB:
-               debug(1, "FSACTL_GET_NEXT_ADAPTER_FIB");
+               arg = *(caddr_t*)arg;
+       case FSACTL_LNX_GET_NEXT_ADAPTER_FIB:
+               fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_NEXT_ADAPTER_FIB");
                error = aac_getnext_aif(sc, arg);
                break;
        case FSACTL_CLOSE_GET_ADAPTER_FIB:
-               debug(1, "FSACTL_CLOSE_GET_ADAPTER_FIB");
-               /* don't do anything here */
+               arg = *(caddr_t*)arg;
+       case FSACTL_LNX_CLOSE_GET_ADAPTER_FIB:
+               fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_CLOSE_GET_ADAPTER_FIB");
+               error = aac_close_aif(sc, arg);
                break;
        case FSACTL_MINIPORT_REV_CHECK:
-               debug(1, "FSACTL_MINIPORT_REV_CHECK");
+               arg = *(caddr_t*)arg;
+       case FSACTL_LNX_MINIPORT_REV_CHECK:
+               fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_MINIPORT_REV_CHECK");
                error = aac_rev_check(sc, arg);
                break;
        case FSACTL_QUERY_DISK:
-               debug(1, "FSACTL_QUERY_DISK");
+               arg = *(caddr_t*)arg;
+       case FSACTL_LNX_QUERY_DISK:
+               fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_QUERY_DISK");
                error = aac_query_disk(sc, arg);
                break;
        case FSACTL_DELETE_DISK:
+       case FSACTL_LNX_DELETE_DISK:
                /*
                 * We don't trust the underland to tell us when to delete a
                 * container, rather we rely on an AIF coming from the
@@ -3048,11 +2886,17 @@ aac_ioctl(struct dev_ioctl_args *ap)
        case FSACTL_GET_PCI_INFO:
                arg = *(caddr_t*)arg;
        case FSACTL_LNX_GET_PCI_INFO:
-               debug(1, "FSACTL_GET_PCI_INFO");
+               fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_PCI_INFO");
                error = aac_get_pci_info(sc, arg);
                break;
+       case FSACTL_GET_FEATURES:
+               arg = *(caddr_t*)arg;
+       case FSACTL_LNX_GET_FEATURES:
+               fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "FSACTL_GET_FEATURES");
+               error = aac_supported_features(sc, arg);
+               break;
        default:
-               debug(1, "unsupported cmd 0x%lx\n", ap->a_cmd);
+               fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "unsupported cmd 0x%lx\n", cmd);
                error = EINVAL;
                break;
        }
@@ -3060,7 +2904,7 @@ aac_ioctl(struct dev_ioctl_args *ap)
 }
 
 static struct filterops aac_filterops =
-       { FILTEROP_ISFD, NULL, aac_filter_detach, aac_filter };
+       { FILTEROP_ISFD|FILTEROP_MPSAFE, NULL, aac_filter_detach, aac_filter_read };
 
 static int
 aac_kqfilter(struct dev_kqfilter_args *ap)
@@ -3099,19 +2943,21 @@ aac_filter_detach(struct knote *kn)
 }
 
 static int
-aac_filter(struct knote *kn, long hint)
+aac_filter_read(struct knote *kn, long hint)
 {
-       struct aac_softc *sc = (struct aac_softc *)kn->kn_hook;
-       int ready = 0;
+       struct aac_softc *sc;
+       struct aac_fib_context *ctx;
 
-       AAC_LOCK_ACQUIRE(&sc->aac_aifq_lock);
-       if (sc->aac_aifq_tail != sc->aac_aifq_head)
-               ready = 1;
-       AAC_LOCK_RELEASE(&sc->aac_aifq_lock);
+       sc = (struct aac_softc *)kn->kn_hook;
 
-       return (ready);
-}
+       lockmgr(&sc->aac_aifq_lock, LK_EXCLUSIVE);
+       for (ctx = sc->fibctx; ctx; ctx = ctx->next)
+               if (ctx->ctx_idx != sc->aifq_idx || ctx->ctx_wrap)
+                       return(1);
+       lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
 
+       return (0);
+}
 
 static void
 aac_ioctl_event(struct aac_softc *sc, struct aac_event *event, void *arg)
@@ -3119,15 +2965,13 @@ aac_ioctl_event(struct aac_softc *sc, struct aac_event *event, void *arg)
 
        switch (event->ev_type) {
        case AAC_EVENT_CMFREE:
-               AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+               KKASSERT(lockstatus(&sc->aac_io_lock, curthread) != 0);
                if (aac_alloc_command(sc, (struct aac_command **)arg)) {
                        aac_add_event(sc, event);
-                       AAC_LOCK_RELEASE(&sc->aac_io_lock);
                        return;
                }
                kfree(event, M_AACBUF);
                wakeup(arg);
-               AAC_LOCK_RELEASE(&sc->aac_io_lock);
                break;
        default:
                break;
@@ -3143,14 +2987,14 @@ aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
        struct aac_command *cm;
        int size, error;
 
-       debug_called(2);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        cm = NULL;
 
        /*
         * Get a command
         */
-       AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+       lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
        if (aac_alloc_command(sc, &cm)) {
                struct aac_event *event;
 
@@ -3160,12 +3004,9 @@ aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
                event->ev_callback = aac_ioctl_event;
                event->ev_arg = &cm;
                aac_add_event(sc, event);
-               tsleep_interlock(&cm, 0);
-               AAC_LOCK_RELEASE(&sc->aac_io_lock);
-               tsleep(&cm, PINTERLOCKED, "sendfib", 0);
-               AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+               lksleep(&cm, &sc->aac_io_lock, 0, "sendfib", 0);
        }
-       AAC_LOCK_RELEASE(&sc->aac_io_lock);
+       lockmgr(&sc->aac_io_lock, LK_RELEASE);
 
        /*
         * Fetch the FIB header, then re-copy to get data as well.
@@ -3174,10 +3015,10 @@ aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
                            sizeof(struct aac_fib_header))) != 0)
                goto out;
        size = cm->cm_fib->Header.Size + sizeof(struct aac_fib_header);
-       if (size > sizeof(struct aac_fib)) {
-               device_printf(sc->aac_dev, "incoming FIB oversized (%d > %zd)\n",
-                             size, sizeof(struct aac_fib));
-               size = sizeof(struct aac_fib);
+       if (size > sc->aac_max_fib_size) {
+               device_printf(sc->aac_dev, "incoming FIB oversized (%d > %d)\n",
+                             size, sc->aac_max_fib_size);
+               size = sc->aac_max_fib_size;
        }
        if ((error = copyin(ufib, cm->cm_fib, size)) != 0)
                goto out;
@@ -3187,35 +3028,195 @@ aac_ioctl_sendfib(struct aac_softc *sc, caddr_t ufib)
        /*
         * Pass the FIB to the controller, wait for it to complete.
         */
-       AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
-       if ((error = aac_wait_command(cm)) != 0) {
+       lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
+       error = aac_wait_command(cm);
+       lockmgr(&sc->aac_io_lock, LK_RELEASE);
+       if (error != 0) {
                device_printf(sc->aac_dev,
                              "aac_wait_command return %d\n", error);
                goto out;
        }
-       AAC_LOCK_RELEASE(&sc->aac_io_lock);
 
        /*
         * Copy the FIB and data back out to the caller.
         */
        size = cm->cm_fib->Header.Size;
-       if (size > sizeof(struct aac_fib)) {
-               device_printf(sc->aac_dev, "outbound FIB oversized (%d > %zd)\n",
-                             size, sizeof(struct aac_fib));
-               size = sizeof(struct aac_fib);
+       if (size > sc->aac_max_fib_size) {
+               device_printf(sc->aac_dev, "outbound FIB oversized (%d > %d)\n",
+                             size, sc->aac_max_fib_size);
+               size = sc->aac_max_fib_size;
        }
        error = copyout(cm->cm_fib, ufib, size);
-       AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
 
 out:
        if (cm != NULL) {
+               lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
                aac_release_command(cm);
+               lockmgr(&sc->aac_io_lock, LK_RELEASE);
+       }
+       return(error);
+}
+
+/*
+ * Send a passthrough FIB supplied from userspace
+ */
+static int
+aac_ioctl_send_raw_srb(struct aac_softc *sc, caddr_t arg)
+{
+       struct aac_command *cm;
+       struct aac_event *event;
+       struct aac_fib *fib;
+       struct aac_srb *srbcmd, *user_srb;
+       struct aac_sg_entry *sge;
+       struct aac_sg_entry64 *sge64;
+       void *srb_sg_address, *ureply;
+       uint32_t fibsize, srb_sg_bytecount;
+       int error, transfer_data;
+
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+       cm = NULL;
+       transfer_data = 0;
+       fibsize = 0;
+       user_srb = (struct aac_srb *)arg;
+
+       lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
+       if (aac_alloc_command(sc, &cm)) {
+                event = kmalloc(sizeof(struct aac_event), M_AACBUF,
+                   M_NOWAIT | M_ZERO);
+               if (event == NULL) {
+                       error = EBUSY;
+                       lockmgr(&sc->aac_io_lock, LK_RELEASE);
+                       goto out;
+               }
+               event->ev_type = AAC_EVENT_CMFREE;
+               event->ev_callback = aac_ioctl_event;
+               event->ev_arg = &cm;
+               aac_add_event(sc, event);
+               lksleep(cm, &sc->aac_io_lock, 0, "aacraw", 0);
+       }
+       lockmgr(&sc->aac_io_lock, LK_RELEASE);
+
+       cm->cm_data = NULL;
+       fib = cm->cm_fib;
+       srbcmd = (struct aac_srb *)fib->data;
+       error = copyin(&user_srb->data_len, &fibsize, sizeof(uint32_t));
+       if (error != 0)
+               goto out;
+       if (fibsize > (sc->aac_max_fib_size - sizeof(struct aac_fib_header))) {
+               error = EINVAL;
+               goto out;
+       }
+       error = copyin(user_srb, srbcmd, fibsize);
+       if (error != 0)
+               goto out;
+       srbcmd->function = 0;
+       srbcmd->retry_limit = 0;
+       if (srbcmd->sg_map.SgCount > 1) {
+               error = EINVAL;
+               goto out;
+       }
+
+       /* Retrieve correct SG entries. */
+       if (fibsize == (sizeof(struct aac_srb) +
+           srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry))) {
+               sge = srbcmd->sg_map.SgEntry;
+               sge64 = NULL;
+               srb_sg_bytecount = sge->SgByteCount;
+               srb_sg_address = (void *)(uintptr_t)sge->SgAddress;
+       }
+#ifdef __amd64__
+       else if (fibsize == (sizeof(struct aac_srb) +
+           srbcmd->sg_map.SgCount * sizeof(struct aac_sg_entry64))) {
+               sge = NULL;
+               sge64 = (struct aac_sg_entry64 *)srbcmd->sg_map.SgEntry;
+               srb_sg_bytecount = sge64->SgByteCount;
+               srb_sg_address = (void *)sge64->SgAddress;
+               if (sge64->SgAddress > 0xffffffffull &&
+                   (sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
+                       error = EINVAL;
+                       goto out;
+               }
+       }
+#endif
+       else {
+               error = EINVAL;
+               goto out;
+       }
+       ureply = (char *)arg + fibsize;
+       srbcmd->data_len = srb_sg_bytecount;
+       if (srbcmd->sg_map.SgCount == 1)
+               transfer_data = 1;
+
+       cm->cm_sgtable = (struct aac_sg_table *)&srbcmd->sg_map;
+       if (transfer_data) {
+               cm->cm_datalen = srb_sg_bytecount;
+               cm->cm_data = kmalloc(cm->cm_datalen, M_AACBUF, M_NOWAIT);
+               if (cm->cm_data == NULL) {
+                       error = ENOMEM;
+                       goto out;
+               }
+               if (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN)
+                       cm->cm_flags |= AAC_CMD_DATAIN;
+               if (srbcmd->flags & AAC_SRB_FLAGS_DATA_OUT) {
+                       cm->cm_flags |= AAC_CMD_DATAOUT;
+                       error = copyin(srb_sg_address, cm->cm_data,
+                           cm->cm_datalen);
+                       if (error != 0)
+                               goto out;
+               }
        }
 
-       AAC_LOCK_RELEASE(&sc->aac_io_lock);
+       fib->Header.Size = sizeof(struct aac_fib_header) +
+           sizeof(struct aac_srb);
+       fib->Header.XferState =
+           AAC_FIBSTATE_HOSTOWNED   |
+           AAC_FIBSTATE_INITIALISED |
+           AAC_FIBSTATE_EMPTY       |
+           AAC_FIBSTATE_FROMHOST    |
+           AAC_FIBSTATE_REXPECTED   |
+           AAC_FIBSTATE_NORM        |
+           AAC_FIBSTATE_ASYNC       |
+           AAC_FIBSTATE_FAST_RESPONSE;
+       fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) != 0 ?
+           ScsiPortCommandU64 : ScsiPortCommand;
+
+       lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
+       aac_wait_command(cm);
+       lockmgr(&sc->aac_io_lock, LK_RELEASE);
+
+       if (transfer_data && (srbcmd->flags & AAC_SRB_FLAGS_DATA_IN) != 0) {
+               error = copyout(cm->cm_data, srb_sg_address, cm->cm_datalen);
+               if (error != 0)
+                       goto out;
+       }
+       error = copyout(fib->data, ureply, sizeof(struct aac_srb_response));
+out:
+       if (cm != NULL) {
+               if (cm->cm_data != NULL)
+                       kfree(cm->cm_data, M_AACBUF);
+               lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
+               aac_release_command(cm);
+               lockmgr(&sc->aac_io_lock, LK_RELEASE);
+       }
        return(error);
 }
 
+static int
+aac_close(struct dev_close_args *ap)
+{
+       cdev_t dev = ap->a_head.a_dev;
+       struct aac_softc *sc;
+
+       sc = dev->si_drv1;
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+       get_mplock();
+       device_unbusy(sc->aac_dev);
+       rel_mplock();
+
+       return 0;
+}
+
 /*
  * Handle an AIF sent to us by the controller; queue it for later reference.
  * If the queue fills up, then drop the older entries.
@@ -3225,13 +3226,13 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
 {
        struct aac_aif_command *aif;
        struct aac_container *co, *co_next;
-       struct aac_mntinfo *mi;
-       struct aac_mntinforesp *mir = NULL;
-       u_int16_t rsize;
-       int next, found;
+       struct aac_fib_context *ctx;
+       struct aac_mntinforesp *mir;
+       int next, current, found;
        int count = 0, added = 0, i = 0;
+       uint32_t channel;
 
-       debug_called(2);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        aif = (struct aac_aif_command*)&fib->data[0];
        aac_print_aif(sc, aif);
@@ -3248,7 +3249,6 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
                         * containers and sort things out.
                         */
                        aac_alloc_sync_fib(sc, &fib);
-                       mi = (struct aac_mntinfo *)&fib->data[0];
                        do {
                                /*
                                 * Ask the controller for its containers one at
@@ -3257,22 +3257,10 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
                                 * midway through this enumaration?
                                 * XXX This should be done async.
                                 */
-                               bzero(mi, sizeof(struct aac_mntinfo));
-                               mi->Command = VM_NameServe;
-                               mi->MntType = FT_FILESYS;
-                               mi->MntCount = i;
-                               rsize = sizeof(mir);
-                               if (aac_sync_fib(sc, ContainerCommand, 0, fib,
-                                                sizeof(struct aac_mntinfo))) {
-                                       device_printf(sc->aac_dev,
-                                           "Error probing container %d\n", i);
-
+                               if ((mir = aac_get_container_info(sc, fib, i)) == NULL)
                                        continue;
-                               }
-                               mir = (struct aac_mntinforesp *)&fib->data[0];
-                               /* XXX Need to check if count changed */
-                               count = mir->MntRespCount;
-
+                               if (i == 0)
+                                       count = mir->MntRespCount;
                                /*
                                 * Check the container against our list.
                                 * co->co_found was already set to 0 in a
@@ -3321,19 +3309,17 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
                        co = TAILQ_FIRST(&sc->aac_container_tqh);
                        while (co != NULL) {
                                if (co->co_found == 0) {
-                                       AAC_LOCK_RELEASE(&sc->aac_io_lock);
+                                       lockmgr(&sc->aac_io_lock, LK_RELEASE);
                                        get_mplock();
                                        device_delete_child(sc->aac_dev,
                                                            co->co_disk);
                                        rel_mplock();
-                                       AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+                                       lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
                                        co_next = TAILQ_NEXT(co, co_link);
-                                       AAC_LOCK_ACQUIRE(&sc->
-                                                       aac_container_lock);
+                                       lockmgr(&sc->aac_container_lock, LK_EXCLUSIVE);
                                        TAILQ_REMOVE(&sc->aac_container_tqh, co,
                                                     co_link);
-                                       AAC_LOCK_RELEASE(&sc->
-                                                        aac_container_lock);
+                                       lockmgr(&sc->aac_container_lock, LK_RELEASE);
                                        kfree(co, M_AACBUF);
                                        co = co_next;
                                } else {
@@ -3344,13 +3330,34 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
 
                        /* Attach the newly created containers */
                        if (added) {
-                               AAC_LOCK_RELEASE(&sc->aac_io_lock);
+                               lockmgr(&sc->aac_io_lock, LK_RELEASE);
                                get_mplock();
                                bus_generic_attach(sc->aac_dev);
                                rel_mplock();
-                               AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+                               lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
+                       }
+
+                       break;
+
+               case AifEnEnclosureManagement:
+                       switch (aif->data.EN.data.EEE.eventType) {
+                       case AIF_EM_DRIVE_INSERTION:
+                       case AIF_EM_DRIVE_REMOVAL:
+                               channel = aif->data.EN.data.EEE.unitID;
+                               if (sc->cam_rescan_cb != NULL)
+                                       sc->cam_rescan_cb(sc,
+                                           (channel >> 24) & 0xF,
+                                           (channel & 0xFFFF));
+                               break;
                        }
+                       break;
 
+               case AifEnAddJBOD:
+               case AifEnDeleteJBOD:
+                       channel = aif->data.EN.data.ECE.container;
+                       if (sc->cam_rescan_cb != NULL)
+                               sc->cam_rescan_cb(sc, (channel >> 24) & 0xF,
+                                   AAC_CAM_TARGET_WILDCARD);
                        break;
 
                default:
@@ -3362,21 +3369,30 @@ aac_handle_aif(struct aac_softc *sc, struct aac_fib *fib)
        }
 
        /* Copy the AIF data to the AIF queue for ioctl retrieval */
-       AAC_LOCK_ACQUIRE(&sc->aac_aifq_lock);
-       next = (sc->aac_aifq_head + 1) % AAC_AIFQ_LENGTH;
-       if (next != sc->aac_aifq_tail) {
-               bcopy(aif, &sc->aac_aifq[next], sizeof(struct aac_aif_command));
-               sc->aac_aifq_head = next;
-
-               /* On the off chance that someone is sleeping for an aif... */
-               if (sc->aac_state & AAC_STATE_AIF_SLEEPER)
-                       wakeup(sc->aac_aifq);
-               /* token may have been lost */
-               /* Wakeup any poll()ers */
-               KNOTE(&sc->rcv_kq.ki_note, 0);
-               /* token may have been lost */
-       }
-       AAC_LOCK_RELEASE(&sc->aac_aifq_lock);
+       lockmgr(&sc->aac_aifq_lock, LK_EXCLUSIVE);
+       current = sc->aifq_idx;
+       next = (current + 1) % AAC_AIFQ_LENGTH;
+       if (next == 0)
+               sc->aifq_filled = 1;
+       bcopy(fib, &sc->aac_aifq[current], sizeof(struct aac_fib));
+       /* modify AIF contexts */
+       if (sc->aifq_filled) {
+               for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
+                       if (next == ctx->ctx_idx)
+                               ctx->ctx_wrap = 1;
+                       else if (current == ctx->ctx_idx && ctx->ctx_wrap)
+                               ctx->ctx_idx = next;
+               }
+       }
+       sc->aifq_idx = next;
+       /* On the off chance that someone is sleeping for an aif... */
+       if (sc->aac_state & AAC_STATE_AIF_SLEEPER)
+               wakeup(sc->aac_aifq);
+       /* token may have been lost */
+       /* Wakeup any poll()ers */
+       KNOTE(&sc->rcv_kq.ki_note, 0);
+       /* token may have been lost */
+       lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
 
        return;
 }
@@ -3394,7 +3410,7 @@ aac_rev_check(struct aac_softc *sc, caddr_t udata)
        struct aac_rev_check_resp rev_check_resp;
        int error = 0;
 
-       debug_called(2);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        /*
         * Copyin the revision struct from userspace
@@ -3404,55 +3420,134 @@ aac_rev_check(struct aac_softc *sc, caddr_t udata)
                return error;
        }
 
-       debug(2, "Userland revision= %d\n",
+       fwprintf(sc, HBA_FLAGS_DBG_IOCTL_COMMANDS_B, "Userland revision= %d\n",
              rev_check.callingRevision.buildNumber);
 
        /*
         * Doctor up the response struct.
         */
        rev_check_resp.possiblyCompatible = 1;
-       rev_check_resp.adapterSWRevision.external.ul =
-           sc->aac_revision.external.ul;
+       rev_check_resp.adapterSWRevision.external.comp.major =
+           AAC_DRIVER_MAJOR_VERSION;
+       rev_check_resp.adapterSWRevision.external.comp.minor =
+           AAC_DRIVER_MINOR_VERSION;
+       rev_check_resp.adapterSWRevision.external.comp.type =
+           AAC_DRIVER_TYPE;
+       rev_check_resp.adapterSWRevision.external.comp.dash =
+           AAC_DRIVER_BUGFIX_LEVEL;
        rev_check_resp.adapterSWRevision.buildNumber =
-           sc->aac_revision.buildNumber;
+           AAC_DRIVER_BUILD;
 
        return(copyout((caddr_t)&rev_check_resp, udata,
                        sizeof(struct aac_rev_check_resp)));
 }
 
 /*
+ * Pass the fib context to the caller
+ */
+static int
+aac_open_aif(struct aac_softc *sc, caddr_t arg)
+{
+       struct aac_fib_context *fibctx, *ctx;
+       int error = 0;
+
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+       fibctx = kmalloc(sizeof(struct aac_fib_context), M_AACBUF, M_NOWAIT|M_ZERO);
+       if (fibctx == NULL)
+               return (ENOMEM);
+
+       lockmgr(&sc->aac_aifq_lock, LK_EXCLUSIVE);
+       /* all elements are already 0, add to queue */
+       if (sc->fibctx == NULL)
+               sc->fibctx = fibctx;
+       else {
+               for (ctx = sc->fibctx; ctx->next; ctx = ctx->next)
+                       ;
+               ctx->next = fibctx;
+               fibctx->prev = ctx;
+       }
+
+       /* evaluate unique value */
+       fibctx->unique = (*(u_int32_t *)&fibctx & 0xffffffff);
+       ctx = sc->fibctx;
+       while (ctx != fibctx) {
+               if (ctx->unique == fibctx->unique) {
+                       fibctx->unique++;
+                       ctx = sc->fibctx;
+               } else {
+                       ctx = ctx->next;
+               }
+       }
+       lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
+
+       error = copyout(&fibctx->unique, (void *)arg, sizeof(u_int32_t));
+       if (error)
+               aac_close_aif(sc, (caddr_t)ctx);
+       return error;
+}
+
+/*
+ * Close the caller's fib context
+ */
+static int
+aac_close_aif(struct aac_softc *sc, caddr_t arg)
+{
+       struct aac_fib_context *ctx;
+
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+       lockmgr(&sc->aac_aifq_lock, LK_EXCLUSIVE);
+       for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
+               if (ctx->unique == *(uint32_t *)&arg) {
+                       if (ctx == sc->fibctx)
+                               sc->fibctx = NULL;
+                       else {
+                               ctx->prev->next = ctx->next;
+                               if (ctx->next)
+                                       ctx->next->prev = ctx->prev;
+                       }
+                       break;
+               }
+       }
+       lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
+       if (ctx)
+               kfree(ctx, M_AACBUF);
+
+       return 0;
+}
+
+/*
  * Pass the caller the next AIF in their queue
  */
 static int
 aac_getnext_aif(struct aac_softc *sc, caddr_t arg)
 {
        struct get_adapter_fib_ioctl agf;
+       struct aac_fib_context *ctx;
        int error;
 
-       debug_called(2);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        if ((error = copyin(arg, &agf, sizeof(agf))) == 0) {
-
-               /*
-                * Check the magic number that we gave the caller.
-                */
-               if (agf.AdapterFibContext != (int)(uintptr_t)sc->aifthread) {
-                       error = EFAULT;
-               } else {
-       
-                       error = aac_return_aif(sc, agf.AifFib);
-       
-                       if ((error == EAGAIN) && (agf.Wait)) {
-                               sc->aac_state |= AAC_STATE_AIF_SLEEPER;
-                               while (error == EAGAIN) {
-                                       error = tsleep(sc->aac_aifq,
-                                                      PCATCH, "aacaif", 0);
-                                       if (error == 0)
-                                               error = aac_return_aif(sc,
-                                                   agf.AifFib);
-                               }
-                               sc->aac_state &= ~AAC_STATE_AIF_SLEEPER;
+               for (ctx = sc->fibctx; ctx; ctx = ctx->next) {
+                       if (agf.AdapterFibContext == ctx->unique)
+                               break;
+               }
+               if (!ctx)
+                       return (EFAULT);
+
+               error = aac_return_aif(sc, ctx, agf.AifFib);
+               if (error == EAGAIN && agf.Wait) {
+                       fwprintf(sc, HBA_FLAGS_DBG_AIF_B, "aac_getnext_aif(): waiting for AIF");
+                       sc->aac_state |= AAC_STATE_AIF_SLEEPER;
+                       while (error == EAGAIN) {
+                               error = tsleep(sc->aac_aifq,
+                                              PCATCH, "aacaif", 0);
+                               if (error == 0)
+                                       error = aac_return_aif(sc, ctx, agf.AifFib);
                        }
+                       sc->aac_state &= ~AAC_STATE_AIF_SLEEPER;
                }
        }
        return(error);
@@ -3460,32 +3555,31 @@ aac_getnext_aif(struct aac_softc *sc, caddr_t arg)
 
 /*
  * Hand the next AIF off the top of the queue out to userspace.
- *
- * YYY token could be lost during copyout
  */
 static int
-aac_return_aif(struct aac_softc *sc, caddr_t uptr)
+aac_return_aif(struct aac_softc *sc, struct aac_fib_context *ctx, caddr_t uptr)
 {
-       int next, error;
+       int current, error;
 
-       debug_called(2);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       AAC_LOCK_ACQUIRE(&sc->aac_aifq_lock);
-       if (sc->aac_aifq_tail == sc->aac_aifq_head) {
-               AAC_LOCK_RELEASE(&sc->aac_aifq_lock);
+       lockmgr(&sc->aac_aifq_lock, LK_EXCLUSIVE);
+       current = ctx->ctx_idx;
+       if (current == sc->aifq_idx && !ctx->ctx_wrap) {
+               /* empty */
+               lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
                return (EAGAIN);
        }
-
-       next = (sc->aac_aifq_tail + 1) % AAC_AIFQ_LENGTH;
-       error = copyout(&sc->aac_aifq[next], uptr,
-                       sizeof(struct aac_aif_command));
+       error =
+               copyout(&sc->aac_aifq[current], (void *)uptr, sizeof(struct aac_fib));
        if (error)
                device_printf(sc->aac_dev,
                    "aac_return_aif: copyout returned %d\n", error);
-       else
-               sc->aac_aifq_tail = next;
-
-       AAC_LOCK_RELEASE(&sc->aac_aifq_lock);
+       else {
+               ctx->ctx_wrap = 0;
+               ctx->ctx_idx = (current + 1) % AAC_AIFQ_LENGTH;
+       }
+       lockmgr(&sc->aac_aifq_lock, LK_RELEASE);
        return(error);
 }
 
@@ -3498,7 +3592,7 @@ aac_get_pci_info(struct aac_softc *sc, caddr_t uptr)
        } pciinf;
        int error;
 
-       debug_called(2);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        pciinf.bus = pci_get_bus(sc->aac_dev);
        pciinf.slot = pci_get_slot(sc->aac_dev);
@@ -3509,6 +3603,43 @@ aac_get_pci_info(struct aac_softc *sc, caddr_t uptr)
        return (error);
 }
 
+static int
+aac_supported_features(struct aac_softc *sc, caddr_t uptr)
+{
+       struct aac_features f;
+       int error;
+
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
+
+       if ((error = copyin(uptr, &f, sizeof (f))) != 0)
+               return (error);
+
+       /*
+        * When the management driver receives FSACTL_GET_FEATURES ioctl with
+        * ALL zero in the featuresState, the driver will return the current
+        * state of all the supported features, the data field will not be
+        * valid.
+        * When the management driver receives FSACTL_GET_FEATURES ioctl with
+        * a specific bit set in the featuresState, the driver will return the
+        * current state of this specific feature and whatever data that are
+        * associated with the feature in the data field or perform whatever
+        * action needed indicates in the data field.
+        */
+       if (f.feat.fValue == 0) {
+               f.feat.fBits.largeLBA =
+                   (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
+               /* TODO: In the future, add other features state here as well */
+       } else {
+               if (f.feat.fBits.largeLBA)
+                       f.feat.fBits.largeLBA =
+                           (sc->flags & AAC_FLAGS_LBA_64BIT) ? 1 : 0;
+               /* TODO: Add other features state and data in the future */
+       }
+
+       error = copyout(&f, uptr, sizeof (f));
+       return (error);
+}
+
 /*
  * Give the userland some information about the container.  The AAC arch
  * expects the driver to be a SCSI passthrough type driver, so it expects
@@ -3522,7 +3653,7 @@ aac_query_disk(struct aac_softc *sc, caddr_t uptr)
        struct aac_disk *disk;
        int error, id;
 
-       debug_called(2);
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        disk = NULL;
 
@@ -3535,7 +3666,7 @@ aac_query_disk(struct aac_softc *sc, caddr_t uptr)
        if (id == -1)
                return (EINVAL);
 
-       AAC_LOCK_ACQUIRE(&sc->aac_container_lock);
+       lockmgr(&sc->aac_container_lock, LK_EXCLUSIVE);
        TAILQ_FOREACH(co, &sc->aac_container_tqh, co_link) {
                if (co->co_mntobj.ObjectId == id)
                        break;
@@ -3558,7 +3689,7 @@ aac_query_disk(struct aac_softc *sc, caddr_t uptr)
                bcopy(disk->ad_dev_t->si_name,
                      &query_disk.diskDeviceName[0], 10);
        }
-       AAC_LOCK_RELEASE(&sc->aac_container_lock);
+       lockmgr(&sc->aac_container_lock, LK_RELEASE);
 
        error = copyout((caddr_t)&query_disk, uptr,
                        sizeof(struct aac_query_disk));
@@ -3579,7 +3710,7 @@ aac_get_bus_info(struct aac_softc *sc)
        device_t child;
        int i, found, error;
 
-       AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
+       lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
        aac_alloc_sync_fib(sc, &fib);
        c_cmd = (struct aac_ctcfg *)&fib->data[0];
        bzero(c_cmd, sizeof(struct aac_ctcfg));
@@ -3594,7 +3725,7 @@ aac_get_bus_info(struct aac_softc *sc)
                device_printf(sc->aac_dev, "Error %d sending "
                    "VM_ContainerConfig command\n", error);
                aac_release_sync_fib(sc);
-               AAC_LOCK_RELEASE(&sc->aac_io_lock);
+               lockmgr(&sc->aac_io_lock, LK_RELEASE);
                return;
        }
 
@@ -3603,7 +3734,7 @@ aac_get_bus_info(struct aac_softc *sc)
                device_printf(sc->aac_dev, "VM_ContainerConfig returned 0x%x\n",
                    c_resp->Status);
                aac_release_sync_fib(sc);
-               AAC_LOCK_RELEASE(&sc->aac_io_lock);
+               lockmgr(&sc->aac_io_lock, LK_RELEASE);
                return;
        }
 
@@ -3619,26 +3750,27 @@ aac_get_bus_info(struct aac_softc *sc)
        vmi->IoctlCmd = GetBusInfo;
 
        error = aac_sync_fib(sc, ContainerCommand, 0, fib,
-           sizeof(struct aac_vmioctl));
+           sizeof(struct aac_vmi_businf_resp));
        if (error) {
                device_printf(sc->aac_dev, "Error %d sending VMIoctl command\n",
                    error);
                aac_release_sync_fib(sc);
-               AAC_LOCK_RELEASE(&sc->aac_io_lock);
+               lockmgr(&sc->aac_io_lock, LK_RELEASE);
                return;
        }
 
        vmi_resp = (struct aac_vmi_businf_resp *)&fib->data[0];
        if (vmi_resp->Status != ST_OK) {
-               debug(1, "VM_Ioctl returned %d\n", vmi_resp->Status);
+               device_printf(sc->aac_dev, "VM_Ioctl returned %d\n",
+                   vmi_resp->Status);
                aac_release_sync_fib(sc);
-               AAC_LOCK_RELEASE(&sc->aac_io_lock);
+               lockmgr(&sc->aac_io_lock, LK_RELEASE);
                return;
        }
 
        bcopy(&vmi_resp->BusInf, &businfo, sizeof(struct aac_getbusinf));
        aac_release_sync_fib(sc);
-       AAC_LOCK_RELEASE(&sc->aac_io_lock);
+       lockmgr(&sc->aac_io_lock, LK_RELEASE);
 
        found = 0;
        for (i = 0; i < businfo.BusCount; i++) {
@@ -3655,7 +3787,7 @@ aac_get_bus_info(struct aac_softc *sc)
                            i);
                        kfree(caminf, M_AACBUF);
                        break;
-               };
+               }
 
                caminf->TargetsPerBus = businfo.TargetsPerBus;
                caminf->BusNumber = i;
index da26f25..8537aa2 100644 (file)
@@ -23,8 +23,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     $FreeBSD: src/sys/dev/aac/aac_cam.c,v 1.2.2.4 2003/04/08 13:22:08 scottl Exp $
- *     $DragonFly: src/sys/dev/raid/aac/aac_cam.c,v 1.10 2008/05/18 20:30:23 pavalos Exp $
+ * $FreeBSD: src/sys/dev/aac/aac_cam.c,v 1.40 2010/12/06 17:06:21 jhb Exp $
  */
 
 /*
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/sysctl.h>
+#include <sys/lock.h>
 #include <sys/malloc.h>
 #include <sys/module.h>
 
 #include <bus/cam/cam.h>
 #include <bus/cam/cam_ccb.h>
 #include <bus/cam/cam_debug.h>
+#include <bus/cam/cam_periph.h>
 #include <bus/cam/cam_sim.h>
+#include <bus/cam/cam_xpt_periph.h>
 #include <bus/cam/cam_xpt_sim.h>
 #include <bus/cam/scsi/scsi_all.h>
 #include <bus/cam/scsi/scsi_message.h>
 
 #include <sys/bus.h>
 #include <sys/conf.h>
-#include <sys/devicestat.h>
 #include <sys/disk.h>
-#include <sys/rman.h>
 
 #include <machine/md_var.h>
-
-#include <sys/mplock2.h>
+#include <sys/rman.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
 
-#include "aacreg.h"
-#include "aac_ioctl.h"
-#include "aacvar.h"
+#include <dev/raid/aac/aacreg.h>
+#include <dev/raid/aac/aac_ioctl.h>
+#include <dev/raid/aac/aacvar.h>
 
 struct aac_cam {
        device_t                dev;
@@ -78,6 +77,10 @@ static int aac_cam_detach(device_t dev);
 static void aac_cam_action(struct cam_sim *, union ccb *);
 static void aac_cam_poll(struct cam_sim *);
 static void aac_cam_complete(struct aac_command *);
+static void aac_cam_rescan(struct aac_softc *sc, uint32_t channel,
+    uint32_t target_id);
+static void aac_bus_scan_cb(struct cam_periph *periph, union ccb *ccb);
+
 static u_int32_t aac_cam_reset_bus(struct cam_sim *, union ccb *);
 static u_int32_t aac_cam_abort_ccb(struct cam_sim *, union ccb *);
 static u_int32_t aac_cam_term_io(struct cam_sim *, union ccb *);
@@ -103,15 +106,70 @@ MODULE_DEPEND(aacp, cam, 1, 1, 1);
 MALLOC_DEFINE(M_AACCAM, "aaccam", "AAC CAM info");
 
 static void
+aac_cam_rescan(struct aac_softc *sc, uint32_t channel, uint32_t target_id)
+{
+       union ccb *ccb;
+       struct aac_sim *sim;
+       struct aac_cam *camsc;
+
+       if (target_id == AAC_CAM_TARGET_WILDCARD)
+               target_id = CAM_TARGET_WILDCARD;
+
+       TAILQ_FOREACH(sim, &sc->aac_sim_tqh, sim_link) {
+               camsc = sim->aac_cam;
+               if (camsc == NULL || camsc->inf == NULL ||
+                   camsc->inf->BusNumber != channel)
+                       continue;
+
+               ccb = xpt_alloc_ccb();
+               if (ccb == NULL) {
+                       device_printf(sc->aac_dev,
+                           "Cannot allocate ccb for bus rescan.\n");
+                       return;
+               }
+
+               if (xpt_create_path(&ccb->ccb_h.path, xpt_periph,
+                   cam_sim_path(camsc->sim),
+                   target_id, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
+                       xpt_free_ccb(ccb);
+                       device_printf(sc->aac_dev,
+                           "Cannot create path for bus rescan.\n");
+                       return;
+               }
+               xpt_setup_ccb(&ccb->ccb_h, ccb->ccb_h.path, 5/*priority (low)*/);
+               ccb->ccb_h.func_code = XPT_SCAN_BUS;
+               ccb->ccb_h.cbfcnp = aac_bus_scan_cb;
+               ccb->crcn.flags = CAM_FLAG_NONE;
+               xpt_action(ccb);
+               break;
+       }
+}
+
+static void
+aac_bus_scan_cb(struct cam_periph *periph, union ccb *ccb)
+{
+       if (ccb->ccb_h.status != CAM_REQ_CMP)
+               kprintf("cam_scan_callback: failure status = %x\n",
+                       ccb->ccb_h.status);
+
+       xpt_free_path(ccb->ccb_h.path);
+       kfree(ccb, M_TEMP);
+}
+
+static void
 aac_cam_event(struct aac_softc *sc, struct aac_event *event, void *arg)
 {
+       union ccb *ccb;
        struct aac_cam *camsc;
 
        switch (event->ev_type) {
        case AAC_EVENT_CMFREE:
-               camsc = arg;
+               ccb = arg;
+               camsc = ccb->ccb_h.sim_priv.entries[0].ptr;
                kfree(event, M_AACCAM);
                xpt_release_simq(camsc->sim, 1);
+               ccb->ccb_h.status = CAM_REQUEUE_REQ;
+               xpt_done(ccb);
                break;
        default:
                device_printf(sc->aac_dev, "unknown event %d in aac_cam\n",
@@ -125,7 +183,7 @@ aac_cam_event(struct aac_softc *sc, struct aac_event *event, void *arg)
 static int
 aac_cam_probe(device_t dev)
 {
-       debug_called(2);
+       fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        return (0);
 }
@@ -133,19 +191,24 @@ aac_cam_probe(device_t dev)
 static int
 aac_cam_detach(device_t dev)
 {
+       struct aac_softc *sc;
        struct aac_cam *camsc;
-       debug_called(2);
+       fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        camsc = (struct aac_cam *)device_get_softc(dev);
+       sc = camsc->inf->aac_sc;
+       camsc->inf->aac_cam = NULL;
 
-       get_mplock();
+       lockmgr(&sc->aac_io_lock, LK_EXCLUSIVE);
 
        xpt_async(AC_LOST_DEVICE, camsc->path, NULL);
        xpt_free_path(camsc->path);
        xpt_bus_deregister(cam_sim_path(camsc->sim));
        cam_sim_free(camsc->sim);
 
-       rel_mplock();
+       sc->cam_rescan_cb = NULL;
+
+       lockmgr(&sc->aac_io_lock, LK_RELEASE);
 
        return (0);
 }
@@ -162,26 +225,28 @@ aac_cam_attach(device_t dev)
        struct aac_cam *camsc;
        struct aac_sim *inf;
 
-       debug_called(1);
+       fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        camsc = (struct aac_cam *)device_get_softc(dev);
        inf = (struct aac_sim *)device_get_ivars(dev);
        camsc->inf = inf;
+       camsc->inf->aac_cam = camsc;
 
        devq = cam_simq_alloc(inf->TargetsPerBus);
        if (devq == NULL)
                return (EIO);
 
        sim = cam_sim_alloc(aac_cam_action, aac_cam_poll, "aacp", camsc,
-           device_get_unit(dev), &sim_mplock, 1, 1, devq);
+           device_get_unit(dev), &inf->aac_sc->aac_io_lock, 1, 1, devq);
        cam_simq_release(devq);
-       if (sim == NULL) {
+       if (sim == NULL)
                return (EIO);
-       }
 
        /* Since every bus has it's own sim, every bus 'appears' as bus 0 */
+       lockmgr(&inf->aac_sc->aac_io_lock, LK_EXCLUSIVE);
        if (xpt_bus_register(sim, 0) != CAM_SUCCESS) {
                cam_sim_free(sim);
+               lockmgr(&inf->aac_sc->aac_io_lock, LK_RELEASE);
                return (EIO);
        }
 
@@ -189,8 +254,11 @@ aac_cam_attach(device_t dev)
            CAM_TARGET_WILDCARD, CAM_LUN_WILDCARD) != CAM_REQ_CMP) {
                xpt_bus_deregister(cam_sim_path(sim));
                cam_sim_free(sim);
+               lockmgr(&inf->aac_sc->aac_io_lock, LK_RELEASE);
                return (EIO);
        }
+       inf->aac_sc->cam_rescan_cb = aac_cam_rescan;
+       lockmgr(&inf->aac_sc->aac_io_lock, LK_RELEASE);
 
        camsc->sim = sim;
        camsc->path = path;
@@ -203,14 +271,13 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
 {
        struct  aac_cam *camsc;
        struct  aac_softc *sc;
-       struct  aac_srb32 *srb;
+       struct  aac_srb *srb;
        struct  aac_fib *fib;
        struct  aac_command *cm;
 
-       debug_called(2);
-
        camsc = (struct aac_cam *)cam_sim_softc(sim);
        sc = camsc->inf->aac_sc;
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        /* Synchronous ops, and ops that don't require communication with the
         * controller */
@@ -253,8 +320,11 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
                cpi->hba_inquiry = PI_WIDE_16;
                cpi->target_sprt = 0;
 
-               /* Resetting via the passthrough causes problems. */
-               cpi->hba_misc = PIM_NOBUSRESET;
+               /*
+                * Resetting via the passthrough or parallel bus scan
+                * causes problems.
+                */
+               cpi->hba_misc = PIM_NOBUSRESET | PIM_SEQSCAN;
                cpi->hba_eng_cnt = 0;
                cpi->max_target = camsc->inf->TargetsPerBus;
                cpi->max_lun = 8;       /* Per the controller spec */
@@ -265,10 +335,10 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
                strncpy(cpi->hba_vid, "Adaptec", HBA_IDLEN);
                strncpy(cpi->dev_name, cam_sim_name(sim), DEV_IDLEN);
                cpi->unit_number = cam_sim_unit(sim);
-                cpi->transport = XPORT_SPI;
-                cpi->transport_version = 2;
-                cpi->protocol = PROTO_SCSI;
-                cpi->protocol_version = SCSI_REV_2;
+               cpi->transport = XPORT_SPI;
+               cpi->transport_version = 2;
+               cpi->protocol = PROTO_SCSI;
+               cpi->protocol_version = SCSI_REV_2;
                ccb->ccb_h.status = CAM_REQ_CMP;
                xpt_done(ccb);
                return;
@@ -323,25 +393,23 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
 
        /* Async ops that require communcation with the controller */
 
-       AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
        if (aac_alloc_command(sc, &cm)) {
                struct aac_event *event;
 
                xpt_freeze_simq(sim, 1);
-               ccb->ccb_h.status = CAM_REQUEUE_REQ;
-               xpt_done(ccb);
+               ccb->ccb_h.status = CAM_RESRC_UNAVAIL;
+               ccb->ccb_h.sim_priv.entries[0].ptr = camsc;
                event = kmalloc(sizeof(struct aac_event), M_AACCAM,
                                M_INTWAIT | M_ZERO);
                event->ev_callback = aac_cam_event;
-               event->ev_arg = camsc;
+               event->ev_arg = ccb;
                event->ev_type = AAC_EVENT_CMFREE;
                aac_add_event(sc, event);
-               AAC_LOCK_RELEASE(&sc->aac_io_lock);
                return;
        }
 
        fib = cm->cm_fib;
-       srb = (struct aac_srb32 *)&fib->data[0];
+       srb = (struct aac_srb *)&fib->data[0];
        cm->cm_datalen = 0;
 
        switch (ccb->ccb_h.flags & CAM_DIR_MASK) {
@@ -381,20 +449,21 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
                        bcopy(csio->cdb_io.cdb_bytes, (u_int8_t *)&srb->cdb[0],
                            srb->cdb_len);
 
+               /* Set command */
+               fib->Header.Command = (sc->flags & AAC_FLAGS_SG_64BIT) ?
+                       ScsiPortCommandU64 : ScsiPortCommand;
+
                /* Map the s/g list. XXX 32bit addresses only! */
                if ((ccb->ccb_h.flags & CAM_DIR_MASK) != CAM_DIR_NONE) {
                        if ((ccb->ccb_h.flags & CAM_SCATTER_VALID) == 0) {
                                srb->data_len = csio->dxfer_len;
                                if (ccb->ccb_h.flags & CAM_DATA_PHYS) {
-                                       /*
-                                        * XXX This isn't 64-bit clean.
-                                        * However, this condition is not
-                                        * normally used in CAM.
-                                        */
-                                       srb->sg_map32.SgCount = 1;
-                                       srb->sg_map32.SgEntry[0].SgAddress =
+                                       /* Send a 32bit command */
+                                       fib->Header.Command = ScsiPortCommand;
+                                       srb->sg_map.SgCount = 1;
+                                       srb->sg_map.SgEntry[0].SgAddress =
                                            (uint32_t)(uintptr_t)csio->data_ptr;
-                                       srb->sg_map32.SgEntry[0].SgByteCount =
+                                       srb->sg_map.SgEntry[0].SgByteCount =
                                            csio->dxfer_len;
                                } else {
                                        /*
@@ -403,15 +472,15 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
                                         */
                                        cm->cm_data = (void *)csio->data_ptr;
                                        cm->cm_datalen = csio->dxfer_len;
-                                       cm->cm_sgtable = &srb->sg_map32;
+                                       cm->cm_sgtable = &srb->sg_map;
                                }
                        } else {
                                /* XXX Need to handle multiple s/g elements */
                                panic("aac_cam: multiple s/g elements");
                        }
                } else {
-                       srb->sg_map32.SgCount = 0;
-                       srb->sg_map32.SgEntry[0].SgByteCount = 0;
+                       srb->sg_map.SgCount = 0;
+                       srb->sg_map.SgEntry[0].SgByteCount = 0;
                        srb->data_len = 0;
                }
 
@@ -424,7 +493,6 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
                } else {
                        ccb->ccb_h.status = CAM_REQ_CMP;
                        xpt_done(ccb);
-                       AAC_LOCK_RELEASE(&sc->aac_io_lock);
                        return;
                }
        default:
@@ -440,7 +508,6 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
        cm->cm_complete = aac_cam_complete;
        cm->cm_private = ccb;
        cm->cm_timestamp = time_second;
-       cm->cm_queue = AAC_ADAP_NORM_CMD_QUEUE;
 
        fib->Header.XferState =
            AAC_FIBSTATE_HOSTOWNED      |
@@ -448,15 +515,12 @@ aac_cam_action(struct cam_sim *sim, union ccb *ccb)
            AAC_FIBSTATE_FROMHOST       |
            AAC_FIBSTATE_REXPECTED      |
            AAC_FIBSTATE_NORM;
-       fib->Header.Command = ScsiPortCommand;
        fib->Header.Size = sizeof(struct aac_fib_header) +
-           sizeof(struct aac_srb32);
+           sizeof(struct aac_srb);
 
        aac_enqueue_ready(cm);
        aac_startio(cm->cm_sc);
 
-       AAC_LOCK_RELEASE(&sc->aac_io_lock);
-
        return;
 }
 
@@ -476,9 +540,8 @@ aac_cam_complete(struct aac_command *cm)
        struct  aac_srb_response *srbr;
        struct  aac_softc *sc;
 
-       debug_called(2);
-
        sc = cm->cm_sc;
+       fwprintf(sc, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
        ccb = cm->cm_private;
        srbr = (struct aac_srb_response *)&cm->cm_fib->data[0];
 
@@ -504,14 +567,14 @@ aac_cam_complete(struct aac_command *cm)
 
                                scsi_sense_len = sizeof(struct scsi_sense_data);
                                bzero(&ccb->csio.sense_data, scsi_sense_len);
-                               sense_len = (srbr->sense_len > 
+                               sense_len = (srbr->sense_len >
                                    scsi_sense_len) ? scsi_sense_len :
                                    srbr->sense_len;
                                bcopy(&srbr->sense[0], &ccb->csio.sense_data,
                                    srbr->sense_len);
                                ccb->csio.sense_len = sense_len;
                                ccb->ccb_h.status |= CAM_AUTOSNS_VALID;
-                               /* scsi_sense_print(&ccb->csio); */
+                               // scsi_sense_print(&ccb->csio);
                        }
 
                        /* If this is an inquiry command, fake things out */
@@ -520,8 +583,8 @@ aac_cam_complete(struct aac_command *cm)
                        else
                                command = ccb->csio.cdb_io.cdb_bytes[0];
 
-                       if ((command == INQUIRY) &&
-                           (ccb->ccb_h.status == CAM_REQ_CMP)) {
+                       if (command == INQUIRY) {
+                               if (ccb->ccb_h.status == CAM_REQ_CMP) {
                                device = ccb->csio.data_ptr[0] & 0x1f;
                                /*
                                 * We want DASD and PROC devices to only be
@@ -533,6 +596,11 @@ aac_cam_complete(struct aac_command *cm)
                                        ccb->csio.data_ptr[0] =
                                            ((ccb->csio.data_ptr[0] & 0xe0) |
                                            T_NODEVICE);
+                               } else if (ccb->ccb_h.status == CAM_SEL_TIMEOUT &&
+                                       ccb->ccb_h.target_lun != 0) {
+                                       /* fix for INQUIRYs on Lun>0 */
+                                       ccb->ccb_h.status = CAM_DEV_NOT_THERE;
+                               }
                        }
                }
        }
@@ -557,11 +625,10 @@ aac_cam_reset_bus(struct cam_sim *sim, union ccb *ccb)
        sc = camsc->inf->aac_sc;
 
        if (sc == NULL) {
-               kprintf("Null sc?\n");
+               kprintf("aac: Null sc?\n");
                return (CAM_REQ_ABORTED);
        }
 
-       AAC_LOCK_ACQUIRE(&sc->aac_io_lock);
        aac_alloc_sync_fib(sc, &fib);
 
        vmi = (struct aac_vmioctl *)&fib->data[0];
@@ -582,12 +649,10 @@ aac_cam_reset_bus(struct cam_sim *sim, union ccb *ccb)
                device_printf(sc->aac_dev,"Error %d sending ResetBus command\n",
                    e);
                aac_release_sync_fib(sc);
-               AAC_LOCK_RELEASE(&sc->aac_io_lock);
                return (CAM_REQ_ABORTED);
        }
 
        aac_release_sync_fib(sc);
-       AAC_LOCK_RELEASE(&sc->aac_io_lock);
        return (CAM_REQ_CMP);
 }
 
index ac4209b..7165419 100644 (file)
@@ -26,8 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     $FreeBSD: src/sys/dev/aac/aac_debug.c,v 1.2.2.5 2003/01/11 18:39:39 scottl Exp $
- *     $DragonFly: src/sys/dev/raid/aac/aac_debug.c,v 1.8 2008/01/20 03:40:35 pavalos Exp $
+ * $FreeBSD: src/sys/dev/aac/aac_debug.c,v 1.26 2010/04/13 00:33:07 emaste Exp $
  */
 
 /*
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
+#include <sys/conf.h>
 
 #include <sys/bus.h>
-#include <sys/devicestat.h>
-#include <sys/disk.h>
 
-#include "aacreg.h"
-#include "aac_ioctl.h"
-#include "aacvar.h"
+#include <dev/raid/aac/aacreg.h>
+#include <dev/raid/aac/aac_ioctl.h>
+#include <dev/raid/aac/aacvar.h>
 
 #ifdef AAC_DEBUG
+int    aac_debug_enable = 0;
 void   aac_printstate0(void);
 
-static void    aac_print_queues(struct aac_softc *sc);
-
 /*
  * Dump the command queue indices
  */
@@ -61,66 +58,63 @@ aac_print_queues(struct aac_softc *sc)
        device_printf(sc->aac_dev, "FIB queue header at %p  queues at %p\n",
            &sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][0],
            &sc->aac_queues->qt_HostNormCmdQueue[0]);
-       device_printf(sc->aac_dev, "HOST_NORM_CMD  %d/%d (%d)\n", 
+       device_printf(sc->aac_dev, "HOST_NORM_CMD  %d/%d (%d)\n",
            sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][
                                      AAC_PRODUCER_INDEX],
            sc->aac_queues->qt_qindex[AAC_HOST_NORM_CMD_QUEUE][
-                                     AAC_CONSUMER_INDEX], 
+                                     AAC_CONSUMER_INDEX],
            AAC_HOST_NORM_CMD_ENTRIES);
-       device_printf(sc->aac_dev, "HOST_HIGH_CMD  %d/%d (%d)\n", 
+       device_printf(sc->aac_dev, "HOST_HIGH_CMD  %d/%d (%d)\n",
            sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][
                                      AAC_PRODUCER_INDEX],
            sc->aac_queues->qt_qindex[AAC_HOST_HIGH_CMD_QUEUE][
-                                     AAC_CONSUMER_INDEX], 
+                                     AAC_CONSUMER_INDEX],
            AAC_HOST_HIGH_CMD_ENTRIES);
-       device_printf(sc->aac_dev, "ADAP_NORM_CMD  %d/%d (%d)\n", 
+       device_printf(sc->aac_dev, "ADAP_NORM_CMD  %d/%d (%d)\n",
            sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][
                                      AAC_PRODUCER_INDEX],
            sc->aac_queues->qt_qindex[AAC_ADAP_NORM_CMD_QUEUE][
-                                     AAC_CONSUMER_INDEX], 
+                                     AAC_CONSUMER_INDEX],
            AAC_ADAP_NORM_CMD_ENTRIES);
-       device_printf(sc->aac_dev, "ADAP_HIGH_CMD  %d/%d (%d)\n", 
+       device_printf(sc->aac_dev, "ADAP_HIGH_CMD  %d/%d (%d)\n",
            sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][
                                      AAC_PRODUCER_INDEX],
            sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_CMD_QUEUE][
-                                     AAC_CONSUMER_INDEX], 
+                                     AAC_CONSUMER_INDEX],
            AAC_ADAP_HIGH_CMD_ENTRIES);
-       device_printf(sc->aac_dev, "HOST_NORM_RESP %d/%d (%d)\n", 
+       device_printf(sc->aac_dev, "HOST_NORM_RESP %d/%d (%d)\n",
            sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][
                                      AAC_PRODUCER_INDEX],
            sc->aac_queues->qt_qindex[AAC_HOST_NORM_RESP_QUEUE][
                                      AAC_CONSUMER_INDEX],
            AAC_HOST_NORM_RESP_ENTRIES);
-       device_printf(sc->aac_dev, "HOST_HIGH_RESP %d/%d (%d)\n", 
+       device_printf(sc->aac_dev, "HOST_HIGH_RESP %d/%d (%d)\n",
            sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][
                                      AAC_PRODUCER_INDEX],
            sc->aac_queues->qt_qindex[AAC_HOST_HIGH_RESP_QUEUE][
                                      AAC_CONSUMER_INDEX],
            AAC_HOST_HIGH_RESP_ENTRIES);
-       device_printf(sc->aac_dev, "ADAP_NORM_RESP %d/%d (%d)\n", 
+       device_printf(sc->aac_dev, "ADAP_NORM_RESP %d/%d (%d)\n",
            sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][
                                      AAC_PRODUCER_INDEX],
            sc->aac_queues->qt_qindex[AAC_ADAP_NORM_RESP_QUEUE][
                                      AAC_CONSUMER_INDEX],
            AAC_ADAP_NORM_RESP_ENTRIES);
-       device_printf(sc->aac_dev, "ADAP_HIGH_RESP %d/%d (%d)\n", 
+       device_printf(sc->aac_dev, "ADAP_HIGH_RESP %d/%d (%d)\n",
            sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][
                                      AAC_PRODUCER_INDEX],
            sc->aac_queues->qt_qindex[AAC_ADAP_HIGH_RESP_QUEUE][
                                      AAC_CONSUMER_INDEX],
            AAC_ADAP_HIGH_RESP_ENTRIES);
-       device_printf(sc->aac_dev, "AACQ_FREE      %d/%d\n", 
+       device_printf(sc->aac_dev, "AACQ_FREE      %d/%d\n",
            sc->aac_qstat[AACQ_FREE].q_length, sc->aac_qstat[AACQ_FREE].q_max);
-       device_printf(sc->aac_dev, "AACQ_BIO       %d/%d\n", 
+       device_printf(sc->aac_dev, "AACQ_BIO       %d/%d\n",
            sc->aac_qstat[AACQ_BIO].q_length, sc->aac_qstat[AACQ_BIO].q_max);
-       device_printf(sc->aac_dev, "AACQ_READY     %d/%d\n", 
+       device_printf(sc->aac_dev, "AACQ_READY     %d/%d\n",
            sc->aac_qstat[AACQ_READY].q_length,
            sc->aac_qstat[AACQ_READY].q_max);
-       device_printf(sc->aac_dev, "AACQ_BUSY      %d/%d\n", 
+       device_printf(sc->aac_dev, "AACQ_BUSY      %d/%d\n",
            sc->aac_qstat[AACQ_BUSY].q_length, sc->aac_qstat[AACQ_BUSY].q_max);
-       device_printf(sc->aac_dev, "AACQ_COMPLETE  %d/%d\n", 
-           sc->aac_qstat[AACQ_COMPLETE].q_length,
-           sc->aac_qstat[AACQ_COMPLETE].q_max);
 }
 
 /*
@@ -131,22 +125,23 @@ aac_printstate0(void)
 {
        struct aac_softc *sc;
 
-       sc = devclass_get_softc(aac_devclass, 0);
+       sc = devclass_get_softc(devclass_find("aac"), 0);
 
        aac_print_queues(sc);
        switch (sc->aac_hwif) {
        case AAC_HWIF_I960RX:
+       case AAC_HWIF_NARK:
                device_printf(sc->aac_dev, "IDBR 0x%08x  IIMR 0x%08x  "
-                   "IISR 0x%08x\n", AAC_GETREG4(sc, AAC_RX_IDBR),
-                   AAC_GETREG4(sc, AAC_RX_IIMR), AAC_GETREG4(sc, AAC_RX_IISR));
+                   "IISR 0x%08x\n", AAC_MEM0_GETREG4(sc, AAC_RX_IDBR),
+                   AAC_MEM0_GETREG4(sc, AAC_RX_IIMR), AAC_MEM0_GETREG4(sc, AAC_RX_IISR));
                device_printf(sc->aac_dev, "ODBR 0x%08x  OIMR 0x%08x  "
-                   "OISR 0x%08x\n", AAC_GETREG4(sc, AAC_RX_ODBR),
-                   AAC_GETREG4(sc, AAC_RX_OIMR), AAC_GETREG4(sc, AAC_RX_OISR));
-               AAC_SETREG4(sc, AAC_RX_OIMR, 0/*~(AAC_DB_COMMAND_READY |
+                   "OISR 0x%08x\n", AAC_MEM0_GETREG4(sc, AAC_RX_ODBR),
+                   AAC_MEM0_GETREG4(sc, AAC_RX_OIMR), AAC_MEM0_GETREG4(sc, AAC_RX_OISR));
+               AAC_MEM0_SETREG4(sc, AAC_RX_OIMR, 0/*~(AAC_DB_COMMAND_READY |
                            AAC_DB_RESPONSE_READY | AAC_DB_PRINTF)*/);
                device_printf(sc->aac_dev, "ODBR 0x%08x  OIMR 0x%08x  "
-                   "OISR 0x%08x\n", AAC_GETREG4(sc, AAC_RX_ODBR),
-                   AAC_GETREG4(sc, AAC_RX_OIMR), AAC_GETREG4(sc, AAC_RX_OISR));
+                   "OISR 0x%08x\n", AAC_MEM0_GETREG4(sc, AAC_RX_ODBR),
+                   AAC_MEM0_GETREG4(sc, AAC_RX_OIMR), AAC_MEM0_GETREG4(sc, AAC_RX_OISR));
                break;
        case AAC_HWIF_STRONGARM:
                /* XXX implement */
@@ -155,6 +150,16 @@ aac_printstate0(void)
 }
 
 /*
+ * Panic in a slightly informative fashion
+ */
+void
+aac_panic(struct aac_softc *sc, char *reason)
+{
+       aac_print_queues(sc);
+       panic(reason);
+}
+
+/*
  * Print a FIB
  */
 void
@@ -216,8 +221,8 @@ aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller)
 
                if (br->Command == VM_CtBlockRead) {
                        device_printf(sc->aac_dev,
-                                     "  BlockRead: container %d  0x%x/%d\n", 
-                                     br->ContainerId, br->BlockNumber, 
+                                     "  BlockRead: container %d  0x%x/%d\n",
+                                     br->ContainerId, br->BlockNumber,
                                      br->ByteCount);
                        sg = &br->SgMap;
                }
@@ -225,7 +230,7 @@ aac_print_fib(struct aac_softc *sc, struct aac_fib *fib, const char *caller)
                        device_printf(sc->aac_dev,
                                      "  BlockWrite: container %d  0x%x/%d "
                                      "(%s)\n", bw->ContainerId,
-                                     bw->BlockNumber, bw->ByteCount, 
+                                     bw->BlockNumber, bw->ByteCount,
                                      bw->Stable == CSTABLE ? "stable" :
                                      "unstable");
                        sg = &bw->SgMap;
@@ -258,7 +263,7 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
                device_printf(sc->aac_dev, "EventNotify(%d)\n", aif->seqNumber);
                switch(aif->data.EN.type) {
                case AifEnGeneric:              /* Generic notification */
-                       device_printf(sc->aac_dev, "(Generic) %.*s\n", 
+                       device_printf(sc->aac_dev, "(Generic) %.*s\n",
                                  (int)sizeof(aif->data.EN.data.EG),
                                  aif->data.EN.data.EG.text);
                        break;
@@ -272,21 +277,21 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
                case AifEnContainerChange:      /* Adapter specific container
                                                 * configuration change */
                        device_printf(sc->aac_dev, "(ContainerChange) "
-                                     "container %d,%d\n", 
-                                     aif->data.EN.data.ECC.container[0], 
+                                     "container %d,%d\n",
+                                     aif->data.EN.data.ECC.container[0],
                                      aif->data.EN.data.ECC.container[1]);
                        break;
                case AifEnDeviceFailure:        /* SCSI device failed */
                        device_printf(sc->aac_dev, "(DeviceFailure) "
-                                     "handle %d\n", 
+                                     "handle %d\n",
                                      aif->data.EN.data.EDF.deviceHandle);
                        break;
                case AifEnMirrorFailover:       /* Mirror failover started */
                        device_printf(sc->aac_dev, "(MirrorFailover) "
                                      "container %d failed, "
                                      "migrating from slice %d to %d\n",
-                                     aif->data.EN.data.EMF.container, 
-                                     aif->data.EN.data.EMF.failedSlice, 
+                                     aif->data.EN.data.EMF.container,
+                                     aif->data.EN.data.EMF.failedSlice,
                                      aif->data.EN.data.EMF.creatingSlice);
                        break;
                case AifEnContainerEvent:       /* Significant container
@@ -316,7 +321,7 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
                        device_printf(sc->aac_dev, "(EnclosureManagement) "
                                      "EMPID %d unit %d "
                                      "event %d\n", aif->data.EN.data.EEE.empID,
-                                     aif->data.EN.data.EEE.unitID, 
+                                     aif->data.EN.data.EEE.unitID,
                                      aif->data.EN.data.EEE.eventType);
                        break;
                case AifEnBatteryEvent:         /* Significant NV battery
@@ -339,14 +344,14 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
                        device_printf(sc->aac_dev, "(BatteryNeedsRecond)\n");
                        break;
                case AifEnClusterEvent:         /* Some cluster event */
-                       device_printf(sc->aac_dev, "(ClusterEvent) event %d\n", 
+                       device_printf(sc->aac_dev, "(ClusterEvent) event %d\n",
                                      aif->data.EN.data.ECLE.eventType);
                        break;
                case AifEnDiskSetEvent:         /* A disk set event occured. */
                        device_printf(sc->aac_dev, "(DiskSetEvent) event %d "
                                      "diskset %jd creator %jd\n",
-                                     aif->data.EN.data.EDS.eventType, 
-                                     (intmax_t)aif->data.EN.data.EDS.DsNum, 
+                                     aif->data.EN.data.EDS.eventType,
+                                     (intmax_t)aif->data.EN.data.EDS.DsNum,
                                      (intmax_t)aif->data.EN.data.EDS.CreatorId);
                        break;
                case AifDenMorphComplete:       /* A morph operation
@@ -383,7 +388,7 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
                }               
        
                device_printf(sc->aac_dev, "JobProgress (%d) - %s (%d, %d)\n",
-                             aif->seqNumber, status, 
+                             aif->seqNumber, status,
                              aif->data.PR[0].currentTick,
                              aif->data.PR[0].finalTick);
                switch(aif->data.PR[0].jd.type) {
@@ -409,12 +414,12 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
                        break;
                case AifJobCtrZero:             /* Container clear operation */
                        device_printf(sc->aac_dev,
-                                     "(ContainerZero) container %d\n", 
+                                     "(ContainerZero) container %d\n",
                                      aif->data.PR[0].jd.client.container.src);
                        break;
                case AifJobCtrCopy:             /* Container copy operation */
                        device_printf(sc->aac_dev,
-                                     "(ContainerCopy) container %d to %d\n", 
+                                     "(ContainerCopy) container %d to %d\n",
                                      aif->data.PR[0].jd.client.container.src,
                                      aif->data.PR[0].jd.client.container.dst);
                        break;
@@ -447,12 +452,12 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
                case AifJobCtrScrubRaid5:       /* Container Scrub Raid5
                                                 * operation */
                        device_printf(sc->aac_dev,
-                                     "(ContainerScrubRaid5) container %d\n", 
+                                     "(ContainerScrubRaid5) container %d\n",
                                      aif->data.PR[0].jd.client.container.src);
                        break;
                case AifJobCtrMorph:            /* Container morph operation */
                        device_printf(sc->aac_dev,
-                                     "(ContainerMorph) container %d\n", 
+                                     "(ContainerMorph) container %d\n",
                                      aif->data.PR[0].jd.client.container.src);
                                      /* XXX two containers? */
                        break;
@@ -467,13 +472,13 @@ aac_print_aif(struct aac_softc *sc, struct aac_aif_command *aif)
                case AifJobCtrRebuildMirror:    /* Container Rebuild Mirror
                                                 * operation */
                        device_printf(sc->aac_dev,
-                                     "(ContainerRebuildMirror) container " 
+                                     "(ContainerRebuildMirror) container "
                                      "%d\n",
                                      aif->data.PR[0].jd.client.container.src);
                        break;
                case AifJobCtrCrazyCache:       /* crazy cache */
                        device_printf(sc->aac_dev,
-                                     "(ContainerCrazyCache) container %d\n", 
+                                     "(ContainerCrazyCache) container %d\n",
                                      aif->data.PR[0].jd.client.container.src);
                                      /* XXX two containers? */
                        break;
index 85812d0..f8abf75 100644 (file)
@@ -26,8 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     $FreeBSD: src/sys/dev/aac/aac_disk.c,v 1.3.2.8 2003/01/11 18:39:39 scottl Exp $
- *     $DragonFly: src/sys/dev/raid/aac/aac_disk.c,v 1.20 2008/01/20 03:40:35 pavalos Exp $
+ * $FreeBSD: src/sys/dev/aac/aac_disk.c,v 1.49 2010/09/16 23:33:24 emaste Exp $
  */
 
 #include "opt_aac.h"
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
-#include <sys/sysctl.h>
 
 #include <sys/bus.h>
 #include <sys/conf.h>
-#include <sys/devicestat.h>
 #include <sys/disk.h>
 #include <sys/dtype.h>
-#include <sys/rman.h>
 
 #include <vm/vm.h>
 #include <vm/pmap.h>
 
 #include <machine/md_var.h>
+#include <sys/rman.h>
 
-#include "aacreg.h"
-#include "aac_ioctl.h"
-#include "aacvar.h"
+#include <dev/raid/aac/aacreg.h>
+#include <dev/raid/aac/aac_ioctl.h>
+#include <dev/raid/aac/aacvar.h>
 
 /*
  * Interface to parent.
@@ -69,10 +66,8 @@ static       d_close_t       aac_disk_close;
 static d_strategy_t    aac_disk_strategy;
 static d_dump_t        aac_disk_dump;
 
-#define AAC_DISK_CDEV_MAJOR    151
-
 static struct dev_ops aac_disk_ops = {
-       { "aacd", AAC_DISK_CDEV_MAJOR, D_DISK },
+       { "aacd", 0, D_DISK },
        .d_open =               aac_disk_open,
        .d_close =              aac_disk_close,
        .d_read =               physread,
@@ -96,33 +91,22 @@ static driver_t aac_disk_driver = {
        sizeof(struct aac_disk)
 };
 
-#define AAC_MAXIO      65536
-
 DRIVER_MODULE(aacd, aac, aac_disk_driver, aac_disk_devclass, 0, 0);
 
-/* sysctl tunables */
-static unsigned int aac_iosize_max = AAC_MAXIO;        /* due to limits of the card */
-TUNABLE_INT("hw.aac.iosize_max", &aac_iosize_max);
-
-SYSCTL_DECL(_hw_aac);
-SYSCTL_UINT(_hw_aac, OID_AUTO, iosize_max, CTLFLAG_RD, &aac_iosize_max, 0,
-           "Max I/O size per transfer to an array");
-
 /*
  * Handle open from generic layer.
  *
- * This is called by the diskslice code on first open in order to get the 
+ * This is called by the diskslice code on first open in order to get the
  * basic device geometry paramters.
  */
 static int
 aac_disk_open(struct dev_open_args *ap)
 {
-       cdev_t dev = ap->a_head.a_dev;
        struct aac_disk *sc;
 
-       debug_called(0);
+       fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       sc = (struct aac_disk *)dev->si_drv1;
+       sc = ap->a_head.a_dev->si_drv1;
        
        if (sc == NULL) {
                kprintf("aac_disk_open: No Softc\n");
@@ -131,25 +115,12 @@ aac_disk_open(struct dev_open_args *ap)
 
        /* check that the controller is up and running */
        if (sc->ad_controller->aac_state & AAC_STATE_SUSPEND) {
-               kprintf("Controller Suspended controller state = 0x%x\n",
-                      sc->ad_controller->aac_state);
+               device_printf(sc->ad_controller->aac_dev,
+                   "Controller Suspended controller state = 0x%x\n",
+                   sc->ad_controller->aac_state);
                return(ENXIO);
        }
 
-       /* build synthetic label */
-#if 0
-       bzero(&info, sizeof(info));
-       info.d_media_blksize= AAC_BLOCK_SIZE;           /* mandatory */
-       info.d_media_blocks = sc->ad_size;
-
-       info.d_type = DTYPE_ESDI;                       /* optional */
-       info.d_secpertrack   = sc->ad_sectors;
-       info.d_nheads   = sc->ad_heads;
-       info.d_ncylinders = sc->ad_cylinders;
-       info.d_secpercyl  = sc->ad_sectors * sc->ad_heads;
-
-       disk_setdiskinfo(&sc->ad_disk, &info);
-#endif
        sc->ad_flags |= AAC_DISK_OPEN;
        return (0);
 }
@@ -160,12 +131,11 @@ aac_disk_open(struct dev_open_args *ap)
 static int
 aac_disk_close(struct dev_close_args *ap)
 {
-       cdev_t dev = ap->a_head.a_dev;
        struct aac_disk *sc;
 
-       debug_called(0);
+       fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
-       sc = (struct aac_disk *)dev->si_drv1;
+       sc = ap->a_head.a_dev->si_drv1;
        
        if (sc == NULL)
                return (ENXIO);
@@ -180,120 +150,195 @@ aac_disk_close(struct dev_close_args *ap)
 static int
 aac_disk_strategy(struct dev_strategy_args *ap)
 {
-       cdev_t dev = ap->a_head.a_dev;
        struct bio *bio = ap->a_bio;
        struct buf *bp = bio->bio_buf;
        struct aac_disk *sc;
 
-       debug_called(4);
-
-       sc = (struct aac_disk *)dev->si_drv1;
+       sc = ap->a_head.a_dev->si_drv1;
+       fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        /* bogus disk? */
        if (sc == NULL) {
                bp->b_flags |= B_ERROR;
                bp->b_error = EINVAL;
                biodone(bio);
-               return(0);
+               return (0);
        }
 
        /* do-nothing operation? */
        if (bp->b_bcount == 0) {
                bp->b_resid = bp->b_bcount;
                biodone(bio);
-               return(0);
+               return (0);
        }
 
        /* perform accounting */
 
        /* pass the bio to the controller - it can work out who we are */
-       AAC_LOCK_ACQUIRE(&sc->ad_controller->aac_io_lock);
+       lockmgr(&sc->ad_controller->aac_io_lock, LK_EXCLUSIVE);
        devstat_start_transaction(&sc->ad_stats);
        aac_submit_bio(sc, bio);
-       AAC_LOCK_RELEASE(&sc->ad_controller->aac_io_lock);
+       lockmgr(&sc->ad_controller->aac_io_lock, LK_RELEASE);
 
-       return(0);
+       return (0);
+}
+
+/*
+ * Map the S/G elements for doing a dump.
+ */
+static void
+aac_dump_map_sg(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+{
+       struct aac_fib *fib;
+       struct aac_blockwrite *bw;
+       struct aac_sg_table *sg;
+       int i;
+
+       fib = (struct aac_fib *)arg;
+       bw = (struct aac_blockwrite *)&fib->data[0];
+       sg = &bw->SgMap;
+
+       if (sg != NULL) {
+               sg->SgCount = nsegs;
+               for (i = 0; i < nsegs; i++) {
+                       if (segs[i].ds_addr >= BUS_SPACE_MAXADDR_32BIT)
+                               return;
+                       sg->SgEntry[i].SgAddress = segs[i].ds_addr;
+                       sg->SgEntry[i].SgByteCount = segs[i].ds_len;
+               }
+               fib->Header.Size = nsegs * sizeof(struct aac_sg_entry);
+       }
+}
+
+/*
+ * Map the S/G elements for doing a dump on 64-bit capable devices.
+ */
+static void
+aac_dump_map_sg64(void *arg, bus_dma_segment_t *segs, int nsegs, int error)
+{
+       struct aac_fib *fib;
+       struct aac_blockwrite64 *bw;
+       struct aac_sg_table64 *sg;
+       int i;
+
+       fib = (struct aac_fib *)arg;
+       bw = (struct aac_blockwrite64 *)&fib->data[0];
+       sg = &bw->SgMap64;
+
+       if (sg != NULL) {
+               sg->SgCount = nsegs;
+               for (i = 0; i < nsegs; i++) {
+                       sg->SgEntry64[i].SgAddress = segs[i].ds_addr;
+                       sg->SgEntry64[i].SgByteCount = segs[i].ds_len;
+               }
+               fib->Header.Size = nsegs * sizeof(struct aac_sg_entry64);
+       }
 }
 
 /*
  * Dump memory out to an array
  *
- * This queues blocks of memory of size AAC_MAXIO to the controller and waits
- * for the controller to complete the requests.
+ * Send out one command at a time with up to maxio of data.
  */
 static int
 aac_disk_dump(struct dev_dump_args *ap)
 {
-       kprintf("dumps on aac are currently broken, not dumping\n");
-       return (ENXIO);
-#if 0
        cdev_t dev = ap->a_head.a_dev;
+       size_t length = ap->a_length;
+       off_t offset = ap->a_offset;
+       void *virtual = ap->a_virtual;
+       vm_offset_t physical = ap->a_physical;
        struct aac_disk *ad;
        struct aac_softc *sc;
-       vm_offset_t addr;
-       long blkcnt;
-       int dumppages;
-       int i, error;
+       struct aac_fib *fib;
+       size_t len, maxio;
+       int size;
+       static bus_dmamap_t dump_datamap;
+       static int first = 0;
+       bus_dmamap_callback_t *callback;
+       u_int32_t command;
 
        ad = dev->si_drv1;
-       addr = 0;
-       dumppages = AAC_MAXIO / PAGE_SIZE;
 
        if (ad == NULL)
-               return (ENXIO);
+               return (EINVAL);
 
        sc= ad->ad_controller;
 
-       blkcnt = howmany(PAGE_SIZE, ap->a_secsize);
-
-       while (ap->a_count > 0) {
-               caddr_t va = NULL;
-
-               if ((ap->a_count / blkcnt) < dumppages)
-                       dumppages = ap->a_count / blkcnt;
+       if (!first) {
+               first = 1;
+               if (bus_dmamap_create(sc->aac_buffer_dmat, 0, &dump_datamap)) {
+                       device_printf(sc->aac_dev,
+                           "bus_dmamap_create failed\n");
+                       return (ENOMEM);
+               }
+       }
 
-               for (i = 0; i < dumppages; ++i) {
-                       vm_offset_t a = addr + (i * PAGE_SIZE);
-                       if (is_physical_memory(a)) {
-                               va = pmap_kenter_temporary(trunc_page(a), i);
-                       } else {
-                               va = pmap_kenter_temporary(trunc_page(0), i);
-                       }
+       /* Skip aac_alloc_sync_fib().  We don't want to mess with sleep locks */
+       fib = &sc->aac_common->ac_sync_fib;
+
+       while (length > 0) {
+               maxio = sc->aac_max_sectors << 9;
+               len = (length > maxio) ? maxio : length;
+               if ((sc->flags & AAC_FLAGS_SG_64BIT) == 0) {
+                       struct aac_blockwrite *bw;
+                       bw = (struct aac_blockwrite *)&fib->data[0];
+                       bw->Command = VM_CtBlockWrite;
+                       bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
+                       bw->BlockNumber = offset / AAC_BLOCK_SIZE;
+                       bw->ByteCount = len;
+                       bw->Stable = CUNSTABLE;
+                       command = ContainerCommand;
+                       callback = aac_dump_map_sg;
+                       size = sizeof(struct aac_blockwrite);
+               } else {
+                       struct aac_blockwrite64 *bw;
+                       bw = (struct aac_blockwrite64 *)&fib->data[0];
+                       bw->Command = VM_CtHostWrite64;
+                       bw->ContainerId = ad->ad_container->co_mntobj.ObjectId;
+                       bw->BlockNumber = offset / AAC_BLOCK_SIZE;
+                       bw->SectorCount = len / AAC_BLOCK_SIZE;
+                       bw->Pad = 0;
+                       bw->Flags = 0;
+                       command = ContainerCommand64;
+                       callback = aac_dump_map_sg64;
+                       size = sizeof(struct aac_blockwrite64);
                }
 
-retry:
                /*
-                * Queue the block to the controller.  If the queue is full,
-                * EBUSY will be returned.
+                * There really isn't any way to recover from errors or
+                * resource shortages here.  Oh well.  Because of that, don't
+                * bother trying to send the command from the callback; there
+                * is too much required context.
                 */
-               error = aac_dump_enqueue(ad, ap->a_blkno, va, dumppages);
-               if (error && (error != EBUSY))
-                       return (error);
-
-               if (!error) {
-                       if (dumpstatus(addr, (off_t)(ap->a_count * DEV_BSIZE)) < 0)
-                       return (EINTR);
-
-                       ap->a_blkno += blkcnt * dumppages;
-                       ap->a_count -= blkcnt * dumppages;
-                       addr += PAGE_SIZE * dumppages;
-                       if (ap->a_count > 0)
-                       continue;
+               if (bus_dmamap_load(sc->aac_buffer_dmat, dump_datamap, virtual,
+                   len, callback, fib, BUS_DMA_NOWAIT) != 0)
+                       return (ENOMEM);
+
+               bus_dmamap_sync(sc->aac_buffer_dmat, dump_datamap,
+                   BUS_DMASYNC_PREWRITE);
+
+               /* fib->Header.Size is set in aac_dump_map_sg */
+               size += fib->Header.Size;
+
+               if (aac_sync_fib(sc, command, 0, fib, size)) {
+                       device_printf(sc->aac_dev,
+                            "Error dumping block 0x%jx\n",
+                            (uintmax_t)physical);
+                       return (EIO);
                }
 
-               /*
-                * Either the queue was full on the last attemp, or we have no
-                * more data to dump.  Let the queue drain out and retry the
-                * block if the queue was full.
-                */
-               aac_dump_complete(sc);
+               bus_dmamap_sync(sc->aac_buffer_dmat, dump_datamap,
+                   BUS_DMASYNC_POSTWRITE);
+
+               bus_dmamap_unload(sc->aac_buffer_dmat, dump_datamap);
 
-               if (error == EBUSY)
-                       goto retry;
+               length -= len;
+               offset += len;
+               virtual = (uint8_t *)virtual + len;
        }
 
        return (0);
-#endif
 }
 
 /*
@@ -305,15 +350,15 @@ aac_biodone(struct bio *bio, const char *code)
        struct buf *bp = bio->bio_buf;
        struct aac_disk *sc;
 
-       debug_called(4);
-
        sc = (struct aac_disk *)bio->bio_driver_info;
+       fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        devstat_end_transaction_buf(&sc->ad_stats, bp);
        if (bp->b_flags & B_ERROR) {
                diskerr(bio, sc->ad_dev_t,
                        code, 0, 0);
        }
+
        biodone(bio);
 }
 
@@ -324,7 +369,7 @@ static int
 aac_disk_probe(device_t dev)
 {
 
-       debug_called(2);
+       fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        return (0);
 }
@@ -338,9 +383,8 @@ aac_disk_attach(device_t dev)
        struct disk_info info;
        struct aac_disk *sc;
        
-       debug_called(0);
-
        sc = (struct aac_disk *)device_get_softc(dev);
+       fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        /* initialise our softc */
        sc->ad_controller =
@@ -353,6 +397,9 @@ aac_disk_attach(device_t dev)
         * disk!
         */
        sc->ad_size = sc->ad_container->co_mntobj.Capacity;
+       if (sc->ad_controller->flags & AAC_FLAGS_LBA_64BIT)
+               sc->ad_size += (u_int64_t)
+                       sc->ad_container->co_mntobj.CapacityHigh << 32;
        if (sc->ad_size >= (2 * 1024 * 1024)) {         /* 2GB */
                sc->ad_heads = 255;
                sc->ad_sectors = 63;
@@ -365,10 +412,9 @@ aac_disk_attach(device_t dev)
        }
        sc->ad_cylinders = (sc->ad_size / (sc->ad_heads * sc->ad_sectors));
 
-       device_printf(dev, "%uMB (%u sectors)\n",
-                     sc->ad_size / ((1024 * 1024) / AAC_BLOCK_SIZE),
-                     sc->ad_size);
-
+       device_printf(dev, "%juMB (%ju sectors)\n",
+                     (intmax_t)sc->ad_size / ((1024 * 1024) / AAC_BLOCK_SIZE),
+                     (intmax_t)sc->ad_size);
        devstat_add_entry(&sc->ad_stats, "aacd", device_get_unit(dev),
                          AAC_BLOCK_SIZE, DEVSTAT_NO_ORDERED_TAGS,
                          DEVSTAT_TYPE_STORARRAY | DEVSTAT_TYPE_IF_OTHER, 
@@ -379,7 +425,7 @@ aac_disk_attach(device_t dev)
                                   &aac_disk_ops);
        sc->ad_dev_t->si_drv1 = sc;
 
-       sc->ad_dev_t->si_iosize_max = aac_iosize_max;
+       sc->ad_dev_t->si_iosize_max = sc->ad_controller->aac_max_sectors << 9;
        sc->unit = device_get_unit(dev);
 
        /*
@@ -409,14 +455,14 @@ aac_disk_detach(device_t dev)
 {
        struct aac_disk *sc;
 
-       debug_called(2);
-
        sc = (struct aac_disk *)device_get_softc(dev);
+       fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        if (sc->ad_flags & AAC_DISK_OPEN)
                return(EBUSY);
 
        devstat_remove_entry(&sc->ad_stats);
        disk_destroy(&sc->ad_disk);
+
        return(0);
 }
index a2456ea..1c83a81 100644 (file)
@@ -25,8 +25,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     $FreeBSD: src/sys/dev/aac/aac_ioctl.h,v 1.2.2.2 2001/09/19 19:09:11 scottl Exp $
- *     $DragonFly: src/sys/dev/raid/aac/aac_ioctl.h,v 1.2 2003/06/17 04:28:21 dillon Exp $
+ *     $FreeBSD: src/sys/sys/aac_ioctl.h,v 1.14 2009/10/29 17:21:41 emaste Exp $
  */
 
 #include <sys/ioccom.h>
@@ -38,8 +37,7 @@
 #define AACQ_BIO       1
 #define AACQ_READY     2
 #define AACQ_BUSY      3
-#define AACQ_COMPLETE  4
-#define AACQ_COUNT     5       /* total number of queues */
+#define AACQ_COUNT     4       /* total number of queues */
 
 struct aac_qstat {
        u_int32_t       q_length;
@@ -73,6 +71,8 @@ union aac_statrequest {
 
 #define FSACTL_LNX_SENDFIB             CTL_CODE(FILE_DEVICE_CONTROLLER, 2050, \
                                        METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define FSACTL_LNX_SEND_RAW_SRB                CTL_CODE(FILE_DEVICE_CONTROLLER, 2067, \
+                                       METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define FSACTL_LNX_GET_COMM_PERF_DATA  CTL_CODE(FILE_DEVICE_CONTROLLER, 2084, \
                                        METHOD_BUFFERED, FILE_ANY_ACCESS)
 #define FSACTL_LNX_OPENCLS_COMM_PERF_DATA CTL_CODE(FILE_DEVICE_CONTROLLER, \
@@ -97,6 +97,10 @@ union aac_statrequest {
                                        METHOD_NEITHER, FILE_ANY_ACCESS)
 #define FSACTL_LNX_AIF_THREAD          CTL_CODE(FILE_DEVICE_CONTROLLER, 2127, \
                                        METHOD_NEITHER, FILE_ANY_ACCESS)
+#define FSACTL_LNX_SEND_LARGE_FIB      CTL_CODE(FILE_DEVICE_CONTROLLER, 2138, \
+                                       METHOD_BUFFERED, FILE_ANY_ACCESS)
+#define        FSACTL_LNX_GET_FEATURES         CTL_CODE(FILE_DEVICE_CONTROLLER, 2139, \
+                                       METHOD_BUFFERED, FILE_ANY_ACCESS)
 
 /* Why these don't follow the previous convention, I don't know */
 #define FSACTL_LNX_NULL_IO_TEST                0x43
@@ -120,6 +124,7 @@ union aac_statrequest {
  * command number.  9 is used for the odd overflow case.
  */
 #define FSACTL_SENDFIB                 _IO('8', 2)
+#define FSACTL_SEND_RAW_SRB            _IO('8', 19)
 #define FSACTL_GET_COMM_PERF_DATA      _IO('8', 36)
 #define FSACTL_OPENCLS_COMM_PERF_DATA  _IO('8', 37)
 #define FSACTL_OPEN_GET_ADAPTER_FIB    _IO('8', 52)
@@ -132,6 +137,8 @@ union aac_statrequest {
 #define FSACTL_GET_PCI_INFO            _IO('8', 71)
 #define FSACTL_FORCE_DELETE_DISK       _IO('8', 72)
 #define FSACTL_AIF_THREAD              _IO('8', 79)
+#define FSACTL_SEND_LARGE_FIB          _IO('8', 90)
+#define        FSACTL_GET_FEATURES             _IO('8', 91)
 
 #define FSACTL_NULL_IO_TEST            _IO('8', 67)
 #define FSACTL_SIM_IO_TEST             _IO('8', 83)
@@ -145,7 +152,7 @@ union aac_statrequest {
 
 #define FSACTL_PROBE_CONTAINERS                _IO('9', 83)    /* Just guessing */
 
-
+#ifdef _KERNEL
 /*
  * Support for faking the "miniport" version.
  */
@@ -180,3 +187,24 @@ struct aac_query_disk {
        char            diskDeviceName[10];
        u_int32_t       UnMapped;
 };
+
+/* Features, asked from the tools to know if the driver
+ * supports drives >2TB
+ */
+typedef union {
+       struct {
+               u_int32_t largeLBA  : 1;        /* disk support greater 2TB */
+               u_int32_t IoctlBuf  : 1;        /* ARCIOCTL call support */
+               u_int32_t AIFSupport: 1;        /* AIF support */
+               u_int32_t JBODSupport:1;        /* fw + driver support JBOD */
+               u_int32_t fReserved : 28;
+       } fBits;
+       u_int32_t fValue;
+} featuresState;
+
+struct aac_features {
+       featuresState feat;
+       u_int32_t data[31];
+       u_int32_t reserved[32];
+} __packed;
+#endif
index 1c5ba18..4dc3229 100644 (file)
@@ -1,8 +1,5 @@
 /*-
- * Copyright (c) 2000 Michael Smith
- * Copyright (c) 2001 Scott Long
- * Copyright (c) 2000 BSDi
- * Copyright (c) 2001 Adaptec, Inc.
+ * Copyright (c) 2002 Scott Long
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     $FreeBSD: src/sys/dev/aac/aac_linux.c,v 1.1.4.1 2003/03/28 19:50:17 scottl Exp $
- *     $DragonFly: src/sys/dev/raid/aac/aac_linux.c,v 1.7 2008/01/20 03:40:35 pavalos Exp $
+ * $FreeBSD: src/sys/dev/aac/aac_linux.c,v 1.4 2006/12/20 17:10:53 delphij Exp $
+ */
+
+/*
+ * Linux ioctl handler for the aac device driver
  */
 
 #include <sys/param.h>
 #include <sys/file.h>
 #include <sys/mapped_ioctl.h>
 #include <sys/proc.h>
-#include <sys/file2.h>
+#ifdef __amd64__
+#include <machine/../linux32/linux.h>
+#include <machine/../linux32/linux32_proto.h>
+#else
 #include <emulation/linux/i386/linux.h>
 #include <emulation/linux/i386/linux_proto.h>
+#endif
 #include <emulation/linux/linux_ioctl.h>
 
-#include "aacreg.h"            /* needed by aac_ioctl.h */
-#include "aac_ioctl.h"
+#include <dev/raid/aac/aacreg.h>       /* needed by aac_ioctl.h */
+#include <dev/raid/aac/aac_ioctl.h>
 
 /* Define ioctl mappings */
 static struct ioctl_map_range aac_linux_ioctl_cmds[] = {
@@ -93,4 +97,4 @@ aac_linux_modevent(module_t mod, int type, void *data)
 }
 
 DEV_MODULE(aac_linux, aac_linux_modevent, NULL);
-MODULE_DEPEND(aac, linux, 1, 1, 1);
+MODULE_DEPEND(aac_linux, linux, 1, 1, 1);
index 01cfa2b..5ada686 100644 (file)
@@ -1,8 +1,8 @@
-# $DragonFly: src/sys/dev/raid/aac/aac_linux/Makefile,v 1.1 2003/08/15 08:32:31 dillon Exp $
+# $FreeBSD: src/sys/modules/aac/aac_linux/Makefile,v 1.1 2002/09/25 05:00:25 scottl Exp $
 
 .PATH: ${.CURDIR}/..
 
-KMOD=  aac_linux
-SRCS=  aac_linux.c
+KMOD=  aac_linux
+SRCS=  aac_linux.c
 
 .include <bsd.kmod.mk>
index 8704ee2..8becbde 100644 (file)
@@ -26,8 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     $FreeBSD: src/sys/dev/aac/aac_pci.c,v 1.3.2.19 2003/11/01 18:44:51 scottl Exp $
- *     $DragonFly: src/sys/dev/raid/aac/aac_pci.c,v 1.13 2008/01/20 03:40:35 pavalos Exp $
+ * $FreeBSD: src/sys/dev/aac/aac_pci.c,v 1.74 2010/04/13 01:16:15 emaste Exp $
  */
 
 /*
 #include <sys/kernel.h>
 #include <sys/module.h>
 
+#include <sys/bio.h>
 #include <sys/bus.h>
 #include <sys/conf.h>
-#include <sys/devicestat.h>
 #include <sys/disk.h>
+
 #include <sys/rman.h>
 
 #include <bus/pci/pcireg.h>
 #include <bus/pci/pcivar.h>
 
-#include "aacreg.h"
-#include "aac_ioctl.h"
-#include "aacvar.h"
+#include <dev/raid/aac/aacreg.h>
+#include <dev/raid/aac/aac_ioctl.h>
+#include <dev/raid/aac/aacvar.h>
 
 static int     aac_pci_probe(device_t dev);
 static int     aac_pci_attach(device_t dev);
@@ -76,11 +76,13 @@ static driver_t aac_pci_driver = {
        sizeof(struct aac_softc)
 };
 
-devclass_t     aac_devclass;
+static devclass_t      aac_devclass;
 
 DRIVER_MODULE(aac, pci, aac_pci_driver, aac_devclass, 0, 0);
+MODULE_DEPEND(aac, pci, 1, 1, 1);
+
 
-static struct aac_ident
+struct aac_ident
 {
        u_int16_t               vendor;
        u_int16_t               device;
@@ -113,15 +115,15 @@ static struct aac_ident
        {0x1011, 0x0046, 0x9005, 0x0365, AAC_HWIF_STRONGARM,
         AAC_FLAGS_BROKEN_MEMMAP, "Adaptec SCSI RAID 5400S"},
        {0x1011, 0x0046, 0x9005, 0x1364, AAC_HWIF_STRONGARM, AAC_FLAGS_PERC2QC,
-       "Dell PERC 2/QC"},
+        "Dell PERC 2/QC"},
        {0x1011, 0x0046, 0x103c, 0x10c2, AAC_HWIF_STRONGARM, 0,
-       "HP NetRaid-4M"},
-       {0x9005, 0x0285, 0x9005, 0x0285, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
-       "Adaptec SCSI RAID 2200S"},
-       {0x9005, 0x0285, 0x1028, 0x0287, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
-       "Dell PERC 320/DC"},
-       {0x9005, 0x0285, 0x9005, 0x0286, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
-       "Adaptec SCSI RAID 2120S"},
+        "HP NetRaid-4M"},
+       {0x9005, 0x0285, 0x9005, 0x0285, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
+        AAC_FLAGS_256FIBS, "Adaptec SCSI RAID 2200S"},
+       {0x9005, 0x0285, 0x1028, 0x0287, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
+        AAC_FLAGS_256FIBS, "Dell PERC 320/DC"},
+       {0x9005, 0x0285, 0x9005, 0x0286, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB |
+        AAC_FLAGS_256FIBS, "Adaptec SCSI RAID 2120S"},
        {0x9005, 0x0285, 0x9005, 0x0290, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
         "Adaptec SATA RAID 2410SA"},
        {0x9005, 0x0285, 0x1028, 0x0291, AAC_HWIF_I960RX, AAC_FLAGS_NO4GB,
@@ -163,16 +165,16 @@ static struct aac_ident
         "ICP ICP9014RO SCSI RAID"},
        {0x9005, 0x0285, 0x9005, 0x0294, AAC_HWIF_I960RX, 0,
         "Adaptec SATA RAID 2026ZCR"},
-       {0x9005, 0x0285, 0x103c, 0x3227, AAC_HWIF_I960RX, 0,
-        "Adaptec SATA RAID 2610SA"},
        {0x9005, 0x0285, 0x9005, 0x0296, AAC_HWIF_I960RX, 0,
         "Adaptec SCSI RAID 2240S"},
        {0x9005, 0x0285, 0x9005, 0x0297, AAC_HWIF_I960RX, 0,
         "Adaptec SAS RAID 4005SAS"},
        {0x9005, 0x0285, 0x1014, 0x02f2, AAC_HWIF_I960RX, 0,
         "IBM ServeRAID 8i"},
+       {0x9005, 0x0285, 0x1014, 0x0312, AAC_HWIF_I960RX, 0,
+        "IBM ServeRAID 8i"},
        {0x9005, 0x0285, 0x9005, 0x0298, AAC_HWIF_I960RX, 0,
-        "Adaptec SAS RAID 4000SAS"},
+        "Adaptec RAID 4000"},
        {0x9005, 0x0285, 0x9005, 0x0299, AAC_HWIF_I960RX, 0,
         "Adaptec SAS RAID 4800SAS"},
        {0x9005, 0x0285, 0x9005, 0x029a, AAC_HWIF_I960RX, 0,
@@ -189,14 +191,96 @@ static struct aac_ident
         "ICP ICP9047MA SATA RAID"},
        {0x9005, 0x0286, 0x9005, 0x02a1, AAC_HWIF_RKT, 0,
         "ICP ICP9087MA SATA RAID"},
+       {0x9005, 0x0286, 0x9005, 0x02a6, AAC_HWIF_RKT, 0,
+        "ICP9067MA SATA RAID"},
+       {0x9005, 0x0285, 0x9005, 0x02b5, AAC_HWIF_I960RX, 0,
+        "Adaptec RAID 5445"},
+       {0x9005, 0x0285, 0x9005, 0x02b6, AAC_HWIF_I960RX, 0,
+        "Adaptec RAID 5805"},
+       {0x9005, 0x0285, 0x9005, 0x02b7, AAC_HWIF_I960RX, 0,
+        "Adaptec RAID 5085"},
+       {0x9005, 0x0285, 0x9005, 0x02b8, AAC_HWIF_I960RX, 0,
+        "ICP RAID ICP5445SL"},
+       {0x9005, 0x0285, 0x9005, 0x02b9, AAC_HWIF_I960RX, 0,
+        "ICP RAID ICP5085SL"},
+       {0x9005, 0x0285, 0x9005, 0x02ba, AAC_HWIF_I960RX, 0,
+        "ICP RAID ICP5805SL"},
        {0x9005, 0x0285, 0x9005, 0x02bb, AAC_HWIF_I960RX, 0,
         "Adaptec RAID 3405"},
        {0x9005, 0x0285, 0x9005, 0x02bc, AAC_HWIF_I960RX, 0,
         "Adaptec RAID 3805"},
+       {0x9005, 0x0285, 0x9005, 0x02bd, AAC_HWIF_I960RX, 0,
+        "Adaptec RAID 31205"},
+       {0x9005, 0x0285, 0x9005, 0x02be, AAC_HWIF_I960RX, 0,
+        "Adaptec RAID 31605"},
+       {0x9005, 0x0285, 0x9005, 0x02bf, AAC_HWIF_I960RX, 0,
+        "ICP RAID ICP5045BL"},
+       {0x9005, 0x0285, 0x9005, 0x02c0, AAC_HWIF_I960RX, 0,
+        "ICP RAID ICP5085BL"},
+       {0x9005, 0x0285, 0x9005, 0x02c1, AAC_HWIF_I960RX, 0,
+        "ICP RAID ICP5125BR"},
+       {0x9005, 0x0285, 0x9005, 0x02c2, AAC_HWIF_I960RX, 0,
+        "ICP RAID ICP5165BR"},
+       {0x9005, 0x0285, 0x9005, 0x02c3, AAC_HWIF_I960RX, 0,
+        "Adaptec RAID 51205"},
+       {0x9005, 0x0285, 0x9005, 0x02c4, AAC_HWIF_I960RX, 0,
+        "Adaptec RAID 51605"},
+       {0x9005, 0x0285, 0x9005, 0x02c5, AAC_HWIF_I960RX, 0,
+        "ICP RAID ICP5125SL"},
+       {0x9005, 0x0285, 0x9005, 0x02c6, AAC_HWIF_I960RX, 0,
+        "ICP RAID ICP5165SL"},
+       {0x9005, 0x0285, 0x9005, 0x02c7, AAC_HWIF_I960RX, 0,
+        "Adaptec RAID 3085"},
+       {0x9005, 0x0285, 0x9005, 0x02c8, AAC_HWIF_I960RX, 0,
+        "ICP RAID ICP5805BL"},
+       {0x9005, 0x0285, 0x9005, 0x02ce, AAC_HWIF_I960RX, 0,
+        "Adaptec RAID 51245"},
+       {0x9005, 0x0285, 0x9005, 0x02cf, AAC_HWIF_I960RX, 0,
+        "Adaptec RAID 51645"},
+       {0x9005, 0x0285, 0x9005, 0x02d0, AAC_HWIF_I960RX, 0,
+        "Adaptec RAID 52445"},
        {0x9005, 0x0285, 0x9005, 0x02d1, AAC_HWIF_I960RX, 0,
         "Adaptec RAID 5405"},
+       {0x9005, 0x0285, 0x9005, 0x02d4, AAC_HWIF_I960RX, 0,
+        "Adaptec RAID 2045"},
+       {0x9005, 0x0285, 0x9005, 0x02d5, AAC_HWIF_I960RX, 0,
+        "Adaptec RAID 2405"},
+       {0x9005, 0x0285, 0x9005, 0x02d6, AAC_HWIF_I960RX, 0,
+        "Adaptec RAID 2445"},
+       {0x9005, 0x0285, 0x9005, 0x02d7, AAC_HWIF_I960RX, 0,
+        "Adaptec RAID 2805"},
        {0x9005, 0x0286, 0x1014, 0x9580, AAC_HWIF_RKT, 0,
         "IBM ServeRAID-8k"},
+       {0x9005, 0x0285, 0x1014, 0x034d, AAC_HWIF_I960RX, 0,
+        "IBM ServeRAID 8s"},
+       {0x9005, 0x0285, 0x108e, 0x7aac, AAC_HWIF_I960RX, 0,
+        "Sun STK RAID REM"},
+       {0x9005, 0x0285, 0x108e, 0x7aae, AAC_HWIF_I960RX, 0,
+        "Sun STK RAID EM"},
+       {0x9005, 0x0285, 0x108e, 0x286, AAC_HWIF_I960RX, 0,
+        "SG-XPCIESAS-R-IN"},
+       {0x9005, 0x0285, 0x108e, 0x287, AAC_HWIF_I960RX, 0,
+        "SG-XPCIESAS-R-EX"},
+       {0x9005, 0x0285, 0x15d9, 0x2b5, AAC_HWIF_I960RX, 0,
+        "AOC-USAS-S4i"},
+       {0x9005, 0x0285, 0x15d9, 0x2b6, AAC_HWIF_I960RX, 0,
+        "AOC-USAS-S8i"},
+       {0x9005, 0x0285, 0x15d9, 0x2c9, AAC_HWIF_I960RX, 0,
+        "AOC-USAS-S4iR"},
+       {0x9005, 0x0285, 0x15d9, 0x2ca, AAC_HWIF_I960RX, 0,
+        "AOC-USAS-S8iR"},
+       {0x9005, 0x0285, 0x15d9, 0x2d2, AAC_HWIF_I960RX, 0,
+        "AOC-USAS-S8i-LP"},
+       {0x9005, 0x0285, 0x15d9, 0x2d3, AAC_HWIF_I960RX, 0,
+        "AOC-USAS-S8iR-LP"},
+       {0, 0, 0, 0, 0, 0, 0}
+};
+struct aac_ident
+aac_family_identifiers[] = {
+       {0x9005, 0x0285, 0, 0, AAC_HWIF_I960RX, 0,
+        "Adaptec RAID Controller"},
+       {0x9005, 0x0286, 0, 0, AAC_HWIF_RKT, 0,
+        "Adaptec RAID Controller"},
        {0, 0, 0, 0, 0, 0, 0}
 };
 
@@ -204,13 +288,23 @@ static struct aac_ident *
 aac_find_ident(device_t dev)
 {
        struct aac_ident *m;
+       u_int16_t vendid, devid, sub_vendid, sub_devid;
+
+       vendid = pci_get_vendor(dev);
+       devid = pci_get_device(dev);
+       sub_vendid = pci_get_subvendor(dev);
+       sub_devid = pci_get_subdevice(dev);
 
        for (m = aac_identifiers; m->vendor != 0; m++) {
-               if ((m->vendor == pci_get_vendor(dev)) &&
-                   (m->device == pci_get_device(dev)) &&
-                   (m->subvendor == pci_get_subvendor(dev)) &&
-                   (m->subdevice == pci_get_subdevice(dev)))
-               return (m);
+               if ((m->vendor == vendid) && (m->device == devid) &&
+                   (m->subvendor == sub_vendid) &&
+                   (m->subdevice == sub_devid))
+                       return (m);
+       }
+
+       for (m = aac_family_identifiers; m->vendor != 0; m++) {
+               if ((m->vendor == vendid) && (m->device == devid))
+                       return (m);
        }
 
        return (NULL);
@@ -224,7 +318,7 @@ aac_pci_probe(device_t dev)
 {
        struct aac_ident *id;
 
-       debug_called(1);
+       fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        if ((id = aac_find_ident(dev)) != NULL) {
                device_set_desc(dev, id->desc);
@@ -244,7 +338,7 @@ aac_pci_attach(device_t dev)
        int error;
        u_int32_t command;
 
-       debug_called(1);
+       fwprintf(NULL, HBA_FLAGS_DBG_FUNCTION_ENTRY_B, "");
 
        /*
         * Initialise softc.
@@ -256,7 +350,7 @@ aac_pci_attach(device_t dev)
        /* assume failure is 'not configured' */
        error = ENXIO;
 
-       /* 
+       /*
         * Verify that the adapter is correctly set up in PCI space.
         */
        command = pci_read_config(sc->aac_dev, PCIR_COMMAND, 2);
@@ -275,25 +369,36 @@ aac_pci_attach(device_t dev)
        /*
         * Allocate the PCI register window.
         */
-       sc->aac_regs_rid = PCIR_BAR(0);
-       if ((sc->aac_regs_resource = bus_alloc_resource_any(sc->aac_dev,
-                                                           SYS_RES_MEMORY,
-                                                           &sc->aac_regs_rid,
-                                                           RF_ACTIVE)) ==
-                                                           NULL) {
+       sc->aac_regs_rid0 = PCIR_BAR(0);
+       if ((sc->aac_regs_res0 = bus_alloc_resource_any(sc->aac_dev,
+           SYS_RES_MEMORY, &sc->aac_regs_rid0, RF_ACTIVE)) == NULL) {
                device_printf(sc->aac_dev,
-                             "couldn't allocate register window\n");
+                   "couldn't allocate register window 0\n");
                goto out;
        }
-       sc->aac_btag = rman_get_bustag(sc->aac_regs_resource);
-       sc->aac_bhandle = rman_get_bushandle(sc->aac_regs_resource);
-
-       /* assume failure is 'out of memory' */
-       error = ENOMEM;
+       sc->aac_btag0 = rman_get_bustag(sc->aac_regs_res0);
+       sc->aac_bhandle0 = rman_get_bushandle(sc->aac_regs_res0);
+
+       if (sc->aac_hwif == AAC_HWIF_NARK) {
+               sc->aac_regs_rid1 = PCIR_BAR(1);
+               if ((sc->aac_regs_res1 = bus_alloc_resource_any(sc->aac_dev,
+                   SYS_RES_MEMORY, &sc->aac_regs_rid1, RF_ACTIVE)) == NULL) {
+                       device_printf(sc->aac_dev,
+                           "couldn't allocate register window 1\n");
+                       goto out;
+               }
+               sc->aac_btag1 = rman_get_bustag(sc->aac_regs_res1);
+               sc->aac_bhandle1 = rman_get_bushandle(sc->aac_regs_res1);
+       } else {
+               sc->aac_regs_res1 = sc->aac_regs_res0;
+               sc->aac_regs_rid1 = sc->aac_regs_rid0;
+               sc->aac_btag1 = sc->aac_btag0;
+               sc->aac_bhandle1 = sc->aac_bhandle0;
+       }
 
        /*
         * Allocate the parent bus DMA tag appropriate for our PCI interface.
-        * 
+        *
         * Note that some of these controllers are 64-bit capable.
         */
        if (bus_dma_tag_create(NULL,                    /* parent */
@@ -310,7 +415,7 @@ aac_pci_attach(device_t dev)
                goto out;
        }
 
-       /* 
+       /*
         * Detect the hardware interface version, set up the bus interface
         * indirection.
         */
@@ -318,19 +423,16 @@ aac_pci_attach(device_t dev)
        sc->aac_hwif = id->hwif;
        switch(sc->aac_hwif) {
        case AAC_HWIF_I960RX:
-               debug(2, "set hardware up for i960Rx");
+       case AAC_HWIF_NARK:
+               fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for i960Rx/NARK");
                sc->aac_if = aac_rx_interface;
                break;
        case AAC_HWIF_STRONGARM:
-               debug(2, "set hardware up for StrongARM");
+               fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for StrongARM");
                sc->aac_if = aac_sa_interface;
                break;
-       case AAC_HWIF_FALCON:
-               debug(2, "set hardware up for Falcon/PPC");
-               sc->aac_if = aac_fa_interface;
-               break;
        case AAC_HWIF_RKT:
-               debug(2, "set hardware up for Rocket/MIPS");
+               fwprintf(sc, HBA_FLAGS_DBG_INIT_B, "set hardware up for Rocket/MIPS");
                sc->aac_if = aac_rkt_interface;
                break;
        default:
index 8075798..ae26799 100644 (file)
@@ -24,8 +24,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     $FreeBSD: src/sys/dev/aac/aac_tables.h,v 1.1.2.3 2001/12/04 02:38:04 scottl Exp $
- *     $DragonFly: src/sys/dev/raid/aac/aac_tables.h,v 1.3 2008/01/20 03:40:35 pavalos Exp $
+ *     $FreeBSD: src/sys/dev/aac/aac_tables.h,v 1.8 2010/04/13 12:10:55 emaste Exp $
  */
 
 /*
  * relevant only to FSA operations.
  */
 static struct aac_code_lookup aac_command_status_table[] = {
-       {"OK",                                  0},
-       {"operation not permitted",             1},
-       {"not found",                           2},
-       {"I/O error",                           5},
-       {"device not configured",               6},
-       {"too big",                             7},
-       {"permission denied",                   13},
-       {"file exists",                         17},
-       {"cross-device link",                   18},
-       {"operation not supported by device",   19},
-       {"not a directory",                     20},
-       {"is a directory",                      21},
-       {"invalid argument",                    22},
-       {"file too large",                      27},
-       {"no space on device",                  28},
-       {"readonly filesystem",                 30},
-       {"too many links",                      31},
-       {"operation would block",               35},
-       {"file name too long",                  63},
-       {"directory not empty",                 66},
-       {"quota exceeded",                      69},
-       {"stale file handle",                   70},
-       {"too many levels of remote in path",   71},
-       {"bad file handle",                     10001},
-       {"not sync",                            10002},
-       {"bad cookie",                          10003},
-       {"operation not supported",             10004},
-       {"too small",                           10005},
-       {"server fault",                        10006},
-       {"bad type",                            10007},
-       {"jukebox",                             10008},
-       {"not mounted",                         10009},
-       {"in maintenance mode",                 10010},
-       {"stale ACL",                           10011},
+       {"OK",                                  ST_OK},
+       {"operation not permitted",             ST_PERM},
+       {"not found",                           ST_NOENT},
+       {"I/O error",                           ST_IO},
+       {"device not configured",               ST_NXIO},
+       {"too big",                             ST_E2BIG},
+       {"permission denied",                   ST_ACCES},
+       {"file exists",                         ST_EXIST},
+       {"cross-device link",                   ST_XDEV},
+       {"operation not supported by device",   ST_NODEV},
+       {"not a directory",                     ST_NOTDIR},
+       {"is a directory",                      ST_ISDIR},
+       {"invalid argument",                    ST_INVAL},
+       {"file too large",                      ST_FBIG},
+       {"no space on device",                  ST_NOSPC},
+       {"readonly filesystem",                 ST_ROFS},
+       {"too many links",                      ST_MLINK},
+       {"operation would block",               ST_WOULDBLOCK},
+       {"file name too long",                  ST_NAMETOOLONG},
+       {"directory not empty",                 ST_NOTEMPTY},
+       {"quota exceeded",                      ST_DQUOT},
+       {"stale file handle",                   ST_STALE},
+       {"too many levels of remote in path",   ST_REMOTE},
+       {"device busy (spinning up)",           ST_NOT_READY},
+       {"bad file handle",                     ST_BADHANDLE},
+       {"not sync",                            ST_NOT_SYNC},
+       {"bad cookie",                          ST_BAD_COOKIE},
+       {"operation not supported",             ST_NOTSUPP},
+       {"too small",                           ST_TOOSMALL},
+       {"server fault",                        ST_SERVERFAULT},
+       {"bad type",                            ST_BADTYPE},
+       {"jukebox",                             ST_JUKEBOX},
+       {"not mounted",                         ST_NOTMOUNTED},
+       {"in maintenance mode",                 ST_MAINTMODE},
+       {"stale ACL",                           ST_STALEACL},
+       {"bus reset - command aborted",         ST_BUS_RESET},
        {NULL,                                  0},
        {"unknown command status",              0}
 };
index 5900935..17fe7ce 100644 (file)
@@ -26,8 +26,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- *     $FreeBSD: src/sys/dev/aac/aacreg.h,v 1.4.2.7 2003/04/08 13:22:08 scottl Exp $
- *     $DragonFly: src/sys/dev/raid/aac/aacreg.h,v 1.4 2008/01/20 03:40:35 pavalos Exp $
+ *     $FreeBSD: src/sys/dev/aac/aacreg.h,v 1.34 2010/09/29 14:22:00 emaste Exp $
  */
 
 /*
@@ -85,7 +84,7 @@
 struct aac_queue_entry {
        u_int32_t       aq_fib_size;    /* FIB size in bytes */
        u_int32_t       aq_fib_addr;    /* receiver-space address of the FIB */
-} __attribute__ ((packed));
+} __packed;
 
 #define AAC_PRODUCER_INDEX     0
 #define AAC_CONSUMER_INDEX     1
@@ -107,7 +106,7 @@ struct aac_queue_table {
        struct aac_queue_entry qt_HostHighRespQueue[AAC_HOST_HIGH_RESP_ENTRIES];
        struct aac_queue_entry qt_AdapNormRespQueue[AAC_ADAP_NORM_RESP_ENTRIES];
        struct aac_queue_entry qt_AdapHighRespQueue[AAC_ADAP_HIGH_RESP_ENTRIES];
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * Queue names
@@ -129,9 +128,9 @@ struct aac_queue_table {
  * our private command structure and don't touch these)
  */
 struct aac_fib_list_entry {
-       u_int32_t Flink;
-       u_int32_t Blink;
-} __attribute__ ((packed));
+       u_int32_t       Flink;
+       u_int32_t       Blink;
+} __packed;
 
 /*
  * FIB (FSA Interface Block?); this is the datastructure passed between the host
@@ -154,14 +153,14 @@ struct aac_fib_header {
                } _s;
                struct aac_fib_list_entry FibLinks;
        } _u;
-} __attribute__ ((packed));
+} __packed;
 
 #define AAC_FIB_DATASIZE       (512 - sizeof(struct aac_fib_header))
 
 struct aac_fib {
        struct aac_fib_header   Header;
        u_int8_t                        data[AAC_FIB_DATASIZE];
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * FIB commands
@@ -221,20 +220,20 @@ typedef enum {
        IsAdapterPaused =               704,
        SendHostTime =                  705,
        RequestSupplementAdapterInfo =  706,    /* Supp. Info for set in UCC
-                                                * use only if supported 
+                                                * use only if supported
                                                 * (RequestAdapterInfo first) */
        LastMiscCommand =               707,
-  
-       OnLineDiagnostic =              800,      
-       FduAdapterTest =                801, 
+
+       OnLineDiagnostic =              800,
+       FduAdapterTest =                801,
        RequestCompatibilityId =        802,
        AdapterEnvironmentInfo =        803,    /* temp. sensors */
        NvsramEventLog =                900,
        ResetNvsramEventLogPointers =   901,
        EnableEventLog =                902,
        DisableEventLog =               903,
-       EncryptedKeyTransportFIB=       904,    
-       KeyableFeaturesFIB=             905     
+       EncryptedKeyTransportFIB=       904,
+       KeyableFeaturesFIB=             905
 } AAC_FibCommands;
 
 /*
@@ -284,7 +283,7 @@ typedef enum {
 #define AAC_ERROR_FIB_DEALLOCATION_FAILED      0x08
 
 /*
- * Adapter Init Structure: this is passed to the adapter with the 
+ * Adapter Init Structure: this is passed to the adapter with the
  * AAC_MONKER_INITSTRUCT command to point it at our control structures.
  */
 struct aac_adapter_init {
@@ -307,13 +306,13 @@ struct aac_adapter_init {
        u_int32_t       HostElapsedSeconds;
        /* ADAPTER_INIT_STRUCT_REVISION_4 begins here */
        u_int32_t       InitFlags;                      /* flags for supported features */
-#define INITFLAGS_NEW_COMM_SUPPORTED   1
+#define        AAC_INITFLAGS_NEW_COMM_SUPPORTED        1
+#define        AAC_INITFLAGS_DRIVER_USES_UTC_TIME      0x10
+#define        AAC_INITFLAGS_DRIVER_SUPPORTS_PM        0x20
        u_int32_t       MaxIoCommands;          /* max outstanding commands */
        u_int32_t       MaxIoSize;                      /* largest I/O command */
        u_int32_t       MaxFibSize;                     /* largest FIB to adapter */
-} __attribute__ ((packed));
-
-typedef u_int32_t      aac_phys_addr_t;
+} __packed;
 
 /*
  * Shared data types
@@ -332,14 +331,14 @@ typedef enum {
        CT_MORPH,
        CT_PASSTHRU,
        CT_RAID4,
-       CT_RAID10,                  /* stripe of mirror */
-       CT_RAID00,                  /* stripe of stripe */
-       CT_VOLUME_OF_MIRRORS,       /* volume of mirror */
-       CT_PSEUDO_RAID3,            /* really raid4 */
-       CT_RAID50,                  /* stripe of raid5 */
-       CT_RAID5D,                  /* raid5 distributed hot-sparing */
+       CT_RAID10,              /* stripe of mirror */
+       CT_RAID00,              /* stripe of stripe */
+       CT_VOLUME_OF_MIRRORS,   /* volume of mirror */
+       CT_PSEUDO_RAID3,        /* really raid4 */
+       CT_RAID50,              /* stripe of raid5 */
+       CT_RAID5D,              /* raid5 distributed hot-sparing */
        CT_RAID5D0,
-       CT_RAID1E,                  /* extended raid1 mirroring */
+       CT_RAID1E,              /* extended raid1 mirroring */
        CT_RAID6,
        CT_RAID60,
 } AAC_FSAVolType;
@@ -348,23 +347,23 @@ typedef enum {
  * Host-addressable object types
  */
 typedef enum {
-       FT_REG = 1,     /* regular file */
-       FT_DIR,         /* directory */
-       FT_BLK,         /* "block" device - reserved */
-       FT_CHR,         /* "character special" device - reserved */
-       FT_LNK,         /* symbolic link */
-       FT_SOCK,        /* socket */
-       FT_FIFO,        /* fifo */
-       FT_FILESYS,     /* ADAPTEC's "FSA"(tm) filesystem */
-       FT_DRIVE,       /* physical disk - addressable in scsi by b/t/l */
-       FT_SLICE,       /* virtual disk - raw volume - slice */
-       FT_PARTITION,   /* FSA partition - carved out of a slice - building
+       FT_REG = 1,     /* regular file */
+       FT_DIR,         /* directory */
+       FT_BLK,         /* "block" device - reserved */
+       FT_CHR,         /* "character special" device - reserved */
+       FT_LNK,         /* symbolic link */
+       FT_SOCK,        /* socket */
+       FT_FIFO,        /* fifo */
+       FT_FILESYS,     /* ADAPTEC's "FSA"(tm) filesystem */
+       FT_DRIVE,       /* physical disk - addressable in scsi by b/t/l */
+       FT_SLICE,       /* virtual disk - raw volume - slice */
+       FT_PARTITION,   /* FSA partition - carved out of a slice - building
                         * block for containers */
-       FT_VOLUME,      /* Container - Volume Set */
-       FT_STRIPE,      /* Container - Stripe Set */
-       FT_MIRROR,      /* Container - Mirror Set */
-       FT_RAID5,       /* Container - Raid 5 Set */
-       FT_DATABASE     /* Storage object with "foreign" content manager */
+       FT_VOLUME,      /* Container - Volume Set */
+       FT_STRIPE,      /* Container - Stripe Set */
+       FT_MIRROR,      /* Container - Mirror Set */
+       FT_RAID5,       /* Container - Raid 5 Set */
+       FT_DATABASE     /* Storage object with "foreign" content manager */
 } AAC_FType;
 
 /*
@@ -373,7 +372,7 @@ typedef enum {
 struct aac_sg_entry {
        u_int32_t       SgAddress;
        u_int32_t       SgByteCount;
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_sg_entry64 {
        u_int64_t       SgAddress;
@@ -391,7 +390,7 @@ struct aac_sg_entryraw {
 struct aac_sg_table {
        u_int32_t               SgCount;
        struct aac_sg_entry     SgEntry[0];
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * Host-side scatter/gather list for 64-bit commands.
@@ -399,7 +398,7 @@ struct aac_sg_table {
 struct aac_sg_table64 {
        u_int32_t       SgCount;
        struct aac_sg_entry64   SgEntry64[0];
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * s/g list for raw commands
@@ -423,7 +422,7 @@ struct aac_container_creation {
        u_int32_t       Minute:6;       /* 0-59 */
        u_int32_t       Second:6;       /* 0-59 */
        u_int64_t       ViaAdapterSerialNumber;
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * Revision number handling
@@ -452,7 +451,7 @@ struct FsaRevision {
                u_int32_t       ul;
        } external;
        u_int32_t       buildNumber;
-}  __attribute__ ((packed));
+}  __packed;
 
 /*
  * Adapter Information
@@ -470,7 +469,7 @@ typedef enum {
        CPU_MIPS,
        CPU_XSCALE,
        CPU__last
-} AAC_CpuType;  
+} AAC_CpuType;
 
 typedef enum {
        CPUI960_JX = 1,
@@ -547,7 +546,7 @@ typedef enum {
  * XXX the aac-2622 with no battery present reports PLATFORM_BAT_OPT_PRESENT
  */
 typedef enum
-{ 
+{
        PLATFORM_BAT_REQ_PRESENT = 1,   /* BATTERY REQUIRED AND PRESENT */
        PLATFORM_BAT_REQ_NOTPRESENT,    /* BATTERY REQUIRED AND NOT PRESENT */
        PLATFORM_BAT_OPT_PRESENT,       /* BATTERY OPTIONAL AND PRESENT */
@@ -555,9 +554,9 @@ typedef enum
        PLATFORM_BAT_NOT_SUPPORTED      /* BATTERY NOT SUPPORTED */
 } AAC_BatteryPlatform;
 
-/* 
+/*
  * options supported by this board
- * there has to be a one to one mapping of these defines and the ones in 
+ * there has to be a one to one mapping of these defines and the ones in
  * fsaapi.h, search for FSA_SUPPORT_SNAPSHOT
  */
 #define AAC_SUPPORTED_SNAPSHOT         0x01
@@ -580,24 +579,24 @@ typedef enum
 #define AAC_SUPPORTED_64BIT_ARRAYSIZE  0x40000
 #define AAC_SUPPORTED_HEAT_SENSOR      0x80000
 
-/* 
+/*
  * Structure used to respond to a RequestAdapterInfo fib.
  */
 struct aac_adapter_info {
-       AAC_Platform            PlatformBase;    /* adapter type */
+       AAC_Platform            PlatformBase;    /* adapter type */
        AAC_CpuType             CpuArchitecture; /* adapter CPU type */
-       AAC_CpuSubType          CpuVariant;      /* adapter CPU subtype */
-       u_int32_t               ClockSpeed;      /* adapter CPU clockspeed */
-       u_int32_t               ExecutionMem;    /* adapter Execution Memory
+       AAC_CpuSubType          CpuVariant;      /* adapter CPU subtype */
+       u_int32_t               ClockSpeed;      /* adapter CPU clockspeed */
+       u_int32_t               ExecutionMem;    /* adapter Execution Memory
                                                  * size */
-       u_int32_t               BufferMem;       /* adapter Data Memory */
-       u_int32_t               TotalMem;        /* adapter Total Memory */
+       u_int32_t               BufferMem;       /* adapter Data Memory */
+       u_int32_t               TotalMem;        /* adapter Total Memory */
        struct FsaRevision      KernelRevision;  /* adapter Kernel Software
                                                  * Revision */
        struct FsaRevision      MonitorRevision; /* adapter Monitor/Diagnostic
                                                  * Software Revision */
        struct FsaRevision      HardwareRevision;/* TBD */
-       struct FsaRevision      BIOSRevision;    /* adapter BIOS Revision */
+       struct FsaRevision      BIOSRevision;    /* adapter BIOS Revision */
        u_int32_t               ClusteringEnabled;
        u_int32_t               ClusterChannelMask;
        u_int64_t               SerialNumber;
@@ -605,7 +604,59 @@ struct aac_adapter_info {
        u_int32_t               SupportedOptions; /* supported features of this
                                                   * controller */
        AAC_OemFlavor   OemVariant;
-} __attribute__ ((packed));
+} __packed;
+
+/*
+ * Structure used to respond to a RequestSupplementAdapterInfo fib.
+ */
+struct vpd_info {
+       u_int8_t                AssemblyPn[8];
+       u_int8_t                FruPn[8];
+       u_int8_t                BatteryFruPn[8];
+       u_int8_t                EcVersionString[8];
+       u_int8_t                Tsid[12];
+} __packed;
+
+#define        MFG_PCBA_SERIAL_NUMBER_WIDTH    12
+#define        MFG_WWN_WIDTH                   8
+
+struct aac_supplement_adapter_info {
+       /* The assigned Adapter Type Text, extra byte for null termination */
+       int8_t          AdapterTypeText[17+1];
+       /* Pad for the text above */
+       int8_t          Pad[2];
+       /* Size in bytes of the memory that is flashed */
+       u_int32_t       FlashMemoryByteSize;
+       /* The assigned IMAGEID_xxx for this adapter */
+       u_int32_t       FlashImageId;
+       /*
+        * The maximum number of Phys available on a SATA/SAS
+        * Controller, 0 otherwise
+        */
+       u_int32_t       MaxNumberPorts;
+       /* Version of expansion area */
+       u_int32_t       Version;
+       u_int32_t       FeatureBits;
+       u_int8_t                SlotNumber;
+       u_int8_t                ReservedPad0[3];
+       u_int8_t                BuildDate[12];
+       /* The current number of Ports on a SAS controller, 0 otherwise */
+       u_int32_t       CurrentNumberPorts;
+
+       struct vpd_info VpdInfo;
+
+       /* Firmware Revision (Vmaj.min-dash.) */
+       struct FsaRevision      FlashFirmwareRevision;
+       u_int32_t       RaidTypeMorphOptions;
+       /* Firmware's boot code Revision (Vmaj.min-dash.) */
+       struct FsaRevision      FlashFirmwareBootRevision;
+       /* PCBA serial no. from th MFG sector */
+       u_int8_t                MfgPcbaSerialNo[MFG_PCBA_SERIAL_NUMBER_WIDTH];
+       /* WWN from the MFG sector */
+       u_int8_t                MfgWWNName[MFG_WWN_WIDTH];
+       /* Growth Area for future expansion ((7*4) - 12 - 8)/4 = 2 words */
+       u_int32_t       ReservedGrowth[2];
+} __packed;
 
 /*
  * Monitor/Kernel interface.
@@ -643,7 +694,7 @@ struct aac_adapter_info {
 #define AAC_KERNEL_PANIC       0x00000100
 
 /*
- * Data types relating to control and monitoring of the NVRAM/WriteCache 
+ * Data types relating to control and monitoring of the NVRAM/WriteCache
  * subsystem.
  */
 
@@ -695,7 +746,7 @@ struct aac_nvramdevinfo {
        u_int32_t       NV_NDirty;      /* count of dirty NVRAM buffers */
        u_int32_t       NV_NActive;     /* count of NVRAM buffers being
                                         * written */
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_nvraminfo {
        AAC_NVSTATUS            NV_Status;      /* nvram subsystem status */
@@ -715,7 +766,7 @@ struct aac_nvraminfo {
        u_int32_t               NV_BattNeedsReconditioning;     /* boolean */
        u_int32_t               NV_TotalSize;   /* size of all non-volatile
                                                 * memories in bytes */
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * Data types relating to adapter-initiated FIBs
@@ -783,11 +834,11 @@ typedef enum {
 struct aac_AifContainers {
        u_int32_t       src;            /* from/master */
        u_int32_t       dst;            /* to/slave */
-} __attribute__ ((packed));
+} __packed;
 
 union aac_AifJobClient {
        struct aac_AifContainers        container;      /* For Container and
-                                                        * file system progress
+                                                        * filesystem progress
                                                         * ops; */
        int32_t                         scsi_dh;        /* For SCSI progress
                                                         * ops */
@@ -799,7 +850,7 @@ struct aac_AifJobDesc {
        AAC_AifJobType          type;           /* Operation that is being
                                                 * performed */
        union aac_AifJobClient  client;         /* Details */
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_AifJobProgressReport {
        struct aac_AifJobDesc   jd;
@@ -808,7 +859,7 @@ struct aac_AifJobProgressReport {
        u_int32_t               currentTick;
        u_int32_t               jobSpecificData1;
        u_int32_t               jobSpecificData2;
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * Event Notification
@@ -818,7 +869,7 @@ typedef enum {
        AifEnGeneric = 1,               /* Generic notification */
        AifEnTaskComplete,              /* Task has completed */
        AifEnConfigChange,              /* Adapter config change occurred */
-       AifEnContainerChange,           /* Adapter specific container 
+       AifEnContainerChange,           /* Adapter specific container
                                         * configuration change */
        AifEnDeviceFailure,             /* SCSI device failed */
        AifEnMirrorFailover,            /* Mirror failover started */
@@ -832,10 +883,21 @@ typedef enum {
        AifEnBatteryEvent,              /* Significant NV battery event */
        AifEnAddContainer,              /* A new container was created. */
        AifEnDeleteContainer,           /* A container was deleted. */
-       AifEnSMARTEvent,                /* SMART Event */
+       AifEnSMARTEvent,                /* SMART Event */
        AifEnBatteryNeedsRecond,        /* The battery needs reconditioning */
        AifEnClusterEvent,              /* Some cluster event */
        AifEnDiskSetEvent,              /* A disk set event occured. */
+       AifEnContainerScsiEvent,        /* a container event with no. and scsi id */
+       AifEnPicBatteryEvent,   /* An event gen. by pic_battery.c for an ABM */
+       AifEnExpEvent,          /* Exp. Event Type to replace CTPopUp messages */
+       AifEnRAID6RebuildDone,  /* RAID6 rebuild finished */
+       AifEnSensorOverHeat,    /* Heat Sensor indicate overheat */
+       AifEnSensorCoolDown,    /* Heat Sensor ind. cooled down after overheat */
+       AifFeatureKeysModified, /* notif. of updated feature keys */
+       AifApplicationExpirationEvent,  /* notif. on app. expiration status */
+       AifEnBackgroundConsistencyCheck,/* BCC notif. for NEC - DDTS 94700 */
+       AifEnAddJBOD,           /* A new JBOD type drive was created (30) */
+       AifEnDeleteJBOD,        /* A JBOD type drive was deleted (31) */
        AifDriverNotifyStart=199,       /* Notifies for host driver go here */
        /* Host driver notifications start here */
        AifDenMorphComplete,            /* A morph operation completed */
@@ -844,46 +906,51 @@ typedef enum {
 
 struct aac_AifEnsGeneric {
        char    text[132];              /* Generic text */
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_AifEnsDeviceFailure {
        u_int32_t       deviceHandle;   /* SCSI device handle */
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_AifEnsMirrorFailover {
        u_int32_t       container;      /* Container with failed element */
        u_int32_t       failedSlice;    /* Old slice which failed */
        u_int32_t       creatingSlice;  /* New slice used for auto-create */
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_AifEnsContainerChange {
        u_int32_t       container[2];   /* container that changed, -1 if no
                                         * container */
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_AifEnsContainerEvent {
        u_int32_t       container;      /* container number  */
        u_int32_t       eventType;      /* event type */
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_AifEnsEnclosureEvent {
        u_int32_t       empID;          /* enclosure management proc number  */
        u_int32_t       unitID;         /* unitId, fan id, power supply id,
                                         * slot id, tempsensor id.  */
        u_int32_t       eventType;      /* event type */
-} __attribute__ ((packed));
+} __packed;
+
+typedef enum {
+       AIF_EM_DRIVE_INSERTION=31,
+       AIF_EM_DRIVE_REMOVAL
+} aac_AifEMEventType;
 
 struct aac_AifEnsBatteryEvent {
        AAC_NVBATT_TRANSITION   transition_type;        /* eg from low to ok */
        AAC_NVBATTSTATUS        current_state;          /* current batt state */
        AAC_NVBATTSTATUS        prior_state;            /* prev batt state */
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_AifEnsDiskSetEvent {
        u_int32_t       eventType;
        u_int64_t       DsNum;
        u_int64_t       CreatorId;
-} __attribute__ ((packed));
+} __packed;
 
 typedef enum {
        CLUSTER_NULL_EVENT = 0,
@@ -897,7 +964,7 @@ typedef enum {
 
 struct aac_AifEnsClusterEvent {
        AAC_ClusterAifEvent     eventType;
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_AifEventNotify {
        AAC_AifEventNotifyType  type;
@@ -913,12 +980,12 @@ struct aac_AifEventNotify {
 /*             struct aac_AifEnsSMARTEvent             ES;*/
                struct aac_AifEnsClusterEvent           ECLE;
        } data;
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * Adapter Initiated FIB command structures. Start with the adapter
  * initiated FIBs that really come from the adapter, and get responded
- * to by the host. 
+ * to by the host.
  */
 #define AAC_AIF_REPORT_MAX_SIZE 64
 
@@ -951,7 +1018,7 @@ struct aac_aif_command {
                u_int8_t                        AR[AAC_AIF_REPORT_MAX_SIZE];
                u_int8_t                        data[AAC_FIB_DATASIZE - 8];
        } data;
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * Filesystem commands/data
@@ -1032,6 +1099,7 @@ typedef enum {
        ST_DQUOT = 69,
        ST_STALE = 70,
        ST_REMOTE = 71,
+       ST_NOT_READY = 72,
        ST_BADHANDLE = 10001,
        ST_NOT_SYNC = 10002,
        ST_BAD_COOKIE = 10003,
@@ -1042,7 +1110,8 @@ typedef enum {
        ST_JUKEBOX = 10008,
        ST_NOTMOUNTED = 10009,
        ST_MAINTMODE = 10010,
-       ST_STALEACL = 10011
+       ST_STALEACL = 10011,
+       ST_BUS_RESET = 20001
 } AAC_FSAStatus;
 
 /*
@@ -1071,7 +1140,7 @@ typedef enum _VM_COMMANDS {
        VM_CtHostRead64,
        VM_CtHostWrite64,
        VM_DrvErrTblLog,        /* drive error table/log type of command */
-       VM_NameServe64           
+       VM_NameServe64
 } AAC_VMCommand;
 
 /*
@@ -1091,20 +1160,21 @@ struct aac_mntobj {
                u_int32_t       pad[8];
        } ObjExtension;
        u_int32_t                       AlterEgoId;
-} __attribute__ ((packed));
+       u_int32_t                       CapacityHigh;
+} __packed;
 
 struct aac_mntinfo {
        u_int32_t               Command;
        u_int32_t               MntType;
        u_int32_t               MntCount;
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_mntinforesp {
        u_int32_t               Status;
        u_int32_t               MntType;
        u_int32_t               MntRespCount;
        struct aac_mntobj       MntTable[1];
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * Container shutdown command.
@@ -1112,7 +1182,7 @@ struct aac_mntinforesp {
 struct aac_closecommand {
        u_int32_t       Command;
        u_int32_t       ContainerId;
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * Container Config Command
@@ -1122,13 +1192,13 @@ struct aac_ctcfg {
        u_int32_t               Command;
        u_int32_t               cmd;
        u_int32_t               param;
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_ctcfg_resp {
        u_int32_t               Status;
        u_int32_t               resp;
        u_int32_t               param;
-} __attribute__ ((packed));
+} __packed;
 
 /*
  * 'Ioctl' commads
@@ -1146,7 +1216,7 @@ struct aac_getbusinf {
        u_int32_t               TargetsPerBus;
        u_int8_t                InitiatorBusId[AAC_SCSI_MAX_PORTS];
        u_int8_t                BusValid[AAC_SCSI_MAX_PORTS];
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_vmioctl {
        u_int32_t               Command;
@@ -1155,7 +1225,7 @@ struct aac_vmioctl {
        u_int32_t               ObjId;
        u_int32_t               IoctlCmd;
        u_int32_t               IoctlBuf[1];    /* Placeholder? */
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_vmi_businf_resp {
        u_int32_t               Status;
@@ -1164,7 +1234,7 @@ struct aac_vmi_businf_resp {
        u_int32_t               ObjId;
        u_int32_t               IoctlCmd;
        struct aac_getbusinf    BusInf;
-} __attribute__ ((packed));
+} __packed;
 
 #if 0
 #define AAC_BTL_TO_HANDLE(b, t, l) \
@@ -1250,7 +1320,7 @@ struct aac_blockread {
        u_int32_t               BlockNumber;
        u_int32_t               ByteCount;
        struct aac_sg_table     SgMap;          /* variable size */
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_blockread64 {
        u_int32_t               Command;
@@ -1265,7 +1335,7 @@ struct aac_blockread64 {
 struct aac_blockread_response {
        u_int32_t               Status;
        u_int32_t               ByteCount;
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_blockwrite {
        u_int32_t               Command;        /* not FSACommand! */
@@ -1274,7 +1344,7 @@ struct aac_blockwrite {
        u_int32_t               ByteCount;
        u_int32_t               Stable;
        struct aac_sg_table     SgMap;          /* variable size */
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_blockwrite64 {
        u_int32_t               Command;        /* not FSACommand! */
@@ -1290,7 +1360,7 @@ struct aac_blockwrite_response {
        u_int32_t               Status;
        u_int32_t               ByteCount;
        u_int32_t               Committed;
-} __attribute__ ((packed));
+} __packed;
 
 struct aac_raw_io {
        u_int64_t               BlockNumber;
@@ -1306,14 +1376,14 @@ struct aac_raw_io {
  * Container shutdown command.
  */
 struct aac_close_command {
-       u_int32_t          Command;
-       u_int32_t          ContainerId;
+       u_int32_t               Command;
+       u_int32_t               ContainerId;
 };
 
 /*
  * SCSI Passthrough structures
  */
-struct aac_srb32 {
+struct aac_srb {
        u_int32_t               function;
        u_int32_t               bus;
        u_int32_t               target;
@@ -1324,7 +1394,7 @@ struct aac_srb32 {
        u_int32_t               retry_limit;
        u_int32_t               cdb_len;
        u_int8_t                cdb[16];
-       struct aac_sg_table     sg_map32;
+       struct aac_sg_table     sg_map;
 };
 
 enum {
@@ -1403,24 +1473,6 @@ enum {
 };
 
 /*
- * Register set for adapters based on the Falcon bridge and PPC core
- */
-
-#define AAC_FA_DOORBELL0_CLEAR         0x00
-#define AAC_FA_DOORBELL1_CLEAR         0x02
-#define AAC_FA_DOORBELL0               0x04
-#define AAC_FA_DOORBELL1               0x06
-#define AAC_FA_MASK0_CLEAR             0x08
-#define AAC_FA_MASK1_CLEAR             0x0a
-#define        AAC_FA_MASK0                    0x0c
-#define AAC_FA_MASK1                   0x0e
-#define AAC_FA_MAILBOX                 0x10
-#define        AAC_FA_FWSTATUS                 0x2c    /* Mailbox 7 */
-#define        AAC_FA_INTSRC                   0x900
-
-#define AAC_FA_HACK(sc)        (void)AAC_GETREG4(sc, AAC_FA_INTSRC)
-
-/*
  * Register definitions for the Adaptec AAC-364 'Jalapeno I/II' adapters, based
  * on the SA110 'StrongArm'.
  */
@@ -1445,6 +1497,8 @@ enum {
  * and other related adapters.
  */
 
+#define AAC_RX_OMR0            0x18    /* outbound message register 0 */
+#define AAC_RX_OMR1            0x1c    /* outbound message register 1 */
 #define AAC_RX_IDBR            0x20    /* inbound doorbell register */
 #define AAC_RX_IISR            0x24    /* inbound interrupt status register */
 #define AAC_RX_IIMR            0x28    /* inbound interrupt mask register */
@@ -1462,6 +1516,8 @@ enum {
  * Unsurprisingly, it's quite similar to the i960!
  */
 
+#define AAC_RKT_OMR0           0x18    /* outbound message register 0 */
+#define AAC_RKT_OMR1           0x1c    /* outbound message register 1 */
 #define AAC_RKT_IDBR           0x20    /* inbound doorbell register */
 #define AAC_RKT_IISR           0x24    /* inbound interrupt status register */
 #define AAC_RKT_IIMR           0x28    /* inbound interrupt mask register */
@@ -1490,7 +1546,7 @@ enum {
 /*
  * The adapter can request the host print a message by setting the
  * DB_PRINTF flag in DOORBELL0.  The driver responds by collecting the
- * message from the printf buffer, clearing the DB_PRINTF flag in 
+ * message from the printf buffer, clearing the DB_PRINTF flag in
  * DOORBELL0 and setting it in DOORBELL1.
  * (ODBR and IDBR respectively for the i960Rx adapters)
  */
index 02e9126..58f428c 100644 (file)
  * 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.4.2.7 2003/04/08 13:22:08 scottl Exp $
+ *     $FreeBSD: src/sys/dev/aac/aacvar.h,v 1.60 2010/09/29 14:22:00 emaste Exp $
  */
 
-#include <sys/buf.h>
-#include <sys/buf2.h>
-#include <sys/eventhandler.h>
+#include <sys/bio.h>
+#include <sys/callout.h>
 #include <sys/lock.h>
-#include <sys/event.h>
 #include <sys/taskqueue.h>
-#include <sys/thread2.h>
+#include <sys/buf2.h>
+#include <sys/devicestat.h>
+#include <sys/disk.h>
+#include <sys/eventhandler.h>
+
+#define        AAC_TYPE_DEVO                   1
+#define        AAC_TYPE_ALPHA                  2
+#define        AAC_TYPE_BETA                   3
+#define        AAC_TYPE_RELEASE                4
+
+#define        AAC_DRIVER_MAJOR_VERSION        2
+#define        AAC_DRIVER_MINOR_VERSION        1
+#define        AAC_DRIVER_BUGFIX_LEVEL         9
+#define        AAC_DRIVER_TYPE                 AAC_TYPE_RELEASE
+
+#ifndef AAC_DRIVER_BUILD
+# define AAC_DRIVER_BUILD 1
+#endif
 
 /*
  * Driver Parameter Definitions
  */
 
 /*
- * The firmware interface allows for a 16-bit s/g list length.  We limit 
+ * The firmware interface allows for a 16-bit s/g list length.  We limit
  * ourselves to a reasonable maximum and ensure alignment.
  */
 #define AAC_MAXSGENTRIES       64      /* max S/G entries, limit 65535 */              
 #define AAC_ADAPTER_FIBS       8
 
 /*
- * FIBs are allocated in page-size chunks and can grow up to the 512
- * limit imposed by the hardware.
- */
-#define AAC_PREALLOCATE_FIBS   128
-#define AAC_NUM_MGT_FIB                8
-/*
  * The controller reports status events in AIFs.  We hang on to a number of
  * these in order to pass them out to user-space management tools.
  */
@@ -70,7 +79,7 @@
 #define AAC_PRINTF_BUFSIZE     256
 
 /*
- * We wait this many seconds for the adapter to come ready if it is still 
+ * We wait this many seconds for the adapter to come ready if it is still
  * booting
  */
 #define AAC_BOOT_TIMEOUT       (3 * 60)
@@ -83,7 +92,7 @@
 /*
  * Timeout for normal commands
  */
-#define AAC_CMD_TIMEOUT                30              /* seconds */
+#define AAC_CMD_TIMEOUT                120             /* seconds */
 
 /*
  * Rate at which we periodically check for timed out commands and kick the
@@ -105,6 +114,7 @@ struct aac_container
 /*
  * Per-SIM data structure
  */
+struct aac_cam;
 struct aac_sim
 {
        device_t                sim_dev;
@@ -112,13 +122,14 @@ struct aac_sim
        int                     BusNumber;
        int                     InitiatorBusId;
        struct aac_softc        *aac_sc;
+       struct aac_cam          *aac_cam;
        TAILQ_ENTRY(aac_sim)    sim_link;
 };
 
 /*
  * Per-disk structure
  */
-struct aac_disk 
+struct aac_disk
 {
        device_t                        ad_dev;
        cdev_t                          ad_dev_t;
@@ -131,7 +142,7 @@ struct aac_disk
        int                             ad_cylinders;
        int                             ad_heads;
        int                             ad_sectors;
-       u_int32_t                       ad_size;
+       u_int64_t                       ad_size;
        int                             unit;
 };
 
@@ -147,7 +158,7 @@ struct aac_command
        struct aac_fib          *cm_fib;        /* FIB associated with this
                                                 * command */
        u_int64_t               cm_fibphys;     /* bus address of the FIB */
-       struct buf              *cm_data;       /* pointer to data in kernel
+       struct bio              *cm_data;       /* pointer to data in kernel
                                                 * space */
        u_int32_t               cm_datalen;     /* data length */
        bus_dmamap_t            cm_datamap;     /* DMA map for bio data */
@@ -165,10 +176,9 @@ struct aac_command
 #define AAC_ON_AACQ_FREE       (1<<5)
 #define AAC_ON_AACQ_READY      (1<<6)
 #define AAC_ON_AACQ_BUSY       (1<<7)
-#define AAC_ON_AACQ_COMPLETE   (1<<8)
+#define AAC_ON_AACQ_AIF                (1<<8)
 #define AAC_ON_AACQ_NORM       (1<<10)
-#define AAC_ON_AACQ_AIF                (1<<11)
-#define AAC_ON_AACQ_MASK       ((1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<10)|(1<<11))
+#define AAC_ON_AACQ_MASK       ((1<<5)|(1<<6)|(1<<7)|(1<<8)|(1<<10))
 #define AAC_QUEUE_FRZN         (1<<9)          /* Freeze the processing of
                                                 * commands on the queue. */
 
@@ -211,7 +221,7 @@ struct aac_common {
                                AAC_QUEUE_ALIGN];
 
        /* buffer for text messages from the controller */
-       char                    ac_printf[AAC_PRINTF_BUFSIZE];
+       char                    ac_printf[AAC_PRINTF_BUFSIZE];
        
        /* fib for synchronous commands */
        struct aac_fib          ac_sync_fib;
@@ -220,7 +230,7 @@ struct aac_common {
 /*
  * Interface operations
  */
-struct aac_interface 
+struct aac_interface
 {
        int     (*aif_get_fwstatus)(struct aac_softc *sc);
        void    (*aif_qnotify)(struct aac_softc *sc, int qbit);
@@ -231,9 +241,9 @@ struct aac_interface
                                   u_int32_t arg2, u_int32_t arg3);
        int     (*aif_get_mailbox)(struct aac_softc *sc, int mb);
        void    (*aif_set_interrupts)(struct aac_softc *sc, int enable);
-       int     (*aif_send_command)(struct aac_softc *sc, struct aac_command *cm);
-       int     (*aif_get_outb_queue)(struct aac_softc *sc);
-       void    (*aif_set_outb_queue)(struct aac_softc *sc, int index);
+       int (*aif_send_command)(struct aac_softc *sc, struct aac_command *cm);
+       int (*aif_get_outb_queue)(struct aac_softc *sc);
+       void (*aif_set_outb_queue)(struct aac_softc *sc, int index);
 };
 extern struct aac_interface    aac_rx_interface;
 extern struct aac_interface    aac_sa_interface;
@@ -258,38 +268,51 @@ extern struct aac_interface       aac_rkt_interface;
 #define AAC_GET_OUTB_QUEUE(sc)         ((sc)->aac_if.aif_get_outb_queue((sc)))
 #define AAC_SET_OUTB_QUEUE(sc, idx)    ((sc)->aac_if.aif_set_outb_queue((sc), (idx)))
 
-#define AAC_SETREG4(sc, reg, val)      bus_space_write_4(sc->aac_btag, \
-                                       sc->aac_bhandle, reg, val)
-#define AAC_GETREG4(sc, reg)           bus_space_read_4 (sc->aac_btag, \
-                                       sc->aac_bhandle, reg)
-#define AAC_SETREG2(sc, reg, val)      bus_space_write_2(sc->aac_btag, \
-                                       sc->aac_bhandle, reg, val)
-#define AAC_GETREG2(sc, reg)           bus_space_read_2 (sc->aac_btag, \
-                                       sc->aac_bhandle, reg)
-#define AAC_SETREG1(sc, reg, val)      bus_space_write_1(sc->aac_btag, \
-                                       sc->aac_bhandle, reg, val)
-#define AAC_GETREG1(sc, reg)           bus_space_read_1 (sc->aac_btag, \
-                                       sc->aac_bhandle, reg)
-
-/* Define the OS version specific locks */
-typedef struct lock aac_lock_t;
-#define AAC_LOCK_INIT(l, s)    lockinit(l, s, 0, LK_CANRECURSE)
-#define AAC_LOCK_ACQUIRE(l)    lockmgr(l, LK_EXCLUSIVE)
-#define AAC_LOCK_RELEASE(l)    lockmgr(l, LK_RELEASE)
+#define AAC_MEM0_SETREG4(sc, reg, val) bus_space_write_4(sc->aac_btag0, \
+                                       sc->aac_bhandle0, reg, val)
+#define AAC_MEM0_GETREG4(sc, reg)      bus_space_read_4(sc->aac_btag0, \
+                                       sc->aac_bhandle0, reg)
+#define AAC_MEM0_SETREG2(sc, reg, val) bus_space_write_2(sc->aac_btag0, \
+                                       sc->aac_bhandle0, reg, val)
+#define AAC_MEM0_GETREG2(sc, reg)      bus_space_read_2(sc->aac_btag0, \
+                                       sc->aac_bhandle0, reg)
+#define AAC_MEM0_SETREG1(sc, reg, val) bus_space_write_1(sc->aac_btag0, \
+                                       sc->aac_bhandle0, reg, val)
+#define AAC_MEM0_GETREG1(sc, reg)      bus_space_read_1(sc->aac_btag0, \
+                                       sc->aac_bhandle0, reg)
+
+#define AAC_MEM1_SETREG4(sc, reg, val) bus_space_write_4(sc->aac_btag1, \
+                                       sc->aac_bhandle1, reg, val)
+#define AAC_MEM1_GETREG4(sc, reg)      bus_space_read_4(sc->aac_btag1, \
+                                       sc->aac_bhandle1, reg)
+#define AAC_MEM1_SETREG2(sc, reg, val) bus_space_write_2(sc->aac_btag1, \
+                                       sc->aac_bhandle1, reg, val)
+#define AAC_MEM1_GETREG2(sc, reg)      bus_space_read_2(sc->aac_btag1, \
+                                       sc->aac_bhandle1, reg)
+#define AAC_MEM1_SETREG1(sc, reg, val) bus_space_write_1(sc->aac_btag1, \
+                                       sc->aac_bhandle1, reg, val)
+#define AAC_MEM1_GETREG1(sc, reg)      bus_space_read_1(sc->aac_btag1, \
+                                       sc->aac_bhandle1, reg)
+
+/* fib context (IOCTL) */
+struct aac_fib_context {
+       u_int32_t               unique;
+       int                     ctx_idx;
+       int                     ctx_wrap;
+       struct aac_fib_context *next, *prev;
+};
 
 /*
  * Per-controller structure.
  */
-struct aac_softc 
+struct aac_softc
 {
        /* bus connections */
        device_t                aac_dev;
-       struct callout          aac_watchdog;
-       struct resource         *aac_regs_resource;     /* register interface
-                                                        * window */
-       int                     aac_regs_rid;           /* resource ID */
-       bus_space_handle_t      aac_bhandle;            /* bus space handle */
-       bus_space_tag_t         aac_btag;               /* bus space tag */
+       struct resource         *aac_regs_res0, *aac_regs_res1; /* reg. if. window */
+       int                     aac_regs_rid0, aac_regs_rid1;           /* resource ID */
+       bus_space_handle_t      aac_bhandle0, aac_bhandle1;             /* bus space handle */
+       bus_space_tag_t         aac_btag0, aac_btag1;           /* bus space tag */
        bus_dma_tag_t           aac_parent_dmat;        /* parent DMA tag */
        bus_dma_tag_t           aac_buffer_dmat;        /* data buffer/command
                                                         * DMA tag */
@@ -301,7 +324,7 @@ struct aac_softc
        /* controller features, limits and status */
        int                     aac_state;
 #define AAC_STATE_SUSPEND      (1<<0)
-#define        AAC_STATE_OPEN          (1<<1)
+#define        AAC_STATE_UNUSED0       (1<<1)
 #define AAC_STATE_INTERRUPTS_ON        (1<<2)
 #define AAC_STATE_AIF_SLEEPER  (1<<3)
        struct FsaRevision              aac_revision;
@@ -310,8 +333,8 @@ struct aac_softc
        int                     aac_hwif;
 #define AAC_HWIF_I960RX                0
 #define AAC_HWIF_STRONGARM     1
-#define AAC_HWIF_FALCON                2
 #define AAC_HWIF_RKT           3
+#define        AAC_HWIF_NARK           4
 #define AAC_HWIF_UNKNOWN       -1
        bus_dma_tag_t           aac_common_dmat;        /* common structure
                                                         * DMA tag */
@@ -328,18 +351,12 @@ struct aac_softc
        struct aac_command      *aac_commands;
 
        /* command management */
-       TAILQ_HEAD(,aac_command) aac_free;      /* command structures 
+       TAILQ_HEAD(,aac_command) aac_free;      /* command structures
                                                 * available for reuse */
        TAILQ_HEAD(,aac_command) aac_ready;     /* commands on hold for
                                                 * controller resources */
        TAILQ_HEAD(,aac_command) aac_busy;
-       TAILQ_HEAD(,aac_command) aac_complete;  /* commands which have been
-                                                * returned by the controller */
-       TAILQ_HEAD(,aac_command) aac_aif;
-#if 0
-       TAILQ_HEAD(,aac_command) aac_norm;
-#endif
-       TAILQ_HEAD(,aac_event)  aac_ev_cmfree;
+       TAILQ_HEAD(,aac_event)  aac_ev_cmfree;
        struct bio_queue_head   aac_bioq;
        struct aac_queue_table  *aac_queues;
        struct aac_queue_entry  *aac_qentries[AAC_QUEUE_COUNT];
@@ -348,13 +365,13 @@ struct aac_softc
 
        /* connected containters */
        TAILQ_HEAD(,aac_container)      aac_container_tqh;
-       aac_lock_t              aac_container_lock;
+       struct lock             aac_container_lock;
 
        /*
         * The general I/O lock.  This protects the sync fib, the lists, the
         * queues, and the registers.
         */
-       aac_lock_t              aac_io_lock;
+       struct lock             aac_io_lock;
 
        /* delayed activity infrastructure */
        struct task             aac_task_complete;      /* deferred-completion
@@ -362,11 +379,12 @@ struct aac_softc
        struct intr_config_hook aac_ich;
 
        /* management interface */
-       cdev_t                  aac_dev_t;
-       aac_lock_t              aac_aifq_lock;
-       struct aac_aif_command  aac_aifq[AAC_AIFQ_LENGTH];
-       int                     aac_aifq_head;
-       int                     aac_aifq_tail;
+       struct cdev *aac_dev_t;
+       struct lock             aac_aifq_lock;
+       struct aac_fib          aac_aifq[AAC_AIFQ_LENGTH];
+       int                     aifq_idx;
+       int                     aifq_filled;
+       struct aac_fib_context *fibctx;
        struct kqinfo           rcv_kq;
        struct thread           *aifthread;
        int                     aifflags;
@@ -385,25 +403,31 @@ struct aac_softc
 #define        AAC_FLAGS_CAM_PASSONLY  (1 << 3)        /* Only create pass devices */
 #define        AAC_FLAGS_SG_64BIT      (1 << 4)        /* Use 64-bit S/G addresses */
 #define        AAC_FLAGS_4GB_WINDOW    (1 << 5)        /* Device can access host mem
-                                                * 2GB-4GB range */
+                                                * 2GB-4GB range */
 #define        AAC_FLAGS_NO4GB         (1 << 6)        /* Can't access host mem >2GB */
 #define        AAC_FLAGS_256FIBS       (1 << 7)        /* Can only do 256 commands */
-#define AAC_FLAGS_BROKEN_MEMMAP        (1 << 8)        /* Broken HostPhysMemPages */
-#define AAC_FLAGS_SLAVE                (1 << 9)
+#define        AAC_FLAGS_BROKEN_MEMMAP (1 << 8)        /* Broken HostPhysMemPages */
+#define AAC_FLAGS_SLAVE        (1 << 9)
 #define AAC_FLAGS_MASTER       (1 << 10)
 #define AAC_FLAGS_NEW_COMM     (1 << 11)       /* New comm. interface supported */
 #define AAC_FLAGS_RAW_IO       (1 << 12)       /* Raw I/O interface */
 #define AAC_FLAGS_ARRAY_64BIT  (1 << 13)       /* 64-bit array size */
-  
+#define        AAC_FLAGS_LBA_64BIT     (1 << 14)       /* 64-bit LBA support */
+
        u_int32_t               supported_options;
        u_int32_t               scsi_method_id;
        TAILQ_HEAD(,aac_sim)    aac_sim_tqh;
 
+       struct callout  aac_daemontime;         /* clock daemon callout */
+
        u_int32_t       aac_max_fibs;           /* max. FIB count */
-       u_int32_t       aac_max_fibs_alloc;     /* max. alloc. per alloc_commands() */
-       u_int32_t       aac_max_fib_size;       /* max. FIB size */
-       u_int32_t       aac_sg_tablesize;       /* max. sg count from host */
-       u_int32_t       aac_max_sectors;        /* max. I/O size from host (blocks) */
+       u_int32_t       aac_max_fibs_alloc;             /* max. alloc. per alloc_commands() */
+       u_int32_t       aac_max_fib_size;               /* max. FIB size */
+       u_int32_t       aac_sg_tablesize;               /* max. sg count from host */
+       u_int32_t       aac_max_sectors;                /* max. I/O size from host (blocks) */
+#define AAC_CAM_TARGET_WILDCARD ~0
+       void                    (*cam_rescan_cb)(struct aac_softc *, uint32_t,
+                                   uint32_t);
 };
 
 /*
@@ -411,7 +435,7 @@ struct aac_softc
  */
 #define AAC_EVENT_NONE         0x00
 #define AAC_EVENT_CMFREE       0x01
-#define AAC_EVENT_MASK         0xff
+#define        AAC_EVENT_MASK          0xff
 #define AAC_EVENT_REPEAT       0x100
 
 typedef void aac_event_cb_t(struct aac_softc *sc, struct aac_event *event,
@@ -423,26 +447,19 @@ struct aac_event {
        void                    *ev_arg;
 };
 
-#ifndef AAC_DRIVER_BUILD
-# define AAC_DRIVER_BUILD 1
-#endif
-
 /*
  * Public functions
  */
 extern void            aac_free(struct aac_softc *sc);
 extern int             aac_attach(struct aac_softc *sc);
 extern int             aac_detach(device_t dev);
-extern int             aac_suspend(device_t dev); 
+extern int             aac_shutdown(device_t dev);
+extern int             aac_suspend(device_t dev);
 extern int             aac_resume(device_t dev);
 extern void            aac_new_intr(void *arg);
-extern void            aac_fast_intr(void *arg);
-extern devclass_t      aac_devclass;
+extern void            aac_filter(void *arg);
 extern void            aac_submit_bio(struct aac_disk *ad, struct bio *bio);
 extern void            aac_biodone(struct bio *bio, const char *code);
-extern int             aac_dump_enqueue(struct aac_disk *ad, u_int64_t lba,
-                                        void *data, int nblks);
-extern void            aac_dump_complete(struct aac_softc *sc);
 extern void            aac_startio(struct aac_softc *sc);
 extern int             aac_alloc_command(struct aac_softc *sc,
                                          struct aac_command **cmp);
@@ -453,32 +470,33 @@ extern int                aac_sync_fib(struct aac_softc *sc, u_int32_t command,
 extern void            aac_add_event(struct aac_softc *sc, struct aac_event
                                      *event);
 
-/*
- * Debugging levels:
- *  0 - quiet, only emit warnings
- *  1 - noisy, emit major function points and things done
- *  2 - extremely noisy, emit trace items in loops, etc.
- */
 #ifdef AAC_DEBUG
-# define debug(level, fmt, args...)                                    \
-       do {                                                            \
-       if (level <=AAC_DEBUG) kprintf("%s: " fmt "\n", __func__ , ##args); \
-       } while (0)
-# define debug_called(level)                                           \
-       do {                                                            \
-       if (level <= AAC_DEBUG) kprintf("%s: called\n", __func__); \
-       } while (0)
-
+extern int     aac_debug_enable;
+# define fwprintf(sc, flags, fmt, args...)                             \
+do {                                                                   \
+       if (!aac_debug_enable)                                          \
+               break;                                                  \
+       if (sc != NULL)                                                 \
+               device_printf(((struct aac_softc *)sc)->aac_dev,        \
+                   "%s: " fmt "\n", __func__, ##args);                 \
+       else                                                            \
+               kprintf("%s: " fmt "\n", __func__, ##args);             \
+} while(0)
+
+extern void    aac_print_queues(struct aac_softc *sc);
+extern void    aac_panic(struct aac_softc *sc, char *reason);
 extern void    aac_print_fib(struct aac_softc *sc, struct aac_fib *fib,
                              const char *caller);
 extern void    aac_print_aif(struct aac_softc *sc,
                              struct aac_aif_command *aif);
 
-# define AAC_PRINT_FIB(sc, fib)        aac_print_fib(sc, fib, __func__)
+#define AAC_PRINT_FIB(sc, fib) aac_print_fib(sc, fib, __func__)
 
 #else
-# define debug(level, fmt, args...)
-# define debug_called(level)
+# define fwprintf(sc, flags, fmt, args...)
+
+# define aac_print_queues(sc)
+# define aac_panic(sc, reason)
 
 # define AAC_PRINT_FIB(sc, fib)
 # define aac_print_aif(sc, aac_aif_command)
@@ -522,7 +540,7 @@ static __inline void                                                        \
 aac_enqueue_ ## name (struct aac_command *cm)                          \
 {                                                                      \
        if ((cm->cm_flags & AAC_ON_AACQ_MASK) != 0) {                   \
-               kprintf("command %p is on another queue, flags = %#x\n",        \
+               kprintf("command %p is on another queue, flags = %#x\n", \
                       cm, cm->cm_flags);                               \
                panic("command is on another queue");                   \
        }                                                               \
@@ -534,7 +552,7 @@ static __inline void                                                        \
 aac_requeue_ ## name (struct aac_command *cm)                          \
 {                                                                      \
        if ((cm->cm_flags & AAC_ON_AACQ_MASK) != 0) {                   \
-               kprintf("command %p is on another queue, flags = %#x\n",        \
+               kprintf("command %p is on another queue, flags = %#x\n", \
                       cm, cm->cm_flags);                               \
                panic("command is on another queue");                   \
        }                                                               \
@@ -549,8 +567,8 @@ aac_dequeue_ ## name (struct aac_softc *sc)                         \
                                                                        \
        if ((cm = TAILQ_FIRST(&sc->aac_ ## name)) != NULL) {            \
                if ((cm->cm_flags & AAC_ON_ ## index) == 0) {           \
-                       kprintf("command %p not in queue, flags = %#x, "        \
-                              "bit = %#x\n", cm, cm->cm_flags,         \
+                       kprintf("command %p not in queue, flags = %#x, " \
+                              "bit = %#x\n", cm, cm->cm_flags,         \
                               AAC_ON_ ## index);                       \
                        panic("command not in queue");                  \
                }                                                       \
@@ -564,7 +582,7 @@ static __inline void                                                        \
 aac_remove_ ## name (struct aac_command *cm)                           \
 {                                                                      \
        if ((cm->cm_flags & AAC_ON_ ## index) == 0) {                   \
-               kprintf("command %p not in queue, flags = %#x, "                \
+               kprintf("command %p not in queue, flags = %#x, "        \
                       "bit = %#x\n", cm, cm->cm_flags,                 \
                       AAC_ON_ ## index);                               \
                panic("command not in queue");                          \
@@ -578,7 +596,6 @@ struct hack
 AACQ_COMMAND_QUEUE(free, AACQ_FREE);
 AACQ_COMMAND_QUEUE(ready, AACQ_READY);
 AACQ_COMMAND_QUEUE(busy, AACQ_BUSY);
-AACQ_COMMAND_QUEUE(complete, AACQ_COMPLETE);
 
 /*
  * outstanding bio queue
@@ -591,22 +608,22 @@ aac_initq_bio(struct aac_softc *sc)
 }
 
 static __inline void
-aac_enqueue_bio(struct aac_softc *sc, struct bio *bio)
+aac_enqueue_bio(struct aac_softc *sc, struct bio *bp)
 {
-       bioqdisksort(&sc->aac_bioq, bio);
+       bioq_insert_tail(&sc->aac_bioq, bp);
        AACQ_ADD(sc, AACQ_BIO);
 }
 
 static __inline struct bio *
 aac_dequeue_bio(struct aac_softc *sc)
 {
-       struct bio *bio;
+       struct bio *bp;
 
-       if ((bio = bioq_first(&sc->aac_bioq)) != NULL) {
-               bioq_remove(&sc->aac_bioq, bio);
+       if ((bp = bioq_first(&sc->aac_bioq)) != NULL) {
+               bioq_remove(&sc->aac_bioq, bp);
                AACQ_REMOVE(sc, AACQ_BIO);
        }
-       return(bio);
+       return(bp);
 }
 
 static __inline void