git: 9front

Download patch

ref: 969a8d0f78afcc37db7d73ac9e544d31b495febd
parent: d119b0f42a2b6a4d6470351ede57ccd643c4865e
author: google <google@daverabbitz.ath.cx>
date: Sun Sep 9 13:22:12 EDT 2012

Add alignment hints for e512 ATA drives.

--- a/sys/include/disk.h
+++ b/sys/include/disk.h
@@ -42,6 +42,8 @@
 	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;
--- a/sys/include/fis.h
+++ b/sys/include/fis.h
@@ -102,6 +102,7 @@
 	uint	sig;
 	uint	lsectsz;
 	uint	physshift;	/* log2(log/phys) */
+	uint	physalign; /* location of lba0 within phys0 */
 	uint	c;		/* disgusting, no? */
 	uint	h;
 	uint	s;
--- a/sys/src/9/pc/sdiahci.c
+++ b/sys/src/9/pc/sdiahci.c
@@ -2226,6 +2226,8 @@
 	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<<d->portm.physshift, d->portm.physalign);
 	return p - op;
 }
 
--- a/sys/src/9/pc/sdide.c
+++ b/sys/src/9/pc/sdide.c
@@ -2349,6 +2349,8 @@
 		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<<drive->physshift, drive->physalign);
 	}
 	p = seprint(p, e, "missirq	%ud\n", drive->missirq);
 	p = seprint(p, e, "sloop	%ud\n", drive->spurloop);
--- a/sys/src/cmd/disk/prep/prep.c
+++ b/sys/src/cmd/disk/prep/prep.c
@@ -354,7 +354,8 @@
 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 @@
 			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 @@
 			print("%s %llud\n", autox[i].name, autox[i].size);
 
 	s = 0;
+	secs = edit->disk->secs;
 	for(i=0; i<nelem(autox); i++){
 		if(autox[i].alloc == 0)
 			continue;
-		if(err = addpart(edit, mkpart(autox[i].name, s, s+autox[i].size, 1)))
+		e = (s + autox[i].size);
+		if((e + pa) % stride) e += stride - (e + pa) % stride;
+		if(e>secs) 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;
 	}
 }
 
--- a/sys/src/libdisk/disk.c
+++ b/sys/src/libdisk/disk.c
@@ -247,6 +247,10 @@
 				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;
@@ -253,7 +257,7 @@
 		}
 	}
 
-	
+	if (!disk->psecsize) disk->psecsize = disk->secsize;	
 	disk->size = disk->secs * disk->secsize;
 	if(disk->size <= 0) {
 		strcpy(disk->part, "");
--- a/sys/src/libfis/fis.c
+++ b/sys/src/libfis/fis.c
@@ -307,20 +307,24 @@
 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<<f->physshift);
+		if((pa = gbit16(id + 209)) & 0x4000)
+			f->physalign = pa & 0x3fff;
+	}
+	return f->lsectsz;
 }
 
 uvlong
--