--- bsd/kernel.cc.orig	Tue Oct 14 09:53:17 2003
+++ bsd/kernel.cc	Fri Jan 27 16:02:27 2006
@@ -54,6 +54,7 @@
 #endif
 
 #ifdef HAVE_DEVSTAT
+#include <sys/dkstat.h>
 #include <devstat.h>
 #include <stdlib.h>	/*  For malloc().  */
 void DevStat_Init();
@@ -211,19 +212,28 @@
 
 { "_bufspace" },
 #define BUFSPACE_SYM_INDEX      3
+#if __FreeBSD_version < 500000
 { "_intr_countp" },
 #define INTRCOUNTP_SYM_INDEX 	4
+{ DUMMY_SYM },
+#define DUMMY_5			5
+#else
+{ "_intrnames" },
+#define INTRNAMES_SYM_INDEX 	4
+{ "_eintrnames" },
+#define EINTRNAMES_SYM_INDEX 	5
+#endif /* FreeBSD < 5.x */
 { "_intrcnt" },
-#define INTRCNT_SYM_INDEX 	5
+#define INTRCNT_SYM_INDEX 	6
 { "_eintrcnt" },
-#define EINTRCNT_SYM_INDEX 	6
+#define EINTRCNT_SYM_INDEX 	7
 
 #ifndef HAVE_DEVSTAT
 
 { "_dk_ndrive" },
-#define DK_NDRIVE_SYM_INDEX     7
+#define DK_NDRIVE_SYM_INDEX     8
 { "_dk_wds" },
-#define DK_WDS_SYM_INDEX        8
+#define DK_WDS_SYM_INDEX        9
 
 #endif /*HAVE_DEVSTAT */
 
@@ -329,7 +339,12 @@
   while (nlp && nlp->n_name && strncmp(nlp->n_name, DUMMY_SYM, strlen(DUMMY_SYM))) {
     if ((nlp->n_type == 0) || (nlp->n_value == 0))
       /*errx (-1, "kvm_nlist() lookup failed for symbol '%s'.", nlp->n_name);*/
+#if defined(XOSVIEW_FREEBSD) && defined(__alpha__)
+	/* XXX: this should be properly fixed. */
+	;
+#else
       warnx ("kvm_nlist() lookup failed for symbol '%s'.", nlp->n_name);
+#endif
     nlp++;
   }
 #ifdef HAVE_DEVSTAT
@@ -597,13 +612,21 @@
 	 * Make sure that the userland devstat version matches the kernel
 	 * devstat version.
 	 */
