aboutsummaryrefslogtreecommitdiff
path: root/sys/dev/ata/ata-raid.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/dev/ata/ata-raid.c')
-rw-r--r--sys/dev/ata/ata-raid.c63
1 files changed, 33 insertions, 30 deletions
diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c
index 14ee7b0fb0cf..9159e426b34b 100644
--- a/sys/dev/ata/ata-raid.c
+++ b/sys/dev/ata/ata-raid.c
@@ -97,11 +97,12 @@ ata_raiddisk_attach(struct ad_softc *adp)
continue;
for (disk = 0; disk < rdp->total_disks; disk++) {
- if (rdp->disks[disk].device == adp->device) {
+ if ((rdp->disks[disk].flags & AR_DF_ASSIGNED) &&
+ rdp->disks[disk].device == adp->device) {
ata_prtdev(rdp->disks[disk].device,
"inserted into ar%d disk%d as spare\n",
array, disk);
- rdp->disks[disk].flags = (AR_DF_PRESENT | AR_DF_SPARE);
+ rdp->disks[disk].flags |= (AR_DF_PRESENT | AR_DF_SPARE);
AD_SOFTC(rdp->disks[disk])->flags = AD_F_RAID_SUBDISK;
ar_config_changed(rdp, 1);
return 1;
@@ -216,18 +217,19 @@ ar_attach_raid(struct ar_softc *rdp, int update)
}
printf(" subdisks:\n");
for (disk = 0; disk < rdp->total_disks; disk++) {
- if (rdp->disks[disk].flags & AR_DF_ONLINE)
- printf(" %d READY ", disk);
+ if (rdp->disks[disk].flags & AR_DF_PRESENT) {
+ if (rdp->disks[disk].flags & AR_DF_ONLINE)
+ printf(" %d READY ", disk);
+ else if (rdp->disks[disk].flags & AR_DF_SPARE)
+ printf(" %d SPARE ", disk);
+ else
+ printf(" %d FREE ", disk);
+ ad_print(AD_SOFTC(rdp->disks[disk]));
+ }
else if (rdp->disks[disk].flags & AR_DF_ASSIGNED)
- printf(" %d DOWN ", disk);
- else if (rdp->disks[disk].flags & AR_DF_SPARE)
- printf(" %d SPARE ", disk);
- else if (rdp->disks[disk].flags & AR_DF_PRESENT)
- printf(" %d FREE ", disk);
+ printf(" %d DOWN\n", disk);
else
printf(" %d INVALID no RAID config info on this disk\n", disk);
- if (rdp->disks[disk].flags & AR_DF_PRESENT)
- ad_print(AD_SOFTC(rdp->disks[disk]));
}
}
@@ -286,7 +288,8 @@ ata_raid_create(struct raid_setup *setup)
break;
}
if (rdp->flags & (AR_F_PROMISE_RAID|AR_F_HIGHPOINT_RAID) &&
- (rdp->flags & (AR_F_PROMISE_RAID|AR_F_HIGHPOINT_RAID)) != ctlr){
+ (rdp->flags & (AR_F_PROMISE_RAID|AR_F_HIGHPOINT_RAID)) !=
+ (ctlr & (AR_F_PROMISE_RAID|AR_F_HIGHPOINT_RAID))) {
free(rdp, M_AR);
return EXDEV;
}
@@ -555,7 +558,8 @@ arstrategy(struct bio *bp)
switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) {
case AR_F_SPAN:
case AR_F_RAID0:
- if (rdp->disks[buf1->drive].flags & AR_DF_ONLINE &&
+ if ((rdp->disks[buf1->drive].flags &
+ (AR_DF_PRESENT|AR_DF_ONLINE))==(AR_DF_PRESENT|AR_DF_ONLINE) &&
!AD_SOFTC(rdp->disks[buf1->drive])->dev->si_disk) {
rdp->disks[buf1->drive].flags &= ~AR_DF_ONLINE;
ar_config_changed(rdp, 1);
@@ -579,12 +583,14 @@ arstrategy(struct bio *bp)
tsleep(rdp, PRIBIO, "arwait", 0);
}
}
- if (rdp->disks[buf1->drive].flags & AR_DF_ONLINE &&
+ if ((rdp->disks[buf1->drive].flags &
+ (AR_DF_PRESENT|AR_DF_ONLINE))==(AR_DF_PRESENT|AR_DF_ONLINE) &&
!AD_SOFTC(rdp->disks[buf1->drive])->dev->si_disk) {
rdp->disks[buf1->drive].flags &= ~AR_DF_ONLINE;
change = 1;
}
- if (rdp->disks[buf1->drive + rdp->width].flags & AR_DF_ONLINE &&
+ if ((rdp->disks[buf1->drive + rdp->width].flags &
+ (AR_DF_PRESENT|AR_DF_ONLINE))==(AR_DF_PRESENT|AR_DF_ONLINE) &&
!AD_SOFTC(rdp->disks[buf1->drive + rdp->width])->dev->si_disk) {
rdp->disks[buf1->drive + rdp->width].flags &= ~AR_DF_ONLINE;
change = 1;
@@ -727,6 +733,10 @@ ar_config_changed(struct ar_softc *rdp, int writeback)
rdp->flags |= AR_F_READY;
rdp->flags &= ~AR_F_DEGRADED;
+ for (disk = 0; disk < rdp->total_disks; disk++)
+ if (!(rdp->disks[disk].flags & AR_DF_PRESENT))
+ rdp->disks[disk].flags &= ~AR_DF_ONLINE;
+
for (disk = 0; disk < rdp->total_disks; disk++) {
switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) {
case AR_F_SPAN:
@@ -1228,12 +1238,12 @@ ar_promise_read_conf(struct ad_softc *adp, struct ar_softc **raidp, int local)
raid->disks[disk].flags |= AR_DF_ONLINE;
if (info->raid.disk[disk].flags & PR_F_ASSIGNED)
raid->disks[disk].flags |= AR_DF_ASSIGNED;
- if (info->raid.disk[disk].flags & PR_F_SPARE)
- raid->disks[disk].flags |= AR_DF_SPARE;
- if (info->raid.disk[disk].flags & (PR_F_REDIR | PR_F_DOWN)) {
+ if (info->raid.disk[disk].flags & PR_F_SPARE) {
raid->disks[disk].flags &= ~AR_DF_ONLINE;
- raid->disks[disk].flags |= AR_DF_PRESENT;
+ raid->disks[disk].flags |= AR_DF_SPARE;
}
+ if (info->raid.disk[disk].flags & (PR_F_REDIR | PR_F_DOWN))
+ raid->disks[disk].flags &= ~AR_DF_ONLINE;
}
if (!disksum) {
free(raidp[array], M_AR);
@@ -1285,18 +1295,8 @@ ar_promise_write_conf(struct ar_softc *rdp)
config->magic_0 = PR_MAGIC0(rdp->disks[disk]) | timestamp.tv_sec;
config->magic_1 = timestamp.tv_sec >> 16;
config->magic_2 = timestamp.tv_sec;
-
config->raid.integrity = PR_I_VALID;
- config->raid.flags = 0;
- if (rdp->disks[disk].flags & AR_DF_PRESENT)
- config->raid.flags |= PR_F_VALID;
- if (rdp->disks[disk].flags & AR_DF_ASSIGNED)
- config->raid.flags |= PR_F_ASSIGNED;
- if (rdp->disks[disk].flags & AR_DF_ONLINE)
- config->raid.flags |= PR_F_ONLINE;
- else
- config->raid.flags |= PR_F_DOWN;
config->raid.disk_number = disk;
if (rdp->disks[disk].flags & AR_DF_PRESENT && rdp->disks[disk].device) {
config->raid.channel = rdp->disks[disk].device->channel->unit;
@@ -1310,6 +1310,7 @@ ar_promise_write_conf(struct ar_softc *rdp)
config->raid.generation = rdp->generation;
if (rdp->flags & AR_F_READY) {
+ config->raid.flags = (PR_F_VALID | PR_F_ASSIGNED | PR_F_ONLINE);
config->raid.status =
(PR_S_VALID | PR_S_ONLINE | PR_S_INITED | PR_S_READY);
if (rdp->flags & AR_F_DEGRADED)
@@ -1317,8 +1318,10 @@ ar_promise_write_conf(struct ar_softc *rdp)
else
config->raid.status |= PR_S_FUNCTIONAL;
}
- else
+ else {
+ config->raid.flags = PR_F_DOWN;
config->raid.status = 0;
+ }
switch (rdp->flags & (AR_F_RAID0 | AR_F_RAID1 | AR_F_SPAN)) {
case AR_F_RAID0: