Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
at v3.17-rc6 284 lines 8.0 kB view raw
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 <drm/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 */ 44int 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 if (!master) 51 return 0; 52 53 if (master->unique) { 54 seq_printf(m, "%s %s %s\n", 55 dev->driver->name, 56 dev_name(dev->dev), master->unique); 57 } else { 58 seq_printf(m, "%s %s\n", 59 dev->driver->name, dev_name(dev->dev)); 60 } 61 return 0; 62} 63 64/** 65 * Called when "/proc/dri/.../vm" is read. 66 * 67 * Prints information about all mappings in drm_device::maplist. 68 */ 69int drm_vm_info(struct seq_file *m, void *data) 70{ 71 struct drm_info_node *node = (struct drm_info_node *) m->private; 72 struct drm_device *dev = node->minor->dev; 73 struct drm_local_map *map; 74 struct drm_map_list *r_list; 75 76 /* Hardcoded from _DRM_FRAME_BUFFER, 77 _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and 78 _DRM_SCATTER_GATHER and _DRM_CONSISTENT */ 79 const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" }; 80 const char *type; 81 int i; 82 83 mutex_lock(&dev->struct_mutex); 84 seq_printf(m, "slot offset size type flags address mtrr\n\n"); 85 i = 0; 86 list_for_each_entry(r_list, &dev->maplist, head) { 87 map = r_list->map; 88 if (!map) 89 continue; 90 if (map->type < 0 || map->type > 5) 91 type = "??"; 92 else 93 type = types[map->type]; 94 95 seq_printf(m, "%4d 0x%016llx 0x%08lx %4.4s 0x%02x 0x%08lx ", 96 i, 97 (unsigned long long)map->offset, 98 map->size, type, map->flags, 99 (unsigned long) r_list->user_token); 100 if (map->mtrr < 0) 101 seq_printf(m, "none\n"); 102 else 103 seq_printf(m, "%4d\n", map->mtrr); 104 i++; 105 } 106 mutex_unlock(&dev->struct_mutex); 107 return 0; 108} 109 110/** 111 * Called when "/proc/dri/.../bufs" is read. 112 */ 113int drm_bufs_info(struct seq_file *m, void *data) 114{ 115 struct drm_info_node *node = (struct drm_info_node *) m->private; 116 struct drm_device *dev = node->minor->dev; 117 struct drm_device_dma *dma; 118 int i, seg_pages; 119 120 mutex_lock(&dev->struct_mutex); 121 dma = dev->dma; 122 if (!dma) { 123 mutex_unlock(&dev->struct_mutex); 124 return 0; 125 } 126 127 seq_printf(m, " o size count free segs pages kB\n\n"); 128 for (i = 0; i <= DRM_MAX_ORDER; i++) { 129 if (dma->bufs[i].buf_count) { 130 seg_pages = dma->bufs[i].seg_count * (1 << dma->bufs[i].page_order); 131 seq_printf(m, "%2d %8d %5d %5d %5d %5d %5ld\n", 132 i, 133 dma->bufs[i].buf_size, 134 dma->bufs[i].buf_count, 135 0, 136 dma->bufs[i].seg_count, 137 seg_pages, 138 seg_pages * PAGE_SIZE / 1024); 139 } 140 } 141 seq_printf(m, "\n"); 142 for (i = 0; i < dma->buf_count; i++) { 143 if (i && !(i % 32)) 144 seq_printf(m, "\n"); 145 seq_printf(m, " %d", dma->buflist[i]->list); 146 } 147 seq_printf(m, "\n"); 148 mutex_unlock(&dev->struct_mutex); 149 return 0; 150} 151 152/** 153 * Called when "/proc/dri/.../vblank" is read. 154 */ 155int drm_vblank_info(struct seq_file *m, void *data) 156{ 157 struct drm_info_node *node = (struct drm_info_node *) m->private; 158 struct drm_device *dev = node->minor->dev; 159 int crtc; 160 161 mutex_lock(&dev->struct_mutex); 162 for (crtc = 0; crtc < dev->num_crtcs; crtc++) { 163 seq_printf(m, "CRTC %d enable: %d\n", 164 crtc, atomic_read(&dev->vblank[crtc].refcount)); 165 seq_printf(m, "CRTC %d counter: %d\n", 166 crtc, drm_vblank_count(dev, crtc)); 167 seq_printf(m, "CRTC %d last wait: %d\n", 168 crtc, dev->vblank[crtc].last_wait); 169 seq_printf(m, "CRTC %d in modeset: %d\n", 170 crtc, dev->vblank[crtc].inmodeset); 171 } 172 mutex_unlock(&dev->struct_mutex); 173 return 0; 174} 175 176/** 177 * Called when "/proc/dri/.../clients" is read. 178 * 179 */ 180int drm_clients_info(struct seq_file *m, void *data) 181{ 182 struct drm_info_node *node = (struct drm_info_node *) m->private; 183 struct drm_device *dev = node->minor->dev; 184 struct drm_file *priv; 185 186 mutex_lock(&dev->struct_mutex); 187 seq_printf(m, "a dev pid uid magic\n\n"); 188 list_for_each_entry(priv, &dev->filelist, lhead) { 189 seq_printf(m, "%c %3d %5d %5d %10u\n", 190 priv->authenticated ? 'y' : 'n', 191 priv->minor->index, 192 pid_vnr(priv->pid), 193 from_kuid_munged(seq_user_ns(m), priv->uid), 194 priv->magic); 195 } 196 mutex_unlock(&dev->struct_mutex); 197 return 0; 198} 199 200 201static int drm_gem_one_name_info(int id, void *ptr, void *data) 202{ 203 struct drm_gem_object *obj = ptr; 204 struct seq_file *m = data; 205 206 seq_printf(m, "%6d %8zd %7d %8d\n", 207 obj->name, obj->size, 208 obj->handle_count, 209 atomic_read(&obj->refcount.refcount)); 210 return 0; 211} 212 213int drm_gem_name_info(struct seq_file *m, void *data) 214{ 215 struct drm_info_node *node = (struct drm_info_node *) m->private; 216 struct drm_device *dev = node->minor->dev; 217 218 seq_printf(m, " name size handles refcount\n"); 219 220 mutex_lock(&dev->object_name_lock); 221 idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, m); 222 mutex_unlock(&dev->object_name_lock); 223 224 return 0; 225} 226 227#if DRM_DEBUG_CODE 228 229int drm_vma_info(struct seq_file *m, void *data) 230{ 231 struct drm_info_node *node = (struct drm_info_node *) m->private; 232 struct drm_device *dev = node->minor->dev; 233 struct drm_vma_entry *pt; 234 struct vm_area_struct *vma; 235 unsigned long vma_count = 0; 236#if defined(__i386__) 237 unsigned int pgprot; 238#endif 239 240 mutex_lock(&dev->struct_mutex); 241 list_for_each_entry(pt, &dev->vmalist, head) 242 vma_count++; 243 244 seq_printf(m, "vma use count: %lu, high_memory = %pK, 0x%pK\n", 245 vma_count, high_memory, 246 (void *)(unsigned long)virt_to_phys(high_memory)); 247 248 list_for_each_entry(pt, &dev->vmalist, head) { 249 vma = pt->vma; 250 if (!vma) 251 continue; 252 seq_printf(m, 253 "\n%5d 0x%pK-0x%pK %c%c%c%c%c%c 0x%08lx000", 254 pt->pid, 255 (void *)vma->vm_start, (void *)vma->vm_end, 256 vma->vm_flags & VM_READ ? 'r' : '-', 257 vma->vm_flags & VM_WRITE ? 'w' : '-', 258 vma->vm_flags & VM_EXEC ? 'x' : '-', 259 vma->vm_flags & VM_MAYSHARE ? 's' : 'p', 260 vma->vm_flags & VM_LOCKED ? 'l' : '-', 261 vma->vm_flags & VM_IO ? 'i' : '-', 262 vma->vm_pgoff); 263 264#if defined(__i386__) 265 pgprot = pgprot_val(vma->vm_page_prot); 266 seq_printf(m, " %c%c%c%c%c%c%c%c%c", 267 pgprot & _PAGE_PRESENT ? 'p' : '-', 268 pgprot & _PAGE_RW ? 'w' : 'r', 269 pgprot & _PAGE_USER ? 'u' : 's', 270 pgprot & _PAGE_PWT ? 't' : 'b', 271 pgprot & _PAGE_PCD ? 'u' : 'c', 272 pgprot & _PAGE_ACCESSED ? 'a' : '-', 273 pgprot & _PAGE_DIRTY ? 'd' : '-', 274 pgprot & _PAGE_PSE ? 'm' : 'k', 275 pgprot & _PAGE_GLOBAL ? 'g' : 'l'); 276#endif 277 seq_printf(m, "\n"); 278 } 279 mutex_unlock(&dev->struct_mutex); 280 return 0; 281} 282 283#endif 284