diff options
Diffstat (limited to 'sys/dev/ata/ata-raid.c')
-rw-r--r-- | sys/dev/ata/ata-raid.c | 63 |
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: |