Subject: port-i386/19478: sysctl CTL_MACHDEP:CPU_DISKINFO has zero disk size
To: None <gnats-bugs@gnats.netbsd.org>
From: None <dsl@l8s.co.uk>
List: netbsd-bugs
Date: 12/20/2002 21:43:52
>Number:         19478
>Category:       port-i386
>Synopsis:       sysctl CTL_MACHDEP:CPU_DISKINFO has zero disk size
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    port-i386-maintainer
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Dec 20 13:41:00 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     David Laight
>Release:        NetBSD 1.6K
>Organization:
	no
>Environment:
System: NetBSD snowdrop 1.6K NetBSD 1.6K (GENERIC) #201: Wed Dec 18 15:44:12 GMT 2002 dsl@snowdrop:/oldroot/usr/bsd-current/src/sys/arch/i386/compile/GENERIC i386
Architecture: i386
Machine: i386
>Description:
	The disk size reported by sysctl is always zero sectors.
	(Found while trying to improve the way fdisk sorts out the disk
	geometry).
>How-To-Repeat:
	Apply the following patch to sbin/sysctl/sysctl.c so that it
	formats the response to the CPU_DISKINFO request.
	Notice that the number of sectors is zero:

Index: sysctl.c
===================================================================
RCS file: /cvsroot/src/sbin/sysctl/sysctl.c,v
retrieving revision 1.61
diff -u -r1.61 sysctl.c
--- sysctl.c	2002/11/30 03:10:54	1.61
+++ sysctl.c	2002/12/20 21:20:23
@@ -634,7 +634,40 @@
 		return;
 	}
 	if (special & DISKINFO) {
+#ifdef CPU_DISKINFO
 		/* Don't know a good way to deal with this i386 specific one */
+		/* OTOH this does pass the info out... */
+		struct disklist *dl = (void *)buf;
+		struct biosdisk_info *bi;
+		struct nativedisk_info *ni;
+		uint i, b, lim;
+		if (!nflag)
+			printf("%s: ", string);
+		lim = dl->dl_nbiosdisks;
+		if (lim > MAX_BIOSDISKS)
+			lim = MAX_BIOSDISKS;
+		for (bi = dl->dl_biosdisks, i = 0; i < lim; bi++, i++) {
+			printf("%x:%lld(%d.%d.%d),%x ",
+				bi->bi_dev, bi->bi_lbasecs, bi->bi_cyl,
+				bi->bi_head, bi->bi_sec, bi->bi_flags);
+		}
+		lim = dl->dl_nnativedisks;
+		ni = dl->dl_nativedisks;
+		bi = dl->dl_biosdisks;
+		if ((char *)&ni[lim] != (char *)buf + size) {
+			printf("size mismatch\n");
+			return;
+		}
+		for (i = 0; i < lim; ni++, i++) {
+			char sep = ':';
+			printf(" %.*s", (int)sizeof ni->ni_devname,
+				ni->ni_devname);
+			for (b = 0; b < ni->ni_nmatches; sep = ',', b++)
+				printf("%c%x", sep,
+					bi[ni->ni_biosmatches[b]].bi_dev);
+		}
+		printf("\n");
+#endif
 		return;
 	}
 	if (special & CPTIME) {

>Fix:
	On my system (at least) the BIOS reports 'totsec' but not the
	cyl/head/sec values when reporting the extint13 disk geometry.
	Applying the fix below passes the total number of sectors through.
	Note that the header file comment for EXT13_GEOM_VALID is:
	    /* geometry in c/h/s in struct valid */
	Which is consistent with what I see: cyl=head=sec=0, totsec!=0.

	With both fixes, 'sysctl machdep.diskinfo' reports:
	'machdep.diskinfo: 80:40032696(1023.255.63),2  wd0:80'

Index: bootinfo_biosgeom.c
===================================================================
RCS file: /cvsroot/src/sys/arch/i386/stand/lib/bootinfo_biosgeom.c,v
retrieving revision 1.9
diff -u -r1.9 bootinfo_biosgeom.c
--- bootinfo_biosgeom.c	2001/07/07 22:57:57	1.9
+++ bootinfo_biosgeom.c	2002/12/20 21:24:08
@@ -85,13 +85,14 @@
 #ifdef GEOM_DEBUG
 		printf("#%d: %x: C %d H %d S %d\n", nvalid,
 		    d.dev, d.cyl, d.head, d.sec);
+		printf("   sz %d fl %x cyl %d head %d sec %d totsec %lld sbytes %d\n",
+			ed.size, ed.flags, ed.cyl, ed.head, ed.sec,
+			ed.totsec, ed.sbytes);
 #endif
 
 		if (d.flags & BIOSDISK_EXT13) {
-			if (ed.flags & EXT13_GEOM_VALID)
-				bibg->disk[nvalid].totsec = ed.totsec;
-			else
-				bibg->disk[nvalid].totsec = 0;
+			bibg->disk[nvalid].totsec = ed.totsec;
 			bibg->disk[nvalid].flags |= BI_GEOM_EXTINT13;
 		}
 		for (j = 0, cksum = 0; j < BIOSDISK_SECSIZE; j++)
>Release-Note:
>Audit-Trail:
>Unformatted: