Index: Makefile
===================================================================
RCS file: /home/dcvs/dfports/x11/nvidia-driver/Makefile,v
retrieving revision 1.4
diff -u -r1.4 Makefile
--- Makefile	18 Aug 2004 14:20:02 -0000	1.4
+++ Makefile	26 Sep 2004 12:41:30 -0000
@@ -32,12 +32,8 @@
 XSERVVERSION!=	/usr/sbin/pkg_info -O x11-servers/XFree86-4-Server 2>/dev/null | ${GREP} Server- || true
 XLIBVERSION!=	/usr/sbin/pkg_info -O x11/XFree86-4-libraries 2>/dev/null | ${GREP} libraries- || true
 
-PLIST_SUB=	XSERVVERSION=${XSERVVERSION} XLIBVERSION=${XLIBVERSION} \
-		LINUXBASE=${LINUXBASE} NVVERSION=${NVVERSION}
+PLIST_SUB=	XSERVVERSION=${XSERVVERSION} XLIBVERSION=${XLIBVERSION} NVVERSION=${NVVERSION}
 
-.if !defined(WITHOUT_LINUX)
-USE_LINUX=	yes
-.endif
 
 pre-everything::
 .if !defined(WITH_DRAGONFLY_AGP)
@@ -67,10 +63,6 @@
 .endif
 
 pre-install:
-.if defined(WITHOUT_LINUX)
-	@${MKDIR} ${LINUXBASE}/usr/lib
-.endif
-	-@(kldstat -n linux || kldload linux)
 	-rm -f ${WRKSRC}/src/i386
 
 post-install:
Index: files/patch-dfly
===================================================================
RCS file: /home/dcvs/dfports/x11/nvidia-driver/files/patch-dfly,v
retrieving revision 1.6
diff -u -r1.6 patch-dfly
--- files/patch-dfly	18 Aug 2004 14:20:02 -0000	1.6
+++ files/patch-dfly	26 Sep 2004 12:39:12 -0000
@@ -1,6 +1,18 @@
-diff -urN ../../NVIDIA-FreeBSD-x86-1.0-6113/src/Makefile.rej ./src/Makefile.rej
---- ../../NVIDIA-FreeBSD-x86-1.0-6113/src/Makefile.rej	1970-01-01 01:00:00.000000000 +0100
-+++ ./src/Makefile.rej	2004-08-04 21:26:57.000000000 +0200
+diff -urN ./src/Makefile ../../nvidia-patched/src/Makefile
+--- ./src/Makefile	2004-08-03 01:27:38.000000000 +0200
++++ ../../nvidia-patched/src/Makefile	2004-09-26 14:14:10.000000000 +0200
+@@ -10,7 +10,7 @@
+ .endif
+ 
+ SRCS=		nvidia_ctl.c nvidia_dev.c nvidia_linux.c nvidia_os.c nvidia_os_pci.c nvidia_os_registry.c nvidia_pci.c nvidia_subr.c nvidia_sysctl.c 
+-SRCS+=		device_if.h bus_if.h pci_if.h vnode_if.h
++SRCS+=		device_if.h bus_if.h pci_if.h 
+ CFLAGS+=	-I${NVIDIA_ROOT}/src -DNV_MAJOR_VERSION=1 -DNV_MINOR_VERSION=0 -DNV_PATCHLEVEL=6113  -DNVCPU_X86  -DNV_BSD  -DNV_INT64_OK  -DNV_UNIX   
+ CFLAGS+=	-D__KERNEL__ -UDEBUG -U_DEBUG -DNDEBUG -O -fno-common
+ 
+diff -urN ./src/Makefile.rej ../../nvidia-patched/src/Makefile.rej
+--- ./src/Makefile.rej	1970-01-01 01:00:00.000000000 +0100
++++ ../../nvidia-patched/src/Makefile.rej	2004-09-26 14:13:39.000000000 +0200
 @@ -0,0 +1,17 @@
 +***************
 +*** 12,18 ****
@@ -19,9 +31,9 @@
 +  
 +  OBJS+=		${RMOBJ}
 +  NOOBJ=		true
-diff -urN ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nv-dragonfly.h ./src/nv-dragonfly.h
---- ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nv-dragonfly.h	1970-01-01 01:00:00.000000000 +0100
-+++ ./src/nv-dragonfly.h	2004-08-04 21:26:57.000000000 +0200
+diff -urN ./src/nv-dragonfly.h ../../nvidia-patched/src/nv-dragonfly.h
+--- ./src/nv-dragonfly.h	1970-01-01 01:00:00.000000000 +0100
++++ ../../nvidia-patched/src/nv-dragonfly.h	2004-09-26 14:31:37.000000000 +0200
 @@ -0,0 +1,360 @@
 +/* _NVRM_COPYRIGHT_BEGIN_
 + *
@@ -169,7 +181,7 @@
 + * no need for Linux 3D applications, you can safely unset this flag.
 + */
 +
-+#define NV_SUPPORT_LINUX_COMPAT
++#undef NV_SUPPORT_LINUX_COMPAT /* XXX: BROKEN! DO NOT ENABLE! */
 +
 +/*
 + * Enable/Disable support for ACPI Power Management. This is untested and
@@ -242,7 +254,7 @@
 +    struct sysctl_ctx_list sysctl_ctx;
 +    struct selinfo rsel;
 +
-+    struct callout_handle timer_ch;
++    struct callout timer_ch;
 +
 +    /* list of allocations */
 +    SLIST_HEAD(alloc_list, nv_alloc) alloc_list;
@@ -383,9 +395,9 @@
 +
 +#endif /* __NV_DRAGONFLY_H */
 +
-diff -urN ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_ctl.c ./src/nvidia_ctl.c
---- ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_ctl.c	2004-08-03 01:27:38.000000000 +0200
-+++ ./src/nvidia_ctl.c	2004-08-04 21:26:57.000000000 +0200
+diff -urN ./src/nvidia_ctl.c ../../nvidia-patched/src/nvidia_ctl.c
+--- ./src/nvidia_ctl.c	2004-08-03 01:27:38.000000000 +0200
++++ ../../nvidia-patched/src/nvidia_ctl.c	2004-09-26 14:13:39.000000000 +0200
 @@ -11,7 +11,8 @@
  #include "nv-misc.h"
  #include "os-interface.h"
@@ -500,9 +512,9 @@
      }
  
      return 0;
-diff -urN ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_dev.c ./src/nvidia_dev.c
---- ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_dev.c	2004-08-03 01:27:38.000000000 +0200
-+++ ./src/nvidia_dev.c	2004-08-04 21:26:57.000000000 +0200
+diff -urN ./src/nvidia_dev.c ../../nvidia-patched/src/nvidia_dev.c
+--- ./src/nvidia_dev.c	2004-08-03 01:27:38.000000000 +0200
++++ ../../nvidia-patched/src/nvidia_dev.c	2004-09-26 14:13:39.000000000 +0200
 @@ -11,7 +11,7 @@
  #include "nv-misc.h"
  #include "os-interface.h"
@@ -621,9 +633,9 @@
      return 0;
  }
  
-diff -urN ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_linux.c ./src/nvidia_linux.c
---- ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_linux.c	2004-08-03 01:27:38.000000000 +0200
-+++ ./src/nvidia_linux.c	2004-08-04 21:26:57.000000000 +0200
+diff -urN ./src/nvidia_linux.c ../../nvidia-patched/src/nvidia_linux.c
+--- ./src/nvidia_linux.c	2004-08-03 01:27:38.000000000 +0200
++++ ../../nvidia-patched/src/nvidia_linux.c	2004-09-26 14:13:39.000000000 +0200
 @@ -11,7 +11,7 @@
  #include "nv-misc.h"
  #include "os-interface.h"
@@ -642,9 +654,9 @@
  }
  
  struct linux_ioctl_handler nvidia_handler = {
-diff -urN ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_os.c ./src/nvidia_os.c
---- ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_os.c	2004-08-03 01:27:38.000000000 +0200
-+++ ./src/nvidia_os.c	2004-08-04 21:27:27.000000000 +0200
+diff -urN ./src/nvidia_os.c ../../nvidia-patched/src/nvidia_os.c
+--- ./src/nvidia_os.c	2004-08-03 01:27:38.000000000 +0200
++++ ../../nvidia-patched/src/nvidia_os.c	2004-09-26 14:13:39.000000000 +0200
 @@ -11,13 +11,13 @@
  #include "nv-misc.h"
  #include "os-interface.h"
@@ -714,9 +726,9 @@
  
      mtx->refcnt = 1;
      *semaphore = (void *) mtx;
-diff -urN ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_os_pci.c ./src/nvidia_os_pci.c
---- ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_os_pci.c	2004-08-03 01:27:38.000000000 +0200
-+++ ./src/nvidia_os_pci.c	2004-08-04 21:26:57.000000000 +0200
+diff -urN ./src/nvidia_os_pci.c ../../nvidia-patched/src/nvidia_os_pci.c
+--- ./src/nvidia_os_pci.c	2004-08-03 01:27:38.000000000 +0200
++++ ../../nvidia-patched/src/nvidia_os_pci.c	2004-09-26 14:13:39.000000000 +0200
 @@ -11,7 +11,7 @@
  #include "nv-misc.h"
  #include "os-interface.h"
@@ -726,9 +738,9 @@
  
  
  void* os_pci_init_handle(
-diff -urN ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_os_registry.c ./src/nvidia_os_registry.c
---- ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_os_registry.c	2004-08-03 01:27:38.000000000 +0200
-+++ ./src/nvidia_os_registry.c	2004-08-04 21:26:57.000000000 +0200
+diff -urN ./src/nvidia_os_registry.c ../../nvidia-patched/src/nvidia_os_registry.c
+--- ./src/nvidia_os_registry.c	2004-08-03 01:27:38.000000000 +0200
++++ ../../nvidia-patched/src/nvidia_os_registry.c	2004-09-26 14:13:39.000000000 +0200
 @@ -11,7 +11,7 @@
  #include "nv-misc.h"
  #include "os-interface.h"
@@ -738,9 +750,9 @@
  
  
  /*
-diff -urN ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_pci.c ./src/nvidia_pci.c
---- ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_pci.c	2004-08-03 01:27:38.000000000 +0200
-+++ ./src/nvidia_pci.c	2004-08-04 21:26:57.000000000 +0200
+diff -urN ./src/nvidia_pci.c ../../nvidia-patched/src/nvidia_pci.c
+--- ./src/nvidia_pci.c	2004-08-03 01:27:38.000000000 +0200
++++ ../../nvidia-patched/src/nvidia_pci.c	2004-09-26 14:13:39.000000000 +0200
 @@ -11,7 +11,7 @@
  #include "nv-misc.h"
  #include "os-interface.h"
@@ -767,9 +779,9 @@
  
      return 0;
  
-diff -urN ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_subr.c ./src/nvidia_subr.c
---- ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_subr.c	2004-08-03 01:27:38.000000000 +0200
-+++ ./src/nvidia_subr.c	2004-08-04 21:34:46.000000000 +0200
+diff -urN ./src/nvidia_subr.c ../../nvidia-patched/src/nvidia_subr.c
+--- ./src/nvidia_subr.c	2004-08-03 01:27:38.000000000 +0200
++++ ../../nvidia-patched/src/nvidia_subr.c	2004-09-26 14:37:35.000000000 +0200
 @@ -11,7 +11,7 @@
  #include "nv-misc.h"
  #include "os-interface.h"
@@ -788,7 +800,41 @@
      nv->os_state         = sc;
      nv->flags            = 0;
      nv->device_number    = device_get_unit(dev);
-@@ -683,18 +685,6 @@
+@@ -50,6 +52,9 @@
+         return status;
+ 
+     nv_sysctl_init(nv);
++
++    callout_init(&sc->timer_ch);
++
+     return 0;
+ }
+ 
+@@ -59,8 +64,12 @@
+     struct nvidia_softc *sc;
+ 
+     sc = device_get_softc(dev);
++
++    crit_enter();
++    callout_stop(&sc->timer_ch); /* just in case */
+     nv_sysctl_exit(sc->nv_state);
+ 
++
+     status = nvidia_dev_detach(sc);
+     if (status) {
+         device_printf(dev, "NVRM: NVIDIA driver DEV detach failed.\n");
+@@ -72,8 +81,9 @@
+         device_printf(dev, "NVRM: NVIDIA driver CTL detach failed.\n");
+         goto fail;
+     }
+-
++    
+ fail:
++    crit_exit();
+     /* XXX Fix me? (state) */
+     return status;
+ }
+@@ -683,18 +693,6 @@
  
  void nv_lock_rm(nv_state_t *nv)
  {
@@ -807,7 +853,7 @@
      /* 
       * While SMP configurations are handled with a global kernel lock and
       * in such a way that only one of the CPUs is executing a process and
-@@ -704,28 +694,16 @@
+@@ -704,28 +702,16 @@
       * This "lock" thus disables interrupts for the duration of this code
       * segment's execution.
       */
@@ -838,1634 +884,37 @@
  }
  
  
-diff -urN ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_subr.c~ ./src/nvidia_subr.c~
---- ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_subr.c~	1970-01-01 01:00:00.000000000 +0100
-+++ ./src/nvidia_subr.c~	2004-08-04 21:32:49.000000000 +0200
-@@ -0,0 +1,1621 @@
-+/* _NVRM_COPYRIGHT_BEGIN_
-+ *
-+ * Copyright 2001-2002 by NVIDIA Corporation.  All rights reserved.  All
-+ * information contained herein is proprietary and confidential to NVIDIA
-+ * Corporation.  Any use, reproduction, or disclosure without the written
-+ * permission of NVIDIA Corporation is prohibited.
-+ *
-+ * _NVRM_COPYRIGHT_END_
-+ */
-+
-+#include "nv-misc.h"
-+#include "os-interface.h"
-+#include "nv.h"
-+#include "nv-dragonfly.h"
-+
-+
-+devclass_t nvidia_devclass;
-+nv_state_t nvidia_ctl_state;
-+
-+#define rman_get_extends(x) (rman_get_end(x) - rman_get_start(x) + 1)
-+
-+int nvidia_attach(device_t dev)
-+{
-+    int status;
-+    struct nvidia_softc *sc;
-+    nv_state_t *nv;
-+
-+    sc = device_get_softc(dev);
-+    nv = sc->nv_state;
-+
-+    printf("nvidia_attach() called - state %d\n", nv);
-+
-+    nv->os_state         = sc;
-+    nv->flags            = 0;
-+    nv->device_number    = device_get_unit(dev);
-+    nv->bus              = pci_get_bus(dev);
-+    nv->slot             = pci_get_slot(dev);
-+    nv->vendor_id        = pci_get_vendor(dev);
-+    nv->device_id        = pci_get_device(dev);
-+    nv->interrupt_line   = pci_get_irq(dev);
-+    nv->bar.fb.address   = rman_get_start(sc->mem);
-+    nv->bar.fb.size      = rman_get_extends(sc->mem);
-+    nv->bar.fb.map       = NULL;
-+    nv->bar.regs.address = rman_get_start(sc->reg);
-+    nv->bar.regs.size    = rman_get_extends(sc->reg);
-+    nv->bar.regs.map     = NULL;
-+
-+    if ((status = nvidia_dev_attach(sc)) != 0)
-+        return status;
-+
-+    if ((status = nvidia_ctl_attach()) != 0)
-+        return status;
-+
-+    nv_sysctl_init(nv);
-+    return 0;
-+}
-+
-+int nvidia_detach(device_t dev)
-+{
-+    int status;
-+    struct nvidia_softc *sc;
-+
-+    sc = device_get_softc(dev);
-+    nv_sysctl_exit(sc->nv_state);
-+
-+    status = nvidia_dev_detach(sc);
-+    if (status) {
-+        device_printf(dev, "NVRM: NVIDIA driver DEV detach failed.\n");
-+        goto fail;
-+    }
-+
-+    status = nvidia_ctl_detach();
-+    if (status) {
-+        device_printf(dev, "NVRM: NVIDIA driver CTL detach failed.\n");
-+        goto fail;
-+    }
-+
-+fail:
-+    /* XXX Fix me? (state) */
-+    return status;
-+}
-+
-+
-+#ifdef NV_SUPPORT_ACPI_PM
-+int nvidia_suspend(device_t dev)
-+{
-+    struct nvidia_softc *sc;
-+    nv_state_t *nv;
-+    int status = RM_ERROR;
-+
-+    /* Only if ACPI is running */
-+    if (devclass_get_softc(devclass_find("ACPI"), 0) == NULL)
-+        return ENODEV;
-+
-+    sc = device_get_softc(dev);
-+    nv = sc->nv_state;
-+
-+    NV_PCI_ENABLE_DEVICE(nv);
-+
-+    if (nv->pdev != NULL) {
-+        /* Only if we have RM state */
-+        status = rm_power_management(nv, 0, NV_PM_ACPI_STANDBY);
-+    }
-+
-+    return status;
-+}
-+
-+int nvidia_resume(device_t dev)
-+{
-+    struct nvidia_softc *sc;
-+    nv_state_t *nv;
-+    int status = RM_ERROR;
-+
-+    sc = device_get_softc(dev);
-+    nv = sc->nv_state;
-+
-+    NV_PCI_ENABLE_DEVICE(nv);
-+
-+    if (nv->pdev != NULL) {
-+        /* Only if we have RM state */
-+        status = rm_power_management(nv, 0, NV_PM_ACPI_RESUME);
-+    }
-+
-+    return status;
-+}
-+#endif /* NV_SUPPORT_ACPI_PM */
-+
-+
-+int nvidia_alloc(device_t dev)
-+{
-+    int error = 0;
-+    struct nvidia_softc *sc;
-+
-+    sc = device_get_softc(dev);
-+    sc->dev = dev;
-+
-+    sc->nv_state = malloc(sizeof(nv_state_t), M_NVIDIA, M_WAITOK | M_ZERO);
-+    if (sc->nv_state == NULL) {
-+        error = ENOMEM;
-+        goto fail;
-+    }
-+
-+    sc->reg = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->reg_rid,
-+                    0, ~0, 1, 0);
-+    if (sc->reg == NULL) {
-+        device_printf(dev, "NVRM: NVIDIA REG resource alloc failed.\n");
-+        error = ENXIO;
-+        goto fail;
-+    }
-+
-+    sc->mem = bus_alloc_resource(dev, SYS_RES_MEMORY, &sc->mem_rid,
-+                    0, ~0, 1, 0);
-+    if (sc->mem == NULL) {
-+        device_printf(dev, "NVRM: NVIDIA MEM resource alloc failed.\n");
-+        error = ENXIO;
-+        goto fail;
-+    }
-+
-+    sc->irq = bus_alloc_resource(dev, SYS_RES_IRQ, &sc->irq_rid,
-+                     0, ~0, 1, RF_SHAREABLE | RF_ACTIVE);
-+    if (sc->irq == NULL) {
-+        device_printf(dev, "NVRM: NVIDIA IRQ resource alloc failed.\n");
-+        error = ENXIO;
-+        goto fail;
-+    }
-+
-+fail:
-+    return (error);
-+}
-+
-+void nvidia_free(device_t dev)
-+{
-+    struct nvidia_softc *sc;
-+
-+    sc = device_get_softc(dev);
-+
-+    if (sc->reg != NULL)
-+        bus_release_resource(dev, SYS_RES_MEMORY, sc->reg_rid, sc->reg);
-+    if (sc->mem != NULL)
-+        bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem);
-+    if (sc->irq != NULL)
-+        bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq);
-+    if (sc->iop != NULL)
-+        bus_release_resource(dev, SYS_RES_IOPORT, sc->iop_rid, sc->iop);
-+
-+    if (sc->nv_state != NULL)
-+        free(sc->nv_state, M_NVIDIA);
-+}
-+
-+void nvidia_intr(void *xsc)
-+{
-+    struct nvidia_softc *sc;
-+    nv_state_t *nv;
-+    U032 run_bottom_half = 0;
-+
-+    sc = (struct nvidia_softc *) xsc;
-+    nv = sc->nv_state;
-+
-+    NV_PCI_ENABLE_DEVICE(nv);
-+    rm_isr(nv->device_number, &run_bottom_half);
-+
-+    if (run_bottom_half) {
-+        /* We're not executing in an HW ISR context */
-+        rm_isr_bh(nv->pdev);
-+    }
-+}
-+
-+int nvidia_post_vbios(struct nv_ioctl_post_vbios *pv)
-+{
-+    int i;
-+    struct nvidia_softc *sc;
-+    nv_state_t *nv;
-+
-+    for (i = 0; i < NV_MAX_DEVICES; i++) {
-+        sc = devclass_get_softc(nvidia_devclass, i);
-+        if (!sc)
-+            continue;
-+        nv = sc->nv_state;
-+
-+        if ((nv->bus == pv->bus) && (nv->slot == pv->slot) &&
-+                (nv->flags & NV_FLAG_WAS_POSTED) == 0)
-+            nv->flags |= NV_FLAG_NEEDS_POSTING;
-+    }
-+
-+    return 0;
-+}
-+
-+int nvidia_get_api_version(struct nv_ioctl_rm_api_version *av)
-+{
-+    av->major   = NV_MAJOR_VERSION;
-+    av->minor   = NV_MINOR_VERSION;
-+    av->patch   = NV_PATCHLEVEL;
-+    av->version = NV_RM_API_VERSION;
-+
-+    return 0;
-+}
-+
-+int nvidia_get_card_info(struct nv_ioctl_card_info *ci)
-+{
-+    int i;
-+    struct nvidia_softc *sc;
-+    nv_state_t *nv;
-+
-+    /*
-+     * Clients supporting versioning will pass version magic in the first
-+     * card information field.
-+     */
-+    struct nv_ioctl_rm_api_version *av = (void *) ci;
-+
-+    if (av->magic != NV_RM_API_VERSION_MAGIC_REQ ||
-+        av->version != NV_RM_API_VERSION) {
-+        /*
-+         * This client either has no versioning support its version isn't
-+         * identical to ours. While this is fine most of the time, it can
-+         * result in severe problems.
-+         */
-+        av->magic   = NV_RM_API_VERSION_MAGIC_REP;
-+        av->major   = NV_MAJOR_VERSION;
-+        av->minor   = NV_MINOR_VERSION;
-+        av->patch   = NV_PATCHLEVEL;
-+        av->version = NV_RM_API_VERSION;
-+
-+        return -EINVAL;
-+    }
-+
-+    /* clear card information structure */
-+    memset(ci, 0, sizeof(ci));
-+
-+    for (i = 0; i < NV_MAX_DEVICES; i++) {
-+        sc = devclass_get_softc(nvidia_devclass, i);
-+        if (!sc)
-+            continue;
-+        nv = sc->nv_state;
-+
-+        ci[i].flags          = (NV_IOCTL_CARD_INFO_FLAG_PRESENT |
-+                                NV_IOCTL_CARD_INFO_FLAG_NEED_MSYNC);
-+        ci[i].bus            = nv->bus;
-+        ci[i].slot           = nv->slot;
-+        ci[i].vendor_id      = nv->vendor_id;
-+        ci[i].device_id      = nv->device_id;
-+        ci[i].interrupt_line = nv->interrupt_line;
-+        ci[i].fb_address     = nv->bar.fb.address;
-+        ci[i].fb_size        = nv->bar.fb.size;
-+        ci[i].reg_address    = nv->bar.regs.address;
-+        ci[i].reg_size       = nv->bar.regs.size;
-+    }
-+
-+    return 0;
-+}
-+
-+
-+int nvidia_handle_ioctl(
-+    dev_t dev,
-+    u_long cmd,
-+    caddr_t data,
-+    int fflag,
-+    d_thread_t *td
-+)
-+{
-+    struct nvidia_softc *sc;
-+    nv_state_t *nv;
-+    int unit = minor(dev);
-+
-+    if (unit == CDEV_CTL_MINOR) {
-+        /* the control device is "special" */
-+        nv = &nvidia_ctl_state;
-+    } else {
-+        sc = devclass_get_softc(nvidia_devclass, unit);
-+        if (!sc)
-+            return ENXIO;
-+        nv = sc->nv_state;
-+    }
-+
-+    NV_PCI_ENABLE_DEVICE(nv);
-+
-+    if (rm_ioctl(nv, __TD_FDT(td), __NV_IOC_NR(cmd), data))
-+        return 0;
-+
-+    return EINVAL;
-+}
-+
-+
-+int nvidia_open_ctl(void)
-+{
-+    struct nvidia_softc *sc;
-+    nv_state_t *nv = &nvidia_ctl_state;
-+
-+    sc = nv->os_state;
-+    sc->refcnt++;
-+
-+    nv->device_number = NV_CONTROL_DEVICE_NUMBER;
-+
-+    nv->flags |= NV_FLAG_OPEN;
-+    nv->flags |= NV_FLAG_CONTROL;
-+
-+    nv->flags &= ~NV_FLAG_HOTKEY_OCCURRED;
-+
-+    return 0;
-+}
-+
-+int nvidia_close_ctl(
-+    dev_t dev,
-+    d_thread_t *td
-+)
-+{
-+    struct nvidia_softc *sc;
-+    nv_state_t *nv = &nvidia_ctl_state;
-+
-+    if (__TD_FDT_CNT(td) == 0)
-+        rm_free_unused_clients(nv, 0, __TD_FDT(td));
-+
-+    sc = nv->os_state;
-+    sc->refcnt--;
-+
-+    if (sc->refcnt == 0) {
-+        /*
-+         * The control device has been released; without physical devices
-+         * backing it, we only need to reset the flags.
-+         */
-+        nv->flags = 0;
-+    }
-+
-+    return 0;
-+}
-+
-+int nvidia_open_dev(struct nvidia_softc *sc)
-+{
-+    nv_state_t *nv = sc->nv_state;
-+
-+    NV_PCI_ENABLE_DEVICE(nv);
-+
-+    if ((nv->flags & NV_FLAG_OPEN) == 0) {
-+        /*
-+         * The device flags indicate that this device has not been opened
-+         * or else shut down previously. There isn't much we can do here,
-+         * the core resource manager does the actual work. We update both
-+         * the flags and the usage count.
-+         */
-+        STAILQ_INIT(&sc->event_queue);
-+
-+        if (!rm_init_adapter(nv)) {
-+            device_printf(sc->dev, "NVRM: rm_init_adapter() failed!\n");
-+            return EIO;
-+        }
-+
-+        nv->flags |= NV_FLAG_OPEN;
-+    }
-+
-+    sc->refcnt++;
-+
-+    return 0;
-+}
-+
-+int nvidia_close_dev(
-+    struct nvidia_softc *sc,
-+    dev_t dev,
-+    d_thread_t *td
-+)
-+{
-+    nv_state_t *nv = sc->nv_state;
-+    nv_os_event_t *et;
-+
-+    NV_PCI_ENABLE_DEVICE(nv);
-+
-+    if (__TD_FDT_CNT(td) == 0)
-+        rm_free_unused_clients(nv, 0, __TD_FDT(td));
-+
-+    sc->refcnt--;
-+
-+    if (sc->refcnt == 0) {
-+        /*
-+         * The usage count for this device has dropped to zero, it can be
-+         * safely shut down. We don't need to wait for bottom-halfes like
-+         * we do on Linux, they are not run asynchronously on FreeBSD. We
-+         * do need to reset certain flags, though.
-+         */
-+        rm_disable_adapter(nv);
-+        rm_shutdown_adapter(nv);
-+
-+        while ((et = STAILQ_FIRST(&sc->event_queue))) {
-+            STAILQ_REMOVE(&sc->event_queue, et, nv_os_event, queue);
-+            free(et, M_NVIDIA);
-+        }
-+
-+        nv->flags &= ~NV_FLAG_OPEN;
-+    }
-+
-+    return 0;
-+}
-+
-+
-+int nvidia_modevent(
-+    module_t mod,
-+    int what,
-+    void *arg
-+)
-+{
-+    nv_state_t *nv;
-+    struct nvidia_softc *sc;
-+
-+    switch (what) {
-+        case MOD_LOAD:
-+            /*
-+             * The module load event. Our KLD has just been loaded and is
-+             * ready to initialize. We setup the core resource manager in
-+             * this routine, further initialization takes place at attach
-+             * time.
-+             */
-+            if (!rm_init_rm()) {
-+                printf("NVRM: rm_init_rm() failed!\n");
-+                return EIO;
-+            }
-+
-+            nvidia_sysctl_init();
-+            nvidia_linux_init();
-+            rm_load_registry(nv_parms);
-+
-+            break;
-+
-+        case MOD_UNLOAD:
-+            /*
-+             * Check if the control device is still open and reject the
-+             * unload request if it is. This event can occur even when the
-+             * module usage count is non-zero!
-+             */
-+            nv = &nvidia_ctl_state;
-+            sc = nv->os_state;
-+
-+            if (sc->refcnt != 0) /* XXX Fix me? (refcnt) */
-+                return EBUSY;
-+
-+            rm_shutdown_rm();
-+
-+            nvidia_sysctl_exit();
-+            nvidia_linux_exit();
-+
-+            break;
-+
-+        default:
-+            break;
-+    }
-+
-+    return 0;
-+}
-+
-+
-+#ifdef NV_SUPPORT_OS_AGP
-+S032 nv_os_agp_init(
-+    nv_state_t *nv,
-+    void **base,
-+    void **linear,
-+    U032 *limit
-+)
-+{
-+    void *bitmap;
-+    struct nvidia_softc *sc = nv->os_state;
-+    struct agp_info ai;
-+
-+    U032 mode = 0;
-+    U032 fw   = 0;
-+    U032 sba  = 0;
-+    U032 rate = AGP_MODE_RATE_1x | AGP_MODE_RATE_2x | AGP_MODE_RATE_4x;
-+    U032 size = 0;
-+
-+    sc->agp_dev = agp_find_device();
-+    if (!sc->agp_dev) {
-+        printf("NVRM: agp_find_device failed, chipset unsupported?\n");
-+        return -ENODEV;
-+    }
-+
-+    if (agp_acquire(sc->agp_dev) != 0)
-+        return -EBUSY;
-+
-+    agp_get_info(sc->agp_dev, &ai);
-+    mode = ai.ai_mode;
-+
-+    if (os_set_mem_range(ai.ai_aperture_base, ai.ai_aperture_size,
-+                NV_MEMORY_WRITECOMBINED) != RM_OK) {
-+        /*
-+         * Failure to set a write-combining range for the AGP aperture is
-+         * not necessarily a fatal error condition; we don't know at this
-+         * point, however, and abort to prevent performance and stability
-+         * problems that may be hard to track down otherwise.
-+         */
-+        agp_release(sc->agp_dev);
-+        return -EIO;
-+    }
-+
-+    rm_read_registry_dword(nv, "NVreg", "ReqAGPRate", &rate);
-+    rm_read_registry_dword(nv, "NVreg", "EnableAGPFW", &fw);
-+    rm_read_registry_dword(nv, "NVreg", "EnableAGPSBA", &sba);
-+
-+    mode = AGP_MODE_SET_RATE(mode, AGP_MODE_GET_RATE(mode) & rate);
-+    mode = AGP_MODE_SET_FW(mode, fw);
-+    mode = AGP_MODE_SET_SBA(mode, sba);
-+
-+    if (agp_enable(sc->agp_dev, mode) != 0) {
-+        agp_release(sc->agp_dev);
-+        os_unset_mem_range(ai.ai_aperture_base, ai.ai_aperture_size);
-+        return -EIO;
-+    }
-+
-+    size = ai.ai_aperture_size / RM_PAGE_SIZE / 8;
-+    
-+    if (os_alloc_mem(&bitmap, size) != RM_OK) {
-+        agp_release(sc->agp_dev);
-+        os_unset_mem_range(ai.ai_aperture_base, ai.ai_aperture_size);
-+        return -EIO;
-+    }
-+
-+    os_mem_set(bitmap, 0xff, size);
-+
-+    if (rm_set_agp_bitmap(nv, bitmap) != RM_OK) {
-+        agp_release(sc->agp_dev);
-+        os_free_mem(bitmap);
-+        os_unset_mem_range(ai.ai_aperture_base, ai.ai_aperture_size);
-+        return -EIO;
-+    }
-+
-+    *base   = (void *) ai.ai_aperture_base;
-+    *linear = (void *) ai.ai_aperture_va;
-+    *limit  = (U032)   ai.ai_aperture_size - 1;
-+
-+    return 0;
-+}
-+
-+S032 nv_os_agp_teardown(nv_state_t *nv)
-+{
-+    struct nvidia_softc *sc = nv->os_state;
-+    void *bitmap;
-+
-+    if (agp_release(sc->agp_dev) != 0)
-+        return -EBUSY;
-+
-+    rm_clear_agp_bitmap(nv, &bitmap);
-+    os_free_mem(bitmap);
-+
-+    os_unset_mem_range(nv->agp.address, nv->agp.size);
-+
-+    return 0;
-+}
-+#endif /* NV_SUPPORT_OS_AGP */
-+
-+S032 nv_agp_init(
-+    nv_state_t *nv,
-+    void **base,
-+    void **linear,
-+    void *limit,
-+    U032 config
-+)
-+{
-+    if (config == NVOS_AGP_CONFIG_DISABLE_AGP)
-+        return 1;
-+
-+    if ((config & NVOS_AGP_CONFIG_OSAGP) != 0) {
-+#ifndef NV_SUPPORT_OS_AGP
-+        /*
-+         * Inform the user that the kernel module needs to be built
-+         * with FreeBSD AGP GART driver (agp.ko) support.
-+         */
-+        /* XXX Fix me? (agp.ko) */
-+        /* printf("NVRM: build nvidia.ko with FreeBSD agp.ko support.\n"); */
-+#else
-+        if (nv_os_agp_init(nv, base, linear, limit) == 0) {
-+            /*
-+             * If the operating system AGP GART driver successfully
-+             * configured its backend, apply chipset overrides.
-+             */
-+            rm_update_agp_config(nv);
-+            nv->agp_config = NVOS_AGP_CONFIG_OSAGP;
-+            return 0;
-+        }
-+#endif /* NV_SUPPORT_OS_AGP */
-+    }
-+
-+    if ((config & NVOS_AGP_CONFIG_NVAGP) == 0)
-+        goto failed;
-+
-+    if (devclass_get_softc(devclass_find("agp"), 0) != NULL) {
-+        /*
-+         * Make sure we don't try to use the internal GART driver when
-+         * the OS AGPGART driver (agp.ko) is attached. While that may
-+         * be perfectly fine on most systems, but is known to break on
-+         * some.
-+         * -------------------------------------------------------------
-+         * DON'T REDISTRIBUTE THE DRIVER WITH THIS SANITY CHECK REMOVED!
-+         * -------------------------------------------------------------
-+         */
-+        printf("NVRM: detected agp.ko, aborting NVIDIA AGP setup!\n");
-+        goto failed;
-+    }
-+
-+    if (rm_init_agp(nv) == RM_OK) {
-+        nv->agp_config = NVOS_AGP_CONFIG_NVAGP;
-+        return 0;
-+    }
-+
-+failed:
-+    nv->agp_config = NVOS_AGP_CONFIG_DISABLE_AGP;
-+    return -EIO;
-+}
-+
-+S032 nv_agp_teardown(nv_state_t *nv)
-+{
-+    S032 status = -EINVAL;
-+
-+    switch (nv->agp_config) {   /* see above */
-+#ifdef NV_SUPPORT_OS_AGP
-+        case NVOS_AGP_CONFIG_OSAGP:
-+            /*
-+             * Release the backend, the AGP core logic will remain
-+             * initialized. This is by design (agp.ko).
-+             */
-+            status = nv_os_agp_teardown(nv);
-+            break;
-+#endif
-+        case NVOS_AGP_CONFIG_NVAGP:
-+            /*
-+             * Shut down the NVIDIA AGP GART driver, clearning all
-+             * internal state.
-+             */
-+            status = rm_teardown_agp(nv);
-+            break;
-+    }
-+
-+    nv->agp_config = NVOS_AGP_CONFIG_DISABLE_AGP;
-+    return status;
-+}
-+
-+S032 nv_no_incoherent_mappings(void)
-+{
-+    /* XXX Fix me! (no_incoherent_mappings) */
-+    return 0;
-+}
-+
-+void* nv_find_agp_kernel_mapping(
-+    nv_state_t *nv,
-+    ULONG address
-+)
-+{
-+    /* XXX Implement me? (kmap lookup) */
-+    return NULL;
-+}
-+
-+
-+void nv_lock_rm(nv_state_t *nv)
-+{
-+    /* 
-+     * While SMP configurations are handled with a global kernel lock and
-+     * in such a way that only one of the CPUs is executing a process and
-+     * servicing interrupts at any point in time, it is possible that the
-+     * interrupt handlers (th/bh) may interfere with critical code.
-+     *
-+     * This "lock" thus disables interrupts for the duration of this code
-+     * segment's execution.
-+     */
-+    crit_enter();
-+}
-+
-+void nv_unlock_rm(nv_state_t *nv)
-+{
-+    /*
-+     * Restore the interrupt mask upon existing the critical code segment
-+     * and thus allow interrupt handlers to execute again.
-+     */
-+    crit_exit();
-+}
-+
-+
-+void nv_lock_api(nv_state_t *nv)
-+{
-+    /*
-+     * Since it is entirely possible that we involuntarily go to sleep at
-+     * certain points in time, we make sure that we execute only a single
-+     * of our system calls at a time.
-+     */
-+    struct nvidia_softc *sc = nv->os_state;
-+    lockmgr(&sc->api_lock, LK_EXCLUSIVE, 0, CURTHREAD);
-+}
-+
-+void nv_unlock_api(nv_state_t *nv)
-+{
-+    /*
-+     * Release the API lock and allow a process sleeping on it to execute
-+     * its system call.
-+     */
-+    struct nvidia_softc *sc = nv->os_state;
-+    lockmgr(&sc->api_lock, LK_RELEASE, 0, CURTHREAD);
-+}
-+
-+
-+void nv_post_event(
-+    nv_state_t *nv,
-+    nv_event_t *event,
-+    U032 hObject,
-+    U032 index
-+)
-+{
-+    struct nvidia_softc *sc;
-+    nv_os_event_t *et; 
-+
-+    if (!(et = malloc(sizeof(nv_os_event_t), M_NVIDIA, M_ZERO)))
-+        return;
-+
-+    et->event = *event;
-+    et->event.hObject = hObject;
-+    et->event.index = index;
-+
-+    nv_lock_rm(nv);
-+
-+    sc = nv->os_state;
-+    STAILQ_INSERT_TAIL(&sc->event_queue, et, queue);
-+
-+    nv_unlock_rm(nv);
-+
-+/*  printf("NVRM: nv_post_event()\n");
-+    printf("NVRM:     hParent: 0x%08x\n", et->event.hParent);
-+    printf("NVRM:     hObject: 0x%08x\n", et->event.hObject); */
-+
-+    /* XXX Fix me? (os events) */
-+    selwakeup(&sc->rsel);
-+}
-+
-+S032 nv_get_event(
-+    nv_state_t *nv,
-+    void *file,
-+    nv_event_t *event,
-+    U032 *pending
-+)
-+{
-+    struct nvidia_softc *sc = nv->os_state;
-+    nv_os_event_t *et;
-+
-+    nv_lock_rm(nv);
-+
-+    if (!(et = STAILQ_FIRST(&sc->event_queue))) {
-+        nv_unlock_rm(nv);
-+        return RM_ERROR; /* RM polling? */
-+    }
-+
-+    *event = et->event;
-+
-+    STAILQ_REMOVE_HEAD(&sc->event_queue, queue);
-+    free(et, M_NVIDIA);
-+
-+/*  printf("NVRM: nv_get_event(), %d\n", *pending);
-+    printf("NVRM:     hParent: 0x%08x\n", event->hParent);
-+    printf("NVRM:     hObject: 0x%08x\n", event->hObject); */
-+    
-+    /* XXX: Fix me? (os events) */
-+    *pending = !(STAILQ_EMPTY(&sc->event_queue));
-+
-+    nv_unlock_rm(nv);
-+
-+    return RM_OK;
-+}
-+
-+void* nv_find_alloc(
-+    nv_state_t *nv,
-+    vm_offset_t address
-+)
-+{
-+    nv_alloc_t *at;
-+    struct nvidia_softc *sc = nv->os_state;
-+
-+    SLIST_FOREACH(at, &sc->alloc_list, list) {
-+        /*
-+         * XXX Match an incoming address to a known allocation. We
-+         * should use type flags here.
-+         */
-+        if (at->address == address)
-+            return (void *) at;
-+    }
-+
-+    return NULL;
-+}
-+
-+void* nv_find_alloc_obj(
-+    nv_state_t *nv,
-+    vm_offset_t object
-+)
-+{
-+    nv_alloc_t *at;
-+    struct nvidia_softc *sc = nv->os_state;
-+
-+    SLIST_FOREACH(at, &sc->alloc_list, list) {
-+        /*
-+         * XXX Match the incoming object to a known allocation. We
-+         * should use type flags here.
-+         */
-+        if (at->object == (vm_object_t) object)
-+            return (void *) at;
-+    }
-+
-+    return NULL;
-+}
-+
-+void* nv_find_nv_mapping(
-+    nv_state_t *nv,
-+    ULONG address
-+)
-+{
-+    nv_alloc_t *at;
-+    struct nvidia_softc *sc = nv->os_state;
-+    vm_offset_t offset, linear;
-+
-+    offset = (vm_offset_t) address & PAGE_MASK;
-+    address &= ~PAGE_MASK;
-+
-+    SLIST_FOREACH(at, &sc->alloc_list, list) {
-+        /*
-+         * XXX Match an incoming address to a known allocation. We
-+         * should use type flags here.
-+         */
-+        if (at->address == 0)
-+            continue;
-+        linear = at->address;
-+        do {
-+            if (vtophys(linear) == (vm_offset_t) address)
-+                return (void *)(linear + offset);
-+            linear += PAGE_SIZE;
-+        } while (linear < (at->address + at->size));
-+    }
-+
-+    return NULL;
-+}
-+
-+ULONG nv_find_dma_mapping(
-+    nv_state_t *nv,
-+    ULONG address
-+)
-+{
-+    /* XXX Fix me? (x86 only, amd64 dma) */
-+    return address;
-+}
-+
-+S032 nv_agp_translate_address(
-+    nv_state_t *nv,
-+    void *base,
-+    U032 index,
-+    U032 *address
-+)
-+{
-+    nv_alloc_t *at;
-+    struct nvidia_softc *sc = nv->os_state;
-+
-+    vm_page_t m;
-+
-+    SLIST_FOREACH(at, &sc->alloc_list, list) {
-+        /*
-+         * The purpose of this function is to extract the actual physical
-+         * addresses of each page in the allocation with the base address
-+         * passed by the caller.
-+         */
-+        if (at->object == (vm_object_t) base &&
-+            at->size > index * PAGE_SIZE) {
-+            VM_OBJECT_LOCK(at->object);
-+            m = vm_page_lookup(at->object, index);
-+            *address = VM_PAGE_TO_PHYS(m);
-+            VM_OBJECT_UNLOCK(at->object);
-+            return 0;
-+        }
-+    }
-+
-+    return -1;
-+}
-+
-+S032 nv_alloc_contig_pages(
-+    nv_state_t *nv,
-+    void **address,
-+    U032 count
-+)
-+{
-+    nv_alloc_t *at;
-+    struct nvidia_softc *sc = nv->os_state;
-+    U032 size = count * PAGE_SIZE;
-+
-+    if (os_alloc_contig_pages(address, size) != RM_OK)
-+        return -ENOMEM;
-+
-+    at = malloc(sizeof(nv_alloc_t), M_NVIDIA, M_WAITOK | M_ZERO);
-+    if (!at) {
-+        os_free_contig_pages(*address, size);
-+        return -ENOMEM;
-+    }
-+
-+    at->object = 0;
-+    at->size = size;
-+    at->address = (vm_offset_t) *address;
-+    at->offset = ~0;
-+
-+    SLIST_INSERT_HEAD(&sc->alloc_list, at, list);
-+
-+    return 0;
-+}
-+
-+S032 nv_free_contig_pages(
-+    nv_state_t *nv,
-+    void *address
-+)
-+{
-+    nv_alloc_t *at;
-+    struct nvidia_softc *sc = nv->os_state;
-+    U032 size;
-+
-+    at = nv_find_alloc(nv, (vm_offset_t) address);
-+    if (!at) {
-+        os_dbg_breakpoint();
-+        return -EINVAL;
-+    }
-+
-+    size = at->size;
-+    SLIST_REMOVE(&sc->alloc_list, at, nv_alloc, list);
-+
-+    free(at, M_NVIDIA);
-+    os_free_contig_pages(address, size);
-+
-+    return 0;
-+}
-+
-+S032 nv_alloc_system_pages(
-+    nv_state_t  *nv,
-+    void **address,
-+    U032 count
-+)
-+{
-+    nv_alloc_t *at;
-+    struct nvidia_softc *sc = nv->os_state;
-+
-+    void *vm;
-+    u_int32_t i, size = count * PAGE_SIZE;
-+
-+    at = malloc(sizeof(nv_alloc_t), M_NVIDIA, M_WAITOK | M_ZERO);
-+    if (!at) {
-+        return -ENOMEM;
-+    }
-+
-+    vm = malloc(size, M_NVIDIA, M_WAITOK | M_ZERO);
-+    if (!vm) {
-+        free(at, M_NVIDIA);
-+        return -ENOMEM;
-+    }
-+
-+    at->pte = malloc(sizeof(vm_offset_t) * count, M_NVIDIA, M_WAITOK);
-+    if (!at->pte) {
-+        free(at, M_NVIDIA);
-+        free(vm, M_NVIDIA);
-+        return -ENOMEM;
-+    }
-+
-+    for (i = 0; i < count; i++) {
-+        at->pte[i] = vtophys((vm_offset_t) vm + (i * PAGE_SIZE));
-+        vm_page_lock_queues();
-+        vm_page_wire(PHYS_TO_VM_PAGE(at->pte[i]));
-+        vm_page_unlock_queues();
-+    }
-+
-+    at->object = 0;
-+    at->size = size;
-+    at->address = (vm_offset_t) vm;
-+    at->offset = ~0;
-+
-+    SLIST_INSERT_HEAD(&sc->alloc_list, at, list);
-+    *address = (void *) at->address;
-+
-+    return 0;
-+}
-+
-+S032 nv_free_system_pages(
-+    nv_state_t *nv,
-+    void *address
-+)
-+{
-+    nv_alloc_t *at;
-+    struct nvidia_softc *sc = nv->os_state;
-+
-+    vm_offset_t pa;
-+    u_int32_t i, count;
-+
-+    at = nv_find_alloc(nv, (vm_offset_t) address);
-+    if (!at) {
-+        os_dbg_breakpoint();
-+        return -EINVAL;
-+    }
-+
-+    count = at->size / PAGE_SIZE;
-+    SLIST_REMOVE(&sc->alloc_list, at, nv_alloc, list);
-+
-+    for (i = 0; i < count; i++) {
-+        pa = vtophys(at->address + (i * PAGE_SIZE));
-+        vm_page_lock_queues();
-+        vm_page_unwire(PHYS_TO_VM_PAGE(pa), 0);
-+        vm_page_unlock_queues();
-+    }
-+
-+    free(at->pte, M_NVIDIA);
-+    free(at, M_NVIDIA);
-+    free(address, M_NVIDIA);
-+
-+    return 0;
-+}
-+
-+
-+S032 nv_alloc_vm_object(
-+    nv_state_t *nv,
-+    void **address,
-+    U032 count
-+)
-+{
-+    nv_alloc_t *at;
-+    struct nvidia_softc *sc = nv->os_state;
-+
-+    u_int32_t i, j;
-+    vm_page_t m;
-+    vm_object_t object;
-+
-+    at = malloc(sizeof(nv_alloc_t), M_NVIDIA, M_WAITOK | M_ZERO);
-+    if (!at) {
-+        return -ENOMEM;
-+    }
-+
-+    object = vm_object_allocate(OBJT_DEFAULT, count);
-+
-+    for (i = 0; i < count; i++) {
-+        /*
-+         * Find the individual pages belonging to the allocation from the
-+         * VM object; since this is the first time they're accessed, they
-+         * will be allocated.
-+         */
-+
-+#if __FreeBSD_version >= 500000
-+        /*
-+         * Request that this range of pages be wired down to prevent them
-+         * from being paged out. This is done below for FreeBSD 4.
-+         */
-+        VM_OBJECT_LOCK(object);
-+        m = vm_page_grab(object, i, VM_ALLOC_NORMAL | VM_ALLOC_WIRED);
-+        VM_OBJECT_UNLOCK(object);
-+#else
-+        m = vm_page_grab(object, i, VM_ALLOC_NORMAL);
-+#endif
-+        if (!m) {
-+            VM_OBJECT_LOCK(object);
-+            for (j = 0; j < i; j++) {
-+                m = vm_page_lookup(object, j);
-+                vm_page_lock_queues();
-+                vm_page_unwire(m, 0);
-+                vm_page_unlock_queues();
-+            }
-+            VM_OBJECT_UNLOCK(object);
-+            return -ENOMEM;
-+        }
-+
-+#if __FreeBSD_version < 500000
-+        vm_page_wire(m);
-+#endif
-+        vm_page_lock_queues();
-+        vm_page_wakeup(m);
-+        vm_page_unlock_queues();
-+    }
-+
-+    at->object = object;
-+    at->offset = ~0;
-+    at->size = ptoa(count);
-+    at->address = 0;
-+
-+    SLIST_INSERT_HEAD(&sc->alloc_list, at, list);
-+    *address = (void *) at->object;
-+
-+    return 0;
-+}
-+
-+S032 nv_free_vm_object(
-+    nv_state_t *nv,
-+    void *address
-+)
-+{
-+    nv_alloc_t *at;
-+    struct nvidia_softc *sc = nv->os_state;
-+
-+    vm_page_t m;
-+    u_int32_t i, count;
-+
-+    at = nv_find_alloc_obj(nv, (vm_offset_t) address);
-+    if (!at) {
-+        os_dbg_breakpoint();
-+        return -EINVAL;
-+    }
-+
-+    count = at->size / PAGE_SIZE;
-+    SLIST_REMOVE(&sc->alloc_list, at, nv_alloc, list);
-+
-+    VM_OBJECT_LOCK(at->object);
-+    for (i = 0; i < count; i++) {
-+        /*
-+         * Release "one wiring" of this page; this may reenable paging as
-+         * a result, depending on the total number of "wirings".
-+         */
-+        m = vm_page_lookup(at->object, i);
-+        vm_page_lock_queues();
-+        vm_page_unwire(m, 0);
-+        vm_page_unlock_queues();
-+    }
-+    VM_OBJECT_UNLOCK(at->object);
-+
-+    vm_object_deallocate(at->object);
-+    free(at, M_NVIDIA);
-+
-+    return 0;
-+}
-+
-+
-+#ifdef NV_SUPPORT_OS_AGP
-+S032 nv_alloc_agp_pages(
-+    nv_state_t *nv,
-+    void **address,
-+    U032 count,
-+    U032 offset,
-+    void **private
-+)
-+{
-+    void *handle;
-+    struct nvidia_softc *sc = nv->os_state;
-+
-+    handle = agp_alloc_memory(sc->agp_dev, 0, count << PAGE_SHIFT);
-+    if (!handle) {
-+        /*
-+         * This is very unlikely to happen, the system's memory resources
-+         * would have to be nearly exhausted.
-+         */
-+        return -ENOMEM;
-+    }
-+
-+    if (agp_bind_memory(sc->agp_dev, handle, offset) != 0) {
-+        /*
-+         * This shouldn't happen, we claimed the AGP backend and are thus
-+         * using it exclusively; the resource manager manages AGP offsets
-+         * internally, we wouldn't have been called had we run out of AGP
-+         * aperture space.
-+         */
-+        os_dbg_breakpoint();
-+
-+        agp_free_memory(sc->agp_dev, handle);
-+        return -ENOMEM;
-+    }
-+
-+    *private = handle;
-+    return 0;
-+}
-+
-+S032 nv_free_agp_pages(
-+    nv_state_t *nv,
-+    void **address,
-+    U032 count,
-+    void *handle
-+)
-+{
-+    struct nvidia_softc *sc = nv->os_state;
-+
-+    if (agp_unbind_memory(sc->agp_dev, handle) != 0) {
-+        /*
-+         * This is the only place where previously bound AGP memory would
-+         * be freed. If we fail to unbind this memory now, something very
-+         * wrong must have happened.
-+         */
-+        os_dbg_breakpoint();
-+    }
-+
-+    agp_free_memory(sc->agp_dev, handle);
-+    return 0;
-+}
-+#endif /* NV_SUPPORT_OS_AGP */
-+
-+
-+S032 nv_alloc_pages(
-+    nv_state_t *nv,
-+    void **address,
-+    U032 count,
-+    U032 alloc_type_agp,
-+    U032 alloc_type_contiguous,
-+    U032 cache,
-+    U032 alloc_type_kernel,
-+    U032 class,
-+    void **private
-+)
-+{
-+    /* XXX Fix me! (cache types) */
-+    U032 alloc_type_cached = (cache != NV_MEMORY_UNCACHED);
-+
-+    if (alloc_type_agp) {
-+#ifdef NV_SUPPORT_OS_AGP
-+        U032 offset;
-+
-+        if ((nv->agp_config & NVOS_AGP_CONFIG_OSAGP) == 0)
-+            return -EINVAL;
-+
-+        if (rm_alloc_agp_bitmap(nv, count, &offset) != RM_OK) {
-+            /*
-+             * We've run out of AGP aperture space, the requestor will be
-+             * forced to fall back to general system memory.
-+             */
-+            return -ENOMEM;
-+        }
-+
-+        if (nv_alloc_agp_pages(nv, address, count, offset << PAGE_SHIFT,
-+                private) != 0) {
-+            /*
-+             * The AGP aperture is managed internally by core resman, the
-+             * offset passed to us should work; thus, this shouldn't fail
-+             * unless the system memory is exhausted.
-+             */
-+            rm_free_agp_bitmap(nv, offset, count);
-+            return -ENOMEM;
-+        }
-+
-+        *address = (void *)(nv->agp.address + (offset << PAGE_SHIFT));
-+        return 0;
-+#else
-+        nv_alloc_t *at;
-+
-+        if ((nv->agp_config & NVOS_AGP_CONFIG_NVAGP) == 0)
-+            return -EINVAL;
-+
-+        if (nv_alloc_vm_object(nv, address, count) != 0) {
-+            /*
-+             * Hopefully, this error condition will be much more unlikely
-+             * to occur than failure to allocate the same number of pages
-+             * with nv_alloc_system_pages.
-+             */
-+            return -ENOMEM;
-+        }
-+
-+        at = nv_find_alloc_obj(nv, (vm_offset_t) *address);
-+        if (!at) {
-+            os_dbg_breakpoint();
-+            return -ENOMEM;
-+        }
-+
-+        if (rm_alloc_agp_pages(nv, address, count, class, private,
-+                &at->offset) != RM_OK) {
-+            /*
-+             * In theory, this should only fail if we run out of aperture
-+             * space (which is not unlikely).
-+             */
-+            nv_free_vm_object(nv, *address);
-+            return -ENOMEM;
-+        }
-+
-+        *address = (void *)(nv->agp.address + (at->offset << PAGE_SHIFT));
-+        return 0;
-+#endif /* NV_SUPPORT_OS_AGP */
-+    } else {
-+        /*
-+         * Save the allocation parameters for use in nv_free_pages, where
-+         * we won't have access to all of them (sigh).
-+         */
-+        nv_alloc_private_t *ap;
-+        vm_offset_t vm;
-+
-+        /* XXX Fix me! (PAT) */
-+        if (cache == NV_MEMORY_WRITECOMBINED)
-+            return -ENOMEM;
-+
-+        ap = malloc(sizeof(nv_alloc_private_t), M_NVIDIA, M_WAITOK | M_ZERO);
-+        if (!ap) {
-+            return -ENOMEM;
-+        }
-+        *private = (void *) ap;
-+
-+        ap->count = count;
-+        ap->alloc_type_contiguous = alloc_type_contiguous;
-+        ap->alloc_type_cached = alloc_type_cached;
-+        ap->alloc_type_kernel = alloc_type_kernel;
-+        ap->class = class;
-+
-+        if (alloc_type_kernel &&
-+            !alloc_type_contiguous && alloc_type_cached) {
-+            /*
-+             * Obtain general system memory for the resource mananger, it
-+             * doesn't need to be contiguous.
-+             */
-+            if (nv_alloc_system_pages(nv, address, count))
-+                goto failed;
-+
-+        } else if (alloc_type_contiguous ||
-+                   (alloc_type_kernel && !alloc_type_cached)) {
-+            /*
-+             * Make sure the pages are contiguous in physical memory; the
-+             * memory will not be used for DMA push buffers, the returned
-+             * linear mapping is expected to be usable as-is.
-+             */
-+            if (nv_alloc_contig_pages(nv, address, count))
-+                goto failed;
-+
-+            /* XXX Fix me! (uc kernel) */
-+            if (alloc_type_kernel && !alloc_type_cached)
-+                /* goto failed */;
-+
-+        } else if (!alloc_type_kernel) {
-+            /*
-+             * Allocate general system memory for DMA push buffers. These
-+             * pages may be non-contiguous; the individual addresses must
-+             * be retrievable from the mmap(2) implementation.
-+             */
-+            if (nv_alloc_system_pages(nv, address, count))
-+                goto failed;
-+
-+            vm = ((vm_offset_t) *address) - VM_MIN_KERNEL_ADDRESS;
-+            *address = (void *) vm;
-+        }
-+
-+        return 0;
-+
-+failed:
-+        free(*private, M_NVIDIA);
-+        return -ENOMEM;
-+    }
-+}
-+
-+S032 nv_free_pages(
-+    nv_state_t *nv,
-+    void **address,
-+    U032 count,
-+    U032 alloc_type_agp,
-+    void *private
-+)
-+{
-+    U032 offset;
-+    offset = ((U032) *address - nv->agp.address) >> PAGE_SHIFT;
-+
-+    if (alloc_type_agp) {
-+#ifdef NV_SUPPORT_OS_AGP
-+        if ((nv->agp_config & NVOS_AGP_CONFIG_OSAGP) == 0)
-+            return -EINVAL;
-+
-+        if (nv_free_agp_pages(nv, address, count, private) != 0) {
-+            /*
-+             * The following is a sanity check, this mustn't ever fail in
-+             * in real-world scenario.
-+             */
-+            os_dbg_breakpoint();
-+            return -EINVAL;
-+        }
-+
-+        rm_free_agp_bitmap(nv, offset, count);
-+#else
-+        nv_alloc_t *at;
-+        struct nvidia_softc *sc = nv->os_state;
-+
-+        if ((nv->agp_config & NVOS_AGP_CONFIG_NVAGP) == 0)
-+            return -EINVAL;
-+
-+        if (rm_free_agp_pages(nv, address, private) != RM_OK) {
-+            /*
-+             * Don't free the underlying system memory unless the request
-+             * to free the RM AGP resources completes successfully, which
-+             * should never actually fail.
-+             */
-+            os_dbg_breakpoint();
-+            return -EINVAL;
-+        }
-+
-+        SLIST_FOREACH(at, &sc->alloc_list, list) {
-+            if (at->offset == offset) {
-+                nv_free_vm_object(nv, (void *)at->object);
-+                break;
-+            }
-+        }
-+#endif /* NV_SUPPORT_OS_AGP */
-+
-+        return 0;
-+    } else {
-+        nv_alloc_private_t *ap;
-+        vm_offset_t vm;
-+
-+	ap = (nv_alloc_private_t *) private;
-+        if (!ap) {
-+            os_dbg_breakpoint();
-+            return -EINVAL;
-+        }
-+
-+        if (ap->alloc_type_kernel &&
-+            !ap->alloc_type_contiguous && ap->alloc_type_cached) {
-+            /*
-+             * Generic system memory used by the resource manager; almost
-+             * identical to the user memory case.
-+             */
-+            if (nv_free_system_pages(nv, *address))
-+                return -EINVAL;
-+
-+        } else if (ap->alloc_type_contiguous ||
-+                   (ap->alloc_type_kernel && !ap->alloc_type_cached)) {
-+            /*
-+             * Free contigous system memory; this resource is rarely used
-+             * and hence managed globally.
-+             */
-+            if (nv_free_contig_pages(nv, *address))
-+                return -EINVAL;
-+
-+            /* XXX Fix me! (uc kernel) */
-+            if (ap->alloc_type_kernel && !ap->alloc_type_cached)
-+                /* return -EINVAL */;
-+
-+        } else if (!ap->alloc_type_kernel) {
-+            /*
-+             * XXX Generic system memory used for DMA push buffers. There
-+             * are munmap(2) considerations in this case on Linux, are we
-+             * really safe here?
-+             */
-+            vm = (vm_offset_t) *address;
-+            *address = (void *)(vm + VM_MIN_KERNEL_ADDRESS);
-+
-+            if (nv_free_system_pages(nv, *address))
-+                return -EINVAL;
-+        }
-+
-+        free(ap, M_NVIDIA);
-+        return 0;
-+    }
-+
-+    return -EINVAL;
-+}
-+
-+ULONG nv_get_kern_phys_address(ULONG address)
-+{
-+    vm_offset_t va = (vm_offset_t) address;
-+
-+    if (va < VM_MIN_KERNEL_ADDRESS) {
-+        os_dbg_breakpoint();
-+        return 0;
-+    }
-+
-+    return vtophys(va);
-+}
-+
-+ULONG nv_get_user_phys_address(ULONG address)
-+{
-+    struct vmspace *vm;
-+    vm_offset_t va = (vm_offset_t) address;
-+
-+    if (va >= VM_MIN_KERNEL_ADDRESS) {
-+        os_dbg_breakpoint();
-+        return 0;
-+    }
-+
-+    if (vm_fault_quick((caddr_t) va, VM_PROT_WRITE))
-+        return 0;
-+
-+    vm = curproc->p_vmspace;
-+    return pmap_extract(vmspace_pmap(vm), va);
-+}
-+
-+
-+int nvidia_mmap_dev(
-+    struct nvidia_softc *sc,
-+    vm_offset_t offset,
-+    vm_offset_t *physical
-+)
-+{
-+    nv_alloc_t *at;
-+    nv_state_t *nv = sc->nv_state;
-+
-+    NV_PCI_ENABLE_DEVICE(nv);
-+
-+    /*
-+     * Offsets that fall into the frame buffer, registry or AGP apertures
-+     * are physical addresses and mapped into user-space directly. We can
-+     * only do some basic sanity checking here.
-+     */
-+    if (IS_FB_OFFSET(nv, offset, PAGE_SIZE)) {
-+        *physical = offset;
-+        return 0;
-+    }
-+    
-+    if (IS_REG_OFFSET(nv, offset, PAGE_SIZE)) {
-+        *physical = offset;
-+        return 0;
-+    }
-+    
-+    if (IS_AGP_OFFSET(nv, offset, PAGE_SIZE)) {
-+        *physical = offset;
-+        return 0;
-+    }
-+
-+    offset += VM_MIN_KERNEL_ADDRESS;
-+
-+    /*
-+     * If the offset does not fall into any of the relevant apertures, we
-+     * must assume that it corresponds to a memory allocation. Offsets of
-+     * this kind are kernel virtual addresses that fall within one of the
-+     * allocated ranges, provided they are valid. These logical addresses
-+     * are translated into physical addresses and then mapped.
-+     */
-+    SLIST_FOREACH(at, &sc->alloc_list, list) {
-+        if (offset >= at->address &&
-+                offset < at->address + at->size) {
-+            *physical = vtophys(offset);
-+            return 0;
-+        }
-+    }
-+
-+    return -1;
-+}
-+
-+
-+int nv_int10h_call(
-+    nv_state_t * nv,
-+    U032 *eax,
-+    U032 *ebx,
-+    U032 *ecx,
-+    U032 *edx,
-+    void *buffer
-+)
-+{
-+#ifdef NV_USE_OS_VM86_INT10CALL
-+    struct vm86frame vmf;
-+
-+    vmf.vmf_eax = *eax;
-+    vmf.vmf_ebx = *ebx;
-+    vmf.vmf_ecx = *ecx;
-+    vmf.vmf_edx = *edx;
-+
-+    if (vm86_intcall(0x10, &vmf) == 0) {
-+        *eax = vmf.vmf_eax;
-+        *ebx = vmf.vmf_ebx;
-+        *ecx = vmf.vmf_ecx;
-+        *edx = vmf.vmf_edx;
-+        return RM_OK;
-+    }
-+#endif /* NV_USE_OS_VM86_INT10CALL */
-+
-+    return RM_ERROR;  /* XXX Fixm me? (vm86_intcall) */
-+}
-+
-+void nvidia_rc_timer(void *data)
-+{
-+    nv_state_t *nv = (nv_state_t *) data;
-+    struct nvidia_softc *sc;
-+    
-+    NV_PCI_ENABLE_DEVICE(nv);
+@@ -1608,7 +1594,7 @@
+     rm_run_rc_callback(nv);
+ 
+     sc = nv->os_state;
+-    sc->timer_ch = timeout(nvidia_rc_timer, (void *) nv, hz);
++    callout_reset(&sc->timer_ch, hz, nvidia_rc_timer, nv);
+ }
+ 
+ int nv_start_rc_timer(
+@@ -1620,7 +1606,8 @@
+     if (nv->rc_timer_enabled != 0)
+         return -EIO;
+ 
+-    sc->timer_ch = timeout(nvidia_rc_timer, (void *) nv, hz);
++    callout_reset(&sc->timer_ch, hz, nvidia_rc_timer, nv); 
 +
-+    /*
-+     * We need this timer to trigger again one second from
-+     * now, reset the timeout.
-+     */
-+    rm_run_rc_callback(nv);
-+
-+    sc = nv->os_state;
-+    sc->timer_ch = timeout(nvidia_rc_timer, (void *) nv, hz);
-+}
-+
-+int nv_start_rc_timer(
-+    nv_state_t *nv
-+)
-+{
-+    struct nvidia_softc *sc = nv->os_state;
-+
-+    if (nv->rc_timer_enabled != 0)
-+        return -EIO;
-+
-+    sc->timer_ch = timeout(nvidia_rc_timer, (void *) nv, hz);
-+    nv->rc_timer_enabled = 1;
-+
-+    return 0;
-+}
-+
-+int nv_stop_rc_timer(
-+    nv_state_t *nv
-+)
-+{
-+    struct nvidia_softc *sc = nv->os_state;
-+
-+    if (nv->rc_timer_enabled == 0)
-+        return -EIO;
-+
-+    untimeout(nvidia_rc_timer, (void *) nv, sc->timer_ch);
-+    nv->rc_timer_enabled = 0;
-+
-+    return 0;
-+}
-+
-diff -urN ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_sysctl.c ./src/nvidia_sysctl.c
---- ../../NVIDIA-FreeBSD-x86-1.0-6113/src/nvidia_sysctl.c	2004-08-03 01:27:38.000000000 +0200
-+++ ./src/nvidia_sysctl.c	2004-08-04 21:26:57.000000000 +0200
+     nv->rc_timer_enabled = 1;
+ 
+     return 0;
+@@ -1635,7 +1622,7 @@
+     if (nv->rc_timer_enabled == 0)
+         return -EIO;
+ 
+-    untimeout(nvidia_rc_timer, (void *) nv, sc->timer_ch);
++    callout_stop(&sc->timer_ch);
+     nv->rc_timer_enabled = 0;
+ 
+     return 0;
+diff -urN ./src/nvidia_sysctl.c ../../nvidia-patched/src/nvidia_sysctl.c
+--- ./src/nvidia_sysctl.c	2004-08-03 01:27:38.000000000 +0200
++++ ../../nvidia-patched/src/nvidia_sysctl.c	2004-09-26 14:13:39.000000000 +0200
 @@ -11,7 +11,7 @@
  #include "nv-misc.h"
  #include "os-interface.h"
