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;
 	}
