summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2002-04-02 13:48:17 +0000
committersos <sos@FreeBSD.org>2002-04-02 13:48:17 +0000
commit9b962a4e9b5fedc67b4a99f7e601ead5e560046a (patch)
tree130b7364b744c920bbc15c1d12ef48b5ebff5b0c /sys
parent5c4e8e05b641c2b0660eec42dfa25fb9b7821e10 (diff)
downloadFreeBSD-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.c3
-rw-r--r--sys/dev/ata/ata-raid.c45
-rw-r--r--sys/dev/ata/ata-raid.h1
-rw-r--r--sys/sys/ata.h16
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;
OpenPOWER on IntegriCloud