diff -urN usr-patched1.orig/src/nv/Makefile.kbuild usr/src/nv/Makefile.kbuild --- usr-patched1.orig/src/nv/Makefile.kbuild 2014-05-10 20:51:32.248123258 -0800 +++ usr/src/nv/Makefile.kbuild 2014-05-10 21:05:34.589180475 -0800 @@ -189,7 +189,11 @@ agp_memory \ scatterlist \ file_operations \ - sg_init_table + sg_init_table \ + proc_create_data \ + pde_data \ + proc_remove \ + get_num_physpages else COMPILE_TESTS = \ remap_page_range \ diff -urN usr-patched1.orig/src/nv/Makefile.kbuild.orig usr/src/nv/Makefile.kbuild.orig --- usr-patched1.orig/src/nv/Makefile.kbuild.orig 1969-12-31 14:00:00.000000000 -1000 +++ usr/src/nv/Makefile.kbuild.orig 2014-05-10 20:51:32.000000000 -0800 @@ -0,0 +1,333 @@ +# This Makefile is automatically generated; do not edit +# Generated on 'swio-display-x86-rh72-02.nvidia.com' on Fri Aug 31 14:52:31 PDT 2012 + +# to use this file, rename or delete the default Makefile, then rename or +# link this file to Makefile. then type 'make' + +# +# KBUILD Makefile for the NVIDIA Linux kernel module. +# +# The motivation for replacing the original Makefile is the hope that this +# version will simplify the build and installation process. In the past, +# many architectural and cosmetic changes to the Linux kernel have made it +# difficult to maintain compatibility or required duplication of logic. +# +# Linux 2.6 introduces numerous such changes, many of which impact modules. +# Relying on KBUILD, some aspects of the build system otherwise difficult +# to support (for example, module versioning) are abstracted away and dealt +# with elsewhere, making life significantly easier here. +# +# The new approach currently has its own share of problems, some of which +# are architectural difficulties with KBUILD, others minor annoyances. For +# this reason, an improved version of the NVIDIA Makefile is available to +# those experiencing difficulties. +# +# kbuild Makefile originally developed by: +# +# Alistair J Strachan (alistair@devzero.co.uk) (first pass, enhancements) +# Christian Zander (zander@mail.minion.de) (enhancements) +# + +all: install +install: package-install + +# +# The NVIDIA kernel module base name and static file names. KBUILD will go +# ahead and append ".o" or ".ko" to form the final module name. +# + +MODULE_NAME := nvidia +VERSION_HEADER := nv_compiler.h + +# +# List of object files to link into NVIDIA kernel module; make sure KBUILD +# understands that we want a module. +# + +CORE_OBJS := nv-kernel.o +RESMAN_GLUE_OBJS := nv.o nv-vm.o os-agp.o os-interface.o os-registry.o nv-i2c.o + +$(MODULE_NAME)-objs := $(CORE_OBJS) $(RESMAN_GLUE_OBJS) + +# +# The precompiled kernel module build process requires a separation of the +# closed source and open source object files. +# + +KERNEL_GLUE_NAME := nv-linux.o +KERNEL_GLUE_OBJS := $(RESMAN_GLUE_OBJS) $(MODULE_NAME).mod.o + +# +# A bug in KBUILD 2.4 means that leaving obj-m set in top-level context +# will cause Rules.make to call pathdown.sh, which is wrong. So, we only +# set this conditional of a kernel-level instance. +# + +TOPDIR ?= $(srctree) + +ifdef TOPDIR +obj-m := $(MODULE_NAME).o +endif + +# +# Include local source directory in $(CC)'s include path and set disable any +# warning types that are of little interest to us. +# + +EXTRA_CFLAGS += -I$(src) +EXTRA_CFLAGS += -Wall -Wimplicit -Wreturn-type -Wswitch -Wformat -Wchar-subscripts -Wparentheses -Wno-multichar -Werror -MD $(DEFINES) $(INCLUDES) -Wno-cast-qual -Wno-error + +# +# We rely on these two definitions below; if they aren't set, we set them to +# reasonable defaults (Linux 2.4's KBUILD, and top-level passes will not set +# these). +# + +src ?= . +obj ?= . + +# +# Determine location of the Linux kernel source tree. Allow users to override +# the default (i.e. automatically determined) kernel source location with the +# SYSSRC directive; this new directive replaces NVIDIA's SYSINCLUDE. +# + +KERNEL_MODLIB := /lib/modules/$(shell uname -r) + +ifdef SYSSRC + KERNEL_SOURCES := $(SYSSRC) + KERNEL_HEADERS := $(KERNEL_SOURCES)/include +else + KERNEL_UNAME := $(shell uname -r) + KERNEL_SOURCES := $(shell test -d $(KERNEL_MODLIB)/source && echo $(KERNEL_MODLIB)/source || echo $(KERNEL_MODLIB)/build) + KERNEL_HEADERS := $(KERNEL_SOURCES)/include +endif + +KERNEL_OUTPUT := $(KERNEL_SOURCES) +KBUILD_PARAMS := + +ifdef SYSOUT + ifneq ($(SYSOUT), $(KERNEL_SOURCES)) + KERNEL_OUTPUT := $(SYSOUT) + KBUILD_PARAMS := KBUILD_OUTPUT=$(KERNEL_OUTPUT) + endif +else + ifeq ($(KERNEL_SOURCES), $(KERNEL_MODLIB)/source) + KERNEL_OUTPUT := $(KERNEL_MODLIB)/build + KBUILD_PARAMS := KBUILD_OUTPUT=$(KERNEL_OUTPUT) + endif +endif + +CC ?= cc +HOST_CC ?= $(CC) +OBJDUMP ?= objdump +CONFTEST := /bin/sh $(src)/conftest.sh "$(CC)" "$(HOST_CC)" $(KERNEL_SOURCES) $(KERNEL_OUTPUT) + +KERNEL_UNAME ?= $(shell $(CONFTEST) get_uname) +MODULE_ROOT := /lib/modules/$(KERNEL_UNAME)/kernel/drivers + +# +# Sets any internal variables left unset by KBUILD (e.g. this happens during +# a top-level run). +# + +TOPDIR ?= $(KERNEL_SOURCES) +PATCHLEVEL ?= $(shell $(CONFTEST) kernel_patch_level) + +# +# Linux 2.4 uses the .o module extension. Linux 2.6, however, uses the .ko +# module extension. Handle these gracefully. +# + +ifeq ($(PATCHLEVEL), 4) + MODULE_OBJECT := $(MODULE_NAME).o +else + MODULE_OBJECT := $(MODULE_NAME).ko +endif + +# +# NVIDIA specific CFLAGS and #define's. The remap_page_range check has become +# necessary with the introduction of the five argument version to Linux 2.4 +# distribution kernels; this conflicting change cannot be detected at compile +# time. +# + +EXTRA_CFLAGS += -D_LOOSE_KERNEL_NAMES -D__KERNEL__ -DMODULE -DNVRM -DNV_VERSION_STRING=\"96.43.23\" -UDEBUG -U_DEBUG -DNDEBUG + +ifeq ($(shell echo $(NVDEBUG)),1) + ifeq ($(shell test -z $(RMDEBUG) && echo yes),yes) + RMDEBUG=1 + endif +endif + +ifeq ($(shell echo $(RMDEBUG)),1) + EXTRA_CFLAGS += -DDEBUG -g +endif + +ifneq ($(PATCHLEVEL), 4) + COMPILE_TESTS = \ + remap_page_range \ + remap_pfn_range \ + vmap \ + agp_backend_acquire \ + set_pages_uc \ + change_page_attr \ + i2c_adapter \ + pci_get_class \ + pm_message_t \ + irq_handler_t \ + pci_choose_state \ + vm_insert_page \ + acquire_console_sem \ + kmem_cache_create \ + on_each_cpu \ + smp_call_function \ + ioremap_cache \ + ioremap_wc \ + proc_dir_entry \ + acpi_walk_namespace \ + agp_memory \ + scatterlist \ + file_operations \ + sg_init_table +else + COMPILE_TESTS = \ + remap_page_range \ + vmap \ + change_page_attr \ + i2c_adapter \ + smp_call_function \ + proc_dir_entry \ + scatterlist +endif + +# +# Miscellaneous NVIDIA kernel module build support targets. They are needed +# to satisfy KBUILD requirements and to support NVIDIA specifics. +# + +$(obj)/$(CORE_OBJS): + cp $(src)/$(CORE_OBJS) $(obj)/$(CORE_OBJS) + +$(obj)/$(VERSION_HEADER): + @ echo \#define NV_COMPILER \"`$(CC) -v 2>&1 | tail -n 1`\" > $@ + +$(obj)/conftest.h: + @if ! $(CONFTEST) compile_tests $(COMPILE_TESTS); then exit 1; fi + +$(obj)/patches.h: + @if ! $(CONFTEST) patch_check; then exit 1; fi + +RESMAN_GLUE_TARGETS = $(addprefix $(obj)/,$(RESMAN_GLUE_OBJS)) + +$(RESMAN_GLUE_TARGETS): $(obj)/conftest.h $(obj)/patches.h + +$(obj)/nv.o: $(obj)/$(VERSION_HEADER) + +# +# More quirks for Linux 2.4 KBUILD, which doesn't link automatically. +# + +ifeq ($(PATCHLEVEL), 4) +$(obj)/$(MODULE_NAME).o: $($(MODULE_NAME)-objs) + $(LD) $(EXTRA_LDFLAGS) -r -o $@ $($(MODULE_NAME)-objs) +endif + +# +# KBUILD build parameters. +# + +KBUILD_PARAMS += KBUILD_VERBOSE=1 -C $(KERNEL_SOURCES) M=$(PWD) + +# +# NVIDIA sanity checks. +# + +.PHONY: suser-sanity-check rmmod-sanity-check build-sanity-checks + +suser-sanity-check: + @if ! $(CONFTEST) suser_sanity_check; then exit 1; fi + +rmmod-sanity-check: + @if ! $(CONFTEST) rmmod_sanity_check; then exit 1; fi + +build-sanity-checks: + @if ! $(CONFTEST) cc_version_check full_output; then exit 1; fi + @if ! $(CONFTEST) rivafb_sanity_check full_output; then exit 1; fi + @if ! $(CONFTEST) nvidiafb_sanity_check full_output; then exit 1; fi + @if ! $(CONFTEST) xen_sanity_check full_output; then exit 1; fi + +# +# Build the NVIDIA kernel module using Linux KBUILD. This target is used by +# the "package-install" target below. +# + +module: build-sanity-checks + @if [ -z "$(PATCHLEVEL)" ]; then \ + echo "failed to determine PATCHLEVEL!"; \ + exit 1; \ + fi; \ + echo "NVIDIA: calling KBUILD..."; \ + echo "make CC=$(CC) $(KBUILD_PARAMS) modules"; \ + make "CC=$(CC)" $(KBUILD_PARAMS) modules; \ + echo "NVIDIA: left KBUILD."; \ + if ! [ -f $(MODULE_OBJECT) ]; then \ + echo "$(MODULE_OBJECT) failed to build!"; \ + exit 1; \ + fi + +# +# Build the NVIDIA kernel module with KBUILD. Verify that the user posesses +# sufficient privileges. Rebuild the module dependency file. +# + +module-install: suser-sanity-check module + @mkdir -p $(MODULE_ROOT)/video; \ + install -m 0664 -o root -g root $(MODULE_OBJECT) $(MODULE_ROOT)/video; \ + PATH="$(PATH):/bin:/sbin" depmod -ae; + +# +# This target builds, then installs, then creates device nodes and inserts +# the module, if successful. +# + +package-install: module-install rmmod-sanity-check + PATH="$(PATH):/bin:/sbin" modprobe $(MODULE_NAME) && \ + echo "$(MODULE_OBJECT) installed successfully."; + +# +# Build an object file suitable for further processing by the installer and +# inclusion as a precompiled kernel interface file. +# + +$(KERNEL_GLUE_NAME): module + $(LD) $(EXTRA_LDFLAGS) -r -o $(KERNEL_GLUE_NAME) $(KERNEL_GLUE_OBJS) + +# +# Support hack, KBUILD isn't prepared to clean up after external modules. +# + +clean: + @ $(RM) -f $(RESMAN_GLUE_OBJS) $(KERNEL_GLUE_OBJS) + @ $(RM) -f build-in.o nv-linux.o *.d .*.{cmd,flags} + @ $(RM) -f $(MODULE_NAME).{o,ko,mod.{o,c}} $(VERSION_HEADER) *~ + @ $(RM) -f patches.h + @ $(RM) -f conftest*.c conftest.h + @ $(RM) -rf Modules.symvers .tmp_versions + +# +# This target just prints the kernel module filename (for use by the +# installer) +# + +print-module-filename: + @ echo $(MODULE_OBJECT) + +# +# Linux 2.4 KBUILD requires the inclusion of Rules.make; Linux 2.6's KBUILD +# includes dependencies automatically. +# + +ifeq ($(PATCHLEVEL), 4) +include $(KERNEL_SOURCES)/Rules.make +endif diff -urN usr-patched1.orig/src/nv/Makefile.nvidia usr/src/nv/Makefile.nvidia --- usr-patched1.orig/src/nv/Makefile.nvidia 2012-08-31 14:04:44.000000000 -0800 +++ usr/src/nv/Makefile.nvidia 2014-05-10 21:06:13.166083401 -0800 @@ -62,7 +62,10 @@ smp_call_function \ proc_dir_entry \ scatterlist \ - file_operations + file_operations \ + proc_create_data \ + pde_data \ + proc_remove DEFINES+=$(EXTRA_DEFINES) diff -urN usr-patched1.orig/src/nv/Makefile.nvidia.orig usr/src/nv/Makefile.nvidia.orig --- usr-patched1.orig/src/nv/Makefile.nvidia.orig 1969-12-31 14:00:00.000000000 -1000 +++ usr/src/nv/Makefile.nvidia.orig 2012-08-31 14:04:44.000000000 -0800 @@ -0,0 +1,133 @@ +# This Makefile is automatically generated; do not edit +# Generated on 'swio-display-x86-rh72-02.nvidia.com' on Fri Aug 31 14:52:31 PDT 2012 + +MODULE_NAME := nvidia + +LINUX_MODULE=nv-linux.o +DEFINES=-D__KERNEL__ -DMODULE -D_LOOSE_KERNEL_NAMES -DNVRM -DNV_VERSION_STRING=\"96.43.23\" +INCLUDES=-I. + +OBJECTS=nv.o nv-vm.o os-agp.o os-interface.o os-registry.o nv-i2c.o +HEADERS=os-agp.h os-interface.h nv-linux.h nv-misc.h nv-memdbg.h nv-vm.h nv.h rmretval.h cpuopsys.h nvtypes.h nvreadme.h $(VERSION_HDR) conftest.h patches.h + +CFLAGS=-Wall -Wimplicit -Wreturn-type -Wswitch -Wformat -Wchar-subscripts -Wparentheses -Wpointer-arith -Wno-multichar -Werror -O -UDEBUG -U_DEBUG -DNDEBUG -MD $(DEFINES) $(INCLUDES) -Wsign-compare -Wno-cast-qual -Wno-error + +CORE_OBJECTS=nv-kernel.o + +# +# Determine location of the Linux kernel source tree. Allow users to override +# the default (i.e. automatically determined) kernel source location with the +# SYSSRC directive; this new directive replaces NVIDIA's SYSINCLUDE. +# + +ifdef SYSSRC + KERNEL_SOURCES := $(SYSSRC) + KERNEL_HEADERS := $(KERNEL_SOURCES)/include +else + ifdef SYSINCLUDE + KERNEL_HEADERS := $(SYSINCLUDE) + KERNEL_SOURCES := $(KERNEL_HEADERS)/.. + else + KERNEL_UNAME := $(shell uname -r) + KERNEL_SOURCES := /lib/modules/$(KERNEL_UNAME)/build + KERNEL_HEADERS := $(KERNEL_SOURCES)/include + endif +endif + +CC ?= cc +HOST_CC ?= $(CC) +OBJDUMP ?= objdump +CONFTEST := /bin/sh ./conftest.sh "$(CC)" "$(HOST_CC)" $(KERNEL_SOURCES) $(KERNEL_SOURCES) + +KERNEL_UNAME ?= $(shell $(CONFTEST) get_uname) +MODULE_ROOT := /lib/modules/$(KERNEL_UNAME)/kernel/drivers + +ifeq ($(shell echo $(NVDEBUG)),1) + ifeq ($(shell test -z $(RMDEBUG) && echo yes),yes) + RMDEBUG=1 + endif +endif + +ifeq ($(shell echo $(RMDEBUG)),1) +CFLAGS += -DDEBUG -g +endif + +INCLUDES += -I$(KERNEL_HEADERS) + +COMPILE_TESTS = \ + remap_page_range \ + vmap \ + change_page_attr \ + i2c_adapter \ + smp_call_function \ + proc_dir_entry \ + scatterlist \ + file_operations + +DEFINES+=$(EXTRA_DEFINES) + +# allow build parameters to be passed in through the environment +ifdef BUILD_PARAMS + DEFINES+=-D$(BUILD_PARAMS) +endif + +VERSION_HDR=nv_compiler.h + +all: install + +install: package-install + +.PHONY: suser-sanity-check rmmod-sanity-check build-sanity-checks + +suser-sanity-check: + @if ! $(CONFTEST) suser_sanity_check; then exit; fi + +rmmod-sanity-check: + @if ! $(CONFTEST) rmmod_sanity_check; then exit; fi + +build-sanity-checks: + @if ! $(CONFTEST) cc_version_check full_output; then exit; fi + @if ! $(CONFTEST) rivafb_sanity_check full_output; then exit; fi + +module: build-sanity-checks $(LINUX_MODULE) $(CORE_OBJECTS) + $(LD) -r -o $(MODULE_NAME).o $(LINUX_MODULE) $(CORE_OBJECTS) + +package-install: module suser-sanity-check rmmod-sanity-check + mkdir -p $(MODULE_ROOT)/video && \ + install -m 0664 -o root -g root $(MODULE_NAME).o \ + $(MODULE_ROOT)/video/$(MODULE_NAME).o && \ + PATH="$(PATH):/bin:/sbin" depmod -a && \ + PATH="$(PATH):/bin:/sbin" modprobe $(MODULE_NAME) && \ + echo "$(MODULE_NAME).o installed successfully."; \ + +$(VERSION_HDR): + @ echo \#define NV_COMPILER \"`$(CC) -v 2>&1 | tail -n 1`\" > $@ + +$(LINUX_MODULE): $(OBJECTS) + $(LD) -r -o $@ $(OBJECTS) + +conftest.h: + @if ! $(CONFTEST) compile_tests $(COMPILE_TESTS); then exit; fi + +patches.h: + @if ! $(CONFTEST) patch_check; then exit; fi + +%.o: %.c $(HEADERS) + $(CC) -c $(CFLAGS) $< + +# debug tool to preprocess the file and leave .i to make it easier to untangle #defines +%.i: %.c + $(CC) $(CFLAGS) -E $< > $@ + +%.s: %.c + $(CC) $(CFLAGS) -S $< > $@ + +clean: + @ $(RM) $(OBJECTS) $(LINUX_MODULE) $(VERSION_HDR) *.d NVdriver $(MODULE_NAME).o + @ $(RM) patches.h + @ $(RM) conftest*.c conftest.h + +print-module-filename: + @echo "$(MODULE_NAME).o" + +-include $(OBJECTS:%.o=%.d) diff -urN usr-patched1.orig/src/nv/conftest.sh usr/src/nv/conftest.sh --- usr-patched1.orig/src/nv/conftest.sh 2014-05-10 21:02:17.740161977 -0800 +++ usr/src/nv/conftest.sh 2014-05-10 21:04:52.221795799 -0800 @@ -1208,6 +1208,99 @@ fi ;; + proc_create_data) + # + # Determine if the proc_create_data() function is present. + # + echo "$CONFTEST_PREAMBLE + #include + void conftest_proc_create_data(void) { + proc_create_data(); + }" > conftest$$.c + + $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1 + rm -f conftest$$.c + + if [ -f conftest$$.o ]; then + rm -f conftest$$.o + echo "#undef NV_PROC_CREATE_DATA_PRESENT" >> conftest.h + return + else + echo "#define NV_PROC_CREATE_DATA_PRESENT" >> conftest.h + return + fi + ;; + + + pde_data) + # + # Determine if the PDE_DATA() function is present. + # + echo "$CONFTEST_PREAMBLE + #include + void conftest_PDE_DATA(void) { + PDE_DATA(); + }" > conftest$$.c + + $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1 + rm -f conftest$$.c + + if [ -f conftest$$.o ]; then + rm -f conftest$$.o + echo "#undef NV_PDE_DATA_PRESENT" >> conftest.h + return + else + echo "#define NV_PDE_DATA_PRESENT" >> conftest.h + return + fi + ;; + + proc_remove) + # + # Determine if the proc_remove() function is present. + # + echo "$CONFTEST_PREAMBLE + #include + void conftest_proc_remove(void) { + proc_remove(); + }" > conftest$$.c + + $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1 + rm -f conftest$$.c + + if [ -f conftest$$.o ]; then + rm -f conftest$$.o + echo "#undef NV_PROC_REMOVE_PRESENT" >> conftest.h + return + else + echo "#define NV_PROC_REMOVE_PRESENT" >> conftest.h + return + fi + ;; + + get_num_physpages) + # + # Determine if the get_num_physpages() function is present. + # + echo "$CONFTEST_PREAMBLE + #include + void conftest_get_num_physpages(void) { + get_num_physpages(NULL); + }" > conftest$$.c + + $CC $CFLAGS -c conftest$$.c > /dev/null 2>&1 + rm -f conftest$$.c + + if [ -f conftest$$.o ]; then + rm -f conftest$$.o + echo "#undef NV_GET_NUM_PHYSPAGES_PRESENT" >> conftest.h + return + else + echo "#define NV_GET_NUM_PHYSPAGES_PRESENT" >> conftest.h + return + fi + ;; + esac } diff -urN usr-patched1.orig/src/nv/conftest.sh.orig usr/src/nv/conftest.sh.orig --- usr-patched1.orig/src/nv/conftest.sh.orig 2012-08-31 14:04:44.000000000 -0800 +++ usr/src/nv/conftest.sh.orig 2014-05-10 21:02:17.740161977 -0800 @@ -128,6 +128,7 @@ if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ]; then MACH_CFLAGS="$MACH_CFLAGS -I$HEADERS/asm-x86/mach-default" MACH_CFLAGS="$MACH_CFLAGS -I$SOURCES/arch/x86/include/asm/mach-default" + MACH_CFLAGS="$MACH_CFLAGS -I$HEADERS/arch/x86/include/uapi" fi if [ "$XEN_PRESENT" != "0" ]; then MACH_CFLAGS="-I$HEADERS/asm-$ARCH/mach-xen $MACH_CFLAGS" @@ -137,16 +138,21 @@ if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ]; then MACH_CFLAGS="$MACH_CFLAGS -I$HEADERS/asm-x86/mach-default" MACH_CFLAGS="$MACH_CFLAGS -I$SOURCES/arch/x86/include/asm/mach-default" + MACH_CFLAGS="$MACH_CFLAGS -I$HEADERS/arch/x86/include/uapi" fi if [ "$XEN_PRESENT" != "0" ]; then MACH_CFLAGS="-I$HEADERS/asm/mach-xen $MACH_CFLAGS" fi fi - CFLAGS="$BASE_CFLAGS $MACH_CFLAGS $OUTPUT_CFLAGS -I$HEADERS $AUTOCONF_CFLAGS" + CFLAGS="$BASE_CFLAGS $MACH_CFLAGS $OUTPUT_CFLAGS $AUTOCONF_CFLAGS" + CFLAGS="$CFLAGS -I$HEADERS -I$HEADERS/uapi -I$OUTPUT/include/generated/uapi" if [ "$ARCH" = "i386" -o "$ARCH" = "x86_64" ]; then - CFLAGS="$CFLAGS -I$SOURCES/arch/x86/include -I$OUTPUT/arch/x86/include/generated" + CFLAGS="$CFLAGS -I$SOURCES/arch/x86/include" + CFLAGS="$CFLAGS -I$SOURCES/arch/x86/include/uapi" + CFLAGS="$CFLAGS -I$OUTPUT/arch/x86/include/generated" + CFLAGS="$CFLAGS -I$OUTPUT/arch/x86/include/generated/uapi" fi if [ -n "$BUILD_PARAMS" ]; then CFLAGS="$CFLAGS -D$BUILD_PARAMS" @@ -1407,7 +1413,8 @@ FILE="linux/version.h" SELECTED_MAKEFILE="" - if [ -f $HEADERS/$FILE -o -f $OUTPUT/include/$FILE ]; then + if [ -f $HEADERS/$FILE -o -f $OUTPUT/include/$FILE -o \ + -f $OUTPUT/include/generated/uapi/$FILE ]; then # # We are either looking at a configured kernel source # tree or at headers shipped for a specific kernel. diff -urN usr-patched1.orig/src/nv/nv-i2c.c usr/src/nv/nv-i2c.c --- usr-patched1.orig/src/nv/nv-i2c.c 2012-08-31 14:04:44.000000000 -0800 +++ usr/src/nv/nv-i2c.c 2014-05-10 21:04:52.274802535 -0800 @@ -285,8 +285,6 @@ BOOL NV_API_CALL nv_i2c_del_adapter(nv_state_t *nv, void *data) { struct i2c_adapter *pI2cAdapter = (struct i2c_adapter *)data; - int osstatus = 0; - BOOL wasReleased = FALSE; #if defined(KERNEL_2_4) if (!NV_WEAK_SYMBOL_PRESENT(i2c_add_adapter)) @@ -297,16 +295,11 @@ if (!pI2cAdapter) return FALSE; - // attempt release with the OS - osstatus = i2c_del_adapter(pI2cAdapter); + // release with the OS + i2c_del_adapter(pI2cAdapter); + os_free_mem(pI2cAdapter); - if (!osstatus) - { - os_free_mem(pI2cAdapter); - wasReleased = TRUE; - } - - return wasReleased; + return TRUE; } #else // (defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)) diff -urN usr-patched1.orig/src/nv/nv-linux.h usr/src/nv/nv-linux.h --- usr-patched1.orig/src/nv/nv-linux.h 2014-05-10 21:02:17.747162867 -0800 +++ usr/src/nv/nv-linux.h 2014-05-10 21:04:52.277802917 -0800 @@ -140,6 +140,7 @@ #ifdef CONFIG_PROC_FS #include +#include #endif #ifdef CONFIG_MTRR diff -urN usr-patched1.orig/src/nv/nv-linux.h.orig usr/src/nv/nv-linux.h.orig --- usr-patched1.orig/src/nv/nv-linux.h.orig 1969-12-31 14:00:00.000000000 -1000 +++ usr/src/nv/nv-linux.h.orig 2014-05-10 21:02:17.747162867 -0800 @@ -0,0 +1,1286 @@ +/* _NVRM_COPYRIGHT_BEGIN_ + * + * Copyright 2001 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_ + */ + + +#ifndef _NV_LINUX_H_ +#define _NV_LINUX_H_ + +#include "nv.h" +#include "conftest.h" + +#if defined(NV_GENERATED_AUTOCONF_H_PRESENT) +#include +#else +#include +#endif + +#include +#include + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 4, 7) +# error This driver does not support 2.4 kernels older than 2.4.7! +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 5, 0) +# define KERNEL_2_4 +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 0) +# error This driver does not support 2.5 kernels! +#elif LINUX_VERSION_CODE < KERNEL_VERSION(2, 7, 0) +# define KERNEL_2_6 +#elif LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0) +# define KERNEL_3 +#else +# error This driver does not support development kernels! +#endif + +#if defined(KERNEL_2_4) +#define NV_KMEM_CACHE_CREATE_PRESENT +#define NV_KMEM_CACHE_CREATE_ARGUMENT_COUNT 6 +#define NV_IRQ_HANDLER_T_TAKES_PTREGS +#endif + +#if defined (CONFIG_SMP) && !defined (__SMP__) +#define __SMP__ +#endif + +#if defined (CONFIG_MODVERSIONS) && !defined (MODVERSIONS) +# define MODVERSIONS +#endif + +#if defined(MODVERSIONS) && defined(KERNEL_2_4) +#include +#endif + +#if defined(KERNEL_2_4) && !defined(EXPORT_SYMTAB) +#define EXPORT_SYMTAB +#endif + +#include +#include +#include + +#include + +#if !defined(VM_RESERVED) +#define VM_RESERVED 0x00000000 +#endif +#if !defined(VM_DONTEXPAND) +#define VM_DONTEXPAND 0x00000000 +#endif +#if !defined(VM_DONTDUMP) +#define VM_DONTDUMP 0x00000000 +#endif + +#include /* module_init, module_exit */ +#include /* pic_t, size_t, __u32, etc */ +#include /* error codes */ +#include /* circular linked list */ +#include /* NULL, offsetof */ +#include /* wait queues */ +#include /* strchr(), strpbrk() */ +#include /* isspace(), etc */ + +#include /* kmalloc, kfree, etc */ +#include /* vmalloc, vfree, etc */ + +#include /* poll_wait */ +#include /* mdelay, udelay */ + +#if !defined(KERNEL_2_4) +#include /* suser(), capable() replacement */ +#include /* module_param() */ +#include /* flush_tlb(), flush_tlb_all() */ +#include /* page table entry lookup */ +#endif + +#include /* pci_find_class, etc */ +#include /* tasklets, interrupt helpers */ +#include + +#include /* do_div() */ +#if defined(NV_ASM_SYSTEM_H_PRESENT) +#include /* cli, sli, save_flags */ +#endif +#include /* ioremap, virt_to_phys */ +#include /* access_ok */ +#include /* PAGE_OFFSET */ +#include /* pte bit definitions */ + +#if defined(NVCPU_X86_64) && !defined(KERNEL_2_4) && !defined(HAVE_COMPAT_IOCTL) +#include /* sys_ioctl() */ +#include /* register_ioctl32_conversion() */ +#endif + +#if defined(NVCPU_X86_64) && defined(KERNEL_2_4) +#include /* sys_ioctl() (ioctl32) */ +#endif + +#if !defined(NV_FILE_OPERATIONS_HAS_IOCTL) && \ + !defined(NV_FILE_OPERATIONS_HAS_UNLOCKED_IOCTL) +#error "struct file_operations compile test likely failed!" +#endif + +#if defined(CONFIG_VGA_ARB) +#include +#endif + +#include +#if defined(NV_LINUX_SEMAPHORE_H_PRESENT) +#include +#else +#include +#endif +#include +#include + +#ifdef CONFIG_PROC_FS +#include +#endif + +#ifdef CONFIG_MTRR +#include +#endif + +#ifdef CONFIG_KDB +#include +#include +#endif + +#if defined(CONFIG_X86_REMOTE_DEBUG) +#include +#endif + +#if defined (CONFIG_AGP) || defined (CONFIG_AGP_MODULE) +#define AGPGART +#include +#include +#endif + +#if defined(NVCPU_X86) || defined(NVCPU_X86_64) +#define NV_ENABLE_PAT_SUPPORT +#endif + +#define NV_PAT_MODE_DISABLED 0 +#define NV_PAT_MODE_KERNEL 1 +#define NV_PAT_MODE_BUILTIN 2 + +extern int nv_pat_mode; + +#if defined(CONFIG_HOTPLUG_CPU) +#include /* CPU hotplug support */ +#include /* struct notifier_block, etc */ +#endif + +#if (defined(CONFIG_I2C) || defined(CONFIG_I2C_MODULE)) +#include +#endif + +#if defined(KERNEL_2_4) || \ + (NV_ACPI_WALK_NAMESPACE_ARGUMENT_COUNT == 6) +#define NV_ACPI_WALK_NAMESPACE(type, args...) acpi_walk_namespace(type, args) +#elif (NV_ACPI_WALK_NAMESPACE_ARGUMENT_COUNT == 7) +#define NV_ACPI_WALK_NAMESPACE(type, start_object, max_depth, \ + user_function, args...) \ + acpi_walk_namespace(type, start_object, max_depth, \ + user_function, NULL, args) +#else +#error "NV_ACPI_WALK_NAMESPACE_ARGUMENT_COUNT value unrecognized!" +#endif + +#if defined(CONFIG_PREEMPT_RT) +typedef atomic_spinlock_t nv_spinlock_t; +#define NV_SPIN_LOCK_INIT(lock) atomic_spin_lock_init(lock) +#define NV_SPIN_LOCK_IRQ(lock) atomic_spin_lock_irq(lock) +#define NV_SPIN_UNLOCK_IRQ(lock) atomic_spin_unlock_irq(lock) +#define NV_SPIN_LOCK_IRQSAVE(lock,flags) atomic_spin_lock_irqsave(lock,flags) +#define NV_SPIN_UNLOCK_IRQRESTORE(lock,flags) \ + atomic_spin_unlock_irqrestore(lock,flags) +#define NV_SPIN_LOCK(lock) atomic_spin_lock(lock) +#define NV_SPIN_UNLOCK(lock) atomic_spin_unlock(lock) +#define NV_SPIN_UNLOCK_WAIT(lock) atomic_spin_unlock_wait(lock) +#else +typedef spinlock_t nv_spinlock_t; +#define NV_SPIN_LOCK_INIT(lock) spin_lock_init(lock) +#define NV_SPIN_LOCK_IRQ(lock) spin_lock_irq(lock) +#define NV_SPIN_UNLOCK_IRQ(lock) spin_unlock_irq(lock) +#define NV_SPIN_LOCK_IRQSAVE(lock,flags) spin_lock_irqsave(lock,flags) +#define NV_SPIN_UNLOCK_IRQRESTORE(lock,flags) spin_unlock_irqrestore(lock,flags) +#define NV_SPIN_LOCK(lock) spin_lock(lock) +#define NV_SPIN_UNLOCK(lock) spin_unlock(lock) +#define NV_SPIN_UNLOCK_WAIT(lock) spin_unlock_wait(lock) +#endif + +#if defined(NVCPU_X86) +#ifndef write_cr4 +#define write_cr4(x) __asm__ ("movl %0,%%cr4" :: "r" (x)); +#endif + +#ifndef read_cr4 +#define read_cr4() \ + ({ \ + unsigned int __cr4; \ + __asm__ ("movl %%cr4,%0" : "=r" (__cr4)); \ + __cr4; \ + }) +#endif + +#ifndef wbinvd +#define wbinvd() __asm__ __volatile__("wbinvd" ::: "memory"); +#endif +#endif /* defined(NVCPU_X86) */ + +#ifndef get_cpu +#define get_cpu() smp_processor_id() +#define put_cpu() +#endif + +#if !defined(unregister_hotcpu_notifier) +#define unregister_hotcpu_notifier unregister_cpu_notifier +#endif +#if !defined(register_hotcpu_notifier) +#define register_hotcpu_notifier register_cpu_notifier +#endif + +#if !defined (list_for_each) +#define list_for_each(pos, head) \ + for (pos = (head)->next; pos != (head); pos = (pos)->next) +#endif + +#if !defined(pmd_large) +#define pmd_large(_pmd) \ + ((pmd_val(_pmd) & (_PAGE_PSE|_PAGE_PRESENT)) == (_PAGE_PSE|_PAGE_PRESENT)) +#endif + +#if !defined(page_count) && defined(KERNEL_2_4) +#define page_count(page) (atomic_read(&(page)->count)) +#endif + +#define NV_GET_PAGE_COUNT(page_ptr) \ + (unsigned int)page_count(NV_GET_PAGE_STRUCT(page_ptr->phys_addr)) + +#if !defined(__GFP_COMP) +#define __GFP_COMP 0 +#endif + +#if !defined(DEBUG) && defined(__GFP_NOWARN) +#define NV_GFP_KERNEL (GFP_KERNEL | __GFP_NOWARN) +#define NV_GFP_ATOMIC (GFP_ATOMIC | __GFP_NOWARN) +#else +#define NV_GFP_KERNEL (GFP_KERNEL) +#define NV_GFP_ATOMIC (GFP_ATOMIC) +#endif + +#if defined(GFP_DMA32) +/* + * GFP_DMA32 is similar to GFP_DMA, but instructs the Linux zone + * allocator to allocate memory from the first 4GB on platforms + * such as Linux/x86-64; the alternative is to use an IOMMU such + * as the one implemented with the K8 GART, if available. + */ +#define NV_GFP_DMA32 (NV_GFP_KERNEL | GFP_DMA32) +#else +#define NV_GFP_DMA32 (NV_GFP_KERNEL) +#endif + +#define CACHE_FLUSH() asm volatile("wbinvd":::"memory") +#define WRITE_COMBINE_FLUSH() asm volatile("sfence":::"memory") + +#if !defined(IRQF_SHARED) +#define IRQF_SHARED SA_SHIRQ +#endif + +#define NV_MAX_RECURRING_WARNING_MESSAGES 10 + +/* add support for iommu. + * On the x86-64 platform, the driver may need to remap system + * memory pages via AMD K8/Intel VT-d IOMMUs if a given + * GPUs addressing capabilities are limited such that it can + * not access the original page directly. Examples of this + * are legacy PCI-E devices. + */ +#if (defined(NVCPU_X86_64) && !defined(GFP_DMA32)) || defined(CONFIG_DMAR) +#define NV_SG_MAP_BUFFERS 1 +extern int nv_swiotlb; + +#if defined(CONFIG_DMAR) +#define NV_INTEL_IOMMU 1 +#else +/* + * Limit use of IOMMU/SWIOTLB space to 60 MB, leaving 4 MB for the rest of + * the system (assuming a 64 MB IOMMU/SWIOTLB). + * This is not required if Intel VT-d IOMMU is used to remap pages. + */ +#define NV_NEED_REMAP_CHECK 1 +#define NV_REMAP_LIMIT_DEFAULT (60 * 1024 * 1024) +#endif +#endif + +/* add support for software i/o tlb support. + * normally, you'd expect this to be transparent, but unfortunately this is not + * the case. for starters, the sw io tlb is a pool of pre-allocated pages that + * are < 32-bits. when we ask to remap a page through this sw io tlb, we are + * returned one of these pages, which means we have 2 different pages, rather + * than 2 mappings to the same page. secondly, this pre-allocated pool is very + * tiny, and the kernel panics when it is exhausted. try to warn the user that + * they need to boost the size of their pool. + */ +#if defined(CONFIG_SWIOTLB) && !defined(GFP_DMA32) +#define NV_SWIOTLB 1 +#endif + +/* + * early 2.6 kernels changed their swiotlb codepath, running into a + * latent bug that returns virtual addresses when it should return + * physical addresses. we try to gracefully account for that, by + * comparing the returned address to what should be it's virtual + * equivalent. this should hopefully account for when the bug is + * fixed in the core kernel. + */ +#if defined(NV_SWIOTLB) && !defined(KERNEL_2_4) +#define NV_FIXUP_SWIOTLB_VIRT_ADDR_BUG(dma_addr) \ + if ((dma_addr) == ((dma_addr) | PAGE_OFFSET)) \ + (dma_addr) = __pa((dma_addr)) +#else +#define NV_FIXUP_SWIOTLB_VIRT_ADDR_BUG(dma_addr) +#endif + +#if !defined(KERNEL_2_4) && defined(NV_SG_INIT_TABLE_PRESENT) +#define NV_SG_INIT_TABLE(sgl, nents) \ + sg_init_table(sgl, nents) +#else +#define NV_SG_INIT_TABLE(sgl, nents) \ + memset(sgl, 0, (sizeof(*(sgl)) * (nents))); +#endif + +#ifndef NVWATCH + +/* various memory tracking/debugging techniques + * disabled for retail builds, enabled for debug builds + */ + +// allow an easy way to convert all debug printfs related to memory +// management back and forth between 'info' and 'errors' +#if defined(NV_DBG_MEM) +#define NV_DBG_MEMINFO NV_DBG_ERRORS +#else +#define NV_DBG_MEMINFO NV_DBG_INFO +#endif + +#ifdef DEBUG +#define NV_ENABLE_MEM_TRACKING 1 +#endif + +#if defined(NV_ENABLE_MEM_TRACKING) +#define NV_MEM_TRACKING_PAD_SIZE(size) ((size) += sizeof(void *)) +#define NV_MEM_TRACKING_HIDE_SIZE(ptr, size) \ + if ((ptr) && *(ptr)) { \ + U008 *__ptr; \ + *(unsigned long *) *(ptr) = (size); \ + __ptr = *(ptr); __ptr += sizeof(void *); \ + *(ptr) = (void *) __ptr; \ + } +#define NV_MEM_TRACKING_RETRIEVE_SIZE(ptr, size) \ + { \ + U008 *__ptr = (ptr); __ptr -= sizeof(void *); \ + (ptr) = (void *) __ptr; \ + size = *(unsigned long *) (ptr); \ + } +#else +#define NV_MEM_TRACKING_PAD_SIZE(size) +#define NV_MEM_TRACKING_HIDE_SIZE(ptr, size) +#define NV_MEM_TRACKING_RETRIEVE_SIZE(ptr, size) ((size) = 0) +#endif + + +/* poor man's memory allocation tracker. + * main intention is just to see how much memory is being used to recognize + * when memory usage gets out of control or if memory leaks are happening + */ + +/* keep track of memory usage */ +#if defined(NV_ENABLE_MEM_TRACKING) + +/* print out a running tally of memory allocation amounts, disabled by default */ +// #define POOR_MANS_MEM_CHECK 1 + + +/* slightly more advanced memory allocation tracker. + * track who's allocating memory and print out a list of currently allocated + * memory at key points in the driver + */ + +#define MEMDBG_ALLOC(a,b) (a = kmalloc(b, NV_GFP_ATOMIC)) +#define MEMDBG_FREE(a) (kfree(a)) + +#include "nv-memdbg.h" + +#undef MEMDBG_ALLOC +#undef MEMDBG_FREE + +/* print out list of memory allocations */ +/* default to enabled for now */ +#define LIST_MEM_CHECK 1 + +/* decide which memory types to apply mem trackers to */ +#define VM_CHECKER 1 +#define KM_CHECKER 1 + +#endif /* NV_ENABLE_MEM_TRACKING */ + +#if defined(VM_CHECKER) +/* kernel virtual memory usage/allocation information */ +extern U032 vm_usage; +extern struct mem_track_t *vm_list; +extern nv_spinlock_t vm_lock; + +# if defined(POOR_MANS_MEM_CHECK) +# define VM_PRINT(str, args...) printk(str, ##args) +# else +# define VM_PRINT(str, args...) +# endif +# if defined(LIST_MEM_CHECK) +# define VM_ADD_MEM(a,b,c,d) nv_add_mem(&vm_list, a, b, c, d) +# define VM_FREE_MEM(a,b,c,d) nv_free_mem(&vm_list, a, b, c, d) +# else +# define VM_ADD_MEM(a,b,c,d) +# define VM_FREE_MEM(a,b,c,d) +# endif +# define VM_ALLOC_RECORD(ptr, size, name) \ + if (ptr != NULL) \ + { \ + NV_SPIN_LOCK(&vm_lock); \ + vm_usage += size; \ + VM_PRINT("NVRM: %s (0x%p: 0x%x): VM usage is now 0x%x bytes\n", \ + name, (void *)ptr, size, vm_usage); \ + VM_ADD_MEM(ptr, size, __FILE__, __LINE__); \ + NV_SPIN_UNLOCK(&vm_lock); \ + } +# define VM_FREE_RECORD(ptr, size, name) \ + if (ptr != NULL) \ + { \ + NV_SPIN_LOCK(&vm_lock); \ + vm_usage -= size; \ + VM_PRINT("NVRM: %s (0x%p: 0x%x): VM usage is now 0x%x bytes\n", \ + name, (void *)ptr, size, vm_usage); \ + VM_FREE_MEM(ptr, size, __FILE__, __LINE__); \ + NV_SPIN_UNLOCK(&vm_lock); \ + } +#else +# define VM_ALLOC_RECORD(a,b,c) +# define VM_FREE_RECORD(a,b,c) +#endif + +#if defined(KM_CHECKER) +/* kernel logical memory usage/allocation information */ +extern U032 km_usage; +extern struct mem_track_t *km_list; +extern nv_spinlock_t km_lock; + +# if defined(POOR_MANS_MEM_CHECK) +# define KM_PRINT(str, args...) printk(str, ##args) +# else +# define KM_PRINT(str, args...) +# endif +# if defined(LIST_MEM_CHECK) +# define KM_ADD_MEM(a,b,c,d) nv_add_mem(&km_list, a, b, c, d) +# define KM_FREE_MEM(a,b,c,d) nv_free_mem(&km_list, a, b, c, d) +# else +# define KM_ADD_MEM(a,b,c,d) +# define KM_FREE_MEM(a,b,c,d) +# endif +# define KM_ALLOC_RECORD(ptr, size, name) \ + if (ptr != NULL) \ + { \ + unsigned long __eflags; \ + NV_SPIN_LOCK_IRQSAVE(&km_lock, __eflags); \ + km_usage += size; \ + KM_PRINT("NVRM: %s (0x%p: 0x%x): KM usage is now 0x%x bytes\n", \ + name, (void *)ptr, size, km_usage); \ + KM_ADD_MEM(ptr, size, __FILE__, __LINE__); \ + NV_SPIN_UNLOCK_IRQRESTORE(&km_lock, __eflags); \ + } +# define KM_FREE_RECORD(ptr, size, name) \ + if (ptr != NULL) \ + { \ + unsigned long __eflags; \ + NV_SPIN_LOCK_IRQSAVE(&km_lock, __eflags); \ + km_usage -= size; \ + KM_PRINT("NVRM: %s (0x%p: 0x%x): KM usage is now 0x%x bytes\n", \ + name, (void *)ptr, size, km_usage); \ + KM_FREE_MEM(ptr, size, __FILE__, __LINE__); \ + NV_SPIN_UNLOCK_IRQRESTORE(&km_lock, __eflags); \ + } +#else +# define KM_ALLOC_RECORD(a,b,c) +# define KM_FREE_RECORD(a,b,c) +#endif + +#define NV_VMALLOC(ptr, size, cached) \ + { \ + pgprot_t __prot = (cached) ? PAGE_KERNEL : PAGE_KERNEL_NOCACHE; \ + (ptr) = __vmalloc(size, GFP_KERNEL, __prot); \ + VM_ALLOC_RECORD(ptr, size, "vm_vmalloc"); \ + } + +#define NV_VFREE(ptr, size) \ + { \ + VM_FREE_RECORD(ptr, size, "vm_vfree"); \ + vfree((void *) (ptr)); \ + } + +#define NV_IOREMAP(ptr, physaddr, size) \ + { \ + (ptr) = ioremap(physaddr, size); \ + VM_ALLOC_RECORD(ptr, size, "vm_ioremap"); \ + } + +#define NV_IOREMAP_NOCACHE(ptr, physaddr, size) \ + { \ + (ptr) = ioremap_nocache(physaddr, size); \ + VM_ALLOC_RECORD(ptr, size, "vm_ioremap_nocache"); \ + } + +#if defined(NV_IOREMAP_CACHE_PRESENT) +#define NV_IOREMAP_CACHE(ptr, physaddr, size) \ + { \ + (ptr) = ioremap_cache(physaddr, size); \ + VM_ALLOC_RECORD(ptr, size, "vm_ioremap_cache"); \ + } +#else +#define NV_IOREMAP_CACHE NV_IOREMAP +#endif + +#if defined(NV_IOREMAP_WC_PRESENT) +#define NV_IOREMAP_WC(ptr, physaddr, size) \ + { \ + (ptr) = ioremap_wc(physaddr, size); \ + VM_ALLOC_RECORD(ptr, size, "vm_ioremap_wc"); \ + } +#else +#define NV_IOREMAP_WC NV_IOREMAP_NOCACHE +#endif + +#define NV_IOUNMAP(ptr, size) \ + { \ + VM_FREE_RECORD(ptr, size, "vm_iounmap"); \ + iounmap(ptr); \ + } + +/* only use this because GFP_KERNEL may sleep.. + * GFP_ATOMIC is ok, it won't sleep + */ +#define NV_KMALLOC(ptr, size) \ + { \ + (ptr) = kmalloc(size, NV_GFP_KERNEL); \ + KM_ALLOC_RECORD(ptr, size, "km_alloc"); \ + } + +#define NV_KMALLOC_ATOMIC(ptr, size) \ + { \ + (ptr) = kmalloc(size, NV_GFP_ATOMIC); \ + KM_ALLOC_RECORD(ptr, size, "km_alloc_atomic"); \ + } + + +#define NV_KFREE(ptr, size) \ + { \ + KM_FREE_RECORD(ptr, size, "km_free"); \ + kfree((void *) (ptr)); \ + } + +#define NV_GET_FREE_PAGES(ptr, order, gfp_mask) \ + { \ + (ptr) = __get_free_pages(gfp_mask, order); \ + } + +#define NV_FREE_PAGES(ptr, order) \ + { \ + free_pages(ptr, order); \ + } + +#if defined(NV_KMEM_CACHE_CREATE_PRESENT) +#if (NV_KMEM_CACHE_CREATE_ARGUMENT_COUNT == 6) +#define NV_KMEM_CACHE_CREATE(kmem_cache, name, type) \ + { \ + kmem_cache = kmem_cache_create(name, sizeof(type), \ + 0, 0, NULL, NULL); \ + } +#elif (NV_KMEM_CACHE_CREATE_ARGUMENT_COUNT == 5) +#define NV_KMEM_CACHE_CREATE(kmem_cache, name, type) \ + { \ + kmem_cache = kmem_cache_create(name, sizeof(type), \ + 0, 0, NULL); \ + } +#else +#error "NV_KMEM_CACHE_CREATE_ARGUMENT_COUNT value unrecognized!" +#endif +#define NV_KMEM_CACHE_DESTROY(kmem_cache) \ + { \ + kmem_cache_destroy(kmem_cache); \ + kmem_cache = NULL; \ + } +#else +#error "NV_KMEM_CACHE_CREATE() undefined (kmem_cache_create() unavailable)!" +#endif + +#define NV_KMEM_CACHE_ALLOC(ptr, kmem_cache, type) \ + { \ + (ptr) = kmem_cache_alloc(kmem_cache, GFP_KERNEL); \ + } + +#define NV_KMEM_CACHE_FREE(ptr, type, kmem_cache) \ + { \ + kmem_cache_free(kmem_cache, ptr); \ + } + +#if defined(NV_VMAP_PRESENT) +#if (NV_VMAP_ARGUMENT_COUNT == 2) +#define NV_VMAP_KERNEL(ptr, pages, count, prot) \ + { \ + (ptr) = (unsigned long)vmap(pages, count); \ + VM_ALLOC_RECORD((void *)ptr, (count) * PAGE_SIZE, "vm_vmap"); \ + } +#elif (NV_VMAP_ARGUMENT_COUNT == 4) +#ifndef VM_MAP +#define VM_MAP 0 +#endif +#define NV_VMAP_KERNEL(ptr, pages, count, prot) \ + { \ + (ptr) = (unsigned long)vmap(pages, count, VM_MAP, prot); \ + VM_ALLOC_RECORD((void *)ptr, (count) * PAGE_SIZE, "vm_vmap"); \ + } +#else +#error "NV_VMAP_ARGUMENT_COUNT value unrecognized!" +#endif +#else +#if defined(NV_SG_MAP_BUFFERS) +#error "NV_VMAP() undefined (vmap() unavailable)!" +#endif +#endif /* NV_VMAP_PRESENT */ + +#define NV_VUNMAP_KERNEL(ptr, count) \ + { \ + VM_FREE_RECORD((void *)ptr, (count) * PAGE_SIZE, "vm_vunmap"); \ + vunmap((void *)(ptr)); \ + } + +#define NV_VMAP(addr, pages, count, cached) \ + { \ + pgprot_t __prot = (cached) ? PAGE_KERNEL : PAGE_KERNEL_NOCACHE; \ + void *__ptr = nv_vmap(pages, count, __prot); \ + (addr) = (unsigned long)__ptr; \ + } + +#define NV_VUNMAP(addr, count) nv_vunmap((void *)addr, count) + + +#endif /* !defined NVWATCH */ + +#if defined(NV_SMP_CALL_FUNCTION_PRESENT) +#if (NV_SMP_CALL_FUNCTION_ARGUMENT_COUNT == 4) +#define NV_SMP_CALL_FUNCTION(func, info, wait) \ + ({ \ + int __ret = smp_call_function(func, info, 1, wait); \ + __ret; \ + }) +#elif (NV_SMP_CALL_FUNCTION_ARGUMENT_COUNT == 3) +#define NV_SMP_CALL_FUNCTION(func, info, wait) \ + ({ \ + int __ret = smp_call_function(func, info, wait); \ + __ret; \ + }) +#else +#error "NV_SMP_CALL_FUNCTION_ARGUMENT_COUNT value unrecognized!" +#endif +#elif defined(CONFIG_SMP) +#error "NV_SMP_CALL_FUNCTION() undefined (smp_call_function() unavailable)!" +#endif + +#if defined(NV_ON_EACH_CPU_PRESENT) +#if (NV_ON_EACH_CPU_ARGUMENT_COUNT == 4) +#define NV_ON_EACH_CPU(func, info, wait) \ + ({ \ + int __ret = on_each_cpu(func, info, 1, wait); \ + __ret; \ + }) +#elif (NV_ON_EACH_CPU_ARGUMENT_COUNT == 3) +#define NV_ON_EACH_CPU(func, info, wait) \ + ({ \ + int __ret = on_each_cpu(func, info, wait); \ + __ret; \ + }) +#else +#error "NV_ON_EACH_CPU_ARGUMENT_COUNT value unrecognized!" +#endif +#elif !defined(KERNEL_2_4) && defined(CONFIG_SMP) +#error "NV_ON_EACH_CPU() undefined (on_each_cpu() unavailable)!" +#endif + +static inline int nv_execute_on_all_cpus(void (*func)(void *info), void *info) +{ + int ret = 0; +#if !defined(CONFIG_SMP) + func(info); +#elif defined(KERNEL_2_4) +#if defined(preempt_disable) + preempt_disable(); +#endif + ret = NV_SMP_CALL_FUNCTION(func, info, 1); + func(info); +#if defined(preempt_enable) + preempt_enable(); +#endif +#else + ret = NV_ON_EACH_CPU(func, info, 1); +#endif + return ret; +} + +#if defined(CONFIG_PREEMPT_RT) +#define NV_INIT_MUTEX(mutex) semaphore_init(mutex) +#else +#define NV_INIT_MUTEX(mutex) \ + { \ + struct semaphore __mutex = \ + __SEMAPHORE_INITIALIZER(*(mutex), 1); \ + *(mutex) = __mutex; \ + } +#endif + +#if defined (KERNEL_2_4) +# define NV_IS_SUSER() suser() +# define NV_PCI_DEVICE_NAME(dev) ((dev)->name) +# define NV_NUM_CPUS() smp_num_cpus +# define NV_CLI() __cli() +# define NV_SAVE_FLAGS(eflags) __save_flags(eflags) +# define NV_RESTORE_FLAGS(eflags) __restore_flags(eflags) +# define NV_MAY_SLEEP() (!in_interrupt()) +# define NV_MODULE_PARAMETER(x) MODULE_PARM(x, "i") +# define NV_MODULE_STRING_PARAMETER(x) MODULE_PARM(x, "s") +#endif + +#if !defined(KERNEL_2_4) +# define NV_IS_SUSER() capable(CAP_SYS_ADMIN) +# define NV_PCI_DEVICE_NAME(dev) ((dev)->pretty_name) +# define NV_NUM_CPUS() num_online_cpus() +# define NV_CLI() local_irq_disable() +# define NV_SAVE_FLAGS(eflags) local_save_flags(eflags) +# define NV_RESTORE_FLAGS(eflags) local_irq_restore(eflags) +# define NV_MAY_SLEEP() (!irqs_disabled() && !in_interrupt() && !in_atomic()) +# define NV_MODULE_PARAMETER(x) module_param(x, int, 0) +# define NV_MODULE_STRING_PARAMETER(x) module_param(x, charp, 0) +# undef MODULE_PARM +#endif + +#if defined(NV_SIGNAL_STRUCT_HAS_RLIM) +/* per-process rlimit settings */ +#define NV_TASK_STRUCT_RLIM(current) ((current)->signal->rlim) +#else +/* per-thread rlimit settings */ +#define NV_TASK_STRUCT_RLIM(current) ((current)->rlim) +#endif + +#define NV_GET_PAGE_STRUCT(phys_page) virt_to_page(__va(phys_page)) +#define NV_VMA_PGOFF(vma) ((vma)->vm_pgoff) +#define NV_VMA_SIZE(vma) ((vma)->vm_end - (vma)->vm_start) +#define NV_VMA_OFFSET(vma) (((NvU64)(vma)->vm_pgoff) << PAGE_SHIFT) +#define NV_VMA_PRIVATE(vma) ((vma)->vm_private_data) +#define NV_VMA_FILE(vma) ((vma)->vm_file) + +#define NV_DEVICE_NUMBER(x) minor((x)->i_rdev) +#define NV_IS_CONTROL_DEVICE(x) (minor((x)->i_rdev) == 255) + +#define NV_PCI_DISABLE_DEVICE(dev) \ + { \ + NvU16 __cmd[2]; \ + pci_read_config_word((dev), PCI_COMMAND, &__cmd[0]); \ + pci_disable_device(dev); \ + pci_read_config_word((dev), PCI_COMMAND, &__cmd[1]); \ + __cmd[1] |= PCI_COMMAND_MEMORY; \ + pci_write_config_word((dev), PCI_COMMAND, \ + (__cmd[1] | (__cmd[0] & PCI_COMMAND_IO))); \ + } + +#define NV_PCI_RESOURCE_START(dev, bar) pci_resource_start(dev, (bar)) +#define NV_PCI_RESOURCE_SIZE(dev, bar) pci_resource_len(dev, (bar)) +#define NV_PCI_RESOURCE_FLAGS(dev, bar) pci_resource_flags(dev, (bar)) +#define NV_PCI_RESOURCE_VALID(dev, bar) \ + (NV_PCI_RESOURCE_START(dev, bar) != 0 && NV_PCI_RESOURCE_SIZE(dev, bar) != 0) + +#define NV_PCI_BUS_NUMBER(dev) (dev)->bus->number +#define NV_PCI_DEVFN(dev) (dev)->devfn +#define NV_PCI_SLOT_NUMBER(dev) PCI_SLOT(NV_PCI_DEVFN(dev)) + +#if defined(NV_PCI_GET_CLASS_PRESENT) +#define NV_PCI_DEV_PUT(dev) pci_dev_put(dev) +#define NV_PCI_GET_DEVICE(vendor,device,from) pci_get_device(vendor,device,from) +#define NV_PCI_GET_SLOT(bus,devfn) \ + ({ \ + struct pci_dev *__dev = NULL; \ + while ((__dev = pci_get_device(PCI_ANY_ID, PCI_ANY_ID, __dev))) \ + { \ + if (NV_PCI_BUS_NUMBER(__dev) == bus \ + && NV_PCI_DEVFN(__dev) == devfn) break; \ + } \ + __dev; \ + }) +#define NV_PCI_GET_CLASS(class,from) pci_get_class(class,from) +#else +#define NV_PCI_DEV_PUT(dev) +#define NV_PCI_GET_DEVICE(vendor,device,from) pci_find_device(vendor,device,from) +#define NV_PCI_GET_SLOT(bus,devfn) pci_find_slot(bus,devfn) +#define NV_PCI_GET_CLASS(class,from) pci_find_class(class,from) +#endif + +#define NV_PRINT_AT(nv_debug_level,at) \ + { \ + nv_printf(nv_debug_level, \ + "NVRM: VM: %s: 0x%p, %d page(s), count = %d, flags = 0x%08x, 0x%p, 0x%p\n", \ + __FUNCTION__, at, at->num_pages, NV_ATOMIC_READ(at->usage_count), \ + at->flags, at->key_mapping, at->page_table); \ + } + +#define NV_PRINT_VMA(nv_debug_level,vma) \ + { \ + nv_printf(nv_debug_level, \ + "NVRM: VM: %s: 0x%lx - 0x%lx, 0x%08x bytes @ 0x%016llx, 0x%p, 0x%p\n", \ + __FUNCTION__, vma->vm_start, vma->vm_end, NV_VMA_SIZE(vma), \ + NV_VMA_OFFSET(vma), NV_VMA_PRIVATE(vma), NV_VMA_FILE(vma)); \ + } + +/* + * On Linux 2.6, we support both APM and ACPI power management. On Linux + * 2.4, we support APM, only. ACPI support has been back-ported to the + * Linux 2.4 kernel, but the Linux 2.4 driver model is not sufficient for + * full ACPI support: it may work with some systems, but not reliably + * enough for us to officially support this configuration. + * + * We support two Linux kernel power managment interfaces: the original + * pm_register()/pm_unregister() on Linux 2.4 and the device driver model + * backed PCI driver power management callbacks introduced with Linux + * 2.6. + * + * The code below determines which interface to support on this kernel + * version, if any; if built for Linux 2.6, it will also determine if the + * kernel comes with ACPI or APM power management support. + */ +#if !defined(KERNEL_2_4) && defined(CONFIG_PM) +#define NV_PM_SUPPORT_DEVICE_DRIVER_MODEL +#if (defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)) && !defined(CONFIG_ACPI) +#define NV_PM_SUPPORT_NEW_STYLE_APM +#endif +#endif + +/* + * On Linux 2.6 kernels >= 2.6.11, the PCI subsystem provides a new + * interface that allows PCI drivers to determine the correct power state + * for a given system power state; our suspend/resume callbacks now use + * this interface and operate on PCI power state defines. + * + * Define these new PCI power state #define's here for compatibility with + * older Linux 2.6 kernels. + */ +#if !defined(KERNEL_2_4) && !defined(PCI_D0) +#define PCI_D0 PM_SUSPEND_ON +#define PCI_D3hot PM_SUSPEND_MEM +#endif + +#if !defined(KERNEL_2_4) && !defined(NV_PM_MESSAGE_T_PRESENT) +typedef u32 pm_message_t; +#endif + +#if defined(KERNEL_2_4) && (defined(CONFIG_APM) || defined(CONFIG_APM_MODULE)) +#include +#define NV_PM_SUPPORT_OLD_STYLE_APM +#endif + +#ifndef minor +# define minor(x) MINOR(x) +#endif + +#if defined(cpu_relax) +#define NV_CPU_RELAX() cpu_relax() +#else +#define NV_CPU_RELAX() barrier() +#endif + +#ifndef IRQ_RETVAL +typedef void irqreturn_t; +#define IRQ_RETVAL(a) +#endif + +#ifndef PCI_CAP_ID_EXP +#define PCI_CAP_ID_EXP 0x10 +#endif + +#if defined(NV_VM_INSERT_PAGE_PRESENT) +#define NV_VM_INSERT_PAGE(vma, addr, page) \ + vm_insert_page(vma, addr, page) +#endif +#if defined(NV_REMAP_PFN_RANGE_PRESENT) +#define NV_REMAP_PAGE_RANGE(from, offset, x...) \ + remap_pfn_range(vma, from, ((offset) >> PAGE_SHIFT), x) +#elif defined(NV_REMAP_PAGE_RANGE_PRESENT) +#if (NV_REMAP_PAGE_RANGE_ARGUMENT_COUNT == 5) +#define NV_REMAP_PAGE_RANGE(x...) remap_page_range(vma, x) +#elif (NV_REMAP_PAGE_RANGE_ARGUMENT_COUNT == 4) +#define NV_REMAP_PAGE_RANGE(x...) remap_page_range(x) +#else +#error "NV_REMAP_PAGE_RANGE_ARGUMENT_COUNT value unrecognized!" +#endif +#else +#error "NV_REMAP_PAGE_RANGE() undefined!" +#endif + +#define NV_PGD_OFFSET(address, kernel, mm) \ + ({ \ + struct mm_struct *__mm = (mm); \ + pgd_t *__pgd; \ + if (!kernel) \ + __pgd = pgd_offset(__mm, address); \ + else \ + __pgd = pgd_offset_k(address); \ + __pgd; \ + }) + +#define NV_PGD_PRESENT(pgd) \ + ({ \ + if ((pgd != NULL) && \ + (pgd_bad(*pgd) || pgd_none(*pgd))) \ + /* static */ pgd = NULL; \ + pgd != NULL; \ + }) + +#if defined(pmd_offset_map) +#define NV_PMD_OFFSET(address, pgd) \ + ({ \ + pmd_t *__pmd; \ + __pmd = pmd_offset_map(pgd, address); \ + }) +#define NV_PMD_UNMAP(pmd) pmd_unmap(pmd); +#else +#if defined(PUD_SHIFT) /* 4-level pgtable */ +#define NV_PMD_OFFSET(address, pgd) \ + ({ \ + pmd_t *__pmd = NULL; \ + pud_t *__pud; \ + __pud = pud_offset(pgd, address); \ + if ((__pud != NULL) && \ + !(pud_bad(*__pud) || pud_none(*__pud))) \ + __pmd = pmd_offset(__pud, address); \ + __pmd; \ + }) +#else /* 3-level pgtable */ +#define NV_PMD_OFFSET(address, pgd) \ + ({ \ + pmd_t *__pmd; \ + __pmd = pmd_offset(pgd, address); \ + }) +#endif +#define NV_PMD_UNMAP(pmd) +#endif + +#define NV_PMD_PRESENT(pmd) \ + ({ \ + if ((pmd != NULL) && \ + (pmd_bad(*pmd) || pmd_none(*pmd))) \ + { \ + NV_PMD_UNMAP(pmd); \ + pmd = NULL; /* mark invalid */ \ + } \ + pmd != NULL; \ + }) + +#if defined(pte_offset_atomic) +#define NV_PTE_OFFSET(address, pmd) \ + ({ \ + pte_t *__pte; \ + __pte = pte_offset_atomic(pmd, address); \ + NV_PMD_UNMAP(pmd); __pte; \ + }) +#define NV_PTE_UNMAP(pte) pte_kunmap(pte); +#elif defined(pte_offset) +#define NV_PTE_OFFSET(address, pmd) \ + ({ \ + pte_t *__pte; \ + __pte = pte_offset(pmd, address); \ + NV_PMD_UNMAP(pmd); __pte; \ + }) +#define NV_PTE_UNMAP(pte) +#else +#define NV_PTE_OFFSET(address, pmd) \ + ({ \ + pte_t *__pte; \ + __pte = pte_offset_map(pmd, address); \ + NV_PMD_UNMAP(pmd); __pte; \ + }) +#define NV_PTE_UNMAP(pte) pte_unmap(pte); +#endif + +#define NV_PTE_PRESENT(pte) \ + ({ \ + if ((pte != NULL) && !pte_present(*pte)) \ + { \ + NV_PTE_UNMAP(pte); \ + pte = NULL; /* mark invalid */ \ + } \ + pte != NULL; \ + }) + +#define NV_PTE_VALUE(pte) \ + ({ \ + unsigned long __pte_value = pte_val(*pte); \ + NV_PTE_UNMAP(pte); \ + __pte_value; \ + }) + + +#define NV_PAGE_ALIGN(addr) ( ((addr) + PAGE_SIZE - 1) / PAGE_SIZE) +#define NV_MASK_OFFSET(addr) ( (addr) & (PAGE_SIZE - 1) ) + +#if defined(NVCPU_X86) || defined(NVCPU_X86_64) +/* this isn't defined in some older kernel header files */ +#define NV_CPU_INTERRUPT_FLAGS_BIT (1<<9) +#else +#error define NV_CPU_INTERRUPT_FLAGS_BIT +#endif + +static inline int NV_IRQL_IS_RAISED(void) + { + unsigned long int eflags; + NV_SAVE_FLAGS(eflags); + return !(eflags & NV_CPU_INTERRUPT_FLAGS_BIT); + } + +static inline int nv_calc_order(unsigned int size) + { + int order = 0; + while ( ((1 << order) * PAGE_SIZE) < (size)) + { + order++; + } + return order; + } + +/* mark memory UC-, rather than UC (don't use _PAGE_PWT) */ +static inline pgprot_t pgprot_noncached_weak(pgprot_t old_prot) + { + pgprot_t new_prot = old_prot; + if (boot_cpu_data.x86 > 3) + new_prot = __pgprot(pgprot_val(old_prot) | _PAGE_PCD); + return new_prot; + } + +#if !defined (pgprot_noncached) +static inline pgprot_t pgprot_noncached(pgprot_t old_prot) + { + pgprot_t new_prot = old_prot; + if (boot_cpu_data.x86 > 3) + new_prot = __pgprot(pgprot_val(old_prot) | _PAGE_PCD | _PAGE_PWT); + return new_prot; + } +#endif +#if defined(KERNEL_2_4) && defined(NVCPU_X86) && !defined(pfn_to_page) +#define pfn_to_page(pfn) (mem_map + (pfn)) +#endif + +/* + * An allocated bit of memory using NV_MEMORY_ALLOCATION_OFFSET + * looks like this in the driver + */ + +typedef struct nv_pte_t { + unsigned long phys_addr; + unsigned long virt_addr; + dma_addr_t dma_addr; +#ifdef NV_SG_MAP_BUFFERS + struct scatterlist sg_list; +#endif +#if defined(NV_SWIOTLB) + unsigned long orig_phys_addr; + unsigned long orig_virt_addr; +#endif + unsigned int page_count; +} nv_pte_t; + +typedef struct nv_alloc_s { + struct nv_alloc_s *next; + atomic_t usage_count; + unsigned int flags; + unsigned int num_pages; + unsigned int order; + unsigned int size; + nv_pte_t **page_table; /* list of physical pages allocated */ + void *key_mapping; /* mapping used as a key for finding this nv_alloc_t */ + void *file; + unsigned int pid; + void *priv_data; + nv_state_t *nv; +} nv_alloc_t; + + +#define NV_ALLOC_TYPE_PCI (1<<0) +#define NV_ALLOC_TYPE_AGP (1<<1) +#define NV_ALLOC_TYPE_CONTIG (1<<2) + +#define NV_ALLOC_MAPPING_SHIFT 16 +#define NV_ALLOC_MAPPING(flags) (((flags)>>NV_ALLOC_MAPPING_SHIFT)&0xff) +#define NV_ALLOC_ENC_MAPPING(flags) ((flags)<private_data) + +#define NV_GET_NVFP(filep) ((nv_file_private_t *) FILE_PRIVATE(filep)) + +/* for the card devices */ +#define NVL_FROM_FILEP(filep) (NV_GET_NVFP(filep)->nvptr) + +#define NV_GET_NVL_FROM_NV_STATE(nv) \ + ((nv_linux_state_t *) nv->os_state) + +#define NV_STATE_PTR(nvl) (&((nvl)->nv_state)) + + +#define NV_ATOMIC_SET(data,val) atomic_set(&(data), (val)) +#define NV_ATOMIC_INC(data) atomic_inc(&(data)) +#define NV_ATOMIC_DEC(data) atomic_dec(&(data)) +#define NV_ATOMIC_DEC_AND_TEST(data) atomic_dec_and_test(&(data)) +#define NV_ATOMIC_READ(data) atomic_read(&(data)) + +extern int nv_update_memory_types; + +/* + * Using change_page_attr() on early Linux/x86-64 2.6 kernels may + * result in a BUG() being triggered. The underlying problem + * actually exists on multiple architectures and kernels, but only + * the above check for the condition and trigger a BUG(). + * + * Note that this is a due to a bug in the Linux kernel, not an + * NVIDIA driver bug (it can also be triggered by AGPGART). + * + * We therefore need to determine at runtime if change_page_attr() + * can be used safely on these kernels. + */ +#if defined(NV_CHANGE_PAGE_ATTR_PRESENT) && defined(NVCPU_X86_64) && \ + !defined(KERNEL_2_4) && \ + (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 11)) +#define NV_CHANGE_PAGE_ATTR_BUG_PRESENT +#endif + +#if defined(NVCPU_X86) || defined(NVCPU_X86_64) +/* + * On Linux/x86-64 (and recent Linux/x86) kernels, the PAGE_KERNEL + * and PAGE_KERNEL_NOCACHE protection bit masks include _PAGE_NX + * to indicate that the no-execute protection page feature is used + * for the page in question. + * + * We need to be careful to mask out _PAGE_NX when the host system + * doesn't support this feature or when it's disabled: the kernel + * may not do this in its implementation of the change_page_attr() + * interface. + */ +#ifndef X86_FEATURE_NX +#define X86_FEATURE_NX (1*32+20) +#endif +#ifndef boot_cpu_has +#define boot_cpu_has(x) test_bit(x, boot_cpu_data.x86_capability) +#endif +#ifndef MSR_EFER +#define MSR_EFER 0xc0000080 +#endif +#ifndef EFER_NX +#define EFER_NX (1 << 11) +#endif +#ifndef _PAGE_NX +#define _PAGE_NX ((NvU64)1 << 63) +#endif +extern NvU64 __nv_supported_pte_mask; +#endif + +#if defined(DEBUG) +#define NV_ASSERT(message, condition) \ +do \ +{ \ + if (!(condition)) \ + { \ + nv_printf(NV_DBG_ERRORS, "NVRM: ASSERT: %s\n", message); \ + os_dbg_breakpoint(); \ + } \ +} \ +while (0) +#else +#define NV_ASSERT(message, condition) +#endif /* DEBUG */ + +int nv_verify_page_mappings(nv_pte_t *, unsigned int); + +#endif /* _NV_LINUX_H_ */ diff -urN usr-patched1.orig/src/nv/nv.c usr/src/nv/nv.c --- usr-patched1.orig/src/nv/nv.c 2014-05-10 21:02:17.745162613 -0800 +++ usr/src/nv/nv.c 2014-05-10 21:04:52.273802408 -0800 @@ -163,6 +163,91 @@ /* lock-related functions that should only be called from this file */ static void nv_lock_init_locks(nv_state_t *nv); +#if defined(NV_PROC_DIR_ENTRY_HAS_OWNER) +#define NV_SET_PROC_ENTRY_OWNER(entry) ((entry)->owner = THIS_MODULE) +#else +#define NV_SET_PROC_ENTRY_OWNER(entry) +#endif + +#if defined(NV_PROC_CREATE_DATA_PRESENT) +# define NV_CREATE_PROC_ENTRY(name,mode,parent,fops,__data) \ + proc_create_data(name, __mode, parent, fops, __data) +#else +# define NV_CREATE_PROC_ENTRY(name,mode,parent,fops,__data) \ + ({ \ + struct proc_dir_entry *__entry; \ + __entry = create_proc_entry(name, mode, parent); \ + if (__entry != NULL) \ + { \ + NV_SET_PROC_ENTRY_OWNER(__entry); \ + __entry->proc_fops = fops; \ + __entry->data = (__data); \ + } \ + __entry; \ + }) +#endif + +#define NV_CREATE_PROC_FILE(filename,parent,__name,__data) \ + ({ \ + struct proc_dir_entry *__entry; \ + int __mode = (S_IFREG | S_IRUGO); \ + const struct file_operations *fops = &nv_kern_##__name##_fops; \ + if (fops->write != 0) \ + __mode |= S_IWUSR; \ + __entry = NV_CREATE_PROC_ENTRY(filename, __mode, parent, fops, \ + __data); \ + __entry; \ + }) + +/* + * proc_mkdir_mode exists in Linux 2.6.9, but isn't exported until Linux 3.0. + * Use the older interface instead unless the newer interface is necessary. + */ +#if defined(NV_PROC_REMOVE_PRESENT) +# define NV_PROC_MKDIR_MODE(name, mode, parent) \ + proc_mkdir_mode(name, mode, parent) +#else +# define NV_PROC_MKDIR_MODE(name, mode, parent) \ + ({ \ + struct proc_dir_entry *__entry; \ + __entry = create_proc_entry(name, mode, parent); \ + if (__entry != NULL) \ + NV_SET_PROC_ENTRY_OWNER(__entry); \ + __entry; \ + }) +#endif + +#define NV_CREATE_PROC_DIR(name,parent) \ + ({ \ + struct proc_dir_entry *__entry; \ + int __mode = (S_IFDIR | S_IRUGO | S_IXUGO); \ + __entry = NV_PROC_MKDIR_MODE(name, __mode, parent); \ + __entry; \ + }) + +#if defined(NV_PDE_DATA_PRESENT) +# define NV_PDE_DATA(inode) PDE_DATA(inode) +#else +# define NV_PDE_DATA(inode) PDE(inode)->data +#endif + +#define NV_DEFINE_PROCFS_SINGLE_FILE(__name) \ + static int nv_kern_open_##__name( \ + struct inode *inode, \ + struct file *filep \ + ) \ + { \ + return single_open(filep, nv_kern_read_##__name, \ + NV_PDE_DATA(inode)); \ + } \ + \ + static const struct file_operations nv_kern_##__name##_fops = { \ + .owner = THIS_MODULE, \ + .open = nv_kern_open_##__name, \ + .read = seq_read, \ + .llseek = seq_lseek, \ + .release = single_release, \ + }; /*** *** EXPORTS to Linux Kernel @@ -190,13 +275,6 @@ static int nv_kern_apm_event(struct pm_dev *, pm_request_t, void *); #endif -static int nv_kern_read_cardinfo(char *, char **, off_t off, int, int *, void *); -static int nv_kern_read_status(char *, char **, off_t off, int, int *, void *); -static int nv_kern_read_registry(char *, char **, off_t off, int, int *, void *); -static int nv_kern_read_agpinfo(char *, char **, off_t off, int, int *, void *); -static int nv_kern_read_version(char *, char **, off_t off, int, int *, void *); -static int nv_kern_read_text_file(char *, char **, off_t off, int, int *, void *); - int nv_kern_ctl_open(struct inode *, struct file *); int nv_kern_ctl_close(struct inode *, struct file *); unsigned int nv_kern_ctl_poll(struct file *, poll_table *); @@ -490,156 +568,17 @@ return NULL; } -static void nvos_proc_create(void) +static int +nv_kern_read_text_file( + struct seq_file *s, + void *v +) { -#ifdef CONFIG_PROC_FS - struct pci_dev *dev; - U032 j, i = 0; - char name[6]; - - struct proc_dir_entry *entry; - struct proc_dir_entry *proc_nvidia_agp, *proc_nvidia_cards; - - /* world readable directory */ - int d_flags = S_IFDIR | S_IRUGO | S_IXUGO; - - /* world readable file */ - int flags = S_IFREG | S_IRUGO; - - nv_state_t *nv; - nv_linux_state_t *nvl; - - proc_nvidia = create_proc_entry("driver/nvidia", d_flags, NULL); - if (!proc_nvidia) - goto failed; - - proc_nvidia_cards = create_proc_entry("cards", d_flags, proc_nvidia); - if (!proc_nvidia_cards) - goto failed; - - proc_nvidia_warnings = create_proc_entry("warnings", d_flags, proc_nvidia); - if (!proc_nvidia_warnings) - goto failed; - - proc_nvidia_patches = create_proc_entry("patches", d_flags, proc_nvidia); - if (!proc_nvidia_patches) - goto failed; - - /* - * Set the module owner to ensure that the reference - * count reflects accesses to the proc files. - */ -#if defined(NV_PROC_DIR_ENTRY_HAS_OWNER) - proc_nvidia->owner = THIS_MODULE; - proc_nvidia_cards->owner = THIS_MODULE; - proc_nvidia_warnings->owner = THIS_MODULE; - proc_nvidia_patches->owner = THIS_MODULE; -#endif - - for (j = 0; j < num_nv_devices; j++) - { - nvl = &nv_linux_devices[j]; - nv = NV_STATE_PTR(nvl); - - dev = nv_get_pci_device(nv); - if (!dev) - break; - - sprintf(name, "%d", i++); - entry = create_proc_entry(name, flags, proc_nvidia_cards); - if (!entry) { - NV_PCI_DEV_PUT(dev); - goto failed; - } - - entry->data = nv; - entry->read_proc = nv_kern_read_cardinfo; -#if defined(NV_PROC_DIR_ENTRY_HAS_OWNER) - entry->owner = THIS_MODULE; -#endif - - if (nvos_find_agp_capability(dev)) { - /* - * Create the /proc/driver/nvidia/agp/{status,host-bridge,card} - * entries now that we know there's AGP hardware. - */ - entry = create_proc_entry("agp", d_flags, proc_nvidia); - if (!entry) { - NV_PCI_DEV_PUT(dev); - goto failed; - } - -#if defined(NV_PROC_DIR_ENTRY_HAS_OWNER) - entry->owner = THIS_MODULE; -#endif - proc_nvidia_agp = entry; - - entry = create_proc_entry("status", flags, proc_nvidia_agp); - if (!entry) { - NV_PCI_DEV_PUT(dev); - goto failed; - } - - entry->data = nv; - entry->read_proc = nv_kern_read_status; -#if defined(NV_PROC_DIR_ENTRY_HAS_OWNER) - entry->owner = THIS_MODULE; -#endif - - entry = create_proc_entry("host-bridge", flags, proc_nvidia_agp); - if (!entry) { - NV_PCI_DEV_PUT(dev); - goto failed; - } - - entry->data = NULL; - entry->read_proc = nv_kern_read_agpinfo; -#if defined(NV_PROC_DIR_ENTRY_HAS_OWNER) - entry->owner = THIS_MODULE; -#endif - - entry = create_proc_entry("card", flags, proc_nvidia_agp); - if (!entry) { - NV_PCI_DEV_PUT(dev); - goto failed; - } - - entry->data = nv; - entry->read_proc = nv_kern_read_agpinfo; -#if defined(NV_PROC_DIR_ENTRY_HAS_OWNER) - entry->owner = THIS_MODULE; -#endif - } - - NV_PCI_DEV_PUT(dev); - } - - entry = create_proc_entry("version", flags, proc_nvidia); - if (!entry) - goto failed; - - entry->read_proc = nv_kern_read_version; -#if defined(NV_PROC_DIR_ENTRY_HAS_OWNER) - entry->owner = THIS_MODULE; -#endif - - entry = create_proc_entry("registry", flags, proc_nvidia); - if (!entry) - goto failed; - - entry->read_proc = nv_kern_read_registry; -#if defined(NV_PROC_DIR_ENTRY_HAS_OWNER) - entry->owner = THIS_MODULE; -#endif - - return; - -failed: - nv_printf(NV_DBG_ERRORS, "NVRM: failed to create /proc entries!\n"); - nvos_proc_remove_all(proc_nvidia); -#endif + return seq_puts(s, s->private); } +NV_DEFINE_PROCFS_SINGLE_FILE(text_file); + static void nvos_proc_add_text_file( struct proc_dir_entry *parent, @@ -647,26 +586,15 @@ const char *text ) { -#ifdef CONFIG_PROC_FS - struct proc_dir_entry *entry; - - /* world readable file */ - int flags = S_IFREG | S_IRUGO; - - entry = create_proc_entry(filename, flags, parent); - if (!entry) return; - - entry->data = (void *)text; - entry->read_proc = nv_kern_read_text_file; -#if defined(NV_PROC_DIR_ENTRY_HAS_OWNER) - entry->owner = THIS_MODULE; -#endif -#endif + NV_CREATE_PROC_FILE(filename, parent, text_file, (void *)text); } #ifdef CONFIG_PROC_FS static void nvos_proc_remove_all(struct proc_dir_entry *entry) { +#if defined(NV_PROC_REMOVE_PRESENT) + proc_remove(entry); +#else while (entry) { struct proc_dir_entry *next = entry->next; if (entry->subdir) @@ -676,6 +604,7 @@ break; entry = next; } +#endif } #endif @@ -2847,18 +2776,17 @@ } static int -nv_kern_read_cardinfo(char *page, char **start, off_t off, - int count, int *eof, void *data) +nv_kern_read_cardinfo( + struct seq_file *s, + void *v +) { + nv_state_t *nv = s->private; struct pci_dev *dev; char *type, *fmt, tmpstr[NV_DEVICE_NAME_LENGTH]; - int len = 0, status; + int status; U032 vbios_rev1, vbios_rev2, vbios_rev3, vbios_rev4, vbios_rev5; - nv_state_t *nv; - nv = (nv_state_t *) data; - *eof = 1; - dev = nv_get_pci_device(nv); if (!dev) return 0; @@ -2868,61 +2796,61 @@ strcpy (tmpstr, "Unknown"); } - len += sprintf(page+len, "Model: \t\t %s\n", tmpstr); - len += sprintf(page+len, "IRQ: \t\t %d\n", nv->interrupt_line); + seq_printf(s, "Model: \t\t %s\n", tmpstr); + seq_printf(s, "IRQ: \t\t %d\n", nv->interrupt_line); status = rm_get_vbios_version(nv, &vbios_rev1, &vbios_rev2, &vbios_rev3, &vbios_rev4, &vbios_rev5); if (status < 0) { /* before rm_init_adapter */ - len += sprintf(page+len, "Video BIOS: \t ??.??.??.??.??\n"); + seq_printf(s, "Video BIOS: \t ??.??.??.??.??\n"); } else { fmt = "Video BIOS: \t %02x.%02x.%02x.%02x.%02x\n"; - len += sprintf(page+len, fmt, vbios_rev1, vbios_rev2, vbios_rev3, - vbios_rev4, vbios_rev5); + seq_printf(s, fmt, vbios_rev1, vbios_rev2, vbios_rev3, vbios_rev4, + vbios_rev5); } if (nvos_find_agp_capability(dev)) type = "AGP"; else if (nvos_find_pci_express_capability(dev)) type = "PCI-E"; else type = "PCI"; - len += sprintf(page+len, "Card Type: \t %s\n", type); + seq_printf(s, "Card Type: \t %s\n", type); // Report the number of bits set in dev->dma_mask - len += sprintf(page+len, "DMA Size: \t %d bits\n", - nv_count_bits(dev->dma_mask)); - len += sprintf(page+len, "DMA Mask: \t 0x%llx\n", dev->dma_mask); + seq_printf(s, "DMA Size: \t %d bits\n", nv_count_bits(dev->dma_mask)); + seq_printf(s, "DMA Mask: \t 0x%llx\n", dev->dma_mask); NV_PCI_DEV_PUT(dev); - return len; + return 0; } +NV_DEFINE_PROCFS_SINGLE_FILE(cardinfo); + static int -nv_kern_read_version(char *page, char **start, off_t off, - int count, int *eof, void *data) +nv_kern_read_version( + struct seq_file *s, + void *v +) { - int len = 0; - *eof = 1; - - len += sprintf(page+len, "NVRM version: %s\n", pNVRM_ID); - len += sprintf(page+len, "GCC version: %s\n", NV_COMPILER); - - return len; + seq_printf(s, "NVRM version: %s\n", pNVRM_ID); + seq_printf(s, "GCC version: %s\n", NV_COMPILER); + + return 0; } +NV_DEFINE_PROCFS_SINGLE_FILE(version); + static int -nv_kern_read_agpinfo(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ +nv_kern_read_agpinfo( + struct seq_file *s, + void *v +) + { + nv_state_t *nv = s->private; struct pci_dev *dev; char *fw, *sba; u8 cap_ptr; u32 status, command, agp_rate; - int len = 0; - - nv_state_t *nv; - nv = (nv_state_t *) data; - *eof = 1; if (nv) { dev = nv_get_pci_device(nv); @@ -2933,13 +2861,12 @@ if (!dev) return 0; - len += sprintf(page+len, "Host Bridge: \t "); + seq_printf(s, "Host Bridge: \t "); #if defined(CONFIG_PCI_NAMES) - len += sprintf(page+len, "%s\n", NV_PCI_DEVICE_NAME(dev)); + seq_printf(s, "%s\n", NV_PCI_DEVICE_NAME(dev)); #else - len += sprintf(page+len, "PCI device %04x:%04x\n", - dev->vendor, dev->device); + seq_printf(s, "PCI device %04x:%04x\n", dev->vendor, dev->device); #endif } @@ -2952,40 +2879,40 @@ fw = (status & 0x00000010) ? "Supported" : "Not Supported"; sba = (status & 0x00000200) ? "Supported" : "Not Supported"; - len += sprintf(page+len, "Fast Writes: \t %s\n", fw); - len += sprintf(page+len, "SBA: \t\t %s\n", sba); + seq_printf(s, "Fast Writes: \t %s\n", fw); + seq_printf(s, "SBA: \t\t %s\n", sba); agp_rate = status & 0x7; if (status & 0x8) // agp 3.0 agp_rate <<= 2; - len += sprintf(page+len, "AGP Rates: \t %s%s%s%s\n", + seq_printf(s, "AGP Rates: \t %s%s%s%s\n", (agp_rate & 0x00000008) ? "8x " : "", (agp_rate & 0x00000004) ? "4x " : "", (agp_rate & 0x00000002) ? "2x " : "", (agp_rate & 0x00000001) ? "1x " : ""); - len += sprintf(page+len, "Registers: \t 0x%08x:0x%08x\n", status, command); + seq_printf(s, "Registers: \t 0x%08x:0x%08x\n", status, command); NV_PCI_DEV_PUT(dev); - return len; + return 0; } +NV_DEFINE_PROCFS_SINGLE_FILE(agpinfo); + static int -nv_kern_read_status(char *page, char **start, off_t off, - int count, int *eof, void *data) -{ +nv_kern_read_agp_status( + struct seq_file *s, + void *v +) + { + nv_state_t *nv = s->private; struct pci_dev *dev; char *fw, *sba, *drv; - int len = 0; u8 cap_ptr; u32 scratch; u32 status, command, agp_rate; - nv_state_t *nv; - nv = (nv_state_t *) data; - *eof = 1; - dev = nvos_get_agp_device_by_class(PCI_CLASS_BRIDGE_HOST); if (!dev) return 0; @@ -3006,10 +2933,10 @@ command &= scratch; if (NV_AGP_ENABLED(nv) && (command & 0x100)) { - len += sprintf(page+len, "Status: \t Enabled\n"); + seq_printf(s, "Status: \t Enabled\n"); drv = NV_OSAGP_ENABLED(nv) ? "AGPGART" : "NVIDIA"; - len += sprintf(page+len, "Driver: \t %s\n", drv); + seq_printf(s, "Driver: \t %s\n", drv); // mask off agp rate. // If this is agp 3.0, we need to shift the value @@ -3017,17 +2944,17 @@ if (status & 0x8) // agp 3.0 agp_rate <<= 2; - len += sprintf(page+len, "AGP Rate: \t %dx\n", agp_rate); + seq_printf(s, "AGP Rate: \t %dx\n", agp_rate); fw = (command & 0x00000010) ? "Enabled" : "Disabled"; - len += sprintf(page+len, "Fast Writes: \t %s\n", fw); + seq_printf(s, "Fast Writes: \t %s\n", fw); sba = (command & 0x00000200) ? "Enabled" : "Disabled"; - len += sprintf(page+len, "SBA: \t\t %s\n", sba); + seq_printf(s, "SBA: \t\t %s\n", sba); } else { int agp_config = 0; - len += sprintf(page+len, "Status: \t Disabled\n\n"); + seq_printf(s, "Status: \t Disabled\n\n"); /* * If we find AGP is disabled, but the RM registry indicates it @@ -3041,7 +2968,7 @@ rm_read_registry_dword(nv, "NVreg", "XNvAGP", &agp_config); if (agp_config != NVOS_AGP_CONFIG_DISABLE_AGP && NV_AGP_FAILED(nv)) { - len += sprintf(page+len, + seq_printf(s, "AGP initialization failed, please check the ouput \n" "of the 'dmesg' command and/or your system log file \n" "for additional information on this problem. \n"); @@ -3049,35 +2976,133 @@ } NV_PCI_DEV_PUT(dev); - return len; + return 0; } +NV_DEFINE_PROCFS_SINGLE_FILE(agp_status); + extern nv_parm_t nv_parms[]; extern char *NVreg_RegistryDwords; static int -nv_kern_read_registry(char *page, char **start, off_t off, - int count, int *eof, void *data) +nv_kern_read_registry( + struct seq_file *s, + void *v +) { - unsigned int i, len = 0; + unsigned int i; nv_parm_t *entry; - *eof = 1; for (i = 0; (entry = &nv_parms[i])->name != NULL; i++) - len += sprintf(page+len, "%s: %u\n", entry->name, *entry->data); + seq_printf(s, "%s: %u\n", entry->name, *entry->data); - len += sprintf(page+len, "RegistryDwords: \"%s\"\n", - (NVreg_RegistryDwords != NULL) ? NVreg_RegistryDwords : ""); + seq_printf(s, "RegistryDwords: \"%s\"\n", + (NVreg_RegistryDwords != NULL) ? NVreg_RegistryDwords : ""); - return len; + return 0; } -static int -nv_kern_read_text_file(char *page, char **start, off_t off, - int count, int *eof, void *data) +NV_DEFINE_PROCFS_SINGLE_FILE(registry); + +static void nvos_proc_create(void) { - *eof = 1; - return sprintf(page, "%s", (char *)data); +#ifdef CONFIG_PROC_FS + struct pci_dev *dev; + U032 j, i = 0; + char name[6]; + + struct proc_dir_entry *entry; + struct proc_dir_entry *proc_nvidia_agp, *proc_nvidia_cards; + + nv_state_t *nv; + nv_linux_state_t *nvl; + + proc_nvidia = NV_CREATE_PROC_DIR("driver/nvidia", NULL); + if (!proc_nvidia) + goto failed; + + proc_nvidia_cards = NV_CREATE_PROC_DIR("cards", proc_nvidia); + if (!proc_nvidia_cards) + goto failed; + + proc_nvidia_warnings = NV_CREATE_PROC_DIR("warnings", proc_nvidia); + if (!proc_nvidia_warnings) + goto failed; + + proc_nvidia_patches = NV_CREATE_PROC_DIR("patches", proc_nvidia); + if (!proc_nvidia_patches) + goto failed; + + for (j = 0; j < num_nv_devices; j++) + { + nvl = &nv_linux_devices[j]; + nv = NV_STATE_PTR(nvl); + + dev = nv_get_pci_device(nv); + if (!dev) + break; + + sprintf(name, "%d", i++); + entry = NV_CREATE_PROC_FILE(name, proc_nvidia_cards, cardinfo, nv); + if (!entry) { + NV_PCI_DEV_PUT(dev); + goto failed; + } + + if (nvos_find_agp_capability(dev)) { + /* + * Create the /proc/driver/nvidia/agp/{status,host-bridge,card} + * entries now that we know there's AGP hardware. + */ + entry = NV_CREATE_PROC_DIR("agp", proc_nvidia); + if (!entry) { + NV_PCI_DEV_PUT(dev); + goto failed; + } + +#if defined(NV_PROC_DIR_ENTRY_HAS_OWNER) + entry->owner = THIS_MODULE; +#endif + proc_nvidia_agp = entry; + + entry = NV_CREATE_PROC_FILE("status", proc_nvidia_agp, agp_status, + nv); + if (!entry) { + NV_PCI_DEV_PUT(dev); + goto failed; + } + + entry = NV_CREATE_PROC_FILE("host-bridge", proc_nvidia_agp, agpinfo, + NULL); + if (!entry) { + NV_PCI_DEV_PUT(dev); + goto failed; + } + + entry = NV_CREATE_PROC_FILE("card", proc_nvidia_agp, agpinfo, nv); + if (!entry) { + NV_PCI_DEV_PUT(dev); + goto failed; + } + } + + NV_PCI_DEV_PUT(dev); + } + + entry = NV_CREATE_PROC_FILE("version", proc_nvidia, version, NULL); + if (!entry) + goto failed; + + entry = NV_CREATE_PROC_FILE("registry", proc_nvidia, registry, NULL); + if (!entry) + goto failed; + + return; + +failed: + nv_printf(NV_DBG_ERRORS, "NVRM: failed to create /proc entries!\n"); + nvos_proc_remove_all(proc_nvidia); +#endif } /*** diff -urN usr-patched1.orig/src/nv/nv.c.orig usr/src/nv/nv.c.orig --- usr-patched1.orig/src/nv/nv.c.orig 2012-08-31 14:04:44.000000000 -0800 +++ usr/src/nv/nv.c.orig 2014-05-10 21:02:17.745162613 -0800 @@ -2348,9 +2348,8 @@ NV_PRINT_AT(NV_DBG_MEMINFO, at); nv_vm_list_page_count(&at->page_table[i], pages); - /* prevent the swapper from swapping it out */ - /* mark the memory i/o so the buffers aren't dumped on core dumps */ vma->vm_flags |= (VM_IO | VM_LOCKED | VM_RESERVED); + vma->vm_flags |= (VM_DONTEXPAND | VM_DONTDUMP); } NV_VMA_FILE(vma) = file; diff -urN usr-patched1.orig/src/nv/os-interface.c usr/src/nv/os-interface.c --- usr-patched1.orig/src/nv/os-interface.c 2012-08-31 14:04:44.000000000 -0800 +++ usr/src/nv/os-interface.c 2014-05-10 21:04:52.279803171 -0800 @@ -261,7 +261,15 @@ NvU64 NV_API_CALL os_get_system_memory_size(void) { - return ((NvU64) num_physpages * PAGE_SIZE) / RM_PAGE_SIZE; + NvU64 num_pages; + +#if defined(NV_GET_NUM_PHYSPAGES_PRESENT) + num_pages = get_num_physpages(); +#else + num_pages = num_physpages; +#endif + + return ((num_pages * PAGE_SIZE) / RM_PAGE_SIZE); } //