Module Name:    src
Committed By:   bsh
Date:           Tue Jul  6 18:03:21 UTC 2010

Modified Files:
        src/sys/dev/ata: ata_raid.c ata_raid_intel.c ata_raidvar.h

Log Message:
fix some probles with ataraid(4) and Intel MatrixRaid.
 * handle volumes largetr than 2TiB.
 * support multiple arrays for Intel Matrix RAID


To generate a diff of this commit:
cvs rdiff -u -r1.33 -r1.34 src/sys/dev/ata/ata_raid.c
cvs rdiff -u -r1.4 -r1.5 src/sys/dev/ata/ata_raid_intel.c
cvs rdiff -u -r1.11 -r1.12 src/sys/dev/ata/ata_raidvar.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/ata/ata_raid.c
diff -u src/sys/dev/ata/ata_raid.c:1.33 src/sys/dev/ata/ata_raid.c:1.34
--- src/sys/dev/ata/ata_raid.c:1.33	Tue May 12 14:07:01 2009
+++ src/sys/dev/ata/ata_raid.c	Tue Jul  6 18:03:21 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata_raid.c,v 1.33 2009/05/12 14:07:01 cegger Exp $	*/
+/*	$NetBSD: ata_raid.c,v 1.34 2010/07/06 18:03:21 bsh Exp $	*/
 
 /*
  * Copyright (c) 2003 Wasabi Systems, Inc.
@@ -40,7 +40,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata_raid.c,v 1.33 2009/05/12 14:07:01 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_raid.c,v 1.34 2010/07/06 18:03:21 bsh Exp $");
 
 #include <sys/param.h>
 #include <sys/buf.h>
@@ -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) {

Index: src/sys/dev/ata/ata_raid_intel.c
diff -u src/sys/dev/ata/ata_raid_intel.c:1.4 src/sys/dev/ata/ata_raid_intel.c:1.5
--- src/sys/dev/ata/ata_raid_intel.c:1.4	Mon May 11 17:14:31 2009
+++ src/sys/dev/ata/ata_raid_intel.c	Tue Jul  6 18:03:21 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata_raid_intel.c,v 1.4 2009/05/11 17:14:31 cegger Exp $	*/
+/*	$NetBSD: ata_raid_intel.c,v 1.5 2010/07/06 18:03:21 bsh Exp $	*/
 
 /*-
  * Copyright (c) 2000-2008 Søren Schmidt <[email protected]>
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ata_raid_intel.c,v 1.4 2009/05/11 17:14:31 cegger Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ata_raid_intel.c,v 1.5 2010/07/06 18:03:21 bsh Exp $");
 
 #include <sys/param.h>
 #include <sys/buf.h>
@@ -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;
@@ -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;
+}

Index: src/sys/dev/ata/ata_raidvar.h
diff -u src/sys/dev/ata/ata_raidvar.h:1.11 src/sys/dev/ata/ata_raidvar.h:1.12
--- src/sys/dev/ata/ata_raidvar.h:1.11	Tue May 12 14:16:53 2009
+++ src/sys/dev/ata/ata_raidvar.h	Tue Jul  6 18:03:21 2010
@@ -1,4 +1,4 @@
-/*	$NetBSD: ata_raidvar.h,v 1.11 2009/05/12 14:16:53 cegger Exp $	*/
+/*	$NetBSD: ata_raidvar.h,v 1.12 2010/07/06 18:03:21 bsh Exp $	*/
 
 /*
  * Copyright (c) 2003 Wasabi Systems, Inc.
@@ -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];
 };
 

Reply via email to