initial import
[grml.org.git] / kernel-devel / nvidia-kernel_fix_2.6.16_problem.patch
1 diff -ru usr/src/nv/Makefile.kbuild usr/src/nv.U012206/Makefile.kbuild
2 --- usr/src/nv/Makefile.kbuild  2005-12-15 01:57:35.000000000 +0100
3 +++ usr/src/nv.U012206/Makefile.kbuild  2006-01-22 15:32:35.775636750 +0100
4 @@ -186,6 +186,18 @@
5    ifeq ($(shell $(CONFTEST) sysctl_max_map_count), 1)
6      EXTRA_CFLAGS += -DNV_SYSCTL_MAX_MAP_COUNT_PRESENT
7    endif
8 +
9 +  ifeq ($(shell $(CONFTEST) pm_message_t), 1)
10 +    EXTRA_CFLAGS += -DNV_PM_MESSAGE_T_PRESENT
11 +  endif
12 +
13 +  ifeq ($(shell $(CONFTEST) pci_choose_state), 1)
14 +    EXTRA_CFLAGS += -DNV_PCI_CHOOSE_STATE_PRESENT
15 +  endif
16 +
17 +  ifeq ($(shell $(CONFTEST) vm_insert_page), 1)
18 +       EXTRA_CFLAGS += -DNV_VM_INSERT_PAGE_PRESENT
19 +  endif
20  endif
21  
22  ifeq ($(shell $(CONFTEST) remap_pfn_range), 1)
23 diff -ru usr/src/nv/conftest.sh usr/src/nv.U012206/conftest.sh
24 --- usr/src/nv/conftest.sh      2005-12-15 01:57:35.000000000 +0100
25 +++ usr/src/nv.U012206/conftest.sh      2006-01-22 15:32:06.353798000 +0100
26 @@ -22,8 +22,8 @@
27  OUTPUT=$4
28  
29  CFLAGS="-D__KERNEL__ \
30 --nostdinc -isystem $ISYSTEM \
31 --Werror -Wimplicit-function-declaration"
32 +-DKBUILD_BASENAME=\"#conftest$$\" -DKBUILD_MODNAME=\"#conftest$$\" \
33 +-nostdinc -isystem $ISYSTEM"
34  
35  if [ "$OUTPUT" != "$SOURCES" ]; then
36      ARCH=`uname -m | sed -e 's/i.86/i386/'`
37 @@ -40,9 +40,22 @@
38          #
39  
40          echo "#include <linux/mm.h>
41 -        int nv_remap_page_range(void) {
42 +        void conftest_remap_page_range(void) {
43 +           remap_page_range();
44 +        }" > conftest$$.c
45 +
46 +        $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
47 +        rm -f conftest$$.c
48 +
49 +        if [ -f conftest$$.o ]; then
50 +          rm -f conftest$$.o
51 +          exit 1
52 +        fi
53 +
54 +        echo "#include <linux/mm.h>
55 +        int conftest_remap_page_range(void) {
56             pgprot_t pgprot = __pgprot(0);
57 -           remap_page_range(NULL, 0L, 0L, 0L, pgprot);
58 +           return remap_page_range(NULL, 0L, 0L, 0L, pgprot);
59          }" > conftest$$.c
60  
61          $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
62 @@ -55,9 +68,9 @@
63          fi
64  
65          echo "#include <linux/mm.h>
66 -        int nv_remap_page_range(void) {
67 +        int conftest_remap_page_range(void) {
68             pgprot_t pgprot = __pgprot(0);
69 -           remap_page_range(0L, 0L, 0L, pgprot);
70 +           return remap_page_range(0L, 0L, 0L, pgprot);
71          }" > conftest$$.c
72  
73          $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
74 @@ -330,7 +343,7 @@
75                  return 0;
76              }" > conftest$$.c
77  
78 -            $HOSTCC $CFLAGS -Wno-error -o conftest$$ conftest$$.c > /dev/null 2>&1
79 +            $HOSTCC $CFLAGS -o conftest$$ conftest$$.c > /dev/null 2>&1
80              rm -f conftest$$.c
81  
82              if [ -f conftest$$ ]; then
83 @@ -483,8 +496,8 @@
84          #if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 0)
85            #include <asm/cacheflush.h>
86          #endif
87 -        int nv_change_page_attr(struct page *pp, int i, pgprot_t prot) {
88 -            return change_page_attr(pp, i, prot);
89 +        void conftest_change_page_attr() {
90 +            change_page_attr();
91          }" > conftest$$.c
92  
93          $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
94 @@ -492,9 +505,9 @@
95  
96          if [ -f conftest$$.o ]; then
97              rm -f conftest$$.o
98 -            echo 1
99 -        else
100              echo 0
101 +        else
102 +            echo 1
103          fi
104      ;;
105  
106 @@ -504,9 +517,8 @@
107          #
108  
109          echo "#include <linux/pci.h>
110 -        struct pci_dev*
111 -        nv_pci_get_class(unsigned int class, struct pci_dev *from) {
112 -            return pci_get_class(class, from);
113 +        void conftest_pci_get_class(void) {
114 +            pci_get_class();
115          }" > conftest$$.c
116  
117          $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
118 @@ -514,9 +526,9 @@
119  
120          if [ -f conftest$$.o ]; then
121              rm -f conftest$$.o
122 -            echo 1
123 -        else
124              echo 0
125 +        else
126 +            echo 1
127          fi
128      ;;
129  
130 @@ -526,9 +538,8 @@
131          #
132  
133          echo "#include <linux/mm.h>
134 -        int nv_remap_pfn_range(void) {
135 -            pgprot_t pgprot = __pgprot(0);
136 -            remap_pfn_range(NULL, 0L, 0L, 0L, pgprot);
137 +        void conftest_remap_pfn_range(void) {
138 +            remap_pfn_range();
139          }" > conftest$$.c
140  
141          $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
142 @@ -536,9 +547,9 @@
143  
144          if [ -f conftest$$.o ]; then
145              rm -f conftest$$.o
146 -            echo 1
147 -        else
148              echo 0
149 +        else
150 +            echo 1
151          fi
152      ;;
153  
154 @@ -548,11 +559,11 @@
155          #
156  
157          echo "#include <linux/sched.h>
158 -        struct rlimit *nv_signal_struct_rlim(void) {
159 +        struct rlimit *conftest_signal_struct_rlim(void) {
160              return current->signal->rlim;
161          }" > conftest$$.c
162  
163 -        $CC $CFLAGS -Wno-error -c conftest$$.c > /dev/null 2>&1
164 +        $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
165          rm -f conftest$$.c
166  
167          if [ -f conftest$$.o ]; then
168 @@ -572,7 +583,7 @@
169          echo "#include <linux/types.h>
170          #include <linux/agp_backend.h>
171          typedef struct agp_bridge_data agp_bridge_data;
172 -        agp_bridge_data *nv_agp_backend_acquire(struct pci_dev *dev) {
173 +        agp_bridge_data *conftest_agp_backend_acquire(struct pci_dev *dev) {
174              return agp_backend_acquire(dev);
175          }" > conftest$$.c
176  
177 @@ -594,9 +605,23 @@
178          #
179  
180          echo "#include <linux/vmalloc.h>
181 -        void *nv_vmap(struct page **pg, int cnt) {
182 +        void conftest_vmap(void) {
183 +            vmap();
184 +        }" > conftest$$.c
185 +
186 +        $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
187 +        rm -f conftest$$.c
188 +
189 +        if [ -f conftest$$.o ]; then
190 +            rm -f conftest$$.o
191 +            exit 1
192 +        fi
193 +
194 +        echo "#include <linux/vmalloc.h>
195 +        void *conftest_vmap(struct page **pg, int cnt) {
196              return vmap(pg, cnt);
197          }" > conftest$$.c
198 +
199          $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
200          rm -f conftest$$.c
201  
202 @@ -608,9 +633,10 @@
203  
204          echo "#include <linux/vmalloc.h>
205          #include <linux/mm.h>
206 -        void *nv_vmap(struct page **pg, int cnt) {
207 +        void *conftest_vmap(struct page **pg, int cnt) {
208              return vmap(pg, cnt, 0, PAGE_KERNEL);
209          }" > conftest$$.c
210 +
211          $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
212          rm -f conftest$$.c
213  
214 @@ -618,7 +644,11 @@
215              rm -f conftest$$.o
216              echo 4
217          else
218 -            exit 1  # there ain't no vmap()
219 +            #
220 +            # We couldn't determine the number of arguments expected by the
221 +            # vmap() function.
222 +            #
223 +            exit 1
224          fi
225      ;;
226  
227 @@ -629,7 +659,7 @@
228          #
229  
230          echo "#include <linux/sched.h>
231 -        int nv_test_sysctl_max_map_count(void) {
232 +        int conftest_sysctl_max_map_count(void) {
233              return sysctl_max_map_count;
234          }" > conftest$$.c
235  
236 @@ -644,4 +674,67 @@
237          fi
238      ;;
239  
240 +    pm_message_t)
241 +        #
242 +        # Does linux/pm.h declare the pm_message_t type?
243 +        #
244 +
245 +        echo "#include <linux/pm.h>
246 +        void conftest_pm_message_t(pm_message_t state) {
247 +            pm_message_t *p = &state;
248 +        }" > conftest$$.c
249 +
250 +        $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
251 +        rm -f conftest$$.c
252 +
253 +        if [ -f conftest$$.o ]; then
254 +            rm -f conftest$$.o
255 +            echo 1
256 +        else
257 +            echo 0
258 +        fi
259 +    ;;
260 +
261 +    pci_choose_state)
262 +        #
263 +        # Determine if pci_choose_state() is present.
264 +        #
265 +
266 +        echo "#include <linux/pci.h>
267 +        void conftest_pci_choose_state(void) {
268 +            pci_choose_state();
269 +        }" > conftest$$.c
270 +
271 +        $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
272 +        rm -f conftest$$.c
273 +
274 +        if [ -f conftest$$.o ]; then
275 +            rm -f conftest$$.o
276 +            echo 0
277 +        else
278 +            echo 1
279 +        fi
280 +    ;;
281 +
282 +    vm_insert_page)
283 +        #
284 +        # Determine if vm_insert_page() is present.
285 +        #
286 +
287 +        echo "#include <linux/mm.h>
288 +        void conftest_vm_insert_page(void) {
289 +            vm_insert_page();
290 +        }" > conftest$$.c
291 +
292 +        $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1
293 +        rm -f conftest$$.c
294 +
295 +        if [ -f conftest$$.o ]; then
296 +            rm -f conftest$$.o
297 +            echo 0
298 +        else
299 +            echo 1
300 +        fi
301 +    ;;
302 +
303  esac
304 diff -ru usr/src/nv/nv-linux.h usr/src/nv.U012206/nv-linux.h
305 --- usr/src/nv/nv-linux.h       2005-12-15 01:57:35.000000000 +0100
306 +++ usr/src/nv.U012206/nv-linux.h       2006-01-22 15:32:35.775636750 +0100
307 @@ -642,15 +642,49 @@
308  #define NV_PRINT_AT(at)
309  #endif
310  
311 -// acpi support has been back-ported to the 2.4 kernel, but the 2.4 driver
312 -// model is not sufficient for full acpi support. it may work in some cases,
313 -// but not enough for us to officially support this configuration.
314 -#if defined(CONFIG_ACPI) && defined(KERNEL_2_6)
315 -#define NV_PM_SUPPORT_ACPI
316 +/*
317 + * On Linux 2.6, we support both APM and ACPI power management. On Linux
318 + * 2.4, we support APM, only. ACPI support has been back-ported to the
319 + * Linux 2.4 kernel, but the Linux 2.4 driver model is not sufficient for
320 + * full ACPI support: it may work with some systems, but not reliably
321 + * enough for us to officially support this configuration.
322 + *
323 + * We support two Linux kernel power managment interfaces: the original
324 + * pm_register()/pm_unregister() on Linux 2.4 and the device driver model
325 + * backed PCI driver power management callbacks introduced with Linux
326 + * 2.6.
327 + *
328 + * The code below determines which interface to support on this kernel
329 + * version, if any; if built for Linux 2.6, it will also determine if the
330 + * kernel comes with ACPI or APM power management support.
331 + */
332 +#if defined(KERNEL_2_6) && (defined(CONFIG_APM) || defined(CONFIG_APM_MODULE) || defined(CONFIG_ACPI))
333 +#define NV_PM_SUPPORT_DEVICE_DRIVER_MODEL
334 +#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
335 +#define NV_PM_SUPPORT_NEW_STYLE_APM
336 +#endif
337  #endif
338  
339 -#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
340 -#define NV_PM_SUPPORT_APM
341 +/*
342 + * On Linux 2.6 kernels >= 2.6.11, the PCI subsystem provides a new 
343 + * interface that allows PCI drivers to determine the correct power state
344 + * for a given system power state; our suspend/resume callbacks now use
345 + * this interface and operate on PCI power state defines.
346 + *
347 + * Define these new PCI power state #define's here for compatibility with
348 + * older Linux 2.6 kernels.
349 + */
350 +#if defined(KERNEL_2_6) && !defined(PCI_D0)
351 +#define PCI_D0 PM_SUSPEND_ON
352 +#define PCI_D3hot PM_SUSPEND_MEM
353 +#endif
354 +
355 +#if defined(KERNEL_2_6) && !defined(NV_PM_MESSAGE_T_PRESENT)
356 +typedef u32 pm_message_t;
357 +#endif
358 +
359 +#if defined(KERNEL_2_4) && (defined(CONFIG_APM) || defined(CONFIG_APM_MODULE))
360 +#define NV_PM_SUPPORT_OLD_STYLE_APM
361  #endif
362  
363  #ifndef minor
364 @@ -666,9 +700,13 @@
365  #define PCI_CAP_ID_EXP 0x10
366  #endif
367  
368 +#if defined(NV_VM_INSERT_PAGE_PRESENT)
369 +#define NV_VM_INSERT_PAGE(vma, addr, page) \
370 +    vm_insert_page(vma, addr, page)
371 +#endif
372  #if defined(NV_REMAP_PFN_RANGE_PRESENT)
373  #define NV_REMAP_PAGE_RANGE(from, offset, x...) \
374 -     remap_pfn_range(vma, from, ((offset) >> PAGE_SHIFT), x)
375 +    remap_pfn_range(vma, from, ((offset) >> PAGE_SHIFT), x)
376  #elif defined(NV_REMAP_PAGE_RANGE_5_PRESENT)
377  #define NV_REMAP_PAGE_RANGE(x...) remap_page_range(vma, x)
378  #elif defined(NV_REMAP_PAGE_RANGE_4_PRESENT)
379 @@ -840,11 +878,7 @@
380      }
381  #endif
382  
383 -#if !defined(page_to_pfn)
384 -#define page_to_pfn(page)  ((page) - mem_map)
385 -#endif
386 -
387 -#if !defined(pfn_to_page)
388 +#if defined(KERNEL_2_4) && defined(NVCPU_X86) && !defined(pfn_to_page)
389  #define pfn_to_page(pfn) (mem_map + (pfn))
390  #endif
391  
392 diff -ru usr/src/nv/nv-vm.c usr/src/nv.U012206/nv-vm.c
393 --- usr/src/nv/nv-vm.c  2005-12-15 01:57:35.000000000 +0100
394 +++ usr/src/nv.U012206/nv-vm.c  2006-01-22 15:32:35.775636750 +0100
395 @@ -105,6 +105,15 @@
396  #endif
397  }
398  
399 +static inline BOOL nv_page_locked(nv_pte_t *page_ptr)
400 +{
401 +    BOOL locked = FALSE; 
402 +#if defined(PageReserved)
403 +    locked = PageReserved(NV_GET_PAGE_STRUCT(page_ptr->phys_addr));
404 +#endif 
405 +    return locked;
406 +}
407 +
408  #if defined(NV_SG_MAP_BUFFERS)
409  
410  /* track how much memory has been remapped through the iommu/swiotlb */
411 @@ -704,7 +713,7 @@
412          if (!NV_ALLOC_MAPPING_CONTIG(at->flags))
413              nv_sg_unmap_buffer(dev, &page_ptr->sg_list, page_ptr);
414  #endif
415 -        if (!NV_ALLOC_MAPPING_CONTIG(at->flags) && !NV_ALLOC_MAPPING_VMALLOC(at->flags))
416 +        if (!NV_ALLOC_MAPPING_CONTIG(at->flags) && !NV_ALLOC_MAPPING_VMALLOC(at->flags) && !nv_page_locked(page_ptr))
417              NV_FREE_PAGES(page_ptr->virt_addr, 0);
418      }
419      nv_flush_caches();
420 diff -ru usr/src/nv/nv.c usr/src/nv.U012206/nv.c
421 --- usr/src/nv/nv.c     2005-12-15 01:57:35.000000000 +0100
422 +++ usr/src/nv.U012206/nv.c     2006-01-22 15:32:35.775636750 +0100
423 @@ -29,7 +29,7 @@
424  
425  static nv_linux_state_t nv_linux_devices[NV_MAX_DEVICES];
426  
427 -#if defined(NV_PM_SUPPORT_APM)
428 +#if defined(NV_PM_SUPPORT_OLD_STYLE_APM)
429  static struct pm_dev *apm_nv_dev[NV_MAX_DEVICES] = { 0 };
430  #endif
431  
432 @@ -244,8 +244,8 @@
433  void          nv_kern_isr_bh(unsigned long);
434  irqreturn_t   nv_kern_isr(int, void *, struct pt_regs *);
435  void          nv_kern_rc_timer(unsigned long);
436 -#if defined(NV_PM_SUPPORT_APM)
437 -int           nv_kern_apm_event(struct pm_dev *dev, pm_request_t rqst, void *data);
438 +#if defined(NV_PM_SUPPORT_OLD_STYLE_APM)
439 +static int    nv_kern_apm_event(struct pm_dev *, pm_request_t, void *);
440  #endif
441  
442  static int    nv_kern_read_cardinfo(char *, char **, off_t off, int, int *, void *);
443 @@ -265,9 +265,10 @@
444  unsigned int  nv_kern_ctl_poll(struct file *, poll_table *);
445  
446  int nv_kern_probe(struct pci_dev *, const struct pci_device_id *);
447 -#if defined(NV_PM_SUPPORT_ACPI)
448 -int nv_kern_acpi_standby(struct pci_dev *, u32);
449 -int nv_kern_acpi_resume(struct pci_dev *);
450 +
451 +#if defined(NV_PM_SUPPORT_DEVICE_DRIVER_MODEL)
452 +static int    nv_kern_suspend(struct pci_dev *, pm_message_t);
453 +static int    nv_kern_resume(struct pci_dev *);
454  #endif
455  
456  /***
457 @@ -292,9 +293,9 @@
458      .name     = "nvidia",
459      .id_table = nv_pci_table,
460      .probe    = nv_kern_probe,
461 -#if defined(NV_PM_SUPPORT_ACPI)
462 -    .suspend  = nv_kern_acpi_standby,
463 -    .resume   = nv_kern_acpi_resume,
464 +#if defined(NV_PM_SUPPORT_DEVICE_DRIVER_MODEL)
465 +    .suspend  = nv_kern_suspend,
466 +    .resume   = nv_kern_resume,
467  #endif
468  };
469  
470 @@ -852,7 +853,8 @@
471  
472      if (!test_bit(X86_FEATURE_PAT, (volatile unsigned long *)&boot_cpu_data.x86_capability))
473      {
474 -        nv_printf(NV_DBG_ERRORS, "NVRM: cpu does not support PAT, aborting..\n");
475 +        nv_printf(NV_DBG_ERRORS,
476 +            "NVRM: CPU does not support the PAT, falling back to MTRRs.\n");
477          return 0;
478      }
479  
480 @@ -1084,9 +1086,12 @@
481  
482          // broken kernels may get confused after splitting the page and
483          // restore the page before returning to us. detect that case.
484 -        if ( (pte_val(*kpte) == kpte_val) &&
485 -             (pte_val(*kpte) & _PAGE_PSE))
486 +        if (((pte_val(*kpte) & ~_PAGE_NX) == kpte_val) &&
487 +            (pte_val(*kpte) & _PAGE_PSE))
488          {
489 +            if ((pte_val(*kpte) & _PAGE_NX) &&
490 +                    (__nv_supported_pte_mask & _PAGE_NX) == 0)
491 +                clear_bit(_PAGE_BIT_NX, kpte);
492              spin_unlock(&init_mm.page_table_lock);
493              // don't change the page back, as it's already been reverted
494              put_page(kpte_page);
495 @@ -1299,7 +1304,7 @@
496          nv_lock_init_locks(nv_ctl);
497      }
498  
499 -#if defined(NV_PM_SUPPORT_APM)
500 +#if defined(NV_PM_SUPPORT_OLD_STYLE_APM)
501      for (i = 0; i < num_nv_devices; i++)
502      {
503          apm_nv_dev[i] = pm_register(PM_PCI_DEV, PM_SYS_VGA, nv_kern_apm_event);
504 @@ -1407,8 +1412,11 @@
505  
506  #if defined(NV_BUILD_NV_PAT_SUPPORT)
507      if (!nv_disable_pat)
508 -    {
509          __nv_enable_pat_support();
510 +    else
511 +    {
512 +        nv_printf(NV_DBG_ERRORS,
513 +            "NVRM: builtin PAT support disabled, falling back to MTRRs.\n");
514      }
515  #endif
516  
517 @@ -1418,7 +1426,7 @@
518      if (nv_pte_t_cache != NULL)
519          NV_KMEM_CACHE_DESTROY(nv_pte_t_cache);
520  
521 -#if defined(NV_PM_SUPPORT_APM)
522 +#if defined(NV_PM_SUPPORT_OLD_STYLE_APM)
523      for (i = 0; i < num_nv_devices; i++)
524          if (apm_nv_dev[i] != NULL) pm_unregister(apm_nv_dev[i]);
525  #endif
526 @@ -1473,10 +1481,10 @@
527      inter_module_unregister("nv_linux_devices");
528  #endif
529  
530 -#if defined(NV_PM_SUPPORT_APM)
531 +#if defined(NV_PM_SUPPORT_OLD_STYLE_APM)
532      for (i = 0; i < num_nv_devices; i++)
533      {
534 -        pm_unregister(apm_nv_dev[i]);
535 +        if (apm_nv_dev[i] != NULL) pm_unregister(apm_nv_dev[i]);
536      }
537  #endif
538  
539 @@ -1889,9 +1897,6 @@
540      // allow setting or refusal of specific caching types
541      switch (cache_type)
542      {
543 -        case NV_MEMORY_CACHED:
544 -        //case NV_MEMORY_WRITEBACK:
545 -            break;
546          case NV_MEMORY_UNCACHED_WEAK:
547              *prot = pgprot_noncached_weak(*prot);
548              break;
549 @@ -1899,19 +1904,53 @@
550              *prot = pgprot_noncached(*prot);
551              break;
552          case NV_MEMORY_WRITECOMBINED:
553 -            if (nv_pat_enabled)
554 +            if (nv_pat_enabled &&
555 +                (memory_type != NV_MEMORY_TYPE_REGISTERS))
556              {
557                  *prot = pgprot_writecombined(*prot);
558                  break;
559              }
560 -            /* agp allocations should be covered by an mtrr if pat isn't enabled */
561 +            /*
562 +             * If PAT support is unavailable and the memory space isn't
563 +             * NV_MEMORY_TYPE_AGP, we need to return an error code to
564 +             * the caller, but do not print a warning message.
565 +             *
566 +             * In the case of AGP memory, we will have attempted to add
567 +             * a WC MTRR for the AGP aperture and aborted the AGP
568 +             * initialization if this failed, so we can safely return
569 +             * success here.
570 +             *
571 +             * For frame buffer memory, callers are expected to use the
572 +             * UC- memory type if we report WC as unsupported, which
573 +             * translates to the effective memory type WC if a WC MTRR
574 +             * exists or else UC.
575 +             */
576              if (memory_type == NV_MEMORY_TYPE_AGP)
577                  break;
578 +            return 1;
579 +        case NV_MEMORY_CACHED:
580 +        //case NV_MEMORY_WRITEBACK:
581 +            /*
582 +             * RAM is cached on Linux by default, we can assume there's
583 +             * nothing to be done here. This is not the case for the
584 +             * other memory spaces: as commented on above, we will have
585 +             * added a WC MTRR for the AGP aperture (or else aborted
586 +             * AGP initialization), and we will have made an attempt to
587 +             * add a WC MTRR for the frame buffer.
588 +             *
589 +             * If a WC MTRR is present, we can't satisfy the WB mapping
590 +             * attempt here, since the achievable effective memory
591 +             * types in that case are WC and UC, if not it's typically
592 +             * UC (MTRRdefType is UC); we could only satisfy WB mapping
593 +             * requests with a WB MTRR.
594 +             */
595 +            if (memory_type == NV_MEMORY_TYPE_SYSTEM)
596 +                break;
597          //case NV_MEMORY_WRITETHRU:
598          //case NV_MEMORY_WRITEPROTECT:
599          default:
600              nv_printf(NV_DBG_ERRORS,
601 -                "NVRM: memory caching type 0x%x not supported for memory space %d!\n",
602 +                "NVRM: VM: memory type %d not supported for memory space %d!\n",
603                  cache_type, memory_type);
604              return 1;
605      }
606 @@ -2118,8 +2157,13 @@
607          for (j = i; j < (i + pages); j++)
608          {
609              nv_verify_page_mappings(at->page_table[j], NV_ALLOC_MAPPING(at->flags));
610 +#if defined(NV_VM_INSERT_PAGE_PRESENT)
611 +            if (NV_VM_INSERT_PAGE(vma, start,
612 +                    NV_GET_PAGE_STRUCT(at->page_table[j]->phys_addr)))
613 +#else
614              if (NV_REMAP_PAGE_RANGE(start, at->page_table[j]->phys_addr,
615                      PAGE_SIZE, vma->vm_page_prot))
616 +#endif
617              {
618                  NV_ATOMIC_DEC(at->usage_count);
619                  return -EAGAIN;
620 @@ -2429,9 +2473,9 @@
621      mod_timer(&nvl->rc_timer, jiffies + HZ);  /* set another timeout in 1 second */
622  }
623  
624 -#if defined(NV_PM_SUPPORT_APM)
625 +#if defined(NV_PM_SUPPORT_OLD_STYLE_APM)
626  /* kernel calls us with a power management event */
627 -int
628 +static int
629  nv_kern_apm_event(
630      struct pm_dev *dev,
631      pm_request_t rqst,
632 @@ -2466,7 +2510,6 @@
633  
634      switch (rqst)
635      {
636 -#if defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)
637          case PM_RESUME:
638              nv_printf(NV_DBG_INFO, "NVRM: APM: received resume event\n");
639              status = rm_power_management(nv, 0, NV_PM_APM_RESUME);
640 @@ -2476,15 +2519,12 @@
641              nv_printf(NV_DBG_INFO, "NVRM: APM: received suspend event\n");
642              status = rm_power_management(nv, 0, NV_PM_APM_SUSPEND);
643              break;
644 -#endif
645  
646 -#if defined(KERNEL_2_4)
647          // 2.4 kernels sent a PM_SAVE_STATE request when powering down via
648          // ACPI. just ignore it and return success so the power down works
649          case PM_SAVE_STATE:
650              status = RM_OK;
651              break;
652 -#endif
653  
654          default:
655              nv_printf(NV_DBG_WARNINGS, "NVRM: APM: unsupported event: %d\n", rqst);
656 @@ -2496,7 +2536,7 @@
657  
658      return status;
659  }
660 -#endif
661 +#endif /* defined(NV_PM_SUPPORT_OLD_STYLE_APM) */
662  
663  /*
664  ** nv_kern_ctl_open
665 @@ -3739,6 +3779,7 @@
666      nvl = &nv_linux_devices[num_nv_devices];
667      nv  = NV_STATE_PTR(nvl);
668  
669 +    pci_set_drvdata(dev, (void *)nvl);
670      nvl->dev          = dev;
671      nv->vendor_id     = dev->vendor;
672      nv->device_id     = dev->device;
673 @@ -3816,11 +3857,10 @@
674  #endif
675  }
676  
677 -#if defined(NV_PM_SUPPORT_ACPI)
678 +#if defined(NV_PM_SUPPORT_DEVICE_DRIVER_MODEL)
679  
680 -int
681 -nv_acpi_event
682 -(
683 +static int
684 +nv_power_management(
685      struct pci_dev *dev, 
686      u32 state
687  )
688 @@ -3828,70 +3868,77 @@
689      nv_state_t *nv;
690      nv_linux_state_t *lnv = NULL;
691      int status = RM_OK;
692 -    U032 i;
693  
694 -    nv_printf(NV_DBG_INFO, "NVRM: nv_acpi_event: %d\n", state);
695 -
696 -    for (i = 0; i < num_nv_devices; i++)
697 -    {
698 -        if (nv_linux_devices[i].dev == dev)
699 -        {
700 -            lnv = &nv_linux_devices[i];
701 -            break;
702 -        }
703 -    }
704 +    nv_printf(NV_DBG_INFO, "NVRM: nv_power_management: %d\n", state);
705 +    lnv = pci_get_drvdata(dev);
706  
707      if ((!lnv) || (lnv->dev != dev))
708      {
709 -        nv_printf(NV_DBG_WARNINGS, "NVRM: ACPI: invalid device!\n");
710 +        nv_printf(NV_DBG_WARNINGS, "NVRM: PM: invalid device!\n");
711          return -1;
712      }
713  
714      nv = NV_STATE_PTR(lnv);
715 +    nv_verify_pci_config(NV_STATE_PTR(lnv), TRUE);
716  
717      switch (state)
718      {
719 -        case PM_SUSPEND_MEM:
720 +#if defined(NV_PM_SUPPORT_NEW_STYLE_APM)
721 +        case PCI_D3hot:
722 +            nv_printf(NV_DBG_INFO, "NVRM: APM: received suspend event\n");
723 +            status = rm_power_management(nv, 0, NV_PM_APM_SUSPEND);
724 +            break;
725 +
726 +        case PCI_D0:
727 +            nv_printf(NV_DBG_INFO, "NVRM: APM: received resume event\n");
728 +            status = rm_power_management(nv, 0, NV_PM_APM_RESUME);
729 +            break;
730 +#else
731 +        case PCI_D3hot:
732              nv_printf(NV_DBG_INFO, "NVRM: ACPI: received suspend event\n");
733              status = rm_power_management(nv, 0, NV_PM_ACPI_STANDBY);
734              break;
735  
736 -        case PM_SUSPEND_ON:
737 +        case PCI_D0:
738              nv_printf(NV_DBG_INFO, "NVRM: ACPI: received resume event\n");
739              status = rm_power_management(nv, 0, NV_PM_ACPI_RESUME);
740              break;
741 -
742 +#endif
743          default:
744 -            nv_printf(NV_DBG_WARNINGS, "NVRM: ACPI: unsupported event: %d\n", state);
745 +            nv_printf(NV_DBG_WARNINGS, "NVRM: PM: unsupported event: %d\n", state);
746              return -1;
747      }
748  
749      if (status != RM_OK)
750 -        nv_printf(NV_DBG_ERRORS, "NVRM: ACPI: failed event: %d\n", state);
751 +        nv_printf(NV_DBG_ERRORS, "NVRM: PM: failed event: %d\n", state);
752  
753      return status;
754  }
755  
756 -int
757 -nv_kern_acpi_standby
758 -(
759 -    struct pci_dev *dev, 
760 -    u32 state
761 +static int nv_kern_suspend(
762 +    struct pci_dev *dev,
763 +    pm_message_t state
764  )
765  {
766 -    return nv_acpi_event(dev, state);
767 +    int power_state = -1;
768 +
769 +#if !defined(NV_PM_MESSAGE_T_PRESENT)
770 +    power_state = state;
771 +#elif defined(NV_PCI_CHOOSE_STATE_PRESENT)
772 +    power_state = pci_choose_state(dev, state);
773 +#endif
774 +
775 +    return nv_power_management(dev, power_state);
776  }
777  
778 -int
779 -nv_kern_acpi_resume
780 -(
781 +static int nv_kern_resume(
782      struct pci_dev *dev
783  )
784  {
785 -    return nv_acpi_event(dev, PM_SUSPEND_ON);
786 +    return nv_power_management(dev, PCI_D0);
787  }
788  
789 -#endif
790 +#endif /* defined(NV_PM_SUPPORT_DEVICE_DRIVER_MODEL) */
791  
792  void* NV_API_CALL nv_get_adapter_state(
793      U016 bus,