File: /usr/src/linux/drivers/char/drm/drm_proc.h

1     /* drm_proc.h -- /proc support for DRM -*- linux-c -*-
2      * Created: Mon Jan 11 09:48:47 1999 by faith@valinux.com
3      *
4      * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
5      * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
6      * All Rights Reserved.
7      *
8      * Permission is hereby granted, free of charge, to any person obtaining a
9      * copy of this software and associated documentation files (the "Software"),
10      * to deal in the Software without restriction, including without limitation
11      * the rights to use, copy, modify, merge, publish, distribute, sublicense,
12      * and/or sell copies of the Software, and to permit persons to whom the
13      * Software is furnished to do so, subject to the following conditions:
14      *
15      * The above copyright notice and this permission notice (including the next
16      * paragraph) shall be included in all copies or substantial portions of the
17      * Software.
18      *
19      * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
20      * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
21      * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
22      * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
23      * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
24      * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
25      * OTHER DEALINGS IN THE SOFTWARE.
26      *
27      * Authors:
28      *    Rickard E. (Rik) Faith <faith@valinux.com>
29      *    Gareth Hughes <gareth@valinux.com>
30      *
31      * Acknowledgements:
32      *    Matthew J Sottek <matthew.j.sottek@intel.com> sent in a patch to fix
33      *    the problem with the proc files not outputting all their information.
34      */
35     
36     #define __NO_VERSION__
37     #include "drmP.h"
38     
39     static int	   DRM(name_info)(char *buf, char **start, off_t offset,
40     				  int request, int *eof, void *data);
41     static int	   DRM(vm_info)(char *buf, char **start, off_t offset,
42     				int request, int *eof, void *data);
43     static int	   DRM(clients_info)(char *buf, char **start, off_t offset,
44     				     int request, int *eof, void *data);
45     static int	   DRM(queues_info)(char *buf, char **start, off_t offset,
46     				    int request, int *eof, void *data);
47     static int	   DRM(bufs_info)(char *buf, char **start, off_t offset,
48     				  int request, int *eof, void *data);
49     #if DRM_DEBUG_CODE
50     static int	   DRM(vma_info)(char *buf, char **start, off_t offset,
51     				 int request, int *eof, void *data);
52     #endif
53     #if __HAVE_DMA_HISTOGRAM
54     static int	   DRM(histo_info)(char *buf, char **start, off_t offset,
55     				   int request, int *eof, void *data);
56     #endif
57     
58     struct drm_proc_list {
59     	const char *name;
60     	int	   (*f)(char *, char **, off_t, int, int *, void *);
61     } DRM(proc_list)[] = {
62     	{ "name",    DRM(name_info)    },
63     	{ "mem",     DRM(mem_info)     },
64     	{ "vm",	     DRM(vm_info)      },
65     	{ "clients", DRM(clients_info) },
66     	{ "queues",  DRM(queues_info)  },
67     	{ "bufs",    DRM(bufs_info)    },
68     #if DRM_DEBUG_CODE
69     	{ "vma",     DRM(vma_info)     },
70     #endif
71     #if __HAVE_DMA_HISTOGRAM
72     	{ "histo",   DRM(histo_info)   },
73     #endif
74     };
75     #define DRM_PROC_ENTRIES (sizeof(DRM(proc_list))/sizeof(DRM(proc_list)[0]))
76     
77     struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor,
78     				      struct proc_dir_entry *root,
79     				      struct proc_dir_entry **dev_root)
80     {
81     	struct proc_dir_entry *ent;
82     	int		      i, j;
83     	char                  name[64];
84     
85     	if (!minor) root = create_proc_entry("dri", S_IFDIR, NULL);
86     	if (!root) {
87     		DRM_ERROR("Cannot create /proc/dri\n");
88     		return NULL;
89     	}
90     
91     	sprintf(name, "%d", minor);
92     	*dev_root = create_proc_entry(name, S_IFDIR, root);
93     	if (!*dev_root) {
94     		DRM_ERROR("Cannot create /proc/%s\n", name);
95     		return NULL;
96     	}
97     
98     	for (i = 0; i < DRM_PROC_ENTRIES; i++) {
99     		ent = create_proc_entry(DRM(proc_list)[i].name,
100     					S_IFREG|S_IRUGO, *dev_root);
101     		if (!ent) {
102     			DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
103     				  name, DRM(proc_list)[i].name);
104     			for (j = 0; j < i; j++)
105     				remove_proc_entry(DRM(proc_list)[i].name,
106     						  *dev_root);
107     			remove_proc_entry(name, root);
108     			if (!minor) remove_proc_entry("dri", NULL);
109     			return NULL;
110     		}
111     		ent->read_proc = DRM(proc_list)[i].f;
112     		ent->data      = dev;
113     	}
114     
115     	return root;
116     }
117     
118     
119     int DRM(proc_cleanup)(int minor, struct proc_dir_entry *root,
120     		      struct proc_dir_entry *dev_root)
121     {
122     	int  i;
123     	char name[64];
124     
125     	if (!root || !dev_root) return 0;
126     
127     	for (i = 0; i < DRM_PROC_ENTRIES; i++)
128     		remove_proc_entry(DRM(proc_list)[i].name, dev_root);
129     	sprintf(name, "%d", minor);
130     	remove_proc_entry(name, root);
131     	if (!minor) remove_proc_entry("dri", NULL);
132     
133     	return 0;
134     }
135     
136     static int DRM(name_info)(char *buf, char **start, off_t offset, int request,
137     			  int *eof, void *data)
138     {
139     	drm_device_t *dev = (drm_device_t *)data;
140     	int          len  = 0;
141     
142     	if (offset > DRM_PROC_LIMIT) {
143     		*eof = 1;
144     		return 0;
145     	}
146     
147     	*start = &buf[offset];
148     	*eof   = 0;
149     
150     	if (dev->unique) {
151     		DRM_PROC_PRINT("%s 0x%x %s\n",
152     			       dev->name, dev->device, dev->unique);
153     	} else {
154     		DRM_PROC_PRINT("%s 0x%x\n", dev->name, dev->device);
155     	}
156     
157     	if (len > request + offset) return request;
158     	*eof = 1;
159     	return len - offset;
160     }
161     
162     static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
163     			 int *eof, void *data)
164     {
165     	drm_device_t *dev = (drm_device_t *)data;
166     	int          len  = 0;
167     	drm_map_t    *map;
168     	drm_map_list_t *r_list;
169     	struct list_head *list;
170     
171     				/* Hardcoded from _DRM_FRAME_BUFFER,
172                                        _DRM_REGISTERS, _DRM_SHM, and
173                                        _DRM_AGP. */
174     	const char   *types[] = { "FB", "REG", "SHM", "AGP" };
175     	const char   *type;
176     	int	     i;
177     
178     	if (offset > DRM_PROC_LIMIT) {
179     		*eof = 1;
180     		return 0;
181     	}
182     
183     	*start = &buf[offset];
184     	*eof   = 0;
185     
186     	DRM_PROC_PRINT("slot	 offset	      size type flags	 "
187     		       "address mtrr\n\n");
188     	i = 0;
189     	list_for_each(list, &dev->maplist->head) {
190     		r_list = (drm_map_list_t *)list;
191     		map = r_list->map;
192     		if(!map) continue;
193     		if (map->type < 0 || map->type > 3) type = "??";
194     		else				    type = types[map->type];
195     		DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s  0x%02x 0x%08lx ",
196     			       i,
197     			       map->offset,
198     			       map->size,
199     			       type,
200     			       map->flags,
201     			       (unsigned long)map->handle);
202     		if (map->mtrr < 0) {
203     			DRM_PROC_PRINT("none\n");
204     		} else {
205     			DRM_PROC_PRINT("%4d\n", map->mtrr);
206     		}
207     		i++;
208     	}
209     
210     	if (len > request + offset) return request;
211     	*eof = 1;
212     	return len - offset;
213     }
214     
215     static int DRM(vm_info)(char *buf, char **start, off_t offset, int request,
216     			int *eof, void *data)
217     {
218     	drm_device_t *dev = (drm_device_t *)data;
219     	int	     ret;
220     
221     	down(&dev->struct_sem);
222     	ret = DRM(_vm_info)(buf, start, offset, request, eof, data);
223     	up(&dev->struct_sem);
224     	return ret;
225     }
226     
227     
228     static int DRM(_queues_info)(char *buf, char **start, off_t offset,
229     			     int request, int *eof, void *data)
230     {
231     	drm_device_t *dev = (drm_device_t *)data;
232     	int          len  = 0;
233     	int	     i;
234     	drm_queue_t  *q;
235     
236     	if (offset > DRM_PROC_LIMIT) {
237     		*eof = 1;
238     		return 0;
239     	}
240     
241     	*start = &buf[offset];
242     	*eof   = 0;
243     
244     	DRM_PROC_PRINT("  ctx/flags   use   fin"
245     		       "   blk/rw/rwf  wait    flushed	   queued"
246     		       "      locks\n\n");
247     	for (i = 0; i < dev->queue_count; i++) {
248     		q = dev->queuelist[i];
249     		atomic_inc(&q->use_count);
250     		DRM_PROC_PRINT_RET(atomic_dec(&q->use_count),
251     				   "%5d/0x%03x %5d %5d"
252     				   " %5d/%c%c/%c%c%c %5Zd\n",
253     				   i,
254     				   q->flags,
255     				   atomic_read(&q->use_count),
256     				   atomic_read(&q->finalization),
257     				   atomic_read(&q->block_count),
258     				   atomic_read(&q->block_read) ? 'r' : '-',
259     				   atomic_read(&q->block_write) ? 'w' : '-',
260     				   waitqueue_active(&q->read_queue) ? 'r':'-',
261     				   waitqueue_active(&q->write_queue) ? 'w':'-',
262     				   waitqueue_active(&q->flush_queue) ? 'f':'-',
263     				   DRM_BUFCOUNT(&q->waitlist));
264     		atomic_dec(&q->use_count);
265     	}
266     
267     	if (len > request + offset) return request;
268     	*eof = 1;
269     	return len - offset;
270     }
271     
272     static int DRM(queues_info)(char *buf, char **start, off_t offset, int request,
273     			    int *eof, void *data)
274     {
275     	drm_device_t *dev = (drm_device_t *)data;
276     	int	     ret;
277     
278     	down(&dev->struct_sem);
279     	ret = DRM(_queues_info)(buf, start, offset, request, eof, data);
280     	up(&dev->struct_sem);
281     	return ret;
282     }
283     
284     /* drm_bufs_info is called whenever a process reads
285        /dev/dri/<dev>/bufs. */
286     
287     static int DRM(_bufs_info)(char *buf, char **start, off_t offset, int request,
288     			   int *eof, void *data)
289     {
290     	drm_device_t	 *dev = (drm_device_t *)data;
291     	int              len  = 0;
292     	drm_device_dma_t *dma = dev->dma;
293     	int		 i;
294     
295     	if (!dma || offset > DRM_PROC_LIMIT) {
296     		*eof = 1;
297     		return 0;
298     	}
299     
300     	*start = &buf[offset];
301     	*eof   = 0;
302     
303     	DRM_PROC_PRINT(" o     size count  free	 segs pages    kB\n\n");
304     	for (i = 0; i <= DRM_MAX_ORDER; i++) {
305     		if (dma->bufs[i].buf_count)
306     			DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n",
307     				       i,
308     				       dma->bufs[i].buf_size,
309     				       dma->bufs[i].buf_count,
310     				       atomic_read(&dma->bufs[i]
311     						   .freelist.count),
312     				       dma->bufs[i].seg_count,
313     				       dma->bufs[i].seg_count
314     				       *(1 << dma->bufs[i].page_order),
315     				       (dma->bufs[i].seg_count
316     					* (1 << dma->bufs[i].page_order))
317     				       * PAGE_SIZE / 1024);
318     	}
319     	DRM_PROC_PRINT("\n");
320     	for (i = 0; i < dma->buf_count; i++) {
321     		if (i && !(i%32)) DRM_PROC_PRINT("\n");
322     		DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
323     	}
324     	DRM_PROC_PRINT("\n");
325     
326     	if (len > request + offset) return request;
327     	*eof = 1;
328     	return len - offset;
329     }
330     
331     static int DRM(bufs_info)(char *buf, char **start, off_t offset, int request,
332     			  int *eof, void *data)
333     {
334     	drm_device_t *dev = (drm_device_t *)data;
335     	int	     ret;
336     
337     	down(&dev->struct_sem);
338     	ret = DRM(_bufs_info)(buf, start, offset, request, eof, data);
339     	up(&dev->struct_sem);
340     	return ret;
341     }
342     
343     
344     static int DRM(_clients_info)(char *buf, char **start, off_t offset,
345     			      int request, int *eof, void *data)
346     {
347     	drm_device_t *dev = (drm_device_t *)data;
348     	int          len  = 0;
349     	drm_file_t   *priv;
350     
351     	if (offset > DRM_PROC_LIMIT) {
352     		*eof = 1;
353     		return 0;
354     	}
355     
356     	*start = &buf[offset];
357     	*eof   = 0;
358     
359     	DRM_PROC_PRINT("a dev	pid    uid	magic	  ioctls\n\n");
360     	for (priv = dev->file_first; priv; priv = priv->next) {
361     		DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
362     			       priv->authenticated ? 'y' : 'n',
363     			       priv->minor,
364     			       priv->pid,
365     			       priv->uid,
366     			       priv->magic,
367     			       priv->ioctl_count);
368     	}
369     
370     	if (len > request + offset) return request;
371     	*eof = 1;
372     	return len - offset;
373     }
374     
375     static int DRM(clients_info)(char *buf, char **start, off_t offset,
376     			     int request, int *eof, void *data)
377     {
378     	drm_device_t *dev = (drm_device_t *)data;
379     	int	     ret;
380     
381     	down(&dev->struct_sem);
382     	ret = DRM(_clients_info)(buf, start, offset, request, eof, data);
383     	up(&dev->struct_sem);
384     	return ret;
385     }
386     
387     #if DRM_DEBUG_CODE
388     
389     #define DRM_VMA_VERBOSE 0
390     
391     static int DRM(_vma_info)(char *buf, char **start, off_t offset, int request,
392     			  int *eof, void *data)
393     {
394     	drm_device_t	      *dev = (drm_device_t *)data;
395     	int                   len  = 0;
396     	drm_vma_entry_t	      *pt;
397     	struct vm_area_struct *vma;
398     #if DRM_VMA_VERBOSE
399     	unsigned long	      i;
400     	unsigned long	      address;
401     	pgd_t		      *pgd;
402     	pmd_t		      *pmd;
403     	pte_t		      *pte;
404     #endif
405     #if defined(__i386__)
406     	unsigned int	      pgprot;
407     #endif
408     
409     	if (offset > DRM_PROC_LIMIT) {
410     		*eof = 1;
411     		return 0;
412     	}
413     
414     	*start = &buf[offset];
415     	*eof   = 0;
416     
417     	DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
418     		       atomic_read(&dev->vma_count),
419     		       high_memory, virt_to_phys(high_memory));
420     	for (pt = dev->vmalist; pt; pt = pt->next) {
421     		if (!(vma = pt->vma)) continue;
422     		DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
423     			       pt->pid,
424     			       vma->vm_start,
425     			       vma->vm_end,
426     			       vma->vm_flags & VM_READ	   ? 'r' : '-',
427     			       vma->vm_flags & VM_WRITE	   ? 'w' : '-',
428     			       vma->vm_flags & VM_EXEC	   ? 'x' : '-',
429     			       vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
430     			       vma->vm_flags & VM_LOCKED   ? 'l' : '-',
431     			       vma->vm_flags & VM_IO	   ? 'i' : '-',
432     			       VM_OFFSET(vma));
433     
434     #if defined(__i386__)
435     		pgprot = pgprot_val(vma->vm_page_prot);
436     		DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
437     			       pgprot & _PAGE_PRESENT  ? 'p' : '-',
438     			       pgprot & _PAGE_RW       ? 'w' : 'r',
439     			       pgprot & _PAGE_USER     ? 'u' : 's',
440     			       pgprot & _PAGE_PWT      ? 't' : 'b',
441     			       pgprot & _PAGE_PCD      ? 'u' : 'c',
442     			       pgprot & _PAGE_ACCESSED ? 'a' : '-',
443     			       pgprot & _PAGE_DIRTY    ? 'd' : '-',
444     			       pgprot & _PAGE_PSE      ? 'm' : 'k',
445     			       pgprot & _PAGE_GLOBAL   ? 'g' : 'l' );
446     #endif
447     		DRM_PROC_PRINT("\n");
448     #if 0
449     		for (i = vma->vm_start; i < vma->vm_end; i += PAGE_SIZE) {
450     			pgd = pgd_offset(vma->vm_mm, i);
451     			pmd = pmd_offset(pgd, i);
452     			pte = pte_offset(pmd, i);
453     			if (pte_present(*pte)) {
454     				address = __pa(pte_page(*pte))
455     					+ (i & (PAGE_SIZE-1));
456     				DRM_PROC_PRINT("      0x%08lx -> 0x%08lx"
457     					       " %c%c%c%c%c\n",
458     					       i,
459     					       address,
460     					       pte_read(*pte)  ? 'r' : '-',
461     					       pte_write(*pte) ? 'w' : '-',
462     					       pte_exec(*pte)  ? 'x' : '-',
463     					       pte_dirty(*pte) ? 'd' : '-',
464     					       pte_young(*pte) ? 'a' : '-' );
465     			} else {
466     				DRM_PROC_PRINT("      0x%08lx\n", i);
467     			}
468     		}
469     #endif
470     	}
471     
472     	if (len > request + offset) return request;
473     	*eof = 1;
474     	return len - offset;
475     }
476     
477     static int DRM(vma_info)(char *buf, char **start, off_t offset, int request,
478     			 int *eof, void *data)
479     {
480     	drm_device_t *dev = (drm_device_t *)data;
481     	int	     ret;
482     
483     	down(&dev->struct_sem);
484     	ret = DRM(_vma_info)(buf, start, offset, request, eof, data);
485     	up(&dev->struct_sem);
486     	return ret;
487     }
488     #endif
489     
490     
491     #if __HAVE_DMA_HISTOGRAM
492     static int DRM(_histo_info)(char *buf, char **start, off_t offset, int request,
493     			    int *eof, void *data)
494     {
495     	drm_device_t	 *dev = (drm_device_t *)data;
496     	int              len  = 0;
497     	drm_device_dma_t *dma = dev->dma;
498     	int		 i;
499     	unsigned long	 slot_value = DRM_DMA_HISTOGRAM_INITIAL;
500     	unsigned long	 prev_value = 0;
501     	drm_buf_t	 *buffer;
502     
503     	if (offset > DRM_PROC_LIMIT) {
504     		*eof = 1;
505     		return 0;
506     	}
507     
508     	*start = &buf[offset];
509     	*eof   = 0;
510     
511     	DRM_PROC_PRINT("general statistics:\n");
512     	DRM_PROC_PRINT("total	 %10u\n", atomic_read(&dev->histo.total));
513     	DRM_PROC_PRINT("open	 %10u\n",
514     		       atomic_read(&dev->counts[_DRM_STAT_OPENS]));
515     	DRM_PROC_PRINT("close	 %10u\n",
516     		       atomic_read(&dev->counts[_DRM_STAT_CLOSES]));
517     	DRM_PROC_PRINT("ioctl	 %10u\n",
518     		       atomic_read(&dev->counts[_DRM_STAT_IOCTLS]));
519     
520     	DRM_PROC_PRINT("\nlock statistics:\n");
521     	DRM_PROC_PRINT("locks	 %10u\n",
522     		       atomic_read(&dev->counts[_DRM_STAT_LOCKS]));
523     	DRM_PROC_PRINT("unlocks	 %10u\n",
524     		       atomic_read(&dev->counts[_DRM_STAT_UNLOCKS]));
525     
526     	if (dma) {
527     #if 0
528     		DRM_PROC_PRINT("\ndma statistics:\n");
529     		DRM_PROC_PRINT("prio	 %10u\n",
530     			       atomic_read(&dma->total_prio));
531     		DRM_PROC_PRINT("bytes	 %10u\n",
532     			       atomic_read(&dma->total_bytes));
533     		DRM_PROC_PRINT("dmas	 %10u\n",
534     			       atomic_read(&dma->total_dmas));
535     		DRM_PROC_PRINT("missed:\n");
536     		DRM_PROC_PRINT("  dma	 %10u\n",
537     			       atomic_read(&dma->total_missed_dma));
538     		DRM_PROC_PRINT("  lock	 %10u\n",
539     			       atomic_read(&dma->total_missed_lock));
540     		DRM_PROC_PRINT("  free	 %10u\n",
541     			       atomic_read(&dma->total_missed_free));
542     		DRM_PROC_PRINT("  sched	 %10u\n",
543     			       atomic_read(&dma->total_missed_sched));
544     		DRM_PROC_PRINT("tried	 %10u\n",
545     			       atomic_read(&dma->total_tried));
546     		DRM_PROC_PRINT("hit	 %10u\n",
547     			       atomic_read(&dma->total_hit));
548     		DRM_PROC_PRINT("lost	 %10u\n",
549     			       atomic_read(&dma->total_lost));
550     #endif
551     
552     		buffer = dma->next_buffer;
553     		if (buffer) {
554     			DRM_PROC_PRINT("next_buffer %7d\n", buffer->idx);
555     		} else {
556     			DRM_PROC_PRINT("next_buffer    none\n");
557     		}
558     		buffer = dma->this_buffer;
559     		if (buffer) {
560     			DRM_PROC_PRINT("this_buffer %7d\n", buffer->idx);
561     		} else {
562     			DRM_PROC_PRINT("this_buffer    none\n");
563     		}
564     	}
565     
566     
567     	DRM_PROC_PRINT("\nvalues:\n");
568     	if (dev->lock.hw_lock) {
569     		DRM_PROC_PRINT("lock	       0x%08x\n",
570     			       dev->lock.hw_lock->lock);
571     	} else {
572     		DRM_PROC_PRINT("lock		     none\n");
573     	}
574     	DRM_PROC_PRINT("context_flag   0x%08lx\n", dev->context_flag);
575     	DRM_PROC_PRINT("interrupt_flag 0x%08lx\n", dev->interrupt_flag);
576     	DRM_PROC_PRINT("dma_flag       0x%08lx\n", dev->dma_flag);
577     
578     	DRM_PROC_PRINT("queue_count    %10d\n",	 dev->queue_count);
579     	DRM_PROC_PRINT("last_context   %10d\n",	 dev->last_context);
580     	DRM_PROC_PRINT("last_switch    %10lu\n", dev->last_switch);
581     	DRM_PROC_PRINT("last_checked   %10d\n",	 dev->last_checked);
582     
583     
584     	DRM_PROC_PRINT("\n		       q2d	  d2c	     c2f"
585     		       "	q2c	   q2f	      dma	 sch"
586     		       "	ctx	  lacq	     lhld\n\n");
587     	for (i = 0; i < DRM_DMA_HISTOGRAM_SLOTS; i++) {
588     		DRM_PROC_PRINT("%s %10lu %10u %10u %10u %10u %10u"
589     			       " %10u %10u %10u %10u %10u\n",
590     			       i == DRM_DMA_HISTOGRAM_SLOTS - 1 ? ">=" : "< ",
591     			       i == DRM_DMA_HISTOGRAM_SLOTS - 1
592     			       ? prev_value : slot_value ,
593     
594     			       atomic_read(&dev->histo
595     					   .queued_to_dispatched[i]),
596     			       atomic_read(&dev->histo
597     					   .dispatched_to_completed[i]),
598     			       atomic_read(&dev->histo
599     					   .completed_to_freed[i]),
600     
601     			       atomic_read(&dev->histo
602     					   .queued_to_completed[i]),
603     			       atomic_read(&dev->histo
604     					   .queued_to_freed[i]),
605     			       atomic_read(&dev->histo.dma[i]),
606     			       atomic_read(&dev->histo.schedule[i]),
607     			       atomic_read(&dev->histo.ctx[i]),
608     			       atomic_read(&dev->histo.lacq[i]),
609     			       atomic_read(&dev->histo.lhld[i]));
610     		prev_value = slot_value;
611     		slot_value = DRM_DMA_HISTOGRAM_NEXT(slot_value);
612     	}
613     
614     	if (len > request + offset) return request;
615     	*eof = 1;
616     	return len - offset;
617     }
618     
619     static int DRM(histo_info)(char *buf, char **start, off_t offset, int request,
620     			   int *eof, void *data)
621     {
622     	drm_device_t *dev = (drm_device_t *)data;
623     	int	     ret;
624     
625     	down(&dev->struct_sem);
626     	ret = DRM(_histo_info)(buf, start, offset, request, eof, data);
627     	up(&dev->struct_sem);
628     	return ret;
629     }
630     #endif
631