summaryrefslogtreecommitdiffstats
path: root/sys/dev/ata
diff options
context:
space:
mode:
authorsos <sos@FreeBSD.org>2003-04-08 07:48:52 +0000
committersos <sos@FreeBSD.org>2003-04-08 07:48:52 +0000
commit8568dcf658fe1a574149d8272cff160df5654c5c (patch)
tree761c784e03a5e6528c27842ed2771d854328265a /sys/dev/ata
parentbf5f76d431cb9d693e3259042a2526316cc64891 (diff)
downloadFreeBSD-src-8568dcf658fe1a574149d8272cff160df5654c5c.zip
FreeBSD-src-8568dcf658fe1a574149d8272cff160df5654c5c.tar.gz
Fix a long standing bug in handling the last part of a stripe
on "odd" size disks. Add printout of the RAID structure on verbose boot.
Diffstat (limited to 'sys/dev/ata')
-rw-r--r--sys/dev/ata/ata-raid.c47
-rw-r--r--sys/dev/ata/ata-raid.h3
2 files changed, 43 insertions, 7 deletions
diff --git a/sys/dev/ata/ata-raid.c b/sys/dev/ata/ata-raid.c
index 021fdf4..c392478 100644
--- a/sys/dev/ata/ata-raid.c
+++ b/sys/dev/ata/ata-raid.c
@@ -64,6 +64,7 @@ static int ar_promise_read_conf(struct ad_softc *, struct ar_softc **, int);
static int ar_promise_write_conf(struct ar_softc *);
static int ar_rw(struct ad_softc *, u_int32_t, int, caddr_t, int);
static struct ata_device *ar_locate_disk(int);
+static void ar_print_conf(struct ar_softc *);
/* internal vars */
static struct ar_softc **ar_table = NULL;
@@ -155,6 +156,8 @@ ata_raid_attach()
for (array = 0; array < MAX_ARRAYS; array++) {
if (!(rdp = ar_table[array]) || !rdp->flags)
continue;
+ if (bootverbose)
+ ar_print_conf(rdp);
ar_attach_raid(rdp, 0);
}
}
@@ -493,11 +496,17 @@ arstrategy(struct bio *bp)
case AR_F_RAID0 | AR_F_RAID1:
tmplba = blkno / rdp->interleave;
chunk = blkno % rdp->interleave;
- if (tmplba == rdp->total_sectors / rdp->interleave) {
- lbs = (rdp->total_sectors-(tmplba*rdp->interleave))/rdp->width;
- drv = chunk / lbs;
- lba = ((tmplba/rdp->width)*rdp->interleave) + chunk%lbs;
- chunk = min(count, lbs);
+ if (blkno >= (rdp->total_sectors / (rdp->interleave * rdp->width)) *
+ (rdp->interleave * rdp->width) ) {
+ lbs = (rdp->total_sectors -
+ ((rdp->total_sectors / (rdp->interleave * rdp->width)) *
+ (rdp->interleave * rdp->width))) / rdp->width;
+ drv = (blkno -
+ ((rdp->total_sectors / (rdp->interleave * rdp->width)) *
+ (rdp->interleave * rdp->width))) / lbs;
+ lba = ((tmplba / rdp->width) * rdp->interleave) +
+ (blkno - ((tmplba / rdp->width) * rdp->interleave)) % lbs;
+ chunk = min(count, lbs);
}
else {
drv = tmplba % rdp->width;
@@ -1431,3 +1440,31 @@ ar_locate_disk(int diskno)
}
return NULL;
}
+
+static void
+ar_print_conf(struct ar_softc *config)
+{
+ int i;
+
+ printf("lun %d\n", config->lun);
+ printf("magic_0 0x%08x\n", config->magic_0);
+ printf("magic_1 0x%08x\n", config->magic_1);
+ printf("flags 0x%02x %b\n", config->flags, config->flags,
+ "\20\16HIGHPOINT\15PROMISE\13REBUILDING\12DEGRADED\11READY\3SPAN\2RAID1\1RAID0\n");
+ printf("total_disks %d\n", config->total_disks);
+ printf("generation %d\n", config->generation);
+ printf("width %d\n", config->width);
+ printf("heads %d\n", config->heads);
+ printf("sectors %d\n", config->sectors);
+ printf("cylinders %d\n", config->cylinders);
+ printf("total_sectors %lld\n", config->total_sectors);
+ printf("interleave %d\n", config->interleave);
+ printf("reserved %d\n", config->reserved);
+ printf("offset %d\n", config->offset);
+ for (i = 0; i < config->total_disks; i++) {
+ printf("disk %d: flags = 0x%02x %b\n", i, config->disks[i].flags, config->disks[i].flags, "\20\4ONLINE\3SPARE\2ASSIGNED\1PRESENT\n");
+ if (config->disks[i].device)
+ printf(" %s\n", config->disks[i].device->name);
+ printf(" sectors %lld\n", config->disks[i].disk_sectors);
+ }
+}
diff --git a/sys/dev/ata/ata-raid.h b/sys/dev/ata/ata-raid.h
index 973b279..b4cf301 100644
--- a/sys/dev/ata/ata-raid.h
+++ b/sys/dev/ata/ata-raid.h
@@ -221,11 +221,10 @@ struct promise_raid_conf {
u_int32_t checksum;
} __packed;
-int ata_raiddisk_probe(struct ad_softc *);
int ata_raiddisk_attach(struct ad_softc *);
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_status(int, struct raid_status *);
int ata_raid_rebuild(int);
OpenPOWER on IntegriCloud