at v2.6.29 733 lines 20 kB view raw
1/** 2 * \file drm_proc.c 3 * /proc support for DRM 4 * 5 * \author Rickard E. (Rik) Faith <faith@valinux.com> 6 * \author Gareth Hughes <gareth@valinux.com> 7 * 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. 11 */ 12 13/* 14 * Created: Mon Jan 11 09:48:47 1999 by faith@valinux.com 15 * 16 * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas. 17 * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California. 18 * All Rights Reserved. 19 * 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: 26 * 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. 30 * 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. 38 */ 39 40#include "drmP.h" 41 42static int drm_name_info(char *buf, char **start, off_t offset, 43 int request, int *eof, void *data); 44static int drm_vm_info(char *buf, char **start, off_t offset, 45 int request, int *eof, void *data); 46static int drm_clients_info(char *buf, char **start, off_t offset, 47 int request, int *eof, void *data); 48static int drm_queues_info(char *buf, char **start, off_t offset, 49 int request, int *eof, void *data); 50static int drm_bufs_info(char *buf, char **start, off_t offset, 51 int request, int *eof, void *data); 52static int drm_vblank_info(char *buf, char **start, off_t offset, 53 int request, int *eof, void *data); 54static int drm_gem_name_info(char *buf, char **start, off_t offset, 55 int request, int *eof, void *data); 56static int drm_gem_object_info(char *buf, char **start, off_t offset, 57 int request, int *eof, void *data); 58#if DRM_DEBUG_CODE 59static int drm_vma_info(char *buf, char **start, off_t offset, 60 int request, int *eof, void *data); 61#endif 62 63/** 64 * Proc file list. 65 */ 66static 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[] = { 71 {"name", drm_name_info, 0}, 72 {"mem", drm_mem_info, 0}, 73 {"vm", drm_vm_info, 0}, 74 {"clients", drm_clients_info, 0}, 75 {"queues", drm_queues_info, 0}, 76 {"bufs", drm_bufs_info, 0}, 77 {"vblank", drm_vblank_info, 0}, 78 {"gem_names", drm_gem_name_info, DRIVER_GEM}, 79 {"gem_objects", drm_gem_object_info, DRIVER_GEM}, 80#if DRM_DEBUG_CODE 81 {"vma", drm_vma_info}, 82#endif 83}; 84 85#define DRM_PROC_ENTRIES ARRAY_SIZE(drm_proc_list) 86 87/** 88 * Initialize the DRI proc filesystem for a device. 89 * 90 * \param dev DRM device. 91 * \param minor device minor number. 92 * \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. 95 * 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%". 99 */ 100int drm_proc_init(struct drm_minor *minor, int minor_id, 101 struct proc_dir_entry *root) 102{ 103 struct drm_device *dev = minor->dev; 104 struct proc_dir_entry *ent; 105 int i, j, ret; 106 char name[64]; 107 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 } 114 115 for (i = 0; i < DRM_PROC_ENTRIES; i++) { 116 u32 features = drm_proc_list[i].driver_features; 117 118 if (features != 0 && 119 (dev->driver->driver_features & features) != features) 120 continue; 121 122 ent = create_proc_entry(drm_proc_list[i].name, 123 S_IFREG | S_IRUGO, minor->dev_root); 124 if (!ent) { 125 DRM_ERROR("Cannot create /proc/dri/%s/%s\n", 126 name, drm_proc_list[i].name); 127 ret = -1; 128 goto fail; 129 } 130 ent->read_proc = drm_proc_list[i].f; 131 ent->data = minor; 132 } 133 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 } 141 } 142 143 return 0; 144 fail: 145 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; 151 return ret; 152} 153 154/** 155 * Cleanup the proc filesystem resources. 156 * 157 * \param minor device minor number. 158 * \param root DRI proc dir entry. 159 * \param dev_root DRI device proc dir entry. 160 * \return always zero. 161 * 162 * Remove all proc entries created by proc_init(). 163 */ 164int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root) 165{ 166 struct drm_device *dev = minor->dev; 167 int i; 168 char name[64]; 169 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 */ 197static 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; 208 } 209 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)); 223 } 224 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 */ 244static 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); 288 } 289 i++; 290 } 291 292 if (len > request + offset) 293 return request; 294 *eof = 1; 295 return len - offset; 296} 297 298/** 299 * Simply calls _vm_info() while holding the drm_device::struct_mutex lock. 300 */ 301static int drm_vm_info(char *buf, char **start, off_t offset, int request, 302 int *eof, void *data) 303{ 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 */ 325static 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; 331 int i; 332 struct drm_queue *q; 333 334 if (offset > DRM_PROC_LIMIT) { 335 *eof = 1; 336 return 0; 337 } 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; 371} 372 373/** 374 * Simply calls _queues_info() while holding the drm_device::struct_mutex lock. 375 */ 376static 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. 391 * 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 */ 400static 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 */ 450static 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. 465 * 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. 473 */ 474static int drm__vblank_info(char *buf, char **start, off_t offset, int request, 475 int *eof, void *data) 476{ 477 struct drm_minor *minor = (struct drm_minor *) data; 478 struct drm_device *dev = minor->dev; 479 int len = 0; 480 int crtc; 481 482 if (offset > DRM_PROC_LIMIT) { 483 *eof = 1; 484 return 0; 485 } 486 487 *start = &buf[offset]; 488 *eof = 0; 489 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 } 500 501 if (len > request + offset) 502 return request; 503 *eof = 1; 504 return len - offset; 505} 506 507/** 508 * Simply calls _vblank_info() while holding the drm_device::struct_mutex lock. 509 */ 510static 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 */ 534static 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 */ 568static 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 581struct drm_gem_name_info_data { 582 int len; 583 char *buf; 584 int eof; 585}; 586 587static 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 return 0; 606} 607 608static 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 633static 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 661static 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 721static 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