Index: sys/dev/ic/aac.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/aac.c,v
retrieving revision 1.40
diff -u -r1.40 aac.c
--- sys/dev/ic/aac.c    8 Jun 2008 12:43:51 -0000       1.40
+++ sys/dev/ic/aac.c    29 Sep 2008 13:33:19 -0000
@@ -458,10 +458,8 @@
                   (sc->sc_if.aif_send_command != NULL)) {
                       sc->sc_quirks |= AAC_QUIRK_NEW_COMM;
               }
-#ifdef notyet
               if (opts & AAC_SUPPORTED_64BIT_ARRAYSIZE)
                       sc->sc_quirks |= AAC_QUIRK_ARRAY_64BIT;
-#endif
       }

       sc->sc_max_fibs = (sc->sc_quirks & AAC_QUIRK_256FIBS) ? 256 : 512;
@@ -538,6 +536,16 @@

       sc->sc_max_fibs_alloc = PAGE_SIZE / sc->sc_max_fib_size;

+       if (sc->sc_max_fib_size > sizeof(struct aac_fib)) {
+               sc->sc_quirks |= AAC_QUIRK_RAW_IO;
+               aprint_debug_dev(&sc->sc_dv, "Enable raw I/O\n");
+       }
+       if ((sc->sc_quirks & AAC_QUIRK_RAW_IO) &&
+           (sc->sc_quirks & AAC_QUIRK_ARRAY_64BIT)) {
+               sc->sc_quirks |= AAC_QUIRK_LBA_64BIT;
+               aprint_normal_dev(&sc->sc_dv, "Enable 64-bit array support\n");
+       }
+
       return (0);
}

@@ -632,10 +640,8 @@
        */
       ip = &sc->sc_common->ac_init;
       ip->InitStructRevision = htole32(AAC_INIT_STRUCT_REVISION);
-       if (sc->sc_max_fib_size > sizeof(struct aac_fib)) {
+       if (sc->sc_quirks & AAC_QUIRK_RAW_IO)
               ip->InitStructRevision = htole32(AAC_INIT_STRUCT_REVISION_4);
-               sc->sc_quirks |= AAC_QUIRK_RAW_IO;
-       }
       ip->MiniPortRevision = htole32(AAC_INIT_STRUCT_MINIPORT_REVISION);

       ip->AdapterFibsPhysicalAddress = htole32(sc->sc_common_seg.ds_addr +
@@ -812,6 +818,7 @@
       struct aac_mntinforesponse mir;
       struct aac_drive *hd;
       u_int16_t rsize;
+       size_t ersize;
       int i;

       /*
@@ -824,7 +831,14 @@
                * Request information on this container.
                */
               memset(&mi, 0, sizeof(mi));
-               mi.Command = htole32(VM_NameServe);
+               /* use 64-bit LBA if enabled */
+               if (sc->sc_quirks & AAC_QUIRK_LBA_64BIT) {
+                       mi.Command = htole32(VM_NameServe64);
+                       ersize = sizeof(mir);
+               } else {
+                       mi.Command = htole32(VM_NameServe);
+                       ersize = sizeof(mir) - sizeof(mir.MntTable[0].CapacityHigh);
+               }
               mi.MntType = htole32(FT_FILESYS);
               mi.MntCount = htole32(i);
               if (aac_sync_fib(sc, ContainerCommand, 0, &mi, sizeof(mi), &mir,
@@ -832,9 +846,9 @@
                       aprint_error_dev(&sc->sc_dv, "error probing container %d\n", i);
                       continue;
               }
-               if (rsize != sizeof(mir)) {
+               if (rsize != ersize) {
                       aprint_error_dev(&sc->sc_dv, "container info response wrong size "
-                           "(%d should be %zu)\n", rsize, sizeof(mir));
+                           "(%d should be %zu)\n", rsize, ersize);
                       continue;
               }

@@ -848,6 +862,9 @@

               hd->hd_present = 1;
               hd->hd_size = le32toh(mir.MntTable[0].Capacity);
+               if (sc->sc_quirks & AAC_QUIRK_LBA_64BIT)
+                       hd->hd_size += (u_int64_t)
+                           le32toh(mir.MntTable[0].CapacityHigh) << 32;
               hd->hd_devtype = le32toh(mir.MntTable[0].VolType);
               hd->hd_size &= ~0x1f;
               sc->sc_nunits++;
Index: sys/dev/ic/aacreg.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/aacreg.h,v
retrieving revision 1.12
diff -u -r1.12 aacreg.h
--- sys/dev/ic/aacreg.h 8 Sep 2008 23:36:54 -0000       1.12
+++ sys/dev/ic/aacreg.h 29 Sep 2008 13:33:19 -0000
@@ -535,6 +535,7 @@
               u_int32_t pad[8];
       } ObjExtension;
       u_int32_t AlterEgoId;
+       u_int32_t CapacityHigh; /* Only if VM_NameServe64 */
} __packed;

