Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/ata fix some probles with ataraid(4) and Intel Matri...



details:   https://anonhg.NetBSD.org/src/rev/d856fd13b521
branches:  trunk
changeset: 756103:d856fd13b521
user:      bsh <bsh%NetBSD.org@localhost>
date:      Tue Jul 06 18:03:21 2010 +0000

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

diffstat:

 sys/dev/ata/ata_raid.c       |  10 +---
 sys/dev/ata/ata_raid_intel.c |  82 ++++++++++++++++++++++++++++++++++++++-----
 sys/dev/ata/ata_raidvar.h    |  13 +++---
 3 files changed, 81 insertions(+), 24 deletions(-)

diffs (224 lines):

diff -r 5229ea4041aa -r d856fd13b521 sys/dev/ata/ata_raid.c
--- a/sys/dev/ata/ata_raid.c    Tue Jul 06 18:01:14 2010 +0000
+++ b/sys/dev/ata/ata_raid.c    Tue Jul 06 18:03:21 2010 +0000
@@ -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) {
diff -r 5229ea4041aa -r d856fd13b521 sys/dev/ata/ata_raid_intel.c
--- a/sys/dev/ata/ata_raid_intel.c      Tue Jul 06 18:01:14 2010 +0000
+++ b/sys/dev/ata/ata_raid_intel.c      Tue Jul 06 18:03:21 2010 +0000
@@ -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 <sos%FreeBSD.org@localhost>
@@ -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;
+}
diff -r 5229ea4041aa -r d856fd13b521 sys/dev/ata/ata_raidvar.h
--- a/sys/dev/ata/ata_raidvar.h Tue Jul 06 18:01:14 2010 +0000
+++ b/sys/dev/ata/ata_raidvar.h Tue Jul 06 18:03:21 2010 +0000
@@ -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];
 };
 



Home | Main Index | Thread Index | Old Index