diff -ru usr/src/nv/nv-linux.h usr/src/nv.1201042/nv-linux.h
--- usr/src/nv/nv-linux.h	2004-11-03 22:53:00.000000000 +0100
+++ usr/src/nv.1201042/nv-linux.h	2005-01-26 01:56:26.000000000 +0100
@@ -565,11 +565,6 @@
 #define PCI_CAP_ID_EXP 0x10
 #endif
 
-#if defined(KERNEL_2_6) && defined(AGPGART)
-typedef struct agp_kern_info agp_kern_info;
-typedef struct agp_memory agp_memory;
-#endif
-
 #if defined(CONFIG_DEVFS_FS)
 #  if defined(KERNEL_2_6)
      typedef void* devfs_handle_t;
diff -ru usr/src/nv/nv.c usr/src/nv.1201042/nv.c
--- usr/src/nv/nv.c	2004-11-03 22:53:00.000000000 +0100
+++ usr/src/nv.1201042/nv.c	2005-01-26 01:56:28.000000000 +0100
@@ -2987,32 +2987,47 @@
      */
     if ( (!NV_AGP_ENABLED(nv)) && (config & NVOS_AGP_CONFIG_NVAGP) )
     {
-        /* make sure the user does not have agpgart loaded */
-        if (inter_module_get("drm_agp")) {
+#if defined(KERNEL_2_4)
+        if (inter_module_get("drm_agp"))
+        {
             inter_module_put("drm_agp");
-            nv_printf(NV_DBG_WARNINGS, "NVRM: not using NVAGP, AGPGART is loaded!!\n");
-        } else {
-#if defined(CONFIG_X86_64) && defined(CONFIG_GART_IOMMU)
+            nv_printf(NV_DBG_WARNINGS, "NVRM: not using NVAGP, AGPGART is loaded!\n");
+            return status;
+        }
+#elif defined(AGPGART)
+        int error;
+        /*
+         * We can only safely use NvAGP when no backend has been
+         * registered with the AGPGART frontend. This condition
+         * is only met when the acquire function returns -EINVAL.
+         *
+         * Other return codes indicate that a backend is present
+         * and was either acquired, busy or else unavailable.
+         */
+        if ((error = agp_backend_acquire()) != -EINVAL)
+        {
+            if (!error) agp_backend_release();
             nv_printf(NV_DBG_WARNINGS,
-                "NVRM: not using NVAGP, kernel was compiled with GART_IOMMU support!!\n");
-#else
-            status = rm_init_agp(nv);
-            if (status == RM_OK)
-            {
-                nv->agp_config = NVOS_AGP_CONFIG_NVAGP;
-                nv->agp_status = NV_AGP_STATUS_ENABLED;
-            }
+                      "NVRM: not using NVAGP, an AGPGART backend is loaded!\n");
+            return status;
+        }
 #endif
+#if defined(CONFIG_X86_64) && defined(CONFIG_GART_IOMMU)
+        nv_printf(NV_DBG_WARNINGS,
+            "NVRM: not using NVAGP, kernel was compiled with GART_IOMMU support!\n");
+#else
+        status = rm_init_agp(nv);
+        if (status == RM_OK)
+        {
+            nv->agp_config = NVOS_AGP_CONFIG_NVAGP;
+            nv->agp_status = NV_AGP_STATUS_ENABLED;
         }
+#endif
     }
 
     if (NV_AGP_ENABLED(nv))
         old_error = 0; /* report new errors */
 
-    nv_printf(NV_DBG_SETUP, 
-        "NVRM: agp_init finished with status 0x%x and config %d\n",
-        status, nv->agp_config);
-
     return status;
 }
 
@@ -3036,9 +3051,6 @@
     nv->agp_config = NVOS_AGP_CONFIG_DISABLE_AGP;
     nv->agp_status = NV_AGP_STATUS_DISABLED;
 
-    nv_printf(NV_DBG_SETUP, "NVRM: teardown finished with status 0x%x\n", 
-        status);
-
     return status;
 }
 
diff -ru usr/src/nv/os-agp.c usr/src/nv.1201042/os-agp.c
--- usr/src/nv/os-agp.c	2004-11-03 22:53:00.000000000 +0100
+++ usr/src/nv.1201042/os-agp.c	2005-01-26 01:56:30.000000000 +0100
@@ -25,6 +25,13 @@
 
 #ifdef AGPGART
 