+#if __FreeBSD_version >= 500000
+	if (devstat_checkversion(kd) < 0) {
+#else
 	if (checkversion() < 0) {
+#endif
 		nodisk++;
 		return;
 	}
 
 	/* find out how many devices we have */
+#if __FreeBSD_version >= 500000
+	if ((num_devices = devstat_getnumdevs(kd)) < 0) {
+#else
 	if ((num_devices = getnumdevs()) < 0) {
+#endif
 		nodisk++;
 		return;
 	}
@@ -618,7 +641,11 @@
 	 * changed here, since it almost certainly has.  We only look for
 	 * errors.
 	 */
+#if __FreeBSD_version >= 500000
+	if (devstat_getdevs(kd,&cur) == -1) {
+#else
 	if (getdevs(&cur) == -1) {
+#endif
 		nodisk++;
 		return;
 	}
@@ -630,7 +657,11 @@
 
 	/* only interested in disks */
 	matches = NULL;
+#if __FreeBSD_version >= 500000
+	if (devstat_buildmatch("da", &matches, &num_matches) != 0) {
+#else
 	if (buildmatch("da", &matches, &num_matches) != 0) {
+#endif
 		nodisk++;
 		return;
 	}
@@ -645,7 +676,11 @@
 	 * device list has changed, so we don't look for return values of 0
 	 * or 1.  If we get back -1, though, there is an error.
 	 */
+#if __FreeBSD_version >= 500000
+	if (devstat_selectdevs(&dev_select, &num_selected,
+#else
 	if (selectdevs(&dev_select, &num_selected,
+#endif
 		       &num_selections, &select_generation,
 		       generation, cur.dinfo->devices, num_devices,
 		       matches, num_matches,
@@ -672,7 +707,11 @@
 		 * the selection process again, in case a device that we
 		 * were previously displaying has gone away.
 		 */
+#if __FreeBSD_version >= 500000
+		switch (devstat_getdevs(kd,&cur)) {
+#else
 		switch (getdevs(&cur)) {
+#endif
 		case -1:
 			return (0);
 		case 1: {
@@ -680,7 +719,11 @@
 
 			num_devices = cur.dinfo->numdevs;
 			generation = cur.dinfo->generation;
+#if __FreeBSD_version >= 500000
+			retval = devstat_selectdevs(&dev_select, &num_selected,
+#else
 			retval = selectdevs(&dev_select, &num_selected,
+#endif
 					    &num_selections, &select_generation,
 					    generation, cur.dinfo->devices,
 					    num_devices, matches, num_matches,
@@ -704,14 +747,22 @@
 		 * Calculate elapsed time up front, since it's the same for all
 		 * devices.
 		 */
+#if __FreeBSD_version >= 500000
+		busy_seconds = cur.snap_time - last.snap_time;
+#else
 		busy_seconds = compute_etime(cur.busy_time, last.busy_time);
+#endif
 
 		/* this is the first time thru so just copy cur to last */
 		if (last.dinfo->numdevs == 0) {
 			tmp_dinfo = last.dinfo;
 			last.dinfo = cur.dinfo;
 			cur.dinfo = tmp_dinfo;
+#if __FreeBSD_version >= 500000
+			last.snap_time = cur.snap_time;
+#else
 			last.busy_time = cur.busy_time;
+#endif
 			return (0);
 		}
 
@@ -725,7 +776,11 @@
 
 			di = dev_select[dn].position;
 
+#if __FreeBSD_version >= 500000
+			if (devstat_compute_statistics(&cur.dinfo->devices[di],
+#else
 			if (compute_stats(&cur.dinfo->devices[di],
+#endif
 				  &last.dinfo->devices[di], busy_seconds,
 				  &total_bytes, &total_transfers,
 				  NULL, NULL,
@@ -740,7 +795,11 @@
 		last.dinfo = cur.dinfo;
 		cur.dinfo = tmp_dinfo;
 
+#if __FreeBSD_version >= 500000
+		last.snap_time = cur.snap_time;
+#else
 		last.busy_time = cur.busy_time;
+#endif
 
 	} else {
 		/* no disks found ? */
@@ -912,25 +971,26 @@
   OpenKDIfNeeded(); 
   nintr = (nlst[EINTRCNT_SYM_INDEX].n_value -
 	   nlst[INTRCNT_SYM_INDEX].n_value)   / sizeof(int);
-#ifdef XOSVIEW_FREEBSD
-  /*  I'm not sure exactly how FreeBSD does things, but just do
+#if defined(i386)
+# if defined(XOSVIEW_FREEBSD)
+  /*  I'm not sure exactly how FreeBSD/i386 does things, but just do
    *  16 for now.  bgrayson  */
   return 16;
-#else
-# if defined(i386)
+# else
   /*  On the 386 platform, we count stray interrupts between
    *  intrct and eintrcnt, also, but we don't want to show these.  */
   return nintr/2;
-# else
-  return nintr;
 # endif
+#else
+  return nintr;
 #endif
 }
 #endif /* XOSVIEW_OPENBSD */
 
 void
 BSDGetIntrStats (unsigned long intrCount[NUM_INTR]) {
-#ifdef XOSVIEW_FREEBSD
+#if defined(XOSVIEW_FREEBSD) && defined(__i386__)
+#if __FreeBSD_version < 500000
     /* FreeBSD has an array of interrupt counts, indexed by device number.
        These are also indirected by IRQ num with intr_countp: */
     safe_kvm_read (nlst[INTRCOUNTP_SYM_INDEX].n_value,
@@ -944,6 +1004,46 @@
 	    sizeof(unsigned long);
 	intrCount[i] = kvm_intrcnt[idx];
     }
+#else /* FreeBSD 5.x and 6.x */
+    /* This code is stolen from vmstat */
+    unsigned long *kvm_intrcnt, *base_intrcnt;
+    char *kvm_intrname, *base_intrname;
+    size_t inamlen, intrcntlen;
+    unsigned int i, nintr;
+    int d;
+
+    intrcntlen = (nlst[EINTRCNT_SYM_INDEX].n_value - nlst[INTRCNT_SYM_INDEX].n_value);
+    inamlen = nlst[EINTRNAMES_SYM_INDEX].n_value - nlst[INTRNAMES_SYM_INDEX].n_value;
+    nintr = intrcntlen / sizeof(unsigned long);
+
+    if (((kvm_intrcnt = (unsigned long *)malloc(intrcntlen)) == NULL) || 
+	((kvm_intrname = (char *)malloc(inamlen)) == NULL))
+      err(1, "malloc()");
+
+    // keep track of the mem we're given:
+    base_intrcnt = kvm_intrcnt;
+    base_intrname = kvm_intrname;
+
+    safe_kvm_read (nlst[INTRCNT_SYM_INDEX].n_value, kvm_intrcnt, intrcntlen);
+    safe_kvm_read (nlst[INTRNAMES_SYM_INDEX].n_value, kvm_intrname, inamlen);
+
+    /* kvm_intrname has the ASCII names of the IRQs, every null-terminated
+     * string corresponds to a value in the kvm_intrcnt array */
+    for (i=0; i < nintr; i++) {
+	if (kvm_intrname[0] != '\0' && (*kvm_intrcnt != 0)) {
+	  /* Figure out which irq we have here */
+	    if (1 == sscanf(kvm_intrname, "irq%d:", &d))
+	      if (d < NUM_INTR)
+		intrCount[d] = *kvm_intrcnt;
+	}
+	kvm_intrcnt++;
+	kvm_intrname += strlen(kvm_intrname) + 1;
+    }
+
+    // Doh! somebody needs to free this stuff too... (pavel 20-Jan-2006)
+    free(base_intrcnt);
+    free(base_intrname);
+#endif
 #elif defined (XOSVIEW_BSDI)
     int nintr = 16;
 #if _BSDI_VERSION >= 199802 /* BSD/OS 4.x */


syntax highlighted by Code2HTML, v. 0.9.1