diff -r d8ec6a195b58 src/sys/dev/ata/ata_raid.c
--- a/src/sys/dev/ata/ata_raid.c        Tue Jun 01 00:42:40 2010 +0900
+++ b/src/sys/dev/ata/ata_raid.c        Wed Jun 02 23:02:46 2010 +0900
@@ -270,14 +270,10 @@
       aai = malloc(sizeof(*aai), M_DEVBUF, M_WAITOK | M_ZERO);
       aai->aai_type = type;
       aai->aai_arrayno = arrayno;
+       aai->aai_curdisk = 0;

       ataraid_array_info_count++;

-       if (TAILQ_EMPTY(&ataraid_array_info_list)) {
-               TAILQ_INSERT_TAIL(&ataraid_array_info_list, aai, aai_list);
-               goto out;
-       }
-
       /* Sort it into the list: type first, then array number. */
       TAILQ_FOREACH(laai, &ataraid_array_info_list, aai_list) {
               if (aai->aai_type < laai->aai_type) {
diff -r d8ec6a195b58 src/sys/dev/ata/ata_raid_intel.c
--- a/src/sys/dev/ata/ata_raid_intel.c  Tue Jun 01 00:42:40 2010 +0900
+++ b/src/sys/dev/ata/ata_raid_intel.c  Wed Jun 02 23:02:46 2010 +0900
@@ -62,6 +62,9 @@
#define        DPRINTF(x)      /* nothing */
#endif

+static int find_volume_id(struct intel_raid_conf *);
+
+
#ifdef ATA_RAID_DEBUG
static const char *
ata_raid_intel_type(int type)
@@ -139,10 +142,10 @@
       struct ataraid_disk_info *adi;
       struct vnode *vp;
       uint32_t checksum, *ptr;
-       static int curdrive;
       int bmajor, count, curvol = 0, error = 0;
       char *tmp;
       dev_t dev;
+       int volumeid, diskidx;

       info = malloc(1536, M_DEVBUF, M_WAITOK|M_ZERO);

@@ -203,11 +206,19 @@
       /* This one points to the first volume */
       map = (struct intel_raid_mapping *)&info->disk[info->total_disks];

+       volumeid = find_volume_id(info);
+       if (volumeid < 0) {
+               aprint_error_dev(sc->sc_dev,
+                                "too many RAID arrays\n");
+               error = ENOMEM;
+               goto out;
+       }
+
findvol:
       /*
        * Lookup or allocate a new array info structure for this array.
        */
-       aai = ata_raid_get_array_info(ATA_RAID_TYPE_INTEL, curvol);
+       aai = ata_raid_get_array_info(ATA_RAID_TYPE_INTEL, volumeid + curvol);

       /* Fill in array info */
       aai->aai_generation = info->generation;
@@ -241,7 +252,7 @@

       aai->aai_type = ATA_RAID_TYPE_INTEL;
       aai->aai_capacity = map->total_sectors;
-       aai->aai_interleave = map->stripe_sectors / 2;
+       aai->aai_interleave = map->stripe_sectors;
       aai->aai_ndisks = map->total_disks;
       aai->aai_heads = 255;
       aai->aai_sectors = 63;
@@ -253,24 +264,26 @@
               strlcpy(aai->aai_name, map->name, sizeof(aai->aai_name));

       /* Fill in disk info */
-       adi = &aai->aai_disks[curdrive];
+       diskidx = aai->aai_curdisk++;
+       adi = &aai->aai_disks[diskidx];
       adi->adi_status = 0;

-       if (info->disk[curdrive].flags & INTEL_F_ONLINE)
+       if (info->disk[diskidx].flags & INTEL_F_ONLINE)
               adi->adi_status |= ADI_S_ONLINE;
-       if (info->disk[curdrive].flags & INTEL_F_ASSIGNED)
+       if (info->disk[diskidx].flags & INTEL_F_ASSIGNED)
               adi->adi_status |= ADI_S_ASSIGNED;
-       if (info->disk[curdrive].flags & INTEL_F_SPARE) {
+       if (info->disk[diskidx].flags & INTEL_F_SPARE) {
               adi->adi_status &= ~ADI_S_ONLINE;
               adi->adi_status |= ADI_S_SPARE;
       }
-       if (info->disk[curdrive].flags & INTEL_F_DOWN)
+       if (info->disk[diskidx].flags & INTEL_F_DOWN)
               adi->adi_status &= ~ADI_S_ONLINE;

       if (adi->adi_status) {
               adi->adi_dev = sc->sc_dev;
-               adi->adi_sectors = info->disk[curdrive].sectors;
+               adi->adi_sectors = info->disk[diskidx].sectors;
               adi->adi_compsize = adi->adi_sectors - aai->aai_reserved;
+
               /*
                * Check if that is the only volume, otherwise repeat
                * the process to find more.
@@ -281,10 +294,57 @@
                           &map->disk_idx[map->total_disks];
                       goto findvol;
               }
-               curdrive++;
       }

 out:
       free(info, M_DEVBUF);
       return error;
}
+
+
+/*
+ * Assign `volume id' to RAID volumes.
+ */
+static struct {
+       /* We assume disks are on the same array if these three values
+          are same. */
+       uint32_t config_id;
+       uint32_t generation;
+       uint32_t checksum;
+
+       int id;
+} array_note[10]; /* XXX: this array is not used after ld_ataraid is
+                  * configured. */
+
+static int n_array = 0;
+static int volume_id = 0;
+
+static int
+find_volume_id(struct intel_raid_conf *info)
+{
+       int i, ret;
+
+       for (i=0; i < n_array; ++i) {
+               if (info->checksum == array_note[i].checksum &&
+                   info->config_id == array_note[i].config_id &&
+                   info->generation == array_note[i].generation) {
+                       /* we have already seen this array */
+                       return array_note[i].id;
+               }
+       }
+
+       if (n_array >= __arraycount(array_note)) {
+               /* Too many arrays */
+               return -1;
+       }
+
+       array_note[n_array].checksum = info->checksum;
+       array_note[n_array].config_id = info->config_id;
+       array_note[n_array].generation = info->generation;
+       array_note[n_array].id = ret = volume_id;
+
+       /* Allocate volume ids for all volumes in this array */
+       volume_id += info->total_volumes;
+       ++n_array;
+       return ret;
+}
diff -r d8ec6a195b58 src/sys/dev/ata/ata_raidvar.h
--- a/src/sys/dev/ata/ata_raidvar.h     Tue Jun 01 00:42:40 2010 +0900
+++ b/src/sys/dev/ata/ata_raidvar.h     Wed Jun 02 23:02:46 2010 +0900
@@ -67,8 +67,8 @@
struct ataraid_disk_info {
       device_t adi_dev;               /* disk's device */
       int     adi_status;             /* disk's status */
-       u_int   adi_sectors;
-       u_int   adi_compsize;           /* in sectors */
+       uint64_t        adi_sectors;
+       uint64_t        adi_compsize;           /* in sectors */
};

/* adi_status */
@@ -94,12 +94,13 @@
       u_int   aai_heads;              /* tracks/cyl */
       u_int   aai_sectors;            /* secs/track */
       u_int   aai_cylinders;          /* cyl/unit */
-       u_int   aai_capacity;           /* in sectors */
-       u_int   aai_offset;             /* component start offset */
-       u_int   aai_reserved;           /* component reserved sectors */
+       uint64_t        aai_capacity;           /* in sectors */
+       daddr_t         aai_offset;             /* component start offset */
+       uint64_t        aai_reserved;           /* component reserved sectors */

       char    aai_name[32];           /* array volume name */

+       uint aai_curdisk;       /* to enumerate component disks */
       struct ataraid_disk_info aai_disks[ATA_RAID_MAX_DISKS];
};

diff -r d8ec6a195b58 src/sys/dev/ata/ld_ataraid.c
--- a/src/sys/dev/ata/ld_ataraid.c      Tue Jun 01 00:42:40 2010 +0900
+++ b/src/sys/dev/ata/ld_ataraid.c      Wed Jun 02 23:02:46 2010 +0900
@@ -621,6 +621,7 @@
{
       struct ataraid_array_info *aai = sc->sc_aai;
       struct ld_softc *ld = &sc->sc_ld;
+#define        to_kibytes(ld,s)        (ld->sc_secsize*(s)/1024)

       /* Fill in data for _this_ volume */
       bv->bv_percent = -1;
@@ -640,7 +641,7 @@
       switch (aai->aai_level) {
       case AAI_L_SPAN:
       case AAI_L_RAID0:
-               bv->bv_stripe_size = aai->aai_interleave;
+               bv->bv_stripe_size = to_kibytes(ld, aai->aai_interleave);
               bv->bv_level = 0;
               break;
       case AAI_L_RAID1:
@@ -648,7 +649,7 @@
               bv->bv_level = 1;
               break;
       case AAI_L_RAID5:
-               bv->bv_stripe_size = aai->aai_interleave;
+               bv->bv_stripe_size = to_kibytes(ld, aai->aai_interleave);
               bv->bv_level = 5;
               break;
       }