+#if defined(KERNEL_2_6)
+typedef struct agp_kern_info agp_kern_info;
+typedef struct agp_memory agp_memory;
+#elif defined(KERNEL_2_4)
+const drm_agp_t *drm_agp_p; /* functions */
+#endif
+
 typedef struct {
     agp_memory *ptr;
     int num_pages;
@@ -45,7 +52,6 @@
 
 agp_kern_info         agpinfo;
 agp_gart              gart;
-const drm_agp_t       *drm_agp_p;
 
 #if defined(CONFIG_MTRR)
 #define MTRR_DEL(gart) if ((gart).mtrr > 0) mtrr_del((gart).mtrr, 0, 0);
@@ -53,6 +59,26 @@
 #define MTRR_DEL(gart)
 #endif
 
+#if defined(KERNEL_2_6)
+#define NV_AGPGART_BACKEND_ACQUIRE(o) agp_backend_acquire()
+#define NV_AGPGART_BACKEND_ENABLE(o,mode) agp_enable(mode)
+#define NV_AGPGART_BACKEND_RELEASE(o) agp_backend_release()
+#define NV_AGPGART_COPY_INFO(o,p) agp_copy_info(p)
+#define NV_AGPGART_ALLOCATE_MEMORY(o,count,type) agp_allocate_memory(count,type)
+#define NV_AGPGART_FREE_MEMORY(o,p) agp_free_memory(p)
+#define NV_AGPGART_BIND_MEMORY(o,p,offset) agp_bind_memory(p,offset)
+#define NV_AGPGART_UNBIND_MEMORY(o,p) agp_unbind_memory(p)
+#elif defined(KERNEL_2_4)
+#define NV_AGPGART_BACKEND_ACQUIRE(o) ({ (o)->acquire(); 0; })
+#define NV_AGPGART_BACKEND_ENABLE(o,mode) (o)->enable(mode)
+#define NV_AGPGART_BACKEND_RELEASE(o) ((o)->release())
+#define NV_AGPGART_COPY_INFO(o,p) ({ (o)->copy_info(p); 0; })
+#define NV_AGPGART_ALLOCATE_MEMORY(o,count,type) (o)->allocate_memory(count,type)
+#define NV_AGPGART_FREE_MEMORY(o,p) (o)->free_memory(p)
+#define NV_AGPGART_BIND_MEMORY(o,p,offset) (o)->bind_memory(p,offset)
+#define NV_AGPGART_UNBIND_MEMORY(o,p) (o)->unbind_memory(p)
+#endif
+
 #endif /* AGPGART */
 
 BOOL KernInitAGP(
@@ -73,8 +99,10 @@
 
     memset( (void *) &gart, 0, sizeof(agp_gart));
 
+#if defined(KERNEL_2_4)
     if (!(drm_agp_p = inter_module_get_request("drm_agp", "agpgart")))
         return 1;
+#endif
 
     /* NOTE: from here down, return an error code of '-1'
      * that indicates that agpgart is loaded, but we failed to use it
@@ -82,11 +110,10 @@
      * the memory controller.
      */
 
-    if (drm_agp_p->acquire())
+    if (NV_AGPGART_BACKEND_ACQUIRE(drm_agp_p))
     {
-        nv_printf(NV_DBG_ERRORS, "NVRM: AGPGART: backend in use\n");
-        inter_module_put("drm_agp");
-        return -1;
+        nv_printf(NV_DBG_INFO, "NVRM: AGPGART: no backend available\n");
+        goto bailout;
     }
 
     if (rm_read_registry_dword(nv, "NVreg", "ReqAGPRate", &agp_rate) == RM_ERROR)
@@ -101,21 +128,12 @@
         agp_fw = 1;
     agp_fw &= 0x00000001;
 
-#if defined(KERNEL_2_4)
-    /*
-     * The original Linux 2.4 AGP GART driver interface declared copy_info to
-     * return nothing. This changed in Linux 2.5, which reports unsupported
-     * chipsets via this function. If this Linux 2.4 kernels behaves the same
-     * way, we have no way to know.
-     */
-    drm_agp_p->copy_info(&agpinfo);
-#else
-    if (drm_agp_p->copy_info(&agpinfo)) {
+    if (NV_AGPGART_COPY_INFO(drm_agp_p, &agpinfo))
+    {
         nv_printf(NV_DBG_ERRORS,
             "NVRM: AGPGART: kernel reports chipset as unsupported\n");
         goto failed;
     }
-#endif
 
 #ifdef CONFIG_MTRR
     /*
@@ -170,7 +188,7 @@
     if (!(agp_rate & 0x00000004)) agpinfo.mode &= ~0x00000004;
     if (!(agp_rate & 0x00000002)) agpinfo.mode &= ~0x00000002;
     
-    drm_agp_p->enable(agpinfo.mode);
+    NV_AGPGART_BACKEND_ENABLE(drm_agp_p, agpinfo.mode);
 
     *ap_phys_base   = (void*) agpinfo.aper_base;
     *ap_mapped_base = (void*) gart.aperture;
@@ -182,8 +200,11 @@
 
 failed:
     MTRR_DEL(gart); /* checks gart.mtrr */
-    drm_agp_p->release();
+    NV_AGPGART_BACKEND_RELEASE(drm_agp_p);
+bailout:
+#if defined(KERNEL_2_4)
     inter_module_put("drm_agp");
+#endif
 
     return -1;
 
@@ -213,9 +234,10 @@
         NV_IOUNMAP(gart.aperture, RM_PAGE_SIZE);
     }
 
-    drm_agp_p->release();
-
+    NV_AGPGART_BACKEND_RELEASE(drm_agp_p);
+#if defined(KERNEL_2_4)
     inter_module_put("drm_agp");
+#endif
 
     if (rm_clear_agp_bitmap(nv, &bitmap))
     {
@@ -244,7 +266,6 @@
     return RM_ERROR;
 #else
     agp_memory *ptr;
-    int err;
     agp_priv_data *data;
     RM_STATUS status;
 
@@ -262,7 +283,7 @@
         return RM_ERROR;
     }
 
-    ptr = drm_agp_p->allocate_memory(PageCount, AGP_NORMAL_MEMORY);
+    ptr = NV_AGPGART_ALLOCATE_MEMORY(drm_agp_p, PageCount, AGP_NORMAL_MEMORY);
     if (ptr == NULL)
     {
         *pAddress = (void*) 0;
@@ -270,8 +291,7 @@
         return RM_ERR_NO_FREE_MEM;
     }
     
-    err = drm_agp_p->bind_memory(ptr, *Offset);
-    if (err)
+    if (NV_AGPGART_BIND_MEMORY(drm_agp_p, ptr, *Offset))
     {
         // this happens a lot when the aperture itself fills up..
         // not a big deal, so don't alarm people with an error message
@@ -280,14 +300,11 @@
         goto fail;
     }
 
-    /* return the agp aperture address */ 
-    *pAddress = (void *) (agpinfo.aper_base + (*Offset << PAGE_SHIFT));
-
     status = os_alloc_mem((void **)&data, sizeof(agp_priv_data));
     if (status != RM_OK)
     {
         nv_printf(NV_DBG_ERRORS, "NVRM: AGPGART: memory allocation failed\n");
-        drm_agp_p->unbind_memory(ptr);
+        NV_AGPGART_UNBIND_MEMORY(drm_agp_p, ptr);
         goto fail;
     }
 
@@ -302,7 +319,7 @@
     return RM_OK;
 
 fail:
-    drm_agp_p->free_memory(ptr);
+    NV_AGPGART_FREE_MEMORY(drm_agp_p, ptr);
     *pAddress = (void*) 0;
 
     return RM_ERROR;
@@ -342,7 +359,7 @@
     {
         nv_printf(NV_DBG_ERRORS, "NVRM: AGPGART: unable to remap %lu pages\n",
             (unsigned long)agp_data->num_pages);
-        drm_agp_p->unbind_memory(agp_data->ptr);
+        NV_AGPGART_UNBIND_MEMORY(drm_agp_p, agp_data->ptr);
         goto fail;
     }
     
@@ -441,8 +458,8 @@
     {
         size_t pages = ptr->page_count;
 
-        drm_agp_p->unbind_memory(ptr);
-        drm_agp_p->free_memory(ptr);
+        NV_AGPGART_UNBIND_MEMORY(drm_agp_p, ptr);
+        NV_AGPGART_FREE_MEMORY(drm_agp_p, ptr);
 
         nv_printf(NV_DBG_INFO, "NVRM: AGPGART: freed %ld pages\n",
             (unsigned long)pages);
