Merge comment updates from DRI CVS tree.
[linux-2.6/history.git] / drivers / char / drm / drm_proc.h
blob2e607ca367300c1d9eae4e03f44f310e05128ade
1 /**
2 * \file drm_proc.h
3 * /proc support for DRM
5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
6 * \author Gareth Hughes <gareth@valinux.com>
8 * \par Acknowledgements:
9 * Matthew J Sottek <matthew.j.sottek@intel.com> sent in a patch to fix
10 * the problem with the proc files not outputting all their information.
14 * Created: Mon Jan 11 09:48:47 1999 by faith@valinux.com
16 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
17 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
18 * All Rights Reserved.
20 * Permission is hereby granted, free of charge, to any person obtaining a
21 * copy of this software and associated documentation files (the "Software"),
22 * to deal in the Software without restriction, including without limitation
23 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
24 * and/or sell copies of the Software, and to permit persons to whom the
25 * Software is furnished to do so, subject to the following conditions:
27 * The above copyright notice and this permission notice (including the next
28 * paragraph) shall be included in all copies or substantial portions of the
29 * Software.
31 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
32 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
33 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
34 * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
35 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
36 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
37 * OTHER DEALINGS IN THE SOFTWARE.
40 #include "drmP.h"
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 #if DRM_DEBUG_CODE
53 static int DRM(vma_info)(char *buf, char **start, off_t offset,
54 int request, int *eof, void *data);
55 #endif
57 /**
58 * Proc file list.
60 struct drm_proc_list {
61 const char *name; /**< file name */
62 int (*f)(char *, char **, off_t, int, int *, void *); /**< proc callback*/
63 } DRM(proc_list)[] = {
64 { "name", DRM(name_info) },
65 { "mem", DRM(mem_info) },
66 { "vm", DRM(vm_info) },
67 { "clients", DRM(clients_info) },
68 { "queues", DRM(queues_info) },
69 { "bufs", DRM(bufs_info) },
70 #if DRM_DEBUG_CODE
71 { "vma", DRM(vma_info) },
72 #endif
74 #define DRM_PROC_ENTRIES (sizeof(DRM(proc_list))/sizeof(DRM(proc_list)[0]))
76 /**
77 * Initialize the DRI proc filesystem for a device.
79 * \param dev DRM device.
80 * \param minor device minor number.
81 * \param root DRI proc dir entry.
82 * \param dev_root resulting DRI device proc dir entry.
83 * \return root entry pointer on success, or NULL on failure.
85 * Create the DRI proc root entry "/proc/dri", the device proc root entry
86 * "/proc/dri/%minor%/", and each entry in proc_list as
87 * "/proc/dri/%minor%/%name%".
89 struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor,
90 struct proc_dir_entry *root,
91 struct proc_dir_entry **dev_root)
93 struct proc_dir_entry *ent;
94 int i, j;
95 char name[64];
97 if (!minor) root = create_proc_entry("dri", S_IFDIR, NULL);
98 if (!root) {
99 DRM_ERROR("Cannot create /proc/dri\n");
100 return NULL;
103 sprintf(name, "%d", minor);
104 *dev_root = create_proc_entry(name, S_IFDIR, root);
105 if (!*dev_root) {
106 DRM_ERROR("Cannot create /proc/dri/%s\n", name);
107 return NULL;
110 for (i = 0; i < DRM_PROC_ENTRIES; i++) {
111 ent = create_proc_entry(DRM(proc_list)[i].name,
112 S_IFREG|S_IRUGO, *dev_root);
113 if (!ent) {
114 DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
115 name, DRM(proc_list)[i].name);
116 for (j = 0; j < i; j++)
117 remove_proc_entry(DRM(proc_list)[i].name,
118 *dev_root);
119 remove_proc_entry(name, root);
120 if (!minor) remove_proc_entry("dri", NULL);
121 return NULL;
123 ent->read_proc = DRM(proc_list)[i].f;
124 ent->data = dev;
127 return root;
132 * Cleanup the proc filesystem resources.
134 * \param minor device minor number.
135 * \param root DRI proc dir entry.
136 * \param dev_root DRI device proc dir entry.
137 * \return always zero.
139 * Remove all proc entries created by proc_init().
141 int DRM(proc_cleanup)(int minor, struct proc_dir_entry *root,
142 struct proc_dir_entry *dev_root)
144 int i;
145 char name[64];
147 if (!root || !dev_root) return 0;
149 for (i = 0; i < DRM_PROC_ENTRIES; i++)
150 remove_proc_entry(DRM(proc_list)[i].name, dev_root);
151 sprintf(name, "%d", minor);
152 remove_proc_entry(name, root);
153 if (!minor) remove_proc_entry("dri", NULL);
155 return 0;
159 * Called when "/proc/dri/.../name" is read.
161 * \param buf output buffer.
162 * \param start start of output data.
163 * \param offset requested start offset.
164 * \param request requested number of bytes.
165 * \param eof whether there is no more data to return.
166 * \param data private data.
167 * \return number of written bytes.
169 * Prints the device name together with the bus id if available.
171 static int DRM(name_info)(char *buf, char **start, off_t offset, int request,
172 int *eof, void *data)
174 drm_device_t *dev = (drm_device_t *)data;
175 int len = 0;
177 if (offset > DRM_PROC_LIMIT) {
178 *eof = 1;
179 return 0;
182 *start = &buf[offset];
183 *eof = 0;
185 if (dev->unique) {
186 DRM_PROC_PRINT("%s 0x%lx %s\n",
187 dev->name, (long)dev->device, dev->unique);
188 } else {
189 DRM_PROC_PRINT("%s 0x%lx\n", dev->name, (long)dev->device);
192 if (len > request + offset) return request;
193 *eof = 1;
194 return len - offset;
198 * Called when "/proc/dri/.../vm" is read.
200 * \param buf output buffer.
201 * \param start start of output data.
202 * \param offset requested start offset.
203 * \param request requested number of bytes.
204 * \param eof whether there is no more data to return.
205 * \param data private data.
206 * \return number of written bytes.
208 * Prints information about all mappings in drm_device::maplist.
210 static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
211 int *eof, void *data)
213 drm_device_t *dev = (drm_device_t *)data;
214 int len = 0;
215 drm_map_t *map;
216 drm_map_list_t *r_list;
217 struct list_head *list;
219 /* Hardcoded from _DRM_FRAME_BUFFER,
220 _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
221 _DRM_SCATTER_GATHER. */
222 const char *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
223 const char *type;
224 int i;
226 if (offset > DRM_PROC_LIMIT) {
227 *eof = 1;
228 return 0;
231 *start = &buf[offset];
232 *eof = 0;
234 DRM_PROC_PRINT("slot offset size type flags "
235 "address mtrr\n\n");
236 i = 0;
237 if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) {
238 r_list = list_entry(list, drm_map_list_t, head);
239 map = r_list->map;
240 if(!map) continue;
241 if (map->type < 0 || map->type > 4) type = "??";
242 else type = types[map->type];
243 DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
245 map->offset,
246 map->size,
247 type,
248 map->flags,
249 (unsigned long)map->handle);
250 if (map->mtrr < 0) {
251 DRM_PROC_PRINT("none\n");
252 } else {
253 DRM_PROC_PRINT("%4d\n", map->mtrr);
255 i++;
258 if (len > request + offset) return request;
259 *eof = 1;
260 return len - offset;
264 * Simply calls _vm_info() while holding the drm_device::struct_sem lock.
266 static int DRM(vm_info)(char *buf, char **start, off_t offset, int request,
267 int *eof, void *data)
269 drm_device_t *dev = (drm_device_t *)data;
270 int ret;
272 down(&dev->struct_sem);
273 ret = DRM(_vm_info)(buf, start, offset, request, eof, data);
274 up(&dev->struct_sem);
275 return ret;
279 * Called when "/proc/dri/.../queues" is read.
281 * \param buf output buffer.
282 * \param start start of output data.
283 * \param offset requested start offset.
284 * \param request requested number of bytes.
285 * \param eof whether there is no more data to return.
286 * \param data private data.
287 * \return number of written bytes.
289 static int DRM(_queues_info)(char *buf, char **start, off_t offset,
290 int request, int *eof, void *data)
292 drm_device_t *dev = (drm_device_t *)data;
293 int len = 0;
294 int i;
295 drm_queue_t *q;
297 if (offset > DRM_PROC_LIMIT) {
298 *eof = 1;
299 return 0;
302 *start = &buf[offset];
303 *eof = 0;
305 DRM_PROC_PRINT(" ctx/flags use fin"
306 " blk/rw/rwf wait flushed queued"
307 " locks\n\n");
308 for (i = 0; i < dev->queue_count; i++) {
309 q = dev->queuelist[i];
310 atomic_inc(&q->use_count);
311 DRM_PROC_PRINT_RET(atomic_dec(&q->use_count),
312 "%5d/0x%03x %5d %5d"
313 " %5d/%c%c/%c%c%c %5Zd\n",
315 q->flags,
316 atomic_read(&q->use_count),
317 atomic_read(&q->finalization),
318 atomic_read(&q->block_count),
319 atomic_read(&q->block_read) ? 'r' : '-',
320 atomic_read(&q->block_write) ? 'w' : '-',
321 waitqueue_active(&q->read_queue) ? 'r':'-',
322 waitqueue_active(&q->write_queue) ? 'w':'-',
323 waitqueue_active(&q->flush_queue) ? 'f':'-',
324 DRM_BUFCOUNT(&q->waitlist));
325 atomic_dec(&q->use_count);
328 if (len > request + offset) return request;
329 *eof = 1;
330 return len - offset;
334 * Simply calls _queues_info() while holding the drm_device::struct_sem lock.
336 static int DRM(queues_info)(char *buf, char **start, off_t offset, int request,
337 int *eof, void *data)
339 drm_device_t *dev = (drm_device_t *)data;
340 int ret;
342 down(&dev->struct_sem);
343 ret = DRM(_queues_info)(buf, start, offset, request, eof, data);
344 up(&dev->struct_sem);
345 return ret;
349 * Called when "/proc/dri/.../bufs" is read.
351 * \param buf output buffer.
352 * \param start start of output data.
353 * \param offset requested start offset.
354 * \param request requested number of bytes.
355 * \param eof whether there is no more data to return.
356 * \param data private data.
357 * \return number of written bytes.
359 static int DRM(_bufs_info)(char *buf, char **start, off_t offset, int request,
360 int *eof, void *data)
362 drm_device_t *dev = (drm_device_t *)data;
363 int len = 0;
364 drm_device_dma_t *dma = dev->dma;
365 int i;
367 if (!dma || offset > DRM_PROC_LIMIT) {
368 *eof = 1;
369 return 0;
372 *start = &buf[offset];
373 *eof = 0;
375 DRM_PROC_PRINT(" o size count free segs pages kB\n\n");
376 for (i = 0; i <= DRM_MAX_ORDER; i++) {
377 if (dma->bufs[i].buf_count)
378 DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n",
380 dma->bufs[i].buf_size,
381 dma->bufs[i].buf_count,
382 atomic_read(&dma->bufs[i]
383 .freelist.count),
384 dma->bufs[i].seg_count,
385 dma->bufs[i].seg_count
386 *(1 << dma->bufs[i].page_order),
387 (dma->bufs[i].seg_count
388 * (1 << dma->bufs[i].page_order))
389 * PAGE_SIZE / 1024);
391 DRM_PROC_PRINT("\n");
392 for (i = 0; i < dma->buf_count; i++) {
393 if (i && !(i%32)) DRM_PROC_PRINT("\n");
394 DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
396 DRM_PROC_PRINT("\n");
398 if (len > request + offset) return request;
399 *eof = 1;
400 return len - offset;
404 * Simply calls _bufs_info() while holding the drm_device::struct_sem lock.
406 static int DRM(bufs_info)(char *buf, char **start, off_t offset, int request,
407 int *eof, void *data)
409 drm_device_t *dev = (drm_device_t *)data;
410 int ret;
412 down(&dev->struct_sem);
413 ret = DRM(_bufs_info)(buf, start, offset, request, eof, data);
414 up(&dev->struct_sem);
415 return ret;
419 * Called when "/proc/dri/.../clients" is read.
421 * \param buf output buffer.
422 * \param start start of output data.
423 * \param offset requested start offset.
424 * \param request requested number of bytes.
425 * \param eof whether there is no more data to return.
426 * \param data private data.
427 * \return number of written bytes.
429 static int DRM(_clients_info)(char *buf, char **start, off_t offset,
430 int request, int *eof, void *data)
432 drm_device_t *dev = (drm_device_t *)data;
433 int len = 0;
434 drm_file_t *priv;
436 if (offset > DRM_PROC_LIMIT) {
437 *eof = 1;
438 return 0;
441 *start = &buf[offset];
442 *eof = 0;
444 DRM_PROC_PRINT("a dev pid uid magic ioctls\n\n");
445 for (priv = dev->file_first; priv; priv = priv->next) {
446 DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
447 priv->authenticated ? 'y' : 'n',
448 priv->minor,
449 priv->pid,
450 priv->uid,
451 priv->magic,
452 priv->ioctl_count);
455 if (len > request + offset) return request;
456 *eof = 1;
457 return len - offset;
461 * Simply calls _clients_info() while holding the drm_device::struct_sem lock.
463 static int DRM(clients_info)(char *buf, char **start, off_t offset,
464 int request, int *eof, void *data)
466 drm_device_t *dev = (drm_device_t *)data;
467 int ret;
469 down(&dev->struct_sem);
470 ret = DRM(_clients_info)(buf, start, offset, request, eof, data);
471 up(&dev->struct_sem);
472 return ret;
475 #if DRM_DEBUG_CODE
477 static int DRM(_vma_info)(char *buf, char **start, off_t offset, int request,
478 int *eof, void *data)
480 drm_device_t *dev = (drm_device_t *)data;
481 int len = 0;
482 drm_vma_entry_t *pt;
483 struct vm_area_struct *vma;
484 #if defined(__i386__)
485 unsigned int pgprot;
486 #endif
488 if (offset > DRM_PROC_LIMIT) {
489 *eof = 1;
490 return 0;
493 *start = &buf[offset];
494 *eof = 0;
496 DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
497 atomic_read(&dev->vma_count),
498 high_memory, virt_to_phys(high_memory));
499 for (pt = dev->vmalist; pt; pt = pt->next) {
500 if (!(vma = pt->vma)) continue;
501 DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
502 pt->pid,
503 vma->vm_start,
504 vma->vm_end,
505 vma->vm_flags & VM_READ ? 'r' : '-',
506 vma->vm_flags & VM_WRITE ? 'w' : '-',
507 vma->vm_flags & VM_EXEC ? 'x' : '-',
508 vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
509 vma->vm_flags & VM_LOCKED ? 'l' : '-',
510 vma->vm_flags & VM_IO ? 'i' : '-',
511 VM_OFFSET(vma));
513 #if defined(__i386__)
514 pgprot = pgprot_val(vma->vm_page_prot);
515 DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
516 pgprot & _PAGE_PRESENT ? 'p' : '-',
517 pgprot & _PAGE_RW ? 'w' : 'r',
518 pgprot & _PAGE_USER ? 'u' : 's',
519 pgprot & _PAGE_PWT ? 't' : 'b',
520 pgprot & _PAGE_PCD ? 'u' : 'c',
521 pgprot & _PAGE_ACCESSED ? 'a' : '-',
522 pgprot & _PAGE_DIRTY ? 'd' : '-',
523 pgprot & _PAGE_PSE ? 'm' : 'k',
524 pgprot & _PAGE_GLOBAL ? 'g' : 'l' );
525 #endif
526 DRM_PROC_PRINT("\n");
529 if (len > request + offset) return request;
530 *eof = 1;
531 return len - offset;
534 static int DRM(vma_info)(char *buf, char **start, off_t offset, int request,
535 int *eof, void *data)
537 drm_device_t *dev = (drm_device_t *)data;
538 int ret;
540 down(&dev->struct_sem);
541 ret = DRM(_vma_info)(buf, start, offset, request, eof, data);
542 up(&dev->struct_sem);
543 return ret;
545 #endif