Support multiple volumes connected to Intel MatrixRAID controllers.

Code contributed by Juan RP in PR kern/39552.
This commit is contained in:
tron 2008-09-16 11:45:30 +00:00
parent d17c220979
commit 6264f47cc6
6 changed files with 130 additions and 33 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: ataraid.4,v 1.13 2008/09/15 11:44:50 tron Exp $
.\" $NetBSD: ataraid.4,v 1.14 2008/09/16 11:45:30 tron Exp $
.\"
.\" Copyright (c) 2005 The NetBSD Foundation, Inc.
.\" All rights reserved.
@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE.
.\"
.Dd September 15, 2008
.Dd September 16, 2008
.Dt ATARAID 4
.Os
.Sh NAME
@ -92,7 +92,3 @@ state, and it does not do the right thing.
.Pp
At least part of the reason for this is that the publically-available
information on these formats is quite limited.
.Pp
The support with Intel MatrixRAID controller is incomplete, and only
the first volume found will be used.
This will be fixed in future revisions of this driver.

View File

@ -1,4 +1,4 @@
/* $NetBSD: ata_raid_intel.c,v 1.2 2008/09/15 11:44:50 tron Exp $ */
/* $NetBSD: ata_raid_intel.c,v 1.3 2008/09/16 11:45:30 tron Exp $ */
/*-
* Copyright (c) 2000-2008 Søren Schmidt <sos@FreeBSD.org>
@ -33,7 +33,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ata_raid_intel.c,v 1.2 2008/09/15 11:44:50 tron Exp $");
__KERNEL_RCSID(0, "$NetBSD: ata_raid_intel.c,v 1.3 2008/09/16 11:45:30 tron Exp $");
#include <sys/param.h>
#include <sys/buf.h>
@ -140,7 +140,7 @@ ata_raid_read_config_intel(struct wd_softc *sc)
struct vnode *vp;
uint32_t checksum, *ptr;
static int curdrive;
int bmajor, count, error = 0;
int bmajor, count, curvol = 0, error = 0;
char *tmp;
dev_t dev;
@ -203,14 +203,11 @@ ata_raid_read_config_intel(struct wd_softc *sc)
/* This one points to the first volume */
map = (struct intel_raid_mapping *)&info->disk[info->total_disks];
findvol:
/*
* Lookup or allocate a new array info structure for this array.
*
* TODO:
* We only look at the first volume. Need to solve a few issues before
* multiple volumes are working correctly.
*/
aai = ata_raid_get_array_info(ATA_RAID_TYPE_INTEL, 0);
aai = ata_raid_get_array_info(ATA_RAID_TYPE_INTEL, curvol);
/* Fill in array info */
aai->aai_generation = info->generation;
@ -244,7 +241,7 @@ ata_raid_read_config_intel(struct wd_softc *sc)
aai->aai_type = ATA_RAID_TYPE_INTEL;
aai->aai_capacity = map->total_sectors;
aai->aai_interleave = map->stripe_sectors;
aai->aai_interleave = map->stripe_sectors / 2;
aai->aai_ndisks = map->total_disks;
aai->aai_heads = 255;
aai->aai_sectors = 63;
@ -274,6 +271,16 @@ ata_raid_read_config_intel(struct wd_softc *sc)
adi->adi_dev = sc->sc_dev;
adi->adi_sectors = info->disk[curdrive].sectors;
adi->adi_compsize = adi->adi_sectors - aai->aai_reserved;
/*
* Check if that is the only volume, otherwise repeat
* the process to find more.
*/
if ((curvol + 1) < info->total_volumes) {
curvol++;
map = (struct intel_raid_mapping *)
&map->disk_idx[map->total_disks];
goto findvol;
}
curdrive++;
}

101
sys/dev/ata/ata_raid_subr.c Normal file
View File

@ -0,0 +1,101 @@
/* $NetBSD: ata_raid_subr.c,v 1.1 2008/09/16 11:45:30 tron Exp $ */
/*-
* Copyright (c) 2008 Juan Romero Pardines.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ata_raid_subr.c,v 1.1 2008/09/16 11:45:30 tron Exp $");
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/kernel.h>
#include <sys/dkio.h>
#include <sys/disk.h>
#include <sys/disklabel.h>
#include <sys/fcntl.h>
#include <sys/vnode.h>
#include <sys/kauth.h>
#include <sys/kmem.h>
#include <dev/ata/ata_raidvar.h>
struct ataraid_disk_vnode {
struct ataraid_disk_info *adv_adi;
struct vnode *adv_vnode;
SLIST_ENTRY(ataraid_disk_vnode) adv_next;
};
static SLIST_HEAD(, ataraid_disk_vnode) ataraid_disk_vnode_list =
SLIST_HEAD_INITIALIZER(ataraid_disk_vnode_list);
/*
* Finds the RAW_PART vnode of the block device associated with a component
* by looking at the singly linked list; otherwise creates, opens and
* returns the vnode to the caller.
*/
struct vnode *
ata_raid_disk_vnode_find(struct ataraid_disk_info *adi)
{
struct ataraid_disk_vnode *adv = NULL;
struct vnode *vp = NULL;
device_t devlist;
int bmajor, error = 0;
dev_t dev;
SLIST_FOREACH(adv, &ataraid_disk_vnode_list, adv_next) {
devlist = adv->adv_adi->adi_dev;
if (strcmp(device_xname(devlist),
device_xname(adi->adi_dev)) == 0)
return adv->adv_vnode;
}
adv = NULL;
adv = kmem_zalloc(sizeof(struct ataraid_disk_vnode), KM_SLEEP);
bmajor = devsw_name2blk(device_xname(adi->adi_dev), NULL, 0);
dev = MAKEDISKDEV(bmajor, device_unit(adi->adi_dev), RAW_PART);
error = bdevvp(dev, &vp);
if (error) {
kmem_free(adv, sizeof(struct ataraid_disk_vnode));
return NULL;
}
error = VOP_OPEN(vp, FREAD|FWRITE, NOCRED);
if (error) {
vput(vp);
kmem_free(adv, sizeof(struct ataraid_disk_vnode));
return NULL;
}
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
VOP_UNLOCK(vp, 0);
adv->adv_adi = adi;
adv->adv_vnode = vp;
SLIST_INSERT_HEAD(&ataraid_disk_vnode_list, adv, adv_next);
return adv->adv_vnode;
}

