Add support for status reports via bio(4) to ataraid(4).

The code was contributed by Juan RP in PR kern/39514.
This commit is contained in:
tron 2008-09-15 11:44:50 +00:00
parent 38d7b7ba2e
commit 25f901a460
6 changed files with 186 additions and 12 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: ataraid.4,v 1.12 2008/09/11 11:18:11 wiz Exp $ .\" $NetBSD: ataraid.4,v 1.13 2008/09/15 11:44:50 tron Exp $
.\" .\"
.\" Copyright (c) 2005 The NetBSD Foundation, Inc. .\" Copyright (c) 2005 The NetBSD Foundation, Inc.
.\" All rights reserved. .\" All rights reserved.
@ -27,7 +27,7 @@
.\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE .\" ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
.\" POSSIBILITY OF SUCH DAMAGE. .\" POSSIBILITY OF SUCH DAMAGE.
.\" .\"
.Dd September 11, 2008 .Dd September 15, 2008
.Dt ATARAID 4 .Dt ATARAID 4
.Os .Os
.Sh NAME .Sh NAME
@ -61,8 +61,14 @@ Promise FastTrak
.It .It
Via V-RAID (found in many VIA-based motherboards) Via V-RAID (found in many VIA-based motherboards)
.El .El
.Pp
Status of the logical disk as well as the disks associated with it,
can be viewed through the
.Xr bioctl 8
utility.
.Sh SEE ALSO .Sh SEE ALSO
.Xr ld 4 .Xr ld 4 ,
.Xr bioctl 8
.Sh HISTORY .Sh HISTORY
The The
.Nm .Nm

View File

@ -1,4 +1,4 @@
/* $NetBSD: ata_raid_adaptec.c,v 1.8 2008/03/18 20:46:36 cube Exp $ */ /* $NetBSD: ata_raid_adaptec.c,v 1.9 2008/09/15 11:44:50 tron Exp $ */
/*- /*-
* Copyright (c) 2000,2001,2002 Søren Schmidt <sos@FreeBSD.org> * Copyright (c) 2000,2001,2002 Søren Schmidt <sos@FreeBSD.org>
@ -35,7 +35,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ata_raid_adaptec.c,v 1.8 2008/03/18 20:46:36 cube Exp $"); __KERNEL_RCSID(0, "$NetBSD: ata_raid_adaptec.c,v 1.9 2008/09/15 11:44:50 tron Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/buf.h> #include <sys/buf.h>
@ -160,6 +160,9 @@ ata_raid_read_config_adaptec(struct wd_softc *sc)
aai->aai_cylinders = aai->aai_capacity / (63 * 255); aai->aai_cylinders = aai->aai_capacity / (63 * 255);
aai->aai_offset = 0; aai->aai_offset = 0;
aai->aai_reserved = 17; aai->aai_reserved = 17;
if (info->configs[0].name)
strlcpy(aai->aai_name, info->configs[0].name,
sizeof(aai->aai_name));
/* XXX - bogus. RAID1 shouldn't really have an interleave */ /* XXX - bogus. RAID1 shouldn't really have an interleave */
if (aai->aai_interleave == 0) if (aai->aai_interleave == 0)

View File

@ -1,4 +1,4 @@
/* $NetBSD: ata_raid_intel.c,v 1.1 2008/09/11 11:08:50 tron Exp $ */ /* $NetBSD: ata_raid_intel.c,v 1.2 2008/09/15 11:44:50 tron Exp $ */
/*- /*-
* Copyright (c) 2000-2008 Søren Schmidt <sos@FreeBSD.org> * Copyright (c) 2000-2008 Søren Schmidt <sos@FreeBSD.org>
@ -33,7 +33,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ata_raid_intel.c,v 1.1 2008/09/11 11:08:50 tron Exp $"); __KERNEL_RCSID(0, "$NetBSD: ata_raid_intel.c,v 1.2 2008/09/15 11:44:50 tron Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/buf.h> #include <sys/buf.h>
@ -252,6 +252,8 @@ ata_raid_read_config_intel(struct wd_softc *sc)
aai->aai_capacity / (aai->aai_heads * aai->aai_sectors); aai->aai_capacity / (aai->aai_heads * aai->aai_sectors);
aai->aai_offset = map->offset; aai->aai_offset = map->offset;
aai->aai_reserved = 3; aai->aai_reserved = 3;
if (map->name)
strlcpy(aai->aai_name, map->name, sizeof(aai->aai_name));
/* Fill in disk info */ /* Fill in disk info */
adi = &aai->aai_disks[curdrive]; adi = &aai->aai_disks[curdrive];

View File

