diff options
author | sos <sos@FreeBSD.org> | 2002-04-02 13:48:17 +0000 |
---|---|---|
committer | sos <sos@FreeBSD.org> | 2002-04-02 13:48:17 +0000 |
commit | 9b962a4e9b5fedc67b4a99f7e601ead5e560046a (patch) | |
tree | 130b7364b744c920bbc15c1d12ef48b5ebff5b0c /sys | |
parent | 5c4e8e05b641c2b0660eec42dfa25fb9b7821e10 (diff) | |
download | FreeBSD-src-9b962a4e9b5fedc67b4a99f7e601ead5e560046a.zip FreeBSD-src-9b962a4e9b5fedc67b4a99f7e601ead5e560046a.tar.gz |
Add get-status to the ATA RAID subsystem.
Diffstat (limited to 'sys')
-rw-r--r-- | sys/dev/ata/ata-all.c | 3 | ||||
-rw-r--r-- | sys/dev/ata/ata-raid.c | 45 | ||||
-rw-r--r-- | sys/dev/ata/ata-raid.h | 1 | ||||
-rw-r--r-- | sys/sys/ata.h | 16 |
4 files changed, 64 insertions, 1 deletions
diff --git a/sys/dev/ata/ata-all.c b/sys/dev/ata/ata-all.c index 1dae0c4..9d4d1e9 100644 --- a/sys/dev/ata/ata-all.c +++ b/sys/dev/ata/ata-all.c @@ -415,6 +415,9 @@ ataioctl(dev_t dev, u_long cmd, caddr_t addr, int32_t flag, struct thread *td) case ATARAIDDELETE: return ata_raid_delete(iocmd->channel); + + case ATARAIDSTATUS: + return ata_raid_status(iocmd->channel, &iocmd->u.raid_status); #endif #if defined(DEV_ATAPICD) || defined(DEV_ATAPIFD) || defined(DEV_ATAPIST) case ATAPICMD: { diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c index 13e17e4..14ee7b0 100644 --- a/sys/dev/ata/ata-raid.c +++ b/sys/dev/ata/ata-raid.c @@ -404,7 +404,50 @@ ata_raid_delete(int array) ar_table[array] = NULL; return 0; } - + +int +ata_raid_status(int array, struct raid_status *status) +{ + struct ar_softc *rdp; + int i; + + if (!ar_table || !(rdp = ar_table[array])) + return ENXIO; + + switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) { + case AR_F_RAID0: + status->type = AR_RAID0; + break; + case AR_F_RAID1: + status->type = AR_RAID1; + break; + case AR_F_RAID0 | AR_F_RAID1: + status->type = AR_RAID0 | AR_RAID1; + break; + case AR_F_SPAN: + status->type = AR_SPAN; + break; + } + status->total_disks = rdp->total_disks; + for (i = 0; i < rdp->total_disks; i++ ) { + if ((rdp->disks[i].flags & AR_DF_PRESENT) && rdp->disks[i].device) + status->disks[i] = AD_SOFTC(rdp->disks[i])->lun; + else + status->disks[i] = -1; + } + status->interleave = rdp->interleave; + status->status = 0; + if (rdp->flags & AR_F_READY) + status->status |= AR_READY; + if (rdp->flags & AR_F_DEGRADED) + status->status |= AR_DEGRADED; + if (rdp->flags & AR_F_REBUILDING) { + status->status |= AR_REBUILDING; + status->progress = 100*rdp->lock_start/(rdp->total_sectors/rdp->width); + } + return 0; +} + int ata_raid_rebuild(int array) { diff --git a/sys/dev/ata/ata-raid.h b/sys/dev/ata/ata-raid.h index 85f91c7..8755acc 100644 --- a/sys/dev/ata/ata-raid.h +++ b/sys/dev/ata/ata-raid.h @@ -228,4 +228,5 @@ int ata_raiddisk_detach(struct ad_softc *); void ata_raid_attach(void); int ata_raid_create(struct raid_setup *); int ata_raid_delete(int); +int ata_raid_status(int array, struct raid_status *); int ata_raid_rebuild(int); diff --git a/sys/sys/ata.h b/sys/sys/ata.h index 82c79c1..d0a584a 100644 --- a/sys/sys/ata.h +++ b/sys/sys/ata.h @@ -250,11 +250,27 @@ struct ata_cmd { } param; struct raid_setup { int type; +#define AR_RAID0 1 +#define AR_RAID1 2 +#define AR_SPAN 4 + int total_disks; int disks[16]; int interleave; int unit; } raid_setup; + struct raid_status { + int type; + int total_disks; + int disks[16]; + int interleave; + int status; +#define AR_READY 1 +#define AR_DEGRADED 2 +#define AR_REBUILDING 4 + + int progress; + } raid_status; struct { int fan; int temp; |