diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2006-08-27 09:56:21 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2006-08-27 09:56:21 +0000 |
commit | 3303f585d297012ea36ee41c57e5dc4364683642 (patch) | |
tree | 2a44458912d498529fccd8bb6bbf2086c8c309ad /sys/dev/pci | |
parent | 7c64792c480cc84add17e4b02e4a031fc8e292fc (diff) |
try to get the status of the volume out of the arc firmware and into
bioctl output. this is actually a bit of a struggle since the firmware
doesnt represent these states well at all. im only showing the obvious
ones: online, init, rebuild, and offline. i have no idea how they tell if
a volume is degraded.
Diffstat (limited to 'sys/dev/pci')
-rw-r--r-- | sys/dev/pci/arc.c | 44 |
1 files changed, 32 insertions, 12 deletions
diff --git a/sys/dev/pci/arc.c b/sys/dev/pci/arc.c index 06919c1c70b..6e124091f6a 100644 --- a/sys/dev/pci/arc.c +++ b/sys/dev/pci/arc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: arc.c,v 1.44 2006/08/27 09:29:26 dlg Exp $ */ +/* $OpenBSD: arc.c,v 1.45 2006/08/27 09:56:20 dlg Exp $ */ /* * Copyright (c) 2006 David Gwynne <dlg@openbsd.org> @@ -264,6 +264,17 @@ struct arc_fw_volinfo { u_int32_t new_fail_mask; u_int32_t new_stripe_size; u_int32_t volume_status; +#define ARC_FW_VOL_STATUS_NORMAL 0x00 +#define ARC_FW_VOL_STATUS_INITTING (1<<0) +#define ARC_FW_VOL_STATUS_FAILED (1<<1) +#define ARC_FW_VOL_STATUS_MIGRATING (1<<2) +#define ARC_FW_VOL_STATUS_REBUILDING (1<<3) +#define ARC_FW_VOL_STATUS_NEED_INIT (1<<4) +#define ARC_FW_VOL_STATUS_NEED_MIGRATE (1<<5) +#define ARC_FW_VOL_STATUS_INIT_FLAG (1<<6) +#define ARC_FW_VOL_STATUS_NEED_REGEN (1<<7) +#define ARC_FW_VOL_STATUS_CHECKING (1<<8) +#define ARC_FW_VOL_STATUS_NEED_CHECK (1<<9) u_int32_t progress; struct arc_fw_scsiattr scsi_attr; u_int8_t member_disks; @@ -1130,6 +1141,7 @@ arc_bio_vol(struct arc_softc *sc, struct bioc_vol *bv) struct arc_fw_volinfo *volinfo; struct scsi_link *sc_link; struct device *dev; + u_int32_t status; int error = 0; volinfo = malloc(sizeof(struct arc_fw_volinfo), M_TEMP, M_WAITOK); @@ -1139,22 +1151,25 @@ arc_bio_vol(struct arc_softc *sc, struct bioc_vol *bv) arc_lock(sc); error = arc_bio_getvol(sc, bv->bv_volid, volinfo); arc_unlock(sc); - if (error != 0) goto out; - sc_link = sc->sc_scsibus->sc_link[volinfo->scsi_attr.target] - [volinfo->scsi_attr.lun]; - if (sc_link == NULL) { - error = ENODEV; - goto out; - } - dev = sc_link->device_softc; - bv->bv_percent = -1; bv->bv_seconds = 0; - bv->bv_status = BIOC_SVONLINE; + status = letoh32(volinfo->volume_status); + if (status == 0x0) + bv->bv_status = BIOC_SVONLINE; + else if (status & ARC_FW_VOL_STATUS_FAILED) + bv->bv_status = BIOC_SVOFFLINE; + else if (status & ARC_FW_VOL_STATUS_INITTING) { + bv->bv_status = BIOC_SVBUILDING; + bv->bv_percent = letoh32(volinfo->progress) / 10; + } else if (status & ARC_FW_VOL_STATUS_REBUILDING) { + bv->bv_status = BIOC_SVREBUILD; + bv->bv_percent = letoh32(volinfo->progress) / 10; + } + bv->bv_size = (u_int64_t)letoh32(volinfo->capacity) * ARC_BLOCKSIZE; switch (volinfo->raid_level) { @@ -1180,7 +1195,12 @@ arc_bio_vol(struct arc_softc *sc, struct bioc_vol *bv) } bv->bv_nodisk = volinfo->member_disks; - strlcpy(bv->bv_dev, dev->dv_xname, sizeof(bv->bv_dev)); + sc_link = sc->sc_scsibus->sc_link[volinfo->scsi_attr.target] + [volinfo->scsi_attr.lun]; + if (sc_link != NULL) { + dev = sc_link->device_softc; + strlcpy(bv->bv_dev, dev->dv_xname, sizeof(bv->bv_dev)); + } out: free(volinfo, M_TEMP); |