#!/bin/sh -e

# Patch by  Martin Schlemmer (i believe as posted to the lkml)

if [ $# -lt 1 ]; then
    echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
    exit 1
fi
	
patch_opts="-f -N --no-backup-if-mismatch -p3"

echo $1

case "$1" in
	-patch) patch $patch_opts -p3 < $0;;
	-unpatch) patch $patch_opts -p3 -R < $0;;
	*)
     		echo >&2 "`basename $0`: script expects -patch|-unpatch as argument"
		exit 1;;
esac

exit 0

@DPATCH@

diff -urN NVIDIA-Linux-x86-1.0-5336/usr/src/nv/Makefile.kbuild NVIDIA-Linux-x86-1.0-5336.sysfs/usr/src/nv/Makefile.kbuild
--- NVIDIA-Linux-x86-1.0-5336/usr/src/nv/Makefile.kbuild	2004-01-15 05:29:12.000000000 +0200
+++ NVIDIA-Linux-x86-1.0-5336.sysfs/usr/src/nv/Makefile.kbuild	2004-05-22 21:04:52.143088872 +0200
@@ -117,6 +117,9 @@
   MODULE_OBJECT := $(MODULE_NAME).o
 else
   MODULE_OBJECT := $(MODULE_NAME).ko
+
+  # We need this for the conftest.sh tests to work
+  KERNEL_HEADERS += -I$(KERNEL_SOURCES)/include/asm/mach-generic
 endif
 
 #
@@ -146,6 +149,16 @@
   EXTRA_CFLAGS += -DREMAP_PAGE_RANGE_4
 endif
 
+ifeq ($(shell sh $(src)/conftest.sh remap_page_range $(KERNEL_HEADERS)),)
+  # Check if 'conftest.sh remap_page_rage' have no output - if so, we
+  # can expect issues ... !
+  $(error Cannot compile tests!  Please check $$KERNEL_HEADERS)
+endif
+
+ifeq ($(shell sh $(src)/conftest.sh class_simple $(KERNEL_HEADERS)), yes)
+  EXTRA_CFLAGS += -DHAVE_CLASS_SIMPLE
+endif
+  
 #
 # NVIDIA binary object file includes .common section.
 #
diff -urN NVIDIA-Linux-x86-1.0-5336/usr/src/nv/conftest.sh NVIDIA-Linux-x86-1.0-5336.sysfs/usr/src/nv/conftest.sh
--- NVIDIA-Linux-x86-1.0-5336/usr/src/nv/conftest.sh	2004-01-15 05:29:11.000000000 +0200
+++ NVIDIA-Linux-x86-1.0-5336.sysfs/usr/src/nv/conftest.sh	2004-05-22 20:58:19.382797512 +0200
@@ -42,6 +42,29 @@
         fi
     ;;
 
+    class_simple)
+        shift
+        #
+        # Determine if we have struct class_simple needed for limited sysfs
+        # support in 2.6
+        #
+        echo "#include <linux/device.h>
+        void add_test_class(void) {
+           struct class_simple *test_class;
+           test_class = class_simple_create(THIS_MODULE, \"test\");
+        }" > conftest.c
+
+        gcc -Wall -c conftest.c -o conftest.o $* -D__KERNEL__  > output.log 2>&1
+
+        if test -f conftest.o && test -z "`cat output.log`"; then
+          echo "yes"
+        else
+          echo "no"
+        fi
+
+        rm -f conftest.{c,o} output.log
+    ;;
+
     cc_sanity_check)
         shift
         #
diff -urN NVIDIA-Linux-x86-1.0-5336/usr/src/nv/nv-linux.h NVIDIA-Linux-x86-1.0-5336.sysfs/usr/src/nv/nv-linux.h
--- NVIDIA-Linux-x86-1.0-5336/usr/src/nv/nv-linux.h	2004-01-15 05:29:11.000000000 +0200
+++ NVIDIA-Linux-x86-1.0-5336.sysfs/usr/src/nv/nv-linux.h	2004-05-22 20:58:19.387796752 +0200
@@ -448,6 +448,33 @@
 #  endif // defined(KERNEL_2_4)
 #endif // defined(CONFIG_DEVFS_FS)
 
