summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'xf86drm.c')
-rw-r--r--xf86drm.c2433
1 files changed, 1643 insertions, 790 deletions
diff --git a/xf86drm.c b/xf86drm.c
index 7e28b4f7..88f86ed5 100644
--- a/xf86drm.c
+++ b/xf86drm.c
@@ -1,5 +1,5 @@
1/** 1/**
2 * \file xf86drm.c 2 * \file xf86drm.c
3 * User-level interface to DRM device 3 * User-level interface to DRM device
4 * 4 *
5 * \author Rickard E. (Rik) Faith <faith@valinux.com> 5 * \author Rickard E. (Rik) Faith <faith@valinux.com>
@@ -54,8 +54,11 @@
54#include <sys/ioctl.h> 54#include <sys/ioctl.h>
55#include <sys/time.h> 55#include <sys/time.h>
56#include <stdarg.h> 56#include <stdarg.h>
57#ifdef HAVE_SYS_MKDEV_H 57#ifdef MAJOR_IN_MKDEV
58# include <sys/mkdev.h> /* defines major(), minor(), and makedev() on Solaris */ 58#include <sys/mkdev.h>
59#endif
60#ifdef MAJOR_IN_SYSMACROS
61#include <sys/sysmacros.h>
59#endif 62#endif
60#include <math.h> 63#include <math.h>
61 64
@@ -70,13 +73,13 @@
70#include "util_math.h" 73#include "util_math.h"
71 74
72#ifdef __OpenBSD__ 75#ifdef __OpenBSD__
73#define DRM_PRIMARY_MINOR_NAME "drm" 76#define DRM_PRIMARY_MINOR_NAME "drm"
74#define DRM_CONTROL_MINOR_NAME "drmC" 77#define DRM_CONTROL_MINOR_NAME "drmC"
75#define DRM_RENDER_MINOR_NAME "drmR" 78#define DRM_RENDER_MINOR_NAME "drmR"
76#else 79#else
77#define DRM_PRIMARY_MINOR_NAME "card" 80#define DRM_PRIMARY_MINOR_NAME "card"
78#define DRM_CONTROL_MINOR_NAME "controlD" 81#define DRM_CONTROL_MINOR_NAME "controlD"
79#define DRM_RENDER_MINOR_NAME "renderD" 82#define DRM_RENDER_MINOR_NAME "renderD"
80#endif 83#endif
81 84
82#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) 85#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__)
@@ -96,7 +99,23 @@
96#endif /* __OpenBSD__ */ 99#endif /* __OpenBSD__ */
97 100
98#ifndef DRM_MAJOR 101#ifndef DRM_MAJOR
99#define DRM_MAJOR 226 /* Linux */ 102#define DRM_MAJOR 226 /* Linux */
103#endif
104
105#ifdef __OpenBSD__
106struct drm_pciinfo {
107 uint16_t domain;
108 uint8_t bus;
109 uint8_t dev;
110 uint8_t func;
111 uint16_t vendor_id;
112 uint16_t device_id;
113 uint16_t subvendor_id;
114 uint16_t subdevice_id;
115 uint8_t revision_id;
116};
117
118#define DRM_IOCTL_GET_PCIINFO DRM_IOR(0x15, struct drm_pciinfo)
100#endif 119#endif
101 120
102#define DRM_MSG_VERBOSITY 3 121#define DRM_MSG_VERBOSITY 3
@@ -128,18 +147,18 @@ drmDebugPrint(const char *format, va_list ap)
128void 147void
129drmMsg(const char *format, ...) 148drmMsg(const char *format, ...)
130{ 149{
131 va_list ap; 150 va_list ap;
132 const char *env; 151 const char *env;
133 if (((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) || 152 if (((env = getenv("LIBGL_DEBUG")) && strstr(env, "verbose")) ||
134 (drm_server_info && drm_server_info->debug_print)) 153 (drm_server_info && drm_server_info->debug_print))
135 { 154 {
136 va_start(ap, format); 155 va_start(ap, format);
137 if (drm_server_info) { 156 if (drm_server_info) {
138 drm_server_info->debug_print(format,ap); 157 drm_server_info->debug_print(format,ap);
139 } else { 158 } else {
140 drmDebugPrint(format, ap); 159 drmDebugPrint(format, ap);
141 } 160 }
142 va_end(ap); 161 va_end(ap);
143 } 162 }
144} 163}
145 164
@@ -166,10 +185,10 @@ void drmFree(void *pt)
166int 185int
167drmIoctl(int fd, unsigned long request, void *arg) 186drmIoctl(int fd, unsigned long request, void *arg)
168{ 187{
169 int ret; 188 int ret;
170 189
171 do { 190 do {
172 ret = ioctl(fd, request, arg); 191 ret = ioctl(fd, request, arg);
173 } while (ret == -1 && (errno == EINTR || errno == EAGAIN)); 192 } while (ret == -1 && (errno == EINTR || errno == EAGAIN));
174 return ret; 193 return ret;
175} 194}
@@ -190,16 +209,16 @@ drmHashEntry *drmGetEntry(int fd)
190 drmHashEntry *entry; 209 drmHashEntry *entry;
191 210
192 if (!drmHashTable) 211 if (!drmHashTable)
193 drmHashTable = drmHashCreate(); 212 drmHashTable = drmHashCreate();
194 213
195 if (drmHashLookup(drmHashTable, key, &value)) { 214 if (drmHashLookup(drmHashTable, key, &value)) {
196 entry = drmMalloc(sizeof(*entry)); 215 entry = drmMalloc(sizeof(*entry));
197 entry->fd = fd; 216 entry->fd = fd;
198 entry->f = NULL; 217 entry->f = NULL;
199 entry->tagTable = drmHashCreate(); 218 entry->tagTable = drmHashCreate();
200 drmHashInsert(drmHashTable, key, entry); 219 drmHashInsert(drmHashTable, key, entry);
201 } else { 220 } else {
202 entry = value; 221 entry = value;
203 } 222 }
204 return entry; 223 return entry;
205} 224}
@@ -221,41 +240,41 @@ static int drmMatchBusID(const char *id1, const char *id2, int pci_domain_ok)
221{ 240{
222 /* First, check if the IDs are exactly the same */ 241 /* First, check if the IDs are exactly the same */
223 if (strcasecmp(id1, id2) == 0) 242 if (strcasecmp(id1, id2) == 0)
224 return 1; 243 return 1;
225 244
226 /* Try to match old/new-style PCI bus IDs. */ 245 /* Try to match old/new-style PCI bus IDs. */
227 if (strncasecmp(id1, "pci", 3) == 0) { 246 if (strncasecmp(id1, "pci", 3) == 0) {
228 unsigned int o1, b1, d1, f1; 247 unsigned int o1, b1, d1, f1;
229 unsigned int o2, b2, d2, f2; 248 unsigned int o2, b2, d2, f2;
230 int ret; 249 int ret;
231 250
232 ret = sscanf(id1, "pci:%04x:%02x:%02x.%u", &o1, &b1, &d1, &f1); 251 ret = sscanf(id1, "pci:%04x:%02x:%02x.%u", &o1, &b1, &d1, &f1);
233 if (ret != 4) { 252 if (ret != 4) {
234 o1 = 0; 253 o1 = 0;
235 ret = sscanf(id1, "PCI:%u:%u:%u", &b1, &d1, &f1); 254 ret = sscanf(id1, "PCI:%u:%u:%u", &b1, &d1, &f1);
236 if (ret != 3) 255 if (ret != 3)
237 return 0; 256 return 0;
238 } 257 }
239 258
240 ret = sscanf(id2, "pci:%04x:%02x:%02x.%u", &o2, &b2, &d2, &f2); 259 ret = sscanf(id2, "pci:%04x:%02x:%02x.%u", &o2, &b2, &d2, &f2);
241 if (ret != 4) { 260 if (ret != 4) {
242 o2 = 0; 261 o2 = 0;
243 ret = sscanf(id2, "PCI:%u:%u:%u", &b2, &d2, &f2); 262 ret = sscanf(id2, "PCI:%u:%u:%u", &b2, &d2, &f2);
244 if (ret != 3) 263 if (ret != 3)
245 return 0; 264 return 0;
246 } 265 }
247 266
248 /* If domains aren't properly supported by the kernel interface, 267 /* If domains aren't properly supported by the kernel interface,
249 * just ignore them, which sucks less than picking a totally random 268 * just ignore them, which sucks less than picking a totally random
250 * card with "open by name" 269 * card with "open by name"
251 */ 270 */
252 if (!pci_domain_ok) 271 if (!pci_domain_ok)
253 o1 = o2 = 0; 272 o1 = o2 = 0;
254 273
255 if ((o1 != o2) || (b1 != b2) || (d1 != d2) || (f1 != f2)) 274 if ((o1 != o2) || (b1 != b2) || (d1 != d2) || (f1 != f2))
256 return 0; 275 return 0;
257 else 276 else
258 return 1; 277 return 1;
259 } 278 }
260 return 0; 279 return 0;
261} 280}
@@ -277,18 +296,18 @@ static int drmMatchBusID(const char *id1, const char *id2, int pci_domain_ok)
277#if !defined(UDEV) 296#if !defined(UDEV)
278static int chown_check_return(const char *path, uid_t owner, gid_t group) 297static int chown_check_return(const char *path, uid_t owner, gid_t group)
279{ 298{
280 int rv; 299 int rv;
281 300
282 do { 301 do {
283 rv = chown(path, owner, group); 302 rv = chown(path, owner, group);
284 } while (rv != 0 && errno == EINTR); 303 } while (rv != 0 && errno == EINTR);
285 304
286 if (rv == 0) 305 if (rv == 0)
287 return 0; 306 return 0;
288 307
289 drmMsg("Failed to change owner or group for file %s! %d: %s\n", 308 drmMsg("Failed to change owner or group for file %s! %d: %s\n",
290 path, errno, strerror(errno)); 309 path, errno, strerror(errno));
291 return -1; 310 return -1;
292} 311}
293#endif 312#endif
294 313
@@ -297,7 +316,7 @@ static int chown_check_return(const char *path, uid_t owner, gid_t group)
297 * 316 *
298 * \param dev major and minor numbers of the device. 317 * \param dev major and minor numbers of the device.
299 * \param minor minor number of the device. 318 * \param minor minor number of the device.
300 * 319 *
301 * \return a file descriptor on success, or a negative value on error. 320 * \return a file descriptor on success, or a negative value on error.
302 * 321 *
303 * \internal 322 * \internal
@@ -321,99 +340,99 @@ static int drmOpenDevice(dev_t dev, int minor, int type)
321 340
322 switch (type) { 341 switch (type) {
323 case DRM_NODE_PRIMARY: 342 case DRM_NODE_PRIMARY:
324 dev_name = DRM_DEV_NAME; 343 dev_name = DRM_DEV_NAME;
325 break; 344 break;
326 case DRM_NODE_CONTROL: 345 case DRM_NODE_CONTROL:
327 dev_name = DRM_CONTROL_DEV_NAME; 346 dev_name = DRM_CONTROL_DEV_NAME;
328 break; 347 break;
329 case DRM_NODE_RENDER: 348 case DRM_NODE_RENDER:
330 dev_name = DRM_RENDER_DEV_NAME; 349 dev_name = DRM_RENDER_DEV_NAME;
331 break; 350 break;
332 default: 351 default:
333 return -EINVAL; 352 return -EINVAL;
334 }; 353 };
335 354
336 sprintf(buf, dev_name, DRM_DIR_NAME, minor); 355 sprintf(buf, dev_name, DRM_DIR_NAME, minor);
337 drmMsg("drmOpenDevice: node name is %s\n", buf); 356 drmMsg("drmOpenDevice: node name is %s\n", buf);
338 357
339 if (drm_server_info && drm_server_info->get_perms) { 358 if (drm_server_info && drm_server_info->get_perms) {
340 drm_server_info->get_perms(&serv_group, &serv_mode); 359 drm_server_info->get_perms(&serv_group, &serv_mode);
341 devmode = serv_mode ? serv_mode : DRM_DEV_MODE; 360 devmode = serv_mode ? serv_mode : DRM_DEV_MODE;
342 devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH); 361 devmode &= ~(S_IXUSR|S_IXGRP|S_IXOTH);
343 } 362 }
344 363
345#if !defined(UDEV) 364#if !defined(UDEV)
346 if (stat(DRM_DIR_NAME, &st)) { 365 if (stat(DRM_DIR_NAME, &st)) {
347 if (!isroot) 366 if (!isroot)
348 return DRM_ERR_NOT_ROOT; 367 return DRM_ERR_NOT_ROOT;
349 mkdir(DRM_DIR_NAME, DRM_DEV_DIRMODE); 368 mkdir(DRM_DIR_NAME, DRM_DEV_DIRMODE);
350 chown_check_return(DRM_DIR_NAME, 0, 0); /* root:root */ 369 chown_check_return(DRM_DIR_NAME, 0, 0); /* root:root */
351 chmod(DRM_DIR_NAME, DRM_DEV_DIRMODE); 370 chmod(DRM_DIR_NAME, DRM_DEV_DIRMODE);
352 } 371 }
353 372
354 /* Check if the device node exists and create it if necessary. */ 373 /* Check if the device node exists and create it if necessary. */
355 if (stat(buf, &st)) { 374 if (stat(buf, &st)) {
356 if (!isroot) 375 if (!isroot)
357 return DRM_ERR_NOT_ROOT; 376 return DRM_ERR_NOT_ROOT;
358 remove(buf); 377 remove(buf);
359 mknod(buf, S_IFCHR | devmode, dev); 378 mknod(buf, S_IFCHR | devmode, dev);
360 } 379 }
361 380
362 if (drm_server_info && drm_server_info->get_perms) { 381 if (drm_server_info && drm_server_info->get_perms) {
363 group = ((int)serv_group >= 0) ? serv_group : DRM_DEV_GID; 382 group = ((int)serv_group >= 0) ? serv_group : DRM_DEV_GID;
364 chown_check_return(buf, user, group); 383 chown_check_return(buf, user, group);
365 chmod(buf, devmode); 384 chmod(buf, devmode);
366 } 385 }
367#else 386#else
368 /* if we modprobed then wait for udev */ 387 /* if we modprobed then wait for udev */
369 { 388 {
370 int udev_count = 0; 389 int udev_count = 0;
371wait_for_udev: 390wait_for_udev:
372 if (stat(DRM_DIR_NAME, &st)) { 391 if (stat(DRM_DIR_NAME, &st)) {
373 usleep(20); 392 usleep(20);
374 udev_count++; 393 udev_count++;
375 394
376 if (udev_count == 50) 395 if (udev_count == 50)
377 return -1; 396 return -1;
378 goto wait_for_udev; 397 goto wait_for_udev;
379 } 398 }
380 399
381 if (stat(buf, &st)) { 400 if (stat(buf, &st)) {
382 usleep(20); 401 usleep(20);
383 udev_count++; 402 udev_count++;
384 403
385 if (udev_count == 50) 404 if (udev_count == 50)
386 return -1; 405 return -1;
387 goto wait_for_udev; 406 goto wait_for_udev;
388 } 407 }
389 } 408 }
390#endif 409#endif
391 410
392 fd = open(buf, O_RDWR, 0); 411 fd = open(buf, O_RDWR, 0);
393 drmMsg("drmOpenDevice: open result is %d, (%s)\n", 412 drmMsg("drmOpenDevice: open result is %d, (%s)\n",
394 fd, fd < 0 ? strerror(errno) : "OK"); 413 fd, fd < 0 ? strerror(errno) : "OK");
395 if (fd >= 0) 414 if (fd >= 0)
396 return fd; 415 return fd;
397 416
398#if !defined(UDEV) 417#if !defined(UDEV)
399 /* Check if the device node is not what we expect it to be, and recreate it 418 /* Check if the device node is not what we expect it to be, and recreate it
400 * and try again if so. 419 * and try again if so.
401 */ 420 */
402 if (st.st_rdev != dev) { 421 if (st.st_rdev != dev) {
403 if (!isroot) 422 if (!isroot)
404 return DRM_ERR_NOT_ROOT; 423 return DRM_ERR_NOT_ROOT;
405 remove(buf); 424 remove(buf);
406 mknod(buf, S_IFCHR | devmode, dev); 425 mknod(buf, S_IFCHR | devmode, dev);
407 if (drm_server_info && drm_server_info->get_perms) { 426 if (drm_server_info && drm_server_info->get_perms) {
408 chown_check_return(buf, user, group); 427 chown_check_return(buf, user, group);
409 chmod(buf, devmode); 428 chmod(buf, devmode);
410 } 429 }
411 } 430 }
412 fd = open(buf, O_RDWR, 0); 431 fd = open(buf, O_RDWR, 0);
413 drmMsg("drmOpenDevice: open result is %d, (%s)\n", 432 drmMsg("drmOpenDevice: open result is %d, (%s)\n",
414 fd, fd < 0 ? strerror(errno) : "OK"); 433 fd, fd < 0 ? strerror(errno) : "OK");
415 if (fd >= 0) 434 if (fd >= 0)
416 return fd; 435 return fd;
417 436
418 drmMsg("drmOpenDevice: Open failed\n"); 437 drmMsg("drmOpenDevice: Open failed\n");
419 remove(buf); 438 remove(buf);
@@ -429,7 +448,7 @@ wait_for_udev:
429 * \param create allow to create the device if set. 448 * \param create allow to create the device if set.
430 * 449 *
431 * \return a file descriptor on success, or a negative value on error. 450 * \return a file descriptor on success, or a negative value on error.
432 * 451 *
433 * \internal 452 * \internal
434 * Calls drmOpenDevice() if \p create is set, otherwise assembles the device 453 * Calls drmOpenDevice() if \p create is set, otherwise assembles the device
435 * name from \p minor and opens it. 454 * name from \p minor and opens it.
@@ -439,37 +458,37 @@ static int drmOpenMinor(int minor, int create, int type)
439 int fd; 458 int fd;
440 char buf[64]; 459 char buf[64];
441 const char *dev_name; 460 const char *dev_name;
442 461
443 if (create) 462 if (create)
444 return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type); 463 return drmOpenDevice(makedev(DRM_MAJOR, minor), minor, type);
445 464
446 switch (type) { 465 switch (type) {
447 case DRM_NODE_PRIMARY: 466 case DRM_NODE_PRIMARY:
448 dev_name = DRM_DEV_NAME; 467 dev_name = DRM_DEV_NAME;
449 break; 468 break;
450 case DRM_NODE_CONTROL: 469 case DRM_NODE_CONTROL:
451 dev_name = DRM_CONTROL_DEV_NAME; 470 dev_name = DRM_CONTROL_DEV_NAME;
452 break; 471 break;
453 case DRM_NODE_RENDER: 472 case DRM_NODE_RENDER:
454 dev_name = DRM_RENDER_DEV_NAME; 473 dev_name = DRM_RENDER_DEV_NAME;
455 break; 474 break;
456 default: 475 default:
457 return -EINVAL; 476 return -EINVAL;
458 }; 477 };
459 478
460 sprintf(buf, dev_name, DRM_DIR_NAME, minor); 479 sprintf(buf, dev_name, DRM_DIR_NAME, minor);
461 if ((fd = open(buf, O_RDWR, 0)) >= 0) 480 if ((fd = open(buf, O_RDWR, 0)) >= 0)
462 return fd; 481 return fd;
463 return -errno; 482 return -errno;
464} 483}
465 484
466 485
467/** 486/**
468 * Determine whether the DRM kernel driver has been loaded. 487 * Determine whether the DRM kernel driver has been loaded.
469 * 488 *
470 * \return 1 if the DRM driver is loaded, 0 otherwise. 489 * \return 1 if the DRM driver is loaded, 0 otherwise.
471 * 490 *
472 * \internal 491 * \internal
473 * Determine the presence of the kernel driver by attempting to open the 0 492 * Determine the presence of the kernel driver by attempting to open the 0
474 * minor and get version information. For backward compatibility with older 493 * minor and get version information. For backward compatibility with older
475 * Linux implementations, /proc/dri is also checked. 494 * Linux implementations, /proc/dri is also checked.
@@ -482,16 +501,16 @@ int drmAvailable(void)
482 501
483 if ((fd = drmOpenMinor(0, 1, DRM_NODE_PRIMARY)) < 0) { 502 if ((fd = drmOpenMinor(0, 1, DRM_NODE_PRIMARY)) < 0) {
484#ifdef __linux__ 503#ifdef __linux__
485 /* Try proc for backward Linux compatibility */ 504 /* Try proc for backward Linux compatibility */
486 if (!access("/proc/dri/0", R_OK)) 505 if (!access("/proc/dri/0", R_OK))
487 return 1; 506 return 1;
488#endif 507#endif
489 return 0; 508 return 0;
490 } 509 }
491 510
492 if ((version = drmGetVersion(fd))) { 511 if ((version = drmGetVersion(fd))) {
493 retval = 1; 512 retval = 1;
494 drmFreeVersion(version); 513 drmFreeVersion(version);
495 } 514 }
496 close(fd); 515 close(fd);
497 516
@@ -570,37 +589,37 @@ static int drmOpenByBusid(const char *busid, int type)
570 589
571 drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid); 590 drmMsg("drmOpenByBusid: Searching for BusID %s\n", busid);
572 for (i = base; i < base + DRM_MAX_MINOR; i++) { 591 for (i = base; i < base + DRM_MAX_MINOR; i++) {
573 fd = drmOpenMinor(i, 1, type); 592 fd = drmOpenMinor(i, 1, type);
574 drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd); 593 drmMsg("drmOpenByBusid: drmOpenMinor returns %d\n", fd);
575 if (fd >= 0) { 594 if (fd >= 0) {
576 /* We need to try for 1.4 first for proper PCI domain support 595 /* We need to try for 1.4 first for proper PCI domain support
577 * and if that fails, we know the kernel is busted 596 * and if that fails, we know the kernel is busted
578 */ 597 */
579 sv.drm_di_major = 1; 598 sv.drm_di_major = 1;
580 sv.drm_di_minor = 4; 599 sv.drm_di_minor = 4;
581 sv.drm_dd_major = -1; /* Don't care */ 600 sv.drm_dd_major = -1; /* Don't care */
582 sv.drm_dd_minor = -1; /* Don't care */ 601 sv.drm_dd_minor = -1; /* Don't care */
583 if (drmSetInterfaceVersion(fd, &sv)) { 602 if (drmSetInterfaceVersion(fd, &sv)) {
584#ifndef __alpha__ 603#ifndef __alpha__
585 pci_domain_ok = 0; 604 pci_domain_ok = 0;
586#endif 605#endif
587 sv.drm_di_major = 1; 606 sv.drm_di_major = 1;
588 sv.drm_di_minor = 1; 607 sv.drm_di_minor = 1;
589 sv.drm_dd_major = -1; /* Don't care */ 608 sv.drm_dd_major = -1; /* Don't care */
590 sv.drm_dd_minor = -1; /* Don't care */ 609 sv.drm_dd_minor = -1; /* Don't care */
591 drmMsg("drmOpenByBusid: Interface 1.4 failed, trying 1.1\n"); 610 drmMsg("drmOpenByBusid: Interface 1.4 failed, trying 1.1\n");
592 drmSetInterfaceVersion(fd, &sv); 611 drmSetInterfaceVersion(fd, &sv);
593 } 612 }
594 buf = drmGetBusid(fd); 613 buf = drmGetBusid(fd);
595 drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf); 614 drmMsg("drmOpenByBusid: drmGetBusid reports %s\n", buf);
596 if (buf && drmMatchBusID(buf, busid, pci_domain_ok)) { 615 if (buf && drmMatchBusID(buf, busid, pci_domain_ok)) {
597 drmFreeBusid(buf); 616 drmFreeBusid(buf);
598 return fd; 617 return fd;
599 } 618 }
600 if (buf) 619 if (buf)
601 drmFreeBusid(buf); 620 drmFreeBusid(buf);
602 close(fd); 621 close(fd);
603 } 622 }
604 } 623 }
605 return -1; 624 return -1;
606} 625}
@@ -611,14 +630,14 @@ static int drmOpenByBusid(const char *busid, int type)
611 * 630 *
612 * \param name driver name. 631 * \param name driver name.
613 * \param type the device node type. 632 * \param type the device node type.
614 * 633 *
615 * \return a file descriptor on success, or a negative value on error. 634 * \return a file descriptor on success, or a negative value on error.
616 * 635 *
617 * \internal 636 * \internal
618 * This function opens the first minor number that matches the driver name and 637 * This function opens the first minor number that matches the driver name and
619 * isn't already in use. If it's in use it then it will already have a bus ID 638 * isn't already in use. If it's in use it then it will already have a bus ID
620 * assigned. 639 * assigned.
621 * 640 *
622 * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid(). 641 * \sa drmOpenMinor(), drmGetVersion() and drmGetBusid().
623 */ 642 */
624static int drmOpenByName(const char *name, int type) 643static int drmOpenByName(const char *name, int type)
@@ -637,56 +656,56 @@ static int drmOpenByName(const char *name, int type)
637 * already in use. If it's in use it will have a busid assigned already. 656 * already in use. If it's in use it will have a busid assigned already.
638 */ 657 */
639 for (i = base; i < base + DRM_MAX_MINOR; i++) { 658 for (i = base; i < base + DRM_MAX_MINOR; i++) {
640 if ((fd = drmOpenMinor(i, 1, type)) >= 0) { 659 if ((fd = drmOpenMinor(i, 1, type)) >= 0) {
641 if ((version = drmGetVersion(fd))) { 660 if ((version = drmGetVersion(fd))) {
642 if (!strcmp(version->name, name)) { 661 if (!strcmp(version->name, name)) {
643 drmFreeVersion(version); 662 drmFreeVersion(version);
644 id = drmGetBusid(fd); 663 id = drmGetBusid(fd);
645 drmMsg("drmGetBusid returned '%s'\n", id ? id : "NULL"); 664 drmMsg("drmGetBusid returned '%s'\n", id ? id : "NULL");
646 if (!id || !*id) { 665 if (!id || !*id) {
647 if (id) 666 if (id)
648 drmFreeBusid(id); 667 drmFreeBusid(id);
649 return fd; 668 return fd;
650 } else { 669 } else {
651 drmFreeBusid(id); 670 drmFreeBusid(id);
652 } 671 }
653 } else { 672 } else {
654 drmFreeVersion(version); 673 drmFreeVersion(version);
655 } 674 }
656 } 675 }
657 close(fd); 676 close(fd);
658 } 677 }
659 } 678 }
660 679
661#ifdef __linux__ 680#ifdef __linux__
662 /* Backward-compatibility /proc support */ 681 /* Backward-compatibility /proc support */
663 for (i = 0; i < 8; i++) { 682 for (i = 0; i < 8; i++) {
664 char proc_name[64], buf[512]; 683 char proc_name[64], buf[512];
665 char *driver, *pt, *devstring; 684 char *driver, *pt, *devstring;
666 int retcode; 685 int retcode;
667 686
668 sprintf(proc_name, "/proc/dri/%d/name", i); 687 sprintf(proc_name, "/proc/dri/%d/name", i);
669 if ((fd = open(proc_name, 0, 0)) >= 0) { 688 if ((fd = open(proc_name, 0, 0)) >= 0) {
670 retcode = read(fd, buf, sizeof(buf)-1); 689 retcode = read(fd, buf, sizeof(buf)-1);
671 close(fd); 690 close(fd);
672 if (retcode) { 691 if (retcode) {
673 buf[retcode-1] = '\0'; 692 buf[retcode-1] = '\0';
674 for (driver = pt = buf; *pt && *pt != ' '; ++pt) 693 for (driver = pt = buf; *pt && *pt != ' '; ++pt)
675 ; 694 ;
676 if (*pt) { /* Device is next */ 695 if (*pt) { /* Device is next */
677 *pt = '\0'; 696 *pt = '\0';
678 if (!strcmp(driver, name)) { /* Match */ 697 if (!strcmp(driver, name)) { /* Match */
679 for (devstring = ++pt; *pt && *pt != ' '; ++pt) 698 for (devstring = ++pt; *pt && *pt != ' '; ++pt)
680 ; 699 ;
681 if (*pt) { /* Found busid */ 700 if (*pt) { /* Found busid */
682 return drmOpenByBusid(++pt, type); 701 return drmOpenByBusid(++pt, type);
683 } else { /* No busid */ 702 } else { /* No busid */
684 return drmOpenDevice(strtol(devstring, NULL, 0),i, type); 703 return drmOpenDevice(strtol(devstring, NULL, 0),i, type);
685 } 704 }
686 } 705 }
687 } 706 }
688 } 707 }
689 } 708 }
690 } 709 }
691#endif 710#endif
692 711
@@ -702,9 +721,9 @@ static int drmOpenByName(const char *name, int type)
702 * 721 *
703 * \param name driver name. Not referenced if bus ID is supplied. 722 * \param name driver name. Not referenced if bus ID is supplied.
704 * \param busid bus ID. Zero if not known. 723 * \param busid bus ID. Zero if not known.
705 * 724 *
706 * \return a file descriptor on success, or a negative value on error. 725 * \return a file descriptor on success, or a negative value on error.
707 * 726 *
708 * \internal 727 * \internal
709 * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName() 728 * It calls drmOpenByBusid() if \p busid is specified or drmOpenByName()
710 * otherwise. 729 * otherwise.
@@ -734,21 +753,21 @@ int drmOpenWithType(const char *name, const char *busid, int type)
734{ 753{
735 if (!drmAvailable() && name != NULL && drm_server_info && 754 if (!drmAvailable() && name != NULL && drm_server_info &&
736 drm_server_info->load_module) { 755 drm_server_info->load_module) {
737 /* try to load the kernel module */ 756 /* try to load the kernel module */
738 if (!drm_server_info->load_module(name)) { 757 if (!drm_server_info->load_module(name)) {
739 drmMsg("[drm] failed to load kernel module \"%s\"\n", name); 758 drmMsg("[drm] failed to load kernel module \"%s\"\n", name);
740 return -1; 759 return -1;
741 } 760 }
742 } 761 }
743 762
744 if (busid) { 763 if (busid) {
745 int fd = drmOpenByBusid(busid, type); 764 int fd = drmOpenByBusid(busid, type);
746 if (fd >= 0) 765 if (fd >= 0)
747 return fd; 766 return fd;
748 } 767 }
749 768
750 if (name) 769 if (name)
751 return drmOpenByName(name, type); 770 return drmOpenByName(name, type);
752 771
753 return -1; 772 return -1;
754} 773}
@@ -775,7 +794,7 @@ int drmOpenRender(int minor)
775void drmFreeVersion(drmVersionPtr v) 794void drmFreeVersion(drmVersionPtr v)
776{ 795{
777 if (!v) 796 if (!v)
778 return; 797 return;
779 drmFree(v->name); 798 drmFree(v->name);
780 drmFree(v->date); 799 drmFree(v->date);
781 drmFree(v->desc); 800 drmFree(v->desc);
@@ -795,7 +814,7 @@ void drmFreeVersion(drmVersionPtr v)
795static void drmFreeKernelVersion(drm_version_t *v) 814static void drmFreeKernelVersion(drm_version_t *v)
796{ 815{
797 if (!v) 816 if (!v)
798 return; 817 return;
799 drmFree(v->name); 818 drmFree(v->name);
800 drmFree(v->date); 819 drmFree(v->date);
801 drmFree(v->desc); 820 drmFree(v->desc);
@@ -805,10 +824,10 @@ static void drmFreeKernelVersion(drm_version_t *v)
805 824
806/** 825/**
807 * Copy version information. 826 * Copy version information.
808 * 827 *
809 * \param d destination pointer. 828 * \param d destination pointer.
810 * \param s source pointer. 829 * \param s source pointer.
811 * 830 *
812 * \internal 831 * \internal
813 * Used by drmGetVersion() to translate the information returned by the ioctl 832 * Used by drmGetVersion() to translate the information returned by the ioctl
814 * interface in a private structure into the public structure counterpart. 833 * interface in a private structure into the public structure counterpart.
@@ -831,12 +850,12 @@ static void drmCopyVersion(drmVersionPtr d, const drm_version_t *s)
831 * Query the driver version information. 850 * Query the driver version information.
832 * 851 *
833 * \param fd file descriptor. 852 * \param fd file descriptor.
834 * 853 *
835 * \return pointer to a drmVersion structure which should be freed with 854 * \return pointer to a drmVersion structure which should be freed with
836 * drmFreeVersion(). 855 * drmFreeVersion().
837 * 856 *
838 * \note Similar information is available via /proc/dri. 857 * \note Similar information is available via /proc/dri.
839 * 858 *
840 * \internal 859 * \internal
841 * It gets the version information via successive DRM_IOCTL_VERSION ioctls, 860 * It gets the version information via successive DRM_IOCTL_VERSION ioctls,
842 * first with zeros to get the string lengths, and then the actually strings. 861 * first with zeros to get the string lengths, and then the actually strings.
@@ -850,21 +869,21 @@ drmVersionPtr drmGetVersion(int fd)
850 memclear(*version); 869 memclear(*version);
851 870
852 if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) { 871 if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
853 drmFreeKernelVersion(version); 872 drmFreeKernelVersion(version);
854 return NULL; 873 return NULL;
855 } 874 }
856 875
857 if (version->name_len) 876 if (version->name_len)
858 version->name = drmMalloc(version->name_len + 1); 877 version->name = drmMalloc(version->name_len + 1);
859 if (version->date_len) 878 if (version->date_len)
860 version->date = drmMalloc(version->date_len + 1); 879 version->date = drmMalloc(version->date_len + 1);
861 if (version->desc_len) 880 if (version->desc_len)
862 version->desc = drmMalloc(version->desc_len + 1); 881 version->desc = drmMalloc(version->desc_len + 1);
863 882
864 if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) { 883 if (drmIoctl(fd, DRM_IOCTL_VERSION, version)) {
865 drmMsg("DRM_IOCTL_VERSION: %s\n", strerror(errno)); 884 drmMsg("DRM_IOCTL_VERSION: %s\n", strerror(errno));
866 drmFreeKernelVersion(version); 885 drmFreeKernelVersion(version);
867 return NULL; 886 return NULL;
868 } 887 }
869 888
870 /* The results might not be null-terminated strings, so terminate them. */ 889 /* The results might not be null-terminated strings, so terminate them. */
@@ -881,13 +900,13 @@ drmVersionPtr drmGetVersion(int fd)
881 900
882/** 901/**
883 * Get version information for the DRM user space library. 902 * Get version information for the DRM user space library.
884 * 903 *
885 * This version number is driver independent. 904 * This version number is driver independent.
886 * 905 *
887 * \param fd file descriptor. 906 * \param fd file descriptor.
888 * 907 *
889 * \return version information. 908 * \return version information.
890 * 909 *
891 * \internal 910 * \internal
892 * This function allocates and fills a drm_version structure with a hard coded 911 * This function allocates and fills a drm_version structure with a hard coded
893 * version number. 912 * version number.
@@ -915,29 +934,29 @@ drmVersionPtr drmGetLibVersion(int fd)
915 934
916int drmGetCap(int fd, uint64_t capability, uint64_t *value) 935int drmGetCap(int fd, uint64_t capability, uint64_t *value)
917{ 936{
918 struct drm_get_cap cap; 937 struct drm_get_cap cap;
919 int ret; 938 int ret;
920 939
921 memclear(cap); 940 memclear(cap);
922 cap.capability = capability; 941 cap.capability = capability;
923 942
924 ret = drmIoctl(fd, DRM_IOCTL_GET_CAP, &cap); 943 ret = drmIoctl(fd, DRM_IOCTL_GET_CAP, &cap);
925 if (ret) 944 if (ret)
926 return ret; 945 return ret;
927 946
928 *value = cap.value; 947 *value = cap.value;
929 return 0; 948 return 0;
930} 949}
931 950
932int drmSetClientCap(int fd, uint64_t capability, uint64_t value) 951int drmSetClientCap(int fd, uint64_t capability, uint64_t value)
933{ 952{
934 struct drm_set_client_cap cap; 953 struct drm_set_client_cap cap;
935 954
936 memclear(cap); 955 memclear(cap);
937 cap.capability = capability; 956 cap.capability = capability;
938 cap.value = value; 957 cap.value = value;
939 958
940 return drmIoctl(fd, DRM_IOCTL_SET_CLIENT_CAP, &cap); 959 return drmIoctl(fd, DRM_IOCTL_SET_CLIENT_CAP, &cap);
941} 960}
942 961
943/** 962/**
@@ -973,10 +992,10 @@ char *drmGetBusid(int fd)
973 memclear(u); 992 memclear(u);
974 993
975 if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) 994 if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
976 return NULL; 995 return NULL;
977 u.unique = drmMalloc(u.unique_len + 1); 996 u.unique = drmMalloc(u.unique_len + 1);
978 if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u)) 997 if (drmIoctl(fd, DRM_IOCTL_GET_UNIQUE, &u))
979 return NULL; 998 return NULL;
980 u.unique[u.unique_len] = '\0'; 999 u.unique[u.unique_len] = '\0';
981 1000
982 return u.unique; 1001 return u.unique;
@@ -1004,7 +1023,7 @@ int drmSetBusid(int fd, const char *busid)
1004 u.unique_len = strlen(busid); 1023 u.unique_len = strlen(busid);
1005 1024
1006 if (drmIoctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) { 1025 if (drmIoctl(fd, DRM_IOCTL_SET_UNIQUE, &u)) {
1007 return -errno; 1026 return -errno;
1008 } 1027 }
1009 return 0; 1028 return 0;
1010} 1029}
@@ -1017,7 +1036,7 @@ int drmGetMagic(int fd, drm_magic_t * magic)
1017 1036
1018 *magic = 0; 1037 *magic = 0;
1019 if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth)) 1038 if (drmIoctl(fd, DRM_IOCTL_GET_MAGIC, &auth))
1020 return -errno; 1039 return -errno;
1021 *magic = auth.magic; 1040 *magic = auth.magic;
1022 return 0; 1041 return 0;
1023} 1042}
@@ -1029,7 +1048,7 @@ int drmAuthMagic(int fd, drm_magic_t magic)
1029 memclear(auth); 1048 memclear(auth);
1030 auth.magic = magic; 1049 auth.magic = magic;
1031 if (drmIoctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth)) 1050 if (drmIoctl(fd, DRM_IOCTL_AUTH_MAGIC, &auth))
1032 return -errno; 1051 return -errno;
1033 return 0; 1052 return 0;
1034} 1053}
1035 1054
@@ -1045,7 +1064,7 @@ int drmAuthMagic(int fd, drm_magic_t magic)
1045 * \param flags combination of several flags to modify the function actions. 1064 * \param flags combination of several flags to modify the function actions.
1046 * \param handle will be set to a value that may be used as the offset 1065 * \param handle will be set to a value that may be used as the offset
1047 * parameter for mmap(). 1066 * parameter for mmap().
1048 * 1067 *
1049 * \return zero on success or a negative value on error. 1068 * \return zero on success or a negative value on error.
1050 * 1069 *
1051 * \par Mapping the frame buffer 1070 * \par Mapping the frame buffer
@@ -1056,7 +1075,7 @@ int drmAuthMagic(int fd, drm_magic_t magic)
1056 * 1075 *
1057 * \par 1076 * \par
1058 * The area mapped will be uncached. If MTRR support is available in the 1077 * The area mapped will be uncached. If MTRR support is available in the
1059 * kernel, the frame buffer area will be set to write combining. 1078 * kernel, the frame buffer area will be set to write combining.
1060 * 1079 *
1061 * \par Mapping the MMIO register area 1080 * \par Mapping the MMIO register area
1062 * For the MMIO register area, 1081 * For the MMIO register area,
@@ -1064,19 +1083,19 @@ int drmAuthMagic(int fd, drm_magic_t magic)
1064 * - \p size will be the size of the register area bytes, and 1083 * - \p size will be the size of the register area bytes, and
1065 * - \p type will be DRM_REGISTERS. 1084 * - \p type will be DRM_REGISTERS.
1066 * \par 1085 * \par
1067 * The area mapped will be uncached. 1086 * The area mapped will be uncached.
1068 * 1087 *
1069 * \par Mapping the SAREA 1088 * \par Mapping the SAREA
1070 * For the SAREA, 1089 * For the SAREA,
1071 * - \p offset will be ignored and should be set to zero, 1090 * - \p offset will be ignored and should be set to zero,
1072 * - \p size will be the desired size of the SAREA in bytes, 1091 * - \p size will be the desired size of the SAREA in bytes,
1073 * - \p type will be DRM_SHM. 1092 * - \p type will be DRM_SHM.
1074 * 1093 *
1075 * \par 1094 * \par
1076 * A shared memory area of the requested size will be created and locked in 1095 * A shared memory area of the requested size will be created and locked in
1077 * kernel memory. This area may be mapped into client-space by using the handle 1096 * kernel memory. This area may be mapped into client-space by using the handle
1078 * returned. 1097 * returned.
1079 * 1098 *
1080 * \note May only be called by root. 1099 * \note May only be called by root.
1081 * 1100 *
1082 * \internal 1101 * \internal
@@ -1084,7 +1103,7 @@ int drmAuthMagic(int fd, drm_magic_t magic)
1084 * the arguments in a drm_map structure. 1103 * the arguments in a drm_map structure.
1085 */ 1104 */
1086int drmAddMap(int fd, drm_handle_t offset, drmSize size, drmMapType type, 1105int drmAddMap(int fd, drm_handle_t offset, drmSize size, drmMapType type,
1087 drmMapFlags flags, drm_handle_t *handle) 1106 drmMapFlags flags, drm_handle_t *handle)
1088{ 1107{
1089 drm_map_t map; 1108 drm_map_t map;
1090 1109
@@ -1094,9 +1113,9 @@ int drmAddMap(int fd, drm_handle_t offset, drmSize size, drmMapType type,
1094 map.type = type; 1113 map.type = type;
1095 map.flags = flags; 1114 map.flags = flags;
1096 if (drmIoctl(fd, DRM_IOCTL_ADD_MAP, &map)) 1115 if (drmIoctl(fd, DRM_IOCTL_ADD_MAP, &map))
1097 return -errno; 1116 return -errno;
1098 if (handle) 1117 if (handle)
1099 *handle = (drm_handle_t)(uintptr_t)map.handle; 1118 *handle = (drm_handle_t)(uintptr_t)map.handle;
1100 return 0; 1119 return 0;
1101} 1120}
1102 1121
@@ -1108,18 +1127,18 @@ int drmRmMap(int fd, drm_handle_t handle)
1108 map.handle = (void *)(uintptr_t)handle; 1127 map.handle = (void *)(uintptr_t)handle;
1109 1128
1110 if(drmIoctl(fd, DRM_IOCTL_RM_MAP, &map)) 1129 if(drmIoctl(fd, DRM_IOCTL_RM_MAP, &map))
1111 return -errno; 1130 return -errno;
1112 return 0; 1131 return 0;
1113} 1132}
1114 1133
1115/** 1134/**
1116 * Make buffers available for DMA transfers. 1135 * Make buffers available for DMA transfers.
1117 * 1136 *
1118 * \param fd file descriptor. 1137 * \param fd file descriptor.
1119 * \param count number of buffers. 1138 * \param count number of buffers.
1120 * \param size size of each buffer. 1139 * \param size size of each buffer.
1121 * \param flags buffer allocation flags. 1140 * \param flags buffer allocation flags.
1122 * \param agp_offset offset in the AGP aperture 1141 * \param agp_offset offset in the AGP aperture
1123 * 1142 *
1124 * \return number of buffers allocated, negative on error. 1143 * \return number of buffers allocated, negative on error.
1125 * 1144 *
@@ -1129,7 +1148,7 @@ int drmRmMap(int fd, drm_handle_t handle)
1129 * \sa drm_buf_desc. 1148 * \sa drm_buf_desc.
1130 */ 1149 */
1131int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags, 1150int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
1132 int agp_offset) 1151 int agp_offset)
1133{ 1152{
1134 drm_buf_desc_t request; 1153 drm_buf_desc_t request;
1135 1154
@@ -1140,7 +1159,7 @@ int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags,
1140 request.agp_start = agp_offset; 1159 request.agp_start = agp_offset;
1141 1160
1142 if (drmIoctl(fd, DRM_IOCTL_ADD_BUFS, &request)) 1161 if (drmIoctl(fd, DRM_IOCTL_ADD_BUFS, &request))
1143 return -errno; 1162 return -errno;
1144 return request.count; 1163 return request.count;
1145} 1164}
1146 1165
@@ -1152,28 +1171,28 @@ int drmMarkBufs(int fd, double low, double high)
1152 memclear(info); 1171 memclear(info);
1153 1172
1154 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) 1173 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
1155 return -EINVAL; 1174 return -EINVAL;
1156 1175
1157 if (!info.count) 1176 if (!info.count)
1158 return -EINVAL; 1177 return -EINVAL;
1159 1178
1160 if (!(info.list = drmMalloc(info.count * sizeof(*info.list)))) 1179 if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
1161 return -ENOMEM; 1180 return -ENOMEM;
1162 1181
1163 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) { 1182 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
1164 int retval = -errno; 1183 int retval = -errno;
1165 drmFree(info.list); 1184 drmFree(info.list);
1166 return retval; 1185 return retval;
1167 } 1186 }
1168 1187
1169 for (i = 0; i < info.count; i++) { 1188 for (i = 0; i < info.count; i++) {
1170 info.list[i].low_mark = low * info.list[i].count; 1189 info.list[i].low_mark = low * info.list[i].count;
1171 info.list[i].high_mark = high * info.list[i].count; 1190 info.list[i].high_mark = high * info.list[i].count;
1172 if (drmIoctl(fd, DRM_IOCTL_MARK_BUFS, &info.list[i])) { 1191 if (drmIoctl(fd, DRM_IOCTL_MARK_BUFS, &info.list[i])) {
1173 int retval = -errno; 1192 int retval = -errno;
1174 drmFree(info.list); 1193 drmFree(info.list);
1175 return retval; 1194 return retval;
1176 } 1195 }
1177 } 1196 }
1178 drmFree(info.list); 1197 drmFree(info.list);
1179 1198
@@ -1188,9 +1207,9 @@ int drmMarkBufs(int fd, double low, double high)
1188 * \param list list of buffers to be freed. 1207 * \param list list of buffers to be freed.
1189 * 1208 *
1190 * \return zero on success, or a negative value on failure. 1209 * \return zero on success, or a negative value on failure.
1191 * 1210 *
1192 * \note This function is primarily used for debugging. 1211 * \note This function is primarily used for debugging.
1193 * 1212 *
1194 * \internal 1213 * \internal
1195 * This function is a wrapper around the DRM_IOCTL_FREE_BUFS ioctl, passing 1214 * This function is a wrapper around the DRM_IOCTL_FREE_BUFS ioctl, passing
1196 * the arguments in a drm_buf_free structure. 1215 * the arguments in a drm_buf_free structure.
@@ -1203,7 +1222,7 @@ int drmFreeBufs(int fd, int count, int *list)
1203 request.count = count; 1222 request.count = count;
1204 request.list = list; 1223 request.list = list;
1205 if (drmIoctl(fd, DRM_IOCTL_FREE_BUFS, &request)) 1224 if (drmIoctl(fd, DRM_IOCTL_FREE_BUFS, &request))
1206 return -errno; 1225 return -errno;
1207 return 0; 1226 return 0;
1208} 1227}
1209 1228
@@ -1243,7 +1262,7 @@ int drmClose(int fd)
1243 * begins. 1262 * begins.
1244 * 1263 *
1245 * \return zero on success, or a negative value on failure. 1264 * \return zero on success, or a negative value on failure.
1246 * 1265 *
1247 * \internal 1266 * \internal
1248 * This function is a wrapper for mmap(). 1267 * This function is a wrapper for mmap().
1249 */ 1268 */
@@ -1252,16 +1271,16 @@ int drmMap(int fd, drm_handle_t handle, drmSize size, drmAddressPtr address)
1252 static unsigned long pagesize_mask = 0; 1271 static unsigned long pagesize_mask = 0;
1253 1272
1254 if (fd < 0) 1273 if (fd < 0)
1255 return -EINVAL; 1274 return -EINVAL;
1256 1275
1257 if (!pagesize_mask) 1276 if (!pagesize_mask)
1258 pagesize_mask = getpagesize() - 1; 1277 pagesize_mask = getpagesize() - 1;
1259 1278
1260 size = (size + pagesize_mask) & ~pagesize_mask; 1279 size = (size + pagesize_mask) & ~pagesize_mask;
1261 1280
1262 *address = drm_mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle); 1281 *address = drm_mmap(0, size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, handle);
1263 if (*address == MAP_FAILED) 1282 if (*address == MAP_FAILED)
1264 return -errno; 1283 return -errno;
1265 return 0; 1284 return 0;
1266} 1285}
1267 1286
@@ -1271,7 +1290,7 @@ int drmMap(int fd, drm_handle_t handle, drmSize size, drmAddressPtr address)
1271 * 1290 *
1272 * \param address address as given by drmMap(). 1291 * \param address address as given by drmMap().
1273 * \param size size in bytes. Must match the size used by drmMap(). 1292 * \param size size in bytes. Must match the size used by drmMap().
1274 * 1293 *
1275 * \return zero on success, or a negative value on failure. 1294 * \return zero on success, or a negative value on failure.
1276 * 1295 *
1277 * \internal 1296 * \internal
@@ -1291,28 +1310,28 @@ drmBufInfoPtr drmGetBufInfo(int fd)
1291 memclear(info); 1310 memclear(info);
1292 1311
1293 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) 1312 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info))
1294 return NULL; 1313 return NULL;
1295 1314
1296 if (info.count) { 1315 if (info.count) {
1297 if (!(info.list = drmMalloc(info.count * sizeof(*info.list)))) 1316 if (!(info.list = drmMalloc(info.count * sizeof(*info.list))))
1298 return NULL; 1317 return NULL;
1299 1318
1300 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) { 1319 if (drmIoctl(fd, DRM_IOCTL_INFO_BUFS, &info)) {
1301 drmFree(info.list); 1320 drmFree(info.list);
1302 return NULL; 1321 return NULL;
1303 } 1322 }
1304 1323
1305 retval = drmMalloc(sizeof(*retval)); 1324 retval = drmMalloc(sizeof(*retval));
1306 retval->count = info.count; 1325 retval->count = info.count;
1307 retval->list = drmMalloc(info.count * sizeof(*retval->list)); 1326 retval->list = drmMalloc(info.count * sizeof(*retval->list));
1308 for (i = 0; i < info.count; i++) { 1327 for (i = 0; i < info.count; i++) {
1309 retval->list[i].count = info.list[i].count; 1328 retval->list[i].count = info.list[i].count;
1310 retval->list[i].size = info.list[i].size; 1329 retval->list[i].size = info.list[i].size;
1311 retval->list[i].low_mark = info.list[i].low_mark; 1330 retval->list[i].low_mark = info.list[i].low_mark;
1312 retval->list[i].high_mark = info.list[i].high_mark; 1331 retval->list[i].high_mark = info.list[i].high_mark;
1313 } 1332 }
1314 drmFree(info.list); 1333 drmFree(info.list);
1315 return retval; 1334 return retval;
1316 } 1335 }
1317 return NULL; 1336 return NULL;
1318} 1337}
@@ -1326,12 +1345,12 @@ drmBufInfoPtr drmGetBufInfo(int fd)
1326 * 1345 *
1327 * \note The client may not use these buffers until obtaining buffer indices 1346 * \note The client may not use these buffers until obtaining buffer indices
1328 * with drmDMA(). 1347 * with drmDMA().
1329 * 1348 *
1330 * \internal 1349 * \internal
1331 * This function calls the DRM_IOCTL_MAP_BUFS ioctl and copies the returned 1350 * This function calls the DRM_IOCTL_MAP_BUFS ioctl and copies the returned
1332 * information about the buffers in a drm_buf_map structure into the 1351 * information about the buffers in a drm_buf_map structure into the
1333 * client-visible data structures. 1352 * client-visible data structures.
1334 */ 1353 */
1335drmBufMapPtr drmMapBufs(int fd) 1354drmBufMapPtr drmMapBufs(int fd)
1336{ 1355{
1337 drm_buf_map_t bufs; 1356 drm_buf_map_t bufs;
@@ -1340,32 +1359,31 @@ drmBufMapPtr drmMapBufs(int fd)
1340 1359
1341 memclear(bufs); 1360 memclear(bufs);
1342 if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) 1361 if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs))
1343 return NULL; 1362 return NULL;
1344 1363
1345 if (!bufs.count) 1364 if (!bufs.count)
1346 return NULL; 1365 return NULL;
1347 1366
1348 if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list)))) 1367 if (!(bufs.list = drmMalloc(bufs.count * sizeof(*bufs.list))))
1349 return NULL; 1368 return NULL;
1350 1369
1351 if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) { 1370 if (drmIoctl(fd, DRM_IOCTL_MAP_BUFS, &bufs)) {
1352 drmFree(bufs.list); 1371 drmFree(bufs.list);
1353 return NULL; 1372 return NULL;
1354 } 1373 }
1355 1374
1356 retval = drmMalloc(sizeof(*retval)); 1375 retval = drmMalloc(sizeof(*retval));
1357 retval->count = bufs.count; 1376 retval->count = bufs.count;
1358 retval->list = drmMalloc(bufs.count * sizeof(*retval->list)); 1377 retval->list = drmMalloc(bufs.count * sizeof(*retval->list));
1359 for (i = 0; i < bufs.count; i++) { 1378 for (i = 0; i < bufs.count; i++) {
1360 retval->list[i].idx = bufs.list[i].idx; 1379 retval->list[i].idx = bufs.list[i].idx;
1361 retval->list[i].total = bufs.list[i].total; 1380 retval->list[i].total = bufs.list[i].total;
1362 retval->list[i].used = 0; 1381 retval->list[i].used = 0;
1363 retval->list[i].address = bufs.list[i].address; 1382 retval->list[i].address = bufs.list[i].address;
1364 } 1383 }
1365 1384
1366 drmFree(bufs.list); 1385 drmFree(bufs.list);
1367 1386 return retval;
1368 return retval;
1369} 1387}
1370 1388
1371 1389
@@ -1383,24 +1401,23 @@ int drmUnmapBufs(drmBufMapPtr bufs)
1383 int i; 1401 int i;
1384 1402
1385 for (i = 0; i < bufs->count; i++) { 1403 for (i = 0; i < bufs->count; i++) {
1386 drm_munmap(bufs->list[i].address, bufs->list[i].total); 1404 drm_munmap(bufs->list[i].address, bufs->list[i].total);
1387 } 1405 }
1388 1406
1389 drmFree(bufs->list); 1407 drmFree(bufs->list);
1390 drmFree(bufs); 1408 drmFree(bufs);
1391
1392 return 0; 1409 return 0;
1393} 1410}
1394 1411
1395 1412
1396#define DRM_DMA_RETRY 16 1413#define DRM_DMA_RETRY 16
1397 1414
1398/** 1415/**
1399 * Reserve DMA buffers. 1416 * Reserve DMA buffers.
1400 * 1417 *
1401 * \param fd file descriptor. 1418 * \param fd file descriptor.
1402 * \param request 1419 * \param request
1403 * 1420 *
1404 * \return zero on success, or a negative value on failure. 1421 * \return zero on success, or a negative value on failure.
1405 * 1422 *
1406 * \internal 1423 * \internal
@@ -1424,14 +1441,14 @@ int drmDMA(int fd, drmDMAReqPtr request)
1424 dma.granted_count = 0; 1441 dma.granted_count = 0;
1425 1442
1426 do { 1443 do {
1427 ret = ioctl( fd, DRM_IOCTL_DMA, &dma ); 1444 ret = ioctl( fd, DRM_IOCTL_DMA, &dma );
1428 } while ( ret && errno == EAGAIN && i++ < DRM_DMA_RETRY ); 1445 } while ( ret && errno == EAGAIN && i++ < DRM_DMA_RETRY );
1429 1446
1430 if ( ret == 0 ) { 1447 if ( ret == 0 ) {
1431 request->granted_count = dma.granted_count; 1448 request->granted_count = dma.granted_count;
1432 return 0; 1449 return 0;
1433 } else { 1450 } else {
1434 return -errno; 1451 return -errno;
1435 } 1452 }
1436} 1453}
1437 1454
@@ -1443,9 +1460,9 @@ int drmDMA(int fd, drmDMAReqPtr request)
1443 * \param context context. 1460 * \param context context.
1444 * \param flags flags that determine the sate of the hardware when the function 1461 * \param flags flags that determine the sate of the hardware when the function
1445 * returns. 1462 * returns.
1446 * 1463 *
1447 * \return always zero. 1464 * \return always zero.
1448 * 1465 *
1449 * \internal 1466 * \internal
1450 * This function translates the arguments into a drm_lock structure and issue 1467 * This function translates the arguments into a drm_lock structure and issue
1451 * the DRM_IOCTL_LOCK ioctl until the lock is successfully acquired. 1468 * the DRM_IOCTL_LOCK ioctl until the lock is successfully acquired.
@@ -1465,7 +1482,7 @@ int drmGetLock(int fd, drm_context_t context, drmLockFlags flags)
1465 if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES; 1482 if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
1466 1483
1467 while (drmIoctl(fd, DRM_IOCTL_LOCK, &lock)) 1484 while (drmIoctl(fd, DRM_IOCTL_LOCK, &lock))
1468 ; 1485 ;
1469 return 0; 1486 return 0;
1470} 1487}
1471 1488
@@ -1474,9 +1491,9 @@ int drmGetLock(int fd, drm_context_t context, drmLockFlags flags)
1474 * 1491 *
1475 * \param fd file descriptor. 1492 * \param fd file descriptor.
1476 * \param context context. 1493 * \param context context.
1477 * 1494 *
1478 * \return zero on success, or a negative value on failure. 1495 * \return zero on success, or a negative value on failure.
1479 * 1496 *
1480 * \internal 1497 * \internal
1481 * This function is a wrapper around the DRM_IOCTL_UNLOCK ioctl, passing the 1498 * This function is a wrapper around the DRM_IOCTL_UNLOCK ioctl, passing the
1482 * argument in a drm_lock structure. 1499 * argument in a drm_lock structure.
@@ -1499,24 +1516,24 @@ drm_context_t *drmGetReservedContextList(int fd, int *count)
1499 1516
1500 memclear(res); 1517 memclear(res);
1501 if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res)) 1518 if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
1502 return NULL; 1519 return NULL;
1503 1520
1504 if (!res.count) 1521 if (!res.count)
1505 return NULL; 1522 return NULL;
1506 1523
1507 if (!(list = drmMalloc(res.count * sizeof(*list)))) 1524 if (!(list = drmMalloc(res.count * sizeof(*list))))
1508 return NULL; 1525 return NULL;
1509 if (!(retval = drmMalloc(res.count * sizeof(*retval)))) { 1526 if (!(retval = drmMalloc(res.count * sizeof(*retval)))) {
1510 drmFree(list); 1527 drmFree(list);
1511 return NULL; 1528 return NULL;
1512 } 1529 }
1513 1530
1514 res.contexts = list; 1531 res.contexts = list;
1515 if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res)) 1532 if (drmIoctl(fd, DRM_IOCTL_RES_CTX, &res))
1516 return NULL; 1533 return NULL;
1517 1534
1518 for (i = 0; i < res.count; i++) 1535 for (i = 0; i < res.count; i++)
1519 retval[i] = list[i].handle; 1536 retval[i] = list[i].handle;
1520 drmFree(list); 1537 drmFree(list);
1521 1538
1522 *count = res.count; 1539 *count = res.count;
@@ -1537,11 +1554,11 @@ void drmFreeReservedContextList(drm_context_t *pt)
1537 * \param fd file descriptor. 1554 * \param fd file descriptor.
1538 * \param handle is set on success. To be used by the client when requesting DMA 1555 * \param handle is set on success. To be used by the client when requesting DMA
1539 * dispatch with drmDMA(). 1556 * dispatch with drmDMA().
1540 * 1557 *
1541 * \return zero on success, or a negative value on failure. 1558 * \return zero on success, or a negative value on failure.
1542 * 1559 *
1543 * \note May only be called by root. 1560 * \note May only be called by root.
1544 * 1561 *
1545 * \internal 1562 * \internal
1546 * This function is a wrapper around the DRM_IOCTL_ADD_CTX ioctl, passing the 1563 * This function is a wrapper around the DRM_IOCTL_ADD_CTX ioctl, passing the
1547 * argument in a drm_ctx structure. 1564 * argument in a drm_ctx structure.
@@ -1552,7 +1569,7 @@ int drmCreateContext(int fd, drm_context_t *handle)
1552 1569
1553 memclear(ctx); 1570 memclear(ctx);
1554 if (drmIoctl(fd, DRM_IOCTL_ADD_CTX, &ctx)) 1571 if (drmIoctl(fd, DRM_IOCTL_ADD_CTX, &ctx))
1555 return -errno; 1572 return -errno;
1556 *handle = ctx.handle; 1573 *handle = ctx.handle;
1557 return 0; 1574 return 0;
1558} 1575}
@@ -1564,7 +1581,7 @@ int drmSwitchToContext(int fd, drm_context_t context)
1564 memclear(ctx); 1581 memclear(ctx);
1565 ctx.handle = context; 1582 ctx.handle = context;
1566 if (drmIoctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx)) 1583 if (drmIoctl(fd, DRM_IOCTL_SWITCH_CTX, &ctx))
1567 return -errno; 1584 return -errno;
1568 return 0; 1585 return 0;
1569} 1586}
1570 1587
@@ -1581,11 +1598,11 @@ int drmSetContextFlags(int fd, drm_context_t context, drm_context_tFlags flags)
1581 memclear(ctx); 1598 memclear(ctx);
1582 ctx.handle = context; 1599 ctx.handle = context;
1583 if (flags & DRM_CONTEXT_PRESERVED) 1600 if (flags & DRM_CONTEXT_PRESERVED)
1584 ctx.flags |= _DRM_CONTEXT_PRESERVED; 1601 ctx.flags |= _DRM_CONTEXT_PRESERVED;
1585 if (flags & DRM_CONTEXT_2DONLY) 1602 if (flags & DRM_CONTEXT_2DONLY)
1586 ctx.flags |= _DRM_CONTEXT_2DONLY; 1603 ctx.flags |= _DRM_CONTEXT_2DONLY;
1587 if (drmIoctl(fd, DRM_IOCTL_MOD_CTX, &ctx)) 1604 if (drmIoctl(fd, DRM_IOCTL_MOD_CTX, &ctx))
1588 return -errno; 1605 return -errno;
1589 return 0; 1606 return 0;
1590} 1607}
1591 1608
@@ -1597,12 +1614,12 @@ int drmGetContextFlags(int fd, drm_context_t context,
1597 memclear(ctx); 1614 memclear(ctx);
1598 ctx.handle = context; 1615 ctx.handle = context;
1599 if (drmIoctl(fd, DRM_IOCTL_GET_CTX, &ctx)) 1616 if (drmIoctl(fd, DRM_IOCTL_GET_CTX, &ctx))
1600 return -errno; 1617 return -errno;
1601 *flags = 0; 1618 *flags = 0;
1602 if (ctx.flags & _DRM_CONTEXT_PRESERVED) 1619 if (ctx.flags & _DRM_CONTEXT_PRESERVED)
1603 *flags |= DRM_CONTEXT_PRESERVED; 1620 *flags |= DRM_CONTEXT_PRESERVED;
1604 if (ctx.flags & _DRM_CONTEXT_2DONLY) 1621 if (ctx.flags & _DRM_CONTEXT_2DONLY)
1605 *flags |= DRM_CONTEXT_2DONLY; 1622 *flags |= DRM_CONTEXT_2DONLY;
1606 return 0; 1623 return 0;
1607} 1624}
1608 1625
@@ -1611,14 +1628,14 @@ int drmGetContextFlags(int fd, drm_context_t context,
1611 * 1628 *
1612 * Free any kernel-level resources allocated with drmCreateContext() associated 1629 * Free any kernel-level resources allocated with drmCreateContext() associated
1613 * with the context. 1630 * with the context.
1614 * 1631 *
1615 * \param fd file descriptor. 1632 * \param fd file descriptor.
1616 * \param handle handle given by drmCreateContext(). 1633 * \param handle handle given by drmCreateContext().
1617 * 1634 *
1618 * \return zero on success, or a negative value on failure. 1635 * \return zero on success, or a negative value on failure.
1619 * 1636 *
1620 * \note May only be called by root. 1637 * \note May only be called by root.
1621 * 1638 *
1622 * \internal 1639 * \internal
1623 * This function is a wrapper around the DRM_IOCTL_RM_CTX ioctl, passing the 1640 * This function is a wrapper around the DRM_IOCTL_RM_CTX ioctl, passing the
1624 * argument in a drm_ctx structure. 1641 * argument in a drm_ctx structure.
@@ -1630,7 +1647,7 @@ int drmDestroyContext(int fd, drm_context_t handle)
1630 memclear(ctx); 1647 memclear(ctx);
1631 ctx.handle = handle; 1648 ctx.handle = handle;
1632 if (drmIoctl(fd, DRM_IOCTL_RM_CTX, &ctx)) 1649 if (drmIoctl(fd, DRM_IOCTL_RM_CTX, &ctx))
1633 return -errno; 1650 return -errno;
1634 return 0; 1651 return 0;
1635} 1652}
1636 1653
@@ -1640,7 +1657,7 @@ int drmCreateDrawable(int fd, drm_drawable_t *handle)
1640 1657
1641 memclear(draw); 1658 memclear(draw);
1642 if (drmIoctl(fd, DRM_IOCTL_ADD_DRAW, &draw)) 1659 if (drmIoctl(fd, DRM_IOCTL_ADD_DRAW, &draw))
1643 return -errno; 1660 return -errno;
1644 *handle = draw.handle; 1661 *handle = draw.handle;
1645 return 0; 1662 return 0;
1646} 1663}
@@ -1652,13 +1669,13 @@ int drmDestroyDrawable(int fd, drm_drawable_t handle)
1652 memclear(draw); 1669 memclear(draw);
1653 draw.handle = handle; 1670 draw.handle = handle;
1654 if (drmIoctl(fd, DRM_IOCTL_RM_DRAW, &draw)) 1671 if (drmIoctl(fd, DRM_IOCTL_RM_DRAW, &draw))
1655 return -errno; 1672 return -errno;
1656 return 0; 1673 return 0;
1657} 1674}
1658 1675
1659int drmUpdateDrawableInfo(int fd, drm_drawable_t handle, 1676int drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
1660 drm_drawable_info_type_t type, unsigned int num, 1677 drm_drawable_info_type_t type, unsigned int num,
1661 void *data) 1678 void *data)
1662{ 1679{
1663 drm_update_draw_t update; 1680 drm_update_draw_t update;
1664 1681
@@ -1669,7 +1686,7 @@ int drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
1669 update.data = (unsigned long long)(unsigned long)data; 1686 update.data = (unsigned long long)(unsigned long)data;
1670 1687
1671 if (drmIoctl(fd, DRM_IOCTL_UPDATE_DRAW, &update)) 1688 if (drmIoctl(fd, DRM_IOCTL_UPDATE_DRAW, &update))
1672 return -errno; 1689 return -errno;
1673 1690
1674 return 0; 1691 return 0;
1675} 1692}
@@ -1680,16 +1697,16 @@ int drmUpdateDrawableInfo(int fd, drm_drawable_t handle,
1680 * Must be called before any of the other AGP related calls. 1697 * Must be called before any of the other AGP related calls.
1681 * 1698 *
1682 * \param fd file descriptor. 1699 * \param fd file descriptor.
1683 * 1700 *
1684 * \return zero on success, or a negative value on failure. 1701 * \return zero on success, or a negative value on failure.
1685 * 1702 *
1686 * \internal 1703 * \internal
1687 * This function is a wrapper around the DRM_IOCTL_AGP_ACQUIRE ioctl. 1704 * This function is a wrapper around the DRM_IOCTL_AGP_ACQUIRE ioctl.
1688 */ 1705 */
1689int drmAgpAcquire(int fd) 1706int drmAgpAcquire(int fd)
1690{ 1707{
1691 if (drmIoctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL)) 1708 if (drmIoctl(fd, DRM_IOCTL_AGP_ACQUIRE, NULL))
1692 return -errno; 1709 return -errno;
1693 return 0; 1710 return 0;
1694} 1711}
1695 1712
@@ -1698,16 +1715,16 @@ int drmAgpAcquire(int fd)
1698 * Release the AGP device. 1715 * Release the AGP device.
1699 * 1716 *
1700 * \param fd file descriptor. 1717 * \param fd file descriptor.
1701 * 1718 *
1702 * \return zero on success, or a negative value on failure. 1719 * \return zero on success, or a negative value on failure.
1703 * 1720 *
1704 * \internal 1721 * \internal
1705 * This function is a wrapper around the DRM_IOCTL_AGP_RELEASE ioctl. 1722 * This function is a wrapper around the DRM_IOCTL_AGP_RELEASE ioctl.
1706 */ 1723 */
1707int drmAgpRelease(int fd) 1724int drmAgpRelease(int fd)
1708{ 1725{
1709 if (drmIoctl(fd, DRM_IOCTL_AGP_RELEASE, NULL)) 1726 if (drmIoctl(fd, DRM_IOCTL_AGP_RELEASE, NULL))
1710 return -errno; 1727 return -errno;
1711 return 0; 1728 return 0;
1712} 1729}
1713 1730
@@ -1717,9 +1734,9 @@ int drmAgpRelease(int fd)
1717 * 1734 *
1718 * \param fd file descriptor. 1735 * \param fd file descriptor.
1719 * \param mode AGP mode. 1736 * \param mode AGP mode.
1720 * 1737 *
1721 * \return zero on success, or a negative value on failure. 1738 * \return zero on success, or a negative value on failure.
1722 * 1739 *
1723 * \internal 1740 * \internal
1724 * This function is a wrapper around the DRM_IOCTL_AGP_ENABLE ioctl, passing the 1741 * This function is a wrapper around the DRM_IOCTL_AGP_ENABLE ioctl, passing the
1725 * argument in a drm_agp_mode structure. 1742 * argument in a drm_agp_mode structure.
@@ -1731,7 +1748,7 @@ int drmAgpEnable(int fd, unsigned long mode)
1731 memclear(m); 1748 memclear(m);
1732 m.mode = mode; 1749 m.mode = mode;
1733 if (drmIoctl(fd, DRM_IOCTL_AGP_ENABLE, &m)) 1750 if (drmIoctl(fd, DRM_IOCTL_AGP_ENABLE, &m))
1734 return -errno; 1751 return -errno;
1735 return 0; 1752 return 0;
1736} 1753}
1737 1754
@@ -1745,15 +1762,15 @@ int drmAgpEnable(int fd, unsigned long mode)
1745 * \param address if not zero, will be set to the physical address of the 1762 * \param address if not zero, will be set to the physical address of the
1746 * allocated memory. 1763 * allocated memory.
1747 * \param handle on success will be set to a handle of the allocated memory. 1764 * \param handle on success will be set to a handle of the allocated memory.
1748 * 1765 *
1749 * \return zero on success, or a negative value on failure. 1766 * \return zero on success, or a negative value on failure.
1750 * 1767 *
1751 * \internal 1768 * \internal
1752 * This function is a wrapper around the DRM_IOCTL_AGP_ALLOC ioctl, passing the 1769 * This function is a wrapper around the DRM_IOCTL_AGP_ALLOC ioctl, passing the
1753 * arguments in a drm_agp_buffer structure. 1770 * arguments in a drm_agp_buffer structure.
1754 */ 1771 */
1755int drmAgpAlloc(int fd, unsigned long size, unsigned long type, 1772int drmAgpAlloc(int fd, unsigned long size, unsigned long type,
1756 unsigned long *address, drm_handle_t *handle) 1773 unsigned long *address, drm_handle_t *handle)
1757{ 1774{
1758 drm_agp_buffer_t b; 1775 drm_agp_buffer_t b;
1759 1776
@@ -1762,9 +1779,9 @@ int drmAgpAlloc(int fd, unsigned long size, unsigned long type,
1762 b.size = size; 1779 b.size = size;
1763 b.type = type; 1780 b.type = type;
1764 if (drmIoctl(fd, DRM_IOCTL_AGP_ALLOC, &b)) 1781 if (drmIoctl(fd, DRM_IOCTL_AGP_ALLOC, &b))
1765 return -errno; 1782 return -errno;
1766 if (address != 0UL) 1783 if (address != 0UL)
1767 *address = b.physical; 1784 *address = b.physical;
1768 *handle = b.handle; 1785 *handle = b.handle;
1769 return 0; 1786 return 0;
1770} 1787}
@@ -1775,9 +1792,9 @@ int drmAgpAlloc(int fd, unsigned long size, unsigned long type,
1775 * 1792 *
1776 * \param fd file descriptor. 1793 * \param fd file descriptor.
1777 * \param handle handle to the allocated memory, as given by drmAgpAllocate(). 1794 * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1778 * 1795 *
1779 * \return zero on success, or a negative value on failure. 1796 * \return zero on success, or a negative value on failure.
1780 * 1797 *
1781 * \internal 1798 * \internal
1782 * This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the 1799 * This function is a wrapper around the DRM_IOCTL_AGP_FREE ioctl, passing the
1783 * argument in a drm_agp_buffer structure. 1800 * argument in a drm_agp_buffer structure.
@@ -1789,7 +1806,7 @@ int drmAgpFree(int fd, drm_handle_t handle)
1789 memclear(b); 1806 memclear(b);
1790 b.handle = handle; 1807 b.handle = handle;
1791 if (drmIoctl(fd, DRM_IOCTL_AGP_FREE, &b)) 1808 if (drmIoctl(fd, DRM_IOCTL_AGP_FREE, &b))
1792 return -errno; 1809 return -errno;
1793 return 0; 1810 return 0;
1794} 1811}
1795 1812
@@ -1800,9 +1817,9 @@ int drmAgpFree(int fd, drm_handle_t handle)
1800 * \param fd file descriptor. 1817 * \param fd file descriptor.
1801 * \param handle handle to the allocated memory, as given by drmAgpAllocate(). 1818 * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1802 * \param offset offset in bytes. It will round to page boundary. 1819 * \param offset offset in bytes. It will round to page boundary.
1803 * 1820 *
1804 * \return zero on success, or a negative value on failure. 1821 * \return zero on success, or a negative value on failure.
1805 * 1822 *
1806 * \internal 1823 * \internal
1807 * This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the 1824 * This function is a wrapper around the DRM_IOCTL_AGP_BIND ioctl, passing the
1808 * argument in a drm_agp_binding structure. 1825 * argument in a drm_agp_binding structure.
@@ -1815,7 +1832,7 @@ int drmAgpBind(int fd, drm_handle_t handle, unsigned long offset)
1815 b.handle = handle; 1832 b.handle = handle;
1816 b.offset = offset; 1833 b.offset = offset;
1817 if (drmIoctl(fd, DRM_IOCTL_AGP_BIND, &b)) 1834 if (drmIoctl(fd, DRM_IOCTL_AGP_BIND, &b))
1818 return -errno; 1835 return -errno;
1819 return 0; 1836 return 0;
1820} 1837}
1821 1838
@@ -1825,9 +1842,9 @@ int drmAgpBind(int fd, drm_handle_t handle, unsigned long offset)
1825 * 1842 *
1826 * \param fd file descriptor. 1843 * \param fd file descriptor.
1827 * \param handle handle to the allocated memory, as given by drmAgpAllocate(). 1844 * \param handle handle to the allocated memory, as given by drmAgpAllocate().
1828 * 1845 *
1829 * \return zero on success, or a negative value on failure. 1846 * \return zero on success, or a negative value on failure.
1830 * 1847 *
1831 * \internal 1848 * \internal
1832 * This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing 1849 * This function is a wrapper around the DRM_IOCTL_AGP_UNBIND ioctl, passing
1833 * the argument in a drm_agp_binding structure. 1850 * the argument in a drm_agp_binding structure.
@@ -1839,7 +1856,7 @@ int drmAgpUnbind(int fd, drm_handle_t handle)
1839 memclear(b); 1856 memclear(b);
1840 b.handle = handle; 1857 b.handle = handle;
1841 if (drmIoctl(fd, DRM_IOCTL_AGP_UNBIND, &b)) 1858 if (drmIoctl(fd, DRM_IOCTL_AGP_UNBIND, &b))
1842 return -errno; 1859 return -errno;
1843 return 0; 1860 return 0;
1844} 1861}
1845 1862
@@ -1848,9 +1865,9 @@ int drmAgpUnbind(int fd, drm_handle_t handle)
1848 * Get AGP driver major version number. 1865 * Get AGP driver major version number.
1849 * 1866 *
1850 * \param fd file descriptor. 1867 * \param fd file descriptor.
1851 * 1868 *
1852 * \return major version number on success, or a negative value on failure.. 1869 * \return major version number on success, or a negative value on failure..
1853 * 1870 *
1854 * \internal 1871 * \internal
1855 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1872 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1856 * necessary information in a drm_agp_info structure. 1873 * necessary information in a drm_agp_info structure.
@@ -1862,7 +1879,7 @@ int drmAgpVersionMajor(int fd)
1862 memclear(i); 1879 memclear(i);
1863 1880
1864 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1881 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1865 return -errno; 1882 return -errno;
1866 return i.agp_version_major; 1883 return i.agp_version_major;
1867} 1884}
1868 1885
@@ -1871,9 +1888,9 @@ int drmAgpVersionMajor(int fd)
1871 * Get AGP driver minor version number. 1888 * Get AGP driver minor version number.
1872 * 1889 *
1873 * \param fd file descriptor. 1890 * \param fd file descriptor.
1874 * 1891 *
1875 * \return minor version number on success, or a negative value on failure. 1892 * \return minor version number on success, or a negative value on failure.
1876 * 1893 *
1877 * \internal 1894 * \internal
1878 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1895 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1879 * necessary information in a drm_agp_info structure. 1896 * necessary information in a drm_agp_info structure.
@@ -1885,7 +1902,7 @@ int drmAgpVersionMinor(int fd)
1885 memclear(i); 1902 memclear(i);
1886 1903
1887 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1904 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1888 return -errno; 1905 return -errno;
1889 return i.agp_version_minor; 1906 return i.agp_version_minor;
1890} 1907}
1891 1908
@@ -1894,9 +1911,9 @@ int drmAgpVersionMinor(int fd)
1894 * Get AGP mode. 1911 * Get AGP mode.
1895 * 1912 *
1896 * \param fd file descriptor. 1913 * \param fd file descriptor.
1897 * 1914 *
1898 * \return mode on success, or zero on failure. 1915 * \return mode on success, or zero on failure.
1899 * 1916 *
1900 * \internal 1917 * \internal
1901 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1918 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1902 * necessary information in a drm_agp_info structure. 1919 * necessary information in a drm_agp_info structure.
@@ -1908,7 +1925,7 @@ unsigned long drmAgpGetMode(int fd)
1908 memclear(i); 1925 memclear(i);
1909 1926
1910 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1927 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1911 return 0; 1928 return 0;
1912 return i.mode; 1929 return i.mode;
1913} 1930}
1914 1931
@@ -1917,9 +1934,9 @@ unsigned long drmAgpGetMode(int fd)
1917 * Get AGP aperture base. 1934 * Get AGP aperture base.
1918 * 1935 *
1919 * \param fd file descriptor. 1936 * \param fd file descriptor.
1920 * 1937 *
1921 * \return aperture base on success, zero on failure. 1938 * \return aperture base on success, zero on failure.
1922 * 1939 *
1923 * \internal 1940 * \internal
1924 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1941 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1925 * necessary information in a drm_agp_info structure. 1942 * necessary information in a drm_agp_info structure.
@@ -1931,7 +1948,7 @@ unsigned long drmAgpBase(int fd)
1931 memclear(i); 1948 memclear(i);
1932 1949
1933 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1950 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1934 return 0; 1951 return 0;
1935 return i.aperture_base; 1952 return i.aperture_base;
1936} 1953}
1937 1954
@@ -1940,9 +1957,9 @@ unsigned long drmAgpBase(int fd)
1940 * Get AGP aperture size. 1957 * Get AGP aperture size.
1941 * 1958 *
1942 * \param fd file descriptor. 1959 * \param fd file descriptor.
1943 * 1960 *
1944 * \return aperture size on success, zero on failure. 1961 * \return aperture size on success, zero on failure.
1945 * 1962 *
1946 * \internal 1963 * \internal
1947 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1964 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1948 * necessary information in a drm_agp_info structure. 1965 * necessary information in a drm_agp_info structure.
@@ -1954,7 +1971,7 @@ unsigned long drmAgpSize(int fd)
1954 memclear(i); 1971 memclear(i);
1955 1972
1956 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1973 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1957 return 0; 1974 return 0;
1958 return i.aperture_size; 1975 return i.aperture_size;
1959} 1976}
1960 1977
@@ -1963,9 +1980,9 @@ unsigned long drmAgpSize(int fd)
1963 * Get used AGP memory. 1980 * Get used AGP memory.
1964 * 1981 *
1965 * \param fd file descriptor. 1982 * \param fd file descriptor.
1966 * 1983 *
1967 * \return memory used on success, or zero on failure. 1984 * \return memory used on success, or zero on failure.
1968 * 1985 *
1969 * \internal 1986 * \internal
1970 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 1987 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1971 * necessary information in a drm_agp_info structure. 1988 * necessary information in a drm_agp_info structure.
@@ -1977,7 +1994,7 @@ unsigned long drmAgpMemoryUsed(int fd)
1977 memclear(i); 1994 memclear(i);
1978 1995
1979 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 1996 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
1980 return 0; 1997 return 0;
1981 return i.memory_used; 1998 return i.memory_used;
1982} 1999}
1983 2000
@@ -1986,9 +2003,9 @@ unsigned long drmAgpMemoryUsed(int fd)
1986 * Get available AGP memory. 2003 * Get available AGP memory.
1987 * 2004 *
1988 * \param fd file descriptor. 2005 * \param fd file descriptor.
1989 * 2006 *
1990 * \return memory available on success, or zero on failure. 2007 * \return memory available on success, or zero on failure.
1991 * 2008 *
1992 * \internal 2009 * \internal
1993 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 2010 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
1994 * necessary information in a drm_agp_info structure. 2011 * necessary information in a drm_agp_info structure.
@@ -2000,7 +2017,7 @@ unsigned long drmAgpMemoryAvail(int fd)
2000 memclear(i); 2017 memclear(i);
2001 2018
2002 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 2019 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
2003 return 0; 2020 return 0;
2004 return i.memory_allowed; 2021 return i.memory_allowed;
2005} 2022}
2006 2023
@@ -2009,9 +2026,9 @@ unsigned long drmAgpMemoryAvail(int fd)
2009 * Get hardware vendor ID. 2026 * Get hardware vendor ID.
2010 * 2027 *
2011 * \param fd file descriptor. 2028 * \param fd file descriptor.
2012 * 2029 *
2013 * \return vendor ID on success, or zero on failure. 2030 * \return vendor ID on success, or zero on failure.
2014 * 2031 *
2015 * \internal 2032 * \internal
2016 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 2033 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
2017 * necessary information in a drm_agp_info structure. 2034 * necessary information in a drm_agp_info structure.
@@ -2023,7 +2040,7 @@ unsigned int drmAgpVendorId(int fd)
2023 memclear(i); 2040 memclear(i);
2024 2041
2025 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 2042 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
2026 return 0; 2043 return 0;
2027 return i.id_vendor; 2044 return i.id_vendor;
2028} 2045}
2029 2046
@@ -2032,9 +2049,9 @@ unsigned int drmAgpVendorId(int fd)
2032 * Get hardware device ID. 2049 * Get hardware device ID.
2033 * 2050 *
2034 * \param fd file descriptor. 2051 * \param fd file descriptor.
2035 * 2052 *
2036 * \return zero on success, or zero on failure. 2053 * \return zero on success, or zero on failure.
2037 * 2054 *
2038 * \internal 2055 * \internal
2039 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the 2056 * This function is a wrapper around the DRM_IOCTL_AGP_INFO ioctl, getting the
2040 * necessary information in a drm_agp_info structure. 2057 * necessary information in a drm_agp_info structure.
@@ -2046,7 +2063,7 @@ unsigned int drmAgpDeviceId(int fd)
2046 memclear(i); 2063 memclear(i);
2047 2064
2048 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i)) 2065 if (drmIoctl(fd, DRM_IOCTL_AGP_INFO, &i))
2049 return 0; 2066 return 0;
2050 return i.id_device; 2067 return i.id_device;
2051} 2068}
2052 2069
@@ -2059,7 +2076,7 @@ int drmScatterGatherAlloc(int fd, unsigned long size, drm_handle_t *handle)
2059 *handle = 0; 2076 *handle = 0;
2060 sg.size = size; 2077 sg.size = size;
2061 if (drmIoctl(fd, DRM_IOCTL_SG_ALLOC, &sg)) 2078 if (drmIoctl(fd, DRM_IOCTL_SG_ALLOC, &sg))
2062 return -errno; 2079 return -errno;
2063 *handle = sg.handle; 2080 *handle = sg.handle;
2064 return 0; 2081 return 0;
2065} 2082}
@@ -2071,7 +2088,7 @@ int drmScatterGatherFree(int fd, drm_handle_t handle)
2071 memclear(sg); 2088 memclear(sg);
2072 sg.handle = handle; 2089 sg.handle = handle;
2073 if (drmIoctl(fd, DRM_IOCTL_SG_FREE, &sg)) 2090 if (drmIoctl(fd, DRM_IOCTL_SG_FREE, &sg))
2074 return -errno; 2091 return -errno;
2075 return 0; 2092 return 0;
2076} 2093}
2077 2094
@@ -2080,9 +2097,9 @@ int drmScatterGatherFree(int fd, drm_handle_t handle)
2080 * 2097 *
2081 * \param fd file descriptor. 2098 * \param fd file descriptor.
2082 * \param vbl pointer to a drmVBlank structure. 2099 * \param vbl pointer to a drmVBlank structure.
2083 * 2100 *
2084 * \return zero on success, or a negative value on failure. 2101 * \return zero on success, or a negative value on failure.
2085 * 2102 *
2086 * \internal 2103 * \internal
2087 * This function is a wrapper around the DRM_IOCTL_WAIT_VBLANK ioctl. 2104 * This function is a wrapper around the DRM_IOCTL_WAIT_VBLANK ioctl.
2088 */ 2105 */
@@ -2093,8 +2110,8 @@ int drmWaitVBlank(int fd, drmVBlankPtr vbl)
2093 2110
2094 ret = clock_gettime(CLOCK_MONOTONIC, &timeout); 2111 ret = clock_gettime(CLOCK_MONOTONIC, &timeout);
2095 if (ret < 0) { 2112 if (ret < 0) {
2096 fprintf(stderr, "clock_gettime failed: %s\n", strerror(errno)); 2113 fprintf(stderr, "clock_gettime failed: %s\n", strerror(errno));
2097 goto out; 2114 goto out;
2098 } 2115 }
2099 timeout.tv_sec++; 2116 timeout.tv_sec++;
2100 2117
@@ -2102,15 +2119,15 @@ int drmWaitVBlank(int fd, drmVBlankPtr vbl)
2102 ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl); 2119 ret = ioctl(fd, DRM_IOCTL_WAIT_VBLANK, vbl);
2103 vbl->request.type &= ~DRM_VBLANK_RELATIVE; 2120 vbl->request.type &= ~DRM_VBLANK_RELATIVE;
2104 if (ret && errno == EINTR) { 2121 if (ret && errno == EINTR) {
2105 clock_gettime(CLOCK_MONOTONIC, &cur); 2122 clock_gettime(CLOCK_MONOTONIC, &cur);
2106 /* Timeout after 1s */ 2123 /* Timeout after 1s */
2107 if (cur.tv_sec > timeout.tv_sec + 1 || 2124 if (cur.tv_sec > timeout.tv_sec + 1 ||
2108 (cur.tv_sec == timeout.tv_sec && cur.tv_nsec >= 2125 (cur.tv_sec == timeout.tv_sec && cur.tv_nsec >=
2109 timeout.tv_nsec)) { 2126 timeout.tv_nsec)) {
2110 errno = EBUSY; 2127 errno = EBUSY;
2111 ret = -1; 2128 ret = -1;
2112 break; 2129 break;
2113 } 2130 }
2114 } 2131 }
2115 } while (ret && errno == EINTR); 2132 } while (ret && errno == EINTR);
2116 2133
@@ -2122,22 +2139,22 @@ int drmError(int err, const char *label)
2122{ 2139{
2123 switch (err) { 2140 switch (err) {
2124 case DRM_ERR_NO_DEVICE: 2141 case DRM_ERR_NO_DEVICE:
2125 fprintf(stderr, "%s: no device\n", label); 2142 fprintf(stderr, "%s: no device\n", label);
2126 break; 2143 break;
2127 case DRM_ERR_NO_ACCESS: 2144 case DRM_ERR_NO_ACCESS:
2128 fprintf(stderr, "%s: no access\n", label); 2145 fprintf(stderr, "%s: no access\n", label);
2129 break; 2146 break;
2130 case DRM_ERR_NOT_ROOT: 2147 case DRM_ERR_NOT_ROOT:
2131 fprintf(stderr, "%s: not root\n", label); 2148 fprintf(stderr, "%s: not root\n", label);
2132 break; 2149 break;
2133 case DRM_ERR_INVALID: 2150 case DRM_ERR_INVALID:
2134 fprintf(stderr, "%s: invalid args\n", label); 2151 fprintf(stderr, "%s: invalid args\n", label);
2135 break; 2152 break;
2136 default: 2153 default:
2137 if (err < 0) 2154 if (err < 0)
2138 err = -err; 2155 err = -err;
2139 fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) ); 2156 fprintf( stderr, "%s: error %d (%s)\n", label, err, strerror(err) );
2140 break; 2157 break;
2141 } 2158 }
2142 2159
2143 return 1; 2160 return 1;
@@ -2148,9 +2165,9 @@ int drmError(int err, const char *label)
2148 * 2165 *
2149 * \param fd file descriptor. 2166 * \param fd file descriptor.
2150 * \param irq IRQ number. 2167 * \param irq IRQ number.
2151 * 2168 *
2152 * \return zero on success, or a negative value on failure. 2169 * \return zero on success, or a negative value on failure.
2153 * 2170 *
2154 * \internal 2171 * \internal
2155 * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the 2172 * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
2156 * argument in a drm_control structure. 2173 * argument in a drm_control structure.
@@ -2163,7 +2180,7 @@ int drmCtlInstHandler(int fd, int irq)
2163 ctl.func = DRM_INST_HANDLER; 2180 ctl.func = DRM_INST_HANDLER;
2164 ctl.irq = irq; 2181 ctl.irq = irq;
2165 if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl)) 2182 if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
2166 return -errno; 2183 return -errno;
2167 return 0; 2184 return 0;
2168} 2185}
2169 2186
@@ -2172,9 +2189,9 @@ int drmCtlInstHandler(int fd, int irq)
2172 * Uninstall IRQ handler. 2189 * Uninstall IRQ handler.
2173 * 2190 *
2174 * \param fd file descriptor. 2191 * \param fd file descriptor.
2175 * 2192 *
2176 * \return zero on success, or a negative value on failure. 2193 * \return zero on success, or a negative value on failure.
2177 * 2194 *
2178 * \internal 2195 * \internal
2179 * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the 2196 * This function is a wrapper around the DRM_IOCTL_CONTROL ioctl, passing the
2180 * argument in a drm_control structure. 2197 * argument in a drm_control structure.
@@ -2187,7 +2204,7 @@ int drmCtlUninstHandler(int fd)
2187 ctl.func = DRM_UNINST_HANDLER; 2204 ctl.func = DRM_UNINST_HANDLER;
2188 ctl.irq = 0; 2205 ctl.irq = 0;
2189 if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl)) 2206 if (drmIoctl(fd, DRM_IOCTL_CONTROL, &ctl))
2190 return -errno; 2207 return -errno;
2191 return 0; 2208 return 0;
2192} 2209}
2193 2210
@@ -2204,7 +2221,7 @@ int drmFinish(int fd, int context, drmLockFlags flags)
2204 if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES; 2221 if (flags & DRM_HALT_ALL_QUEUES) lock.flags |= _DRM_HALT_ALL_QUEUES;
2205 if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES; 2222 if (flags & DRM_HALT_CUR_QUEUES) lock.flags |= _DRM_HALT_CUR_QUEUES;
2206 if (drmIoctl(fd, DRM_IOCTL_FINISH, &lock)) 2223 if (drmIoctl(fd, DRM_IOCTL_FINISH, &lock))
2207 return -errno; 2224 return -errno;
2208 return 0; 2225 return 0;
2209} 2226}
2210 2227
@@ -2215,9 +2232,9 @@ int drmFinish(int fd, int context, drmLockFlags flags)
2215 * \param busnum bus number. 2232 * \param busnum bus number.
2216 * \param devnum device number. 2233 * \param devnum device number.
2217 * \param funcnum function number. 2234 * \param funcnum function number.
2218 * 2235 *
2219 * \return IRQ number on success, or a negative value on failure. 2236 * \return IRQ number on success, or a negative value on failure.
2220 * 2237 *
2221 * \internal 2238 * \internal
2222 * This function is a wrapper around the DRM_IOCTL_IRQ_BUSID ioctl, passing the 2239 * This function is a wrapper around the DRM_IOCTL_IRQ_BUSID ioctl, passing the
2223 * arguments in a drm_irq_busid structure. 2240 * arguments in a drm_irq_busid structure.
@@ -2231,7 +2248,7 @@ int drmGetInterruptFromBusID(int fd, int busnum, int devnum, int funcnum)
2231 p.devnum = devnum; 2248 p.devnum = devnum;
2232 p.funcnum = funcnum; 2249 p.funcnum = funcnum;
2233 if (drmIoctl(fd, DRM_IOCTL_IRQ_BUSID, &p)) 2250 if (drmIoctl(fd, DRM_IOCTL_IRQ_BUSID, &p))
2234 return -errno; 2251 return -errno;
2235 return p.irq; 2252 return p.irq;
2236} 2253}
2237 2254
@@ -2240,8 +2257,8 @@ int drmAddContextTag(int fd, drm_context_t context, void *tag)
2240 drmHashEntry *entry = drmGetEntry(fd); 2257 drmHashEntry *entry = drmGetEntry(fd);
2241 2258
2242 if (drmHashInsert(entry->tagTable, context, tag)) { 2259 if (drmHashInsert(entry->tagTable, context, tag)) {
2243 drmHashDelete(entry->tagTable, context); 2260 drmHashDelete(entry->tagTable, context);
2244 drmHashInsert(entry->tagTable, context, tag); 2261 drmHashInsert(entry->tagTable, context, tag);
2245 } 2262 }
2246 return 0; 2263 return 0;
2247} 2264}
@@ -2259,7 +2276,7 @@ void *drmGetContextTag(int fd, drm_context_t context)
2259 void *value; 2276 void *value;
2260 2277
2261 if (drmHashLookup(entry->tagTable, context, &value)) 2278 if (drmHashLookup(entry->tagTable, context, &value))
2262 return NULL; 2279 return NULL;
2263 2280
2264 return value; 2281 return value;
2265} 2282}
@@ -2274,7 +2291,7 @@ int drmAddContextPrivateMapping(int fd, drm_context_t ctx_id,
2274 map.handle = (void *)(uintptr_t)handle; 2291 map.handle = (void *)(uintptr_t)handle;
2275 2292
2276 if (drmIoctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map)) 2293 if (drmIoctl(fd, DRM_IOCTL_SET_SAREA_CTX, &map))
2277 return -errno; 2294 return -errno;
2278 return 0; 2295 return 0;
2279} 2296}
2280 2297
@@ -2287,23 +2304,23 @@ int drmGetContextPrivateMapping(int fd, drm_context_t ctx_id,
2287 map.ctx_id = ctx_id; 2304 map.ctx_id = ctx_id;
2288 2305
2289 if (drmIoctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map)) 2306 if (drmIoctl(fd, DRM_IOCTL_GET_SAREA_CTX, &map))
2290 return -errno; 2307 return -errno;
2291 if (handle) 2308 if (handle)
2292 *handle = (drm_handle_t)(uintptr_t)map.handle; 2309 *handle = (drm_handle_t)(uintptr_t)map.handle;
2293 2310
2294 return 0; 2311 return 0;
2295} 2312}
2296 2313
2297int drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size, 2314int drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size,
2298 drmMapType *type, drmMapFlags *flags, drm_handle_t *handle, 2315 drmMapType *type, drmMapFlags *flags, drm_handle_t *handle,
2299 int *mtrr) 2316 int *mtrr)
2300{ 2317{
2301 drm_map_t map; 2318 drm_map_t map;
2302 2319
2303 memclear(map); 2320 memclear(map);
2304 map.offset = idx; 2321 map.offset = idx;
2305 if (drmIoctl(fd, DRM_IOCTL_GET_MAP, &map)) 2322 if (drmIoctl(fd, DRM_IOCTL_GET_MAP, &map))
2306 return -errno; 2323 return -errno;
2307 *offset = map.offset; 2324 *offset = map.offset;
2308 *size = map.size; 2325 *size = map.size;
2309 *type = map.type; 2326 *type = map.type;
@@ -2314,14 +2331,14 @@ int drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size,
2314} 2331}
2315 2332
2316int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid, 2333int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid,
2317 unsigned long *magic, unsigned long *iocs) 2334 unsigned long *magic, unsigned long *iocs)
2318{ 2335{
2319 drm_client_t client; 2336 drm_client_t client;
2320 2337
2321 memclear(client); 2338 memclear(client);
2322 client.idx = idx; 2339 client.idx = idx;
2323 if (drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client)) 2340 if (drmIoctl(fd, DRM_IOCTL_GET_CLIENT, &client))
2324 return -errno; 2341 return -errno;
2325 *auth = client.auth; 2342 *auth = client.auth;
2326 *pid = client.pid; 2343 *pid = client.pid;
2327 *uid = client.uid; 2344 *uid = client.uid;
@@ -2337,12 +2354,12 @@ int drmGetStats(int fd, drmStatsT *stats)
2337 2354
2338 memclear(s); 2355 memclear(s);
2339 if (drmIoctl(fd, DRM_IOCTL_GET_STATS, &s)) 2356 if (drmIoctl(fd, DRM_IOCTL_GET_STATS, &s))
2340 return -errno; 2357 return -errno;
2341 2358
2342 stats->count = 0; 2359 stats->count = 0;
2343 memset(stats, 0, sizeof(*stats)); 2360 memset(stats, 0, sizeof(*stats));
2344 if (s.count > sizeof(stats->data)/sizeof(stats->data[0])) 2361 if (s.count > sizeof(stats->data)/sizeof(stats->data[0]))
2345 return -1; 2362 return -1;
2346 2363
2347#define SET_VALUE \ 2364#define SET_VALUE \
2348 stats->data[i].long_format = "%-20.20s"; \ 2365 stats->data[i].long_format = "%-20.20s"; \
@@ -2369,87 +2386,87 @@ int drmGetStats(int fd, drmStatsT *stats)
2369 2386
2370 stats->count = s.count; 2387 stats->count = s.count;
2371 for (i = 0; i < s.count; i++) { 2388 for (i = 0; i < s.count; i++) {
2372 stats->data[i].value = s.data[i].value; 2389 stats->data[i].value = s.data[i].value;
2373 switch (s.data[i].type) { 2390 switch (s.data[i].type) {
2374 case _DRM_STAT_LOCK: 2391 case _DRM_STAT_LOCK:
2375 stats->data[i].long_name = "Lock"; 2392 stats->data[i].long_name = "Lock";
2376 stats->data[i].rate_name = "Lock"; 2393 stats->data[i].rate_name = "Lock";
2377 SET_VALUE; 2394 SET_VALUE;
2378 break; 2395 break;
2379 case _DRM_STAT_OPENS: 2396 case _DRM_STAT_OPENS:
2380 stats->data[i].long_name = "Opens"; 2397 stats->data[i].long_name = "Opens";
2381 stats->data[i].rate_name = "O"; 2398 stats->data[i].rate_name = "O";
2382 SET_COUNT; 2399 SET_COUNT;
2383 stats->data[i].verbose = 1; 2400 stats->data[i].verbose = 1;
2384 break; 2401 break;
2385 case _DRM_STAT_CLOSES: 2402 case _DRM_STAT_CLOSES:
2386 stats->data[i].long_name = "Closes"; 2403 stats->data[i].long_name = "Closes";
2387 stats->data[i].rate_name = "Lock"; 2404 stats->data[i].rate_name = "Lock";
2388 SET_COUNT; 2405 SET_COUNT;
2389 stats->data[i].verbose = 1; 2406 stats->data[i].verbose = 1;
2390 break; 2407 break;
2391 case _DRM_STAT_IOCTLS: 2408 case _DRM_STAT_IOCTLS:
2392 stats->data[i].long_name = "Ioctls"; 2409 stats->data[i].long_name = "Ioctls";
2393 stats->data[i].rate_name = "Ioc/s"; 2410 stats->data[i].rate_name = "Ioc/s";
2394 SET_COUNT; 2411 SET_COUNT;
2395 break; 2412 break;
2396 case _DRM_STAT_LOCKS: 2413 case _DRM_STAT_LOCKS:
2397 stats->data[i].long_name = "Locks"; 2414 stats->data[i].long_name = "Locks";
2398 stats->data[i].rate_name = "Lck/s"; 2415 stats->data[i].rate_name = "Lck/s";
2399 SET_COUNT; 2416 SET_COUNT;
2400 break; 2417 break;
2401 case _DRM_STAT_UNLOCKS: 2418 case _DRM_STAT_UNLOCKS:
2402 stats->data[i].long_name = "Unlocks"; 2419 stats->data[i].long_name = "Unlocks";
2403 stats->data[i].rate_name = "Unl/s"; 2420 stats->data[i].rate_name = "Unl/s";
2404 SET_COUNT; 2421 SET_COUNT;
2405 break; 2422 break;
2406 case _DRM_STAT_IRQ: 2423 case _DRM_STAT_IRQ:
2407 stats->data[i].long_name = "IRQs"; 2424 stats->data[i].long_name = "IRQs";
2408 stats->data[i].rate_name = "IRQ/s"; 2425 stats->data[i].rate_name = "IRQ/s";
2409 SET_COUNT; 2426 SET_COUNT;
2410 break; 2427 break;
2411 case _DRM_STAT_PRIMARY: 2428 case _DRM_STAT_PRIMARY:
2412 stats->data[i].long_name = "Primary Bytes"; 2429 stats->data[i].long_name = "Primary Bytes";
2413 stats->data[i].rate_name = "PB/s"; 2430 stats->data[i].rate_name = "PB/s";
2414 SET_BYTE; 2431 SET_BYTE;
2415 break; 2432 break;
2416 case _DRM_STAT_SECONDARY: 2433 case _DRM_STAT_SECONDARY:
2417 stats->data[i].long_name = "Secondary Bytes"; 2434 stats->data[i].long_name = "Secondary Bytes";
2418 stats->data[i].rate_name = "SB/s"; 2435 stats->data[i].rate_name = "SB/s";
2419 SET_BYTE; 2436 SET_BYTE;
2420 break; 2437 break;
2421 case _DRM_STAT_DMA: 2438 case _DRM_STAT_DMA:
2422 stats->data[i].long_name = "DMA"; 2439 stats->data[i].long_name = "DMA";
2423 stats->data[i].rate_name = "DMA/s"; 2440 stats->data[i].rate_name = "DMA/s";
2424 SET_COUNT; 2441 SET_COUNT;
2425 break; 2442 break;
2426 case _DRM_STAT_SPECIAL: 2443 case _DRM_STAT_SPECIAL:
2427 stats->data[i].long_name = "Special DMA"; 2444 stats->data[i].long_name = "Special DMA";
2428 stats->data[i].rate_name = "dma/s"; 2445 stats->data[i].rate_name = "dma/s";
2429 SET_COUNT; 2446 SET_COUNT;
2430 break; 2447 break;
2431 case _DRM_STAT_MISSED: 2448 case _DRM_STAT_MISSED:
2432 stats->data[i].long_name = "Miss"; 2449 stats->data[i].long_name = "Miss";
2433 stats->data[i].rate_name = "Ms/s"; 2450 stats->data[i].rate_name = "Ms/s";
2434 SET_COUNT; 2451 SET_COUNT;
2435 break; 2452 break;
2436 case _DRM_STAT_VALUE: 2453 case _DRM_STAT_VALUE:
2437 stats->data[i].long_name = "Value"; 2454 stats->data[i].long_name = "Value";
2438 stats->data[i].rate_name = "Value"; 2455 stats->data[i].rate_name = "Value";
2439 SET_VALUE; 2456 SET_VALUE;
2440 break; 2457 break;
2441 case _DRM_STAT_BYTE: 2458 case _DRM_STAT_BYTE:
2442 stats->data[i].long_name = "Bytes"; 2459 stats->data[i].long_name = "Bytes";
2443 stats->data[i].rate_name = "B/s"; 2460 stats->data[i].rate_name = "B/s";
2444 SET_BYTE; 2461 SET_BYTE;
2445 break; 2462 break;
2446 case _DRM_STAT_COUNT: 2463 case _DRM_STAT_COUNT:
2447 default: 2464 default:
2448 stats->data[i].long_name = "Count"; 2465 stats->data[i].long_name = "Count";
2449 stats->data[i].rate_name = "Cnt/s"; 2466 stats->data[i].rate_name = "Cnt/s";
2450 SET_COUNT; 2467 SET_COUNT;
2451 break; 2468 break;
2452 } 2469 }
2453 } 2470 }
2454 return 0; 2471 return 0;
2455} 2472}
@@ -2458,14 +2475,14 @@ int drmGetStats(int fd, drmStatsT *stats)
2458 * Issue a set-version ioctl. 2475 * Issue a set-version ioctl.
2459 * 2476 *
2460 * \param fd file descriptor. 2477 * \param fd file descriptor.
2461 * \param drmCommandIndex command index 2478 * \param drmCommandIndex command index
2462 * \param data source pointer of the data to be read and written. 2479 * \param data source pointer of the data to be read and written.
2463 * \param size size of the data to be read and written. 2480 * \param size size of the data to be read and written.
2464 * 2481 *
2465 * \return zero on success, or a negative value on failure. 2482 * \return zero on success, or a negative value on failure.
2466 * 2483 *
2467 * \internal 2484 * \internal
2468 * It issues a read-write ioctl given by 2485 * It issues a read-write ioctl given by
2469 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2486 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2470 */ 2487 */
2471int drmSetInterfaceVersion(int fd, drmSetVersion *version) 2488int drmSetInterfaceVersion(int fd, drmSetVersion *version)
@@ -2480,7 +2497,7 @@ int drmSetInterfaceVersion(int fd, drmSetVersion *version)
2480 sv.drm_dd_minor = version->drm_dd_minor; 2497 sv.drm_dd_minor = version->drm_dd_minor;
2481 2498
2482 if (drmIoctl(fd, DRM_IOCTL_SET_VERSION, &sv)) { 2499 if (drmIoctl(fd, DRM_IOCTL_SET_VERSION, &sv)) {
2483 retcode = -errno; 2500 retcode = -errno;
2484 } 2501 }
2485 2502
2486 version->drm_di_major = sv.drm_di_major; 2503 version->drm_di_major = sv.drm_di_major;
@@ -2495,12 +2512,12 @@ int drmSetInterfaceVersion(int fd, drmSetVersion *version)
2495 * Send a device-specific command. 2512 * Send a device-specific command.
2496 * 2513 *
2497 * \param fd file descriptor. 2514 * \param fd file descriptor.
2498 * \param drmCommandIndex command index 2515 * \param drmCommandIndex command index
2499 * 2516 *
2500 * \return zero on success, or a negative value on failure. 2517 * \return zero on success, or a negative value on failure.
2501 * 2518 *
2502 * \internal 2519 * \internal
2503 * It issues a ioctl given by 2520 * It issues a ioctl given by
2504 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2521 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2505 */ 2522 */
2506int drmCommandNone(int fd, unsigned long drmCommandIndex) 2523int drmCommandNone(int fd, unsigned long drmCommandIndex)
@@ -2510,7 +2527,7 @@ int drmCommandNone(int fd, unsigned long drmCommandIndex)
2510 request = DRM_IO( DRM_COMMAND_BASE + drmCommandIndex); 2527 request = DRM_IO( DRM_COMMAND_BASE + drmCommandIndex);
2511 2528
2512 if (drmIoctl(fd, request, NULL)) { 2529 if (drmIoctl(fd, request, NULL)) {
2513 return -errno; 2530 return -errno;
2514 } 2531 }
2515 return 0; 2532 return 0;
2516} 2533}
@@ -2520,14 +2537,14 @@ int drmCommandNone(int fd, unsigned long drmCommandIndex)
2520 * Send a device-specific read command. 2537 * Send a device-specific read command.
2521 * 2538 *
2522 * \param fd file descriptor. 2539 * \param fd file descriptor.
2523 * \param drmCommandIndex command index 2540 * \param drmCommandIndex command index
2524 * \param data destination pointer of the data to be read. 2541 * \param data destination pointer of the data to be read.
2525 * \param size size of the data to be read. 2542 * \param size size of the data to be read.
2526 * 2543 *
2527 * \return zero on success, or a negative value on failure. 2544 * \return zero on success, or a negative value on failure.
2528 * 2545 *
2529 * \internal 2546 * \internal
2530 * It issues a read ioctl given by 2547 * It issues a read ioctl given by
2531 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2548 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2532 */ 2549 */
2533int drmCommandRead(int fd, unsigned long drmCommandIndex, void *data, 2550int drmCommandRead(int fd, unsigned long drmCommandIndex, void *data,
@@ -2535,11 +2552,11 @@ int drmCommandRead(int fd, unsigned long drmCommandIndex, void *data,
2535{ 2552{
2536 unsigned long request; 2553 unsigned long request;
2537 2554
2538 request = DRM_IOC( DRM_IOC_READ, DRM_IOCTL_BASE, 2555 request = DRM_IOC( DRM_IOC_READ, DRM_IOCTL_BASE,
2539 DRM_COMMAND_BASE + drmCommandIndex, size); 2556 DRM_COMMAND_BASE + drmCommandIndex, size);
2540 2557
2541 if (drmIoctl(fd, request, data)) { 2558 if (drmIoctl(fd, request, data)) {
2542 return -errno; 2559 return -errno;
2543 } 2560 }
2544 return 0; 2561 return 0;
2545} 2562}
@@ -2549,14 +2566,14 @@ int drmCommandRead(int fd, unsigned long drmCommandIndex, void *data,
2549 * Send a device-specific write command. 2566 * Send a device-specific write command.
2550 * 2567 *
2551 * \param fd file descriptor. 2568 * \param fd file descriptor.
2552 * \param drmCommandIndex command index 2569 * \param drmCommandIndex command index
2553 * \param data source pointer of the data to be written. 2570 * \param data source pointer of the data to be written.
2554 * \param size size of the data to be written. 2571 * \param size size of the data to be written.
2555 * 2572 *
2556 * \return zero on success, or a negative value on failure. 2573 * \return zero on success, or a negative value on failure.
2557 * 2574 *
2558 * \internal 2575 * \internal
2559 * It issues a write ioctl given by 2576 * It issues a write ioctl given by
2560 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2577 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2561 */ 2578 */
2562int drmCommandWrite(int fd, unsigned long drmCommandIndex, void *data, 2579int drmCommandWrite(int fd, unsigned long drmCommandIndex, void *data,
@@ -2564,11 +2581,11 @@ int drmCommandWrite(int fd, unsigned long drmCommandIndex, void *data,
2564{ 2581{
2565 unsigned long request; 2582 unsigned long request;
2566 2583
2567 request = DRM_IOC( DRM_IOC_WRITE, DRM_IOCTL_BASE, 2584 request = DRM_IOC( DRM_IOC_WRITE, DRM_IOCTL_BASE,
2568 DRM_COMMAND_BASE + drmCommandIndex, size); 2585 DRM_COMMAND_BASE + drmCommandIndex, size);
2569 2586
2570 if (drmIoctl(fd, request, data)) { 2587 if (drmIoctl(fd, request, data)) {
2571 return -errno; 2588 return -errno;
2572 } 2589 }
2573 return 0; 2590 return 0;
2574} 2591}
@@ -2578,14 +2595,14 @@ int drmCommandWrite(int fd, unsigned long drmCommandIndex, void *data,
2578 * Send a device-specific read-write command. 2595 * Send a device-specific read-write command.
2579 * 2596 *
2580 * \param fd file descriptor. 2597 * \param fd file descriptor.
2581 * \param drmCommandIndex command index 2598 * \param drmCommandIndex command index
2582 * \param data source pointer of the data to be read and written. 2599 * \param data source pointer of the data to be read and written.
2583 * \param size size of the data to be read and written. 2600 * \param size size of the data to be read and written.
2584 * 2601 *
2585 * \return zero on success, or a negative value on failure. 2602 * \return zero on success, or a negative value on failure.
2586 * 2603 *
2587 * \internal 2604 * \internal
2588 * It issues a read-write ioctl given by 2605 * It issues a read-write ioctl given by
2589 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode. 2606 * \code DRM_COMMAND_BASE + drmCommandIndex \endcode.
2590 */ 2607 */
2591int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data, 2608int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data,
@@ -2593,11 +2610,11 @@ int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data,
2593{ 2610{
2594 unsigned long request; 2611 unsigned long request;
2595 2612
2596 request = DRM_IOC( DRM_IOC_READ|DRM_IOC_WRITE, DRM_IOCTL_BASE, 2613 request = DRM_IOC( DRM_IOC_READ|DRM_IOC_WRITE, DRM_IOCTL_BASE,
2597 DRM_COMMAND_BASE + drmCommandIndex, size); 2614 DRM_COMMAND_BASE + drmCommandIndex, size);
2598 2615
2599 if (drmIoctl(fd, request, data)) 2616 if (drmIoctl(fd, request, data))
2600 return -errno; 2617 return -errno;
2601 return 0; 2618 return 0;
2602} 2619}
2603 2620
@@ -2611,9 +2628,9 @@ static struct {
2611 2628
2612static int nr_fds = 0; 2629static int nr_fds = 0;
2613 2630
2614int drmOpenOnce(void *unused, 2631int drmOpenOnce(void *unused,
2615 const char *BusID, 2632 const char *BusID,
2616 int *newlyopened) 2633 int *newlyopened)
2617{ 2634{
2618 return drmOpenOnceWithType(BusID, newlyopened, DRM_NODE_PRIMARY); 2635 return drmOpenOnceWithType(BusID, newlyopened, DRM_NODE_PRIMARY);
2619} 2636}
@@ -2622,19 +2639,19 @@ int drmOpenOnceWithType(const char *BusID, int *newlyopened, int type)
2622{ 2639{
2623 int i; 2640 int i;
2624 int fd; 2641 int fd;
2625 2642
2626 for (i = 0; i < nr_fds; i++) 2643 for (i = 0; i < nr_fds; i++)
2627 if ((strcmp(BusID, connection[i].BusID) == 0) && 2644 if ((strcmp(BusID, connection[i].BusID) == 0) &&
2628 (connection[i].type == type)) { 2645 (connection[i].type == type)) {
2629 connection[i].refcount++; 2646 connection[i].refcount++;
2630 *newlyopened = 0; 2647 *newlyopened = 0;
2631 return connection[i].fd; 2648 return connection[i].fd;
2632 } 2649 }
2633 2650
2634 fd = drmOpenWithType(NULL, BusID, type); 2651 fd = drmOpenWithType(NULL, BusID, type);
2635 if (fd < 0 || nr_fds == DRM_MAX_FDS) 2652 if (fd < 0 || nr_fds == DRM_MAX_FDS)
2636 return fd; 2653 return fd;
2637 2654
2638 connection[nr_fds].BusID = strdup(BusID); 2655 connection[nr_fds].BusID = strdup(BusID);
2639 connection[nr_fds].fd = fd; 2656 connection[nr_fds].fd = fd;
2640 connection[nr_fds].refcount = 1; 2657 connection[nr_fds].refcount = 1;
@@ -2642,9 +2659,9 @@ int drmOpenOnceWithType(const char *BusID, int *newlyopened, int type)
2642 *newlyopened = 1; 2659 *newlyopened = 1;
2643 2660
2644 if (0) 2661 if (0)
2645 fprintf(stderr, "saved connection %d for %s %d\n", 2662 fprintf(stderr, "saved connection %d for %s %d\n",
2646 nr_fds, connection[nr_fds].BusID, 2663 nr_fds, connection[nr_fds].BusID,
2647 strcmp(BusID, connection[nr_fds].BusID)); 2664 strcmp(BusID, connection[nr_fds].BusID));
2648 2665
2649 nr_fds++; 2666 nr_fds++;
2650 2667
@@ -2656,181 +2673,262 @@ void drmCloseOnce(int fd)
2656 int i; 2673 int i;
2657 2674
2658 for (i = 0; i < nr_fds; i++) { 2675 for (i = 0; i < nr_fds; i++) {
2659 if (fd == connection[i].fd) { 2676 if (fd == connection[i].fd) {
2660 if (--connection[i].refcount == 0) { 2677 if (--connection[i].refcount == 0) {
2661 drmClose(connection[i].fd); 2678 drmClose(connection[i].fd);
2662 free(connection[i].BusID); 2679 free(connection[i].BusID);
2663 2680
2664 if (i < --nr_fds) 2681 if (i < --nr_fds)
2665 connection[i] = connection[nr_fds]; 2682 connection[i] = connection[nr_fds];
2666 2683
2667 return; 2684 return;
2668 } 2685 }
2669 } 2686 }
2670 } 2687 }
2671} 2688}
2672 2689
2673int drmSetMaster(int fd) 2690int drmSetMaster(int fd)
2674{ 2691{
2675 return drmIoctl(fd, DRM_IOCTL_SET_MASTER, NULL); 2692 return drmIoctl(fd, DRM_IOCTL_SET_MASTER, NULL);
2676} 2693}
2677 2694
2678int drmDropMaster(int fd) 2695int drmDropMaster(int fd)
2679{ 2696{
2680 return drmIoctl(fd, DRM_IOCTL_DROP_MASTER, NULL); 2697 return drmIoctl(fd, DRM_IOCTL_DROP_MASTER, NULL);
2681} 2698}
2682 2699
2683char *drmGetDeviceNameFromFd(int fd) 2700char *drmGetDeviceNameFromFd(int fd)
2684{ 2701{
2685 char name[128]; 2702 char name[128];
2686 struct stat sbuf; 2703 struct stat sbuf;
2687 dev_t d; 2704 dev_t d;
2688 int i; 2705 int i;
2689 2706
2690 /* The whole drmOpen thing is a fiasco and we need to find a way 2707 /* The whole drmOpen thing is a fiasco and we need to find a way
2691 * back to just using open(2). For now, however, lets just make 2708 * back to just using open(2). For now, however, lets just make
2692 * things worse with even more ad hoc directory walking code to 2709 * things worse with even more ad hoc directory walking code to
2693 * discover the device file name. */ 2710 * discover the device file name. */
2694 2711
2695 fstat(fd, &sbuf); 2712 fstat(fd, &sbuf);
2696 d = sbuf.st_rdev; 2713 d = sbuf.st_rdev;
2697 2714
2698 for (i = 0; i < DRM_MAX_MINOR; i++) { 2715 for (i = 0; i < DRM_MAX_MINOR; i++) {
2699 snprintf(name, sizeof name, DRM_DEV_NAME, DRM_DIR_NAME, i); 2716 snprintf(name, sizeof name, DRM_DEV_NAME, DRM_DIR_NAME, i);
2700 if (stat(name, &sbuf) == 0 && sbuf.st_rdev == d) 2717 if (stat(name, &sbuf) == 0 && sbuf.st_rdev == d)
2701 break; 2718 break;
2702 } 2719 }
2703 if (i == DRM_MAX_MINOR) 2720 if (i == DRM_MAX_MINOR)
2704 return NULL; 2721 return NULL;
2705 2722
2706 return strdup(name); 2723 return strdup(name);
2707} 2724}
2708 2725
2709int drmGetNodeTypeFromFd(int fd) 2726int drmGetNodeTypeFromFd(int fd)
2710{ 2727{
2711 struct stat sbuf; 2728 struct stat sbuf;
2712 int maj, min, type; 2729 int maj, min, type;
2713 2730
2714 if (fstat(fd, &sbuf)) 2731 if (fstat(fd, &sbuf))
2715 return -1; 2732 return -1;
2716 2733
2717 maj = major(sbuf.st_rdev); 2734 maj = major(sbuf.st_rdev);
2718 min = minor(sbuf.st_rdev); 2735 min = minor(sbuf.st_rdev);
2719 2736
2720 if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) { 2737 if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) {
2721 errno = EINVAL; 2738 errno = EINVAL;
2722 return -1; 2739 return -1;
2723 } 2740 }
2724 2741
2725 type = drmGetMinorType(min); 2742 type = drmGetMinorType(min);
2726 if (type == -1) 2743 if (type == -1)
2727 errno = ENODEV; 2744 errno = ENODEV;
2728 return type; 2745 return type;
2729} 2746}
2730 2747
2731int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd) 2748int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd)
2732{ 2749{
2733 struct drm_prime_handle args; 2750 struct drm_prime_handle args;
2734 int ret; 2751 int ret;
2735 2752
2736 memclear(args); 2753 memclear(args);
2737 args.fd = -1; 2754 args.fd = -1;
2738 args.handle = handle; 2755 args.handle = handle;
2739 args.flags = flags; 2756 args.flags = flags;
2740 ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args); 2757 ret = drmIoctl(fd, DRM_IOCTL_PRIME_HANDLE_TO_FD, &args);
2741 if (ret) 2758 if (ret)
2742 return ret; 2759 return ret;
2743 2760
2744 *prime_fd = args.fd; 2761 *prime_fd = args.fd;
2745 return 0; 2762 return 0;
2746} 2763}
2747 2764
2748int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle) 2765int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle)
2749{ 2766{
2750 struct drm_prime_handle args; 2767 struct drm_prime_handle args;
2751 int ret; 2768 int ret;
2752 2769
2753 memclear(args); 2770 memclear(args);
2754 args.fd = prime_fd; 2771 args.fd = prime_fd;
2755 ret = drmIoctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args); 2772 ret = drmIoctl(fd, DRM_IOCTL_PRIME_FD_TO_HANDLE, &args);
2756 if (ret) 2773 if (ret)
2757 return ret; 2774 return ret;
2758 2775
2759 *handle = args.handle; 2776 *handle = args.handle;
2760 return 0; 2777 return 0;
2761} 2778}
2762 2779
2763static char *drmGetMinorNameForFD(int fd, int type) 2780static char *drmGetMinorNameForFD(int fd, int type)
2764{ 2781{
2765#ifdef __linux__ 2782#ifdef __linux__
2766 DIR *sysdir; 2783 DIR *sysdir;
2767 struct dirent *pent, *ent; 2784 struct dirent *pent, *ent;
2768 struct stat sbuf; 2785 struct stat sbuf;
2769 const char *name = drmGetMinorName(type); 2786 const char *name = drmGetMinorName(type);
2770 int len; 2787 int len;
2771 char dev_name[64], buf[64]; 2788 char dev_name[64], buf[64];
2772 long name_max; 2789 long name_max;
2773 int maj, min; 2790 int maj, min;
2774 2791
2775 if (!name) 2792 if (!name)
2776 return NULL; 2793 return NULL;
2777 2794
2778 len = strlen(name); 2795 len = strlen(name);
2779 2796
2780 if (fstat(fd, &sbuf)) 2797 if (fstat(fd, &sbuf))
2781 return NULL; 2798 return NULL;
2782 2799
2783 maj = major(sbuf.st_rdev); 2800 maj = major(sbuf.st_rdev);
2784 min = minor(sbuf.st_rdev); 2801 min = minor(sbuf.st_rdev);
2785 2802
2786 if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode)) 2803 if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
2787 return NULL; 2804 return NULL;
2788 2805
2789 snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/device/drm", maj, min); 2806 snprintf(buf, sizeof(buf), "/sys/dev/char/%d:%d/device/drm", maj, min);
2790 2807
2791 sysdir = opendir(buf); 2808 sysdir = opendir(buf);
2792 if (!sysdir) 2809 if (!sysdir)
2793 return NULL; 2810 return NULL;
2794 2811
2795 name_max = fpathconf(dirfd(sysdir), _PC_NAME_MAX); 2812 name_max = fpathconf(dirfd(sysdir), _PC_NAME_MAX);
2796 if (name_max == -1) 2813 if (name_max == -1)
2797 goto out_close_dir; 2814 goto out_close_dir;
2798 2815
2799 pent = malloc(offsetof(struct dirent, d_name) + name_max + 1); 2816 pent = malloc(offsetof(struct dirent, d_name) + name_max + 1);
2800 if (pent == NULL) 2817 if (pent == NULL)
2801 goto out_close_dir; 2818 goto out_close_dir;
2802 2819
2803 while (readdir_r(sysdir, pent, &ent) == 0 && ent != NULL) { 2820 while (readdir_r(sysdir, pent, &ent) == 0 && ent != NULL) {
2804 if (strncmp(ent->d_name, name, len) == 0) { 2821 if (strncmp(ent->d_name, name, len) == 0) {
2805 snprintf(dev_name, sizeof(dev_name), DRM_DIR_NAME "/%s", 2822 snprintf(dev_name, sizeof(dev_name), DRM_DIR_NAME "/%s",
2806 ent->d_name); 2823 ent->d_name);
2807 2824
2808 free(pent); 2825 free(pent);
2809 closedir(sysdir); 2826 closedir(sysdir);
2810 2827
2811 return strdup(dev_name); 2828 return strdup(dev_name);
2812 } 2829 }
2813 } 2830 }
2814 2831
2815 free(pent); 2832 free(pent);
2816 2833
2817out_close_dir: 2834out_close_dir:
2818 closedir(sysdir); 2835 closedir(sysdir);
2819#else 2836#else
2820#warning "Missing implementation of drmGetMinorNameForFD" 2837 struct stat sbuf;
2838 char buf[PATH_MAX + 1];
2839 const char *dev_name;
2840 unsigned int maj, min;
2841 int n, base;
2842
2843 if (fstat(fd, &sbuf))
2844 return NULL;
2845
2846 maj = major(sbuf.st_rdev);
2847 min = minor(sbuf.st_rdev);
2848
2849 if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
2850 return NULL;
2851
2852 switch (type) {
2853 case DRM_NODE_PRIMARY:
2854 dev_name = DRM_DEV_NAME;
2855 break;
2856 case DRM_NODE_CONTROL:
2857 dev_name = DRM_CONTROL_DEV_NAME;
2858 break;
2859 case DRM_NODE_RENDER:
2860 dev_name = DRM_RENDER_DEV_NAME;
2861 break;
2862 default:
2863 return NULL;
2864 };
2865
2866 base = drmGetMinorBase(type);
2867 if (base < 0)
2868 return NULL;
2869
2870 n = snprintf(buf, sizeof(buf), dev_name, DRM_DIR_NAME, min - base);
2871 if (n == -1 || n >= sizeof(buf))
2872 return NULL;
2873
2874 return strdup(buf);
2821#endif 2875#endif
2822 return NULL; 2876 return NULL;
2823} 2877}
2824 2878
2825char *drmGetPrimaryDeviceNameFromFd(int fd) 2879char *drmGetPrimaryDeviceNameFromFd(int fd)
2826{ 2880{
2827 return drmGetMinorNameForFD(fd, DRM_NODE_PRIMARY); 2881 return drmGetMinorNameForFD(fd, DRM_NODE_PRIMARY);
2828} 2882}
2829 2883
2830char *drmGetRenderDeviceNameFromFd(int fd) 2884char *drmGetRenderDeviceNameFromFd(int fd)
2831{ 2885{
2832 return drmGetMinorNameForFD(fd, DRM_NODE_RENDER); 2886 return drmGetMinorNameForFD(fd, DRM_NODE_RENDER);
2887}
2888
2889#ifdef __linux__
2890static char * DRM_PRINTFLIKE(2, 3)
2891sysfs_uevent_get(const char *path, const char *fmt, ...)
2892{
2893 char filename[PATH_MAX + 1], *key, *line = NULL, *value = NULL;
2894 size_t size = 0, len;
2895 ssize_t num;
2896 va_list ap;
2897 FILE *fp;
2898
2899 va_start(ap, fmt);
2900 num = vasprintf(&key, fmt, ap);
2901 va_end(ap);
2902 len = num;
2903
2904 snprintf(filename, sizeof(filename), "%s/uevent", path);
2905
2906 fp = fopen(filename, "r");
2907 if (!fp) {
2908 free(key);
2909 return NULL;
2910 }
2911
2912 while ((num = getline(&line, &size, fp)) >= 0) {
2913 if ((strncmp(line, key, len) == 0) && (line[len] == '=')) {
2914 char *start = line + len + 1, *end = line + num - 1;
2915
2916 if (*end != '\n')
2917 end++;
2918
2919 value = strndup(start, end - start);
2920 break;
2921 }
2922 }
2923
2924 free(line);
2925 fclose(fp);
2926
2927 free(key);
2928
2929 return value;
2833} 2930}
2931#endif
2834 2932
2835static int drmParseSubsystemType(int maj, int min) 2933static int drmParseSubsystemType(int maj, int min)
2836{ 2934{
@@ -2852,7 +2950,18 @@ static int drmParseSubsystemType(int maj, int min)
2852 if (strncmp(name, "/pci", 4) == 0) 2950 if (strncmp(name, "/pci", 4) == 0)
2853 return DRM_BUS_PCI; 2951 return DRM_BUS_PCI;
2854 2952
2953 if (strncmp(name, "/usb", 4) == 0)
2954 return DRM_BUS_USB;
2955
2956 if (strncmp(name, "/platform", 9) == 0)
2957 return DRM_BUS_PLATFORM;
2958
2959 if (strncmp(name, "/host1x", 7) == 0)
2960 return DRM_BUS_HOST1X;
2961
2855 return -EINVAL; 2962 return -EINVAL;
2963#elif defined(__OpenBSD__)
2964 return DRM_BUS_PCI;
2856#else 2965#else
2857#warning "Missing implementation of drmParseSubsystemType" 2966#warning "Missing implementation of drmParseSubsystemType"
2858 return -EINVAL; 2967 return -EINVAL;
@@ -2862,31 +2971,21 @@ static int drmParseSubsystemType(int maj, int min)
2862static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info) 2971static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info)
2863{ 2972{
2864#ifdef __linux__ 2973#ifdef __linux__
2865 char path[PATH_MAX + 1]; 2974 unsigned int domain, bus, dev, func;
2866 char data[128]; 2975 char path[PATH_MAX + 1], *value;
2867 char *str; 2976 int num;
2868 int domain, bus, dev, func;
2869 int fd, ret;
2870 2977
2871 snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/uevent", maj, min); 2978 snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
2872 fd = open(path, O_RDONLY);
2873 if (fd < 0)
2874 return -errno;
2875 2979
2876 ret = read(fd, data, sizeof(data)); 2980 value = sysfs_uevent_get(path, "PCI_SLOT_NAME");
2877 close(fd); 2981 if (!value)
2878 if (ret < 0) 2982 return -ENOENT;
2879 return -errno;
2880 2983
2881#define TAG "PCI_SLOT_NAME=" 2984 num = sscanf(value, "%04x:%02x:%02x.%1u", &domain, &bus, &dev, &func);
2882 str = strstr(data, TAG); 2985 free(value);
2883 if (str == NULL)
2884 return -EINVAL;
2885 2986
2886 if (sscanf(str, TAG "%04x:%02x:%02x.%1u", 2987 if (num != 4)
2887 &domain, &bus, &dev, &func) != 4)
2888 return -EINVAL; 2988 return -EINVAL;
2889#undef TAG
2890 2989
2891 info->domain = domain; 2990 info->domain = domain;
2892 info->bus = bus; 2991 info->bus = bus;
@@ -2894,6 +2993,30 @@ static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info)
2894 info->func = func; 2993 info->func = func;
2895 2994
2896 return 0; 2995 return 0;
2996#elif defined(__OpenBSD__)
2997 struct drm_pciinfo pinfo;
2998 int fd, type;
2999
3000 type = drmGetMinorType(min);
3001 if (type == -1)
3002 return -ENODEV;
3003
3004 fd = drmOpenMinor(min, 0, type);
3005 if (fd < 0)
3006 return -errno;
3007
3008 if (drmIoctl(fd, DRM_IOCTL_GET_PCIINFO, &pinfo)) {
3009 close(fd);
3010 return -errno;
3011 }
3012 close(fd);
3013
3014 info->domain = pinfo.domain;
3015 info->bus = pinfo.bus;
3016 info->dev = pinfo.dev;
3017 info->func = pinfo.func;
3018
3019 return 0;
2897#else 3020#else
2898#warning "Missing implementation of drmParsePciBusInfo" 3021#warning "Missing implementation of drmParsePciBusInfo"
2899 return -EINVAL; 3022 return -EINVAL;
@@ -2911,6 +3034,16 @@ static int drmCompareBusInfo(drmDevicePtr a, drmDevicePtr b)
2911 switch (a->bustype) { 3034 switch (a->bustype) {
2912 case DRM_BUS_PCI: 3035 case DRM_BUS_PCI:
2913 return memcmp(a->businfo.pci, b->businfo.pci, sizeof(drmPciBusInfo)); 3036 return memcmp(a->businfo.pci, b->businfo.pci, sizeof(drmPciBusInfo));
3037
3038 case DRM_BUS_USB:
3039 return memcmp(a->businfo.usb, b->businfo.usb, sizeof(drmUsbBusInfo));
3040
3041 case DRM_BUS_PLATFORM:
3042 return memcmp(a->businfo.platform, b->businfo.platform, sizeof(drmPlatformBusInfo));
3043
3044 case DRM_BUS_HOST1X:
3045 return memcmp(a->businfo.host1x, b->businfo.host1x, sizeof(drmHost1xBusInfo));
3046
2914 default: 3047 default:
2915 break; 3048 break;
2916 } 3049 }
@@ -2941,18 +3074,58 @@ static int drmGetMaxNodeName(void)
2941 MAX3(sizeof(DRM_PRIMARY_MINOR_NAME), 3074 MAX3(sizeof(DRM_PRIMARY_MINOR_NAME),
2942 sizeof(DRM_CONTROL_MINOR_NAME), 3075 sizeof(DRM_CONTROL_MINOR_NAME),
2943 sizeof(DRM_RENDER_MINOR_NAME)) + 3076 sizeof(DRM_RENDER_MINOR_NAME)) +
2944 3 /* lenght of the node number */; 3077 3 /* length of the node number */;
2945} 3078}
2946 3079
2947static int drmParsePciDeviceInfo(const char *d_name,
2948 drmPciDeviceInfoPtr device)
2949{
2950#ifdef __linux__ 3080#ifdef __linux__
3081static int parse_separate_sysfs_files(int maj, int min,
3082 drmPciDeviceInfoPtr device,
3083 bool ignore_revision)
3084{
3085#define ARRAY_SIZE(a) (sizeof(a) / sizeof((a)[0]))
3086 static const char *attrs[] = {
3087 "revision", /* Older kernels are missing the file, so check for it first */
3088 "vendor",
3089 "device",
3090 "subsystem_vendor",
3091 "subsystem_device",
3092 };
3093 char path[PATH_MAX + 1];
3094 unsigned int data[ARRAY_SIZE(attrs)];
3095 FILE *fp;
3096 int ret;
3097
3098 for (unsigned i = ignore_revision ? 1 : 0; i < ARRAY_SIZE(attrs); i++) {
3099 snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/%s", maj, min,
3100 attrs[i]);
3101 fp = fopen(path, "r");
3102 if (!fp)
3103 return -errno;
3104
3105 ret = fscanf(fp, "%x", &data[i]);
3106 fclose(fp);
3107 if (ret != 1)
3108 return -errno;
3109
3110 }
3111
3112 device->revision_id = ignore_revision ? 0xff : data[0] & 0xff;
3113 device->vendor_id = data[1] & 0xffff;
3114 device->device_id = data[2] & 0xffff;
3115 device->subvendor_id = data[3] & 0xffff;
3116 device->subdevice_id = data[4] & 0xffff;
3117
3118 return 0;
3119}
3120
3121static int parse_config_sysfs_file(int maj, int min,
3122 drmPciDeviceInfoPtr device)
3123{
2951 char path[PATH_MAX + 1]; 3124 char path[PATH_MAX + 1];
2952 unsigned char config[64]; 3125 unsigned char config[64];
2953 int fd, ret; 3126 int fd, ret;
2954 3127
2955 snprintf(path, PATH_MAX, "/sys/class/drm/%s/device/config", d_name); 3128 snprintf(path, PATH_MAX, "/sys/dev/char/%d:%d/device/config", maj, min);
2956 fd = open(path, O_RDONLY); 3129 fd = open(path, O_RDONLY);
2957 if (fd < 0) 3130 if (fd < 0)
2958 return -errno; 3131 return -errno;
@@ -2969,17 +3142,101 @@ static int drmParsePciDeviceInfo(const char *d_name,
2969 device->subdevice_id = config[46] | (config[47] << 8); 3142 device->subdevice_id = config[46] | (config[47] << 8);
2970 3143
2971 return 0; 3144 return 0;
3145}
3146#endif
3147
3148static int drmParsePciDeviceInfo(int maj, int min,
3149 drmPciDeviceInfoPtr device,
3150 uint32_t flags)
3151{
3152#ifdef __linux__
3153 if (!(flags & DRM_DEVICE_GET_PCI_REVISION))
3154 return parse_separate_sysfs_files(maj, min, device, true);
3155
3156 if (parse_separate_sysfs_files(maj, min, device, false))
3157 return parse_config_sysfs_file(maj, min, device);
3158
3159 return 0;
3160#elif defined(__OpenBSD__)
3161 struct drm_pciinfo pinfo;
3162 int fd, type;
3163
3164 type = drmGetMinorType(min);
3165 if (type == -1)
3166 return -ENODEV;
3167
3168 fd = drmOpenMinor(min, 0, type);
3169 if (fd < 0)
3170 return -errno;
3171
3172 if (drmIoctl(fd, DRM_IOCTL_GET_PCIINFO, &pinfo)) {
3173 close(fd);
3174 return -errno;
3175 }
3176 close(fd);
3177
3178 device->vendor_id = pinfo.vendor_id;
3179 device->device_id = pinfo.device_id;
3180 device->revision_id = pinfo.revision_id;
3181 device->subvendor_id = pinfo.subvendor_id;
3182 device->subdevice_id = pinfo.subdevice_id;
3183
3184 return 0;
2972#else 3185#else
2973#warning "Missing implementation of drmParsePciDeviceInfo" 3186#warning "Missing implementation of drmParsePciDeviceInfo"
2974 return -EINVAL; 3187 return -EINVAL;
2975#endif 3188#endif
2976} 3189}
2977 3190
3191static void drmFreePlatformDevice(drmDevicePtr device)
3192{
3193 if (device->deviceinfo.platform) {
3194 if (device->deviceinfo.platform->compatible) {
3195 char **compatible = device->deviceinfo.platform->compatible;
3196
3197 while (*compatible) {
3198 free(*compatible);
3199 compatible++;
3200 }
3201
3202 free(device->deviceinfo.platform->compatible);
3203 }
3204 }
3205}
3206
3207static void drmFreeHost1xDevice(drmDevicePtr device)
3208{
3209 if (device->deviceinfo.host1x) {
3210 if (device->deviceinfo.host1x->compatible) {
3211 char **compatible = device->deviceinfo.host1x->compatible;
3212
3213 while (*compatible) {
3214 free(*compatible);
3215 compatible++;
3216 }
3217
3218 free(device->deviceinfo.host1x->compatible);
3219 }
3220 }
3221}
3222
2978void drmFreeDevice(drmDevicePtr *device) 3223void drmFreeDevice(drmDevicePtr *device)
2979{ 3224{
2980 if (device == NULL) 3225 if (device == NULL)
2981 return; 3226 return;
2982 3227
3228 if (*device) {
3229 switch ((*device)->bustype) {
3230 case DRM_BUS_PLATFORM:
3231 drmFreePlatformDevice(*device);
3232 break;
3233
3234 case DRM_BUS_HOST1X:
3235 drmFreeHost1xDevice(*device);
3236 break;
3237 }
3238 }
3239
2983 free(*device); 3240 free(*device);
2984 *device = NULL; 3241 *device = NULL;
2985} 3242}
@@ -2991,63 +3248,415 @@ void drmFreeDevices(drmDevicePtr devices[], int count)
2991 if (devices == NULL) 3248 if (devices == NULL)
2992 return; 3249 return;
2993 3250
2994 for (i = 0; i < count && devices[i] != NULL; i++) 3251 for (i = 0; i < count; i++)
2995 drmFreeDevice(&devices[i]); 3252 if (devices[i])
3253 drmFreeDevice(&devices[i]);
2996} 3254}
2997 3255
2998static int drmProcessPciDevice(drmDevicePtr *device, const char *d_name, 3256static drmDevicePtr drmDeviceAlloc(unsigned int type, const char *node,
2999 const char *node, int node_type, 3257 size_t bus_size, size_t device_size,
3000 int maj, int min, bool fetch_deviceinfo) 3258 char **ptrp)
3001{ 3259{
3002 const int max_node_str = drmGetMaxNodeName(); 3260 size_t max_node_length, extra, size;
3003 int ret, i; 3261 drmDevicePtr device;
3004 char *addr; 3262 unsigned int i;
3263 char *ptr;
3005 3264
3006 *device = calloc(1, sizeof(drmDevice) + 3265 max_node_length = ALIGN(drmGetMaxNodeName(), sizeof(void *));
3007 (DRM_NODE_MAX * (sizeof(void *) + max_node_str)) + 3266 extra = DRM_NODE_MAX * (sizeof(void *) + max_node_length);
3008 sizeof(drmPciBusInfo) + 3267
3009 sizeof(drmPciDeviceInfo)); 3268 size = sizeof(*device) + extra + bus_size + device_size;
3010 if (!*device) 3269
3011 return -ENOMEM; 3270 device = calloc(1, size);
3271 if (!device)
3272 return NULL;
3273
3274 device->available_nodes = 1 << type;
3012 3275
3013 addr = (char*)*device; 3276 ptr = (char *)device + sizeof(*device);
3014 3277 device->nodes = (char **)ptr;
3015 (*device)->bustype = DRM_BUS_PCI;
3016 (*device)->available_nodes = 1 << node_type;
3017 3278
3018 addr += sizeof(drmDevice); 3279 ptr += DRM_NODE_MAX * sizeof(void *);
3019 (*device)->nodes = (char**)addr;
3020 3280
3021 addr += DRM_NODE_MAX * sizeof(void *);
3022 for (i = 0; i < DRM_NODE_MAX; i++) { 3281 for (i = 0; i < DRM_NODE_MAX; i++) {
3023 (*device)->nodes[i] = addr; 3282 device->nodes[i] = ptr;
3024 addr += max_node_str; 3283 ptr += max_node_length;
3025 } 3284 }
3026 memcpy((*device)->nodes[node_type], node, max_node_str);
3027 3285
3028 (*device)->businfo.pci = (drmPciBusInfoPtr)addr; 3286 memcpy(device->nodes[type], node, max_node_length);
3287
3288 *ptrp = ptr;
3289
3290 return device;
3291}
3292
3293static int drmProcessPciDevice(drmDevicePtr *device,
3294 const char *node, int node_type,
3295 int maj, int min, bool fetch_deviceinfo,
3296 uint32_t flags)
3297{
3298 drmDevicePtr dev;
3299 char *addr;
3300 int ret;
3301
3302 dev = drmDeviceAlloc(node_type, node, sizeof(drmPciBusInfo),
3303 sizeof(drmPciDeviceInfo), &addr);
3304 if (!dev)
3305 return -ENOMEM;
3306
3307 dev->bustype = DRM_BUS_PCI;
3308
3309 dev->businfo.pci = (drmPciBusInfoPtr)addr;
3029 3310
3030 ret = drmParsePciBusInfo(maj, min, (*device)->businfo.pci); 3311 ret = drmParsePciBusInfo(maj, min, dev->businfo.pci);
3031 if (ret) 3312 if (ret)
3032 goto free_device; 3313 goto free_device;
3033 3314
3034 // Fetch the device info if the user has requested it 3315 // Fetch the device info if the user has requested it
3035 if (fetch_deviceinfo) { 3316 if (fetch_deviceinfo) {
3036 addr += sizeof(drmPciBusInfo); 3317 addr += sizeof(drmPciBusInfo);
3037 (*device)->deviceinfo.pci = (drmPciDeviceInfoPtr)addr; 3318 dev->deviceinfo.pci = (drmPciDeviceInfoPtr)addr;
3038 3319
3039 ret = drmParsePciDeviceInfo(d_name, (*device)->deviceinfo.pci); 3320 ret = drmParsePciDeviceInfo(maj, min, dev->deviceinfo.pci, flags);
3040 if (ret) 3321 if (ret)
3041 goto free_device; 3322 goto free_device;
3042 } 3323 }
3324
3325 *device = dev;
3326
3043 return 0; 3327 return 0;
3044 3328
3045free_device: 3329free_device:
3046 free(*device); 3330 free(dev);
3047 *device = NULL; 3331 return ret;
3332}
3333
3334static int drmParseUsbBusInfo(int maj, int min, drmUsbBusInfoPtr info)
3335{
3336#ifdef __linux__
3337 char path[PATH_MAX + 1], *value;
3338 unsigned int bus, dev;
3339 int ret;
3340
3341 snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
3342
3343 value = sysfs_uevent_get(path, "BUSNUM");
3344 if (!value)
3345 return -ENOENT;
3346
3347 ret = sscanf(value, "%03u", &bus);
3348 free(value);
3349
3350 if (ret <= 0)
3351 return -errno;
3352
3353 value = sysfs_uevent_get(path, "DEVNUM");
3354 if (!value)
3355 return -ENOENT;
3356
3357 ret = sscanf(value, "%03u", &dev);
3358 free(value);
3359
3360 if (ret <= 0)
3361 return -errno;
3362
3363 info->bus = bus;
3364 info->dev = dev;
3365
3366 return 0;
3367#else
3368#warning "Missing implementation of drmParseUsbBusInfo"
3369 return -EINVAL;
3370#endif
3371}
3372
3373static int drmParseUsbDeviceInfo(int maj, int min, drmUsbDeviceInfoPtr info)
3374{
3375#ifdef __linux__
3376 char path[PATH_MAX + 1], *value;
3377 unsigned int vendor, product;
3378 int ret;
3379
3380 snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
3381
3382 value = sysfs_uevent_get(path, "PRODUCT");
3383 if (!value)
3384 return -ENOENT;
3385
3386 ret = sscanf(value, "%x/%x", &vendor, &product);
3387 free(value);
3388
3389 if (ret <= 0)
3390 return -errno;
3391
3392 info->vendor = vendor;
3393 info->product = product;
3394
3395 return 0;
3396#else
3397#warning "Missing implementation of drmParseUsbDeviceInfo"
3398 return -EINVAL;
3399#endif
3400}
3401
3402static int drmProcessUsbDevice(drmDevicePtr *device, const char *node,
3403 int node_type, int maj, int min,
3404 bool fetch_deviceinfo, uint32_t flags)
3405{
3406 drmDevicePtr dev;
3407 char *ptr;
3408 int ret;
3409
3410 dev = drmDeviceAlloc(node_type, node, sizeof(drmUsbBusInfo),
3411 sizeof(drmUsbDeviceInfo), &ptr);
3412 if (!dev)
3413 return -ENOMEM;
3414
3415 dev->bustype = DRM_BUS_USB;
3416
3417 dev->businfo.usb = (drmUsbBusInfoPtr)ptr;
3418
3419 ret = drmParseUsbBusInfo(maj, min, dev->businfo.usb);
3420 if (ret < 0)
3421 goto free_device;
3422
3423 if (fetch_deviceinfo) {
3424 ptr += sizeof(drmUsbBusInfo);
3425 dev->deviceinfo.usb = (drmUsbDeviceInfoPtr)ptr;
3426
3427 ret = drmParseUsbDeviceInfo(maj, min, dev->deviceinfo.usb);
3428 if (ret < 0)
3429 goto free_device;
3430 }
3431
3432 *device = dev;
3433
3434 return 0;
3435
3436free_device:
3437 free(dev);
3438 return ret;
3439}
3440
3441static int drmParsePlatformBusInfo(int maj, int min, drmPlatformBusInfoPtr info)
3442{
3443#ifdef __linux__
3444 char path[PATH_MAX + 1], *name;
3445
3446 snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
3447
3448 name = sysfs_uevent_get(path, "OF_FULLNAME");
3449 if (!name)
3450 return -ENOENT;
3451
3452 strncpy(info->fullname, name, DRM_PLATFORM_DEVICE_NAME_LEN);
3453 info->fullname[DRM_PLATFORM_DEVICE_NAME_LEN - 1] = '\0';
3454 free(name);
3455
3456 return 0;
3457#else
3458#warning "Missing implementation of drmParsePlatformBusInfo"
3459 return -EINVAL;
3460#endif
3461}
3462
3463static int drmParsePlatformDeviceInfo(int maj, int min,
3464 drmPlatformDeviceInfoPtr info)
3465{
3466#ifdef __linux__
3467 char path[PATH_MAX + 1], *value;
3468 unsigned int count, i;
3469 int err;
3470
3471 snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
3472
3473 value = sysfs_uevent_get(path, "OF_COMPATIBLE_N");
3474 if (!value)
3475 return -ENOENT;
3476
3477 sscanf(value, "%u", &count);
3478 free(value);
3479
3480 info->compatible = calloc(count + 1, sizeof(*info->compatible));
3481 if (!info->compatible)
3482 return -ENOMEM;
3483
3484 for (i = 0; i < count; i++) {
3485 value = sysfs_uevent_get(path, "OF_COMPATIBLE_%u", i);
3486 if (!value) {
3487 err = -ENOENT;
3488 goto free;
3489 }
3490
3491 info->compatible[i] = value;
3492 }
3493
3494 return 0;
3495
3496free:
3497 while (i--)
3498 free(info->compatible[i]);
3499
3500 free(info->compatible);
3501 return err;
3502#else
3503#warning "Missing implementation of drmParsePlatformDeviceInfo"
3504 return -EINVAL;
3505#endif
3506}
3507
3508static int drmProcessPlatformDevice(drmDevicePtr *device,
3509 const char *node, int node_type,
3510 int maj, int min, bool fetch_deviceinfo,
3511 uint32_t flags)
3512{
3513 drmDevicePtr dev;
3514 char *ptr;
3515 int ret;
3516
3517 dev = drmDeviceAlloc(node_type, node, sizeof(drmPlatformBusInfo),
3518 sizeof(drmPlatformDeviceInfo), &ptr);
3519 if (!dev)
3520 return -ENOMEM;
3521
3522 dev->bustype = DRM_BUS_PLATFORM;
3523
3524 dev->businfo.platform = (drmPlatformBusInfoPtr)ptr;
3525
3526 ret = drmParsePlatformBusInfo(maj, min, dev->businfo.platform);
3527 if (ret < 0)
3528 goto free_device;
3529
3530 if (fetch_deviceinfo) {
3531 ptr += sizeof(drmPlatformBusInfo);
3532 dev->deviceinfo.platform = (drmPlatformDeviceInfoPtr)ptr;
3533
3534 ret = drmParsePlatformDeviceInfo(maj, min, dev->deviceinfo.platform);
3535 if (ret < 0)
3536 goto free_device;
3537 }
3538
3539 *device = dev;
3540
3541 return 0;
3542
3543free_device:
3544 free(dev);
3545 return ret;
3546}
3547
3548static int drmParseHost1xBusInfo(int maj, int min, drmHost1xBusInfoPtr info)
3549{
3550#ifdef __linux__
3551 char path[PATH_MAX + 1], *name;
3552
3553 snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
3554
3555 name = sysfs_uevent_get(path, "OF_FULLNAME");
3556 if (!name)
3557 return -ENOENT;
3558
3559 strncpy(info->fullname, name, DRM_HOST1X_DEVICE_NAME_LEN);
3560 info->fullname[DRM_HOST1X_DEVICE_NAME_LEN - 1] = '\0';
3561 free(name);
3562
3563 return 0;
3564#else
3565#warning "Missing implementation of drmParseHost1xBusInfo"
3566 return -EINVAL;
3567#endif
3568}
3569
3570static int drmParseHost1xDeviceInfo(int maj, int min,
3571 drmHost1xDeviceInfoPtr info)
3572{
3573#ifdef __linux__
3574 char path[PATH_MAX + 1], *value;
3575 unsigned int count, i;
3576 int err;
3577
3578 snprintf(path, sizeof(path), "/sys/dev/char/%d:%d/device", maj, min);
3579
3580 value = sysfs_uevent_get(path, "OF_COMPATIBLE_N");
3581 if (!value)
3582 return -ENOENT;
3583
3584 sscanf(value, "%u", &count);
3585 free(value);
3586
3587 info->compatible = calloc(count + 1, sizeof(*info->compatible));
3588 if (!info->compatible)
3589 return -ENOMEM;
3590
3591 for (i = 0; i < count; i++) {
3592 value = sysfs_uevent_get(path, "OF_COMPATIBLE_%u", i);
3593 if (!value) {
3594 err = -ENOENT;
3595 goto free;
3596 }
3597
3598 info->compatible[i] = value;
3599 }
3600
3601 return 0;
3602
3603free:
3604 while (i--)
3605 free(info->compatible[i]);
3606
3607 free(info->compatible);
3608 return err;
3609#else
3610#warning "Missing implementation of drmParseHost1xDeviceInfo"
3611 return -EINVAL;
3612#endif
3613}
3614
3615static int drmProcessHost1xDevice(drmDevicePtr *device,
3616 const char *node, int node_type,
3617 int maj, int min, bool fetch_deviceinfo,
3618 uint32_t flags)
3619{
3620 drmDevicePtr dev;
3621 char *ptr;
3622 int ret;
3623
3624 dev = drmDeviceAlloc(node_type, node, sizeof(drmHost1xBusInfo),
3625 sizeof(drmHost1xDeviceInfo), &ptr);
3626 if (!dev)
3627 return -ENOMEM;
3628
3629 dev->bustype = DRM_BUS_HOST1X;
3630
3631 dev->businfo.host1x = (drmHost1xBusInfoPtr)ptr;
3632
3633 ret = drmParseHost1xBusInfo(maj, min, dev->businfo.host1x);
3634 if (ret < 0)
3635 goto free_device;
3636
3637 if (fetch_deviceinfo) {
3638 ptr += sizeof(drmHost1xBusInfo);
3639 dev->deviceinfo.host1x = (drmHost1xDeviceInfoPtr)ptr;
3640
3641 ret = drmParseHost1xDeviceInfo(maj, min, dev->deviceinfo.host1x);
3642 if (ret < 0)
3643 goto free_device;
3644 }
3645
3646 *device = dev;
3647
3648 return 0;
3649
3650free_device:
3651 free(dev);
3048 return ret; 3652 return ret;
3049} 3653}
3050 3654
3655/* Consider devices located on the same bus as duplicate and fold the respective
3656 * entries into a single one.
3657 *
3658 * Note: this leaves "gaps" in the array, while preserving the length.
3659 */
3051static void drmFoldDuplicatedDevices(drmDevicePtr local_devices[], int count) 3660static void drmFoldDuplicatedDevices(drmDevicePtr local_devices[], int count)
3052{ 3661{
3053 int node_type, i, j; 3662 int node_type, i, j;
@@ -3065,17 +3674,93 @@ static void drmFoldDuplicatedDevices(drmDevicePtr local_devices[], int count)
3065 } 3674 }
3066} 3675}
3067 3676
3677/* Check that the given flags are valid returning 0 on success */
3678static int
3679drm_device_validate_flags(uint32_t flags)
3680{
3681 return (flags & ~DRM_DEVICE_GET_PCI_REVISION);
3682}
3683
3068/** 3684/**
3069 * Get information about the opened drm device 3685 * Get information about the opened drm device
3070 * 3686 *
3071 * \param fd file descriptor of the drm device 3687 * \param fd file descriptor of the drm device
3688 * \param flags feature/behaviour bitmask
3072 * \param device the address of a drmDevicePtr where the information 3689 * \param device the address of a drmDevicePtr where the information
3073 * will be allocated in stored 3690 * will be allocated in stored
3074 * 3691 *
3075 * \return zero on success, negative error code otherwise. 3692 * \return zero on success, negative error code otherwise.
3693 *
3694 * \note Unlike drmGetDevice it does not retrieve the pci device revision field
3695 * unless the DRM_DEVICE_GET_PCI_REVISION \p flag is set.
3076 */ 3696 */
3077int drmGetDevice(int fd, drmDevicePtr *device) 3697int drmGetDevice2(int fd, uint32_t flags, drmDevicePtr *device)
3078{ 3698{
3699#ifdef __OpenBSD__
3700 /*
3701 * DRI device nodes on OpenBSD are not in their own directory, they reside
3702 * in /dev along with a large number of statically generated /dev nodes.
3703 * Avoid stat'ing all of /dev needlessly by implementing this custom path.
3704 */
3705 drmDevicePtr d;
3706 struct stat sbuf;
3707 char node[PATH_MAX + 1];
3708 const char *dev_name;
3709 int node_type, subsystem_type;
3710 int maj, min, n, ret, base;
3711
3712 if (fd == -1 || device == NULL)
3713 return -EINVAL;
3714
3715 if (fstat(fd, &sbuf))
3716 return -errno;
3717
3718 maj = major(sbuf.st_rdev);
3719 min = minor(sbuf.st_rdev);
3720
3721 if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
3722 return -EINVAL;
3723
3724 node_type = drmGetMinorType(min);
3725 if (node_type == -1)
3726 return -ENODEV;
3727
3728 switch (node_type) {
3729 case DRM_NODE_PRIMARY:
3730 dev_name = DRM_DEV_NAME;
3731 break;
3732 case DRM_NODE_CONTROL:
3733 dev_name = DRM_CONTROL_DEV_NAME;
3734 break;
3735 case DRM_NODE_RENDER:
3736 dev_name = DRM_RENDER_DEV_NAME;
3737 break;
3738 default:
3739 return -EINVAL;
3740 };
3741
3742 base = drmGetMinorBase(node_type);
3743 if (base < 0)
3744 return -EINVAL;
3745
3746 n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min - base);
3747 if (n == -1 || n >= PATH_MAX)
3748 return -errno;
3749 if (stat(node, &sbuf))
3750 return -EINVAL;
3751
3752 subsystem_type = drmParseSubsystemType(maj, min);
3753 if (subsystem_type != DRM_BUS_PCI)
3754 return -ENODEV;
3755
3756 ret = drmProcessPciDevice(&d, node, node_type, maj, min, true, flags);
3757 if (ret)
3758 return ret;
3759
3760 *device = d;
3761
3762 return 0;
3763#else
3079 drmDevicePtr *local_devices; 3764 drmDevicePtr *local_devices;
3080 drmDevicePtr d; 3765 drmDevicePtr d;
3081 DIR *sysdir; 3766 DIR *sysdir;
@@ -3086,6 +3771,10 @@ int drmGetDevice(int fd, drmDevicePtr *device)
3086 int maj, min; 3771 int maj, min;
3087 int ret, i, node_count; 3772 int ret, i, node_count;
3088 int max_count = 16; 3773 int max_count = 16;
3774 dev_t find_rdev;
3775
3776 if (drm_device_validate_flags(flags))
3777 return -EINVAL;
3089 3778
3090 if (fd == -1 || device == NULL) 3779 if (fd == -1 || device == NULL)
3091 return -EINVAL; 3780 return -EINVAL;
@@ -3093,6 +3782,7 @@ int drmGetDevice(int fd, drmDevicePtr *device)
3093 if (fstat(fd, &sbuf)) 3782 if (fstat(fd, &sbuf))
3094 return -errno; 3783 return -errno;
3095 3784
3785 find_rdev = sbuf.st_rdev;
3096 maj = major(sbuf.st_rdev); 3786 maj = major(sbuf.st_rdev);
3097 min = minor(sbuf.st_rdev); 3787 min = minor(sbuf.st_rdev);
3098 3788
@@ -3132,14 +3822,34 @@ int drmGetDevice(int fd, drmDevicePtr *device)
3132 3822
3133 switch (subsystem_type) { 3823 switch (subsystem_type) {
3134 case DRM_BUS_PCI: 3824 case DRM_BUS_PCI:
3135 ret = drmProcessPciDevice(&d, dent->d_name, node, node_type, 3825 ret = drmProcessPciDevice(&d, node, node_type, maj, min, true, flags);
3136 maj, min, true);
3137 if (ret) 3826 if (ret)
3138 goto free_devices; 3827 continue;
3828
3829 break;
3830
3831 case DRM_BUS_USB:
3832 ret = drmProcessUsbDevice(&d, node, node_type, maj, min, true, flags);
3833 if (ret)
3834 continue;
3835
3836 break;
3837
3838 case DRM_BUS_PLATFORM:
3839 ret = drmProcessPlatformDevice(&d, node, node_type, maj, min, true, flags);
3840 if (ret)
3841 continue;
3139 3842
3140 break; 3843 break;
3844
3845 case DRM_BUS_HOST1X:
3846 ret = drmProcessHost1xDevice(&d, node, node_type, maj, min, true, flags);
3847 if (ret)
3848 continue;
3849
3850 break;
3851
3141 default: 3852 default:
3142 fprintf(stderr, "The subsystem type is not supported yet\n");
3143 continue; 3853 continue;
3144 } 3854 }
3145 3855
@@ -3153,20 +3863,26 @@ int drmGetDevice(int fd, drmDevicePtr *device)
3153 local_devices = temp; 3863 local_devices = temp;
3154 } 3864 }
3155 3865
3156 local_devices[i] = d; 3866 /* store target at local_devices[0] for ease to use below */
3867 if (find_rdev == sbuf.st_rdev && i) {
3868 local_devices[i] = local_devices[0];
3869 local_devices[0] = d;
3870 }
3871 else
3872 local_devices[i] = d;
3157 i++; 3873 i++;
3158 } 3874 }
3159 node_count = i; 3875 node_count = i;
3160 3876
3161 /* Fold nodes into a single device if they share the same bus info */
3162 drmFoldDuplicatedDevices(local_devices, node_count); 3877 drmFoldDuplicatedDevices(local_devices, node_count);
3163 3878
3164 *device = local_devices[0]; 3879 *device = local_devices[0];
3165 for (i = 1; i < node_count && local_devices[i]; i++) 3880 drmFreeDevices(&local_devices[1], node_count - 1);
3166 drmFreeDevice(&local_devices[i]);
3167 3881
3168 closedir(sysdir); 3882 closedir(sysdir);
3169 free(local_devices); 3883 free(local_devices);
3884 if (*device == NULL)
3885 return -ENODEV;
3170 return 0; 3886 return 0;
3171 3887
3172free_devices: 3888free_devices:
@@ -3176,11 +3892,27 @@ free_devices:
3176free_locals: 3892free_locals:
3177 free(local_devices); 3893 free(local_devices);
3178 return ret; 3894 return ret;
3895#endif
3896}
3897
3898/**
3899 * Get information about the opened drm device
3900 *
3901 * \param fd file descriptor of the drm device
3902 * \param device the address of a drmDevicePtr where the information
3903 * will be allocated in stored
3904 *
3905 * \return zero on success, negative error code otherwise.
3906 */
3907int drmGetDevice(int fd, drmDevicePtr *device)
3908{
3909 return drmGetDevice2(fd, DRM_DEVICE_GET_PCI_REVISION, device);
3179} 3910}
3180 3911
3181/** 3912/**
3182 * Get drm devices on the system 3913 * Get drm devices on the system
3183 * 3914 *
3915 * \param flags feature/behaviour bitmask
3184 * \param devices the array of devices with drmDevicePtr elements 3916 * \param devices the array of devices with drmDevicePtr elements
3185 * can be NULL to get the device number first 3917 * can be NULL to get the device number first
3186 * \param max_devices the maximum number of devices for the array 3918 * \param max_devices the maximum number of devices for the array
@@ -3189,8 +3921,11 @@ free_locals:
3189 * if devices is NULL - total number of devices available on the system, 3921 * if devices is NULL - total number of devices available on the system,
3190 * alternatively the number of devices stored in devices[], which is 3922 * alternatively the number of devices stored in devices[], which is
3191 * capped by the max_devices. 3923 * capped by the max_devices.
3924 *
3925 * \note Unlike drmGetDevices it does not retrieve the pci device revision field
3926 * unless the DRM_DEVICE_GET_PCI_REVISION \p flag is set.
3192 */ 3927 */
3193int drmGetDevices(drmDevicePtr devices[], int max_devices) 3928int drmGetDevices2(uint32_t flags, drmDevicePtr devices[], int max_devices)
3194{ 3929{
3195 drmDevicePtr *local_devices; 3930 drmDevicePtr *local_devices;
3196 drmDevicePtr device; 3931 drmDevicePtr device;
@@ -3203,6 +3938,9 @@ int drmGetDevices(drmDevicePtr devices[], int max_devices)
3203 int ret, i, node_count, device_count; 3938 int ret, i, node_count, device_count;
3204 int max_count = 16; 3939 int max_count = 16;
3205 3940
3941 if (drm_device_validate_flags(flags))
3942 return -EINVAL;
3943
3206 local_devices = calloc(max_count, sizeof(drmDevicePtr)); 3944 local_devices = calloc(max_count, sizeof(drmDevicePtr));
3207 if (local_devices == NULL) 3945 if (local_devices == NULL)
3208 return -ENOMEM; 3946 return -ENOMEM;
@@ -3236,14 +3974,38 @@ int drmGetDevices(drmDevicePtr devices[], int max_devices)
3236 3974
3237 switch (subsystem_type) { 3975 switch (subsystem_type) {
3238 case DRM_BUS_PCI: 3976 case DRM_BUS_PCI:
3239 ret = drmProcessPciDevice(&device, dent->d_name, node, node_type, 3977 ret = drmProcessPciDevice(&device, node, node_type,
3240 maj, min, devices != NULL); 3978 maj, min, devices != NULL, flags);
3979 if (ret)
3980 continue;
3981
3982 break;
3983
3984 case DRM_BUS_USB:
3985 ret = drmProcessUsbDevice(&device, node, node_type, maj, min,
3986 devices != NULL, flags);
3987 if (ret)
3988 goto free_devices;
3989
3990 break;
3991
3992 case DRM_BUS_PLATFORM:
3993 ret = drmProcessPlatformDevice(&device, node, node_type, maj, min,
3994 devices != NULL, flags);
3995 if (ret)
3996 goto free_devices;
3997
3998 break;
3999
4000 case DRM_BUS_HOST1X:
4001 ret = drmProcessHost1xDevice(&device, node, node_type, maj, min,
4002 devices != NULL, flags);
3241 if (ret) 4003 if (ret)
3242 goto free_devices; 4004 goto free_devices;
3243 4005
3244 break; 4006 break;
4007
3245 default: 4008 default:
3246 fprintf(stderr, "The subsystem type is not supported yet\n");
3247 continue; 4009 continue;
3248 } 4010 }
3249 4011
@@ -3262,11 +4024,13 @@ int drmGetDevices(drmDevicePtr devices[], int max_devices)
3262 } 4024 }
3263 node_count = i; 4025 node_count = i;
3264 4026
3265 /* Fold nodes into a single device if they share the same bus info */
3266 drmFoldDuplicatedDevices(local_devices, node_count); 4027 drmFoldDuplicatedDevices(local_devices, node_count);
3267 4028
3268 device_count = 0; 4029 device_count = 0;
3269 for (i = 0; i < node_count && local_devices[i]; i++) { 4030 for (i = 0; i < node_count; i++) {
4031 if (!local_devices[i])
4032 continue;
4033
3270 if ((devices != NULL) && (device_count < max_devices)) 4034 if ((devices != NULL) && (device_count < max_devices))
3271 devices[device_count] = local_devices[i]; 4035 devices[device_count] = local_devices[i];
3272 else 4036 else
@@ -3287,3 +4051,92 @@ free_locals:
3287 free(local_devices); 4051 free(local_devices);
3288 return ret; 4052 return ret;
3289} 4053}
4054
4055/**
4056 * Get drm devices on the system
4057 *
4058 * \param devices the array of devices with drmDevicePtr elements
4059 * can be NULL to get the device number first
4060 * \param max_devices the maximum number of devices for the array
4061 *
4062 * \return on error - negative error code,
4063 * if devices is NULL - total number of devices available on the system,
4064 * alternatively the number of devices stored in devices[], which is
4065 * capped by the max_devices.
4066 */
4067int drmGetDevices(drmDevicePtr devices[], int max_devices)
4068{
4069 return drmGetDevices2(DRM_DEVICE_GET_PCI_REVISION, devices, max_devices);
4070}
4071
4072char *drmGetDeviceNameFromFd2(int fd)
4073{
4074#ifdef __linux__
4075 struct stat sbuf;
4076 char path[PATH_MAX + 1], *value;
4077 unsigned int maj, min;
4078
4079 if (fstat(fd, &sbuf))
4080 return NULL;
4081
4082 maj = major(sbuf.st_rdev);
4083 min = minor(sbuf.st_rdev);
4084
4085 if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
4086 return NULL;
4087
4088 snprintf(path, sizeof(path), "/sys/dev/char/%d:%d", maj, min);
4089
4090 value = sysfs_uevent_get(path, "DEVNAME");
4091 if (!value)
4092 return NULL;
4093
4094 snprintf(path, sizeof(path), "/dev/%s", value);
4095 free(value);
4096
4097 return strdup(path);
4098#else
4099 struct stat sbuf;
4100 char node[PATH_MAX + 1];
4101 const char *dev_name;
4102 int node_type;
4103 int maj, min, n, base;
4104
4105 if (fstat(fd, &sbuf))
4106 return NULL;
4107
4108 maj = major(sbuf.st_rdev);
4109 min = minor(sbuf.st_rdev);
4110
4111 if (maj != DRM_MAJOR || !S_ISCHR(sbuf.st_mode))
4112 return NULL;
4113
4114 node_type = drmGetMinorType(min);
4115 if (node_type == -1)
4116 return NULL;
4117
4118 switch (node_type) {
4119 case DRM_NODE_PRIMARY:
4120 dev_name = DRM_DEV_NAME;
4121 break;
4122 case DRM_NODE_CONTROL:
4123 dev_name = DRM_CONTROL_DEV_NAME;
4124 break;
4125 case DRM_NODE_RENDER:
4126 dev_name = DRM_RENDER_DEV_NAME;
4127 break;
4128 default:
4129 return NULL;
4130 };
4131
4132 base = drmGetMinorBase(node_type);
4133 if (base < 0)
4134 return NULL;
4135
4136 n = snprintf(node, PATH_MAX, dev_name, DRM_DIR_NAME, min - base);
4137 if (n == -1 || n >= PATH_MAX)
4138 return NULL;
4139
4140 return strdup(node);
4141#endif
4142}