]>
Commit | Line | Data |
---|---|---|
33afafb0 JR |
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 | |
5 | ||
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) | |
12 | #endif | |
13 | ||
14 | -#define NV_CREATE_PROC_ENTRY(name,mode,parent) \ | |
15 | - ({ \ | |
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); \ | |
20 | - __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) | |
24 | +#else | |
25 | +# define NV_CREATE_PROC_ENTRY(name,mode,parent,fops,__data) \ | |
26 | + ({ \ | |
27 | + struct proc_dir_entry *__entry; \ | |
28 | + __entry = create_proc_entry(name, mode, parent); \ | |
29 | + if (__entry != NULL) \ | |
30 | + { \ | |
31 | + NV_SET_PROC_ENTRY_OWNER(__entry); \ | |
32 | + __entry->proc_fops = fops; \ | |
33 | + __entry->data = (__data); \ | |
34 | + } \ | |
35 | + __entry; \ | |
36 | + }) | |
37 | +#endif | |
38 | + | |
39 | +#define NV_CREATE_PROC_FILE(filename,parent,__name,__data) \ | |
40 | + ({ \ | |
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, \ | |
47 | + __data); \ | |
48 | + __entry; \ | |
49 | }) | |
50 | ||
51 | -#define NV_CREATE_PROC_FILE(name,parent,__read_proc, \ | |
52 | - __write_proc,__fops,__data) \ | |
53 | +/* | |
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. | |
56 | + */ | |
57 | +#if defined(NV_PROC_REMOVE_PRESENT) | |
58 | +# define NV_PROC_MKDIR_MODE(name, mode, parent) \ | |
59 | + proc_mkdir_mode(name, mode, parent) | |
60 | +#else | |
61 | +# define NV_PROC_MKDIR_MODE(name, mode, parent) \ | |
62 | ({ \ | |
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) \ | |
70 | - { \ | |
71 | - if ((NvUPtr)(__read_proc) != 0) \ | |
72 | - __entry->read_proc = (__read_proc); \ | |
73 | - if ((NvUPtr)(__write_proc) != 0) \ | |
74 | - { \ | |
75 | - __entry->write_proc = (__write_proc); \ | |
76 | - __entry->proc_fops = (__fops); \ | |
77 | - } \ | |
78 | - __entry->data = (__data); \ | |
79 | - } \ | |
80 | + NV_SET_PROC_ENTRY_OWNER(__entry); \ | |
81 | __entry; \ | |
82 | }) | |
83 | +#endif | |
84 | ||
85 | #define NV_CREATE_PROC_DIR(name,parent) \ | |
86 | ({ \ | |
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); \ | |
91 | __entry; \ | |
92 | }) | |
93 | ||
94 | +#if defined(NV_PDE_DATA_PRESENT) | |
95 | +# define NV_PDE_DATA(inode) PDE_DATA(inode) | |
96 | +#else | |
97 | +# define NV_PDE_DATA(inode) PDE(inode)->data | |
98 | +#endif | |
99 | + | |
100 | +#define NV_DEFINE_PROCFS_SINGLE_FILE(__name) \ | |
101 | + static int nv_procfs_open_##__name( \ | |
102 | + struct inode *inode, \ | |
103 | + struct file *filep \ | |
104 | + ) \ | |
105 | + { \ | |
106 | + return single_open(filep, nv_procfs_read_##__name, \ | |
107 | + NV_PDE_DATA(inode)); \ | |
108 | + } \ | |
109 | + \ | |
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, \ | |
116 | + }; | |
117 | + | |
118 | +static int nv_procfs_read_registry(struct seq_file *s, void *v); | |
119 | + | |
120 | #define NV_PROC_WRITE_BUFFER_SIZE (64 * RM_PAGE_SIZE) | |
121 | ||
122 | static int | |
123 | nv_procfs_read_gpu_info( | |
124 | - char *page, | |
125 | - char **start, | |
126 | - off_t off, | |
127 | - int count, | |
128 | - int *eof, | |
129 | - void *data | |
130 | + struct seq_file *s, | |
131 | + void *v | |
132 | ) | |
133 | { | |
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; | |
140 | + int status; | |
141 | NvU8 *uuid; | |
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; | |
145 | ||
146 | - *eof = 1; | |
147 | - | |
148 | NV_KMEM_CACHE_ALLOC_STACK(sp); | |
149 | if (sp == NULL) | |
150 | { | |
151 | @@ -139,26 +176,26 @@ nv_procfs_read_gpu_info( | |
152 | } | |
153 | } | |
154 | ||
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); | |
159 | ||
160 | if (NV_IS_GVI_DEVICE(nv)) | |
161 | { | |
162 | status = rm_gvi_get_firmware_version(sp, nv, &fpga_rev1, &fpga_rev2, | |
163 | &fpga_rev3); | |
164 | if (status != RM_OK) | |
165 | - len += sprintf(page+len, "Firmware: \t ????.??.??\n"); | |
166 | + seq_printf(s, "Firmware: \t ????.??.??\n"); | |
167 | else | |
168 | { | |
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); | |
172 | } | |
173 | } | |
174 | else | |
175 | { | |
176 | if (rm_get_gpu_uuid(sp, nv, &uuid, NULL) == RM_OK) | |
177 | { | |
178 | - len += sprintf(page+len, "GPU UUID: \t %s\n", (char *)uuid); | |
179 | + seq_printf(s, "GPU UUID: \t %s\n", (char *)uuid); | |
180 | os_free_mem(uuid); | |
181 | } | |
182 | ||
183 | @@ -166,65 +203,62 @@ nv_procfs_read_gpu_info( | |
184 | &vbios_rev3, &vbios_rev4, | |
185 | &vbios_rev5) != RM_OK) | |
186 | { | |
187 | - len += sprintf(page+len, "Video BIOS: \t ??.??.??.??.??\n"); | |
188 | + seq_printf(s, "Video BIOS: \t ??.??.??.??.??\n"); | |
189 | } | |
190 | else | |
191 | { | |
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, | |
196 | + vbios_rev5); | |
197 | } | |
198 | } | |
199 | ||
200 | if (nv_find_pci_capability(dev, PCI_CAP_ID_AGP)) | |
201 | type = "AGP"; | |
202 | else if (nv_find_pci_capability(dev, PCI_CAP_ID_EXP)) | |
203 | - type = "PCI-E"; | |
204 | + type = "PCIe"; | |
205 | else | |
206 | type = "PCI"; | |
207 | - len += sprintf(page+len, "Bus Type: \t %s\n", type); | |
208 | + seq_printf(s, "Bus Type: \t %s\n", type); | |
209 | ||
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)); | |
219 | #if defined(DEBUG) | |
220 | do | |
221 | { | |
222 | int j; | |
223 | for (j = 0; j < NV_GPU_NUM_BARS; j++) | |
224 | { | |
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)); | |
229 | } | |
230 | } while (0); | |
231 | #endif | |
232 | ||
233 | NV_KMEM_CACHE_FREE_STACK(sp); | |
234 | ||
235 | - return len; | |
236 | + return 0; | |
237 | } | |
238 | ||
239 | +NV_DEFINE_PROCFS_SINGLE_FILE(gpu_info); | |
240 | + | |
241 | static int | |
242 | nv_procfs_read_version( | |
243 | - char *page, | |
244 | - char **start, | |
245 | - off_t off, | |
246 | - int count, | |
247 | - int *eof, | |
248 | - void *data | |
249 | + struct seq_file *s, | |
250 | + void *v | |
251 | ) | |
252 | { | |
253 | - int len = 0; | |
254 | - *eof = 1; | |
255 | + seq_printf(s, "NVRM version: %s\n", pNVRM_ID); | |
256 | + seq_printf(s, "GCC version: %s\n", NV_COMPILER); | |
257 | ||
258 | - len += sprintf(page+len, "NVRM version: %s\n", pNVRM_ID); | |
259 | - len += sprintf(page+len, "GCC version: %s\n", NV_COMPILER); | |
260 | - | |
261 | - return len; | |
262 | + return 0; | |
263 | } | |
264 | ||
265 | +NV_DEFINE_PROCFS_SINGLE_FILE(version); | |
266 | + | |
267 | static struct pci_dev *nv_get_agp_device_by_class(unsigned int class) | |
268 | { | |
269 | struct pci_dev *dev, *fdev; | |
270 | @@ -256,23 +290,16 @@ static struct pci_dev *nv_get_agp_device_by_class(unsigned int class) | |
271 | ||
272 | static int | |
273 | nv_procfs_read_agp_info( | |
274 | - char *page, | |
275 | - char **start, | |
276 | - off_t off, | |
277 | - int count, | |
278 | - int *eof, | |
279 | - void *data | |
280 | + struct seq_file *s, | |
281 | + void *v | |
282 | ) | |
283 | { | |
284 | - nv_state_t *nv = data; | |
285 | + nv_state_t *nv = s->private; | |
286 | nv_linux_state_t *nvl = NULL; | |
287 | struct pci_dev *dev; | |
288 | char *fw, *sba; | |
289 | u8 cap_ptr; | |
290 | u32 status, command, agp_rate; | |
291 | - int len = 0; | |
292 | - | |
293 | - *eof = 1; | |
294 | ||
295 | if (nv != NULL) | |
296 | { | |
297 | @@ -285,13 +312,12 @@ nv_procfs_read_agp_info( | |
298 | if (!dev) | |
299 | return 0; | |
300 | ||
301 | - len += sprintf(page+len, "Host Bridge: \t "); | |
302 | + seq_printf(s, "Host Bridge: \t "); | |
303 | ||
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)); | |
307 | #else | |
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); | |
311 | #endif | |
312 | } | |
313 | ||
314 | @@ -303,48 +329,43 @@ nv_procfs_read_agp_info( | |
315 | fw = (status & 0x00000010) ? "Supported" : "Not Supported"; | |
316 | sba = (status & 0x00000200) ? "Supported" : "Not Supported"; | |
317 | ||
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); | |
322 | ||
323 | agp_rate = status & 0x7; | |
324 | if (status & 0x8) | |
325 | agp_rate <<= 2; | |
326 | ||
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 " : ""); | |
337 | ||
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); | |
340 | ||
341 | if (nvl == NULL) | |
342 | NV_PCI_DEV_PUT(dev); | |
343 | ||
344 | - return len; | |
345 | + return 0; | |
346 | } | |
347 | ||
348 | +NV_DEFINE_PROCFS_SINGLE_FILE(agp_info); | |
349 | + | |
350 | static int | |
351 | nv_procfs_read_agp_status( | |
352 | - char *page, | |
353 | - char **start, | |
354 | - off_t off, | |
355 | - int count, | |
356 | - int *eof, | |
357 | - void *data | |
358 | + struct seq_file *s, | |
359 | + void *v | |
360 | ) | |
361 | { | |
362 | - nv_state_t *nv = data; | |
363 | + nv_state_t *nv = s->private; | |
364 | struct pci_dev *dev; | |
365 | char *fw, *sba, *drv; | |
366 | - int len = 0; | |
367 | u8 cap_ptr; | |
368 | u32 scratch; | |
369 | u32 status, command, agp_rate; | |
370 | nv_stack_t *sp = NULL; | |
371 | ||
372 | - *eof = 1; | |
373 | - | |
374 | dev = nv_get_agp_device_by_class(PCI_CLASS_BRIDGE_HOST); | |
375 | if (!dev) | |
376 | return 0; | |
377 | @@ -366,22 +387,22 @@ nv_procfs_read_agp_status( | |
378 | ||
379 | if (NV_AGP_ENABLED(nv) && (command & 0x100)) | |
380 | { | |
381 | - len += sprintf(page+len, "Status: \t Enabled\n"); | |
382 | + seq_printf(s, "Status: \t Enabled\n"); | |
383 | ||
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); | |
387 | ||
388 | agp_rate = command & 0x7; | |
389 | if (status & 0x8) | |
390 | agp_rate <<= 2; | |
391 | ||
392 | - len += sprintf(page+len, "AGP Rate: \t %dx\n", agp_rate); | |
393 | + seq_printf(s, "AGP Rate: \t %dx\n", agp_rate); | |
394 | ||
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); | |
398 | ||
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); | |
402 | } | |
403 | else | |
404 | { | |
405 | @@ -394,7 +415,7 @@ nv_procfs_read_agp_status( | |
406 | return 0; | |
407 | } | |
408 | ||
409 | - len += sprintf(page+len, "Status: \t Disabled\n\n"); | |
410 | + seq_printf(s, "Status: \t Disabled\n\n"); | |
411 | ||
412 | /* | |
413 | * If we find AGP is disabled, but the RM registry indicates it | |
414 | @@ -409,7 +430,7 @@ nv_procfs_read_agp_status( | |
415 | ||
416 | if (agp_config != NVOS_AGP_CONFIG_DISABLE_AGP && NV_AGP_FAILED(nv)) | |
417 | { | |
418 | - len += sprintf(page+len, | |
419 | + seq_printf(s, | |
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( | |
424 | } | |
425 | ||
426 | NV_PCI_DEV_PUT(dev); | |
427 | - return len; | |
428 | + return 0; | |
429 | } | |
430 | ||
431 | +NV_DEFINE_PROCFS_SINGLE_FILE(agp_status); | |
432 | + | |
433 | static int | |
434 | nv_procfs_open_registry( | |
435 | struct inode *inode, | |
436 | @@ -431,9 +454,6 @@ nv_procfs_open_registry( | |
437 | nv_file_private_t *nvfp = NULL; | |
438 | nv_stack_t *sp = NULL; | |
439 | ||
440 | - if (0 == (file->f_mode & FMODE_WRITE)) | |
441 | - return 0; | |
442 | - | |
443 | nvfp = nv_alloc_file_private(); | |
444 | if (nvfp == NULL) | |
445 | { | |
446 | @@ -441,6 +461,11 @@ nv_procfs_open_registry( | |
447 | return -ENOMEM; | |
448 | } | |
449 | ||
450 | + nvfp->proc_data = NV_PDE_DATA(inode); | |
451 | + | |
452 | + if (0 == (file->f_mode & FMODE_WRITE)) | |
453 | + goto done; | |
454 | + | |
455 | NV_KMEM_CACHE_ALLOC_STACK(sp); | |
456 | if (sp == NULL) | |
457 | { | |
458 | @@ -449,19 +474,19 @@ nv_procfs_open_registry( | |
459 | return -ENOMEM; | |
460 | } | |
461 | ||
462 | - NV_SET_FILE_PRIVATE(file, nvfp); | |
463 | - | |
464 | if (RM_OK != os_alloc_mem((void **)&nvfp->data, NV_PROC_WRITE_BUFFER_SIZE)) | |
465 | { | |
466 | nv_free_file_private(nvfp); | |
467 | NV_KMEM_CACHE_FREE_STACK(sp); | |
468 | - NV_SET_FILE_PRIVATE(file, NULL); | |
469 | return -ENOMEM; | |
470 | } | |
471 | ||
472 | os_mem_set((void *)nvfp->data, 0, NV_PROC_WRITE_BUFFER_SIZE); | |
473 | nvfp->fops_sp[NV_FOPS_STACK_INDEX_PROCFS] = sp; | |
474 | ||
475 | +done: | |
476 | + single_open(file, nv_procfs_read_registry, nvfp); | |
477 | + | |
478 | return 0; | |
479 | } | |
480 | ||
481 | @@ -471,6 +496,7 @@ nv_procfs_close_registry( | |
482 | struct file *file | |
483 | ) | |
484 | { | |
485 | + struct seq_file *s = file->private_data; | |
486 | nv_file_private_t *nvfp; | |
487 | nv_state_t *nv; | |
488 | nv_linux_state_t *nvl = NULL; | |
489 | @@ -481,9 +507,8 @@ nv_procfs_close_registry( | |
490 | RM_STATUS rm_status; | |
491 | int rc = 0; | |
492 | ||
493 | - nvfp = NV_GET_FILE_PRIVATE(file); | |
494 | - if (nvfp == NULL) | |
495 | - return 0; | |
496 | + nvfp = s->private; | |
497 | + single_release(inode, file); | |
498 | ||
499 | sp = nvfp->fops_sp[NV_FOPS_STACK_INDEX_PROCFS]; | |
500 | ||
501 | @@ -538,56 +563,42 @@ done: | |
502 | os_free_mem(nvfp->data); | |
503 | ||
504 | nv_free_file_private(nvfp); | |
505 | - NV_SET_FILE_PRIVATE(file, NULL); | |
506 | ||
507 | - NV_KMEM_CACHE_FREE_STACK(sp); | |
508 | + if (sp != NULL) | |
509 | + NV_KMEM_CACHE_FREE_STACK(sp); | |
510 | ||
511 | return rc; | |
512 | } | |
513 | ||
514 | -static struct file_operations nv_procfs_registry_fops = { | |
515 | - .open = nv_procfs_open_registry, | |
516 | - .release = nv_procfs_close_registry, | |
517 | -}; | |
518 | - | |
519 | static int | |
520 | nv_procfs_read_params( | |
521 | - char *page, | |
522 | - char **start, | |
523 | - off_t off, | |
524 | - int count, | |
525 | - int *eof, | |
526 | - void *data | |
527 | + struct seq_file *s, | |
528 | + void *v | |
529 | ) | |
530 | { | |
531 | unsigned int i; | |
532 | - int len = 0; | |
533 | nv_parm_t *entry; | |
534 | ||
535 | - *eof = 1; | |
536 | - | |
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); | |
540 | ||
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 : ""); | |
547 | ||
548 | - return len; | |
549 | + return 0; | |
550 | } | |
551 | ||
552 | +NV_DEFINE_PROCFS_SINGLE_FILE(params); | |
553 | + | |
554 | static int | |
555 | nv_procfs_read_registry( | |
556 | - char *page, | |
557 | - char **start, | |
558 | - off_t off, | |
559 | - int count, | |
560 | - int *eof, | |
561 | - void *data | |
562 | + struct seq_file *s, | |
563 | + void *v | |
564 | ) | |
565 | { | |
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; | |
570 | char *registry_keys; | |
571 | ||
572 | @@ -596,20 +607,20 @@ nv_procfs_read_registry( | |
573 | registry_keys = ((nvl != NULL) ? | |
574 | nvl->registry_keys : nv_registry_keys); | |
575 | ||
576 | - *eof = 1; | |
577 | - return sprintf(page, "Binary: \"%s\"\n", registry_keys); | |
578 | + return seq_printf(s, "Binary: \"%s\"\n", registry_keys); | |
579 | } | |
580 | ||
581 | -static int | |
582 | +static ssize_t | |
583 | nv_procfs_write_registry( | |
584 | struct file *file, | |
585 | - const char *buffer, | |
586 | - unsigned long count, | |
587 | - void *data | |
588 | + const char *buffer, | |
589 | + size_t count, | |
590 | + loff_t *pos | |
591 | ) | |
592 | { | |
593 | int status = 0; | |
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; | |
597 | char *proc_buffer; | |
598 | unsigned long bytes_left; | |
599 | ||
600 | @@ -637,30 +648,37 @@ nv_procfs_write_registry( | |
601 | } | |
602 | else | |
603 | { | |
604 | - nvfp->proc_data = data; | |
605 | nvfp->off += count; | |
606 | } | |
607 | ||
608 | + *pos = nvfp->off; | |
609 | + | |
610 | done: | |
611 | up(&nvfp->fops_sp_lock[NV_FOPS_STACK_INDEX_PROCFS]); | |
612 | ||
613 | return ((status < 0) ? status : (int)count); | |
614 | } | |
615 | ||
616 | +static struct file_operations nv_procfs_registry_fops = { | |
617 | + .owner = THIS_MODULE, | |
618 | + .open = nv_procfs_open_registry, | |
619 | + .read = seq_read, | |
620 | + .write = nv_procfs_write_registry, | |
621 | + .llseek = seq_lseek, | |
622 | + .release = nv_procfs_close_registry, | |
623 | +}; | |
624 | + | |
625 | static int | |
626 | nv_procfs_read_text_file( | |
627 | - char *page, | |
628 | - char **start, | |
629 | - off_t off, | |
630 | - int count, | |
631 | - int *eof, | |
632 | - void *data | |
633 | + struct seq_file *s, | |
634 | + void *v | |
635 | ) | |
636 | { | |
637 | - *eof = 1; | |
638 | - return sprintf(page, "%s", (char *)data); | |
639 | + return seq_puts(s, s->private); | |
640 | } | |
641 | ||
642 | +NV_DEFINE_PROCFS_SINGLE_FILE(text_file); | |
643 | + | |
644 | static void | |
645 | nv_procfs_add_text_file( | |
646 | struct proc_dir_entry *parent, | |
647 | @@ -668,12 +686,14 @@ nv_procfs_add_text_file( | |
648 | const char *text | |
649 | ) | |
650 | { | |
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); | |
654 | } | |
655 | ||
656 | static void nv_procfs_unregister_all(struct proc_dir_entry *entry) | |
657 | { | |
658 | +#if defined(NV_PROC_REMOVE_PRESENT) | |
659 | + proc_remove(entry); | |
660 | +#else | |
661 | while (entry) | |
662 | { | |
663 | struct proc_dir_entry *next = entry->next; | |
664 | @@ -684,6 +704,7 @@ static void nv_procfs_unregister_all(struct proc_dir_entry *entry) | |
665 | break; | |
666 | entry = next; | |
667 | } | |
668 | +#endif | |
669 | } | |
670 | #endif | |
671 | ||
672 | @@ -713,26 +734,11 @@ int nv_register_procfs(void) | |
673 | if (!proc_nvidia) | |
674 | goto failed; | |
675 | ||
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); | |
679 | if (!entry) | |
680 | goto failed; | |
681 | ||
682 | - /* | |
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. | |
689 | - */ | |
690 | - nv_procfs_registry_fops.read = entry->proc_fops->read; | |
691 | - nv_procfs_registry_fops.write = entry->proc_fops->write; | |
692 | - | |
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); | |
698 | if (!entry) | |
699 | goto failed; | |
700 | ||
701 | @@ -753,8 +759,7 @@ int nv_register_procfs(void) | |
702 | ||
703 | nv_procfs_add_text_file(proc_nvidia_patches, "README", __README_patches); | |
704 | ||
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); | |
708 | if (!entry) | |
709 | goto failed; | |
710 | ||
711 | @@ -771,15 +776,12 @@ int nv_register_procfs(void) | |
712 | if (!proc_nvidia_gpu) | |
713 | goto failed; | |
714 | ||
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, | |
718 | + nv); | |
719 | if (!entry) | |
720 | goto failed; | |
721 | ||
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); | |
727 | if (!entry) | |
728 | goto failed; | |
729 | ||
730 | @@ -789,18 +791,17 @@ int nv_register_procfs(void) | |
731 | if (!proc_nvidia_agp) | |
732 | goto failed; | |
733 | ||
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, | |
737 | + nv); | |
738 | if (!entry) | |
739 | goto failed; | |
740 | ||
741 | entry = NV_CREATE_PROC_FILE("host-bridge", proc_nvidia_agp, | |
742 | - nv_procfs_read_agp_info, NULL, NULL, NULL); | |
743 | + agp_info, NULL); | |
744 | if (!entry) | |
745 | goto failed; | |
746 | ||
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); | |
750 | if (!entry) | |
751 | goto failed; | |
752 | } |