diff options
Diffstat (limited to 'xf86drm.c')
-rw-r--r-- | xf86drm.c | 2433 |
1 files changed, 1643 insertions, 790 deletions
@@ -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__ | ||
106 | struct 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) | |||
128 | void | 147 | void |
129 | drmMsg(const char *format, ...) | 148 | drmMsg(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) | |||
166 | int | 185 | int |
167 | drmIoctl(int fd, unsigned long request, void *arg) | 186 | drmIoctl(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) |
278 | static int chown_check_return(const char *path, uid_t owner, gid_t group) | 297 | static 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; |
371 | wait_for_udev: | 390 | wait_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 | */ |
624 | static int drmOpenByName(const char *name, int type) | 643 | static 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) | |||
775 | void drmFreeVersion(drmVersionPtr v) | 794 | void 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) | |||
795 | static void drmFreeKernelVersion(drm_version_t *v) | 814 | static 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 | ||
916 | int drmGetCap(int fd, uint64_t capability, uint64_t *value) | 935 | int 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 | ||
932 | int drmSetClientCap(int fd, uint64_t capability, uint64_t value) | 951 | int 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 | */ |
1086 | int drmAddMap(int fd, drm_handle_t offset, drmSize size, drmMapType type, | 1105 | int 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 | */ |
1131 | int drmAddBufs(int fd, int count, int size, drmBufDescFlags flags, | 1150 | int 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 | */ |
1335 | drmBufMapPtr drmMapBufs(int fd) | 1354 | drmBufMapPtr 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 | ||
1659 | int drmUpdateDrawableInfo(int fd, drm_drawable_t handle, | 1676 | int 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 | */ |
1689 | int drmAgpAcquire(int fd) | 1706 | int 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 | */ |
1707 | int drmAgpRelease(int fd) | 1724 | int 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 | */ |
1755 | int drmAgpAlloc(int fd, unsigned long size, unsigned long type, | 1772 | int 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 | ||
2297 | int drmGetMap(int fd, int idx, drm_handle_t *offset, drmSize *size, | 2314 | int 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 | ||
2316 | int drmGetClient(int fd, int idx, int *auth, int *pid, int *uid, | 2333 | int 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 | */ |
2471 | int drmSetInterfaceVersion(int fd, drmSetVersion *version) | 2488 | int 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 | */ |
2506 | int drmCommandNone(int fd, unsigned long drmCommandIndex) | 2523 | int 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 | */ |
2533 | int drmCommandRead(int fd, unsigned long drmCommandIndex, void *data, | 2550 | int 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 | */ |
2562 | int drmCommandWrite(int fd, unsigned long drmCommandIndex, void *data, | 2579 | int 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 | */ |
2591 | int drmCommandWriteRead(int fd, unsigned long drmCommandIndex, void *data, | 2608 | int 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 | ||
2612 | static int nr_fds = 0; | 2629 | static int nr_fds = 0; |
2613 | 2630 | ||
2614 | int drmOpenOnce(void *unused, | 2631 | int 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 | ||
2673 | int drmSetMaster(int fd) | 2690 | int 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 | ||
2678 | int drmDropMaster(int fd) | 2695 | int 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 | ||
2683 | char *drmGetDeviceNameFromFd(int fd) | 2700 | char *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 | ||
2709 | int drmGetNodeTypeFromFd(int fd) | 2726 | int 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 | ||
2731 | int drmPrimeHandleToFD(int fd, uint32_t handle, uint32_t flags, int *prime_fd) | 2748 | int 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 | ||
2748 | int drmPrimeFDToHandle(int fd, int prime_fd, uint32_t *handle) | 2765 | int 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 | ||
2763 | static char *drmGetMinorNameForFD(int fd, int type) | 2780 | static 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 | ||
2817 | out_close_dir: | 2834 | out_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 | ||
2825 | char *drmGetPrimaryDeviceNameFromFd(int fd) | 2879 | char *drmGetPrimaryDeviceNameFromFd(int fd) |
2826 | { | 2880 | { |
2827 | return drmGetMinorNameForFD(fd, DRM_NODE_PRIMARY); | 2881 | return drmGetMinorNameForFD(fd, DRM_NODE_PRIMARY); |
2828 | } | 2882 | } |
2829 | 2883 | ||
2830 | char *drmGetRenderDeviceNameFromFd(int fd) | 2884 | char *drmGetRenderDeviceNameFromFd(int fd) |
2831 | { | 2885 | { |
2832 | return drmGetMinorNameForFD(fd, DRM_NODE_RENDER); | 2886 | return drmGetMinorNameForFD(fd, DRM_NODE_RENDER); |
2887 | } | ||
2888 | |||
2889 | #ifdef __linux__ | ||
2890 | static char * DRM_PRINTFLIKE(2, 3) | ||
2891 | sysfs_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 | ||
2835 | static int drmParseSubsystemType(int maj, int min) | 2933 | static 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) | |||
2862 | static int drmParsePciBusInfo(int maj, int min, drmPciBusInfoPtr info) | 2971 | static 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 | ||
2947 | static int drmParsePciDeviceInfo(const char *d_name, | ||
2948 | drmPciDeviceInfoPtr device) | ||
2949 | { | ||
2950 | #ifdef __linux__ | 3080 | #ifdef __linux__ |
3081 | static 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 | |||
3121 | static 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 | |||
3148 | static 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 | ||
3191 | static 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 | |||
3207 | static 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 | |||
2978 | void drmFreeDevice(drmDevicePtr *device) | 3223 | void 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 | ||
2998 | static int drmProcessPciDevice(drmDevicePtr *device, const char *d_name, | 3256 | static 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 | |||
3293 | static 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 | ||
3045 | free_device: | 3329 | free_device: |
3046 | free(*device); | 3330 | free(dev); |
3047 | *device = NULL; | 3331 | return ret; |
3332 | } | ||
3333 | |||
3334 | static 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 | |||
3373 | static 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 | |||
3402 | static 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 | |||
3436 | free_device: | ||
3437 | free(dev); | ||
3438 | return ret; | ||
3439 | } | ||
3440 | |||
3441 | static 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 | |||
3463 | static 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 | |||
3496 | free: | ||
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 | |||
3508 | static 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 | |||
3543 | free_device: | ||
3544 | free(dev); | ||
3545 | return ret; | ||
3546 | } | ||
3547 | |||
3548 | static 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 | |||
3570 | static 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 | |||
3603 | free: | ||
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 | |||
3615 | static 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 | |||
3650 | free_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 | */ | ||
3051 | static void drmFoldDuplicatedDevices(drmDevicePtr local_devices[], int count) | 3660 | static 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 */ | ||
3678 | static int | ||
3679 | drm_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 | */ |
3077 | int drmGetDevice(int fd, drmDevicePtr *device) | 3697 | int 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 | ||
3172 | free_devices: | 3888 | free_devices: |
@@ -3176,11 +3892,27 @@ free_devices: | |||
3176 | free_locals: | 3892 | free_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 | */ | ||
3907 | int 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 | */ |
3193 | int drmGetDevices(drmDevicePtr devices[], int max_devices) | 3928 | int 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 | */ | ||
4067 | int drmGetDevices(drmDevicePtr devices[], int max_devices) | ||
4068 | { | ||
4069 | return drmGetDevices2(DRM_DEVICE_GET_PCI_REVISION, devices, max_devices); | ||
4070 | } | ||
4071 | |||
4072 | char *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 | } | ||