@ -1,4 +1,4 @@
/* $NetBSD: ata_raid_jmicron.c,v 1.2 2008/09/10 16:59:32 tron Exp $ */ /* $NetBSD: ata_raid_jmicron.c,v 1.3 2008/09/15 11:44:50 tron Exp $ */
/*- /*-
* Copyright (c) 2000-2008 Søren Schmidt <sos@FreeBSD.org> * Copyright (c) 2000-2008 Søren Schmidt <sos@FreeBSD.org>
@ -35,7 +35,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ata_raid_jmicron.c,v 1.2 2008/09/10 16:59:32 tron Exp $"); __KERNEL_RCSID(0, "$NetBSD: ata_raid_jmicron.c,v 1.3 2008/09/15 11:44:50 tron Exp $");
#include <sys/param.h> #include <sys/param.h>
#include <sys/buf.h> #include <sys/buf.h>
@ -240,6 +240,8 @@ ata_raid_read_config_jmicron(struct wd_softc *sc)
aai->aai_capacity / (aai->aai_heads * aai->aai_sectors); aai->aai_capacity / (aai->aai_heads * aai->aai_sectors);
aai->aai_offset = info->offset * 16; aai->aai_offset = info->offset * 16;
aai->aai_reserved = 2; aai->aai_reserved = 2;
if (info->name)
strlcpy(aai->aai_name, info->name, sizeof(aai->aai_name));
atabus = device_private(device_parent(sc->sc_dev)); atabus = device_private(device_parent(sc->sc_dev));
drive = atabus->sc_chan->ch_channel; drive = atabus->sc_chan->ch_channel;

View File

@ -1,4 +1,4 @@
/* $NetBSD: ata_raidvar.h,v 1.8 2008/09/11 11:08:50 tron Exp $ */ /* $NetBSD: ata_raidvar.h,v 1.9 2008/09/15 11:44:50 tron Exp $ */
/* /*
* Copyright (c) 2003 Wasabi Systems, Inc. * Copyright (c) 2003 Wasabi Systems, Inc.
@ -98,6 +98,8 @@ struct ataraid_array_info {
u_int aai_offset; /* component start offset */ u_int aai_offset; /* component start offset */
u_int aai_reserved; /* component reserved sectors */ u_int aai_reserved; /* component reserved sectors */
char aai_name[32]; /* array volume name */
struct ataraid_disk_info aai_disks[ATA_RAID_MAX_DISKS]; struct ataraid_disk_info aai_disks[ATA_RAID_MAX_DISKS];
}; };

View File

