Subject: tape drive instrumentation round 2
To: None <tech-kern@netbsd.org>
From: Brett Lymn <blymn@baesystems.com.au>
List: tech-kern
Date: 11/13/2005 01:12:10
--X1bOJ3K7DJ5YkBrT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline


Folks,

After I committed the tape drive statistics code it was pointed out
that the implementation was too specific to just st tape devices and
the code should be more generic.  Based on those comments I have
reworked the instrumentation of both disks and tapes to unify the
drives into a common statistics collection framework.  Since the
instrumentation no longer just applies to disks I decided it would be
best to rename some files that used to have "disk" in their names to a
more generic "drive" naming to reflect the fact they no longer just
apply to disk drives (sys/disk.h -> sys/drive.h, kern/subr_disk.c ->
kern/subr_drive.c), this change created a fairly large diff of mostly
mechanical changes of naming.

The meat of the changes are removing the instrumentation entries from
the disk struct and putting them into a separate structure, the disk
struct now has a pointer to the instrumentation structure.  Change the
disk linked list to be a linked list of instrumentation structures,
since the original linked list was only used when reporting the disk
statistics there was no point in having the whole disk struct on the
list escpecially now that there are more than just disks on the list.
I shifted the sysctl node setups for disknames and diskstats into
subr_drive.c and renamed the sysctl nodes to drivenames and
drivestats.  I cleaned up the code in st.c to replace the code I
previously added with the new style instrumentation code.  As an extra
bonus I added instrumentation to nfs mounts too so
iostat/vmstat/systat will now report nfs read/write statistics - the
only problem with doing this is the naming of the mount, using the
mount path will not work so I do what Solaris does append a number to
the string "nfs" that indicates the number of nfs mounts.. the number
is monotonically increasing and the mount path can be worked out using
mount.

In userland I backed out the changes to vmstat and renamed dkstat.c to
drvstat.c to better reflect the non-disk related nature of the new
file.  Note that due to the sysctl numbers being the same an old
userland will work fine with the updated kernel code.

After doing these changes I nfs mounted my laptop's / to my main
machine that has a tape drive and started a tar of the nfs mount to
tape.  This is what iostat reports:

device  read KB/t    r/s   time     MB/s write KB/t    w/s   time     MB/s
fd0          0.00      0   0.00     0.00       0.00      0   0.00     0.00
md0          0.00      0   0.00     0.00       0.00      0   0.00     0.00
wd0          0.00      0   0.00     0.00       8.00      0   0.00     0.00
cd0          0.00      0   0.00     0.00       0.00      0   0.00     0.00
sd0          0.00      0   0.00     0.00       0.00      0   0.00     0.00
st0          0.00      0   0.04     0.00      10.00     22   0.04     0.22
cd1          0.00      0   0.00     0.00       0.00      0   0.00     0.00
nfs0         4.22     37   1.00     0.15       0.00      0   1.00     0.00
device  read KB/t    r/s   time     MB/s write KB/t    w/s   time     MB/s
fd0          0.00      0   0.00     0.00       0.00      0   0.00     0.00
md0          0.00      0   0.00     0.00       0.00      0   0.00     0.00
wd0          0.00      0   0.00     0.00       0.00      0   0.00     0.00
cd0          0.00      0   0.00     0.00       0.00      0   0.00     0.00
sd0          0.00      0   0.00     0.00       0.00      0   0.00     0.00
st0          0.00      0   0.04     0.00      10.00     28   0.04     0.27
cd1          0.00      0   0.00     0.00       0.00      0   0.00     0.00
nfs0         4.03     49   1.00     0.19       0.00      0   1.00     0.00

Attached are the patches and extra files.  The diff is relative to the
top of the source tree.  Put drive.h into sys/sys, subr_drive.c into
sys/kern.  Put the drvstats.* files into usr.bin/vmstat.

Just in case the attachments mess up, there is a tar file on
ftp.netbsd.org in /pub/NetBSD/misc/blymn/drives_patch.tar.gz that
contains all the files.

Any comments/feedback?

-- 
Brett Lymn

--X1bOJ3K7DJ5YkBrT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="drive.patch"

? drive.patch
? sys.patch.log
? sys.tar
Index: sys/arch/acorn32/mainbus/fd.c
===================================================================
RCS file: /cvsroot/src/sys/arch/acorn32/mainbus/fd.c,v
retrieving revision 1.21
diff -u -r1.21 fd.c
--- sys/arch/acorn32/mainbus/fd.c	15 Oct 2005 17:29:10 -0000	1.21
+++ sys/arch/acorn32/mainbus/fd.c	12 Nov 2005 13:10:29 -0000
@@ -101,7 +101,7 @@
 #include <sys/ioctl.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/buf.h>
 #include <sys/bufq.h>
 #include <sys/malloc.h>
@@ -1030,8 +1030,8 @@
 		fd->sc_cylin = -1;
 		fdc->sc_state = SEEKWAIT;
 
-		fd->sc_dk.dk_seek++;
-		disk_busy(&fd->sc_dk);
+		fd->sc_dk.stats->seek++;
+		drive_busy(fd->sc_dk.stats);
 
 		callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc);
 		return 1;
@@ -1120,7 +1120,7 @@
 		}
 		fdc->sc_state = IOCOMPLETE;
 
-		disk_busy(&fd->sc_dk);
+		drive_busy(fd->sc_dk.stats);
 
 		/* allow 2 seconds for operation */
 		callout_reset(&fdc->sc_timo_ch, 2 * hz, fdctimeout, fdc);
@@ -1137,7 +1137,7 @@
 
 	case SEEKCOMPLETE:
 		/* no data on seek */
-		disk_unbusy(&fd->sc_dk, 0, 0);
+		drive_unbusy(fd->sc_dk.stats, 0, 0);
 
 		/* Make sure seek really happened. */
 		out_fdc(iot, ioh, NE7CMD_SENSEI);
@@ -1164,7 +1164,7 @@
 	case IOCOMPLETE: /* IO DONE, post-analyze */
 		callout_stop(&fdc->sc_timo_ch);
 
