|
Lines 15-20
Link Here
|
| 15 |
#include "nv_compiler.h" |
15 |
#include "nv_compiler.h" |
| 16 |
#include "os-agp.h" |
16 |
#include "os-agp.h" |
| 17 |
|
17 |
|
|
|
18 |
MODULE_LICENSE("NVIDIA"); |
| 18 |
|
19 |
|
| 19 |
/* |
20 |
/* |
| 20 |
* our global state; one per device |
21 |
* our global state; one per device |
|
Lines 33-64
Link Here
|
| 33 |
*/ |
34 |
*/ |
| 34 |
|
35 |
|
| 35 |
nv_linux_state_t nv_ctl_device = { { 0 } }; |
36 |
nv_linux_state_t nv_ctl_device = { { 0 } }; |
| 36 |
void *nv_ctl_wqueue = NULL; |
37 |
wait_queue_head_t nv_ctl_waitqueue; |
| 37 |
|
38 |
|
| 38 |
// keep track of opened clients and their process id so they |
39 |
// keep track of opened clients and their process id so they |
| 39 |
// can be free'd up on abnormal close |
40 |
// can be free'd up on abnormal close |
| 40 |
nv_client_t nv_clients[NV_MAX_CLIENTS]; |
41 |
nv_client_t nv_clients[NV_MAX_CLIENTS]; |
| 41 |
struct tq_struct nv_bottom_halves[NV_MAX_CLIENTS]; |
|
|
| 42 |
|
42 |
|
| 43 |
#ifdef CONFIG_PROC_FS |
43 |
#ifdef CONFIG_PROC_FS |
| 44 |
struct proc_dir_entry *proc_nvidia; |
44 |
struct proc_dir_entry *proc_nvidia; |
| 45 |
#endif |
45 |
#endif |
| 46 |
|
46 |
|
| 47 |
#ifdef CONFIG_DEVFS_FS |
47 |
#ifdef CONFIG_DEVFS_FS |
| 48 |
devfs_handle_t nv_dev_handle[NV_MAX_DEVICES]; |
48 |
devfs_handle_t nv_devfs_handles[NV_MAX_DEVICES+1]; |
| 49 |
devfs_handle_t nv_ctl_handle; |
|
|
| 50 |
#endif |
49 |
#endif |
| 51 |
|
50 |
|
| 52 |
/* |
|
|
| 53 |
* pick apart our minor device number |
| 54 |
* low 3 bits is NV device |
| 55 |
* if 255, then its the control device |
| 56 |
*/ |
| 57 |
|
| 58 |
#define NV_DEVICE_NUMBER(_minor) ((_minor) & 0x0f) |
| 59 |
#define NV_DEVICE_IS_CONTROL_DEVICE(_minor) \ |
| 60 |
(((_minor) & 0xFF) == 0xFF) |
| 61 |
|
| 62 |
// #define NV_DBG_MEM 1 |
51 |
// #define NV_DBG_MEM 1 |
| 63 |
#undef NV_DBG_MEM |
52 |
#undef NV_DBG_MEM |
| 64 |
|
53 |
|
|
Lines 121-130
Link Here
|
| 121 |
*** EXPORTS to Linux Kernel |
110 |
*** EXPORTS to Linux Kernel |
| 122 |
***/ |
111 |
***/ |
| 123 |
|
112 |
|
| 124 |
/* linux module interface functions (called by linux kernel) */ |
|
|
| 125 |
int init_module(void); |
| 126 |
void cleanup_module(void); |
| 127 |
|
| 128 |
/* nv_kern_ functions, interfaces used by linux kernel */ |
113 |
/* nv_kern_ functions, interfaces used by linux kernel */ |
| 129 |
void nv_kern_vma_open(struct vm_area_struct *vma); |
114 |
void nv_kern_vma_open(struct vm_area_struct *vma); |
| 130 |
void nv_kern_vma_release(struct vm_area_struct *vma); |
115 |
void nv_kern_vma_release(struct vm_area_struct *vma); |
|
Lines 135-141
Link Here
|
| 135 |
unsigned int nv_kern_poll(struct file *, poll_table *); |
120 |
unsigned int nv_kern_poll(struct file *, poll_table *); |
| 136 |
int nv_kern_ioctl(struct inode *, struct file *, unsigned int, unsigned long); |
121 |
int nv_kern_ioctl(struct inode *, struct file *, unsigned int, unsigned long); |
| 137 |
void nv_kern_bh(void *); |
122 |
void nv_kern_bh(void *); |
| 138 |
void nv_kern_isr(int, void *, struct pt_regs *); |
123 |
irqreturn_t nv_kern_isr(int, void *, struct pt_regs *); |
| 139 |
void nv_kern_rc_timer(unsigned long); |
124 |
void nv_kern_rc_timer(unsigned long); |
| 140 |
#ifdef CONFIG_PM |
125 |
#ifdef CONFIG_PM |
| 141 |
int nv_kern_pm(struct pm_dev *dev, pm_request_t rqst, void *data); |
126 |
int nv_kern_pm(struct pm_dev *dev, pm_request_t rqst, void *data); |
|
Lines 158-163
Link Here
|
| 158 |
/* character driver entry points */ |
143 |
/* character driver entry points */ |
| 159 |
|
144 |
|
| 160 |
static struct file_operations nv_fops = { |
145 |
static struct file_operations nv_fops = { |
|
|
146 |
owner: THIS_MODULE, |
| 161 |
poll: nv_kern_poll, |
147 |
poll: nv_kern_poll, |
| 162 |
ioctl: nv_kern_ioctl, |
148 |
ioctl: nv_kern_ioctl, |
| 163 |
mmap: nv_kern_mmap, |
149 |
mmap: nv_kern_mmap, |
|
Lines 329-336
Link Here
|
| 329 |
{ |
315 |
{ |
| 330 |
nv_printf(NV_DBG_MEMINFO, " 0x%x (0x%x): count %d flags 0x%x\n", |
316 |
nv_printf(NV_DBG_MEMINFO, " 0x%x (0x%x): count %d flags 0x%x\n", |
| 331 |
page_ptr->phys_addr, page_ptr->dma_addr, |
317 |
page_ptr->phys_addr, page_ptr->dma_addr, |
| 332 |
(GET_MAP_NR(page_ptr->phys_addr))->count, |
318 |
(virt_to_page(__va(page_ptr->phys_addr)))->count, |
| 333 |
(GET_MAP_NR(page_ptr->phys_addr))->flags); |
319 |
(virt_to_page(__va(page_ptr->phys_addr)))->flags); |
| 334 |
num_pages--; |
320 |
num_pages--; |
| 335 |
page_ptr++; |
321 |
page_ptr++; |
| 336 |
} |
322 |
} |
|
Lines 401-407
Link Here
|
| 401 |
phys_addr = virt_to_phys((void *) virt_addr); |
387 |
phys_addr = virt_to_phys((void *) virt_addr); |
| 402 |
|
388 |
|
| 403 |
/* lock the page for dma purposes */ |
389 |
/* lock the page for dma purposes */ |
| 404 |
mem_map_reserve(GET_MAP_NR(phys_addr)); |
390 |
SetPageReserved(virt_to_page(__va(phys_addr))); |
| 405 |
|
391 |
|
| 406 |
page_ptr->phys_addr = phys_addr; |
392 |
page_ptr->phys_addr = phys_addr; |
| 407 |
page_ptr->virt_addr = virt_addr; |
393 |
page_ptr->virt_addr = virt_addr; |
|
Lines 447-453
Link Here
|
| 447 |
// but if we failed pci_map_sg, make sure to free this page |
433 |
// but if we failed pci_map_sg, make sure to free this page |
| 448 |
if (page_ptr->virt_addr) |
434 |
if (page_ptr->virt_addr) |
| 449 |
{ |
435 |
{ |
| 450 |
mem_map_unreserve(GET_MAP_NR(page_ptr->phys_addr)); |
436 |
ClearPageReserved(virt_to_page(__va(page_ptr->phys_addr))); |
| 451 |
NV_SET_PAGE_ATTRIB_CACHED(page_ptr); |
437 |
NV_SET_PAGE_ATTRIB_CACHED(page_ptr); |
| 452 |
#if defined(NVCPU_X86_64) |
438 |
#if defined(NVCPU_X86_64) |
| 453 |
// only unmap the page if it really was mapped through |
439 |
// only unmap the page if it really was mapped through |
|
Lines 481-487
Link Here
|
| 481 |
|
467 |
|
| 482 |
while (pages_left) |
468 |
while (pages_left) |
| 483 |
{ |
469 |
{ |
| 484 |
mem_map_unreserve(GET_MAP_NR(page_ptr->phys_addr)); |
470 |
ClearPageReserved(virt_to_page(__va(page_ptr->phys_addr))); |
| 485 |
page_ptr++; |
471 |
page_ptr++; |
| 486 |
pages_left--; |
472 |
pages_left--; |
| 487 |
} |
473 |
} |
|
Lines 674-684
Link Here
|
| 674 |
nv_linux_state_t *nvl; |
660 |
nv_linux_state_t *nvl; |
| 675 |
nv_linux_state_t *nv_max_devices; |
661 |
nv_linux_state_t *nv_max_devices; |
| 676 |
|
662 |
|
| 677 |
#if defined (KERNEL_2_2) |
|
|
| 678 |
struct proc_dir_entry *proc_root_driver; |
| 679 |
proc_root_driver = create_proc_entry("driver", flags, &proc_root); |
| 680 |
#endif |
| 681 |
|
| 682 |
proc_nvidia = create_proc_entry("nvidia", flags, proc_root_driver); |
663 |
proc_nvidia = create_proc_entry("nvidia", flags, proc_root_driver); |
| 683 |
proc_nvidia_cards = create_proc_entry("cards", flags, proc_nvidia); |
664 |
proc_nvidia_cards = create_proc_entry("cards", flags, proc_nvidia); |
| 684 |
proc_nvidia_agp = create_proc_entry("agp", flags, proc_nvidia); |
665 |
proc_nvidia_agp = create_proc_entry("agp", flags, proc_nvidia); |
|
Lines 740-748
Link Here
|
| 740 |
{ |
721 |
{ |
| 741 |
#ifdef CONFIG_PROC_FS |
722 |
#ifdef CONFIG_PROC_FS |
| 742 |
nvos_proc_remove_all(proc_nvidia); |
723 |
nvos_proc_remove_all(proc_nvidia); |
| 743 |
#if defined (KERNEL_2_2) |
|
|
| 744 |
remove_proc_entry("driver", &proc_root); |
| 745 |
#endif |
| 746 |
#endif |
724 |
#endif |
| 747 |
} |
725 |
} |
| 748 |
|
726 |
|
|
Lines 831-839
Link Here
|
| 831 |
*** EXPORTS to Linux Kernel |
809 |
*** EXPORTS to Linux Kernel |
| 832 |
***/ |
810 |
***/ |
| 833 |
|
811 |
|
| 834 |
int init_module(void) |
812 |
static int __init nvidia_init_module(void) |
| 835 |
{ |
813 |
{ |
| 836 |
nv_linux_state_t *nvl; |
|
|
| 837 |
int rc, i; |
814 |
int rc, i; |
| 838 |
|
815 |
|
| 839 |
memset(nv_linux_devices, 0, sizeof(nv_linux_devices)); |
816 |
memset(nv_linux_devices, 0, sizeof(nv_linux_devices)); |
|
Lines 846-852
Link Here
|
| 846 |
|
823 |
|
| 847 |
nv_printf(NV_DBG_ERRORS, "nvidia: loading %s\n", pNVRM_ID); |
824 |
nv_printf(NV_DBG_ERRORS, "nvidia: loading %s\n", pNVRM_ID); |
| 848 |
|
825 |
|
| 849 |
#ifdef CONFIG_DEVFS_FS |
826 |
#if defined(CONFIG_DEVFS_FS) && !defined(KERNEL_2_6) |
| 850 |
rc = devfs_register_chrdev(nv_major, "nvidia", &nv_fops); |
827 |
rc = devfs_register_chrdev(nv_major, "nvidia", &nv_fops); |
| 851 |
#else |
828 |
#else |
| 852 |
rc = register_chrdev(nv_major, "nvidia", &nv_fops); |
829 |
rc = register_chrdev(nv_major, "nvidia", &nv_fops); |
|
Lines 858-891
Link Here
|
| 858 |
} |
835 |
} |
| 859 |
|
836 |
|
| 860 |
#ifdef CONFIG_DEVFS_FS |
837 |
#ifdef CONFIG_DEVFS_FS |
| 861 |
memset(nv_dev_handle, 0, sizeof(devfs_handle_t) * NV_MAX_DEVICES); |
|
|
| 862 |
do { |
838 |
do { |
|
|
839 |
/* |
| 840 |
* XXX This code isn't pretty, but neither is dealing with the |
| 841 |
* various Linux devfs implemenation(s). While Linux APIs are |
| 842 |
* known to be anything but stable and oftentimes anything but |
| 843 |
* well designed, the devfs interface has been more painful to |
| 844 |
* deal with than most other APIs. |
| 845 |
*/ |
| 863 |
char name[10]; |
846 |
char name[10]; |
| 864 |
|
847 |
|
| 865 |
nv_ctl_handle = devfs_register(NULL, "nvidiactl", |
848 |
nv_devfs_handles[0] = NV_DEVFS_REGISTER("nvidiactl", 255); |
| 866 |
DEVFS_FL_DEFAULT, nv_major, 255, |
|
|
| 867 |
S_IFCHR | S_IRUGO | S_IWUGO, |
| 868 |
&nv_fops, NULL); |
| 869 |
|
849 |
|
| 870 |
for (i = 0; i < num_nv_devices; i++) { |
850 |
for (i = 0; i < num_nv_devices; i++) { |
| 871 |
sprintf(name, "nvidia%d", i); |
851 |
sprintf(name, "nvidia%d", i); |
| 872 |
nv_dev_handle[i] = devfs_register(NULL, name, |
852 |
nv_devfs_handles[i+1] = NV_DEVFS_REGISTER(name, i); |
| 873 |
DEVFS_FL_DEFAULT, nv_major, i, |
|
|
| 874 |
S_IFCHR | S_IRUGO | S_IWUGO, |
| 875 |
&nv_fops, NULL); |
| 876 |
} |
853 |
} |
| 877 |
} while(0); |
854 |
} while(0); |
| 878 |
#endif |
855 |
#endif |
| 879 |
|
856 |
|
| 880 |
nv_printf(NV_DBG_INFO, "init_module: major number %d\n", nv_major); |
857 |
nv_printf(NV_DBG_INFO, "nvidia_init_module: major number %d\n", nv_major); |
| 881 |
|
858 |
|
| 882 |
// init all the bottom half structures |
859 |
/* instantiate tasklets */ |
| 883 |
for (nvl = nv_linux_devices; nvl < nv_linux_devices + NV_MAX_DEVICES; nvl++) |
860 |
for (i = 0; i < NV_MAX_DEVICES; i++) { |
| 884 |
{ |
861 |
/* |
| 885 |
nvl->bh = &nv_bottom_halves[nvl - nv_linux_devices]; |
862 |
* We keep one tasklet per card to avoid latency issues with more |
| 886 |
nvl->bh->routine = nv_kern_bh; |
863 |
* than one device; no two instances of a single tasklet are ever |
| 887 |
nvl->bh->data = (void *) nvl; |
864 |
* executed concurrently. |
| 888 |
nvl->bh->sync = 0; |
865 |
*/ |
|
|
866 |
atomic_set(&nv_linux_devices[i].tasklet.count, 1); |
| 889 |
} |
867 |
} |
| 890 |
|
868 |
|
| 891 |
// init the nvidia control device |
869 |
// init the nvidia control device |
|
Lines 893-898
Link Here
|
| 893 |
nv_state_t *nv_ctl = NV_STATE_PTR(&nv_ctl_device); |
871 |
nv_state_t *nv_ctl = NV_STATE_PTR(&nv_ctl_device); |
| 894 |
nv_ctl->os_state = (void *) &nv_ctl_device; |
872 |
nv_ctl->os_state = (void *) &nv_ctl_device; |
| 895 |
nv_lock_init_locks(nv_ctl); |
873 |
nv_lock_init_locks(nv_ctl); |
|
|
874 |
init_waitqueue_head(&nv_ctl_waitqueue); |
| 896 |
} |
875 |
} |
| 897 |
|
876 |
|
| 898 |
#ifdef CONFIG_PM |
877 |
#ifdef CONFIG_PM |
|
Lines 919-932
Link Here
|
| 919 |
/* create /proc/driver/nvidia */ |
898 |
/* create /proc/driver/nvidia */ |
| 920 |
nvos_proc_create(); |
899 |
nvos_proc_create(); |
| 921 |
|
900 |
|
| 922 |
#if defined(DEBUG) && !defined(KERNEL_2_2) |
901 |
#if defined(DEBUG) |
| 923 |
inter_module_register("nv_linux_devices", THIS_MODULE, nv_linux_devices); |
902 |
inter_module_register("nv_linux_devices", THIS_MODULE, nv_linux_devices); |
| 924 |
#endif |
903 |
#endif |
| 925 |
|
904 |
|
| 926 |
return 0; |
905 |
return 0; |
| 927 |
|
906 |
|
| 928 |
failed: |
907 |
failed: |
| 929 |
#ifdef CONFIG_DEVFS_FS |
908 |
#if defined(CONFIG_DEVFS_FS) && !defined(KERNEL_2_6) |
| 930 |
devfs_unregister_chrdev(nv_major, "nvidia"); |
909 |
devfs_unregister_chrdev(nv_major, "nvidia"); |
| 931 |
#else |
910 |
#else |
| 932 |
unregister_chrdev(nv_major, "nvidia"); |
911 |
unregister_chrdev(nv_major, "nvidia"); |
|
Lines 934-959
Link Here
|
| 934 |
return rc; |
913 |
return rc; |
| 935 |
} |
914 |
} |
| 936 |
|
915 |
|
| 937 |
void cleanup_module(void) |
916 |
static void __exit nvidia_exit_module(void) |
| 938 |
{ |
917 |
{ |
| 939 |
int rc, i; |
918 |
int rc; |
| 940 |
nv_linux_state_t *nvl; |
919 |
nv_linux_state_t *nvl, *max_devices; |
| 941 |
nv_linux_state_t *max_devices; |
|
|
| 942 |
|
920 |
|
| 943 |
/* remove /proc/driver/nvidia */ |
921 |
/* remove /proc/driver/nvidia */ |
| 944 |
nvos_proc_remove(); |
922 |
nvos_proc_remove(); |
| 945 |
|
923 |
|
| 946 |
nv_printf(NV_DBG_INFO, "cleanup_module\n"); |
924 |
nv_printf(NV_DBG_INFO, "nvidia_exit_module\n"); |
| 947 |
|
925 |
|
| 948 |
#if defined(DEBUG) && !defined(KERNEL_2_2) |
926 |
#if defined(DEBUG) |
| 949 |
inter_module_unregister("nv_linux_devices"); |
927 |
inter_module_unregister("nv_linux_devices"); |
| 950 |
#endif |
928 |
#endif |
| 951 |
|
929 |
|
| 952 |
#ifdef CONFIG_PM |
930 |
#ifdef CONFIG_PM |
| 953 |
for (i = 0; i < num_nv_devices; i++) |
931 |
do { |
| 954 |
{ |
932 |
int i; |
| 955 |
pm_unregister(pm_nv_dev[i]); |
933 |
for (i = 0; i < num_nv_devices; i++) { |
| 956 |
} |
934 |
pm_unregister(pm_nv_dev[i]); |
|
|
935 |
} |
| 936 |
} while (0); |
| 957 |
#endif |
937 |
#endif |
| 958 |
|
938 |
|
| 959 |
// Shutdown the resource manager |
939 |
// Shutdown the resource manager |
|
Lines 972-1001
Link Here
|
| 972 |
continue; |
952 |
continue; |
| 973 |
|
953 |
|
| 974 |
nv_printf(NV_DBG_ERRORS, |
954 |
nv_printf(NV_DBG_ERRORS, |
| 975 |
"still have vm que at cleanup_module(): 0x%x to 0x%x\n", |
955 |
"still have vm que at nvidia_exit_module(): 0x%x to 0x%x\n", |
| 976 |
nvl->alloc_queue->vma->vm_start, |
956 |
nvl->alloc_queue->vma->vm_start, |
| 977 |
nvl->alloc_queue->vma->vm_end); |
957 |
nvl->alloc_queue->vma->vm_end); |
| 978 |
} |
958 |
} |
| 979 |
} |
959 |
} |
| 980 |
|
960 |
|
| 981 |
#ifdef CONFIG_DEVFS_FS |
961 |
#if defined(CONFIG_DEVFS_FS) && !defined(KERNEL_2_6) |
| 982 |
rc = devfs_unregister_chrdev(nv_major, "nvidia"); |
962 |
rc = devfs_unregister_chrdev(nv_major, "nvidia"); |
| 983 |
#else |
963 |
#else |
| 984 |
rc = unregister_chrdev(nv_major, "nvidia"); |
964 |
rc = unregister_chrdev(nv_major, "nvidia"); |
| 985 |
#endif |
965 |
#endif |
| 986 |
|
966 |
|
| 987 |
if (rc < 0) { |
967 |
if (rc < 0) { |
| 988 |
nv_printf(NV_DBG_ERRORS, "cleanup_module: unregister nv failed\n"); |
968 |
nv_printf(NV_DBG_ERRORS, "nvidia_exit_module: unregister nv failed\n"); |
| 989 |
} |
969 |
} |
| 990 |
|
970 |
|
| 991 |
#ifdef CONFIG_DEVFS_FS |
971 |
#ifdef CONFIG_DEVFS_FS |
| 992 |
do { |
972 |
do { |
| 993 |
int i; |
973 |
int i; |
| 994 |
for (i = 0; nv_dev_handle[i] != 0; i++) { |
974 |
NV_DEVFS_REMOVE_CONTROL(); |
| 995 |
devfs_unregister(nv_dev_handle[i]); |
975 |
for (i = 0; i < num_nv_devices; i++) |
| 996 |
} |
976 |
NV_DEVFS_REMOVE_DEVICE(i); |
| 997 |
} while(0); |
977 |
} while (0); |
| 998 |
devfs_unregister(nv_ctl_handle); |
|
|
| 999 |
#endif |
978 |
#endif |
| 1000 |
|
979 |
|
| 1001 |
#if NV_ENABLE_MEM_TRACKING |
980 |
#if NV_ENABLE_MEM_TRACKING |
|
Lines 1007-1012
Link Here
|
| 1007 |
#endif |
986 |
#endif |
| 1008 |
} |
987 |
} |
| 1009 |
|
988 |
|
|
|
989 |
module_init(nvidia_init_module); |
| 990 |
module_exit(nvidia_exit_module); |
| 1010 |
|
991 |
|
| 1011 |
/* this is only called when the vmas are duplicated. |
992 |
/* this is only called when the vmas are duplicated. |
| 1012 |
* this appears to only happen when the process is cloned to create |
993 |
* this appears to only happen when the process is cloned to create |
|
Lines 1020-1030
Link Here
|
| 1020 |
nv_kern_vma_open(struct vm_area_struct *vma) |
1001 |
nv_kern_vma_open(struct vm_area_struct *vma) |
| 1021 |
{ |
1002 |
{ |
| 1022 |
nv_printf(NV_DBG_MEMINFO, "vma_open for 0x%x - 0x%x, offset 0x%x\n", |
1003 |
nv_printf(NV_DBG_MEMINFO, "vma_open for 0x%x - 0x%x, offset 0x%x\n", |
| 1023 |
vma->vm_start, vma->vm_end, LINUX_VMA_OFFS(vma)); |
1004 |
vma->vm_start, vma->vm_end, NV_VMA_OFFSET(vma)); |
| 1024 |
|
1005 |
|
| 1025 |
if (VMA_PRIVATE(vma)) |
1006 |
if (NV_VMA_PRIVATE(vma)) |
| 1026 |
{ |
1007 |
{ |
| 1027 |
nv_alloc_t *at = (nv_alloc_t *) VMA_PRIVATE(vma); |
1008 |
nv_alloc_t *at = (nv_alloc_t *) NV_VMA_PRIVATE(vma); |
| 1028 |
at->usage_count++; |
1009 |
at->usage_count++; |
| 1029 |
|
1010 |
|
| 1030 |
nv_printf(NV_DBG_MEMINFO, " at 0x%x, usage count %d, page_table 0x%x\n", |
1011 |
nv_printf(NV_DBG_MEMINFO, " at 0x%x, usage count %d, page_table 0x%x\n", |
|
Lines 1032-1039
Link Here
|
| 1032 |
|
1013 |
|
| 1033 |
nvos_list_page_count(at->page_table, at->num_pages); |
1014 |
nvos_list_page_count(at->page_table, at->num_pages); |
| 1034 |
} |
1015 |
} |
| 1035 |
|
|
|
| 1036 |
MOD_INC_USE_COUNT; |
| 1037 |
} |
1016 |
} |
| 1038 |
|
1017 |
|
| 1039 |
|
1018 |
|
|
Lines 1041-1051
Link Here
|
| 1041 |
nv_kern_vma_release(struct vm_area_struct *vma) |
1020 |
nv_kern_vma_release(struct vm_area_struct *vma) |
| 1042 |
{ |
1021 |
{ |
| 1043 |
nv_printf(NV_DBG_MEMINFO, "vma_release for 0x%x - 0x%x, offset 0x%x\n", |
1022 |
nv_printf(NV_DBG_MEMINFO, "vma_release for 0x%x - 0x%x, offset 0x%x\n", |
| 1044 |
vma->vm_start, vma->vm_end, LINUX_VMA_OFFS(vma)); |
1023 |
vma->vm_start, vma->vm_end, NV_VMA_OFFSET(vma)); |
| 1045 |
|
1024 |
|
| 1046 |
if (VMA_PRIVATE(vma)) |
1025 |
if (NV_VMA_PRIVATE(vma)) |
| 1047 |
{ |
1026 |
{ |
| 1048 |
nv_alloc_t *at = (nv_alloc_t *) VMA_PRIVATE(vma); |
1027 |
nv_alloc_t *at = (nv_alloc_t *) NV_VMA_PRIVATE(vma); |
| 1049 |
|
1028 |
|
| 1050 |
at->usage_count--; |
1029 |
at->usage_count--; |
| 1051 |
|
1030 |
|
|
Lines 1063-1097
Link Here
|
| 1063 |
if (at->page_table) |
1042 |
if (at->page_table) |
| 1064 |
nvos_unlock_pages(at); |
1043 |
nvos_unlock_pages(at); |
| 1065 |
nvos_free_alloc(at); |
1044 |
nvos_free_alloc(at); |
| 1066 |
VMA_PRIVATE(vma) = NULL; |
1045 |
NV_VMA_PRIVATE(vma) = NULL; |
| 1067 |
} |
1046 |
} |
| 1068 |
} |
1047 |
} |
| 1069 |
|
|
|
| 1070 |
MOD_DEC_USE_COUNT; |
| 1071 |
} |
1048 |
} |
| 1072 |
|
1049 |
|
| 1073 |
|
1050 |
|
| 1074 |
/* at this point, this code just plain won't work with 2.2 kernels. |
|
|
| 1075 |
* additionally, only ia64 & the 460GX need a nopage handler, and 2.2 doesn't |
| 1076 |
* work on ia64 anyways. It's expected that at some point other agp chipsets |
| 1077 |
* will work similar to the 460GX (AGP 3.0 spec), so pre-emptively make sure |
| 1078 |
* this works on our standard ia32 driver. |
| 1079 |
*/ |
| 1080 |
#if !defined(KERNEL_2_2) |
| 1081 |
|
| 1082 |
/* AGP allocations under the 460GX are not mapped to the aperture |
1051 |
/* AGP allocations under the 460GX are not mapped to the aperture |
| 1083 |
* addresses by the CPU. This nopage handler will fault on CPU |
1052 |
* addresses by the CPU. This nopage handler will fault on CPU |
| 1084 |
* accesses to AGP memory and map the address to the correct page. |
1053 |
* accesses to AGP memory and map the address to the correct page. |
| 1085 |
*/ |
1054 |
*/ |
| 1086 |
struct page *nv_kern_vma_nopage(struct vm_area_struct *vma, unsigned long address, int write_access) |
1055 |
struct page *nv_kern_vma_nopage(struct vm_area_struct *vma, unsigned long address, int write_access) |
| 1087 |
{ |
1056 |
{ |
|
|
1057 |
#if defined(NVCPU_IA64) && (LINUX_VERSION_CODE >= KERNEL_VERSION(2, 4, 9)) |
| 1088 |
nv_alloc_t *at, *tmp; |
1058 |
nv_alloc_t *at, *tmp; |
| 1089 |
nv_linux_state_t *nvl; |
1059 |
nv_linux_state_t *nvl; |
| 1090 |
nv_state_t *nv; |
1060 |
nv_state_t *nv; |
| 1091 |
struct page *page_ptr; |
1061 |
struct page *page_ptr; |
| 1092 |
int rm_status, index; |
1062 |
int rm_status, index; |
| 1093 |
|
1063 |
|
| 1094 |
at = VMA_PRIVATE(vma); |
1064 |
at = NV_VMA_PRIVATE(vma); |
| 1095 |
if (at == NULL) |
1065 |
if (at == NULL) |
| 1096 |
{ |
1066 |
{ |
| 1097 |
nv_printf(NV_DBG_ERRORS, "NVRM: nopage handler called without an at: " |
1067 |
nv_printf(NV_DBG_ERRORS, "NVRM: nopage handler called without an at: " |
|
Lines 1130-1136
Link Here
|
| 1130 |
// far again |
1100 |
// far again |
| 1131 |
nv_printf(NV_DBG_ERRORS, "NVRM: nopage handler called on a freed" |
1101 |
nv_printf(NV_DBG_ERRORS, "NVRM: nopage handler called on a freed" |
| 1132 |
"address: vm_start 0x%x, at 0x%x\n", vma->vm_start, at); |
1102 |
"address: vm_start 0x%x, at 0x%x\n", vma->vm_start, at); |
| 1133 |
VMA_PRIVATE(vma) = NULL; |
1103 |
NV_VMA_PRIVATE(vma) = NULL; |
| 1134 |
return NOPAGE_SIGBUS; |
1104 |
return NOPAGE_SIGBUS; |
| 1135 |
} |
1105 |
} |
| 1136 |
|
1106 |
|
|
Lines 1154-1168
Link Here
|
| 1154 |
at->page_table[index].virt_addr = (unsigned long) __va(page_to_pfn(page_ptr) << PAGE_SHIFT); |
1124 |
at->page_table[index].virt_addr = (unsigned long) __va(page_to_pfn(page_ptr) << PAGE_SHIFT); |
| 1155 |
|
1125 |
|
| 1156 |
return page_ptr; |
1126 |
return page_ptr; |
| 1157 |
} |
|
|
| 1158 |
#endif |
1127 |
#endif |
|
|
1128 |
return NOPAGE_SIGBUS; |
| 1129 |
} |
| 1159 |
|
1130 |
|
| 1160 |
struct vm_operations_struct nv_vm_ops = { |
1131 |
struct vm_operations_struct nv_vm_ops = { |
| 1161 |
nv_kern_vma_open, |
1132 |
nv_kern_vma_open, |
| 1162 |
nv_kern_vma_release, /* "close" */ |
1133 |
nv_kern_vma_release, /* "close" */ |
| 1163 |
#if !defined(KERNEL_2_2) |
|
|
| 1164 |
nv_kern_vma_nopage, |
1134 |
nv_kern_vma_nopage, |
| 1165 |
#endif |
|
|
| 1166 |
}; |
1135 |
}; |
| 1167 |
|
1136 |
|
| 1168 |
static nv_file_private_t * |
1137 |
static nv_file_private_t * |
|
Lines 1177-1183
Link Here
|
| 1177 |
memset(nvfp, 0, sizeof(nv_file_private_t)); |
1146 |
memset(nvfp, 0, sizeof(nv_file_private_t)); |
| 1178 |
|
1147 |
|
| 1179 |
// initialize this file's event queue |
1148 |
// initialize this file's event queue |
| 1180 |
INIT_EVENT_QUEUE(nvfp->wqueue); |
1149 |
init_waitqueue_head(&nvfp->waitqueue); |
| 1181 |
|
1150 |
|
| 1182 |
nv_init_lock(nvfp->fp_lock); |
1151 |
nv_init_lock(nvfp->fp_lock); |
| 1183 |
|
1152 |
|
|
Lines 1197-1203
Link Here
|
| 1197 |
if (nvfp == NULL) |
1166 |
if (nvfp == NULL) |
| 1198 |
return; |
1167 |
return; |
| 1199 |
|
1168 |
|
| 1200 |
FREE_EVENT_QUEUE(nvfp->wqueue); |
|
|
| 1201 |
NV_VFREE(nvfp->event_fifo, sizeof(nv_event_t) * NV_EVENT_FIFO_SIZE); |
1169 |
NV_VFREE(nvfp->event_fifo, sizeof(nv_event_t) * NV_EVENT_FIFO_SIZE); |
| 1202 |
NV_VFREE(nvfp, sizeof(nv_file_private_t)); |
1170 |
NV_VFREE(nvfp, sizeof(nv_file_private_t)); |
| 1203 |
} |
1171 |
} |
|
Lines 1226-1236
Link Here
|
| 1226 |
|
1194 |
|
| 1227 |
/* for control device, just jump to its open routine */ |
1195 |
/* for control device, just jump to its open routine */ |
| 1228 |
/* after setting up the private data */ |
1196 |
/* after setting up the private data */ |
| 1229 |
if (NV_DEVICE_IS_CONTROL_DEVICE(inode->i_rdev)) |
1197 |
if (NV_IS_CONTROL_DEVICE(inode)) |
| 1230 |
return nv_kern_ctl_open(inode, file); |
1198 |
return nv_kern_ctl_open(inode, file); |
| 1231 |
|
1199 |
|
| 1232 |
/* what device are we talking about? */ |
1200 |
/* what device are we talking about? */ |
| 1233 |
devnum = NV_DEVICE_NUMBER(inode->i_rdev); |
1201 |
devnum = NV_DEVICE_NUMBER(inode); |
| 1234 |
if (devnum >= NV_MAX_DEVICES) |
1202 |
if (devnum >= NV_MAX_DEVICES) |
| 1235 |
{ |
1203 |
{ |
| 1236 |
rc = -ENODEV; |
1204 |
rc = -ENODEV; |
|
Lines 1283-1294
Link Here
|
| 1283 |
goto failed; |
1251 |
goto failed; |
| 1284 |
} |
1252 |
} |
| 1285 |
|
1253 |
|
|
|
1254 |
nvl->tasklet.func = (void *) rm_isr_bh; |
| 1255 |
nvl->tasklet.data = (unsigned long) nv->pdev; |
| 1256 |
tasklet_enable(&nvl->tasklet); |
| 1286 |
|
1257 |
|
| 1287 |
nv->flags |= NV_FLAG_OPEN; |
1258 |
nv->flags |= NV_FLAG_OPEN; |
| 1288 |
} |
1259 |
} |
| 1289 |
|
1260 |
|
| 1290 |
nv->usage_count++; |
1261 |
nv->usage_count++; |
| 1291 |
MOD_INC_USE_COUNT; |
|
|
| 1292 |
|
1262 |
|
| 1293 |
failed: |
1263 |
failed: |
| 1294 |
nv_unlock(nvl->ldata_lock); |
1264 |
nv_unlock(nvl->ldata_lock); |
|
Lines 1319-1356
Link Here
|
| 1319 |
|
1289 |
|
| 1320 |
/* for control device, just jump to its open routine */ |
1290 |
/* for control device, just jump to its open routine */ |
| 1321 |
/* after setting up the private data */ |
1291 |
/* after setting up the private data */ |
| 1322 |
if (NV_DEVICE_IS_CONTROL_DEVICE(inode->i_rdev)) |
1292 |
if (NV_IS_CONTROL_DEVICE(inode)) |
| 1323 |
return nv_kern_ctl_close(inode, file); |
1293 |
return nv_kern_ctl_close(inode, file); |
| 1324 |
|
1294 |
|
| 1325 |
nv_printf(NV_DBG_INFO, "nv_kern_close on device %d\n", NV_DEVICE_NUMBER(inode->i_rdev)); |
1295 |
nv_printf(NV_DBG_INFO, "nv_kern_close on device %d\n", NV_DEVICE_NUMBER(inode)); |
| 1326 |
|
1296 |
|
| 1327 |
rm_free_unused_clients(nv, current->pid, (void *) file); |
1297 |
rm_free_unused_clients(nv, current->pid, (void *) file); |
| 1328 |
|
1298 |
|
| 1329 |
nv_lock(nvl->ldata_lock); |
1299 |
nv_lock(nvl->ldata_lock); |
| 1330 |
if (--nv->usage_count == 0) |
1300 |
if (--nv->usage_count == 0) |
| 1331 |
{ |
1301 |
{ |
| 1332 |
int counter = 0; |
1302 |
/* |
| 1333 |
|
1303 |
* The usage count for this device has dropped to zero, it can be shut |
| 1334 |
/* turn off interrupts. |
1304 |
* down safely; disable its interrupts. |
| 1335 |
** be careful to make sure any pending bottom half gets run |
1305 |
*/ |
| 1336 |
** or disabled before calling rm_shutdown_adapter() since |
|
|
| 1337 |
** it will free up the pdev. This is hard to see on single |
| 1338 |
** cpu systems, but easy on dual cpu :-) |
| 1339 |
*/ |
| 1340 |
rm_disable_adapter(nv); |
1306 |
rm_disable_adapter(nv); |
| 1341 |
|
1307 |
|
| 1342 |
/* give it a moment to allow any bottom half to run */ |
1308 |
/* |
| 1343 |
|
1309 |
* Disable this device's tasklet to make sure that no bottom half will |
| 1344 |
#define MAX_BH_TASKS 10 |
1310 |
* run with undefined device state. |
| 1345 |
while (NV_ATOMIC_READ(nvl->bh_count) && (counter < MAX_BH_TASKS)) |
1311 |
*/ |
| 1346 |
{ |
1312 |
tasklet_disable(&nvl->tasklet); |
| 1347 |
current->state = TASK_INTERRUPTIBLE; |
|
|
| 1348 |
schedule_timeout(HZ/50); |
| 1349 |
counter++; |
| 1350 |
} |
| 1351 |
|
1313 |
|
| 1352 |
/* free the irq, which may block until any pending interrupts */ |
1314 |
/* |
| 1353 |
/* are done being processed. */ |
1315 |
* Free the IRQ, which may block until all pending interrupt processing |
|
|
1316 |
* has completed. |
| 1317 |
*/ |
| 1354 |
free_irq(nv->interrupt_line, (void *) nv); |
1318 |
free_irq(nv->interrupt_line, (void *) nv); |
| 1355 |
|
1319 |
|
| 1356 |
rm_shutdown_adapter(nv); |
1320 |
rm_shutdown_adapter(nv); |
|
Lines 1381-1388
Link Here
|
| 1381 |
FILE_PRIVATE(file) = NULL; |
1345 |
FILE_PRIVATE(file) = NULL; |
| 1382 |
} |
1346 |
} |
| 1383 |
|
1347 |
|
| 1384 |
MOD_DEC_USE_COUNT; |
|
|
| 1385 |
|
| 1386 |
return 0; |
1348 |
return 0; |
| 1387 |
} |
1349 |
} |
| 1388 |
|
1350 |
|
|
Lines 1399-1408
Link Here
|
| 1399 |
nv_printf(NV_DBG_INFO, "mmap([0x%p-0x%p] off=0x%lx)\n", |
1361 |
nv_printf(NV_DBG_INFO, "mmap([0x%p-0x%p] off=0x%lx)\n", |
| 1400 |
vma->vm_start, |
1362 |
vma->vm_start, |
| 1401 |
vma->vm_end, |
1363 |
vma->vm_end, |
| 1402 |
LINUX_VMA_OFFS(vma)); |
1364 |
NV_VMA_OFFSET(vma)); |
| 1403 |
|
1365 |
|
| 1404 |
// be a bit paranoid for now |
1366 |
// be a bit paranoid for now |
| 1405 |
if ((NV_MASK_OFFSET(LINUX_VMA_OFFS(vma))) || |
1367 |
if ((NV_MASK_OFFSET(NV_VMA_OFFSET(vma))) || |
| 1406 |
(NV_MASK_OFFSET(vma->vm_start)) || |
1368 |
(NV_MASK_OFFSET(vma->vm_start)) || |
| 1407 |
(NV_MASK_OFFSET(vma->vm_end))) |
1369 |
(NV_MASK_OFFSET(vma->vm_end))) |
| 1408 |
{ |
1370 |
{ |
|
Lines 1420-1426
Link Here
|
| 1420 |
|
1382 |
|
| 1421 |
|
1383 |
|
| 1422 |
/* NV reg space */ |
1384 |
/* NV reg space */ |
| 1423 |
if (IS_REG_OFFSET(nv, LINUX_VMA_OFFS(vma), vma->vm_end - vma->vm_start)) |
1385 |
if (IS_REG_OFFSET(nv, NV_VMA_OFFSET(vma), vma->vm_end - vma->vm_start)) |
| 1424 |
{ |
1386 |
{ |
| 1425 |
/* truncate to size of registers */ |
1387 |
/* truncate to size of registers */ |
| 1426 |
if (pages > nv->regs->size / PAGE_SIZE) |
1388 |
if (pages > nv->regs->size / PAGE_SIZE) |
|
Lines 1428-1434
Link Here
|
| 1428 |
|
1390 |
|
| 1429 |
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
1391 |
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
| 1430 |
if (NV_REMAP_PAGE_RANGE(vma->vm_start, |
1392 |
if (NV_REMAP_PAGE_RANGE(vma->vm_start, |
| 1431 |
phys_to_uncached(LINUX_VMA_OFFS(vma)), |
1393 |
phys_to_uncached(NV_VMA_OFFSET(vma)), |
| 1432 |
vma->vm_end - vma->vm_start, |
1394 |
vma->vm_end - vma->vm_start, |
| 1433 |
vma->vm_page_prot)) |
1395 |
vma->vm_page_prot)) |
| 1434 |
return -EAGAIN; |
1396 |
return -EAGAIN; |
|
Lines 1438-1444
Link Here
|
| 1438 |
} |
1400 |
} |
| 1439 |
|
1401 |
|
| 1440 |
/* NV fb space */ |
1402 |
/* NV fb space */ |
| 1441 |
else if (IS_FB_OFFSET(nv, LINUX_VMA_OFFS(vma), vma->vm_end - vma->vm_start)) |
1403 |
else if (IS_FB_OFFSET(nv, NV_VMA_OFFSET(vma), vma->vm_end - vma->vm_start)) |
| 1442 |
{ |
1404 |
{ |
| 1443 |
|
1405 |
|
| 1444 |
/* truncate to size of framebuffer */ |
1406 |
/* truncate to size of framebuffer */ |
|
Lines 1447-1453
Link Here
|
| 1447 |
|
1409 |
|
| 1448 |
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
1410 |
vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); |
| 1449 |
if (NV_REMAP_PAGE_RANGE(vma->vm_start, |
1411 |
if (NV_REMAP_PAGE_RANGE(vma->vm_start, |
| 1450 |
phys_to_uncached(LINUX_VMA_OFFS(vma)), |
1412 |
phys_to_uncached(NV_VMA_OFFSET(vma)), |
| 1451 |
vma->vm_end - vma->vm_start, |
1413 |
vma->vm_end - vma->vm_start, |
| 1452 |
vma->vm_page_prot)) |
1414 |
vma->vm_page_prot)) |
| 1453 |
return -EAGAIN; |
1415 |
return -EAGAIN; |
|
Lines 1457-1466
Link Here
|
| 1457 |
} |
1419 |
} |
| 1458 |
|
1420 |
|
| 1459 |
/* AGP allocator */ |
1421 |
/* AGP allocator */ |
| 1460 |
else if (IS_AGP_OFFSET(nv, LINUX_VMA_OFFS(vma), vma->vm_end - vma->vm_start)) |
1422 |
else if (IS_AGP_OFFSET(nv, NV_VMA_OFFSET(vma), vma->vm_end - vma->vm_start)) |
| 1461 |
{ |
1423 |
{ |
| 1462 |
nv_lock(nvl->at_lock); |
1424 |
nv_lock(nvl->at_lock); |
| 1463 |
at = nvl_find_alloc(nvl, LINUX_VMA_OFFS(vma), NV_ALLOC_TYPE_AGP); |
1425 |
at = nvl_find_alloc(nvl, NV_VMA_OFFSET(vma), NV_ALLOC_TYPE_AGP); |
| 1464 |
|
1426 |
|
| 1465 |
if (at == NULL) |
1427 |
if (at == NULL) |
| 1466 |
{ |
1428 |
{ |
|
Lines 1478-1484
Link Here
|
| 1478 |
} |
1440 |
} |
| 1479 |
|
1441 |
|
| 1480 |
at->vma = vma; |
1442 |
at->vma = vma; |
| 1481 |
VMA_PRIVATE(vma) = at; |
1443 |
NV_VMA_PRIVATE(vma) = at; |
| 1482 |
at->usage_count++; |
1444 |
at->usage_count++; |
| 1483 |
|
1445 |
|
| 1484 |
if (NV_OSAGP_ENABLED(nv)) |
1446 |
if (NV_OSAGP_ENABLED(nv)) |
|
Lines 1502-1514
Link Here
|
| 1502 |
} |
1464 |
} |
| 1503 |
|
1465 |
|
| 1504 |
/* Magic allocator */ |
1466 |
/* Magic allocator */ |
| 1505 |
else // if (LINUX_VMA_OFFS(vma) == NV_MMAP_ALLOCATION_OFFSET) |
1467 |
else // if (NV_VMA_OFFSET(vma) == NV_MMAP_ALLOCATION_OFFSET) |
| 1506 |
{ |
1468 |
{ |
| 1507 |
unsigned long page = 0, pos, start; |
1469 |
unsigned long page = 0, pos, start; |
| 1508 |
int i = 0; |
1470 |
int i = 0; |
| 1509 |
|
1471 |
|
| 1510 |
nv_lock(nvl->at_lock); |
1472 |
nv_lock(nvl->at_lock); |
| 1511 |
at = nvl_find_alloc(nvl, LINUX_VMA_OFFS(vma), NV_ALLOC_TYPE_PCI); |
1473 |
at = nvl_find_alloc(nvl, NV_VMA_OFFSET(vma), NV_ALLOC_TYPE_PCI); |
| 1512 |
|
1474 |
|
| 1513 |
if (at == NULL) |
1475 |
if (at == NULL) |
| 1514 |
{ |
1476 |
{ |
|
Lines 1526-1532
Link Here
|
| 1526 |
} |
1488 |
} |
| 1527 |
|
1489 |
|
| 1528 |
at->vma = vma; |
1490 |
at->vma = vma; |
| 1529 |
VMA_PRIVATE(vma) = at; |
1491 |
NV_VMA_PRIVATE(vma) = at; |
| 1530 |
at->usage_count++; |
1492 |
at->usage_count++; |
| 1531 |
|
1493 |
|
| 1532 |
nv_printf(NV_DBG_INFO, "remapping %d system pages for at 0x%x\n", pages, at); |
1494 |
nv_printf(NV_DBG_INFO, "remapping %d system pages for at 0x%x\n", pages, at); |
|
Lines 1548-1556
Link Here
|
| 1548 |
|
1510 |
|
| 1549 |
vma->vm_file = file; |
1511 |
vma->vm_file = file; |
| 1550 |
|
1512 |
|
| 1551 |
/* just increment usage count, rather than calling vma_open */ |
|
|
| 1552 |
MOD_INC_USE_COUNT; |
| 1553 |
|
| 1554 |
return 0; |
1513 |
return 0; |
| 1555 |
} |
1514 |
} |
| 1556 |
|
1515 |
|
|
Lines 1577-1583
Link Here
|
| 1577 |
{ |
1536 |
{ |
| 1578 |
nv_printf(NV_DBG_EVENTINFO, "calling poll_wait\n"); |
1537 |
nv_printf(NV_DBG_EVENTINFO, "calling poll_wait\n"); |
| 1579 |
// add us to the list |
1538 |
// add us to the list |
| 1580 |
poll_wait(file, EVENT_QUEUE(nvfp->wqueue), wait); |
1539 |
poll_wait(file, &nvfp->waitqueue, wait); |
| 1581 |
} |
1540 |
} |
| 1582 |
|
1541 |
|
| 1583 |
nv_lock_irq(nvfp->fp_lock, eflags); |
1542 |
nv_lock_irq(nvfp->fp_lock, eflags); |
|
Lines 1645-1656
Link Here
|
| 1645 |
|
1604 |
|
| 1646 |
switch (_IOC_NR(cmd)) |
1605 |
switch (_IOC_NR(cmd)) |
| 1647 |
{ |
1606 |
{ |
|
|
1607 |
#if !defined(KERNEL_2_6) |
| 1648 |
/* debug tool; zap the module use count so we can unload driver */ |
1608 |
/* debug tool; zap the module use count so we can unload driver */ |
| 1649 |
/* even if it is confused */ |
1609 |
/* even if it is confused */ |
| 1650 |
case NV_ESC_MODULE_RESET: |
1610 |
case NV_ESC_MODULE_RESET: |
| 1651 |
atomic_set(&__this_module.uc.usecount, 1); |
1611 |
atomic_set(&__this_module.uc.usecount, 1); |
| 1652 |
break; |
1612 |
break; |
| 1653 |
|
1613 |
#endif |
| 1654 |
/* pass out info about the card */ |
1614 |
/* pass out info about the card */ |
| 1655 |
case NV_ESC_CARD_INFO: |
1615 |
case NV_ESC_CARD_INFO: |
| 1656 |
{ |
1616 |
{ |
|
Lines 1777-1783
Link Here
|
| 1777 |
* driver receives an interrupt |
1737 |
* driver receives an interrupt |
| 1778 |
* if someone waiting, then hand it off. |
1738 |
* if someone waiting, then hand it off. |
| 1779 |
*/ |
1739 |
*/ |
| 1780 |
void nv_kern_isr( |
1740 |
irqreturn_t nv_kern_isr( |
| 1781 |
int irq, |
1741 |
int irq, |
| 1782 |
void *arg, |
1742 |
void *arg, |
| 1783 |
struct pt_regs *regs |
1743 |
struct pt_regs *regs |
|
Lines 1791-1799
Link Here
|
| 1791 |
if (need_to_run_bottom_half) |
1751 |
if (need_to_run_bottom_half) |
| 1792 |
{ |
1752 |
{ |
| 1793 |
NV_ATOMIC_INC(nvl->bh_count); |
1753 |
NV_ATOMIC_INC(nvl->bh_count); |
| 1794 |
queue_task(nvl->bh, &tq_immediate); |
1754 |
tasklet_schedule(&nvl->tasklet); |
| 1795 |
mark_bh(IMMEDIATE_BH); |
|
|
| 1796 |
} |
1755 |
} |
|
|
1756 |
|
| 1757 |
return IRQ_HANDLED; |
| 1797 |
} |
1758 |
} |
| 1798 |
|
1759 |
|
| 1799 |
void nv_kern_bh( |
1760 |
void nv_kern_bh( |
|
Lines 1911-1921
Link Here
|
| 1911 |
|
1872 |
|
| 1912 |
if (nv->usage_count == 0) |
1873 |
if (nv->usage_count == 0) |
| 1913 |
{ |
1874 |
{ |
| 1914 |
INIT_EVENT_QUEUE(nv_ctl_wqueue); |
1875 |
init_waitqueue_head(&nv_ctl_waitqueue); |
| 1915 |
} |
1876 |
} |
| 1916 |
|
1877 |
|
| 1917 |
MOD_INC_USE_COUNT; |
|
|
| 1918 |
|
| 1919 |
nv->flags |= NV_FLAG_OPEN + NV_FLAG_CONTROL; |
1878 |
nv->flags |= NV_FLAG_OPEN + NV_FLAG_CONTROL; |
| 1920 |
|
1879 |
|
| 1921 |
/* turn off the hotkey occurred bit */ |
1880 |
/* turn off the hotkey occurred bit */ |
|
Lines 1943-1952
Link Here
|
| 1943 |
|
1902 |
|
| 1944 |
nv_lock(nvl->ldata_lock); |
1903 |
nv_lock(nvl->ldata_lock); |
| 1945 |
if (--nv->usage_count == 0) |
1904 |
if (--nv->usage_count == 0) |
| 1946 |
{ |
|
|
| 1947 |
FREE_EVENT_QUEUE(nv_ctl_wqueue); |
| 1948 |
nv->flags = 0; |
1905 |
nv->flags = 0; |
| 1949 |
} |
1906 |
|
| 1950 |
nv_unlock(nvl->ldata_lock); |
1907 |
nv_unlock(nvl->ldata_lock); |
| 1951 |
|
1908 |
|
| 1952 |
rm_free_unused_clients(nv, current->pid, (void *) file); |
1909 |
rm_free_unused_clients(nv, current->pid, (void *) file); |
|
Lines 1957-1964
Link Here
|
| 1957 |
FILE_PRIVATE(file) = NULL; |
1914 |
FILE_PRIVATE(file) = NULL; |
| 1958 |
} |
1915 |
} |
| 1959 |
|
1916 |
|
| 1960 |
MOD_DEC_USE_COUNT; |
|
|
| 1961 |
|
| 1962 |
return 0; |
1917 |
return 0; |
| 1963 |
} |
1918 |
} |
| 1964 |
|
1919 |
|
|
Lines 1982-1988
Link Here
|
| 1982 |
nv = NV_STATE_PTR(nvl); |
1937 |
nv = NV_STATE_PTR(nvl); |
| 1983 |
|
1938 |
|
| 1984 |
if ( !(file->f_flags & O_NONBLOCK) ) |
1939 |
if ( !(file->f_flags & O_NONBLOCK) ) |
| 1985 |
poll_wait(file, EVENT_QUEUE(nv_ctl_wqueue), wait); |
1940 |
poll_wait(file, &nv_ctl_waitqueue, wait); |
| 1986 |
|
1941 |
|
| 1987 |
nv_lock(nvl->ldata_lock); |
1942 |
nv_lock(nvl->ldata_lock); |
| 1988 |
|
1943 |
|
|
Lines 2013-2019
Link Here
|
| 2013 |
nv_ctl_device.nv_state.flags |= NV_FLAG_HOTKEY_OCCURRED; |
1968 |
nv_ctl_device.nv_state.flags |= NV_FLAG_HOTKEY_OCCURRED; |
| 2014 |
nv_unlock(nv_ctl_device.ldata_lock); |
1969 |
nv_unlock(nv_ctl_device.ldata_lock); |
| 2015 |
|
1970 |
|
| 2016 |
wake_up_interruptible(EVENT_QUEUE(nv_ctl_wqueue)); |
1971 |
wake_up_interruptible(&nv_ctl_waitqueue); |
| 2017 |
} |
1972 |
} |
| 2018 |
|
1973 |
|
| 2019 |
int nv_kern_read_cardinfo(char *page, char **start, off_t off, |
1974 |
int nv_kern_read_cardinfo(char *page, char **start, off_t off, |
|
Lines 2092-2098
Link Here
|
| 2092 |
len += sprintf(page+len, "Host Bridge: \t "); |
2047 |
len += sprintf(page+len, "Host Bridge: \t "); |
| 2093 |
|
2048 |
|
| 2094 |
#if defined(CONFIG_PCI_NAMES) |
2049 |
#if defined(CONFIG_PCI_NAMES) |
| 2095 |
len += sprintf(page+len, "%s\n", dev->name); |
2050 |
len += sprintf(page+len, "%s\n", NV_PCI_DEVICE_NAME(dev)); |
| 2096 |
#else |
2051 |
#else |
| 2097 |
len += sprintf(page+len, "PCI device %04x:%04x\n", |
2052 |
len += sprintf(page+len, "PCI device %04x:%04x\n", |
| 2098 |
dev->vendor, dev->device); |
2053 |
dev->vendor, dev->device); |
|
Lines 2304-2330
Link Here
|
| 2304 |
int kern |
2259 |
int kern |
| 2305 |
) |
2260 |
) |
| 2306 |
{ |
2261 |
{ |
| 2307 |
pgd_t *pg_dir; |
2262 |
pgd_t *pgd; |
| 2308 |
pmd_t *pg_mid_dir; |
2263 |
pmd_t *pmd; |
| 2309 |
pte_t pte; |
2264 |
pte_t *pte; |
| 2310 |
unsigned long retval; |
2265 |
unsigned long retval; |
| 2311 |
|
2266 |
|
| 2312 |
if (kern) pg_dir = pgd_offset_k(address); |
2267 |
if (kern) |
| 2313 |
else pg_dir = pgd_offset(current->mm, address); |
2268 |
pgd = pgd_offset_k(address); |
|
|
2269 |
else |
| 2270 |
pgd = pgd_offset(current->mm, address); |
| 2314 |
|
2271 |
|
| 2315 |
if (pgd_none(*pg_dir)) |
2272 |
if (!pgd || pgd_none(*pgd)) |
| 2316 |
goto failed; |
2273 |
goto failed; |
| 2317 |
|
2274 |
|
| 2318 |
pg_mid_dir = pmd_offset(pg_dir, address); |
2275 |
NV_PMD_OFFSET(address, pgd, pmd); |
| 2319 |
if (pmd_none(*pg_mid_dir)) |
2276 |
|
|
|
2277 |
if (!NV_PMD_PRESENT(pmd)) |
| 2320 |
goto failed; |
2278 |
goto failed; |
| 2321 |
|
2279 |
|
| 2322 |
NV_PTE_OFFSET(address, pg_mid_dir, pte); |
2280 |
NV_PTE_OFFSET(address, pmd, pte); |
| 2323 |
|
2281 |
|
| 2324 |
if (!pte_present(pte)) |
2282 |
if (!NV_PTE_PRESENT(pte)) |
| 2325 |
goto failed; |
2283 |
goto failed; |
| 2326 |
|
2284 |
|
| 2327 |
retval = ((pte_val(pte) & KERN_PAGE_MASK) | NV_MASK_OFFSET(address)); |
2285 |
retval = ((NV_PTE_VALUE(pte) & KERN_PAGE_MASK) | NV_MASK_OFFSET(address)); |
| 2328 |
|
2286 |
|
| 2329 |
#if defined(NVCPU_X86_64) && defined(_PAGE_NX) |
2287 |
#if defined(NVCPU_X86_64) && defined(_PAGE_NX) |
| 2330 |
// mask out the non-executable page bit for the true physical address |
2288 |
// mask out the non-executable page bit for the true physical address |
|
Lines 2759-2765
Link Here
|
| 2759 |
|
2717 |
|
| 2760 |
if (nvfp->num_events == NV_EVENT_FIFO_SIZE) |
2718 |
if (nvfp->num_events == NV_EVENT_FIFO_SIZE) |
| 2761 |
{ |
2719 |
{ |
| 2762 |
wake_up_interruptible(EVENT_QUEUE(nvfp->wqueue)); |
2720 |
wake_up_interruptible(&nvfp->waitqueue); |
| 2763 |
nv_unlock_irq(nvfp->fp_lock, eflags); |
2721 |
nv_unlock_irq(nvfp->fp_lock, eflags); |
| 2764 |
return; |
2722 |
return; |
| 2765 |
} |
2723 |
} |
|
Lines 2776-2782
Link Here
|
| 2776 |
if (nvfp->put >= NV_EVENT_FIFO_SIZE) |
2734 |
if (nvfp->put >= NV_EVENT_FIFO_SIZE) |
| 2777 |
nvfp->put = 0; |
2735 |
nvfp->put = 0; |
| 2778 |
|
2736 |
|
| 2779 |
wake_up_interruptible(EVENT_QUEUE(nvfp->wqueue)); |
2737 |
wake_up_interruptible(&nvfp->waitqueue); |
| 2780 |
nv_unlock_irq(nvfp->fp_lock, eflags); |
2738 |
nv_unlock_irq(nvfp->fp_lock, eflags); |
| 2781 |
} |
2739 |
} |
| 2782 |
|
2740 |
|
|
Lines 2866-2877
Link Here
|
| 2866 |
if ( (NV_AGP_DISABLED(nv)) && (config & NVOS_AGP_CONFIG_NVAGP) ) |
2824 |
if ( (NV_AGP_DISABLED(nv)) && (config & NVOS_AGP_CONFIG_NVAGP) ) |
| 2867 |
{ |
2825 |
{ |
| 2868 |
/* make sure the user does not have agpgart loaded */ |
2826 |
/* make sure the user does not have agpgart loaded */ |
| 2869 |
#if !defined (KERNEL_2_2) |
|
|
| 2870 |
if (inter_module_get("drm_agp")) { |
2827 |
if (inter_module_get("drm_agp")) { |
| 2871 |
inter_module_put("drm_agp"); |
2828 |
inter_module_put("drm_agp"); |
| 2872 |
#else |
|
|
| 2873 |
if (GET_MODULE_SYMBOL(0, __MODULE_STRING(agp_enable))) { |
| 2874 |
#endif |
| 2875 |
nv_printf(NV_DBG_WARNINGS, "NVRM: not using NVAGP, AGPGART is loaded!!\n"); |
2829 |
nv_printf(NV_DBG_WARNINGS, "NVRM: not using NVAGP, AGPGART is loaded!!\n"); |
| 2876 |
} else { |
2830 |
} else { |
| 2877 |
#if defined(CONFIG_X86_64) && defined(CONFIG_GART_IOMMU) |
2831 |
#if defined(CONFIG_X86_64) && defined(CONFIG_GART_IOMMU) |