drm_proc.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666
  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. * Created: Mon Jan 11 09:48:47 1999 by faith@valinux.com
  14. *
  15. * Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
  16. * Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
  17. * All Rights Reserved.
  18. *
  19. * Permission is hereby granted, free of charge, to any person obtaining a
  20. * copy of this software and associated documentation files (the "Software"),
  21. * to deal in the Software without restriction, including without limitation
  22. * the rights to use, copy, modify, merge, publish, distribute, sublicense,
  23. * and/or sell copies of the Software, and to permit persons to whom the
  24. * Software is furnished to do so, subject to the following conditions:
  25. *
  26. * The above copyright notice and this permission notice (including the next
  27. * paragraph) shall be included in all copies or substantial portions of the
  28. * Software.
  29. *
  30. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  31. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  32. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  33. * VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
  34. * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
  35. * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
  36. * OTHER DEALINGS IN THE SOFTWARE.
  37. */
  38. #include "drmP.h"
  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. static int drm_gem_name_info(char *buf, char **start, off_t offset,
  50. int request, int *eof, void *data);
  51. static int drm_gem_object_info(char *buf, char **start, off_t offset,
  52. int request, int *eof, void *data);
  53. #if DRM_DEBUG_CODE
  54. static int drm_vma_info(char *buf, char **start, off_t offset,
  55. int request, int *eof, void *data);
  56. #endif
  57. /**
  58. * Proc file list.
  59. */
  60. static struct drm_proc_list {
  61. const char *name; /**< file name */
  62. int (*f) (char *, char **, off_t, int, int *, void *); /**< proc callback*/
  63. u32 driver_features; /**< Required driver features for this entry */
  64. } drm_proc_list[] = {
  65. {"name", drm_name_info, 0},
  66. {"mem", drm_mem_info, 0},
  67. {"vm", drm_vm_info, 0},
  68. {"clients", drm_clients_info, 0},
  69. {"queues", drm_queues_info, 0},
  70. {"bufs", drm_bufs_info, 0},
  71. {"gem_names", drm_gem_name_info, DRIVER_GEM},
  72. {"gem_objects", drm_gem_object_info, DRIVER_GEM},
  73. #if DRM_DEBUG_CODE
  74. {"vma", drm_vma_info},
  75. #endif
  76. };
  77. #define DRM_PROC_ENTRIES ARRAY_SIZE(drm_proc_list)
  78. /**
  79. * Initialize the DRI proc filesystem for a device.
  80. *
  81. * \param dev DRM device.
  82. * \param minor device minor number.
  83. * \param root DRI proc dir entry.
  84. * \param dev_root resulting DRI device proc dir entry.
  85. * \return root entry pointer on success, or NULL on failure.
  86. *
  87. * Create the DRI proc root entry "/proc/dri", the device proc root entry
  88. * "/proc/dri/%minor%/", and each entry in proc_list as
  89. * "/proc/dri/%minor%/%name%".
  90. */
  91. int drm_proc_init(struct drm_minor *minor, int minor_id,
  92. struct proc_dir_entry *root)
  93. {
  94. struct drm_device *dev = minor->dev;
  95. struct proc_dir_entry *ent;
  96. int i, j, ret;
  97. char name[64];
  98. sprintf(name, "%d", minor_id);
  99. minor->dev_root = proc_mkdir(name, root);
  100. if (!minor->dev_root) {
  101. DRM_ERROR("Cannot create /proc/dri/%s\n", name);
  102. return -1;
  103. }
  104. for (i = 0; i < DRM_PROC_ENTRIES; i++) {
  105. u32 features = drm_proc_list[i].driver_features;
  106. if (features != 0 &&
  107. (dev->driver->driver_features & features) != features)
  108. continue;
  109. ent = create_proc_entry(drm_proc_list[i].name,
  110. S_IFREG | S_IRUGO, minor->dev_root);
  111. if (!ent) {
  112. DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
  113. name, drm_proc_list[i].name);
  114. ret = -1;
  115. goto fail;
  116. }
  117. ent->read_proc = drm_proc_list[i].f;
  118. ent->data = minor;
  119. }
  120. if (dev->driver->proc_init) {
  121. ret = dev->driver->proc_init(minor);
  122. if (ret) {
  123. DRM_ERROR("DRM: Driver failed to initialize "
  124. "/proc/dri.\n");
  125. goto fail;
  126. }
  127. }
  128. return 0;
  129. fail:
  130. for (j = 0; j < i; j++)
  131. remove_proc_entry(drm_proc_list[i].name,
  132. minor->dev_root);
  133. remove_proc_entry(name, root);
  134. minor->dev_root = NULL;
  135. return ret;
  136. }
  137. /**
  138. * Cleanup the proc filesystem resources.
  139. *
  140. * \param minor device minor number.
  141. * \param root DRI proc dir entry.
  142. * \param dev_root DRI device proc dir entry.
  143. * \return always zero.
  144. *
  145. * Remove all proc entries created by proc_init().
  146. */
  147. int drm_proc_cleanup(struct drm_minor *minor, struct proc_dir_entry *root)
  148. {
  149. struct drm_device *dev = minor->dev;
  150. int i;
  151. char name[64];
  152. if (!root || !minor->dev_root)
  153. return 0;
  154. if (dev->driver->proc_cleanup)
  155. dev->driver->proc_cleanup(minor);
  156. for (i = 0; i < DRM_PROC_ENTRIES; i++)
  157. remove_proc_entry(drm_proc_list[i].name, minor->dev_root);
  158. sprintf(name, "%d", minor->index);
  159. remove_proc_entry(name, root);
  160. return 0;
  161. }
  162. /**
  163. * Called when "/proc/dri/.../name" is read.
  164. *
  165. * \param buf output buffer.
  166. * \param start start of output data.
  167. * \param offset requested start offset.
  168. * \param request requested number of bytes.
  169. * \param eof whether there is no more data to return.
  170. * \param data private data.
  171. * \return number of written bytes.
  172. *
  173. * Prints the device name together with the bus id if available.
  174. */
  175. static int drm_name_info(char *buf, char **start, off_t offset, int request,
  176. int *eof, void *data)
  177. {
  178. struct drm_minor *minor = (struct drm_minor *) data;
  179. struct drm_device *dev = minor->dev;
  180. int len = 0;
  181. if (offset > DRM_PROC_LIMIT) {
  182. *eof = 1;
  183. return 0;
  184. }
  185. *start = &buf[offset];
  186. *eof = 0;
  187. if (dev->unique) {
  188. DRM_PROC_PRINT("%s %s %s\n",
  189. dev->driver->pci_driver.name,
  190. pci_name(dev->pdev), dev->unique);
  191. } else {
  192. DRM_PROC_PRINT("%s %s\n", dev->driver->pci_driver.name,
  193. pci_name(dev->pdev));
  194. }
  195. if (len > request + offset)
  196. return request;
  197. *eof = 1;
  198. return len - offset;
  199. }
  200. /**
  201. * Called when "/proc/dri/.../vm" is read.
  202. *
  203. * \param buf output buffer.
  204. * \param start start of output data.
  205. * \param offset requested start offset.
  206. * \param request requested number of bytes.
  207. * \param eof whether there is no more data to return.
  208. * \param data private data.
  209. * \return number of written bytes.
  210. *
  211. * Prints information about all mappings in drm_device::maplist.
  212. */
  213. static int drm__vm_info(char *buf, char **start, off_t offset, int request,
  214. int *eof, void *data)
  215. {
  216. struct drm_minor *minor = (struct drm_minor *) data;
  217. struct drm_device *dev = minor->dev;
  218. int len = 0;
  219. struct drm_map *map;
  220. struct drm_map_list *r_list;
  221. /* Hardcoded from _DRM_FRAME_BUFFER,
  222. _DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
  223. _DRM_SCATTER_GATHER and _DRM_CONSISTENT */
  224. const char *types[] = { "FB", "REG", "SHM", "AGP", "SG", "PCI" };
  225. const char *type;
  226. int i;
  227. if (offset > DRM_PROC_LIMIT) {
  228. *eof = 1;
  229. return 0;
  230. }
  231. *start = &buf[offset];
  232. *eof = 0;
  233. DRM_PROC_PRINT("slot offset size type flags "
  234. "address mtrr\n\n");
  235. i = 0;
  236. list_for_each_entry(r_list, &dev->maplist, head) {
  237. map = r_list->map;
  238. if (!map)
  239. continue;
  240. if (map->type < 0 || map->type > 5)
  241. type = "??";
  242. else
  243. type = types[map->type];
  244. DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
  245. i,
  246. map->offset,
  247. map->size, type, map->flags,
  248. (unsigned long) r_list->user_token);
  249. if (map->mtrr < 0) {
  250. DRM_PROC_PRINT("none\n");
  251. } else {
  252. DRM_PROC_PRINT("%4d\n", map->mtrr);
  253. }
  254. i++;
  255. }
  256. if (len > request + offset)
  257. return request;
  258. *eof = 1;
  259. return len - offset;
  260. }
  261. /**
  262. * Simply calls _vm_info() while holding the drm_device::struct_mutex lock.
  263. */
  264. static int drm_vm_info(char *buf, char **start, off_t offset, int request,
  265. int *eof, void *data)
  266. {
  267. struct drm_minor *minor = (struct drm_minor *) data;
  268. struct drm_device *dev = minor->dev;
  269. int ret;
  270. mutex_lock(&dev->struct_mutex);
  271. ret = drm__vm_info(buf, start, offset, request, eof, data);
  272. mutex_unlock(&dev->struct_mutex);
  273. return ret;
  274. }
  275. /**
  276. * Called when "/proc/dri/.../queues" is read.
  277. *
  278. * \param buf output buffer.
  279. * \param start start of output data.
  280. * \param offset requested start offset.
  281. * \param request requested number of bytes.
  282. * \param eof whether there is no more data to return.
  283. * \param data private data.
  284. * \return number of written bytes.
  285. */
  286. static int drm__queues_info(char *buf, char **start, off_t offset,
  287. int request, int *eof, void *data)
  288. {
  289. struct drm_minor *minor = (struct drm_minor *) data;
  290. struct drm_device *dev = minor->dev;
  291. int len = 0;
  292. int i;
  293. struct drm_queue *q;
  294. if (offset > DRM_PROC_LIMIT) {
  295. *eof = 1;
  296. return 0;
  297. }
  298. *start = &buf[offset];
  299. *eof = 0;
  300. DRM_PROC_PRINT(" ctx/flags use fin"
  301. " blk/rw/rwf wait flushed queued"
  302. " locks\n\n");
  303. for (i = 0; i < dev->queue_count; i++) {
  304. q = dev->queuelist[i];
  305. atomic_inc(&q->use_count);
  306. DRM_PROC_PRINT_RET(atomic_dec(&q->use_count),
  307. "%5d/0x%03x %5d %5d"
  308. " %5d/%c%c/%c%c%c %5Zd\n",
  309. i,
  310. q->flags,
  311. atomic_read(&q->use_count),
  312. atomic_read(&q->finalization),
  313. atomic_read(&q->block_count),
  314. atomic_read(&q->block_read) ? 'r' : '-',
  315. atomic_read(&q->block_write) ? 'w' : '-',
  316. waitqueue_active(&q->read_queue) ? 'r' : '-',
  317. waitqueue_active(&q->
  318. write_queue) ? 'w' : '-',
  319. waitqueue_active(&q->
  320. flush_queue) ? 'f' : '-',
  321. DRM_BUFCOUNT(&q->waitlist));
  322. atomic_dec(&q->use_count);
  323. }
  324. if (len > request + offset)
  325. return request;
  326. *eof = 1;
  327. return len - offset;
  328. }
  329. /**
  330. * Simply calls _queues_info() while holding the drm_device::struct_mutex lock.
  331. */
  332. static int drm_queues_info(char *buf, char **start, off_t offset, int request,
  333. int *eof, void *data)
  334. {
  335. struct drm_minor *minor = (struct drm_minor *) data;
  336. struct drm_device *dev = minor->dev;
  337. int ret;
  338. mutex_lock(&dev->struct_mutex);
  339. ret = drm__queues_info(buf, start, offset, request, eof, data);
  340. mutex_unlock(&dev->struct_mutex);
  341. return ret;
  342. }
  343. /**
  344. * Called when "/proc/dri/.../bufs" is read.
  345. *
  346. * \param buf output buffer.
  347. * \param start start of output data.
  348. * \param offset requested start offset.
  349. * \param request requested number of bytes.
  350. * \param eof whether there is no more data to return.
  351. * \param data private data.
  352. * \return number of written bytes.
  353. */
  354. static int drm__bufs_info(char *buf, char **start, off_t offset, int request,
  355. int *eof, void *data)
  356. {
  357. struct drm_minor *minor = (struct drm_minor *) data;
  358. struct drm_device *dev = minor->dev;
  359. int len = 0;
  360. struct drm_device_dma *dma = dev->dma;
  361. int i;
  362. if (!dma || offset > DRM_PROC_LIMIT) {
  363. *eof = 1;
  364. return 0;
  365. }
  366. *start = &buf[offset];
  367. *eof = 0;
  368. DRM_PROC_PRINT(" o size count free segs pages kB\n\n");
  369. for (i = 0; i <= DRM_MAX_ORDER; i++) {
  370. if (dma->bufs[i].buf_count)
  371. DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n",
  372. i,
  373. dma->bufs[i].buf_size,
  374. dma->bufs[i].buf_count,
  375. atomic_read(&dma->bufs[i]
  376. .freelist.count),
  377. dma->bufs[i].seg_count,
  378. dma->bufs[i].seg_count
  379. * (1 << dma->bufs[i].page_order),
  380. (dma->bufs[i].seg_count
  381. * (1 << dma->bufs[i].page_order))
  382. * PAGE_SIZE / 1024);
  383. }
  384. DRM_PROC_PRINT("\n");
  385. for (i = 0; i < dma->buf_count; i++) {
  386. if (i && !(i % 32))
  387. DRM_PROC_PRINT("\n");
  388. DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
  389. }
  390. DRM_PROC_PRINT("\n");
  391. if (len > request + offset)
  392. return request;
  393. *eof = 1;
  394. return len - offset;
  395. }
  396. /**
  397. * Simply calls _bufs_info() while holding the drm_device::struct_mutex lock.
  398. */
  399. static int drm_bufs_info(char *buf, char **start, off_t offset, int request,
  400. int *eof, void *data)
  401. {
  402. struct drm_minor *minor = (struct drm_minor *) data;
  403. struct drm_device *dev = minor->dev;
  404. int ret;
  405. mutex_lock(&dev->struct_mutex);
  406. ret = drm__bufs_info(buf, start, offset, request, eof, data);
  407. mutex_unlock(&dev->struct_mutex);
  408. return ret;
  409. }
  410. /**
  411. * Called when "/proc/dri/.../clients" is read.
  412. *
  413. * \param buf output buffer.
  414. * \param start start of output data.
  415. * \param offset requested start offset.
  416. * \param request requested number of bytes.
  417. * \param eof whether there is no more data to return.
  418. * \param data private data.
  419. * \return number of written bytes.
  420. */
  421. static int drm__clients_info(char *buf, char **start, off_t offset,
  422. int request, int *eof, void *data)
  423. {
  424. struct drm_minor *minor = (struct drm_minor *) data;
  425. struct drm_device *dev = minor->dev;
  426. int len = 0;
  427. struct drm_file *priv;
  428. if (offset > DRM_PROC_LIMIT) {
  429. *eof = 1;
  430. return 0;
  431. }
  432. *start = &buf[offset];
  433. *eof = 0;
  434. DRM_PROC_PRINT("a dev pid uid magic ioctls\n\n");
  435. list_for_each_entry(priv, &dev->filelist, lhead) {
  436. DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
  437. priv->authenticated ? 'y' : 'n',
  438. priv->minor->index,
  439. priv->pid,
  440. priv->uid, priv->magic, priv->ioctl_count);
  441. }
  442. if (len > request + offset)
  443. return request;
  444. *eof = 1;
  445. return len - offset;
  446. }
  447. /**
  448. * Simply calls _clients_info() while holding the drm_device::struct_mutex lock.
  449. */
  450. static int drm_clients_info(char *buf, char **start, off_t offset,
  451. int request, 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. mutex_lock(&dev->struct_mutex);
  457. ret = drm__clients_info(buf, start, offset, request, eof, data);
  458. mutex_unlock(&dev->struct_mutex);
  459. return ret;
  460. }
  461. struct drm_gem_name_info_data {
  462. int len;
  463. char *buf;
  464. int eof;
  465. };
  466. static int drm_gem_one_name_info(int id, void *ptr, void *data)
  467. {
  468. struct drm_gem_object *obj = ptr;
  469. struct drm_gem_name_info_data *nid = data;
  470. DRM_INFO("name %d size %zd\n", obj->name, obj->size);
  471. if (nid->eof)
  472. return 0;
  473. nid->len += sprintf(&nid->buf[nid->len],
  474. "%6d %8zd %7d %8d\n",
  475. obj->name, obj->size,
  476. atomic_read(&obj->handlecount.refcount),
  477. atomic_read(&obj->refcount.refcount));
  478. if (nid->len > DRM_PROC_LIMIT) {
  479. nid->eof = 1;
  480. return 0;
  481. }
  482. return 0;
  483. }
  484. static int drm_gem_name_info(char *buf, char **start, off_t offset,
  485. int request, int *eof, void *data)
  486. {
  487. struct drm_minor *minor = (struct drm_minor *) data;
  488. struct drm_device *dev = minor->dev;
  489. struct drm_gem_name_info_data nid;
  490. if (offset > DRM_PROC_LIMIT) {
  491. *eof = 1;
  492. return 0;
  493. }
  494. nid.len = sprintf(buf, " name size handles refcount\n");
  495. nid.buf = buf;
  496. nid.eof = 0;
  497. idr_for_each(&dev->object_name_idr, drm_gem_one_name_info, &nid);
  498. *start = &buf[offset];
  499. *eof = 0;
  500. if (nid.len > request + offset)
  501. return request;
  502. *eof = 1;
  503. return nid.len - offset;
  504. }
  505. static int drm_gem_object_info(char *buf, char **start, off_t offset,
  506. int request, int *eof, void *data)
  507. {
  508. struct drm_minor *minor = (struct drm_minor *) data;
  509. struct drm_device *dev = minor->dev;
  510. int len = 0;
  511. if (offset > DRM_PROC_LIMIT) {
  512. *eof = 1;
  513. return 0;
  514. }
  515. *start = &buf[offset];
  516. *eof = 0;
  517. DRM_PROC_PRINT("%d objects\n", atomic_read(&dev->object_count));
  518. DRM_PROC_PRINT("%d object bytes\n", atomic_read(&dev->object_memory));
  519. DRM_PROC_PRINT("%d pinned\n", atomic_read(&dev->pin_count));
  520. DRM_PROC_PRINT("%d pin bytes\n", atomic_read(&dev->pin_memory));
  521. DRM_PROC_PRINT("%d gtt bytes\n", atomic_read(&dev->gtt_memory));
  522. DRM_PROC_PRINT("%d gtt total\n", dev->gtt_total);
  523. if (len > request + offset)
  524. return request;
  525. *eof = 1;
  526. return len - offset;
  527. }
  528. #if DRM_DEBUG_CODE
  529. static int drm__vma_info(char *buf, char **start, off_t offset, int request,
  530. int *eof, void *data)
  531. {
  532. struct drm_minor *minor = (struct drm_minor *) data;
  533. struct drm_device *dev = minor->dev;
  534. int len = 0;
  535. struct drm_vma_entry *pt;
  536. struct vm_area_struct *vma;
  537. #if defined(__i386__)
  538. unsigned int pgprot;
  539. #endif
  540. if (offset > DRM_PROC_LIMIT) {
  541. *eof = 1;
  542. return 0;
  543. }
  544. *start = &buf[offset];
  545. *eof = 0;
  546. DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
  547. atomic_read(&dev->vma_count),
  548. high_memory, virt_to_phys(high_memory));
  549. list_for_each_entry(pt, &dev->vmalist, head) {
  550. if (!(vma = pt->vma))
  551. continue;
  552. DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx000",
  553. pt->pid,
  554. vma->vm_start,
  555. vma->vm_end,
  556. vma->vm_flags & VM_READ ? 'r' : '-',
  557. vma->vm_flags & VM_WRITE ? 'w' : '-',
  558. vma->vm_flags & VM_EXEC ? 'x' : '-',
  559. vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
  560. vma->vm_flags & VM_LOCKED ? 'l' : '-',
  561. vma->vm_flags & VM_IO ? 'i' : '-',
  562. vma->vm_pgoff);
  563. #if defined(__i386__)
  564. pgprot = pgprot_val(vma->vm_page_prot);
  565. DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
  566. pgprot & _PAGE_PRESENT ? 'p' : '-',
  567. pgprot & _PAGE_RW ? 'w' : 'r',
  568. pgprot & _PAGE_USER ? 'u' : 's',
  569. pgprot & _PAGE_PWT ? 't' : 'b',
  570. pgprot & _PAGE_PCD ? 'u' : 'c',
  571. pgprot & _PAGE_ACCESSED ? 'a' : '-',
  572. pgprot & _PAGE_DIRTY ? 'd' : '-',
  573. pgprot & _PAGE_PSE ? 'm' : 'k',
  574. pgprot & _PAGE_GLOBAL ? 'g' : 'l');
  575. #endif
  576. DRM_PROC_PRINT("\n");
  577. }
  578. if (len > request + offset)
  579. return request;
  580. *eof = 1;
  581. return len - offset;
  582. }
  583. static int drm_vma_info(char *buf, char **start, off_t offset, int request,
  584. int *eof, void *data)
  585. {
  586. struct drm_minor *minor = (struct drm_minor *) data;
  587. struct drm_device *dev = minor->dev;
  588. int ret;
  589. mutex_lock(&dev->struct_mutex);
  590. ret = drm__vma_info(buf, start, offset, request, eof, data);
  591. mutex_unlock(&dev->struct_mutex);
  592. return ret;
  593. }
  594. #endif