1 Author: Andreas Beckmann <anbe@debian.org>
2 Bug-Debian: http://bugs.debian.org/717361
3 Description: adjust for kernel 3.10 procfs interface changes
4 backported from 304.108
6 diff --git a/kernel/nv-procfs.c b/kernel/nv-procfs.c
7 index 3e05ef5..7a9fb70 100644
8 --- a/kernel/nv-procfs.c
9 +++ b/kernel/nv-procfs.c
10 @@ -51,69 +51,106 @@ static char nv_registry_keys[NV_MAX_REGISTRY_KEYS_LENGTH];
11 #define NV_SET_PROC_ENTRY_OWNER(entry)
14 -#define NV_CREATE_PROC_ENTRY(name,mode,parent) \
16 - struct proc_dir_entry *__entry; \
17 - __entry = create_proc_entry(name, mode, parent); \
18 - if (__entry != NULL) \
19 - NV_SET_PROC_ENTRY_OWNER(__entry); \
21 +#if defined(NV_PROC_CREATE_DATA_PRESENT)
22 +# define NV_CREATE_PROC_ENTRY(name,mode,parent,fops,__data) \
23 + proc_create_data(name, __mode, parent, fops, __data)
25 +# define NV_CREATE_PROC_ENTRY(name,mode,parent,fops,__data) \
27 + struct proc_dir_entry *__entry; \
28 + __entry = create_proc_entry(name, mode, parent); \
29 + if (__entry != NULL) \
31 + NV_SET_PROC_ENTRY_OWNER(__entry); \
32 + __entry->proc_fops = fops; \
33 + __entry->data = (__data); \
39 +#define NV_CREATE_PROC_FILE(filename,parent,__name,__data) \
41 + struct proc_dir_entry *__entry; \
42 + int __mode = (S_IFREG | S_IRUGO); \
43 + const struct file_operations *fops = &nv_procfs_##__name##_fops; \
44 + if (fops->write != 0) \
45 + __mode |= S_IWUSR; \
46 + __entry = NV_CREATE_PROC_ENTRY(filename, __mode, parent, fops, \
51 -#define NV_CREATE_PROC_FILE(name,parent,__read_proc, \
52 - __write_proc,__fops,__data) \
54 + * proc_mkdir_mode exists in Linux 2.6.9, but isn't exported until Linux 3.0.
55 + * Use the older interface instead unless the newer interface is necessary.
57 +#if defined(NV_PROC_REMOVE_PRESENT)
58 +# define NV_PROC_MKDIR_MODE(name, mode, parent) \
59 + proc_mkdir_mode(name, mode, parent)
61 +# define NV_PROC_MKDIR_MODE(name, mode, parent) \
63 struct proc_dir_entry *__entry; \
64 - int __mode = (S_IFREG | S_IRUGO); \
65 - if ((NvUPtr)(__write_proc) != 0) \
66 - __mode |= S_IWUSR; \
67 - __entry = NV_CREATE_PROC_ENTRY(name, __mode, parent); \
68 + __entry = create_proc_entry(name, mode, parent); \
69 if (__entry != NULL) \
71 - if ((NvUPtr)(__read_proc) != 0) \
72 - __entry->read_proc = (__read_proc); \
73 - if ((NvUPtr)(__write_proc) != 0) \
75 - __entry->write_proc = (__write_proc); \
76 - __entry->proc_fops = (__fops); \
78 - __entry->data = (__data); \
80 + NV_SET_PROC_ENTRY_OWNER(__entry); \
85 #define NV_CREATE_PROC_DIR(name,parent) \
87 struct proc_dir_entry *__entry; \
88 int __mode = (S_IFDIR | S_IRUGO | S_IXUGO); \
89 - __entry = NV_CREATE_PROC_ENTRY(name, __mode, parent); \
90 + __entry = NV_PROC_MKDIR_MODE(name, __mode, parent); \
94 +#if defined(NV_PDE_DATA_PRESENT)
95 +# define NV_PDE_DATA(inode) PDE_DATA(inode)
97 +# define NV_PDE_DATA(inode) PDE(inode)->data
100 +#define NV_DEFINE_PROCFS_SINGLE_FILE(__name) \
101 + static int nv_procfs_open_##__name( \
102 + struct inode *inode, \
103 + struct file *filep \
106 + return single_open(filep, nv_procfs_read_##__name, \
107 + NV_PDE_DATA(inode)); \
110 + static const struct file_operations nv_procfs_##__name##_fops = { \
111 + .owner = THIS_MODULE, \
112 + .open = nv_procfs_open_##__name, \
113 + .read = seq_read, \
114 + .llseek = seq_lseek, \
115 + .release = single_release, \
118 +static int nv_procfs_read_registry(struct seq_file *s, void *v);
120 #define NV_PROC_WRITE_BUFFER_SIZE (64 * RM_PAGE_SIZE)
123 nv_procfs_read_gpu_info(
130 + struct seq_file *s,
134 - nv_state_t *nv = data;
135 + nv_state_t *nv = s->private;
136 nv_linux_state_t *nvl = NV_GET_NVL_FROM_NV_STATE(nv);
137 struct pci_dev *dev = nvl->dev;
138 char *type, *fmt, tmpstr[NV_DEVICE_NAME_LENGTH];
139 - int len = 0, status;
142 NvU32 vbios_rev1, vbios_rev2, vbios_rev3, vbios_rev4, vbios_rev5;
143 NvU32 fpga_rev1, fpga_rev2, fpga_rev3;
144 nv_stack_t *sp = NULL;
148 NV_KMEM_CACHE_ALLOC_STACK(sp);
151 @@ -139,26 +176,26 @@ nv_procfs_read_gpu_info(
155 - len += sprintf(page+len, "Model: \t\t %s\n", tmpstr);
156 - len += sprintf(page+len, "IRQ: \t\t %d\n", nv->interrupt_line);
157 + seq_printf(s, "Model: \t\t %s\n", tmpstr);
158 + seq_printf(s, "IRQ: \t\t %d\n", nv->interrupt_line);
160 if (NV_IS_GVI_DEVICE(nv))
162 status = rm_gvi_get_firmware_version(sp, nv, &fpga_rev1, &fpga_rev2,
165 - len += sprintf(page+len, "Firmware: \t ????.??.??\n");
166 + seq_printf(s, "Firmware: \t ????.??.??\n");
169 fmt = "Firmware: \t %x.%x.%x\n";
170 - len += sprintf(page+len, fmt, fpga_rev1, fpga_rev2, fpga_rev3);
171 + seq_printf(s, fmt, fpga_rev1, fpga_rev2, fpga_rev3);
176 if (rm_get_gpu_uuid(sp, nv, &uuid, NULL) == RM_OK)
178 - len += sprintf(page+len, "GPU UUID: \t %s\n", (char *)uuid);
179 + seq_printf(s, "GPU UUID: \t %s\n", (char *)uuid);
183 @@ -166,65 +203,62 @@ nv_procfs_read_gpu_info(
184 &vbios_rev3, &vbios_rev4,
185 &vbios_rev5) != RM_OK)
187 - len += sprintf(page+len, "Video BIOS: \t ??.??.??.??.??\n");
188 + seq_printf(s, "Video BIOS: \t ??.??.??.??.??\n");
192 fmt = "Video BIOS: \t %02x.%02x.%02x.%02x.%02x\n";
193 - len += sprintf(page+len, fmt, vbios_rev1, vbios_rev2, vbios_rev3,
194 - vbios_rev4, vbios_rev5);
195 + seq_printf(s, fmt, vbios_rev1, vbios_rev2, vbios_rev3, vbios_rev4,
200 if (nv_find_pci_capability(dev, PCI_CAP_ID_AGP))
202 else if (nv_find_pci_capability(dev, PCI_CAP_ID_EXP))
207 - len += sprintf(page+len, "Bus Type: \t %s\n", type);
208 + seq_printf(s, "Bus Type: \t %s\n", type);
210 - len += sprintf(page+len, "DMA Size: \t %d bits\n",
211 + seq_printf(s, "DMA Size: \t %d bits\n",
212 nv_count_bits(dev->dma_mask));
213 - len += sprintf(page+len, "DMA Mask: \t 0x%llx\n", dev->dma_mask);
214 - len += sprintf(page+len, "Bus Location: \t %04x:%02x.%02x.%x\n",
215 - nv->domain, nv->bus, nv->slot, PCI_FUNC(dev->devfn));
216 + seq_printf(s, "DMA Mask: \t 0x%llx\n", dev->dma_mask);
217 + seq_printf(s, "Bus Location: \t %04x:%02x.%02x.%x\n",
218 + nv->domain, nv->bus, nv->slot, PCI_FUNC(dev->devfn));
223 for (j = 0; j < NV_GPU_NUM_BARS; j++)
225 - len += sprintf(page+len, "BAR%u: \t\t 0x%llx (%lluMB)\n",
226 - j, nv->bars[j].address, (nv->bars[j].size >> 20));
227 + seq_printf(s, "BAR%u: \t\t 0x%llx (%lluMB)\n",
228 + j, nv->bars[j].address, (nv->bars[j].size >> 20));
233 NV_KMEM_CACHE_FREE_STACK(sp);
239 +NV_DEFINE_PROCFS_SINGLE_FILE(gpu_info);
242 nv_procfs_read_version(
249 + struct seq_file *s,
255 + seq_printf(s, "NVRM version: %s\n", pNVRM_ID);
256 + seq_printf(s, "GCC version: %s\n", NV_COMPILER);
258 - len += sprintf(page+len, "NVRM version: %s\n", pNVRM_ID);
259 - len += sprintf(page+len, "GCC version: %s\n", NV_COMPILER);
265 +NV_DEFINE_PROCFS_SINGLE_FILE(version);
267 static struct pci_dev *nv_get_agp_device_by_class(unsigned int class)
269 struct pci_dev *dev, *fdev;
270 @@ -256,23 +290,16 @@ static struct pci_dev *nv_get_agp_device_by_class(unsigned int class)
273 nv_procfs_read_agp_info(
280 + struct seq_file *s,
284 - nv_state_t *nv = data;
285 + nv_state_t *nv = s->private;
286 nv_linux_state_t *nvl = NULL;
290 u32 status, command, agp_rate;
297 @@ -285,13 +312,12 @@ nv_procfs_read_agp_info(
301 - len += sprintf(page+len, "Host Bridge: \t ");
302 + seq_printf(s, "Host Bridge: \t ");
304 #if defined(CONFIG_PCI_NAMES)
305 - len += sprintf(page+len, "%s\n", NV_PCI_DEVICE_NAME(dev));
306 + seq_printf(s, "%s\n", NV_PCI_DEVICE_NAME(dev));
308 - len += sprintf(page+len, "PCI device %04x:%04x\n",
309 - dev->vendor, dev->device);
310 + seq_printf(s, "PCI device %04x:%04x\n", dev->vendor, dev->device);
314 @@ -303,48 +329,43 @@ nv_procfs_read_agp_info(
315 fw = (status & 0x00000010) ? "Supported" : "Not Supported";
316 sba = (status & 0x00000200) ? "Supported" : "Not Supported";
318 - len += sprintf(page+len, "Fast Writes: \t %s\n", fw);
319 - len += sprintf(page+len, "SBA: \t\t %s\n", sba);
320 + seq_printf(s, "Fast Writes: \t %s\n", fw);
321 + seq_printf(s, "SBA: \t\t %s\n", sba);
323 agp_rate = status & 0x7;
327 - len += sprintf(page+len, "AGP Rates: \t %s%s%s%s\n",
328 - (agp_rate & 0x00000008) ? "8x " : "",
329 - (agp_rate & 0x00000004) ? "4x " : "",
330 - (agp_rate & 0x00000002) ? "2x " : "",
331 - (agp_rate & 0x00000001) ? "1x " : "");
332 + seq_printf(s, "AGP Rates: \t %s%s%s%s\n",
333 + (agp_rate & 0x00000008) ? "8x " : "",
334 + (agp_rate & 0x00000004) ? "4x " : "",
335 + (agp_rate & 0x00000002) ? "2x " : "",
336 + (agp_rate & 0x00000001) ? "1x " : "");
338 - len += sprintf(page+len, "Registers: \t 0x%08x:0x%08x\n", status, command);
339 + seq_printf(s, "Registers: \t 0x%08x:0x%08x\n", status, command);
348 +NV_DEFINE_PROCFS_SINGLE_FILE(agp_info);
351 nv_procfs_read_agp_status(
358 + struct seq_file *s,
362 - nv_state_t *nv = data;
363 + nv_state_t *nv = s->private;
365 char *fw, *sba, *drv;
369 u32 status, command, agp_rate;
370 nv_stack_t *sp = NULL;
374 dev = nv_get_agp_device_by_class(PCI_CLASS_BRIDGE_HOST);
377 @@ -366,22 +387,22 @@ nv_procfs_read_agp_status(
379 if (NV_AGP_ENABLED(nv) && (command & 0x100))
381 - len += sprintf(page+len, "Status: \t Enabled\n");
382 + seq_printf(s, "Status: \t Enabled\n");
384 drv = NV_OSAGP_ENABLED(nv) ? "AGPGART" : "NVIDIA";
385 - len += sprintf(page+len, "Driver: \t %s\n", drv);
386 + seq_printf(s, "Driver: \t %s\n", drv);
388 agp_rate = command & 0x7;
392 - len += sprintf(page+len, "AGP Rate: \t %dx\n", agp_rate);
393 + seq_printf(s, "AGP Rate: \t %dx\n", agp_rate);
395 fw = (command & 0x00000010) ? "Enabled" : "Disabled";
396 - len += sprintf(page+len, "Fast Writes: \t %s\n", fw);
397 + seq_printf(s, "Fast Writes: \t %s\n", fw);
399 sba = (command & 0x00000200) ? "Enabled" : "Disabled";
400 - len += sprintf(page+len, "SBA: \t\t %s\n", sba);
401 + seq_printf(s, "SBA: \t\t %s\n", sba);
405 @@ -394,7 +415,7 @@ nv_procfs_read_agp_status(
409 - len += sprintf(page+len, "Status: \t Disabled\n\n");
410 + seq_printf(s, "Status: \t Disabled\n\n");
413 * If we find AGP is disabled, but the RM registry indicates it
414 @@ -409,7 +430,7 @@ nv_procfs_read_agp_status(
416 if (agp_config != NVOS_AGP_CONFIG_DISABLE_AGP && NV_AGP_FAILED(nv))
418 - len += sprintf(page+len,
420 "AGP initialization failed, please check the ouput \n"
421 "of the 'dmesg' command and/or your system log file \n"
422 "for additional information on this problem. \n");
423 @@ -419,9 +440,11 @@ nv_procfs_read_agp_status(
431 +NV_DEFINE_PROCFS_SINGLE_FILE(agp_status);
434 nv_procfs_open_registry(
436 @@ -431,9 +454,6 @@ nv_procfs_open_registry(
437 nv_file_private_t *nvfp = NULL;
438 nv_stack_t *sp = NULL;
440 - if (0 == (file->f_mode & FMODE_WRITE))
443 nvfp = nv_alloc_file_private();
446 @@ -441,6 +461,11 @@ nv_procfs_open_registry(
450 + nvfp->proc_data = NV_PDE_DATA(inode);
452 + if (0 == (file->f_mode & FMODE_WRITE))
455 NV_KMEM_CACHE_ALLOC_STACK(sp);
458 @@ -449,19 +474,19 @@ nv_procfs_open_registry(
462 - NV_SET_FILE_PRIVATE(file, nvfp);
464 if (RM_OK != os_alloc_mem((void **)&nvfp->data, NV_PROC_WRITE_BUFFER_SIZE))
466 nv_free_file_private(nvfp);
467 NV_KMEM_CACHE_FREE_STACK(sp);
468 - NV_SET_FILE_PRIVATE(file, NULL);
472 os_mem_set((void *)nvfp->data, 0, NV_PROC_WRITE_BUFFER_SIZE);
473 nvfp->fops_sp[NV_FOPS_STACK_INDEX_PROCFS] = sp;
476 + single_open(file, nv_procfs_read_registry, nvfp);
481 @@ -471,6 +496,7 @@ nv_procfs_close_registry(
485 + struct seq_file *s = file->private_data;
486 nv_file_private_t *nvfp;
488 nv_linux_state_t *nvl = NULL;
489 @@ -481,9 +507,8 @@ nv_procfs_close_registry(
493 - nvfp = NV_GET_FILE_PRIVATE(file);
497 + single_release(inode, file);
499 sp = nvfp->fops_sp[NV_FOPS_STACK_INDEX_PROCFS];
501 @@ -538,56 +563,42 @@ done:
502 os_free_mem(nvfp->data);
504 nv_free_file_private(nvfp);
505 - NV_SET_FILE_PRIVATE(file, NULL);
507 - NV_KMEM_CACHE_FREE_STACK(sp);
509 + NV_KMEM_CACHE_FREE_STACK(sp);
514 -static struct file_operations nv_procfs_registry_fops = {
515 - .open = nv_procfs_open_registry,
516 - .release = nv_procfs_close_registry,
520 nv_procfs_read_params(
527 + struct seq_file *s,
537 for (i = 0; (entry = &nv_parms[i])->name != NULL; i++)
538 - len += sprintf(page+len, "%s: %u\n", entry->name, *entry->data);
539 + seq_printf(s, "%s: %u\n", entry->name, *entry->data);
541 - len += sprintf(page+len, "RegistryDwords: \"%s\"\n",
542 + seq_printf(s, "RegistryDwords: \"%s\"\n",
543 (NVreg_RegistryDwords != NULL) ? NVreg_RegistryDwords : "");
544 - len += sprintf(page+len, "RmMsg: \"%s\"\n",
545 - (NVreg_RmMsg != NULL) ? NVreg_RmMsg : "");
546 + seq_printf(s, "RmMsg: \"%s\"\n", (NVreg_RmMsg != NULL) ? NVreg_RmMsg : "");
552 +NV_DEFINE_PROCFS_SINGLE_FILE(params);
555 nv_procfs_read_registry(
562 + struct seq_file *s,
566 - nv_state_t *nv = data;
567 + nv_file_private_t *nvfp = s->private;
568 + nv_state_t *nv = nvfp->proc_data;
569 nv_linux_state_t *nvl = NULL;
572 @@ -596,20 +607,20 @@ nv_procfs_read_registry(
573 registry_keys = ((nvl != NULL) ?
574 nvl->registry_keys : nv_registry_keys);
577 - return sprintf(page, "Binary: \"%s\"\n", registry_keys);
578 + return seq_printf(s, "Binary: \"%s\"\n", registry_keys);
583 nv_procfs_write_registry(
585 - const char *buffer,
586 - unsigned long count,
588 + const char *buffer,
594 - nv_file_private_t *nvfp = NV_GET_FILE_PRIVATE(file);
595 + struct seq_file *s = file->private_data;
596 + nv_file_private_t *nvfp = s->private;
598 unsigned long bytes_left;
600 @@ -637,30 +648,37 @@ nv_procfs_write_registry(
604 - nvfp->proc_data = data;
611 up(&nvfp->fops_sp_lock[NV_FOPS_STACK_INDEX_PROCFS]);
613 return ((status < 0) ? status : (int)count);
616 +static struct file_operations nv_procfs_registry_fops = {
617 + .owner = THIS_MODULE,
618 + .open = nv_procfs_open_registry,
620 + .write = nv_procfs_write_registry,
621 + .llseek = seq_lseek,
622 + .release = nv_procfs_close_registry,
626 nv_procfs_read_text_file(
633 + struct seq_file *s,
638 - return sprintf(page, "%s", (char *)data);
639 + return seq_puts(s, s->private);
642 +NV_DEFINE_PROCFS_SINGLE_FILE(text_file);
645 nv_procfs_add_text_file(
646 struct proc_dir_entry *parent,
647 @@ -668,12 +686,14 @@ nv_procfs_add_text_file(
651 - NV_CREATE_PROC_FILE(filename, parent,
652 - nv_procfs_read_text_file, NULL, NULL, (void *)text);
653 + NV_CREATE_PROC_FILE(filename, parent, text_file, (void *)text);
656 static void nv_procfs_unregister_all(struct proc_dir_entry *entry)
658 +#if defined(NV_PROC_REMOVE_PRESENT)
659 + proc_remove(entry);
663 struct proc_dir_entry *next = entry->next;
664 @@ -684,6 +704,7 @@ static void nv_procfs_unregister_all(struct proc_dir_entry *entry)
672 @@ -713,26 +734,11 @@ int nv_register_procfs(void)
676 - entry = NV_CREATE_PROC_FILE("params", proc_nvidia,
677 - nv_procfs_read_params, NULL, NULL, NULL);
678 + entry = NV_CREATE_PROC_FILE("params", proc_nvidia, params, NULL);
683 - * entry->proc_fops originally points to a constant
684 - * structure, so to add more methods for the
685 - * binary registry write path, we need to replace the
686 - * said entry->proc_fops with a new fops structure.
687 - * However, in preparation for this, we need to preserve
688 - * the procfs read() and write() operations.
690 - nv_procfs_registry_fops.read = entry->proc_fops->read;
691 - nv_procfs_registry_fops.write = entry->proc_fops->write;
693 - entry = NV_CREATE_PROC_FILE("registry", proc_nvidia,
694 - nv_procfs_read_registry,
695 - nv_procfs_write_registry,
696 - &nv_procfs_registry_fops, NULL);
697 + entry = NV_CREATE_PROC_FILE("registry", proc_nvidia, registry, NULL);
701 @@ -753,8 +759,7 @@ int nv_register_procfs(void)
703 nv_procfs_add_text_file(proc_nvidia_patches, "README", __README_patches);
705 - entry = NV_CREATE_PROC_FILE("version", proc_nvidia,
706 - nv_procfs_read_version, NULL, NULL, NULL);
707 + entry = NV_CREATE_PROC_FILE("version", proc_nvidia, version, NULL);
711 @@ -771,15 +776,12 @@ int nv_register_procfs(void)
712 if (!proc_nvidia_gpu)
715 - entry = NV_CREATE_PROC_FILE("information", proc_nvidia_gpu,
716 - nv_procfs_read_gpu_info, NULL, NULL, nv);
717 + entry = NV_CREATE_PROC_FILE("information", proc_nvidia_gpu, gpu_info,
722 - entry = NV_CREATE_PROC_FILE("registry", proc_nvidia_gpu,
723 - nv_procfs_read_registry,
724 - nv_procfs_write_registry,
725 - &nv_procfs_registry_fops, nv);
726 + entry = NV_CREATE_PROC_FILE("registry", proc_nvidia_gpu, registry, nv);
730 @@ -789,18 +791,17 @@ int nv_register_procfs(void)
731 if (!proc_nvidia_agp)
734 - entry = NV_CREATE_PROC_FILE("status", proc_nvidia_agp,
735 - nv_procfs_read_agp_status, NULL, NULL, nv);
736 + entry = NV_CREATE_PROC_FILE("status", proc_nvidia_agp, agp_status,
741 entry = NV_CREATE_PROC_FILE("host-bridge", proc_nvidia_agp,
742 - nv_procfs_read_agp_info, NULL, NULL, NULL);
747 - entry = NV_CREATE_PROC_FILE("gpu", proc_nvidia_agp,
748 - nv_procfs_read_agp_info, NULL, NULL, nv);
749 + entry = NV_CREATE_PROC_FILE("gpu", proc_nvidia_agp, agp_info, nv);