View File

@ -1,4 +1,4 @@
/* $NetBSD: ata_raidvar.h,v 1.9 2008/09/15 11:44:50 tron Exp $ */
/* $NetBSD: ata_raidvar.h,v 1.10 2008/09/16 11:45:30 tron Exp $ */
/*
* Copyright (c) 2003 Wasabi Systems, Inc.
@ -126,6 +126,8 @@ struct ataraid_array_info *ata_raid_get_array_info(u_int, u_int);
int ata_raid_config_block_rw(struct vnode *, daddr_t, void *,
size_t, int);
struct vnode *ata_raid_disk_vnode_find(struct ataraid_disk_info *);
/* Promise RAID support */
int ata_raid_read_config_promise(struct wd_softc *);

View File

@ -1,4 +1,4 @@
# $NetBSD: files.ata,v 1.19 2008/09/11 11:08:50 tron Exp $
# $NetBSD: files.ata,v 1.20 2008/09/16 11:45:30 tron Exp $
#
# Config file and device description for machine-independent devices
# which attach to ATA busses. Included by ports that need it. Ports
@ -18,6 +18,7 @@ file dev/ata/ata.c (ata_hl | atapi) & atabus
# ATA RAID configuration support
defpseudodev ataraid {[vendtype = -1], [unit = -1]}
file dev/ata/ata_raid.c ataraid needs-flag
file dev/ata/ata_raid_subr.c ataraid
file dev/ata/ata_raid_promise.c ataraid
file dev/ata/ata_raid_adaptec.c ataraid
file dev/ata/ata_raid_nvidia.c ataraid

View File

@ -1,4 +1,4 @@
/* $NetBSD: ld_ataraid.c,v 1.31 2008/09/15 11:53:52 tron Exp $ */
/* $NetBSD: ld_ataraid.c,v 1.32 2008/09/16 11:45:30 tron Exp $ */
/*
* Copyright (c) 2003 Wasabi Systems, Inc.
@ -47,7 +47,7 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ld_ataraid.c,v 1.31 2008/09/15 11:53:52 tron Exp $");
__KERNEL_RCSID(0, "$NetBSD: ld_ataraid.c,v 1.32 2008/09/16 11:45:30 tron Exp $");
#include "bio.h"
#include "rnd.h"
@ -143,6 +143,7 @@ ld_ataraid_attach(device_t parent, device_t self, void *aux)
struct ld_ataraid_softc *sc = device_private(self);
struct ld_softc *ld = &sc->sc_ld;
struct ataraid_array_info *aai = aux;
struct ataraid_disk_info *adi = NULL;
const char *level;
struct vnode *vp;
char unklev[32];
@ -215,18 +216,9 @@ ld_ataraid_attach(device_t parent, device_t self, void *aux)
* Configure all the component disks.
*/
for (i = 0; i < aai->aai_ndisks; i++) {
struct ataraid_disk_info *adi = &aai->aai_disks[i];
int bmajor, error;
dev_t dev;
bmajor = devsw_name2blk(device_xname(adi->adi_dev), NULL, 0);
dev = MAKEDISKDEV(bmajor, device_unit(adi->adi_dev), RAW_PART);
error = bdevvp(dev, &vp);
if (error)
break;
error = VOP_OPEN(vp, FREAD|FWRITE, NOCRED);
if (error) {
vput(vp);
adi = &aai->aai_disks[i];
vp = ata_raid_disk_vnode_find(adi);
if (vp == NULL) {
/*
* XXX This is bogus. We should just mark the
* XXX component as FAILED, and write-back new
@ -234,8 +226,6 @@ ld_ataraid_attach(device_t parent, device_t self, void *aux)
*/
break;
}
VOP_UNLOCK(vp, 0);
sc->sc_vnodes[i] = vp;
}
if (i == aai->aai_ndisks) {