struct aac_mntinfo {
Index: sys/dev/ic/aacvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/aacvar.h,v
retrieving revision 1.12
diff -u -r1.12 aacvar.h
--- sys/dev/ic/aacvar.h 28 Apr 2008 20:23:48 -0000      1.12
+++ sys/dev/ic/aacvar.h 29 Sep 2008 13:33:19 -0000
@@ -160,6 +160,7 @@
#define AAC_QUIRK_NEW_COMM     (1 << 11)       /* New comm. i/f supported */
#define AAC_QUIRK_RAW_IO       (1 << 12)       /* Raw I/O interface */
#define AAC_QUIRK_ARRAY_64BIT  (1 << 13)       /* 64-bit array size */
+#define AAC_QUIRK_LBA_64BIT    (1 << 14)       /* 64-bit LBA support */


/*
@@ -284,7 +285,7 @@
struct aac_drive {
       u_int   hd_present;
       u_int   hd_devtype;
-       u_int   hd_size;
+       u_int64_t       hd_size;
};

/*
Index: sys/dev/ic/ld_aac.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/ld_aac.c,v
retrieving revision 1.21
diff -u -r1.21 ld_aac.c
--- sys/dev/ic/ld_aac.c 9 Sep 2008 12:45:39 -0000       1.21
+++ sys/dev/ic/ld_aac.c 29 Sep 2008 13:33:19 -0000
@@ -63,7 +63,7 @@

static void    ld_aac_attach(device_t, device_t, void *);
static void    ld_aac_intr(struct aac_ccb *);
-static int     ld_aac_dobio(struct ld_aac_softc *, void *, int, int, int,
+static int     ld_aac_dobio(struct ld_aac_softc *, void *, int, daddr_t, int,
                            struct buf *);
static int     ld_aac_dump(struct ld_softc *, void *, int, int);
static int     ld_aac_match(device_t, cfdata_t, void *);
@@ -106,7 +106,7 @@
}

static int
-ld_aac_dobio(struct ld_aac_softc *sc, void *data, int datasize, int blkno,
+ld_aac_dobio(struct ld_aac_softc *sc, void *data, int datasize, daddr_t blkno,
            int dowrite, struct buf *bp)
{
       struct aac_blockread_response *brr;
@@ -145,7 +145,37 @@
           AAC_FIBSTATE_REXPECTED | AAC_FIBSTATE_NORM |
           AAC_FIBSTATE_ASYNC | AAC_FIBSTATE_FAST_RESPONSE );

-       if ((aac->sc_quirks & AAC_QUIRK_SG_64BIT) == 0) {
+       if (aac->sc_quirks & AAC_QUIRK_RAW_IO) {
+               struct aac_raw_io *raw;
+               struct aac_sg_entryraw *sge;
+               struct aac_sg_tableraw *sgt;
+
+               raw = (struct aac_raw_io *)&fib->data[0];
+               fib->Header.Command = htole16(RawIo);
+               raw->BlockNumber = htole64(blkno);
+               raw->ByteCount = htole32(datasize);
+               raw->ContainerId = htole16(sc->sc_hwunit);
+               raw->BpTotal = 0;
+               raw->BpComplete = 0;
+               size = sizeof(struct aac_raw_io);
+               sgt = &raw->SgMapRaw;
+               raw->Flags = (dowrite ? 0 : 1);
+
+               xfer = ac->ac_dmamap_xfer;
+               sgt->SgCount = xfer->dm_nsegs;
+               sge = sgt->SgEntryRaw;
+
+               for (i = 0; i < xfer->dm_nsegs; i++, sge++) {
+                       sge->SgAddress = htole64(xfer->dm_segs[i].ds_addr);
+                       sge->SgByteCount = htole32(xfer->dm_segs[i].ds_len);
+                       sge->Next = 0;
+                       sge->Prev = 0;
+                       sge->Flags = 0;
+               }
+               size += xfer->dm_nsegs * sizeof(struct aac_sg_entryraw);
+               size = sizeof(fib->Header) + size;
+               fib->Header.Size = htole16(size);
+       } else if ((aac->sc_quirks & AAC_QUIRK_SG_64BIT) == 0) {
               struct aac_blockread *br;
               struct aac_blockwrite *bw;
               struct aac_sg_entry *sge;
@@ -188,7 +218,7 @@
               }

               size += xfer->dm_nsegs * sizeof(struct aac_sg_entry);
-               size = htole16(sizeof(fib->Header) + size);
+               size = sizeof(fib->Header) + size;
               fib->Header.Size = htole16(size);
       } else {
               struct aac_blockread64 *br;
@@ -240,7 +270,7 @@
                           (u_long)xfer->dm_segs[i].ds_len));
               }
               size += xfer->dm_nsegs * sizeof(struct aac_sg_entry64);
-               size = htole16(sizeof(fib->Header) + size);
+               size = sizeof(fib->Header) + size;
               fib->Header.Size = htole16(size);
       }