@ -1,4 +1,4 @@
/* $NetBSD: ld_ataraid.c,v 1.29 2008/09/09 12:45:39 tron Exp $ */ /* $NetBSD: ld_ataraid.c,v 1.30 2008/09/15 11:44:50 tron Exp $ */
/* /*
* Copyright (c) 2003 Wasabi Systems, Inc. * Copyright (c) 2003 Wasabi Systems, Inc.
@ -42,11 +42,14 @@
* controllers we're dealing with (Promise, etc.) only support * controllers we're dealing with (Promise, etc.) only support
* configuration data on the component disks, with the BIOS supporting * configuration data on the component disks, with the BIOS supporting
* booting from the RAID volumes. * booting from the RAID volumes.
*
* bio(4) support was written by Juan Romero Pardines <xtraeme@gmail.com>.
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: ld_ataraid.c,v 1.29 2008/09/09 12:45:39 tron Exp $"); __KERNEL_RCSID(0, "$NetBSD: ld_ataraid.c,v 1.30 2008/09/15 11:44:50 tron Exp $");
#include "bio.h"
#include "rnd.h" #include "rnd.h"
#include <sys/param.h> #include <sys/param.h>
@ -66,6 +69,13 @@ __KERNEL_RCSID(0, "$NetBSD: ld_ataraid.c,v 1.29 2008/09/09 12:45:39 tron Exp $")
#if NRND > 0 #if NRND > 0
#include <sys/rnd.h> #include <sys/rnd.h>
#endif #endif
#if NBIO > 0
#include <dev/ata/atavar.h>
#include <dev/ata/atareg.h>
#include <dev/ata/wdvar.h>
#include <dev/biovar.h>
#include <dev/scsipi/scsipiconf.h> /* for scsipi_strvis() */
#endif
#include <miscfs/specfs/specdev.h> #include <miscfs/specfs/specdev.h>
@ -92,6 +102,14 @@ static int ld_ataraid_start_span(struct ld_softc *, struct buf *);
static int ld_ataraid_start_raid0(struct ld_softc *, struct buf *); static int ld_ataraid_start_raid0(struct ld_softc *, struct buf *);
static void ld_ataraid_iodone_raid0(struct buf *); static void ld_ataraid_iodone_raid0(struct buf *);
#if NBIO > 0
static int ld_ataraid_bioctl(device_t, u_long, void *);
static int ld_ataraid_bioinq(struct ld_ataraid_softc *, struct bioc_inq *);
static int ld_ataraid_biovol(struct ld_ataraid_softc *, struct bioc_vol *);
static int ld_ataraid_biodisk(struct ld_ataraid_softc *,
struct bioc_disk *);
#endif
CFATTACH_DECL_NEW(ld_ataraid, sizeof(struct ld_ataraid_softc), CFATTACH_DECL_NEW(ld_ataraid, sizeof(struct ld_ataraid_softc),
ld_ataraid_match, ld_ataraid_attach, NULL, NULL); ld_ataraid_match, ld_ataraid_attach, NULL, NULL);
@ -233,6 +251,11 @@ ld_ataraid_attach(device_t parent, device_t self, void *aux)
} }
finish: finish:
#if NBIO > 0
if (bio_register(self, ld_ataraid_bioctl) != 0)
panic("%s: bioctl registration failed\n",
device_xname(ld->sc_dv));
#endif
ldattach(ld); ldattach(ld);
} }
@ -541,3 +564,139 @@ ld_ataraid_dump(struct ld_softc *sc, void *data,
return (EIO); return (EIO);
} }
#if NBIO > 0
static int
ld_ataraid_bioctl(device_t self, u_long cmd, void *addr)
{
struct ld_ataraid_softc *sc = device_private(self);
int error = 0;
switch (cmd) {
case BIOCINQ:
error = ld_ataraid_bioinq(sc, (struct bioc_inq *)addr);
break;
case BIOCVOL:
error = ld_ataraid_biovol(sc, (struct bioc_vol *)addr);
break;
case BIOCDISK:
error = ld_ataraid_biodisk(sc, (struct bioc_disk *)addr);
break;
default:
error = ENOTTY;
break;
}
return error;
}
static int
ld_ataraid_bioinq(struct ld_ataraid_softc *sc, struct bioc_inq *bi)
{
struct ataraid_array_info *aai = sc->sc_aai;
/* there's always one volume per ld device */
bi->bi_novol = 1;
bi->bi_nodisk = aai->aai_ndisks;
return 0;
}
static int
ld_ataraid_biovol(struct ld_ataraid_softc *sc, struct bioc_vol *bv)
{
struct ataraid_array_info *aai = sc->sc_aai;
struct ld_softc *ld = &sc->sc_ld;
/* Fill in data for _this_ volume */
bv->bv_percent = -1;
bv->bv_seconds = 0;
switch (aai->aai_status) {
case AAI_S_READY:
bv->bv_status = BIOC_SVONLINE;
break;
case AAI_S_DEGRADED:
bv->bv_status = BIOC_SVDEGRADED;
break;
}
bv->bv_size = ld->sc_secsize * ld->sc_secperunit;
switch (aai->aai_level) {
case AAI_L_SPAN:
case AAI_L_RAID0:
bv->bv_stripe_size = aai->aai_interleave;
bv->bv_level = 0;
break;
case AAI_L_RAID1:
bv->bv_stripe_size = 0;
bv->bv_level = 1;
break;
case AAI_L_RAID5:
bv->bv_stripe_size = aai->aai_interleave;
bv->bv_level = 5;
break;
}
bv->bv_nodisk = aai->aai_ndisks;
strlcpy(bv->bv_dev, device_xname(ld->sc_dv), sizeof(bv->bv_dev));
if (aai->aai_name)
strlcpy(bv->bv_vendor, aai->aai_name,
sizeof(bv->bv_vendor));
return 0;
}
static int
ld_ataraid_biodisk(struct ld_ataraid_softc *sc, struct bioc_disk *bd)
{
struct ataraid_array_info *aai = sc->sc_aai;
struct ataraid_disk_info *adi;
struct ld_softc *ld = &sc->sc_ld;
struct atabus_softc *atabus;
struct wd_softc *wd;
char model[81], serial[41], rev[17];
/* sanity check */
if (bd->bd_diskid > aai->aai_ndisks)
return EINVAL;
adi = &aai->aai_disks[bd->bd_diskid];
atabus = device_private(device_parent(adi->adi_dev));
wd = device_private(adi->adi_dev);
/* fill in data for _this_ disk */
switch (adi->adi_status) {
case ADI_S_ONLINE | ADI_S_ASSIGNED:
bd->bd_status = BIOC_SDONLINE;
break;
case ADI_S_SPARE:
bd->bd_status = BIOC_SDHOTSPARE;
break;
default:
bd->bd_status = BIOC_SDOFFLINE;
break;
}
bd->bd_channel = 0;
bd->bd_target = atabus->sc_chan->ch_channel;
bd->bd_lun = 0;
bd->bd_size = (wd->sc_capacity * ld->sc_secsize) - aai->aai_reserved;
strlcpy(bd->bd_procdev, device_xname(adi->adi_dev),
sizeof(bd->bd_procdev));
scsipi_strvis(serial, sizeof(serial), wd->sc_params.atap_serial,
sizeof(wd->sc_params.atap_serial));
scsipi_strvis(model, sizeof(model), wd->sc_params.atap_model,
sizeof(wd->sc_params.atap_model));
scsipi_strvis(rev, sizeof(rev), wd->sc_params.atap_revision,
sizeof(wd->sc_params.atap_revision));
snprintf(bd->bd_vendor, sizeof(bd->bd_vendor), "%s %s", model, rev);
strlcpy(bd->bd_serial, serial, sizeof(bd->bd_serial));
return 0;
}
#endif /* NBIO > 0 */