-		disk_unbusy(&fd->sc_dk, (bp->b_bcount - bp->b_resid),
+		drive_unbusy(fd->sc_dk.stats, (bp->b_bcount - bp->b_resid),
 		    (bp->b_flags & B_READ));
 
 		if (fdcresult(fdc) != 7 || (st0 & 0xf8) != 0) {
Index: sys/arch/algor/algor/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/algor/algor/disksubr.c,v
retrieving revision 1.9
diff -u -r1.9 disksubr.c
--- sys/arch/algor/algor/disksubr.c	9 Jun 2005 06:48:44 -0000	1.9
+++ sys/arch/algor/algor/disksubr.c	12 Nov 2005 13:10:29 -0000
@@ -36,7 +36,7 @@
 #include <sys/ioccom.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/systm.h>
 
 #include <machine/cpu.h>
Index: sys/arch/alpha/alpha/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/alpha/alpha/disksubr.c,v
retrieving revision 1.28
diff -u -r1.28 disksubr.c
--- sys/arch/alpha/alpha/disksubr.c	1 Jun 2005 16:11:15 -0000	1.28
+++ sys/arch/alpha/alpha/disksubr.c	12 Nov 2005 13:10:29 -0000
@@ -37,7 +37,7 @@
 #include <sys/ioccom.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 
 #include <machine/cpu.h>
 #include <machine/autoconf.h>
Index: sys/arch/amd64/amd64/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amd64/amd64/disksubr.c,v
retrieving revision 1.8
diff -u -r1.8 disksubr.c
--- sys/arch/amd64/amd64/disksubr.c	8 Oct 2003 04:25:44 -0000	1.8
+++ sys/arch/amd64/amd64/disksubr.c	12 Nov 2005 13:10:29 -0000
@@ -43,7 +43,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 
 #include "opt_mbr.h"
Index: sys/arch/amiga/amiga/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amiga/amiga/autoconf.c,v
retrieving revision 1.97
diff -u -r1.97 autoconf.c
--- sys/arch/amiga/amiga/autoconf.c	3 Jul 2005 10:22:25 -0000	1.97
+++ sys/arch/amiga/amiga/autoconf.c	12 Nov 2005 13:10:29 -0000
@@ -40,7 +40,7 @@
 #include <sys/buf.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/proc.h>
 #include <machine/cpu.h>
 #include <amiga/amiga/cfdev.h>
@@ -400,7 +400,7 @@
 			 * device.
 			 */
 			devs = (struct device **)sd_cd.cd_devs;
-			if ((dkp = disk_find(devs[unit]->dv_xname)) == NULL)
+			if ((dkp = drive_find(devs[unit]->dv_xname)) == NULL)
 				continue;
 
 			if (dkp->dk_driver == NULL ||
@@ -449,7 +449,7 @@
 			 * current device.
 			 */
 			devs = (struct device **)genericconf[i]->cd_devs;
-			if ((dkp = disk_find(devs[unit]->dv_xname)) == NULL)
+			if ((dkp = drive_find(devs[unit]->dv_xname)) == NULL)
 				continue;
 
 			if (dkp->dk_driver == NULL ||
Index: sys/arch/amiga/amiga/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amiga/amiga/disksubr.c,v
retrieving revision 1.46
diff -u -r1.46 disksubr.c
--- sys/arch/amiga/amiga/disksubr.c	13 Jun 2005 19:31:54 -0000	1.46
+++ sys/arch/amiga/amiga/disksubr.c	12 Nov 2005 13:10:30 -0000
@@ -72,7 +72,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <amiga/amiga/adosglue.h>
 
 /*
Index: sys/arch/amiga/dev/fd.c
===================================================================
RCS file: /cvsroot/src/sys/arch/amiga/dev/fd.c,v
retrieving revision 1.65
diff -u -r1.65 fd.c
--- sys/arch/amiga/dev/fd.c	15 Oct 2005 17:29:10 -0000	1.65
+++ sys/arch/amiga/dev/fd.c	12 Nov 2005 13:10:30 -0000
@@ -46,7 +46,7 @@
 #include <sys/ioctl.h>
 #include <sys/fcntl.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/dkbad.h>
 #include <sys/proc.h>
 #include <sys/conf.h>
@@ -1193,7 +1193,7 @@
 	 * Mark us as busy now, in case fddone() gets called in one
 	 * of the cases below.
 	 */
-	disk_busy(&sc->dkdev);
+	drive_busy(sc->dkdev.stats);
 
 	/*
 	 * make sure same disk is loaded
@@ -1581,7 +1581,7 @@
 	 */
 	(void)BUFQ_GET(sc->bufq);
 
-	disk_unbusy(&sc->dkdev, (bp->b_bcount - bp->b_resid),
+	drive_unbusy(sc->dkdev.stats, (bp->b_bcount - bp->b_resid),
 	    (bp->b_flags & B_READ));
 
 	biodone(bp);
Index: sys/arch/arc/arc/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/arc/disksubr.c,v
retrieving revision 1.21
diff -u -r1.21 disksubr.c
--- sys/arch/arc/arc/disksubr.c	3 Jun 2005 12:30:53 -0000	1.21
+++ sys/arch/arc/arc/disksubr.c	12 Nov 2005 13:10:30 -0000
@@ -39,7 +39,7 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/buf.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/syslog.h>
 
Index: sys/arch/arc/jazz/fd.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/jazz/fd.c,v
retrieving revision 1.22
diff -u -r1.22 fd.c
--- sys/arch/arc/jazz/fd.c	15 Oct 2005 17:29:10 -0000	1.22
+++ sys/arch/arc/jazz/fd.c	12 Nov 2005 13:10:31 -0000
@@ -84,7 +84,7 @@
 #include <sys/ioctl.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/buf.h>
 #include <sys/bufq.h>
 #include <sys/uio.h>
@@ -831,8 +831,8 @@
 		fd->sc_cylin = -1;
 		fdc->sc_state = SEEKWAIT;
 
-		fd->sc_dk.dk_seek++;
-		disk_busy(&fd->sc_dk);
+		fd->sc_dk.stats->seek++;
+		drive_busy(fd->sc_dk.stats);
 
 		callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc);
 		return 1;
@@ -885,7 +885,7 @@
 		out_fdc(iot, ioh, type->datalen);	/* data length */
 		fdc->sc_state = IOCOMPLETE;
 
-		disk_busy(&fd->sc_dk);
+		drive_busy(fd->sc_dk.stats);
 
 		/* allow 2 seconds for operation */
 		callout_reset(&fdc->sc_timo_ch, 2 * hz, fdctimeout, fdc);
@@ -899,7 +899,7 @@
 		return 1;
 
 	case SEEKCOMPLETE:
-		disk_unbusy(&fd->sc_dk, 0, 0);
+		drive_unbusy(fd->sc_dk.stats, 0, 0);
 
 		/* Make sure seek really happened. */
 		out_fdc(iot, ioh, NE7CMD_SENSEI);
@@ -926,7 +926,7 @@
 	case IOCOMPLETE: /* IO DONE, post-analyze */
 		callout_stop(&fdc->sc_timo_ch);
 
-		disk_unbusy(&fd->sc_dk, (bp->b_bcount - bp->b_resid),
+		drive_unbusy(fd->sc_dk.stats, (bp->b_bcount - bp->b_resid),
 		    (bp->b_flags & B_READ));
 
 		i = fdcresult(fdc);
Index: sys/arch/arc/stand/boot/conf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/stand/boot/conf.c,v
retrieving revision 1.2
diff -u -r1.2 conf.c
--- sys/arch/arc/stand/boot/conf.c	23 Jun 2005 19:44:00 -0000	1.2
+++ sys/arch/arc/stand/boot/conf.c	12 Nov 2005 13:10:31 -0000
@@ -48,7 +48,7 @@
 #include <lib/libsa/dev_net.h>
 #include <lib/libsa/nfs.h>
 #endif
-#include "disk.h"
+#include "drive.h"
 
 #ifndef LIBSA_SINGLE_DEVICE
 
Index: sys/arch/arc/stand/boot/disk.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arc/stand/boot/disk.c,v
retrieving revision 1.2
diff -u -r1.2 disk.c
--- sys/arch/arc/stand/boot/disk.c	21 Apr 2005 13:34:29 -0000	1.2
+++ sys/arch/arc/stand/boot/disk.c	12 Nov 2005 13:10:31 -0000
@@ -43,7 +43,7 @@
 #include <dev/arcbios/arcbios.h>
 
 #include "common.h"
-#include "disk.h"
+#include "drive.h"
 
 #define	RF_PROTECTED_SECTORS	64	/* XXX refer to <.../rf_optnames.h> */
 
Index: sys/arch/arm/arm/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/arm/arm/disksubr.c,v
retrieving revision 1.13
diff -u -r1.13 disksubr.c
--- sys/arch/arm/arm/disksubr.c	2 Jun 2005 17:45:59 -0000	1.13
+++ sys/arch/arm/arm/disksubr.c	12 Nov 2005 13:10:31 -0000
@@ -106,7 +106,7 @@
 #include <sys/disklabel.h>
 #include <sys/syslog.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 
 /*
  * Attempt to read a disk label from a device
Index: sys/arch/atari/atari/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/atari/atari/autoconf.c,v
retrieving revision 1.51
diff -u -r1.51 autoconf.c
--- sys/arch/atari/atari/autoconf.c	3 Jul 2005 10:22:25 -0000	1.51
+++ sys/arch/atari/atari/autoconf.c	12 Nov 2005 13:10:31 -0000
@@ -40,7 +40,7 @@
 #include <sys/buf.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <machine/disklabel.h>
 #include <machine/cpu.h>
 #include <atari/atari/device.h>
@@ -218,7 +218,7 @@
 			 * current device.
 			 */
 			devs = (struct device **)genericconf[i]->cd_devs;
-			if ((dkp = disk_find(devs[unit]->dv_xname)) == NULL)
+			if ((dkp = drive_find(devs[unit]->dv_xname)) == NULL)
 				continue;
 
 			if (dkp->dk_driver == NULL ||
Index: sys/arch/atari/atari/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/atari/atari/disksubr.c,v
retrieving revision 1.29
diff -u -r1.29 disksubr.c
--- sys/arch/atari/atari/disksubr.c	15 Jul 2003 01:19:43 -0000	1.29
+++ sys/arch/atari/atari/disksubr.c	12 Nov 2005 13:10:31 -0000
@@ -44,7 +44,7 @@
 #include <sys/buf.h>
 #include <ufs/ufs/dinode.h>
 #include <ufs/ffs/fs.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <machine/ahdilabel.h>
 
Index: sys/arch/atari/dev/fd.c
===================================================================
RCS file: /cvsroot/src/sys/arch/atari/dev/fd.c,v
retrieving revision 1.51
diff -u -r1.51 fd.c
--- sys/arch/atari/dev/fd.c	15 Oct 2005 17:29:10 -0000	1.51
+++ sys/arch/atari/dev/fd.c	12 Nov 2005 13:10:32 -0000
@@ -64,7 +64,7 @@
 #include <sys/fcntl.h>
 #include <sys/conf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/dkbad.h>
 #include <atari/atari/device.h>
 #include <atari/atari/stalloc.h>
@@ -707,7 +707,7 @@
 	fd_state     = FLP_XFER;	/* Yes, we're going to transfer	*/
 
 	/* Instrumentation. */
-	disk_busy(&sc->dkdev);
+	drive_busy(sc->dkdev.stats);
 
 	fd_xfer(sc);
 }
@@ -747,7 +747,7 @@
 #endif
 		bp->b_resid = sc->io_bytes;
 
-		disk_unbusy(&sc->dkdev, (bp->b_bcount - bp->b_resid),
+		drive_unbusy(sc->dkdev.stats, (bp->b_bcount - bp->b_resid),
 		    (bp->b_flags & B_READ));
 
 		biodone(bp);
Index: sys/arch/atari/dev/hdfd.c
===================================================================
RCS file: /cvsroot/src/sys/arch/atari/dev/hdfd.c,v
retrieving revision 1.46
diff -u -r1.46 hdfd.c
--- sys/arch/atari/dev/hdfd.c	15 Oct 2005 17:29:10 -0000	1.46
+++ sys/arch/atari/dev/hdfd.c	12 Nov 2005 13:10:32 -0000
@@ -103,7 +103,7 @@
 #include <sys/ioctl.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/buf.h>
 #include <sys/bufq.h>
 #include <sys/malloc.h>
@@ -1050,8 +1050,8 @@
 		fd->sc_cylin = -1;
 		fdc->sc_state = SEEKWAIT;
 
-		fd->sc_dk.dk_seek++;
-		disk_busy(&fd->sc_dk);
+		fd->sc_dk.stats->seek++;
+		drive_busy(fd->sc_dk.stats);
 
 		callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc);
 		return 1;
@@ -1130,7 +1130,7 @@
 		}
 		fdc->sc_state = IOCOMPLETE;
 
-		disk_busy(&fd->sc_dk);
+		drive_busy(fd->sc_dk.stats);
 
 		/* allow 2 seconds for operation */
 		callout_reset(&fdc->sc_timo_ch, 2 * hz, fdctimeout, fdc);
@@ -1145,7 +1145,7 @@
 
 	case SEEKCOMPLETE:
 		/* no data on seek */
-		disk_unbusy(&fd->sc_dk, 0, 0);
+		drive_unbusy(fd->sc_dk.stats, 0, 0);
 
 		/* Make sure seek really happened. */
 		out_fdc(NE7CMD_SENSEI);
@@ -1170,7 +1170,7 @@
 	case IOCOMPLETE: /* IO DONE, post-analyze */
 		callout_stop(&fdc->sc_timo_ch);
 
-		disk_unbusy(&fd->sc_dk, (bp->b_bcount - bp->b_resid),
+		drive_unbusy(fd->sc_dk.stats, (bp->b_bcount - bp->b_resid),
 		    (bp->b_flags & B_READ));
 
 		if (fdcresult(fdc) != 7 || (st1 & 0x37) != 0) {
Index: sys/arch/atari/dev/md_root.c
===================================================================
RCS file: /cvsroot/src/sys/arch/atari/dev/md_root.c,v
retrieving revision 1.19
diff -u -r1.19 md_root.c
--- sys/arch/atari/dev/md_root.c	15 Jul 2003 01:19:51 -0000	1.19
+++ sys/arch/atari/dev/md_root.c	12 Nov 2005 13:10:32 -0000
@@ -44,7 +44,7 @@
 #include <sys/fcntl.h>
 #include <sys/conf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/dkbad.h>
 
 #include <dev/cons.h>
Index: sys/arch/bebox/bebox/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/bebox/bebox/disksubr.c,v
retrieving revision 1.17
diff -u -r1.17 disksubr.c
--- sys/arch/bebox/bebox/disksubr.c	10 Jun 2005 15:42:55 -0000	1.17
+++ sys/arch/bebox/bebox/disksubr.c	12 Nov 2005 13:10:32 -0000
@@ -38,7 +38,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 
 #include "opt_mbr.h"
Index: sys/arch/cobalt/cobalt/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/cobalt/cobalt/disksubr.c,v
retrieving revision 1.15
diff -u -r1.15 disksubr.c
--- sys/arch/cobalt/cobalt/disksubr.c	4 Jun 2005 06:05:38 -0000	1.15
+++ sys/arch/cobalt/cobalt/disksubr.c	12 Nov 2005 13:10:33 -0000
@@ -36,7 +36,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 
 #define NO_MBR_SIGNATURE ((struct mbr_partition *) -1)
Index: sys/arch/dreamcast/dev/gdrom.c
===================================================================
RCS file: /cvsroot/src/sys/arch/dreamcast/dev/gdrom.c,v
retrieving revision 1.17
diff -u -r1.17 gdrom.c
--- sys/arch/dreamcast/dev/gdrom.c	19 Feb 2005 15:37:34 -0000	1.17
+++ sys/arch/dreamcast/dev/gdrom.c	12 Nov 2005 13:10:33 -0000
@@ -43,7 +43,7 @@
 #include <sys/ioctl.h>
 #include <sys/fcntl.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/cdio.h>
 #include <sys/proc.h>
 #include <sys/conf.h>
Index: sys/arch/dreamcast/dev/maple/mmemcard.c
===================================================================
RCS file: /cvsroot/src/sys/arch/dreamcast/dev/maple/mmemcard.c,v
retrieving revision 1.6
diff -u -r1.6 mmemcard.c
--- sys/arch/dreamcast/dev/maple/mmemcard.c	15 Oct 2005 17:29:10 -0000	1.6
+++ sys/arch/dreamcast/dev/maple/mmemcard.c	12 Nov 2005 13:10:33 -0000
@@ -44,7 +44,7 @@
 #include <sys/bufq.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/proc.h>
@@ -776,7 +776,7 @@
 
 	pt = &sc->sc_pt[MMEM_PART(DISKUNIT(bp->b_dev))];
 	s = splbio();
-	disk_busy(&pt->pt_dk);
+	drive_busy(pt->pt_dk.stats);
 	splx(s);
 
 	/*
@@ -886,7 +886,7 @@
 		/* terminate current transfer */
 		sc->sc_bp = NULL;
 		s = splbio();
-		disk_unbusy(&pt->pt_dk, sc->sc_iobuf - bp->b_data,
+		drive_unbusy(pt->pt_dk.stats, sc->sc_iobuf - bp->b_data,
 		    sc->sc_stat == MMEM_READ);
 		biodone(bp);
 		splx(s);
Index: sys/arch/evbmips/evbmips/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbmips/evbmips/disksubr.c,v
retrieving revision 1.8
diff -u -r1.8 disksubr.c
--- sys/arch/evbmips/evbmips/disksubr.c	9 Jun 2005 21:43:13 -0000	1.8
+++ sys/arch/evbmips/evbmips/disksubr.c	12 Nov 2005 13:10:34 -0000
@@ -36,7 +36,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 
 /*
  * Attempt to read a disk label from a device
Index: sys/arch/evbppc/evbppc/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/evbppc/evbppc/disksubr.c,v
retrieving revision 1.8
diff -u -r1.8 disksubr.c
--- sys/arch/evbppc/evbppc/disksubr.c	3 Jun 2005 11:15:25 -0000	1.8
+++ sys/arch/evbppc/evbppc/disksubr.c	12 Nov 2005 13:10:34 -0000
@@ -38,7 +38,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 
 /*
Index: sys/arch/hp300/dev/rd.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hp300/dev/rd.c,v
retrieving revision 1.68
diff -u -r1.68 rd.c
--- sys/arch/hp300/dev/rd.c	15 Oct 2005 17:29:10 -0000	1.68
+++ sys/arch/hp300/dev/rd.c	12 Nov 2005 13:10:34 -0000
@@ -128,7 +128,7 @@
 #include <sys/bufq.h>
 #include <sys/conf.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/fcntl.h>
 #include <sys/ioctl.h>
@@ -835,8 +835,8 @@
 		     sizeof(rs->sc_ioc)-2) == sizeof(rs->sc_ioc)-2) {
 
 		/* Instrumentation. */
-		disk_busy(&rs->sc_dkdev);
-		rs->sc_dkdev.dk_seek++;
+		drive_busy(rs->sc_dkdev.stats);
+		rs->sc_dkdev->stats->seek++;
 
 #ifdef DEBUG
 		if (rddebug & RDB_IO)
@@ -889,7 +889,7 @@
 	rw = bp->b_flags & B_READ;
 
 	/* Instrumentation. */
-	disk_busy(&rs->sc_dkdev);
+	drive_busy(rs->sc_dkdev.stats);
 
 #ifdef USELEDS
 	ledcontrol(0, 0, LED_DISK);
@@ -919,7 +919,7 @@
 		return;
 	}
 #endif
-	disk_unbusy(&rs->sc_dkdev, (bp->b_bcount - bp->b_resid),
+	drive_unbusy(rs->sc_dkdev.stats, (bp->b_bcount - bp->b_resid),
 	    (bp->b_flags & B_READ));
 
 	if (rs->sc_flags & RDF_SEEK) {
@@ -938,7 +938,7 @@
 #endif
 
 			/* Instrumentation. */
-			disk_busy(&rs->sc_dkdev);
+			drive_busy(rs->sc_dkdev.stats);
 			rs->sc_flags |= RDF_SWAIT;
 			hpibawait(ctlr);
 			return;
Index: sys/arch/hp300/hp300/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hp300/hp300/disksubr.c,v
retrieving revision 1.22
diff -u -r1.22 disksubr.c
--- sys/arch/hp300/hp300/disksubr.c	2 Jun 2005 16:45:41 -0000	1.22
+++ sys/arch/hp300/hp300/disksubr.c	12 Nov 2005 13:10:34 -0000
@@ -42,7 +42,7 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/buf.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 
 /*
Index: sys/arch/hp700/hp700/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hp700/hp700/disksubr.c,v
retrieving revision 1.14
diff -u -r1.14 disksubr.c
--- sys/arch/hp700/hp700/disksubr.c	31 May 2005 16:13:09 -0000	1.14
+++ sys/arch/hp700/hp700/disksubr.c	12 Nov 2005 13:10:35 -0000
@@ -114,7 +114,7 @@
 #include <sys/device.h>
 #include <sys/disklabel.h>
 #include <sys/syslog.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 
 const char *readliflabel(struct buf *, void (*)(struct buf *),
     struct disklabel *, struct cpu_disklabel *, int *, int *, int);
Index: sys/arch/hpc/hpc/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/hpc/hpc/disksubr.c,v
retrieving revision 1.10
diff -u -r1.10 disksubr.c
--- sys/arch/hpc/hpc/disksubr.c	31 May 2005 22:45:04 -0000	1.10
+++ sys/arch/hpc/hpc/disksubr.c	12 Nov 2005 13:10:35 -0000
@@ -38,7 +38,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 
 #include "opt_mbr.h"
Index: sys/arch/luna68k/luna68k/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/luna68k/luna68k/disksubr.c,v
retrieving revision 1.18
diff -u -r1.18 disksubr.c
--- sys/arch/luna68k/luna68k/disksubr.c	5 Jun 2005 09:08:48 -0000	1.18
+++ sys/arch/luna68k/luna68k/disksubr.c	12 Nov 2005 13:10:36 -0000
@@ -110,7 +110,7 @@
 #include <sys/buf.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/dkbad.h>
 
 #include <dev/sun/disklabel.h>
Index: sys/arch/mac68k/mac68k/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mac68k/mac68k/autoconf.c,v
retrieving revision 1.63
diff -u -r1.63 autoconf.c
--- sys/arch/mac68k/mac68k/autoconf.c	9 Jun 2005 22:00:40 -0000	1.63
+++ sys/arch/mac68k/mac68k/autoconf.c	12 Nov 2005 13:10:36 -0000
@@ -58,7 +58,7 @@
 #include <sys/conf.h>
 #include <sys/reboot.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 
 #include <dev/cons.h>
 
Index: sys/arch/mac68k/mac68k/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mac68k/mac68k/disksubr.c,v
retrieving revision 1.50
diff -u -r1.50 disksubr.c
--- sys/arch/mac68k/mac68k/disksubr.c	9 Jun 2005 21:59:24 -0000	1.50
+++ sys/arch/mac68k/mac68k/disksubr.c	12 Nov 2005 13:10:36 -0000
@@ -70,7 +70,7 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/buf.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/bootblock.h>
 #include <sys/syslog.h>
Index: sys/arch/mac68k/obio/iwm_fd.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mac68k/obio/iwm_fd.c,v
retrieving revision 1.34
diff -u -r1.34 iwm_fd.c
--- sys/arch/mac68k/obio/iwm_fd.c	15 Oct 2005 17:29:10 -0000	1.34
+++ sys/arch/mac68k/obio/iwm_fd.c	12 Nov 2005 13:10:37 -0000
@@ -56,7 +56,7 @@
 #define DKTYPENAMES
 #include <sys/disklabel.h>
 
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/dkbad.h>
 #include <sys/buf.h>
 #include <sys/bufq.h>
@@ -1201,7 +1201,7 @@
 	}
 	fd->ioDirection = bp->b_flags & B_READ;
 
-	disk_busy(&fd->diskInfo);
+	drive_busy(fd->diskInfo.stats);
 	if (!(fd->state & IWM_FD_MOTOR_ON)) {
 		iwmMotor(fd->unit, 1);
 		fd->state |= IWM_FD_MOTOR_ON;
@@ -1604,7 +1604,7 @@
 	if (DISABLED && TRACE_STRAT)
 		printf(" Next buf (bufQueue first) at %p\n",
 		    BUFQ_PEEK(fd->bufQueue));
-	disk_unbusy(&fd->diskInfo, bp->b_bcount - bp->b_resid,
+	drive_unbusy(fd->diskInfo.stats, bp->b_bcount - bp->b_resid,
 	    (bp->b_flags & B_READ));
 	biodone(bp);
 	/* 
Index: sys/arch/macppc/macppc/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/macppc/macppc/disksubr.c,v
retrieving revision 1.35
diff -u -r1.35 disksubr.c
--- sys/arch/macppc/macppc/disksubr.c	3 Jun 2005 18:19:11 -0000	1.35
+++ sys/arch/macppc/macppc/disksubr.c	12 Nov 2005 13:10:37 -0000
@@ -112,7 +112,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/conf.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/bootblock.h>
 #include <sys/syslog.h>
Index: sys/arch/mipsco/mipsco/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mipsco/mipsco/disksubr.c,v
retrieving revision 1.16
diff -u -r1.16 disksubr.c
--- sys/arch/mipsco/mipsco/disksubr.c	9 Jun 2005 13:49:15 -0000	1.16
+++ sys/arch/mipsco/mipsco/disksubr.c	12 Nov 2005 13:10:37 -0000
@@ -38,7 +38,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/syslog.h>
 #include <ufs/ufs/dinode.h>		/* XXX for fs.h */
Index: sys/arch/mvme68k/mvme68k/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mvme68k/mvme68k/disksubr.c,v
retrieving revision 1.28
diff -u -r1.28 disksubr.c
--- sys/arch/mvme68k/mvme68k/disksubr.c	3 Jun 2005 08:52:55 -0000	1.28
+++ sys/arch/mvme68k/mvme68k/disksubr.c	12 Nov 2005 13:10:37 -0000
@@ -39,7 +39,7 @@
 #include <sys/device.h>
 #define FSTYPENAMES
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 
 #include <dev/scsipi/scsi_all.h>
 #include <dev/scsipi/scsipi_all.h>
Index: sys/arch/mvmeppc/mvmeppc/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/mvmeppc/mvmeppc/disksubr.c,v
retrieving revision 1.10
diff -u -r1.10 disksubr.c
--- sys/arch/mvmeppc/mvmeppc/disksubr.c	3 Jun 2005 10:57:17 -0000	1.10
+++ sys/arch/mvmeppc/mvmeppc/disksubr.c	12 Nov 2005 13:10:37 -0000
@@ -38,7 +38,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 
 #include "opt_mbr.h"
Index: sys/arch/news68k/news68k/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/news68k/news68k/disksubr.c,v
retrieving revision 1.22
diff -u -r1.22 disksubr.c
--- sys/arch/news68k/news68k/disksubr.c	2 Jun 2005 14:36:25 -0000	1.22
+++ sys/arch/news68k/news68k/disksubr.c	12 Nov 2005 13:10:38 -0000
@@ -38,7 +38,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 
 /*
Index: sys/arch/newsmips/newsmips/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/newsmips/newsmips/disksubr.c,v
retrieving revision 1.19
diff -u -r1.19 disksubr.c
--- sys/arch/newsmips/newsmips/disksubr.c	3 Jun 2005 13:44:50 -0000	1.19
+++ sys/arch/newsmips/newsmips/disksubr.c	12 Nov 2005 13:10:38 -0000
@@ -38,7 +38,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 
 /*
Index: sys/arch/next68k/next68k/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/next68k/next68k/disksubr.c,v
retrieving revision 1.18
diff -u -r1.18 disksubr.c
--- sys/arch/next68k/next68k/disksubr.c	5 Jun 2005 11:35:09 -0000	1.18
+++ sys/arch/next68k/next68k/disksubr.c	12 Nov 2005 13:10:38 -0000
@@ -46,7 +46,7 @@
 #include <sys/disklabel.h>
 #include <sys/syslog.h>
 
-#include <sys/disk.h>
+#include <sys/drive.h>
 
 #include <ufs/ufs/dinode.h>             /* XXX for fs.h */
 #include <ufs/ffs/fs.h>                 /* XXX for SBLOCKSIZE */
Index: sys/arch/ofppc/ofppc/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/ofppc/ofppc/disksubr.c,v
retrieving revision 1.16
diff -u -r1.16 disksubr.c
--- sys/arch/ofppc/ofppc/disksubr.c	8 Oct 2003 04:25:45 -0000	1.16
+++ sys/arch/ofppc/ofppc/disksubr.c	12 Nov 2005 13:10:38 -0000
@@ -38,7 +38,7 @@
 #include <sys/buf.h>
 #include <sys/conf.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/bootblock.h>
 #include <sys/fcntl.h>
Index: sys/arch/pc532/pc532/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/pc532/pc532/disksubr.c,v
retrieving revision 1.27
diff -u -r1.27 disksubr.c
--- sys/arch/pc532/pc532/disksubr.c	2 Oct 2005 15:07:41 -0000	1.27
+++ sys/arch/pc532/pc532/disksubr.c	12 Nov 2005 13:10:38 -0000
@@ -38,7 +38,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/reboot.h>
 #include <sys/syslog.h>
Index: sys/arch/pdp10/dev/hp.c
===================================================================
RCS file: /cvsroot/src/sys/arch/pdp10/dev/hp.c,v
retrieving revision 1.3
diff -u -r1.3 hp.c
--- sys/arch/pdp10/dev/hp.c	15 Oct 2005 17:29:11 -0000	1.3
+++ sys/arch/pdp10/dev/hp.c	12 Nov 2005 13:10:38 -0000
@@ -44,7 +44,7 @@
 #include <sys/systm.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/dkio.h>
 #include <sys/buf.h>
 #include <sys/bufq.h>
@@ -264,8 +264,8 @@
 	/*
 	 * Collect statistics.
 	 */
-	disk_busy(&sc->sc_disk);
-	sc->sc_disk.dk_seek++;
+	drive_busy(sc->sc_disk.stats);
+	sc->sc_disk.stats->seek++;
 
 	bn = bp->b_rawblkno;
 	if (bn) {
@@ -448,7 +448,7 @@
 		    sc->sc_dev.dv_xname, mbasr);
 
 	BUFQ_PEEK(md->md_q)->b_resid = 0;
-	disk_unbusy(&sc->sc_disk, BUFQ_PEEK(md->md_q)->b_bcount,
+	drive_unbusy(sc->sc_disk.stats, BUFQ_PEEK(&md->md_q)->b_bcount,
 	    (bp->b_flags & B_READ));
 	return XFER_FINISH;
 }
Index: sys/arch/pdp10/pdp10/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/pdp10/pdp10/disksubr.c,v
retrieving revision 1.1
diff -u -r1.1 disksubr.c
--- sys/arch/pdp10/pdp10/disksubr.c	19 Aug 2003 10:55:00 -0000	1.1
+++ sys/arch/pdp10/pdp10/disksubr.c	12 Nov 2005 13:10:38 -0000
@@ -40,7 +40,7 @@
 #include <sys/buf.h>
 #include <sys/dkbad.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 #include <sys/proc.h>
 #include <sys/user.h>
Index: sys/arch/playstation2/playstation2/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/playstation2/playstation2/disksubr.c,v
retrieving revision 1.10
diff -u -r1.10 disksubr.c
--- sys/arch/playstation2/playstation2/disksubr.c	26 Jun 2005 19:57:30 -0000	1.10
+++ sys/arch/playstation2/playstation2/disksubr.c	12 Nov 2005 13:10:39 -0000
@@ -36,7 +36,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 
 #define NO_MBR_SIGNATURE ((struct mbr_partition *) -1)
 
Index: sys/arch/pmax/pmax/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/pmax/pmax/disksubr.c,v
retrieving revision 1.42
diff -u -r1.42 disksubr.c
--- sys/arch/pmax/pmax/disksubr.c	1 Jun 2005 18:34:12 -0000	1.42
+++ sys/arch/pmax/pmax/disksubr.c	12 Nov 2005 13:10:39 -0000
@@ -39,7 +39,7 @@
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/buf.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 
 #ifdef COMPAT_ULTRIX
Index: sys/arch/pmppc/pmppc/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/pmppc/pmppc/disksubr.c,v
retrieving revision 1.9
diff -u -r1.9 disksubr.c
--- sys/arch/pmppc/pmppc/disksubr.c	4 Jun 2005 20:33:57 -0000	1.9
+++ sys/arch/pmppc/pmppc/disksubr.c	12 Nov 2005 13:10:39 -0000
@@ -38,7 +38,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 
 #include "opt_mbr.h"
Index: sys/arch/powerpc/powerpc/ofw_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/powerpc/powerpc/ofw_machdep.c,v
retrieving revision 1.14
diff -u -r1.14 ofw_machdep.c
--- sys/arch/powerpc/powerpc/ofw_machdep.c	15 Jul 2003 02:54:48 -0000	1.14
+++ sys/arch/powerpc/powerpc/ofw_machdep.c	12 Nov 2005 13:10:39 -0000
@@ -38,7 +38,7 @@
 #include <sys/buf.h>
 #include <sys/conf.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/fcntl.h>
 #include <sys/ioctl.h>
Index: sys/arch/prep/prep/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/prep/prep/disksubr.c,v
retrieving revision 1.12
diff -u -r1.12 disksubr.c
--- sys/arch/prep/prep/disksubr.c	5 Jun 2005 17:56:31 -0000	1.12
+++ sys/arch/prep/prep/disksubr.c	12 Nov 2005 13:10:39 -0000
@@ -38,7 +38,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 
 #include "opt_mbr.h"
Index: sys/arch/sandpoint/sandpoint/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sandpoint/sandpoint/disksubr.c,v
retrieving revision 1.10
diff -u -r1.10 disksubr.c
--- sys/arch/sandpoint/sandpoint/disksubr.c	2 Jun 2005 14:11:19 -0000	1.10
+++ sys/arch/sandpoint/sandpoint/disksubr.c	12 Nov 2005 13:10:40 -0000
@@ -38,7 +38,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 
 #include "opt_mbr.h"
Index: sys/arch/sbmips/sbmips/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sbmips/sbmips/disksubr.c,v
retrieving revision 1.10
diff -u -r1.10 disksubr.c
--- sys/arch/sbmips/sbmips/disksubr.c	3 Jun 2005 20:58:33 -0000	1.10
+++ sys/arch/sbmips/sbmips/disksubr.c	12 Nov 2005 13:10:40 -0000
@@ -36,7 +36,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 
 #define	NO_MBR_SIGNATURE ((struct mbr_partition *) -1)
Index: sys/arch/sgimips/sgimips/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sgimips/sgimips/disksubr.c,v
retrieving revision 1.16
diff -u -r1.16 disksubr.c
--- sys/arch/sgimips/sgimips/disksubr.c	4 Oct 2005 14:47:50 -0000	1.16
+++ sys/arch/sgimips/sgimips/disksubr.c	12 Nov 2005 13:10:40 -0000
@@ -41,7 +41,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <ufs/ufs/dinode.h>
 #include <ufs/ffs/fs.h>
 
Index: sys/arch/sh3/sh3/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sh3/sh3/disksubr.c,v
retrieving revision 1.18
diff -u -r1.18 disksubr.c
--- sys/arch/sh3/sh3/disksubr.c	1 Jun 2005 11:59:13 -0000	1.18
+++ sys/arch/sh3/sh3/disksubr.c	12 Nov 2005 13:10:40 -0000
@@ -40,7 +40,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 
 #include <machine/bswap.h>
Index: sys/arch/sparc/dev/fd.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/dev/fd.c,v
retrieving revision 1.119
diff -u -r1.119 fd.c
--- sys/arch/sparc/dev/fd.c	1 Nov 2005 21:00:56 -0000	1.119
+++ sys/arch/sparc/dev/fd.c	12 Nov 2005 13:10:41 -0000
@@ -121,7 +121,7 @@
 #include <sys/ioctl.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/fdio.h>
 #include <sys/buf.h>
 #include <sys/bufq.h>
@@ -1542,9 +1542,9 @@
 		fdc->sc_state = SEEKWAIT;
 		fdc->sc_nstat = 0;
 
-		fd->sc_dk.dk_seek++;
+		fd->sc_dk.stats->seek++;
 
-		disk_busy(&fd->sc_dk);
+		drive_busy(fd->sc_dk.stats);
 		callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc);
 
 		/* specify command */
@@ -1566,7 +1566,7 @@
 		 * Disk change: force a seek operation by going to cyl 1
 		 * followed by a recalibrate.
 		 */
-		disk_busy(&fd->sc_dk);
+		drive_busy(fd->sc_dk.stats);
 		callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc);
 		fd->sc_cylin = -1;
 		fdc->sc_nstat = 0;
@@ -1640,7 +1640,7 @@
 		fdc->sc_itask = FDC_ITASK_DMA;
 		fdc->sc_nstat = 0;
 
-		disk_busy(&fd->sc_dk);
+		drive_busy(fd->sc_dk.stats);
 
 		/* allow 3 seconds for operation */
 		callout_reset(&fdc->sc_timo_ch, 3 * hz, fdctimeout, fdc);
Index: sys/arch/sparc/sparc/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/sparc/autoconf.c,v
retrieving revision 1.212
diff -u -r1.212 autoconf.c
--- sys/arch/sparc/sparc/autoconf.c	24 Sep 2005 22:30:15 -0000	1.212
+++ sys/arch/sparc/sparc/autoconf.c	12 Nov 2005 13:10:41 -0000
@@ -65,7 +65,7 @@
 #include <sys/buf.h>
 #include <sys/disklabel.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/conf.h>
 #include <sys/reboot.h>
 #include <sys/socket.h>
Index: sys/arch/sparc/sparc/genassym.cf
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc/sparc/genassym.cf,v
retrieving revision 1.47
diff -u -r1.47 genassym.cf
--- sys/arch/sparc/sparc/genassym.cf	24 Sep 2005 22:44:44 -0000	1.47
+++ sys/arch/sparc/sparc/genassym.cf	12 Nov 2005 13:10:42 -0000
@@ -87,7 +87,7 @@
 include <sys/user.h>
 include <sys/device.h>
 include <sys/disklabel.h>
-include <sys/disk.h>
+include <sys/drive.h>
 
 include <uvm/uvm.h>
 
Index: sys/arch/sparc64/sparc64/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/autoconf.c,v
retrieving revision 1.104
diff -u -r1.104 autoconf.c
--- sys/arch/sparc64/sparc64/autoconf.c	14 Aug 2005 19:12:02 -0000	1.104
+++ sys/arch/sparc64/sparc64/autoconf.c	12 Nov 2005 13:10:42 -0000
@@ -59,7 +59,7 @@
 #include <sys/buf.h>
 #include <sys/disklabel.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/conf.h>
 #include <sys/reboot.h>
 #include <sys/socket.h>
Index: sys/arch/sparc64/sparc64/genassym.cf
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/genassym.cf,v
retrieving revision 1.38
diff -u -r1.38 genassym.cf
--- sys/arch/sparc64/sparc64/genassym.cf	10 Jul 2005 00:50:16 -0000	1.38
+++ sys/arch/sparc64/sparc64/genassym.cf	12 Nov 2005 13:10:42 -0000
@@ -88,7 +88,7 @@
 include <sys/user.h>
 include <sys/device.h>
 include <sys/disklabel.h>
-include <sys/disk.h>
+include <sys/drive.h>
 
 include <uvm/uvm.h>
 
Index: sys/arch/sparc64/sparc64/ofw_machdep.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sparc64/sparc64/ofw_machdep.c,v
retrieving revision 1.27
diff -u -r1.27 ofw_machdep.c
--- sys/arch/sparc64/sparc64/ofw_machdep.c	31 May 2005 00:53:02 -0000	1.27
+++ sys/arch/sparc64/sparc64/ofw_machdep.c	12 Nov 2005 13:10:42 -0000
@@ -38,7 +38,7 @@
 #include <sys/buf.h>
 #include <sys/conf.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/fcntl.h>
 #include <sys/ioctl.h>
Index: sys/arch/sun3/dev/fd.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sun3/dev/fd.c,v
retrieving revision 1.44
diff -u -r1.44 fd.c
--- sys/arch/sun3/dev/fd.c	15 Oct 2005 17:29:11 -0000	1.44
+++ sys/arch/sun3/dev/fd.c	12 Nov 2005 13:10:43 -0000
@@ -84,7 +84,7 @@
 #include <sys/ioctl.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/fdio.h>
 #include <sys/buf.h>
 #include <sys/bufq.h>
@@ -1212,8 +1212,8 @@
 		fdc->sc_state = SEEKWAIT;
 		fdc->sc_nstat = 0;
 
-		fd->sc_dk.dk_seek++;
-		disk_busy(&fd->sc_dk);
+		fd->sc_dk.stats->seek++;
+		drive_busy(fd->sc_dk.stats);
 
 		callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc);
 		return (1);
@@ -1293,7 +1293,7 @@
 			OUT_FDC(fdc, type->datalen, IOTIMEDOUT);/*data length*/
 		}
 
-		disk_busy(&fd->sc_dk);
+		drive_busy(fd->sc_dk.stats);
 
 		/* allow 2 seconds for operation */
 		callout_reset(&fdc->sc_timo_ch, 2 * hz, fdctimeout, fdc);
@@ -1311,7 +1311,7 @@
 		/*FALLTHROUGH*/
 	case SEEKCOMPLETE:
 		/* no data on seek */
-		disk_unbusy(&fd->sc_dk, 0, 0);
+		drive_unbusy(fd->sc_dk.stats, 0, 0);
 
 		/* Make sure seek really happened. */
 		if (fdc->sc_nstat != 2 || (st0 & 0xf8) != 0x20 ||
@@ -1343,7 +1343,7 @@
 	case IOCOMPLETE: /* IO DONE, post-analyze */
 		callout_stop(&fdc->sc_timo_ch);
 
-		disk_unbusy(&fd->sc_dk, (bp->b_bcount - bp->b_resid),
+		drive_unbusy(fd->sc_dk.stats, (bp->b_bcount - bp->b_resid),
 		    (bp->b_flags & B_READ));
 
 		if (fdc->sc_nstat != 7 || (st0 & 0xf8) != 0 || st1 != 0) {
Index: sys/arch/sun3/dev/xd.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sun3/dev/xd.c,v
retrieving revision 1.50
diff -u -r1.50 xd.c
--- sys/arch/sun3/dev/xd.c	15 Oct 2005 17:29:11 -0000	1.50
+++ sys/arch/sun3/dev/xd.c	12 Nov 2005 13:10:43 -0000
@@ -73,7 +73,7 @@
 #include <sys/malloc.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 #include <sys/dkbad.h>
 #include <sys/conf.h>
@@ -1382,7 +1382,7 @@
 	xdc_rqtopb(iorq, iopb, (bp->b_flags & B_READ) ? XDCMD_RD : XDCMD_WR, 0);
 
 	/* Instrumentation. */
-	disk_busy(&xdsc->sc_dk);
+	drive_busy(xdsc->sc_dk.stats);
 
 	/* now submit [note that xdc_submit_iorq can never fail on NORM reqs] */
 
@@ -1649,7 +1649,7 @@
 				/* Sun3: map/unmap regardless of B_PHYS */
 				dvma_mapout(iorq->dbufbase,
 				            iorq->buf->b_bcount);
-			    disk_unbusy(&iorq->xd->sc_dk,
+			    drive_unbusy(iorq->xd->sc_dk.stats,
 					(iorq->buf->b_bcount - iorq->buf->b_resid),
 					(iorq->buf->b_flags & B_READ));
 			    biodone(iorq->buf);
@@ -1850,7 +1850,7 @@
 			/* Sun3: map/unmap regardless of B_PHYS */
 			dvma_mapout(iorq->dbufbase,
 					    iorq->buf->b_bcount);
-			disk_unbusy(&iorq->xd->sc_dk,
+			drive_unbusy(iorq->xd->sc_dk.stats,
 			    (bp->b_bcount - bp->b_resid),
 			    (bp->b_flags & B_READ));
 			XDC_FREE(xdcsc, rqno);
Index: sys/arch/sun3/dev/xy.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sun3/dev/xy.c,v
retrieving revision 1.52
diff -u -r1.52 xy.c
--- sys/arch/sun3/dev/xy.c	15 Oct 2005 17:29:11 -0000	1.52
+++ sys/arch/sun3/dev/xy.c	12 Nov 2005 13:10:44 -0000
@@ -73,7 +73,7 @@
 #include <sys/malloc.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 #include <sys/dkbad.h>
 #include <sys/conf.h>
@@ -1254,7 +1254,7 @@
 	xyc_rqtopb(iorq, iopb, (bp->b_flags & B_READ) ? XYCMD_RD : XYCMD_WR, 0);
 
 	/* Instrumentation. */
-	disk_busy(&xysc->sc_dk);
+	drive_busy(xysc->sc_dk.stats);
 
 	return (XY_ERR_AOK);
 }
@@ -1579,7 +1579,7 @@
 				dvma_mapout(iorq->dbufbase,
 				            iorq->buf->b_bcount);
 			    (void)BUFQ_GET(iorq->xy->xyq);
-			    disk_unbusy(&iorq->xy->sc_dk,
+			    drive_unbusy(iorq->xy->sc_dk.stats,
 				(iorq->buf->b_bcount - iorq->buf->b_resid),
 				(iorq->buf->b_flags & B_READ));
 			    biodone(iorq->buf);
@@ -1752,7 +1752,7 @@
 			dvma_mapout(iorq->dbufbase,
 					    iorq->buf->b_bcount);
 			(void)BUFQ_GET(iorq->xy->xyq);
-			disk_unbusy(&iorq->xy->sc_dk,
+			drive_unbusy(iorq->xy->sc_dk.stats,
 			    (bp->b_bcount - bp->b_resid),
 			    (bp->b_flags & B_READ));
 			iorq->mode = XY_SUB_FREE;
Index: sys/arch/sun68k/sun68k/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/sun68k/sun68k/disksubr.c,v
retrieving revision 1.10
diff -u -r1.10 disksubr.c
--- sys/arch/sun68k/sun68k/disksubr.c	3 Jun 2005 21:57:16 -0000	1.10
+++ sys/arch/sun68k/sun68k/disksubr.c	12 Nov 2005 13:10:44 -0000
@@ -109,7 +109,7 @@
 #include <sys/buf.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/dkbad.h>
 
 #include <dev/sun/disklabel.h>
Index: sys/arch/vax/mba/hp.c
===================================================================
RCS file: /cvsroot/src/sys/arch/vax/mba/hp.c,v
retrieving revision 1.38
diff -u -r1.38 hp.c
--- sys/arch/vax/mba/hp.c	15 Oct 2005 17:29:11 -0000	1.38
+++ sys/arch/vax/mba/hp.c	12 Nov 2005 13:10:44 -0000
@@ -48,7 +48,7 @@
 #include <sys/systm.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/dkio.h>
 #include <sys/buf.h>
 #include <sys/bufq.h>
@@ -234,8 +234,8 @@
 	/*
 	 * Collect statistics.
 	 */
-	disk_busy(&sc->sc_disk);
-	sc->sc_disk.dk_seek++;
+	drive_busy(sc->sc_disk.stats);
+	sc->sc_disk->stats.seek++;
 
 	bn = bp->b_rawblkno;
 	if (bn) {
@@ -406,7 +406,7 @@
 		    sc->sc_dev.dv_xname, mbasr);
 
 	BUFQ_PEEK(md->md_q)->b_resid = 0;
-	disk_unbusy(&sc->sc_disk, BUFQ_PEEK(md->md_q)->b_bcount,
+	drive_unbusy(sc->sc_disk.stats, BUFQ_PEEK(&md->md_q)->b_bcount,
 	    (bp->b_flags & B_READ));
 	return XFER_FINISH;
 }
Index: sys/arch/vax/vax/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/vax/vax/autoconf.c,v
retrieving revision 1.84
diff -u -r1.84 autoconf.c
--- sys/arch/vax/vax/autoconf.c	27 Jun 2005 11:03:25 -0000	1.84
+++ sys/arch/vax/vax/autoconf.c	12 Nov 2005 13:10:44 -0000
@@ -40,7 +40,7 @@
 #include <sys/systm.h>
 #include <sys/device.h>
 #include <sys/reboot.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/buf.h>
 #include <sys/bufq.h>
 #include <sys/conf.h>
Index: sys/arch/vax/vax/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/vax/vax/disksubr.c,v
retrieving revision 1.38
diff -u -r1.38 disksubr.c
--- sys/arch/vax/vax/disksubr.c	27 Jun 2005 11:03:25 -0000	1.38
+++ sys/arch/vax/vax/disksubr.c	12 Nov 2005 13:10:44 -0000
@@ -39,7 +39,7 @@
 #include <sys/buf.h>
 #include <sys/dkbad.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 #include <sys/proc.h>
 #include <sys/user.h>
Index: sys/arch/vax/vsa/hdc9224.c
===================================================================
RCS file: /cvsroot/src/sys/arch/vax/vsa/hdc9224.c,v
retrieving revision 1.32
diff -u -r1.32 hdc9224.c
--- sys/arch/vax/vsa/hdc9224.c	15 Oct 2005 17:29:11 -0000	1.32
+++ sys/arch/vax/vsa/hdc9224.c	12 Nov 2005 13:10:45 -0000
@@ -66,7 +66,7 @@
 #include <sys/user.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 #include <sys/reboot.h>
 
Index: sys/arch/x68k/dev/bmd.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x68k/dev/bmd.c,v
retrieving revision 1.4
diff -u -r1.4 bmd.c
--- sys/arch/x68k/dev/bmd.c	13 Jun 2005 00:34:08 -0000	1.4
+++ sys/arch/x68k/dev/bmd.c	12 Nov 2005 13:10:45 -0000
@@ -41,7 +41,7 @@
 #include <sys/device.h>
 #include <sys/kernel.h>
 #include <sys/stat.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/ioctl.h>
 #include <sys/fcntl.h>
Index: sys/arch/x68k/dev/fd.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x68k/dev/fd.c,v
retrieving revision 1.65
diff -u -r1.65 fd.c
--- sys/arch/x68k/dev/fd.c	15 Oct 2005 17:29:11 -0000	1.65
+++ sys/arch/x68k/dev/fd.c	12 Nov 2005 13:10:45 -0000
@@ -88,7 +88,7 @@
 #include <sys/malloc.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/buf.h>
 #include <sys/bufq.h>
 #include <sys/uio.h>
@@ -1109,8 +1109,8 @@
 		fd->sc_cylin = -1;
 		fdc->sc_state = SEEKWAIT;
 
-		fd->sc_dk.dk_seek++;
-		disk_busy(&fd->sc_dk);
+		fd->sc_dk.stats->seek++;
+		drive_busy(fd->sc_dk.stats);
 
 		callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc);
 		return 1;
@@ -1203,7 +1203,7 @@
 		out_fdc(iot, ioh, type->datalen);	/* data length */
 		fdc->sc_state = IOCOMPLETE;
 
-		disk_busy(&fd->sc_dk);
+		drive_busy(fd->sc_dk.stats);
 
 		/* allow 2 seconds for operation */
 		callout_reset(&fdc->sc_timo_ch, 2 * hz, fdctimeout, fdc);
Index: sys/arch/x68k/x68k/autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x68k/x68k/autoconf.c,v
retrieving revision 1.44
diff -u -r1.44 autoconf.c
--- sys/arch/x68k/x68k/autoconf.c	3 Jul 2005 10:22:25 -0000	1.44
+++ sys/arch/x68k/x68k/autoconf.c	12 Nov 2005 13:10:45 -0000
@@ -41,7 +41,7 @@
 #include <sys/reboot.h>
 #include <sys/conf.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/malloc.h>
 #include <machine/cpu.h>
Index: sys/arch/x68k/x68k/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x68k/x68k/disksubr.c,v
retrieving revision 1.25
diff -u -r1.25 disksubr.c
--- sys/arch/x68k/x68k/disksubr.c	13 Jun 2005 00:12:21 -0000	1.25
+++ sys/arch/x68k/x68k/disksubr.c	12 Nov 2005 13:10:46 -0000
@@ -41,7 +41,7 @@
 #include <sys/buf.h>
 #include <sys/disklabel.h>
 #include <sys/syslog.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 
 /* get rid of DEV_BSIZE dependency */
 #define DEF_BSIZE	DEV_BSIZE  /* default sector size = 512 */
Index: sys/arch/x86/x86/x86_autoconf.c
===================================================================
RCS file: /cvsroot/src/sys/arch/x86/x86/x86_autoconf.c,v
retrieving revision 1.4
diff -u -r1.4 x86_autoconf.c
--- sys/arch/x86/x86/x86_autoconf.c	29 May 2005 21:36:40 -0000	1.4
+++ sys/arch/x86/x86/x86_autoconf.c	12 Nov 2005 13:10:46 -0000
@@ -48,7 +48,7 @@
 #include <sys/malloc.h>
 #include <sys/vnode.h>
 #include <sys/fcntl.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/proc.h>
 #include <sys/md5.h>
 
Index: sys/arch/xen/xen/hypervisor.c
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/xen/hypervisor.c,v
retrieving revision 1.17
diff -u -r1.17 hypervisor.c
--- sys/arch/xen/xen/hypervisor.c	20 Sep 2005 20:33:53 -0000	1.17
+++ sys/arch/xen/xen/hypervisor.c	12 Nov 2005 13:10:46 -0000
@@ -108,7 +108,7 @@
 
 #if NXBD > 0
 #include <sys/buf.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/bufq.h>
 #include <dev/dkvar.h>
 #include <machine/xbdvar.h>
Index: sys/arch/xen/xen/xbd.c
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/xen/xbd.c,v
retrieving revision 1.24
diff -u -r1.24 xbd.c
--- sys/arch/xen/xen/xbd.c	18 Oct 2005 00:14:43 -0000	1.24
+++ sys/arch/xen/xen/xbd.c	12 Nov 2005 13:10:46 -0000
@@ -49,7 +49,7 @@
 #include <sys/pool.h>
 #include <sys/ioctl.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/fcntl.h>
 #include <sys/vnode.h>
@@ -1282,7 +1282,7 @@
 					unmap_align(pxr);
 				PUT_XBDREQ(pxr);
 				if (xs) {
-					disk_unbusy(&xs->sc_dksc.sc_dkdev,
+					drive_unbusy(xs->sc_dksc.sc_dkdev.stats,
 					    (bp->b_bcount - bp->b_resid),
 					    (bp->b_flags & B_READ));
 #if NRND > 0
@@ -1342,7 +1342,7 @@
 	if (__predict_false(pxr == NULL))
 		goto out;
 
-	disk_busy(&dksc->sc_dkdev); /* XXX: put in dksubr.c */
+	drive_busy(dksc->sc_dkdev.stats); /* XXX: put in dksubr.c */
 	/*
 	 * We have a request slot, return 0 to make dk_start remove
 	 * the bp from the work queue.
@@ -1449,7 +1449,7 @@
 
 				PUT_XBDREQ(pxr);
 				if (xs) {
-					disk_unbusy(&xs->sc_dksc.sc_dkdev,
+					drive_unbusy(xs->sc_dksc.sc_dkdev.stats,
 					    (bp->b_bcount - bp->b_resid),
 					    (bp->b_flags & B_READ));
 #if NRND > 0
Index: sys/arch/xen/xen/xbdback.c
===================================================================
RCS file: /cvsroot/src/sys/arch/xen/xen/xbdback.c,v
retrieving revision 1.16
diff -u -r1.16 xbdback.c
--- sys/arch/xen/xen/xbdback.c	20 Sep 2005 20:29:18 -0000	1.16
+++ sys/arch/xen/xen/xbdback.c	12 Nov 2005 13:10:47 -0000
@@ -37,7 +37,7 @@
 #include <sys/queue.h>
 #include <sys/kernel.h>
 #include <sys/conf.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/fcntl.h>
 #include <sys/vnode.h>
Index: sys/conf/files
===================================================================
RCS file: /cvsroot/src/sys/conf/files,v
retrieving revision 1.739
diff -u -r1.739 files
--- sys/conf/files	29 Oct 2005 11:23:19 -0000	1.739
+++ sys/conf/files	12 Nov 2005 13:10:49 -0000
@@ -1256,7 +1256,7 @@
 file	kern/subr_blist.c		vmswap
 file	kern/subr_bufq.c
 file	kern/subr_devsw.c
-file	kern/subr_disk.c
+file	kern/subr_drive.c
 file	kern/subr_evcnt.c
 file	kern/subr_extent.c
 file	kern/subr_log.c
Index: sys/dev/ccd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ccd.c,v
retrieving revision 1.106
diff -u -r1.106 ccd.c
--- sys/dev/ccd.c	15 Oct 2005 17:29:11 -0000	1.106
+++ sys/dev/ccd.c	12 Nov 2005 13:10:49 -0000
@@ -140,7 +140,7 @@
 #include <sys/ioctl.h>
 #include <sys/disklabel.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 #include <sys/fcntl.h>
 #include <sys/vnode.h>
@@ -720,7 +720,7 @@
 	/* See if there is work for us to do. */
 	while ((bp = BUFQ_PEEK(cs->sc_bufq)) != NULL) {
 		/* Instrumentation. */
-		disk_busy(&cs->sc_dkdev);
+		drive_busy(cs->sc_dkdev.stats);
 
 		bp->b_resid = bp->b_bcount;
 		bn = bp->b_rawblkno;
@@ -744,7 +744,7 @@
 					SIMPLEQ_REMOVE_HEAD(&cbufq, cb_q);
 					CCD_PUTBUF(cbp);
 				}
-				disk_unbusy(&cs->sc_dkdev, 0, 0);
+				drive_unbusy(cs->sc_dkdev.stats, 0, 0);
 				return;
 			}
 			SIMPLEQ_INSERT_TAIL(&cbufq, cbp, cb_q);
@@ -882,7 +882,7 @@
 	 */
 	if (bp->b_flags & B_ERROR)
 		bp->b_resid = bp->b_bcount;
-	disk_unbusy(&cs->sc_dkdev, (bp->b_bcount - bp->b_resid),
+	drive_unbusy(cs->sc_dkdev.stats, (bp->b_bcount - bp->b_resid),
 	    (bp->b_flags & B_READ));
 	biodone(bp);
 }
Index: sys/dev/cgd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/cgd.c,v
retrieving revision 1.31
diff -u -r1.31 cgd.c
--- sys/dev/cgd.c	18 Oct 2005 00:14:43 -0000	1.31
+++ sys/dev/cgd.c	12 Nov 2005 13:10:49 -0000
@@ -50,7 +50,7 @@
 #include <sys/pool.h>
 #include <sys/ioctl.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/fcntl.h>
 #include <sys/vnode.h>
@@ -299,7 +299,7 @@
 	int s;
 
 	DPRINTF_FOLLOW(("cgdstart(%p, %p)\n", dksc, bp));
-	disk_busy(&dksc->sc_dkdev); /* XXX: put in dksubr.c */
+	drive_busy(dksc->sc_dkdev.stats); /* XXX: put in dksubr.c */
 
 	bn = bp->b_rawblkno;
 
@@ -312,7 +312,8 @@
 	nbp = pool_get(&bufpool, PR_NOWAIT);
 	splx(s);
 	if (nbp == NULL) {
-		disk_unbusy(&dksc->sc_dkdev, 0, (bp->b_flags & B_READ));
+		drive_unbusy(dksc->sc_dkdev.stats, 0,
+			     (bp->b_flags & B_READ));
 		return -1;
 	}
 
@@ -328,7 +329,8 @@
 			s = splbio();
 			pool_put(&bufpool, nbp);
 			splx(s);
-			disk_unbusy(&dksc->sc_dkdev, 0, (bp->b_flags & B_READ));
+			drive_unbusy(dksc->sc_dkdev.stats, 0,
+				     (bp->b_flags & B_READ));
 			return -1;
 		}
 		cgd_cipher(cs, newaddr, addr, bp->b_bcount, bn,
@@ -397,7 +399,7 @@
 	obp->b_resid = 0;
 	if (obp->b_flags & B_ERROR)
 		obp->b_resid = obp->b_bcount;
-	disk_unbusy(&dksc->sc_dkdev, obp->b_bcount - obp->b_resid,
+	drive_unbusy(dksc->sc_dkdev.stats, obp->b_bcount - obp->b_resid,
 	    (obp->b_flags & B_READ));
 	biodone(obp);
 	dk_iodone(di, dksc);
Index: sys/dev/dksubr.c
===================================================================
RCS file: /cvsroot/src/sys/dev/dksubr.c,v
retrieving revision 1.18
diff -u -r1.18 dksubr.c
--- sys/dev/dksubr.c	18 Oct 2005 00:14:43 -0000	1.18
+++ sys/dev/dksubr.c	12 Nov 2005 13:10:49 -0000
@@ -45,7 +45,7 @@
 #include <sys/proc.h>
 #include <sys/ioctl.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/buf.h>
 #include <sys/bufq.h>
Index: sys/dev/fss.c
===================================================================
RCS file: /cvsroot/src/sys/dev/fss.c,v
retrieving revision 1.17
diff -u -r1.17 fss.c
--- sys/dev/fss.c	24 Oct 2005 14:25:06 -0000	1.17
+++ sys/dev/fss.c	12 Nov 2005 13:10:50 -0000
@@ -57,7 +57,7 @@
 #include <sys/ioctl.h>
 #include <sys/disklabel.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/stat.h>
 #include <sys/mount.h>
 #include <sys/vnode.h>
Index: sys/dev/ld.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ld.c,v
retrieving revision 1.38
diff -u -r1.38 ld.c
--- sys/dev/ld.c	15 Oct 2005 17:29:11 -0000	1.38
+++ sys/dev/ld.c	12 Nov 2005 13:10:50 -0000
@@ -55,7 +55,7 @@
 #include <sys/bufq.h>
 #include <sys/endian.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/dkio.h>
 #include <sys/stat.h>
 #include <sys/lock.h>
@@ -612,7 +612,7 @@
 		if ((bp = BUFQ_PEEK(sc->sc_bufq)) == NULL)
 			break;
 
-		disk_busy(&sc->sc_dk);
+		drive_busy(sc->sc_dk.stats);
 		sc->sc_queuecnt++;
 
 		if (__predict_true((error = (*sc->sc_start)(sc, bp)) == 0)) {
@@ -622,7 +622,8 @@
 			 */
 			(void) BUFQ_GET(sc->sc_bufq);
 		} else  {
-			disk_unbusy(&sc->sc_dk, 0, (bp->b_flags & B_READ));
+			drive_unbusy(sc->sc_dk.stats, 0,
+				     (bp->b_flags & B_READ));
 			sc->sc_queuecnt--;
 			if (error == EAGAIN) {
 				/*
@@ -654,7 +655,7 @@
 		printf("\n");
 	}
 
-	disk_unbusy(&sc->sc_dk, bp->b_bcount - bp->b_resid,
+	drive_unbusy(sc->sc_dk.stats, bp->b_bcount - bp->b_resid,
 	    (bp->b_flags & B_READ));
 #if NRND > 0
 	rnd_add_uint32(&sc->sc_rnd_source, bp->b_rawblkno);
Index: sys/dev/md.c
===================================================================
RCS file: /cvsroot/src/sys/dev/md.c,v
retrieving revision 1.42
diff -u -r1.42 md.c
--- sys/dev/md.c	15 Oct 2005 17:29:11 -0000	1.42
+++ sys/dev/md.c	12 Nov 2005 13:10:50 -0000
@@ -57,7 +57,7 @@
 #include <sys/buf.h>
 #include <sys/bufq.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/proc.h>
 #include <sys/conf.h>
 #include <sys/disklabel.h>
Index: sys/dev/vnd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/vnd.c,v
retrieving revision 1.123
diff -u -r1.123 vnd.c
--- sys/dev/vnd.c	15 Oct 2005 17:29:12 -0000	1.123
+++ sys/dev/vnd.c	12 Nov 2005 13:10:50 -0000
@@ -152,7 +152,7 @@
 #include <sys/ioctl.h>
 #include <sys/disklabel.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/stat.h>
 #include <sys/mount.h>
 #include <sys/vnode.h>
@@ -646,7 +646,7 @@
 #endif
 
 			/* Instrumentation. */
-			disk_busy(&vnd->sc_dkdev);
+			drive_busy(vnd->sc_dkdev.stats);
 
 			if ((nbp->vb_buf.b_flags & B_READ) == 0)
 				vp->v_numoutput++;
@@ -705,7 +705,7 @@
 
 	resid = vbp->vb_buf.b_bcount - vbp->vb_buf.b_resid;
 	pbp->b_resid -= resid;
-	disk_unbusy(&vnd->sc_dkdev, resid, (pbp->b_flags & B_READ));
+	drive_unbusy(vnd->sc_dkdev.stats, resid, (pbp->b_flags & B_READ));
 	vnx->vx_pending--;
 
 	if (vbp->vb_buf.b_error) {
Index: sys/dev/acpi/fdc_acpi.c
===================================================================
RCS file: /cvsroot/src/sys/dev/acpi/fdc_acpi.c,v
retrieving revision 1.26
diff -u -r1.26 fdc_acpi.c
--- sys/dev/acpi/fdc_acpi.c	11 Jul 2005 18:31:12 -0000	1.26
+++ sys/dev/acpi/fdc_acpi.c	12 Nov 2005 13:10:50 -0000
@@ -42,7 +42,7 @@
 #include <sys/buf.h>
 #include <sys/bufq.h>
 #include <sys/queue.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #if NRND > 0
 #include <sys/rnd.h>
 #endif
Index: sys/dev/ata/ata_raid.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/ata_raid.c,v
retrieving revision 1.16
diff -u -r1.16 ata_raid.c
--- sys/dev/ata/ata_raid.c	25 Aug 2005 22:33:18 -0000	1.16
+++ sys/dev/ata/ata_raid.c	12 Nov 2005 13:10:50 -0000
@@ -47,7 +47,7 @@
 #include <sys/bufq.h>
 #include <sys/conf.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/fcntl.h>
 #include <sys/malloc.h>
Index: sys/dev/ata/ata_raid_adaptec.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/ata_raid_adaptec.c,v
retrieving revision 1.1
diff -u -r1.1 ata_raid_adaptec.c
--- sys/dev/ata/ata_raid_adaptec.c	20 Jun 2005 02:11:57 -0000	1.1
+++ sys/dev/ata/ata_raid_adaptec.c	12 Nov 2005 13:10:50 -0000
@@ -42,7 +42,7 @@
 #include <sys/bufq.h>
 #include <sys/conf.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/fcntl.h>
 #include <sys/malloc.h>
Index: sys/dev/ata/ata_raid_promise.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/ata_raid_promise.c,v
retrieving revision 1.5
diff -u -r1.5 ata_raid_promise.c
--- sys/dev/ata/ata_raid_promise.c	27 Feb 2005 00:26:58 -0000	1.5
+++ sys/dev/ata/ata_raid_promise.c	12 Nov 2005 13:10:51 -0000
@@ -42,7 +42,7 @@
 #include <sys/bufq.h>
 #include <sys/conf.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/fcntl.h>
 #include <sys/malloc.h>
Index: sys/dev/ata/ld_ataraid.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/ld_ataraid.c,v
retrieving revision 1.13
diff -u -r1.13 ld_ataraid.c
--- sys/dev/ata/ld_ataraid.c	28 Oct 2004 07:07:39 -0000	1.13
+++ sys/dev/ata/ld_ataraid.c	12 Nov 2005 13:10:51 -0000
@@ -57,7 +57,7 @@
 #include <sys/buf.h>
 #include <sys/bufq.h>
 #include <sys/dkio.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/fcntl.h>
 #include <sys/malloc.h>
Index: sys/dev/ata/wd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ata/wd.c,v
retrieving revision 1.313
diff -u -r1.313 wd.c
--- sys/dev/ata/wd.c	1 Nov 2005 20:44:04 -0000	1.313
+++ sys/dev/ata/wd.c	12 Nov 2005 13:10:51 -0000
@@ -87,7 +87,7 @@
 #include <sys/malloc.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 #include <sys/proc.h>
 #include <sys/vnode.h>
@@ -731,7 +731,7 @@
 	wd->sc_wdc_bio.bcount = bp->b_bcount;
 	wd->sc_wdc_bio.databuf = bp->b_data;
 	/* Instrumentation. */
-	disk_busy(&wd->sc_dk);
+	drive_busy(wd->sc_dk.stats);
 	switch (wd->atabus->ata_bio(wd->drvp, &wd->sc_wdc_bio)) {
 	case ATACMD_TRY_AGAIN:
 		callout_reset(&wd->sc_restart_ch, hz, wdrestart, wd);
@@ -827,7 +827,7 @@
 		bp->b_error = EIO;
 		break;
 	}
-	disk_unbusy(&wd->sc_dk, (bp->b_bcount - bp->b_resid),
+	drive_unbusy(wd->sc_dk.stats, (bp->b_bcount - bp->b_resid),
 	    (bp->b_flags & B_READ));
 #if NRND > 0
 	rnd_add_uint32(&wd->rnd_source, bp->b_blkno);
Index: sys/dev/dkwedge/dk.c
===================================================================
RCS file: /cvsroot/src/sys/dev/dkwedge/dk.c,v
retrieving revision 1.9
diff -u -r1.9 dk.c
--- sys/dev/dkwedge/dk.c	15 Oct 2005 17:29:12 -0000	1.9
+++ sys/dev/dkwedge/dk.c	12 Nov 2005 13:10:51 -0000
@@ -48,7 +48,7 @@
 #include <sys/pool.h>
 #include <sys/ioctl.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/fcntl.h>
 #include <sys/buf.h>
 #include <sys/bufq.h>
@@ -269,6 +269,7 @@
 {
 	struct dkwedge_softc *sc, *lsc;
 	struct disk *pdk;
+	struct drive_stats *statp;
 	u_int unit;
 	int error;
 	dev_t pdev;
@@ -277,7 +278,8 @@
 		dkwedge_cfglue_init();
 
 	dkw->dkw_parent[sizeof(dkw->dkw_parent) - 1] = '\0';
-	pdk = disk_find(dkw->dkw_parent);
+	statp = drive_find(dkw->dkw_parent);
+	pdk = (struct disk *) statp->parent;
 	if (pdk == NULL)
 		return (ENODEV);
 
@@ -1034,7 +1036,7 @@
 		}
 
 		/* Instrumentation. */
-		disk_busy(&sc->sc_dk);
+		drive_busy(sc->sc_dk.stats);
 
 		nbp = pool_get(&bufpool, PR_NOWAIT);
 		if (nbp == NULL) {
@@ -1043,7 +1045,8 @@
 			 * buffer queued up, and schedule a timer to
 			 * restart the queue in 1/2 a second.
 			 */
-			disk_unbusy(&sc->sc_dk, 0, bp->b_flags & B_READ);
+			drive_unbusy(sc->sc_dk.stats, 0,
+				     bp->b_flags & B_READ);
 			callout_schedule(&sc->sc_restart_ch, hz / 2);
 			return;
 		}
@@ -1092,7 +1095,7 @@
 		wakeup(&sc->sc_iopend);
 	}
 
-	disk_unbusy(&sc->sc_dk, obp->b_bcount - obp->b_resid,
+	drive_unbusy(sc->sc_dk.stats, obp->b_bcount - obp->b_resid,
 	    obp->b_flags & B_READ);
 
 	biodone(obp);
Index: sys/dev/dkwedge/dkwedge_bsdlabel.c
===================================================================
RCS file: /cvsroot/src/sys/dev/dkwedge/dkwedge_bsdlabel.c,v
retrieving revision 1.3
diff -u -r1.3 dkwedge_bsdlabel.c
--- sys/dev/dkwedge/dkwedge_bsdlabel.c	27 Feb 2005 00:26:59 -0000	1.3
+++ sys/dev/dkwedge/dkwedge_bsdlabel.c	12 Nov 2005 13:10:52 -0000
@@ -92,7 +92,7 @@
 #include <sys/systm.h>
 #include <sys/proc.h>
 #include <sys/errno.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/vnode.h>
 #include <sys/malloc.h>
 
Index: sys/dev/dkwedge/dkwedge_gpt.c
===================================================================
RCS file: /cvsroot/src/sys/dev/dkwedge/dkwedge_gpt.c,v
retrieving revision 1.1
diff -u -r1.1 dkwedge_gpt.c
--- sys/dev/dkwedge/dkwedge_gpt.c	4 Oct 2004 01:07:25 -0000	1.1
+++ sys/dev/dkwedge/dkwedge_gpt.c	12 Nov 2005 13:10:52 -0000
@@ -47,7 +47,7 @@
 #include <sys/systm.h>
 #include <sys/proc.h>
 #include <sys/errno.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/vnode.h>
 #include <sys/malloc.h>
 
Index: sys/dev/dkwedge/dkwedge_mbr.c
===================================================================
RCS file: /cvsroot/src/sys/dev/dkwedge/dkwedge_mbr.c,v
retrieving revision 1.2
diff -u -r1.2 dkwedge_mbr.c
--- sys/dev/dkwedge/dkwedge_mbr.c	1 Jan 2005 19:29:59 -0000	1.2
+++ sys/dev/dkwedge/dkwedge_mbr.c	12 Nov 2005 13:10:52 -0000
@@ -47,7 +47,7 @@
 #include <sys/systm.h>
 #include <sys/proc.h>
 #include <sys/errno.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/vnode.h>
 #include <sys/malloc.h>
 
Index: sys/dev/gpib/rd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/gpib/rd.c,v
retrieving revision 1.6
diff -u -r1.6 rd.c
--- sys/dev/gpib/rd.c	15 Oct 2005 17:29:12 -0000	1.6
+++ sys/dev/gpib/rd.c	12 Nov 2005 13:10:52 -0000
@@ -129,7 +129,7 @@
 #include <sys/callout.h>
 #include <sys/conf.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/endian.h>
 #include <sys/fcntl.h>
@@ -784,8 +784,8 @@
 	if (gpibsend(sc->sc_ic, slave, CS80CMD_SCMD, &sc->sc_ioc.c_unit,
 	    sizeof(sc->sc_ioc)-1) == sizeof(sc->sc_ioc)-1) {
 		/* Instrumentation. */
-		disk_busy(&sc->sc_dk);
-		sc->sc_dk.dk_seek++;
+		drive_busy(sc->sc_dk.stats);
+		sc->sc_dk.stats->seek++;
 		gpibawait(sc->sc_ic);
 		return;
 	}
@@ -834,7 +834,7 @@
 	    sc->sc_dev.dv_xname, bp, (bp->b_flags & B_READ) ? 'R' : 'W',
 	    sc->sc_flags));
 
-	disk_unbusy(&sc->sc_dk, (bp->b_bcount - bp->b_resid),
+	drive_unbusy(sc->sc_dk.stats, (bp->b_bcount - bp->b_resid),
 		(bp->b_flags & B_READ));
 
 	if (sc->sc_flags & RDF_SEEK) {
@@ -842,13 +842,13 @@
 		dir = (bp->b_flags & B_READ ? GPIB_READ : GPIB_WRITE);
 		gpibxfer(sc->sc_ic, slave, CS80CMD_EXEC, sc->sc_addr,
 		    sc->sc_resid, dir, dir == GPIB_READ);
-		disk_busy(&sc->sc_dk);
+		drive_busy(sc->sc_dk.stats);
 		return;
 	}
 	if ((sc->sc_flags & RDF_SWAIT) == 0) {
 		if (gpibpptest(sc->sc_ic, slave) == 0) {
 			/* Instrumentation. */
-			disk_busy(&sc->sc_dk);
+			drive_busy(sc->sc_dk.stats);
 			sc->sc_flags |= RDF_SWAIT;
 			gpibawait(sc->sc_ic);
 			return;
Index: sys/dev/i2o/ld_iop.c
===================================================================
RCS file: /cvsroot/src/sys/dev/i2o/ld_iop.c,v
retrieving revision 1.17
diff -u -r1.17 ld_iop.c
--- sys/dev/i2o/ld_iop.c	30 May 2005 04:37:57 -0000	1.17
+++ sys/dev/i2o/ld_iop.c	12 Nov 2005 13:10:53 -0000
@@ -56,7 +56,7 @@
 #include <sys/bufq.h>
 #include <sys/endian.h>
 #include <sys/dkio.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/proc.h>
 #if NRND > 0
 #include <sys/rnd.h>
Index: sys/dev/ic/icp.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/icp.c,v
retrieving revision 1.16
diff -u -r1.16 icp.c
--- sys/dev/ic/icp.c	25 Aug 2005 22:33:19 -0000	1.16
+++ sys/dev/ic/icp.c	12 Nov 2005 13:10:54 -0000
@@ -94,7 +94,7 @@
 #include <sys/buf.h>
 #include <sys/endian.h>
 #include <sys/malloc.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 
 #include <uvm/uvm_extern.h>
 
Index: sys/dev/ic/ld_aac.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/ld_aac.c,v
retrieving revision 1.8
diff -u -r1.8 ld_aac.c
--- sys/dev/ic/ld_aac.c	27 Feb 2005 00:27:01 -0000	1.8
+++ sys/dev/ic/ld_aac.c	12 Nov 2005 13:10:54 -0000
@@ -49,7 +49,7 @@
 #include <sys/bufq.h>
 #include <sys/endian.h>
 #include <sys/dkio.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #if NRND > 0
 #include <sys/rnd.h>
 #endif
Index: sys/dev/ic/ld_cac.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/ld_cac.c,v
retrieving revision 1.11
diff -u -r1.11 ld_cac.c
--- sys/dev/ic/ld_cac.c	27 Feb 2005 00:27:01 -0000	1.11
+++ sys/dev/ic/ld_cac.c	12 Nov 2005 13:10:54 -0000
@@ -53,7 +53,7 @@
 #include <sys/bufq.h>
 #include <sys/endian.h>
 #include <sys/dkio.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #if NRND > 0
 #include <sys/rnd.h>
 #endif
Index: sys/dev/ic/ld_icp.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/ld_icp.c,v
retrieving revision 1.11
diff -u -r1.11 ld_icp.c
--- sys/dev/ic/ld_icp.c	27 Feb 2005 00:27:01 -0000	1.11
+++ sys/dev/ic/ld_icp.c	12 Nov 2005 13:10:54 -0000
@@ -53,7 +53,7 @@
 #include <sys/bufq.h>
 #include <sys/endian.h>
 #include <sys/dkio.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #if NRND > 0
 #include <sys/rnd.h>
 #endif
Index: sys/dev/ic/ld_mlx.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/ld_mlx.c,v
retrieving revision 1.9
diff -u -r1.9 ld_mlx.c
--- sys/dev/ic/ld_mlx.c	8 Feb 2005 05:16:17 -0000	1.9
+++ sys/dev/ic/ld_mlx.c	12 Nov 2005 13:10:54 -0000
@@ -53,7 +53,7 @@
 #include <sys/bufq.h>
 #include <sys/endian.h>
 #include <sys/dkio.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #if NRND > 0
 #include <sys/rnd.h>
 #endif
Index: sys/dev/ic/mlx.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ic/mlx.c,v
retrieving revision 1.36
diff -u -r1.36 mlx.c
--- sys/dev/ic/mlx.c	25 Aug 2005 22:33:19 -0000	1.36
+++ sys/dev/ic/mlx.c	12 Nov 2005 13:10:55 -0000
@@ -90,7 +90,7 @@
 #include <sys/malloc.h>
 #include <sys/conf.h>
 #include <sys/kthread.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 
 #include <machine/vmparam.h>
 #include <machine/bus.h>
Index: sys/dev/isa/fd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/isa/fd.c,v
retrieving revision 1.60
diff -u -r1.60 fd.c
--- sys/dev/isa/fd.c	15 Oct 2005 17:29:12 -0000	1.60
+++ sys/dev/isa/fd.c	12 Nov 2005 13:10:55 -0000
@@ -111,7 +111,7 @@
 #include <sys/ioctl.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/buf.h>
 #include <sys/bufq.h>
 #include <sys/malloc.h>
@@ -1042,8 +1042,8 @@
 		fd->sc_cylin = -1;
 		fdc->sc_state = SEEKWAIT;
 
-		fd->sc_dk.dk_seek++;
-		disk_busy(&fd->sc_dk);
+		fd->sc_dk.stats->seek++;
+		drive_busy(fd->sc_dk.stats);
 
 		callout_reset(&fdc->sc_timo_ch, 4 * hz, fdctimeout, fdc);
 		return 1;
@@ -1114,7 +1114,7 @@
 		}
 		fdc->sc_state = IOCOMPLETE;
 
-		disk_busy(&fd->sc_dk);
+		drive_busy(fd->sc_dk.stats);
 
 		/* allow 2 seconds for operation */
 		callout_reset(&fdc->sc_timo_ch, 2 * hz, fdctimeout, fdc);
@@ -1129,7 +1129,7 @@
 
 	case SEEKCOMPLETE:
 		/* no data on seek */
-		disk_unbusy(&fd->sc_dk, 0, 0);
+		drive_unbusy(fd->sc_dk.stats, 0, 0);
 
 		/* Make sure seek really happened. */
 		out_fdc(iot, ioh, NE7CMD_SENSEI);
@@ -1155,7 +1155,7 @@
 	case IOCOMPLETE: /* IO DONE, post-analyze */
 		callout_stop(&fdc->sc_timo_ch);
 
-		disk_unbusy(&fd->sc_dk, (bp->b_bcount - bp->b_resid),
+		drive_unbusy(fd->sc_dk.stats, (bp->b_bcount - bp->b_resid),
 		    (bp->b_flags & B_READ));
 
 		if (fdcresult(fdc) != 7 || (st0 & 0xf8) != 0) {
Index: sys/dev/isa/mcd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/isa/mcd.c,v
retrieving revision 1.91
diff -u -r1.91 mcd.c
--- sys/dev/isa/mcd.c	15 Oct 2005 17:29:12 -0000	1.91
+++ sys/dev/isa/mcd.c	12 Nov 2005 13:10:56 -0000
@@ -74,7 +74,7 @@
 #include <sys/errno.h>
 #include <sys/disklabel.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 
 #include <machine/cpu.h>
 #include <machine/intr.h>
@@ -528,7 +528,7 @@
 
 	/* Instrumentation. */
 	s = splbio();
-	disk_busy(&sc->sc_dk);
+	drive_busy(sc->sc_dk.stats);
 	splx(s);
 
 	sc->mbx.retry = MCD_RDRETRIES;
@@ -1288,7 +1288,8 @@
 
 		/* Return buffer. */
 		bp->b_resid = 0;
-		disk_unbusy(&sc->sc_dk, bp->b_bcount, (bp->b_flags & B_READ));
+		drive_unbusy(sc->sc_dk.stats, bp->b_bcount,
+			     (bp->b_flags & B_READ));
 		biodone(bp);
 
 		mcdstart(sc);
@@ -1321,7 +1322,7 @@
 	/* Invalidate the buffer. */
 	bp->b_flags |= B_ERROR;
 	bp->b_resid = bp->b_bcount - mbx->skip;
-	disk_unbusy(&sc->sc_dk, (bp->b_bcount - bp->b_resid),
+	drive_unbusy(sc->sc_dk.stats, (bp->b_bcount - bp->b_resid),
 	    (bp->b_flags & B_READ));
 	biodone(bp);
 
Index: sys/dev/mca/ed_mca.c
===================================================================
RCS file: /cvsroot/src/sys/dev/mca/ed_mca.c,v
retrieving revision 1.30
diff -u -r1.30 ed_mca.c
--- sys/dev/mca/ed_mca.c	15 Oct 2005 17:29:25 -0000	1.30
+++ sys/dev/mca/ed_mca.c	12 Nov 2005 13:10:56 -0000
@@ -55,7 +55,7 @@
 #include <sys/malloc.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 #include <sys/proc.h>
 #include <sys/vnode.h>
Index: sys/dev/mca/edc_mca.c
===================================================================
RCS file: /cvsroot/src/sys/dev/mca/edc_mca.c,v
retrieving revision 1.31
diff -u -r1.31 edc_mca.c
--- sys/dev/mca/edc_mca.c	15 Oct 2005 17:29:25 -0000	1.31
+++ sys/dev/mca/edc_mca.c	12 Nov 2005 13:10:56 -0000
@@ -63,7 +63,7 @@
 #include <sys/malloc.h>
 #include <sys/endian.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 #include <sys/proc.h>
 #include <sys/vnode.h>
@@ -870,7 +870,7 @@
 			simple_unlock(&ed->sc_q_lock);
 
 			/* Instrumentation. */
-			disk_busy(&ed->sc_dk);
+			drive_busy(ed->sc_dk.stats);
 
 			error = edc_bio(sc, ed, bp->b_data, bp->b_bcount,
 				bp->b_rawblkno, (bp->b_flags & B_READ), 0);
@@ -883,8 +883,9 @@
 				bp->b_resid = sc->sc_resblk * DEV_BSIZE;
 			}
 
-			disk_unbusy(&ed->sc_dk, (bp->b_bcount - bp->b_resid),
-			    (bp->b_flags & B_READ));
+			drive_unbusy(ed->sc_dk.stats,
+				     (bp->b_bcount - bp->b_resid),
+				     (bp->b_flags & B_READ));
 #if NRND > 0
 			rnd_add_uint32(&ed->rnd_source, bp->b_blkno);
 #endif
Index: sys/dev/mscp/mscp_disk.c
===================================================================
RCS file: /cvsroot/src/sys/dev/mscp/mscp_disk.c,v
retrieving revision 1.48
diff -u -r1.48 mscp_disk.c
--- sys/dev/mscp/mscp_disk.c	15 Oct 2005 17:29:25 -0000	1.48
+++ sys/dev/mscp/mscp_disk.c	12 Nov 2005 13:10:59 -0000
@@ -87,7 +87,7 @@
 #include <sys/buf.h>
 #include <sys/bufq.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
@@ -380,7 +380,7 @@
 	if (ra->ra_state == DK_RDLABEL) {
 	        /* Make some statistics... /bqt */
 	        b = splbio();
-	        disk_busy(&ra->ra_disk);
+	        drive_busy(ra->ra_disk.stats);
 		splx(b);
 		mscp_strategy(bp, ra->ra_dev.dv_parent);
 		return;
@@ -403,7 +403,7 @@
 
 	/* Make some statistics... /bqt */
 	b = splbio();
-	disk_busy(&ra->ra_disk);
+	drive_busy(ra->ra_disk.stats);
 	splx(b);
 	mscp_strategy(bp, ra->ra_dev.dv_parent);
 	return;
@@ -839,7 +839,7 @@
 
 	/* Make some statistics... /bqt */
 	b = splbio();
-	disk_busy(&rx->ra_disk);
+	drive_busy(rx->ra_disk.stats);
 	splx(b);
 	mscp_strategy(bp, rx->ra_dev.dv_parent);
 	return;
@@ -1000,7 +1000,8 @@
 #endif
 		panic("rriodone: unexpected major %d unit %d",
 		    major(bp->b_dev), unit);
-	disk_unbusy(&ra->ra_disk, bp->b_bcount, (bp->b_flags & B_READ));
+	drive_unbusy(ra->ra_disk.stats, bp->b_bcount,
+		     (bp->b_flags & B_READ));
 
 	biodone(bp);
 }
Index: sys/dev/ofw/ofdisk.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ofw/ofdisk.c,v
retrieving revision 1.31
diff -u -r1.31 ofdisk.c
--- sys/dev/ofw/ofdisk.c	9 Jun 2005 12:23:23 -0000	1.31
+++ sys/dev/ofw/ofdisk.c	12 Nov 2005 13:10:59 -0000
@@ -39,7 +39,7 @@
 #include <sys/device.h>
 #include <sys/conf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/fcntl.h>
 #include <sys/ioctl.h>
 #include <sys/stat.h>
@@ -294,7 +294,7 @@
 		blkno = bp->b_blkno + p->p_offset;
 	}
 
-	disk_busy(&of->sc_dk);
+	drive_busy(of->sc_dk.stats);
 
 	off = (u_quad_t)blkno * DEV_BSIZE;
 	read = -1;
@@ -311,7 +311,7 @@
 	} else
 		bp->b_resid = bp->b_bcount - read;
 
-	disk_unbusy(&of->sc_dk, bp->b_bcount - bp->b_resid,
+	drive_unbusy(of->sc_dk.stats, bp->b_bcount - bp->b_resid,
 	    (bp->b_flags & B_READ));
 
 done:
Index: sys/dev/ofw/ofnet.c
===================================================================
RCS file: /cvsroot/src/sys/dev/ofw/ofnet.c,v
retrieving revision 1.33
diff -u -r1.33 ofnet.c
--- sys/dev/ofw/ofnet.c	27 Feb 2005 00:27:32 -0000	1.33
+++ sys/dev/ofw/ofnet.c	12 Nov 2005 13:10:59 -0000
@@ -42,7 +42,7 @@
 #include <sys/systm.h>
 #include <sys/callout.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/ioctl.h>
 #include <sys/mbuf.h>
 #include <sys/socket.h>
Index: sys/dev/pci/ld_amr.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/ld_amr.c,v
retrieving revision 1.7
diff -u -r1.7 ld_amr.c
--- sys/dev/pci/ld_amr.c	28 Jun 2005 00:28:42 -0000	1.7
+++ sys/dev/pci/ld_amr.c	12 Nov 2005 13:10:59 -0000
@@ -53,7 +53,7 @@
 #include <sys/bufq.h>
 #include <sys/endian.h>
 #include <sys/dkio.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #if NRND > 0
 #include <sys/rnd.h>
 #endif
Index: sys/dev/pci/ld_twe.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/ld_twe.c,v
retrieving revision 1.22
diff -u -r1.22 ld_twe.c
--- sys/dev/pci/ld_twe.c	8 Feb 2005 05:16:17 -0000	1.22
+++ sys/dev/pci/ld_twe.c	12 Nov 2005 13:10:59 -0000
@@ -53,7 +53,7 @@
 #include <sys/bufq.h>
 #include <sys/endian.h>
 #include <sys/dkio.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #if NRND > 0
 #include <sys/rnd.h>
 #endif
Index: sys/dev/pci/twe.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pci/twe.c,v
retrieving revision 1.70
diff -u -r1.70 twe.c
--- sys/dev/pci/twe.c	26 Aug 2005 11:20:33 -0000	1.70
+++ sys/dev/pci/twe.c	12 Nov 2005 13:11:00 -0000
@@ -82,7 +82,7 @@
 #include <sys/endian.h>
 #include <sys/malloc.h>
 #include <sys/conf.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/sysctl.h>
 #include <sys/syslog.h>
 
Index: sys/dev/pcmcia/fdc_pcmcia.c
===================================================================
RCS file: /cvsroot/src/sys/dev/pcmcia/fdc_pcmcia.c,v
retrieving revision 1.16
diff -u -r1.16 fdc_pcmcia.c
--- sys/dev/pcmcia/fdc_pcmcia.c	27 Feb 2005 00:27:43 -0000	1.16
+++ sys/dev/pcmcia/fdc_pcmcia.c	12 Nov 2005 13:11:00 -0000
@@ -43,7 +43,7 @@
 #include <sys/systm.h>
 #include <sys/conf.h>
 #include <sys/device.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/buf.h>
 
 #include <machine/bus.h>
Index: sys/dev/qbus/rf.c
===================================================================
RCS file: /cvsroot/src/sys/dev/qbus/rf.c,v
retrieving revision 1.9
diff -u -r1.9 rf.c
--- sys/dev/qbus/rf.c	15 Oct 2005 17:29:25 -0000	1.9
+++ sys/dev/qbus/rf.c	12 Nov 2005 13:11:00 -0000
@@ -54,7 +54,7 @@
 /* disk interface */
 #include <sys/types.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 
 /* general system data and functions */
 #include <sys/systm.h>
@@ -663,7 +663,7 @@
 		 */
 		switch (rf_sc->sc_state & RFS_CMDS) {
 		case RFS_PROBING:	/* density detect / verify started */
-			disk_unbusy(&rf_sc->sc_disk, 0, 1);
+			drive_unbusy(rf_sc->sc_disk.stats, 0, 1);
 			if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh,
 			    RX2CS) & RX2CS_ERR) == 0) {
 				RFS_SETCMD(rf_sc->sc_state, RFS_IDLE);
@@ -674,13 +674,14 @@
 				    && (rf_sc->sc_state & RFS_AD) != 0) {
 					/* retry at DD */
 					rf_sc->sc_state |= RFS_DENS;
-					disk_busy(&rf_sc->sc_disk);
+					drive_busy(rf_sc->sc_disk.stats);
 					if (rfc_sendcmd(rfc_sc, RX2CS_RSEC
 					    | RX2CS_IE | RX2CS_DD |
 					    (rf_sc->sc_dnum == 0 ? 0 :
 					    RX2CS_US), 1, 1) < 0) {
-						disk_unbusy(&rf_sc->sc_disk,
-						    0, 1);
+						drive_unbusy(
+							rf_sc->sc_disk.stats,
+							0, 1);
 						RFS_SETCMD(rf_sc->sc_state,
 						    RFS_NOTINIT);
 						wakeup(rf_sc);
@@ -707,7 +708,7 @@
 			    & B_READ) != 0 ? RFS_RSEC : RFS_FBUF);
 			break;
 		case RFS_RSEC:	/* Read Sector */
-			disk_unbusy(&rf_sc->sc_disk, 0, 1);
+			drive_unbusy(rf_sc->sc_disk.stats, 0, 1);
 			/* check for errors */
 			if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh,
 			    RX2CS) & RX2CS_ERR) != 0) {
@@ -722,7 +723,7 @@
 		case RFS_WSEC:	/* Write Sector */
 			i = (rf_sc->sc_state & RFS_DENS) == 0
 				? RX2_BYTE_SD : RX2_BYTE_DD;
-			disk_unbusy(&rf_sc->sc_disk, i, 0);
+			drive_unbusy(rf_sc->sc_disk.stats, i, 0);
 			/* check for errors */
 			if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh,
 			    RX2CS) & RX2CS_ERR) != 0) {
@@ -747,7 +748,7 @@
 			    ? RFS_RSEC : RFS_FBUF);
 			break;
 		case RFS_FBUF:	/* Fill Buffer */
-			disk_unbusy(&rf_sc->sc_disk, 0, 0);
+			drive_unbusy(rf_sc->sc_disk.stats, 0, 0);
 			bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam);
 			/* check for errors */
 			if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh,
@@ -763,7 +764,7 @@
 		case RFS_EBUF:	/* Empty Buffer */
 			i = (rf_sc->sc_state & RFS_DENS) == 0
 			    ? RX2_BYTE_SD : RX2_BYTE_DD;
-			disk_unbusy(&rf_sc->sc_disk, i, 1);
+			drive_unbusy(rf_sc->sc_disk.stats, i, 1);
 			bus_dmamap_unload(rfc_sc->sc_dmat, rfc_sc->sc_dmam);
 			/* check for errors */
 			if ((bus_space_read_2(rfc_sc->sc_iot, rfc_sc->sc_ioh,
@@ -829,7 +830,7 @@
 				rfc_sc->sc_curbuf->b_flags |= B_ERROR;
 				break;
 			}
-			disk_busy(&rf_sc->sc_disk);
+			drive_busy(rf_sc->sc_disk.stats);
 			if (rfc_sendcmd(rfc_sc, RX2CS_EBUF | RX2CS_IE
 			    | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD)
 			    | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
@@ -837,7 +838,7 @@
 			    & 0x30000) >>4), ((rf_sc->sc_state & RFS_DENS) == 0
 			    ? RX2_BYTE_SD : RX2_BYTE_DD) / 2,
 			    rfc_sc->sc_dmam->dm_segs[0].ds_addr & 0xffff) < 0) {
-				disk_unbusy(&rf_sc->sc_disk, 0, 1);
+				drive_unbusy(rf_sc->sc_disk.stats, 0, 1);
 				rfc_sc->sc_curbuf->b_flags |= B_ERROR;
 				bus_dmamap_unload(rfc_sc->sc_dmat,
 				rfc_sc->sc_dmam);
@@ -854,7 +855,7 @@
 				rfc_sc->sc_curbuf->b_flags |= B_ERROR;
 				break;
 			}
-			disk_busy(&rf_sc->sc_disk);
+			drive_busy(rf_sc->sc_disk.stats);
 			if (rfc_sendcmd(rfc_sc, RX2CS_FBUF | RX2CS_IE
 			    | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD)
 			    | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
@@ -862,7 +863,7 @@
 			    & 0x30000)>>4), ((rf_sc->sc_state & RFS_DENS) == 0
 			    ? RX2_BYTE_SD : RX2_BYTE_DD) / 2,
 			    rfc_sc->sc_dmam->dm_segs[0].ds_addr & 0xffff) < 0) {
-				disk_unbusy(&rf_sc->sc_disk, 0, 0);
+				drive_unbusy(rf_sc->sc_disk.stats, 0, 0);
 				rfc_sc->sc_curbuf->b_flags |= B_ERROR;
 				bus_dmamap_unload(rfc_sc->sc_dmat,
 				    rfc_sc->sc_dmam);
@@ -877,12 +878,12 @@
 				rfc_sc->sc_curbuf->b_flags |= B_ERROR;
 				break;
 			}
-			disk_busy(&rf_sc->sc_disk);
+			drive_busy(rf_sc->sc_disk.stats);
 			if (rfc_sendcmd(rfc_sc, RX2CS_WSEC | RX2CS_IE
 			    | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
 			    | ((rf_sc->sc_state& RFS_DENS) == 0 ? 0 : RX2CS_DD),
 			    i % RX2_SECTORS + 1, i / RX2_SECTORS) < 0) {
-				disk_unbusy(&rf_sc->sc_disk, 0, 0);
+				drive_unbusy(rf_sc->sc_disk.stats, 0, 0);
 				rfc_sc->sc_curbuf->b_flags |= B_ERROR;
 			}
 			break;
@@ -895,12 +896,12 @@
 				rfc_sc->sc_curbuf->b_flags |= B_ERROR;
 				break;
 			}
-			disk_busy(&rf_sc->sc_disk);
+			drive_busy(rf_sc->sc_disk.stats);
 			if (rfc_sendcmd(rfc_sc, RX2CS_RSEC | RX2CS_IE
 			    | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
 			    | ((rf_sc->sc_state& RFS_DENS) == 0 ? 0 : RX2CS_DD),
 			    i % RX2_SECTORS + 1, i / RX2_SECTORS) < 0) {
-				disk_unbusy(&rf_sc->sc_disk, 0, 1);
+				drive_unbusy(rf_sc->sc_disk.stats, 0, 1);
 				rfc_sc->sc_curbuf->b_flags |= B_ERROR;
 			}
 			break;
@@ -1011,7 +1012,7 @@
 		 * media must be purchased preformatted. fsck DEC makreting!
 		 */
 		RFS_SETCMD(rf_sc->sc_state, RFS_PROBING);
-		disk_busy(&rf_sc->sc_disk);
+		drive_busy(rf_sc->sc_disk.stats);
 		if (rfc_sendcmd(rfc_sc, RX2CS_RSEC | RX2CS_IE
 		    | (rf_sc->sc_dnum == 0 ? 0 : RX2CS_US)
 		    | ((rf_sc->sc_state & RFS_DENS) == 0 ? 0 : RX2CS_DD),
Index: sys/dev/qbus/rl.c
===================================================================
RCS file: /cvsroot/src/sys/dev/qbus/rl.c,v
retrieving revision 1.26
diff -u -r1.26 rl.c
--- sys/dev/qbus/rl.c	15 Oct 2005 17:29:25 -0000	1.26
+++ sys/dev/qbus/rl.c	12 Nov 2005 13:11:00 -0000
@@ -49,7 +49,7 @@
 #include <sys/device.h>
 #include <sys/systm.h>
 #include <sys/conf.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/disklabel.h>
 #include <sys/buf.h>
 #include <sys/bufq.h>
Index: sys/dev/raidframe/rf_netbsdkintf.c
===================================================================
RCS file: /cvsroot/src/sys/dev/raidframe/rf_netbsdkintf.c,v
retrieving revision 1.191
diff -u -r1.191 rf_netbsdkintf.c
--- sys/dev/raidframe/rf_netbsdkintf.c	15 Oct 2005 17:29:25 -0000	1.191
+++ sys/dev/raidframe/rf_netbsdkintf.c	12 Nov 2005 13:11:01 -0000
@@ -153,7 +153,7 @@
 #include <sys/pool.h>
 #include <sys/proc.h>
 #include <sys/queue.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/device.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
@@ -1768,7 +1768,7 @@
 		 */
 		do_async = 1;
 
-		disk_busy(&rs->sc_dkdev);
+		drive_busy(rs->sc_dkdev.stats);
 
 		/* XXX we're still at splbio() here... do we *really*
 		   need to be? */
@@ -3318,7 +3318,7 @@
 	struct buf *bp;
 
 	bp = (struct buf *)desc->bp;
-	disk_unbusy(&raid_softc[desc->raidPtr->raidid].sc_dkdev,
+	drive_unbusy(raid_softc[desc->raidPtr->raidid].sc_dkdev.stats,
 	    (bp->b_bcount - bp->b_resid), (bp->b_flags & B_READ));
 }
 
Index: sys/dev/scsipi/cd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/cd.c,v
retrieving revision 1.228
diff -u -r1.228 cd.c
--- sys/dev/scsipi/cd.c	15 Oct 2005 17:29:25 -0000	1.228
+++ sys/dev/scsipi/cd.c	12 Nov 2005 13:11:02 -0000
@@ -71,7 +71,7 @@
 #include <sys/errno.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/cdio.h>
 #include <sys/dvdio.h>
 #include <sys/scsiio.h>
@@ -822,7 +822,7 @@
 		}
 
 		/* Instrumentation. */
-		disk_busy(&cd->sc_dk);
+		drive_busy(cd->sc_dk.stats);
 
 		/*
 		 * Figure out what flags to use.
@@ -886,7 +886,7 @@
 		if (error)
 			bp->b_flags |= B_ERROR;
 
-		disk_unbusy(&cd->sc_dk, bp->b_bcount - bp->b_resid,
+		drive_unbusy(cd->sc_dk.stats, bp->b_bcount - bp->b_resid,
 		    (bp->b_flags & B_READ));
 #if NRND > 0
 		rnd_add_uint32(&cd->rnd_source, bp->b_rawblkno);
Index: sys/dev/scsipi/if_se.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/if_se.c,v
retrieving revision 1.58
diff -u -r1.58 if_se.c
--- sys/dev/scsipi/if_se.c	3 Jun 2005 13:44:11 -0000	1.58
+++ sys/dev/scsipi/if_se.c	12 Nov 2005 13:11:02 -0000
@@ -82,7 +82,7 @@
 #include <sys/errno.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/proc.h>
 #include <sys/conf.h>
 
Index: sys/dev/scsipi/sd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/sd.c,v
retrieving revision 1.241
diff -u -r1.241 sd.c
--- sys/dev/scsipi/sd.c	15 Oct 2005 17:29:25 -0000	1.241
+++ sys/dev/scsipi/sd.c	12 Nov 2005 13:11:03 -0000
@@ -73,7 +73,7 @@
 #include <sys/errno.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/proc.h>
 #include <sys/conf.h>
 #include <sys/vnode.h>
@@ -859,7 +859,7 @@
 		}
 
 		/* Instrumentation. */
-		disk_busy(&sd->sc_dk);
+		drive_busy(sd->sc_dk.stats);
 
 		/*
 		 * Mark the disk dirty so that the cache will be
@@ -935,7 +935,7 @@
 		if (error)
 			bp->b_flags |= B_ERROR;
 
-		disk_unbusy(&sd->sc_dk, bp->b_bcount - bp->b_resid,
+		drive_unbusy(sd->sc_dk.stats, bp->b_bcount - bp->b_resid,
 		    (bp->b_flags & B_READ));
 #if NRND > 0
 		rnd_add_uint32(&sd->rnd_source, bp->b_rawblkno);
Index: sys/dev/scsipi/ses.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/ses.c,v
retrieving revision 1.31
diff -u -r1.31 ses.c
--- sys/dev/scsipi/ses.c	30 May 2005 04:25:32 -0000	1.31
+++ sys/dev/scsipi/ses.c	12 Nov 2005 13:11:03 -0000
@@ -43,7 +43,7 @@
 #include <sys/errno.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/proc.h>
 #include <sys/conf.h>
 #include <sys/vnode.h>
Index: sys/dev/scsipi/st.c
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/st.c,v
retrieving revision 1.185
diff -u -r1.185 st.c
--- sys/dev/scsipi/st.c	15 Oct 2005 17:29:26 -0000	1.185
+++ sys/dev/scsipi/st.c	12 Nov 2005 13:11:04 -0000
@@ -76,7 +76,7 @@
 #include <sys/conf.h>
 #include <sys/kernel.h>
 #include <sys/vnode.h>
-#include <sys/tape.h>
+#include <sys/drive.h>
 #include <sys/sysctl.h>
 
 #include <dev/scsipi/scsi_spc.h>
@@ -107,9 +107,6 @@
 #define		ST_MOUNT_DELAY		0
 #endif
 
-struct tape *
-drive_attach(char *name);
-
 static dev_type_open(stopen);
 static dev_type_close(stclose);
 static dev_type_read(stread);
@@ -352,14 +349,6 @@
 	stdone
 };
 
-/*
- * A global list of all tape drives attached to the system.  May grow or
- * shrink over time.
- */
-struct  tapelist_head tapelist = TAILQ_HEAD_INITIALIZER(tapelist);
-int     tape_count = 0;             /* number of drives in global tapelist */
-struct simplelock tapelist_slock = SIMPLELOCK_INITIALIZER;
-
 #if	defined(ST_ENABLE_EARLYWARN)
 #define	ST_INIT_FLAGS	ST_EARLYWARN
 #else
@@ -423,7 +412,8 @@
 		    (st->flags & ST_READONLY) ? "protected" : "enabled");
 	}
 
-	st->stats = drive_attach(st->sc_dev.dv_xname);
+	st->stats = drive_stats_alloc(DRV_TAPE);
+	st->stats->name = st->sc_dev.dv_xname;
 	
 #if NRND > 0
 	rnd_attach_source(&st->rnd_source, st->sc_dev.dv_xname,
@@ -480,17 +470,8 @@
 	vdevgone(bmaj, mn, mn+STNMINOR-1, VBLK);
 	vdevgone(cmaj, mn, mn+STNMINOR-1, VCHR);
 
-	if (tape_count == 0) {
-		printf("%s detach: tape_count already zero\n",
-		       st->sc_dev.dv_xname);
-	} else {
-		simple_lock(&tapelist_slock);
-		TAILQ_REMOVE(&tapelist, st->stats, link);
-		tape_count--;
-		simple_unlock(&tapelist_slock);
-		free(st->stats, M_DEVBUF);
-	}
-
+	drive_stats_free(st->stats);
+	
 #if NRND > 0
 	/* Unhook the entropy source. */
 	rnd_detach_source(&st->rnd_source);
@@ -1187,7 +1168,7 @@
 	struct buf *bp;
 	struct scsi_rw_tape cmd;
 	struct scsipi_xfer *xs;
-	int flags, error, s;
+	int flags, error;
 
 	SC_DEBUG(periph, SCSIPI_DB2, ("ststart "));
 	/*
@@ -1224,11 +1205,7 @@
 		if ((bp = BUFQ_PEEK(st->buf_queue)) == NULL)
 			return;
 
-		if (st->stats->busy++ == 0) {
-			s = splclock();
-			st->stats->timestamp = mono_time;
-			splx(s);
-		}
+		drive_busy(st->stats);
 		
 		/*
 		 * only FIXEDBLOCK devices have pending I/O or space operations.
@@ -1356,8 +1333,6 @@
 {
 	struct st_softc *st = (void *)xs->xs_periph->periph_dev;
 	struct buf *bp = xs->bp;
-	int s;
-	struct timeval st_time, diff_time;
 
 	if (bp) {
 		bp->b_error = error;
@@ -1370,30 +1345,8 @@
 		else
 			st->flags &= ~ST_WRITTEN;
 
-		if (st->stats->busy-- == 0) {
-			  /* this is not really fatal so we don't panic */
-			printf("%s: busy < 0, Oops.\n", st->stats->name);
-			st->stats->busy = 0;
-		} else {
-			s = splclock();
-			st_time = mono_time;
-			splx(s);
-
-			timersub(&st_time, &st->stats->timestamp, &diff_time);
-			timeradd(&st->stats->time, &diff_time,
-				 &st->stats->time);
-
-			st->stats->timestamp = st_time;
-			if (bp->b_bcount > 0) {
-				if ((bp->b_flags & B_READ) == B_WRITE) {
-					st->stats->wbytes += bp->b_bcount;
-					st->stats->wxfer++;
-				} else {
-					st->stats->rbytes += bp->b_bcount;
-					st->stats->rxfer++;
-				}
-			}
-		}
+		drive_unbusy(st->stats, bp->b_bcount,
+			     ((bp->b_flags & B_READ) == B_READ));
 		
 			
 #if NRND > 0
@@ -2453,156 +2406,3 @@
 	/* Not implemented. */
 	return (ENXIO);
 }
-
-int
-sysctl_hw_tapenames(SYSCTLFN_ARGS)
-{
-	char bf[TAPENAMELEN + 1];
-	char *where = oldp;
-	struct tape *tapep;
-	size_t needed, left, slen;
-	int error, first;
-
-	if (newp != NULL)
-		return (EPERM);
-	if (namelen != 0)
-		return (EINVAL);
-
-	first = 1;
-	error = 0;
-	needed = 0;
-	left = *oldlenp;
-
-	simple_lock(&tapelist_slock);
-	for (tapep = TAILQ_FIRST(&tapelist); tapep != NULL;
-	    tapep = TAILQ_NEXT(tapep, link)) {
-		if (where == NULL)
-			needed += strlen(tapep->name) + 1;
-		else {
-			memset(bf, 0, sizeof(bf));
-			if (first) {
-				strncpy(bf, tapep->name, sizeof(bf));
-				first = 0;
-			} else {
-				bf[0] = ' ';
-				strncpy(bf + 1, tapep->name, sizeof(bf) - 1);
-			}
-			bf[TAPENAMELEN] = '\0';
-			slen = strlen(bf);
-			if (left < slen + 1)
-				break;
-			/* +1 to copy out the trailing NUL byte */
-			error = copyout(bf, where, slen + 1);
-			if (error)
-				break;
-			where += slen;
-			needed += slen;
-			left -= slen;
-		}
-	}
-	simple_unlock(&tapelist_slock);
-	*oldlenp = needed;
-	return (error);
-}
-
-int
-sysctl_hw_tapestats(SYSCTLFN_ARGS)
-{
-	struct tape_sysctl stape;
-	struct tape *tapep;
-	char *where = oldp;
-	size_t tocopy, left;
-	int error;
-
-	if (newp != NULL)
-		return (EPERM);
-
-	tocopy = name[0];
-
-	if (where == NULL) {
-		*oldlenp = tape_count * tocopy;
-		return (0);
-	}
-
-	error = 0;
-	left = *oldlenp;
-	memset(&stape, 0, sizeof(stape));
-	*oldlenp = 0;
-
-	simple_lock(&tapelist_slock);
-	TAILQ_FOREACH(tapep, &tapelist, link) {
-		if (left < tocopy)
-			break;
-		strncpy(stape.name, tapep->name, sizeof(stape.name));
-		stape.xfer = tapep->rxfer + tapep->wxfer;
-		stape.rxfer = tapep->rxfer;
-		stape.wxfer = tapep->wxfer;
-		stape.bytes = tapep->rbytes + tapep->wbytes;
-		stape.rbytes = tapep->rbytes;
-		stape.wbytes = tapep->wbytes;
-		stape.attachtime_sec = tapep->attachtime.tv_sec;
-		stape.attachtime_usec = tapep->attachtime.tv_usec;
-		stape.timestamp_sec = tapep->timestamp.tv_sec;
-		stape.timestamp_usec = tapep->timestamp.tv_usec;
-		stape.time_sec = tapep->time.tv_sec;
-		stape.time_usec = tapep->time.tv_usec;
-		stape.busy = tapep->busy;
-
-		error = copyout(&stape, where, min(tocopy, sizeof(stape)));
-		if (error)
-			break;
-		where += tocopy;
-		*oldlenp += tocopy;
-		left -= tocopy;
-	}
-	simple_unlock(&tapelist_slock);
-	return (error);
-}
-
-struct tape *
-drive_attach(char *name) 
-{
-	struct tape *stats;
-	int s;
-	
-	/* Allocate and initialise statistics */
-	stats = (struct tape *) malloc(sizeof(struct tape), M_DEVBUF,
-					   M_WAITOK);
-	stats->rxfer = stats->wxfer = stats->rbytes = 0;
-	stats->wbytes = stats->busy = 0;
-
-	/*
-	 * Set the attached timestamp.
-	 */
-	s = splclock();
-	stats->attachtime = mono_time;
-	splx(s);
-
-	  /* and clear the utilisation time */
-	timerclear(&stats->time);
-
-	  /* link the tape drive to the tapelist */
-	simple_lock(&tapelist_slock);
-	TAILQ_INSERT_TAIL(&tapelist, stats, link);
-	tape_count++;
-	simple_unlock(&tapelist_slock);
-	stats->name = name;
-
-	return stats;
-}
-
-SYSCTL_SETUP(sysctl_tape_stats_setup, "sysctl tape stats setup")
-{
-	sysctl_createv(clog, 0, NULL, NULL,
-		       CTLFLAG_PERMANENT,
-		       CTLTYPE_STRING, "tapenames",
-		       SYSCTL_DESCR("List of tape devices present"),
-		       sysctl_hw_tapenames, 0, NULL, 0,
-		       CTL_HW, HW_TAPENAMES, CTL_EOL);
-	sysctl_createv(clog, 0, NULL, NULL,
-		       CTLFLAG_PERMANENT,
-		       CTLTYPE_STRUCT, "tapestats",
-		       SYSCTL_DESCR("Statistics on tape drive operation"),
-		       sysctl_hw_tapestats, 0, NULL, 0,
-		       CTL_HW, HW_TAPESTATS, CTL_EOL);
-}
Index: sys/dev/scsipi/stvar.h
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/stvar.h,v
retrieving revision 1.15
diff -u -r1.15 stvar.h
--- sys/dev/scsipi/stvar.h	15 Oct 2005 17:29:26 -0000	1.15
+++ sys/dev/scsipi/stvar.h	12 Nov 2005 13:11:04 -0000
@@ -151,7 +151,7 @@
 	struct callout sc_callout;	/* restarting the queue after */
 					/* transient error */
 	
-	struct tape *stats;		/* statistics for the drive */
+	struct drive_stats *stats;	/* statistics for the drive */
 	
 #if NRND > 0
 	rndsource_element_t	rnd_source;
Index: sys/dev/sun/disksubr.c
===================================================================
RCS file: /cvsroot/src/sys/dev/sun/disksubr.c,v
retrieving revision 1.6
diff -u -r1.6 disksubr.c
--- sys/dev/sun/disksubr.c	31 May 2005 00:47:54 -0000	1.6
+++ sys/dev/sun/disksubr.c	12 Nov 2005 13:11:04 -0000
@@ -63,7 +63,7 @@
 #include <sys/ioccom.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/dkbad.h>
 
 #include <dev/sun/disklabel.h>
Index: sys/dev/usb/umass_scsipi.c
===================================================================
RCS file: /cvsroot/src/sys/dev/usb/umass_scsipi.c,v
retrieving revision 1.26
diff -u -r1.26 umass_scsipi.c
--- sys/dev/usb/umass_scsipi.c	22 Sep 2005 22:39:37 -0000	1.26
+++ sys/dev/usb/umass_scsipi.c	12 Nov 2005 13:11:04 -0000
@@ -66,7 +66,7 @@
 #include <dev/scsipi/scsi_disk.h>
 #include <dev/scsipi/scsi_changer.h>
 
-#include <sys/disk.h>		/* XXX */
+#include <sys/drive.h>		/* XXX */
 #include <dev/scsipi/sdvar.h>	/* XXX */
 
 /* USB */
Index: sys/dev/vme/xd.c
===================================================================
RCS file: /cvsroot/src/sys/dev/vme/xd.c,v
retrieving revision 1.58
diff -u -r1.58 xd.c
--- sys/dev/vme/xd.c	15 Oct 2005 17:29:26 -0000	1.58
+++ sys/dev/vme/xd.c	12 Nov 2005 13:11:05 -0000
@@ -72,7 +72,7 @@
 #include <sys/malloc.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 #include <sys/dkbad.h>
 #include <sys/conf.h>
@@ -1652,7 +1652,7 @@
 	xdc_rqtopb(iorq, iopb, (bp->b_flags & B_READ) ? XDCMD_RD : XDCMD_WR, 0);
 
 	/* Instrumentation. */
-	disk_busy(&xdsc->sc_dk);
+	drive_busy(xdsc->sc_dk.stats);
 
 	/* now submit [note that xdc_submit_iorq can never fail on NORM reqs] */
 
@@ -1939,7 +1939,7 @@
 
 			    bus_dmamap_unload(xdcsc->dmatag, iorq->dmamap);
 
-			    disk_unbusy(&xdcsc->reqs[lcv].xd->sc_dk,
+			    drive_unbusy(xdcsc->reqs[lcv].xd->sc_dk.stats,
 				(xdcsc->reqs[lcv].buf->b_bcount -
 				xdcsc->reqs[lcv].buf->b_resid),
 				(iorq->buf->b_flags & B_READ));
@@ -2150,7 +2150,7 @@
 						: BUS_DMASYNC_POSTWRITE);
 			bus_dmamap_unload(xdcsc->dmatag, iorq->dmamap);
 
-			disk_unbusy(&iorq->xd->sc_dk,
+			drive_unbusy(iorq->xd->sc_dk.stats,
 			    (bp->b_bcount - bp->b_resid),
 			    (bp->b_flags & B_READ));
 			XDC_FREE(xdcsc, rqno);
Index: sys/dev/vme/xy.c
===================================================================
RCS file: /cvsroot/src/sys/dev/vme/xy.c,v
retrieving revision 1.60
diff -u -r1.60 xy.c
--- sys/dev/vme/xy.c	15 Oct 2005 17:29:26 -0000	1.60
+++ sys/dev/vme/xy.c	12 Nov 2005 13:11:06 -0000
@@ -72,7 +72,7 @@
 #include <sys/malloc.h>
 #include <sys/device.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 #include <sys/dkbad.h>
 #include <sys/conf.h>
@@ -1490,7 +1490,7 @@
 	xyc_rqtopb(iorq, iopb, (bp->b_flags & B_READ) ? XYCMD_RD : XYCMD_WR, 0);
 
 	/* Instrumentation. */
-	disk_busy(&xysc->sc_dk);
+	drive_busy(xysc->sc_dk.stats);
 
 	return (XY_ERR_AOK);
 }
@@ -1844,7 +1844,7 @@
 			    bus_dmamap_unload(xycsc->dmatag, iorq->dmamap);
 
 			    (void)BUFQ_GET(iorq->xy->xyq);
-			    disk_unbusy(&xycsc->reqs[lcv].xy->sc_dk,
+			    drive_unbusy(xycsc->reqs[lcv].xy->sc_dk.stats,
 				(xycsc->reqs[lcv].buf->b_bcount -
 				xycsc->reqs[lcv].buf->b_resid),
 				(xycsc->reqs[lcv].buf->b_flags & B_READ));
@@ -2028,7 +2028,7 @@
 			bus_dmamap_unload(xycsc->dmatag, iorq->dmamap);
 
 			(void)BUFQ_GET(iorq->xy->xyq);
-			disk_unbusy(&iorq->xy->sc_dk,
+			drive_unbusy(iorq->xy->sc_dk.stats,
 			    (bp->b_bcount - bp->b_resid),
 			    (bp->b_flags & B_READ));
 			iorq->mode = XY_SUB_FREE;
Index: sys/kern/init_sysctl.c
===================================================================
RCS file: /cvsroot/src/sys/kern/init_sysctl.c,v
retrieving revision 1.56
diff -u -r1.56 init_sysctl.c
--- sys/kern/init_sysctl.c	8 Oct 2005 06:35:56 -0000	1.56
+++ sys/kern/init_sysctl.c	12 Nov 2005 13:11:06 -0000
@@ -896,18 +896,6 @@
 		       CTL_HW, HW_PAGESIZE, CTL_EOL);
 	sysctl_createv(clog, 0, NULL, NULL,
 		       CTLFLAG_PERMANENT,
-		       CTLTYPE_STRING, "disknames",
-		       SYSCTL_DESCR("List of disk devices present"),
-		       sysctl_hw_disknames, 0, NULL, 0,
-		       CTL_HW, HW_DISKNAMES, CTL_EOL);
-	sysctl_createv(clog, 0, NULL, NULL,
-		       CTLFLAG_PERMANENT,
-		       CTLTYPE_STRUCT, "diskstats",
-		       SYSCTL_DESCR("Statistics on disk operation"),
-		       sysctl_hw_diskstats, 0, NULL, 0,
-		       CTL_HW, HW_DISKSTATS, CTL_EOL);
-	sysctl_createv(clog, 0, NULL, NULL,
-		       CTLFLAG_PERMANENT,
 		       CTLTYPE_STRING, "machine_arch",
 		       SYSCTL_DESCR("Machine CPU class"),
 		       NULL, 0, machine_arch, 0,
Index: sys/kern/subr_disk.c
===================================================================
RCS file: /cvsroot/src/sys/kern/subr_disk.c,v
retrieving revision 1.71
diff -u -r1.71 subr_disk.c
--- sys/kern/subr_disk.c	15 Oct 2005 17:29:26 -0000	1.71
+++ sys/kern/subr_disk.c	12 Nov 2005 13:11:06 -0000
@@ -84,7 +84,7 @@
 #include <sys/buf.h>
 #include <sys/syslog.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/sysctl.h>
 #include <lib/libkern/libkern.h>
 
Index: sys/kern/subr_disk_mbr.c
===================================================================
RCS file: /cvsroot/src/sys/kern/subr_disk_mbr.c,v
retrieving revision 1.6
diff -u -r1.6 subr_disk_mbr.c
--- sys/kern/subr_disk_mbr.c	26 Feb 2005 21:34:55 -0000	1.6
+++ sys/kern/subr_disk_mbr.c	12 Nov 2005 13:11:07 -0000
@@ -60,7 +60,7 @@
 #include <sys/systm.h>
 #include <sys/buf.h>
 #include <sys/disklabel.h>
-#include <sys/disk.h>
+#include <sys/drive.h>
 #include <sys/syslog.h>
 
 #include "opt_mbr.h"
Index: sys/nfs/nfs_vfsops.c
===================================================================
RCS file: /cvsroot/src/sys/nfs/nfs_vfsops.c,v
retrieving revision 1.150
diff -u -r1.150 nfs_vfsops.c
--- sys/nfs/nfs_vfsops.c	23 Sep 2005 12:10:33 -0000	1.150
+++ sys/nfs/nfs_vfsops.c	12 Nov 2005 13:11:07 -0000
@@ -77,6 +77,12 @@
 extern struct nfsstats nfsstats;
 extern int nfs_ticks;
 
+/*
+ * keep a count of the nfs mounts to generate ficticious drive names
+ * for the per drive stats.
+ */
+unsigned int nfs_mount_count = 0;
+
 MALLOC_DEFINE(M_NFSMNT, "NFS mount", "NFS mount structure");
 
 /*
@@ -798,6 +804,13 @@
 	nmp->nm_vnode = *vpp;
 	VOP_UNLOCK(*vpp, 0);
 
+	nmp->stats = drive_stats_alloc(DRV_NFS);
+	nmp->stats->parent = nmp;
+	  /* generate a ficticious drive name for the nfs mount */
+	MALLOC(nmp->stats->name, char *, DRIVENAMELEN, M_NFSMNT, M_WAITOK);
+	snprintf(nmp->stats->name, DRIVENAMELEN, "nfs%u", nfs_mount_count);
+	nfs_mount_count++;
+	
 	return (0);
 bad:
 	nfs_disconnect(nmp);
@@ -867,6 +880,14 @@
 	nmp->nm_iflag |= NFSMNT_DISMNT;
 
 	/*
+	 * Clean up the stats... note that we carefully avoid decrementing
+	 * nfs_mount_count here for good reason - we may not be unmounting
+	 * the last thing mounted.
+	 */
+	FREE(nmp->stats->name, M_NFSMNT);
+	drive_stats_free(nmp->stats);
+	
+	/*
 	 * There are two reference counts to get rid of here
 	 * (see comment in mountnfs()).
 	 */
Index: sys/nfs/nfs_vnops.c
===================================================================
RCS file: /cvsroot/src/sys/nfs/nfs_vnops.c,v
retrieving revision 1.229
diff -u -r1.229 nfs_vnops.c
--- sys/nfs/nfs_vnops.c	5 Nov 2005 19:21:14 -0000	1.229
+++ sys/nfs/nfs_vnops.c	12 Nov 2005 13:11:09 -0000
@@ -53,6 +53,7 @@
 #include <sys/proc.h>
 #include <sys/mount.h>
 #include <sys/buf.h>
+#include <sys/drive.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
 #include <sys/namei.h>
@@ -1240,7 +1241,7 @@
 	caddr_t bpos, dpos, cp2;
 	struct mbuf *mreq, *mrep, *md, *mb;
 	struct nfsmount *nmp;
-	int error = 0, len, retlen, tsiz, eof;
+	int error = 0, len, retlen, tsiz, eof, byte_count;
 	const int v3 = NFS_ISV3(vp);
 	struct nfsnode *np = VTONFS(vp);
 #ifndef NFS_V2_ONLY
@@ -1254,6 +1255,8 @@
 	tsiz = uiop->uio_resid;
 	if (uiop->uio_offset + tsiz > nmp->nm_maxfilesize)
 		return (EFBIG);
+	drive_busy(nmp->stats);
+	byte_count = 0; /* count bytes actually transferred */
 	while (tsiz > 0) {
 		nfsstats.rpccnt[NFSPROC_READ]++;
 		len = (tsiz > nmp->nm_rsize) ? nmp->nm_rsize : tsiz;
@@ -1288,6 +1291,7 @@
 		nfsm_mtouio(uiop, retlen);
 		m_freem(mrep);
 		tsiz -= retlen;
+		byte_count += retlen;
 #ifndef NFS_V2_ONLY
 		if (v3) {
 			if (eof || retlen == 0)
@@ -1298,6 +1302,7 @@
 			tsiz = 0;
 	}
 nfsmout:
+	drive_unbusy(nmp->stats, byte_count, 1);
 	return (error);
 }
 
@@ -1347,7 +1352,7 @@
 	int committed = NFSV3WRITE_FILESYNC;
 	struct nfsnode *np = VTONFS(vp);
 	struct nfs_writerpc_context ctx;
-	int s;
+	int s, byte_count;
 	struct lwp *l = NULL;
 	size_t origresid;
 #ifndef NFS_V2_ONLY
@@ -1376,6 +1381,8 @@
 retry:
 	origresid = uiop->uio_resid;
 	KASSERT(origresid == uiop->uio_iov->iov_len);
+	drive_busy(nmp->stats);
+	byte_count = 0; /* count of bytes actually written */
 	while (tsiz > 0) {
 		uint32_t datalen; /* data bytes need to be allocated in mbuf */
 		uint32_t backup;
@@ -1508,6 +1515,7 @@
 		if (error)
 			break;
 		tsiz -= len;
+		byte_count += len;
 		if (stalewriteverf) {
 			*stalewriteverfp = TRUE;
 			stalewriteverf = FALSE;
@@ -1528,6 +1536,7 @@
 		}
 	}
 nfsmout:
+	drive_unbusy(nmp->stats, byte_count, 0);
 	if (pageprotected) {
 		/*
 		 * wait until mbufs go away.
Index: sys/nfs/nfsmount.h
===================================================================
RCS file: /cvsroot/src/sys/nfs/nfsmount.h,v
retrieving revision 1.35
diff -u -r1.35 nfsmount.h
--- sys/nfs/nfsmount.h	23 Sep 2005 12:10:33 -0000	1.35
+++ sys/nfs/nfsmount.h	12 Nov 2005 13:11:09 -0000
@@ -37,6 +37,9 @@
 
 #ifndef _NFS_NFSMOUNT_H_
 #define _NFS_NFSMOUNT_H_
+#ifdef _KERNEL
+#include <sys/drive.h>
+#endif
 
 /*
  * Arguments to mount NFS
@@ -167,6 +170,7 @@
 	int	nm_iflag;		/* internal flags */
 	int	nm_waiters;		/* number of waiting listeners.. */
 	long	nm_wcckludgetime;	/* see nfs_check_wccdata() */
+	struct drive_stats *stats;	/* per nfs mount statistics */
 };
 
 /*
Index: sys/sys/Makefile
===================================================================
RCS file: /cvsroot/src/sys/sys/Makefile,v
retrieving revision 1.77
diff -u -r1.77 Makefile
--- sys/sys/Makefile	30 Oct 2005 23:35:17 -0000	1.77
+++ sys/sys/Makefile	12 Nov 2005 13:11:09 -0000
@@ -6,7 +6,7 @@
 	bootblock.h bswap.h buf.h \
 	callout.h cdefs.h cdefs_aout.h \
 	cdefs_elf.h cdio.h chio.h clockctl.h conf.h core.h \
-	device.h dir.h dirent.h disk.h disklabel.h disklabel_acorn.h \
+	device.h dir.h dirent.h drive.h disklabel.h disklabel_acorn.h \
 	dkbad.h dkio.h dkstat.h domain.h drvctlio.h dvdio.h \
 	endian.h envsys.h errno.h event.h exec.h exec_aout.h \
 	exec_coff.h exec_ecoff.h exec_elf.h exec_script.h extattr.h extent.h \
Index: sys/sys/disk.h
===================================================================
RCS file: /cvsroot/src/sys/sys/disk.h,v
retrieving revision 1.30
diff -u -r1.30 disk.h
--- sys/sys/disk.h	20 Aug 2005 12:00:01 -0000	1.30
+++ sys/sys/disk.h	12 Nov 2005 13:11:09 -0000
@@ -87,6 +87,7 @@
  */
 
 #include <sys/dkio.h>
+#include <sys/drive.h>
 #include <sys/time.h>
 #include <sys/queue.h>
 #include <sys/lock.h>
@@ -243,29 +244,6 @@
 	struct cpu_disklabel *dk_cpulabel;
 };
 
-#define	DK_DISKNAMELEN	16
-
-/* The following structure is 64-bit alignment safe */
-struct disk_sysctl {
-	char		dk_name[DK_DISKNAMELEN];
-	int32_t		dk_busy;
-	int32_t		pad;
-	u_int64_t	dk_xfer;
-	u_int64_t	dk_seek;
-	u_int64_t	dk_bytes;
-	u_int32_t	dk_attachtime_sec;
-	u_int32_t	dk_attachtime_usec;
-	u_int32_t	dk_timestamp_sec;
-	u_int32_t	dk_timestamp_usec;
-	u_int32_t	dk_time_sec;
-	u_int32_t	dk_time_usec;
-	/* New separate read/write stats */
-	u_int64_t	dk_rxfer;
-	u_int64_t	dk_rbytes;
-	u_int64_t	dk_wxfer;
-	u_int64_t	dk_wbytes;
-};
-
 struct dkdriver {
 	void	(*d_strategy)(struct buf *);
 	void	(*d_minphys)(struct buf *);
Index: sys/sys/sysctl.h
===================================================================
RCS file: /cvsroot/src/sys/sys/sysctl.h,v
retrieving revision 1.141
diff -u -r1.141 sysctl.h
--- sys/sys/sysctl.h	7 Sep 2005 16:26:16 -0000	1.141
+++ sys/sys/sysctl.h	12 Nov 2005 13:11:09 -0000
@@ -702,8 +702,8 @@
 #define	HW_PHYSMEM	 5		/* int: total memory (bytes) */
 #define	HW_USERMEM	 6		/* int: non-kernel memory (bytes) */
 #define	HW_PAGESIZE	 7		/* int: software page size */
-#define	HW_DISKNAMES	 8		/* string: disk drive names */
-#define	HW_DISKSTATS	 9		/* struct: diskstats[] */
+#define	HW_DRIVENAMES	 8		/* string: disk drive names */
+#define	HW_DRIVESTATS	 9		/* struct: diskstats[] */
 #define	HW_MACHINE_ARCH	10		/* string: machine architecture */
 #define	HW_ALIGNBYTES	11		/* int: ALIGNBYTES for the kernel */
 #define	HW_CNMAGIC	12		/* string: console magic sequence(s) */
@@ -722,8 +722,8 @@
 	{ "physmem", CTLTYPE_INT }, \
 	{ "usermem", CTLTYPE_INT }, \
 	{ "pagesize", CTLTYPE_INT }, \
-	{ "disknames", CTLTYPE_STRING }, \
-	{ "diskstats", CTLTYPE_STRUCT }, \
+	{ "drivenames", CTLTYPE_STRING }, \
+	{ "drivestats", CTLTYPE_STRUCT }, \
 	{ "machine_arch", CTLTYPE_STRING }, \
 	{ "alignbytes", CTLTYPE_INT }, \
 	{ "cnmagic", CTLTYPE_STRING }, \
@@ -1083,8 +1083,6 @@
  * these helpers are in other files (XXX so should the nodes be) or
  * are used by more than one node
  */
-int	sysctl_hw_disknames(SYSCTLFN_PROTO);
-int	sysctl_hw_diskstats(SYSCTLFN_PROTO);
 int	sysctl_hw_tapenames(SYSCTLFN_PROTO);
 int	sysctl_hw_tapestats(SYSCTLFN_PROTO);
 int	sysctl_kern_vnode(SYSCTLFN_PROTO);
Index: usr.bin/systat/Makefile
===================================================================
RCS file: /cvsroot/src/usr.bin/systat/Makefile,v
retrieving revision 1.31
diff -u -r1.31 Makefile
--- usr.bin/systat/Makefile	7 Aug 2005 12:32:38 -0000	1.31
+++ usr.bin/systat/Makefile	12 Nov 2005 13:11:09 -0000
@@ -11,7 +11,7 @@
 CPPFLAGS+=-I${NETBSDSRCDIR}/usr.bin/vmstat -DSUPPORT_UTMP -DSUPPORT_UTMPX \
 	-I${NETBSDSRCDIR}/usr.bin/who
 CWARNFLAGS+=    -Wno-format-y2k
-SRCS=	bufcache.c cmds.c cmdtab.c disks.c df.c dkstats.c tpstats.c fetch.c \
+SRCS=	bufcache.c cmds.c cmdtab.c disks.c df.c drvstats.c fetch.c \
 	globalcmds.c icmp.c iostat.c ip.c keyboard.c main.c mbufs.c \
 	netcmds.c netstat.c pigs.c ps.c swap.c tcp.c vmstat.c utmpentry.c
 DPADD=	${LIBCURSES} ${LIBM} ${LIBKVM}
Index: usr.bin/systat/disks.c
===================================================================
RCS file: /cvsroot/src/usr.bin/systat/disks.c,v
retrieving revision 1.15
diff -u -r1.15 disks.c
--- usr.bin/systat/disks.c	26 Feb 2005 18:58:45 -0000	1.15
+++ usr.bin/systat/disks.c	12 Nov 2005 13:11:09 -0000
@@ -42,16 +42,16 @@
 
 #include "systat.h"
 #include "extern.h"
-#include "dkstats.h"
+#include "drvstats.h"
 
-static void dkselect(char *args, int truefalse, int selections[]);
+static void drvselect(char *args, int truefalse, int selections[]);
 
 void
 disks_add(char *args)
 {
 
 	if (args)
-		dkselect(args, 1, dk_select);
+		drvselect(args, 1, drv_select);
 }
 
 void
@@ -59,7 +59,7 @@
 {
 
 	if (args)
-		dkselect(args, 0, dk_select);
+		drvselect(args, 0, drv_select);
 }
 
 void
@@ -68,19 +68,19 @@
 	int i;
 
 	if (args) {
-		for (i = 0; i < dk_ndrive; i++)
-			dk_select[i] = 0;
+		for (i = 0; i < ndrive; i++)
+			drv_select[i] = 0;
 		disks_add(args);
 	} else {
 		move(CMDLINE, 0);
 		clrtoeol();
-		for (i = 0; i < dk_ndrive; i++)
+		for (i = 0; i < ndrive; i++)
 			printw("%s ", dr_name[i]);
 	}
 }
 
 static void
-dkselect(char *args, int truefalse, int selections[])
+drvselect(char *args, int truefalse, int selections[])
 {
 	char *cp;
 	int i;
@@ -98,12 +98,12 @@
 			*cp++ = '\0';
 		if (cp - args == 0)
 			break;
-		for (i = 0; i < dk_ndrive; i++)
+		for (i = 0; i < ndrive; i++)
 			if (strcmp(args, dr_name[i]) == 0) {
 				selections[i] = truefalse;
 				break;
 			}
-		if (i >= dk_ndrive)
+		if (i >= ndrive)
 			error("%s: unknown drive", args);
 		args = cp;
 	}
Index: usr.bin/systat/iostat.c
===================================================================
RCS file: /cvsroot/src/usr.bin/systat/iostat.c,v
retrieving revision 1.33
diff -u -r1.33 iostat.c
--- usr.bin/systat/iostat.c	7 Aug 2005 12:32:38 -0000	1.33
+++ usr.bin/systat/iostat.c	12 Nov 2005 13:11:09 -0000
@@ -43,8 +43,7 @@
 
 #include "systat.h"
 #include "extern.h"
-#include "dkstats.h"
-#include "tpstats.h"
+#include "drvstats.h"
 
 static  int linesperregion;
 static  double etime;
@@ -56,7 +55,6 @@
 static void histogram(double, int, double);
 static int numlabels(int);
 static int stats(int, int, int);
-static int tpstats(int, int, int);
 static void stat1(int, int);
 
 
@@ -82,10 +80,8 @@
 initiostat(void)
 {
 
-	dkinit(1);
-	tpinit(1);
-	dkreadstats();
-	tpreadstats();
+	drvinit(1);
+	drvreadstats();
 	return(1);
 }
 
@@ -93,15 +89,11 @@
 fetchiostat(void)
 {
 
-	if (dk_ndrive == 0)
+	if (ndrive == 0)
 		return;
 	else
-		dkreadstats();
+		drvreadstats();
 
-	if (tp_ndrive == 0)
-		return;
-	else
-		tpreadstats();
 }
 
 #define	INSET	14
@@ -111,7 +103,7 @@
 {
 	int row;
 
-	if ((dk_ndrive == 0) && (tp_ndrive == 0)) {
+	if (ndrive == 0) {
 		error("No drives defined.");
 		return;
 	}
@@ -137,11 +129,8 @@
 
 #define COLWIDTH	(9 + secs * 5 + 1 + read_write * 9 + 1)
 #define DRIVESPERLINE	((getmaxx(wnd) + 1) / COLWIDTH)
-	for (ndrives = 0, i = 0; i < dk_ndrive; i++)
-		if (cur.dk_select[i])
-			ndrives++;
-	for (i = 0; i < tp_ndrive; i++)
-		if (cur_tape.select[i])
+	for (ndrives = 0, i = 0; i < ndrive; i++)
+		if (cur.select[i])
 			ndrives++;
 	
 	regions = howmany(ndrives, DRIVESPERLINE);
@@ -156,21 +145,15 @@
 	if (linesperregion < 3)
 		linesperregion = 3;
 	col = 0;
-	for (i = 0; i < (dk_ndrive + tp_ndrive); i++)
-		if (((i < dk_ndrive) && (cur.dk_select[i])) ||
-		    ((i >= dk_ndrive) && (cur_tape.select[i - dk_ndrive]))) {
+	for (i = 0; i < ndrive; i++)
+		if (cur.select[i]) {
 			if (col + COLWIDTH - 1 > getmaxx(wnd)) {
 				col = 0, row += linesperregion + 1;
 				if (row > getmaxy(wnd) - (linesperregion))
 					break;
 			}
 
-			if (i < dk_ndrive)
-				mvwprintw(wnd, row, col + 5, "%s",
-					  cur.dk_name[i]);
-			else
-				mvwprintw(wnd, row, col + 5, "%s",
-					  cur_tape.name[i - dk_ndrive]);
+			mvwprintw(wnd, row, col + 5, "%s", cur.name[i]);
 			
 			if (read_write)
 				mvwprintw(wnd, row, col + 11 + secs * 5,
@@ -196,26 +179,12 @@
 	mvwaddstr(wnd, row++, INSET,
 	    "/0   /10  /20  /30  /40  /50  /60  /70  /80  /90  /100");
 	linesperregion = 2 + secs + (read_write ? 2 : 0);
-	for (i = 0; i < dk_ndrive; i++)
-		if (cur.dk_select[i]) {
-			if (row > getmaxy(wnd) - linesperregion)
-				break;
-			mvwprintw(wnd, row++, 0, "%7.7s  kBps|",
-			    cur.dk_name[i]);
-			mvwaddstr(wnd, row++, 0, "          tps|");
-			if (read_write) {
-				mvwprintw(wnd, row++, 0, " (write) kBps|");
-				mvwaddstr(wnd, row++, 0, "          tps|");
-			}
-			if (secs)
-				mvwaddstr(wnd, row++, 0, "         msec|");
-		}
-	for (i = 0; i < tp_ndrive; i++)
-		if (cur_tape.select[i]) {
+	for (i = 0; i < ndrive; i++) {
+		if (cur.select[i]) {
 			if (row > getmaxy(wnd) - linesperregion)
 				break;
 			mvwprintw(wnd, row++, 0, "%7.7s  kBps|",
-			    cur_tape.name[i]);
+			    cur.name[i]);
 			mvwaddstr(wnd, row++, 0, "          tps|");
 			if (read_write) {
 				mvwprintw(wnd, row++, 0, " (write) kBps|");
@@ -224,6 +193,8 @@
 			if (secs)
 				mvwaddstr(wnd, row++, 0, "         msec|");
 		}
+	}
+	
 	return (row);
 }
 
@@ -232,10 +203,9 @@
 {
 	int i, row, col;
 
-	if (dk_ndrive == 0)
+	if (ndrive == 0)
 		return;
-	dkswap();
-	tpswap();
+	drvswap();
 
 	etime = cur.cp_etime;
 	row = 1;
@@ -247,18 +217,12 @@
 		stat1(row++, i);
 	if (!numbers) {
 		row += 2;
-		for (i = 0; i < dk_ndrive; i++)
-			if (cur.dk_select[i]) {
+		for (i = 0; i < ndrive; i++)
+			if (cur.select[i]) {
 				if (row > getmaxy(wnd) - linesperregion)
 					break;
 				row = stats(row, INSET, i);
 			}
-		for (i = 0; i < tp_ndrive; i++)
-			if (cur_tape.select[i]) {
-				if (row > getmaxy(wnd) - linesperregion)
-					break;
-				row = tpstats(row, INSET, i);
-			}
 		return;
 	}
 	col = 0;
@@ -266,22 +230,8 @@
 	wdeleteln(wnd);
 	wmove(wnd, row + 3, 0);
 	winsertln(wnd);
-	for (i = 0; i < dk_ndrive; i++)
-		if (cur.dk_select[i]) {
-			if (col + COLWIDTH - 1 > getmaxx(wnd)) {
-				col = 0, row += linesperregion + 1;
-				if (row > getmaxy(wnd) - (linesperregion + 1))
-					break;
-				wmove(wnd, row + linesperregion, 0);
-				wdeleteln(wnd);
-				wmove(wnd, row + 3, 0);
-				winsertln(wnd);
-			}
-			(void) stats(row + 3, col, i);
-			col += COLWIDTH;
-		}
-	for (i = 0; i < tp_ndrive; i++)
-		if (cur_tape.select[i]) {
+	for (i = 0; i < ndrive; i++)
+		if (cur.select[i]) {
 			if (col + COLWIDTH - 1 > getmaxx(wnd)) {
 				col = 0, row += linesperregion + 1;
 				if (row > getmaxy(wnd) - (linesperregion + 1))
@@ -303,64 +253,16 @@
 	uint64_t rxfer;
 
 	/* time busy in disk activity */
-	atime = (double)cur.dk_time[dn].tv_sec +
-		((double)cur.dk_time[dn].tv_usec / (double)1000000);
-
-	/* # of k transferred */
-	rwords = cur.dk_rbytes[dn] / 1024.0;
-	wwords = cur.dk_wbytes[dn] / 1024.0;
-	rxfer = cur.dk_rxfer[dn];
-	if (!read_write) {
-		rwords = wwords;
-		rxfer += cur.dk_wxfer[dn];
-	}
-	if (numbers) {
-		mvwprintw(wnd, row, col, "%5.0f%4.0f",
-		    rwords / etime, rxfer / etime);
-		if (secs)
-			wprintw(wnd, "%5.1f", atime / etime);
-		if (read_write)
-			wprintw(wnd, " %5.0f%4.0f",
-			    wwords / etime, cur.dk_wxfer[dn] / etime);
-		return (row);
-	}
-
-	wmove(wnd, row++, col);
-	histogram(rwords / etime, 50, 0.5);
-	wmove(wnd, row++, col);
-	histogram(rxfer / etime, 50, 0.5);
-	if (read_write) {
-		wmove(wnd, row++, col);
-		histogram(wwords / etime, 50, 0.5);
-		wmove(wnd, row++, col);
-		histogram(cur.dk_wxfer[dn] / etime, 50, 0.5);
-	}
-
-	if (secs) {
-		wmove(wnd, row++, col);
-		atime *= 1000;	/* In milliseconds */
-		histogram(atime / etime, 50, 0.5);
-	}
-	return (row);
-}
-
-static int
-tpstats(int row, int col, int dn)
-{
-	double atime, rwords, wwords;
-	uint64_t rxfer;
-
-	/* time busy in disk activity */
-	atime = (double)cur_tape.time[dn].tv_sec +
-		((double)cur_tape.time[dn].tv_usec / (double)1000000);
+	atime = (double)cur.time[dn].tv_sec +
+		((double)cur.time[dn].tv_usec / (double)1000000);
 
 	/* # of k transferred */
-	rwords = cur_tape.rbytes[dn] / 1024.0;
-	wwords = cur_tape.wbytes[dn] / 1024.0;
-	rxfer = cur_tape.rxfer[dn];
+	rwords = cur.rbytes[dn] / 1024.0;
+	wwords = cur.wbytes[dn] / 1024.0;
+	rxfer = cur.rxfer[dn];
 	if (!read_write) {
 		rwords = wwords;
-		rxfer += cur_tape.wxfer[dn];
+		rxfer += cur.wxfer[dn];
 	}
 	if (numbers) {
 		mvwprintw(wnd, row, col, "%5.0f%4.0f",
@@ -369,7 +271,7 @@
 			wprintw(wnd, "%5.1f", atime / etime);
 		if (read_write)
 			wprintw(wnd, " %5.0f%4.0f",
-			    wwords / etime, cur_tape.wxfer[dn] / etime);
+			    wwords / etime, cur.wxfer[dn] / etime);
 		return (row);
 	}
 
@@ -381,7 +283,7 @@
 		wmove(wnd, row++, col);
 		histogram(wwords / etime, 50, 0.5);
 		wmove(wnd, row++, col);
-		histogram(cur_tape.wxfer[dn] / etime, 50, 0.5);
+		histogram(cur.wxfer[dn] / etime, 50, 0.5);
 	}
 
 	if (secs) {
Index: usr.bin/systat/vmstat.c
===================================================================
RCS file: /cvsroot/src/usr.bin/systat/vmstat.c,v
retrieving revision 1.61
diff -u -r1.61 vmstat.c
--- usr.bin/systat/vmstat.c	7 Aug 2005 12:32:38 -0000	1.61
+++ usr.bin/systat/vmstat.c	12 Nov 2005 13:11:09 -0000
@@ -55,8 +55,7 @@
 
 #include "systat.h"
 #include "extern.h"
-#include "dkstats.h"
-#include "tpstats.h"
+#include "drvstats.h"
 #include "utmpentry.h"
 
 static struct Info {
@@ -80,7 +79,6 @@
 static void copyinfo(struct Info *, struct Info *);
 static float cputime(int);
 static void dinfo(int, int, int);
-static void tinfo(int, int, int);
 static void getinfo(struct Info *, enum state);
 static void putint(int, int, int, int);
 static void putfloat(double, int, int, int, int, int);
@@ -221,9 +219,7 @@
 		}
 	}
 	hertz = stathz ? stathz : hz;
-	if (!dkinit(1))
-		return(0);
-	if (!tpinit(1))
+	if (!drvinit(1))
 		return(0);
 
 	/* Old style interrupt counts - deprecated */
@@ -426,8 +422,7 @@
 	}
 
 	if (state == TIME) {
-		dkswap();
-		tpswap();
+		drvswap();
 		etime = cur.cp_etime;
 		/* < 5 ticks - ignore this trash */
 		if ((etime * hertz) < 1.0) {
@@ -557,14 +552,9 @@
 	PUTRATE(uvmexp.softs, GENSTATROW + 1, GENSTATCOL + 22, 5);
 	PUTRATE(uvmexp.faults, GENSTATROW + 1, GENSTATCOL + 27, 6);
 	for (l = 0, i = 0, r = DISKROW, c = DISKCOL;
-	     i < (dk_ndrive + tp_ndrive); i++) {
-		if (i < dk_ndrive) {
-			if (!dk_select[i])
-				continue;
-		} else {
-			if (!tp_select[i - dk_ndrive])
-				continue;
-		}
+	     i < ndrive; i++) {
+		if (!drv_select[i])
+			continue;
 
 		if (disk_horiz)
 			c += DISKCOLWIDTH;
@@ -588,10 +578,7 @@
 		}
 		l++;
 
-		if (i < dk_ndrive)
-			dinfo(i, r, c);
-		else
-			tinfo(i - dk_ndrive, r, c);
+		dinfo(i, r, c);
 	}
 	/* blank out if we lost any disks */
 	for (i = l; i < last_disks; i++) {
@@ -749,8 +736,7 @@
 	size_t size;
 	int i;
 
-	dkreadstats();
-	tpreadstats();
+	drvreadstats();
 	NREAD(X_NCHSTATS, &stats->nchstats, sizeof stats->nchstats);
 	if (nintr)
 		NREAD(X_INTRCNT, stats->intrcnt, nintr * LONG);
@@ -810,17 +796,17 @@
 	mvprintw(r, c, "%*.*s", DISKCOLWIDTH, DISKCOLWIDTH, dr_name[dn]);
 	ADV;
 
-	putint((int)(cur.dk_seek[dn]/etime+0.5), r, c, DISKCOLWIDTH);
+	putint((int)(cur.seek[dn]/etime+0.5), r, c, DISKCOLWIDTH);
 	ADV;
-	putint((int)((cur.dk_rxfer[dn]+cur.dk_wxfer[dn])/etime+0.5),
+	putint((int)((cur.rxfer[dn]+cur.wxfer[dn])/etime+0.5),
 	    r, c, DISKCOLWIDTH);
 	ADV;
-	puthumanint((cur.dk_rbytes[dn] + cur.dk_wbytes[dn]) / etime + 0.5,
+	puthumanint((cur.rbytes[dn] + cur.wbytes[dn]) / etime + 0.5,
 		    r, c, DISKCOLWIDTH);
 	ADV;
 
 	/* time busy in disk activity */
-	atime = cur.dk_time[dn].tv_sec + cur.dk_time[dn].tv_usec / 1000000.0;
+	atime = cur.time[dn].tv_sec + cur.time[dn].tv_usec / 1000000.0;
 	atime = atime * 100.0 / etime;
 	if (atime >= 100)
 		putint(100, r, c, DISKCOLWIDTH);
@@ -828,30 +814,3 @@
 		putfloat(atime, r, c, DISKCOLWIDTH, 1, 1);
 }
 
-static void
-tinfo(int dn, int r, int c)
-{
-	double atime;
-
-	mvprintw(r, c, "%*.*s", DISKCOLWIDTH, DISKCOLWIDTH, tp_name[dn]);
-	ADV;
-	ADV; /* skip over the seeks column - not relevant for tape drives */
-
-	putint((int)((cur_tape.rxfer[dn]+cur_tape.wxfer[dn])/etime+0.5),
-	    r, c, DISKCOLWIDTH);
-	ADV;
-	puthumanint((cur_tape.rbytes[dn] + cur_tape.wbytes[dn]) / etime + 0.5,
-		    r, c, DISKCOLWIDTH);
-	ADV;
-
-	/* time busy in disk activity */
-	atime = cur_tape.time[dn].tv_sec + cur_tape.time[dn].tv_usec / 1000000.0;
-	atime = atime * 100.0 / etime;
-	if (atime >= 100)
-		putint(100, r, c, DISKCOLWIDTH);
-	else
-		putfloat(atime, r, c, DISKCOLWIDTH, 1, 1);
-#undef ADV
-}
-
-
Index: usr.bin/vmstat/Makefile
===================================================================
RCS file: /cvsroot/src/usr.bin/vmstat/Makefile,v
retrieving revision 1.22
diff -u -r1.22 Makefile
--- usr.bin/vmstat/Makefile	7 Aug 2005 12:23:20 -0000	1.22
+++ usr.bin/vmstat/Makefile	12 Nov 2005 13:11:09 -0000
@@ -4,7 +4,7 @@
 PROG=	vmstat
 WARNS=3
 
-SRCS=	dkstats.c tpstats.c vmstat.c
+SRCS=	drvstats.c vmstat.c
 MAN=	vmstat.1
 DPADD=	${LIBKVM}
 LDADD=	-lkvm
Index: usr.bin/vmstat/vmstat.c
===================================================================
RCS file: /cvsroot/src/usr.bin/vmstat/vmstat.c,v
retrieving revision 1.138
diff -u -r1.138 vmstat.c
--- usr.bin/vmstat/vmstat.c	22 Oct 2005 15:32:48 -0000	1.138
+++ usr.bin/vmstat/vmstat.c	12 Nov 2005 13:11:10 -0000
@@ -132,8 +132,7 @@
 #include <unistd.h>
 #include <util.h>
 
-#include "dkstats.h"
-#include "tpstats.h"
+#include "drvstats.h"
 
 /*
  * General namelist
@@ -252,8 +251,7 @@
 
 void	cpustats(void);
 void	deref_kptr(const void *, void *, size_t, const char *);
-void	dkstats(void);
-void	tpstats(void);
+void	drvstats(void);
 void	doevcnt(int verbose);
 void	dohashstat(int, int, const char *);
 void	dointr(int verbose);
@@ -405,8 +403,7 @@
 	if (todo & VMSTAT) {
 		struct winsize winsize;
 
-		dkinit(0);	/* Initialize disk stats, no disks selected. */
-		tpinit(0);
+		drvinit(0);	/* Initialize disk stats, no disks selected. */
 
 		(void)setgid(getgid()); /* don't need privs anymore */
 
@@ -511,32 +508,18 @@
 		if (isdigit((unsigned char)**argv))
 			break;
 #endif
-		for (i = 0; i < dk_ndrive; i++) {
+		for (i = 0; i < ndrive; i++) {
 			if (strcmp(dr_name[i], *argv))
 				continue;
-			dk_select[i] = 1;
+			drv_select[i] = 1;
 			++ndrives;
 			break;
 		}
-		for (i = 0; i < tp_ndrive; i++) {
-			if (strcmp(tp_name[i], *argv))
-				continue;
-			tp_select[i] = 1;
-			++ndrives;
-			break;
-		}
-	}
-	for (i = 0; i < dk_ndrive && ndrives < 3; i++) {
-		if (dk_select[i])
-			continue;
-		dk_select[i] = 1;
-		++ndrives;
 	}
-	
-	for (i = 0; i < tp_ndrive && ndrives < 3; i++) {
-		if (tp_select[i])
+	for (i = 0; i < ndrive && ndrives < 3; i++) {
+		if (drv_select[i])
 			continue;
-		tp_select[i] = 1;
+		drv_select[i] = 1;
 		++ndrives;
 	}
 	
@@ -645,7 +628,7 @@
 		if (!--hdrcnt)
 			printhdr();
 		/* Read new disk statistics */
-		dkreadstats();
+		drvreadstats();
 		kread(namelist, X_UVMEXP, &uvmexp, sizeof(uvmexp));
 		if (memf != NULL) {
 			/*
@@ -677,8 +660,7 @@
 		    rate(uvmexp.pgswapout - ouvmexp.pgswapout));
 		(void)printf("%4lu ", rate(uvmexp.pdfreed - ouvmexp.pdfreed));
 		(void)printf("%4lu ", rate(uvmexp.pdscans - ouvmexp.pdscans));
-		dkstats();
-		tpstats();
+		drvstats();
 		(void)printf("%4lu %4lu %3lu ",
 		    rate(uvmexp.intrs - ouvmexp.intrs),
 		    rate(uvmexp.syscalls - ouvmexp.syscalls),
@@ -714,8 +696,8 @@
 		    ndrives * 3, "");
 
 	(void)printf(" r b w    avm    fre  flt  re  pi   po   fr   sr ");
-	for (i = 0; i < dk_ndrive; i++)
-		if (dk_select[i])
+	for (i = 0; i < ndrive; i++)
+		if (drv_select[i])
 			(void)printf("%c%c ", dr_name[i][0],
 			    dr_name[i][strlen(dr_name[i]) - 1]);
 	(void)printf("  in   sy  cs us sy id\n");
@@ -882,38 +864,20 @@
 }
 
 void
-dkstats(void)
+drvstats(void)
 {
 	int dn;
 	double etime;
 
 	/* Calculate disk stat deltas. */
-	dkswap();
-	etime = cur.cp_etime;
-
-	for (dn = 0; dn < dk_ndrive; ++dn) {
-		if (!dk_select[dn])
-			continue;
-		(void)printf("%2.0f ",
-		    (cur.dk_rxfer[dn] + cur.dk_wxfer[dn]) / etime);
-	}
-}
-
-void
-tpstats(void)
-{
-	int dn;
-	double etime;
-
-	/* Calculate tape stat deltas. */
-	tpswap();
+	drvswap();
 	etime = cur.cp_etime;
 
-	for (dn = 0; dn < tp_ndrive; ++dn) {
-		if (!tp_select[dn])
+	for (dn = 0; dn < ndrive; ++dn) {
+		if (!drv_select[dn])
 			continue;
 		(void)printf("%2.0f ",
-		    (cur_tape.rxfer[dn] + cur_tape.wxfer[dn]) / etime);
+		    (cur.rxfer[dn] + cur.wxfer[dn]) / etime);
 	}
 }
 
Index: usr.sbin/iostat/Makefile
===================================================================
RCS file: /cvsroot/src/usr.sbin/iostat/Makefile,v
retrieving revision 1.21
diff -u -r1.21 Makefile
--- usr.sbin/iostat/Makefile	7 Aug 2005 12:34:21 -0000	1.21
+++ usr.sbin/iostat/Makefile	12 Nov 2005 13:11:10 -0000
@@ -11,7 +11,7 @@
 CPPFLAGS+=-I${NETBSDSRCDIR}/usr.bin/vmstat
 
 # dkstats.c pulled in from ../../usr.bin/vmstat
-SRCS=	dkstats.c tpstats.c iostat.c
+SRCS=	drvstats.c iostat.c
 
 DPADD=	${LIBKVM}
 LDADD=	-lkvm
Index: usr.sbin/iostat/iostat.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/iostat/iostat.c,v
retrieving revision 1.45
diff -u -r1.45 iostat.c
--- usr.sbin/iostat/iostat.c	7 Aug 2005 12:34:21 -0000	1.45
+++ usr.sbin/iostat/iostat.c	12 Nov 2005 13:11:10 -0000
@@ -88,8 +88,7 @@
 #include <string.h>
 #include <unistd.h>
 
-#include "dkstats.h"
-#include "tpstats.h"
+#include "drvstats.h"
 
 /* Namelist and memory files. */
 char	*nlistf, *memf;
@@ -110,9 +109,9 @@
 #define	SHOW_STATS_ALL	(SHOW_STATS_1 | SHOW_STATS_2 | SHOW_STATS_X)
 
 static void cpustats(void);
-static void disk_stats(double);
-static void disk_stats2(double);
-static void disk_statsx(double);
+static void drive_stats(double);
+static void drive_stats2(double);
+static void drive_statsx(double);
 static void sig_header(int);
 static volatile int do_header;
 static void header(void);
@@ -194,13 +193,11 @@
 		defdrives -= 9;		/* XXX magic number */
 	defdrives /= 18;		/* XXX magic number */
 
-	dkinit(0);
-	tpinit(0);
-	dkreadstats();
-	tpreadstats();
+	drvinit(0);
+	drvreadstats();
 	ndrives = selectdrives(argc, argv);
 	if (ndrives == 0) {
-		/* No drives are selected.  No need to show disk stats. */
+		/* No drives are selected.  No need to show drive stats. */
 		todo &= ~SHOW_STATS_ALL;
 		if (todo == 0)
 			errx(1, "no drives");
@@ -227,8 +224,7 @@
 		}
 
 		if (!ISSET(todo, SHOW_TOTALS)) {
-			dkswap();
-			tpswap();
+			drvswap();
 		}
 		
 		display();
@@ -236,8 +232,7 @@
 		if (reps >= 0 && --reps <= 0)
 			break;
 		nanosleep(&tv, NULL);
-		dkreadstats();
-		tpreadstats();
+		drvreadstats();
 	}
 	exit(0);
 }
@@ -271,23 +266,15 @@
 		(void)printf("      tty");
 
 	if (ISSET(todo, SHOW_STATS_1)) {
-		for (i = 0; i < dk_ndrive; i++)
-			if (cur.dk_select[i])
-				(void)printf("        %9.9s ", cur.dk_name[i]);
-		for (i = 0; i < tp_ndrive; i++)
-			if (cur_tape.select[i])
-				(void)printf("        %9.9s ",
-					     cur_tape.name[i]);
+		for (i = 0; i < ndrive; i++)
+			if (cur.select[i])
+				(void)printf("        %9.9s ", cur.name[i]);
 	}
 
 	if (ISSET(todo, SHOW_STATS_2)) {
-		for (i = 0; i < dk_ndrive; i++)
-			if (cur.dk_select[i])
-				(void)printf("        %9.9s ", cur.dk_name[i]);
-		for (i = 0; i < tp_ndrive; i++)
-			if (cur_tape.select[i])
-				(void)printf("        %9.9s ",
-					     cur_tape.name[i]);
+		for (i = 0; i < ndrive; i++)
+			if (cur.select[i])
+				(void)printf("        %9.9s ", cur.name[i]);
 	}
 	
 	if (ISSET(todo, SHOW_CPU))
@@ -300,15 +287,8 @@
 		printf(" tin tout");
 
 	if (ISSET(todo, SHOW_STATS_1)) {
-		for (i = 0; i < dk_ndrive; i++)
-			if (cur.dk_select[i]) {
-				if (ISSET(todo, SHOW_TOTALS))
-					(void)printf("  KB/t  xfr  MB   ");
-				else
-					(void)printf("  KB/t  t/s  MB/s ");
-			}
-		for (i = 0; i < tp_ndrive; i++)
-			if (cur_tape.select[i]) {
+		for (i = 0; i < ndrive; i++)
+			if (cur.select[i]) {
 				if (ISSET(todo, SHOW_TOTALS))
 					(void)printf("  KB/t  xfr  MB   ");
 				else
@@ -317,11 +297,8 @@
 	}
 
 	if (ISSET(todo, SHOW_STATS_2)) {
-		for (i = 0; i < dk_ndrive; i++)
-			if (cur.dk_select[i])
-				(void)printf("    KB   xfr time ");
-		for (i = 0; i < tp_ndrive; i++)
-			if (cur_tape.select[i])
+		for (i = 0; i < ndrive; i++)
+			if (cur.select[i])
 				(void)printf("    KB   xfr time ");
 	}
 
@@ -331,150 +308,33 @@
 }
 
 static void
-disk_stats(double etime)
-{
-	int dn;
-	double atime, mbps;
-
-	for (dn = 0; dn < dk_ndrive; ++dn) {
-		if (!cur.dk_select[dn])
-			continue;
-					/* average Kbytes per transfer. */
-		if (cur.dk_rxfer[dn] + cur.dk_wxfer[dn])
-			mbps = ((cur.dk_rbytes[dn] + cur.dk_wbytes[dn]) /
-			    1024.0) / (cur.dk_rxfer[dn] + cur.dk_wxfer[dn]);
-		else
-			mbps = 0.0;
-		(void)printf(" %5.2f", mbps);
-
-					/* average transfers per second. */
-		(void)printf(" %4.0f",
-		    (cur.dk_rxfer[dn] + cur.dk_wxfer[dn]) / etime);
-
-					/* time busy in disk activity */
-		atime = (double)cur.dk_time[dn].tv_sec +
-		    ((double)cur.dk_time[dn].tv_usec / (double)1000000);
-
-					/* Megabytes per second. */
-		if (atime != 0.0)
-			mbps = (cur.dk_rbytes[dn] + cur.dk_wbytes[dn]) /
-			    (double)(1024 * 1024);
-		else
-			mbps = 0;
-		(void)printf(" %5.2f ", mbps / etime);
-	}
-}
-
-static void
-disk_stats2(double etime)
-{
-	int dn;
-	double atime;
-
-	for (dn = 0; dn < dk_ndrive; ++dn) {
-		if (!cur.dk_select[dn])
-			continue;
-
-					/* average kbytes per second. */
-		(void)printf(" %5.0f",
-		    (cur.dk_rbytes[dn] + cur.dk_wbytes[dn]) / 1024.0 / etime);
-
-					/* average transfers per second. */
-		(void)printf(" %5.0f",
-		    (cur.dk_rxfer[dn] + cur.dk_wxfer[dn]) / etime);
-
-					/* average time busy in disk activity */
-		atime = (double)cur.dk_time[dn].tv_sec +
-		    ((double)cur.dk_time[dn].tv_usec / (double)1000000);
-		(void)printf(" %4.2f ", atime / etime);
-	}
-}
-
-static void
-disk_statsx(double etime)
-{
-	int dn;
-	double atime, kbps;
-
-	for (dn = 0; dn < dk_ndrive; ++dn) {
-		if (!cur.dk_select[dn])
-			continue;
-
-		(void)printf("%-8.8s", cur.dk_name[dn]);
-
-					/* average read Kbytes per transfer */
-		if (cur.dk_rxfer[dn])
-			kbps = (cur.dk_rbytes[dn] / 1024.0) / cur.dk_rxfer[dn];
-		else
-			kbps = 0.0;
-		(void)printf(" %8.2f", kbps);
-
-					/* average read transfers
-					   (per second) */
-		(void)printf(" %6.0f", cur.dk_rxfer[dn] / etime);
-
-					/* time read busy in disk activity */
-		atime = (double)cur.dk_time[dn].tv_sec +
-		    ((double)cur.dk_time[dn].tv_usec / (double)1000000);
-		(void)printf(" %6.2f", atime / etime);
-
-					/* average read megabytes
-					   (per second) */
-		(void)printf(" %8.2f",
-		    cur.dk_rbytes[dn] / (1024.0 * 1024) / etime);
-
-
-					/* average write Kbytes per transfer */
-		if (cur.dk_wxfer[dn])
-			kbps = (cur.dk_wbytes[dn] / 1024.0) / cur.dk_wxfer[dn];
-		else
-			kbps = 0.0;
-		(void)printf("   %8.2f", kbps);
-
-					/* average write transfers
-					   (per second) */
-		(void)printf(" %6.0f", cur.dk_wxfer[dn] / etime);
-
-					/* time write busy in disk activity */
-		atime = (double)cur.dk_time[dn].tv_sec +
-		    ((double)cur.dk_time[dn].tv_usec / (double)1000000);
-		(void)printf(" %6.2f", atime / etime);
-
-					/* average write megabytes
-					   (per second) */
-		(void)printf(" %8.2f\n",
-		    cur.dk_wbytes[dn] / (1024.0 * 1024) / etime);
-	}
-}
-
-static void
-tape_stats(double etime)
+drive_stats(double etime)
 {
 	int dn;
 	double atime, mbps;
 
-	for (dn = 0; dn < tp_ndrive; ++dn) {
-		if (!cur_tape.select[dn])
+	for (dn = 0; dn < ndrive; ++dn) {
+		if (!cur.select[dn])
 			continue;
 					/* average Kbytes per transfer. */
-		if (cur_tape.rxfer[dn] + cur_tape.wxfer[dn])
-			mbps = ((cur_tape.rbytes[dn] + cur_tape.wbytes[dn]) /
-			    1024.0) / (cur_tape.rxfer[dn] + cur_tape.wxfer[dn]);
+		if (cur.rxfer[dn] + cur.wxfer[dn])
+			mbps = ((cur.rbytes[dn] + cur.wbytes[dn]) /
+			    1024.0) / (cur.rxfer[dn] + cur.wxfer[dn]);
 		else
 			mbps = 0.0;
 		(void)printf(" %5.2f", mbps);
 
 					/* average transfers per second. */
 		(void)printf(" %4.0f",
-		    (cur_tape.rxfer[dn] + cur_tape.wxfer[dn]) / etime);
+		    (cur.rxfer[dn] + cur.wxfer[dn]) / etime);
 
-					/* time busy in disk activity */
-		atime = (double)cur_tape.time[dn].tv_sec +
-		    ((double)cur_tape.time[dn].tv_usec / (double)1000000);
+					/* time busy in drive activity */
+		atime = (double)cur.time[dn].tv_sec +
+		    ((double)cur.time[dn].tv_usec / (double)1000000);
 
 					/* Megabytes per second. */
 		if (atime != 0.0)
-			mbps = (cur_tape.rbytes[dn] + cur_tape.wbytes[dn]) /
+			mbps = (cur.rbytes[dn] + cur.wbytes[dn]) /
 			    (double)(1024 * 1024);
 		else
 			mbps = 0;
@@ -483,84 +343,84 @@
 }
 
 static void
-tape_stats2(double etime)
+drive_stats2(double etime)
 {
 	int dn;
 	double atime;
 
-	for (dn = 0; dn < tp_ndrive; ++dn) {
-		if (!cur_tape.select[dn])
+	for (dn = 0; dn < ndrive; ++dn) {
+		if (!cur.select[dn])
 			continue;
 
 					/* average kbytes per second. */
 		(void)printf(" %5.0f",
-		    (cur_tape.rbytes[dn] + cur_tape.wbytes[dn]) / 1024.0 / etime);
+		    (cur.rbytes[dn] + cur.wbytes[dn]) / 1024.0 / etime);
 
 					/* average transfers per second. */
 		(void)printf(" %5.0f",
-		    (cur_tape.rxfer[dn] + cur_tape.wxfer[dn]) / etime);
+		    (cur.rxfer[dn] + cur.wxfer[dn]) / etime);
 
-					/* average time busy in disk activity */
-		atime = (double)cur_tape.time[dn].tv_sec +
-		    ((double)cur_tape.time[dn].tv_usec / (double)1000000);
+					/* average time busy in drive activity */
+		atime = (double)cur.time[dn].tv_sec +
+		    ((double)cur.time[dn].tv_usec / (double)1000000);
 		(void)printf(" %4.2f ", atime / etime);
 	}
 }
 
 static void
-tape_statsx(double etime)
+drive_statsx(double etime)
 {
 	int dn;
 	double atime, kbps;
 
-	for (dn = 0; dn < tp_ndrive; ++dn) {
-		if (!cur_tape.select[dn])
+	for (dn = 0; dn < ndrive; ++dn) {
+		if (!cur.select[dn])
 			continue;
 
-		(void)printf("%-8.8s", cur_tape.name[dn]);
+		(void)printf("%-8.8s", cur.name[dn]);
 
 					/* average read Kbytes per transfer */
-		if (cur.dk_rxfer[dn])
-			kbps = (cur_tape.rbytes[dn] / 1024.0) / cur_tape.rxfer[dn];
+		if (cur.rxfer[dn])
+			kbps = (cur.rbytes[dn] / 1024.0) / cur.rxfer[dn];
 		else
 			kbps = 0.0;
 		(void)printf(" %8.2f", kbps);
 
 					/* average read transfers
 					   (per second) */
-		(void)printf(" %6.0f", cur_tape.rxfer[dn] / etime);
+		(void)printf(" %6.0f", cur.rxfer[dn] / etime);
 
-					/* time read busy in disk activity */
-		atime = (double)cur_tape.time[dn].tv_sec +
-		    ((double)cur_tape.time[dn].tv_usec / (double)1000000);
+					/* time read busy in drive activity */
+		atime = (double)cur.time[dn].tv_sec +
+		    ((double)cur.time[dn].tv_usec / (double)1000000);
 		(void)printf(" %6.2f", atime / etime);
 
 					/* average read megabytes
 					   (per second) */
 		(void)printf(" %8.2f",
-		    cur_tape.rbytes[dn] / (1024.0 * 1024) / etime);
+		    cur.rbytes[dn] / (1024.0 * 1024) / etime);
 
 
 					/* average write Kbytes per transfer */
-		if (cur_tape.wxfer[dn])
-			kbps = (cur_tape.wbytes[dn] / 1024.0) / cur_tape.wxfer[dn];
+		if (cur.wxfer[dn])
+			kbps = (cur.wbytes[dn] / 1024.0) / cur.wxfer[dn];
 		else
 			kbps = 0.0;
 		(void)printf("   %8.2f", kbps);
 
 					/* average write transfers
 					   (per second) */
-		(void)printf(" %6.0f", cur_tape.wxfer[dn] / etime);
+		(void)printf(" %6.0f", cur.wxfer[dn] / etime);
 
-					/* time write busy in disk activity */
-		atime = (double)cur_tape.time[dn].tv_sec +
-		    ((double)cur_tape.time[dn].tv_usec / (double)1000000);
+					/* time write busy in drive activity */
+		atime = (double)cur.time[dn].tv_sec +
+		    ((double)cur.time[dn].tv_usec / (double)1000000);
 		(void)printf(" %6.2f", atime / etime);
 
 					/* average write megabytes
 					   (per second) */
 		(void)printf(" %8.2f\n",
-		    cur_tape.wbytes[dn] / (1024.0 * 1024) / etime);
+		    cur.wbytes[dn] / (1024.0 * 1024) / etime);
 	}
 }
 
@@ -605,8 +465,7 @@
 		etime = 1.0;
 
 	if (ISSET(todo, SHOW_STATS_X)) {
-		disk_statsx(etime);
-		tape_statsx(etime);
+		drive_statsx(etime);
 		goto out;
 	}
 
@@ -614,14 +473,12 @@
 		printf("%4.0f %4.0f", cur.tk_nin / etime, cur.tk_nout / etime);
 
 	if (ISSET(todo, SHOW_STATS_1)) {
-		disk_stats(etime);
-		tape_stats(etime);
+		drive_stats(etime);
 	}
 	
 
 	if (ISSET(todo, SHOW_STATS_2)) {
-		disk_stats2(etime);
-		tape_stats2(etime);
+		drive_stats2(etime);
 	}
 	
 
@@ -656,19 +513,13 @@
 			break;
 #endif
 		tried++;
-		for (i = 0; i < dk_ndrive; i++) {
-			if (strcmp(cur.dk_name[i], *argv))
+		for (i = 0; i < ndrive; i++) {
+			if (strcmp(cur.name[i], *argv))
 				continue;
-			cur.dk_select[i] = 1;
+			cur.select[i] = 1;
 			++ndrives;
 		}
 		
-		for (i = 0; i < tp_ndrive; i++) {
-			if (strcmp(cur_tape.name[i], *argv))
-				continue;
-			cur_tape.select[i] = 1;
-			++ndrives;
-		}
 	}
 
 	if (ndrives == 0 && tried == 0) {
@@ -677,14 +528,10 @@
 		 * if none specified.
 		 */
 		maxdrives = (ISSET(todo, SHOW_STATS_X) ||
-			     (dk_ndrive + tp_ndrive) < defdrives)
-			? (dk_ndrive + tp_ndrive) : defdrives;
+			     ndrive < defdrives)
+			? (ndrive) : defdrives;
 		for (i = 0; i < maxdrives; i++) {
-			if (i >= dk_ndrive) {
-				cur_tape.select[i - dk_ndrive] = 1;
-			} else {
-				cur.dk_select[i] = 1;
-			}
+			cur.select[i] = 1;
 			
 			++ndrives;
 			if (!ISSET(todo, SHOW_STATS_X) && ndrives == defdrives)

--X1bOJ3K7DJ5YkBrT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="subr_drive.c"

/*	$NetBSD$	*/
/*	NetBSD: subr_disk.c,v 1.69 2005/05/29 22:24:15 christos Exp	*/

/*-
 * Copyright (c) 1996, 1997, 1999, 2000 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
 * NASA Ames Research Center.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the NetBSD
 *	Foundation, Inc. and its contributors.
 * 4. Neither the name of The NetBSD Foundation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

/*
 * Copyright (c) 1982, 1986, 1988, 1993
 *	The Regents of the University of California.  All rights reserved.
 * (c) UNIX System Laboratories, Inc.
 * All or some portions of this file are derived from material licensed
 * to the University of California by American Telephone and Telegraph
 * Co. or Unix System Laboratories, Inc. and are reproduced herein with
 * the permission of UNIX System Laboratories, Inc.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. Neither the name of the University nor the names of its contributors
 *    may be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 *	@(#)ufs_disksubr.c	8.5 (Berkeley) 1/21/94
 */

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: subr_disk.c,v 1.69 2005/05/29 22:24:15 christos Exp $");

#include "opt_compat_netbsd.h"

#include <sys/param.h>
#include <sys/kernel.h>
#include <sys/malloc.h>
#include <sys/buf.h>
#include <sys/bufq.h>
#include <sys/syslog.h>
#include <sys/disklabel.h>
#include <sys/drive.h>
#include <sys/sysctl.h>
#include <lib/libkern/libkern.h>

/*
 * Function prototypes for sysctl nodes
 */
int	sysctl_hw_drivenames(SYSCTLFN_PROTO);
int	sysctl_hw_drivestats(SYSCTLFN_PROTO);

/*
 * A global list of all drives attached to the system.  May grow or
 * shrink over time.
 */
struct	drivelist_head drivelist = TAILQ_HEAD_INITIALIZER(drivelist);
int	drive_count;		/* number of drives in global drivelist */
struct simplelock drivelist_slock = SIMPLELOCK_INITIALIZER;

/*
 * Compute checksum for disk label.
 */
u_int
dkcksum(struct disklabel *lp)
{
	u_short *start, *end;
	u_short sum = 0;

	start = (u_short *)lp;
	end = (u_short *)&lp->d_partitions[lp->d_npartitions];
	while (start < end)
		sum ^= *start++;
	return (sum);
}

/*
 * Disk error is the preface to plaintive error messages
 * about failing disk transfers.  It prints messages of the form

hp0g: hard error reading fsbn 12345 of 12344-12347 (hp0 bn %d cn %d tn %d sn %d)

 * if the offset of the error in the transfer and a disk label
 * are both available.  blkdone should be -1 if the position of the error
 * is unknown; the disklabel pointer may be null from drivers that have not
 * been converted to use them.  The message is printed with printf
 * if pri is LOG_PRINTF, otherwise it uses log at the specified priority.
 * The message should be completed (with at least a newline) with printf
 * or addlog, respectively.  There is no trailing space.
 */
#ifndef PRIdaddr
#define PRIdaddr PRId64
#endif
void
diskerr(const struct buf *bp, const char *dname, const char *what, int pri,
    int blkdone, const struct disklabel *lp)
{
	int unit = DISKUNIT(bp->b_dev), part = DISKPART(bp->b_dev);
	void (*pr)(const char *, ...);
	char partname = 'a' + part;
	daddr_t sn;

	if (/*CONSTCOND*/0)
		/* Compiler will error this is the format is wrong... */
		printf("%" PRIdaddr, bp->b_blkno);

	if (pri != LOG_PRINTF) {
		static const char fmt[] = "";
		log(pri, fmt);
		pr = addlog;
	} else
		pr = printf;
	(*pr)("%s%d%c: %s %sing fsbn ", dname, unit, partname, what,
	    bp->b_flags & B_READ ? "read" : "writ");
	sn = bp->b_blkno;
	if (bp->b_bcount <= DEV_BSIZE)
		(*pr)("%" PRIdaddr, sn);
	else {
		if (blkdone >= 0) {
			sn += blkdone;
			(*pr)("%" PRIdaddr " of ", sn);
		}
		(*pr)("%" PRIdaddr "-%" PRIdaddr "", bp->b_blkno,
		    bp->b_blkno + (bp->b_bcount - 1) / DEV_BSIZE);
	}
	if (lp && (blkdone >= 0 || bp->b_bcount <= lp->d_secsize)) {
		sn += lp->d_partitions[part].p_offset;
		(*pr)(" (%s%d bn %" PRIdaddr "; cn %" PRIdaddr "",
		    dname, unit, sn, sn / lp->d_secpercyl);
		sn %= lp->d_secpercyl;
		(*pr)(" tn %" PRIdaddr " sn %" PRIdaddr ")",
		    sn / lp->d_nsectors, sn % lp->d_nsectors);
	}
}

/*
 * Searches the drivelist for the drive corresponding to the
 * name provided.
 */
struct drive_stats *
drive_find(char *name)
{
	struct drive_stats *drivep;

	if ((name == NULL) || (drive_count <= 0))
		return (NULL);

	simple_lock(&drivelist_slock);
	for (drivep = TAILQ_FIRST(&drivelist); drivep != NULL;
	    drivep = TAILQ_NEXT(drivep, link))
		if (strcmp(drivep->name, name) == 0) {
			simple_unlock(&drivelist_slock);
			return (drivep);
		}
	simple_unlock(&drivelist_slock);

	return (NULL);
}

static void
disk_init0(struct disk *diskp)
{

	/*
	 * Initialize the wedge-related locks and other fields.
	 */
	lockinit(&diskp->dk_rawlock, PRIBIO, "dkrawlk", 0, 0);
	lockinit(&diskp->dk_openlock, PRIBIO, "dkoplk", 0, 0);
	LIST_INIT(&diskp->dk_wedges);
	diskp->dk_nwedges = 0;
}

static void
disk_attach0(struct disk *diskp)
{

	/*
	 * Allocate and initialize the disklabel structures.  Note that
	 * it's not safe to sleep here, since we're probably going to be
	 * called during autoconfiguration.
	 */
	diskp->dk_label = malloc(sizeof(struct disklabel), M_DEVBUF, M_NOWAIT);
	diskp->dk_cpulabel = malloc(sizeof(struct cpu_disklabel), M_DEVBUF,
	    M_NOWAIT);
	if ((diskp->dk_label == NULL) || (diskp->dk_cpulabel == NULL))
		panic("disk_attach: can't allocate storage for disklabel");

	memset(diskp->dk_label, 0, sizeof(struct disklabel));
	memset(diskp->dk_cpulabel, 0, sizeof(struct cpu_disklabel));

	/*
	 * Set up the stats collection.
	 */
	diskp->stats = drive_stats_alloc(DRV_DISK);
	diskp->stats->parent = (void *) diskp;
	diskp->stats->name = diskp->dk_name;
}

static void
disk_detach0(struct disk *diskp)
{

	/*
	 * Remove from the drivelist.
	 */
	drive_stats_free(diskp->stats);
	
	/*
	 * Free the space used by the disklabel structures.
	 */
	free(diskp->dk_label, M_DEVBUF);
	free(diskp->dk_cpulabel, M_DEVBUF);
}

/*
 * Attach a disk.
 */
void
disk_attach(struct disk *drivep)
{

	disk_init0(drivep);
	disk_attach0(drivep);
}

/*
 * Allocate and initialise memory for the drive statistics.
 */
struct
drive_stats *drive_stats_alloc(int32_t type)
{
	int s;
	struct drive_stats *stats;

	stats = malloc(sizeof(struct drive_stats), M_DEVBUF, M_NOWAIT);

	if (stats == NULL)
		panic("drive_stats_alloc: cannot allocate memory for stats "
		      "buffer");

	stats->type = type;
	stats->rxfer = 0;
	stats->rbytes = 0;
	stats->wxfer = 0;
	stats->wbytes = 0;

	/*
	 * Set the attached timestamp.
	 */
	s = splclock();
	stats->attachtime = mono_time;
	splx(s);

	timerclear(&stats->time);
	timerclear(&stats->timestamp);
	
	/*
	 * Link into the drivelist.
	 */
	simple_lock(&drivelist_slock);
	TAILQ_INSERT_TAIL(&drivelist, stats, link);
	drive_count++;
	simple_unlock(&drivelist_slock);

	return stats;
}

/*
 * Remove drive from stats collection.
 */
void
drive_stats_free(struct drive_stats *stats)
{

	  /*
	   * Remove from the drivelist.
	   */
	if (drive_count == 0)
		panic("drive_detach: drive_count == 0");
	simple_lock(&drivelist_slock);
	TAILQ_REMOVE(&drivelist, stats, link);
	drive_count--;
	simple_unlock(&drivelist_slock);
	free(stats, M_DEVBUF);
}

/*
 * Detach a drive.
 */
void
disk_detach(struct disk *drivep)
{

	(void) lockmgr(&drivep->dk_openlock, LK_DRAIN, NULL);
	disk_detach0(drivep);

}

/*
 * Initialize a pseudo disk.
 */
void
pseudo_disk_init(struct disk *diskp)
{

	disk_init0(diskp);
}

/*
 * Attach a pseudo disk.
 */
void
pseudo_disk_attach(struct disk *diskp)
{

	disk_attach0(diskp);
}

/*
 * Detach a pseudo disk.
 */
void
pseudo_disk_detach(struct disk *diskp)
{

	disk_detach0(diskp);
}


/*
 * Increment a drive's busy counter.  If the counter is going from
 * 0 to 1, set the timestamp.
 */
void
drive_busy(struct drive_stats *stats)
{
	int s;

	/*
	 * XXX We'd like to use something as accurate as microtime(),
	 * but that doesn't depend on the system TOD clock.
	 */
	if (stats->busy++ == 0) {
		s = splclock();
		stats->timestamp = mono_time;
		splx(s);
	}
}

/*
 * Decrement a drive's busy counter, increment the byte count, total busy
 * time, and reset the timestamp.
 */
void
drive_unbusy(struct drive_stats *stats, long bcount, int read)
{
	int s;
	struct timeval dv_time, diff_time;

	if (stats->busy-- == 0) {
		printf("%s: busy < 0\n", stats->name);
		panic("drive_unbusy");
	}

	s = splclock();
	dv_time = mono_time;
	splx(s);

	timersub(&dv_time, &stats->timestamp, &diff_time);
	timeradd(&stats->time, &diff_time, &stats->time);

	stats->timestamp = dv_time;
	if (bcount > 0) {
		if (read) {
			stats->rbytes += bcount;
			stats->rxfer++;
		} else {
			stats->wbytes += bcount;
			stats->wxfer++;
		}
	}
}

/*
 * Reset the metrics counters on the given drive.  Note that we cannot
 * reset the busy counter, as it may case a panic in drive_unbusy().
 * We also must avoid playing with the timestamp information, as it
 * may skew any pending transfer results.
 */
void
drive_resetstat(struct drive_stats *stats)
{
	int s = splbio(), t;

	stats->rxfer = 0;
	stats->rbytes = 0;
	stats->wxfer = 0;
	stats->wbytes = 0;

	t = splclock();
	stats->attachtime = mono_time;
	splx(t);

	timerclear(&stats->time);

	splx(s);
}

int
sysctl_hw_drivenames(SYSCTLFN_ARGS)
{
	char bf[DRIVENAMELEN + 1];
	char *where = oldp;
	struct drive_stats *stats;
	size_t needed, left, slen;
	int error, first;

	if (newp != NULL)
		return (EPERM);
	if (namelen != 0)
		return (EINVAL);

	first = 1;
	error = 0;
	needed = 0;
	left = *oldlenp;

	simple_lock(&drivelist_slock);
	for (stats = TAILQ_FIRST(&drivelist); stats != NULL;
	    stats = TAILQ_NEXT(stats, link)) {
		if (where == NULL)
			needed += strlen(stats->name) + 1;
		else {
			memset(bf, 0, sizeof(bf));
			if (first) {
				strncpy(bf, stats->name, sizeof(bf));
				first = 0;
			} else {
				bf[0] = ' ';
				strncpy(bf + 1, stats->name,
				    sizeof(bf) - 1);
			}
			bf[DRIVENAMELEN] = '\0';
			slen = strlen(bf);
			if (left < slen + 1)
				break;
			/* +1 to copy out the trailing NUL byte */
			error = copyout(bf, where, slen + 1);
			if (error)
				break;
			where += slen;
			needed += slen;
			left -= slen;
		}
	}
	simple_unlock(&drivelist_slock);
	*oldlenp = needed;
	return (error);
}

int
sysctl_hw_drivestats(SYSCTLFN_ARGS)
{
	struct drive_sysctl sdrive;
	struct drive_stats *stats;
	char *where = oldp;
	size_t tocopy, left;
	int error;

	if (newp != NULL)
		return (EPERM);

	/*
	 * The original hw.diskstats call was broken and did not require
	 * the userland to pass in it's size of struct disk_sysctl.  This
	 * was fixed after NetBSD 1.6 was released, and any applications
	 * that do not pass in the size are given an error only, unless
	 * we care about 1.6 compatibility.
	 */
	if (namelen == 0)
#ifdef COMPAT_16
		tocopy = offsetof(struct drive_sysctl, busy);
#else
		return (EINVAL);
#endif
	else
		tocopy = name[0];

	if (where == NULL) {
		*oldlenp = drive_count * tocopy;
		return (0);
	}

	error = 0;
	left = *oldlenp;
	memset(&sdrive, 0, sizeof(sdrive));
	*oldlenp = 0;

	simple_lock(&drivelist_slock);
	TAILQ_FOREACH(stats, &drivelist, link) {
		if (left < tocopy)
			break;
		strncpy(sdrive.name, stats->name, sizeof(sdrive.name));
		sdrive.xfer = stats->rxfer + stats->wxfer;
		sdrive.rxfer = stats->rxfer;
		sdrive.wxfer = stats->wxfer;
		sdrive.seek = stats->seek;
		sdrive.bytes = stats->rbytes + stats->wbytes;
		sdrive.rbytes = stats->rbytes;
		sdrive.wbytes = stats->wbytes;
		sdrive.attachtime_sec = stats->attachtime.tv_sec;
		sdrive.attachtime_usec = stats->attachtime.tv_usec;
		sdrive.timestamp_sec = stats->timestamp.tv_sec;
		sdrive.timestamp_usec = stats->timestamp.tv_usec;
		sdrive.time_sec = stats->time.tv_sec;
		sdrive.time_usec = stats->time.tv_usec;
		sdrive.busy = stats->busy;

		error = copyout(&sdrive, where, min(tocopy, sizeof(sdrive)));
		if (error)
			break;
		where += tocopy;
		*oldlenp += tocopy;
		left -= tocopy;
	}
	simple_unlock(&drivelist_slock);
	return (error);
}

/*
 * Bounds checking against the media size, used for the raw partition.
 * The sector size passed in should currently always be DEV_BSIZE,
 * and the media size the size of the device in DEV_BSIZE sectors.
 */
int
bounds_check_with_mediasize(struct buf *bp, int secsize, u_int64_t mediasize)
{
	int64_t sz;

	sz = howmany(bp->b_bcount, secsize);

	if (bp->b_blkno + sz > mediasize) {
		sz = mediasize - bp->b_blkno;
		if (sz == 0) {
			/* If exactly at end of disk, return EOF. */
			bp->b_resid = bp->b_bcount;
			goto done;
		}
		if (sz < 0) {
			/* If past end of disk, return EINVAL. */
			bp->b_error = EINVAL;
			goto bad;
		}
		/* Otherwise, truncate request. */
		bp->b_bcount = sz << DEV_BSHIFT;
	}

	return 1;

bad:
	bp->b_flags |= B_ERROR;
done:
	return 0;
}

SYSCTL_SETUP(sysctl_drive_stats_setup, "sysctl drive stats setup")
{
	sysctl_createv(clog, 0, NULL, NULL,
		       CTLFLAG_PERMANENT,
		       CTLTYPE_STRING, "drivenames",
		       SYSCTL_DESCR("List of drives present"),
		       sysctl_hw_drivenames, 0, NULL, 0,
		       CTL_HW, HW_DRIVENAMES, CTL_EOL);
	sysctl_createv(clog, 0, NULL, NULL,
		       CTLFLAG_PERMANENT,
		       CTLTYPE_STRUCT, "drivestats",
		       SYSCTL_DESCR("Statistics on drive operation"),
		       sysctl_hw_drivestats, 0, NULL, 0,
		       CTL_HW, HW_DRIVESTATS, CTL_EOL);
}

--X1bOJ3K7DJ5YkBrT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="drive.h"

/*	$NetBSD: disk.h,v 1.29 2005/02/03 19:20:01 perry Exp $	*/

/*-
 * Copyright (c) 1996, 1997, 2004 The NetBSD Foundation, Inc.
 * All rights reserved.
 *
 * This code is derived from software contributed to The NetBSD Foundation
 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
 * NASA Ames Research Center.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *	This product includes software developed by the NetBSD
 *	Foundation, Inc. and its contributors.
 * 4. Neither the name of The NetBSD Foundation nor the names of its
 *    contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef _SYS_DRIVE_H_
#define _SYS_DRIVE_H_

/*
 * Disk device structures.
 */

#include <sys/dkio.h>
#include <sys/drive.h>
#include <sys/time.h>
#include <sys/queue.h>
#include <sys/lock.h>

#define	DRIVENAMELEN	16

struct buf;
struct disk;
struct disklabel;
struct cpu_disklabel;
struct vnode;

/* types of drives we can have */
#define DRV_DISK	0
#define DRV_TAPE	1
#define DRV_NFS		2

/* The following structure is 64-bit alignment safe */
struct drive_sysctl {
	char		name[DRIVENAMELEN];
	int32_t		busy;
	int32_t		type;
	u_int64_t	xfer;
	u_int64_t	seek;
	u_int64_t	bytes;
	u_int32_t	attachtime_sec;
	u_int32_t	attachtime_usec;
	u_int32_t	timestamp_sec;
	u_int32_t	timestamp_usec;
	u_int32_t	time_sec;
	u_int32_t	time_usec;
	/* New separate read/write stats */
	u_int64_t	rxfer;
	u_int64_t	rbytes;
	u_int64_t	wxfer;
	u_int64_t	wbytes;
};

/*
 * Structure for keeping the in-kernel drive stats - these are linked
 * together in drivelist.
 */

struct drive_stats 
{
	char		*name;  /* device name */
	void		*parent; /* pointer to what we are attached to */
	int		type;   /* type of device the state belong to */
	int		busy;	/* busy counter */
	u_int64_t	rxfer;	/* total number of read transfers */
	u_int64_t	wxfer;	/* total number of write transfers */
	u_int64_t	seek;	/* total independent seek operations */
	u_int64_t	rbytes;	/* total bytes read */
	u_int64_t	wbytes;	/* total bytes written */
	struct timeval	attachtime;	/* time disk was attached */
	struct timeval	timestamp;	/* timestamp of last unbusy */
	struct timeval	time;	/* total time spent busy */
	TAILQ_ENTRY(drive_stats) link;
};

/*
 * dkwedge_info:
 *
 *	Information needed to configure (or query configuration of) a
 *	disk wedge.
 */
struct dkwedge_info {
	char		dkw_devname[16];/* device-style name (e.g. "dk0") */
	uint8_t		dkw_wname[128];	/* wedge name (Unicode, UTF-8) */
	char		dkw_parent[16];	/* parent disk device name */
	daddr_t		dkw_offset;	/* LBA offset of wedge in parent */
	uint64_t	dkw_size;	/* size of wedge in blocks */
	char		dkw_ptype[32];	/* partition type string */
};

/*
 * dkwedge_list:
 *
 *	Structure used to query a list of wedges.
 */
struct dkwedge_list {
	void		*dkwl_buf;	/* storage for dkwedge_info array */
	size_t		dkwl_bufsize;	/* size of that buffer */
	u_int		dkwl_nwedges;	/* total number of wedges */
	u_int		dkwl_ncopied;	/* number actually copied */
};

#ifdef _KERNEL
/*
 * dkwedge_discovery_method:
 *
 *	Structure used to describe partition map parsing schemes
 *	used for wedge autodiscovery.
 */
struct dkwedge_discovery_method {
					/* link in wedge driver's list */
	LIST_ENTRY(dkwedge_discovery_method) ddm_list;
	const char	*ddm_name;	/* name of this method */
	int		ddm_priority;	/* search priority */
	int		(*ddm_discover)(struct disk *, struct vnode *);
};

#define	DKWEDGE_DISCOVERY_METHOD_DECL(name, prio, discover)		\
static struct dkwedge_discovery_method name ## _ddm = {			\
	{ 0 },								\
	#name,								\
	prio,								\
	discover							\
};									\
__link_set_add_data(dkwedge_methods, name ## _ddm)
#endif /* _KERNEL */

/* Some common partition types */
#define	DKW_PTYPE_UNKNOWN	""
#define	DKW_PTYPE_UNUSED	"unused"
#define	DKW_PTYPE_SWAP		"swap"
#define	DKW_PTYPE_FFS		"ffs"
#define	DKW_PTYPE_LFS		"lfs"
#define	DKW_PTYPE_EXT2FS	"ext2fs"
#define	DKW_PTYPE_ISO9660	"cd9660"
#define	DKW_PTYPE_AMIGADOS	"ados"
#define	DKW_PTYPE_APPLEHFS	"hfs"
#define	DKW_PTYPE_FAT		"msdos"
#define	DKW_PTYPE_FILECORE	"filecore"
#define	DKW_PTYPE_RAIDFRAME	"raidframe"
#define	DKW_PTYPE_CCD		"ccd"
#define	DKW_PTYPE_APPLEUFS	"appleufs"
#define	DKW_PTYPE_NTFS		"ntfs"

/*
 * Disk geometry information.
 *
 * NOTE: Not all geometry information is relevant for every kind of disk.
 */
struct disk_geom {
	int64_t		dg_secperunit;	/* # of data sectors per unit */
	uint32_t	dg_secsize;	/* # of bytes per sector */
	uint32_t	dg_nsectors;	/* # of data sectors per track */
	uint32_t	dg_ntracks;	/* # of tracks per cylinder */
	uint32_t	dg_ncylinders;	/* # of data cylinders per unit */
	uint32_t	dg_secpercyl;	/* # of data sectors per cylinder */
	uint32_t	dg_pcylinders;	/* # of physical cylinders per unit */

	/*
	 * Spares (bad sector replacements) below are not counted in
	 * dg_nsectors or dg_secpercyl.  Spare sectors are assumed to
	 * be physical sectors which occupy space at the end of each
	 * track and/or cylinder.
	 */
	uint32_t	dg_sparespertrack;
	uint32_t	dg_sparespercyl;
	/*
	 * Alternative cylinders include maintenance, replacement,
	 * configuration description areas, etc.
	 */
	uint32_t	dg_acylinders;
};

struct disk {
	char		*dk_name;	/* disk name */
	int		dk_bopenmask;	/* block devices open */
	int		dk_copenmask;	/* character devices open */
	int		dk_openmask;	/* composite (bopen|copen) */
	int		dk_state;	/* label state   ### */
	int		dk_blkshift;	/* shift to convert DEV_BSIZE to blks */
	int		dk_byteshift;	/* shift to convert bytes to blks */

	struct drive_stats *stats;	/* usage statistics */

	struct	dkdriver *dk_driver;	/* pointer to driver */

	/*
	 * Information required to be the parent of a disk wedge.
	 */
	struct lock	dk_rawlock;	/* lock on these fields */
	struct vnode	*dk_rawvp;	/* vnode for the RAW_PART bdev */
	u_int		dk_rawopens;	/* # of openes of rawvp */

	struct lock	dk_openlock;	/* lock on these and openmask */
	u_int		dk_nwedges;	/* # of configured wedges */
					/* all wedges on this disk */
	LIST_HEAD(, dkwedge_softc) dk_wedges;

	/*
	 * Disk label information.  Storage for the in-core disk label
	 * must be dynamically allocated, otherwise the size of this
	 * structure becomes machine-dependent.
	 */
	daddr_t		dk_labelsector;		/* sector containing label */
	struct disklabel *dk_label;	/* label */
	struct cpu_disklabel *dk_cpulabel;
};

struct dkdriver {
	void	(*d_strategy)(struct buf *);
	void	(*d_minphys)(struct buf *);
#ifdef notyet
	int	(*d_open)(dev_t, int, int, struct proc *);
	int	(*d_close)(dev_t, int, int, struct proc *);
	int	(*d_ioctl)(dev_t, u_long, caddr_t, int, struct proc *);
	int	(*d_dump)(dev_t);
	void	(*d_start)(struct buf *, daddr_t);
	int	(*d_mklabel)(struct disk *);
#endif
};

/* states */
#define	DK_CLOSED	0		/* drive is closed */
#define	DK_WANTOPEN	1		/* drive being opened */
#define	DK_WANTOPENRAW	2		/* drive being opened */
#define	DK_RDLABEL	3		/* label being read */
#define	DK_OPEN		4		/* label read, drive open */
#define	DK_OPENRAW	5		/* open without label */

/*
 * drivelist_head is defined here so that user-land has access to it.
 */
TAILQ_HEAD(drivelist_head, drive_stats);	/* the drivelist is a TAILQ */

/*
 * Bad sector lists per fixed disk
 */
struct disk_badsectors {
	SLIST_ENTRY(disk_badsectors)	dbs_next;
	daddr_t		dbs_min;	/* min. sector number */
	daddr_t		dbs_max;	/* max. sector number */
	struct timeval	dbs_failedat;	/* first failure at */
};

struct disk_badsecinfo {
	u_int32_t	dbsi_bufsize;	/* size of region pointed to */
	u_int32_t	dbsi_skip;	/* how many to skip past */
	u_int32_t	dbsi_copied;	/* how many got copied back */
	u_int32_t	dbsi_left;	/* remaining to copy */
	caddr_t		dbsi_buffer;	/* region to copy disk_badsectors to */
};

#ifdef _KERNEL
extern	int drive_count;			/* number of disks in global
						   drive list */

struct device;
struct proc;

void	disk_attach(struct disk *);
void	disk_detach(struct disk *);
void	pseudo_disk_init(struct disk *);
void	pseudo_disk_attach(struct disk *);
void	pseudo_disk_detach(struct disk *);
void	drive_busy(struct drive_stats *);
void	drive_unbusy(struct drive_stats *, long, int);
void	drive_resetstat(struct drive_stats *);
struct	drive_stats *drive_find(char *);
struct  drive_stats *drive_stats_alloc(int32_t);
void	drive_stats_free(struct drive_stats *);

int	dkwedge_add(struct dkwedge_info *);
int	dkwedge_del(struct dkwedge_info *);
void	dkwedge_delall(struct disk *);
int	dkwedge_list(struct disk *, struct dkwedge_list *, struct proc *);
void	dkwedge_discover(struct disk *);
void	dkwedge_set_bootwedge(struct device *, daddr_t, uint64_t);
int	dkwedge_read(struct disk *, struct vnode *, daddr_t, void *, size_t);
#endif

#endif /* _SYS_DISK_H_ */

--X1bOJ3K7DJ5YkBrT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="drvstats.c"

/*	$NetBSD: dkstats.c,v 1.22 2005/02/26 21:19:18 dsl Exp $	*/

/*
 * Copyright (c) 1996 John M. Vinopal
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed for the NetBSD Project
 *      by John M. Vinopal.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/param.h>
#include <sys/sched.h>
#include <sys/sysctl.h>
#include <sys/time.h>
#include <sys/drive.h>

#include <err.h>
#include <fcntl.h>
#include <kvm.h>
#include <limits.h>
#include <nlist.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "drvstats.h"

static struct nlist namelist[] = {
#define	X_TK_NIN	0
	{ "_tk_nin" },		/* tty characters in */
#define	X_TK_NOUT	1
	{ "_tk_nout" },		/* tty characters out */
#define	X_HZ		2
	{ "_hz" },		/* ticks per second */
#define	X_STATHZ	3
	{ "_stathz" },
#define	X_DRIVE_COUNT	4
	{ "_drive_count" },	/* number of drives */
#define	X_DRIVELIST	5
	{ "_drivelist" },	/* TAILQ of drives */
	{ NULL },
};

/* Structures to hold the statistics. */
struct _drive	cur, last;

/* Kernel pointers: nlistf and memf defined in calling program. */
static kvm_t	*kd = NULL;
extern char	*nlistf;
extern char	*memf;
extern int	hz;

/* Pointer to list of drives. */
static struct drive_stats	*drivehead = NULL;
/* sysctl hw.drivestats buffer. */
static struct drive_sysctl	*drives = NULL;

/* Backward compatibility references. */
int		ndrive = 0;
int		*drv_select;
char		**dr_name;

#define	KVM_ERROR(_string) do {						\
	warnx("%s", (_string));						\
	errx(1, "%s", kvm_geterr(kd));					\
} while (/* CONSTCOND */0)

/*
 * Dereference the namelist pointer `v' and fill in the local copy
 * 'p' which is of size 's'.
 */
#define	deref_nl(v, p, s) do {						\
	deref_kptr((void *)namelist[(v)].n_value, (p), (s));		\
} while (/* CONSTCOND */0)

/* Missing from <sys/time.h> */
#define	timerset(tvp, uvp) do {						\
	((uvp)->tv_sec = (tvp)->tv_sec);				\
	((uvp)->tv_usec = (tvp)->tv_usec);				\
} while (/* CONSTCOND */0)

static void deref_kptr(void *, void *, size_t);

/*
 * Take the delta between the present values and the last recorded
 * values, storing the present values in the 'last' structure, and
 * the delta values in the 'cur' structure.
 */
void
drvswap(void)
{
	double etime;
	u_int64_t tmp;
	int	i, state;

#define	SWAP(fld) do {							\
	tmp = cur.fld;							\
	cur.fld -= last.fld;						\
	last.fld = tmp;							\
} while (/* CONSTCOND */0)

	for (i = 0; i < ndrive; i++) {
		struct timeval	tmp_timer;

		if (!cur.select[i])
			continue;

		/* Delta Values. */
		SWAP(rxfer[i]);
		SWAP(wxfer[i]);
		SWAP(seek[i]);
		SWAP(rbytes[i]);
		SWAP(wbytes[i]);

		/* Delta Time. */
		timerclear(&tmp_timer);
		timerset(&(cur.time[i]), &tmp_timer);
		timersub(&tmp_timer, &(last.time[i]), &(cur.time[i]));
		timerclear(&(last.time[i]));
		timerset(&tmp_timer, &(last.time[i]));
	}
	for (i = 0; i < CPUSTATES; i++)
		SWAP(cp_time[i]);
	SWAP(tk_nin);
	SWAP(tk_nout);

	etime = 0;
	for (state = 0; state < CPUSTATES; ++state) {
		etime += cur.cp_time[state];
	}
	if (etime == 0)
		etime = 1;
	etime /= hz;
	etime /= cur.cp_ncpu;

	cur.cp_etime = etime;

#undef SWAP
}

/*
 * Read the drive statistics for each drive in the drive list.
 * Also collect statistics for tty i/o and CPU ticks.
 */
void
drvreadstats(void)
{
	struct drive_stats	cur_drive, *p;
	size_t		size;
	int		mib[3];
	int		i;

	p = drivehead;

	if (memf == NULL) {
		mib[0] = CTL_HW;
		mib[1] = HW_DRIVESTATS;
		mib[2] = sizeof(struct drive_sysctl);

		size = ndrive * sizeof(struct drive_sysctl);
		if (sysctl(mib, 3, drives, &size, NULL, 0) < 0)
			err(1, "sysctl hw.drivestats failed");
		for (i = 0; i < ndrive; i++) {
			cur.rxfer[i] = drives[i].rxfer;
			cur.wxfer[i] = drives[i].wxfer;
			cur.seek[i] = drives[i].seek;
			cur.rbytes[i] = drives[i].rbytes;
			cur.wbytes[i] = drives[i].wbytes;
			cur.time[i].tv_sec = drives[i].time_sec;
			cur.time[i].tv_usec = drives[i].time_usec;
		}

		mib[0] = CTL_KERN;
		mib[1] = KERN_TKSTAT;
		mib[2] = KERN_TKSTAT_NIN;
		size = sizeof(cur.tk_nin);
		if (sysctl(mib, 3, &cur.tk_nin, &size, NULL, 0) < 0)
			cur.tk_nin = 0;

		mib[2] = KERN_TKSTAT_NOUT;
		size = sizeof(cur.tk_nout);
		if (sysctl(mib, 3, &cur.tk_nout, &size, NULL, 0) < 0)
			cur.tk_nout = 0;
	} else {
		for (i = 0; i < ndrive; i++) {
			deref_kptr(p, &cur_drive, sizeof(cur_drive));
			cur.rxfer[i] = cur_drive.rxfer;
			cur.wxfer[i] = cur_drive.wxfer;
			cur.seek[i] = cur_drive.seek;
			cur.rbytes[i] = cur_drive.rbytes;
			cur.wbytes[i] = cur_drive.wbytes;
			timerset(&(cur_drive.time), &(cur.time[i]));
			p = cur_drive.link.tqe_next;
		}

		deref_nl(X_TK_NIN, &cur.tk_nin, sizeof(cur.tk_nin));
		deref_nl(X_TK_NOUT, &cur.tk_nout, sizeof(cur.tk_nout));
	}

	/*
	 * XXX Need to locate the `correct' CPU when looking for this
	 * XXX in crash dumps.  Just don't report it for now, in that
	 * XXX case.
	 */
	size = sizeof(cur.cp_time);
	memset(cur.cp_time, 0, size);
	if (memf == NULL) {
		mib[0] = CTL_KERN;
		mib[1] = KERN_CP_TIME;
		if (sysctl(mib, 2, cur.cp_time, &size, NULL, 0) < 0)
			memset(cur.cp_time, 0, sizeof(cur.cp_time));
	}
}

/*
 * Perform all of the initialization and memory allocation needed to
 * track drive statistics.
 */
int
drvinit(int selected)
{
	struct drivelist_head drive_head;
	struct drive_stats	cur_drive, *p;
	struct clockinfo clockinfo;
	char		errbuf[_POSIX2_LINE_MAX];
	size_t		size;
	static int	once = 0;
	int		i, mib[3];

	if (once)
		return (1);

	if (memf == NULL) {
		mib[0] = CTL_HW;
		mib[1] = HW_NCPU;
		size = sizeof(cur.cp_ncpu);
		if (sysctl(mib, 2, &cur.cp_ncpu, &size, NULL, 0) == -1)
			err(1, "sysctl hw.ncpu failed");

		mib[0] = CTL_KERN;
		mib[1] = KERN_CLOCKRATE;
		size = sizeof(clockinfo);
		if (sysctl(mib, 2, &clockinfo, &size, NULL, 0) == -1)
			err(1, "sysctl kern.clockrate failed");
		hz = clockinfo.stathz;
		if (!hz)
			hz = clockinfo.hz;

		mib[0] = CTL_HW;
		mib[1] = HW_DRIVESTATS;
		mib[2] = sizeof(struct drive_sysctl);
		if (sysctl(mib, 3, NULL, &size, NULL, 0) == -1)
			err(1, "sysctl hw.drivestats failed");
		ndrive = size / sizeof(struct drive_sysctl);

		if (size == 0) {
			warnx("No drives attached.");
		} else {
			drives = (struct drive_sysctl *)malloc(size);
			if (drives == NULL)
				errx(1, "Memory allocation failure.");
		}
	} else {
		/* Open the kernel. */
		if ((kd = kvm_openfiles(nlistf, memf, NULL, O_RDONLY,
		    errbuf)) == NULL)
			errx(1, "kvm_openfiles: %s", errbuf);

		/* Obtain the namelist symbols from the kernel. */
		if (kvm_nlist(kd, namelist))
			KVM_ERROR("kvm_nlist failed to read symbols.");

		/* Get the number of attached drives. */
		deref_nl(X_DRIVE_COUNT, &ndrive, sizeof(ndrive));

		if (ndrive < 0)
			errx(1, "invalid _drive_count %d.", ndrive);
		else if (ndrive == 0) {
			warnx("No drives attached.");
		} else {
			/* Get a pointer to the first drive. */
			deref_nl(X_DRIVELIST, &drive_head, sizeof(drive_head));
			drivehead = drive_head.tqh_first;
		}

		/* Get ticks per second. */
		deref_nl(X_STATHZ, &hz, sizeof(hz));
		if (!hz)
			deref_nl(X_HZ, &hz, sizeof(hz));
	}

	/* Allocate space for the statistics. */
	cur.time = calloc(ndrive, sizeof(struct timeval));
	cur.rxfer = calloc(ndrive, sizeof(u_int64_t));
	cur.wxfer = calloc(ndrive, sizeof(u_int64_t));
	cur.seek = calloc(ndrive, sizeof(u_int64_t));
	cur.rbytes = calloc(ndrive, sizeof(u_int64_t));
	cur.wbytes = calloc(ndrive, sizeof(u_int64_t));
	last.time = calloc(ndrive, sizeof(struct timeval));
	last.rxfer = calloc(ndrive, sizeof(u_int64_t));
	last.wxfer = calloc(ndrive, sizeof(u_int64_t));
	last.seek = calloc(ndrive, sizeof(u_int64_t));
	last.rbytes = calloc(ndrive, sizeof(u_int64_t));
	last.wbytes = calloc(ndrive, sizeof(u_int64_t));
	cur.select = calloc(ndrive, sizeof(int));
	cur.name = calloc(ndrive, sizeof(char *));

	if (cur.time == NULL || cur.rxfer == NULL ||
	    cur.wxfer == NULL || cur.seek == NULL ||
	    cur.rbytes == NULL || cur.wbytes == NULL ||
	    last.time == NULL || last.rxfer == NULL ||
	    last.wxfer == NULL || last.seek == NULL ||
	    last.rbytes == NULL || last.wbytes == NULL ||
	    cur.select == NULL || cur.name == NULL)
		errx(1, "Memory allocation failure.");

	/* Set up the compatibility interfaces. */
	drv_select = cur.select;
	dr_name = cur.name;

	/* Read the drive names and set intial selection. */
	if (memf == NULL) {
		mib[0] = CTL_HW;		/* Should be still set from */
		mib[1] = HW_DRIVESTATS;		/* ... above, but be safe... */
		mib[2] = sizeof(struct drive_sysctl);
		if (sysctl(mib, 3, drives, &size, NULL, 0) == -1)
			err(1, "sysctl hw.drivestats failed");
		for (i = 0; i < ndrive; i++) {
			cur.name[i] = drives[i].name;
			cur.select[i] = selected;
		}
	} else {
		p = drivehead;
		for (i = 0; i < ndrive; i++) {
			char	buf[10];
			deref_kptr(p, &cur_drive, sizeof(cur_drive));
			deref_kptr(cur_drive.name, buf, sizeof(buf));
			cur.name[i] = strdup(buf);
			if (!cur.name[i])
				err(1, "strdup");
			cur.select[i] = selected;

			p = cur_drive.link.tqe_next;
		}
	}

	/* Never do this initialization again. */
	once = 1;
	return (1);
}

/*
 * Dereference the kernel pointer `kptr' and fill in the local copy
 * pointed to by `ptr'.  The storage space must be pre-allocated,
 * and the size of the copy passed in `len'.
 */
static void
deref_kptr(void *kptr, void *ptr, size_t len)
{
	char buf[128];

	if (kvm_read(kd, (u_long)kptr, (char *)ptr, len) != len) {
		memset(buf, 0, sizeof(buf));
		snprintf(buf, sizeof buf, "can't dereference kptr 0x%lx",
		    (u_long)kptr);
		KVM_ERROR(buf);
	}
}

--X1bOJ3K7DJ5YkBrT
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="drvstats.h"

/*	$NetBSD: dkstats.h,v 1.6 2002/11/01 12:47:56 mrg Exp $	*/

/*
 * Copyright (c) 1996 John M. Vinopal
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 3. All advertising materials mentioning features or use of this software
 *    must display the following acknowledgement:
 *      This product includes software developed for the NetBSD Project
 *      by John M. Vinopal.
 * 4. The name of the author may not be used to endorse or promote products
 *    derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 */

#include <sys/time.h>
#include <sys/sched.h>
#include <unistd.h>

/* poseur disk entry to hold the information we're interested in. */
struct _drive {
	int		 *select;	/* Display stats for selected disks. */
	char		**name;	/* Disk names (sd0, wd1, etc). */
	u_int64_t	 *rxfer;	/* # of read transfers. */
	u_int64_t	 *wxfer;	/* # of write transfers. */
	u_int64_t	 *seek;	/* # of seeks (currently unused). */
	u_int64_t	 *rbytes;	/* # of bytes read. */
	u_int64_t	 *wbytes;	/* # of bytes written. */
	struct timeval	 *time;	/* Time spent in disk i/o. */
	u_int64_t	  tk_nin;	/* TTY Chars in. */
	u_int64_t	  tk_nout;	/* TTY Chars out. */
	u_int64_t	  cp_time[CPUSTATES];	/* System timer ticks. */
	int	 	  cp_ncpu;		/* Number of cpu's */
	double		  cp_etime;		/* Elapsed time */
};

extern struct _drive	cur;
extern char		**dr_name;
extern int		*drv_select, ndrive;

int	drvinit(int);
void	drvreadstats(void);
void	drvswap(void);

--X1bOJ3K7DJ5YkBrT--