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