+#if defined(KERNEL_2_6) && defined(HAVE_CLASS_SIMPLE)
+#  define NV_SYSFS_REGISTER						\
+    nvidia_class = class_simple_create(THIS_MODULE, "nvidia");
+
+#  define NV_SYSFS_ADD_CONTROL						\
+     class_simple_device_add(nvidia_class,				\
+                             MKDEV(NV_MAJOR_DEVICE_NUMBER, 255),	\
+                             NULL, "nvidiactl");
+
+#  define NV_SYSFS_ADD_DEVICE(_name, _minor)				\
+     class_simple_device_add(nvidia_class,				\
+                             MKDEV(NV_MAJOR_DEVICE_NUMBER, _minor),	\
+                             &nv_linux_devices[_minor].dev->dev, _name);
+
+#  define NV_SYSFS_REMOVE_DEVICE(i)					\
+            class_simple_device_remove(MKDEV(NV_MAJOR_DEVICE_NUMBER, i));
+
+#  define NV_SYSFS_UNREGISTER						\
+    class_simple_destroy(nvidia_class);
+#else
+#  define NV_SYSFS_REGISTER
+#  define NV_SYSFS_ADD_CONTROL
+#  define NV_SYSFS_ADD_DEVICE(_name, _minor)
+#  define NV_SYSFS_REMOVE_DEVICE(i)
+#  define NV_SYSFS_UNREGISTER
+#endif
+
 
 /*
  * Linux 2.5 introduced the five argument version of remap_page_range, all
diff -urN NVIDIA-Linux-x86-1.0-5336/usr/src/nv/nv.c NVIDIA-Linux-x86-1.0-5336.sysfs/usr/src/nv/nv.c
--- NVIDIA-Linux-x86-1.0-5336/usr/src/nv/nv.c	2004-01-15 05:29:11.000000000 +0200
+++ NVIDIA-Linux-x86-1.0-5336.sysfs/usr/src/nv/nv.c	2004-05-22 20:58:19.393795840 +0200
@@ -47,6 +47,10 @@
 devfs_handle_t nv_devfs_handles[NV_MAX_DEVICES+1];
 #endif
 
+#if defined(KERNEL_2_6) && defined(HAVE_CLASS_SIMPLE)
+struct class_simple *nvidia_class;
+#endif
+
 // #define NV_DBG_MEM 1
 #undef NV_DBG_MEM
 
@@ -874,23 +878,31 @@
     rc = register_chrdev(nv_major, "nvidia", &nv_fops);
 #endif
 
+    NV_SYSFS_REGISTER;
+
     if (rc < 0)
     {
         nv_printf(NV_DBG_ERRORS, "nvidia_init_module: register failed\n");
         return rc;
     }
 
-#ifdef CONFIG_DEVFS_FS
+#if defined(CONFIG_DEVFS_FS) || defined(KERNEL_2_6)
     do
     {
         char name[10];
 
+# if defined(CONFIG_DEVFS_FS)
         nv_devfs_handles[0] = NV_DEVFS_REGISTER("nvidiactl", 255);
+# endif
+        NV_SYSFS_ADD_CONTROL;
 
         for (i = 0; i < num_nv_devices; i++)
         {
             sprintf(name, "nvidia%d", i);
+# if defined(CONFIG_DEVFS_FS)
             nv_devfs_handles[i+1] = NV_DEVFS_REGISTER(name, i);
+# endif
+            NV_SYSFS_ADD_DEVICE(name, i);
         }
     } while(0);
 #endif
@@ -951,6 +963,7 @@
 #else
     unregister_chrdev(nv_major, "nvidia");
 #endif
+    NV_SYSFS_UNREGISTER;
     return rc;
 }
 
@@ -1011,15 +1024,24 @@
         nv_printf(NV_DBG_ERRORS, "nvidia_exit_module: unregister nv failed\n");
     }
 
-#ifdef CONFIG_DEVFS_FS
+#if defined(CONFIG_DEVFS_FS) || defined(KERNEL_2_6)
     do {
         int i;
+# if defined(CONFIG_DEVFS_FS)
         NV_DEVFS_REMOVE_CONTROL();
-        for (i = 0; i < num_nv_devices; i++)
+# endif
+        NV_SYSFS_REMOVE_DEVICE(255);
+        for (i = 0; i < num_nv_devices; i++) {
+# if defined(CONFIG_DEVFS_FS)
             NV_DEVFS_REMOVE_DEVICE(i);
+# endif
+            NV_SYSFS_REMOVE_DEVICE(i);
+        }
     } while (0);
 #endif
 
+    NV_SYSFS_UNREGISTER;
+
 #if NV_ENABLE_MEM_TRACKING
     nv_list_mem(vm_list);
     nv_list_mem(km_list);
