From dd1b8df8808df4fe295a90ab494da90162c5654f Mon Sep 17 00:00:00 2001 From: google Date: Sun, 9 Sep 2012 17:22:12 +1200 Subject: [PATCH] Add alignment hints for e512 ATA drives. --- sys/include/disk.h | 2 ++ sys/include/fis.h | 1 + sys/src/9/pc/sdiahci.c | 2 ++ sys/src/9/pc/sdide.c | 2 ++ sys/src/cmd/disk/prep/prep.c | 16 ++++++++++++---- sys/src/libdisk/disk.c | 6 +++++- sys/src/libfis/fis.c | 12 ++++++++---- 7 files changed, 32 insertions(+), 9 deletions(-) diff --git a/sys/include/disk.h b/sys/include/disk.h index be0a4a0fe..c22928b49 100644 --- a/sys/include/disk.h +++ b/sys/include/disk.h @@ -42,6 +42,8 @@ struct Disk { vlong size; vlong offset; /* within larger disk, perhaps */ int width; /* of disk size in bytes as decimal string */ + int psecsize; + int physalign; int c; int h; int s; diff --git a/sys/include/fis.h b/sys/include/fis.h index 9ec0ba6aa..8c7ca2c32 100644 --- a/sys/include/fis.h +++ b/sys/include/fis.h @@ -102,6 +102,7 @@ struct Sfis { uint sig; uint lsectsz; uint physshift; /* log2(log/phys) */ + uint physalign; /* location of lba0 within phys0 */ uint c; /* disgusting, no? */ uint h; uint s; diff --git a/sys/src/9/pc/sdiahci.c b/sys/src/9/pc/sdiahci.c index 6d5008286..fdb8f3eb3 100644 --- a/sys/src/9/pc/sdiahci.c +++ b/sys/src/9/pc/sdiahci.c @@ -2226,6 +2226,8 @@ iarctl(SDunit *u, char *p, int l) p = seprint(p, e, "\n"); p = seprint(p, e, "mode\t%s %s\n", modes[d->mode], modes[maxmode(c)]); p = seprint(p, e, "geometry %llud %lud\n", d->sectors, u->secsize); + p = seprint(p, e, "alignment %d %d\n", + d->secsize<portm.physshift, d->portm.physalign); return p - op; } diff --git a/sys/src/9/pc/sdide.c b/sys/src/9/pc/sdide.c index 6ce3040a0..2b2918792 100644 --- a/sys/src/9/pc/sdide.c +++ b/sys/src/9/pc/sdide.c @@ -2349,6 +2349,8 @@ atarctl(SDunit* unit, char* p, int l) if(drive->pkt == 0 && (drive->feat & Dlba) == 0) p = seprint(p, e, " %d %d %d", drive->c, drive->h, drive->s); p = seprint(p, e, "\n"); + p = seprint(p, e, "alignment %d %d\n", + drive->secsize<physshift, drive->physalign); } p = seprint(p, e, "missirq %ud\n", drive->missirq); p = seprint(p, e, "sloop %ud\n", drive->spurloop); diff --git a/sys/src/cmd/disk/prep/prep.c b/sys/src/cmd/disk/prep/prep.c index 506ca9589..b21a2d551 100644 --- a/sys/src/cmd/disk/prep/prep.c +++ b/sys/src/cmd/disk/prep/prep.c @@ -354,7 +354,8 @@ static void autoxpart(Edit *edit) { int i, totw, futz; - vlong secs, secsize, s; + vlong secs, secsize, psecsize, s, e, pa; + long stride; char *err; if(edit->npart > 0) { @@ -362,9 +363,12 @@ autoxpart(Edit *edit) fprint(2, "partitions already exist; not repartitioning\n"); return; } - secs = edit->disk->secs; secsize = edit->disk->secsize; + psecsize = edit->disk->psecsize; + stride = psecsize / secsize; + pa = (edit->disk->offset - edit->disk->physalign + stride) % stride; + secs -= (secs + pa) % stride; for(;;){ /* compute total weights */ totw = 0; @@ -431,12 +435,16 @@ autoxpart(Edit *edit) print("%s %llud\n", autox[i].name, autox[i].size); s = 0; + secs = edit->disk->secs; for(i=0; isecs) e = secs - stride + (secs + pa) % stride; + if(err = addpart(edit, mkpart(autox[i].name, s, e, 1))) fprint(2, "addpart %s: %s\n", autox[i].name, err); - s += autox[i].size; + s = e; } } diff --git a/sys/src/libdisk/disk.c b/sys/src/libdisk/disk.c index dadb92cf2..0ac988438 100644 --- a/sys/src/libdisk/disk.c +++ b/sys/src/libdisk/disk.c @@ -247,13 +247,17 @@ opensd(Disk *disk) disk->s = strtol(f[5], 0, 0); } } + if(nf >= 3 && strcmp(f[0], "alignment") == 0) { + disk->psecsize = strtol(f[1], 0, 0); + disk->physalign = strtol(f[2], 0, 0); + } if(nf >= 4 && strcmp(f[0], "part") == 0 && strcmp(f[1], disk->part) == 0) { disk->offset = strtoll(f[2], 0, 0); disk->secs = strtoll(f[3], 0, 0) - disk->offset; } } - + if (!disk->psecsize) disk->psecsize = disk->secsize; disk->size = disk->secs * disk->secsize; if(disk->size <= 0) { strcpy(disk->part, ""); diff --git a/sys/src/libfis/fis.c b/sys/src/libfis/fis.c index cb6c73407..c04b327ad 100644 --- a/sys/src/libfis/fis.c +++ b/sys/src/libfis/fis.c @@ -307,20 +307,24 @@ idfeat(Sfis *f, ushort *id) int idss(Sfis *f, ushort *id) { - uint sw, i; + uint sw, i, pa; if(f->sig>>16 == 0xeb14) return 0; f->lsectsz = 512; f->physshift = 0; + f->physalign = 0; i = gbit16(id + 106); if(i >> 14 != 1) return f->lsectsz; - if((sw = gbit32(id + 117)) >= 256) + if((i & (1<<12)) && (sw = gbit32(id + 117)) >= 256) f->lsectsz = sw * 2; - if(i & 1<<13) + if(i & 1<<13){ f->physshift = i & 7; - return f->lsectsz * (1<physshift); + if((pa = gbit16(id + 209)) & 0x4000) + f->physalign = pa & 0x3fff; + } + return f->lsectsz; } uvlong