Commit 28a62277e06f93729d0340d9659153dcfbdbe16d
Committed by
Eric Anholt
1 parent
40a5f0decd
Exists in
master
and in
7 other branches
drm: Convert proc files to seq_file and introduce debugfs
The old mechanism to formatting proc files is extremely ugly. The seq_file API was designed specifically for cases like this and greatly simplifies the process. Also, most of the files in /proc really don't belong there. This patch introduces the infrastructure for putting these into debugfs and exposes all of the proc files in debugfs as well. Signed-off-by: Ben Gamari <bgamari@gmail.com> Signed-off-by: Eric Anholt <eric@anholt.net>
Showing 7 changed files with 776 additions and 615 deletions Side-by-side Diff
drivers/gpu/drm/Makefile
... | ... | @@ -10,7 +10,8 @@ |
10 | 10 | drm_lock.o drm_memory.o drm_proc.o drm_stub.o drm_vm.o \ |
11 | 11 | drm_agpsupport.o drm_scatter.o ati_pcigart.o drm_pci.o \ |
12 | 12 | drm_sysfs.o drm_hashtab.o drm_sman.o drm_mm.o \ |
13 | - drm_crtc.o drm_crtc_helper.o drm_modes.o drm_edid.o | |
13 | + drm_crtc.o drm_crtc_helper.o drm_modes.o drm_edid.o \ | |
14 | + drm_info.o drm_debugfs.o | |
14 | 15 | |
15 | 16 | drm-$(CONFIG_COMPAT) += drm_ioc32.o |
16 | 17 |
drivers/gpu/drm/drm_debugfs.c
1 | +/** | |
2 | + * \file drm_debugfs.c | |
3 | + * debugfs support for DRM | |
4 | + * | |
5 | + * \author Ben Gamari <bgamari@gmail.com> | |
6 | + */ | |
7 | + | |
8 | +/* | |
9 | + * Created: Sun Dec 21 13:08:50 2008 by bgamari@gmail.com | |
10 | + * | |
11 | + * Copyright 2008 Ben Gamari <bgamari@gmail.com> | |
12 | + * | |
13 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
14 | + * copy of this software and associated documentation files (the "Software"), | |
15 | + * to deal in the Software without restriction, including without limitation | |
16 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
17 | + * and/or sell copies of the Software, and to permit persons to whom the | |
18 | + * Software is furnished to do so, subject to the following conditions: | |
19 | + * | |
20 | + * The above copyright notice and this permission notice (including the next | |
21 | + * paragraph) shall be included in all copies or substantial portions of the | |
22 | + * Software. | |
23 | + * | |
24 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
25 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
26 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
27 | + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
28 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
29 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
30 | + * OTHER DEALINGS IN THE SOFTWARE. | |
31 | + */ | |
32 | + | |
33 | +#include <linux/debugfs.h> | |
34 | +#include <linux/seq_file.h> | |
35 | +#include "drmP.h" | |
36 | + | |
37 | +#if defined(CONFIG_DEBUG_FS) | |
38 | + | |
39 | +/*************************************************** | |
40 | + * Initialization, etc. | |
41 | + **************************************************/ | |
42 | + | |
43 | +static struct drm_info_list drm_debugfs_list[] = { | |
44 | + {"name", drm_name_info, 0}, | |
45 | + {"vm", drm_vm_info, 0}, | |
46 | + {"clients", drm_clients_info, 0}, | |
47 | + {"queues", drm_queues_info, 0}, | |
48 | + {"bufs", drm_bufs_info, 0}, | |
49 | + {"gem_names", drm_gem_name_info, DRIVER_GEM}, | |
50 | + {"gem_objects", drm_gem_object_info, DRIVER_GEM}, | |
51 | +#if DRM_DEBUG_CODE | |
52 | + {"vma", drm_vma_info, 0}, | |
53 | +#endif | |
54 | +}; | |
55 | +#define DRM_DEBUGFS_ENTRIES ARRAY_SIZE(drm_debugfs_list) | |
56 | + | |
57 | + | |
58 | +static int drm_debugfs_open(struct inode *inode, struct file *file) | |
59 | +{ | |
60 | + struct drm_info_node *node = inode->i_private; | |
61 | + | |
62 | + return single_open(file, node->info_ent->show, node); | |
63 | +} | |
64 | + | |
65 | + | |
66 | +static const struct file_operations drm_debugfs_fops = { | |
67 | + .owner = THIS_MODULE, | |
68 | + .open = drm_debugfs_open, | |
69 | + .read = seq_read, | |
70 | + .llseek = seq_lseek, | |
71 | + .release = single_release, | |
72 | +}; | |
73 | + | |
74 | + | |
75 | +/** | |
76 | + * Initialize a given set of debugfs files for a device | |
77 | + * | |
78 | + * \param files The array of files to create | |
79 | + * \param count The number of files given | |
80 | + * \param root DRI debugfs dir entry. | |
81 | + * \param minor device minor number | |
82 | + * \return Zero on success, non-zero on failure | |
83 | + * | |
84 | + * Create a given set of debugfs files represented by an array of | |
85 | + * gdm_debugfs_lists in the given root directory. | |
86 | + */ | |
87 | +int drm_debugfs_create_files(struct drm_info_list *files, int count, | |
88 | + struct dentry *root, struct drm_minor *minor) | |
89 | +{ | |
90 | + struct drm_device *dev = minor->dev; | |
91 | + struct dentry *ent; | |
92 | + struct drm_info_node *tmp; | |
93 | + char name[64]; | |
94 | + int i, ret; | |
95 | + | |
96 | + for (i = 0; i < count; i++) { | |
97 | + u32 features = files[i].driver_features; | |
98 | + | |
99 | + if (features != 0 && | |
100 | + (dev->driver->driver_features & features) != features) | |
101 | + continue; | |
102 | + | |
103 | + tmp = drm_alloc(sizeof(struct drm_info_node), | |
104 | + _DRM_DRIVER); | |
105 | + ent = debugfs_create_file(files[i].name, S_IFREG | S_IRUGO, | |
106 | + root, tmp, &drm_debugfs_fops); | |
107 | + if (!ent) { | |
108 | + DRM_ERROR("Cannot create /debugfs/dri/%s/%s\n", | |
109 | + name, files[i].name); | |
110 | + drm_free(tmp, sizeof(struct drm_info_node), | |
111 | + _DRM_DRIVER); | |
112 | + ret = -1; | |
113 | + goto fail; | |
114 | + } | |
115 | + | |
116 | + tmp->minor = minor; | |
117 | + tmp->dent = ent; | |
118 | + tmp->info_ent = &files[i]; | |
119 | + list_add(&(tmp->list), &(minor->debugfs_nodes.list)); | |
120 | + } | |
121 | + return 0; | |
122 | + | |
123 | +fail: | |
124 | + drm_debugfs_remove_files(files, count, minor); | |
125 | + return ret; | |
126 | +} | |
127 | +EXPORT_SYMBOL(drm_debugfs_create_files); | |
128 | + | |
129 | +/** | |
130 | + * Initialize the DRI debugfs filesystem for a device | |
131 | + * | |
132 | + * \param dev DRM device | |
133 | + * \param minor device minor number | |
134 | + * \param root DRI debugfs dir entry. | |
135 | + * | |
136 | + * Create the DRI debugfs root entry "/debugfs/dri", the device debugfs root entry | |
137 | + * "/debugfs/dri/%minor%/", and each entry in debugfs_list as | |
138 | + * "/debugfs/dri/%minor%/%name%". | |
139 | + */ | |
140 | +int drm_debugfs_init(struct drm_minor *minor, int minor_id, | |
141 | + struct dentry *root) | |
142 | +{ | |
143 | + struct drm_device *dev = minor->dev; | |
144 | + char name[64]; | |
145 | + int ret; | |
146 | + | |
147 | + INIT_LIST_HEAD(&minor->debugfs_nodes.list); | |
148 | + sprintf(name, "%d", minor_id); | |
149 | + minor->debugfs_root = debugfs_create_dir(name, root); | |
150 | + if (!minor->debugfs_root) { | |
151 | + DRM_ERROR("Cannot create /debugfs/dri/%s\n", name); | |
152 | + return -1; | |
153 | + } | |
154 | + | |
155 | + ret = drm_debugfs_create_files(drm_debugfs_list, DRM_DEBUGFS_ENTRIES, | |
156 | + minor->debugfs_root, minor); | |
157 | + if (ret) { | |
158 | + debugfs_remove(minor->debugfs_root); | |
159 | + minor->debugfs_root = NULL; | |
160 | + DRM_ERROR("Failed to create core drm debugfs files\n"); | |
161 | + return ret; | |
162 | + } | |
163 | + | |
164 | + if (dev->driver->debugfs_init) { | |
165 | + ret = dev->driver->debugfs_init(minor); | |
166 | + if (ret) { | |
167 | + DRM_ERROR("DRM: Driver failed to initialize " | |
168 | + "/debugfs/dri.\n"); | |
169 | + return ret; | |
170 | + } | |
171 | + } | |
172 | + return 0; | |
173 | +} | |
174 | + | |
175 | + | |
176 | +/** | |
177 | + * Remove a list of debugfs files | |
178 | + * | |
179 | + * \param files The list of files | |
180 | + * \param count The number of files | |
181 | + * \param minor The minor of which we should remove the files | |
182 | + * \return always zero. | |
183 | + * | |
184 | + * Remove all debugfs entries created by debugfs_init(). | |
185 | + */ | |
186 | +int drm_debugfs_remove_files(struct drm_info_list *files, int count, | |
187 | + struct drm_minor *minor) | |
188 | +{ | |
189 | + struct list_head *pos, *q; | |
190 | + struct drm_info_node *tmp; | |
191 | + int i; | |
192 | + | |
193 | + for (i = 0; i < count; i++) { | |
194 | + list_for_each_safe(pos, q, &minor->debugfs_nodes.list) { | |
195 | + tmp = list_entry(pos, struct drm_info_node, list); | |
196 | + if (tmp->info_ent == &files[i]) { | |
197 | + debugfs_remove(tmp->dent); | |
198 | + list_del(pos); | |
199 | + drm_free(tmp, sizeof(struct drm_info_node), | |
200 | + _DRM_DRIVER); | |
201 | + } | |
202 | + } | |
203 | + } | |
204 | + return 0; | |
205 | +} | |
206 | +EXPORT_SYMBOL(drm_debugfs_remove_files); | |
207 | + | |
208 | +/** | |
209 | + * Cleanup the debugfs filesystem resources. | |
210 | + * | |
211 | + * \param minor device minor number. | |
212 | + * \return always zero. | |
213 | + * | |
214 | + * Remove all debugfs entries created by debugfs_init(). | |
215 | + */ | |
216 | +int drm_debugfs_cleanup(struct drm_minor *minor) | |
217 | +{ | |
218 | + struct drm_device *dev = minor->dev; | |
219 | + | |
220 | + if (!minor->debugfs_root) | |
221 | + return 0; | |
222 | + | |
223 | + if (dev->driver->debugfs_cleanup) | |
224 | + dev->driver->debugfs_cleanup(minor); | |
225 | + | |
226 | + drm_debugfs_remove_files(drm_debugfs_list, DRM_DEBUGFS_ENTRIES, minor); | |
227 | + | |
228 | + debugfs_remove(minor->debugfs_root); | |
229 | + minor->debugfs_root = NULL; | |
230 | + | |
231 | + return 0; | |
232 | +} | |
233 | + | |
234 | +#endif /* CONFIG_DEBUG_FS */ |
drivers/gpu/drm/drm_drv.c
... | ... | @@ -46,9 +46,11 @@ |
46 | 46 | * OTHER DEALINGS IN THE SOFTWARE. |
47 | 47 | */ |
48 | 48 | |
49 | +#include <linux/debugfs.h> | |
49 | 50 | #include "drmP.h" |
50 | 51 | #include "drm_core.h" |
51 | 52 | |
53 | + | |
52 | 54 | static int drm_version(struct drm_device *dev, void *data, |
53 | 55 | struct drm_file *file_priv); |
54 | 56 | |
... | ... | @@ -178,7 +180,7 @@ |
178 | 180 | |
179 | 181 | /* Clear AGP information */ |
180 | 182 | if (drm_core_has_AGP(dev) && dev->agp && |
181 | - !drm_core_check_feature(dev, DRIVER_MODESET)) { | |
183 | + !drm_core_check_feature(dev, DRIVER_MODESET)) { | |
182 | 184 | struct drm_agp_mem *entry, *tempe; |
183 | 185 | |
184 | 186 | /* Remove AGP resources, but leave dev->agp |
... | ... | @@ -382,6 +384,13 @@ |
382 | 384 | goto err_p3; |
383 | 385 | } |
384 | 386 | |
387 | + drm_debugfs_root = debugfs_create_dir("dri", NULL); | |
388 | + if (!drm_debugfs_root) { | |
389 | + DRM_ERROR("Cannot create /debugfs/dri\n"); | |
390 | + ret = -1; | |
391 | + goto err_p3; | |
392 | + } | |
393 | + | |
385 | 394 | drm_mem_init(); |
386 | 395 | |
387 | 396 | DRM_INFO("Initialized %s %d.%d.%d %s\n", |
... | ... | @@ -400,6 +409,7 @@ |
400 | 409 | static void __exit drm_core_exit(void) |
401 | 410 | { |
402 | 411 | remove_proc_entry("dri", NULL); |
412 | + debugfs_remove(drm_debugfs_root); | |
403 | 413 | drm_sysfs_destroy(); |
404 | 414 | |
405 | 415 | unregister_chrdev(DRM_MAJOR, "drm"); |
drivers/gpu/drm/drm_info.c
1 | +/** | |
2 | + * \file drm_info.c | |
3 | + * DRM info file implementations | |
4 | + * | |
5 | + * \author Ben Gamari <bgamari@gmail.com> | |
6 | + */ | |
7 | + | |
8 | +/* | |
9 | + * Created: Sun Dec 21 13:09:50 2008 by bgamari@gmail.com | |
10 | + * | |
11 | + * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. | |
12 | + * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. | |
13 | + * Copyright 2008 Ben Gamari <bgamari@gmail.com> | |
14 | + * All Rights Reserved. | |
15 | + * | |
16 | + * Permission is hereby granted, free of charge, to any person obtaining a | |
17 | + * copy of this software and associated documentation files (the "Software"), | |
18 | + * to deal in the Software without restriction, including without limitation | |
19 | + * the rights to use, copy, modify, merge, publish, distribute, sublicense, | |
20 | + * and/or sell copies of the Software, and to permit persons to whom the | |
21 | + * Software is furnished to do so, subject to the following conditions: | |
22 | + * | |
23 | + * The above copyright notice and this permission notice (including the next | |
24 | + * paragraph) shall be included in all copies or substantial portions of the | |
25 | + * Software. | |
26 | + * | |
27 | + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
28 | + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
29 | + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | |
30 | + * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR | |
31 | + * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | |
32 | + * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |
33 | + * OTHER DEALINGS IN THE SOFTWARE. | |
34 | + */ | |
35 | + | |
36 | +#include <linux/seq_file.h> | |
37 | +#include "drmP.h" | |
38 | + | |
39 | +/** | |
40 | + * Called when "/proc/dri/.../name" is read. | |
41 | + * | |
42 | + * Prints the device name together with the bus id if available. | |
43 | + */ | |
44 | +int drm_name_info(struct seq_file *m, void *data) | |
45 | +{ | |
46 | + struct drm_info_node *node = (struct drm_info_node *) m->private; | |
47 | + struct drm_minor *minor = node->minor; | |
48 | + struct drm_device *dev = minor->dev; | |
49 | + struct drm_master *master = minor->master; | |
50 | + | |
51 | + if (!master) | |
52 | + return 0; | |
53 | + | |
54 | + if (master->unique) { | |
55 | + seq_printf(m, "%s %s %s\n", | |
56 | + dev->driver->pci_driver.name, | |
57 | + pci_name(dev->pdev), master->unique); | |
58 | + } else { | |
59 | + seq_printf(m, "%s %s\n", dev->driver->pci_driver.name, | |
60 | + pci_name(dev->pdev)); | |
61 | + } | |
62 | + | |
63 | + return 0; | |
64 | +} | |
65 | + | |
66 | +/** | |
67 | + * Called when "/proc/dri/.../vm" is read. | |
68 | + * | |
69 | + * Prints information about all mappings in drm_device::maplist. | |
70 | + */ | |
71 | +int drm_vm_info(struct seq_file *m, void *data) | |
72 | +{ | |
73 | + struct drm_info_node *node = (struct drm_info_node *) m->private; | |
74 | + struct drm_device *dev = node->minor->dev; | |
75 | + struct drm_map *map; | |
76 | + struct drm_map_list *r_list; | |
77 | + | |
78 | + /* Hardcoded from _DRM_FRAME_BUFFER, | |
79 | + _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and | |
80 | + _DRM_SCATTER_GATHER and _DRM_CONSISTENT */ | |
81 | + const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" }; | |
82 | + const char *type; | |
83 | + int i; | |
84 | + | |
85 | + mutex_lock(&dev->struct_mutex); | |
86 | + seq_printf(m, "slot offset size type flags address mtrr\n\n"); | |
87 | + i = 0; | |
88 | + list_for_each_entry(r_list, &dev->maplist, head) { | |
89 | + map = r_list->map; | |
90 | + if (!map) | |
91 | + continue; | |
92 | + if (map->type < 0 || map->type > 5) | |
93 | + type = "??"; | |
94 | + else | |
95 | + type = types[map->type]; | |
96 | + | |
97 | + seq_printf(m, "%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ", | |
98 | + i, | |
99 | + map->offset, | |
100 | + map->size, type, map->flags, | |
101 | + (unsigned long) r_list->user_token); | |
102 | + if (map->mtrr < 0) | |
103 | + seq_printf(m, "none\n"); | |
104 | + else | |
105 | + seq_printf(m, "%4d\n", map->mtrr); | |
106 | + i++; | |
107 | + } | |
108 | + mutex_unlock(&dev->struct_mutex); | |
109 | + return 0; | |
110 | +} | |
111 | + | |
112 | +/** | |
113 | + * Called when "/proc/dri/.../queues" is read. | |
114 | + */ | |
115 | +int drm_queues_info(struct seq_file *m, void *data) | |
116 | +{ | |
117 | + struct drm_info_node *node = (struct drm_info_node *) m->private; | |
118 | + struct drm_device *dev = node->minor->dev; | |
119 | + int i; | |
120 | + struct drm_queue *q; | |
121 | + | |
122 | + mutex_lock(&dev->struct_mutex); | |
123 | + seq_printf(m, " ctx/flags use fin" | |
124 | + " blk/rw/rwf wait flushed queued" | |
125 | + " locks\n\n"); | |
126 | + for (i = 0; i < dev->queue_count; i++) { | |
127 | + q = dev->queuelist[i]; | |
128 | + atomic_inc(&q->use_count); | |
129 | + seq_printf(m, "%5d/0x%03x %5d %5d" | |
130 | + " %5d/%c%c/%c%c%c %5Zd\n", | |
131 | + i, | |
132 | + q->flags, | |
133 | + atomic_read(&q->use_count), | |
134 | + atomic_read(&q->finalization), | |
135 | + atomic_read(&q->block_count), | |
136 | + atomic_read(&q->block_read) ? 'r' : '-', | |
137 | + atomic_read(&q->block_write) ? 'w' : '-', | |
138 | + waitqueue_active(&q->read_queue) ? 'r' : '-', | |
139 | + waitqueue_active(&q->write_queue) ? 'w' : '-', | |
140 | + waitqueue_active(&q->flush_queue) ? 'f' : '-', | |
141 | + DRM_BUFCOUNT(&q->waitlist)); | |
142 | + atomic_dec(&q->use_count); | |
143 | + } | |
144 | + mutex_unlock(&dev->struct_mutex); | |
145 | + return 0; | |
146 | +} | |
147 | + | |
148 | +/** | |
149 | + * Called when "/proc/dri/.../bufs" is read. | |
150 | + */ | |
151 | +int drm_bufs_info(struct seq_file *m, void *data) | |
152 | +{ | |
153 | + struct drm_info_node *node = (struct drm_info_node *) m->private; | |
154 | + struct drm_device *dev = node->minor->dev; | |
155 | + struct drm_device_dma *dma; | |
156 | + int i, seg_pages; | |
157 | + | |
158 | + mutex_lock(&dev->struct_mutex); | |
159 | + dma = dev->dma; | |
160 | + if (!dma) { | |
161 | + mutex_unlock(&dev->struct_mutex); | |
162 | + return 0; | |
163 | + } | |
164 | + | |
165 | + seq_printf(m, " o size count free segs pages kB\n\n"); | |
166 | + for (i = 0; i <= DRM_MAX_ORDER; i++) { | |
167 | + if (dma->bufs[i].buf_count) { | |
168 | + seg_pages = dma->bufs[i].seg_count * (1 << dma->bufs[i].page_order); | |
169 | + seq_printf(m, "%2d %8d %5d %5d %5d %5d %5ld\n", | |
170 | + i, | |
171 | + dma->bufs[i].buf_size, | |
172 | + dma->bufs[i].buf_count, | |
173 | + atomic_read(&dma->bufs[i].freelist.count), | |
174 | + dma->bufs[i].seg_count, | |
175 | + seg_pages, | |
176 | + seg_pages * PAGE_SIZE / 1024); | |
177 | + } | |
178 | + } | |
179 | + seq_printf(m, "\n"); | |
180 | + for (i = 0; i < dma->buf_count; i++) { | |
181 | + if (i && !(i % 32)) | |
182 | + seq_printf(m, "\n"); | |
183 | + seq_printf(m, " %d", dma->buflist[i]->list); | |
184 | + } | |
185 | + seq_printf(m, "\n"); | |
186 | + mutex_unlock(&dev->struct_mutex); | |
187 | + return 0; | |
188 | +} | |
189 | + | |
190 | +/** | |
191 | + * Called when "/proc/dri/.../vblank" is read. | |
192 | + */ | |
193 | +int drm_vblank_info(struct seq_file *m, void *data) | |
194 | +{ | |
195 | + struct drm_info_node *node = (struct drm_info_node *) m->private; | |
196 | + struct drm_device *dev = node->minor->dev; | |
197 | + int crtc; | |
198 | + | |
199 | + mutex_lock(&dev->struct_mutex); | |
200 | + for (crtc = 0; crtc < dev->num_crtcs; crtc++) { | |
201 | + seq_printf(m, "CRTC %d enable: %d\n", | |
202 | + crtc, atomic_read(&dev->vblank_refcount[crtc])); | |
203 | + seq_printf(m, "CRTC %d counter: %d\n", | |
204 | + crtc, drm_vblank_count(dev, crtc)); | |
205 | + seq_printf(m, "CRTC %d last wait: %d\n", | |
206 | + crtc, dev->last_vblank_wait[crtc]); | |
207 | + seq_printf(m, "CRTC %d in modeset: %d\n", | |
208 | + crtc, dev->vblank_inmodeset[crtc]); | |
209 | + } | |
210 | + mutex_unlock(&dev->struct_mutex); | |
211 | + return 0; | |
212 | +} | |
213 | + | |
214 | +/** | |
215 | + * Called when "/proc/dri/.../clients" is read. | |
216 | + * | |
217 | + */ | |
218 | +int drm_clients_info(struct seq_file *m, void *data) | |
219 | +{ | |
220 | + struct drm_info_node *node = (struct drm_info_node *) m->private; | |
221 | + struct drm_device *dev = node->minor->dev; | |
222 | + struct drm_file *priv; | |
223 | + | |
224 | + mutex_lock(&dev->struct_mutex); | |
225 | + seq_printf(m, "a dev pid uid magic ioctls\n\n"); | |
226 | + list_for_each_entry(priv, &dev->filelist, lhead) { | |
227 | + seq_printf(m, "%c %3d %5d %5d %10u %10lu\n", | |
228 | + priv->authenticated ? 'y' : 'n', | |
229 | + priv->minor->index, | |
230 | + priv->pid, | |
231 | + priv->uid, priv->magic, priv->ioctl_count); | |
232 | + } | |
233 | + mutex_unlock(&dev->struct_mutex); | |
234 | + return 0; | |
235 | +} | |
236 | + | |
237 | + | |
238 | +int drm_gem_one_name_info(int id, void *ptr, void *data) | |
239 | +{ | |
240 | + struct drm_gem_object *obj = ptr; | |
241 | + struct seq_file *m = data; | |
242 | + | |
243 | + seq_printf(m, "name %d size %zd\n", obj->name, obj->size); | |
244 | + | |
245 | + seq_printf(m, "%6d %8zd %7d %8d\n", | |
246 | + obj->name, obj->size, | |
247 | + atomic_read(&obj->handlecount.refcount), | |
248 | + atomic_read(&obj->refcount.refcount)); | |
249 | + return 0; | |
250 | +} | |
251 | + | |
252 | +int drm_gem_name_info(struct seq_file *m, void *data) | |
253 | +{ | |
254 | + struct drm_info_node *node = (struct drm_info_node *) m->private; | |
255 | + struct drm_device *dev = node->minor->dev; | |
256 | + | |
257 | + seq_printf(m, " name size handles refcount\n"); | |
258 | + idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, m); | |
259 | + return 0; | |
260 | +} | |
261 | + | |
262 | +int drm_gem_object_info(struct seq_file *m, void* data) | |
263 | +{ | |
264 | + struct drm_info_node *node = (struct drm_info_node *) m->private; | |
265 | + struct drm_device *dev = node->minor->dev; | |
266 | + | |
267 | + seq_printf(m, "%d objects\n", atomic_read(&dev->object_count)); | |
268 | + seq_printf(m, "%d object bytes\n", atomic_read(&dev->object_memory)); | |
269 | + seq_printf(m, "%d pinned\n", atomic_read(&dev->pin_count)); | |
270 | + seq_printf(m, "%d pin bytes\n", atomic_read(&dev->pin_memory)); | |
271 | + seq_printf(m, "%d gtt bytes\n", atomic_read(&dev->gtt_memory)); | |
272 | + seq_printf(m, "%d gtt total\n", dev->gtt_total); | |
273 | + return 0; | |
274 | +} | |
275 | + | |
276 | +#if DRM_DEBUG_CODE | |
277 | + | |
278 | +int drm_vma_info(struct seq_file *m, void *data) | |
279 | +{ | |
280 | + struct drm_info_node *node = (struct drm_info_node *) m->private; | |
281 | + struct drm_device *dev = node->minor->dev; | |
282 | + struct drm_vma_entry *pt; | |
283 | + struct vm_area_struct *vma; | |
284 | +#if defined(__i386__) | |
285 | + unsigned int pgprot; | |
286 | +#endif | |
287 | + | |
288 | + mutex_lock(&dev->struct_mutex); | |
289 | + seq_printf(m, "vma use count: %d, high_memory = %p, 0x%08lx\n", | |
290 | + atomic_read(&dev->vma_count), | |
291 | + high_memory, virt_to_phys(high_memory)); | |
292 | + | |
293 | + list_for_each_entry(pt, &dev->vmalist, head) { | |
294 | + vma = pt->vma; | |
295 | + if (!vma) | |
296 | + continue; | |
297 | + seq_printf(m, | |
298 | + "\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000", | |
299 | + pt->pid, vma->vm_start, vma->vm_end, | |
300 | + vma->vm_flags & VM_READ ? 'r' : '-', | |
301 | + vma->vm_flags & VM_WRITE ? 'w' : '-', | |
302 | + vma->vm_flags & VM_EXEC ? 'x' : '-', | |
303 | + vma->vm_flags & VM_MAYSHARE ? 's' : 'p', | |
304 | + vma->vm_flags & VM_LOCKED ? 'l' : '-', | |
305 | + vma->vm_flags & VM_IO ? 'i' : '-', | |
306 | + vma->vm_pgoff); | |
307 | + | |
308 | +#if defined(__i386__) | |
309 | + pgprot = pgprot_val(vma->vm_page_prot); | |
310 | + seq_printf(m, " %c%c%c%c%c%c%c%c%c", | |
311 | + pgprot & _PAGE_PRESENT ? 'p' : '-', | |
312 | + pgprot & _PAGE_RW ? 'w' : 'r', | |
313 | + pgprot & _PAGE_USER ? 'u' : 's', | |
314 | + pgprot & _PAGE_PWT ? 't' : 'b', | |
315 | + pgprot & _PAGE_PCD ? 'u' : 'c', | |
316 | + pgprot & _PAGE_ACCESSED ? 'a' : '-', | |
317 | + pgprot & _PAGE_DIRTY ? 'd' : '-', | |
318 | + pgprot & _PAGE_PSE ? 'm' : 'k', | |
319 | + pgprot & _PAGE_GLOBAL ? 'g' : 'l'); | |
320 | +#endif | |
321 | + seq_printf(m, "\n"); | |
322 | + } | |
323 | + mutex_unlock(&dev->struct_mutex); | |
324 | + return 0; | |
325 | +} | |
326 | + | |
327 | +#endif |
drivers/gpu/drm/drm_proc.c
... | ... | @@ -37,698 +37,196 @@ |
37 | 37 | * OTHER DEALINGS IN THE SOFTWARE. |
38 | 38 | */ |
39 | 39 | |
40 | +#include <linux/seq_file.h> | |
40 | 41 | #include "drmP.h" |
41 | 42 | |
42 | -static int drm_name_info(char *buf, char **start, off_t offset, | |
43 | - int request, int *eof, void *data); | |
44 | -static int drm_vm_info(char *buf, char **start, off_t offset, | |
45 | - int request, int *eof, void *data); | |
46 | -static int drm_clients_info(char *buf, char **start, off_t offset, | |
47 | - int request, int *eof, void *data); | |
48 | -static int drm_queues_info(char *buf, char **start, off_t offset, | |
49 | - int request, int *eof, void *data); | |
50 | -static int drm_bufs_info(char *buf, char **start, off_t offset, | |
51 | - int request, int *eof, void *data); | |
52 | -static int drm_vblank_info(char *buf, char **start, off_t offset, | |
53 | - int request, int *eof, void *data); | |
54 | -static int drm_gem_name_info(char *buf, char **start, off_t offset, | |
55 | - int request, int *eof, void *data); | |
56 | -static int drm_gem_object_info(char *buf, char **start, off_t offset, | |
57 | - int request, int *eof, void *data); | |
58 | -#if DRM_DEBUG_CODE | |
59 | -static int drm_vma_info(char *buf, char **start, off_t offset, | |
60 | - int request, int *eof, void *data); | |
61 | -#endif | |
62 | 43 | |
44 | +/*************************************************** | |
45 | + * Initialization, etc. | |
46 | + **************************************************/ | |
47 | + | |
63 | 48 | /** |
64 | 49 | * Proc file list. |
65 | 50 | */ |
66 | -static struct drm_proc_list { | |
67 | - const char *name; /**< file name */ | |
68 | - int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/ | |
69 | - u32 driver_features; /**< Required driver features for this entry */ | |
70 | -} drm_proc_list[] = { | |
51 | +static struct drm_info_list drm_proc_list[] = { | |
71 | 52 | {"name", drm_name_info, 0}, |
72 | - {"mem", drm_mem_info, 0}, | |
73 | 53 | {"vm", drm_vm_info, 0}, |
74 | 54 | {"clients", drm_clients_info, 0}, |
75 | 55 | {"queues", drm_queues_info, 0}, |
76 | 56 | {"bufs", drm_bufs_info, 0}, |
77 | - {"vblank", drm_vblank_info, 0}, | |
78 | 57 | {"gem_names", drm_gem_name_info, DRIVER_GEM}, |
79 | 58 | {"gem_objects", drm_gem_object_info, DRIVER_GEM}, |
80 | 59 | #if DRM_DEBUG_CODE |
81 | - {"vma", drm_vma_info}, | |
60 | + {"vma", drm_vma_info, 0}, | |
82 | 61 | #endif |
83 | 62 | }; |
84 | - | |
85 | 63 | #define DRM_PROC_ENTRIES ARRAY_SIZE(drm_proc_list) |
86 | 64 | |
65 | +static int drm_proc_open(struct inode *inode, struct file *file) | |
66 | +{ | |
67 | + struct drm_info_node* node = PDE(inode)->data; | |
68 | + | |
69 | + return single_open(file, node->info_ent->show, node); | |
70 | +} | |
71 | + | |
72 | +static const struct file_operations drm_proc_fops = { | |
73 | + .owner = THIS_MODULE, | |
74 | + .open = drm_proc_open, | |
75 | + .read = seq_read, | |
76 | + .llseek = seq_lseek, | |
77 | + .release = single_release, | |
78 | +}; | |
79 | + | |
80 | + | |
87 | 81 | /** |
88 | - * Initialize the DRI proc filesystem for a device. | |
82 | + * Initialize a given set of proc files for a device | |
89 | 83 | * |
90 | - * \param dev DRM device. | |
91 | - * \param minor device minor number. | |
84 | + * \param files The array of files to create | |
85 | + * \param count The number of files given | |
92 | 86 | * \param root DRI proc dir entry. |
93 | - * \param dev_root resulting DRI device proc dir entry. | |
94 | - * \return root entry pointer on success, or NULL on failure. | |
87 | + * \param minor device minor number | |
88 | + * \return Zero on success, non-zero on failure | |
95 | 89 | * |
96 | - * Create the DRI proc root entry "/proc/dri", the device proc root entry | |
97 | - * "/proc/dri/%minor%/", and each entry in proc_list as | |
98 | - * "/proc/dri/%minor%/%name%". | |
90 | + * Create a given set of proc files represented by an array of | |
91 | + * gdm_proc_lists in the given root directory. | |
99 | 92 | */ |
100 | -int drm_proc_init(struct drm_minor *minor, int minor_id, | |
101 | - struct proc_dir_entry *root) | |
93 | +int drm_proc_create_files(struct drm_info_list *files, int count, | |
94 | + struct proc_dir_entry *root, struct drm_minor *minor) | |
102 | 95 | { |
103 | 96 | struct drm_device *dev = minor->dev; |
104 | 97 | struct proc_dir_entry *ent; |
105 | - int i, j, ret; | |
98 | + struct drm_info_node *tmp; | |
106 | 99 | char name[64]; |
100 | + int i, ret; | |
107 | 101 | |
108 | - sprintf(name, "%d", minor_id); | |
109 | - minor->dev_root = proc_mkdir(name, root); | |
110 | - if (!minor->dev_root) { | |
111 | - DRM_ERROR("Cannot create /proc/dri/%s\n", name); | |
112 | - return -1; | |
113 | - } | |
102 | + for (i = 0; i < count; i++) { | |
103 | + u32 features = files[i].driver_features; | |
114 | 104 | |
115 | - for (i = 0; i < DRM_PROC_ENTRIES; i++) { | |
116 | - u32 features = drm_proc_list[i].driver_features; | |
117 | - | |
118 | 105 | if (features != 0 && |
119 | 106 | (dev->driver->driver_features & features) != features) |
120 | 107 | continue; |
121 | 108 | |
122 | - ent = create_proc_entry(drm_proc_list[i].name, | |
123 | - S_IFREG | S_IRUGO, minor->dev_root); | |
109 | + tmp = drm_alloc(sizeof(struct drm_info_node), _DRM_DRIVER); | |
110 | + ent = create_proc_entry(files[i].name, S_IFREG | S_IRUGO, root); | |
124 | 111 | if (!ent) { |
125 | 112 | DRM_ERROR("Cannot create /proc/dri/%s/%s\n", |
126 | - name, drm_proc_list[i].name); | |
113 | + name, files[i].name); | |
114 | + drm_free(tmp, sizeof(struct drm_info_node), | |
115 | + _DRM_DRIVER); | |
127 | 116 | ret = -1; |
128 | 117 | goto fail; |
129 | 118 | } |
130 | - ent->read_proc = drm_proc_list[i].f; | |
131 | - ent->data = minor; | |
132 | - } | |
133 | 119 | |
134 | - if (dev->driver->proc_init) { | |
135 | - ret = dev->driver->proc_init(minor); | |
136 | - if (ret) { | |
137 | - DRM_ERROR("DRM: Driver failed to initialize " | |
138 | - "/proc/dri.\n"); | |
139 | - goto fail; | |
140 | - } | |
120 | + ent->proc_fops = &drm_proc_fops; | |
121 | + ent->data = tmp; | |
122 | + tmp->minor = minor; | |
123 | + tmp->info_ent = &files[i]; | |
124 | + list_add(&(tmp->list), &(minor->proc_nodes.list)); | |
141 | 125 | } |
142 | - | |
143 | 126 | return 0; |
144 | - fail: | |
145 | 127 | |
146 | - for (j = 0; j < i; j++) | |
147 | - remove_proc_entry(drm_proc_list[i].name, | |
148 | - minor->dev_root); | |
149 | - remove_proc_entry(name, root); | |
150 | - minor->dev_root = NULL; | |
128 | +fail: | |
129 | + for (i = 0; i < count; i++) | |
130 | + remove_proc_entry(drm_proc_list[i].name, minor->proc_root); | |
151 | 131 | return ret; |
152 | 132 | } |
153 | 133 | |
154 | 134 | /** |
155 | - * Cleanup the proc filesystem resources. | |
135 | + * Initialize the DRI proc filesystem for a device | |
156 | 136 | * |
157 | - * \param minor device minor number. | |
137 | + * \param dev DRM device | |
138 | + * \param minor device minor number | |
158 | 139 | * \param root DRI proc dir entry. |
159 | - * \param dev_root DRI device proc dir entry. | |
160 | - * \return always zero. | |
140 | + * \param dev_root resulting DRI device proc dir entry. | |
141 | + * \return root entry pointer on success, or NULL on failure. | |
161 | 142 | * |
162 | - * Remove all proc entries created by proc_init(). | |
143 | + * Create the DRI proc root entry "/proc/dri", the device proc root entry | |
144 | + * "/proc/dri/%minor%/", and each entry in proc_list as | |
145 | + * "/proc/dri/%minor%/%name%". | |
163 | 146 | */ |
164 | -int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) | |
147 | +int drm_proc_init(struct drm_minor *minor, int minor_id, | |
148 | + struct proc_dir_entry *root) | |
165 | 149 | { |
166 | 150 | struct drm_device *dev = minor->dev; |
167 | - int i; | |
168 | 151 | char name[64]; |
152 | + int ret; | |
169 | 153 | |
170 | - if (!root || !minor->dev_root) | |
171 | - return 0; | |
172 | - | |
173 | - if (dev->driver->proc_cleanup) | |
174 | - dev->driver->proc_cleanup(minor); | |
175 | - | |
176 | - for (i = 0; i < DRM_PROC_ENTRIES; i++) | |
177 | - remove_proc_entry(drm_proc_list[i].name, minor->dev_root); | |
178 | - sprintf(name, "%d", minor->index); | |
179 | - remove_proc_entry(name, root); | |
180 | - | |
181 | - return 0; | |
182 | -} | |
183 | - | |
184 | -/** | |
185 | - * Called when "/proc/dri/.../name" is read. | |
186 | - * | |
187 | - * \param buf output buffer. | |
188 | - * \param start start of output data. | |
189 | - * \param offset requested start offset. | |
190 | - * \param request requested number of bytes. | |
191 | - * \param eof whether there is no more data to return. | |
192 | - * \param data private data. | |
193 | - * \return number of written bytes. | |
194 | - * | |
195 | - * Prints the device name together with the bus id if available. | |
196 | - */ | |
197 | -static int drm_name_info(char *buf, char **start, off_t offset, int request, | |
198 | - int *eof, void *data) | |
199 | -{ | |
200 | - struct drm_minor *minor = (struct drm_minor *) data; | |
201 | - struct drm_master *master = minor->master; | |
202 | - struct drm_device *dev = minor->dev; | |
203 | - int len = 0; | |
204 | - | |
205 | - if (offset > DRM_PROC_LIMIT) { | |
206 | - *eof = 1; | |
207 | - return 0; | |
154 | + INIT_LIST_HEAD(&minor->proc_nodes.list); | |
155 | + sprintf(name, "%d", minor_id); | |
156 | + minor->proc_root = proc_mkdir(name, root); | |
157 | + if (!minor->proc_root) { | |
158 | + DRM_ERROR("Cannot create /proc/dri/%s\n", name); | |
159 | + return -1; | |
208 | 160 | } |
209 | 161 | |
210 | - if (!master) | |
211 | - return 0; | |
212 | - | |
213 | - *start = &buf[offset]; | |
214 | - *eof = 0; | |
215 | - | |
216 | - if (master->unique) { | |
217 | - DRM_PROC_PRINT("%s %s %s\n", | |
218 | - dev->driver->pci_driver.name, | |
219 | - pci_name(dev->pdev), master->unique); | |
220 | - } else { | |
221 | - DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name, | |
222 | - pci_name(dev->pdev)); | |
162 | + ret = drm_proc_create_files(drm_proc_list, DRM_PROC_ENTRIES, | |
163 | + minor->proc_root, minor); | |
164 | + if (ret) { | |
165 | + remove_proc_entry(name, root); | |
166 | + minor->proc_root = NULL; | |
167 | + DRM_ERROR("Failed to create core drm proc files\n"); | |
168 | + return ret; | |
223 | 169 | } |
224 | 170 | |
225 | - if (len > request + offset) | |
226 | - return request; | |
227 | - *eof = 1; | |
228 | - return len - offset; | |
229 | -} | |
230 | - | |
231 | -/** | |
232 | - * Called when "/proc/dri/.../vm" is read. | |
233 | - * | |
234 | - * \param buf output buffer. | |
235 | - * \param start start of output data. | |
236 | - * \param offset requested start offset. | |
237 | - * \param request requested number of bytes. | |
238 | - * \param eof whether there is no more data to return. | |
239 | - * \param data private data. | |
240 | - * \return number of written bytes. | |
241 | - * | |
242 | - * Prints information about all mappings in drm_device::maplist. | |
243 | - */ | |
244 | -static int drm__vm_info(char *buf, char **start, off_t offset, int request, | |
245 | - int *eof, void *data) | |
246 | -{ | |
247 | - struct drm_minor *minor = (struct drm_minor *) data; | |
248 | - struct drm_device *dev = minor->dev; | |
249 | - int len = 0; | |
250 | - struct drm_map *map; | |
251 | - struct drm_map_list *r_list; | |
252 | - | |
253 | - /* Hardcoded from _DRM_FRAME_BUFFER, | |
254 | - _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and | |
255 | - _DRM_SCATTER_GATHER and _DRM_CONSISTENT */ | |
256 | - const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" }; | |
257 | - const char *type; | |
258 | - int i; | |
259 | - | |
260 | - if (offset > DRM_PROC_LIMIT) { | |
261 | - *eof = 1; | |
262 | - return 0; | |
263 | - } | |
264 | - | |
265 | - *start = &buf[offset]; | |
266 | - *eof = 0; | |
267 | - | |
268 | - DRM_PROC_PRINT("slot offset size type flags " | |
269 | - "address mtrr\n\n"); | |
270 | - i = 0; | |
271 | - list_for_each_entry(r_list, &dev->maplist, head) { | |
272 | - map = r_list->map; | |
273 | - if (!map) | |
274 | - continue; | |
275 | - if (map->type < 0 || map->type > 5) | |
276 | - type = "??"; | |
277 | - else | |
278 | - type = types[map->type]; | |
279 | - DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ", | |
280 | - i, | |
281 | - map->offset, | |
282 | - map->size, type, map->flags, | |
283 | - (unsigned long) r_list->user_token); | |
284 | - if (map->mtrr < 0) { | |
285 | - DRM_PROC_PRINT("none\n"); | |
286 | - } else { | |
287 | - DRM_PROC_PRINT("%4d\n", map->mtrr); | |
171 | + if (dev->driver->proc_init) { | |
172 | + ret = dev->driver->proc_init(minor); | |
173 | + if (ret) { | |
174 | + DRM_ERROR("DRM: Driver failed to initialize " | |
175 | + "/proc/dri.\n"); | |
176 | + return ret; | |
288 | 177 | } |
289 | - i++; | |
290 | 178 | } |
291 | - | |
292 | - if (len > request + offset) | |
293 | - return request; | |
294 | - *eof = 1; | |
295 | - return len - offset; | |
179 | + return 0; | |
296 | 180 | } |
297 | 181 | |
298 | -/** | |
299 | - * Simply calls _vm_info() while holding the drm_device::struct_mutex lock. | |
300 | - */ | |
301 | -static int drm_vm_info(char *buf, char **start, off_t offset, int request, | |
302 | - int *eof, void *data) | |
182 | +int drm_proc_remove_files(struct drm_info_list *files, int count, | |
183 | + struct drm_minor *minor) | |
303 | 184 | { |
304 | - struct drm_minor *minor = (struct drm_minor *) data; | |
305 | - struct drm_device *dev = minor->dev; | |
306 | - int ret; | |
307 | - | |
308 | - mutex_lock(&dev->struct_mutex); | |
309 | - ret = drm__vm_info(buf, start, offset, request, eof, data); | |
310 | - mutex_unlock(&dev->struct_mutex); | |
311 | - return ret; | |
312 | -} | |
313 | - | |
314 | -/** | |
315 | - * Called when "/proc/dri/.../queues" is read. | |
316 | - * | |
317 | - * \param buf output buffer. | |
318 | - * \param start start of output data. | |
319 | - * \param offset requested start offset. | |
320 | - * \param request requested number of bytes. | |
321 | - * \param eof whether there is no more data to return. | |
322 | - * \param data private data. | |
323 | - * \return number of written bytes. | |
324 | - */ | |
325 | -static int drm__queues_info(char *buf, char **start, off_t offset, | |
326 | - int request, int *eof, void *data) | |
327 | -{ | |
328 | - struct drm_minor *minor = (struct drm_minor *) data; | |
329 | - struct drm_device *dev = minor->dev; | |
330 | - int len = 0; | |
185 | + struct list_head *pos, *q; | |
186 | + struct drm_info_node *tmp; | |
331 | 187 | int i; |
332 | - struct drm_queue *q; | |
333 | 188 | |
334 | - if (offset > DRM_PROC_LIMIT) { | |
335 | - *eof = 1; | |
336 | - return 0; | |
189 | + for (i = 0; i < count; i++) { | |
190 | + list_for_each_safe(pos, q, &minor->proc_nodes.list) { | |
191 | + tmp = list_entry(pos, struct drm_info_node, list); | |
192 | + if (tmp->info_ent == &files[i]) { | |
193 | + remove_proc_entry(files[i].name, | |
194 | + minor->proc_root); | |
195 | + list_del(pos); | |
196 | + drm_free(tmp, sizeof(struct drm_info_node), | |
197 | + _DRM_DRIVER); | |
198 | + } | |
199 | + } | |
337 | 200 | } |
338 | - | |
339 | - *start = &buf[offset]; | |
340 | - *eof = 0; | |
341 | - | |
342 | - DRM_PROC_PRINT(" ctx/flags use fin" | |
343 | - " blk/rw/rwf wait flushed queued" | |
344 | - " locks\n\n"); | |
345 | - for (i = 0; i < dev->queue_count; i++) { | |
346 | - q = dev->queuelist[i]; | |
347 | - atomic_inc(&q->use_count); | |
348 | - DRM_PROC_PRINT_RET(atomic_dec(&q->use_count), | |
349 | - "%5d/0x%03x %5d %5d" | |
350 | - " %5d/%c%c/%c%c%c %5Zd\n", | |
351 | - i, | |
352 | - q->flags, | |
353 | - atomic_read(&q->use_count), | |
354 | - atomic_read(&q->finalization), | |
355 | - atomic_read(&q->block_count), | |
356 | - atomic_read(&q->block_read) ? 'r' : '-', | |
357 | - atomic_read(&q->block_write) ? 'w' : '-', | |
358 | - waitqueue_active(&q->read_queue) ? 'r' : '-', | |
359 | - waitqueue_active(&q-> | |
360 | - write_queue) ? 'w' : '-', | |
361 | - waitqueue_active(&q-> | |
362 | - flush_queue) ? 'f' : '-', | |
363 | - DRM_BUFCOUNT(&q->waitlist)); | |
364 | - atomic_dec(&q->use_count); | |
365 | - } | |
366 | - | |
367 | - if (len > request + offset) | |
368 | - return request; | |
369 | - *eof = 1; | |
370 | - return len - offset; | |
201 | + return 0; | |
371 | 202 | } |
372 | 203 | |
373 | 204 | /** |
374 | - * Simply calls _queues_info() while holding the drm_device::struct_mutex lock. | |
375 | - */ | |
376 | -static int drm_queues_info(char *buf, char **start, off_t offset, int request, | |
377 | - int *eof, void *data) | |
378 | -{ | |
379 | - struct drm_minor *minor = (struct drm_minor *) data; | |
380 | - struct drm_device *dev = minor->dev; | |
381 | - int ret; | |
382 | - | |
383 | - mutex_lock(&dev->struct_mutex); | |
384 | - ret = drm__queues_info(buf, start, offset, request, eof, data); | |
385 | - mutex_unlock(&dev->struct_mutex); | |
386 | - return ret; | |
387 | -} | |
388 | - | |
389 | -/** | |
390 | - * Called when "/proc/dri/.../bufs" is read. | |
205 | + * Cleanup the proc filesystem resources. | |
391 | 206 | * |
392 | - * \param buf output buffer. | |
393 | - * \param start start of output data. | |
394 | - * \param offset requested start offset. | |
395 | - * \param request requested number of bytes. | |
396 | - * \param eof whether there is no more data to return. | |
397 | - * \param data private data. | |
398 | - * \return number of written bytes. | |
399 | - */ | |
400 | -static int drm__bufs_info(char *buf, char **start, off_t offset, int request, | |
401 | - int *eof, void *data) | |
402 | -{ | |
403 | - struct drm_minor *minor = (struct drm_minor *) data; | |
404 | - struct drm_device *dev = minor->dev; | |
405 | - int len = 0; | |
406 | - struct drm_device_dma *dma = dev->dma; | |
407 | - int i; | |
408 | - | |
409 | - if (!dma || offset > DRM_PROC_LIMIT) { | |
410 | - *eof = 1; | |
411 | - return 0; | |
412 | - } | |
413 | - | |
414 | - *start = &buf[offset]; | |
415 | - *eof = 0; | |
416 | - | |
417 | - DRM_PROC_PRINT(" o size count free segs pages kB\n\n"); | |
418 | - for (i = 0; i <= DRM_MAX_ORDER; i++) { | |
419 | - if (dma->bufs[i].buf_count) | |
420 | - DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n", | |
421 | - i, | |
422 | - dma->bufs[i].buf_size, | |
423 | - dma->bufs[i].buf_count, | |
424 | - atomic_read(&dma->bufs[i] | |
425 | - .freelist.count), | |
426 | - dma->bufs[i].seg_count, | |
427 | - dma->bufs[i].seg_count | |
428 | - * (1 << dma->bufs[i].page_order), | |
429 | - (dma->bufs[i].seg_count | |
430 | - * (1 << dma->bufs[i].page_order)) | |
431 | - * PAGE_SIZE / 1024); | |
432 | - } | |
433 | - DRM_PROC_PRINT("\n"); | |
434 | - for (i = 0; i < dma->buf_count; i++) { | |
435 | - if (i && !(i % 32)) | |
436 | - DRM_PROC_PRINT("\n"); | |
437 | - DRM_PROC_PRINT(" %d", dma->buflist[i]->list); | |
438 | - } | |
439 | - DRM_PROC_PRINT("\n"); | |
440 | - | |
441 | - if (len > request + offset) | |
442 | - return request; | |
443 | - *eof = 1; | |
444 | - return len - offset; | |
445 | -} | |
446 | - | |
447 | -/** | |
448 | - * Simply calls _bufs_info() while holding the drm_device::struct_mutex lock. | |
449 | - */ | |
450 | -static int drm_bufs_info(char *buf, char **start, off_t offset, int request, | |
451 | - int *eof, void *data) | |
452 | -{ | |
453 | - struct drm_minor *minor = (struct drm_minor *) data; | |
454 | - struct drm_device *dev = minor->dev; | |
455 | - int ret; | |
456 | - | |
457 | - mutex_lock(&dev->struct_mutex); | |
458 | - ret = drm__bufs_info(buf, start, offset, request, eof, data); | |
459 | - mutex_unlock(&dev->struct_mutex); | |
460 | - return ret; | |
461 | -} | |
462 | - | |
463 | -/** | |
464 | - * Called when "/proc/dri/.../vblank" is read. | |
207 | + * \param minor device minor number. | |
208 | + * \param root DRI proc dir entry. | |
209 | + * \param dev_root DRI device proc dir entry. | |
210 | + * \return always zero. | |
465 | 211 | * |
466 | - * \param buf output buffer. | |
467 | - * \param start start of output data. | |
468 | - * \param offset requested start offset. | |
469 | - * \param request requested number of bytes. | |
470 | - * \param eof whether there is no more data to return. | |
471 | - * \param data private data. | |
472 | - * \return number of written bytes. | |
212 | + * Remove all proc entries created by proc_init(). | |
473 | 213 | */ |
474 | -static int drm__vblank_info(char *buf, char **start, off_t offset, int request, | |
475 | - int *eof, void *data) | |
214 | +int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) | |
476 | 215 | { |
477 | - struct drm_minor *minor = (struct drm_minor *) data; | |
478 | 216 | struct drm_device *dev = minor->dev; |
479 | - int len = 0; | |
480 | - int crtc; | |
217 | + char name[64]; | |
481 | 218 | |
482 | - if (offset > DRM_PROC_LIMIT) { | |
483 | - *eof = 1; | |
219 | + if (!root || !minor->proc_root) | |
484 | 220 | return 0; |
485 | - } | |
486 | 221 | |
487 | - *start = &buf[offset]; | |
488 | - *eof = 0; | |
222 | + if (dev->driver->proc_cleanup) | |
223 | + dev->driver->proc_cleanup(minor); | |
489 | 224 | |
490 | - for (crtc = 0; crtc < dev->num_crtcs; crtc++) { | |
491 | - DRM_PROC_PRINT("CRTC %d enable: %d\n", | |
492 | - crtc, atomic_read(&dev->vblank_refcount[crtc])); | |
493 | - DRM_PROC_PRINT("CRTC %d counter: %d\n", | |
494 | - crtc, drm_vblank_count(dev, crtc)); | |
495 | - DRM_PROC_PRINT("CRTC %d last wait: %d\n", | |
496 | - crtc, dev->last_vblank_wait[crtc]); | |
497 | - DRM_PROC_PRINT("CRTC %d in modeset: %d\n", | |
498 | - crtc, dev->vblank_inmodeset[crtc]); | |
499 | - } | |
225 | + drm_proc_remove_files(drm_proc_list, DRM_PROC_ENTRIES, minor); | |
500 | 226 | |
501 | - if (len > request + offset) | |
502 | - return request; | |
503 | - *eof = 1; | |
504 | - return len - offset; | |
505 | -} | |
227 | + sprintf(name, "%d", minor->index); | |
228 | + remove_proc_entry(name, root); | |
506 | 229 | |
507 | -/** | |
508 | - * Simply calls _vblank_info() while holding the drm_device::struct_mutex lock. | |
509 | - */ | |
510 | -static int drm_vblank_info(char *buf, char **start, off_t offset, int request, | |
511 | - int *eof, void *data) | |
512 | -{ | |
513 | - struct drm_minor *minor = (struct drm_minor *) data; | |
514 | - struct drm_device *dev = minor->dev; | |
515 | - int ret; | |
516 | - | |
517 | - mutex_lock(&dev->struct_mutex); | |
518 | - ret = drm__vblank_info(buf, start, offset, request, eof, data); | |
519 | - mutex_unlock(&dev->struct_mutex); | |
520 | - return ret; | |
521 | -} | |
522 | - | |
523 | -/** | |
524 | - * Called when "/proc/dri/.../clients" is read. | |
525 | - * | |
526 | - * \param buf output buffer. | |
527 | - * \param start start of output data. | |
528 | - * \param offset requested start offset. | |
529 | - * \param request requested number of bytes. | |
530 | - * \param eof whether there is no more data to return. | |
531 | - * \param data private data. | |
532 | - * \return number of written bytes. | |
533 | - */ | |
534 | -static int drm__clients_info(char *buf, char **start, off_t offset, | |
535 | - int request, int *eof, void *data) | |
536 | -{ | |
537 | - struct drm_minor *minor = (struct drm_minor *) data; | |
538 | - struct drm_device *dev = minor->dev; | |
539 | - int len = 0; | |
540 | - struct drm_file *priv; | |
541 | - | |
542 | - if (offset > DRM_PROC_LIMIT) { | |
543 | - *eof = 1; | |
544 | - return 0; | |
545 | - } | |
546 | - | |
547 | - *start = &buf[offset]; | |
548 | - *eof = 0; | |
549 | - | |
550 | - DRM_PROC_PRINT("a dev pid uid magic ioctls\n\n"); | |
551 | - list_for_each_entry(priv, &dev->filelist, lhead) { | |
552 | - DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n", | |
553 | - priv->authenticated ? 'y' : 'n', | |
554 | - priv->minor->index, | |
555 | - priv->pid, | |
556 | - priv->uid, priv->magic, priv->ioctl_count); | |
557 | - } | |
558 | - | |
559 | - if (len > request + offset) | |
560 | - return request; | |
561 | - *eof = 1; | |
562 | - return len - offset; | |
563 | -} | |
564 | - | |
565 | -/** | |
566 | - * Simply calls _clients_info() while holding the drm_device::struct_mutex lock. | |
567 | - */ | |
568 | -static int drm_clients_info(char *buf, char **start, off_t offset, | |
569 | - int request, int *eof, void *data) | |
570 | -{ | |
571 | - struct drm_minor *minor = (struct drm_minor *) data; | |
572 | - struct drm_device *dev = minor->dev; | |
573 | - int ret; | |
574 | - | |
575 | - mutex_lock(&dev->struct_mutex); | |
576 | - ret = drm__clients_info(buf, start, offset, request, eof, data); | |
577 | - mutex_unlock(&dev->struct_mutex); | |
578 | - return ret; | |
579 | -} | |
580 | - | |
581 | -struct drm_gem_name_info_data { | |
582 | - int len; | |
583 | - char *buf; | |
584 | - int eof; | |
585 | -}; | |
586 | - | |
587 | -static int drm_gem_one_name_info(int id, void *ptr, void *data) | |
588 | -{ | |
589 | - struct drm_gem_object *obj = ptr; | |
590 | - struct drm_gem_name_info_data *nid = data; | |
591 | - | |
592 | - DRM_INFO("name %d size %zd\n", obj->name, obj->size); | |
593 | - if (nid->eof) | |
594 | - return 0; | |
595 | - | |
596 | - nid->len += sprintf(&nid->buf[nid->len], | |
597 | - "%6d %8zd %7d %8d\n", | |
598 | - obj->name, obj->size, | |
599 | - atomic_read(&obj->handlecount.refcount), | |
600 | - atomic_read(&obj->refcount.refcount)); | |
601 | - if (nid->len > DRM_PROC_LIMIT) { | |
602 | - nid->eof = 1; | |
603 | - return 0; | |
604 | - } | |
605 | 230 | return 0; |
606 | 231 | } |
607 | - | |
608 | -static int drm_gem_name_info(char *buf, char **start, off_t offset, | |
609 | - int request, int *eof, void *data) | |
610 | -{ | |
611 | - struct drm_minor *minor = (struct drm_minor *) data; | |
612 | - struct drm_device *dev = minor->dev; | |
613 | - struct drm_gem_name_info_data nid; | |
614 | - | |
615 | - if (offset > DRM_PROC_LIMIT) { | |
616 | - *eof = 1; | |
617 | - return 0; | |
618 | - } | |
619 | - | |
620 | - nid.len = sprintf(buf, " name size handles refcount\n"); | |
621 | - nid.buf = buf; | |
622 | - nid.eof = 0; | |
623 | - idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, &nid); | |
624 | - | |
625 | - *start = &buf[offset]; | |
626 | - *eof = 0; | |
627 | - if (nid.len > request + offset) | |
628 | - return request; | |
629 | - *eof = 1; | |
630 | - return nid.len - offset; | |
631 | -} | |
632 | - | |
633 | -static int drm_gem_object_info(char *buf, char **start, off_t offset, | |
634 | - int request, int *eof, void *data) | |
635 | -{ | |
636 | - struct drm_minor *minor = (struct drm_minor *) data; | |
637 | - struct drm_device *dev = minor->dev; | |
638 | - int len = 0; | |
639 | - | |
640 | - if (offset > DRM_PROC_LIMIT) { | |
641 | - *eof = 1; | |
642 | - return 0; | |
643 | - } | |
644 | - | |
645 | - *start = &buf[offset]; | |
646 | - *eof = 0; | |
647 | - DRM_PROC_PRINT("%d objects\n", atomic_read(&dev->object_count)); | |
648 | - DRM_PROC_PRINT("%d object bytes\n", atomic_read(&dev->object_memory)); | |
649 | - DRM_PROC_PRINT("%d pinned\n", atomic_read(&dev->pin_count)); | |
650 | - DRM_PROC_PRINT("%d pin bytes\n", atomic_read(&dev->pin_memory)); | |
651 | - DRM_PROC_PRINT("%d gtt bytes\n", atomic_read(&dev->gtt_memory)); | |
652 | - DRM_PROC_PRINT("%d gtt total\n", dev->gtt_total); | |
653 | - if (len > request + offset) | |
654 | - return request; | |
655 | - *eof = 1; | |
656 | - return len - offset; | |
657 | -} | |
658 | - | |
659 | -#if DRM_DEBUG_CODE | |
660 | - | |
661 | -static int drm__vma_info(char *buf, char **start, off_t offset, int request, | |
662 | - int *eof, void *data) | |
663 | -{ | |
664 | - struct drm_minor *minor = (struct drm_minor *) data; | |
665 | - struct drm_device *dev = minor->dev; | |
666 | - int len = 0; | |
667 | - struct drm_vma_entry *pt; | |
668 | - struct vm_area_struct *vma; | |
669 | -#if defined(__i386__) | |
670 | - unsigned int pgprot; | |
671 | -#endif | |
672 | - | |
673 | - if (offset > DRM_PROC_LIMIT) { | |
674 | - *eof = 1; | |
675 | - return 0; | |
676 | - } | |
677 | - | |
678 | - *start = &buf[offset]; | |
679 | - *eof = 0; | |
680 | - | |
681 | - DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n", | |
682 | - atomic_read(&dev->vma_count), | |
683 | - high_memory, virt_to_phys(high_memory)); | |
684 | - list_for_each_entry(pt, &dev->vmalist, head) { | |
685 | - if (!(vma = pt->vma)) | |
686 | - continue; | |
687 | - DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000", | |
688 | - pt->pid, | |
689 | - vma->vm_start, | |
690 | - vma->vm_end, | |
691 | - vma->vm_flags & VM_READ ? 'r' : '-', | |
692 | - vma->vm_flags & VM_WRITE ? 'w' : '-', | |
693 | - vma->vm_flags & VM_EXEC ? 'x' : '-', | |
694 | - vma->vm_flags & VM_MAYSHARE ? 's' : 'p', | |
695 | - vma->vm_flags & VM_LOCKED ? 'l' : '-', | |
696 | - vma->vm_flags & VM_IO ? 'i' : '-', | |
697 | - vma->vm_pgoff); | |
698 | - | |
699 | -#if defined(__i386__) | |
700 | - pgprot = pgprot_val(vma->vm_page_prot); | |
701 | - DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c", | |
702 | - pgprot & _PAGE_PRESENT ? 'p' : '-', | |
703 | - pgprot & _PAGE_RW ? 'w' : 'r', | |
704 | - pgprot & _PAGE_USER ? 'u' : 's', | |
705 | - pgprot & _PAGE_PWT ? 't' : 'b', | |
706 | - pgprot & _PAGE_PCD ? 'u' : 'c', | |
707 | - pgprot & _PAGE_ACCESSED ? 'a' : '-', | |
708 | - pgprot & _PAGE_DIRTY ? 'd' : '-', | |
709 | - pgprot & _PAGE_PSE ? 'm' : 'k', | |
710 | - pgprot & _PAGE_GLOBAL ? 'g' : 'l'); | |
711 | -#endif | |
712 | - DRM_PROC_PRINT("\n"); | |
713 | - } | |
714 | - | |
715 | - if (len > request + offset) | |
716 | - return request; | |
717 | - *eof = 1; | |
718 | - return len - offset; | |
719 | -} | |
720 | - | |
721 | -static int drm_vma_info(char *buf, char **start, off_t offset, int request, | |
722 | - int *eof, void *data) | |
723 | -{ | |
724 | - struct drm_minor *minor = (struct drm_minor *) data; | |
725 | - struct drm_device *dev = minor->dev; | |
726 | - int ret; | |
727 | - | |
728 | - mutex_lock(&dev->struct_mutex); | |
729 | - ret = drm__vma_info(buf, start, offset, request, eof, data); | |
730 | - mutex_unlock(&dev->struct_mutex); | |
731 | - return ret; | |
732 | -} | |
733 | -#endif |
drivers/gpu/drm/drm_stub.c
... | ... | @@ -50,6 +50,7 @@ |
50 | 50 | |
51 | 51 | struct class *drm_class; |
52 | 52 | struct proc_dir_entry *drm_proc_root; |
53 | +struct dentry *drm_debugfs_root; | |
53 | 54 | |
54 | 55 | static int drm_minor_get_id(struct drm_device *dev, int type) |
55 | 56 | { |
56 | 57 | |
... | ... | @@ -313,8 +314,16 @@ |
313 | 314 | goto err_mem; |
314 | 315 | } |
315 | 316 | } else |
316 | - new_minor->dev_root = NULL; | |
317 | + new_minor->proc_root = NULL; | |
317 | 318 | |
319 | +#if defined(CONFIG_DEBUG_FS) | |
320 | + ret = drm_debugfs_init(new_minor, minor_id, drm_debugfs_root); | |
321 | + if (ret) { | |
322 | + DRM_ERROR("DRM: Failed to initialize /debugfs/dri.\n"); | |
323 | + goto err_g2; | |
324 | + } | |
325 | +#endif | |
326 | + | |
318 | 327 | ret = drm_sysfs_device_add(new_minor); |
319 | 328 | if (ret) { |
320 | 329 | printk(KERN_ERR |
... | ... | @@ -451,6 +460,10 @@ |
451 | 460 | |
452 | 461 | if (minor->type == DRM_MINOR_LEGACY) |
453 | 462 | drm_proc_cleanup(minor, drm_proc_root); |
463 | +#if defined(CONFIG_DEBUG_FS) | |
464 | + drm_debugfs_cleanup(minor); | |
465 | +#endif | |
466 | + | |
454 | 467 | drm_sysfs_device_remove(minor); |
455 | 468 | |
456 | 469 | idr_remove(&drm_minors_idr, minor->index); |
include/drm/drmP.h
... | ... | @@ -758,6 +758,8 @@ |
758 | 758 | |
759 | 759 | int (*proc_init)(struct drm_minor *minor); |
760 | 760 | void (*proc_cleanup)(struct drm_minor *minor); |
761 | + int (*debugfs_init)(struct drm_minor *minor); | |
762 | + void (*debugfs_cleanup)(struct drm_minor *minor); | |
761 | 763 | |
762 | 764 | /** |
763 | 765 | * Driver-specific constructor for drm_gem_objects, to set up |
764 | 766 | |
... | ... | @@ -793,7 +795,49 @@ |
793 | 795 | #define DRM_MINOR_CONTROL 2 |
794 | 796 | #define DRM_MINOR_RENDER 3 |
795 | 797 | |
798 | + | |
796 | 799 | /** |
800 | + * debugfs node list. This structure represents a debugfs file to | |
801 | + * be created by the drm core | |
802 | + */ | |
803 | +struct drm_debugfs_list { | |
804 | + const char *name; /** file name */ | |
805 | + int (*show)(struct seq_file*, void*); /** show callback */ | |
806 | + u32 driver_features; /**< Required driver features for this entry */ | |
807 | +}; | |
808 | + | |
809 | +/** | |
810 | + * debugfs node structure. This structure represents a debugfs file. | |
811 | + */ | |
812 | +struct drm_debugfs_node { | |
813 | + struct list_head list; | |
814 | + struct drm_minor *minor; | |
815 | + struct drm_debugfs_list *debugfs_ent; | |
816 | + struct dentry *dent; | |
817 | +}; | |
818 | + | |
819 | +/** | |
820 | + * Info file list entry. This structure represents a debugfs or proc file to | |
821 | + * be created by the drm core | |
822 | + */ | |
823 | +struct drm_info_list { | |
824 | + const char *name; /** file name */ | |
825 | + int (*show)(struct seq_file*, void*); /** show callback */ | |
826 | + u32 driver_features; /**< Required driver features for this entry */ | |
827 | + void *data; | |
828 | +}; | |
829 | + | |
830 | +/** | |
831 | + * debugfs node structure. This structure represents a debugfs file. | |
832 | + */ | |
833 | +struct drm_info_node { | |
834 | + struct list_head list; | |
835 | + struct drm_minor *minor; | |
836 | + struct drm_info_list *info_ent; | |
837 | + struct dentry *dent; | |
838 | +}; | |
839 | + | |
840 | +/** | |
797 | 841 | * DRM minor structure. This structure represents a drm minor number. |
798 | 842 | */ |
799 | 843 | struct drm_minor { |
... | ... | @@ -802,7 +846,12 @@ |
802 | 846 | dev_t device; /**< Device number for mknod */ |
803 | 847 | struct device kdev; /**< Linux device */ |
804 | 848 | struct drm_device *dev; |
805 | - struct proc_dir_entry *dev_root; /**< proc directory entry */ | |
849 | + | |
850 | + struct proc_dir_entry *proc_root; /**< proc directory entry */ | |
851 | + struct drm_info_node proc_nodes; | |
852 | + struct dentry *debugfs_root; | |
853 | + struct drm_info_node debugfs_nodes; | |
854 | + | |
806 | 855 | struct drm_master *master; /* currently active master for this node */ |
807 | 856 | struct list_head master_list; |
808 | 857 | struct drm_mode_group mode_group; |
... | ... | @@ -1258,6 +1307,7 @@ |
1258 | 1307 | |
1259 | 1308 | extern struct class *drm_class; |
1260 | 1309 | extern struct proc_dir_entry *drm_proc_root; |
1310 | +extern struct dentry *drm_debugfs_root; | |
1261 | 1311 | |
1262 | 1312 | extern struct idr drm_minors_idr; |
1263 | 1313 | |
... | ... | @@ -1267,6 +1317,31 @@ |
1267 | 1317 | extern int drm_proc_init(struct drm_minor *minor, int minor_id, |
1268 | 1318 | struct proc_dir_entry *root); |
1269 | 1319 | extern int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root); |
1320 | + | |
1321 | + /* Debugfs support */ | |
1322 | +#if defined(CONFIG_DEBUG_FS) | |
1323 | +extern int drm_debugfs_init(struct drm_minor *minor, int minor_id, | |
1324 | + struct dentry *root); | |
1325 | +extern int drm_debugfs_create_files(struct drm_info_list *files, int count, | |
1326 | + struct dentry *root, struct drm_minor *minor); | |
1327 | +extern int drm_debugfs_remove_files(struct drm_info_list *files, int count, | |
1328 | + struct drm_minor *minor); | |
1329 | +extern int drm_debugfs_cleanup(struct drm_minor *minor); | |
1330 | +#endif | |
1331 | + | |
1332 | + /* Info file support */ | |
1333 | +extern int drm_name_info(struct seq_file *m, void *data); | |
1334 | +extern int drm_vm_info(struct seq_file *m, void *data); | |
1335 | +extern int drm_queues_info(struct seq_file *m, void *data); | |
1336 | +extern int drm_bufs_info(struct seq_file *m, void *data); | |
1337 | +extern int drm_vblank_info(struct seq_file *m, void *data); | |
1338 | +extern int drm_clients_info(struct seq_file *m, void* data); | |
1339 | +extern int drm_gem_name_info(struct seq_file *m, void *data); | |
1340 | +extern int drm_gem_object_info(struct seq_file *m, void* data); | |
1341 | + | |
1342 | +#if DRM_DEBUG_CODE | |
1343 | +extern int drm_vma_info(struct seq_file *m, void *data); | |
1344 | +#endif | |
1270 | 1345 | |
1271 | 1346 | /* Scatter Gather Support (drm_scatter.h) */ |
1272 | 1347 | extern void drm_sg_cleanup(struct drm_sg_mem * entry); |